Medical Imaging Interaction Toolkit  2026.06.00
Medical Imaging Interaction Toolkit
mitkImageAccessByItk.h
Go to the documentation of this file.
1 /*============================================================================
2 
3 The Medical Imaging Interaction Toolkit (MITK)
4 
5 Copyright (c) German Cancer Research Center (DKFZ)
6 All rights reserved.
7 
8 Use of this source code is governed by a 3-clause BSD license that can be
9 found in the LICENSE file.
10 
11 ============================================================================*/
12 
33 #ifndef mitkImageAccessByItk_h
34 #define mitkImageAccessByItk_h
35 
36 #include <itkCastImageFilter.h>
37 #include <mitkImageToItk.h>
38 #include <mitkPPArgCount.h>
39 #include <boost/preprocessor/expand.hpp>
40 #include <boost/preprocessor/seq/for_each.hpp>
41 #include <boost/preprocessor/seq/for_each_product.hpp>
42 #include <boost/preprocessor/seq/to_tuple.hpp>
43 #include <boost/preprocessor/stringize.hpp>
44 #include <boost/preprocessor/tuple/rem.hpp>
45 
46 #include <sstream>
47 
48 namespace mitk
49 {
58  class AccessByItkException : public virtual std::runtime_error
59  {
60  public:
61  AccessByItkException(const std::string &msg) : std::runtime_error(msg) {}
62  ~AccessByItkException() throw() override {}
63  };
64 }
65 
66 #ifndef DOXYGEN_SKIP
67 
68 #define _accessByItkPixelTypeException(pixelType, pixelTypeSeq) \
69  { \
70  std::string msg("Pixel type "); \
71  msg.append(pixelType.GetPixelTypeAsString()); \
72  msg.append(" is not in " BOOST_PP_STRINGIZE(pixelTypeSeq)); \
73  throw mitk::AccessByItkException(msg); \
74  }
75 
76 #define _accessByItkDimensionException(dim, validDims) \
77  { \
78  std::stringstream msg; \
79  msg << "Dimension " << (dim) << " is not in " << validDims; \
80  throw mitk::AccessByItkException(msg.str()); \
81  }
82 
83 #define _checkSpecificDimensionIter(r, mitkImage, dim) \
84  if (mitkImage->GetDimension() == dim) \
85  ; \
86  else
87 
88 #define _checkSpecificDimension(mitkImage, dimSeq) \
89  BOOST_PP_SEQ_FOR_EACH(_checkSpecificDimensionIter, mitkImage, dimSeq) \
90  _accessByItkDimensionException(mitkImage->GetDimension(), BOOST_PP_STRINGIZE(dimSeq))
91 
92 #define _msvc_expand_bug(macro, arg) BOOST_PP_EXPAND(macro arg)
93 
94 //-------------------------------- 0-Arg Versions --------------------------------------
95 
96 #define _accessByItk(itkImageTypeFunctionAndImageSeq, pixeltype, dimension) \
97  if (pixelType == mitk::MakePixelType<pixeltype, dimension>(pixelType.GetNumberOfComponents()) && \
98  BOOST_PP_SEQ_TAIL(itkImageTypeFunctionAndImageSeq)->GetDimension() == dimension) \
99  { \
100  BOOST_PP_SEQ_HEAD(itkImageTypeFunctionAndImageSeq) \
101  (mitk::ImageToItkImage<pixeltype, dimension>(BOOST_PP_SEQ_TAIL(itkImageTypeFunctionAndImageSeq)).GetPointer()); \
102  } \
103  else
104 
105 #define _accessByItkArgs(itkImageTypeFunction, type) (itkImageTypeFunction, BOOST_PP_TUPLE_REM(2) type)
106 
107 // product will be of the form ((itkImageTypeFunction)(mitkImage))(short)(2) for pixel type short and dimension 2
108 #ifdef _MSC_VER
109 #define _accessByItkProductIter(r, product) \
110  _msvc_expand_bug( \
111  _accessByItk, \
112  _msvc_expand_bug(_accessByItkArgs, (BOOST_PP_SEQ_HEAD(product), BOOST_PP_SEQ_TO_TUPLE(BOOST_PP_SEQ_TAIL(product)))))
113 #else
114 #define _accessByItkProductIter(r, product) \
115  BOOST_PP_EXPAND( \
116  _accessByItk _accessByItkArgs(BOOST_PP_SEQ_HEAD(product), BOOST_PP_SEQ_TO_TUPLE(BOOST_PP_SEQ_TAIL(product))))
117 #endif
118 
119 #define _accessFixedTypeByItk(itkImageTypeFunction, mitkImage, pixelTypeSeq, dimSeq) \
120  BOOST_PP_SEQ_FOR_EACH_PRODUCT(_accessByItkProductIter, (((itkImageTypeFunction)(mitkImage)))(pixelTypeSeq)(dimSeq))
121 
122 //-------------------------------- n-Arg Versions --------------------------------------
123 
124 #define _accessByItk_n(itkImageTypeFunctionAndImageSeq, pixeltype, dimension, args) \
125  if (pixelType == mitk::MakePixelType<pixeltype, dimension>(pixelType.GetNumberOfComponents()) && \
126  BOOST_PP_SEQ_TAIL(itkImageTypeFunctionAndImageSeq)->GetDimension() == dimension) \
127  { \
128  BOOST_PP_SEQ_HEAD(itkImageTypeFunctionAndImageSeq) \
129  (mitk::ImageToItkImage<pixeltype, dimension>(BOOST_PP_SEQ_TAIL(itkImageTypeFunctionAndImageSeq)).GetPointer(), \
130  BOOST_PP_TUPLE_REM(BOOST_PP_SEQ_HEAD(args)) BOOST_PP_SEQ_TAIL(args)); \
131  } \
132  else
133 
134 #define _accessByItkArgs_n(itkImageTypeFunction, type, args) (itkImageTypeFunction, BOOST_PP_TUPLE_REM(2) type, args)
135 
136 // product will be of the form (((itkImageTypeFunction)(mitkImage))(3)(a,b,c))(short)(2)
137 // for the variable argument list a,b,c and for pixel type short and dimension 2
138 #ifdef _MSC_VER
139 #define _accessByItkProductIter_n(r, product) \
140  _msvc_expand_bug(_accessByItk_n, \
141  _msvc_expand_bug(_accessByItkArgs_n, \
142  (BOOST_PP_SEQ_HEAD(BOOST_PP_SEQ_HEAD(product)), \
143  BOOST_PP_SEQ_TO_TUPLE(BOOST_PP_SEQ_TAIL(product)), \
144  BOOST_PP_SEQ_TAIL(BOOST_PP_SEQ_HEAD(product)))))
145 #else
146 #define _accessByItkProductIter_n(r, product) \
147  BOOST_PP_EXPAND(_accessByItk_n _accessByItkArgs_n(BOOST_PP_SEQ_HEAD(BOOST_PP_SEQ_HEAD(product)), \
148  BOOST_PP_SEQ_TO_TUPLE(BOOST_PP_SEQ_TAIL(product)), \
149  BOOST_PP_SEQ_TAIL(BOOST_PP_SEQ_HEAD(product))))
150 #endif
151 
152 #define _accessFixedTypeByItk_n(itkImageTypeFunction, mitkImage, pixelTypeSeq, dimSeq, va_tuple) \
153  BOOST_PP_SEQ_FOR_EACH_PRODUCT( \
154  _accessByItkProductIter_n, \
155  ((((itkImageTypeFunction)(mitkImage))(MITK_PP_ARG_COUNT va_tuple)va_tuple))(pixelTypeSeq)(dimSeq))
156 
157 #endif // DOXYGEN_SKIP
158 
208 #define AccessByItk(mitkImage, itkImageTypeFunction) \
209  AccessFixedTypeByItk( \
210  mitkImage, itkImageTypeFunction, MITK_ACCESSBYITK_PIXEL_TYPES_SEQ, MITK_ACCESSBYITK_DIMENSIONS_SEQ)
211 
233 #define AccessFixedPixelTypeByItk(mitkImage, itkImageTypeFunction, pixelTypeSeq) \
234  AccessFixedTypeByItk(mitkImage, itkImageTypeFunction, pixelTypeSeq, MITK_ACCESSBYITK_DIMENSIONS_SEQ)
235 
250 #define AccessIntegralPixelTypeByItk(mitkImage, itkImageTypeFunction) \
251  AccessFixedTypeByItk( \
252  mitkImage, itkImageTypeFunction, MITK_ACCESSBYITK_INTEGRAL_PIXEL_TYPES_SEQ, MITK_ACCESSBYITK_DIMENSIONS_SEQ)
253 
268 #define AccessFloatingPixelTypeByItk(mitkImage, itkImageTypeFunction) \
269  AccessFixedTypeByItk( \
270  mitkImage, itkImageTypeFunction, MITK_ACCESSBYITK_FLOATING_PIXEL_TYPES_SEQ, MITK_ACCESSBYITK_DIMENSIONS_SEQ)
271 
288 #define AccessVectorPixelTypeByItk(mitkImage, itkImageTypeFunction) \
289  AccessFixedTypeByItk( \
290  mitkImage, itkImageTypeFunction, MITK_ACCESSBYITK_VECTOR_PIXEL_TYPES_SEQ, MITK_ACCESSBYITK_DIMENSIONS_SEQ)
291 
313 #define AccessFixedDimensionByItk(mitkImage, itkImageTypeFunction, dimension) \
314  AccessFixedTypeByItk(mitkImage, itkImageTypeFunction, MITK_ACCESSBYITK_PIXEL_TYPES_SEQ, (dimension))
315 
336 #define AccessVectorFixedDimensionByItk(mitkImage, itkImageTypeFunction, dimension) \
337  AccessFixedTypeByItk(mitkImage, itkImageTypeFunction, MITK_ACCESSBYITK_VECTOR_PIXEL_TYPES_SEQ, (dimension))
338 
370 #define AccessFixedTypeByItk(mitkImage, itkImageTypeFunction, pixelTypeSeq, dimSeq) \
371  \
372  { \
373  const mitk::PixelType &pixelType = mitkImage->GetPixelType(); \
374  _checkSpecificDimension(mitkImage, dimSeq); \
375  _accessFixedTypeByItk(itkImageTypeFunction, mitkImage, pixelTypeSeq, dimSeq) \
376  _accessByItkPixelTypeException(mitkImage->GetPixelType(), pixelTypeSeq) \
377  }
378 
379 //------------------------------ n-Arg Access Macros -----------------------------------
380 
428 #define AccessByItk_n(mitkImage, itkImageTypeFunction, va_tuple) \
429  AccessFixedTypeByItk_n( \
430  mitkImage, itkImageTypeFunction, MITK_ACCESSBYITK_PIXEL_TYPES_SEQ, MITK_ACCESSBYITK_DIMENSIONS_SEQ, va_tuple)
431 
456 #define AccessFixedPixelTypeByItk_n(mitkImage, itkImageTypeFunction, pixelTypeSeq, va_tuple) \
457  AccessFixedTypeByItk_n(mitkImage, itkImageTypeFunction, pixelTypeSeq, MITK_ACCESSBYITK_DIMENSIONS_SEQ, va_tuple)
458 
476 #define AccessIntegralPixelTypeByItk_n(mitkImage, itkImageTypeFunction, va_tuple) \
477  AccessFixedTypeByItk_n(mitkImage, \
478  itkImageTypeFunction, \
479  MITK_ACCESSBYITK_INTEGRAL_PIXEL_TYPES_SEQ, \
480  MITK_ACCESSBYITK_DIMENSIONS_SEQ, \
481  va_tuple)
482 
500 #define AccessFloatingPixelTypeByItk_n(mitkImage, itkImageTypeFunction, va_tuple) \
501  AccessFixedTypeByItk_n(mitkImage, \
502  itkImageTypeFunction, \
503  MITK_ACCESSBYITK_FLOATING_PIXEL_TYPES_SEQ, \
504  MITK_ACCESSBYITK_DIMENSIONS_SEQ, \
505  va_tuple)
506 
522 #define AccessVectorPixelTypeByItk_n(mitkImage, itkImageTypeFunction, va_tuple) \
523  AccessFixedTypeByItk_n(mitkImage, \
524  itkImageTypeFunction, \
525  MITK_ACCESSBYITK_VECTOR_PIXEL_TYPES_SEQ, \
526  MITK_ACCESSBYITK_DIMENSIONS_SEQ, \
527  va_tuple)
528 
553 #define AccessFixedDimensionByItk_n(mitkImage, itkImageTypeFunction, dimension, va_tuple) \
554  AccessFixedTypeByItk_n(mitkImage, itkImageTypeFunction, MITK_ACCESSBYITK_PIXEL_TYPES_SEQ, (dimension), va_tuple)
555 
579 #define AccessVectorFixedDimensionByItk_n(mitkImage, itkImageTypeFunction, dimension, va_tuple) \
580  AccessFixedTypeByItk_n( \
581  mitkImage, itkImageTypeFunction, MITK_ACCESSBYITK_VECTOR_PIXEL_TYPES_SEQ, (dimension), va_tuple)
582 
610 #define AccessFixedTypeByItk_n(mitkImage, itkImageTypeFunction, pixelTypeSeq, dimSeq, va_tuple) \
611  \
612  { \
613  const mitk::PixelType &pixelType = mitkImage->GetPixelType(); \
614  _checkSpecificDimension(mitkImage, dimSeq); \
615  _accessFixedTypeByItk_n(itkImageTypeFunction, mitkImage, pixelTypeSeq, dimSeq, va_tuple) \
616  _accessByItkPixelTypeException(mitkImage->GetPixelType(), pixelTypeSeq) \
617  }
618 
619 //------------------------- For back-wards compatibility -------------------------------
620 
621 #define AccessByItk_1(mitkImage, itkImageTypeFunction, arg1) AccessByItk_n(mitkImage, itkImageTypeFunction, (arg1))
622 #define AccessFixedPixelTypeByItk_1(mitkImage, itkImageTypeFunction, pixelTypeSeq, arg1) \
623  AccessFixedPixelTypeByItk_n(mitkImage, itkImageTypeFunction, pixelTypeSeq, (arg1))
624 #define AccessFixedDimensionByItk_1(mitkImage, itkImageTypeFunction, dimension, arg1) \
625  AccessFixedDimensionByItk_n(mitkImage, itkImageTypeFunction, dimension, (arg1))
626 #define AccessFixedTypeByItk_1(mitkImage, itkImageTypeFunction, pixelTypeSeq, dimSeq, arg1) \
627  AccessFixedTypeByItk_n(mitkImage, itkImageTypeFunction, pixelTypeSeq, dimSeq, (arg1))
628 
629 #define AccessByItk_2(mitkImage, itkImageTypeFunction, arg1, arg2) \
630  AccessByItk_n(mitkImage, itkImageTypeFunction, (arg1, arg2))
631 #define AccessFixedPixelTypeByItk_2(mitkImage, itkImageTypeFunction, pixelTypeSeq, arg1, arg2) \
632  AccessFixedPixelTypeByItk_n(mitkImage, itkImageTypeFunction, pixelTypeSeq, (arg1, arg2))
633 #define AccessFixedDimensionByItk_2(mitkImage, itkImageTypeFunction, dimension, arg1, arg2) \
634  AccessFixedDimensionByItk_n(mitkImage, itkImageTypeFunction, dimension, (arg1, arg2))
635 #define AccessFixedTypeByItk_2(mitkImage, itkImageTypeFunction, pixelTypeSeq, dimSeq, arg1, arg2) \
636  AccessFixedTypeByItk_n(mitkImage, itkImageTypeFunction, pixelTypeSeq, dimSeq, (arg1, arg2))
637 
638 #define AccessByItk_3(mitkImage, itkImageTypeFunction, arg1, arg2, arg3) \
639  AccessByItk_n(mitkImage, itkImageTypeFunction, (arg1, arg2, arg3))
640 #define AccessFixedPixelTypeByItk_3(mitkImage, itkImageTypeFunction, pixelTypeSeq, arg1, arg2, arg3) \
641  AccessFixedPixelTypeByItk_n(mitkImage, itkImageTypeFunction, pixelTypeSeq, (arg1, arg2, arg3))
642 #define AccessFixedDimensionByItk_3(mitkImage, itkImageTypeFunction, dimension, arg1, arg2, arg3) \
643  AccessFixedDimensionByItk_n(mitkImage, itkImageTypeFunction, dimension, (arg1, arg2, arg3))
644 #define AccessFixedTypeByItk_3(mitkImage, itkImageTypeFunction, pixelTypeSeq, dimSeq, arg1, arg2, arg3) \
645  AccessFixedTypeByItk_n(mitkImage, itkImageTypeFunction, pixelTypeSeq, dimSeq, (arg1, arg2, arg3))
646 
647 //----------------------------- Access two MITK Images ---------------------------------
648 
649 #ifndef DOXYGEN_SKIP
650 
651 #define _accessTwoImagesByItk(itkImageTypeFunction, pixeltype1, dim1, pixeltype2, dim2) \
652  if (pixelType1 == mitk::MakePixelType<itk::Image<pixeltype1, dim1>>() && \
653  pixelType2 == mitk::MakePixelType<itk::Image<pixeltype2, dim2>>() && constImage1->GetDimension() == dim1 && \
654  constImage2->GetDimension() == dim2) \
655  { \
656  typedef itk::Image<pixeltype1, dim1> ImageType1; \
657  typedef itk::Image<pixeltype2, dim2> ImageType2; \
658  typedef mitk::ImageToItk<ImageType1> ImageToItkType1; \
659  typedef mitk::ImageToItk<ImageType2> ImageToItkType2; \
660  itk::SmartPointer<ImageToItkType1> imagetoitk1 = ImageToItkType1::New(); \
661  imagetoitk1->SetInput(nonConstImage1); \
662  imagetoitk1->Update(); \
663  itk::SmartPointer<ImageToItkType2> imagetoitk2 = ImageToItkType2::New(); \
664  imagetoitk2->SetInput(nonConstImage2); \
665  imagetoitk2->Update(); \
666  itkImageTypeFunction(imagetoitk1->GetOutput(), imagetoitk2->GetOutput()); \
667  } \
668  else
669 
670 #define _accessTwoImagesByItkArgs2(itkImageTypeFunction, type1, type2) \
671  (itkImageTypeFunction, BOOST_PP_TUPLE_REM(2) type1, BOOST_PP_TUPLE_REM(2) type2)
672 
673 #define _accessTwoImagesByItkArgs(product) \
674  BOOST_PP_EXPAND(_accessTwoImagesByItkArgs2 BOOST_PP_EXPAND( \
675  (BOOST_PP_SEQ_HEAD(product), BOOST_PP_TUPLE_REM(2) BOOST_PP_SEQ_TO_TUPLE(BOOST_PP_SEQ_TAIL(product)))))
676 
677 // product is of the form (itkImageTypeFunction)((short,2))((char,2))
678 #ifdef _MSC_VER
679 #define _accessTwoImagesByItkIter(r, product) \
680  BOOST_PP_EXPAND(_accessTwoImagesByItk _msvc_expand_bug( \
681  _accessTwoImagesByItkArgs2, \
682  (BOOST_PP_SEQ_HEAD(product), \
683  _msvc_expand_bug(BOOST_PP_TUPLE_REM(2), BOOST_PP_EXPAND(BOOST_PP_SEQ_TO_TUPLE(BOOST_PP_SEQ_TAIL(product)))))))
684 #else
685 #define _accessTwoImagesByItkIter(r, product) BOOST_PP_EXPAND(_accessTwoImagesByItk _accessTwoImagesByItkArgs(product))
686 #endif
687 
688 #define _accessTwoImagesByItkForEach(itkImageTypeFunction, tseq1, tseq2) \
689  BOOST_PP_SEQ_FOR_EACH_PRODUCT(_accessTwoImagesByItkIter, ((itkImageTypeFunction))(tseq1)(tseq2))
690 
691 #endif // DOXYGEN_SKIP
692 
737 #define AccessTwoImagesFixedDimensionByItk(mitkImage1, mitkImage2, itkImageTypeFunction, dimension) \
738  \
739  { \
740  const mitk::PixelType &pixelType1 = mitkImage1->GetPixelType(); \
741  const mitk::PixelType &pixelType2 = mitkImage2->GetPixelType(); \
742  const mitk::Image *constImage1 = mitkImage1; \
743  const mitk::Image *constImage2 = mitkImage2; \
744  mitk::Image *nonConstImage1 = const_cast<mitk::Image *>(constImage1); \
745  mitk::Image *nonConstImage2 = const_cast<mitk::Image *>(constImage2); \
746  nonConstImage1->Update(); \
747  nonConstImage2->Update(); \
748  _checkSpecificDimension(mitkImage1, (dimension)); \
749  _checkSpecificDimension(mitkImage2, (dimension)); \
750  _accessTwoImagesByItkForEach( \
751  itkImageTypeFunction, MITK_ACCESSBYITK_TYPES_DIMN_SEQ(dimension), MITK_ACCESSBYITK_TYPES_DIMN_SEQ(dimension)) \
752  { \
753  std::string msg("Pixel type "); \
754  msg.append(pixelType1.GetComponentTypeAsString()); \
755  msg.append(" or pixel type "); \
756  msg.append(pixelType2.GetComponentTypeAsString()); \
757  msg.append(" is not in " BOOST_PP_STRINGIZE(MITK_ACCESSBYITK_TYPES_DIMN_SEQ(dimension))); \
758  throw mitk::AccessByItkException(msg); \
759  } \
760  }
761 
762 #endif
Exception class thrown in AccessByItk macros.
AccessByItkException(const std::string &msg)
Preprocessor utility macros for counting the number of variadic macro arguments at compile time.
Find image slices visible on a given plane.