1 /*=========================================================================
2  *
3  *  Copyright Insight Software Consortium
4  *
5  *  Licensed under the Apache License, Version 2.0 (the "License");
6  *  you may not use this file except in compliance with the License.
7  *  You may obtain a copy of the License at
8  *
9  *         http://www.apache.org/licenses/LICENSE-2.0.txt
10  *
11  *  Unless required by applicable law or agreed to in writing, software
12  *  distributed under the License is distributed on an "AS IS" BASIS,
13  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  *  See the License for the specific language governing permissions and
15  *  limitations under the License.
16  *
17  *=========================================================================*/
18 #ifndef itkVectorImage_h
19 #define itkVectorImage_h
20 
21 #include "itkImageRegion.h"
22 #include "itkImportImageContainer.h"
23 #include "itkDefaultVectorPixelAccessor.h"
24 #include "itkDefaultVectorPixelAccessorFunctor.h"
25 #include "itkVectorImageNeighborhoodAccessorFunctor.h"
26 #include "itkWeakPointer.h"
27 
28 namespace itk
29 {
30 /** \class VectorImage
31  *  \brief Templated n-dimensional vector image class.
32  *
33  * This class differs from Image in that it is intended to represent multiple
34  * images. Each pixel represents \e k measurements, each of datatype \e TPixel.
35  * The memory organization of the resulting image is as follows:
36  *   ... Pi0 Pi1 Pi2 Pi3 P(i+1)0 P(i+1)1 P(i+1)2 P(i+1)3 P(i+2)0 ...
37  * where Pi0 represents the 0th measurement of the pixel at index i.
38  *
39  * Conceptually, a <tt>VectorImage< TPixel, 3 ></tt> is the same as a
40  * <tt>Image< VariableLengthVector< TPixel >, 3 ></tt>. The difference lies in the memory
41  * organization. The latter results in a fragmented
42  * organization with each location in the Image holding a pointer to an \c VariableLengthVector
43  * holding the actual pixel. The former stores the \e k pixels instead of a
44  * pointer reference, which apart from avoiding fragmentation of memory also avoids
45  * storing a 8 bytes of pointer reference for each pixel.
46  * The parameter \e k can be set using \c SetVectorLength.
47  *
48  * The API of the class is such that it returns a pixeltype VariableLengthVector< TPixel > when
49  * queried, with the data internally pointing to the buffer. (the container does not
50  * manage the memory). Similarly SetPixel calls can be made with VariableLengthVector< TPixel >.
51  *
52  * The API of this class is similar to Image.
53  *
54  * \par Caveats:
55  * When using Iterators on this image, you cannot use the it.Value(). You must use
56  * Set/Get() methods instead.
57  *
58  * \note
59  * This work is part of the National Alliance for Medical Image Computing
60  * (NAMIC), funded by the National Institutes of Health through the NIH Roadmap
61  * for Medical Research, Grant U54 EB005149.
62  *
63  * \sa DefaultVectorPixelAccessor
64  * \sa DefaultVectorPixelAccessorFunctor
65  * \sa VectorImageToImagePixelAccessor
66  * \sa VectorImageToImageAdaptor
67  * \sa Image
68  * \sa ImportImageContainer
69  *
70  *
71  * \ingroup ImageObjects
72  * \ingroup ITKCommon
73  *
74  * \wiki
75  * \wikiexample{IO/ReadVectorImage,Read an image file with an unknown number of components}
76  * \wikiexample{VectorImages/VectorImage,Create a vector image}
77  * \wikiexample{VectorImages/NeighborhoodIterator,NeighborhoodIterator on a VectorImage}
78  * \endwiki
79  */
80 template< typename TPixel, unsigned int VImageDimension = 3 >
81 class ITK_TEMPLATE_EXPORT VectorImage:
82   public ImageBase< VImageDimension >
83 {
84 public:
85   ITK_DISALLOW_COPY_AND_ASSIGN(VectorImage);
86 
87   /** Standard class type aliases */
88   using Self = VectorImage;
89   using Superclass = ImageBase< VImageDimension >;
90   using Pointer = SmartPointer< Self >;
91   using ConstPointer = SmartPointer< const Self >;
92   using ConstWeakPointer = WeakPointer< const Self >;
93 
94   /** Method for creation through the object factory. */
95   itkNewMacro(Self);
96 
97   /** Run-time type information (and related methods). */
98   itkTypeMacro(VectorImage, ImageBase);
99 
100   /** Pixel type alias support Used to declare pixel type in filters
101    * or other operations. This is not the actual pixel type contained in
102    * the buffer, ie m_Buffer. The image exhibits an external API of an
103    * VariableLengthVector< T > and internally stores its data as type T. */
104   using PixelType = VariableLengthVector< TPixel >;
105 
106   /** This is the actual pixel type contained in the buffer. Each vector
107    * pixel is composed of 'm_VectorLength' contiguous InternalPixelType.
108    */
109   using InternalPixelType = TPixel;
110 
111   /** Typedef alias for PixelType */
112   using ValueType = PixelType;
113 
114   using IOPixelType = InternalPixelType;
115 
116   /** Accessor type that convert data between internal and external
117    *  representations.  */
118   using AccessorType = DefaultVectorPixelAccessor< InternalPixelType >;
119 
120   /** Functor to provide a common API between DefaultPixelAccessor and
121    * DefaultVectorPixelAccessor */
122   using AccessorFunctorType = DefaultVectorPixelAccessorFunctor< Self >;
123 
124   /** Typedef for the functor used to access a neighborhood of pixel
125    * pointers. */
126   using NeighborhoodAccessorFunctorType = VectorImageNeighborhoodAccessorFunctor<Self>;
127 
128   /** Dimension of the image.  This constant is used by functions that are
129    * templated over image type (as opposed to being templated over pixel type
130    * and dimension) when they need compile time access to the dimension of
131    * the image. */
132   static constexpr unsigned int ImageDimension = VImageDimension;
133 
134   /** Index type alias support An index is used to access pixel values. */
135   using IndexType = typename Superclass::IndexType;
136   using IndexValueType = typename Superclass::IndexValueType;
137 
138   /** Offset type alias support An offset is used to access pixel values. */
139   using OffsetType = typename Superclass::OffsetType;
140 
141   /** Size type alias support A size is used to define region bounds. */
142   using SizeType = typename Superclass::SizeType;
143 
144   /** Container used to store pixels in the image. */
145   using PixelContainer = ImportImageContainer< SizeValueType, InternalPixelType >;
146 
147   /** Direction type alias support A matrix of direction cosines. */
148   using DirectionType = typename Superclass::DirectionType;
149 
150   /** Region type alias support A region is used to specify a subset of an image.
151     */
152   using RegionType = typename Superclass::RegionType;
153 
154   /** Spacing type alias support  Spacing holds the size of a pixel.  The
155    * spacing is the geometric distance between image samples. */
156   using SpacingType = typename Superclass::SpacingType;
157 
158   /** Origin type alias support  The origin is the geometric coordinates
159    * of the index (0,0). */
160   using PointType = typename Superclass::PointType;
161 
162   /** A pointer to the pixel container. */
163   using PixelContainerPointer = typename PixelContainer::Pointer;
164   using PixelContainerConstPointer = typename PixelContainer::ConstPointer;
165 
166   /** Offset type alias (relative position between indices) */
167   using OffsetValueType = typename Superclass::OffsetValueType;
168 
169   using VectorLengthType = unsigned int;
170 
171   /**
172    * \brief A structure which enable changing any image class' pixel
173    * type to another.
174    *
175    * Since the pixel type of this class is a VariableLengthVector of
176    * TPixelType, the following two rebinds result in the same type to
177    * enable usage with the numeric trait's type.
178    *
179      \code
180      typename InputImageType::template template Rebind<double>::Type RealImageType1;
181      typename InputImageType::template template Rebind<VariableLengthVector<double> >::Type RealImageType2;
182      \endcode
183    *
184    * \sa Image::Rebind
185    * \deprecated Use template alias RebindImageType instead
186    */
187   template <typename UPixelType, unsigned int NUImageDimension = VImageDimension>
188   struct Rebind
189   {
190     using Type = itk::VectorImage<UPixelType, NUImageDimension>;
191   };
192 
193   /// \cond HIDE_SPECIALIZATION_DOCUMENTATION
194   template <typename UElementType, unsigned int NUImageDimension>
195   struct Rebind< VariableLengthVector< UElementType >, NUImageDimension>
196   {
197     using Type = itk::VectorImage<UElementType, NUImageDimension>;
198   };
199   /// \endcond
200 
201   template <typename UPixelType, unsigned int NUImageDimension = VImageDimension>
202     using RebindImageType = typename Rebind<UPixelType, NUImageDimension>::Type;
203 
204   /** Allocate the image memory. The size of the image must
205    * already be set, e.g. by calling SetRegions(). */
206   void Allocate(bool UseDefaultConstructor = false) override;
207 
208   /** Restore the data object to its initial state. This means releasing
209    * memory. */
210   void Initialize() override;
211 
212   /** Fill the image buffer with a value.  Be sure to call Allocate()
213    * first. */
214   void FillBuffer(const PixelType & value);
215 
216   /** \brief Set a pixel value.
217    *
218    * Allocate() needs to have been called first -- for efficiency,
219    * this function does not check that the image has actually been
220    * allocated yet. */
221   void SetPixel(const IndexType & index, const PixelType & value)
222   {
223     OffsetValueType offset = m_VectorLength * this->FastComputeOffset(index);
224 
225     for ( VectorLengthType i = 0; i < m_VectorLength; i++ )
226       {
227       ( *m_Buffer )[offset + i] = value[i];
228       }
229   }
230 
231   /** \brief Get a pixel (read only version).
232    *
233    * For efficiency, this function does not check that the
234    * image has actually been allocated yet. Note that the method returns a
235    * pixel on the stack. */
236   const PixelType GetPixel(const IndexType & index) const
237   {
238     OffsetValueType offset = m_VectorLength * this->FastComputeOffset(index);
239 
240     // Do not create a local for this method, to use return value
241     // optimization.
242     return PixelType(&( ( *m_Buffer )[offset] ), m_VectorLength);
243   }
244 
245   /** \brief Get a "reference" to a pixel. This result cannot be used
246    * as an lvalue because the pixel is converted on the fly to a
247    * VariableLengthVector.
248    *
249    * To use the results to modify this image, return value
250    * optimization must be relied upon.
251    *
252    * For efficiency, this function does not check that the
253    * image has actually been allocated yet. */
254   PixelType  GetPixel(const IndexType & index)
255   {
256     OffsetValueType offset = m_VectorLength * this->FastComputeOffset(index);
257 
258     // Correctness of this method relies of return value optimization, do
259     // not create a local for the value.
260     return PixelType(&( ( *m_Buffer )[offset] ), m_VectorLength);
261   }
262 
263   /** \brief Access a pixel. This result cannot be used as an lvalue
264    * because the pixel is converted on the fly to a
265    * VariableLengthVector.
266    *
267    * To use the results to modify this image, return value
268    * optimization must be relied upon.
269    *
270    * For efficiency, this function does not check that the
271    * image has actually been allocated yet. */
272   PixelType operator[](const IndexType & index) { return this->GetPixel(index); }
273 
274   /** \brief Access a pixel.
275    *
276    * For efficiency, this function does not check that the
277    * image has actually been allocated yet. */
278   const PixelType operator[](const IndexType & index) const { return this->GetPixel(index); }
279 
280   /** Return a pointer to the beginning of the buffer.  This is used by
281    * the image iterator class. */
282   InternalPixelType * GetBufferPointer()
283   {
284     return m_Buffer ? m_Buffer->GetBufferPointer() : nullptr;
285   }
286   const InternalPixelType * GetBufferPointer() const
287   {
288     return m_Buffer ? m_Buffer->GetBufferPointer() : nullptr;
289   }
290 
291   /** Return a pointer to the container. */
292   PixelContainer * GetPixelContainer() { return m_Buffer.GetPointer(); }
293 
294   /** Return a pointer to the container. */
295   const PixelContainer * GetPixelContainer() const { return m_Buffer.GetPointer(); }
296 
297   /** Set the container to use. Note that this does not cause the
298    * DataObject to be modified. */
299   void SetPixelContainer(PixelContainer *container);
300 
301   /** Graft the data and information from one image to another. This
302    * is a convenience method to setup a second image with all the meta
303    * information of another image and use the same pixel
304    * container. Note that this method is different than just using two
305    * SmartPointers to the same image since separate DataObjects are
306    * still maintained. This method is similar to
307    * ImageSource::GraftOutput(). The implementation in ImageBase
308    * simply calls CopyInformation() and copies the region ivars.
309    * The implementation here refers to the superclass' implementation
310    * and then copies over the pixel container. */
311   virtual void Graft(const Self *data);
312 
313   /** Return the Pixel Accessor object */
314   AccessorType GetPixelAccessor() { return AccessorType(m_VectorLength); }
315 
316   /** Return the Pixel Accesor object */
317   const AccessorType GetPixelAccessor() const { return AccessorType(m_VectorLength); }
318 
319   /** Return the NeighborhoodAccessor functor */
320   NeighborhoodAccessorFunctorType GetNeighborhoodAccessor()
321   {
322     return NeighborhoodAccessorFunctorType(m_VectorLength);
323   }
324 
325   /** Return the NeighborhoodAccessor functor */
326   const NeighborhoodAccessorFunctorType GetNeighborhoodAccessor() const
327   {
328     return NeighborhoodAccessorFunctorType(m_VectorLength);
329   }
330 
331   /** Set/Get macros for the length of each vector in the vector image */
332   itkSetMacro(VectorLength, VectorLengthType);
333   itkGetConstReferenceMacro(VectorLength, VectorLengthType);
334 
335   /** Get/Set the number of components each pixel has, ie the VectorLength */
336   unsigned int GetNumberOfComponentsPerPixel() const override;
337 
338   void SetNumberOfComponentsPerPixel(unsigned int n) override;
339 
340 protected:
341   VectorImage();
342   void PrintSelf(std::ostream & os, Indent indent) const override;
343 
344   ~VectorImage() override = default;
345   void Graft(const DataObject *data) override;
346   using Superclass::Graft;
347 private:
348   /** Length of the "vector pixel" */
349   VectorLengthType m_VectorLength{0};
350 
351   /** Memory for the current buffer. */
352   PixelContainerPointer m_Buffer;
353 };
354 } // end namespace itk
355 
356 #ifndef ITK_MANUAL_INSTANTIATION
357 #include "itkVectorImage.hxx"
358 #endif
359 
360 #endif
361