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