File: | src/nrrd/kernel.c |
Location: | line 3423, column 7 |
Description: | Branch condition evaluates to a garbage value |
1 | /* | |||
2 | Teem: Tools to process and visualize scientific data and images . | |||
3 | Copyright (C) 2013, 2012, 2011, 2010, 2009 University of Chicago | |||
4 | Copyright (C) 2008, 2007, 2006, 2005 Gordon Kindlmann | |||
5 | Copyright (C) 2004, 2003, 2002, 2001, 2000, 1999, 1998 University of Utah | |||
6 | ||||
7 | This library is free software; you can redistribute it and/or | |||
8 | modify it under the terms of the GNU Lesser General Public License | |||
9 | (LGPL) as published by the Free Software Foundation; either | |||
10 | version 2.1 of the License, or (at your option) any later version. | |||
11 | The terms of redistributing and/or modifying this software also | |||
12 | include exceptions to the LGPL that facilitate static linking. | |||
13 | ||||
14 | This library is distributed in the hope that it will be useful, | |||
15 | but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
16 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |||
17 | Lesser General Public License for more details. | |||
18 | ||||
19 | You should have received a copy of the GNU Lesser General Public License | |||
20 | along with this library; if not, write to Free Software Foundation, Inc., | |||
21 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA | |||
22 | */ | |||
23 | ||||
24 | #include "nrrd.h" | |||
25 | ||||
26 | /* | |||
27 | ** summary of information about how the kernel parameter vector is set: | |||
28 | ** Note that, annoyingly, nrrdKernelUsesScale (at end of this file) | |||
29 | ** has to be updated to record which kernels (including their derivatives) | |||
30 | ** use parm[0] for scale. | |||
31 | ||||
32 | numParm parm[0] parm[1] parm[2] | |||
33 | nrrdKernelHann 2 scale cut-off | |||
34 | nrrdKernelBlackman 2 scale cut-off | |||
35 | nrrdKernelCatmullRom 0 | |||
36 | nrrdKernelBSpline3 0 | |||
37 | nrrdKernelBSpline3ApproxInverse 0 | |||
38 | nrrdKernelBSpline5 0 | |||
39 | nrrdKernelBSpline5ApproxInverse 0 | |||
40 | nrrdKernelBSpline7 0 | |||
41 | nrrdKernelBSpline7ApproxInverse 0 | |||
42 | nrrdKernelZero 1 scale | |||
43 | nrrdKernelBox 1 scale | |||
44 | nrrdKernelCatmullRomSupportDebug 1 support | |||
45 | nrrdKernelBoxSupportDebug 1 support | |||
46 | nrrdKernelCos4SupportDebug 1 support | |||
47 | nrrdKernelCheap 1 scale | |||
48 | nrrdKernelHermiteScaleSpaceFlag 0 | |||
49 | nrrdKernelTent 1 scale | |||
50 | nrrdKernelForwDiff 1 scale | |||
51 | nrrdKernelCentDiff 1 scale | |||
52 | nrrdKernelBCCubic 3 scale B C | |||
53 | nrrdKernelAQuartic 2 scale A | |||
54 | nrrdKernelC3Quintic 0 | |||
55 | nrrdKernelC4Hexic 0 | |||
56 | nrrdKernelC4HexicApproxInverse 0 | |||
57 | nrrdKernelC5Septic 0 | |||
58 | nrrdKernelGaussian 2 sigma cut-off | |||
59 | nrrdKernelDiscreteGaussian 2 sigma cut-off | |||
60 | nrrdKernelTMF[][][] 1 a | |||
61 | ||||
62 | ** Note that when parm[0] is named "scale", that parameter is optional, | |||
63 | ** and the default is 1.0, when given in string form | |||
64 | ** E.g. "tent" is understood as "tent:1", | |||
65 | ** but "gauss:4" isn't complete and won't parse; while "gauss:1,4" is good | |||
66 | ** See note above about nrrdKernelUsesScale (at end of this file) | |||
67 | */ | |||
68 | ||||
69 | /* these functions replace what had been a lot of | |||
70 | identical functions for similar kernels */ | |||
71 | ||||
72 | static double | |||
73 | returnZero(const double *parm) { | |||
74 | AIR_UNUSED(parm)(void)(parm); | |||
75 | return 0.0; | |||
76 | } | |||
77 | ||||
78 | static double | |||
79 | returnOne(const double *parm) { | |||
80 | AIR_UNUSED(parm)(void)(parm); | |||
81 | return 1.0; | |||
82 | } | |||
83 | ||||
84 | static double | |||
85 | returnTwo(const double *parm) { | |||
86 | AIR_UNUSED(parm)(void)(parm); | |||
87 | return 2.0; | |||
88 | } | |||
89 | ||||
90 | static double | |||
91 | returnThree(const double *parm) { | |||
92 | AIR_UNUSED(parm)(void)(parm); | |||
93 | return 3.0; | |||
94 | } | |||
95 | ||||
96 | static double | |||
97 | returnFour(const double *parm) { | |||
98 | AIR_UNUSED(parm)(void)(parm); | |||
99 | return 4.0; | |||
100 | } | |||
101 | ||||
102 | /* ------------------------------------------------------------ */ | |||
103 | ||||
104 | /* learned: if you copy/paste the macros for these kernels into | |||
105 | ** other code, you *have* to make sure that the arguments for the | |||
106 | ** kernels that are supposed to be reals, are not passed as an | |||
107 | ** integral type (had this problem trying to re-use _BCCUBIC | |||
108 | ** with constant B="1" and C="0" and had trouble figuring out | |||
109 | ** why the kernel was give garbage results | |||
110 | */ | |||
111 | ||||
112 | /* the "zero" kernel is here more as a template than for anything else | |||
113 | (as well as when you need the derivative of nrrdKernelForwDiff or | |||
114 | any other piece-wise constant kernels) | |||
115 | In particular the support method is pretty silly. */ | |||
116 | ||||
117 | #define _ZERO(x)0 0 | |||
118 | ||||
119 | static double | |||
120 | _nrrdZeroSup(const double *parm) { | |||
121 | double S; | |||
122 | ||||
123 | S = parm[0]; | |||
124 | return S; | |||
125 | } | |||
126 | ||||
127 | static double | |||
128 | _nrrdZero1_d(double x, const double *parm) { | |||
129 | double S; | |||
130 | ||||
131 | S = parm[0]; | |||
132 | x = AIR_ABS(x)((x) > 0.0f ? (x) : -(x))/S; | |||
133 | return _ZERO(x)0/S; | |||
134 | } | |||
135 | ||||
136 | static float | |||
137 | _nrrdZero1_f(float x, const double *parm) { | |||
138 | float S; | |||
139 | ||||
140 | S = AIR_CAST(float, parm[0])((float)(parm[0])); | |||
141 | x = AIR_ABS(x)((x) > 0.0f ? (x) : -(x))/S; | |||
142 | return _ZERO(x)0/S; | |||
143 | } | |||
144 | ||||
145 | static void | |||
146 | _nrrdZeroN_d(double *f, const double *x, size_t len, const double *parm) { | |||
147 | double S; | |||
148 | double t; | |||
149 | size_t i; | |||
150 | ||||
151 | S = parm[0]; | |||
152 | for (i=0; i<len; i++) { | |||
153 | t = x[i]; t = AIR_ABS(t)((t) > 0.0f ? (t) : -(t))/S; | |||
154 | f[i] = _ZERO(t)0/S; | |||
155 | } | |||
156 | } | |||
157 | ||||
158 | static void | |||
159 | _nrrdZeroN_f(float *f, const float *x, size_t len, const double *parm) { | |||
160 | float t, S; | |||
161 | size_t i; | |||
162 | ||||
163 | S = AIR_CAST(float, parm[0])((float)(parm[0])); | |||
164 | for (i=0; i<len; i++) { | |||
165 | t = x[i]; t = AIR_ABS(t)((t) > 0.0f ? (t) : -(t))/S; | |||
166 | f[i] = _ZERO(t)0/S; | |||
167 | } | |||
168 | } | |||
169 | ||||
170 | static NrrdKernel | |||
171 | _nrrdKernelZero = { | |||
172 | "zero", | |||
173 | 1, _nrrdZeroSup, returnZero, | |||
174 | _nrrdZero1_f, _nrrdZeroN_f, _nrrdZero1_d, _nrrdZeroN_d | |||
175 | }; | |||
176 | NrrdKernel *const | |||
177 | nrrdKernelZero = &_nrrdKernelZero; | |||
178 | ||||
179 | /* ------------------------------------------------------------ */ | |||
180 | ||||
181 | #define _BOX(x)(x > 0.5 ? 0 : (x < 0.5 ? 1 : 0.5)) (x > 0.5 ? 0 : (x < 0.5 ? 1 : 0.5)) | |||
182 | ||||
183 | static double | |||
184 | _nrrdBoxSup(const double *parm) { | |||
185 | double S; | |||
186 | ||||
187 | S = parm[0]; | |||
188 | /* adding the 0.5 is to ensure that weights computed within the | |||
189 | support really do catch all the non-zero values */ | |||
190 | return S/2 + 0.5; | |||
191 | } | |||
192 | ||||
193 | static double | |||
194 | _nrrdBox1_d(double x, const double *parm) { | |||
195 | double S; | |||
196 | ||||
197 | S = parm[0]; | |||
198 | x = AIR_ABS(x)((x) > 0.0f ? (x) : -(x))/S; | |||
199 | return _BOX(x)(x > 0.5 ? 0 : (x < 0.5 ? 1 : 0.5))/S; | |||
200 | } | |||
201 | ||||
202 | static float | |||
203 | _nrrdBox1_f(float x, const double *parm) { | |||
204 | float S; | |||
205 | ||||
206 | S = AIR_CAST(float, parm[0])((float)(parm[0])); | |||
207 | x = AIR_ABS(x)((x) > 0.0f ? (x) : -(x))/S; | |||
208 | return AIR_CAST(float, _BOX(x)/S)((float)((x > 0.5 ? 0 : (x < 0.5 ? 1 : 0.5))/S)); | |||
209 | } | |||
210 | ||||
211 | static void | |||
212 | _nrrdBoxN_d(double *f, const double *x, size_t len, const double *parm) { | |||
213 | double S; | |||
214 | double t; | |||
215 | size_t i; | |||
216 | ||||
217 | S = parm[0]; | |||
218 | for (i=0; i<len; i++) { | |||
219 | t = x[i]; t = AIR_ABS(t)((t) > 0.0f ? (t) : -(t))/S; | |||
220 | f[i] = _BOX(t)(t > 0.5 ? 0 : (t < 0.5 ? 1 : 0.5))/S; | |||
221 | } | |||
222 | } | |||
223 | ||||
224 | static void | |||
225 | _nrrdBoxN_f(float *f, const float *x, size_t len, const double *parm) { | |||
226 | float t, S; | |||
227 | size_t i; | |||
228 | ||||
229 | S = AIR_CAST(float, parm[0])((float)(parm[0])); | |||
230 | for (i=0; i<len; i++) { | |||
231 | t = x[i]; t = AIR_ABS(t)((t) > 0.0f ? (t) : -(t))/S; | |||
232 | f[i] = AIR_CAST(float, _BOX(t)/S)((float)((t > 0.5 ? 0 : (t < 0.5 ? 1 : 0.5))/S)); | |||
233 | } | |||
234 | } | |||
235 | ||||
236 | static NrrdKernel | |||
237 | _nrrdKernelBox = { | |||
238 | "box", | |||
239 | 1, _nrrdBoxSup, returnOne, | |||
240 | _nrrdBox1_f, _nrrdBoxN_f, _nrrdBox1_d, _nrrdBoxN_d | |||
241 | }; | |||
242 | NrrdKernel *const | |||
243 | nrrdKernelBox = &_nrrdKernelBox; | |||
244 | ||||
245 | /* ------------------------------------------------------------ */ | |||
246 | ||||
247 | static double | |||
248 | _nrrdBoxSDSup(const double *parm) { | |||
249 | ||||
250 | return parm[0]; | |||
251 | } | |||
252 | ||||
253 | static double | |||
254 | _nrrdBoxSD1_d(double x, const double *parm) { | |||
255 | AIR_UNUSED(parm)(void)(parm); | |||
256 | x = AIR_ABS(x)((x) > 0.0f ? (x) : -(x)); | |||
257 | return _BOX(x)(x > 0.5 ? 0 : (x < 0.5 ? 1 : 0.5)); | |||
258 | } | |||
259 | ||||
260 | static float | |||
261 | _nrrdBoxSD1_f(float x, const double *parm) { | |||
262 | AIR_UNUSED(parm)(void)(parm); | |||
263 | x = AIR_ABS(x)((x) > 0.0f ? (x) : -(x)); | |||
264 | return AIR_CAST(float, _BOX(x))((float)((x > 0.5 ? 0 : (x < 0.5 ? 1 : 0.5)))); | |||
265 | } | |||
266 | ||||
267 | static void | |||
268 | _nrrdBoxSDN_d(double *f, const double *x, size_t len, const double *parm) { | |||
269 | size_t i; | |||
270 | AIR_UNUSED(parm)(void)(parm); | |||
271 | for (i=0; i<len; i++) { | |||
272 | double t; | |||
273 | t = AIR_ABS(x[i])((x[i]) > 0.0f ? (x[i]) : -(x[i])); | |||
274 | f[i] = _BOX(t)(t > 0.5 ? 0 : (t < 0.5 ? 1 : 0.5)); | |||
275 | } | |||
276 | } | |||
277 | ||||
278 | static void | |||
279 | _nrrdBoxSDN_f(float *f, const float *x, size_t len, const double *parm) { | |||
280 | size_t i; | |||
281 | AIR_UNUSED(parm)(void)(parm); | |||
282 | for (i=0; i<len; i++) { | |||
283 | float t; | |||
284 | t = AIR_ABS(x[i])((x[i]) > 0.0f ? (x[i]) : -(x[i])); | |||
285 | f[i] = AIR_CAST(float, _BOX(t))((float)((t > 0.5 ? 0 : (t < 0.5 ? 1 : 0.5)))); | |||
286 | } | |||
287 | } | |||
288 | ||||
289 | static NrrdKernel | |||
290 | _nrrdKernelBoxSupportDebug = { | |||
291 | "boxsup", | |||
292 | 1, _nrrdBoxSDSup, returnOne, | |||
293 | _nrrdBoxSD1_f, _nrrdBoxSDN_f, _nrrdBoxSD1_d, _nrrdBoxSDN_d | |||
294 | }; | |||
295 | NrrdKernel *const | |||
296 | nrrdKernelBoxSupportDebug = &_nrrdKernelBoxSupportDebug; | |||
297 | ||||
298 | /* ------------------------------------------------------------ */ | |||
299 | ||||
300 | #define COS4(x)(x > 0.5 ? 0.0 : cos(3.14159265358979323846*x)*cos(3.14159265358979323846 *x)*cos(3.14159265358979323846*x)*cos(3.14159265358979323846* x)) (x > 0.5 \ | |||
301 | ? 0.0 \ | |||
302 | : cos(AIR_PI3.14159265358979323846*x)*cos(AIR_PI3.14159265358979323846*x)*cos(AIR_PI3.14159265358979323846*x)*cos(AIR_PI3.14159265358979323846*x)) | |||
303 | ||||
304 | static double | |||
305 | _nrrdCos4SDInt(const double *parm) { | |||
306 | AIR_UNUSED(parm)(void)(parm); | |||
307 | return 3.0/8.0; | |||
308 | } | |||
309 | ||||
310 | static double | |||
311 | _nrrdCos4SDSup(const double *parm) { | |||
312 | ||||
313 | return parm[0]; | |||
314 | } | |||
315 | ||||
316 | static double | |||
317 | _nrrdCos4SD1_d(double x, const double *parm) { | |||
318 | AIR_UNUSED(parm)(void)(parm); | |||
319 | x = AIR_ABS(x)((x) > 0.0f ? (x) : -(x)); | |||
320 | return COS4(x)(x > 0.5 ? 0.0 : cos(3.14159265358979323846*x)*cos(3.14159265358979323846 *x)*cos(3.14159265358979323846*x)*cos(3.14159265358979323846* x)); | |||
321 | } | |||
322 | ||||
323 | static float | |||
324 | _nrrdCos4SD1_f(float x, const double *parm) { | |||
325 | AIR_UNUSED(parm)(void)(parm); | |||
326 | x = AIR_ABS(x)((x) > 0.0f ? (x) : -(x)); | |||
327 | return AIR_CAST(float, COS4(x))((float)((x > 0.5 ? 0.0 : cos(3.14159265358979323846*x)*cos (3.14159265358979323846*x)*cos(3.14159265358979323846*x)*cos( 3.14159265358979323846*x)))); | |||
328 | } | |||
329 | ||||
330 | static void | |||
331 | _nrrdCos4SDN_d(double *f, const double *x, size_t len, const double *parm) { | |||
332 | size_t i; | |||
333 | AIR_UNUSED(parm)(void)(parm); | |||
334 | for (i=0; i<len; i++) { | |||
335 | double t; | |||
336 | t = AIR_ABS(x[i])((x[i]) > 0.0f ? (x[i]) : -(x[i])); | |||
337 | f[i] = COS4(t)(t > 0.5 ? 0.0 : cos(3.14159265358979323846*t)*cos(3.14159265358979323846 *t)*cos(3.14159265358979323846*t)*cos(3.14159265358979323846* t)); | |||
338 | } | |||
339 | } | |||
340 | ||||
341 | static void | |||
342 | _nrrdCos4SDN_f(float *f, const float *x, size_t len, const double *parm) { | |||
343 | size_t i; | |||
344 | AIR_UNUSED(parm)(void)(parm); | |||
345 | for (i=0; i<len; i++) { | |||
346 | float t; | |||
347 | t = AIR_ABS(x[i])((x[i]) > 0.0f ? (x[i]) : -(x[i])); | |||
348 | f[i] = AIR_CAST(float, COS4(t))((float)((t > 0.5 ? 0.0 : cos(3.14159265358979323846*t)*cos (3.14159265358979323846*t)*cos(3.14159265358979323846*t)*cos( 3.14159265358979323846*t)))); | |||
349 | } | |||
350 | } | |||
351 | ||||
352 | static NrrdKernel | |||
353 | _nrrdKernelCos4SupportDebug = { | |||
354 | "cos4sup", | |||
355 | 1, _nrrdCos4SDSup, _nrrdCos4SDInt, | |||
356 | _nrrdCos4SD1_f, _nrrdCos4SDN_f, _nrrdCos4SD1_d, _nrrdCos4SDN_d | |||
357 | }; | |||
358 | NrrdKernel *const | |||
359 | nrrdKernelCos4SupportDebug = &_nrrdKernelCos4SupportDebug; | |||
360 | ||||
361 | /* ------------------------------------------------------------ */ | |||
362 | ||||
363 | #define DCOS4(x)(x > 0.5 ? 0.0 : -4*3.14159265358979323846*(cos(3.14159265358979323846 *x)*cos(3.14159265358979323846*x)*cos(3.14159265358979323846* x) *sin(3.14159265358979323846*x))) (x > 0.5 \ | |||
364 | ? 0.0 \ | |||
365 | : -4*AIR_PI3.14159265358979323846*(cos(AIR_PI3.14159265358979323846*x)*cos(AIR_PI3.14159265358979323846*x)*cos(AIR_PI3.14159265358979323846*x) \ | |||
366 | *sin(AIR_PI3.14159265358979323846*x))) | |||
367 | ||||
368 | static double | |||
369 | _nrrdDCos4SDSup(const double *parm) { | |||
370 | return parm[0]; | |||
371 | } | |||
372 | ||||
373 | static double | |||
374 | _nrrdDCos4SD1_d(double x, const double *parm) { | |||
375 | int sgn; | |||
376 | AIR_UNUSED(parm)(void)(parm); | |||
377 | if (x < 0) { x = -x; sgn = -1; } else { sgn = 1; } | |||
378 | return sgn*DCOS4(x)(x > 0.5 ? 0.0 : -4*3.14159265358979323846*(cos(3.14159265358979323846 *x)*cos(3.14159265358979323846*x)*cos(3.14159265358979323846* x) *sin(3.14159265358979323846*x))); | |||
379 | } | |||
380 | ||||
381 | static float | |||
382 | _nrrdDCos4SD1_f(float x, const double *parm) { | |||
383 | int sgn; | |||
384 | AIR_UNUSED(parm)(void)(parm); | |||
385 | if (x < 0) { x = -x; sgn = -1; } else { sgn = 1; } | |||
386 | return AIR_CAST(float, sgn*DCOS4(x))((float)(sgn*(x > 0.5 ? 0.0 : -4*3.14159265358979323846*(cos (3.14159265358979323846*x)*cos(3.14159265358979323846*x)*cos( 3.14159265358979323846*x) *sin(3.14159265358979323846*x))))); | |||
387 | } | |||
388 | ||||
389 | static void | |||
390 | _nrrdDCos4SDN_d(double *f, const double *x, size_t len, const double *parm) { | |||
391 | int sgn; | |||
392 | double t; | |||
393 | size_t i; | |||
394 | AIR_UNUSED(parm)(void)(parm); | |||
395 | for (i=0; i<len; i++) { | |||
396 | t = x[i]; | |||
397 | if (t < 0) { t = -t; sgn = -1; } else { sgn = 1; } | |||
398 | f[i] = sgn*DCOS4(t)(t > 0.5 ? 0.0 : -4*3.14159265358979323846*(cos(3.14159265358979323846 *t)*cos(3.14159265358979323846*t)*cos(3.14159265358979323846* t) *sin(3.14159265358979323846*t))); | |||
399 | } | |||
400 | } | |||
401 | ||||
402 | static void | |||
403 | _nrrdDCos4SDN_f(float *f, const float *x, size_t len, const double *parm) { | |||
404 | int sgn; | |||
405 | float t; | |||
406 | size_t i; | |||
407 | AIR_UNUSED(parm)(void)(parm); | |||
408 | for (i=0; i<len; i++) { | |||
409 | t = x[i]; | |||
410 | if (t < 0) { t = -t; sgn = -1; } else { sgn = 1; } | |||
411 | f[i] = AIR_CAST(float, sgn*DCOS4(t))((float)(sgn*(t > 0.5 ? 0.0 : -4*3.14159265358979323846*(cos (3.14159265358979323846*t)*cos(3.14159265358979323846*t)*cos( 3.14159265358979323846*t) *sin(3.14159265358979323846*t))))); | |||
412 | } | |||
413 | } | |||
414 | ||||
415 | static NrrdKernel | |||
416 | _nrrdKernelCos4SupportDebugD = { | |||
417 | "cos4supD", | |||
418 | 1, _nrrdDCos4SDSup, returnZero, | |||
419 | _nrrdDCos4SD1_f, _nrrdDCos4SDN_f, _nrrdDCos4SD1_d, _nrrdDCos4SDN_d | |||
420 | }; | |||
421 | NrrdKernel *const | |||
422 | nrrdKernelCos4SupportDebugD = &_nrrdKernelCos4SupportDebugD; | |||
423 | ||||
424 | /* ------------------------------------------------------------ */ | |||
425 | ||||
426 | #define DDCOS4(x)(x > 0.5 ? 0.0 : -2*3.14159265358979323846*3.14159265358979323846 *(cos(3.14159265358979323846*2*x) + cos(3.14159265358979323846 *4*x))) (x > 0.5 \ | |||
427 | ? 0.0 \ | |||
428 | : -2*AIR_PI3.14159265358979323846*AIR_PI3.14159265358979323846*(cos(AIR_PI3.14159265358979323846*2*x) + cos(AIR_PI3.14159265358979323846*4*x))) | |||
429 | ||||
430 | static double | |||
431 | _nrrdDDCos4SDSup(const double *parm) { | |||
432 | return parm[0]; | |||
433 | } | |||
434 | ||||
435 | static double | |||
436 | _nrrdDDCos4SD1_d(double x, const double *parm) { | |||
437 | AIR_UNUSED(parm)(void)(parm); | |||
438 | x = AIR_ABS(x)((x) > 0.0f ? (x) : -(x)); | |||
439 | return DDCOS4(x)(x > 0.5 ? 0.0 : -2*3.14159265358979323846*3.14159265358979323846 *(cos(3.14159265358979323846*2*x) + cos(3.14159265358979323846 *4*x))); | |||
440 | } | |||
441 | ||||
442 | static float | |||
443 | _nrrdDDCos4SD1_f(float x, const double *parm) { | |||
444 | AIR_UNUSED(parm)(void)(parm); | |||
445 | x = AIR_ABS(x)((x) > 0.0f ? (x) : -(x)); | |||
446 | return AIR_CAST(float, DDCOS4(x))((float)((x > 0.5 ? 0.0 : -2*3.14159265358979323846*3.14159265358979323846 *(cos(3.14159265358979323846*2*x) + cos(3.14159265358979323846 *4*x))))); | |||
447 | } | |||
448 | ||||
449 | static void | |||
450 | _nrrdDDCos4SDN_d(double *f, const double *x, size_t len, const double *parm) { | |||
451 | size_t i; | |||
452 | AIR_UNUSED(parm)(void)(parm); | |||
453 | for (i=0; i<len; i++) { | |||
454 | double t; | |||
455 | t = AIR_ABS(x[i])((x[i]) > 0.0f ? (x[i]) : -(x[i])); | |||
456 | f[i] = DDCOS4(t)(t > 0.5 ? 0.0 : -2*3.14159265358979323846*3.14159265358979323846 *(cos(3.14159265358979323846*2*t) + cos(3.14159265358979323846 *4*t))); | |||
457 | } | |||
458 | } | |||
459 | ||||
460 | static void | |||
461 | _nrrdDDCos4SDN_f(float *f, const float *x, size_t len, const double *parm) { | |||
462 | size_t i; | |||
463 | AIR_UNUSED(parm)(void)(parm); | |||
464 | for (i=0; i<len; i++) { | |||
465 | float t; | |||
466 | t = AIR_ABS(x[i])((x[i]) > 0.0f ? (x[i]) : -(x[i])); | |||
467 | f[i] = AIR_CAST(float, DDCOS4(t))((float)((t > 0.5 ? 0.0 : -2*3.14159265358979323846*3.14159265358979323846 *(cos(3.14159265358979323846*2*t) + cos(3.14159265358979323846 *4*t))))); | |||
468 | } | |||
469 | } | |||
470 | ||||
471 | static NrrdKernel | |||
472 | _nrrdKernelCos4SupportDebugDD = { | |||
473 | "cos4supDD", | |||
474 | 1, _nrrdDDCos4SDSup, returnZero, | |||
475 | _nrrdDDCos4SD1_f, _nrrdDDCos4SDN_f, _nrrdDDCos4SD1_d, _nrrdDDCos4SDN_d | |||
476 | }; | |||
477 | NrrdKernel *const | |||
478 | nrrdKernelCos4SupportDebugDD = &_nrrdKernelCos4SupportDebugDD; | |||
479 | ||||
480 | /* ------------------------------------------------------------ */ | |||
481 | ||||
482 | #define DDDCOS4(x)(x > 0.5 ? 0.0 : 4*3.14159265358979323846*3.14159265358979323846 *3.14159265358979323846*(sin(2*3.14159265358979323846*x) + 2* sin(4*3.14159265358979323846*x))) (x > 0.5 \ | |||
483 | ? 0.0 \ | |||
484 | : 4*AIR_PI3.14159265358979323846*AIR_PI3.14159265358979323846*AIR_PI3.14159265358979323846*(sin(2*AIR_PI3.14159265358979323846*x) + 2*sin(4*AIR_PI3.14159265358979323846*x))) | |||
485 | ||||
486 | static double | |||
487 | _nrrdDDDCos4SDSup(const double *parm) { | |||
488 | return parm[0]; | |||
489 | } | |||
490 | ||||
491 | static double | |||
492 | _nrrdDDDCos4SD1_d(double x, const double *parm) { | |||
493 | int sgn; | |||
494 | AIR_UNUSED(parm)(void)(parm); | |||
495 | if (x < 0) { x = -x; sgn = -1; } else { sgn = 1; } | |||
496 | return sgn*DDDCOS4(x)(x > 0.5 ? 0.0 : 4*3.14159265358979323846*3.14159265358979323846 *3.14159265358979323846*(sin(2*3.14159265358979323846*x) + 2* sin(4*3.14159265358979323846*x))); | |||
497 | } | |||
498 | ||||
499 | static float | |||
500 | _nrrdDDDCos4SD1_f(float x, const double *parm) { | |||
501 | int sgn; | |||
502 | AIR_UNUSED(parm)(void)(parm); | |||
503 | if (x < 0) { x = -x; sgn = -1; } else { sgn = 1; } | |||
504 | return AIR_CAST(float, sgn*DDDCOS4(x))((float)(sgn*(x > 0.5 ? 0.0 : 4*3.14159265358979323846*3.14159265358979323846 *3.14159265358979323846*(sin(2*3.14159265358979323846*x) + 2* sin(4*3.14159265358979323846*x))))); | |||
505 | } | |||
506 | ||||
507 | static void | |||
508 | _nrrdDDDCos4SDN_d(double *f, const double *x, size_t len, const double *parm) { | |||
509 | int sgn; | |||
510 | double t; | |||
511 | size_t i; | |||
512 | AIR_UNUSED(parm)(void)(parm); | |||
513 | for (i=0; i<len; i++) { | |||
514 | t = x[i]; | |||
515 | if (t < 0) { t = -t; sgn = -1; } else { sgn = 1; } | |||
516 | f[i] = sgn*DDDCOS4(t)(t > 0.5 ? 0.0 : 4*3.14159265358979323846*3.14159265358979323846 *3.14159265358979323846*(sin(2*3.14159265358979323846*t) + 2* sin(4*3.14159265358979323846*t))); | |||
517 | } | |||
518 | } | |||
519 | ||||
520 | static void | |||
521 | _nrrdDDDCos4SDN_f(float *f, const float *x, size_t len, const double *parm) { | |||
522 | int sgn; | |||
523 | float t; | |||
524 | size_t i; | |||
525 | AIR_UNUSED(parm)(void)(parm); | |||
526 | for (i=0; i<len; i++) { | |||
527 | t = x[i]; | |||
528 | if (t < 0) { t = -t; sgn = -1; } else { sgn = 1; } | |||
529 | f[i] = AIR_CAST(float, sgn*DDDCOS4(t))((float)(sgn*(t > 0.5 ? 0.0 : 4*3.14159265358979323846*3.14159265358979323846 *3.14159265358979323846*(sin(2*3.14159265358979323846*t) + 2* sin(4*3.14159265358979323846*t))))); | |||
530 | } | |||
531 | } | |||
532 | ||||
533 | static NrrdKernel | |||
534 | _nrrdKernelCos4SupportDebugDDD = { | |||
535 | "cos4supDDD", | |||
536 | 1, _nrrdDDDCos4SDSup, returnZero, | |||
537 | _nrrdDDDCos4SD1_f, _nrrdDDDCos4SDN_f, _nrrdDDDCos4SD1_d, _nrrdDDDCos4SDN_d | |||
538 | }; | |||
539 | NrrdKernel *const | |||
540 | nrrdKernelCos4SupportDebugDDD = &_nrrdKernelCos4SupportDebugDDD; | |||
541 | ||||
542 | /* ------------------------------------------------------------ */ | |||
543 | ||||
544 | /* The point here is that post-kernel-evaluation, we need to see | |||
545 | which sample is closest to the origin, and this is one way of | |||
546 | enabling that | |||
547 | SO: this kernel will not usefully report its integral or support! */ | |||
548 | #define _CHEAP(x)((x) > 0.0f ? (x) : -(x)) AIR_ABS(x)((x) > 0.0f ? (x) : -(x)) | |||
549 | ||||
550 | static double | |||
551 | _nrrdCheapSup(const double *parm) { | |||
552 | double S; | |||
553 | ||||
554 | S = parm[0]; | |||
555 | /* adding the 0.5 is to insure that weights computed within the | |||
556 | support really do catch all the non-zero values */ | |||
557 | return S/2 + 0.5; | |||
558 | } | |||
559 | ||||
560 | static double | |||
561 | _nrrdCheap1_d(double x, const double *parm) { | |||
562 | ||||
563 | return _CHEAP(x)((x) > 0.0f ? (x) : -(x))/parm[0]; | |||
564 | } | |||
565 | ||||
566 | static float | |||
567 | _nrrdCheap1_f(float x, const double *parm) { | |||
568 | ||||
569 | return AIR_CAST(float, _CHEAP(x)/parm[0])((float)(((x) > 0.0f ? (x) : -(x))/parm[0])); | |||
570 | } | |||
571 | ||||
572 | static void | |||
573 | _nrrdCheapN_d(double *f, const double *x, size_t len, const double *parm) { | |||
574 | double t; | |||
575 | size_t i; | |||
576 | ||||
577 | for (i=0; i<len; i++) { | |||
578 | t = x[i]; | |||
579 | f[i] = _CHEAP(t)((t) > 0.0f ? (t) : -(t))/parm[0]; | |||
580 | } | |||
581 | } | |||
582 | ||||
583 | static void | |||
584 | _nrrdCheapN_f(float *f, const float *x, size_t len, const double *parm) { | |||
585 | float t; | |||
586 | size_t i; | |||
587 | ||||
588 | for (i=0; i<len; i++) { | |||
589 | t = x[i]; | |||
590 | f[i] = AIR_CAST(float, _CHEAP(t)/parm[0])((float)(((t) > 0.0f ? (t) : -(t))/parm[0])); | |||
591 | } | |||
592 | } | |||
593 | ||||
594 | static NrrdKernel | |||
595 | _nrrdKernelCheap = { | |||
596 | "cheap", | |||
597 | 1, _nrrdCheapSup, returnOne, | |||
598 | _nrrdCheap1_f, _nrrdCheapN_f, _nrrdCheap1_d, _nrrdCheapN_d | |||
599 | }; | |||
600 | NrrdKernel *const | |||
601 | nrrdKernelCheap = &_nrrdKernelCheap; | |||
602 | ||||
603 | /* ------------------------------------------------------------ */ | |||
604 | ||||
605 | #define _TENT(x)(x >= 1 ? 0 : 1 - x) (x >= 1 ? 0 : 1 - x) | |||
606 | ||||
607 | static double | |||
608 | _nrrdTentSup(const double *parm) { | |||
609 | double S; | |||
610 | ||||
611 | S = parm[0]; | |||
612 | return S; | |||
613 | } | |||
614 | ||||
615 | static double | |||
616 | _nrrdTent1_d(double x, const double *parm) { | |||
617 | double S; | |||
618 | ||||
619 | S = parm[0]; | |||
620 | x = AIR_ABS(x)((x) > 0.0f ? (x) : -(x))/S; | |||
621 | return S ? _TENT(x)(x >= 1 ? 0 : 1 - x)/S : x == 0; | |||
622 | } | |||
623 | ||||
624 | static float | |||
625 | _nrrdTent1_f(float x, const double *parm) { | |||
626 | float S; | |||
627 | ||||
628 | S = AIR_CAST(float, parm[0])((float)(parm[0])); | |||
629 | x = AIR_ABS(x)((x) > 0.0f ? (x) : -(x))/S; | |||
630 | return S ? _TENT(x)(x >= 1 ? 0 : 1 - x)/S : x == 0; | |||
631 | } | |||
632 | ||||
633 | static void | |||
634 | _nrrdTentN_d(double *f, const double *x, size_t len, const double *parm) { | |||
635 | double S; | |||
636 | double t; | |||
637 | size_t i; | |||
638 | ||||
639 | S = parm[0]; | |||
640 | for (i=0; i<len; i++) { | |||
641 | t = x[i]; t = AIR_ABS(t)((t) > 0.0f ? (t) : -(t))/S; | |||
642 | f[i] = S ? _TENT(t)(t >= 1 ? 0 : 1 - t)/S : t == 0; | |||
643 | } | |||
644 | } | |||
645 | ||||
646 | static void | |||
647 | _nrrdTentN_f(float *f, const float *x, size_t len, const double *parm) { | |||
648 | float t, S; | |||
649 | size_t i; | |||
650 | ||||
651 | S = AIR_CAST(float, parm[0])((float)(parm[0])); | |||
652 | for (i=0; i<len; i++) { | |||
653 | t = x[i]; t = AIR_ABS(t)((t) > 0.0f ? (t) : -(t))/S; | |||
654 | f[i] = S ? _TENT(t)(t >= 1 ? 0 : 1 - t)/S : t == 0; | |||
655 | } | |||
656 | } | |||
657 | ||||
658 | static NrrdKernel | |||
659 | _nrrdKernelTent = { | |||
660 | "tent", | |||
661 | 1, _nrrdTentSup, returnOne, | |||
662 | _nrrdTent1_f, _nrrdTentN_f, _nrrdTent1_d, _nrrdTentN_d | |||
663 | }; | |||
664 | NrrdKernel *const | |||
665 | nrrdKernelTent = &_nrrdKernelTent; | |||
666 | ||||
667 | /* ------------------------------------------------------------ */ | |||
668 | ||||
669 | /* | |||
670 | ** NOTE: THERE IS NOT REALLY A HERMITE KERNEL (at least not yet, | |||
671 | ** because it takes both values and derivatives as arguments, which | |||
672 | ** the NrrdKernel currently can't handle). This isn't really a | |||
673 | ** kernel, its mostly a flag (hence the name), but it also has the | |||
674 | ** role of generating weights according to linear interpolation, which | |||
675 | ** is useful for the eventual spline evaluation. | |||
676 | ** | |||
677 | ** This hack is in sinister collusion with gage, to enable Hermite | |||
678 | ** interpolation for its stack reconstruction. | |||
679 | */ | |||
680 | ||||
681 | static double | |||
682 | _nrrdHermite1_d(double x, const double *parm) { | |||
683 | AIR_UNUSED(parm)(void)(parm); | |||
684 | x = AIR_ABS(x)((x) > 0.0f ? (x) : -(x)); | |||
685 | return _TENT(x)(x >= 1 ? 0 : 1 - x); | |||
686 | } | |||
687 | ||||
688 | static float | |||
689 | _nrrdHermite1_f(float x, const double *parm) { | |||
690 | AIR_UNUSED(parm)(void)(parm); | |||
691 | x = AIR_ABS(x)((x) > 0.0f ? (x) : -(x)); | |||
692 | return _TENT(x)(x >= 1 ? 0 : 1 - x); | |||
693 | } | |||
694 | ||||
695 | static void | |||
696 | _nrrdHermiteN_d(double *f, const double *x, size_t len, const double *parm) { | |||
697 | double t; | |||
698 | size_t i; | |||
699 | AIR_UNUSED(parm)(void)(parm); | |||
700 | for (i=0; i<len; i++) { | |||
701 | t = x[i]; t = AIR_ABS(t)((t) > 0.0f ? (t) : -(t)); | |||
702 | f[i] = _TENT(t)(t >= 1 ? 0 : 1 - t); | |||
703 | } | |||
704 | } | |||
705 | ||||
706 | static void | |||
707 | _nrrdHermiteN_f(float *f, const float *x, size_t len, const double *parm) { | |||
708 | float t; | |||
709 | size_t i; | |||
710 | AIR_UNUSED(parm)(void)(parm); | |||
711 | for (i=0; i<len; i++) { | |||
712 | t = x[i]; t = AIR_ABS(t)((t) > 0.0f ? (t) : -(t)); | |||
713 | f[i] = _TENT(t)(t >= 1 ? 0 : 1 - t); | |||
714 | } | |||
715 | } | |||
716 | ||||
717 | /* HEY: should just re-use fields from nrrdKernelTent, instead | |||
718 | of creating new functions */ | |||
719 | static NrrdKernel | |||
720 | _nrrdKernelHermiteScaleSpaceFlag = { | |||
721 | "hermiteSS", | |||
722 | 0, returnOne, returnOne, | |||
723 | _nrrdHermite1_f, _nrrdHermiteN_f, _nrrdHermite1_d, _nrrdHermiteN_d | |||
724 | }; | |||
725 | NrrdKernel *const | |||
726 | nrrdKernelHermiteScaleSpaceFlag = &_nrrdKernelHermiteScaleSpaceFlag; | |||
727 | ||||
728 | /* ------------------------------------------------------------ */ | |||
729 | ||||
730 | #define _FORDIF(x)(x < -1 ? 0.0f : (x < 0 ? 1.0f : (x < 1 ? -1.0f : 0.0f ))) (x < -1 ? 0.0f : \ | |||
731 | (x < 0 ? 1.0f : \ | |||
732 | (x < 1 ? -1.0f : 0.0f ))) | |||
733 | ||||
734 | static double | |||
735 | _nrrdFDSup(const double *parm) { | |||
736 | double S; | |||
737 | ||||
738 | S = parm[0]; | |||
739 | return S+0.0001; /* sigh */ | |||
740 | } | |||
741 | ||||
742 | static double | |||
743 | _nrrdFD1_d(double x, const double *parm) { | |||
744 | double t, S; | |||
745 | ||||
746 | S = parm[0]; | |||
747 | t = x/S; | |||
748 | return _FORDIF(t)(t < -1 ? 0.0f : (t < 0 ? 1.0f : (t < 1 ? -1.0f : 0.0f )))/(S*S); | |||
749 | } | |||
750 | ||||
751 | static float | |||
752 | _nrrdFD1_f(float x, const double *parm) { | |||
753 | float t, S; | |||
754 | ||||
755 | S = AIR_CAST(float, parm[0])((float)(parm[0])); | |||
756 | t = x/S; | |||
757 | return _FORDIF(t)(t < -1 ? 0.0f : (t < 0 ? 1.0f : (t < 1 ? -1.0f : 0.0f )))/(S*S); | |||
758 | } | |||
759 | ||||
760 | static void | |||
761 | _nrrdFDN_d(double *f, const double *x, size_t len, const double *parm) { | |||
762 | double t, S; | |||
763 | size_t i; | |||
764 | ||||
765 | S = parm[0]; | |||
766 | for (i=0; i<len; i++) { | |||
767 | t = x[i]/S; | |||
768 | f[i] = _FORDIF(t)(t < -1 ? 0.0f : (t < 0 ? 1.0f : (t < 1 ? -1.0f : 0.0f )))/(S*S); | |||
769 | } | |||
770 | } | |||
771 | ||||
772 | static void | |||
773 | _nrrdFDN_f(float *f, const float *x, size_t len, const double *parm) { | |||
774 | float t, S; | |||
775 | size_t i; | |||
776 | ||||
777 | S = AIR_CAST(float, parm[0])((float)(parm[0])); | |||
778 | for (i=0; i<len; i++) { | |||
779 | t = x[i]/S; | |||
780 | f[i] = _FORDIF(t)(t < -1 ? 0.0f : (t < 0 ? 1.0f : (t < 1 ? -1.0f : 0.0f )))/(S*S); | |||
781 | } | |||
782 | } | |||
783 | ||||
784 | static NrrdKernel | |||
785 | _nrrdKernelFD = { | |||
786 | "fordif", | |||
787 | 1, _nrrdFDSup, returnZero, | |||
788 | _nrrdFD1_f, _nrrdFDN_f, _nrrdFD1_d, _nrrdFDN_d | |||
789 | }; | |||
790 | NrrdKernel *const | |||
791 | nrrdKernelForwDiff = &_nrrdKernelFD; | |||
792 | ||||
793 | /* ------------------------------------------------------------ */ | |||
794 | ||||
795 | #define _CENDIF(x)(x <= -2 ? 0 : (x <= -1 ? 0.5*x + 1 : (x <= 1 ? -0.5 *x : (x <= 2 ? 0.5*x - 1 : 0 )))) (x <= -2 ? 0 : \ | |||
796 | (x <= -1 ? 0.5*x + 1 : \ | |||
797 | (x <= 1 ? -0.5*x : \ | |||
798 | (x <= 2 ? 0.5*x - 1 : 0 )))) | |||
799 | ||||
800 | static double | |||
801 | _nrrdCDSup(const double *parm) { | |||
802 | double S; | |||
803 | ||||
804 | S = parm[0]; | |||
805 | return 2*S; | |||
806 | } | |||
807 | ||||
808 | static double | |||
809 | _nrrdCD1_d(double x, const double *parm) { | |||
810 | double S; | |||
811 | ||||
812 | S = parm[0]; | |||
813 | x /= S; | |||
814 | return _CENDIF(x)(x <= -2 ? 0 : (x <= -1 ? 0.5*x + 1 : (x <= 1 ? -0.5 *x : (x <= 2 ? 0.5*x - 1 : 0 ))))/(S*S); | |||
815 | } | |||
816 | ||||
817 | static float | |||
818 | _nrrdCD1_f(float x, const double *parm) { | |||
819 | float S; | |||
820 | ||||
821 | S = AIR_CAST(float, parm[0])((float)(parm[0])); | |||
822 | x /= S; | |||
823 | return AIR_CAST(float, _CENDIF(x)/(S*S))((float)((x <= -2 ? 0 : (x <= -1 ? 0.5*x + 1 : (x <= 1 ? -0.5*x : (x <= 2 ? 0.5*x - 1 : 0 ))))/(S*S))); | |||
824 | } | |||
825 | ||||
826 | static void | |||
827 | _nrrdCDN_d(double *f, const double *x, size_t len, const double *parm) { | |||
828 | double S; | |||
829 | double t; | |||
830 | size_t i; | |||
831 | ||||
832 | S = parm[0]; | |||
833 | for (i=0; i<len; i++) { | |||
834 | t = x[i]/S; | |||
835 | f[i] = _CENDIF(t)(t <= -2 ? 0 : (t <= -1 ? 0.5*t + 1 : (t <= 1 ? -0.5 *t : (t <= 2 ? 0.5*t - 1 : 0 ))))/(S*S); | |||
836 | } | |||
837 | } | |||
838 | ||||
839 | static void | |||
840 | _nrrdCDN_f(float *f, const float *x, size_t len, const double *parm) { | |||
841 | float t, S; | |||
842 | size_t i; | |||
843 | ||||
844 | S = AIR_CAST(float, parm[0])((float)(parm[0])); | |||
845 | for (i=0; i<len; i++) { | |||
846 | t = x[i]/S; | |||
847 | f[i] = AIR_CAST(float, _CENDIF(t)/(S*S))((float)((t <= -2 ? 0 : (t <= -1 ? 0.5*t + 1 : (t <= 1 ? -0.5*t : (t <= 2 ? 0.5*t - 1 : 0 ))))/(S*S))); | |||
848 | } | |||
849 | } | |||
850 | ||||
851 | static NrrdKernel | |||
852 | _nrrdKernelCD = { | |||
853 | "cendif", | |||
854 | 1, _nrrdCDSup, returnZero, | |||
855 | _nrrdCD1_f, _nrrdCDN_f, _nrrdCD1_d, _nrrdCDN_d | |||
856 | }; | |||
857 | NrrdKernel *const | |||
858 | nrrdKernelCentDiff = &_nrrdKernelCD; | |||
859 | ||||
860 | /* ------------------------------------------------------------ */ | |||
861 | ||||
862 | #define _BCCUBIC(x, B, C)(x >= 2.0 ? 0 : (x >= 1.0 ? (((-B/6 - C)*x + B + 5*C)*x -2*B - 8*C)*x + 4*B/3 + 4*C : ((2 - 3*B/2 - C)*x - 3 + 2*B + C)*x*x + 1 - B/3)) \ | |||
863 | (x >= 2.0 ? 0 : \ | |||
864 | (x >= 1.0 \ | |||
865 | ? (((-B/6 - C)*x + B + 5*C)*x -2*B - 8*C)*x + 4*B/3 + 4*C \ | |||
866 | : ((2 - 3*B/2 - C)*x - 3 + 2*B + C)*x*x + 1 - B/3)) | |||
867 | ||||
868 | static double | |||
869 | _nrrdBCSup(const double *parm) { | |||
870 | double S; | |||
871 | ||||
872 | S = parm[0]; | |||
873 | return 2*S; | |||
874 | } | |||
875 | ||||
876 | static double | |||
877 | _nrrdBC1_d(double x, const double *parm) { | |||
878 | double S; | |||
879 | double B, C; | |||
880 | ||||
881 | S = parm[0]; B = parm[1]; C = parm[2]; | |||
882 | x = AIR_ABS(x)((x) > 0.0f ? (x) : -(x))/S; | |||
883 | return _BCCUBIC(x, B, C)(x >= 2.0 ? 0 : (x >= 1.0 ? (((-B/6 - C)*x + B + 5*C)*x -2*B - 8*C)*x + 4*B/3 + 4*C : ((2 - 3*B/2 - C)*x - 3 + 2*B + C)*x*x + 1 - B/3))/S; | |||
884 | } | |||
885 | ||||
886 | static float | |||
887 | _nrrdBC1_f(float x, const double *parm) { | |||
888 | float B, C, S; | |||
889 | ||||
890 | S = AIR_CAST(float, parm[0])((float)(parm[0])); | |||
891 | B = AIR_CAST(float, parm[1])((float)(parm[1])); | |||
892 | C = AIR_CAST(float, parm[2])((float)(parm[2])); | |||
893 | x = AIR_ABS(x)((x) > 0.0f ? (x) : -(x))/S; | |||
894 | return _BCCUBIC(x, B, C)(x >= 2.0 ? 0 : (x >= 1.0 ? (((-B/6 - C)*x + B + 5*C)*x -2*B - 8*C)*x + 4*B/3 + 4*C : ((2 - 3*B/2 - C)*x - 3 + 2*B + C)*x*x + 1 - B/3))/S; | |||
895 | } | |||
896 | ||||
897 | static void | |||
898 | _nrrdBCN_d(double *f, const double *x, size_t len, const double *parm) { | |||
899 | double S; | |||
900 | double t, B, C; | |||
901 | size_t i; | |||
902 | ||||
903 | S = parm[0]; B = parm[1]; C = parm[2]; | |||
904 | for (i=0; i<len; i++) { | |||
905 | t = x[i]; | |||
906 | t = AIR_ABS(t)((t) > 0.0f ? (t) : -(t))/S; | |||
907 | f[i] = _BCCUBIC(t, B, C)(t >= 2.0 ? 0 : (t >= 1.0 ? (((-B/6 - C)*t + B + 5*C)*t -2*B - 8*C)*t + 4*B/3 + 4*C : ((2 - 3*B/2 - C)*t - 3 + 2*B + C)*t*t + 1 - B/3))/S; | |||
908 | } | |||
909 | } | |||
910 | ||||
911 | static void | |||
912 | _nrrdBCN_f(float *f, const float *x, size_t len, const double *parm) { | |||
913 | float S, t, B, C; | |||
914 | size_t i; | |||
915 | ||||
916 | S = AIR_CAST(float, parm[0])((float)(parm[0])); | |||
917 | B = AIR_CAST(float, parm[1])((float)(parm[1])); | |||
918 | C = AIR_CAST(float, parm[2])((float)(parm[2])); | |||
919 | for (i=0; i<len; i++) { | |||
920 | t = x[i]; | |||
921 | t = AIR_ABS(t)((t) > 0.0f ? (t) : -(t))/S; | |||
922 | f[i] = _BCCUBIC(t, B, C)(t >= 2.0 ? 0 : (t >= 1.0 ? (((-B/6 - C)*t + B + 5*C)*t -2*B - 8*C)*t + 4*B/3 + 4*C : ((2 - 3*B/2 - C)*t - 3 + 2*B + C)*t*t + 1 - B/3))/S; | |||
923 | } | |||
924 | } | |||
925 | ||||
926 | static NrrdKernel | |||
927 | _nrrdKernelBC = { | |||
928 | "BCcubic", | |||
929 | 3, _nrrdBCSup, returnOne, | |||
930 | _nrrdBC1_f, _nrrdBCN_f, _nrrdBC1_d, _nrrdBCN_d | |||
931 | }; | |||
932 | NrrdKernel *const | |||
933 | nrrdKernelBCCubic = &_nrrdKernelBC; | |||
934 | ||||
935 | /* ------------------------------------------------------------ */ | |||
936 | ||||
937 | #define _DBCCUBIC(x, B, C)(x >= 2.0 ? 0.0 : (x >= 1.0 ? ((-B/2 - 3*C)*x + 2*B + 10 *C)*x -2*B - 8*C : ((6 - 9*B/2 - 3*C)*x - 6 + 4*B + 2*C)*x)) \ | |||
938 | (x >= 2.0 ? 0.0 : \ | |||
939 | (x >= 1.0 \ | |||
940 | ? ((-B/2 - 3*C)*x + 2*B + 10*C)*x -2*B - 8*C \ | |||
941 | : ((6 - 9*B/2 - 3*C)*x - 6 + 4*B + 2*C)*x)) | |||
942 | ||||
943 | static double | |||
944 | _nrrdDBCSup(const double *parm) { | |||
945 | double S; | |||
946 | ||||
947 | S = parm[0]; | |||
948 | return 2*S; | |||
949 | } | |||
950 | ||||
951 | static double | |||
952 | _nrrdDBC1_d(double x, const double *parm) { | |||
953 | double S; | |||
954 | double B, C; | |||
955 | int sgn = 1; | |||
956 | ||||
957 | S = parm[0]; B = parm[1]; C = parm[2]; | |||
958 | if (x < 0) { x = -x; sgn = -1; } | |||
959 | x /= S; | |||
960 | return sgn*_DBCCUBIC(x, B, C)(x >= 2.0 ? 0.0 : (x >= 1.0 ? ((-B/2 - 3*C)*x + 2*B + 10 *C)*x -2*B - 8*C : ((6 - 9*B/2 - 3*C)*x - 6 + 4*B + 2*C)*x))/(S*S); | |||
961 | } | |||
962 | ||||
963 | static float | |||
964 | _nrrdDBC1_f(float x, const double *parm) { | |||
965 | float B, C, S; | |||
966 | int sgn = 1; | |||
967 | ||||
968 | S = AIR_CAST(float, parm[0])((float)(parm[0])); | |||
969 | B = AIR_CAST(float, parm[1])((float)(parm[1])); | |||
970 | C = AIR_CAST(float, parm[2])((float)(parm[2])); | |||
971 | if (x < 0) { x = -x; sgn = -1; } | |||
972 | x /= S; | |||
973 | return AIR_CAST(float, sgn*_DBCCUBIC(x, B, C)/(S*S))((float)(sgn*(x >= 2.0 ? 0.0 : (x >= 1.0 ? ((-B/2 - 3*C )*x + 2*B + 10*C)*x -2*B - 8*C : ((6 - 9*B/2 - 3*C)*x - 6 + 4 *B + 2*C)*x))/(S*S))); | |||
974 | } | |||
975 | ||||
976 | static void | |||
977 | _nrrdDBCN_d(double *f, const double *x, size_t len, const double *parm) { | |||
978 | double S; | |||
979 | double t, B, C; | |||
980 | size_t i; | |||
981 | int sgn; | |||
982 | ||||
983 | S = parm[0]; B = parm[1]; C = parm[2]; | |||
984 | for (i=0; i<len; i++) { | |||
985 | t = x[i]/S; | |||
986 | if (t < 0) { t = -t; sgn = -1; } else { sgn = 1; } | |||
987 | f[i] = sgn*_DBCCUBIC(t, B, C)(t >= 2.0 ? 0.0 : (t >= 1.0 ? ((-B/2 - 3*C)*t + 2*B + 10 *C)*t -2*B - 8*C : ((6 - 9*B/2 - 3*C)*t - 6 + 4*B + 2*C)*t))/(S*S); | |||
988 | } | |||
989 | } | |||
990 | ||||
991 | static void | |||
992 | _nrrdDBCN_f(float *f, const float *x, size_t len, const double *parm) { | |||
993 | float S, t, B, C; | |||
994 | int sgn; | |||
995 | size_t i; | |||
996 | ||||
997 | S = AIR_CAST(float, parm[0])((float)(parm[0])); | |||
998 | B = AIR_CAST(float, parm[1])((float)(parm[1])); | |||
999 | C = AIR_CAST(float, parm[2])((float)(parm[2])); | |||
1000 | for (i=0; i<len; i++) { | |||
1001 | t = x[i]/S; | |||
1002 | if (t < 0) { t = -t; sgn = -1; } else { sgn = 1; } | |||
1003 | f[i] = AIR_CAST(float, sgn*_DBCCUBIC(t, B, C)/(S*S))((float)(sgn*(t >= 2.0 ? 0.0 : (t >= 1.0 ? ((-B/2 - 3*C )*t + 2*B + 10*C)*t -2*B - 8*C : ((6 - 9*B/2 - 3*C)*t - 6 + 4 *B + 2*C)*t))/(S*S))); | |||
1004 | } | |||
1005 | } | |||
1006 | ||||
1007 | static NrrdKernel | |||
1008 | _nrrdKernelDBC = { | |||
1009 | "BCcubicD", | |||
1010 | 3, _nrrdDBCSup, returnZero, | |||
1011 | _nrrdDBC1_f, _nrrdDBCN_f, _nrrdDBC1_d, _nrrdDBCN_d | |||
1012 | }; | |||
1013 | NrrdKernel *const | |||
1014 | nrrdKernelBCCubicD = &_nrrdKernelDBC; | |||
1015 | ||||
1016 | /* ------------------------------------------------------------ */ | |||
1017 | ||||
1018 | #define _DDBCCUBIC(x, B, C)(x >= 2.0 ? 0 : (x >= 1.0 ? (-B - 6*C)*x + 2*B + 10*C : (12 - 9*B - 6*C)*x - 6 + 4*B + 2*C )) \ | |||
1019 | (x >= 2.0 ? 0 : \ | |||
1020 | (x >= 1.0 \ | |||
1021 | ? (-B - 6*C)*x + 2*B + 10*C \ | |||
1022 | : (12 - 9*B - 6*C)*x - 6 + 4*B + 2*C )) | |||
1023 | ||||
1024 | static double | |||
1025 | _nrrdDDBCSup(const double *parm) { | |||
1026 | double S; | |||
1027 | ||||
1028 | S = parm[0]; | |||
1029 | return 2*S; | |||
1030 | } | |||
1031 | ||||
1032 | static double | |||
1033 | _nrrdDDBC1_d(double x, const double *parm) { | |||
1034 | double S; | |||
1035 | double B, C; | |||
1036 | ||||
1037 | S = parm[0]; B = parm[1]; C = parm[2]; | |||
1038 | x = AIR_ABS(x)((x) > 0.0f ? (x) : -(x))/S; | |||
1039 | return _DDBCCUBIC(x, B, C)(x >= 2.0 ? 0 : (x >= 1.0 ? (-B - 6*C)*x + 2*B + 10*C : (12 - 9*B - 6*C)*x - 6 + 4*B + 2*C ))/(S*S*S); | |||
1040 | } | |||
1041 | ||||
1042 | static float | |||
1043 | _nrrdDDBC1_f(float x, const double *parm) { | |||
1044 | float B, C, S; | |||
1045 | ||||
1046 | S = AIR_CAST(float, parm[0])((float)(parm[0])); | |||
1047 | B = AIR_CAST(float, parm[1])((float)(parm[1])); | |||
1048 | C = AIR_CAST(float, parm[2])((float)(parm[2])); | |||
1049 | x = AIR_ABS(x)((x) > 0.0f ? (x) : -(x))/S; | |||
1050 | return _DDBCCUBIC(x, B, C)(x >= 2.0 ? 0 : (x >= 1.0 ? (-B - 6*C)*x + 2*B + 10*C : (12 - 9*B - 6*C)*x - 6 + 4*B + 2*C ))/(S*S*S); | |||
1051 | } | |||
1052 | ||||
1053 | static void | |||
1054 | _nrrdDDBCN_d(double *f, const double *x, size_t len, const double *parm) { | |||
1055 | double S; | |||
1056 | double t, B, C; | |||
1057 | size_t i; | |||
1058 | ||||
1059 | S = parm[0]; B = parm[1]; C = parm[2]; | |||
1060 | for (i=0; i<len; i++) { | |||
1061 | t = x[i]; | |||
1062 | t = AIR_ABS(t)((t) > 0.0f ? (t) : -(t))/S; | |||
1063 | f[i] = _DDBCCUBIC(t, B, C)(t >= 2.0 ? 0 : (t >= 1.0 ? (-B - 6*C)*t + 2*B + 10*C : (12 - 9*B - 6*C)*t - 6 + 4*B + 2*C ))/(S*S*S); | |||
1064 | } | |||
1065 | } | |||
1066 | ||||
1067 | static void | |||
1068 | _nrrdDDBCN_f(float *f, const float *x, size_t len, const double *parm) { | |||
1069 | float S, t, B, C; | |||
1070 | size_t i; | |||
1071 | ||||
1072 | S = AIR_CAST(float, parm[0])((float)(parm[0])); | |||
1073 | B = AIR_CAST(float, parm[1])((float)(parm[1])); | |||
1074 | C = AIR_CAST(float, parm[2])((float)(parm[2])); | |||
1075 | for (i=0; i<len; i++) { | |||
1076 | t = x[i]; | |||
1077 | t = AIR_ABS(t)((t) > 0.0f ? (t) : -(t))/S; | |||
1078 | f[i] = _DDBCCUBIC(t, B, C)(t >= 2.0 ? 0 : (t >= 1.0 ? (-B - 6*C)*t + 2*B + 10*C : (12 - 9*B - 6*C)*t - 6 + 4*B + 2*C ))/(S*S*S); | |||
1079 | } | |||
1080 | } | |||
1081 | ||||
1082 | static NrrdKernel | |||
1083 | _nrrdKernelDDBC = { | |||
1084 | "BCcubicDD", | |||
1085 | 3, _nrrdDDBCSup, returnZero, | |||
1086 | _nrrdDDBC1_f, _nrrdDDBCN_f, _nrrdDDBC1_d, _nrrdDDBCN_d | |||
1087 | }; | |||
1088 | NrrdKernel *const | |||
1089 | nrrdKernelBCCubicDD = &_nrrdKernelDDBC; | |||
1090 | ||||
1091 | /* ------------------------------------------------------------ */ | |||
1092 | ||||
1093 | /* if you've got the definition already, why not use it */ | |||
1094 | #define _CTMR(x)(x >= 2.0 ? 0 : (x >= 1.0 ? (((-0.0/6 - 0.5)*x + 0.0 + 5 *0.5)*x -2*0.0 - 8*0.5)*x + 4*0.0/3 + 4*0.5 : ((2 - 3*0.0/2 - 0.5)*x - 3 + 2*0.0 + 0.5)*x*x + 1 - 0.0/3)) _BCCUBIC(x, 0.0, 0.5)(x >= 2.0 ? 0 : (x >= 1.0 ? (((-0.0/6 - 0.5)*x + 0.0 + 5 *0.5)*x -2*0.0 - 8*0.5)*x + 4*0.0/3 + 4*0.5 : ((2 - 3*0.0/2 - 0.5)*x - 3 + 2*0.0 + 0.5)*x*x + 1 - 0.0/3)) | |||
1095 | ||||
1096 | static double | |||
1097 | _nrrdCTMR1_d(double x, const double *parm) { | |||
1098 | AIR_UNUSED(parm)(void)(parm); | |||
1099 | x = AIR_ABS(x)((x) > 0.0f ? (x) : -(x)); | |||
1100 | return _CTMR(x)(x >= 2.0 ? 0 : (x >= 1.0 ? (((-0.0/6 - 0.5)*x + 0.0 + 5 *0.5)*x -2*0.0 - 8*0.5)*x + 4*0.0/3 + 4*0.5 : ((2 - 3*0.0/2 - 0.5)*x - 3 + 2*0.0 + 0.5)*x*x + 1 - 0.0/3)); | |||
1101 | } | |||
1102 | ||||
1103 | static float | |||
1104 | _nrrdCTMR1_f(float x, const double *parm) { | |||
1105 | AIR_UNUSED(parm)(void)(parm); | |||
1106 | x = AIR_ABS(x)((x) > 0.0f ? (x) : -(x)); | |||
1107 | return AIR_CAST(float, _CTMR(x))((float)((x >= 2.0 ? 0 : (x >= 1.0 ? (((-0.0/6 - 0.5)*x + 0.0 + 5*0.5)*x -2*0.0 - 8*0.5)*x + 4*0.0/3 + 4*0.5 : ((2 - 3*0.0/2 - 0.5)*x - 3 + 2*0.0 + 0.5)*x*x + 1 - 0.0/3)))); | |||
1108 | } | |||
1109 | ||||
1110 | static void | |||
1111 | _nrrdCTMRN_d(double *f, const double *x, size_t len, const double *parm) { | |||
1112 | double t; | |||
1113 | size_t i; | |||
1114 | AIR_UNUSED(parm)(void)(parm); | |||
1115 | for (i=0; i<len; i++) { | |||
1116 | t = x[i]; | |||
1117 | t = AIR_ABS(t)((t) > 0.0f ? (t) : -(t)); | |||
1118 | f[i] = _CTMR(t)(t >= 2.0 ? 0 : (t >= 1.0 ? (((-0.0/6 - 0.5)*t + 0.0 + 5 *0.5)*t -2*0.0 - 8*0.5)*t + 4*0.0/3 + 4*0.5 : ((2 - 3*0.0/2 - 0.5)*t - 3 + 2*0.0 + 0.5)*t*t + 1 - 0.0/3)); | |||
1119 | } | |||
1120 | } | |||
1121 | ||||
1122 | static void | |||
1123 | _nrrdCTMRN_f(float *f, const float *x, size_t len, const double *parm) { | |||
1124 | float t; | |||
1125 | size_t i; | |||
1126 | AIR_UNUSED(parm)(void)(parm); | |||
1127 | for (i=0; i<len; i++) { | |||
1128 | t = x[i]; | |||
1129 | t = AIR_ABS(t)((t) > 0.0f ? (t) : -(t)); | |||
1130 | f[i] = AIR_CAST(float, _CTMR(t))((float)((t >= 2.0 ? 0 : (t >= 1.0 ? (((-0.0/6 - 0.5)*t + 0.0 + 5*0.5)*t -2*0.0 - 8*0.5)*t + 4*0.0/3 + 4*0.5 : ((2 - 3*0.0/2 - 0.5)*t - 3 + 2*0.0 + 0.5)*t*t + 1 - 0.0/3)))); | |||
1131 | } | |||
1132 | } | |||
1133 | ||||
1134 | static NrrdKernel | |||
1135 | _nrrdKernelCatmullRom = { | |||
1136 | "catmull-rom", | |||
1137 | 0, returnTwo, returnOne, | |||
1138 | _nrrdCTMR1_f, _nrrdCTMRN_f, _nrrdCTMR1_d, _nrrdCTMRN_d | |||
1139 | }; | |||
1140 | NrrdKernel *const | |||
1141 | nrrdKernelCatmullRom = &_nrrdKernelCatmullRom; | |||
1142 | ||||
1143 | ||||
1144 | static double | |||
1145 | _nrrdCtmrSDSup(const double *parm) { | |||
1146 | ||||
1147 | return AIR_MAX(2.0, parm[0])((2.0) > (parm[0]) ? (2.0) : (parm[0])); | |||
1148 | } | |||
1149 | ||||
1150 | static NrrdKernel | |||
1151 | _nrrdKernelCatmullRomSupportDebug = { | |||
1152 | "ctmrsup", | |||
1153 | 1, _nrrdCtmrSDSup, returnOne, | |||
1154 | _nrrdCTMR1_f, _nrrdCTMRN_f, _nrrdCTMR1_d, _nrrdCTMRN_d | |||
1155 | }; | |||
1156 | NrrdKernel *const | |||
1157 | nrrdKernelCatmullRomSupportDebug = &_nrrdKernelCatmullRomSupportDebug; | |||
1158 | ||||
1159 | /* ------------------------------------------------------------ */ | |||
1160 | ||||
1161 | /* if you've got the definition already, why not use it */ | |||
1162 | #define _DCTMR(x)(x >= 2.0 ? 0.0 : (x >= 1.0 ? ((-0.0/2 - 3*0.5)*x + 2*0.0 + 10*0.5)*x -2*0.0 - 8*0.5 : ((6 - 9*0.0/2 - 3*0.5)*x - 6 + 4 *0.0 + 2*0.5)*x)) _DBCCUBIC(x, 0.0, 0.5)(x >= 2.0 ? 0.0 : (x >= 1.0 ? ((-0.0/2 - 3*0.5)*x + 2*0.0 + 10*0.5)*x -2*0.0 - 8*0.5 : ((6 - 9*0.0/2 - 3*0.5)*x - 6 + 4 *0.0 + 2*0.5)*x)) | |||
1163 | ||||
1164 | static double | |||
1165 | _nrrdDCTMR1_d(double x, const double *parm) { | |||
1166 | int sgn; | |||
1167 | AIR_UNUSED(parm)(void)(parm); | |||
1168 | if (x < 0) { x = -x; sgn = -1; } else { sgn = 1; } | |||
1169 | return sgn*_DCTMR(x)(x >= 2.0 ? 0.0 : (x >= 1.0 ? ((-0.0/2 - 3*0.5)*x + 2*0.0 + 10*0.5)*x -2*0.0 - 8*0.5 : ((6 - 9*0.0/2 - 3*0.5)*x - 6 + 4 *0.0 + 2*0.5)*x)); | |||
1170 | } | |||
1171 | ||||
1172 | static float | |||
1173 | _nrrdDCTMR1_f(float x, const double *parm) { | |||
1174 | int sgn; | |||
1175 | AIR_UNUSED(parm)(void)(parm); | |||
1176 | if (x < 0) { x = -x; sgn = -1; } else { sgn = 1; } | |||
1177 | return AIR_CAST(float, sgn*_DCTMR(x))((float)(sgn*(x >= 2.0 ? 0.0 : (x >= 1.0 ? ((-0.0/2 - 3 *0.5)*x + 2*0.0 + 10*0.5)*x -2*0.0 - 8*0.5 : ((6 - 9*0.0/2 - 3 *0.5)*x - 6 + 4*0.0 + 2*0.5)*x)))); | |||
1178 | } | |||
1179 | ||||
1180 | static void | |||
1181 | _nrrdDCTMRN_d(double *f, const double *x, size_t len, const double *parm) { | |||
1182 | int sgn; | |||
1183 | double t; | |||
1184 | size_t i; | |||
1185 | AIR_UNUSED(parm)(void)(parm); | |||
1186 | for (i=0; i<len; i++) { | |||
1187 | t = x[i]; | |||
1188 | if (t < 0) { t = -t; sgn = -1; } else { sgn = 1; } | |||
1189 | f[i] = sgn*_DCTMR(t)(t >= 2.0 ? 0.0 : (t >= 1.0 ? ((-0.0/2 - 3*0.5)*t + 2*0.0 + 10*0.5)*t -2*0.0 - 8*0.5 : ((6 - 9*0.0/2 - 3*0.5)*t - 6 + 4 *0.0 + 2*0.5)*t)); | |||
1190 | } | |||
1191 | } | |||
1192 | ||||
1193 | static void | |||
1194 | _nrrdDCTMRN_f(float *f, const float *x, size_t len, const double *parm) { | |||
1195 | int sgn; | |||
1196 | float t; | |||
1197 | size_t i; | |||
1198 | AIR_UNUSED(parm)(void)(parm); | |||
1199 | for (i=0; i<len; i++) { | |||
1200 | t = x[i]; | |||
1201 | if (t < 0) { t = -t; sgn = -1; } else { sgn = 1; } | |||
1202 | f[i] = AIR_CAST(float, sgn*_DCTMR(t))((float)(sgn*(t >= 2.0 ? 0.0 : (t >= 1.0 ? ((-0.0/2 - 3 *0.5)*t + 2*0.0 + 10*0.5)*t -2*0.0 - 8*0.5 : ((6 - 9*0.0/2 - 3 *0.5)*t - 6 + 4*0.0 + 2*0.5)*t)))); | |||
1203 | } | |||
1204 | } | |||
1205 | ||||
1206 | static NrrdKernel | |||
1207 | _nrrdKernelCatmullRomD = { | |||
1208 | "catmull-romD", | |||
1209 | 0, returnTwo, returnZero, | |||
1210 | _nrrdDCTMR1_f, _nrrdDCTMRN_f, _nrrdDCTMR1_d, _nrrdDCTMRN_d | |||
1211 | }; | |||
1212 | NrrdKernel *const | |||
1213 | nrrdKernelCatmullRomD = &_nrrdKernelCatmullRomD; | |||
1214 | ||||
1215 | static NrrdKernel | |||
1216 | _nrrdKernelCatmullRomSupportDebugD = { | |||
1217 | "ctmrsupD", | |||
1218 | 1, _nrrdCtmrSDSup, returnZero, | |||
1219 | _nrrdDCTMR1_f, _nrrdDCTMRN_f, _nrrdDCTMR1_d, _nrrdDCTMRN_d | |||
1220 | }; | |||
1221 | NrrdKernel *const | |||
1222 | nrrdKernelCatmullRomSupportDebugD = &_nrrdKernelCatmullRomSupportDebugD; | |||
1223 | ||||
1224 | /* ------------------------------------------------------------ */ | |||
1225 | ||||
1226 | /* if you've got the definition already, why not use it */ | |||
1227 | #define _DDCTMR(x)(x >= 2.0 ? 0 : (x >= 1.0 ? (-0.0 - 6*0.5)*x + 2*0.0 + 10 *0.5 : (12 - 9*0.0 - 6*0.5)*x - 6 + 4*0.0 + 2*0.5 )) _DDBCCUBIC(x, 0.0, 0.5)(x >= 2.0 ? 0 : (x >= 1.0 ? (-0.0 - 6*0.5)*x + 2*0.0 + 10 *0.5 : (12 - 9*0.0 - 6*0.5)*x - 6 + 4*0.0 + 2*0.5 )) | |||
1228 | ||||
1229 | static double | |||
1230 | _nrrdDDCTMR1_d(double x, const double *parm) { | |||
1231 | AIR_UNUSED(parm)(void)(parm); | |||
1232 | x = AIR_ABS(x)((x) > 0.0f ? (x) : -(x)); | |||
1233 | return _DDCTMR(x)(x >= 2.0 ? 0 : (x >= 1.0 ? (-0.0 - 6*0.5)*x + 2*0.0 + 10 *0.5 : (12 - 9*0.0 - 6*0.5)*x - 6 + 4*0.0 + 2*0.5 )); | |||
1234 | } | |||
1235 | ||||
1236 | static float | |||
1237 | _nrrdDDCTMR1_f(float x, const double *parm) { | |||
1238 | AIR_UNUSED(parm)(void)(parm); | |||
1239 | x = AIR_ABS(x)((x) > 0.0f ? (x) : -(x)); | |||
1240 | return AIR_CAST(float, _DDCTMR(x))((float)((x >= 2.0 ? 0 : (x >= 1.0 ? (-0.0 - 6*0.5)*x + 2*0.0 + 10*0.5 : (12 - 9*0.0 - 6*0.5)*x - 6 + 4*0.0 + 2*0.5 ) ))); | |||
1241 | } | |||
1242 | ||||
1243 | static void | |||
1244 | _nrrdDDCTMRN_d(double *f, const double *x, size_t len, const double *parm) { | |||
1245 | double t; | |||
1246 | size_t i; | |||
1247 | AIR_UNUSED(parm)(void)(parm); | |||
1248 | for (i=0; i<len; i++) { | |||
1249 | t = x[i]; | |||
1250 | t = AIR_ABS(t)((t) > 0.0f ? (t) : -(t)); | |||
1251 | f[i] = _DDCTMR(t)(t >= 2.0 ? 0 : (t >= 1.0 ? (-0.0 - 6*0.5)*t + 2*0.0 + 10 *0.5 : (12 - 9*0.0 - 6*0.5)*t - 6 + 4*0.0 + 2*0.5 )); | |||
1252 | } | |||
1253 | } | |||
1254 | ||||
1255 | static void | |||
1256 | _nrrdDDCTMRN_f(float *f, const float *x, size_t len, const double *parm) { | |||
1257 | float t; | |||
1258 | size_t i; | |||
1259 | AIR_UNUSED(parm)(void)(parm); | |||
1260 | for (i=0; i<len; i++) { | |||
1261 | t = x[i]; | |||
1262 | t = AIR_ABS(t)((t) > 0.0f ? (t) : -(t)); | |||
1263 | f[i] = AIR_CAST(float, _DDCTMR(t))((float)((t >= 2.0 ? 0 : (t >= 1.0 ? (-0.0 - 6*0.5)*t + 2*0.0 + 10*0.5 : (12 - 9*0.0 - 6*0.5)*t - 6 + 4*0.0 + 2*0.5 ) ))); | |||
1264 | } | |||
1265 | } | |||
1266 | ||||
1267 | static NrrdKernel | |||
1268 | _nrrdKernelCatmullRomDD = { | |||
1269 | "catmull-romDD", | |||
1270 | 0, returnTwo, returnZero, | |||
1271 | _nrrdDDCTMR1_f, _nrrdDDCTMRN_f, _nrrdDDCTMR1_d, _nrrdDDCTMRN_d | |||
1272 | }; | |||
1273 | NrrdKernel *const | |||
1274 | nrrdKernelCatmullRomDD = &_nrrdKernelCatmullRomDD; | |||
1275 | ||||
1276 | static NrrdKernel | |||
1277 | _nrrdKernelCatmullRomSupportDebugDD = { | |||
1278 | "ctmrsupDD", | |||
1279 | 1, _nrrdCtmrSDSup, returnZero, | |||
1280 | _nrrdDDCTMR1_f, _nrrdDDCTMRN_f, _nrrdDDCTMR1_d, _nrrdDDCTMRN_d | |||
1281 | }; | |||
1282 | NrrdKernel *const | |||
1283 | nrrdKernelCatmullRomSupportDebugDD = &_nrrdKernelCatmullRomSupportDebugDD; | |||
1284 | ||||
1285 | /* ------------------------------------------------------------ */ | |||
1286 | ||||
1287 | #define _AQUARTIC(x, A)(x >= 3.0 ? 0 : (x >= 2.0 ? A*(-54 + x*(81 + x*(-45 + x *(11 - x)))) : (x >= 1.0 ? 4 - 6*A + x*(-10 + 25*A + x*(9 - 33*A + x*(-3.5 + 17*A + x*(0.5 - 3*A)))) : 1 + x*x*(-3 + 6*A + x*((2.5 - 10*A) + x*(-0.5 + 4*A)))))) \ | |||
1288 | (x >= 3.0 ? 0 : \ | |||
1289 | (x >= 2.0 \ | |||
1290 | ? A*(-54 + x*(81 + x*(-45 + x*(11 - x)))) \ | |||
1291 | : (x >= 1.0 \ | |||
1292 | ? 4 - 6*A + x*(-10 + 25*A + x*(9 - 33*A \ | |||
1293 | + x*(-3.5 + 17*A + x*(0.5 - 3*A)))) \ | |||
1294 | : 1 + x*x*(-3 + 6*A + x*((2.5 - 10*A) + x*(-0.5 + 4*A)))))) | |||
1295 | ||||
1296 | static double | |||
1297 | _nrrdA4Sup(const double *parm) { | |||
1298 | double S; | |||
1299 | ||||
1300 | S = parm[0]; | |||
1301 | return 3*S; | |||
1302 | } | |||
1303 | ||||
1304 | static double | |||
1305 | _nrrdA41_d(double x, const double *parm) { | |||
1306 | double S; | |||
1307 | double A; | |||
1308 | ||||
1309 | S = parm[0]; A = parm[1]; | |||
1310 | x = AIR_ABS(x)((x) > 0.0f ? (x) : -(x))/S; | |||
1311 | return _AQUARTIC(x, A)(x >= 3.0 ? 0 : (x >= 2.0 ? A*(-54 + x*(81 + x*(-45 + x *(11 - x)))) : (x >= 1.0 ? 4 - 6*A + x*(-10 + 25*A + x*(9 - 33*A + x*(-3.5 + 17*A + x*(0.5 - 3*A)))) : 1 + x*x*(-3 + 6*A + x*((2.5 - 10*A) + x*(-0.5 + 4*A))))))/S; | |||
1312 | } | |||
1313 | ||||
1314 | static float | |||
1315 | _nrrdA41_f(float x, const double *parm) { | |||
1316 | float A, S; | |||
1317 | ||||
1318 | S = AIR_CAST(float, parm[0])((float)(parm[0])); A = AIR_CAST(float, parm[1])((float)(parm[1])); | |||
1319 | x = AIR_ABS(x)((x) > 0.0f ? (x) : -(x))/S; | |||
1320 | return AIR_CAST(float, _AQUARTIC(x, A)/S)((float)((x >= 3.0 ? 0 : (x >= 2.0 ? A*(-54 + x*(81 + x *(-45 + x*(11 - x)))) : (x >= 1.0 ? 4 - 6*A + x*(-10 + 25* A + x*(9 - 33*A + x*(-3.5 + 17*A + x*(0.5 - 3*A)))) : 1 + x*x *(-3 + 6*A + x*((2.5 - 10*A) + x*(-0.5 + 4*A))))))/S)); | |||
1321 | } | |||
1322 | ||||
1323 | static void | |||
1324 | _nrrdA4N_d(double *f, const double *x, size_t len, const double *parm) { | |||
1325 | double S; | |||
1326 | double t, A; | |||
1327 | size_t i; | |||
1328 | ||||
1329 | S = parm[0]; A = parm[1]; | |||
1330 | for (i=0; i<len; i++) { | |||
1331 | t = x[i]; | |||
1332 | t = AIR_ABS(t)((t) > 0.0f ? (t) : -(t))/S; | |||
1333 | f[i] = _AQUARTIC(t, A)(t >= 3.0 ? 0 : (t >= 2.0 ? A*(-54 + t*(81 + t*(-45 + t *(11 - t)))) : (t >= 1.0 ? 4 - 6*A + t*(-10 + 25*A + t*(9 - 33*A + t*(-3.5 + 17*A + t*(0.5 - 3*A)))) : 1 + t*t*(-3 + 6*A + t*((2.5 - 10*A) + t*(-0.5 + 4*A))))))/S; | |||
1334 | } | |||
1335 | } | |||
1336 | ||||
1337 | static void | |||
1338 | _nrrdA4N_f(float *f, const float *x, size_t len, const double *parm) { | |||
1339 | float S, t, A; | |||
1340 | size_t i; | |||
1341 | ||||
1342 | S = AIR_CAST(float, parm[0])((float)(parm[0])); A = AIR_CAST(float, parm[1])((float)(parm[1])); | |||
1343 | for (i=0; i<len; i++) { | |||
1344 | t = x[i]; | |||
1345 | t = AIR_ABS(t)((t) > 0.0f ? (t) : -(t))/S; | |||
1346 | f[i] = AIR_CAST(float, _AQUARTIC(t, A)/S)((float)((t >= 3.0 ? 0 : (t >= 2.0 ? A*(-54 + t*(81 + t *(-45 + t*(11 - t)))) : (t >= 1.0 ? 4 - 6*A + t*(-10 + 25* A + t*(9 - 33*A + t*(-3.5 + 17*A + t*(0.5 - 3*A)))) : 1 + t*t *(-3 + 6*A + t*((2.5 - 10*A) + t*(-0.5 + 4*A))))))/S)); | |||
1347 | } | |||
1348 | } | |||
1349 | ||||
1350 | static NrrdKernel | |||
1351 | _nrrdKernelA4 = { | |||
1352 | "Aquartic", | |||
1353 | 2, _nrrdA4Sup, returnOne, | |||
1354 | _nrrdA41_f, _nrrdA4N_f, _nrrdA41_d, _nrrdA4N_d | |||
1355 | }; | |||
1356 | NrrdKernel *const | |||
1357 | nrrdKernelAQuartic = &_nrrdKernelA4; | |||
1358 | ||||
1359 | /* ------------------------------------------------------------ */ | |||
1360 | ||||
1361 | #define _DAQUARTIC(x, A)(x >= 3.0 ? 0 : (x >= 2.0 ? A*(81 + x*(-90 + x*(33 - 4* x))) : (x >= 1.0 ? -10 + 25*A + x*(18 - 66*A + x*(-10.5 + 51 *A + x*(2 - 12*A))) : x*(-6 + 12*A + x*(7.5 - 30*A + x*(-2 + 16 *A)))))) \ | |||
1362 | (x >= 3.0 ? 0 : \ | |||
1363 | (x >= 2.0 \ | |||
1364 | ? A*(81 + x*(-90 + x*(33 - 4*x))) \ | |||
1365 | : (x >= 1.0 \ | |||
1366 | ? -10 + 25*A + x*(18 - 66*A + x*(-10.5 + 51*A + x*(2 - 12*A))) \ | |||
1367 | : x*(-6 + 12*A + x*(7.5 - 30*A + x*(-2 + 16*A)))))) | |||
1368 | ||||
1369 | static double | |||
1370 | _nrrdDA4Sup(const double *parm) { | |||
1371 | double S; | |||
1372 | ||||
1373 | S = parm[0]; | |||
1374 | return 3*S; | |||
1375 | } | |||
1376 | ||||
1377 | static double | |||
1378 | _nrrdDA41_d(double x, const double *parm) { | |||
1379 | double S; | |||
1380 | double A; | |||
1381 | int sgn = 1; | |||
1382 | ||||
1383 | S = parm[0]; A = parm[1]; | |||
1384 | if (x < 0) { x = -x; sgn = -1; } | |||
1385 | x /= S; | |||
1386 | return sgn*_DAQUARTIC(x, A)(x >= 3.0 ? 0 : (x >= 2.0 ? A*(81 + x*(-90 + x*(33 - 4* x))) : (x >= 1.0 ? -10 + 25*A + x*(18 - 66*A + x*(-10.5 + 51 *A + x*(2 - 12*A))) : x*(-6 + 12*A + x*(7.5 - 30*A + x*(-2 + 16 *A))))))/(S*S); | |||
1387 | } | |||
1388 | ||||
1389 | static float | |||
1390 | _nrrdDA41_f(float x, const double *parm) { | |||
1391 | float A, S; | |||
1392 | int sgn = 1; | |||
1393 | ||||
1394 | S = AIR_CAST(float, parm[0])((float)(parm[0])); A = AIR_CAST(float, parm[1])((float)(parm[1])); | |||
1395 | if (x < 0) { x = -x; sgn = -1; } | |||
1396 | x /= S; | |||
1397 | return AIR_CAST(float, sgn*_DAQUARTIC(x, A)/(S*S))((float)(sgn*(x >= 3.0 ? 0 : (x >= 2.0 ? A*(81 + x*(-90 + x*(33 - 4*x))) : (x >= 1.0 ? -10 + 25*A + x*(18 - 66*A + x*(-10.5 + 51*A + x*(2 - 12*A))) : x*(-6 + 12*A + x*(7.5 - 30 *A + x*(-2 + 16*A))))))/(S*S))); | |||
1398 | } | |||
1399 | ||||
1400 | static void | |||
1401 | _nrrdDA4N_d(double *f, const double *x, size_t len, const double *parm) { | |||
1402 | double S; | |||
1403 | double t, A; | |||
1404 | size_t i; | |||
1405 | int sgn; | |||
1406 | ||||
1407 | S = parm[0]; A = parm[1]; | |||
1408 | for (i=0; i<len; i++) { | |||
1409 | t = x[i]/S; | |||
1410 | if (t < 0) { t = -t; sgn = -1; } else { sgn = 1; } | |||
1411 | f[i] = sgn*_DAQUARTIC(t, A)(t >= 3.0 ? 0 : (t >= 2.0 ? A*(81 + t*(-90 + t*(33 - 4* t))) : (t >= 1.0 ? -10 + 25*A + t*(18 - 66*A + t*(-10.5 + 51 *A + t*(2 - 12*A))) : t*(-6 + 12*A + t*(7.5 - 30*A + t*(-2 + 16 *A))))))/(S*S); | |||
1412 | } | |||
1413 | } | |||
1414 | ||||
1415 | static void | |||
1416 | _nrrdDA4N_f(float *f, const float *x, size_t len, const double *parm) { | |||
1417 | float S, t, A; | |||
1418 | size_t i; | |||
1419 | int sgn; | |||
1420 | ||||
1421 | S = AIR_CAST(float, parm[0])((float)(parm[0])); A = AIR_CAST(float, parm[1])((float)(parm[1])); | |||
1422 | for (i=0; i<len; i++) { | |||
1423 | t = x[i]/S; | |||
1424 | if (t < 0) { t = -t; sgn = -1; } else { sgn = 1; } | |||
1425 | f[i] = AIR_CAST(float, sgn*_DAQUARTIC(t, A)/(S*S))((float)(sgn*(t >= 3.0 ? 0 : (t >= 2.0 ? A*(81 + t*(-90 + t*(33 - 4*t))) : (t >= 1.0 ? -10 + 25*A + t*(18 - 66*A + t*(-10.5 + 51*A + t*(2 - 12*A))) : t*(-6 + 12*A + t*(7.5 - 30 *A + t*(-2 + 16*A))))))/(S*S))); | |||
1426 | } | |||
1427 | } | |||
1428 | ||||
1429 | static NrrdKernel | |||
1430 | _nrrdKernelDA4 = { | |||
1431 | "AquarticD", | |||
1432 | 2, _nrrdDA4Sup, returnZero, | |||
1433 | _nrrdDA41_f, _nrrdDA4N_f, _nrrdDA41_d, _nrrdDA4N_d | |||
1434 | }; | |||
1435 | NrrdKernel *const | |||
1436 | nrrdKernelAQuarticD = &_nrrdKernelDA4; | |||
1437 | ||||
1438 | /* ------------------------------------------------------------ */ | |||
1439 | ||||
1440 | #define _DDAQUARTIC(x, A)(x >= 3.0 ? 0 : (x >= 2.0 ? A*(-90 + x*(66 - x*12)) : ( x >= 1.0 ? 18 - 66*A + x*(-21 + 102*A + x*(6 - 36*A)) : -6 + 12*A + x*(15 - 60*A + x*(-6 + 48*A))))) \ | |||
1441 | (x >= 3.0 ? 0 : \ | |||
1442 | (x >= 2.0 \ | |||
1443 | ? A*(-90 + x*(66 - x*12)) \ | |||
1444 | : (x >= 1.0 \ | |||
1445 | ? 18 - 66*A + x*(-21 + 102*A + x*(6 - 36*A)) \ | |||
1446 | : -6 + 12*A + x*(15 - 60*A + x*(-6 + 48*A))))) | |||
1447 | ||||
1448 | static double | |||
1449 | _nrrdDDA4Sup(const double *parm) { | |||
1450 | double S; | |||
1451 | ||||
1452 | S = parm[0]; | |||
1453 | return 3*S; | |||
1454 | } | |||
1455 | ||||
1456 | static double | |||
1457 | _nrrdDDA41_d(double x, const double *parm) { | |||
1458 | double S; | |||
1459 | double A; | |||
1460 | ||||
1461 | S = parm[0]; A = parm[1]; | |||
1462 | x = AIR_ABS(x)((x) > 0.0f ? (x) : -(x))/S; | |||
1463 | return _DDAQUARTIC(x, A)(x >= 3.0 ? 0 : (x >= 2.0 ? A*(-90 + x*(66 - x*12)) : ( x >= 1.0 ? 18 - 66*A + x*(-21 + 102*A + x*(6 - 36*A)) : -6 + 12*A + x*(15 - 60*A + x*(-6 + 48*A)))))/(S*S*S); | |||
1464 | } | |||
1465 | ||||
1466 | static float | |||
1467 | _nrrdDDA41_f(float x, const double *parm) { | |||
1468 | float S, A; | |||
1469 | ||||
1470 | S = AIR_CAST(float, parm[0])((float)(parm[0])); A = AIR_CAST(float, parm[1])((float)(parm[1])); | |||
1471 | x = AIR_ABS(x)((x) > 0.0f ? (x) : -(x))/S; | |||
1472 | return _DDAQUARTIC(x, A)(x >= 3.0 ? 0 : (x >= 2.0 ? A*(-90 + x*(66 - x*12)) : ( x >= 1.0 ? 18 - 66*A + x*(-21 + 102*A + x*(6 - 36*A)) : -6 + 12*A + x*(15 - 60*A + x*(-6 + 48*A)))))/(S*S*S); | |||
1473 | } | |||
1474 | ||||
1475 | static void | |||
1476 | _nrrdDDA4N_d(double *f, const double *x, size_t len, const double *parm) { | |||
1477 | double S; | |||
1478 | double t, A; | |||
1479 | size_t i; | |||
1480 | ||||
1481 | S = parm[0]; A = parm[1]; | |||
1482 | for (i=0; i<len; i++) { | |||
1483 | t = x[i]; | |||
1484 | t = AIR_ABS(t)((t) > 0.0f ? (t) : -(t))/S; | |||
1485 | f[i] = _DDAQUARTIC(t, A)(t >= 3.0 ? 0 : (t >= 2.0 ? A*(-90 + t*(66 - t*12)) : ( t >= 1.0 ? 18 - 66*A + t*(-21 + 102*A + t*(6 - 36*A)) : -6 + 12*A + t*(15 - 60*A + t*(-6 + 48*A)))))/(S*S*S); | |||
1486 | } | |||
1487 | } | |||
1488 | ||||
1489 | static void | |||
1490 | _nrrdDDA4N_f(float *f, const float *x, size_t len, const double *parm) { | |||
1491 | float S, t, A; | |||
1492 | size_t i; | |||
1493 | ||||
1494 | S = AIR_CAST(float, parm[0])((float)(parm[0])); A = AIR_CAST(float, parm[1])((float)(parm[1])); | |||
1495 | for (i=0; i<len; i++) { | |||
1496 | t = x[i]; | |||
1497 | t = AIR_ABS(t)((t) > 0.0f ? (t) : -(t))/S; | |||
1498 | f[i] = _DDAQUARTIC(t, A)(t >= 3.0 ? 0 : (t >= 2.0 ? A*(-90 + t*(66 - t*12)) : ( t >= 1.0 ? 18 - 66*A + t*(-21 + 102*A + t*(6 - 36*A)) : -6 + 12*A + t*(15 - 60*A + t*(-6 + 48*A)))))/(S*S*S); | |||
1499 | } | |||
1500 | } | |||
1501 | ||||
1502 | static NrrdKernel | |||
1503 | _nrrdKernelDDA4 = { | |||
1504 | "AquarticDD", | |||
1505 | 2, _nrrdDDA4Sup, returnZero, | |||
1506 | _nrrdDDA41_f, _nrrdDDA4N_f, _nrrdDDA41_d, _nrrdDDA4N_d | |||
1507 | }; | |||
1508 | NrrdKernel *const | |||
1509 | nrrdKernelAQuarticDD = &_nrrdKernelDDA4; | |||
1510 | ||||
1511 | /* ------------------------------------------------------------ */ | |||
1512 | ||||
1513 | /* | |||
1514 | ** This is the unique, four-sample support, quintic, C^3 kernel, with 1st and | |||
1515 | ** 3rd derivatives zero at origin, which integrates to unity on [-2,2], which | |||
1516 | ** exactly reconstructs 0th and 1st order polynomials. Unfortunately it does | |||
1517 | ** NOT reconstruct 2nd order polynomials, so its not very useful. It worse | |||
1518 | ** than "one step down" from c4hexic (see below), since while its support and | |||
1519 | ** polynomial power is one less than c4hexic, it cannot reconstruct | |||
1520 | ** parabolas; c4hexic can reconstruct cubics. | |||
1521 | ** | |||
1522 | ** The same kernel is also available as nrrdKernelTMF w/ D,C,A = -1,3,2 == | |||
1523 | ** TMF_dn_c3_2ef == "tmf:n,3,2" == nrrdKernelTMF[0][4][2], the only advantage | |||
1524 | ** here being that you have access to the first and second derivatives of | |||
1525 | ** this quintic kernel as nrrdKernelC3QuinticD and nrrdKernelC3QuinticDD. | |||
1526 | ** | |||
1527 | ** By the way, TMF_d0_c3_3ef == TMF_dn_c3_3ef == "tmf:n,3,3", which can (by | |||
1528 | ** definition) reconstruct parabolas, has four-sample support, and has | |||
1529 | ** piecewise polynomial order *seven* | |||
1530 | */ | |||
1531 | ||||
1532 | #define _C3QUINTIC(x)(x >= 2.0 ? 0 : (x >= 1.0 ? 0.8 + x*x*(-2 + x*(2 + x*(- 0.75 + x*0.1))) : 0.7 + x*x*(-1 + x*x*(0.75 - x*0.3)))) \ | |||
1533 | (x >= 2.0 ? 0 : \ | |||
1534 | (x >= 1.0 \ | |||
1535 | ? 0.8 + x*x*(-2 + x*(2 + x*(-0.75 + x*0.1))) \ | |||
1536 | : 0.7 + x*x*(-1 + x*x*(0.75 - x*0.3)))) | |||
1537 | ||||
1538 | static double | |||
1539 | _c3quint1_d(double x, const double *parm) { | |||
1540 | AIR_UNUSED(parm)(void)(parm); | |||
1541 | x = AIR_ABS(x)((x) > 0.0f ? (x) : -(x)); | |||
1542 | return _C3QUINTIC(x)(x >= 2.0 ? 0 : (x >= 1.0 ? 0.8 + x*x*(-2 + x*(2 + x*(- 0.75 + x*0.1))) : 0.7 + x*x*(-1 + x*x*(0.75 - x*0.3)))); | |||
1543 | } | |||
1544 | ||||
1545 | static float | |||
1546 | _c3quint1_f(float x, const double *parm) { | |||
1547 | AIR_UNUSED(parm)(void)(parm); | |||
1548 | x = AIR_ABS(x)((x) > 0.0f ? (x) : -(x)); | |||
1549 | return AIR_CAST(float, _C3QUINTIC(x))((float)((x >= 2.0 ? 0 : (x >= 1.0 ? 0.8 + x*x*(-2 + x* (2 + x*(-0.75 + x*0.1))) : 0.7 + x*x*(-1 + x*x*(0.75 - x*0.3) ))))); | |||
1550 | } | |||
1551 | ||||
1552 | static void | |||
1553 | _c3quintN_d(double *f, const double *x, size_t len, const double *parm) { | |||
1554 | double t; | |||
1555 | size_t i; | |||
1556 | AIR_UNUSED(parm)(void)(parm); | |||
1557 | for (i=0; i<len; i++) { | |||
1558 | t = x[i]; | |||
1559 | t = AIR_ABS(t)((t) > 0.0f ? (t) : -(t)); | |||
1560 | f[i] = _C3QUINTIC(t)(t >= 2.0 ? 0 : (t >= 1.0 ? 0.8 + t*t*(-2 + t*(2 + t*(- 0.75 + t*0.1))) : 0.7 + t*t*(-1 + t*t*(0.75 - t*0.3)))); | |||
1561 | } | |||
1562 | } | |||
1563 | ||||
1564 | static void | |||
1565 | _c3quintN_f(float *f, const float *x, size_t len, const double *parm) { | |||
1566 | float t; | |||
1567 | size_t i; | |||
1568 | AIR_UNUSED(parm)(void)(parm); | |||
1569 | for (i=0; i<len; i++) { | |||
1570 | t = x[i]; | |||
1571 | t = AIR_ABS(t)((t) > 0.0f ? (t) : -(t)); | |||
1572 | f[i] = AIR_CAST(float, _C3QUINTIC(t))((float)((t >= 2.0 ? 0 : (t >= 1.0 ? 0.8 + t*t*(-2 + t* (2 + t*(-0.75 + t*0.1))) : 0.7 + t*t*(-1 + t*t*(0.75 - t*0.3) ))))); | |||
1573 | } | |||
1574 | } | |||
1575 | ||||
1576 | static NrrdKernel | |||
1577 | _c3quint = { | |||
1578 | "C3Quintic", | |||
1579 | 0, returnTwo, returnOne, | |||
1580 | _c3quint1_f, _c3quintN_f, _c3quint1_d, _c3quintN_d | |||
1581 | }; | |||
1582 | NrrdKernel *const | |||
1583 | nrrdKernelC3Quintic = &_c3quint; | |||
1584 | ||||
1585 | /* ------------------------------------------------------------ */ | |||
1586 | ||||
1587 | #define _DC3QUINTIC(x)(x >= 2.0 ? 0 : (x >= 1.0 ? x*(-4 + x*(6 + x*(-3 + x*0.5 ))) : x*(-2 + x*x*(3 - x*1.5)))) \ | |||
1588 | (x >= 2.0 ? 0 : \ | |||
1589 | (x >= 1.0 \ | |||
1590 | ? x*(-4 + x*(6 + x*(-3 + x*0.5))) \ | |||
1591 | : x*(-2 + x*x*(3 - x*1.5)))) | |||
1592 | ||||
1593 | static double | |||
1594 | _Dc3quint1_d(double x, const double *parm) { | |||
1595 | int sgn = 1; | |||
1596 | AIR_UNUSED(parm)(void)(parm); | |||
1597 | if (x < 0) { x = -x; sgn = -1; } | |||
1598 | return sgn*_DC3QUINTIC(x)(x >= 2.0 ? 0 : (x >= 1.0 ? x*(-4 + x*(6 + x*(-3 + x*0.5 ))) : x*(-2 + x*x*(3 - x*1.5)))); | |||
1599 | } | |||
1600 | ||||
1601 | static float | |||
1602 | _Dc3quint1_f(float x, const double *parm) { | |||
1603 | int sgn = 1; | |||
1604 | AIR_UNUSED(parm)(void)(parm); | |||
1605 | if (x < 0) { x = -x; sgn = -1; } | |||
1606 | return AIR_CAST(float, sgn*_DC3QUINTIC(x))((float)(sgn*(x >= 2.0 ? 0 : (x >= 1.0 ? x*(-4 + x*(6 + x*(-3 + x*0.5))) : x*(-2 + x*x*(3 - x*1.5)))))); | |||
1607 | } | |||
1608 | ||||
1609 | static void | |||
1610 | _Dc3quintN_d(double *f, const double *x, size_t len, const double *parm) { | |||
1611 | double t; | |||
1612 | size_t i; | |||
1613 | int sgn; | |||
1614 | AIR_UNUSED(parm)(void)(parm); | |||
1615 | for (i=0; i<len; i++) { | |||
1616 | t = x[i]; | |||
1617 | if (t < 0) { t = -t; sgn = -1; } else { sgn = 1; } | |||
1618 | f[i] = sgn*_DC3QUINTIC(t)(t >= 2.0 ? 0 : (t >= 1.0 ? t*(-4 + t*(6 + t*(-3 + t*0.5 ))) : t*(-2 + t*t*(3 - t*1.5)))); | |||
1619 | } | |||
1620 | } | |||
1621 | ||||
1622 | static void | |||
1623 | _Dc3quintN_f(float *f, const float *x, size_t len, const double *parm) { | |||
1624 | float t; | |||
1625 | size_t i; | |||
1626 | int sgn; | |||
1627 | AIR_UNUSED(parm)(void)(parm); | |||
1628 | for (i=0; i<len; i++) { | |||
1629 | t = x[i]; | |||
1630 | if (t < 0) { t = -t; sgn = -1; } else { sgn = 1; } | |||
1631 | f[i] = AIR_CAST(float, sgn*_DC3QUINTIC(t))((float)(sgn*(t >= 2.0 ? 0 : (t >= 1.0 ? t*(-4 + t*(6 + t*(-3 + t*0.5))) : t*(-2 + t*t*(3 - t*1.5)))))); | |||
1632 | } | |||
1633 | } | |||
1634 | ||||
1635 | static NrrdKernel | |||
1636 | _nrrdKernelDC3Quintic = { | |||
1637 | "C3QuinticD", | |||
1638 | 0, returnTwo, returnZero, | |||
1639 | _Dc3quint1_f, _Dc3quintN_f, _Dc3quint1_d, _Dc3quintN_d | |||
1640 | }; | |||
1641 | NrrdKernel *const | |||
1642 | nrrdKernelC3QuinticD = &_nrrdKernelDC3Quintic; | |||
1643 | ||||
1644 | /* ------------------------------------------------------------ */ | |||
1645 | ||||
1646 | #define _DDC3QUINTIC(x)(x >= 2.0 ? 0 : (x >= 1.0 ? -4 + x*(12 + x*(-9 + x*2)) : -2 + x*x*(9 - x*6))) \ | |||
1647 | (x >= 2.0 ? 0 : \ | |||
1648 | (x >= 1.0 \ | |||
1649 | ? -4 + x*(12 + x*(-9 + x*2)) \ | |||
1650 | : -2 + x*x*(9 - x*6))) | |||
1651 | ||||
1652 | static double | |||
1653 | _DDc3quint1_d(double x, const double *parm) { | |||
1654 | AIR_UNUSED(parm)(void)(parm); | |||
1655 | x = AIR_ABS(x)((x) > 0.0f ? (x) : -(x)); | |||
1656 | return _DDC3QUINTIC(x)(x >= 2.0 ? 0 : (x >= 1.0 ? -4 + x*(12 + x*(-9 + x*2)) : -2 + x*x*(9 - x*6))); | |||
1657 | } | |||
1658 | ||||
1659 | static float | |||
1660 | _DDc3quint1_f(float x, const double *parm) { | |||
1661 | AIR_UNUSED(parm)(void)(parm); | |||
1662 | x = AIR_ABS(x)((x) > 0.0f ? (x) : -(x)); | |||
1663 | return AIR_CAST(float, _DDC3QUINTIC(x))((float)((x >= 2.0 ? 0 : (x >= 1.0 ? -4 + x*(12 + x*(-9 + x*2)) : -2 + x*x*(9 - x*6))))); | |||
1664 | } | |||
1665 | ||||
1666 | static void | |||
1667 | _DDc3quintN_d(double *f, const double *x, size_t len, const double *parm) { | |||
1668 | double t; | |||
1669 | size_t i; | |||
1670 | AIR_UNUSED(parm)(void)(parm); | |||
1671 | for (i=0; i<len; i++) { | |||
1672 | t = x[i]; | |||
1673 | t = AIR_ABS(t)((t) > 0.0f ? (t) : -(t)); | |||
1674 | f[i] = _DDC3QUINTIC(t)(t >= 2.0 ? 0 : (t >= 1.0 ? -4 + t*(12 + t*(-9 + t*2)) : -2 + t*t*(9 - t*6))); | |||
1675 | } | |||
1676 | } | |||
1677 | ||||
1678 | static void | |||
1679 | _DDc3quintN_f(float *f, const float *x, size_t len, const double *parm) { | |||
1680 | float t; | |||
1681 | size_t i; | |||
1682 | AIR_UNUSED(parm)(void)(parm); | |||
1683 | for (i=0; i<len; i++) { | |||
1684 | t = x[i]; | |||
1685 | t = AIR_ABS(t)((t) > 0.0f ? (t) : -(t)); | |||
1686 | f[i] = AIR_CAST(float, _DDC3QUINTIC(t))((float)((t >= 2.0 ? 0 : (t >= 1.0 ? -4 + t*(12 + t*(-9 + t*2)) : -2 + t*t*(9 - t*6))))); | |||
1687 | } | |||
1688 | } | |||
1689 | ||||
1690 | static NrrdKernel | |||
1691 | _DDc3quint = { | |||
1692 | "C3QuinticDD", | |||
1693 | 0, returnTwo, returnZero, | |||
1694 | _DDc3quint1_f, _DDc3quintN_f, _DDc3quint1_d, _DDc3quintN_d | |||
1695 | }; | |||
1696 | NrrdKernel *const | |||
1697 | nrrdKernelC3QuinticDD = &_DDc3quint; | |||
1698 | ||||
1699 | /* ------------------------------------------------------------ */ | |||
1700 | ||||
1701 | /* | |||
1702 | ** This is the unique, 6-sample support, hexic, C^4 kernel, with 1st and 3rd | |||
1703 | ** derivatives zero at origin, which integrates to unity on [-3,3], with 3rd | |||
1704 | ** order Taylor accuracy (errors start showing up when reconstructing 4th | |||
1705 | ** order polynomials) It doesn't interpolate, but its close, and it rings | |||
1706 | ** once. | |||
1707 | ** | |||
1708 | ** this is awfully close to, but not quite the same as, "tmf:n,3,4" == | |||
1709 | ** TMF_dn_c3_4ef == nrrdKernelTMF[0][4][4], which is only C^3 smooth | |||
1710 | */ | |||
1711 | ||||
1712 | #define _C4HEXIC(x)(x >= 3.0 ? 0 : (x >= 2.0 ? 1539.0/160.0 + x*(-189.0/8.0 + x*(747.0/32.0 + x*(-12.0 + x*(109.0/32.0 + x*(-61.0/120.0 + x/32.0))))) : (x >= 1.0 ? 3.0/160.0 + x*(35.0/8.0 + x*(-341.0 /32.0 + x*(10.0 + x*(-147.0/32.0 + x*(25.0/24.0 - x*3.0/32.0) )))) : 69.0/80.0 + x*x*(-23.0/16.0 + x*x*(19.0/16.0 + x*(-7.0 /12.0 + x/16.0))) ))) \ | |||
1713 | (x >= 3.0 \ | |||
1714 | ? 0 \ | |||
1715 | : (x >= 2.0 \ | |||
1716 | ? 1539.0/160.0 + x*(-189.0/8.0 + x*(747.0/32.0 + x*(-12.0 + x*(109.0/32.0 + x*(-61.0/120.0 + x/32.0))))) \ | |||
1717 | : (x >= 1.0 \ | |||
1718 | ? 3.0/160.0 + x*(35.0/8.0 + x*(-341.0/32.0 + x*(10.0 + x*(-147.0/32.0 + x*(25.0/24.0 - x*3.0/32.0))))) \ | |||
1719 | : 69.0/80.0 + x*x*(-23.0/16.0 + x*x*(19.0/16.0 + x*(-7.0/12.0 + x/16.0))) ))) | |||
1720 | ||||
1721 | static double | |||
1722 | _c4hex1_d(double x, const double *parm) { | |||
1723 | AIR_UNUSED(parm)(void)(parm); | |||
1724 | x = AIR_ABS(x)((x) > 0.0f ? (x) : -(x)); | |||
1725 | return _C4HEXIC(x)(x >= 3.0 ? 0 : (x >= 2.0 ? 1539.0/160.0 + x*(-189.0/8.0 + x*(747.0/32.0 + x*(-12.0 + x*(109.0/32.0 + x*(-61.0/120.0 + x/32.0))))) : (x >= 1.0 ? 3.0/160.0 + x*(35.0/8.0 + x*(-341.0 /32.0 + x*(10.0 + x*(-147.0/32.0 + x*(25.0/24.0 - x*3.0/32.0) )))) : 69.0/80.0 + x*x*(-23.0/16.0 + x*x*(19.0/16.0 + x*(-7.0 /12.0 + x/16.0))) ))); | |||
1726 | } | |||
1727 | ||||
1728 | static float | |||
1729 | _c4hex1_f(float x, const double *parm) { | |||
1730 | AIR_UNUSED(parm)(void)(parm); | |||
1731 | x = AIR_ABS(x)((x) > 0.0f ? (x) : -(x)); | |||
1732 | return AIR_CAST(float, _C4HEXIC(x))((float)((x >= 3.0 ? 0 : (x >= 2.0 ? 1539.0/160.0 + x*( -189.0/8.0 + x*(747.0/32.0 + x*(-12.0 + x*(109.0/32.0 + x*(-61.0 /120.0 + x/32.0))))) : (x >= 1.0 ? 3.0/160.0 + x*(35.0/8.0 + x*(-341.0/32.0 + x*(10.0 + x*(-147.0/32.0 + x*(25.0/24.0 - x*3.0/32.0))))) : 69.0/80.0 + x*x*(-23.0/16.0 + x*x*(19.0/16.0 + x*(-7.0/12.0 + x/16.0))) ))))); | |||
1733 | } | |||
1734 | ||||
1735 | static void | |||
1736 | _c4hexN_d(double *f, const double *x, size_t len, const double *parm) { | |||
1737 | double t; | |||
1738 | size_t i; | |||
1739 | AIR_UNUSED(parm)(void)(parm); | |||
1740 | for (i=0; i<len; i++) { | |||
1741 | t = x[i]; | |||
1742 | t = AIR_ABS(t)((t) > 0.0f ? (t) : -(t)); | |||
1743 | f[i] = _C4HEXIC(t)(t >= 3.0 ? 0 : (t >= 2.0 ? 1539.0/160.0 + t*(-189.0/8.0 + t*(747.0/32.0 + t*(-12.0 + t*(109.0/32.0 + t*(-61.0/120.0 + t/32.0))))) : (t >= 1.0 ? 3.0/160.0 + t*(35.0/8.0 + t*(-341.0 /32.0 + t*(10.0 + t*(-147.0/32.0 + t*(25.0/24.0 - t*3.0/32.0) )))) : 69.0/80.0 + t*t*(-23.0/16.0 + t*t*(19.0/16.0 + t*(-7.0 /12.0 + t/16.0))) ))); | |||
1744 | } | |||
1745 | } | |||
1746 | ||||
1747 | static void | |||
1748 | _c4hexN_f(float *f, const float *x, size_t len, const double *parm) { | |||
1749 | float t; | |||
1750 | size_t i; | |||
1751 | AIR_UNUSED(parm)(void)(parm); | |||
1752 | for (i=0; i<len; i++) { | |||
1753 | t = x[i]; | |||
1754 | t = AIR_ABS(t)((t) > 0.0f ? (t) : -(t)); | |||
1755 | f[i] = AIR_CAST(float, _C4HEXIC(t))((float)((t >= 3.0 ? 0 : (t >= 2.0 ? 1539.0/160.0 + t*( -189.0/8.0 + t*(747.0/32.0 + t*(-12.0 + t*(109.0/32.0 + t*(-61.0 /120.0 + t/32.0))))) : (t >= 1.0 ? 3.0/160.0 + t*(35.0/8.0 + t*(-341.0/32.0 + t*(10.0 + t*(-147.0/32.0 + t*(25.0/24.0 - t*3.0/32.0))))) : 69.0/80.0 + t*t*(-23.0/16.0 + t*t*(19.0/16.0 + t*(-7.0/12.0 + t/16.0))) ))))); | |||
1756 | } | |||
1757 | } | |||
1758 | ||||
1759 | static NrrdKernel | |||
1760 | _c4hex = { | |||
1761 | "C4Hexic", | |||
1762 | 0, returnThree, returnOne, | |||
1763 | _c4hex1_f, _c4hexN_f, _c4hex1_d, _c4hexN_d | |||
1764 | }; | |||
1765 | NrrdKernel *const | |||
1766 | nrrdKernelC4Hexic = &_c4hex; | |||
1767 | ||||
1768 | /* ------------------------------------------------------------ */ | |||
1769 | ||||
1770 | #define _DC4HEXIC(x)(x >= 3.0 ? 0 : (x >= 2.0 ? -189.0/8.0 + x*(747.0/16.0 + x*(-36.0 + x*(109.0/8.0 + x*(-61.0/24.0 + x*(3.0/16.0))))) : (x >= 1.0 ? 35.0/8.0 + x*(-341.0/16.0 + x*(30 + x*(-147.0 /8.0 + x*(125.0/24.0 + x*(-9.0/16.0))))) : x*(-23.0/8.0 + x*x *(19.0/4.0 + x*(-35.0/12.0 + x*(3.0/8.0)))) ))) \ | |||
1771 | (x >= 3.0 \ | |||
1772 | ? 0 \ | |||
1773 | : (x >= 2.0 \ | |||
1774 | ? -189.0/8.0 + x*(747.0/16.0 + x*(-36.0 + x*(109.0/8.0 + x*(-61.0/24.0 + x*(3.0/16.0))))) \ | |||
1775 | : (x >= 1.0 \ | |||
1776 | ? 35.0/8.0 + x*(-341.0/16.0 + x*(30 + x*(-147.0/8.0 + x*(125.0/24.0 + x*(-9.0/16.0))))) \ | |||
1777 | : x*(-23.0/8.0 + x*x*(19.0/4.0 + x*(-35.0/12.0 + x*(3.0/8.0)))) ))) | |||
1778 | ||||
1779 | static double | |||
1780 | _Dc4hex1_d(double x, const double *parm) { | |||
1781 | int sgn = 1; | |||
1782 | AIR_UNUSED(parm)(void)(parm); | |||
1783 | if (x < 0) { x = -x; sgn = -1; } | |||
1784 | return sgn*_DC4HEXIC(x)(x >= 3.0 ? 0 : (x >= 2.0 ? -189.0/8.0 + x*(747.0/16.0 + x*(-36.0 + x*(109.0/8.0 + x*(-61.0/24.0 + x*(3.0/16.0))))) : (x >= 1.0 ? 35.0/8.0 + x*(-341.0/16.0 + x*(30 + x*(-147.0 /8.0 + x*(125.0/24.0 + x*(-9.0/16.0))))) : x*(-23.0/8.0 + x*x *(19.0/4.0 + x*(-35.0/12.0 + x*(3.0/8.0)))) ))); | |||
1785 | } | |||
1786 | ||||
1787 | static float | |||
1788 | _Dc4hex1_f(float x, const double *parm) { | |||
1789 | int sgn = 1; | |||
1790 | AIR_UNUSED(parm)(void)(parm); | |||
1791 | if (x < 0) { x = -x; sgn = -1; } | |||
1792 | return AIR_CAST(float, sgn*_DC4HEXIC(x))((float)(sgn*(x >= 3.0 ? 0 : (x >= 2.0 ? -189.0/8.0 + x *(747.0/16.0 + x*(-36.0 + x*(109.0/8.0 + x*(-61.0/24.0 + x*(3.0 /16.0))))) : (x >= 1.0 ? 35.0/8.0 + x*(-341.0/16.0 + x*(30 + x*(-147.0/8.0 + x*(125.0/24.0 + x*(-9.0/16.0))))) : x*(-23.0 /8.0 + x*x*(19.0/4.0 + x*(-35.0/12.0 + x*(3.0/8.0)))) ))))); | |||
1793 | } | |||
1794 | ||||
1795 | static void | |||
1796 | _Dc4hexN_d(double *f, const double *x, size_t len, const double *parm) { | |||
1797 | double t; | |||
1798 | size_t i; | |||
1799 | int sgn; | |||
1800 | AIR_UNUSED(parm)(void)(parm); | |||
1801 | for (i=0; i<len; i++) { | |||
1802 | t = x[i]; | |||
1803 | if (t < 0) { t = -t; sgn = -1; } else { sgn = 1; } | |||
1804 | f[i] = sgn*_DC4HEXIC(t)(t >= 3.0 ? 0 : (t >= 2.0 ? -189.0/8.0 + t*(747.0/16.0 + t*(-36.0 + t*(109.0/8.0 + t*(-61.0/24.0 + t*(3.0/16.0))))) : (t >= 1.0 ? 35.0/8.0 + t*(-341.0/16.0 + t*(30 + t*(-147.0 /8.0 + t*(125.0/24.0 + t*(-9.0/16.0))))) : t*(-23.0/8.0 + t*t *(19.0/4.0 + t*(-35.0/12.0 + t*(3.0/8.0)))) ))); | |||
1805 | } | |||
1806 | } | |||
1807 | ||||
1808 | static void | |||
1809 | _Dc4hexN_f(float *f, const float *x, size_t len, const double *parm) { | |||
1810 | float t; | |||
1811 | size_t i; | |||
1812 | int sgn; | |||
1813 | AIR_UNUSED(parm)(void)(parm); | |||
1814 | for (i=0; i<len; i++) { | |||
1815 | t = x[i]; | |||
1816 | if (t < 0) { t = -t; sgn = -1; } else { sgn = 1; } | |||
1817 | f[i] = AIR_CAST(float, sgn*_DC4HEXIC(t))((float)(sgn*(t >= 3.0 ? 0 : (t >= 2.0 ? -189.0/8.0 + t *(747.0/16.0 + t*(-36.0 + t*(109.0/8.0 + t*(-61.0/24.0 + t*(3.0 /16.0))))) : (t >= 1.0 ? 35.0/8.0 + t*(-341.0/16.0 + t*(30 + t*(-147.0/8.0 + t*(125.0/24.0 + t*(-9.0/16.0))))) : t*(-23.0 /8.0 + t*t*(19.0/4.0 + t*(-35.0/12.0 + t*(3.0/8.0)))) ))))); | |||
1818 | } | |||
1819 | } | |||
1820 | ||||
1821 | static NrrdKernel | |||
1822 | _nrrdKernelDC4hexic = { | |||
1823 | "C4HexicD", | |||
1824 | 0, returnThree, returnZero, | |||
1825 | _Dc4hex1_f, _Dc4hexN_f, _Dc4hex1_d, _Dc4hexN_d | |||
1826 | }; | |||
1827 | NrrdKernel *const | |||
1828 | nrrdKernelC4HexicD = &_nrrdKernelDC4hexic; | |||
1829 | ||||
1830 | /* ------------------------------------------------------------ */ | |||
1831 | ||||
1832 | #define _DDC4HEXIC(x)(x >= 3.0 ? 0 : (x >= 2.0 ? 747.0/16.0 + x*(-72.0 + x*( 327.0/8.0 + x*(-61.0/6.0 + x*15.0/16.0))) : (x >= 1.0 ? -341.0 /16.0 + x*(60 + x*(-441.0/8.0 + x*(125.0/6.0 - x*45.0/16.0))) : -23.0/8.0 + x*x*(57.0/4.0 + x*(-35.0/3.0 + x*(15.0/8.0))) ) )) \ | |||
1833 | (x >= 3.0 \ | |||
1834 | ? 0 \ | |||
1835 | : (x >= 2.0 \ | |||
1836 | ? 747.0/16.0 + x*(-72.0 + x*(327.0/8.0 + x*(-61.0/6.0 + x*15.0/16.0))) \ | |||
1837 | : (x >= 1.0 \ | |||
1838 | ? -341.0/16.0 + x*(60 + x*(-441.0/8.0 + x*(125.0/6.0 - x*45.0/16.0))) \ | |||
1839 | : -23.0/8.0 + x*x*(57.0/4.0 + x*(-35.0/3.0 + x*(15.0/8.0))) ))) | |||
1840 | ||||
1841 | static double | |||
1842 | _DDc4hex1_d(double x, const double *parm) { | |||
1843 | AIR_UNUSED(parm)(void)(parm); | |||
1844 | x = AIR_ABS(x)((x) > 0.0f ? (x) : -(x)); | |||
1845 | return _DDC4HEXIC(x)(x >= 3.0 ? 0 : (x >= 2.0 ? 747.0/16.0 + x*(-72.0 + x*( 327.0/8.0 + x*(-61.0/6.0 + x*15.0/16.0))) : (x >= 1.0 ? -341.0 /16.0 + x*(60 + x*(-441.0/8.0 + x*(125.0/6.0 - x*45.0/16.0))) : -23.0/8.0 + x*x*(57.0/4.0 + x*(-35.0/3.0 + x*(15.0/8.0))) ) )); | |||
1846 | } | |||
1847 | ||||
1848 | static float | |||
1849 | _DDc4hex1_f(float x, const double *parm) { | |||
1850 | AIR_UNUSED(parm)(void)(parm); | |||
1851 | x = AIR_ABS(x)((x) > 0.0f ? (x) : -(x)); | |||
1852 | return AIR_CAST(float, _DDC4HEXIC(x))((float)((x >= 3.0 ? 0 : (x >= 2.0 ? 747.0/16.0 + x*(-72.0 + x*(327.0/8.0 + x*(-61.0/6.0 + x*15.0/16.0))) : (x >= 1.0 ? -341.0/16.0 + x*(60 + x*(-441.0/8.0 + x*(125.0/6.0 - x*45.0 /16.0))) : -23.0/8.0 + x*x*(57.0/4.0 + x*(-35.0/3.0 + x*(15.0 /8.0))) ))))); | |||
1853 | } | |||
1854 | ||||
1855 | static void | |||
1856 | _DDc4hexN_d(double *f, const double *x, size_t len, const double *parm) { | |||
1857 | double t; | |||
1858 | size_t i; | |||
1859 | AIR_UNUSED(parm)(void)(parm); | |||
1860 | for (i=0; i<len; i++) { | |||
1861 | t = x[i]; | |||
1862 | t = AIR_ABS(t)((t) > 0.0f ? (t) : -(t)); | |||
1863 | f[i] = _DDC4HEXIC(t)(t >= 3.0 ? 0 : (t >= 2.0 ? 747.0/16.0 + t*(-72.0 + t*( 327.0/8.0 + t*(-61.0/6.0 + t*15.0/16.0))) : (t >= 1.0 ? -341.0 /16.0 + t*(60 + t*(-441.0/8.0 + t*(125.0/6.0 - t*45.0/16.0))) : -23.0/8.0 + t*t*(57.0/4.0 + t*(-35.0/3.0 + t*(15.0/8.0))) ) )); | |||
1864 | } | |||
1865 | } | |||
1866 | ||||
1867 | static void | |||
1868 | _DDc4hexN_f(float *f, const float *x, size_t len, const double *parm) { | |||
1869 | float t; | |||
1870 | size_t i; | |||
1871 | AIR_UNUSED(parm)(void)(parm); | |||
1872 | for (i=0; i<len; i++) { | |||
1873 | t = x[i]; | |||
1874 | t = AIR_ABS(t)((t) > 0.0f ? (t) : -(t)); | |||
1875 | f[i] = AIR_CAST(float, _DDC4HEXIC(t))((float)((t >= 3.0 ? 0 : (t >= 2.0 ? 747.0/16.0 + t*(-72.0 + t*(327.0/8.0 + t*(-61.0/6.0 + t*15.0/16.0))) : (t >= 1.0 ? -341.0/16.0 + t*(60 + t*(-441.0/8.0 + t*(125.0/6.0 - t*45.0 /16.0))) : -23.0/8.0 + t*t*(57.0/4.0 + t*(-35.0/3.0 + t*(15.0 /8.0))) ))))); | |||
1876 | } | |||
1877 | } | |||
1878 | ||||
1879 | static NrrdKernel | |||
1880 | _DDc4hex = { | |||
1881 | "C4HexicDD", | |||
1882 | 0, returnThree, returnZero, | |||
1883 | _DDc4hex1_f, _DDc4hexN_f, _DDc4hex1_d, _DDc4hexN_d | |||
1884 | }; | |||
1885 | NrrdKernel *const | |||
1886 | nrrdKernelC4HexicDD = &_DDc4hex; | |||
1887 | ||||
1888 | /* ------------------------------------------------------------ */ | |||
1889 | ||||
1890 | #define _DDDC4HEXIC(x)(x >= 3.0 ? 0 : (x >= 2.0 ? -72.0 + x*(327.0/4.0 + x*(- 61.0/2.0 + 15*x/4)) : (x >= 1.0 ? 60 + x*(-441.0/4.0 + x*( 125.0/2.0 - 45*x/4)) : x*(57.0/2.0 + x*(-35 + 15*x/2)) ))) \ | |||
1891 | (x >= 3.0 \ | |||
1892 | ? 0 \ | |||
1893 | : (x >= 2.0 \ | |||
1894 | ? -72.0 + x*(327.0/4.0 + x*(-61.0/2.0 + 15*x/4)) \ | |||
1895 | : (x >= 1.0 \ | |||
1896 | ? 60 + x*(-441.0/4.0 + x*(125.0/2.0 - 45*x/4)) \ | |||
1897 | : x*(57.0/2.0 + x*(-35 + 15*x/2)) \ | |||
1898 | ))) | |||
1899 | ||||
1900 | static double | |||
1901 | _DDDc4hex1_d(double x, const double *parm) { | |||
1902 | int sgn = 1; | |||
1903 | AIR_UNUSED(parm)(void)(parm); | |||
1904 | if (x < 0) { x = -x; sgn = -1; } | |||
1905 | return sgn*_DDDC4HEXIC(x)(x >= 3.0 ? 0 : (x >= 2.0 ? -72.0 + x*(327.0/4.0 + x*(- 61.0/2.0 + 15*x/4)) : (x >= 1.0 ? 60 + x*(-441.0/4.0 + x*( 125.0/2.0 - 45*x/4)) : x*(57.0/2.0 + x*(-35 + 15*x/2)) ))); | |||
1906 | } | |||
1907 | ||||
1908 | static float | |||
1909 | _DDDc4hex1_f(float x, const double *parm) { | |||
1910 | int sgn = 1; | |||
1911 | AIR_UNUSED(parm)(void)(parm); | |||
1912 | if (x < 0) { x = -x; sgn = -1; } | |||
1913 | return AIR_CAST(float, sgn*_DDDC4HEXIC(x))((float)(sgn*(x >= 3.0 ? 0 : (x >= 2.0 ? -72.0 + x*(327.0 /4.0 + x*(-61.0/2.0 + 15*x/4)) : (x >= 1.0 ? 60 + x*(-441.0 /4.0 + x*(125.0/2.0 - 45*x/4)) : x*(57.0/2.0 + x*(-35 + 15*x/ 2)) ))))); | |||
1914 | } | |||
1915 | ||||
1916 | static void | |||
1917 | _DDDc4hexN_d(double *f, const double *x, size_t len, const double *parm) { | |||
1918 | double t; | |||
1919 | size_t i; | |||
1920 | int sgn; | |||
1921 | AIR_UNUSED(parm)(void)(parm); | |||
1922 | for (i=0; i<len; i++) { | |||
1923 | t = x[i]; | |||
1924 | if (t < 0) { t = -t; sgn = -1; } else { sgn = 1; } | |||
1925 | f[i] = sgn*_DDDC4HEXIC(t)(t >= 3.0 ? 0 : (t >= 2.0 ? -72.0 + t*(327.0/4.0 + t*(- 61.0/2.0 + 15*t/4)) : (t >= 1.0 ? 60 + t*(-441.0/4.0 + t*( 125.0/2.0 - 45*t/4)) : t*(57.0/2.0 + t*(-35 + 15*t/2)) ))); | |||
1926 | } | |||
1927 | } | |||
1928 | ||||
1929 | static void | |||
1930 | _DDDc4hexN_f(float *f, const float *x, size_t len, const double *parm) { | |||
1931 | float t; | |||
1932 | size_t i; | |||
1933 | int sgn; | |||
1934 | AIR_UNUSED(parm)(void)(parm); | |||
1935 | for (i=0; i<len; i++) { | |||
1936 | t = x[i]; | |||
1937 | if (t < 0) { t = -t; sgn = -1; } else { sgn = 1; } | |||
1938 | f[i] = AIR_CAST(float, sgn*_DDDC4HEXIC(t))((float)(sgn*(t >= 3.0 ? 0 : (t >= 2.0 ? -72.0 + t*(327.0 /4.0 + t*(-61.0/2.0 + 15*t/4)) : (t >= 1.0 ? 60 + t*(-441.0 /4.0 + t*(125.0/2.0 - 45*t/4)) : t*(57.0/2.0 + t*(-35 + 15*t/ 2)) ))))); | |||
1939 | } | |||
1940 | } | |||
1941 | ||||
1942 | static NrrdKernel | |||
1943 | _nrrdKernelDDDC4hexic = { | |||
1944 | "C4HexicDDD", | |||
1945 | 0, returnThree, returnZero, | |||
1946 | _DDDc4hex1_f, _DDDc4hexN_f, _DDDc4hex1_d, _DDDc4hexN_d | |||
1947 | }; | |||
1948 | NrrdKernel *const | |||
1949 | nrrdKernelC4HexicDDD = &_nrrdKernelDDDC4hexic; | |||
1950 | ||||
1951 | ||||
1952 | /* ------------- approximate inverse of c4h ------------------------- */ | |||
1953 | /* see comments around "_bspl3_ANI" in bsplKernel.c */ | |||
1954 | ||||
1955 | static double | |||
1956 | _c4hex_ANI_kvals[12] = { | |||
1957 | 1.1906949847244948336, | |||
1958 | -0.13537708971729194940, | |||
1959 | 0.047024535491780434571, | |||
1960 | -0.0088462060502312555095, | |||
1961 | 0.0022443498051487024049, | |||
1962 | -0.00048639680369511914410, | |||
1963 | 0.00011421848629250278186, | |||
1964 | -0.000025727759438407893986, | |||
1965 | 5.9204264168395963454e-6, | |||
1966 | -1.3468552403175349134e-6, | |||
1967 | 3.0637649910394681441e-7, | |||
1968 | -5.5762487950611026674e-8}; | |||
1969 | ||||
1970 | static double | |||
1971 | _c4hex_ANI_sup(const double *parm) { | |||
1972 | AIR_UNUSED(parm)(void)(parm); | |||
1973 | return 12.5; | |||
1974 | } | |||
1975 | ||||
1976 | #define C4HEX_ANI(ret, tmp, x)tmp = ((unsigned int)(x+0.5)); if (tmp < 12) { ret = _c4hex_ANI_kvals [tmp]; } else { ret = 0.0; } \ | |||
1977 | tmp = AIR_CAST(unsigned int, x+0.5)((unsigned int)(x+0.5)); \ | |||
1978 | if (tmp < 12) { \ | |||
1979 | ret = _c4hex_ANI_kvals[tmp]; \ | |||
1980 | } else { \ | |||
1981 | ret = 0.0; \ | |||
1982 | } | |||
1983 | ||||
1984 | static double | |||
1985 | _c4hex_ANI_1d(double x, const double *parm) { | |||
1986 | double ax, r; unsigned int tmp; | |||
1987 | AIR_UNUSED(parm)(void)(parm); | |||
1988 | ax = AIR_ABS(x)((x) > 0.0f ? (x) : -(x)); | |||
1989 | C4HEX_ANI(r, tmp, ax)tmp = ((unsigned int)(ax+0.5)); if (tmp < 12) { r = _c4hex_ANI_kvals [tmp]; } else { r = 0.0; }; | |||
1990 | return r; | |||
1991 | } | |||
1992 | ||||
1993 | static float | |||
1994 | _c4hex_ANI_1f(float x, const double *parm) { | |||
1995 | double ax, r; unsigned int tmp; | |||
1996 | AIR_UNUSED(parm)(void)(parm); | |||
1997 | ax = AIR_ABS(x)((x) > 0.0f ? (x) : -(x)); | |||
1998 | C4HEX_ANI(r, tmp, ax)tmp = ((unsigned int)(ax+0.5)); if (tmp < 12) { r = _c4hex_ANI_kvals [tmp]; } else { r = 0.0; }; | |||
1999 | return AIR_CAST(float, r)((float)(r)); | |||
2000 | } | |||
2001 | ||||
2002 | static void | |||
2003 | _c4hex_ANI_Nd(double *f, const double *x, size_t len, const double *parm) { | |||
2004 | double ax, r; unsigned int tmp; | |||
2005 | size_t i; | |||
2006 | AIR_UNUSED(parm)(void)(parm); | |||
2007 | for (i=0; i<len; i++) { | |||
2008 | ax = x[i]; ax = AIR_ABS(ax)((ax) > 0.0f ? (ax) : -(ax)); | |||
2009 | C4HEX_ANI(r, tmp, ax)tmp = ((unsigned int)(ax+0.5)); if (tmp < 12) { r = _c4hex_ANI_kvals [tmp]; } else { r = 0.0; }; | |||
2010 | f[i] = r; | |||
2011 | } | |||
2012 | } | |||
2013 | ||||
2014 | static void | |||
2015 | _c4hex_ANI_Nf(float *f, const float *x, size_t len, const double *parm) { | |||
2016 | double ax, r; unsigned int tmp; | |||
2017 | size_t i; | |||
2018 | AIR_UNUSED(parm)(void)(parm); | |||
2019 | for (i=0; i<len; i++) { | |||
2020 | ax = x[i]; ax = AIR_ABS(ax)((ax) > 0.0f ? (ax) : -(ax)); | |||
2021 | C4HEX_ANI(r, tmp, ax)tmp = ((unsigned int)(ax+0.5)); if (tmp < 12) { r = _c4hex_ANI_kvals [tmp]; } else { r = 0.0; }; | |||
2022 | f[i] = AIR_CAST(float, r)((float)(r)); | |||
2023 | } | |||
2024 | } | |||
2025 | ||||
2026 | static NrrdKernel | |||
2027 | _nrrdKernelC4HexicApproxInverse = { | |||
2028 | "C4HexicAI", 0, | |||
2029 | _c4hex_ANI_sup, returnOne, | |||
2030 | _c4hex_ANI_1f, _c4hex_ANI_Nf, | |||
2031 | _c4hex_ANI_1d, _c4hex_ANI_Nd | |||
2032 | }; | |||
2033 | NrrdKernel *const | |||
2034 | nrrdKernelC4HexicApproxInverse = &_nrrdKernelC4HexicApproxInverse; | |||
2035 | ||||
2036 | /* ------------------------- c5septic ------------------------------ */ | |||
2037 | ||||
2038 | /* | |||
2039 | ** This is the unique, 8-sample support, C^5 kernel, piecewise order-7 | |||
2040 | ** with 4th order Taylor accuracy (errors start showing up when | |||
2041 | ** reconstructing 5th order polynomials). Coincidentally, it has zero | |||
2042 | ** 1st and 3rd deriv at the origin, and it integrates to unity on | |||
2043 | ** [-4,4]. It doesn't interpolate, but its close; it rings twice. */ | |||
2044 | ||||
2045 | #define _C5SEPT0(x)(0.9379776601998824 + x*x*(-1.654320987654321 + x*x*(1.073045267489712 + x*x*(-0.44997427983539096 + x*0.13978909465020575)))) (0.9379776601998824 + x*x*(-1.654320987654321 + x*x*(1.073045267489712 + x*x*(-0.44997427983539096 + x*0.13978909465020575)))) | |||
2046 | #define _C5SEPT1(x)(0.04651675485008818 + x*(-0.7377829218106996 + x*(0.9699074074074074 + x*(0.18531378600823045 + x*(-0.7839506172839507 + x*(0.2357253086419753 + x*(0.12021604938271604 - x*0.054552469135802466))))))) (0.04651675485008818 + x*(-0.7377829218106996 + x*(0.9699074074074074 + x*(0.18531378600823045 + x*(-0.7839506172839507 + x*(0.2357253086419753 + x*(0.12021604938271604 - x*0.054552469135802466))))))) | |||
2047 | #define _C5SEPT2(x)(-0.01860670194003527 + x*(0.14022633744855967 + x*(-0.16296296296296298 + x*(-0.09825102880658436 + x*(0.28858024691358025 + x*(-0.18858024691358025 + x*(0.04405864197530864 - x*0.0013631687242798354))))))) (-0.01860670194003527 + x*(0.14022633744855967 + x*(-0.16296296296296298 + x*(-0.09825102880658436 + x*(0.28858024691358025 + x*(-0.18858024691358025 + x*(0.04405864197530864 - x*0.0013631687242798354))))))) | |||
2048 | #define _C5SEPT3(x)(0.003101116990005879 + x*(-0.014223251028806585 + x*(0.02021604938271605 + x*(0.003729423868312757 + x*(-0.0411522633744856 + x*(0.04714506172839506 + x*(-0.023199588477366254 + x*0.004383450911228689))))))) (0.003101116990005879 + x*(-0.014223251028806585 + x*(0.02021604938271605 + x*(0.003729423868312757 + x*(-0.0411522633744856 + x*(0.04714506172839506 + x*(-0.023199588477366254 + x*0.004383450911228689))))))) | |||
2049 | #define _C5SEPT(i, x)(0 == i ? (0.9379776601998824 + x*x*(-1.654320987654321 + x*x *(1.073045267489712 + x*x*(-0.44997427983539096 + x*0.13978909465020575 )))) : (1 == i ? (0.04651675485008818 + x*(-0.7377829218106996 + x*(0.9699074074074074 + x*(0.18531378600823045 + x*(-0.7839506172839507 + x*(0.2357253086419753 + x*(0.12021604938271604 - x*0.054552469135802466 ))))))) : (2 == i ? (-0.01860670194003527 + x*(0.14022633744855967 + x*(-0.16296296296296298 + x*(-0.09825102880658436 + x*(0.28858024691358025 + x*(-0.18858024691358025 + x*(0.04405864197530864 - x*0.0013631687242798354 ))))))) : (3 == i ? (0.003101116990005879 + x*(-0.014223251028806585 + x*(0.02021604938271605 + x*(0.003729423868312757 + x*(-0.0411522633744856 + x*(0.04714506172839506 + x*(-0.023199588477366254 + x*0.004383450911228689 ))))))) : 0.0)))) \ | |||
2050 | (0 == i ? _C5SEPT0(x)(0.9379776601998824 + x*x*(-1.654320987654321 + x*x*(1.073045267489712 + x*x*(-0.44997427983539096 + x*0.13978909465020575)))) \ | |||
2051 | : (1 == i ? _C5SEPT1(x)(0.04651675485008818 + x*(-0.7377829218106996 + x*(0.9699074074074074 + x*(0.18531378600823045 + x*(-0.7839506172839507 + x*(0.2357253086419753 + x*(0.12021604938271604 - x*0.054552469135802466))))))) \ | |||
2052 | : (2 == i ? _C5SEPT2(x)(-0.01860670194003527 + x*(0.14022633744855967 + x*(-0.16296296296296298 + x*(-0.09825102880658436 + x*(0.28858024691358025 + x*(-0.18858024691358025 + x*(0.04405864197530864 - x*0.0013631687242798354))))))) \ | |||
2053 | : (3 == i ? _C5SEPT3(x)(0.003101116990005879 + x*(-0.014223251028806585 + x*(0.02021604938271605 + x*(0.003729423868312757 + x*(-0.0411522633744856 + x*(0.04714506172839506 + x*(-0.023199588477366254 + x*0.004383450911228689))))))) \ | |||
2054 | : 0.0)))) | |||
2055 | ||||
2056 | static double | |||
2057 | _c5sept1_d(double x, const double *parm) { | |||
2058 | unsigned int xi; | |||
2059 | AIR_UNUSED(parm)(void)(parm); | |||
2060 | x = AIR_ABS(x)((x) > 0.0f ? (x) : -(x)); | |||
2061 | xi = AIR_CAST(unsigned int, x)((unsigned int)(x)); | |||
2062 | x -= xi; | |||
2063 | return _C5SEPT(xi, x)(0 == xi ? (0.9379776601998824 + x*x*(-1.654320987654321 + x* x*(1.073045267489712 + x*x*(-0.44997427983539096 + x*0.13978909465020575 )))) : (1 == xi ? (0.04651675485008818 + x*(-0.7377829218106996 + x*(0.9699074074074074 + x*(0.18531378600823045 + x*(-0.7839506172839507 + x*(0.2357253086419753 + x*(0.12021604938271604 - x*0.054552469135802466 ))))))) : (2 == xi ? (-0.01860670194003527 + x*(0.14022633744855967 + x*(-0.16296296296296298 + x*(-0.09825102880658436 + x*(0.28858024691358025 + x*(-0.18858024691358025 + x*(0.04405864197530864 - x*0.0013631687242798354 ))))))) : (3 == xi ? (0.003101116990005879 + x*(-0.014223251028806585 + x*(0.02021604938271605 + x*(0.003729423868312757 + x*(-0.0411522633744856 + x*(0.04714506172839506 + x*(-0.023199588477366254 + x*0.004383450911228689 ))))))) : 0.0)))); | |||
2064 | } | |||
2065 | ||||
2066 | static float | |||
2067 | _c5sept1_f(float x, const double *parm) { | |||
2068 | unsigned int xi; | |||
2069 | AIR_UNUSED(parm)(void)(parm); | |||
2070 | x = AIR_ABS(x)((x) > 0.0f ? (x) : -(x)); | |||
2071 | xi = AIR_CAST(unsigned int, x)((unsigned int)(x)); | |||
2072 | x -= AIR_CAST(float, xi)((float)(xi)); | |||
2073 | return AIR_CAST(float, _C5SEPT(xi, x))((float)((0 == xi ? (0.9379776601998824 + x*x*(-1.654320987654321 + x*x*(1.073045267489712 + x*x*(-0.44997427983539096 + x*0.13978909465020575 )))) : (1 == xi ? (0.04651675485008818 + x*(-0.7377829218106996 + x*(0.9699074074074074 + x*(0.18531378600823045 + x*(-0.7839506172839507 + x*(0.2357253086419753 + x*(0.12021604938271604 - x*0.054552469135802466 ))))))) : (2 == xi ? (-0.01860670194003527 + x*(0.14022633744855967 + x*(-0.16296296296296298 + x*(-0.09825102880658436 + x*(0.28858024691358025 + x*(-0.18858024691358025 + x*(0.04405864197530864 - x*0.0013631687242798354 ))))))) : (3 == xi ? (0.003101116990005879 + x*(-0.014223251028806585 + x*(0.02021604938271605 + x*(0.003729423868312757 + x*(-0.0411522633744856 + x*(0.04714506172839506 + x*(-0.023199588477366254 + x*0.004383450911228689 ))))))) : 0.0)))))); | |||
2074 | } | |||
2075 | ||||
2076 | static void | |||
2077 | _c5septN_d(double *f, const double *x, size_t len, const double *parm) { | |||
2078 | unsigned int ti; | |||
2079 | double t; | |||
2080 | size_t i; | |||
2081 | AIR_UNUSED(parm)(void)(parm); | |||
2082 | for (i=0; i<len; i++) { | |||
2083 | t = x[i]; | |||
2084 | t = AIR_ABS(t)((t) > 0.0f ? (t) : -(t)); | |||
2085 | ti = AIR_CAST(unsigned int, t)((unsigned int)(t)); | |||
2086 | t -= ti; | |||
2087 | f[i] = _C5SEPT(ti, t)(0 == ti ? (0.9379776601998824 + t*t*(-1.654320987654321 + t* t*(1.073045267489712 + t*t*(-0.44997427983539096 + t*0.13978909465020575 )))) : (1 == ti ? (0.04651675485008818 + t*(-0.7377829218106996 + t*(0.9699074074074074 + t*(0.18531378600823045 + t*(-0.7839506172839507 + t*(0.2357253086419753 + t*(0.12021604938271604 - t*0.054552469135802466 ))))))) : (2 == ti ? (-0.01860670194003527 + t*(0.14022633744855967 + t*(-0.16296296296296298 + t*(-0.09825102880658436 + t*(0.28858024691358025 + t*(-0.18858024691358025 + t*(0.04405864197530864 - t*0.0013631687242798354 ))))))) : (3 == ti ? (0.003101116990005879 + t*(-0.014223251028806585 + t*(0.02021604938271605 + t*(0.003729423868312757 + t*(-0.0411522633744856 + t*(0.04714506172839506 + t*(-0.023199588477366254 + t*0.004383450911228689 ))))))) : 0.0)))); | |||
2088 | } | |||
2089 | } | |||
2090 | ||||
2091 | static void | |||
2092 | _c5septN_f(float *f, const float *x, size_t len, const double *parm) { | |||
2093 | unsigned int ti; | |||
2094 | float t; | |||
2095 | size_t i; | |||
2096 | AIR_UNUSED(parm)(void)(parm); | |||
2097 | for (i=0; i<len; i++) { | |||
2098 | t = x[i]; | |||
2099 | t = AIR_ABS(t)((t) > 0.0f ? (t) : -(t)); | |||
2100 | ti = AIR_CAST(unsigned int, t)((unsigned int)(t)); | |||
2101 | t -= AIR_CAST(float, ti)((float)(ti)); | |||
2102 | f[i] = AIR_CAST(float, _C5SEPT(ti, t))((float)((0 == ti ? (0.9379776601998824 + t*t*(-1.654320987654321 + t*t*(1.073045267489712 + t*t*(-0.44997427983539096 + t*0.13978909465020575 )))) : (1 == ti ? (0.04651675485008818 + t*(-0.7377829218106996 + t*(0.9699074074074074 + t*(0.18531378600823045 + t*(-0.7839506172839507 + t*(0.2357253086419753 + t*(0.12021604938271604 - t*0.054552469135802466 ))))))) : (2 == ti ? (-0.01860670194003527 + t*(0.14022633744855967 + t*(-0.16296296296296298 + t*(-0.09825102880658436 + t*(0.28858024691358025 + t*(-0.18858024691358025 + t*(0.04405864197530864 - t*0.0013631687242798354 ))))))) : (3 == ti ? (0.003101116990005879 + t*(-0.014223251028806585 + t*(0.02021604938271605 + t*(0.003729423868312757 + t*(-0.0411522633744856 + t*(0.04714506172839506 + t*(-0.023199588477366254 + t*0.004383450911228689 ))))))) : 0.0)))))); | |||
2103 | } | |||
2104 | } | |||
2105 | ||||
2106 | static NrrdKernel | |||
2107 | _c5sept = { | |||
2108 | "C5Septic", | |||
2109 | 0, returnFour, returnOne, | |||
2110 | _c5sept1_f, _c5septN_f, _c5sept1_d, _c5septN_d | |||
2111 | }; | |||
2112 | NrrdKernel *const | |||
2113 | nrrdKernelC5Septic = &_c5sept; | |||
2114 | ||||
2115 | #define _DC5SEPT0(x)(x*(-3.308641975308642 + x*x*(4.292181069958848 + x*x*(-2.6998456790123457 + x*0.9785236625514403)))) (x*(-3.308641975308642 + x*x*(4.292181069958848 + x*x*(-2.6998456790123457 + x*0.9785236625514403)))) | |||
2116 | #define _DC5SEPT1(x)(-0.7377829218106996 + x*(1.9398148148148149 + x*(0.5559413580246914 + x*(-3.1358024691358026 + x*(1.1786265432098766 + x*(0.7212962962962963 - x*0.3818672839506173)))))) (-0.7377829218106996 + x*(1.9398148148148149 + x*(0.5559413580246914 + x*(-3.1358024691358026 + x*(1.1786265432098766 + x*(0.7212962962962963 - x*0.3818672839506173)))))) | |||
2117 | #define _DC5SEPT2(x)(0.14022633744855967 + x*(-0.32592592592592595 + x*(-0.29475308641975306 + x*(1.154320987654321 + x*(-0.9429012345679012 + x*(0.26435185185185184 - x*0.009542181069958848)))))) (0.14022633744855967 + x*(-0.32592592592592595 + x*(-0.29475308641975306 + x*(1.154320987654321 + x*(-0.9429012345679012 + x*(0.26435185185185184 - x*0.009542181069958848)))))) | |||
2118 | #define _DC5SEPT3(x)(-0.014223251028806585 + x*(0.0404320987654321 + x*(0.011188271604938271 + x*(-0.1646090534979424 + x*(0.2357253086419753 + x*(-0.13919753086419753 + x*0.03068415637860082)))))) (-0.014223251028806585 + x*(0.0404320987654321 + x*(0.011188271604938271 + x*(-0.1646090534979424 + x*(0.2357253086419753 + x*(-0.13919753086419753 + x*0.03068415637860082)))))) | |||
2119 | #define _DC5SEPT(i, x)(0 == i ? (x*(-3.308641975308642 + x*x*(4.292181069958848 + x *x*(-2.6998456790123457 + x*0.9785236625514403)))) : (1 == i ? (-0.7377829218106996 + x*(1.9398148148148149 + x*(0.5559413580246914 + x*(-3.1358024691358026 + x*(1.1786265432098766 + x*(0.7212962962962963 - x*0.3818672839506173)))))) : (2 == i ? (0.14022633744855967 + x*(-0.32592592592592595 + x*(-0.29475308641975306 + x*(1.154320987654321 + x*(-0.9429012345679012 + x*(0.26435185185185184 - x*0.009542181069958848 )))))) : (3 == i ? (-0.014223251028806585 + x*(0.0404320987654321 + x*(0.011188271604938271 + x*(-0.1646090534979424 + x*(0.2357253086419753 + x*(-0.13919753086419753 + x*0.03068415637860082)))))) : 0.0 )))) \ | |||
2120 | (0 == i ? _DC5SEPT0(x)(x*(-3.308641975308642 + x*x*(4.292181069958848 + x*x*(-2.6998456790123457 + x*0.9785236625514403)))) \ | |||
2121 | : (1 == i ? _DC5SEPT1(x)(-0.7377829218106996 + x*(1.9398148148148149 + x*(0.5559413580246914 + x*(-3.1358024691358026 + x*(1.1786265432098766 + x*(0.7212962962962963 - x*0.3818672839506173)))))) \ | |||
2122 | : (2 == i ? _DC5SEPT2(x)(0.14022633744855967 + x*(-0.32592592592592595 + x*(-0.29475308641975306 + x*(1.154320987654321 + x*(-0.9429012345679012 + x*(0.26435185185185184 - x*0.009542181069958848)))))) \ | |||
2123 | : (3 == i ? _DC5SEPT3(x)(-0.014223251028806585 + x*(0.0404320987654321 + x*(0.011188271604938271 + x*(-0.1646090534979424 + x*(0.2357253086419753 + x*(-0.13919753086419753 + x*0.03068415637860082)))))) \ | |||
2124 | : 0.0)))) | |||
2125 | ||||
2126 | static double | |||
2127 | _dc5sept1_d(double x, const double *parm) { | |||
2128 | unsigned int xi; | |||
2129 | int sgn = 1; | |||
2130 | AIR_UNUSED(parm)(void)(parm); | |||
2131 | if (x < 0) { x = -x; sgn = -1; } | |||
2132 | xi = AIR_CAST(unsigned int, x)((unsigned int)(x)); | |||
2133 | x -= xi; | |||
2134 | return sgn*_DC5SEPT(xi, x)(0 == xi ? (x*(-3.308641975308642 + x*x*(4.292181069958848 + x *x*(-2.6998456790123457 + x*0.9785236625514403)))) : (1 == xi ? (-0.7377829218106996 + x*(1.9398148148148149 + x*(0.5559413580246914 + x*(-3.1358024691358026 + x*(1.1786265432098766 + x*(0.7212962962962963 - x*0.3818672839506173)))))) : (2 == xi ? (0.14022633744855967 + x*(-0.32592592592592595 + x*(-0.29475308641975306 + x*(1.154320987654321 + x*(-0.9429012345679012 + x*(0.26435185185185184 - x*0.009542181069958848 )))))) : (3 == xi ? (-0.014223251028806585 + x*(0.0404320987654321 + x*(0.011188271604938271 + x*(-0.1646090534979424 + x*(0.2357253086419753 + x*(-0.13919753086419753 + x*0.03068415637860082)))))) : 0.0 )))); | |||
2135 | } | |||
2136 | ||||
2137 | static float | |||
2138 | _dc5sept1_f(float x, const double *parm) { | |||
2139 | unsigned int xi; | |||
2140 | int sgn = 1; | |||
2141 | AIR_UNUSED(parm)(void)(parm); | |||
2142 | if (x < 0) { x = -x; sgn = -1; } | |||
2143 | xi = AIR_CAST(unsigned int, x)((unsigned int)(x)); | |||
2144 | x -= AIR_CAST(float, xi)((float)(xi)); | |||
2145 | return AIR_CAST(float, sgn*_DC5SEPT(xi, x))((float)(sgn*(0 == xi ? (x*(-3.308641975308642 + x*x*(4.292181069958848 + x*x*(-2.6998456790123457 + x*0.9785236625514403)))) : (1 == xi ? (-0.7377829218106996 + x*(1.9398148148148149 + x*(0.5559413580246914 + x*(-3.1358024691358026 + x*(1.1786265432098766 + x*(0.7212962962962963 - x*0.3818672839506173)))))) : (2 == xi ? (0.14022633744855967 + x*(-0.32592592592592595 + x*(-0.29475308641975306 + x*(1.154320987654321 + x*(-0.9429012345679012 + x*(0.26435185185185184 - x*0.009542181069958848 )))))) : (3 == xi ? (-0.014223251028806585 + x*(0.0404320987654321 + x*(0.011188271604938271 + x*(-0.1646090534979424 + x*(0.2357253086419753 + x*(-0.13919753086419753 + x*0.03068415637860082)))))) : 0.0 )))))); | |||
2146 | } | |||
2147 | ||||
2148 | static void | |||
2149 | _dc5septN_d(double *f, const double *x, size_t len, const double *parm) { | |||
2150 | unsigned int ti; | |||
2151 | double t; | |||
2152 | size_t i; | |||
2153 | int sgn; | |||
2154 | AIR_UNUSED(parm)(void)(parm); | |||
2155 | for (i=0; i<len; i++) { | |||
2156 | t = x[i]; | |||
2157 | if (t < 0) { t = -t; sgn = -1; } else { sgn = 1; } | |||
2158 | ti = AIR_CAST(unsigned int, t)((unsigned int)(t)); | |||
2159 | t -= ti; | |||
2160 | f[i] = sgn*_DC5SEPT(ti, t)(0 == ti ? (t*(-3.308641975308642 + t*t*(4.292181069958848 + t *t*(-2.6998456790123457 + t*0.9785236625514403)))) : (1 == ti ? (-0.7377829218106996 + t*(1.9398148148148149 + t*(0.5559413580246914 + t*(-3.1358024691358026 + t*(1.1786265432098766 + t*(0.7212962962962963 - t*0.3818672839506173)))))) : (2 == ti ? (0.14022633744855967 + t*(-0.32592592592592595 + t*(-0.29475308641975306 + t*(1.154320987654321 + t*(-0.9429012345679012 + t*(0.26435185185185184 - t*0.009542181069958848 )))))) : (3 == ti ? (-0.014223251028806585 + t*(0.0404320987654321 + t*(0.011188271604938271 + t*(-0.1646090534979424 + t*(0.2357253086419753 + t*(-0.13919753086419753 + t*0.03068415637860082)))))) : 0.0 )))); | |||
2161 | } | |||
2162 | } | |||
2163 | ||||
2164 | static void | |||
2165 | _dc5septN_f(float *f, const float *x, size_t len, const double *parm) { | |||
2166 | unsigned int ti; | |||
2167 | float t; | |||
2168 | size_t i; | |||
2169 | int sgn = 1; | |||
2170 | AIR_UNUSED(parm)(void)(parm); | |||
2171 | for (i=0; i<len; i++) { | |||
2172 | t = x[i]; | |||
2173 | if (t < 0) { t = -t; sgn = -1; } else { sgn = 1; } | |||
2174 | ti = AIR_CAST(unsigned int, t)((unsigned int)(t)); | |||
2175 | t -= AIR_CAST(float, ti)((float)(ti)); | |||
2176 | f[i] = AIR_CAST(float, sgn*_DC5SEPT(ti, t))((float)(sgn*(0 == ti ? (t*(-3.308641975308642 + t*t*(4.292181069958848 + t*t*(-2.6998456790123457 + t*0.9785236625514403)))) : (1 == ti ? (-0.7377829218106996 + t*(1.9398148148148149 + t*(0.5559413580246914 + t*(-3.1358024691358026 + t*(1.1786265432098766 + t*(0.7212962962962963 - t*0.3818672839506173)))))) : (2 == ti ? (0.14022633744855967 + t*(-0.32592592592592595 + t*(-0.29475308641975306 + t*(1.154320987654321 + t*(-0.9429012345679012 + t*(0.26435185185185184 - t*0.009542181069958848 )))))) : (3 == ti ? (-0.014223251028806585 + t*(0.0404320987654321 + t*(0.011188271604938271 + t*(-0.1646090534979424 + t*(0.2357253086419753 + t*(-0.13919753086419753 + t*0.03068415637860082)))))) : 0.0 )))))); | |||
2177 | } | |||
2178 | } | |||
2179 | ||||
2180 | static NrrdKernel | |||
2181 | _dc5sept = { | |||
2182 | "C5SepticD", | |||
2183 | 0, returnFour, returnZero, | |||
2184 | _dc5sept1_f, _dc5septN_f, _dc5sept1_d, _dc5septN_d | |||
2185 | }; | |||
2186 | NrrdKernel *const | |||
2187 | nrrdKernelC5SepticD = &_dc5sept; | |||
2188 | ||||
2189 | #define _DDC5SEPT0(x)(-3.308641975308642 + x*x*(12.876543209876543 + x*x*(-13.499228395061728 + x*5.871141975308642))) (-3.308641975308642 + x*x*(12.876543209876543 + x*x*(-13.499228395061728 + x*5.871141975308642))) | |||
2190 | #define _DDC5SEPT1(x)(1.9398148148148149 + x*(1.1118827160493827 + x*(-9.407407407407407 + x*(4.714506172839506 + x*(3.6064814814814814 - x*2.2912037037037036 ))))) (1.9398148148148149 + x*(1.1118827160493827 + x*(-9.407407407407407 + x*(4.714506172839506 + x*(3.6064814814814814 - x*2.2912037037037036))))) | |||
2191 | #define _DDC5SEPT2(x)(-0.32592592592592595 + x*(-0.5895061728395061 + x*(3.462962962962963 + x*(-3.771604938271605 + x*(1.3217592592592593 - x*0.05725308641975309 ))))) (-0.32592592592592595 + x*(-0.5895061728395061 + x*(3.462962962962963 + x*(-3.771604938271605 + x*(1.3217592592592593 - x*0.05725308641975309))))) | |||
2192 | #define _DDC5SEPT3(x)(0.0404320987654321 + x*(0.022376543209876542 + x*(-0.49382716049382713 + x*(0.9429012345679012 + x*(-0.6959876543209876 + x*0.18410493827160493 ))))) (0.0404320987654321 + x*(0.022376543209876542 + x*(-0.49382716049382713 + x*(0.9429012345679012 + x*(-0.6959876543209876 + x*0.18410493827160493))))) | |||
2193 | #define _DDC5SEPT(i, x)(0 == i ? (-3.308641975308642 + x*x*(12.876543209876543 + x*x *(-13.499228395061728 + x*5.871141975308642))) : (1 == i ? (1.9398148148148149 + x*(1.1118827160493827 + x*(-9.407407407407407 + x*(4.714506172839506 + x*(3.6064814814814814 - x*2.2912037037037036))))) : (2 == i ? (-0.32592592592592595 + x*(-0.5895061728395061 + x*(3.462962962962963 + x*(-3.771604938271605 + x*(1.3217592592592593 - x*0.05725308641975309 ))))) : (3 == i ? (0.0404320987654321 + x*(0.022376543209876542 + x*(-0.49382716049382713 + x*(0.9429012345679012 + x*(-0.6959876543209876 + x*0.18410493827160493))))) : 0.0)))) \ | |||
2194 | (0 == i ? _DDC5SEPT0(x)(-3.308641975308642 + x*x*(12.876543209876543 + x*x*(-13.499228395061728 + x*5.871141975308642))) \ | |||
2195 | : (1 == i ? _DDC5SEPT1(x)(1.9398148148148149 + x*(1.1118827160493827 + x*(-9.407407407407407 + x*(4.714506172839506 + x*(3.6064814814814814 - x*2.2912037037037036 ))))) \ | |||
2196 | : (2 == i ? _DDC5SEPT2(x)(-0.32592592592592595 + x*(-0.5895061728395061 + x*(3.462962962962963 + x*(-3.771604938271605 + x*(1.3217592592592593 - x*0.05725308641975309 ))))) \ | |||
2197 | : (3 == i ? _DDC5SEPT3(x)(0.0404320987654321 + x*(0.022376543209876542 + x*(-0.49382716049382713 + x*(0.9429012345679012 + x*(-0.6959876543209876 + x*0.18410493827160493 ))))) \ | |||
2198 | : 0.0)))) | |||
2199 | ||||
2200 | static double | |||
2201 | _ddc5sept1_d(double x, const double *parm) { | |||
2202 | unsigned int xi; | |||
2203 | AIR_UNUSED(parm)(void)(parm); | |||
2204 | x = AIR_ABS(x)((x) > 0.0f ? (x) : -(x)); | |||
2205 | xi = AIR_CAST(unsigned int, x)((unsigned int)(x)); | |||
2206 | x -= xi; | |||
2207 | return _DDC5SEPT(xi, x)(0 == xi ? (-3.308641975308642 + x*x*(12.876543209876543 + x* x*(-13.499228395061728 + x*5.871141975308642))) : (1 == xi ? ( 1.9398148148148149 + x*(1.1118827160493827 + x*(-9.407407407407407 + x*(4.714506172839506 + x*(3.6064814814814814 - x*2.2912037037037036 ))))) : (2 == xi ? (-0.32592592592592595 + x*(-0.5895061728395061 + x*(3.462962962962963 + x*(-3.771604938271605 + x*(1.3217592592592593 - x*0.05725308641975309))))) : (3 == xi ? (0.0404320987654321 + x*(0.022376543209876542 + x*(-0.49382716049382713 + x*(0.9429012345679012 + x*(-0.6959876543209876 + x*0.18410493827160493))))) : 0.0) ))); | |||
2208 | } | |||
2209 | ||||
2210 | static float | |||
2211 | _ddc5sept1_f(float x, const double *parm) { | |||
2212 | unsigned int xi; | |||
2213 | AIR_UNUSED(parm)(void)(parm); | |||
2214 | x = AIR_ABS(x)((x) > 0.0f ? (x) : -(x)); | |||
2215 | xi = AIR_CAST(unsigned int, x)((unsigned int)(x)); | |||
2216 | x -= AIR_CAST(float, xi)((float)(xi)); | |||
2217 | return AIR_CAST(float, _DDC5SEPT(xi, x))((float)((0 == xi ? (-3.308641975308642 + x*x*(12.876543209876543 + x*x*(-13.499228395061728 + x*5.871141975308642))) : (1 == xi ? (1.9398148148148149 + x*(1.1118827160493827 + x*(-9.407407407407407 + x*(4.714506172839506 + x*(3.6064814814814814 - x*2.2912037037037036 ))))) : (2 == xi ? (-0.32592592592592595 + x*(-0.5895061728395061 + x*(3.462962962962963 + x*(-3.771604938271605 + x*(1.3217592592592593 - x*0.05725308641975309))))) : (3 == xi ? (0.0404320987654321 + x*(0.022376543209876542 + x*(-0.49382716049382713 + x*(0.9429012345679012 + x*(-0.6959876543209876 + x*0.18410493827160493))))) : 0.0) ))))); | |||
2218 | } | |||
2219 | ||||
2220 | static void | |||
2221 | _ddc5septN_d(double *f, const double *x, size_t len, const double *parm) { | |||
2222 | unsigned int ti; | |||
2223 | double t; | |||
2224 | size_t i; | |||
2225 | AIR_UNUSED(parm)(void)(parm); | |||
2226 | for (i=0; i<len; i++) { | |||
2227 | t = x[i]; | |||
2228 | t = AIR_ABS(t)((t) > 0.0f ? (t) : -(t)); | |||
2229 | ti = AIR_CAST(unsigned int, t)((unsigned int)(t)); | |||
2230 | t -= ti; | |||
2231 | f[i] = _DDC5SEPT(ti, t)(0 == ti ? (-3.308641975308642 + t*t*(12.876543209876543 + t* t*(-13.499228395061728 + t*5.871141975308642))) : (1 == ti ? ( 1.9398148148148149 + t*(1.1118827160493827 + t*(-9.407407407407407 + t*(4.714506172839506 + t*(3.6064814814814814 - t*2.2912037037037036 ))))) : (2 == ti ? (-0.32592592592592595 + t*(-0.5895061728395061 + t*(3.462962962962963 + t*(-3.771604938271605 + t*(1.3217592592592593 - t*0.05725308641975309))))) : (3 == ti ? (0.0404320987654321 + t*(0.022376543209876542 + t*(-0.49382716049382713 + t*(0.9429012345679012 + t*(-0.6959876543209876 + t*0.18410493827160493))))) : 0.0) ))); | |||
2232 | } | |||
2233 | } | |||
2234 | ||||
2235 | static void | |||
2236 | _ddc5septN_f(float *f, const float *x, size_t len, const double *parm) { | |||
2237 | unsigned int ti; | |||
2238 | float t; | |||
2239 | size_t i; | |||
2240 | AIR_UNUSED(parm)(void)(parm); | |||
2241 | for (i=0; i<len; i++) { | |||
2242 | t = x[i]; | |||
2243 | t = AIR_ABS(t)((t) > 0.0f ? (t) : -(t)); | |||
2244 | ti = AIR_CAST(unsigned int, t)((unsigned int)(t)); | |||
2245 | t -= AIR_CAST(float, ti)((float)(ti)); | |||
2246 | f[i] = AIR_CAST(float, _DDC5SEPT(ti, t))((float)((0 == ti ? (-3.308641975308642 + t*t*(12.876543209876543 + t*t*(-13.499228395061728 + t*5.871141975308642))) : (1 == ti ? (1.9398148148148149 + t*(1.1118827160493827 + t*(-9.407407407407407 + t*(4.714506172839506 + t*(3.6064814814814814 - t*2.2912037037037036 ))))) : (2 == ti ? (-0.32592592592592595 + t*(-0.5895061728395061 + t*(3.462962962962963 + t*(-3.771604938271605 + t*(1.3217592592592593 - t*0.05725308641975309))))) : (3 == ti ? (0.0404320987654321 + t*(0.022376543209876542 + t*(-0.49382716049382713 + t*(0.9429012345679012 + t*(-0.6959876543209876 + t*0.18410493827160493))))) : 0.0) ))))); | |||
2247 | } | |||
2248 | } | |||
2249 | ||||
2250 | static NrrdKernel | |||
2251 | _ddc5sept = { | |||
2252 | "C5SepticDD", | |||
2253 | 0, returnFour, returnZero, | |||
2254 | _ddc5sept1_f, _ddc5septN_f, _ddc5sept1_d, _ddc5septN_d | |||
2255 | }; | |||
2256 | NrrdKernel *const | |||
2257 | nrrdKernelC5SepticDD = &_ddc5sept; | |||
2258 | ||||
2259 | #define _DDDC5SEPT0(x)(x*(25.75308641975309 + x*x*(-53.99691358024691 + x*29.35570987654321 ))) (x*(25.75308641975309 + x*x*(-53.99691358024691 + x*29.35570987654321))) | |||
2260 | #define _DDDC5SEPT1(x)(1.111882716049383 + x*(-18.81481481481481 + x*(14.14351851851852 + x*(14.42592592592593 - x*11.45601851851852)))) (1.111882716049383 + x*(-18.81481481481481 + x*(14.14351851851852 + x*(14.42592592592593 - x*11.45601851851852)))) | |||
2261 | #define _DDDC5SEPT2(x)(-0.5895061728395062 + x*(6.925925925925926 + x*(-11.31481481481481 + x*(5.287037037037037 - x*0.2862654320987654)))) (-0.5895061728395062 + x*(6.925925925925926 + x*(-11.31481481481481 + x*(5.287037037037037 - x*0.2862654320987654)))) | |||
2262 | #define _DDDC5SEPT3(x)(0.02237654320987654 + x*(-0.9876543209876543 + x*(2.828703703703704 + x*(-2.783950617283951 + x*0.9205246913580247)))) (0.02237654320987654 + x*(-0.9876543209876543 + x*(2.828703703703704 + x*(-2.783950617283951 + x*0.9205246913580247)))) | |||
2263 | #define _DDDC5SEPT(i, x)(0 == i ? (x*(25.75308641975309 + x*x*(-53.99691358024691 + x *29.35570987654321))) : (1 == i ? (1.111882716049383 + x*(-18.81481481481481 + x*(14.14351851851852 + x*(14.42592592592593 - x*11.45601851851852 )))) : (2 == i ? (-0.5895061728395062 + x*(6.925925925925926 + x*(-11.31481481481481 + x*(5.287037037037037 - x*0.2862654320987654 )))) : (3 == i ? (0.02237654320987654 + x*(-0.9876543209876543 + x*(2.828703703703704 + x*(-2.783950617283951 + x*0.9205246913580247 )))) : 0.0)))) \ | |||
2264 | (0 == i ? _DDDC5SEPT0(x)(x*(25.75308641975309 + x*x*(-53.99691358024691 + x*29.35570987654321 ))) \ | |||
2265 | : (1 == i ? _DDDC5SEPT1(x)(1.111882716049383 + x*(-18.81481481481481 + x*(14.14351851851852 + x*(14.42592592592593 - x*11.45601851851852)))) \ | |||
2266 | : (2 == i ? _DDDC5SEPT2(x)(-0.5895061728395062 + x*(6.925925925925926 + x*(-11.31481481481481 + x*(5.287037037037037 - x*0.2862654320987654)))) \ | |||
2267 | : (3 == i ? _DDDC5SEPT3(x)(0.02237654320987654 + x*(-0.9876543209876543 + x*(2.828703703703704 + x*(-2.783950617283951 + x*0.9205246913580247)))) \ | |||
2268 | : 0.0)))) | |||
2269 | ||||
2270 | static double | |||
2271 | _dddc5sept1_d(double x, const double *parm) { | |||
2272 | unsigned int xi; | |||
2273 | int sgn = 1; | |||
2274 | AIR_UNUSED(parm)(void)(parm); | |||
2275 | if (x < 0) { x = -x; sgn = -1; } | |||
2276 | xi = AIR_CAST(unsigned int, x)((unsigned int)(x)); | |||
2277 | x -= xi; | |||
2278 | return sgn*_DDDC5SEPT(xi, x)(0 == xi ? (x*(25.75308641975309 + x*x*(-53.99691358024691 + x *29.35570987654321))) : (1 == xi ? (1.111882716049383 + x*(-18.81481481481481 + x*(14.14351851851852 + x*(14.42592592592593 - x*11.45601851851852 )))) : (2 == xi ? (-0.5895061728395062 + x*(6.925925925925926 + x*(-11.31481481481481 + x*(5.287037037037037 - x*0.2862654320987654 )))) : (3 == xi ? (0.02237654320987654 + x*(-0.9876543209876543 + x*(2.828703703703704 + x*(-2.783950617283951 + x*0.9205246913580247 )))) : 0.0)))); | |||
2279 | } | |||
2280 | ||||
2281 | static float | |||
2282 | _dddc5sept1_f(float x, const double *parm) { | |||
2283 | unsigned int xi; | |||
2284 | int sgn = 1; | |||
2285 | AIR_UNUSED(parm)(void)(parm); | |||
2286 | if (x < 0) { x = -x; sgn = -1; } | |||
2287 | xi = AIR_CAST(unsigned int, x)((unsigned int)(x)); | |||
2288 | x -= AIR_CAST(float, xi)((float)(xi)); | |||
2289 | return AIR_CAST(float, sgn*_DDDC5SEPT(xi, x))((float)(sgn*(0 == xi ? (x*(25.75308641975309 + x*x*(-53.99691358024691 + x*29.35570987654321))) : (1 == xi ? (1.111882716049383 + x *(-18.81481481481481 + x*(14.14351851851852 + x*(14.42592592592593 - x*11.45601851851852)))) : (2 == xi ? (-0.5895061728395062 + x*(6.925925925925926 + x*(-11.31481481481481 + x*(5.287037037037037 - x*0.2862654320987654)))) : (3 == xi ? (0.02237654320987654 + x*(-0.9876543209876543 + x*(2.828703703703704 + x*(-2.783950617283951 + x*0.9205246913580247)))) : 0.0)))))); | |||
2290 | } | |||
2291 | ||||
2292 | static void | |||
2293 | _dddc5septN_d(double *f, const double *x, size_t len, const double *parm) { | |||
2294 | unsigned int ti; | |||
2295 | double t; | |||
2296 | size_t i; | |||
2297 | int sgn; | |||
2298 | AIR_UNUSED(parm)(void)(parm); | |||
2299 | for (i=0; i<len; i++) { | |||
2300 | t = x[i]; | |||
2301 | if (t < 0) { t = -t; sgn = -1; } else { sgn = 1; } | |||
2302 | ti = AIR_CAST(unsigned int, t)((unsigned int)(t)); | |||
2303 | t -= ti; | |||
2304 | f[i] = sgn*_DDDC5SEPT(ti, t)(0 == ti ? (t*(25.75308641975309 + t*t*(-53.99691358024691 + t *29.35570987654321))) : (1 == ti ? (1.111882716049383 + t*(-18.81481481481481 + t*(14.14351851851852 + t*(14.42592592592593 - t*11.45601851851852 )))) : (2 == ti ? (-0.5895061728395062 + t*(6.925925925925926 + t*(-11.31481481481481 + t*(5.287037037037037 - t*0.2862654320987654 )))) : (3 == ti ? (0.02237654320987654 + t*(-0.9876543209876543 + t*(2.828703703703704 + t*(-2.783950617283951 + t*0.9205246913580247 )))) : 0.0)))); | |||
2305 | } | |||
2306 | } | |||
2307 | ||||
2308 | static void | |||
2309 | _dddc5septN_f(float *f, const float *x, size_t len, const double *parm) { | |||
2310 | unsigned int ti; | |||
2311 | float t; | |||
2312 | size_t i; | |||
2313 | int sgn = 1; | |||
2314 | AIR_UNUSED(parm)(void)(parm); | |||
2315 | for (i=0; i<len; i++) { | |||
2316 | t = x[i]; | |||
2317 | if (t < 0) { t = -t; sgn = -1; } else { sgn = 1; } | |||
2318 | ti = AIR_CAST(unsigned int, t)((unsigned int)(t)); | |||
2319 | t -= AIR_CAST(float, ti)((float)(ti)); | |||
2320 | f[i] = AIR_CAST(float, sgn*_DDDC5SEPT(ti, t))((float)(sgn*(0 == ti ? (t*(25.75308641975309 + t*t*(-53.99691358024691 + t*29.35570987654321))) : (1 == ti ? (1.111882716049383 + t *(-18.81481481481481 + t*(14.14351851851852 + t*(14.42592592592593 - t*11.45601851851852)))) : (2 == ti ? (-0.5895061728395062 + t*(6.925925925925926 + t*(-11.31481481481481 + t*(5.287037037037037 - t*0.2862654320987654)))) : (3 == ti ? (0.02237654320987654 + t*(-0.9876543209876543 + t*(2.828703703703704 + t*(-2.783950617283951 + t*0.9205246913580247)))) : 0.0)))))); | |||
2321 | } | |||
2322 | } | |||
2323 | ||||
2324 | static NrrdKernel | |||
2325 | _dddc5sept = { | |||
2326 | "C5SepticDDD", | |||
2327 | 0, returnFour, returnZero, | |||
2328 | _dddc5sept1_f, _dddc5septN_f, _dddc5sept1_d, _dddc5septN_d | |||
2329 | }; | |||
2330 | NrrdKernel *const | |||
2331 | nrrdKernelC5SepticDDD = &_dddc5sept; | |||
2332 | ||||
2333 | /* note that this implies a much more accurate inverse than is given | |||
2334 | for the splines or other kernels; this is a consequence of GLK | |||
2335 | re-purposing the Mathematica expressions for the bpsln7 inverse, | |||
2336 | which is unfortunate: c5septic is nearly interpolating, so far | |||
2337 | fewer terms would suffice */ | |||
2338 | #define C5SEPT_AI_LEN26 26 | |||
2339 | static double | |||
2340 | _c5sept_ANI_kvals[C5SEPT_AI_LEN26] = { | |||
2341 | 1.072662863909143543451743, | |||
2342 | -0.05572032001443187610952953, | |||
2343 | 0.02453993146603215267432700, | |||
2344 | -0.005922375635530229254855750, | |||
2345 | 0.0009781882769025851448681918, | |||
2346 | -0.0002499281491108793120774480, | |||
2347 | 0.00005196973116762945530292666, | |||
2348 | -0.00001090007030248955413371701, | |||
2349 | 2.425581976693179040189747e-6, | |||
2350 | -5.143328756144314306529358e-7, | |||
2351 | 1.109572595055083858393193e-7, | |||
2352 | -2.400323559797703961855318e-8, | |||
2353 | 5.151959978856239469272136e-9, | |||
2354 | -1.111431289951609447815300e-9, | |||
2355 | 2.394624249806782312051293e-10, | |||
2356 | -5.155654818408366273965675e-11, | |||
2357 | 1.111091879440261302739584e-11, | |||
2358 | -2.393303168472914213194646e-12, | |||
2359 | 5.155527554392687415035171e-13, | |||
2360 | -1.110707782883835600110634e-13, | |||
2361 | 2.392644268109899456937863e-14, | |||
2362 | -5.154377464414088544322752e-15, | |||
2363 | 1.110376957658466603291262e-15, | |||
2364 | -2.391459139266885907929865e-16, | |||
2365 | 5.137528165538909945741180e-17, | |||
2366 | -9.024576392408067896802608e-18}; | |||
2367 | ||||
2368 | static double | |||
2369 | _c5sept_ANI_sup(const double *parm) { | |||
2370 | AIR_UNUSED(parm)(void)(parm); | |||
2371 | return C5SEPT_AI_LEN26 + 0.5; | |||
2372 | } | |||
2373 | ||||
2374 | static double | |||
2375 | _c5sept_ANI_int(const double *parm) { | |||
2376 | AIR_UNUSED(parm)(void)(parm); | |||
2377 | return 1.0; | |||
2378 | } | |||
2379 | ||||
2380 | #define C5SEPT_ANI(ret, tmp, x)tmp = ((unsigned int)(x+0.5)); if (tmp < 26) { ret = _c5sept_ANI_kvals [tmp]; } else { ret = 0.0; } \ | |||
2381 | tmp = AIR_CAST(unsigned int, x+0.5)((unsigned int)(x+0.5)); \ | |||
2382 | if (tmp < C5SEPT_AI_LEN26) { \ | |||
2383 | ret = _c5sept_ANI_kvals[tmp]; \ | |||
2384 | } else { \ | |||
2385 | ret = 0.0; \ | |||
2386 | } | |||
2387 | ||||
2388 | static double | |||
2389 | _c5sept_ANI_1d(double x, const double *parm) { | |||
2390 | double ax, r; unsigned int tmp; | |||
2391 | AIR_UNUSED(parm)(void)(parm); | |||
2392 | ||||
2393 | ax = AIR_ABS(x)((x) > 0.0f ? (x) : -(x)); | |||
2394 | C5SEPT_ANI(r, tmp, ax)tmp = ((unsigned int)(ax+0.5)); if (tmp < 26) { r = _c5sept_ANI_kvals [tmp]; } else { r = 0.0; }; | |||
2395 | return r; | |||
2396 | } | |||
2397 | ||||
2398 | static float | |||
2399 | _c5sept_ANI_1f(float x, const double *parm) { | |||
2400 | double ax, r; unsigned int tmp; | |||
2401 | AIR_UNUSED(parm)(void)(parm); | |||
2402 | ||||
2403 | ax = AIR_ABS(x)((x) > 0.0f ? (x) : -(x)); | |||
2404 | C5SEPT_ANI(r, tmp, ax)tmp = ((unsigned int)(ax+0.5)); if (tmp < 26) { r = _c5sept_ANI_kvals [tmp]; } else { r = 0.0; }; | |||
2405 | return AIR_CAST(float, r)((float)(r)); | |||
2406 | } | |||
2407 | ||||
2408 | static void | |||
2409 | _c5sept_ANI_Nd(double *f, const double *x, size_t len, const double *parm) { | |||
2410 | double ax, r; unsigned int tmp; | |||
2411 | size_t i; | |||
2412 | AIR_UNUSED(parm)(void)(parm); | |||
2413 | ||||
2414 | for (i=0; i<len; i++) { | |||
2415 | ax = x[i]; ax = AIR_ABS(ax)((ax) > 0.0f ? (ax) : -(ax)); | |||
2416 | C5SEPT_ANI(r, tmp, ax)tmp = ((unsigned int)(ax+0.5)); if (tmp < 26) { r = _c5sept_ANI_kvals [tmp]; } else { r = 0.0; }; | |||
2417 | f[i] = r; | |||
2418 | } | |||
2419 | } | |||
2420 | ||||
2421 | static void | |||
2422 | _c5sept_ANI_Nf(float *f, const float *x, size_t len, const double *parm) { | |||
2423 | double ax, r; unsigned int tmp; | |||
2424 | size_t i; | |||
2425 | AIR_UNUSED(parm)(void)(parm); | |||
2426 | ||||
2427 | for (i=0; i<len; i++) { | |||
2428 | ax = x[i]; ax = AIR_ABS(ax)((ax) > 0.0f ? (ax) : -(ax)); | |||
2429 | C5SEPT_ANI(r, tmp, ax)tmp = ((unsigned int)(ax+0.5)); if (tmp < 26) { r = _c5sept_ANI_kvals [tmp]; } else { r = 0.0; }; | |||
2430 | f[i] = AIR_CAST(float, r)((float)(r)); | |||
2431 | } | |||
2432 | } | |||
2433 | ||||
2434 | static NrrdKernel | |||
2435 | _nrrdKernelC5SepticApproxInverse = { | |||
2436 | "C5SepticAI", 0, | |||
2437 | _c5sept_ANI_sup, _c5sept_ANI_int, | |||
2438 | _c5sept_ANI_1f, _c5sept_ANI_Nf, | |||
2439 | _c5sept_ANI_1d, _c5sept_ANI_Nd | |||
2440 | }; | |||
2441 | NrrdKernel *const | |||
2442 | nrrdKernelC5SepticApproxInverse = &_nrrdKernelC5SepticApproxInverse; | |||
2443 | ||||
2444 | /* ------------------------------------------------------------ */ | |||
2445 | ||||
2446 | #define _GAUSS(x, sig, cut)( x >= sig*cut ? 0 : exp(-x*x/(2.0*sig*sig))/(sig*2.50662827463100050241 )) ( \ | |||
2447 | x >= sig*cut ? 0 \ | |||
2448 | : exp(-x*x/(2.0*sig*sig))/(sig*2.50662827463100050241)) | |||
2449 | ||||
2450 | static double | |||
2451 | _nrrdGInt(const double *parm) { | |||
2452 | double cut; | |||
2453 | ||||
2454 | cut = parm[1]; | |||
2455 | return airErf(cut/sqrt(2.0)); | |||
2456 | } | |||
2457 | ||||
2458 | static double | |||
2459 | _nrrdGSup(const double *parm) { | |||
2460 | double sig, cut; | |||
2461 | ||||
2462 | sig = parm[0]; | |||
2463 | cut = parm[1]; | |||
2464 | return sig*cut; | |||
2465 | } | |||
2466 | ||||
2467 | static double | |||
2468 | _nrrdG1_d(double x, const double *parm) { | |||
2469 | double sig, cut; | |||
2470 | ||||
2471 | sig = parm[0]; | |||
2472 | cut = parm[1]; | |||
2473 | x = AIR_ABS(x)((x) > 0.0f ? (x) : -(x)); | |||
2474 | return _GAUSS(x, sig, cut)( x >= sig*cut ? 0 : exp(-x*x/(2.0*sig*sig))/(sig*2.50662827463100050241 )); | |||
2475 | } | |||
2476 | ||||
2477 | static float | |||
2478 | _nrrdG1_f(float x, const double *parm) { | |||
2479 | float sig, cut; | |||
2480 | ||||
2481 | sig = AIR_CAST(float, parm[0])((float)(parm[0])); | |||
2482 | cut = AIR_CAST(float, parm[1])((float)(parm[1])); | |||
2483 | x = AIR_ABS(x)((x) > 0.0f ? (x) : -(x)); | |||
2484 | return AIR_CAST(float, _GAUSS(x, sig, cut))((float)(( x >= sig*cut ? 0 : exp(-x*x/(2.0*sig*sig))/(sig *2.50662827463100050241)))); | |||
2485 | } | |||
2486 | ||||
2487 | static void | |||
2488 | _nrrdGN_d(double *f, const double *x, size_t len, const double *parm) { | |||
2489 | double sig, cut, t; | |||
2490 | size_t i; | |||
2491 | ||||
2492 | sig = parm[0]; | |||
2493 | cut = parm[1]; | |||
2494 | for (i=0; i<len; i++) { | |||
2495 | t = x[i]; | |||
2496 | t = AIR_ABS(t)((t) > 0.0f ? (t) : -(t)); | |||
2497 | f[i] = _GAUSS(t, sig, cut)( t >= sig*cut ? 0 : exp(-t*t/(2.0*sig*sig))/(sig*2.50662827463100050241 )); | |||
2498 | } | |||
2499 | } | |||
2500 | ||||
2501 | static void | |||
2502 | _nrrdGN_f(float *f, const float *x, size_t len, const double *parm) { | |||
2503 | float sig, cut, t; | |||
2504 | size_t i; | |||
2505 | ||||
2506 | sig = AIR_CAST(float, parm[0])((float)(parm[0])); | |||
2507 | cut = AIR_CAST(float, parm[1])((float)(parm[1])); | |||
2508 | for (i=0; i<len; i++) { | |||
2509 | t = x[i]; | |||
2510 | t = AIR_ABS(t)((t) > 0.0f ? (t) : -(t)); | |||
2511 | f[i] = AIR_CAST(float, _GAUSS(t, sig, cut))((float)(( t >= sig*cut ? 0 : exp(-t*t/(2.0*sig*sig))/(sig *2.50662827463100050241)))); | |||
2512 | } | |||
2513 | } | |||
2514 | ||||
2515 | static NrrdKernel | |||
2516 | _nrrdKernelG = { | |||
2517 | "gauss", | |||
2518 | 2, _nrrdGSup, _nrrdGInt, | |||
2519 | _nrrdG1_f, _nrrdGN_f, _nrrdG1_d, _nrrdGN_d | |||
2520 | }; | |||
2521 | NrrdKernel *const | |||
2522 | nrrdKernelGaussian = &_nrrdKernelG; | |||
2523 | ||||
2524 | /* ------------------------------------------------------------ */ | |||
2525 | ||||
2526 | #define _DISCRETEGAUSS(xx, sig, abscut)(sig > 0 ? (xx > abscut ? 0 : airBesselInExpScaled(((int )(xx + 0.5)), sig*sig)) : xx <= 0.5) \ | |||
2527 | (sig > 0 \ | |||
2528 | ? (xx > abscut \ | |||
2529 | ? 0 \ | |||
2530 | : airBesselInExpScaled(AIR_CAST(int, xx + 0.5)((int)(xx + 0.5)), sig*sig)) \ | |||
2531 | : xx <= 0.5) | |||
2532 | ||||
2533 | /* the last line used to be AIR_MAX(0.5, (ret)), but the problem was | |||
2534 | that even for reasonable cutoffs, like sigma=6, there would be a | |||
2535 | sudden change in the non-zero values at the edge of the kernel with | |||
2536 | slowly increasing sigma. The real solution is to have a smarter way | |||
2537 | of determining where to cut-off this particular kernel, the | |||
2538 | discrete gaussian, when the values are at the low level one would | |||
2539 | expect with "sigma=6" when talking about a continuous Gaussian */ | |||
2540 | #define _DGABSCUT(ret, sig, cut)(ret) = 0.5 + ceil((sig)*(cut)); (ret) = ((2.5) > ((ret)) ? (2.5) : ((ret))) \ | |||
2541 | (ret) = 0.5 + ceil((sig)*(cut)); \ | |||
2542 | (ret) = AIR_MAX(2.5, (ret))((2.5) > ((ret)) ? (2.5) : ((ret))) | |||
2543 | ||||
2544 | static double | |||
2545 | _nrrdDiscGaussianSup(const double *parm) { | |||
2546 | double ret; | |||
2547 | ||||
2548 | _DGABSCUT(ret, parm[0], parm[1])(ret) = 0.5 + ceil((parm[0])*(parm[1])); (ret) = ((2.5) > ( (ret)) ? (2.5) : ((ret))); | |||
2549 | return ret; | |||
2550 | } | |||
2551 | ||||
2552 | /* the functions are out of their usual definition order because we | |||
2553 | use the function evaluation to determine the integral, rather than | |||
2554 | trying to do it analytically */ | |||
2555 | ||||
2556 | static double | |||
2557 | _nrrdDiscGaussian1_d(double xx, const double *parm) { | |||
2558 | double sig, cut; | |||
2559 | ||||
2560 | sig = parm[0]; | |||
2561 | _DGABSCUT(cut, sig, parm[1])(cut) = 0.5 + ceil((sig)*(parm[1])); (cut) = ((2.5) > ((cut )) ? (2.5) : ((cut))); | |||
2562 | xx = AIR_ABS(xx)((xx) > 0.0f ? (xx) : -(xx)); | |||
2563 | return _DISCRETEGAUSS(xx, sig, cut)(sig > 0 ? (xx > cut ? 0 : airBesselInExpScaled(((int)( xx + 0.5)), sig*sig)) : xx <= 0.5); | |||
2564 | } | |||
2565 | ||||
2566 | static double | |||
2567 | _nrrdDiscGaussianInt(const double *parm) { | |||
2568 | double sum, cut; | |||
2569 | int ii, supp; | |||
2570 | ||||
2571 | _DGABSCUT(cut, parm[0], parm[1])(cut) = 0.5 + ceil((parm[0])*(parm[1])); (cut) = ((2.5) > ( (cut)) ? (2.5) : ((cut))); | |||
2572 | supp = AIR_CAST(int, cut)((int)(cut)); | |||
2573 | sum = 0.0; | |||
2574 | for (ii=-supp; ii<=supp; ii++) { | |||
2575 | sum += _nrrdDiscGaussian1_d(ii, parm); | |||
2576 | } | |||
2577 | return sum; | |||
2578 | } | |||
2579 | ||||
2580 | static float | |||
2581 | _nrrdDiscGaussian1_f(float xx, const double *parm) { | |||
2582 | double sig, cut; | |||
2583 | ||||
2584 | sig = parm[0]; | |||
2585 | _DGABSCUT(cut, sig, parm[1])(cut) = 0.5 + ceil((sig)*(parm[1])); (cut) = ((2.5) > ((cut )) ? (2.5) : ((cut))); | |||
2586 | xx = AIR_ABS(xx)((xx) > 0.0f ? (xx) : -(xx)); | |||
2587 | return AIR_CAST(float, _DISCRETEGAUSS(xx, sig, cut))((float)((sig > 0 ? (xx > cut ? 0 : airBesselInExpScaled (((int)(xx + 0.5)), sig*sig)) : xx <= 0.5))); | |||
2588 | } | |||
2589 | ||||
2590 | static void | |||
2591 | _nrrdDiscGaussianN_d(double *f, const double *x, | |||
2592 | size_t len, const double *parm) { | |||
2593 | double sig, cut, tt; | |||
2594 | size_t ii; | |||
2595 | ||||
2596 | sig = parm[0]; | |||
2597 | _DGABSCUT(cut, sig, parm[1])(cut) = 0.5 + ceil((sig)*(parm[1])); (cut) = ((2.5) > ((cut )) ? (2.5) : ((cut))); | |||
2598 | for (ii=0; ii<len; ii++) { | |||
2599 | tt = AIR_ABS(x[ii])((x[ii]) > 0.0f ? (x[ii]) : -(x[ii])); | |||
2600 | f[ii] = _DISCRETEGAUSS(tt, sig, cut)(sig > 0 ? (tt > cut ? 0 : airBesselInExpScaled(((int)( tt + 0.5)), sig*sig)) : tt <= 0.5); | |||
2601 | } | |||
2602 | } | |||
2603 | ||||
2604 | static void | |||
2605 | _nrrdDiscGaussianN_f(float *f, const float *x, size_t len, const double *parm) { | |||
2606 | double sig, cut, tt; | |||
2607 | size_t ii; | |||
2608 | ||||
2609 | sig = parm[0]; | |||
2610 | _DGABSCUT(cut, sig, parm[1])(cut) = 0.5 + ceil((sig)*(parm[1])); (cut) = ((2.5) > ((cut )) ? (2.5) : ((cut))); | |||
2611 | for (ii=0; ii<len; ii++) { | |||
2612 | tt = AIR_ABS(x[ii])((x[ii]) > 0.0f ? (x[ii]) : -(x[ii])); | |||
2613 | f[ii] = AIR_CAST(float, _DISCRETEGAUSS(tt, sig, cut))((float)((sig > 0 ? (tt > cut ? 0 : airBesselInExpScaled (((int)(tt + 0.5)), sig*sig)) : tt <= 0.5))); | |||
2614 | } | |||
2615 | } | |||
2616 | ||||
2617 | static NrrdKernel | |||
2618 | _nrrdKernelDiscreteGaussian = { | |||
2619 | "discretegauss", 2, | |||
2620 | _nrrdDiscGaussianSup, _nrrdDiscGaussianInt, | |||
2621 | _nrrdDiscGaussian1_f, _nrrdDiscGaussianN_f, | |||
2622 | _nrrdDiscGaussian1_d, _nrrdDiscGaussianN_d | |||
2623 | }; | |||
2624 | NrrdKernel *const | |||
2625 | nrrdKernelDiscreteGaussian = &_nrrdKernelDiscreteGaussian; | |||
2626 | ||||
2627 | /* The current implementation of nrrdKernelDiscreteGaussian, with the current | |||
2628 | implementation of airBesselInExpScaled, has problems for large | |||
2629 | sigma. Until those are fixed, this is a suggested limit on how big sigma | |||
2630 | (kparm[0]) can be and still have an accurate blurring kernel. This | |||
2631 | problem can be avoided completely by doing the blurring in frequency | |||
2632 | space, which is implemented in teem/src/gage/stackBlur.c's | |||
2633 | _stackBlurDiscreteGaussFFT(), although that has its own problem: in places | |||
2634 | where a signal really should zero, the FFT can produce some very | |||
2635 | low-amplitude noise (and hence new extrema) */ | |||
2636 | const double nrrdKernelDiscreteGaussianGoodSigmaMax = 6.0; | |||
2637 | ||||
2638 | /* ------------------------------------------------------------ */ | |||
2639 | ||||
2640 | #define _DGAUSS(x, sig, cut)( x >= sig*cut ? 0 : -exp(-x*x/(2.0*sig*sig))*x/(sig*sig*sig *2.50662827463100050241)) ( \ | |||
2641 | x >= sig*cut ? 0 \ | |||
2642 | : -exp(-x*x/(2.0*sig*sig))*x/(sig*sig*sig*2.50662827463100050241)) | |||
2643 | ||||
2644 | static double | |||
2645 | _nrrdDGInt(const double *parm) { | |||
2646 | AIR_UNUSED(parm)(void)(parm); | |||
2647 | return 0; | |||
2648 | } | |||
2649 | ||||
2650 | static double | |||
2651 | _nrrdDGSup(const double *parm) { | |||
2652 | double sig, cut; | |||
2653 | ||||
2654 | sig = parm[0]; | |||
2655 | cut = parm[1]; | |||
2656 | return sig*cut; | |||
2657 | } | |||
2658 | ||||
2659 | static double | |||
2660 | _nrrdDG1_d(double x, const double *parm) { | |||
2661 | double sig, cut; | |||
2662 | int sgn = 1; | |||
2663 | ||||
2664 | sig = parm[0]; | |||
2665 | cut = parm[1]; | |||
2666 | if (x < 0) { x = -x; sgn = -1; } | |||
2667 | return sgn*_DGAUSS(x, sig, cut)( x >= sig*cut ? 0 : -exp(-x*x/(2.0*sig*sig))*x/(sig*sig*sig *2.50662827463100050241)); | |||
2668 | } | |||
2669 | ||||
2670 | static float | |||
2671 | _nrrdDG1_f(float x, const double *parm) { | |||
2672 | float sig, cut; | |||
2673 | int sgn = 1; | |||
2674 | ||||
2675 | sig = AIR_CAST(float, parm[0])((float)(parm[0])); | |||
2676 | cut = AIR_CAST(float, parm[1])((float)(parm[1])); | |||
2677 | if (x < 0) { x = -x; sgn = -1; } | |||
2678 | return AIR_CAST(float, sgn*_DGAUSS(x, sig, cut))((float)(sgn*( x >= sig*cut ? 0 : -exp(-x*x/(2.0*sig*sig)) *x/(sig*sig*sig*2.50662827463100050241)))); | |||
2679 | } | |||
2680 | ||||
2681 | static void | |||
2682 | _nrrdDGN_d(double *f, const double *x, size_t len, const double *parm) { | |||
2683 | double sig, cut, t; | |||
2684 | size_t i; | |||
2685 | int sgn; | |||
2686 | ||||
2687 | sig = parm[0]; | |||
2688 | cut = parm[1]; | |||
2689 | for (i=0; i<len; i++) { | |||
2690 | t = x[i]; | |||
2691 | if (t < 0) { t = -t; sgn = -1; } else { sgn = 1; } | |||
2692 | f[i] = sgn*_DGAUSS(t, sig, cut)( t >= sig*cut ? 0 : -exp(-t*t/(2.0*sig*sig))*t/(sig*sig*sig *2.50662827463100050241)); | |||
2693 | } | |||
2694 | } | |||
2695 | ||||
2696 | static void | |||
2697 | _nrrdDGN_f(float *f, const float *x, size_t len, const double *parm) { | |||
2698 | float sig, cut, t; | |||
2699 | size_t i; | |||
2700 | int sgn; | |||
2701 | ||||
2702 | sig = AIR_CAST(float, parm[0])((float)(parm[0])); | |||
2703 | cut = AIR_CAST(float, parm[1])((float)(parm[1])); | |||
2704 | for (i=0; i<len; i++) { | |||
2705 | t = x[i]; | |||
2706 | if (t < 0) { t = -t; sgn = -1; } else { sgn = 1; } | |||
2707 | f[i] = AIR_CAST(float, sgn*_DGAUSS(t, sig, cut))((float)(sgn*( t >= sig*cut ? 0 : -exp(-t*t/(2.0*sig*sig)) *t/(sig*sig*sig*2.50662827463100050241)))); | |||
2708 | } | |||
2709 | } | |||
2710 | ||||
2711 | static NrrdKernel | |||
2712 | _nrrdKernelDG = { | |||
2713 | "gaussD", | |||
2714 | 2, _nrrdDGSup, _nrrdDGInt, | |||
2715 | _nrrdDG1_f, _nrrdDGN_f, _nrrdDG1_d, _nrrdDGN_d | |||
2716 | }; | |||
2717 | NrrdKernel *const | |||
2718 | nrrdKernelGaussianD = &_nrrdKernelDG; | |||
2719 | ||||
2720 | /* ------------------------------------------------------------ */ | |||
2721 | ||||
2722 | #define _DDGAUSS(x, sig, cut)( x >= sig*cut ? 0 : exp(-x*x/(2.0*sig*sig))*(x*x-sig*sig) / (sig*sig*sig*sig*sig*2.50662827463100050241)) ( \ | |||
2723 | x >= sig*cut ? 0 \ | |||
2724 | : exp(-x*x/(2.0*sig*sig))*(x*x-sig*sig) / \ | |||
2725 | (sig*sig*sig*sig*sig*2.50662827463100050241)) | |||
2726 | ||||
2727 | static double | |||
2728 | _nrrdDDGInt(const double *parm) { | |||
2729 | double sig, cut; | |||
2730 | ||||
2731 | sig = parm[0]; | |||
2732 | cut = parm[1]; | |||
2733 | return -0.79788456080286535587*cut*exp(-cut*cut/2)/(sig*sig); | |||
2734 | } | |||
2735 | ||||
2736 | static double | |||
2737 | _nrrdDDGSup(const double *parm) { | |||
2738 | double sig, cut; | |||
2739 | ||||
2740 | sig = parm[0]; | |||
2741 | cut = parm[1]; | |||
2742 | return sig*cut; | |||
2743 | } | |||
2744 | ||||
2745 | static double | |||
2746 | _nrrdDDG1_d(double x, const double *parm) { | |||
2747 | double sig, cut; | |||
2748 | ||||
2749 | sig = parm[0]; | |||
2750 | cut = parm[1]; | |||
2751 | x = AIR_ABS(x)((x) > 0.0f ? (x) : -(x)); | |||
2752 | return _DDGAUSS(x, sig, cut)( x >= sig*cut ? 0 : exp(-x*x/(2.0*sig*sig))*(x*x-sig*sig) / (sig*sig*sig*sig*sig*2.50662827463100050241)); | |||
2753 | } | |||
2754 | ||||
2755 | static float | |||
2756 | _nrrdDDG1_f(float x, const double *parm) { | |||
2757 | float sig, cut; | |||
2758 | ||||
2759 | sig = AIR_CAST(float, parm[0])((float)(parm[0])); | |||
2760 | cut = AIR_CAST(float, parm[1])((float)(parm[1])); | |||
2761 | x = AIR_ABS(x)((x) > 0.0f ? (x) : -(x)); | |||
2762 | return AIR_CAST(float, _DDGAUSS(x, sig, cut))((float)(( x >= sig*cut ? 0 : exp(-x*x/(2.0*sig*sig))*(x*x -sig*sig) / (sig*sig*sig*sig*sig*2.50662827463100050241)))); | |||
2763 | } | |||
2764 | ||||
2765 | static void | |||
2766 | _nrrdDDGN_d(double *f, const double *x, size_t len, const double *parm) { | |||
2767 | double sig, cut, t; | |||
2768 | size_t i; | |||
2769 | ||||
2770 | sig = parm[0]; | |||
2771 | cut = parm[1]; | |||
2772 | for (i=0; i<len; i++) { | |||
2773 | t = x[i]; | |||
2774 | t = AIR_ABS(t)((t) > 0.0f ? (t) : -(t)); | |||
2775 | f[i] = _DDGAUSS(t, sig, cut)( t >= sig*cut ? 0 : exp(-t*t/(2.0*sig*sig))*(t*t-sig*sig) / (sig*sig*sig*sig*sig*2.50662827463100050241)); | |||
2776 | } | |||
2777 | } | |||
2778 | ||||
2779 | static void | |||
2780 | _nrrdDDGN_f(float *f, const float *x, size_t len, const double *parm) { | |||
2781 | float sig, cut, t; | |||
2782 | size_t i; | |||
2783 | ||||
2784 | sig = AIR_CAST(float, parm[0])((float)(parm[0])); | |||
2785 | cut = AIR_CAST(float, parm[1])((float)(parm[1])); | |||
2786 | for (i=0; i<len; i++) { | |||
2787 | t = x[i]; | |||
2788 | t = AIR_ABS(t)((t) > 0.0f ? (t) : -(t)); | |||
2789 | f[i] = AIR_CAST(float, _DDGAUSS(t, sig, cut))((float)(( t >= sig*cut ? 0 : exp(-t*t/(2.0*sig*sig))*(t*t -sig*sig) / (sig*sig*sig*sig*sig*2.50662827463100050241)))); | |||
2790 | } | |||
2791 | } | |||
2792 | ||||
2793 | static NrrdKernel | |||
2794 | _nrrdKernelDDG = { | |||
2795 | "gaussDD", | |||
2796 | 2, _nrrdDDGSup, _nrrdDDGInt, | |||
2797 | _nrrdDDG1_f, _nrrdDDGN_f, _nrrdDDG1_d, _nrrdDDGN_d | |||
2798 | }; | |||
2799 | NrrdKernel *const | |||
2800 | nrrdKernelGaussianDD = &_nrrdKernelDDG; | |||
2801 | ||||
2802 | ||||
2803 | /* ------------------------------------------------------------ */ | |||
2804 | ||||
2805 | NrrdKernel * | |||
2806 | _nrrdKernelStrToKern(char *str) { | |||
2807 | ||||
2808 | if (!strcmp("zero", str)) return nrrdKernelZero; | |||
2809 | if (!strcmp("box", str)) return nrrdKernelBox; | |||
2810 | if (!strcmp("boxsup", str)) return nrrdKernelBoxSupportDebug; | |||
2811 | if (!strcmp("cos4sup", str)) return nrrdKernelCos4SupportDebug; | |||
2812 | if (!strcmp("cos4supd", str)) return nrrdKernelCos4SupportDebugD; | |||
2813 | if (!strcmp("cos4supdd", str)) return nrrdKernelCos4SupportDebugDD; | |||
2814 | if (!strcmp("cos4supddd", str)) return nrrdKernelCos4SupportDebugDDD; | |||
2815 | if (!strcmp("cheap", str)) return nrrdKernelCheap; | |||
2816 | if (!strcmp("hermiteflag", str)) return nrrdKernelHermiteScaleSpaceFlag; | |||
2817 | if (!strcmp("hermite", str)) return nrrdKernelHermiteScaleSpaceFlag; | |||
2818 | if (!strcmp("hermitess", str)) return nrrdKernelHermiteScaleSpaceFlag; | |||
2819 | if (!strcmp("herm", str)) return nrrdKernelHermiteScaleSpaceFlag; | |||
2820 | if (!strcmp("tent", str)) return nrrdKernelTent; | |||
2821 | if (!strcmp("tentd", str)) return nrrdKernelForwDiff; | |||
2822 | if (!strcmp("forwdiff", str)) return nrrdKernelForwDiff; | |||
2823 | if (!strcmp("fordif", str)) return nrrdKernelForwDiff; | |||
2824 | if (!strcmp("centdiff", str)) return nrrdKernelCentDiff; | |||
2825 | if (!strcmp("cendif", str)) return nrrdKernelCentDiff; | |||
2826 | if (!strcmp("bccubic", str)) return nrrdKernelBCCubic; | |||
2827 | if (!strcmp("cubic", str)) return nrrdKernelBCCubic; | |||
2828 | if (!strcmp("bccubicd", str)) return nrrdKernelBCCubicD; | |||
2829 | if (!strcmp("cubicd", str)) return nrrdKernelBCCubicD; | |||
2830 | if (!strcmp("bccubicdd", str)) return nrrdKernelBCCubicDD; | |||
2831 | if (!strcmp("cubicdd", str)) return nrrdKernelBCCubicDD; | |||
2832 | if (!strcmp("ctmr", str)) return nrrdKernelCatmullRom; | |||
2833 | if (!strcmp("catmull-rom", str)) return nrrdKernelCatmullRom; | |||
2834 | if (!strcmp("ctmrd", str)) return nrrdKernelCatmullRomD; | |||
2835 | if (!strcmp("catmull-romd", str)) return nrrdKernelCatmullRomD; | |||
2836 | if (!strcmp("ctmrdd", str)) return nrrdKernelCatmullRomDD; | |||
2837 | if (!strcmp("catmull-romdd", str)) return nrrdKernelCatmullRomDD; | |||
2838 | if (!strcmp("ctmrsup", str)) return nrrdKernelCatmullRomSupportDebug; | |||
2839 | if (!strcmp("ctmrsupd", str)) return nrrdKernelCatmullRomSupportDebugD; | |||
2840 | if (!strcmp("ctmrsupdd", str)) return nrrdKernelCatmullRomSupportDebugDD; | |||
2841 | if (!strcmp("aquartic", str)) return nrrdKernelAQuartic; | |||
2842 | if (!strcmp("quartic", str)) return nrrdKernelAQuartic; | |||
2843 | if (!strcmp("aquarticd", str)) return nrrdKernelAQuarticD; | |||
2844 | if (!strcmp("quarticd", str)) return nrrdKernelAQuarticD; | |||
2845 | if (!strcmp("aquarticdd", str)) return nrrdKernelAQuarticDD; | |||
2846 | if (!strcmp("quarticdd", str)) return nrrdKernelAQuarticDD; | |||
2847 | if (!strcmp("c3quintic", str)) return nrrdKernelC3Quintic; | |||
2848 | if (!strcmp("c3q", str)) return nrrdKernelC3Quintic; | |||
2849 | if (!strcmp("c3quinticd", str)) return nrrdKernelC3QuinticD; | |||
2850 | if (!strcmp("c3qd", str)) return nrrdKernelC3QuinticD; | |||
2851 | if (!strcmp("c3quinticdd", str)) return nrrdKernelC3QuinticDD; | |||
2852 | if (!strcmp("c3qdd", str)) return nrrdKernelC3QuinticDD; | |||
2853 | if (!strcmp("c4hexic", str)) return nrrdKernelC4Hexic; | |||
2854 | if (!strcmp("c4hai", str)) return nrrdKernelC4HexicApproxInverse; | |||
2855 | if (!strcmp("c4hexicai", str)) return nrrdKernelC4HexicApproxInverse; | |||
2856 | if (!strcmp("c4h", str)) return nrrdKernelC4Hexic; | |||
2857 | if (!strcmp("c4hexicd", str)) return nrrdKernelC4HexicD; | |||
2858 | if (!strcmp("c4hd", str)) return nrrdKernelC4HexicD; | |||
2859 | if (!strcmp("c4hexicdd", str)) return nrrdKernelC4HexicDD; | |||
2860 | if (!strcmp("c4hdd", str)) return nrrdKernelC4HexicDD; | |||
2861 | if (!strcmp("c4hexicddd", str)) return nrrdKernelC4HexicDDD; | |||
2862 | if (!strcmp("c4hddd", str)) return nrrdKernelC4HexicDDD; | |||
2863 | if (!strcmp("c5septic", str)) return nrrdKernelC5Septic; | |||
2864 | if (!strcmp("c5septicd", str)) return nrrdKernelC5SepticD; | |||
2865 | if (!strcmp("c5septicdd", str)) return nrrdKernelC5SepticDD; | |||
2866 | if (!strcmp("c5septicddd", str))return nrrdKernelC5SepticDDD; | |||
2867 | if (!strcmp("c5septicai", str)) return nrrdKernelC5SepticApproxInverse; | |||
2868 | if (!strcmp("gaussian", str)) return nrrdKernelGaussian; | |||
2869 | if (!strcmp("gauss", str)) return nrrdKernelGaussian; | |||
2870 | if (!strcmp("gaussiand", str)) return nrrdKernelGaussianD; | |||
2871 | if (!strcmp("gaussd", str)) return nrrdKernelGaussianD; | |||
2872 | if (!strcmp("gd", str)) return nrrdKernelGaussianD; | |||
2873 | if (!strcmp("gaussiandd", str)) return nrrdKernelGaussianDD; | |||
2874 | if (!strcmp("gaussdd", str)) return nrrdKernelGaussianDD; | |||
2875 | if (!strcmp("gdd", str)) return nrrdKernelGaussianDD; | |||
2876 | if (!strcmp("ds", str)) return nrrdKernelDiscreteGaussian; | |||
2877 | if (!strcmp("dscale", str)) return nrrdKernelDiscreteGaussian; | |||
2878 | if (!strcmp("dg", str)) return nrrdKernelDiscreteGaussian; | |||
2879 | if (!strcmp("dgauss", str)) return nrrdKernelDiscreteGaussian; | |||
2880 | if (!strcmp("dgaussian", str)) return nrrdKernelDiscreteGaussian; | |||
2881 | if (!strcmp("discretegauss", str)) return nrrdKernelDiscreteGaussian; | |||
2882 | if (!strcmp("hann", str)) return nrrdKernelHann; | |||
2883 | if (!strcmp("hannd", str)) return nrrdKernelHannD; | |||
2884 | if (!strcmp("hanndd", str)) return nrrdKernelHannDD; | |||
2885 | if (!strcmp("bkmn", str)) return nrrdKernelBlackman; | |||
2886 | if (!strcmp("black", str)) return nrrdKernelBlackman; | |||
2887 | if (!strcmp("blackman", str)) return nrrdKernelBlackman; | |||
2888 | if (!strcmp("bkmnd", str)) return nrrdKernelBlackmanD; | |||
2889 | if (!strcmp("blackd", str)) return nrrdKernelBlackmanD; | |||
2890 | if (!strcmp("blackmand", str)) return nrrdKernelBlackmanD; | |||
2891 | if (!strcmp("bkmndd", str)) return nrrdKernelBlackmanDD; | |||
2892 | if (!strcmp("blackdd", str)) return nrrdKernelBlackmanDD; | |||
2893 | if (!strcmp("blackmandd", str)) return nrrdKernelBlackmanDD; | |||
2894 | if (!strcmp("bspl1", str)) return nrrdKernelBSpline1; | |||
2895 | if (!strcmp("bspln1", str)) return nrrdKernelBSpline1; | |||
2896 | if (!strcmp("bspl1d", str)) return nrrdKernelBSpline1D; | |||
2897 | if (!strcmp("bspln1d", str)) return nrrdKernelBSpline1D; | |||
2898 | if (!strcmp("bspl2", str)) return nrrdKernelBSpline2; | |||
2899 | if (!strcmp("bspln2", str)) return nrrdKernelBSpline2; | |||
2900 | if (!strcmp("bspl2d", str)) return nrrdKernelBSpline2D; | |||
2901 | if (!strcmp("bspln2d", str)) return nrrdKernelBSpline2D; | |||
2902 | if (!strcmp("bspl2dd", str)) return nrrdKernelBSpline2DD; | |||
2903 | if (!strcmp("bspln2dd", str)) return nrrdKernelBSpline2DD; | |||
2904 | if (!strcmp("bspl3", str)) return nrrdKernelBSpline3; | |||
2905 | if (!strcmp("bspln3", str)) return nrrdKernelBSpline3; | |||
2906 | if (!strcmp("bspl3ai", str)) return nrrdKernelBSpline3ApproxInverse; | |||
2907 | if (!strcmp("bspln3ai", str)) return nrrdKernelBSpline3ApproxInverse; | |||
2908 | if (!strcmp("bspl3d", str)) return nrrdKernelBSpline3D; | |||
2909 | if (!strcmp("bspln3d", str)) return nrrdKernelBSpline3D; | |||
2910 | if (!strcmp("bspl3dd", str)) return nrrdKernelBSpline3DD; | |||
2911 | if (!strcmp("bspln3dd", str)) return nrrdKernelBSpline3DD; | |||
2912 | if (!strcmp("bspl3ddd", str)) return nrrdKernelBSpline3DDD; | |||
2913 | if (!strcmp("bspln3ddd", str)) return nrrdKernelBSpline3DDD; | |||
2914 | if (!strcmp("bspl4", str)) return nrrdKernelBSpline4; | |||
2915 | if (!strcmp("bspln4", str)) return nrrdKernelBSpline4; | |||
2916 | if (!strcmp("bspl4d", str)) return nrrdKernelBSpline4D; | |||
2917 | if (!strcmp("bspln4d", str)) return nrrdKernelBSpline4D; | |||
2918 | if (!strcmp("bspl4dd", str)) return nrrdKernelBSpline4DD; | |||
2919 | if (!strcmp("bspln4dd", str)) return nrrdKernelBSpline4DD; | |||
2920 | if (!strcmp("bspl4ddd", str)) return nrrdKernelBSpline4DDD; | |||
2921 | if (!strcmp("bspln4ddd", str)) return nrrdKernelBSpline4DDD; | |||
2922 | if (!strcmp("bspl5", str)) return nrrdKernelBSpline5; | |||
2923 | if (!strcmp("bspln5", str)) return nrrdKernelBSpline5; | |||
2924 | if (!strcmp("bspl5ai", str)) return nrrdKernelBSpline5ApproxInverse; | |||
2925 | if (!strcmp("bspln5ai", str)) return nrrdKernelBSpline5ApproxInverse; | |||
2926 | if (!strcmp("bspl5d", str)) return nrrdKernelBSpline5D; | |||
2927 | if (!strcmp("bspln5d", str)) return nrrdKernelBSpline5D; | |||
2928 | if (!strcmp("bspl5dd", str)) return nrrdKernelBSpline5DD; | |||
2929 | if (!strcmp("bspln5dd", str)) return nrrdKernelBSpline5DD; | |||
2930 | if (!strcmp("bspl5ddd", str)) return nrrdKernelBSpline5DDD; | |||
2931 | if (!strcmp("bspln5ddd", str)) return nrrdKernelBSpline5DDD; | |||
2932 | if (!strcmp("bspl6", str)) return nrrdKernelBSpline6; | |||
2933 | if (!strcmp("bspln6", str)) return nrrdKernelBSpline6; | |||
2934 | if (!strcmp("bspl6d", str)) return nrrdKernelBSpline6D; | |||
2935 | if (!strcmp("bspln6d", str)) return nrrdKernelBSpline6D; | |||
2936 | if (!strcmp("bspl6dd", str)) return nrrdKernelBSpline6DD; | |||
2937 | if (!strcmp("bspln6dd", str)) return nrrdKernelBSpline6DD; | |||
2938 | if (!strcmp("bspl6ddd", str)) return nrrdKernelBSpline6DDD; | |||
2939 | if (!strcmp("bspln6ddd", str)) return nrrdKernelBSpline6DDD; | |||
2940 | if (!strcmp("bspl7", str)) return nrrdKernelBSpline7; | |||
2941 | if (!strcmp("bspln7", str)) return nrrdKernelBSpline7; | |||
2942 | if (!strcmp("bspl7ai", str)) return nrrdKernelBSpline7ApproxInverse; | |||
2943 | if (!strcmp("bspln7ai", str)) return nrrdKernelBSpline7ApproxInverse; | |||
2944 | if (!strcmp("bspl7d", str)) return nrrdKernelBSpline7D; | |||
2945 | if (!strcmp("bspln7d", str)) return nrrdKernelBSpline7D; | |||
2946 | if (!strcmp("bspl7dd", str)) return nrrdKernelBSpline7DD; | |||
2947 | if (!strcmp("bspln7dd", str)) return nrrdKernelBSpline7DD; | |||
2948 | if (!strcmp("bspl7ddd", str)) return nrrdKernelBSpline7DDD; | |||
2949 | if (!strcmp("bspln7ddd", str)) return nrrdKernelBSpline7DDD; | |||
2950 | return NULL((void*)0); | |||
2951 | } | |||
2952 | ||||
2953 | /* this returns a number between -1 and max; | |||
2954 | it does NOT do the increment-by-one; | |||
2955 | it does NOT do range checking */ | |||
2956 | int | |||
2957 | _nrrdKernelParseTMFInt(int *val, char *str) { | |||
2958 | static const char me[]="nrrdKernelParseTMFInt"; | |||
2959 | ||||
2960 | if (!strcmp("n", str)) { | |||
2961 | *val = -1; | |||
2962 | } else { | |||
2963 | if (1 != sscanf(str, "%d", val)) { | |||
2964 | biffAddf(NRRDnrrdBiffKey, "%s: couldn't parse \"%s\" as int", me, str); | |||
2965 | return 1; | |||
2966 | } | |||
2967 | } | |||
2968 | return 0; | |||
2969 | } | |||
2970 | ||||
2971 | int | |||
2972 | nrrdKernelParse(const NrrdKernel **kernelP, | |||
2973 | double *parm, const char *_str) { | |||
2974 | static const char me[]="nrrdKernelParse"; | |||
2975 | char str[AIR_STRLEN_HUGE(1024+1)], | |||
2976 | kstr[AIR_STRLEN_MED(256+1)], *_pstr=NULL((void*)0), *pstr, | |||
2977 | *tmfStr[4] = {NULL((void*)0), NULL((void*)0), NULL((void*)0), NULL((void*)0)}; | |||
2978 | int tmfD, tmfC, tmfA; | |||
2979 | unsigned int jj, haveParm, needParm; | |||
2980 | airArray *mop; | |||
2981 | ||||
2982 | if (!(kernelP && parm && _str)) { | |||
2983 | biffAddf(NRRDnrrdBiffKey, "%s: got NULL pointer", me); | |||
2984 | return 1; | |||
2985 | } | |||
2986 | ||||
2987 | /* [jorik] (if i understood this correctly) parm is always of length | |||
2988 | ** NRRD_KERNEL_PARMS_NUM. We have to clear all parameters here, since | |||
2989 | ** nrrdKernelSet copies all arguments into its own array later, and | |||
2990 | ** copying uninitialised memory is bad (it traps my memory debugger). | |||
2991 | */ | |||
2992 | for (jj=0; jj<NRRD_KERNEL_PARMS_NUM8; jj++) { | |||
2993 | parm[jj] = 0; | |||
2994 | } | |||
2995 | ||||
2996 | airStrcpy(str, AIR_STRLEN_HUGE(1024+1), _str); | |||
2997 | strcpy(kstr, "")__builtin___strcpy_chk (kstr, "", __builtin_object_size (kstr , 2 > 1 ? 1 : 0)); | |||
2998 | pstr = NULL((void*)0); | |||
2999 | pstr = strchr(str, ':'); | |||
3000 | if (pstr) { | |||
3001 | *pstr = '\0'; | |||
3002 | _pstr = ++pstr; | |||
3003 | } | |||
3004 | strcpy(kstr, str)__builtin___strcpy_chk (kstr, str, __builtin_object_size (kstr , 2 > 1 ? 1 : 0)); | |||
3005 | airToLower(kstr); | |||
3006 | mop = airMopNew(); | |||
3007 | /* first see if its a TMF, then try parsing it as the other stuff */ | |||
3008 | if (kstr == strstr(kstr, "tmf")) { | |||
3009 | if (4 == airParseStrS(tmfStr, pstr, ",", 4)) { | |||
3010 | airMopAdd(mop, tmfStr[0], airFree, airMopAlways); | |||
3011 | airMopAdd(mop, tmfStr[1], airFree, airMopAlways); | |||
3012 | airMopAdd(mop, tmfStr[2], airFree, airMopAlways); | |||
3013 | airMopAdd(mop, tmfStr[3], airFree, airMopAlways); | |||
3014 | /* a TMF with a parameter: D,C,A,a */ | |||
3015 | if (1 != airSingleSscanf(tmfStr[3], "%lg", parm)) { | |||
3016 | biffAddf(NRRDnrrdBiffKey, "%s: couldn't parse TMF parameter \"%s\" as double", | |||
3017 | me, tmfStr[3]); | |||
3018 | airMopError(mop); return 1; | |||
3019 | } | |||
3020 | } else if (3 == airParseStrS(tmfStr, pstr, ",", 3)) { | |||
3021 | airMopAdd(mop, tmfStr[0], airFree, airMopAlways); | |||
3022 | airMopAdd(mop, tmfStr[1], airFree, airMopAlways); | |||
3023 | airMopAdd(mop, tmfStr[2], airFree, airMopAlways); | |||
3024 | /* a TMF without a parameter: D,C,A ==> a=0.0 */ | |||
3025 | parm[0] = 0.0; | |||
3026 | } else { | |||
3027 | biffAddf(NRRDnrrdBiffKey, "%s: TMF kernels require 3 arguments D, C, A " | |||
3028 | "in the form tmf:D,C,A", me); | |||
3029 | airMopError(mop); return 1; | |||
3030 | } | |||
3031 | if (_nrrdKernelParseTMFInt(&tmfD, tmfStr[0]) | |||
3032 | || _nrrdKernelParseTMFInt(&tmfC, tmfStr[1]) | |||
3033 | || _nrrdKernelParseTMFInt(&tmfA, tmfStr[2])) { | |||
3034 | biffAddf(NRRDnrrdBiffKey, "%s: problem parsing \"%s,%s,%s\" as D,C,A " | |||
3035 | "for TMF kernel", me, tmfStr[0], tmfStr[1], tmfStr[2]); | |||
3036 | airMopError(mop); return 1; | |||
3037 | } | |||
3038 | if (!AIR_IN_CL(-1, tmfD, (int)nrrdKernelTMF_maxD)((-1) <= (tmfD) && (tmfD) <= ((int)nrrdKernelTMF_maxD ))) { | |||
3039 | biffAddf(NRRDnrrdBiffKey, "%s: derivative value %d outside range [-1,%d]", | |||
3040 | me, tmfD, nrrdKernelTMF_maxD); | |||
3041 | airMopError(mop); return 1; | |||
3042 | } | |||
3043 | if (!AIR_IN_CL(-1, tmfC, (int)nrrdKernelTMF_maxC)((-1) <= (tmfC) && (tmfC) <= ((int)nrrdKernelTMF_maxC ))) { | |||
3044 | biffAddf(NRRDnrrdBiffKey, "%s: continuity value %d outside range [-1,%d]", | |||
3045 | me, tmfC, nrrdKernelTMF_maxC); | |||
3046 | airMopError(mop); return 1; | |||
3047 | } | |||
3048 | if (!AIR_IN_CL(1, tmfA, (int)nrrdKernelTMF_maxA)((1) <= (tmfA) && (tmfA) <= ((int)nrrdKernelTMF_maxA ))) { | |||
3049 | biffAddf(NRRDnrrdBiffKey, "%s: accuracy value %d outside range [1,%d]", | |||
3050 | me, tmfA, nrrdKernelTMF_maxA); | |||
3051 | airMopError(mop); return 1; | |||
3052 | } | |||
3053 | /* | |||
3054 | fprintf(stderr, "!%s: D,C,A = %d,%d,%d --> %d,%d,%d\n", me, | |||
3055 | tmfD, tmfC, tmfA, tmfD+1, tmfC+1, tmfA); | |||
3056 | */ | |||
3057 | *kernelP = nrrdKernelTMF[tmfD+1][tmfC+1][tmfA]; | |||
3058 | } else { | |||
3059 | /* its not a TMF */ | |||
3060 | if (!(*kernelP = _nrrdKernelStrToKern(kstr))) { | |||
3061 | biffAddf(NRRDnrrdBiffKey, "%s: kernel \"%s\" not recognized", me, kstr); | |||
3062 | airMopError(mop); return 1; | |||
3063 | } | |||
3064 | if ((*kernelP)->numParm > NRRD_KERNEL_PARMS_NUM8) { | |||
3065 | biffAddf(NRRDnrrdBiffKey, "%s: kernel \"%s\" requests %d parameters > max %d", | |||
3066 | me, kstr, (*kernelP)->numParm, NRRD_KERNEL_PARMS_NUM8); | |||
3067 | airMopError(mop); return 1; | |||
3068 | } | |||
3069 | if (*kernelP == nrrdKernelGaussian || | |||
3070 | *kernelP == nrrdKernelGaussianD || | |||
3071 | *kernelP == nrrdKernelGaussianDD || | |||
3072 | *kernelP == nrrdKernelDiscreteGaussian || | |||
3073 | *kernelP == nrrdKernelBoxSupportDebug || | |||
3074 | *kernelP == nrrdKernelCos4SupportDebug || | |||
3075 | *kernelP == nrrdKernelCos4SupportDebugD || | |||
3076 | *kernelP == nrrdKernelCos4SupportDebugDD || | |||
3077 | *kernelP == nrrdKernelCos4SupportDebugDDD) { | |||
3078 | /* for these kernels, we need all the parameters given explicitly */ | |||
3079 | needParm = (*kernelP)->numParm; | |||
3080 | } else { | |||
3081 | /* For everything else (note that TMF kernels are handled | |||
3082 | separately), we can make do with one less than the required, | |||
3083 | by using the default spacing */ | |||
3084 | needParm = ((*kernelP)->numParm > 0 | |||
3085 | ? (*kernelP)->numParm - 1 | |||
3086 | : 0); | |||
3087 | } | |||
3088 | if (needParm > 0 && !pstr) { | |||
3089 | biffAddf(NRRDnrrdBiffKey, "%s: didn't get any of %d required doubles after " | |||
3090 | "colon in \"%s\"", | |||
3091 | me, needParm, kstr); | |||
3092 | airMopError(mop); return 1; | |||
3093 | } | |||
3094 | for (haveParm=0; haveParm<(*kernelP)->numParm; haveParm++) { | |||
3095 | if (!pstr) | |||
3096 | break; | |||
3097 | if (1 != airSingleSscanf(pstr, "%lg", parm+haveParm)) { | |||
3098 | biffAddf(NRRDnrrdBiffKey, "%s: trouble parsing \"%s\" as double (in \"%s\")", | |||
3099 | me, _pstr, _str); | |||
3100 | airMopError(mop); return 1; | |||
3101 | } | |||
3102 | if ((pstr = strchr(pstr, ','))) { | |||
3103 | pstr++; | |||
3104 | if (!*pstr) { | |||
3105 | biffAddf(NRRDnrrdBiffKey, "%s: nothing after last comma in \"%s\" (in \"%s\")", | |||
3106 | me, _pstr, _str); | |||
3107 | airMopError(mop); return 1; | |||
3108 | } | |||
3109 | } | |||
3110 | } | |||
3111 | /* haveParm is now the number of parameters that were parsed. */ | |||
3112 | if (haveParm < needParm) { | |||
3113 | biffAddf(NRRDnrrdBiffKey, "%s: parsed only %d of %d required doubles " | |||
3114 | "from \"%s\" (in \"%s\")", | |||
3115 | me, haveParm, needParm, _pstr, _str); | |||
3116 | airMopError(mop); return 1; | |||
3117 | } else if (haveParm == needParm && | |||
3118 | needParm == (*kernelP)->numParm-1) { | |||
3119 | /* shift up parsed values, and set parm[0] to default */ | |||
3120 | for (jj=haveParm; jj>=1; jj--) { | |||
3121 | parm[jj] = parm[jj-1]; | |||
3122 | } | |||
3123 | parm[0] = nrrdDefaultKernelParm0; | |||
3124 | } else { | |||
3125 | if (pstr) { | |||
3126 | biffAddf(NRRDnrrdBiffKey, "%s: \"%s\" (in \"%s\") has more than %d doubles", | |||
3127 | me, _pstr, _str, (*kernelP)->numParm); | |||
3128 | airMopError(mop); return 1; | |||
3129 | } | |||
3130 | } | |||
3131 | } | |||
3132 | /* | |||
3133 | fprintf(stderr, "%s: %g %g %g %g %g\n", me, | |||
3134 | parm[0], parm[1], parm[2], parm[3], parm[4]); | |||
3135 | */ | |||
3136 | airMopOkay(mop); | |||
3137 | return 0; | |||
3138 | } | |||
3139 | ||||
3140 | int | |||
3141 | nrrdKernelSpecParse(NrrdKernelSpec *ksp, const char *str) { | |||
3142 | static const char me[]="nrrdKernelSpecParse"; | |||
3143 | const NrrdKernel *kern; | |||
3144 | double kparm[NRRD_KERNEL_PARMS_NUM8]; | |||
3145 | ||||
3146 | if (!( ksp && str )) { | |||
3147 | biffAddf(NRRDnrrdBiffKey, "%s: got NULL pointer", me); | |||
3148 | return 1; | |||
3149 | } | |||
3150 | if (nrrdKernelParse(&kern, kparm, str)) { | |||
3151 | biffAddf(NRRDnrrdBiffKey, "%s: ", me); | |||
3152 | return 1; | |||
3153 | } | |||
3154 | nrrdKernelSpecSet(ksp, kern, kparm); | |||
3155 | return 0; | |||
3156 | } | |||
3157 | ||||
3158 | /* | |||
3159 | ** note that the given string has to be allocated for a certain size | |||
3160 | ** which is plenty big | |||
3161 | */ | |||
3162 | int | |||
3163 | nrrdKernelSpecSprint(char str[AIR_STRLEN_LARGE(512+1)], const NrrdKernelSpec *ksp) { | |||
3164 | static const char me[]="nrrdKernelSpecSprint"; | |||
3165 | unsigned int warnLen = AIR_STRLEN_LARGE(512+1)/3; | |||
3166 | char stmp[AIR_STRLEN_LARGE(512+1)]; | |||
3167 | ||||
3168 | if (!( str && ksp )) { | |||
3169 | biffAddf(NRRDnrrdBiffKey, "%s: got NULL pointer", me); | |||
3170 | return 1; | |||
3171 | } | |||
3172 | if (strlen(ksp->kernel->name) > warnLen) { | |||
3173 | biffAddf(NRRDnrrdBiffKey, "%s: kernel name (len %s) might lead to overflow", me, | |||
3174 | airSprintSize_t(stmp, strlen(ksp->kernel->name))); | |||
3175 | return 1; | |||
3176 | } | |||
3177 | if (strstr(ksp->kernel->name, "TMF")) { | |||
3178 | /* these are handled differently; the identification of the | |||
3179 | kernel is actually packaged as kernel parameters */ | |||
3180 | if (!(ksp->kernel->name == strstr(ksp->kernel->name, "TMF"))) { | |||
3181 | biffAddf(NRRDnrrdBiffKey, "%s: TMF kernel name %s didn't start with TMF", | |||
3182 | me, ksp->kernel->name); | |||
3183 | return 1; | |||
3184 | } | |||
3185 | /* 0123456789012 */ | |||
3186 | /* TMF_dX_cX_Xef */ | |||
3187 | if (!( 13 == strlen(ksp->kernel->name) | |||
3188 | && '_' == ksp->kernel->name[3] | |||
3189 | && '_' == ksp->kernel->name[6] | |||
3190 | && '_' == ksp->kernel->name[9] )) { | |||
3191 | biffAddf(NRRDnrrdBiffKey, "%s: sorry, expected strlen(%s) = 13 with 3 _s", | |||
3192 | me, ksp->kernel->name); | |||
3193 | return 1; | |||
3194 | } | |||
3195 | sprintf(str, "tmf:%c,%c,%c",__builtin___sprintf_chk (str, 0, __builtin_object_size (str, 2 > 1 ? 1 : 0), "tmf:%c,%c,%c", ksp->kernel->name[5], ksp->kernel->name[8], ksp->kernel->name[10]) | |||
3196 | ksp->kernel->name[5],__builtin___sprintf_chk (str, 0, __builtin_object_size (str, 2 > 1 ? 1 : 0), "tmf:%c,%c,%c", ksp->kernel->name[5], ksp->kernel->name[8], ksp->kernel->name[10]) | |||
3197 | ksp->kernel->name[8],__builtin___sprintf_chk (str, 0, __builtin_object_size (str, 2 > 1 ? 1 : 0), "tmf:%c,%c,%c", ksp->kernel->name[5], ksp->kernel->name[8], ksp->kernel->name[10]) | |||
3198 | ksp->kernel->name[10])__builtin___sprintf_chk (str, 0, __builtin_object_size (str, 2 > 1 ? 1 : 0), "tmf:%c,%c,%c", ksp->kernel->name[5], ksp->kernel->name[8], ksp->kernel->name[10]); | |||
3199 | /* see if the single parm should be added on */ | |||
3200 | if (0.0 != ksp->parm[0]) { | |||
3201 | sprintf(stmp, ",%.17g", ksp->parm[0])__builtin___sprintf_chk (stmp, 0, __builtin_object_size (stmp , 2 > 1 ? 1 : 0), ",%.17g", ksp->parm[0]); | |||
3202 | strcat(str, stmp)__builtin___strcat_chk (str, stmp, __builtin_object_size (str , 2 > 1 ? 1 : 0)); | |||
3203 | } | |||
3204 | } else { | |||
3205 | strcpy(str, ksp->kernel->name)__builtin___strcpy_chk (str, ksp->kernel->name, __builtin_object_size (str, 2 > 1 ? 1 : 0)); | |||
3206 | if (ksp->kernel->numParm) { | |||
3207 | unsigned int pi; | |||
3208 | for (pi=0; pi<ksp->kernel->numParm; pi++) { | |||
3209 | sprintf(stmp, "%c%.17g", (!pi ? ':' : ','), ksp->parm[pi])__builtin___sprintf_chk (stmp, 0, __builtin_object_size (stmp , 2 > 1 ? 1 : 0), "%c%.17g", (!pi ? ':' : ','), ksp->parm [pi]); | |||
3210 | if (strlen(str) + strlen(stmp) > warnLen) { | |||
3211 | biffAddf(NRRDnrrdBiffKey, "%s: kernel parm %u could overflow", me, pi); | |||
3212 | return 1; | |||
3213 | } | |||
3214 | strcat(str, stmp)__builtin___strcat_chk (str, stmp, __builtin_object_size (str , 2 > 1 ? 1 : 0)); | |||
3215 | } | |||
3216 | } | |||
3217 | } | |||
3218 | return 0; | |||
3219 | } | |||
3220 | ||||
3221 | int | |||
3222 | nrrdKernelSprint(char str[AIR_STRLEN_LARGE(512+1)], const NrrdKernel *kernel, | |||
3223 | const double kparm[NRRD_KERNEL_PARMS_NUM8]) { | |||
3224 | static const char me[]="nrrdKernelSprint"; | |||
3225 | NrrdKernelSpec ksp; | |||
3226 | ||||
3227 | nrrdKernelSpecSet(&ksp, kernel, kparm); | |||
3228 | if (nrrdKernelSpecSprint(str, &ksp)) { | |||
3229 | biffAddf(NRRDnrrdBiffKey, "%s: trouble", me); | |||
3230 | return 1; | |||
3231 | } | |||
3232 | return 0; | |||
3233 | } | |||
3234 | ||||
3235 | /* | |||
3236 | ** This DOES make an effort to set *differ based on "ordering" (-1 or +1) | |||
3237 | ** but HEY that's very contrived; why bother? | |||
3238 | */ | |||
3239 | int | |||
3240 | nrrdKernelCompare(const NrrdKernel *kernA, | |||
3241 | const double parmA[NRRD_KERNEL_PARMS_NUM8], | |||
3242 | const NrrdKernel *kernB, | |||
3243 | const double parmB[NRRD_KERNEL_PARMS_NUM8], | |||
3244 | int *differ, char explain[AIR_STRLEN_LARGE(512+1)]) { | |||
3245 | static const char me[]="nrrdKernelCompare"; | |||
3246 | unsigned int pnum, pidx; | |||
3247 | ||||
3248 | if (!(kernA && kernB && differ)) { | |||
3249 | biffAddf(NRRDnrrdBiffKey, "%s: got NULL pointer (%p, %p, or %p)", me, | |||
3250 | AIR_CVOIDP(kernA)((const void *)(kernA)), AIR_CVOIDP(kernB)((const void *)(kernB)), AIR_VOIDP(differ)((void *)(differ))); | |||
3251 | return 1; | |||
3252 | } | |||
3253 | if (kernA != kernB) { | |||
3254 | *differ = kernA < kernB ? -1 : 1; | |||
3255 | if (explain) { | |||
3256 | sprintf(explain, "kernA %s kernB", *differ < 0 ? "<" : ">")__builtin___sprintf_chk (explain, 0, __builtin_object_size (explain , 2 > 1 ? 1 : 0), "kernA %s kernB", *differ < 0 ? "<" : ">"); | |||
3257 | } | |||
3258 | return 0; | |||
3259 | } | |||
3260 | pnum = kernA->numParm; | |||
3261 | if (!pnum) { | |||
3262 | /* actually, we're done: no parms and kernels are equal */ | |||
3263 | *differ = 0; | |||
3264 | return 0; | |||
3265 | } | |||
3266 | if (!(parmA && parmB)) { | |||
3267 | biffAddf(NRRDnrrdBiffKey, "%s: kernel %s needs %u parms but got NULL parm vectors", | |||
3268 | me, kernA->name ? kernA->name : "(unnamed)", pnum); | |||
3269 | return 0; | |||
3270 | } | |||
3271 | for (pidx=0; pidx<pnum; pidx++) { | |||
3272 | if (parmA[pidx] != parmB[pidx]) { | |||
3273 | *differ = parmA[pidx] < parmB[pidx] ? -1 : 1; | |||
3274 | if (explain) { | |||
3275 | sprintf(explain, "parmA[%u]=%f %s parmB[%u]=%f", pidx, parmA[pidx],__builtin___sprintf_chk (explain, 0, __builtin_object_size (explain , 2 > 1 ? 1 : 0), "parmA[%u]=%f %s parmB[%u]=%f", pidx, parmA [pidx], *differ < 0 ? "<" : ">", pidx, parmB[pidx]) | |||
3276 | *differ < 0 ? "<" : ">", pidx, parmB[pidx])__builtin___sprintf_chk (explain, 0, __builtin_object_size (explain , 2 > 1 ? 1 : 0), "parmA[%u]=%f %s parmB[%u]=%f", pidx, parmA [pidx], *differ < 0 ? "<" : ">", pidx, parmB[pidx]); | |||
3277 | } | |||
3278 | return 0; | |||
3279 | } | |||
3280 | } | |||
3281 | ||||
3282 | /* so far nothing unequal */ | |||
3283 | *differ = 0; | |||
3284 | return 0; | |||
3285 | } | |||
3286 | ||||
3287 | /* | |||
3288 | ** This DOES NOT make an effort to set *differ based on "ordering"; | |||
3289 | */ | |||
3290 | int | |||
3291 | nrrdKernelSpecCompare(const NrrdKernelSpec *aa, | |||
3292 | const NrrdKernelSpec *bb, | |||
3293 | int *differ, char explain[AIR_STRLEN_LARGE(512+1)]) { | |||
3294 | static const char me[]="nrrdKernelSpecCompare"; | |||
3295 | char subexplain[AIR_STRLEN_LARGE(512+1)]; | |||
3296 | ||||
3297 | if (!( differ )) { | |||
3298 | biffAddf(NRRDnrrdBiffKey, "%s: got NULL differ", me); | |||
3299 | return 1; | |||
3300 | } | |||
3301 | if (!!aa != !!bb) { | |||
3302 | if (explain) { | |||
3303 | sprintf(explain, "different NULL-ities of kspec itself %s != %s",__builtin___sprintf_chk (explain, 0, __builtin_object_size (explain , 2 > 1 ? 1 : 0), "different NULL-ities of kspec itself %s != %s" , aa ? "non-NULL" : "NULL", bb ? "non-NULL" : "NULL") | |||
3304 | aa ? "non-NULL" : "NULL",__builtin___sprintf_chk (explain, 0, __builtin_object_size (explain , 2 > 1 ? 1 : 0), "different NULL-ities of kspec itself %s != %s" , aa ? "non-NULL" : "NULL", bb ? "non-NULL" : "NULL") | |||
3305 | bb ? "non-NULL" : "NULL")__builtin___sprintf_chk (explain, 0, __builtin_object_size (explain , 2 > 1 ? 1 : 0), "different NULL-ities of kspec itself %s != %s" , aa ? "non-NULL" : "NULL", bb ? "non-NULL" : "NULL"); | |||
3306 | } | |||
3307 | *differ = 1; return 0; | |||
3308 | } | |||
3309 | if (!aa) { | |||
3310 | /* got two NULL kernel specs ==> equal */ | |||
3311 | *differ = 0; return 0; | |||
3312 | } | |||
3313 | if (!!aa->kernel != !!bb->kernel) { | |||
3314 | if (explain) { | |||
3315 | sprintf(explain, "different NULL-ities of kspec->kernel %s != %s",__builtin___sprintf_chk (explain, 0, __builtin_object_size (explain , 2 > 1 ? 1 : 0), "different NULL-ities of kspec->kernel %s != %s" , aa->kernel ? "non-NULL" : "NULL", bb->kernel ? "non-NULL" : "NULL") | |||
3316 | aa->kernel ? "non-NULL" : "NULL",__builtin___sprintf_chk (explain, 0, __builtin_object_size (explain , 2 > 1 ? 1 : 0), "different NULL-ities of kspec->kernel %s != %s" , aa->kernel ? "non-NULL" : "NULL", bb->kernel ? "non-NULL" : "NULL") | |||
3317 | bb->kernel ? "non-NULL" : "NULL")__builtin___sprintf_chk (explain, 0, __builtin_object_size (explain , 2 > 1 ? 1 : 0), "different NULL-ities of kspec->kernel %s != %s" , aa->kernel ? "non-NULL" : "NULL", bb->kernel ? "non-NULL" : "NULL"); | |||
3318 | } | |||
3319 | *differ = 1; return 0; | |||
3320 | } | |||
3321 | if (!aa->kernel) { | |||
3322 | /* both kernels NULL, can't do anything informative with parms */ | |||
3323 | *differ = 0; return 0; | |||
3324 | } | |||
3325 | if (nrrdKernelCompare(aa->kernel, aa->parm, | |||
3326 | bb->kernel, bb->parm, | |||
3327 | differ, subexplain)) { | |||
3328 | biffAddf(NRRDnrrdBiffKey, "%s: trouble comparing kernels", me); | |||
3329 | return 1; | |||
3330 | } | |||
3331 | if (*differ) { | |||
3332 | if (explain) { | |||
3333 | sprintf(explain, "kern/parm pairs differ: %s", subexplain)__builtin___sprintf_chk (explain, 0, __builtin_object_size (explain , 2 > 1 ? 1 : 0), "kern/parm pairs differ: %s", subexplain ); | |||
3334 | } | |||
3335 | *differ = 1; /* losing ordering info (of dubious value) */ | |||
3336 | return 0; | |||
3337 | } | |||
3338 | *differ = 0; | |||
3339 | return 0; | |||
3340 | } | |||
3341 | ||||
3342 | /* | |||
3343 | ******** nrrdKernelCheck | |||
3344 | ** | |||
3345 | ** Makes sure a given kernel is behaving as expected | |||
3346 | ** | |||
3347 | ** Tests: | |||
3348 | ** nrrdKernelSprint | |||
3349 | ** nrrdKernelParse | |||
3350 | ** nrrdKernelCompare | |||
3351 | ** nrrdKernelSpecNew | |||
3352 | ** nrrdKernelSpecNix | |||
3353 | ** nrrdKernelSpecSet | |||
3354 | ** nrrdKernelSpecSprint | |||
3355 | ** nrrdKernelSpecParse | |||
3356 | ** and also exercises all the ways of evaluating the kernel and | |||
3357 | ** makes sure they all agree, and agree with the integral kernel, if given | |||
3358 | */ | |||
3359 | int | |||
3360 | nrrdKernelCheck(const NrrdKernel *kern, | |||
3361 | const double parm[NRRD_KERNEL_PARMS_NUM8], | |||
3362 | size_t evalNum, double epsilon, | |||
3363 | unsigned int diffOkEvalMax, | |||
3364 | unsigned int diffOkIntglMax, | |||
3365 | const NrrdKernel *ikern, | |||
3366 | const double iparm[NRRD_KERNEL_PARMS_NUM8]) { | |||
3367 | const NrrdKernel *parsedkern; | |||
3368 | double parsedparm[NRRD_KERNEL_PARMS_NUM8], supp, integral; | |||
3369 | static const char me[]="nrrdKernelCheck"; | |||
3370 | char kstr[AIR_STRLEN_LARGE(512+1)], kspstr[AIR_STRLEN_LARGE(512+1)], | |||
3371 | explain[AIR_STRLEN_LARGE(512+1)], stmp[AIR_STRLEN_SMALL(128+1)]; | |||
3372 | int differ; | |||
| ||||
3373 | size_t evalIdx; | |||
3374 | double *dom_d, *ran_d, wee; | |||
3375 | float *dom_f, *ran_f; | |||
3376 | unsigned int diffOkEvalNum, diffOkIntglNum; | |||
3377 | NrrdKernelSpec *kspA, *kspB; | |||
3378 | airArray *mop; | |||
3379 | ||||
3380 | mop = airMopNew(); | |||
3381 | if (!kern) { | |||
3382 | biffAddf(NRRDnrrdBiffKey, "%s: got NULL kernel", me); | |||
3383 | airMopError(mop); return 1; | |||
3384 | } | |||
3385 | if (!(evalNum > 20)) { | |||
3386 | biffAddf(NRRDnrrdBiffKey, "%s: need evalNum > 20", me); | |||
3387 | airMopError(mop); return 1; | |||
3388 | } | |||
3389 | if (!(kern->support && kern->integral | |||
3390 | && kern->eval1_f && kern->evalN_f | |||
3391 | && kern->eval1_d && kern->evalN_d)) { | |||
3392 | biffAddf(NRRDnrrdBiffKey, "%s: kernel has NULL fields (%d,%d,%d,%d,%d,%d)", me, | |||
3393 | !!(kern->support), !!(kern->integral), | |||
3394 | !!(kern->eval1_f), !!(kern->evalN_f), | |||
3395 | !!(kern->eval1_d), !!(kern->evalN_d)); | |||
3396 | airMopError(mop); return 1; | |||
3397 | } | |||
3398 | kspA = nrrdKernelSpecNew(); | |||
3399 | airMopAdd(mop, kspA, (airMopper)nrrdKernelSpecNix, airMopAlways); | |||
3400 | kspB = nrrdKernelSpecNew(); | |||
3401 | airMopAdd(mop, kspB, (airMopper)nrrdKernelSpecNix, airMopAlways); | |||
3402 | nrrdKernelSpecSet(kspA, kern, parm); | |||
3403 | if (nrrdKernelSprint(kstr, kern, parm) | |||
3404 | || nrrdKernelSpecSprint(kspstr, kspA)) { | |||
3405 | biffAddf(NRRDnrrdBiffKey, "%s: trouble", me); | |||
3406 | airMopError(mop); return 1; | |||
3407 | } | |||
3408 | if (strcmp(kstr, kspstr)) { | |||
3409 | biffAddf(NRRDnrrdBiffKey, "%s: sprinted kernel |%s| != kspec |%s|", me, kstr, kspstr); | |||
3410 | airMopError(mop); return 1; | |||
3411 | } | |||
3412 | if (nrrdKernelParse(&parsedkern, parsedparm, kstr) | |||
3413 | || nrrdKernelSpecParse(kspB, kstr)) { | |||
3414 | biffAddf(NRRDnrrdBiffKey, "%s: trouble parsing |%s| back to kern/parm pair or kspec", | |||
3415 | me, kstr); | |||
3416 | airMopError(mop); return 1; | |||
3417 | } | |||
3418 | if (nrrdKernelCompare(kern, parm, parsedkern, parsedparm, | |||
3419 | &differ, explain)) { | |||
3420 | biffAddf(NRRDnrrdBiffKey, "%s: trouble comparing kern/parm pairs", me); | |||
3421 | airMopError(mop); return 1; | |||
3422 | } | |||
3423 | if (differ) { | |||
| ||||
3424 | biffAddf(NRRDnrrdBiffKey, "%s: given and re-parsed kernels differ: %s", me, explain); | |||
3425 | airMopError(mop); return 1; | |||
3426 | } | |||
3427 | if (nrrdKernelCompare(kspA->kernel, kspA->parm, | |||
3428 | kspB->kernel, kspB->parm, | |||
3429 | &differ, explain)) { | |||
3430 | biffAddf(NRRDnrrdBiffKey, "%s: trouble comparing kspecs", me); | |||
3431 | airMopError(mop); return 1; | |||
3432 | } | |||
3433 | if (differ) { | |||
3434 | biffAddf(NRRDnrrdBiffKey, "%s: given and re-parsed kspecs differ: %s", me, explain); | |||
3435 | airMopError(mop); return 1; | |||
3436 | } | |||
3437 | ||||
3438 | supp = kern->support(parm); | |||
3439 | /* wee is the step between evaluation points */ | |||
3440 | wee = 2*supp/AIR_CAST(double, evalNum)((double)(evalNum)); | |||
3441 | if ( (kern->eval1_d)(supp+wee/1000, parm) || | |||
3442 | (kern->eval1_d)(supp+wee, parm) || | |||
3443 | (kern->eval1_d)(supp+10*wee, parm) || | |||
3444 | (kern->eval1_d)(-supp-wee/1000, parm) || | |||
3445 | (kern->eval1_d)(-supp-wee, parm) || | |||
3446 | (kern->eval1_d)(-supp-10*wee, parm) ) { | |||
3447 | if (nrrdKernelCheap != kern) { | |||
3448 | /* the "cheap" kernel alone gets a pass on reporting its support */ | |||
3449 | biffAddf(NRRDnrrdBiffKey, "%s: kern %s is non-zero outside support %g", | |||
3450 | me, kstr, supp); | |||
3451 | airMopError(mop); return 1; | |||
3452 | } | |||
3453 | } | |||
3454 | /* allocate domain and range for both float and double */ | |||
3455 | dom_d = AIR_CALLOC(evalNum, double)(double*)(calloc((evalNum), sizeof(double))); | |||
3456 | airMopAdd(mop, dom_d, airFree, airMopAlways); | |||
3457 | ran_d = AIR_CALLOC(evalNum, double)(double*)(calloc((evalNum), sizeof(double))); | |||
3458 | airMopAdd(mop, ran_d, airFree, airMopAlways); | |||
3459 | dom_f = AIR_CALLOC(evalNum, float)(float*)(calloc((evalNum), sizeof(float))); | |||
3460 | airMopAdd(mop, dom_f, airFree, airMopAlways); | |||
3461 | ran_f = AIR_CALLOC(evalNum, float)(float*)(calloc((evalNum), sizeof(float))); | |||
3462 | airMopAdd(mop, ran_f, airFree, airMopAlways); | |||
3463 | if (!( dom_d && ran_d && dom_f && ran_f )) { | |||
3464 | biffAddf(NRRDnrrdBiffKey, "%s: couldn't alloc buffers for %s values for %s", | |||
3465 | me, airSprintSize_t(stmp, evalNum), kstr); | |||
3466 | airMopError(mop); return 1; | |||
3467 | } | |||
3468 | for (evalIdx=0; evalIdx<evalNum; evalIdx++) { | |||
3469 | dom_d[evalIdx] = AIR_AFFINE(-0.5, evalIdx,( ((double)(supp)-(-supp))*((double)(evalIdx)-(-0.5)) / ((double )(((double)(evalNum))-0.5)-(-0.5)) + (-supp)) | |||
3470 | AIR_CAST(double, evalNum)-0.5,( ((double)(supp)-(-supp))*((double)(evalIdx)-(-0.5)) / ((double )(((double)(evalNum))-0.5)-(-0.5)) + (-supp)) | |||
3471 | -supp, supp)( ((double)(supp)-(-supp))*((double)(evalIdx)-(-0.5)) / ((double )(((double)(evalNum))-0.5)-(-0.5)) + (-supp)); | |||
3472 | dom_f[evalIdx] = AIR_CAST(float, dom_d[evalIdx])((float)(dom_d[evalIdx])); | |||
3473 | } | |||
3474 | /* do the vector evaluations */ | |||
3475 | kern->evalN_f(ran_f, dom_f, evalNum, parm); | |||
3476 | kern->evalN_d(ran_d, dom_d, evalNum, parm); | |||
3477 | /* | |||
3478 | for (evalIdx=0; evalIdx<evalNum; evalIdx++) { | |||
3479 | fprintf(stderr, "%u %g --> %g\n", AIR_CAST(unsigned int, evalIdx), | |||
3480 | dom_d[evalIdx], ran_d[evalIdx]); | |||
3481 | } | |||
3482 | */ | |||
3483 | /* compare evaluations (and maybe derivatives) and numerically compute | |||
3484 | integral */ | |||
3485 | diffOkEvalNum = 0; | |||
3486 | diffOkIntglNum = 0; | |||
3487 | integral = 0.0; | |||
3488 | for (evalIdx=0; evalIdx<evalNum; evalIdx++) { | |||
3489 | double single_f, single_d; | |||
3490 | single_f = kern->eval1_f(dom_f[evalIdx], parm); | |||
3491 | single_d = kern->eval1_d(dom_d[evalIdx], parm); | |||
3492 | integral += single_d; | |||
3493 | /* single float vs vector float */ | |||
3494 | if (nrrdKernelForwDiff == kern | |||
3495 | || nrrdKernelBCCubic == kern | |||
3496 | || nrrdKernelBCCubicDD == kern | |||
3497 | || nrrdKernelAQuarticDD == kern) { | |||
3498 | /* HEY this is crazy: need a special epsilon for these kernels; | |||
3499 | WHY WHY do these kernels evaluate to different things in the | |||
3500 | single versus the vector case? */ | |||
3501 | float specEps; | |||
3502 | if (nrrdKernelForwDiff == kern) { | |||
3503 | specEps = 5e-9f; | |||
3504 | } else if (nrrdKernelBCCubic == kern) { | |||
3505 | specEps = 5e-8f; | |||
3506 | } else if (nrrdKernelBCCubicDD == kern) { | |||
3507 | specEps = 5e-8f; | |||
3508 | } else if (nrrdKernelAQuarticDD == kern) { | |||
3509 | specEps = 5e-8f; | |||
3510 | } else { | |||
3511 | specEps = 0.0; | |||
3512 | } | |||
3513 | if (fabs(single_f - ran_f[evalIdx]) > specEps) { | |||
3514 | biffAddf(NRRDnrrdBiffKey, "%s: %s (eval1_f(%.17g)=%.17g) != " | |||
3515 | "(evalN_f(%.17g)=%.17g) by %.17g > %.17g", | |||
3516 | me, kstr, dom_f[evalIdx], single_f, | |||
3517 | dom_f[evalIdx], ran_f[evalIdx], | |||
3518 | fabs(single_f - ran_f[evalIdx]), specEps); | |||
3519 | airMopError(mop); return 1; | |||
3520 | } | |||
3521 | } else { | |||
3522 | if (single_f != ran_f[evalIdx]) { | |||
3523 | biffAddf(NRRDnrrdBiffKey, "%s: %s (eval1_f(%.17g)=%.17g) != " | |||
3524 | "(evalN_f(%.17g)=%.17g)", | |||
3525 | me, kstr, dom_f[evalIdx], single_f, | |||
3526 | dom_f[evalIdx], ran_f[evalIdx]); | |||
3527 | airMopError(mop); return 1; | |||
3528 | } | |||
3529 | } | |||
3530 | /* single double vs vector double */ | |||
3531 | if (single_d != ran_d[evalIdx]) { | |||
3532 | biffAddf(NRRDnrrdBiffKey, "%s: %s (eval1_d(%.17g)=%.17g) != (evalN_d(%.17g)=%.17g)", | |||
3533 | me, kstr, dom_d[evalIdx], single_d, | |||
3534 | dom_d[evalIdx], ran_d[evalIdx]); | |||
3535 | airMopError(mop); return 1; | |||
3536 | } | |||
3537 | /* single float vs single double */ | |||
3538 | if (fabs(single_f - single_d) > epsilon) { | |||
3539 | diffOkEvalNum++; | |||
3540 | if (diffOkEvalNum > diffOkEvalMax) { | |||
3541 | biffAddf(NRRDnrrdBiffKey, | |||
3542 | "%s: %s |eval1_f(%.17g)=%.17g) - (eval1_d(%.17g)=%.17g)|" | |||
3543 | " %.17g > epsilon %.17g too many times (%u > %u)", me, | |||
3544 | kstr, dom_f[evalIdx], single_f, dom_d[evalIdx], single_d, | |||
3545 | fabs(single_f - single_d), epsilon, | |||
3546 | diffOkEvalNum, diffOkEvalMax); | |||
3547 | airMopError(mop); return 1; | |||
3548 | } | |||
3549 | } | |||
3550 | /* check whether we're the derivative of ikern */ | |||
3551 | if (ikern) { | |||
3552 | double forw, back, ndrv; | |||
3553 | forw = ikern->eval1_d(dom_d[evalIdx] + wee/2, iparm); | |||
3554 | back = ikern->eval1_d(dom_d[evalIdx] - wee/2, iparm); | |||
3555 | ndrv = (forw - back)/wee; | |||
3556 | if (fabs(ndrv - single_d) > epsilon) { | |||
3557 | diffOkIntglNum++; | |||
3558 | if (diffOkIntglNum > diffOkIntglMax) { | |||
3559 | biffAddf(NRRDnrrdBiffKey, "%s: %s(%.17g) |num deriv(%s) %.17g - %.17g| " | |||
3560 | "%.17g > %.17g too many times (%u > %u)", | |||
3561 | me, kstr, dom_d[evalIdx], ikern->name, ndrv, single_d, | |||
3562 | fabs(ndrv - single_d), epsilon, | |||
3563 | diffOkIntglNum, diffOkIntglMax); | |||
3564 | airMopError(mop); return 1; | |||
3565 | } | |||
3566 | } | |||
3567 | } | |||
3568 | } | |||
3569 | integral *= 2*supp/(AIR_CAST(double, evalNum)((double)(evalNum))); | |||
3570 | /* the "cheap" kernel alone gets a pass on reporting its integral */ | |||
3571 | if (nrrdKernelCheap != kern) { | |||
3572 | double hackeps=10; | |||
3573 | /* hackeps is clearly a hack to permit the integral to have greater | |||
3574 | error than any single evaluation; there must be a more principled | |||
3575 | way to set this */ | |||
3576 | if (fabs(integral - kern->integral(parm)) > hackeps*epsilon) { | |||
3577 | biffAddf(NRRDnrrdBiffKey, "%s: %s |numerical integral %.17g - claimed %.17g| " | |||
3578 | "%.17g > %.17g", me, kstr, integral, kern->integral(parm), | |||
3579 | fabs(integral - kern->integral(parm)), hackeps*epsilon); | |||
3580 | airMopError(mop); return 1; | |||
3581 | } | |||
3582 | } | |||
3583 | ||||
3584 | /* HEY check being derivative of ikern/iparm */ | |||
3585 | AIR_UNUSED(ikern)(void)(ikern); | |||
3586 | AIR_UNUSED(iparm)(void)(iparm); | |||
3587 | ||||
3588 | airMopOkay(mop); | |||
3589 | return 0; | |||
3590 | } | |||
3591 | ||||
3592 | int | |||
3593 | nrrdKernelParm0IsScale(const NrrdKernel *kern) { | |||
3594 | int ret; | |||
3595 | ||||
3596 | if (!kern) { | |||
3597 | ret = 0; | |||
3598 | } else if (nrrdKernelHann == kern || | |||
3599 | nrrdKernelHannD == kern || | |||
3600 | nrrdKernelHannDD == kern || | |||
3601 | nrrdKernelBlackman == kern || | |||
3602 | nrrdKernelBlackmanD == kern || | |||
3603 | nrrdKernelBlackmanDD == kern || | |||
3604 | nrrdKernelZero == kern || | |||
3605 | nrrdKernelBox == kern || | |||
3606 | nrrdKernelCheap == kern || | |||
3607 | nrrdKernelTent == kern || | |||
3608 | nrrdKernelForwDiff == kern || | |||
3609 | nrrdKernelCentDiff == kern || | |||
3610 | nrrdKernelBCCubic == kern || | |||
3611 | nrrdKernelBCCubicD == kern || | |||
3612 | nrrdKernelBCCubicDD == kern || | |||
3613 | nrrdKernelAQuartic == kern || | |||
3614 | nrrdKernelAQuarticD == kern || | |||
3615 | nrrdKernelAQuarticDD == kern || | |||
3616 | nrrdKernelGaussian == kern || | |||
3617 | nrrdKernelGaussianD == kern || | |||
3618 | nrrdKernelGaussianDD == kern || | |||
3619 | nrrdKernelDiscreteGaussian == kern) { | |||
3620 | ret = 1; | |||
3621 | } else { | |||
3622 | ret = 0; | |||
3623 | } | |||
3624 | return ret; | |||
3625 | } |