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