ITK  4.0.0
Insight Segmentation and Registration Toolkit
itkImageConstIterator.h
Go to the documentation of this file.
00001 /*=========================================================================
00002  *
00003  *  Copyright Insight Software Consortium
00004  *
00005  *  Licensed under the Apache License, Version 2.0 (the "License");
00006  *  you may not use this file except in compliance with the License.
00007  *  You may obtain a copy of the License at
00008  *
00009  *         http://www.apache.org/licenses/LICENSE-2.0.txt
00010  *
00011  *  Unless required by applicable law or agreed to in writing, software
00012  *  distributed under the License is distributed on an "AS IS" BASIS,
00013  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
00014  *  See the License for the specific language governing permissions and
00015  *  limitations under the License.
00016  *
00017  *=========================================================================*/
00018 #ifndef __itkImageConstIterator_h
00019 #define __itkImageConstIterator_h
00020 
00021 #include "itkImage.h"
00022 #include "itkIndex.h"
00023 #include "itkNumericTraits.h"
00024 
00025 namespace itk
00026 {
00083 template< typename TImage >
00084 class ITK_EXPORT ImageConstIterator
00085 {
00086 public:
00088   typedef ImageConstIterator Self;
00089 
00094   itkStaticConstMacro(ImageIteratorDimension, unsigned int,
00095                       TImage::ImageDimension);
00096 
00098   typedef typename TImage::IndexType      IndexType;
00099 
00101   typedef typename TImage::SizeType      SizeType;
00102 
00104   typedef typename TImage::OffsetType      OffsetType;
00105 
00107   typedef typename TImage::RegionType RegionType;
00108 
00110   typedef TImage ImageType;
00111 
00115   typedef typename TImage::PixelContainer  PixelContainer;
00116   typedef typename PixelContainer::Pointer PixelContainerPointer;
00117 
00119   typedef typename TImage::InternalPixelType InternalPixelType;
00120 
00122   typedef typename TImage::PixelType PixelType;
00123 
00126   typedef typename TImage::AccessorType        AccessorType;
00127   typedef typename TImage::AccessorFunctorType AccessorFunctorType;
00128 
00131   ImageConstIterator():
00132     m_Region(),
00133     m_PixelAccessor(),
00134     m_PixelAccessorFunctor()
00135   {
00136     m_Image = 0;
00137     m_Buffer = 0;
00138     m_Offset = 0;
00139     m_BeginOffset = 0;
00140     m_EndOffset = 0;
00141     m_PixelAccessorFunctor.SetBegin(m_Buffer);
00142   }
00144 
00146   virtual ~ImageConstIterator() {}
00147 
00150   ImageConstIterator(const Self & it)
00151   {
00152     m_Image = it.m_Image;     // copy the smart pointer
00153 
00154     m_Region = it.m_Region;
00155 
00156     m_Buffer = it.m_Buffer;
00157     m_Offset = it.m_Offset;
00158     m_BeginOffset = it.m_BeginOffset;
00159     m_EndOffset = it.m_EndOffset;
00160     m_PixelAccessor = it.m_PixelAccessor;
00161     m_PixelAccessorFunctor = it.m_PixelAccessorFunctor;
00162     m_PixelAccessorFunctor.SetBegin(m_Buffer);
00163   }
00164 
00167   ImageConstIterator(const ImageType *ptr,
00168                      const RegionType & region)
00169   {
00170     m_Image = ptr;
00171     m_Buffer = m_Image->GetBufferPointer();
00172     m_Region = region;
00174 
00175     if ( region.GetNumberOfPixels() > 0 ) // If region is non-empty
00176       {
00177       const RegionType & bufferedRegion = m_Image->GetBufferedRegion();
00178       itkAssertOrThrowMacro( ( bufferedRegion.IsInside(m_Region) ),
00179                              "Region " << m_Region << " is outside of buffered region " << bufferedRegion );
00180       }
00181 
00182     // Compute the start offset
00183     m_Offset = m_Image->ComputeOffset( m_Region.GetIndex() );
00184     m_BeginOffset = m_Offset;
00185 
00186     // Compute the end offset. If any component of m_Region.GetSize()
00187     // is zero, the region is not valid and we set the EndOffset
00188     // to be same as BeginOffset so that iterator end condition is met
00189     // immediately.
00190     if ( m_Region.GetNumberOfPixels() == 0 )
00191       {
00192       // region is empty, probably has a size of 0 along one dimension
00193       m_EndOffset = m_BeginOffset;
00194       }
00195     else
00196       {
00197       IndexType ind( m_Region.GetIndex() );
00198       SizeType  size( m_Region.GetSize() );
00199       for ( unsigned int i = 0; i < TImage::ImageDimension; ++i )
00200         {
00201         ind[i] += ( static_cast< IndexValueType >( size[i] ) - 1 );
00202         }
00203       m_EndOffset = m_Image->ComputeOffset(ind);
00204       m_EndOffset++;
00205       }
00206 
00207     m_PixelAccessor = ptr->GetPixelAccessor();
00208     m_PixelAccessorFunctor.SetPixelAccessor(m_PixelAccessor);
00209     m_PixelAccessorFunctor.SetBegin(m_Buffer);
00210   }
00211 
00214   Self & operator=(const Self & it)
00215   {
00216     m_Image = it.m_Image;     // copy the smart pointer
00217     m_Region = it.m_Region;
00218 
00219     m_Buffer = it.m_Buffer;
00220     m_Offset = it.m_Offset;
00221     m_BeginOffset = it.m_BeginOffset;
00222     m_EndOffset = it.m_EndOffset;
00223     m_PixelAccessor = it.m_PixelAccessor;
00224     m_PixelAccessorFunctor = it.m_PixelAccessorFunctor;
00225     m_PixelAccessorFunctor.SetBegin(m_Buffer);
00226 
00227     return *this;
00228   }
00229 
00231   static unsigned int GetImageIteratorDimension()
00232   { return TImage::ImageDimension; }
00233 
00236   bool
00237   operator!=(const Self & it) const
00238   {
00239     // two iterators are the same if they "point to" the same memory location
00240     return ( m_Buffer + m_Offset ) != ( it.m_Buffer + it.m_Offset );
00241   }
00242 
00245   bool
00246   operator==(const Self & it) const
00247   {
00248     // two iterators are the same if they "point to" the same memory location
00249     return ( m_Buffer + m_Offset ) == ( it.m_Buffer + it.m_Offset );
00250   }
00251 
00254   bool
00255   operator<=(const Self & it) const
00256   {
00257     // an iterator is "less than" another if it "points to" a lower
00258     // memory location
00259     return ( m_Buffer + m_Offset ) <= ( it.m_Buffer + it.m_Offset );
00260   }
00261 
00264   bool
00265   operator<(const Self & it) const
00266   {
00267     // an iterator is "less than" another if it "points to" a lower
00268     // memory location
00269     return ( m_Buffer + m_Offset ) < ( it.m_Buffer + it.m_Offset );
00270   }
00271 
00274   bool
00275   operator>=(const Self & it) const
00276   {
00277     // an iterator is "greater than" another if it "points to" a higher
00278     // memory location
00279     return ( m_Buffer + m_Offset ) >= ( it.m_Buffer + it.m_Offset );
00280   }
00281 
00284   bool
00285   operator>(const Self & it) const
00286   {
00287     // an iterator is "greater than" another if it "points to" a higher
00288     // memory location
00289     return ( m_Buffer + m_Offset ) > ( it.m_Buffer + it.m_Offset );
00290   }
00291 
00296   const IndexType GetIndex() const
00297   { return m_Image->ComputeIndex( static_cast< OffsetValueType >( m_Offset ) );  }
00298 
00301   virtual void SetIndex(const IndexType & ind)
00302   { m_Offset = m_Image->ComputeOffset(ind); }
00303 
00306   const RegionType & GetRegion() const
00307   { return m_Region; }
00308 
00310   const ImageType * GetImage() const
00311   { return m_Image.GetPointer(); }
00312 
00314   PixelType Get(void) const
00315   { return m_PixelAccessorFunctor.Get( *( m_Buffer + m_Offset ) ); }
00316 
00320   const PixelType & Value(void) const
00321   { return *( m_Buffer + m_Offset ); }
00322 
00327   Self Begin(void) const;
00328 
00331   void GoToBegin()
00332   {
00333     m_Offset = m_BeginOffset;
00334   }
00335 
00340   Self End(void) const;
00341 
00344   void GoToEnd()
00345   {
00346     m_Offset = m_EndOffset;
00347   }
00348 
00351   bool IsAtBegin(void) const
00352   {
00353     return ( m_Offset == m_BeginOffset );
00354   }
00355 
00358   bool IsAtEnd(void) const
00359   {
00360     return ( m_Offset == m_EndOffset );
00361   }
00362 
00363 protected: //made protected so other iterators can access
00364   typename TImage::ConstWeakPointer m_Image;
00365 
00366   RegionType m_Region;                             // region to iterate over
00367 
00368   OffsetValueType m_Offset;
00369   OffsetValueType m_BeginOffset; // offset to first pixel in region
00370   OffsetValueType m_EndOffset;   // offset to one pixel past last pixel in region
00371 
00372   const InternalPixelType *m_Buffer;
00373 
00374   AccessorType        m_PixelAccessor;
00375   AccessorFunctorType m_PixelAccessorFunctor;
00376 };
00377 } // end namespace itk
00378 
00379 // Define instantiation macro for this template.
00380 #define ITK_TEMPLATE_ImageConstIterator(_, EXPORT, TypeX, TypeY)                  \
00381   namespace itk                                                                   \
00382   {                                                                               \
00383   _( 1 ( class EXPORT ImageConstIterator< ITK_TEMPLATE_1 TypeX > ) )              \
00384   namespace Templates                                                             \
00385   {                                                                               \
00386   typedef ImageConstIterator< ITK_TEMPLATE_1 TypeX > ImageConstIterator##TypeY; \
00387   }                                                                               \
00388   }
00389 
00390 #if ITK_TEMPLATE_EXPLICIT
00391 #include "Templates/itkImageConstIterator+-.h"
00392 #endif
00393 
00394 #if ITK_TEMPLATE_TXX
00395 #include "itkImageConstIterator.hxx"
00396 #endif
00397 
00398 #endif
00399