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