Medical Imaging Interaction Toolkit  2024.06.00
Medical Imaging Interaction Toolkit
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Modules Pages
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 
13 #ifndef mitkImageAccessByItk_h
14 #define mitkImageAccessByItk_h
15 
16 #include <itkCastImageFilter.h>
17 #include <mitkImageToItk.h>
18 #include <mitkPPArgCount.h>
19 #include <boost/preprocessor/expand.hpp>
20 #include <boost/preprocessor/seq/for_each.hpp>
21 #include <boost/preprocessor/seq/for_each_product.hpp>
22 #include <boost/preprocessor/seq/to_tuple.hpp>
23 #include <boost/preprocessor/stringize.hpp>
24 #include <boost/preprocessor/tuple/rem.hpp>
25 
26 #include <sstream>
27 
28 namespace mitk
29 {
38  class AccessByItkException : public virtual std::runtime_error
39  {
40  public:
41  AccessByItkException(const std::string &msg) : std::runtime_error(msg) {}
42  ~AccessByItkException() throw() override {}
43  };
44 }
45 
46 #ifndef DOXYGEN_SKIP
47 
48 #define _accessByItkPixelTypeException(pixelType, pixelTypeSeq) \
49  { \
50  std::string msg("Pixel type "); \
51  msg.append(pixelType.GetPixelTypeAsString()); \
52  msg.append(" is not in " BOOST_PP_STRINGIZE(pixelTypeSeq)); \
53  throw mitk::AccessByItkException(msg); \
54  }
55 
56 #define _accessByItkDimensionException(dim, validDims) \
57  { \
58  std::stringstream msg; \
59  msg << "Dimension " << (dim) << " is not in " << validDims; \
60  throw mitk::AccessByItkException(msg.str()); \
61  }
62 
63 #define _checkSpecificDimensionIter(r, mitkImage, dim) \
64  if (mitkImage->GetDimension() == dim) \
65  ; \
66  else
67 
68 #define _checkSpecificDimension(mitkImage, dimSeq) \
69  BOOST_PP_SEQ_FOR_EACH(_checkSpecificDimensionIter, mitkImage, dimSeq) \
70  _accessByItkDimensionException(mitkImage->GetDimension(), BOOST_PP_STRINGIZE(dimSeq))
71 
72 #define _msvc_expand_bug(macro, arg) BOOST_PP_EXPAND(macro arg)
73 
74 //-------------------------------- 0-Arg Versions --------------------------------------
75 
76 #define _accessByItk(itkImageTypeFunctionAndImageSeq, pixeltype, dimension) \
77  if (pixelType == mitk::MakePixelType<pixeltype, dimension>(pixelType.GetNumberOfComponents()) && \
78  BOOST_PP_SEQ_TAIL(itkImageTypeFunctionAndImageSeq)->GetDimension() == dimension) \
79  { \
80  BOOST_PP_SEQ_HEAD(itkImageTypeFunctionAndImageSeq) \
81  (mitk::ImageToItkImage<pixeltype, dimension>(BOOST_PP_SEQ_TAIL(itkImageTypeFunctionAndImageSeq)).GetPointer()); \
82  } \
83  else
84 
85 #define _accessByItkArgs(itkImageTypeFunction, type) (itkImageTypeFunction, BOOST_PP_TUPLE_REM(2) type)
86 
87 // product will be of the form ((itkImageTypeFunction)(mitkImage))(short)(2) for pixel type short and dimension 2
88 #ifdef _MSC_VER
89 #define _accessByItkProductIter(r, product) \
90  _msvc_expand_bug( \
91  _accessByItk, \
92  _msvc_expand_bug(_accessByItkArgs, (BOOST_PP_SEQ_HEAD(product), BOOST_PP_SEQ_TO_TUPLE(BOOST_PP_SEQ_TAIL(product)))))
93 #else
94 #define _accessByItkProductIter(r, product) \
95  BOOST_PP_EXPAND( \
96  _accessByItk _accessByItkArgs(BOOST_PP_SEQ_HEAD(product), BOOST_PP_SEQ_TO_TUPLE(BOOST_PP_SEQ_TAIL(product))))
97 #endif
98 
99 #define _accessFixedTypeByItk(itkImageTypeFunction, mitkImage, pixelTypeSeq, dimSeq) \
100  BOOST_PP_SEQ_FOR_EACH_PRODUCT(_accessByItkProductIter, (((itkImageTypeFunction)(mitkImage)))(pixelTypeSeq)(dimSeq))
101 
102 //-------------------------------- n-Arg Versions --------------------------------------
103 
104 #define _accessByItk_n(itkImageTypeFunctionAndImageSeq, pixeltype, dimension, args) \
105  if (pixelType == mitk::MakePixelType<pixeltype, dimension>(pixelType.GetNumberOfComponents()) && \
106  BOOST_PP_SEQ_TAIL(itkImageTypeFunctionAndImageSeq)->GetDimension() == dimension) \
107  { \
108  BOOST_PP_SEQ_HEAD(itkImageTypeFunctionAndImageSeq) \
109  (mitk::ImageToItkImage<pixeltype, dimension>(BOOST_PP_SEQ_TAIL(itkImageTypeFunctionAndImageSeq)).GetPointer(), \
110  BOOST_PP_TUPLE_REM(BOOST_PP_SEQ_HEAD(args)) BOOST_PP_SEQ_TAIL(args)); \
111  } \
112  else
113 
114 #define _accessByItkArgs_n(itkImageTypeFunction, type, args) (itkImageTypeFunction, BOOST_PP_TUPLE_REM(2) type, args)
115 
116 // product will be of the form (((itkImageTypeFunction)(mitkImage))(3)(a,b,c))(short)(2)
117 // for the variable argument list a,b,c and for pixel type short and dimension 2
118 #ifdef _MSC_VER
119 #define _accessByItkProductIter_n(r, product) \
120  _msvc_expand_bug(_accessByItk_n, \
121  _msvc_expand_bug(_accessByItkArgs_n, \
122  (BOOST_PP_SEQ_HEAD(BOOST_PP_SEQ_HEAD(product)), \
123  BOOST_PP_SEQ_TO_TUPLE(BOOST_PP_SEQ_TAIL(product)), \
124  BOOST_PP_SEQ_TAIL(BOOST_PP_SEQ_HEAD(product)))))
125 #else
126 #define _accessByItkProductIter_n(r, product) \
127  BOOST_PP_EXPAND(_accessByItk_n _accessByItkArgs_n(BOOST_PP_SEQ_HEAD(BOOST_PP_SEQ_HEAD(product)), \
128  BOOST_PP_SEQ_TO_TUPLE(BOOST_PP_SEQ_TAIL(product)), \
129  BOOST_PP_SEQ_TAIL(BOOST_PP_SEQ_HEAD(product))))
130 #endif
131 
132 #define _accessFixedTypeByItk_n(itkImageTypeFunction, mitkImage, pixelTypeSeq, dimSeq, va_tuple) \
133  BOOST_PP_SEQ_FOR_EACH_PRODUCT( \
134  _accessByItkProductIter_n, \
135  ((((itkImageTypeFunction)(mitkImage))(MITK_PP_ARG_COUNT va_tuple)va_tuple))(pixelTypeSeq)(dimSeq))
136 
137 #endif // DOXYGEN_SKIP
138 
188 #define AccessByItk(mitkImage, itkImageTypeFunction) \
189  AccessFixedTypeByItk( \
190  mitkImage, itkImageTypeFunction, MITK_ACCESSBYITK_PIXEL_TYPES_SEQ, MITK_ACCESSBYITK_DIMENSIONS_SEQ)
191 
213 #define AccessFixedPixelTypeByItk(mitkImage, itkImageTypeFunction, pixelTypeSeq) \
214  AccessFixedTypeByItk(mitkImage, itkImageTypeFunction, pixelTypeSeq, MITK_ACCESSBYITK_DIMENSIONS_SEQ)
215 
230 #define AccessIntegralPixelTypeByItk(mitkImage, itkImageTypeFunction) \
231  AccessFixedTypeByItk( \
232  mitkImage, itkImageTypeFunction, MITK_ACCESSBYITK_INTEGRAL_PIXEL_TYPES_SEQ, MITK_ACCESSBYITK_DIMENSIONS_SEQ)
233 
248 #define AccessFloatingPixelTypeByItk(mitkImage, itkImageTypeFunction) \
249  AccessFixedTypeByItk( \
250  mitkImage, itkImageTypeFunction, MITK_ACCESSBYITK_FLOATING_PIXEL_TYPES_SEQ, MITK_ACCESSBYITK_DIMENSIONS_SEQ)
251 
252 #define AccessVectorPixelTypeByItk(mitkImage, itkImageTypeFunction) \
253  AccessFixedTypeByItk( \
254  mitkImage, itkImageTypeFunction, MITK_ACCESSBYITK_VECTOR_PIXEL_TYPES_SEQ, MITK_ACCESSBYITK_DIMENSIONS_SEQ)
255 
277 #define AccessFixedDimensionByItk(mitkImage, itkImageTypeFunction, dimension) \
278  AccessFixedTypeByItk(mitkImage, itkImageTypeFunction, MITK_ACCESSBYITK_PIXEL_TYPES_SEQ, (dimension))
279 
280 #define AccessVectorFixedDimensionByItk(mitkImage, itkImageTypeFunction, dimension) \
281  AccessFixedTypeByItk(mitkImage, itkImageTypeFunction, MITK_ACCESSBYITK_VECTOR_PIXEL_TYPES_SEQ, (dimension))
282 
314 #define AccessFixedTypeByItk(mitkImage, itkImageTypeFunction, pixelTypeSeq, dimSeq) \
315  \
316  { \
317  const mitk::PixelType &pixelType = mitkImage->GetPixelType(); \
318  _checkSpecificDimension(mitkImage, dimSeq); \
319  _accessFixedTypeByItk(itkImageTypeFunction, mitkImage, pixelTypeSeq, dimSeq) \
320  _accessByItkPixelTypeException(mitkImage->GetPixelType(), pixelTypeSeq) \
321  }
322 
323 //------------------------------ n-Arg Access Macros -----------------------------------
324 
372 #define AccessByItk_n(mitkImage, itkImageTypeFunction, va_tuple) \
373  AccessFixedTypeByItk_n( \
374  mitkImage, itkImageTypeFunction, MITK_ACCESSBYITK_PIXEL_TYPES_SEQ, MITK_ACCESSBYITK_DIMENSIONS_SEQ, va_tuple)
375 
400 #define AccessFixedPixelTypeByItk_n(mitkImage, itkImageTypeFunction, pixelTypeSeq, va_tuple) \
401  AccessFixedTypeByItk_n(mitkImage, itkImageTypeFunction, pixelTypeSeq, MITK_ACCESSBYITK_DIMENSIONS_SEQ, va_tuple)
402 
420 #define AccessIntegralPixelTypeByItk_n(mitkImage, itkImageTypeFunction, va_tuple) \
421  AccessFixedTypeByItk_n(mitkImage, \
422  itkImageTypeFunction, \
423  MITK_ACCESSBYITK_INTEGRAL_PIXEL_TYPES_SEQ, \
424  MITK_ACCESSBYITK_DIMENSIONS_SEQ, \
425  va_tuple)
426 
444 #define AccessFloatingPixelTypeByItk_n(mitkImage, itkImageTypeFunction, va_tuple) \
445  AccessFixedTypeByItk_n(mitkImage, \
446  itkImageTypeFunction, \
447  MITK_ACCESSBYITK_FLOATING_PIXEL_TYPES_SEQ, \
448  MITK_ACCESSBYITK_DIMENSIONS_SEQ, \
449  va_tuple)
450 
466 #define AccessVectorPixelTypeByItk_n(mitkImage, itkImageTypeFunction, va_tuple) \
467  AccessFixedTypeByItk_n(mitkImage, \
468  itkImageTypeFunction, \
469  MITK_ACCESSBYITK_VECTOR_PIXEL_TYPES_SEQ, \
470  MITK_ACCESSBYITK_DIMENSIONS_SEQ, \
471  va_tuple)
472 
497 #define AccessFixedDimensionByItk_n(mitkImage, itkImageTypeFunction, dimension, va_tuple) \
498  AccessFixedTypeByItk_n(mitkImage, itkImageTypeFunction, MITK_ACCESSBYITK_PIXEL_TYPES_SEQ, (dimension), va_tuple)
499 
523 #define AccessVectorFixedDimensionByItk_n(mitkImage, itkImageTypeFunction, dimension, va_tuple) \
524  AccessFixedTypeByItk_n( \
525  mitkImage, itkImageTypeFunction, MITK_ACCESSBYITK_VECTOR_PIXEL_TYPES_SEQ, (dimension), va_tuple)
526 
554 #define AccessFixedTypeByItk_n(mitkImage, itkImageTypeFunction, pixelTypeSeq, dimSeq, va_tuple) \
555  \
556  { \
557  const mitk::PixelType &pixelType = mitkImage->GetPixelType(); \
558  _checkSpecificDimension(mitkImage, dimSeq); \
559  _accessFixedTypeByItk_n(itkImageTypeFunction, mitkImage, pixelTypeSeq, dimSeq, va_tuple) \
560  _accessByItkPixelTypeException(mitkImage->GetPixelType(), pixelTypeSeq) \
561  }
562 
563 //------------------------- For back-wards compatibility -------------------------------
564 
565 #define AccessByItk_1(mitkImage, itkImageTypeFunction, arg1) AccessByItk_n(mitkImage, itkImageTypeFunction, (arg1))
566 #define AccessFixedPixelTypeByItk_1(mitkImage, itkImageTypeFunction, pixelTypeSeq, arg1) \
567  AccessFixedPixelTypeByItk_n(mitkImage, itkImageTypeFunction, pixelTypeSeq, (arg1))
568 #define AccessFixedDimensionByItk_1(mitkImage, itkImageTypeFunction, dimension, arg1) \
569  AccessFixedDimensionByItk_n(mitkImage, itkImageTypeFunction, dimension, (arg1))
570 #define AccessFixedTypeByItk_1(mitkImage, itkImageTypeFunction, pixelTypeSeq, dimSeq, arg1) \
571  AccessFixedTypeByItk_n(mitkImage, itkImageTypeFunction, pixelTypeSeq, dimSeq, (arg1))
572 
573 #define AccessByItk_2(mitkImage, itkImageTypeFunction, arg1, arg2) \
574  AccessByItk_n(mitkImage, itkImageTypeFunction, (arg1, arg2))
575 #define AccessFixedPixelTypeByItk_2(mitkImage, itkImageTypeFunction, pixelTypeSeq, arg1, arg2) \
576  AccessFixedPixelTypeByItk_n(mitkImage, itkImageTypeFunction, pixelTypeSeq, (arg1, arg2))
577 #define AccessFixedDimensionByItk_2(mitkImage, itkImageTypeFunction, dimension, arg1, arg2) \
578  AccessFixedDimensionByItk_n(mitkImage, itkImageTypeFunction, dimension, (arg1, arg2))
579 #define AccessFixedTypeByItk_2(mitkImage, itkImageTypeFunction, pixelTypeSeq, dimSeq, arg1, arg2) \
580  AccessFixedTypeByItk_n(mitkImage, itkImageTypeFunction, pixelTypeSeq, dimSeq, (arg1, arg2))
581 
582 #define AccessByItk_3(mitkImage, itkImageTypeFunction, arg1, arg2, arg3) \
583  AccessByItk_n(mitkImage, itkImageTypeFunction, (arg1, arg2, arg3))
584 #define AccessFixedPixelTypeByItk_3(mitkImage, itkImageTypeFunction, pixelTypeSeq, arg1, arg2, arg3) \
585  AccessFixedPixelTypeByItk_n(mitkImage, itkImageTypeFunction, pixelTypeSeq, (arg1, arg2, arg3))
586 #define AccessFixedDimensionByItk_3(mitkImage, itkImageTypeFunction, dimension, arg1, arg2, arg3) \
587  AccessFixedDimensionByItk_n(mitkImage, itkImageTypeFunction, dimension, (arg1, arg2, arg3))
588 #define AccessFixedTypeByItk_3(mitkImage, itkImageTypeFunction, pixelTypeSeq, dimSeq, arg1, arg2, arg3) \
589  AccessFixedTypeByItk_n(mitkImage, itkImageTypeFunction, pixelTypeSeq, dimSeq, (arg1, arg2, arg3))
590 
591 //----------------------------- Access two MITK Images ---------------------------------
592 
593 #ifndef DOXYGEN_SKIP
594 
595 #define _accessTwoImagesByItk(itkImageTypeFunction, pixeltype1, dim1, pixeltype2, dim2) \
596  if (pixelType1 == mitk::MakePixelType<itk::Image<pixeltype1, dim1>>() && \
597  pixelType2 == mitk::MakePixelType<itk::Image<pixeltype2, dim2>>() && constImage1->GetDimension() == dim1 && \
598  constImage2->GetDimension() == dim2) \
599  { \
600  typedef itk::Image<pixeltype1, dim1> ImageType1; \
601  typedef itk::Image<pixeltype2, dim2> ImageType2; \
602  typedef mitk::ImageToItk<ImageType1> ImageToItkType1; \
603  typedef mitk::ImageToItk<ImageType2> ImageToItkType2; \
604  itk::SmartPointer<ImageToItkType1> imagetoitk1 = ImageToItkType1::New(); \
605  imagetoitk1->SetInput(nonConstImage1); \
606  imagetoitk1->Update(); \
607  itk::SmartPointer<ImageToItkType2> imagetoitk2 = ImageToItkType2::New(); \
608  imagetoitk2->SetInput(nonConstImage2); \
609  imagetoitk2->Update(); \
610  itkImageTypeFunction(imagetoitk1->GetOutput(), imagetoitk2->GetOutput()); \
611  } \
612  else
613 
614 #define _accessTwoImagesByItkArgs2(itkImageTypeFunction, type1, type2) \
615  (itkImageTypeFunction, BOOST_PP_TUPLE_REM(2) type1, BOOST_PP_TUPLE_REM(2) type2)
616 
617 #define _accessTwoImagesByItkArgs(product) \
618  BOOST_PP_EXPAND(_accessTwoImagesByItkArgs2 BOOST_PP_EXPAND( \
619  (BOOST_PP_SEQ_HEAD(product), BOOST_PP_TUPLE_REM(2) BOOST_PP_SEQ_TO_TUPLE(BOOST_PP_SEQ_TAIL(product)))))
620 
621 // product is of the form (itkImageTypeFunction)((short,2))((char,2))
622 #ifdef _MSC_VER
623 #define _accessTwoImagesByItkIter(r, product) \
624  BOOST_PP_EXPAND(_accessTwoImagesByItk _msvc_expand_bug( \
625  _accessTwoImagesByItkArgs2, \
626  (BOOST_PP_SEQ_HEAD(product), \
627  _msvc_expand_bug(BOOST_PP_TUPLE_REM(2), BOOST_PP_EXPAND(BOOST_PP_SEQ_TO_TUPLE(BOOST_PP_SEQ_TAIL(product)))))))
628 #else
629 #define _accessTwoImagesByItkIter(r, product) BOOST_PP_EXPAND(_accessTwoImagesByItk _accessTwoImagesByItkArgs(product))
630 #endif
631 
632 #define _accessTwoImagesByItkForEach(itkImageTypeFunction, tseq1, tseq2) \
633  BOOST_PP_SEQ_FOR_EACH_PRODUCT(_accessTwoImagesByItkIter, ((itkImageTypeFunction))(tseq1)(tseq2))
634 
635 #endif // DOXYGEN_SKIP
636 
681 #define AccessTwoImagesFixedDimensionByItk(mitkImage1, mitkImage2, itkImageTypeFunction, dimension) \
682  \
683  { \
684  const mitk::PixelType &pixelType1 = mitkImage1->GetPixelType(); \
685  const mitk::PixelType &pixelType2 = mitkImage2->GetPixelType(); \
686  const mitk::Image *constImage1 = mitkImage1; \
687  const mitk::Image *constImage2 = mitkImage2; \
688  mitk::Image *nonConstImage1 = const_cast<mitk::Image *>(constImage1); \
689  mitk::Image *nonConstImage2 = const_cast<mitk::Image *>(constImage2); \
690  nonConstImage1->Update(); \
691  nonConstImage2->Update(); \
692  _checkSpecificDimension(mitkImage1, (dimension)); \
693  _checkSpecificDimension(mitkImage2, (dimension)); \
694  _accessTwoImagesByItkForEach( \
695  itkImageTypeFunction, MITK_ACCESSBYITK_TYPES_DIMN_SEQ(dimension), MITK_ACCESSBYITK_TYPES_DIMN_SEQ(dimension)) \
696  { \
697  std::string msg("Pixel type "); \
698  msg.append(pixelType1.GetComponentTypeAsString()); \
699  msg.append(" or pixel type "); \
700  msg.append(pixelType2.GetComponentTypeAsString()); \
701  msg.append(" is not in " BOOST_PP_STRINGIZE(MITK_ACCESSBYITK_TYPES_DIMN_SEQ(dimension))); \
702  throw mitk::AccessByItkException(msg); \
703  } \
704  }
705 
706 #endif
mitkPPArgCount.h
mitk
Find image slices visible on a given plane.
Definition: RenderingTests.dox:1
mitk::AccessByItkException::~AccessByItkException
~AccessByItkException() override
Definition: mitkImageAccessByItk.h:42
mitkImageToItk.h
mitk::AccessByItkException
Exception class thrown in AccessByItk macros.
Definition: mitkImageAccessByItk.h:38
mitk::AccessByItkException::AccessByItkException
AccessByItkException(const std::string &msg)
Definition: mitkImageAccessByItk.h:41