VTK
vtkImageInterpolatorInternals.h
Go to the documentation of this file.
1 /*=========================================================================
2 
3  Program: Visualization Toolkit
4  Module: vtkInterpolatorInternals.h
5 
6  Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
7  All rights reserved.
8  See Copyright.txt or http://www.kitware.com/Copyright.htm for details.
9 
10  This software is distributed WITHOUT ANY WARRANTY; without even
11  the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
12  PURPOSE. See the above copyright notice for more information.
13 
14 =========================================================================*/
19 #ifndef vtkInterpolatorInternals_h
20 #define vtkInterpolatorInternals_h
21 
22 #include "vtkMath.h"
23 
24 // The interpolator info struct
26 {
27  const void *Pointer;
28  int Extent[6];
34  void *ExtraInfo;
35 };
36 
37 // The interpolation weights struct
39 {
41  void *Weights[3];
42  int WeightExtent[6];
43  int KernelSize[3];
44  int WeightType; // VTK_FLOAT or VTK_DOUBLE
45 
46  // partial copy contstructor from superclass
48  vtkInterpolationInfo(info) {}
49 };
50 
51 // The internal math functions for the interpolators
53 {
54  // floor with remainder (remainder can be double or float),
55  // includes a small tolerance for values just under an integer
56  template<class F>
57  static int Floor(double x, F &f);
58 
59  // round function optimized for various architectures
60  static int Round(double x);
61 
62  // border-handling functions for keeping index a with in bounds b, c
63  static int Clamp(int a, int b, int c);
64  static int Wrap(int a, int b, int c);
65  static int Mirror(int a, int b, int c);
66 };
67 
68 //--------------------------------------------------------------------------
69 // The 'floor' function is slow, so we want to do an integer
70 // cast but keep the "floor" behavior of always rounding down,
71 // rather than truncating, i.e. we want -0.6 to become -1.
72 // The easiest way to do this is to add a large value in
73 // order to make the value "unsigned", then cast to int, and
74 // then subtract off the large value.
75 
76 // On the old i386 architecture even a cast to int is very
77 // expensive because it requires changing the rounding mode
78 // on the FPU. So we use a bit-trick similar to the one
79 // described at http://www.stereopsis.com/FPU.html
80 
81 #if defined ia64 || defined __ia64__ || defined _M_IA64
82 #define VTK_INTERPOLATE_64BIT_FLOOR
83 #elif defined __ppc64__ || defined __x86_64__ || defined _M_X64
84 #define VTK_INTERPOLATE_64BIT_FLOOR
85 #elif defined __ppc__ || defined sparc || defined mips
86 #define VTK_INTERPOLATE_32BIT_FLOOR
87 #elif defined i386 || defined _M_IX86
88 #define VTK_INTERPOLATE_I386_FLOOR
89 #endif
90 
91 // We add a tolerance of 2^-17 (around 7.6e-6) so that float
92 // values that are just less than the closest integer are
93 // rounded up. This adds robustness against rounding errors.
94 
95 #define VTK_INTERPOLATE_FLOOR_TOL 7.62939453125e-06
96 
97 template<class F>
98 inline int vtkInterpolationMath::Floor(double x, F &f)
99 {
100 #if defined VTK_INTERPOLATE_64BIT_FLOOR
101  x += (103079215104.0 + VTK_INTERPOLATE_FLOOR_TOL);
102 #ifdef VTK_TYPE_USE___INT64
103  __int64 i = static_cast<__int64>(x);
104  f = x - i;
105  return static_cast<int>(i - 103079215104i64);
106 #else
107  long long i = static_cast<long long>(x);
108  f = static_cast<F>(x - i);
109  return static_cast<int>(i - 103079215104LL);
110 #endif
111 #elif defined VTK_INTERPOLATE_32BIT_FLOOR
112  x += (2147483648.0 + VTK_INTERPOLATE_FLOOR_TOL);
113  unsigned int i = static_cast<unsigned int>(x);
114  f = x - i;
115  return static_cast<int>(i - 2147483648U);
116 #elif defined VTK_INTERPOLATE_I386_FLOOR
117  union { double d; unsigned short s[4]; unsigned int i[2]; } dual;
118  dual.d = x + 103079215104.0; // (2**(52-16))*1.5
119  f = dual.s[0]*0.0000152587890625; // 2**(-16)
120  return static_cast<int>((dual.i[1]<<16)|((dual.i[0])>>16));
121 #else
123  int i = vtkMath::Floor(x);
124  f = x - i;
125  return i;
126 #endif
127 }
128 
129 
130 inline int vtkInterpolationMath::Round(double x)
131 {
132 #if defined VTK_INTERPOLATE_64BIT_FLOOR
133  x += (103079215104.5 + VTK_INTERPOLATE_FLOOR_TOL);
134 #ifdef VTK_TYPE_USE___INT64
135  __int64 i = static_cast<__int64>(x);
136  return static_cast<int>(i - 103079215104i64);
137 #else
138  long long i = static_cast<long long>(x);
139  return static_cast<int>(i - 103079215104LL);
140 #endif
141 #elif defined VTK_INTERPOLATE_32BIT_FLOOR
142  x += (2147483648.5 + VTK_INTERPOLATE_FLOOR_TOL);
143  unsigned int i = static_cast<unsigned int>(x);
144  return static_cast<int>(i - 2147483648U);
145 #elif defined VTK_INTERPOLATE_I386_FLOOR
146  union { double d; unsigned int i[2]; } dual;
147  dual.d = x + 103079215104.5; // (2**(52-16))*1.5
148  return static_cast<int>((dual.i[1]<<16)|((dual.i[0])>>16));
149 #else
150  return vtkMath::Floor(x + (0.5 + VTK_INTERPOLATE_FLOOR_TOL));
151 #endif
152 }
153 
154 //----------------------------------------------------------------------------
155 // Perform a clamp to limit an index to [b, c] and subtract b.
156 
157 inline int vtkInterpolationMath::Clamp(int a, int b, int c)
158 {
159  a = (a <= c ? a : c);
160  a -= b;
161  a = (a >= 0 ? a : 0);
162  return a;
163 }
164 
165 //----------------------------------------------------------------------------
166 // Perform a wrap to limit an index to [b, c] and subtract b.
167 
168 inline int vtkInterpolationMath::Wrap(int a, int b, int c)
169 {
170  int range = c - b + 1;
171  a -= b;
172  a %= range;
173  // required for some % implementations
174  a = (a >= 0 ? a : a + range);
175  return a;
176 }
177 
178 //----------------------------------------------------------------------------
179 // Perform a mirror to limit an index to [b, c] and subtract b.
180 
181 inline int vtkInterpolationMath::Mirror(int a, int b, int c)
182 {
183 #ifndef VTK_IMAGE_BORDER_LEGACY_MIRROR
184  int range = c - b;
185  int ifzero = (range == 0);
186  int range2 = 2*range + ifzero;
187  a -= b;
188  a = (a >= 0 ? a : -a);
189  a %= range2;
190  a = (a <= range ? a : range2 - a);
191  return a;
192 #else
193  int range = c - b + 1;
194  int range2 = 2*range;
195  a -= b;
196  a = (a >= 0 ? a : -a - 1);
197  a %= range2;
198  a = (a < range ? a : range2 - a - 1);
199  return a;
200 #endif
201 }
202 
203 #endif
204 // VTK-HeaderTest-Exclude: vtkImageInterpolatorInternals.h
static int Mirror(int a, int b, int c)
static int Clamp(int a, int b, int c)
static int Wrap(int a, int b, int c)
int vtkIdType
Definition: vtkType.h:275
static int Floor(double x)
Definition: vtkMath.h:1017
static int Floor(double x, F &f)
#define VTK_INTERPOLATE_FLOOR_TOL
vtkInterpolationWeights(const vtkInterpolationInfo &info)