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 itkImageRegionExclusionConstIteratorWithIndex_hxx
19 #define itkImageRegionExclusionConstIteratorWithIndex_hxx
20 
21 #include "itkImageRegionExclusionConstIteratorWithIndex.h"
22 
23 namespace itk
24 {
25 
26 template< typename TImage >
27 ImageRegionExclusionConstIteratorWithIndex< TImage >
ImageRegionExclusionConstIteratorWithIndex(const ImageType * ptr,const RegionType & region)28 ::ImageRegionExclusionConstIteratorWithIndex(const ImageType *ptr,
29                                              const RegionType & region) :
30 Superclass(ptr, region)
31 {}
32 
33 template< typename TImage >
34 ImageRegionExclusionConstIteratorWithIndex< TImage >
ImageRegionExclusionConstIteratorWithIndex(const Superclass & it)35 ::ImageRegionExclusionConstIteratorWithIndex(const Superclass & it)
36 {
37   Superclass::operator=(it);
38 }
39 //----------------------------------------------------------------------
40 //  Set the region to exclude from the walk
41 //----------------------------------------------------------------------
42 template< typename TImage >
43 void
44 ImageRegionExclusionConstIteratorWithIndex< TImage >
SetExclusionRegion(const RegionType & region)45 ::SetExclusionRegion(const RegionType & region)
46 {
47   // Crop the exclusion region so that it lies entirely within the
48   // iterator region.
49   m_ExclusionRegion = region;
50   m_ExclusionRegion.Crop( this->m_Region );
51 
52   m_ExclusionBegin       = m_ExclusionRegion.GetIndex();
53   SizeType exclusionSize = m_ExclusionRegion.GetSize();
54 
55   for ( unsigned int i = 0; i < TImage::ImageDimension; ++i )
56     {
57     m_ExclusionEnd[i] = m_ExclusionBegin[i] + exclusionSize[i];
58     }
59 }
60 
61 //----------------------------------------------------------------------
62 //  Set the region to exclude from the walk to a region that is inset
63 //  one pixel from the boundary of the region
64 //----------------------------------------------------------------------
65 template< typename TImage >
66 void
67 ImageRegionExclusionConstIteratorWithIndex< TImage >
SetExclusionRegionToInsetRegion()68 ::SetExclusionRegionToInsetRegion()
69 {
70   RegionType excludeRegion;
71 
72   excludeRegion = this->m_Region;
73   for ( unsigned int i = 0; i < TImage::ImageDimension; ++i )
74     {
75     if ( excludeRegion.GetSize()[i] >= 2 )
76       {
77       // region is large enough to inset, adjust size and index
78       excludeRegion.SetSize(i, excludeRegion.GetSize()[i] - 2);
79       excludeRegion.SetIndex(i, excludeRegion.GetIndex()[i] + 1);
80       }
81     else
82       {
83       // region is not large enough to inset, set exclusion size to
84       // zero and keep the index the same.
85       excludeRegion.SetSize(i, 0);
86       }
87     }
88   this->SetExclusionRegion(excludeRegion);
89 }
90 
91 //----------------------------------------------------------------------
92 // Move to beginning of region
93 //----------------------------------------------------------------------
94 template< typename TImage >
95 void
96 ImageRegionExclusionConstIteratorWithIndex< TImage >
GoToBegin()97 ::GoToBegin()
98 {
99   // Check whether exclusion region covers the entire region
100   if ( m_ExclusionRegion == this->m_Region )
101     {
102     this->m_Position = this->m_End;
103     this->m_Remaining = false;
104     return;
105     }
106 
107   this->Superclass::GoToBegin();
108 
109   // If inside the exclusion region to begin with, jump past it.
110   for ( unsigned int in = 0; in < TImage::ImageDimension; in++ )
111     {
112     if ( m_ExclusionRegion.IsInside( this->m_PositionIndex ) )
113       {
114       if ( m_ExclusionRegion.GetSize()[in] == this->m_Region.GetSize()[in] )
115         {
116         this->m_PositionIndex[in] = this->m_BeginIndex[in];
117         }
118       else
119         {
120         this->m_PositionIndex[in] = m_ExclusionEnd[in];
121         this->m_Position += this->m_OffsetTable[in] * m_ExclusionRegion.GetSize()[in];
122         }
123       }
124     }
125 }
126 
127 //----------------------------------------------------------------------
128 // Move to the end of the region
129 //----------------------------------------------------------------------
130 template< typename TImage >
131 void
132 ImageRegionExclusionConstIteratorWithIndex< TImage >
GoToReverseBegin()133 ::GoToReverseBegin()
134 {
135   // Check whether exclusion region covers the entire region
136   if ( m_ExclusionRegion == this->m_Region )
137     {
138     this->m_Position = this->m_End;
139     this->m_Remaining = false;
140     return;
141     }
142 
143   this->Superclass::GoToReverseBegin();
144 
145   // If inside the exclusion region to begin with, jump past it.
146   for ( unsigned int in = 0; in < TImage::ImageDimension; in++ )
147     {
148     if ( m_ExclusionRegion.IsInside( this->m_PositionIndex ) )
149       {
150       if ( m_ExclusionRegion.GetSize()[in] == this->m_Region.GetSize()[in] )
151         {
152         // The line will be skipped entirely.
153         this->m_PositionIndex[in] = this->m_EndIndex[in] - 1;
154         }
155       else
156         {
157         this->m_PositionIndex[in] = m_ExclusionBegin[in] - 1;
158         this->m_Position -= this->m_OffsetTable[in] * m_ExclusionRegion.GetSize()[in];
159         }
160       }
161     }
162 }
163 
164 //----------------------------------------------------------------------
165 //  Advance along the line, skipping the exclusion region
166 //----------------------------------------------------------------------
167 template< typename TImage >
168 ImageRegionExclusionConstIteratorWithIndex< TImage > &
169 ImageRegionExclusionConstIteratorWithIndex< TImage >
operator ++()170 ::operator++()
171 {
172   this->Superclass::operator++();
173 
174   while ( m_ExclusionRegion.IsInside( this->m_PositionIndex ) && this->m_Remaining )
175     {
176     // Entered the exclusion region, so jump across it
177     this->m_Position += this->m_OffsetTable[0] *
178       ( static_cast< OffsetValueType >( m_ExclusionRegion.GetSize()[0] ) );
179     this->m_PositionIndex[0] = m_ExclusionEnd[0];
180     if ( this->m_PositionIndex[0] == this->m_EndIndex[0] )
181       {
182       this->m_Position -= this->m_OffsetTable[0];
183       this->Superclass::operator++();
184       }
185     }
186 
187   return *this;
188 }
189 
190 //----------------------------------------------------------------------
191 //  Advance along the line in reverse direction, skipping exclusion region
192 //----------------------------------------------------------------------
193 template< typename TImage >
194 ImageRegionExclusionConstIteratorWithIndex< TImage > &
195 ImageRegionExclusionConstIteratorWithIndex< TImage >
operator --()196 ::operator--()
197 {
198   this->Superclass::operator--();
199 
200   while ( m_ExclusionRegion.IsInside( this->m_PositionIndex ) && this->m_Remaining )
201     {
202     // Entered the exclusion region, so jump across it
203     this->m_Position -= this->m_OffsetTable[0] *
204       ( static_cast< OffsetValueType >( m_ExclusionRegion.GetSize()[0] ) );
205     this->m_PositionIndex[0] = m_ExclusionBegin[0] - 1;
206     if ( this->m_PositionIndex[0] < this->m_BeginIndex[0] )
207       {
208       this->m_Position += this->m_OffsetTable[0];
209       this->Superclass::operator--();
210       }
211     }
212 
213   return *this;
214 }
215 
216 
217 } // end namespace itk
218 
219 #endif
220