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 itkImageAlgorithm_h 19 #define itkImageAlgorithm_h 20 21 #include "itkImageRegionIterator.h" 22 23 #include <type_traits> 24 25 namespace itk 26 { 27 28 template <typename TPixelType, unsigned int VImageDimension > class VectorImage; 29 30 31 /** \class ImageAlgorithm 32 * \brief A container of static functions which can operate on Images 33 * with Iterators. 34 * 35 * These methods are modeled after the STL algorithms. They may use 36 * special optimization techniques to implement enhanced versions of 37 * the methods. 38 * 39 * \ingroup ITKCommon 40 */ 41 struct ImageAlgorithm 42 { 43 44 using TrueType = std::true_type; 45 using FalseType = std::false_type; 46 47 /** 48 * \brief This generic function copies a region from one image to 49 * another. It may perform optimizations on the copy for efficiency. 50 * 51 * This method performs the equivalent to the following: 52 \code 53 itk::ImageRegionConstIterator<TInputImage> it( inImage, inRegion ); 54 itk::ImageRegionIterator<TOutputImage> ot( outImage, outRegion ); 55 56 while( !it.IsAtEnd() ) 57 { 58 ot.Set( static_cast< typename TInputImage::PixelType >( it.Get() ) ); 59 ++ot; 60 ++it; 61 } 62 \endcode 63 * 64 * \note: It is important not to explicitly pass the template 65 * arguments to this method as it may not result in an optimized 66 * method being called. 67 */ 68 template<typename InputImageType, typename OutputImageType> CopyImageAlgorithm69 static void Copy( const InputImageType *inImage, OutputImageType *outImage, 70 const typename InputImageType::RegionType &inRegion, 71 const typename OutputImageType::RegionType &outRegion ) 72 { 73 ImageAlgorithm::DispatchedCopy( inImage, outImage, inRegion, outRegion ); 74 } 75 76 /// \cond HIDE_SPECIALIZATION_DOCUMENTATION 77 template<typename TPixel1, typename TPixel2, unsigned int VImageDimension> CopyImageAlgorithm78 static void Copy( const Image<TPixel1, VImageDimension> * inImage, 79 Image<TPixel2, VImageDimension> * outImage, 80 const typename Image<TPixel1, VImageDimension>::RegionType &inRegion, 81 const typename Image<TPixel2, VImageDimension>::RegionType &outRegion ) 82 { 83 using _ImageType1 = Image<TPixel1, VImageDimension>; 84 using _ImageType2 = Image<TPixel2, VImageDimension>; 85 ImageAlgorithm::DispatchedCopy( inImage, outImage, inRegion, outRegion, 86 std::is_convertible<typename _ImageType1::PixelType, 87 typename _ImageType2::PixelType>() 88 ); 89 } 90 91 template<typename TPixel1, typename TPixel2, unsigned int VImageDimension> CopyImageAlgorithm92 static void Copy( const VectorImage<TPixel1, VImageDimension> * inImage, 93 VectorImage<TPixel2, VImageDimension> * outImage, 94 const typename VectorImage<TPixel1, VImageDimension>::RegionType &inRegion, 95 const typename VectorImage<TPixel2, VImageDimension>::RegionType &outRegion ) 96 { 97 using _ImageType1 = VectorImage<TPixel1, VImageDimension>; 98 using _ImageType2 = VectorImage<TPixel2, VImageDimension>; 99 ImageAlgorithm::DispatchedCopy( inImage, outImage, inRegion, outRegion, 100 std::is_convertible<typename _ImageType1::PixelType, 101 typename _ImageType2::PixelType>() 102 ); 103 } 104 105 /// \endcond 106 107 /** 108 * \brief Sets the output region to the smallest 109 * region of the output image that fully contains 110 * the physical space covered by the input 111 * region of the input image 112 */ 113 template<typename InputImageType, typename OutputImageType> 114 static typename OutputImageType::RegionType 115 EnlargeRegionOverBox(const typename InputImageType::RegionType & inputRegion, 116 const InputImageType* inputImage, 117 const OutputImageType* outputImage); 118 119 template<typename InputImageType, typename OutputImageType, typename TransformType> 120 static typename OutputImageType::RegionType 121 EnlargeRegionOverBox(const typename InputImageType::RegionType & inputRegion, 122 const InputImageType* inputImage, 123 const OutputImageType* outputImage, 124 const TransformType* transform); 125 126 private: 127 128 /** This is an optimized method which requires the input and 129 * output images to be the same, and the pixel being POD (Plain Old 130 * Data). 131 */ 132 template<typename InputImageType, typename OutputImageType> 133 static void DispatchedCopy( const InputImageType *inImage, OutputImageType *outImage, 134 const typename InputImageType::RegionType &inRegion, 135 const typename OutputImageType::RegionType &outRegion, TrueType isSpecialized ); 136 137 /** this is the reference image iterator implementation */ 138 template<typename InputImageType, typename OutputImageType> 139 static void DispatchedCopy( const InputImageType *inImage, OutputImageType *outImage, 140 const typename InputImageType::RegionType &inRegion, 141 const typename OutputImageType::RegionType &outRegion, FalseType isSpecialized = FalseType() ); 142 143 144 /** A utility class to get the number of internal pixels to make up 145 * a pixel. 146 */ 147 template <typename TImageType> 148 struct PixelSize 149 { GetImageAlgorithm::PixelSize150 static size_t Get( const TImageType *) 151 { 152 return 1; 153 } 154 }; 155 156 /// \cond HIDE_SPECIALIZATION_DOCUMENTATION 157 template <typename TPixelType, unsigned int VImageDimension> 158 struct PixelSize< VectorImage<TPixelType, VImageDimension> > 159 { 160 using ImageType = VectorImage<TPixelType, VImageDimension>; 161 static size_t Get( const ImageType * i ) 162 { 163 const size_t vectorLength = ImageType::AccessorFunctorType::GetVectorLength(i); 164 return vectorLength; 165 } 166 }; 167 /// \endcond 168 169 /** Unary functor just for static_cast operator */ 170 template<typename TInputType, typename TOutputType> 171 struct StaticCast 172 { 173 TOutputType operator() (const TInputType i) { return static_cast<TOutputType>(i); } 174 }; 175 176 177 /** Function to dispatch to std::copy or std::transform. */ 178 template<typename TType> 179 static TType* CopyHelper(const TType *first, const TType *last, TType *result) 180 { 181 // Note: On some MS compilers the following may generate a 182 // warning. Please include itkMacro.h before <algorithm> or 183 // another stl header to avoid. 184 return std::copy(first, last, result); 185 } 186 187 /// \cond HIDE_SPECIALIZATION_DOCUMENTATION 188 template<typename TInputType, typename TOutputType> 189 static TOutputType* CopyHelper(const TInputType *first, const TInputType *last, TOutputType *result) 190 { 191 return std::transform(first, last, result, StaticCast<TInputType,TOutputType>()); 192 } 193 /// \endcond 194 195 196 }; 197 } // end namespace itk 198 199 200 #ifndef ITK_MANUAL_INSTANTIATION 201 #include "itkImageAlgorithm.hxx" 202 #endif 203 204 205 #endif //itkImageAlgorithm_h 206