/*========================================================================= * * Copyright NumFOCUS * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * https://www.apache.org/licenses/LICENSE-2.0.txt * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * *=========================================================================*/ #ifndef itkImportImageContainer_h #define itkImportImageContainer_h #include "itkObject.h" #include "itkObjectFactory.h" #include namespace itk { /** \class ImportImageContainer * \brief Defines an itk::Image front-end to a standard C-array. * * Defines an itk::Image front-end to a standard C-array. This container * conforms to the ImageContainerInterface. This is a full-fledged Object, * so there is modification time, debug, and reference count information. * * \tparam TElementIdentifier An INTEGRAL type for use in indexing the * imported buffer. * * \tparam TElement The element type stored in the container. * * \ingroup ImageObjects * \ingroup IOFilters * \ingroup ITKCommon */ template class ITK_TEMPLATE_EXPORT ImportImageContainer : public Object { public: ITK_DISALLOW_COPY_AND_MOVE(ImportImageContainer); /** Standard class type aliases. */ using Self = ImportImageContainer; using Superclass = Object; using Pointer = SmartPointer; using ConstPointer = SmartPointer; /** Save the template parameters. */ using ElementIdentifier = TElementIdentifier; using Element = TElement; /** Method for creation through the object factory. */ itkNewMacro(Self); /** \see LightObject::GetNameOfClass() */ itkOverrideGetNameOfClassMacro(ImportImageContainer); /** Get the pointer from which the image data is imported. */ TElement * GetImportPointer() { return m_ImportPointer; } /** Set the pointer from which the image data is imported. "num" is * the number of pixels in the block of memory. If * "LetContainerManageMemory" is false, then the application retains * the responsibility of freeing the memory for this image data. If * "LetContainerManageMemory" is true, then this class will free the * memory when this object is destroyed. */ void SetImportPointer(TElement * ptr, TElementIdentifier num, bool LetContainerManageMemory = false); /** Index operator. This version can be an lvalue. */ TElement & operator[](const ElementIdentifier id) { return m_ImportPointer[id]; } /** Index operator. This version can only be an rvalue */ const TElement & operator[](const ElementIdentifier id) const { return m_ImportPointer[id]; } /** Return a pointer to the beginning of the buffer. This is used by * the image iterator class. */ TElement * GetBufferPointer() { return m_ImportPointer; } /** Get the capacity of the container. */ ElementIdentifier Capacity() const { return m_Capacity; } /** Get the number of elements currently stored in the container. */ ElementIdentifier Size() const { return m_Size; } /** Tell the container to allocate enough memory to allow at least * as many elements as the size given to be stored. If new memory * needs to be allocated, the contents of the old buffer are copied * to the new area. The old buffer is deleted if the original pointer * was passed in using "LetContainerManageMemory"=true. The new buffer's * memory management will be handled by the container from that point on. * * In general, Reserve should not change the usable elements of the * container. However, in this particular case, Reserve as a Resize * semantics that is kept for backward compatibility reasons. * * If UseValueInitialization is true, then POD types will be * zero-initialized. * * \sa SetImportPointer() */ void Reserve(ElementIdentifier size, const bool UseValueInitialization = false); /** Tell the container to try to minimize its memory usage for * storage of the current number of elements. If new memory is * allocated, the contents of old buffer are copied to the new area. * The previous buffer is deleted if the original pointer was in * using "LetContainerManageMemory"=true. The new buffer's memory * management will be handled by the container from that point on. */ void Squeeze(); /** Tell the container to release any of its allocated memory. */ void Initialize(); /** These methods allow to define whether upon destruction of this class * the memory buffer should be released or not. Setting it to true * (or ON) makes that this class will take care of memory release. * Setting it to false (or OFF) will prevent the destructor from * deleting the memory buffer. This is desirable only when the data * is intended to be used by external applications. * Note that the normal logic of this class set the value of the boolean * flag. This may override your setting if you call this methods prematurely. * \warning Improper use of these methods will result in memory leaks */ itkSetMacro(ContainerManageMemory, bool); itkGetConstMacro(ContainerManageMemory, bool); itkBooleanMacro(ContainerManageMemory); protected: ImportImageContainer() = default; ~ImportImageContainer() override; /** PrintSelf routine. Normally this is a protected internal method. It is * made public here so that Image can call this method. Users should not * call this method but should call Print() instead. */ void PrintSelf(std::ostream & os, Indent indent) const override; /** * Allocates elements of the array. If UseValueInitialization is true, then * POD types will be zero-initialized. */ virtual TElement * AllocateElements(ElementIdentifier size, bool UseValueInitialization = false) const; virtual void DeallocateManagedMemory(); /* Set the m_Size member that represents the number of elements * currently stored in the container. Use this function with great * care since it only changes the m_Size member and not the actual size * of the import pointer m_ImportPointer. It should typically * be used only to override AllocateElements and * DeallocateManagedMemory. */ itkSetMacro(Size, TElementIdentifier); /* Set the m_Capacity member that represents the capacity of * the current container. Use this function with great care * since it only changes the m_Capacity member and not the actual * capacity of the import pointer m_ImportPointer. It should typically * be used only to override AllocateElements and * DeallocateManagedMemory. */ itkSetMacro(Capacity, TElementIdentifier); /* Set the m_ImportPointer member. Use this function with great care * since it only changes the m_ImportPointer member but not the m_Size * and m_Capacity members. It should typically be used only to override * AllocateElements and DeallocateManagedMemory. */ void SetImportPointer(TElement * ptr) { m_ImportPointer = ptr; } private: TElement * m_ImportPointer{}; TElementIdentifier m_Size{}; TElementIdentifier m_Capacity{}; bool m_ContainerManageMemory{ true }; }; } // end namespace itk #ifndef ITK_MANUAL_INSTANTIATION # include "itkImportImageContainer.hxx" #endif #endif