/*========================================================================= * * Copyright NumFOCUS * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * https://www.apache.org/licenses/LICENSE-2.0.txt * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * *=========================================================================*/ #ifndef itkMeshConvertPixelTraits_h #define itkMeshConvertPixelTraits_h #include "itkArray.h" #include "itkMatrix.h" #include "itkOffset.h" #include "itkCovariantVector.h" #include "itkVariableLengthVector.h" #include "itkVector.h" #include "itkPoint.h" namespace itk { /** * \class MeshConvertPixelTraits * \brief Traits class used to by ConvertPixels to convert blocks of pixels. * * TOutputPixelType is the destination type. The input type is inferred * by the templated static function Convert. * * This implementation, does a simple assignment operator, so if you are * going from from a higher bit representation to a lower bit one (int to * char), you may want to specialize and add some sort of transfer function. * \ingroup ITKIOMeshBase */ template class MeshConvertPixelTraits { public: /** Determine the pixel data type. */ using ComponentType = typename PixelType::ComponentType; /** Return the number of components per pixel. */ static unsigned int GetNumberOfComponents() { return PixelType::GetNumberOfComponents(); } static unsigned int GetNumberOfComponents(const PixelType &) { return PixelType::GetNumberOfComponents(); } /** Return the nth component of the pixel. */ static ComponentType GetNthComponent(int c, const PixelType & pixel) { return pixel.GetNthComponent(c); } /** Set the nth component of the pixel. */ static void SetNthComponent(int c, PixelType & pixel, const ComponentType & v) { pixel.SetNthComponent(c, v); } /** Return a single scalar value from this pixel. */ static ComponentType GetScalarValue(const PixelType & pixel) { return pixel.GetScalarValue(); } }; #define ITK_DEFAULTCONVERTTRAITS_NATIVE_SPECIAL(type) \ template <> \ class MeshConvertPixelTraits \ { \ public: \ using ComponentType = type; \ static unsigned int \ GetNumberOfComponents() \ { \ return 1; \ } \ static unsigned int \ GetNumberOfComponents(const type & itkNotUsed(pixel)) \ { \ return 1; \ } \ static ComponentType \ GetNthComponent(int itkNotUsed(c), const type & pixel) \ { \ return pixel; \ } \ static void \ SetNthComponent(int, type & pixel, const ComponentType & v) \ { \ pixel = v; \ } \ static type \ GetScalarValue(const type & pixel) \ { \ return pixel; \ } \ } ITK_DEFAULTCONVERTTRAITS_NATIVE_SPECIAL(char); ITK_DEFAULTCONVERTTRAITS_NATIVE_SPECIAL(signed char); ITK_DEFAULTCONVERTTRAITS_NATIVE_SPECIAL(unsigned char); ITK_DEFAULTCONVERTTRAITS_NATIVE_SPECIAL(short); ITK_DEFAULTCONVERTTRAITS_NATIVE_SPECIAL(unsigned short); ITK_DEFAULTCONVERTTRAITS_NATIVE_SPECIAL(int); ITK_DEFAULTCONVERTTRAITS_NATIVE_SPECIAL(unsigned int); ITK_DEFAULTCONVERTTRAITS_NATIVE_SPECIAL(long); ITK_DEFAULTCONVERTTRAITS_NATIVE_SPECIAL(unsigned long); ITK_DEFAULTCONVERTTRAITS_NATIVE_SPECIAL(long long); ITK_DEFAULTCONVERTTRAITS_NATIVE_SPECIAL(unsigned long long); ITK_DEFAULTCONVERTTRAITS_NATIVE_SPECIAL(bool); ITK_DEFAULTCONVERTTRAITS_NATIVE_SPECIAL(float); ITK_DEFAULTCONVERTTRAITS_NATIVE_SPECIAL(double); #undef ITK_DEFAULTCONVERTTRAITS_NATIVE_SPECIAL // // Default traits for the Offset<> pixel type // #define ITK_MESH_DEFAULTCONVERTTRAITS_OFFSET_TYPE(dimension) \ template <> \ class MeshConvertPixelTraits> \ { \ public: \ using TargetType = Offset; \ using ComponentType = TargetType::OffsetValueType; \ static unsigned int \ GetNumberOfComponents() \ { \ return dimension; \ } \ static unsigned int \ GetNumberOfComponents(const TargetType & itkNotUsed(pixel)) \ { \ return dimension; \ } \ static ComponentType \ GetNthComponent(int c, const TargetType & pixel) \ { \ return pixel[c]; \ } \ static void \ SetNthComponent(int i, TargetType & pixel, const ComponentType & v) \ { \ pixel[i] = v; \ } \ static ComponentType \ GetScalarValue(const TargetType & pixel) \ { \ return pixel[0]; \ } \ }; // Define traits for Offset<> from dimensions 1 to 5 ITK_MESH_DEFAULTCONVERTTRAITS_OFFSET_TYPE(1) ITK_MESH_DEFAULTCONVERTTRAITS_OFFSET_TYPE(2) ITK_MESH_DEFAULTCONVERTTRAITS_OFFSET_TYPE(3) ITK_MESH_DEFAULTCONVERTTRAITS_OFFSET_TYPE(4) ITK_MESH_DEFAULTCONVERTTRAITS_OFFSET_TYPE(5) // // Default traits for the pixel types deriving from FixedArray<> // #define ITK_MESH_DEFAULTCONVERTTRAITS_FIXEDARRAY_TYPE(type, componenttype, dimension) \ template <> \ class MeshConvertPixelTraits> \ { \ public: \ using TargetType = type; \ using ComponentType = componenttype; \ static unsigned int \ GetNumberOfComponents() \ { \ return dimension; \ } \ static unsigned int \ GetNumberOfComponents(const TargetType & itkNotUsed(pixel)) \ { \ return dimension; \ } \ static ComponentType \ GetNthComponent(int c, const TargetType & pixel) \ { \ return pixel[c]; \ } \ static void \ SetNthComponent(int i, TargetType & pixel, const ComponentType & v) \ { \ pixel[i] = v; \ } \ static ComponentType \ GetScalarValue(const TargetType & pixel) \ { \ return pixel[0]; \ } \ }; // // // Define traits for Classed deriving from FixedArray from dimensions 1 to 6 // These classes include: Vector, CovariantVector and Point. // // #define ITK_MESH_DEFAULTCONVERTTRAITS_FIXEDARRAY_TYPE_ALL_MACRO(ArrayType, Type) \ ITK_MESH_DEFAULTCONVERTTRAITS_FIXEDARRAY_TYPE(ArrayType, Type, 1) \ ITK_MESH_DEFAULTCONVERTTRAITS_FIXEDARRAY_TYPE(ArrayType, Type, 2) \ ITK_MESH_DEFAULTCONVERTTRAITS_FIXEDARRAY_TYPE(ArrayType, Type, 3) \ ITK_MESH_DEFAULTCONVERTTRAITS_FIXEDARRAY_TYPE(ArrayType, Type, 4) \ ITK_MESH_DEFAULTCONVERTTRAITS_FIXEDARRAY_TYPE(ArrayType, Type, 5) \ ITK_MESH_DEFAULTCONVERTTRAITS_FIXEDARRAY_TYPE(ArrayType, Type, 6) #define ITK_MESH_DEFAULTCONVERTTRAITS_FIXEDARRAY_TYPE_ALL_TYPES_MACRO(ArrayType) \ ITK_MESH_DEFAULTCONVERTTRAITS_FIXEDARRAY_TYPE_ALL_MACRO(ArrayType, char); \ ITK_MESH_DEFAULTCONVERTTRAITS_FIXEDARRAY_TYPE_ALL_MACRO(ArrayType, signed char); \ ITK_MESH_DEFAULTCONVERTTRAITS_FIXEDARRAY_TYPE_ALL_MACRO(ArrayType, unsigned char); \ ITK_MESH_DEFAULTCONVERTTRAITS_FIXEDARRAY_TYPE_ALL_MACRO(ArrayType, short); \ ITK_MESH_DEFAULTCONVERTTRAITS_FIXEDARRAY_TYPE_ALL_MACRO(ArrayType, unsigned short); \ ITK_MESH_DEFAULTCONVERTTRAITS_FIXEDARRAY_TYPE_ALL_MACRO(ArrayType, int); \ ITK_MESH_DEFAULTCONVERTTRAITS_FIXEDARRAY_TYPE_ALL_MACRO(ArrayType, unsigned int); \ ITK_MESH_DEFAULTCONVERTTRAITS_FIXEDARRAY_TYPE_ALL_MACRO(ArrayType, long); \ ITK_MESH_DEFAULTCONVERTTRAITS_FIXEDARRAY_TYPE_ALL_MACRO(ArrayType, unsigned long); \ ITK_MESH_DEFAULTCONVERTTRAITS_FIXEDARRAY_TYPE_ALL_MACRO(ArrayType, long long); \ ITK_MESH_DEFAULTCONVERTTRAITS_FIXEDARRAY_TYPE_ALL_MACRO(ArrayType, unsigned long long); \ ITK_MESH_DEFAULTCONVERTTRAITS_FIXEDARRAY_TYPE_ALL_MACRO(ArrayType, float); \ ITK_MESH_DEFAULTCONVERTTRAITS_FIXEDARRAY_TYPE_ALL_MACRO(ArrayType, double); ITK_MESH_DEFAULTCONVERTTRAITS_FIXEDARRAY_TYPE_ALL_TYPES_MACRO(Vector); ITK_MESH_DEFAULTCONVERTTRAITS_FIXEDARRAY_TYPE_ALL_TYPES_MACRO(CovariantVector); ITK_MESH_DEFAULTCONVERTTRAITS_FIXEDARRAY_TYPE_ALL_TYPES_MACRO(Point); ITK_MESH_DEFAULTCONVERTTRAITS_FIXEDARRAY_TYPE_ALL_TYPES_MACRO(FixedArray); // // End of Traits for the classes deriving from FixedArray. // // // // Default traits for the pixel types deriving from Matrix<> // #define ITK_MESH_DEFAULTCONVERTTRAITS_MATRIX_TYPE(type, componenttype, rows, cols) \ template <> \ class MeshConvertPixelTraits> \ { \ public: \ using TargetType = type; \ using ComponentType = componenttype; \ static unsigned int \ GetNumberOfComponents() \ { \ return rows * cols; \ } \ static unsigned int \ GetNumberOfComponents(const TargetType & itkNotUsed(pixel)) \ { \ return rows * cols; \ } \ static ComponentType \ GetNthComponent(int c, const TargetType & pixel) \ { \ const unsigned int row = c / cols; \ const unsigned int col = c % cols; \ return pixel[row][col]; \ } \ static void \ SetNthComponent(int i, TargetType & pixel, const ComponentType & v) \ { \ const unsigned int row = i / cols; \ const unsigned int col = i % cols; \ pixel[row][col] = v; \ } \ static ComponentType \ GetScalarValue(const TargetType & pixel) \ { \ return pixel[0][0]; \ } \ }; // // // Define traits for Classed deriving from Matrix from dimensions 1 to 6 // // #define ITK_MESH_DEFAULTCONVERTTRAITS_MATRIX_TYPE_ALL_MACRO(ArrayType, Type) \ ITK_MESH_DEFAULTCONVERTTRAITS_MATRIX_TYPE(ArrayType, Type, 1, 1) \ ITK_MESH_DEFAULTCONVERTTRAITS_MATRIX_TYPE(ArrayType, Type, 2, 2) \ ITK_MESH_DEFAULTCONVERTTRAITS_MATRIX_TYPE(ArrayType, Type, 3, 3) \ ITK_MESH_DEFAULTCONVERTTRAITS_MATRIX_TYPE(ArrayType, Type, 4, 4) \ ITK_MESH_DEFAULTCONVERTTRAITS_MATRIX_TYPE(ArrayType, Type, 5, 5) \ ITK_MESH_DEFAULTCONVERTTRAITS_MATRIX_TYPE(ArrayType, Type, 6, 6) #define ITK_MESH_DEFAULTCONVERTTRAITS_MATRIX_TYPE_ALL_TYPES_MACRO(ArrayType) \ ITK_MESH_DEFAULTCONVERTTRAITS_MATRIX_TYPE_ALL_MACRO(ArrayType, char); \ ITK_MESH_DEFAULTCONVERTTRAITS_MATRIX_TYPE_ALL_MACRO(ArrayType, signed char); \ ITK_MESH_DEFAULTCONVERTTRAITS_MATRIX_TYPE_ALL_MACRO(ArrayType, unsigned char); \ ITK_MESH_DEFAULTCONVERTTRAITS_MATRIX_TYPE_ALL_MACRO(ArrayType, short); \ ITK_MESH_DEFAULTCONVERTTRAITS_MATRIX_TYPE_ALL_MACRO(ArrayType, unsigned short); \ ITK_MESH_DEFAULTCONVERTTRAITS_MATRIX_TYPE_ALL_MACRO(ArrayType, int); \ ITK_MESH_DEFAULTCONVERTTRAITS_MATRIX_TYPE_ALL_MACRO(ArrayType, unsigned int); \ ITK_MESH_DEFAULTCONVERTTRAITS_MATRIX_TYPE_ALL_MACRO(ArrayType, long); \ ITK_MESH_DEFAULTCONVERTTRAITS_MATRIX_TYPE_ALL_MACRO(ArrayType, unsigned long); \ ITK_MESH_DEFAULTCONVERTTRAITS_MATRIX_TYPE_ALL_MACRO(ArrayType, long long); \ ITK_MESH_DEFAULTCONVERTTRAITS_MATRIX_TYPE_ALL_MACRO(ArrayType, unsigned long long); \ ITK_MESH_DEFAULTCONVERTTRAITS_MATRIX_TYPE_ALL_MACRO(ArrayType, float); \ ITK_MESH_DEFAULTCONVERTTRAITS_MATRIX_TYPE_ALL_MACRO(ArrayType, double); // // Add here other classes that derive from Matrix or that have the same API // ITK_MESH_DEFAULTCONVERTTRAITS_MATRIX_TYPE_ALL_TYPES_MACRO(Matrix); // // End of Traits for the classes deriving from Matrix. // // // // Default traits for the pixel types deriving from std::complex<> // #define ITK_MESH_DEFAULTCONVERTTRAITS_COMPLEX_TYPE(componenttype) \ template <> \ class MeshConvertPixelTraits> \ { \ public: \ using TargetType = std::complex; \ using ComponentType = componenttype; \ static unsigned int \ GetNumberOfComponents() \ { \ return 2; \ } \ static unsigned int \ GetNumberOfComponents(const TargetType & itkNotUsed(pixel)) \ { \ return 2; \ } \ static ComponentType \ GetNthComponent(int i, TargetType & pixel) \ { \ if (i == 0) \ { \ return pixel.imag(); \ } \ else \ { \ return pixel.real(); \ } \ } \ static void \ SetNthComponent(int i, TargetType & pixel, const ComponentType & v) \ { \ if (i == 0) \ { \ pixel = TargetType(v, pixel.imag()); \ } \ else \ { \ pixel = TargetType(pixel.real(), v); \ } \ } \ static ComponentType \ GetScalarValue(const TargetType & pixel) \ { \ return std::norm(pixel); \ } \ }; ITK_MESH_DEFAULTCONVERTTRAITS_COMPLEX_TYPE(float); ITK_MESH_DEFAULTCONVERTTRAITS_COMPLEX_TYPE(double); #define ITK_MESH_DEFAULTCONVERTTRAITS_ARRAY_TYPE(type, componenttype) \ template <> \ class MeshConvertPixelTraits> \ { \ public: \ using TargetType = type; \ using ComponentType = componenttype; \ static unsigned int \ GetNumberOfComponents() \ { \ return 0; \ } \ static unsigned int \ GetNumberOfComponents(const TargetType & pixel) \ { \ return pixel.Size(); \ } \ static ComponentType \ GetNthComponent(int c, const TargetType & pixel) \ { \ return pixel[c]; \ } \ static void \ SetNthComponent(int i, TargetType & pixel, const ComponentType & v) \ { \ pixel[i] = v; \ } \ static ComponentType \ GetScalarValue(const TargetType & pixel) \ { \ return pixel[0]; \ } \ }; #define ITK_MESH_DEFAULTCONVERTTRAITS_ARRAY_TYPE_ALL_TYPES_MACRO(ArrayType) \ ITK_MESH_DEFAULTCONVERTTRAITS_ARRAY_TYPE(ArrayType, char); \ ITK_MESH_DEFAULTCONVERTTRAITS_ARRAY_TYPE(ArrayType, signed char); \ ITK_MESH_DEFAULTCONVERTTRAITS_ARRAY_TYPE(ArrayType, unsigned char); \ ITK_MESH_DEFAULTCONVERTTRAITS_ARRAY_TYPE(ArrayType, short); \ ITK_MESH_DEFAULTCONVERTTRAITS_ARRAY_TYPE(ArrayType, unsigned short); \ ITK_MESH_DEFAULTCONVERTTRAITS_ARRAY_TYPE(ArrayType, int); \ ITK_MESH_DEFAULTCONVERTTRAITS_ARRAY_TYPE(ArrayType, unsigned int); \ ITK_MESH_DEFAULTCONVERTTRAITS_ARRAY_TYPE(ArrayType, long); \ ITK_MESH_DEFAULTCONVERTTRAITS_ARRAY_TYPE(ArrayType, unsigned long); \ ITK_MESH_DEFAULTCONVERTTRAITS_ARRAY_TYPE(ArrayType, long long); \ ITK_MESH_DEFAULTCONVERTTRAITS_ARRAY_TYPE(ArrayType, unsigned long long); \ ITK_MESH_DEFAULTCONVERTTRAITS_ARRAY_TYPE(ArrayType, float); \ ITK_MESH_DEFAULTCONVERTTRAITS_ARRAY_TYPE(ArrayType, double); ITK_MESH_DEFAULTCONVERTTRAITS_ARRAY_TYPE_ALL_TYPES_MACRO(Array); ITK_MESH_DEFAULTCONVERTTRAITS_ARRAY_TYPE_ALL_TYPES_MACRO(VariableLengthVector); // // End of Traits for the classes deriving from std::complex. // // } // end namespace itk #endif