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 #ifndef itkMeshConvertPixelTraits_h
20 #define itkMeshConvertPixelTraits_h
21 
22 #include "itkArray.h"
23 #include "itkMatrix.h"
24 #include "itkOffset.h"
25 #include "itkCovariantVector.h"
26 #include "itkVariableLengthVector.h"
27 #include "itkVector.h"
28 #include "itkPoint.h"
29 
30 namespace itk
31 {
32 
33 /** \class MeshConvertPixelTraits
34  *  \brief Traits class used to by ConvertPixels to convert blocks of pixels.
35  *
36  *  TOutputPixelType is the destination type. The input type is inferred
37  *  by the templated static function Convert.
38  *
39  *  This implementaion, does a simple assignment operator, so if you are
40  *  going from from a higher bit representation to a lower bit one (int to
41  *  char), you may want to specialize and add some sort of transfer function.
42  *  \ingroup ITKIOMeshBase
43  */
44 template<typename PixelType>
45 class MeshConvertPixelTraits
46 {
47 public:
48   /** Determine the pixel data type. */
49   using ComponentType = typename PixelType::ComponentType;
50 
51   /** Return the number of components per pixel. */
GetNumberOfComponents()52   static unsigned int GetNumberOfComponents()
53   { return PixelType::GetNumberOfComponents();}
54 
GetNumberOfComponents(const PixelType &)55   static unsigned int GetNumberOfComponents(const PixelType& )
56   { return PixelType::GetNumberOfComponents();}
57 
58   /** Return the nth component of the pixel. */
GetNthComponent(int c,const PixelType & pixel)59   static ComponentType GetNthComponent(int c, const PixelType& pixel)
60   { return pixel.GetNthComponent(c); }
61 
62   /** Set the nth component of the pixel. */
SetNthComponent(int c,PixelType & pixel,const ComponentType & v)63   static void SetNthComponent(int c, PixelType& pixel, const ComponentType& v)
64   { pixel.SetNthComponent(c, v); }
65 
66   /** Return a single scalar value from this pixel. */
GetScalarValue(const PixelType & pixel)67   static ComponentType GetScalarValue(const PixelType& pixel)
68   { return pixel.GetScalarValue(); }
69 
70 };
71 
72 #define ITK_DEFAULTCONVERTTRAITS_NATIVE_SPECIAL(type)                     \
73 template<>                                                                \
74   class MeshConvertPixelTraits<type>                                      \
75   {                                                                       \
76   public:                                                                 \
77   using ComponentType = type;                                             \
78   static unsigned int GetNumberOfComponents()                             \
79   {                                                                       \
80   return 1;                                                               \
81   }                                                                       \
82   static unsigned int GetNumberOfComponents(const type& itkNotUsed(pixel))\
83   {                                                                       \
84   return 1;                                                               \
85   }                                                                       \
86   static ComponentType GetNthComponent(int itkNotUsed(c), const type& pixel)\
87   {                                                                       \
88   return pixel;                                                           \
89   }                                                                       \
90   static void SetNthComponent(int , type& pixel, const ComponentType& v)  \
91   {                                                                       \
92   pixel = v;                                                              \
93   }                                                                       \
94   static type GetScalarValue(const type& pixel)                           \
95   {                                                                       \
96   return pixel;                                                           \
97   }                                                                       \
98   };
99 
100   ITK_DEFAULTCONVERTTRAITS_NATIVE_SPECIAL(float)
101   ITK_DEFAULTCONVERTTRAITS_NATIVE_SPECIAL(double)
102   ITK_DEFAULTCONVERTTRAITS_NATIVE_SPECIAL(int)
103   ITK_DEFAULTCONVERTTRAITS_NATIVE_SPECIAL(char)
104   ITK_DEFAULTCONVERTTRAITS_NATIVE_SPECIAL(short)
105   ITK_DEFAULTCONVERTTRAITS_NATIVE_SPECIAL(unsigned int)
106   ITK_DEFAULTCONVERTTRAITS_NATIVE_SPECIAL(signed char)
107   ITK_DEFAULTCONVERTTRAITS_NATIVE_SPECIAL(unsigned char)
108   ITK_DEFAULTCONVERTTRAITS_NATIVE_SPECIAL(unsigned short)
109   ITK_DEFAULTCONVERTTRAITS_NATIVE_SPECIAL(long)
110   ITK_DEFAULTCONVERTTRAITS_NATIVE_SPECIAL(unsigned long)
111   ITK_DEFAULTCONVERTTRAITS_NATIVE_SPECIAL(bool)
112 
113 #undef ITK_DEFAULTCONVERTTRAITS_NATIVE_SPECIAL
114 
115 //
116 //  Default traits for the Offset<> pixel type
117 //
118 
119 #define ITK_MESH_DEFAULTCONVERTTRAITS_OFFSET_TYPE(dimension)                       \
120   template<>                                                                       \
121   class MeshConvertPixelTraits< Offset<dimension> >                                \
122   {                                                                                \
123   public:                                                                          \
124   using TargetType = Offset<dimension>;                                           \
125   using ComponentType = TargetType::OffsetValueType;                              \
126   static unsigned int GetNumberOfComponents()                                      \
127   {                                                                                \
128   return dimension;                                                                \
129   }                                                                                \
130   static unsigned int GetNumberOfComponents(const TargetType& itkNotUsed(pixel))   \
131   {                                                                                \
132   return dimension;                                                                \
133   }                                                                                \
134   static ComponentType GetNthComponent(int c, const TargetType& pixel)             \
135   {                                                                                \
136   return pixel[c];                                                                 \
137   }                                                                                \
138   static void SetNthComponent(int i, TargetType & pixel, const ComponentType& v)   \
139   {                                                                                \
140   pixel[i] = v;                                                                    \
141   }                                                                                \
142   static ComponentType GetScalarValue(const TargetType& pixel)                     \
143   {                                                                                \
144   return pixel[0];                                                                 \
145   }                                                                                \
146   };                                                                               \
147 
148 
149 // Define traits for Offset<> from dimensions 1 to 5
150   ITK_MESH_DEFAULTCONVERTTRAITS_OFFSET_TYPE(1)
151   ITK_MESH_DEFAULTCONVERTTRAITS_OFFSET_TYPE(2)
152   ITK_MESH_DEFAULTCONVERTTRAITS_OFFSET_TYPE(3)
153   ITK_MESH_DEFAULTCONVERTTRAITS_OFFSET_TYPE(4)
154   ITK_MESH_DEFAULTCONVERTTRAITS_OFFSET_TYPE(5)
155 
156 //
157 //  Default traits for the pixel types deriving from FixedArray<>
158 //
159 
160 #define ITK_MESH_DEFAULTCONVERTTRAITS_FIXEDARRAY_TYPE(type,componenttype, dimension) \
161   template<>                                                                         \
162   class MeshConvertPixelTraits< type< componenttype, dimension> >                    \
163   {                                                                                  \
164   public:                                                                            \
165   using TargetType = type< componenttype, dimension >;                              \
166   using ComponentType = componenttype;                           \
167   static unsigned int GetNumberOfComponents()                                        \
168   {                                                                                  \
169   return dimension;                                                                  \
170   }                                                                                  \
171   static unsigned int GetNumberOfComponents(const TargetType& itkNotUsed(pixel))     \
172   {                                                                                  \
173   return dimension;                                                                  \
174   }                                                                                  \
175   static ComponentType GetNthComponent(int c, const TargetType& pixel)               \
176   {                                                                                  \
177   return pixel[c];                                                                   \
178   }                                                                                  \
179   static void SetNthComponent(int i, TargetType & pixel, const ComponentType& v)     \
180   {                                                                                  \
181   pixel[i] = v;                                                                      \
182   }                                                                                  \
183   static ComponentType GetScalarValue(const TargetType& pixel)                       \
184   {                                                                                  \
185   return pixel[0];                                                                   \
186   }                                                                                  \
187   };                                                                                 \
188 
189 //
190 //
191 // Define traits for Classed deriving from FixedArray from dimensions 1 to 6
192 // These classes include: Vector, CovariantVector and Point.
193 //
194 //
195 #define ITK_MESH_DEFAULTCONVERTTRAITS_FIXEDARRAY_TYPE_ALL_MACRO(ArrayType, Type)      \
196   ITK_MESH_DEFAULTCONVERTTRAITS_FIXEDARRAY_TYPE(ArrayType,Type,1)                     \
197   ITK_MESH_DEFAULTCONVERTTRAITS_FIXEDARRAY_TYPE(ArrayType,Type,2)                     \
198   ITK_MESH_DEFAULTCONVERTTRAITS_FIXEDARRAY_TYPE(ArrayType,Type,3)                     \
199   ITK_MESH_DEFAULTCONVERTTRAITS_FIXEDARRAY_TYPE(ArrayType,Type,4)                     \
200   ITK_MESH_DEFAULTCONVERTTRAITS_FIXEDARRAY_TYPE(ArrayType,Type,5)                     \
201   ITK_MESH_DEFAULTCONVERTTRAITS_FIXEDARRAY_TYPE(ArrayType,Type,6)
202 
203 #define ITK_MESH_DEFAULTCONVERTTRAITS_FIXEDARRAY_TYPE_ALL_TYPES_MACRO(ArrayType)      \
204   ITK_MESH_DEFAULTCONVERTTRAITS_FIXEDARRAY_TYPE_ALL_MACRO(ArrayType, char);           \
205   ITK_MESH_DEFAULTCONVERTTRAITS_FIXEDARRAY_TYPE_ALL_MACRO(ArrayType, signed char);    \
206   ITK_MESH_DEFAULTCONVERTTRAITS_FIXEDARRAY_TYPE_ALL_MACRO(ArrayType, unsigned char);  \
207   ITK_MESH_DEFAULTCONVERTTRAITS_FIXEDARRAY_TYPE_ALL_MACRO(ArrayType, short);          \
208   ITK_MESH_DEFAULTCONVERTTRAITS_FIXEDARRAY_TYPE_ALL_MACRO(ArrayType, unsigned short); \
209   ITK_MESH_DEFAULTCONVERTTRAITS_FIXEDARRAY_TYPE_ALL_MACRO(ArrayType, int);            \
210   ITK_MESH_DEFAULTCONVERTTRAITS_FIXEDARRAY_TYPE_ALL_MACRO(ArrayType, unsigned int);   \
211   ITK_MESH_DEFAULTCONVERTTRAITS_FIXEDARRAY_TYPE_ALL_MACRO(ArrayType, long);           \
212   ITK_MESH_DEFAULTCONVERTTRAITS_FIXEDARRAY_TYPE_ALL_MACRO(ArrayType, unsigned long);  \
213   ITK_MESH_DEFAULTCONVERTTRAITS_FIXEDARRAY_TYPE_ALL_MACRO(ArrayType, float);          \
214   ITK_MESH_DEFAULTCONVERTTRAITS_FIXEDARRAY_TYPE_ALL_MACRO(ArrayType, double);
215 
216   ITK_MESH_DEFAULTCONVERTTRAITS_FIXEDARRAY_TYPE_ALL_TYPES_MACRO(Vector);
217   ITK_MESH_DEFAULTCONVERTTRAITS_FIXEDARRAY_TYPE_ALL_TYPES_MACRO(CovariantVector);
218   ITK_MESH_DEFAULTCONVERTTRAITS_FIXEDARRAY_TYPE_ALL_TYPES_MACRO(Point);
219   ITK_MESH_DEFAULTCONVERTTRAITS_FIXEDARRAY_TYPE_ALL_TYPES_MACRO(FixedArray);
220 
221 //
222 //  End of Traits for the classes deriving from FixedArray.
223 //
224 //
225 
226 
227 //
228 //  Default traits for the pixel types deriving from Matrix<>
229 //
230 
231 #define ITK_MESH_DEFAULTCONVERTTRAITS_MATRIX_TYPE(type,componenttype,rows,cols)    \
232 template<>                                                                         \
233   class MeshConvertPixelTraits< type< componenttype, rows, cols > >                \
234   {                                                                                \
235   public:                                                                          \
236   using TargetType = type< componenttype, rows, cols >;                           \
237   using ComponentType = componenttype;                         \
238   static unsigned int GetNumberOfComponents()                                      \
239   {                                                                                \
240   return rows * cols;                                                              \
241   }                                                                                \
242   static unsigned int GetNumberOfComponents(const TargetType& itkNotUsed(pixel))   \
243   {                                                                                \
244   return rows * cols;                                                              \
245   }                                                                                \
246   static ComponentType GetNthComponent(int c, const TargetType& pixel)             \
247   {                                                                                \
248   const unsigned int row = c / cols;                                               \
249   const unsigned int col = c % cols;                                               \
250   return pixel[row][col];                                                          \
251   }                                                                                \
252   static void SetNthComponent(int i, TargetType & pixel, const ComponentType& v)   \
253   {                                                                                \
254   const unsigned int row = i / cols;                                               \
255   const unsigned int col = i % cols;                                               \
256   pixel[row][col] = v;                                                             \
257   }                                                                                \
258   static ComponentType GetScalarValue(const TargetType& pixel)                     \
259   {                                                                                \
260   return pixel[0][0];                                                              \
261   }                                                                                \
262   };                                                                               \
263 
264 //
265 //
266 // Define traits for Classed deriving from Matrix from dimensions 1 to 6
267 //
268 //
269 #define ITK_MESH_DEFAULTCONVERTTRAITS_MATRIX_TYPE_ALL_MACRO(ArrayType, Type)      \
270   ITK_MESH_DEFAULTCONVERTTRAITS_MATRIX_TYPE(ArrayType,Type,1,1)                   \
271   ITK_MESH_DEFAULTCONVERTTRAITS_MATRIX_TYPE(ArrayType,Type,2,2)                   \
272   ITK_MESH_DEFAULTCONVERTTRAITS_MATRIX_TYPE(ArrayType,Type,3,3)                   \
273   ITK_MESH_DEFAULTCONVERTTRAITS_MATRIX_TYPE(ArrayType,Type,4,4)                   \
274   ITK_MESH_DEFAULTCONVERTTRAITS_MATRIX_TYPE(ArrayType,Type,5,5)                   \
275   ITK_MESH_DEFAULTCONVERTTRAITS_MATRIX_TYPE(ArrayType,Type,6,6)
276 
277 #define ITK_MESH_DEFAULTCONVERTTRAITS_MATRIX_TYPE_ALL_TYPES_MACRO(ArrayType)      \
278   ITK_MESH_DEFAULTCONVERTTRAITS_MATRIX_TYPE_ALL_MACRO(ArrayType, char);           \
279   ITK_MESH_DEFAULTCONVERTTRAITS_MATRIX_TYPE_ALL_MACRO(ArrayType, signed char);    \
280   ITK_MESH_DEFAULTCONVERTTRAITS_MATRIX_TYPE_ALL_MACRO(ArrayType, unsigned char);  \
281   ITK_MESH_DEFAULTCONVERTTRAITS_MATRIX_TYPE_ALL_MACRO(ArrayType, short);          \
282   ITK_MESH_DEFAULTCONVERTTRAITS_MATRIX_TYPE_ALL_MACRO(ArrayType, unsigned short); \
283   ITK_MESH_DEFAULTCONVERTTRAITS_MATRIX_TYPE_ALL_MACRO(ArrayType, int);            \
284   ITK_MESH_DEFAULTCONVERTTRAITS_MATRIX_TYPE_ALL_MACRO(ArrayType, unsigned int);   \
285   ITK_MESH_DEFAULTCONVERTTRAITS_MATRIX_TYPE_ALL_MACRO(ArrayType, long);           \
286   ITK_MESH_DEFAULTCONVERTTRAITS_MATRIX_TYPE_ALL_MACRO(ArrayType, unsigned long);  \
287   ITK_MESH_DEFAULTCONVERTTRAITS_MATRIX_TYPE_ALL_MACRO(ArrayType, float);          \
288   ITK_MESH_DEFAULTCONVERTTRAITS_MATRIX_TYPE_ALL_MACRO(ArrayType, double);
289 
290 //
291 // Add here other classes that derive from Matrix or that have the same API
292 //
293   ITK_MESH_DEFAULTCONVERTTRAITS_MATRIX_TYPE_ALL_TYPES_MACRO(Matrix);
294 
295 //
296 //  End of Traits for the classes deriving from Matrix.
297 //
298 //
299 
300 
301 //
302 //  Default traits for the pixel types deriving from std::complex<>
303 //
304 
305 #define ITK_MESH_DEFAULTCONVERTTRAITS_COMPLEX_TYPE( componenttype )                \
306 template<>                                                                         \
307   class MeshConvertPixelTraits< ::std::complex< componenttype > >                  \
308   {                                                                                \
309   public:                                                                          \
310   using TargetType = ::std::complex< componenttype>;                              \
311   using ComponentType = componenttype;                         \
312   static unsigned int GetNumberOfComponents()                                      \
313   {                                                                                \
314   return 2;                                                                        \
315   }                                                                                \
316   static unsigned int GetNumberOfComponents(const TargetType & itkNotUsed(pixel))  \
317   {                                                                                \
318   return 2;                                                                        \
319   }                                                                                \
320   static ComponentType GetNthComponent(int i, TargetType & pixel)                  \
321   {                                                                                \
322   if( i == 0 )                                                                     \
323     {                                                                              \
324     return pixel.imag();                                                           \
325     }                                                                              \
326   else                                                                             \
327     {                                                                              \
328     return pixel.real();                                                           \
329     }                                                                              \
330   }                                                                                \
331   static void SetNthComponent(int i, TargetType & pixel, const ComponentType& v)   \
332   {                                                                                \
333   if( i == 0 )                                                                     \
334     {                                                                              \
335     pixel = TargetType( v, pixel.imag() );                                         \
336     }                                                                              \
337   else                                                                             \
338     {                                                                              \
339     pixel = TargetType( pixel.real(), v );                                         \
340     }                                                                              \
341   }                                                                                \
342   static ComponentType GetScalarValue(const TargetType& pixel)                     \
343   {                                                                                \
344   return std::norm(pixel);                                                         \
345   }                                                                                \
346   };                                                                               \
347 
348   ITK_MESH_DEFAULTCONVERTTRAITS_COMPLEX_TYPE(float);
349   ITK_MESH_DEFAULTCONVERTTRAITS_COMPLEX_TYPE(double);
350 
351 #define ITK_MESH_DEFAULTCONVERTTRAITS_ARRAY_TYPE(type,componenttype)               \
352 template<>                                                                         \
353   class MeshConvertPixelTraits< type< componenttype> >                             \
354   {                                                                                \
355   public:                                                                          \
356   using TargetType = type< componenttype >;                            \
357   using ComponentType = componenttype;                         \
358   static unsigned int GetNumberOfComponents()                                      \
359   {                                                                                \
360   return 0;                                                                        \
361   }                                                                                \
362   static unsigned int GetNumberOfComponents(const TargetType& pixel)               \
363   {                                                                                \
364   return pixel.Size();                                                             \
365   }                                                                                \
366   static ComponentType GetNthComponent(int c, const TargetType& pixel)             \
367   {                                                                                \
368   return pixel[c];                                                                 \
369   }                                                                                \
370   static void SetNthComponent(int i, TargetType & pixel, const ComponentType& v)   \
371   {                                                                                \
372   pixel[i] = v;                                                                    \
373   }                                                                                \
374   static ComponentType GetScalarValue(const TargetType& pixel)                     \
375   {                                                                                \
376   return pixel[0];                                                                 \
377   }                                                                                \
378   };                                                                               \
379 
380 #define ITK_MESH_DEFAULTCONVERTTRAITS_ARRAY_TYPE_ALL_TYPES_MACRO(ArrayType)        \
381   ITK_MESH_DEFAULTCONVERTTRAITS_ARRAY_TYPE(ArrayType, char);                       \
382   ITK_MESH_DEFAULTCONVERTTRAITS_ARRAY_TYPE(ArrayType, signed char);                \
383   ITK_MESH_DEFAULTCONVERTTRAITS_ARRAY_TYPE(ArrayType, unsigned char);              \
384   ITK_MESH_DEFAULTCONVERTTRAITS_ARRAY_TYPE(ArrayType, short);                      \
385   ITK_MESH_DEFAULTCONVERTTRAITS_ARRAY_TYPE(ArrayType, unsigned short);             \
386   ITK_MESH_DEFAULTCONVERTTRAITS_ARRAY_TYPE(ArrayType, int);                        \
387   ITK_MESH_DEFAULTCONVERTTRAITS_ARRAY_TYPE(ArrayType, unsigned int);               \
388   ITK_MESH_DEFAULTCONVERTTRAITS_ARRAY_TYPE(ArrayType, long);                       \
389   ITK_MESH_DEFAULTCONVERTTRAITS_ARRAY_TYPE(ArrayType, unsigned long);              \
390   ITK_MESH_DEFAULTCONVERTTRAITS_ARRAY_TYPE(ArrayType, float);                      \
391   ITK_MESH_DEFAULTCONVERTTRAITS_ARRAY_TYPE(ArrayType, double);
392 
393   ITK_MESH_DEFAULTCONVERTTRAITS_ARRAY_TYPE_ALL_TYPES_MACRO(Array);
394   ITK_MESH_DEFAULTCONVERTTRAITS_ARRAY_TYPE_ALL_TYPES_MACRO(VariableLengthVector);
395 //
396 //  End of Traits for the classes deriving from std::complex.
397 //
398 //
399 
400 } // end namespace itk
401 #endif
402