/* This file is part of the Pangolin Project. * http://github.com/stevenlovegrove/Pangolin * * Copyright (c) 2011 Steven Lovegrove * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation * files (the "Software"), to deal in the Software without * restriction, including without limitation the rights to use, * copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following * conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR * OTHER DEALINGS IN THE SOFTWARE. */ #pragma once #include #include namespace pangolin { template using DefaultImageAllocator = std::allocator; // Image that manages it's own memory, storing a strong pointer to it's memory template > class ManagedImage : public Image { public: // Destructor inline ~ManagedImage() { Deallocate(); } // Null image inline ManagedImage() { } // Row image inline ManagedImage(size_t w) : Image( Allocator().allocate(w), w, 1, w*sizeof(T) ) { } inline ManagedImage(size_t w, size_t h) : Image( Allocator().allocate(w*h), w, h, w*sizeof(T) ) { } inline ManagedImage(size_t w, size_t h, size_t pitch_bytes) : Image( Allocator().allocate( (h*pitch_bytes) / sizeof(T) + 1), w, h, pitch_bytes ) { } // Not copy constructable inline ManagedImage( const ManagedImage& other ) = delete; // Move constructor inline ManagedImage(ManagedImage&& img) { *this = std::move(img); } // Move asignment inline void operator=(ManagedImage&& img) { Deallocate(); Image::pitch = img.pitch; Image::ptr = img.ptr; Image::w = img.w; Image::h = img.h; img.ptr = nullptr; } // Explicit copy constructor template ManagedImage( const CopyObject& other ) { CopyFrom(other.obj); } // Explicit copy assignment template void operator=(const CopyObject& other) { CopyFrom(other.obj); } inline void Swap(ManagedImage& img) { std::swap(img.pitch, Image::pitch); std::swap(img.ptr, Image::ptr); std::swap(img.w, Image::w); std::swap(img.h, Image::h); } inline void CopyFrom(const Image& img) { if(!Image::IsValid() || Image::w != img.w || Image::h != img.h) { Reinitialise(img.w,img.h); } Image::CopyFrom(img); } inline void Reinitialise(size_t w, size_t h) { if(!Image::ptr || Image::w != w || Image::h != h) { *this = ManagedImage(w,h); } } inline void Reinitialise(size_t w, size_t h, size_t pitch) { if(!Image::ptr || Image::w != w || Image::h != h || Image::pitch != pitch) { *this = ManagedImage(w,h,pitch); } } inline void Deallocate() { if (Image::ptr) { Allocator().deallocate(Image::ptr, (Image::h * Image::pitch) / sizeof(T) ); Image::ptr = nullptr; } } // Move asignment template inline void OwnAndReinterpret(ManagedImage&& img) { Deallocate(); Image::pitch = img.pitch; Image::ptr = (T*)img.ptr; Image::w = img.w; Image::h = img.h; img.ptr = nullptr; } }; }