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 itkConstNeighborhoodIterator_h 19 #define itkConstNeighborhoodIterator_h 20 21 #include <vector> 22 #include <cstring> 23 #include <iostream> 24 #include "itkImage.h" 25 #include "itkNeighborhood.h" 26 #include "itkMacro.h" 27 #include "itkZeroFluxNeumannBoundaryCondition.h" 28 29 namespace itk 30 { 31 /** \class ConstNeighborhoodIterator 32 * 33 * \brief Const version of NeighborhoodIterator, defining iteration of a local 34 * N-dimensional neighborhood of pixels across an itk::Image. 35 * 36 * ConstNeighborhoodIterator implements the read-only methods of 37 * NeighborhoodIterator. It serves as a base class from which other iterators 38 * are derived. See NeighborhoodIterator for more complete information. 39 * 40 * \ingroup ImageIterators 41 * 42 * \sa Neighborhood \sa ImageIterator \sa NeighborhoodIterator 43 * \ingroup ITKCommon 44 * 45 * \wiki 46 * \wikiexample{Iterators/ConstNeighborhoodIterator,Iterate over a region of an image with a neighborhood (without write access)} 47 * \endwiki 48 */ 49 template< typename TImage, typename TBoundaryCondition = 50 ZeroFluxNeumannBoundaryCondition< TImage > > 51 class ITK_TEMPLATE_EXPORT ConstNeighborhoodIterator: 52 public Neighborhood< typename TImage::InternalPixelType *, 53 TImage::ImageDimension > 54 { 55 public: 56 /** Extract image type information. */ 57 using InternalPixelType = typename TImage::InternalPixelType; 58 using PixelType = typename TImage::PixelType; 59 60 /** Type used to refer to space dimensions */ 61 using DimensionValueType = unsigned int; 62 63 /** Save the image dimension. */ 64 static constexpr DimensionValueType Dimension = TImage::ImageDimension; 65 66 /** Standard class type aliases. */ 67 using Self = ConstNeighborhoodIterator; 68 using Superclass = Neighborhood< InternalPixelType *, 69 Self::Dimension >; 70 71 /** Inherit type alias from superclass */ 72 using OffsetType = typename Superclass::OffsetType; 73 using RadiusType = typename Superclass::RadiusType; 74 using SizeType = typename Superclass::SizeType; 75 using Iterator = typename Superclass::Iterator; 76 using ConstIterator = typename Superclass::ConstIterator; 77 78 /** Typedef support for common objects */ 79 using ImageType = TImage; 80 using RegionType = typename TImage::RegionType; 81 using IndexType = Index< Self::Dimension >; 82 using NeighborhoodType = Neighborhood< PixelType, Self::Dimension >; 83 84 85 /** Typedef for boundary condition type. */ 86 using BoundaryConditionType = TBoundaryCondition; 87 88 using OutputImageType = typename BoundaryConditionType::OutputImageType; 89 90 /** Type used to refer to the elements in the list of neighbor pixels. */ 91 using NeighborIndexType = typename NeighborhoodType::NeighborIndexType; 92 93 /** Typedef for the functor used to access neighborhoods of pixel pointers. 94 * This is obtained as a trait from the image and is different for Image 95 * and VectorImage. */ 96 using NeighborhoodAccessorFunctorType = typename ImageType::NeighborhoodAccessorFunctorType; 97 98 /** Typedef for generic boundary condition pointer */ 99 using ImageBoundaryConditionPointerType = ImageBoundaryCondition<ImageType, OutputImageType> *; 100 using ImageBoundaryConditionConstPointerType = const ImageBoundaryCondition<ImageType, OutputImageType> *; 101 102 /** Default constructor */ 103 ConstNeighborhoodIterator(); 104 105 /** Virtual destructor */ 106 ~ConstNeighborhoodIterator() override = default; 107 108 /** Copy constructor */ 109 ConstNeighborhoodIterator(const ConstNeighborhoodIterator &); 110 111 /** Constructor which establishes the region size, neighborhood, and image 112 * over which to walk. */ ConstNeighborhoodIterator(const SizeType & radius,const ImageType * ptr,const RegionType & region)113 ConstNeighborhoodIterator(const SizeType & radius, 114 const ImageType *ptr, 115 const RegionType & region) 116 { 117 this->Initialize(radius, ptr, region); 118 for ( DimensionValueType i = 0; i < Dimension; i++ ) 119 { m_InBounds[i] = false; } 120 this->ResetBoundaryCondition(); 121 m_NeighborhoodAccessorFunctor = ptr->GetNeighborhoodAccessor(); 122 m_NeighborhoodAccessorFunctor.SetBegin( ptr->GetBufferPointer() ); 123 } 124 125 /** Assignment operator */ 126 Self & operator=(const Self & orig); 127 128 /** Standard itk print method */ 129 void PrintSelf(std::ostream &, Indent) const override; 130 131 /** Computes the internal, N-d offset of a pixel array position n from 132 * (0,0, ..., 0) in the "upper-left" corner of the neighborhood. */ 133 OffsetType ComputeInternalIndex(const NeighborIndexType n) const; 134 135 /** Returns the array of upper loop bounds used during iteration. */ GetBound()136 IndexType GetBound() const 137 { return m_Bound; } 138 139 /** Returns the loop bound used to define the edge of a single 140 * dimension in the itk::Image region. */ GetBound(NeighborIndexType n)141 IndexValueType GetBound(NeighborIndexType n) const 142 { return m_Bound[n]; } 143 144 /** Returns the pointer to the center pixel of the neighborhood. */ GetCenterPointer()145 const InternalPixelType * GetCenterPointer() const 146 { return ( this->operator[]( ( this->Size() ) >> 1 ) ); } 147 148 /** Returns the pixel referenced at the center of the 149 * ConstNeighborhoodIterator. */ GetCenterPixel()150 PixelType GetCenterPixel() const 151 { return m_NeighborhoodAccessorFunctor.Get( this->GetCenterPointer() ); } 152 153 /** Returns a smartpointer to the image on which this iterator operates. */ GetImagePointer()154 const ImageType * GetImagePointer() const 155 { return m_ConstImage; } 156 157 /** Returns the N-dimensional index of the iterator's position in 158 * the image. */ GetIndex()159 ITK_ITERATOR_VIRTUAL IndexType GetIndex() const ITK_ITERATOR_FINAL 160 { return m_Loop; } 161 GetFastIndexPlusOffset(const OffsetType & o)162 inline IndexType GetFastIndexPlusOffset(const OffsetType & o) const 163 { return m_Loop + o; } 164 165 /** Function that "dereferences" a ConstNeighborhoodIterator, 166 * returning a Neighborhood of pixel values. */ 167 ITK_ITERATOR_VIRTUAL NeighborhoodType GetNeighborhood() const ITK_ITERATOR_FINAL; 168 169 /** Returns the pixel value located at a linear array location i. */ GetPixel(const NeighborIndexType i)170 ITK_ITERATOR_VIRTUAL PixelType GetPixel(const NeighborIndexType i) const ITK_ITERATOR_FINAL 171 { 172 if ( !m_NeedToUseBoundaryCondition || this->InBounds() ) 173 { 174 return ( m_NeighborhoodAccessorFunctor.Get( this->operator[](i) ) ); 175 } 176 177 OffsetType internalIndex; 178 OffsetType offset; 179 180 return this->IndexInBounds(i, internalIndex, offset) ? 181 m_NeighborhoodAccessorFunctor.Get(this->operator[](i)) : 182 m_NeighborhoodAccessorFunctor.BoundaryCondition(internalIndex, offset, this, m_BoundaryCondition); 183 } 184 185 /** Return the pixel value located at a linear array location i. 186 * Sets "IsInBounds" to true if the location is inside the 187 * image and the pixel value returned is an actual pixel in the 188 * image. Sets "IsInBounds" to false if the location is outside the 189 * image and the pixel value returned is a boundary condition. */ 190 ITK_ITERATOR_VIRTUAL PixelType GetPixel(NeighborIndexType i, bool & IsInBounds) const ITK_ITERATOR_FINAL; 191 192 /** Returns the pixel value located at the itk::Offset o from the center of 193 the neighborhood. */ GetPixel(const OffsetType & o)194 ITK_ITERATOR_VIRTUAL PixelType GetPixel(const OffsetType & o) const ITK_ITERATOR_FINAL 195 { 196 bool inbounds; 197 198 return ( this->GetPixel(this->GetNeighborhoodIndex(o), inbounds) ); 199 } 200 201 /** Returns the pixel value located at the itk::Offset o from the center of 202 * the neighborhood. Sets "IsInBounds" to true if the offset is inside the 203 * image and the pixel value returned is an actual pixel in the 204 * image. Sets "IsInBounds" to false if the offset is outside the 205 * image and the pixel value returned is a boundary condition. */ GetPixel(const OffsetType & o,bool & IsInBounds)206 ITK_ITERATOR_VIRTUAL PixelType GetPixel(const OffsetType & o, 207 bool & IsInBounds) const ITK_ITERATOR_FINAL 208 { return ( this->GetPixel(this->GetNeighborhoodIndex(o), IsInBounds) ); } 209 210 /** Returns the pixel value located i pixels distant from the neighborhood 211 * center in the positive specified "axis" direction. No bounds checking 212 * is done on the size of the neighborhood. */ GetNext(const unsigned axis,NeighborIndexType i)213 ITK_ITERATOR_VIRTUAL PixelType GetNext(const unsigned axis, NeighborIndexType i) const ITK_ITERATOR_FINAL 214 { 215 return ( this->GetPixel( this->GetCenterNeighborhoodIndex() 216 + ( i * this->GetStride(axis) ) ) ); 217 } 218 219 /** Returns the pixel value located one pixel distant from the neighborhood 220 * center in the specifed positive axis direction. No bounds checking is 221 * done on the size of the neighborhood. */ GetNext(const unsigned axis)222 ITK_ITERATOR_VIRTUAL PixelType GetNext(const unsigned axis) const ITK_ITERATOR_FINAL 223 { 224 return ( this->GetPixel( this->GetCenterNeighborhoodIndex() 225 + this->GetStride(axis) ) ); 226 } 227 228 /** Returns the pixel value located i pixels distant from the neighborhood 229 * center in the negative specified "axis" direction. No bounds checking 230 * is done on the size of the neighborhood. */ GetPrevious(const unsigned axis,NeighborIndexType i)231 ITK_ITERATOR_VIRTUAL PixelType GetPrevious(const unsigned axis, NeighborIndexType i) const ITK_ITERATOR_FINAL 232 { 233 return ( this->GetPixel( this->GetCenterNeighborhoodIndex() 234 - ( i * this->GetStride(axis) ) ) ); 235 } 236 237 /** Returns the pixel value located one pixel distant from the neighborhood 238 * center in the specifed negative axis direction. No bounds checking is 239 * done on the size of the neighborhood. */ GetPrevious(const unsigned axis)240 ITK_ITERATOR_VIRTUAL PixelType GetPrevious(const unsigned axis) const ITK_ITERATOR_FINAL 241 { 242 return ( this->GetPixel( this->GetCenterNeighborhoodIndex() 243 - this->GetStride(axis) ) ); 244 } 245 246 /** Returns the image index for neighbor pixel at offset o from the center of 247 the neighborhood. */ GetIndex(const OffsetType & o)248 ITK_ITERATOR_VIRTUAL IndexType GetIndex(const OffsetType & o) const ITK_ITERATOR_FINAL 249 { return ( this->GetIndex() + o ); } 250 251 /** Returns the image index for neighbor pixel at index i in the 252 neighborhood. */ GetIndex(NeighborIndexType i)253 ITK_ITERATOR_VIRTUAL IndexType GetIndex(NeighborIndexType i) const ITK_ITERATOR_FINAL 254 { return ( this->GetIndex() + this->GetOffset(i) ); } 255 256 /** Returns the region of iteration. */ GetRegion()257 RegionType GetRegion() const 258 { return m_Region; } 259 260 /** Returns the N-dimensional starting index of the iterator's position on 261 * the image. */ GetBeginIndex()262 IndexType GetBeginIndex() const 263 { return m_BeginIndex; } 264 265 /** Returns a bounding box for the region spanned by this neighborhood 266 represented by an itk::ImageRegion */ 267 RegionType GetBoundingBoxAsImageRegion() const; 268 269 /** Returns the offsets used to wrap across dimensional boundaries. */ GetWrapOffset()270 OffsetType GetWrapOffset() const 271 { return m_WrapOffset; } 272 273 /** Returns the internal offset associated with wrapping around a single 274 * dimension's region boundary in the itk::Image. An offset for each 275 * dimension is necessary to shift pointers when wrapping around region 276 * edges because region memory is not necessarily contiguous within the 277 * buffer. */ GetWrapOffset(NeighborIndexType n)278 OffsetValueType GetWrapOffset(NeighborIndexType n) const 279 { return m_WrapOffset[n]; } 280 281 /** Method for rewinding the iterator to its beginning pixel. */ 282 ITK_ITERATOR_VIRTUAL void GoToBegin() ITK_ITERATOR_FINAL; 283 284 /** Method for sending the iterator to one past the last pixel in its 285 * region. */ 286 ITK_ITERATOR_VIRTUAL void GoToEnd() ITK_ITERATOR_FINAL; 287 288 /** Initializes the iterator to walk a particular image and a particular 289 * region of that image. */ 290 ITK_ITERATOR_VIRTUAL void Initialize(const SizeType & radius, const ImageType *ptr, 291 const RegionType & region) ITK_ITERATOR_FINAL; 292 293 /** Method for determining whether the iterator is at the 294 * beginning of its iteration region. */ IsAtBegin()295 ITK_ITERATOR_VIRTUAL bool IsAtBegin() const ITK_ITERATOR_FINAL 296 { return ( this->GetCenterPointer() == m_Begin ); } 297 298 /** Method for determining whether the iterator has reached the 299 * end of its iteration region. */ IsAtEnd()300 ITK_ITERATOR_VIRTUAL bool IsAtEnd() const ITK_ITERATOR_FINAL 301 { 302 if ( this->GetCenterPointer() > m_End ) 303 { 304 ExceptionObject e(__FILE__, __LINE__); 305 std::ostringstream msg; 306 msg << "In method IsAtEnd, CenterPointer = " << this->GetCenterPointer() 307 << " is greater than End = " << m_End 308 << std::endl 309 << " " << *this; 310 e.SetDescription( msg.str().c_str() ); 311 throw e; 312 } 313 return ( this->GetCenterPointer() == m_End ); 314 } 315 316 /** Increments the pointers in the ConstNeighborhoodIterator, 317 * wraps across boundaries automatically, accounting for 318 * the disparity in the buffer size and the region size of the 319 * image. */ 320 Self & operator++(); 321 322 /** Decrements the pointers in the ConstNeighborhoodIterator, 323 * wraps across boundaries automatically, accounting for 324 * the disparity in the buffer size and the region size of the 325 * image. */ 326 Self & operator--(); 327 328 /** Returns a boolean == comparison of the memory addresses of the center 329 * elements of two ConstNeighborhoodIterators of like pixel type and 330 * dimensionality. The radii of the iterators are ignored. */ 331 bool operator==(const Self & it) const 332 { return it.GetCenterPointer() == this->GetCenterPointer(); } 333 334 /** Returns a boolean != comparison of the memory addresses of the center 335 * elements of two ConstNeighborhoodIterators of like pixel type and 336 * dimensionality. The radii of the iterators are ignored. */ 337 bool operator!=(const Self & it) const 338 { return it.GetCenterPointer() != this->GetCenterPointer(); } 339 340 /** Returns a boolean < comparison of the memory addresses of the center 341 * elements of two ConstNeighborhoodIterators of like pixel type and 342 * dimensionality. The radii of the iterators are ignored. */ 343 bool operator<(const Self & it) const 344 { return this->GetCenterPointer() < it.GetCenterPointer(); } 345 346 /** Returns a boolean < comparison of the memory addresses of the center 347 * elements of two ConstNeighborhoodIterators of like pixel type and 348 * dimensionality. The radii of the iterators are ignored. */ 349 bool operator<=(const Self & it) const 350 { return this->GetCenterPointer() <= it.GetCenterPointer(); } 351 352 /** Returns a boolean > comparison of the memory addresses of the center 353 * elements of two ConstNeighborhoodIterators of like pixel type and 354 * dimensionality. The radii of the iterators are ignored. */ 355 bool operator>(const Self & it) const 356 { return this->GetCenterPointer() > it.GetCenterPointer(); } 357 358 /** Returns a boolean >= comparison of the memory addresses of the center 359 * elements of two ConstNeighborhoodIterators of like pixel type and 360 * dimensionality. The radii of the iterators are ignored. */ 361 bool operator>=(const Self & it) const 362 { return this->GetCenterPointer() >= it.GetCenterPointer(); } 363 364 /** This method positions the iterator at an indexed location in the 365 * image. SetLocation should _NOT_ be used to update the position of the 366 * iterator during iteration, only for initializing it to a position 367 * prior to iteration. This method is not optimized for speed. */ SetLocation(const IndexType & position)368 void SetLocation(const IndexType & position) 369 { 370 this->SetLoop(position); 371 this->SetPixelPointers(position); 372 } 373 374 /** Addition of an itk::Offset. Note that this method does not do any bounds 375 * checking. Adding an offset that moves the iterator out of its assigned 376 * region will produce undefined results. */ 377 Self & operator+=(const OffsetType &); 378 379 /** Subtraction of an itk::Offset. Note that this method does not do any 380 * bounds checking. Subtracting an offset that moves the iterator out 381 * of its assigned region will produce undefined results. */ 382 Self & operator-=(const OffsetType &); 383 384 /** Distance between two iterators */ 385 OffsetType operator-(const Self & b) 386 { return m_Loop - b.m_Loop; } 387 388 /** Returns false if the iterator overlaps region boundaries, true 389 * otherwise. Also updates an internal boolean array indicating 390 * which of the iterator's faces are out of bounds. */ 391 bool InBounds() const; 392 393 /** Returns true if the neighborhood index is within region boundaries, 394 * false otherwise. 395 * If false, then internalIndex and offset are calculated. Otherwise their 396 * values are left unchanged. 397 * Also updates an internal boolean array indicating 398 * which of the iterator's faces are out of bounds. 399 * \param n - linear neighborhood index. 400 * \param internalIndex - calculated for index \c n only when the neighborhood is not 401 * completely within region boundaries. 402 * \param offset - per-dimension offsets for index n to nearest boundary index, 403 * calculate only when the neighborhood is not completely within region boundaries. */ 404 bool IndexInBounds(const NeighborIndexType n, OffsetType & internalIndex, OffsetType & offset ) const; 405 406 /** Returns true if the neighborhood index is within region boundaries, 407 * false otherwise. */ 408 bool IndexInBounds(const NeighborIndexType n ) const; 409 410 /** Allows a user to override the internal boundary condition. Care should 411 * be taken to ensure that the overriding boundary condition is a persistent 412 * object during the time it is referenced. The overriding condition 413 * can be of a different type than the default type as long as it is 414 * a subclass of ImageBoundaryCondition. */ OverrideBoundaryCondition(const ImageBoundaryConditionPointerType i)415 ITK_ITERATOR_VIRTUAL void OverrideBoundaryCondition(const 416 ImageBoundaryConditionPointerType i) ITK_ITERATOR_FINAL 417 { m_BoundaryCondition = i; } 418 419 /** Resets the boundary condition to the internal, default conditions 420 * specified by the template parameter. */ ResetBoundaryCondition()421 ITK_ITERATOR_VIRTUAL void ResetBoundaryCondition() ITK_ITERATOR_FINAL 422 { m_BoundaryCondition = &m_InternalBoundaryCondition; } 423 424 /** Sets the internal, default boundary condition. */ SetBoundaryCondition(const TBoundaryCondition & c)425 void SetBoundaryCondition(const TBoundaryCondition & c) 426 { m_InternalBoundaryCondition = c; } 427 428 /** */ GetBoundaryCondition()429 ImageBoundaryConditionPointerType GetBoundaryCondition() const 430 { return m_BoundaryCondition; } 431 432 /** */ NeedToUseBoundaryConditionOn()433 void NeedToUseBoundaryConditionOn() 434 { 435 this->SetNeedToUseBoundaryCondition(true); 436 } 437 NeedToUseBoundaryConditionOff()438 void NeedToUseBoundaryConditionOff() 439 { 440 this->SetNeedToUseBoundaryCondition(false); 441 } 442 SetNeedToUseBoundaryCondition(bool b)443 void SetNeedToUseBoundaryCondition(bool b) 444 { 445 m_NeedToUseBoundaryCondition = b; 446 } 447 GetNeedToUseBoundaryCondition()448 bool GetNeedToUseBoundaryCondition() const 449 { 450 return m_NeedToUseBoundaryCondition; 451 } 452 453 /** Set the region to iterate over. */ 454 ITK_ITERATOR_VIRTUAL void SetRegion(const RegionType & region) ITK_ITERATOR_FINAL; 455 456 protected: 457 458 /** Default method for setting the coordinate location of the iterator. 459 * Loop indices correspond to the actual Image region index. */ SetLoop(const IndexType & p)460 ITK_ITERATOR_VIRTUAL void SetLoop(const IndexType & p) ITK_ITERATOR_FINAL 461 { m_Loop = p; m_IsInBoundsValid = false; } 462 463 /** Method for setting internal loop boundaries. This 464 * method must be defined in each subclass because 465 * each subclass may handle loop boundaries differently. */ 466 ITK_ITERATOR_VIRTUAL void SetBound(const SizeType &) ITK_ITERATOR_FINAL; 467 468 /** Default method for setting the values of the internal pointers 469 * to itk::Image memory buffer locations. This method should 470 * generally only be called when the iterator is initialized. 471 * \sa SetLocation */ 472 ITK_ITERATOR_VIRTUAL void SetPixelPointers(const IndexType &) ITK_ITERATOR_FINAL; 473 474 /** Default method for setting the index of the first pixel in the 475 * iteration region. */ SetBeginIndex(const IndexType & start)476 ITK_ITERATOR_VIRTUAL void SetBeginIndex(const IndexType & start) ITK_ITERATOR_FINAL 477 { m_BeginIndex = start; } 478 479 /** Default method for setting the index of the first pixel in the 480 * iteration region. */ 481 ITK_ITERATOR_VIRTUAL void SetEndIndex() ITK_ITERATOR_FINAL; 482 483 /** The starting index for iteration within the itk::Image region 484 * on which this ConstNeighborhoodIterator is defined. */ 485 IndexType m_BeginIndex; 486 487 /** An array of upper looping boundaries used during iteration. */ 488 IndexType m_Bound; 489 490 /** A pointer to the first pixel in the iteration region. */ 491 const InternalPixelType *m_Begin; 492 493 /** The image on which iteration is defined. */ 494 typename ImageType::ConstWeakPointer m_ConstImage; 495 496 /** A pointer to one past the last pixel in the iteration region. */ 497 const InternalPixelType *m_End; 498 499 /** The end index for iteration within the itk::Image region 500 * on which this ConstNeighborhoodIterator is defined. */ 501 IndexType m_EndIndex; 502 503 /** Array of loop counters used during iteration. */ 504 IndexType m_Loop; 505 506 /** The region over which iteration is defined. */ 507 RegionType m_Region; 508 509 /** The internal array of offsets that provide support for regions of 510 * interest. 511 * An offset for each dimension is necessary to shift pointers when wrapping 512 * around region edges because region memory is not necessarily contiguous 513 * within the buffer. */ 514 OffsetType m_WrapOffset; 515 516 /** Pointer to the actual boundary condition that will be used. 517 * By default this points to m_BoundaryCondition, but 518 * OverrideBoundaryCondition allows a user to point this variable an external 519 * boundary condition. */ 520 ImageBoundaryConditionPointerType m_BoundaryCondition; 521 522 /** Denotes which of the iterators dimensional sides spill outside 523 * region of interest boundaries. */ 524 mutable bool m_InBounds[Dimension]; 525 526 /** Denotes if iterator is entirely within bounds */ 527 mutable bool m_IsInBounds{false}; 528 529 /** Is the m_InBounds and m_IsInBounds variables up to date? Set to 530 * false whenever the iterator is repositioned. Set to true within 531 * InBounds(). */ 532 mutable bool m_IsInBoundsValid{false}; 533 534 /** Lower threshold of in-bounds loop counter values. */ 535 IndexType m_InnerBoundsLow; 536 537 /** Upper threshold of in-bounds loop counter values. */ 538 IndexType m_InnerBoundsHigh; 539 540 /** Default boundary condition. */ 541 TBoundaryCondition m_InternalBoundaryCondition; 542 543 /** Does the specified region need to worry about boundary conditions? */ 544 bool m_NeedToUseBoundaryCondition{false}; 545 546 /** Functor type used to access neighborhoods of pixel pointers */ 547 NeighborhoodAccessorFunctorType m_NeighborhoodAccessorFunctor; 548 }; 549 550 template< typename TImage > 551 inline ConstNeighborhoodIterator< TImage > 552 operator+(const ConstNeighborhoodIterator< TImage > & it, 553 const typename ConstNeighborhoodIterator< TImage >::OffsetType & ind) 554 { 555 ConstNeighborhoodIterator< TImage > ret ( it ); 556 ret += ind; 557 return ret; 558 } 559 560 template< typename TImage > 561 inline ConstNeighborhoodIterator< TImage > 562 operator+(const typename ConstNeighborhoodIterator< TImage >::OffsetType & ind, 563 const ConstNeighborhoodIterator< TImage > & it) 564 { return ( it + ind ); } 565 566 template< typename TImage > 567 inline ConstNeighborhoodIterator< TImage > 568 operator-(const ConstNeighborhoodIterator< TImage > & it, 569 const typename ConstNeighborhoodIterator< TImage > 570 ::OffsetType & ind) 571 { 572 ConstNeighborhoodIterator< TImage > ret(it); 573 ret -= ind; 574 return ret; 575 } 576 } // namespace itk 577 578 #ifndef ITK_MANUAL_INSTANTIATION 579 #include "itkConstNeighborhoodIterator.hxx" 580 #endif 581 582 #endif 583