ITK  4.2.0
Insight Segmentation and Registration Toolkit
itkImageConstIterator.h
Go to the documentation of this file.
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 __itkImageConstIterator_h
19 #define __itkImageConstIterator_h
20 
21 #include "itkImage.h"
22 #include "itkIndex.h"
23 #include "itkNumericTraits.h"
24 
25 namespace itk
26 {
83 template< typename TImage >
84 class ITK_EXPORT ImageConstIterator
85 {
86 public:
89 
94  itkStaticConstMacro(ImageIteratorDimension, unsigned int,
95  TImage::ImageDimension);
96 
98  typedef typename TImage::IndexType IndexType;
99 
101  typedef typename TImage::SizeType SizeType;
102 
104  typedef typename TImage::OffsetType OffsetType;
105 
107  typedef typename TImage::RegionType RegionType;
108 
110  typedef TImage ImageType;
111 
115  typedef typename TImage::PixelContainer PixelContainer;
116  typedef typename PixelContainer::Pointer PixelContainerPointer;
117 
119  typedef typename TImage::InternalPixelType InternalPixelType;
120 
122  typedef typename TImage::PixelType PixelType;
123 
126  typedef typename TImage::AccessorType AccessorType;
127  typedef typename TImage::AccessorFunctorType AccessorFunctorType;
128 
132  m_Region(),
133  m_PixelAccessor(),
134  m_PixelAccessorFunctor()
135  {
136  m_Image = 0;
137  m_Buffer = 0;
138  m_Offset = 0;
139  m_BeginOffset = 0;
140  m_EndOffset = 0;
141  m_PixelAccessorFunctor.SetBegin(m_Buffer);
142  }
144 
146  virtual ~ImageConstIterator() {}
147 
151  {
152  m_Image = it.m_Image; // copy the smart pointer
153 
154  m_Region = it.m_Region;
155 
156  m_Buffer = it.m_Buffer;
157  m_Offset = it.m_Offset;
158  m_BeginOffset = it.m_BeginOffset;
159  m_EndOffset = it.m_EndOffset;
160  m_PixelAccessor = it.m_PixelAccessor;
161  m_PixelAccessorFunctor = it.m_PixelAccessorFunctor;
162  m_PixelAccessorFunctor.SetBegin(m_Buffer);
163  }
164 
168  const RegionType & region)
169  {
170  m_Image = ptr;
171  m_Buffer = m_Image->GetBufferPointer();
172  m_Region = region;
174 
175  if ( region.GetNumberOfPixels() > 0 ) // If region is non-empty
176  {
177  const RegionType & bufferedRegion = m_Image->GetBufferedRegion();
178  itkAssertOrThrowMacro( ( bufferedRegion.IsInside(m_Region) ),
179  "Region " << m_Region << " is outside of buffered region " << bufferedRegion );
180  }
181 
182  // Compute the start offset
183  m_Offset = m_Image->ComputeOffset( m_Region.GetIndex() );
184  m_BeginOffset = m_Offset;
185 
186  // Compute the end offset. If any component of m_Region.GetSize()
187  // is zero, the region is not valid and we set the EndOffset
188  // to be same as BeginOffset so that iterator end condition is met
189  // immediately.
190  if ( m_Region.GetNumberOfPixels() == 0 )
191  {
192  // region is empty, probably has a size of 0 along one dimension
193  m_EndOffset = m_BeginOffset;
194  }
195  else
196  {
197  IndexType ind( m_Region.GetIndex() );
198  SizeType size( m_Region.GetSize() );
199  for ( unsigned int i = 0; i < TImage::ImageDimension; ++i )
200  {
201  ind[i] += ( static_cast< IndexValueType >( size[i] ) - 1 );
202  }
203  m_EndOffset = m_Image->ComputeOffset(ind);
204  m_EndOffset++;
205  }
206 
207  m_PixelAccessor = ptr->GetPixelAccessor();
208  m_PixelAccessorFunctor.SetPixelAccessor(m_PixelAccessor);
209  m_PixelAccessorFunctor.SetBegin(m_Buffer);
210  }
211 
214  Self & operator=(const Self & it)
215  {
216  m_Image = it.m_Image; // copy the smart pointer
217  m_Region = it.m_Region;
218 
219  m_Buffer = it.m_Buffer;
220  m_Offset = it.m_Offset;
221  m_BeginOffset = it.m_BeginOffset;
222  m_EndOffset = it.m_EndOffset;
223  m_PixelAccessor = it.m_PixelAccessor;
224  m_PixelAccessorFunctor = it.m_PixelAccessorFunctor;
225  m_PixelAccessorFunctor.SetBegin(m_Buffer);
226 
227  return *this;
228  }
229 
231  static unsigned int GetImageIteratorDimension()
232  { return TImage::ImageDimension; }
233 
236  bool
237  operator!=(const Self & it) const
238  {
239  // two iterators are the same if they "point to" the same memory location
240  return ( m_Buffer + m_Offset ) != ( it.m_Buffer + it.m_Offset );
241  }
242 
245  bool
246  operator==(const Self & it) const
247  {
248  // two iterators are the same if they "point to" the same memory location
249  return ( m_Buffer + m_Offset ) == ( it.m_Buffer + it.m_Offset );
250  }
251 
254  bool
255  operator<=(const Self & it) const
256  {
257  // an iterator is "less than" another if it "points to" a lower
258  // memory location
259  return ( m_Buffer + m_Offset ) <= ( it.m_Buffer + it.m_Offset );
260  }
261 
264  bool
265  operator<(const Self & it) const
266  {
267  // an iterator is "less than" another if it "points to" a lower
268  // memory location
269  return ( m_Buffer + m_Offset ) < ( it.m_Buffer + it.m_Offset );
270  }
271 
274  bool
275  operator>=(const Self & it) const
276  {
277  // an iterator is "greater than" another if it "points to" a higher
278  // memory location
279  return ( m_Buffer + m_Offset ) >= ( it.m_Buffer + it.m_Offset );
280  }
281 
284  bool
285  operator>(const Self & it) const
286  {
287  // an iterator is "greater than" another if it "points to" a higher
288  // memory location
289  return ( m_Buffer + m_Offset ) > ( it.m_Buffer + it.m_Offset );
290  }
291 
296  const IndexType GetIndex() const
297  { return m_Image->ComputeIndex( static_cast< OffsetValueType >( m_Offset ) ); }
298 
301  virtual void SetIndex(const IndexType & ind)
302  { m_Offset = m_Image->ComputeOffset(ind); }
303 
306  const RegionType & GetRegion() const
307  { return m_Region; }
308 
310  const ImageType * GetImage() const
311  { return m_Image.GetPointer(); }
312 
314  PixelType Get(void) const
315  { return m_PixelAccessorFunctor.Get( *( m_Buffer + m_Offset ) ); }
316 
320  const PixelType & Value(void) const
321  { return *( m_Buffer + m_Offset ); }
322 
327  itkLegacyMacro(Self Begin(void) const);
328 
331  void GoToBegin()
332  {
333  m_Offset = m_BeginOffset;
334  }
335 
340  itkLegacyMacro(Self End(void) const);
341 
344  void GoToEnd()
345  {
346  m_Offset = m_EndOffset;
347  }
348 
351  bool IsAtBegin(void) const
352  {
353  return ( m_Offset == m_BeginOffset );
354  }
355 
358  bool IsAtEnd(void) const
359  {
360  return ( m_Offset == m_EndOffset );
361  }
362 
363 protected: //made protected so other iterators can access
364  typename TImage::ConstWeakPointer m_Image;
365 
366  RegionType m_Region; // region to iterate over
367 
369  OffsetValueType m_BeginOffset; // offset to first pixel in region
370  OffsetValueType m_EndOffset; // offset to one pixel past last pixel in region
371 
372  const InternalPixelType *m_Buffer;
373 
374  AccessorType m_PixelAccessor;
375  AccessorFunctorType m_PixelAccessorFunctor;
376 };
377 } // end namespace itk
378 
379 // Define instantiation macro for this template.
380 #define ITK_TEMPLATE_ImageConstIterator(_, EXPORT, TypeX, TypeY) \
381  namespace itk \
382  { \
383  _( 1 ( class EXPORT ImageConstIterator< ITK_TEMPLATE_1 TypeX > ) ) \
384  namespace Templates \
385  { \
386  typedef ImageConstIterator< ITK_TEMPLATE_1 TypeX > ImageConstIterator##TypeY; \
387  } \
388  }
389 
390 #if ITK_TEMPLATE_EXPLICIT
391 #include "Templates/itkImageConstIterator+-.h"
392 #endif
393 
394 #if ITK_TEMPLATE_TXX
395 #include "itkImageConstIterator.hxx"
396 #endif
397 
398 #endif
399