1 /*
2  * Medical Image Registration ToolKit (MIRTK)
3  *
4  * Copyright 2013-2015 Imperial College London
5  * Copyright 2013-2015 Andreas Schuh
6  *
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  *     http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  */
19 
20 #ifndef MIRTK_ImageIterator_H
21 #define MIRTK_ImageIterator_H
22 
23 #include "mirtk/Voxel.h"
24 #include "mirtk/BaseImage.h"
25 #include "mirtk/ConstImageIterator.h"
26 
27 
28 namespace mirtk {
29 
30 
31 /**
32  * Base class of non-const image iterator
33  */
34 class ImageIterator : public ConstImageIterator
35 {
36 public:
37 
38   // ---------------------------------------------------------------------------
39   // Construction/Destruction
40 
41   /// Constructor
42   ImageIterator(const ImageAttributes &, int);
43 
44   /// Constructor
45   ImageIterator(const ImageAttributes &, void * = NULL, int = MIRTK_VOXEL_UNKNOWN);
46 
47   /// Constructor
48   ImageIterator(BaseImage &);
49 
50   /// Constructor
51   ImageIterator(BaseImage *);
52 
53   /// Copy constructor
54   ImageIterator(const ConstImageIterator &);
55 
56   /// Assignment operator
57   ImageIterator &operator =(const ImageIterator &);
58 
59   /// Destructor
60   virtual ~ImageIterator();
61 
62   // ---------------------------------------------------------------------------
63   // Iteration
64 
65   /// Get pointer to current iterator position
66   ///
67   /// The VoxelType template argument must match the actual scalar type of the image.
68   template <class VoxelType>
69   VoxelType *Current() const;
70 
71   /// Get pointer to current iterator position
72   ///
73   /// The VoxelType template argument must match the actual scalar type of the image.
74   ///
75   /// \param[in] t Channel/Component/Frame offset relative to current iterator position.
76   ///              For example, set iterator region to only the first channel/frame and
77   ///              then access other channels/vector components/frames using this method.
78   template <class VoxelType>
79   VoxelType *Current(int) const;
80 
81   /// Get pointer to current iterator position and post-increment iterator
82   ///
83   /// The VoxelType template argument must match the actual scalar type of the image.
84   template <class VoxelType>
85   VoxelType *Next();
86 
87   /// Get pointer to current iterator position and post-increment iterator
88   ///
89   /// The VoxelType template argument must match the actual scalar type of the image.
90   ///
91   /// \param[in] t Channel/Component/Frame offset relative to current iterator position.
92   ///              For example, set iterator region to only the first channel/frame and
93   ///              then access other channels/vector components/frames using this method.
94   template <class VoxelType>
95   VoxelType *Next(int);
96 
97   /// Get reference to voxel value at current iterator position
98   ///
99   /// The VoxelType template argument must match the actual scalar type of the image.
100   template <class VoxelType>
101   VoxelType &Value() const;
102 
103   /// Get reference to voxel value at current iterator position
104   ///
105   /// The VoxelType template argument must match the actual scalar type of the image.
106   ///
107   /// \param[in] t Channel/Component/Frame offset relative to current iterator position.
108   ///              For example, set iterator region to only the first channel/frame and
109   ///              then access other channels/vector components/frames using this method.
110   template <class VoxelType>
111   VoxelType &Value(int t) const;
112 
113 };
114 
115 //////////////////////////////////////////////////////////////////////////////
116 // Inline definitions
117 //////////////////////////////////////////////////////////////////////////////
118 
119 // ===========================================================================
120 // Construction/Destruction
121 // ===========================================================================
122 
123 // ---------------------------------------------------------------------------
ImageIterator(const ImageAttributes & attr,int type)124 inline ImageIterator::ImageIterator(const ImageAttributes &attr, int type)
125 :
126   ConstImageIterator(attr, type)
127 {
128 }
129 
130 // ---------------------------------------------------------------------------
ImageIterator(const ImageAttributes & attr,void * data,int type)131 inline ImageIterator::ImageIterator(const ImageAttributes &attr, void *data, int type)
132 :
133   ConstImageIterator(attr, data, type)
134 {
135 }
136 
137 // ---------------------------------------------------------------------------
ImageIterator(BaseImage & image)138 inline ImageIterator::ImageIterator(BaseImage &image)
139 :
140   ConstImageIterator(image)
141 {
142 }
143 
144 // ---------------------------------------------------------------------------
ImageIterator(BaseImage * image)145 inline ImageIterator::ImageIterator(BaseImage *image)
146 :
147   ConstImageIterator(image)
148 {
149 }
150 
151 // ---------------------------------------------------------------------------
ImageIterator(const ConstImageIterator & other)152 inline ImageIterator::ImageIterator(const ConstImageIterator &other)
153 :
154   ConstImageIterator(other)
155 {
156 }
157 
158 // ---------------------------------------------------------------------------
159 inline ImageIterator &ImageIterator::operator =(const ImageIterator &rhs)
160 {
161   ConstImageIterator::operator =(rhs);
162   return *this;
163 }
164 
165 // ---------------------------------------------------------------------------
~ImageIterator()166 inline ImageIterator::~ImageIterator()
167 {
168 }
169 
170 // ===========================================================================
171 // Iteration
172 // ===========================================================================
173 
174 // ---------------------------------------------------------------------------
175 template <class VoxelType>
Current()176 inline VoxelType *ImageIterator::Current() const
177 {
178   return reinterpret_cast<VoxelType *>(const_cast<char *>(_Next));
179 }
180 
181 // ---------------------------------------------------------------------------
182 template <class VoxelType>
Current(int t)183 inline VoxelType *ImageIterator::Current(int t) const
184 {
185   return reinterpret_cast<VoxelType *>(const_cast<char *>(_Next) + t * _XYZ);
186 }
187 
188 // ---------------------------------------------------------------------------
189 template <class VoxelType>
Next()190 inline VoxelType *ImageIterator::Next()
191 {
192   VoxelType *current = reinterpret_cast<VoxelType *>(const_cast<char *>(_Next));
193   this->operator ++();
194   return current;
195 }
196 
197 // ---------------------------------------------------------------------------
198 template <class VoxelType>
Next(int t)199 inline VoxelType *ImageIterator::Next(int t)
200 {
201   VoxelType *current = reinterpret_cast<VoxelType *>(const_cast<char *>(_Next) + t * _XYZ);
202   this->operator ++();
203   return current;
204 }
205 
206 // ---------------------------------------------------------------------------
207 template <class VoxelType>
Value()208 inline VoxelType &ImageIterator::Value() const
209 {
210   return *reinterpret_cast<VoxelType *>(const_cast<char *>(_Next));
211 }
212 
213 // ---------------------------------------------------------------------------
214 template <class VoxelType>
Value(int t)215 inline VoxelType &ImageIterator::Value(int t) const
216 {
217   return *reinterpret_cast<VoxelType *>(const_cast<char *>(_Next) + t * _XYZ);
218 }
219 
220 
221 } // namespace mirtk
222 
223 #endif // MIRTK_ImageIterator_H
224