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 /*=========================================================================
19 *
20 * Portions of this file are subject to the VTK Toolkit Version 3 copyright.
21 *
22 * Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
23 *
24 * For complete copyright, license and disclaimer of warranty information
25 * please refer to the NOTICE file at the top of the ITK source tree.
26 *
27 *=========================================================================*/
28 #ifndef itkImageRegion_hxx
29 #define itkImageRegion_hxx
30
31 #include "itkImageRegion.h"
32
33 namespace itk
34 {
35 template< unsigned int VImageDimension >
36 typename ImageRegion< VImageDimension >::IndexType
37 ImageRegion< VImageDimension >
GetUpperIndex() const38 ::GetUpperIndex() const
39 {
40 IndexType idx;
41 for ( unsigned int i = 0; i < VImageDimension; i++ )
42 {
43 idx[i] = m_Index[i] + m_Size[i] - 1;
44 }
45
46 return idx;
47 }
48
49 template< unsigned int VImageDimension >
50 void
51 ImageRegion< VImageDimension >
SetUpperIndex(const IndexType & idx)52 ::SetUpperIndex( const IndexType & idx )
53 {
54 for ( unsigned int i = 0; i < VImageDimension; i++ )
55 {
56 m_Size[i] = idx[i] - m_Index[i] + 1;
57 }
58 }
59
60 template< unsigned int VImageDimension >
61 void
62 ImageRegion< VImageDimension >
ComputeOffsetTable(OffsetTableType offsetTable) const63 ::ComputeOffsetTable(OffsetTableType offsetTable) const
64 {
65 OffsetValueType num=1;
66
67 offsetTable[0] = num;
68 for (unsigned int i=0; i < ImageDimension; i++)
69 {
70 num *= m_Size[i];
71 offsetTable[i+1] = num;
72 }
73 }
74
75 template< unsigned int VImageDimension >
76 typename ImageRegion< VImageDimension >::SizeValueType
77 ImageRegion< VImageDimension >
GetNumberOfPixels() const78 ::GetNumberOfPixels() const
79 {
80 SizeValueType numPixels = 1;
81
82 for ( unsigned int i = 0; i < VImageDimension; i++ )
83 {
84 numPixels *= m_Size[i];
85 }
86
87 return numPixels;
88 }
89
90 template< unsigned int VImageDimension >
91 void
92 ImageRegion< VImageDimension >
PrintSelf(std::ostream & os,Indent indent) const93 ::PrintSelf(std::ostream & os, Indent indent) const
94 {
95 Superclass::PrintSelf(os, indent);
96
97 os << indent << "Dimension: " << this->GetImageDimension() << std::endl;
98 os << indent << "Index: " << this->GetIndex() << std::endl;
99 os << indent << "Size: " << this->GetSize() << std::endl;
100 }
101
102 template< unsigned int VImageDimension >
103 void
104 ImageRegion< VImageDimension >
PadByRadius(OffsetValueType radius)105 ::PadByRadius(OffsetValueType radius)
106 {
107 SizeType radiusVector;
108
109 for ( unsigned int i = 0; i < VImageDimension; ++i )
110 {
111 radiusVector[i] = radius;
112 }
113
114 this->PadByRadius(radiusVector);
115 }
116
117 template< unsigned int VImageDimension >
118 void
119 ImageRegion< VImageDimension >
PadByRadius(const SizeType & radius)120 ::PadByRadius(const SizeType & radius)
121 {
122 for ( unsigned int i = 0; i < VImageDimension; i++ )
123 {
124 m_Size[i] += 2 * radius[i];
125 m_Index[i] -= static_cast< OffsetValueType >( radius[i] );
126 }
127 }
128
129 template< unsigned int VImageDimension >
130 void
131 ImageRegion< VImageDimension >
PadByRadius(const IndexValueArrayType radius)132 ::PadByRadius(const IndexValueArrayType radius)
133 {
134 for ( unsigned int i = 0; i < VImageDimension; i++ )
135 {
136 m_Size[i] += 2 * radius[i];
137 m_Index[i] -= static_cast< OffsetValueType >( radius[i] );
138 }
139 }
140
141 template< unsigned int VImageDimension >
142 bool
143 ImageRegion< VImageDimension >
ShrinkByRadius(OffsetValueType radius)144 ::ShrinkByRadius(OffsetValueType radius)
145 {
146 SizeType radiusVector;
147
148 for ( unsigned int i = 0; i < VImageDimension; ++i )
149 {
150 radiusVector[i] = radius;
151 }
152
153 return this->ShrinkByRadius(radiusVector);
154 }
155
156 template< unsigned int VImageDimension >
157 bool
158 ImageRegion< VImageDimension >
ShrinkByRadius(const SizeType & radius)159 ::ShrinkByRadius(const SizeType & radius)
160 {
161 bool shrunkSuccessfully = true;
162 for ( unsigned int i = 0; i < VImageDimension; i++ )
163 {
164 if( m_Size[i] <= 2 * radius[i] )
165 {
166 shrunkSuccessfully = false;
167 }
168 else
169 {
170 m_Size[i] -= 2 * radius[i];
171 m_Index[i] += static_cast< OffsetValueType >( radius[i] );
172 }
173 }
174 return shrunkSuccessfully;
175 }
176
177 template< unsigned int VImageDimension >
178 bool
179 ImageRegion< VImageDimension >
ShrinkByRadius(const IndexValueArrayType radius)180 ::ShrinkByRadius(const IndexValueArrayType radius)
181 {
182 bool shrunkSuccessfully = true;
183 for ( unsigned int i = 0; i < VImageDimension; i++ )
184 {
185 if( static_cast< IndexValueType >( m_Size[i] ) <= 2 * radius[i] )
186 {
187 shrunkSuccessfully = false;
188 }
189 else
190 {
191 m_Size[i] -= 2 * radius[i];
192 m_Index[i] += static_cast< OffsetValueType >( radius[i] );
193 }
194 }
195 return shrunkSuccessfully;
196 }
197
198 template< unsigned int VImageDimension >
199 bool
200 ImageRegion< VImageDimension >
Crop(const Self & region)201 ::Crop(const Self & region)
202 {
203 OffsetValueType crop;
204 unsigned int i;
205 bool cropPossible = true;
206
207 // Can we crop?
208 for ( i = 0; i < VImageDimension && cropPossible; i++ )
209 {
210 // Is left edge of current region to the right of the right edge
211 // of the region to crop with? (if so, we cannot crop)
212 if ( m_Index[i] >= region.GetIndex()[i]
213 + static_cast< OffsetValueType >( region.GetSize()[i] ) )
214 {
215 cropPossible = false;
216 }
217 // If right edge of the current region to the left of the left
218 // edge of the region to crop with? (if so, we cannot crop)
219 if ( m_Index[i] + static_cast< OffsetValueType >( m_Size[i] ) <= region.GetIndex()[i] )
220 {
221 cropPossible = false;
222 }
223 }
224
225 // if we cannot crop, return without changing anythin
226 if ( !cropPossible )
227 {
228 return cropPossible;
229 }
230
231 // we can crop, so crop
232 for ( i = 0; i < VImageDimension; i++ )
233 {
234 // first check the start index
235 if ( m_Index[i] < region.GetIndex()[i] )
236 {
237 // how much do we need to adjust
238 crop = region.GetIndex()[i] - m_Index[i];
239
240 // adjust the start index and the size of the current region
241 m_Index[i] += crop;
242 m_Size[i] -= static_cast< SizeValueType >( crop );
243 }
244 // now check the final size
245 if ( m_Index[i] + static_cast< OffsetValueType >( m_Size[i] )
246 > region.GetIndex()[i] + static_cast< OffsetValueType >( region.GetSize()[i] ) )
247 {
248 // how much do we need to adjust
249 crop = m_Index[i] + static_cast< OffsetValueType >( m_Size[i] )
250 - region.GetIndex()[i] - static_cast< OffsetValueType >( region.GetSize()[i] );
251
252 // adjust the size
253 m_Size[i] -= static_cast< SizeValueType >( crop );
254 }
255 }
256
257 return cropPossible;
258 }
259
260 template< unsigned int VImageDimension >
261 typename ImageRegion< VImageDimension >::SliceRegion
262 ImageRegion< VImageDimension >
Slice(const unsigned int dim) const263 ::Slice(const unsigned int dim) const
264 {
265 if ( dim >= VImageDimension )
266 {
267 itkGenericExceptionMacro(
268 << "The dimension to remove: " << dim
269 << " is greater than the dimension of the image: " << VImageDimension);
270 }
271
272 Index< SliceDimension > sliceIndex;
273 Size< SliceDimension > sliceSize;
274
275 sliceIndex.Fill(0);
276 sliceSize.Fill(0);
277 unsigned int ii = 0;
278 for ( unsigned int i = 0; i < VImageDimension; i++ )
279 {
280 if ( i != dim )
281 {
282 sliceIndex[ii] = m_Index[i];
283 sliceSize[ii] = m_Size[i];
284 ++ii;
285 }
286 }
287
288 return ImageRegion< SliceDimension >(sliceIndex, sliceSize);
289 }
290
291 template< unsigned int VImageDimension >
operator <<(std::ostream & os,const ImageRegion<VImageDimension> & region)292 std::ostream & operator<<(std::ostream & os, const ImageRegion< VImageDimension > & region)
293 {
294 region.Print(os);
295 return os;
296 }
297 } // end namespace itk
298
299 #endif
300