00001 /*========================================================================= 00002 00003 Program: Insight Segmentation & Registration Toolkit 00004 Module: $RCSfile: itkImageRegionConstIterator.h,v $ 00005 Language: C++ 00006 Date: $Date: 2002/09/30 12:43:58 $ 00007 Version: $Revision: 1.8 $ 00008 00009 Copyright (c) 2002 Insight Consortium. All rights reserved. 00010 See ITKCopyright.txt or http://www.itk.org/HTML/Copyright.htm for details. 00011 00012 This software is distributed WITHOUT ANY WARRANTY; without even 00013 the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR 00014 PURPOSE. See the above copyright notices for more information. 00015 00016 =========================================================================*/ 00017 #ifndef __itkImageRegionConstIterator_h 00018 #define __itkImageRegionConstIterator_h 00019 00020 #include "itkImageConstIterator.h" 00021 #include "itkImageIterator.h" 00022 00023 namespace itk 00024 { 00025 00072 template<typename TImage> 00073 class ImageRegionConstIterator : public ImageConstIterator<TImage> 00074 { 00075 public: 00077 typedef ImageRegionConstIterator Self; 00078 typedef ImageConstIterator<TImage> Superclass; 00079 00084 itkStaticConstMacro(ImageIteratorDimension, unsigned int, 00085 Superclass::ImageIteratorDimension); 00086 00089 typedef typename Superclass::IndexType IndexType; 00090 00093 typedef typename Superclass::SizeType SizeType; 00094 00096 typedef typename Superclass::RegionType RegionType; 00097 00100 typedef typename Superclass::ImageType ImageType; 00101 00105 typedef typename Superclass::PixelContainer PixelContainer; 00106 typedef typename Superclass::PixelContainerPointer PixelContainerPointer; 00107 00109 typedef typename Superclass::InternalPixelType InternalPixelType; 00110 00112 typedef typename Superclass::PixelType PixelType; 00113 00116 typedef typename Superclass::AccessorType AccessorType; 00117 00119 itkTypeMacro(ImageRegionConstIterator, ImageIterator); 00120 00122 ImageRegionConstIterator() : ImageConstIterator<TImage>() 00123 { 00124 m_SpanBeginOffset = 0; 00125 m_SpanEndOffset = 0; 00126 } 00127 00130 ImageRegionConstIterator(const ImageType *ptr, 00131 const RegionType ®ion) 00132 : ImageConstIterator<TImage>(ptr, region) 00133 { 00134 m_SpanBeginOffset = m_BeginOffset; 00135 m_SpanEndOffset = m_BeginOffset + static_cast<long>(m_Region.GetSize()[0]); 00136 } 00137 00144 ImageRegionConstIterator( const ImageIterator<TImage> &it) 00145 { 00146 this->ImageIterator<TImage>::operator=(it); 00147 IndexType ind = this->GetIndex(); 00148 m_SpanEndOffset = m_Offset + static_cast<long>(m_Region.GetSize()[0]) 00149 - (ind[0] - m_Region.GetIndex()[0]); 00150 m_SpanBeginOffset = m_SpanEndOffset 00151 - static_cast<long>(m_Region.GetSize()[0]); 00152 } 00153 00160 ImageRegionConstIterator( const ImageConstIterator<TImage> &it) 00161 { 00162 this->ImageConstIterator<TImage>::operator=(it); 00163 IndexType ind = this->GetIndex(); 00164 m_SpanEndOffset = m_Offset + static_cast<long>(m_Region.GetSize()[0]) 00165 - (ind[0] - m_Region.GetIndex()[0]); 00166 m_SpanBeginOffset = m_SpanEndOffset 00167 - static_cast<long>(m_Region.GetSize()[0]); 00168 } 00169 00173 Self Begin(void) const; 00174 00178 Self End(void) const; 00179 00180 00184 void SetIndex(const IndexType &ind) 00185 { Superclass::SetIndex(ind); 00186 m_SpanEndOffset = m_Offset + static_cast<long>(m_Region.GetSize()[0]) 00187 - (ind[0] - m_Region.GetIndex()[0]); 00188 m_SpanBeginOffset = m_SpanEndOffset 00189 - static_cast<long>(m_Region.GetSize()[0]); 00190 } 00191 00199 Self & 00200 operator++() 00201 { 00202 if (++m_Offset >= m_SpanEndOffset) 00203 { 00204 // We have reached the end of the span (row), need to wrap around. 00205 00206 // First back up one pixel, because we are going to use a different 00207 // algorithm to compute the next pixel 00208 --m_Offset; 00209 00210 // Get the index of the last pixel on the span (row) 00211 typename ImageIterator<TImage>::IndexType 00212 ind = m_Image->ComputeIndex( static_cast<typename Superclass::OffsetValueType>(m_Offset) ); 00213 00214 const typename ImageIterator<TImage>::IndexType& 00215 startIndex = m_Region.GetIndex(); 00216 const typename ImageIterator<TImage>::SizeType& 00217 size = m_Region.GetSize(); 00218 00219 // Increment along a row, then wrap at the end of the region row. 00220 bool done; 00221 unsigned int dim; 00222 00223 // Check to see if we are past the last pixel in the region 00224 // Note that ++ind[0] moves to the next pixel along the row. 00225 done = (++ind[0] == startIndex[0] + static_cast<typename Superclass::IndexValueType>(size[0])); 00226 for (unsigned int i=1; done && i < ImageIteratorDimension; i++) 00227 { 00228 done = (ind[i] == startIndex[i] + static_cast<typename Superclass::IndexValueType>(size[i]) - 1); 00229 } 00230 00231 // if the iterator is outside the region (but not past region end) then 00232 // we need to wrap around the region 00233 dim = 0; 00234 if (!done) 00235 { 00236 while ( ( dim+1 < ImageIteratorDimension ) 00237 && (ind[dim] > startIndex[dim] + static_cast<typename Superclass::IndexValueType>(size[dim]) - 1) ) 00238 { 00239 ind[dim] = startIndex[dim]; 00240 ind[++dim]++; 00241 } 00242 } 00243 m_Offset = m_Image->ComputeOffset( ind ); 00244 m_SpanEndOffset = m_Offset + static_cast<long>(size[0]); 00245 m_SpanBeginOffset = m_Offset; 00246 } 00247 return *this; 00248 } 00249 00257 Self & operator--() 00258 { 00259 if (--m_Offset < m_SpanBeginOffset) 00260 { 00261 // We have pasted the beginning of the span (row), need to wrap around. 00262 00263 // First move forward one pixel, because we are going to use a different 00264 // algorithm to compute the next pixel 00265 m_Offset++; 00266 00267 // Get the index of the first pixel on the span (row) 00268 typename ImageIterator<TImage>::IndexType 00269 ind = m_Image->ComputeIndex( static_cast<typename Superclass::IndexValueType>(m_Offset) ); 00270 00271 const typename ImageIterator<TImage>::IndexType& 00272 startIndex = m_Region.GetIndex(); 00273 const typename ImageIterator<TImage>::SizeType& 00274 size = m_Region.GetSize(); 00275 00276 // Deccrement along a row, then wrap at the beginning of the region row. 00277 bool done; 00278 unsigned int dim; 00279 00280 // Check to see if we are past the first pixel in the region 00281 // Note that --ind[0] moves to the previous pixel along the row. 00282 done = (--ind[0] == startIndex[0] - 1); 00283 for (unsigned int i=1; done && i < ImageIteratorDimension; i++) 00284 { 00285 done = (ind[i] == startIndex[i]); 00286 } 00287 00288 // if the iterator is outside the region (but not past region begin) then 00289 // we need to wrap around the region 00290 dim = 0; 00291 if (!done) 00292 { 00293 while ( (dim < ImageIteratorDimension - 1) 00294 && (ind[dim] < startIndex[dim]) ) 00295 { 00296 ind[dim] = startIndex[dim] + static_cast<typename Superclass::IndexValueType>(size[dim]) - 1; 00297 ind[++dim]--; 00298 } 00299 } 00300 m_Offset = m_Image->ComputeOffset( ind ); 00301 m_SpanEndOffset = m_Offset + 1; 00302 m_SpanBeginOffset = m_SpanEndOffset - static_cast<long>(size[0]); 00303 } 00304 return *this; 00305 } 00306 00307 protected: 00308 unsigned long m_SpanBeginOffset; // one pixel before the beginning of the span (row) 00309 unsigned long m_SpanEndOffset; // one pixel past the end of the span (row) 00310 00311 }; 00312 00313 } // end namespace itk 00314 00315 #ifndef ITK_MANUAL_INSTANTIATION 00316 #include "itkImageRegionConstIterator.txx" 00317 #endif 00318 00319 #endif