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