1 /*
2  * Medical Image Registration ToolKit (MIRTK)
3  *
4  * Copyright 2008-2017 Imperial College London
5  * Copyright 2008-2013 Daniel Rueckert, Julia Schnabel
6  * Copyright 2013-2017 Andreas Schuh
7  *
8  * Licensed under the Apache License, Version 2.0 (the "License");
9  * you may not use this file except in compliance with the License.
10  * You may obtain a copy of the License at
11  *
12  *     http://www.apache.org/licenses/LICENSE-2.0
13  *
14  * Unless required by applicable law or agreed to in writing, software
15  * distributed under the License is distributed on an "AS IS" BASIS,
16  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17  * See the License for the specific language governing permissions and
18  * limitations under the License.
19  */
20 
21 #ifndef MIRTK_Voxel_H
22 #define MIRTK_Voxel_H
23 
24 #include "mirtk/Math.h"
25 #include "mirtk/Vector3D.h"
26 #include "mirtk/Vector4D.h"
27 #include "mirtk/VectorND.h"
28 #include "mirtk/String.h"
29 
30 #ifdef HAVE_VTK
31   #include "vtkType.h"
32 #endif
33 
34 
35 namespace mirtk {
36 
37 // =============================================================================
38 // Voxel type enumeration
39 // =============================================================================
40 
41 /// Enumeration of voxel data types
42 enum ImageDataType
43 {
44   MIRTK_VOXEL_UNKNOWN,
45   MIRTK_VOXEL_CHAR,
46   MIRTK_VOXEL_UNSIGNED_CHAR,
47   MIRTK_VOXEL_SHORT,
48   MIRTK_VOXEL_UNSIGNED_SHORT,
49   MIRTK_VOXEL_INT,
50   MIRTK_VOXEL_UNSIGNED_INT,
51   MIRTK_VOXEL_FLOAT,
52   MIRTK_VOXEL_DOUBLE,
53   MIRTK_VOXEL_RGB,
54   MIRTK_VOXEL_FLOAT1, // unused
55   MIRTK_VOXEL_FLOAT2,
56   MIRTK_VOXEL_FLOAT3,
57   MIRTK_VOXEL_FLOAT4,
58   MIRTK_VOXEL_FLOAT9,
59   MIRTK_VOXEL_DOUBLE1, // unused
60   MIRTK_VOXEL_DOUBLE2,
61   MIRTK_VOXEL_DOUBLE3,
62   MIRTK_VOXEL_DOUBLE4,
63   MIRTK_VOXEL_DOUBLE9,
64   MIRTK_VOXEL_FLOAT1x1, // unused
65   MIRTK_VOXEL_FLOAT2x2,
66   MIRTK_VOXEL_FLOAT3x3,
67   MIRTK_VOXEL_FLOAT3x4,
68   MIRTK_VOXEL_FLOAT4x4,
69   MIRTK_VOXEL_DOUBLE1x1, // unused
70   MIRTK_VOXEL_DOUBLE2x2,
71   MIRTK_VOXEL_DOUBLE3x3,
72   MIRTK_VOXEL_DOUBLE3x4,
73   MIRTK_VOXEL_DOUBLE4x4,
74   // Last entry of unique enumeration values
75   MIRKT_VOXEL_LAST,
76   // Aliases for common voxel types
77   MIRTK_VOXEL_BINARY = MIRTK_VOXEL_UNSIGNED_CHAR,
78   MIRTK_VOXEL_BYTE   = MIRTK_VOXEL_UNSIGNED_CHAR,
79   MIRTK_VOXEL_GREY   = MIRTK_VOXEL_SHORT,
80 #if MIRTK_USE_FLOAT_BY_DEFAULT
81   MIRTK_VOXEL_REAL    = MIRTK_VOXEL_FLOAT,
82   MIRTK_VOXEL_REAL1   = MIRTK_VOXEL_FLOAT1,
83   MIRTK_VOXEL_REAL2   = MIRTK_VOXEL_FLOAT2,
84   MIRTK_VOXEL_REAL3   = MIRTK_VOXEL_FLOAT3,
85   MIRTK_VOXEL_REAL4   = MIRTK_VOXEL_FLOAT4,
86   MIRTK_VOXEL_REAL9   = MIRTK_VOXEL_FLOAT9,
87   MIRTK_VOXEL_REAL1x1 = MIRTK_VOXEL_FLOAT1x1,
88   MIRTK_VOXEL_REAL2x2 = MIRTK_VOXEL_FLOAT2x2,
89   MIRTK_VOXEL_REAL3x3 = MIRTK_VOXEL_FLOAT3x3,
90   MIRTK_VOXEL_REAL3x4 = MIRTK_VOXEL_FLOAT3x4,
91   MIRTK_VOXEL_REAL4x4 = MIRTK_VOXEL_FLOAT4x4
92 #else // MIRTK_USE_FLOAT_BY_DEFAULT
93   MIRTK_VOXEL_REAL    = MIRTK_VOXEL_DOUBLE,
94   MIRTK_VOXEL_REAL1   = MIRTK_VOXEL_DOUBLE1,
95   MIRTK_VOXEL_REAL2   = MIRTK_VOXEL_DOUBLE2,
96   MIRTK_VOXEL_REAL3   = MIRTK_VOXEL_DOUBLE3,
97   MIRTK_VOXEL_REAL4   = MIRTK_VOXEL_DOUBLE4,
98   MIRTK_VOXEL_REAL9   = MIRTK_VOXEL_DOUBLE9,
99   MIRTK_VOXEL_REAL1x1 = MIRTK_VOXEL_DOUBLE1x1,
100   MIRTK_VOXEL_REAL2x2 = MIRTK_VOXEL_DOUBLE2x2,
101   MIRTK_VOXEL_REAL3x3 = MIRTK_VOXEL_DOUBLE3x3,
102   MIRTK_VOXEL_REAL3x4 = MIRTK_VOXEL_DOUBLE3x4,
103   MIRTK_VOXEL_REAL4x4 = MIRTK_VOXEL_DOUBLE4x4
104 #endif // MIRTK_USE_FLOAT_BY_DEFAULT
105 };
106 
107 /// Convert image data type enumeration value to string
108 template <> string ToString(const ImageDataType &, int, char, bool);
109 
110 /// Convert string to image data type enumeration value
111 template <> bool FromString(const char *, ImageDataType &);
112 
113 // =============================================================================
114 // Conversion from/to VTK data types
115 // =============================================================================
116 #ifdef HAVE_VTK
117 
118 // -----------------------------------------------------------------------------
119 /// Get VTK data type from IRTK voxel type
ToVTKDataType(int type)120 inline int ToVTKDataType(int type)
121 {
122   switch (type) {
123     case MIRTK_VOXEL_CHAR:           return VTK_CHAR;
124     case MIRTK_VOXEL_UNSIGNED_CHAR:  return VTK_UNSIGNED_CHAR;
125     case MIRTK_VOXEL_SHORT:          return VTK_SHORT;
126     case MIRTK_VOXEL_UNSIGNED_SHORT: return VTK_UNSIGNED_SHORT;
127     case MIRTK_VOXEL_INT:            return VTK_INT;
128     case MIRTK_VOXEL_UNSIGNED_INT:   return VTK_UNSIGNED_INT;
129     case MIRTK_VOXEL_FLOAT:          return VTK_FLOAT;
130     case MIRTK_VOXEL_DOUBLE:         return VTK_DOUBLE;
131     default:                         return VTK_VOID;
132   }
133 }
134 
135 // -----------------------------------------------------------------------------
136 /// Get IRTK voxel type from VTK data type
FromVTKDataType(int type)137 inline int FromVTKDataType(int type)
138 {
139   switch (type) {
140     case VTK_CHAR:           return MIRTK_VOXEL_CHAR;
141     case VTK_UNSIGNED_CHAR:  return MIRTK_VOXEL_UNSIGNED_CHAR;
142     case VTK_SHORT:          return MIRTK_VOXEL_SHORT;
143     case VTK_UNSIGNED_SHORT: return MIRTK_VOXEL_UNSIGNED_SHORT;
144     case VTK_INT:            return MIRTK_VOXEL_INT;
145     case VTK_UNSIGNED_INT:   return MIRTK_VOXEL_UNSIGNED_INT;
146     case VTK_FLOAT:          return MIRTK_VOXEL_FLOAT;
147     case VTK_DOUBLE:         return MIRTK_VOXEL_DOUBLE;
148     default:                 return MIRTK_VOXEL_UNKNOWN;
149   }
150 }
151 
152 #endif // HAVE_VTK
153 // =============================================================================
154 // Voxel types
155 // =============================================================================
156 
157 typedef unsigned char BinaryPixel;
158 typedef unsigned char BytePixel;
159 typedef short         GreyPixel;
160 typedef realt         RealPixel;
161 
162 typedef Vector3D<float>     Float3;
163 typedef Vector4D<float>     Float4;
164 typedef VectorND<9, float>  Float9;
165 typedef Vector3D<double>    Double3;
166 typedef Vector4D<double>    Double4;
167 typedef VectorND<9, double> Double9;
168 
169 // =============================================================================
170 // Voxel type limits
171 // =============================================================================
172 
173 const GreyPixel MIN_GREY = numeric_limits<GreyPixel>::min();
174 const GreyPixel MAX_GREY = numeric_limits<GreyPixel>::max();
175 
176 // -----------------------------------------------------------------------------
177 template <class T>
178 struct voxel_limits
179 {
180   /// Minimum value that can be represented by this voxel type as double
181   /// \note For vector types, this corresponds to the minium value that can
182   ///       be represented by each component of the vector.
183   static double min() throw();
184   /// Maximum value that can be represented by this voxel type as double
185   /// \note For vector types, this corresponds to the maxium value that can
186   ///       be represented by each component of the vector.
187   static double max() throw();
188   /// Minimum value that can be represented by this voxel type
189   static T min_value() throw();
190   /// Maximum value that can be represented by this voxel type
191   static T max_value() throw();
192 };
193 
194 // -----------------------------------------------------------------------------
195 template <> struct voxel_limits<char>
196 {
197   static char   min_value() throw() { return numeric_limits<char>::lowest(); }
198   static char   max_value() throw() { return numeric_limits<char>::max(); }
199   static double min()       throw() { return static_cast<double>(min_value()); }
200   static double max()       throw() { return static_cast<double>(max_value()); }
201 };
202 
203 // -----------------------------------------------------------------------------
204 template <> struct voxel_limits<unsigned char>
205 {
206   static unsigned char min_value() throw() { return numeric_limits<unsigned char>::lowest(); }
207   static unsigned char max_value() throw() { return numeric_limits<unsigned char>::max(); }
208   static double        min()       throw() { return static_cast<double>(min_value()); }
209   static double        max()       throw() { return static_cast<double>(max_value()); }
210 };
211 
212 // -----------------------------------------------------------------------------
213 template <> struct voxel_limits<short>
214 {
215   static short  min_value() throw() { return numeric_limits<short>::lowest(); }
216   static short  max_value() throw() { return numeric_limits<short>::max(); }
217   static double min()       throw() { return static_cast<double>(min_value()); }
218   static double max()       throw() { return static_cast<double>(max_value()); }
219 };
220 
221 // -----------------------------------------------------------------------------
222 template <> struct voxel_limits<unsigned short>
223 {
224   static unsigned short min_value() throw() { return numeric_limits<unsigned short>::lowest(); }
225   static unsigned short max_value() throw() { return numeric_limits<unsigned short>::max(); }
226   static double         min()       throw() { return static_cast<double>(min_value()); }
227   static double         max()       throw() { return static_cast<double>(max_value()); }
228 };
229 
230 // -----------------------------------------------------------------------------
231 template <> struct voxel_limits<int> {
232   static int    min_value() throw() { return numeric_limits<int>::lowest(); }
233   static int    max_value() throw() { return numeric_limits<int>::max();  }
234   static double min()       throw() { return static_cast<double>(min_value()); }
235   static double max()       throw() { return static_cast<double>(max_value()); }
236 };
237 
238 // -----------------------------------------------------------------------------
239 template <> struct voxel_limits<unsigned int>
240 {
241   static unsigned int min_value() throw() { return numeric_limits<unsigned int>::lowest(); }
242   static unsigned int max_value() throw() { return numeric_limits<unsigned int>::max(); }
243   static double       min()       throw() { return static_cast<double      >(min_value()); }
244   static double       max()       throw() { return static_cast<double      >(max_value()); }
245 };
246 
247 // -----------------------------------------------------------------------------
248 template <> struct voxel_limits<float>
249 {
250   static float  min_value() throw() { return numeric_limits<float>::lowest(); }
251   static float  max_value() throw() { return numeric_limits<float>::max(); }
252   static double min()       throw() { return static_cast<double>(min_value()); }
253   static double max()       throw() { return static_cast<double>(max_value()); }
254 };
255 
256 // -----------------------------------------------------------------------------
257 template <> struct voxel_limits<double>
258 {
259   static double min_value() throw() { return numeric_limits<double>::lowest(); }
260   static double max_value() throw() { return numeric_limits<double>::max(); }
261   static double min()       throw() { return static_cast<double>(min_value()); }
262   static double max()       throw() { return static_cast<double>(max_value()); }
263 };
264 
265 // -----------------------------------------------------------------------------
266 template <> struct voxel_limits<float1>
267 {
268   static float1 min_value() throw() { return make_float1(voxel_limits<float>::min_value()); }
269   static float1 max_value() throw() { return make_float1(voxel_limits<float>::max_value()); }
270   static double min() throw() { return voxel_limits<float>::min(); }
271   static double max() throw() { return voxel_limits<float>::max(); }
272 };
273 
274 // -----------------------------------------------------------------------------
275 template <> struct voxel_limits<float2>
276 {
277   static float2 min_value() throw() { return make_float2(voxel_limits<float>::min_value()); }
278   static float2 max_value() throw() { return make_float2(voxel_limits<float>::max_value()); }
279   static double min() throw() { return voxel_limits<float>::min(); }
280   static double max() throw() { return voxel_limits<float>::max(); }
281 };
282 
283 // -----------------------------------------------------------------------------
284 template <> struct voxel_limits<float3>
285 {
286   static float3 min_value() throw() { return make_float3(voxel_limits<float>::min_value()); }
287   static float3 max_value() throw() { return make_float3(voxel_limits<float>::max_value()); }
288   static double min() throw() { return voxel_limits<float>::min(); }
289   static double max() throw() { return voxel_limits<float>::max(); }
290 };
291 
292 // -----------------------------------------------------------------------------
293 template <> struct voxel_limits<float4>
294 {
295   static float4 min_value() throw() { return make_float4(voxel_limits<float>::min_value()); }
296   static float4 max_value() throw() { return make_float4(voxel_limits<float>::max_value()); }
297   static double min() throw() { return voxel_limits<float>::min(); }
298   static double max() throw() { return voxel_limits<float>::max(); }
299 };
300 
301 // -----------------------------------------------------------------------------
302 template <> struct voxel_limits<float3x3>
303 {
304   static float3x3 min_value() throw() { return make_float3x3(voxel_limits<float>::min_value()); }
305   static float3x3 max_value() throw() { return make_float3x3(voxel_limits<float>::max_value()); }
306   static double min() throw() { return voxel_limits<float>::min(); }
307   static double max() throw() { return voxel_limits<float>::max(); }
308 };
309 
310 // -----------------------------------------------------------------------------
311 template <> struct voxel_limits<double1>
312 {
313   static double1 min_value() throw() { return make_double1(voxel_limits<double>::min_value()); }
314   static double1 max_value() throw() { return make_double1(voxel_limits<double>::max_value()); }
315   static double min() throw() { return voxel_limits<double>::min(); }
316   static double max() throw() { return voxel_limits<double>::max(); }
317 };
318 
319 // -----------------------------------------------------------------------------
320 template <> struct voxel_limits<double2>
321 {
322   static double2 min_value() throw() { return make_double2(voxel_limits<double>::min_value()); }
323   static double2 max_value() throw() { return make_double2(voxel_limits<double>::max_value()); }
324   static double min() throw() { return voxel_limits<double>::min(); }
325   static double max() throw() { return voxel_limits<double>::max(); }
326 };
327 
328 // -----------------------------------------------------------------------------
329 template <> struct voxel_limits<double3>
330 {
331   static double3 min_value() throw() { return make_double3(voxel_limits<double>::min_value()); }
332   static double3 max_value() throw() { return make_double3(voxel_limits<double>::max_value()); }
333   static double min() throw() { return voxel_limits<double>::min(); }
334   static double max() throw() { return voxel_limits<double>::max(); }
335 };
336 
337 // -----------------------------------------------------------------------------
338 template <> struct voxel_limits<double4>
339 {
340   static double4 min_value() throw() { return make_double4(voxel_limits<double>::min_value()); }
341   static double4 max_value() throw() { return make_double4(voxel_limits<double>::max_value()); }
342   static double min() throw() { return voxel_limits<double>::min(); }
343   static double max() throw() { return voxel_limits<double>::max(); }
344 };
345 
346 // -----------------------------------------------------------------------------
347 template <> struct voxel_limits<double3x3>
348 {
349   static double3x3 min_value() throw() { return make_double3x3(voxel_limits<double>::min_value()); }
350   static double3x3 max_value() throw() { return make_double3x3(voxel_limits<double>::max_value()); }
351   static double min() throw() { return voxel_limits<double>::min(); }
352   static double max() throw() { return voxel_limits<double>::max(); }
353 };
354 
355 // -----------------------------------------------------------------------------
356 template <> struct voxel_limits<Float3>
357 {
358   static Float3 min_value() throw()
359   { return Float3(voxel_limits<float>::min_value()); }
360   static Float3 max_value() throw()
361   { return Float3(voxel_limits<float>::max_value()); }
362   static double min() throw() { return voxel_limits<float>::min(); }
363   static double max() throw() { return voxel_limits<float>::max(); }
364 };
365 
366 // -----------------------------------------------------------------------------
367 template <> struct voxel_limits<Double3>
368 {
369   static Double3 min_value() throw()
370   { return Double3(voxel_limits<double>::min_value()); }
371   static Double3 max_value() throw()
372   { return Double3(voxel_limits<double>::max_value()); }
373   static double min() throw() { return voxel_limits<double>::min(); }
374   static double max() throw() { return voxel_limits<double>::max(); }
375 };
376 
377 // -----------------------------------------------------------------------------
378 template <> struct voxel_limits<Float4>
379 {
380   static Float4 min_value() throw()
381   { return Float4(voxel_limits<float>::min_value()); }
382   static Float4 max_value() throw()
383   { return Float4(voxel_limits<float>::max_value()); }
384   static double min() throw() { return voxel_limits<float>::min(); }
385   static double max() throw() { return voxel_limits<float>::max(); }
386 };
387 
388 // -----------------------------------------------------------------------------
389 template <> struct voxel_limits<Double4>
390 {
391   static Double4 min_value() throw()
392   { return Double4(voxel_limits<double>::min_value()); }
393   static Double4 max_value() throw()
394   { return Double4(voxel_limits<double>::max_value()); }
395   static double min() throw() { return voxel_limits<double>::min(); }
396   static double max() throw() { return voxel_limits<double>::max(); }
397 };
398 
399 // -----------------------------------------------------------------------------
400 template <> struct voxel_limits<Float9>
401 {
402   static Float9 min_value() throw()
403   { return Float9(voxel_limits<float>::min_value()); }
404   static Float9 max_value() throw()
405   { return Float9(voxel_limits<float>::max_value()); }
406   static double min() throw() { return voxel_limits<float>::min(); }
407   static double max() throw() { return voxel_limits<float>::max(); }
408 };
409 
410 // -----------------------------------------------------------------------------
411 template <> struct voxel_limits<Double9>
412 {
413   static Double9 min_value() throw()
414   { return Double9(voxel_limits<double>::min_value()); }
415   static Double9 max_value() throw()
416   { return Double9(voxel_limits<double>::max_value()); }
417   static double min() throw() { return voxel_limits<double>::min(); }
418   static double max() throw() { return voxel_limits<double>::max(); }
419 };
420 
421 // -----------------------------------------------------------------------------
422 // Variable length vector type not allowed as actual voxel type of an image
423 // instance. Only used as voxel type by base class methods and general
424 // interpolators. Treat voxel type as if it was a scalar type here.
425 template <> struct voxel_limits<Vector>
426 {
427   static Vector min_value() throw() { return Vector(1, min()); }
428   static Vector max_value() throw() { return Vector(1, max()); }
429   static double min()       throw() { return numeric_limits<double>::lowest(); }
430   static double max()       throw() { return numeric_limits<double>::max(); }
431 };
432 
433 // =============================================================================
434 // Voxel type information
435 // =============================================================================
436 
437 // -----------------------------------------------------------------------------
438 int DataTypeSize(int);
439 
440 // -----------------------------------------------------------------------------
441 inline string DataTypeName(int type)
442 {
443   return ToString(static_cast<ImageDataType>(type));
444 }
445 
446 // -----------------------------------------------------------------------------
447 inline int ToDataType(const char *str)
448 {
449   ImageDataType type;
450   if (FromString(str, type)) return type;
451   return MIRTK_VOXEL_UNKNOWN;
452 }
453 
454 // -----------------------------------------------------------------------------
455 inline int ToDataType(const string &str)
456 {
457   return ToDataType(str.c_str());
458 }
459 
460 // -----------------------------------------------------------------------------
461 template <class T>
462 struct voxel_info : public voxel_limits<T>
463 {
464   /// Scalar type compatible with this voxel type
465   typedef T ScalarType;
466   /// Floating point type compatible with this voxel type
467   typedef RealPixel RealType;
468   /// Number of (vector) elements stored by this voxel
469   static int vector_size() throw();
470   /// Enumeration value corresponding to voxel type of (vector) elements
471   static int element_type() throw();
472   /// Enumeration value corresponding to this voxel type
473   static int type() throw();
474   /// Minimum value that can be represented by this voxel type as double
475   /// \note For vector types, this corresponds to the minium value that can
476   ///       be represented by each component of the vector.
477   using voxel_limits<T>::min;
478   /// Maximum value that can be represented by this voxel type as double
479   /// \note For vector types, this corresponds to the maxium value that can
480   ///       be represented by each component of the vector.
481   using voxel_limits<T>::max;
482   /// Minimum value that can be represented by this voxel type
483   using voxel_limits<T>::min_value;
484   /// Maximum value that can be represented by this voxel type
485   using voxel_limits<T>::max_value;
486 };
487 
488 // -----------------------------------------------------------------------------
489 template <> struct voxel_info<char>
490 {
491   typedef char        ScalarType;
492   typedef RealPixel   RealType;
493   static int vector_size()  throw() { return 1; }
494   static int element_type() throw() { return MIRTK_VOXEL_CHAR; }
495   static int type()         throw() { return MIRTK_VOXEL_CHAR; }
496 };
497 
498 // -----------------------------------------------------------------------------
499 template <> struct voxel_info<unsigned char>
500 {
501   typedef unsigned char ScalarType;
502   typedef RealPixel     RealType;
503   static int vector_size()  throw() { return 1; }
504   static int element_type() throw() { return MIRTK_VOXEL_UNSIGNED_CHAR; }
505   static int type()         throw() { return MIRTK_VOXEL_UNSIGNED_CHAR; }
506 };
507 
508 // -----------------------------------------------------------------------------
509 template <> struct voxel_info<short>
510 {
511   typedef short     ScalarType;
512   typedef RealPixel RealType;
513   static int vector_size()  throw() { return 1; }
514   static int element_type() throw() { return MIRTK_VOXEL_SHORT; }
515   static int type()         throw() { return MIRTK_VOXEL_SHORT; }
516 };
517 
518 // -----------------------------------------------------------------------------
519 template <> struct voxel_info<unsigned short>
520 {
521   typedef unsigned short ScalarType;
522   typedef RealPixel      RealType;
523   static int vector_size()  throw() { return 1; }
524   static int element_type() throw() { return MIRTK_VOXEL_UNSIGNED_SHORT; }
525   static int type()         throw() { return MIRTK_VOXEL_UNSIGNED_SHORT; }
526 };
527 
528 // -----------------------------------------------------------------------------
529 template <> struct voxel_info<int>
530 {
531   typedef int       ScalarType;
532   typedef RealPixel RealType;
533   static int vector_size()  throw() { return 1; }
534   static int element_type() throw() { return MIRTK_VOXEL_INT; }
535   static int type()         throw() { return MIRTK_VOXEL_INT; }
536 };
537 
538 // -----------------------------------------------------------------------------
539 template <> struct voxel_info<unsigned int>
540 {
541   typedef unsigned int ScalarType;
542   typedef RealPixel    RealType;
543   static int vector_size()  throw() { return 1; }
544   static int element_type() throw() { return MIRTK_VOXEL_UNSIGNED_INT; }
545   static int type()         throw() { return MIRTK_VOXEL_UNSIGNED_INT; }
546 };
547 
548 // -----------------------------------------------------------------------------
549 template <> struct voxel_info<float>
550 {
551   typedef float1   Type1;
552   typedef float2   Type2;
553   typedef float3   Type3;
554   typedef float4   Type4;
555   typedef float2x2 Type2x2;
556   typedef float3x3 Type3x3;
557   typedef float3x4 Type3x4;
558   typedef float4x4 Type4x4;
559   typedef float    ScalarType;
560   typedef float    RealType;
561   static int vector_size()  throw() { return 1; }
562   static int element_type() throw() { return MIRTK_VOXEL_FLOAT; }
563   static int type()         throw() { return MIRTK_VOXEL_FLOAT; }
564 };
565 
566 // -----------------------------------------------------------------------------
567 template <> struct voxel_info<float1>
568 {
569   typedef float  ScalarType;
570   typedef float1 RealType;
571   static int vector_size()  throw() { return 1; }
572   static int element_type() throw() { return MIRTK_VOXEL_FLOAT; }
573   static int type()         throw() { return MIRTK_VOXEL_FLOAT1; }
574 };
575 
576 // -----------------------------------------------------------------------------
577 template <> struct voxel_info<float2>
578 {
579   typedef float  ScalarType;
580   typedef float2 RealType;
581   static int vector_size()  throw() { return 2; }
582   static int element_type() throw() { return MIRTK_VOXEL_FLOAT; }
583   static int type()         throw() { return MIRTK_VOXEL_FLOAT2; }
584 };
585 
586 // -----------------------------------------------------------------------------
587 template <> struct voxel_info<float3>
588 {
589   typedef float  ScalarType;
590   typedef float3 RealType;
591   static int vector_size()  throw() { return 3; }
592   static int element_type() throw() { return MIRTK_VOXEL_FLOAT; }
593   static int type()         throw() { return MIRTK_VOXEL_FLOAT3; }
594 };
595 
596 // -----------------------------------------------------------------------------
597 template <> struct voxel_info<float4>
598 {
599   typedef float  ScalarType;
600   typedef float4 RealType;
601   static int vector_size()  throw() { return 4; }
602   static int element_type() throw() { return MIRTK_VOXEL_FLOAT; }
603   static int type()         throw() { return MIRTK_VOXEL_FLOAT4; }
604 };
605 
606 // -----------------------------------------------------------------------------
607 template <> struct voxel_info<float3x3>
608 {
609   typedef float    ScalarType;
610   typedef float3x3 RealType;
611   static int vector_size()  throw() { return 9; }
612   static int element_type() throw() { return MIRTK_VOXEL_FLOAT; }
613   static int type()         throw() { return MIRTK_VOXEL_FLOAT3x3; }
614 };
615 
616 // -----------------------------------------------------------------------------
617 template <> struct voxel_info<double>
618 {
619   typedef double1   Type1;
620   typedef double2   Type2;
621   typedef double3   Type3;
622   typedef double4   Type4;
623   typedef double2x2 Type2x2;
624   typedef double3x3 Type3x3;
625   typedef double3x4 Type3x4;
626   typedef double4x4 Type4x4;
627   typedef double    ScalarType;
628   typedef double    RealType;
629   static int vector_size()  throw() { return 1; }
630   static int element_type() throw() { return MIRTK_VOXEL_DOUBLE; }
631   static int type()         throw() { return MIRTK_VOXEL_DOUBLE; }
632 };
633 
634 // -----------------------------------------------------------------------------
635 template <> struct voxel_info<double1>
636 {
637   typedef double  ScalarType;
638   typedef double1 RealType;
639   static int vector_size()  throw() { return 1; }
640   static int element_type() throw() { return MIRTK_VOXEL_DOUBLE; }
641   static int type()         throw() { return MIRTK_VOXEL_DOUBLE1; }
642 };
643 
644 // -----------------------------------------------------------------------------
645 template <> struct voxel_info<double2>
646 {
647   typedef double  ScalarType;
648   typedef double2 RealType;
649   static int vector_size()  throw() { return 2; }
650   static int element_type() throw() { return MIRTK_VOXEL_DOUBLE; }
651   static int type()         throw() { return MIRTK_VOXEL_DOUBLE2; }
652 };
653 
654 // -----------------------------------------------------------------------------
655 template <> struct voxel_info<double3>
656 {
657   typedef double  ScalarType;
658   typedef double3 RealType;
659   static int vector_size()  throw() { return 3; }
660   static int element_type() throw() { return MIRTK_VOXEL_DOUBLE; }
661   static int type()         throw() { return MIRTK_VOXEL_DOUBLE3; }
662 };
663 
664 // -----------------------------------------------------------------------------
665 template <> struct voxel_info<double4>
666 {
667   typedef double  ScalarType;
668   typedef double4 RealType;
669   static int vector_size()  throw() { return 4; }
670   static int element_type() throw() { return MIRTK_VOXEL_DOUBLE; }
671   static int type()         throw() { return MIRTK_VOXEL_DOUBLE4; }
672 };
673 
674 // -----------------------------------------------------------------------------
675 template <> struct voxel_info<double3x3>
676 {
677   typedef double    ScalarType;
678   typedef double3x3 RealType;
679   static int vector_size()  throw() { return 9; }
680   static int element_type() throw() { return MIRTK_VOXEL_DOUBLE; }
681   static int type()         throw() { return MIRTK_VOXEL_DOUBLE3x3; }
682 };
683 
684 // -----------------------------------------------------------------------------
685 // Variable length vector type not allowed as actual voxel type of an image
686 // instance. Only used as voxel type by base class methods and general
687 // interpolators. Treat voxel type as if it was a scalar type here.
688 template <> struct voxel_info<Vector>
689 {
690   typedef double ScalarType;
691   typedef double RealType;
692   static int vector_size()  throw() { return 1; }
693   static int element_type() throw() { return MIRTK_VOXEL_DOUBLE; }
694   static int type()         throw() { return MIRTK_VOXEL_DOUBLE; }
695 };
696 
697 // -----------------------------------------------------------------------------
698 template <> struct voxel_info<Float3>
699 {
700   typedef float  ScalarType;
701   typedef Float3 RealType;
702   static int vector_size()  throw() { return 3; }
703   static int element_type() throw() { return MIRTK_VOXEL_FLOAT; }
704   static int type()         throw() { return MIRTK_VOXEL_FLOAT3; }
705 };
706 
707 // -----------------------------------------------------------------------------
708 template <> struct voxel_info<Double3>
709 {
710   typedef double  ScalarType;
711   typedef Double3 RealType;
712   static int vector_size()  throw() { return 3; }
713   static int element_type() throw() { return MIRTK_VOXEL_DOUBLE; }
714   static int type()         throw() { return MIRTK_VOXEL_DOUBLE3; }
715 };
716 
717 // -----------------------------------------------------------------------------
718 template <> struct voxel_info<Float4>
719 {
720   typedef float  ScalarType;
721   typedef Float4 RealType;
722   static int vector_size()  throw() { return 4; }
723   static int element_type() throw() { return MIRTK_VOXEL_FLOAT; }
724   static int type()         throw() { return MIRTK_VOXEL_FLOAT4; }
725 };
726 
727 // -----------------------------------------------------------------------------
728 template <> struct voxel_info<Double4>
729 {
730   typedef double  ScalarType;
731   typedef Double4 RealType;
732   static int vector_size()  throw() { return 4; }
733   static int element_type() throw() { return MIRTK_VOXEL_DOUBLE; }
734   static int type()         throw() { return MIRTK_VOXEL_DOUBLE4; }
735 };
736 
737 // -----------------------------------------------------------------------------
738 template <> struct voxel_info<Float9>
739 {
740   typedef float  ScalarType;
741   typedef Float9 RealType;
742   static int vector_size()  throw() { return 9; }
743   static int element_type() throw() { return MIRTK_VOXEL_FLOAT; }
744   static int type()         throw() { return MIRTK_VOXEL_FLOAT4; }
745 };
746 
747 // -----------------------------------------------------------------------------
748 template <> struct voxel_info<Double9>
749 {
750   typedef double  ScalarType;
751   typedef Double9 RealType;
752   static int vector_size()  throw() { return 9; }
753   static int element_type() throw() { return MIRTK_VOXEL_DOUBLE; }
754   static int type()         throw() { return MIRTK_VOXEL_DOUBLE4; }
755 };
756 
757 
758 } // namespace mirtk
759 
760 #endif // MIRTK_Voxel_H
761