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 itkNeighborhood_hxx
19 #define itkNeighborhood_hxx
20 
21 #include "itkNeighborhood.h"
22 #include "itkNumericTraits.h"
23 
24 namespace itk
25 {
26 template< typename TPixel, unsigned int VDimension, typename TContainer >
27 void
28 Neighborhood< TPixel, VDimension, TContainer >
ComputeNeighborhoodStrideTable()29 ::ComputeNeighborhoodStrideTable()
30 {
31   for ( DimensionValueType dim = 0; dim < VDimension; ++dim )
32     {
33     OffsetValueType stride = 0;
34     OffsetValueType accum = 1;
35 
36     for ( DimensionValueType i = 0; i < VDimension; ++i )
37       {
38       if ( i == dim ) { stride = accum; }
39       accum *= m_Size[i];
40       }
41 
42     m_StrideTable[dim] = stride;
43     }
44 }
45 
46 template< typename TPixel, unsigned int VDimension, typename TContainer >
47 void Neighborhood< TPixel, VDimension, TContainer >
ComputeNeighborhoodOffsetTable()48 ::ComputeNeighborhoodOffsetTable()
49 {
50   m_OffsetTable.clear();
51   m_OffsetTable.reserve( this->Size() );
52   OffsetType   o;
53   DimensionValueType i, j;
54   for ( j = 0; j < VDimension; j++ )
55     {
56     o[j] = -( static_cast< OffsetValueType >( this->GetRadius(j) ) );
57     }
58 
59   for ( i = 0; i < this->Size(); ++i )
60     {
61     m_OffsetTable.push_back(o);
62     for ( j = 0; j < VDimension; j++ )
63       {
64       o[j] = o[j] + 1;
65       if ( o[j] > static_cast< OffsetValueType >( this->GetRadius(j) ) )
66         {
67         o[j] = -( static_cast< OffsetValueType >( this->GetRadius(j) ) );
68         }
69       else { break; }
70       }
71     }
72 }
73 
74 template< typename TPixel, unsigned int VDimension, typename TContainer >
75 void
76 Neighborhood< TPixel, VDimension, TContainer >
SetRadius(const SizeValueType s)77 ::SetRadius(const SizeValueType s)
78 {
79   SizeType k;
80 
81   for ( DimensionValueType i = 0; i < VDimension; i++ )
82     {
83     k[i] = s;
84     }
85   this->SetRadius(k);
86 }
87 
88 template< typename TPixel, unsigned int VDimension, typename TContainer >
89 void
90 Neighborhood< TPixel, VDimension, TContainer >
SetRadius(const SizeType & r)91 ::SetRadius(const SizeType & r)
92 {
93   this->m_Radius = r;
94   this->SetSize();
95 
96   SizeValueType cumul = NumericTraits< SizeValueType >::OneValue();
97   for ( DimensionValueType i = 0; i < VDimension; i++ )
98     {
99     cumul *= m_Size[i];
100     }
101 
102   this->Allocate(cumul);
103   this->ComputeNeighborhoodStrideTable();
104   this->ComputeNeighborhoodOffsetTable();
105 }
106 
107 template< typename TPixel, unsigned int VDimension, typename TContainer >
108 Neighborhood< TPixel, VDimension, TContainer >
Neighborhood(const Self & other)109 ::Neighborhood(const Self & other):
110   m_Radius     ( other.m_Radius ),
111   m_Size       ( other.m_Size ),
112   m_DataBuffer ( other.m_DataBuffer ),
113   m_OffsetTable( other.m_OffsetTable )
114 {
115   std::copy(other.m_StrideTable,
116             other.m_StrideTable+VDimension,
117             m_StrideTable);
118 }
119 
120 template< typename TPixel, unsigned int VDimension, typename TContainer >
121 Neighborhood< TPixel, VDimension, TContainer > &
122 Neighborhood< TPixel, VDimension, TContainer >
operator =(const Self & other)123 ::operator=(const Self & other)
124 {
125   if(this != &other)
126     {
127     m_Radius     = other.m_Radius;
128     m_Size       = other.m_Size;
129     m_DataBuffer = other.m_DataBuffer;
130     std::copy(other.m_StrideTable,
131               other.m_StrideTable+VDimension,
132               m_StrideTable);
133     m_OffsetTable = other.m_OffsetTable;
134     }
135   return *this;
136 }
137 
138 template< typename TPixel, unsigned int VDimension, typename TContainer >
139 std::slice Neighborhood< TPixel, VDimension, TContainer >
GetSlice(unsigned int d) const140 ::GetSlice(unsigned int d) const
141 {
142   const OffsetValueType t = this->GetStride(d);
143   const auto s = static_cast< OffsetValueType >( this->GetSize()[d] );
144 
145   OffsetValueType n = this->Size() / 2;
146   n -= t * s / 2;
147 
148   return { static_cast< size_t >( n ),
149            static_cast< size_t >( s ),
150            static_cast< size_t >( t ) };
151 }
152 
153 template< typename TPixel, unsigned int VDimension, typename TContainer >
154 typename Neighborhood< TPixel, VDimension, TContainer >::NeighborIndexType
155 Neighborhood< TPixel, VDimension, TContainer >
GetNeighborhoodIndex(const OffsetType & o) const156 ::GetNeighborhoodIndex(const OffsetType & o) const
157 {
158   unsigned int idx = ( this->Size() / 2 );
159 
160   for ( unsigned i = 0; i < VDimension; ++i )
161     {
162     idx += o[i] * m_StrideTable[i];
163     }
164   return idx;
165 }
166 
167 template< typename TPixel, unsigned int VDimension, typename TContainer >
168 void Neighborhood< TPixel, VDimension, TContainer >
PrintSelf(std::ostream & os,Indent indent) const169 ::PrintSelf(std::ostream & os, Indent indent) const
170 {
171   os << indent << "m_Size: [ ";
172   for (DimensionValueType i = 0; i < VDimension; ++i )
173     {
174     os << m_Size[i] << " ";
175     }
176   os << "]" << std::endl;
177 
178   os << indent << "m_Radius: [ ";
179   for (DimensionValueType i = 0; i < VDimension; ++i )
180     {
181     os << m_Radius[i] << " ";
182     }
183   os << "]" << std::endl;
184 
185   os << indent << "m_StrideTable: [ ";
186   for (DimensionValueType i = 0; i < VDimension; ++i )
187     {
188     os << m_StrideTable[i] << " ";
189     }
190   os << "]" << std::endl;
191 
192   os << indent << "m_OffsetTable: [ ";
193   for (DimensionValueType i = 0; i < m_OffsetTable.size(); ++i )
194     {
195     os << m_OffsetTable[i] << " ";
196     }
197   os << "]" << std::endl;
198 }
199 }  // namespace itk
200 
201 #endif
202