Medical Imaging Interaction Toolkit  2016.11.0
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,
6 Division of Medical and Biological Informatics.
7 All rights reserved.
8 
9 This software is distributed WITHOUT ANY WARRANTY; without
10 even the implied warranty of MERCHANTABILITY or FITNESS FOR
11 A PARTICULAR PURPOSE.
12 
13 See LICENSE.txt or http://www.mitk.org for details.
14 
15 ===================================================================*/
16 
17 #ifndef MITKIMAGEACCESSBYITK_H_HEADER_INCLUDED
18 #define MITKIMAGEACCESSBYITK_H_HEADER_INCLUDED
19 
20 #include <itkCastImageFilter.h>
21 #include <mitkImageToItk.h>
22 
23 #include <mitkPPArgCount.h>
24 #include <mitkPPCat.h>
25 #include <mitkPPExpand.h>
26 #include <mitkPPSeqForEach.h>
28 #include <mitkPPSeqToTuple.h>
29 #include <mitkPPStringize.h>
30 #include <mitkPPTupleRem.h>
31 
32 #include <sstream>
33 
34 namespace mitk
35 {
44  class AccessByItkException : public virtual std::runtime_error
45  {
46  public:
47  AccessByItkException(const std::string &msg) : std::runtime_error(msg) {}
48  ~AccessByItkException() throw() {}
49  };
50 }
51 
52 #ifndef DOXYGEN_SKIP
53 
54 #define _accessByItkPixelTypeException(pixelType, pixelTypeSeq) \
55  { \
56  std::string msg("Pixel type "); \
57  msg.append(pixelType.GetPixelTypeAsString()); \
58  msg.append(" is not in " MITK_PP_STRINGIZE(pixelTypeSeq)); \
59  throw mitk::AccessByItkException(msg); \
60  }
61 
62 #define _accessByItkDimensionException(dim, validDims) \
63  { \
64  std::stringstream msg; \
65  msg << "Dimension " << (dim) << " is not in " << validDims; \
66  throw mitk::AccessByItkException(msg.str()); \
67  }
68 
69 #define _checkSpecificDimensionIter(r, mitkImage, dim) \
70  if (mitkImage->GetDimension() == dim) \
71  ; \
72  else
73 
74 #define _checkSpecificDimension(mitkImage, dimSeq) \
75  MITK_PP_SEQ_FOR_EACH(_checkSpecificDimensionIter, mitkImage, dimSeq) \
76  _accessByItkDimensionException(mitkImage->GetDimension(), MITK_PP_STRINGIZE(dimSeq))
77 
78 #define _msvc_expand_bug(macro, arg) MITK_PP_EXPAND(macro arg)
79 
80 //-------------------------------- 0-Arg Versions --------------------------------------
81 
82 #define _accessByItk(itkImageTypeFunctionAndImageSeq, pixeltype, dimension) \
83  if (pixelType == mitk::MakePixelType<pixeltype, dimension>(pixelType.GetNumberOfComponents()) && \
84  MITK_PP_SEQ_TAIL(itkImageTypeFunctionAndImageSeq)->GetDimension() == dimension) \
85  { \
86  MITK_PP_SEQ_HEAD(itkImageTypeFunctionAndImageSeq) \
87  (mitk::ImageToItkImage<pixeltype, dimension>(MITK_PP_SEQ_TAIL(itkImageTypeFunctionAndImageSeq)).GetPointer()); \
88  } \
89  else
90 
91 #define _accessByItkArgs(itkImageTypeFunction, type) (itkImageTypeFunction, MITK_PP_TUPLE_REM(2) type)
92 
93 // product will be of the form ((itkImageTypeFunction)(mitkImage))(short)(2) for pixel type short and dimension 2
94 #ifdef _MSC_VER
95 #define _accessByItkProductIter(r, product) \
96  _msvc_expand_bug( \
97  _accessByItk, \
98  _msvc_expand_bug(_accessByItkArgs, (MITK_PP_SEQ_HEAD(product), MITK_PP_SEQ_TO_TUPLE(MITK_PP_SEQ_TAIL(product)))))
99 #else
100 #define _accessByItkProductIter(r, product) \
101  MITK_PP_EXPAND( \
102  _accessByItk _accessByItkArgs(MITK_PP_SEQ_HEAD(product), MITK_PP_SEQ_TO_TUPLE(MITK_PP_SEQ_TAIL(product))))
103 #endif
104 
105 #define _accessFixedTypeByItk(itkImageTypeFunction, mitkImage, pixelTypeSeq, dimSeq) \
106  MITK_PP_SEQ_FOR_EACH_PRODUCT(_accessByItkProductIter, (((itkImageTypeFunction)(mitkImage)))(pixelTypeSeq)(dimSeq))
107 
108 //-------------------------------- n-Arg Versions --------------------------------------
109 
110 #define _accessByItk_n(itkImageTypeFunctionAndImageSeq, pixeltype, dimension, args) \
111  if (pixelType == mitk::MakePixelType<pixeltype, dimension>(pixelType.GetNumberOfComponents()) && \
112  MITK_PP_SEQ_TAIL(itkImageTypeFunctionAndImageSeq)->GetDimension() == dimension) \
113  { \
114  MITK_PP_SEQ_HEAD(itkImageTypeFunctionAndImageSeq) \
115  (mitk::ImageToItkImage<pixeltype, dimension>(MITK_PP_SEQ_TAIL(itkImageTypeFunctionAndImageSeq)).GetPointer(), \
116  MITK_PP_TUPLE_REM(MITK_PP_SEQ_HEAD(args)) MITK_PP_SEQ_TAIL(args)); \
117  } \
118  else
119 
120 #define _accessByItkArgs_n(itkImageTypeFunction, type, args) (itkImageTypeFunction, MITK_PP_TUPLE_REM(2) type, args)
121 
122 // product will be of the form (((itkImageTypeFunction)(mitkImage))(3)(a,b,c))(short)(2)
123 // for the variable argument list a,b,c and for pixel type short and dimension 2
124 #ifdef _MSC_VER
125 #define _accessByItkProductIter_n(r, product) \
126  _msvc_expand_bug(_accessByItk_n, \
127  _msvc_expand_bug(_accessByItkArgs_n, \
128  (MITK_PP_SEQ_HEAD(MITK_PP_SEQ_HEAD(product)), \
129  MITK_PP_SEQ_TO_TUPLE(MITK_PP_SEQ_TAIL(product)), \
130  MITK_PP_SEQ_TAIL(MITK_PP_SEQ_HEAD(product)))))
131 #else
132 #define _accessByItkProductIter_n(r, product) \
133  MITK_PP_EXPAND(_accessByItk_n _accessByItkArgs_n(MITK_PP_SEQ_HEAD(MITK_PP_SEQ_HEAD(product)), \
134  MITK_PP_SEQ_TO_TUPLE(MITK_PP_SEQ_TAIL(product)), \
135  MITK_PP_SEQ_TAIL(MITK_PP_SEQ_HEAD(product))))
136 #endif
137 
138 #define _accessFixedTypeByItk_n(itkImageTypeFunction, mitkImage, pixelTypeSeq, dimSeq, va_tuple) \
139  MITK_PP_SEQ_FOR_EACH_PRODUCT( \
140  _accessByItkProductIter_n, \
141  ((((itkImageTypeFunction)(mitkImage))(MITK_PP_ARG_COUNT va_tuple)va_tuple))(pixelTypeSeq)(dimSeq))
142 
143 #endif // DOXYGEN_SKIP
144 
194 #define AccessByItk(mitkImage, itkImageTypeFunction) \
195  AccessFixedTypeByItk( \
196  mitkImage, itkImageTypeFunction, MITK_ACCESSBYITK_PIXEL_TYPES_SEQ, MITK_ACCESSBYITK_DIMENSIONS_SEQ)
197 
219 #define AccessFixedPixelTypeByItk(mitkImage, itkImageTypeFunction, pixelTypeSeq) \
220  AccessFixedTypeByItk(mitkImage, itkImageTypeFunction, pixelTypeSeq, MITK_ACCESSBYITK_DIMENSIONS_SEQ)
221 
236 #define AccessIntegralPixelTypeByItk(mitkImage, itkImageTypeFunction) \
237  AccessFixedTypeByItk( \
238  mitkImage, itkImageTypeFunction, MITK_ACCESSBYITK_INTEGRAL_PIXEL_TYPES_SEQ, MITK_ACCESSBYITK_DIMENSIONS_SEQ)
239 
254 #define AccessFloatingPixelTypeByItk(mitkImage, itkImageTypeFunction) \
255  AccessFixedTypeByItk( \
256  mitkImage, itkImageTypeFunction, MITK_ACCESSBYITK_FLOATING_PIXEL_TYPES_SEQ, MITK_ACCESSBYITK_DIMENSIONS_SEQ)
257 
258 #define AccessVectorPixelTypeByItk(mitkImage, itkImageTypeFunction) \
259  AccessFixedTypeByItk( \
260  mitkImage, itkImageTypeFunction, MITK_ACCESSBYITK_VECTOR_PIXEL_TYPES_SEQ, MITK_ACCESSBYITK_DIMENSIONS_SEQ)
261 
283 #define AccessFixedDimensionByItk(mitkImage, itkImageTypeFunction, dimension) \
284  AccessFixedTypeByItk(mitkImage, itkImageTypeFunction, MITK_ACCESSBYITK_PIXEL_TYPES_SEQ, (dimension))
285 
286 #define AccessVectorFixedDimensionByItk(mitkImage, itkImageTypeFunction, dimension) \
287  AccessFixedTypeByItk(mitkImage, itkImageTypeFunction, MITK_ACCESSBYITK_VECTOR_PIXEL_TYPES_SEQ, (dimension))
288 
320 #define AccessFixedTypeByItk(mitkImage, itkImageTypeFunction, pixelTypeSeq, dimSeq) \
321  \
322  { \
323  const mitk::PixelType &pixelType = mitkImage->GetPixelType(); \
324  _checkSpecificDimension(mitkImage, dimSeq); \
325  _accessFixedTypeByItk(itkImageTypeFunction, mitkImage, pixelTypeSeq, dimSeq) \
326  _accessByItkPixelTypeException(mitkImage->GetPixelType(), pixelTypeSeq) \
327  }
328 
329 //------------------------------ n-Arg Access Macros -----------------------------------
330 
378 #define AccessByItk_n(mitkImage, itkImageTypeFunction, va_tuple) \
379  AccessFixedTypeByItk_n( \
380  mitkImage, itkImageTypeFunction, MITK_ACCESSBYITK_PIXEL_TYPES_SEQ, MITK_ACCESSBYITK_DIMENSIONS_SEQ, va_tuple)
381 
406 #define AccessFixedPixelTypeByItk_n(mitkImage, itkImageTypeFunction, pixelTypeSeq, va_tuple) \
407  AccessFixedTypeByItk_n(mitkImage, itkImageTypeFunction, pixelTypeSeq, MITK_ACCESSBYITK_DIMENSIONS_SEQ, va_tuple)
408 
426 #define AccessIntegralPixelTypeByItk_n(mitkImage, itkImageTypeFunction, va_tuple) \
427  AccessFixedTypeByItk_n(mitkImage, \
428  itkImageTypeFunction, \
429  MITK_ACCESSBYITK_INTEGRAL_PIXEL_TYPES_SEQ, \
430  MITK_ACCESSBYITK_DIMENSIONS_SEQ, \
431  va_tuple)
432 
450 #define AccessFloatingPixelTypeByItk_n(mitkImage, itkImageTypeFunction, va_tuple) \
451  AccessFixedTypeByItk_n(mitkImage, \
452  itkImageTypeFunction, \
453  MITK_ACCESSBYITK_FLOATING_PIXEL_TYPES_SEQ, \
454  MITK_ACCESSBYITK_DIMENSIONS_SEQ, \
455  va_tuple)
456 
472 #define AccessVectorPixelTypeByItk_n(mitkImage, itkImageTypeFunction, va_tuple) \
473  AccessFixedTypeByItk_n(mitkImage, \
474  itkImageTypeFunction, \
475  MITK_ACCESSBYITK_VECTOR_PIXEL_TYPES_SEQ, \
476  MITK_ACCESSBYITK_DIMENSIONS_SEQ, \
477  va_tuple)
478 
503 #define AccessFixedDimensionByItk_n(mitkImage, itkImageTypeFunction, dimension, va_tuple) \
504  AccessFixedTypeByItk_n(mitkImage, itkImageTypeFunction, MITK_ACCESSBYITK_PIXEL_TYPES_SEQ, (dimension), va_tuple)
505 
529 #define AccessVectorFixedDimensionByItk_n(mitkImage, itkImageTypeFunction, dimension, va_tuple) \
530  AccessFixedTypeByItk_n( \
531  mitkImage, itkImageTypeFunction, MITK_ACCESSBYITK_VECTOR_PIXEL_TYPES_SEQ, (dimension), va_tuple)
532 
560 #define AccessFixedTypeByItk_n(mitkImage, itkImageTypeFunction, pixelTypeSeq, dimSeq, va_tuple) \
561  \
562  { \
563  const mitk::PixelType &pixelType = mitkImage->GetPixelType(); \
564  _checkSpecificDimension(mitkImage, dimSeq); \
565  _accessFixedTypeByItk_n(itkImageTypeFunction, mitkImage, pixelTypeSeq, dimSeq, va_tuple) \
566  _accessByItkPixelTypeException(mitkImage->GetPixelType(), pixelTypeSeq) \
567  }
568 
569 //------------------------- For back-wards compatibility -------------------------------
570 
571 #define AccessByItk_1(mitkImage, itkImageTypeFunction, arg1) AccessByItk_n(mitkImage, itkImageTypeFunction, (arg1))
572 #define AccessFixedPixelTypeByItk_1(mitkImage, itkImageTypeFunction, pixelTypeSeq, arg1) \
573  AccessFixedPixelTypeByItk_n(mitkImage, itkImageTypeFunction, pixelTypeSeq, (arg1))
574 #define AccessFixedDimensionByItk_1(mitkImage, itkImageTypeFunction, dimension, arg1) \
575  AccessFixedDimensionByItk_n(mitkImage, itkImageTypeFunction, dimension, (arg1))
576 #define AccessFixedTypeByItk_1(mitkImage, itkImageTypeFunction, pixelTypeSeq, dimSeq, arg1) \
577  AccessFixedTypeByItk_n(mitkImage, itkImageTypeFunction, pixelTypeSeq, dimSeq, (arg1))
578 
579 #define AccessByItk_2(mitkImage, itkImageTypeFunction, arg1, arg2) \
580  AccessByItk_n(mitkImage, itkImageTypeFunction, (arg1, arg2))
581 #define AccessFixedPixelTypeByItk_2(mitkImage, itkImageTypeFunction, pixelTypeSeq, arg1, arg2) \
582  AccessFixedPixelTypeByItk_n(mitkImage, itkImageTypeFunction, pixelTypeSeq, (arg1, arg2))
583 #define AccessFixedDimensionByItk_2(mitkImage, itkImageTypeFunction, dimension, arg1, arg2) \
584  AccessFixedDimensionByItk_n(mitkImage, itkImageTypeFunction, dimension, (arg1, arg2))
585 #define AccessFixedTypeByItk_2(mitkImage, itkImageTypeFunction, pixelTypeSeq, dimSeq, arg1, arg2) \
586  AccessFixedTypeByItk_n(mitkImage, itkImageTypeFunction, pixelTypeSeq, dimSeq, (arg1, arg2))
587 
588 #define AccessByItk_3(mitkImage, itkImageTypeFunction, arg1, arg2, arg3) \
589  AccessByItk_n(mitkImage, itkImageTypeFunction, (arg1, arg2, arg3))
590 #define AccessFixedPixelTypeByItk_3(mitkImage, itkImageTypeFunction, pixelTypeSeq, arg1, arg2, arg3) \
591  AccessFixedPixelTypeByItk_n(mitkImage, itkImageTypeFunction, pixelTypeSeq, (arg1, arg2, arg3))
592 #define AccessFixedDimensionByItk_3(mitkImage, itkImageTypeFunction, dimension, arg1, arg2, arg3) \
593  AccessFixedDimensionByItk_n(mitkImage, itkImageTypeFunction, dimension, (arg1, arg2, arg3))
594 #define AccessFixedTypeByItk_3(mitkImage, itkImageTypeFunction, pixelTypeSeq, dimSeq, arg1, arg2, arg3) \
595  AccessFixedTypeByItk_n(mitkImage, itkImageTypeFunction, pixelTypeSeq, dimSeq, (arg1, arg2, arg3))
596 
597 //----------------------------- Access two MITK Images ---------------------------------
598 
599 #ifndef DOXYGEN_SKIP
600 
601 #define _accessTwoImagesByItk(itkImageTypeFunction, pixeltype1, dim1, pixeltype2, dim2) \
602  if (pixelType1 == mitk::MakePixelType<itk::Image<pixeltype1, dim1>>() && \
603  pixelType2 == mitk::MakePixelType<itk::Image<pixeltype2, dim2>>() && constImage1->GetDimension() == dim1 && \
604  constImage2->GetDimension() == dim2) \
605  { \
606  typedef itk::Image<pixeltype1, dim1> ImageType1; \
607  typedef itk::Image<pixeltype2, dim2> ImageType2; \
608  typedef mitk::ImageToItk<ImageType1> ImageToItkType1; \
609  typedef mitk::ImageToItk<ImageType2> ImageToItkType2; \
610  itk::SmartPointer<ImageToItkType1> imagetoitk1 = ImageToItkType1::New(); \
611  imagetoitk1->SetInput(nonConstImage1); \
612  imagetoitk1->Update(); \
613  itk::SmartPointer<ImageToItkType2> imagetoitk2 = ImageToItkType2::New(); \
614  imagetoitk2->SetInput(nonConstImage2); \
615  imagetoitk2->Update(); \
616  itkImageTypeFunction(imagetoitk1->GetOutput(), imagetoitk2->GetOutput()); \
617  } \
618  else
619 
620 #define _accessTwoImagesByItkArgs2(itkImageTypeFunction, type1, type2) \
621  (itkImageTypeFunction, MITK_PP_TUPLE_REM(2) type1, MITK_PP_TUPLE_REM(2) type2)
622 
623 #define _accessTwoImagesByItkArgs(product) \
624  MITK_PP_EXPAND(_accessTwoImagesByItkArgs2 MITK_PP_EXPAND( \
625  (MITK_PP_SEQ_HEAD(product), MITK_PP_TUPLE_REM(2) MITK_PP_SEQ_TO_TUPLE(MITK_PP_SEQ_TAIL(product)))))
626 
627 // product is of the form (itkImageTypeFunction)((short,2))((char,2))
628 #ifdef _MSC_VER
629 #define _accessTwoImagesByItkIter(r, product) \
630  MITK_PP_EXPAND(_accessTwoImagesByItk _msvc_expand_bug( \
631  _accessTwoImagesByItkArgs2, \
632  (MITK_PP_SEQ_HEAD(product), \
633  _msvc_expand_bug(MITK_PP_TUPLE_REM(2), MITK_PP_EXPAND(MITK_PP_SEQ_TO_TUPLE(MITK_PP_SEQ_TAIL(product)))))))
634 #else
635 #define _accessTwoImagesByItkIter(r, product) MITK_PP_EXPAND(_accessTwoImagesByItk _accessTwoImagesByItkArgs(product))
636 #endif
637 
638 #define _accessTwoImagesByItkForEach(itkImageTypeFunction, tseq1, tseq2) \
639  MITK_PP_SEQ_FOR_EACH_PRODUCT(_accessTwoImagesByItkIter, ((itkImageTypeFunction))(tseq1)(tseq2))
640 
641 #endif // DOXYGEN_SKIP
642 
687 #define AccessTwoImagesFixedDimensionByItk(mitkImage1, mitkImage2, itkImageTypeFunction, dimension) \
688  \
689  { \
690  const mitk::PixelType &pixelType1 = mitkImage1->GetPixelType(); \
691  const mitk::PixelType &pixelType2 = mitkImage2->GetPixelType(); \
692  const mitk::Image *constImage1 = mitkImage1; \
693  const mitk::Image *constImage2 = mitkImage2; \
694  mitk::Image *nonConstImage1 = const_cast<mitk::Image *>(constImage1); \
695  mitk::Image *nonConstImage2 = const_cast<mitk::Image *>(constImage2); \
696  nonConstImage1->Update(); \
697  nonConstImage2->Update(); \
698  _checkSpecificDimension(mitkImage1, (dimension)); \
699  _checkSpecificDimension(mitkImage2, (dimension)); \
700  _accessTwoImagesByItkForEach( \
701  itkImageTypeFunction, MITK_ACCESSBYITK_TYPES_DIMN_SEQ(dimension), MITK_ACCESSBYITK_TYPES_DIMN_SEQ(dimension)) \
702  { \
703  std::string msg("Pixel type "); \
704  msg.append(pixelType1.GetComponentTypeAsString()); \
705  msg.append(" or pixel type "); \
706  msg.append(pixelType2.GetComponentTypeAsString()); \
707  msg.append(" is not in " MITK_PP_STRINGIZE(MITK_ACCESSBYITK_TYPES_DIMN_SEQ(dimension))); \
708  throw mitk::AccessByItkException(msg); \
709  } \
710  }
711 
712 #endif // of MITKIMAGEACCESSBYITK_H_HEADER_INCLUDED
AccessByItkException(const std::string &msg)
STL namespace.
DataCollection - Class to facilitate loading/accessing structured data.
Exception class thrown in AccessByItk macros.