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