GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: src/nrrd/bsplKernel.c Lines: 88 88 100.0 %
Date: 2017-05-26 Branches: 739 808 91.5 %

Line Branch Exec Source
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
static double
27
returnZero(const double *parm) {
28
  AIR_UNUSED(parm);
29
44
  return 0.0;
30
}
31
32
static double
33
returnOne(const double *parm) {
34
  AIR_UNUSED(parm);
35
6930
  return 1.0;
36
}
37
38
/*
39
** These kernels are the cardinal B-splines of different orders
40
** Using them with convolution assumes that the data has been pre-filtered
41
** so that the spline interpolates the original values.
42
*/
43
44
/* helper macros for doing abs() and remembering sign */
45
#define ABS_SGN(ax, sgn, x)                     \
46
  if (x < 0) {                                  \
47
    sgn = -1;                                   \
48
    ax = -x;                                    \
49
  } else {                                      \
50
    sgn = 1;                                    \
51
    ax = x;                                     \
52
  }
53
54
/* helper macro for listing the various members of the kernel */
55
#define BSPL_DECL(ord, deriv)                   \
56
  0,                                            \
57
    _bspl##ord##_sup,                           \
58
    (0 == deriv ? returnOne : returnZero),      \
59
    _bspl##ord##d##deriv##_1f,                  \
60
    _bspl##ord##d##deriv##_Nf,                  \
61
    _bspl##ord##d##deriv##_1d,                  \
62
    _bspl##ord##d##deriv##_Nd
63
64
/* (the following preceded some of the function definitions before they
65
   were all packed up in the _METHODS macros; but the question about the
66
   type of the locals is still relevant)
67
   HEY: there is a possibly interesting question to be answered here
68
   about whether, to distinguish the float-specific and
69
   double-specific versions of the kernel eval functions, if the
70
   float-specific versions should actually only use floats for locals,
71
   so that no casting to float is needed at return, or, if its too
72
   much of a precision loss to do so, at no real economy of speed, so
73
   doubles should be used for all intermediate calculations, prior to
74
   the final cast to float.  The macros below do the casting,
75
   whether or not is as actually needed, so this can be experimented
76
   with by just changing the type of the locals (without changing the
77
   macro definitions) */
78
79
#define BSPL_EVEN_METHODS(basename, macro)               \
80
  static double                                          \
81
  basename##_1d(double x, const double *parm) {          \
82
    double ax, tmp, r;                                   \
83
    AIR_UNUSED(parm);                                    \
84
                                                         \
85
    ax = AIR_ABS(x);                                     \
86
    macro(r, double, tmp, ax);                           \
87
    return r;                                            \
88
  }                                                      \
89
                                                         \
90
  static float                                           \
91
  basename##_1f(float x, const double *parm) {           \
92
    float ax, tmp, r;                                    \
93
    AIR_UNUSED(parm);                                    \
94
                                                         \
95
    ax = AIR_ABS(x);                                     \
96
    macro(r, float, tmp, ax);                            \
97
    return r;                                            \
98
  }                                                      \
99
                                                         \
100
  static void                                            \
101
  basename##_Nd(double *f, const double *x, size_t len,  \
102
                const double *parm) {                    \
103
    double ax, tmp, r;                                   \
104
    size_t i;                                            \
105
    AIR_UNUSED(parm);                                    \
106
                                                         \
107
    for (i=0; i<len; i++) {                              \
108
      ax = x[i]; ax = AIR_ABS(ax);                       \
109
      macro(r, double, tmp, ax);                         \
110
      f[i] = r;                                          \
111
    }                                                    \
112
  }                                                      \
113
                                                         \
114
  static void                                            \
115
  basename##_Nf(float *f, const float *x, size_t len,    \
116
                const double *parm) {                    \
117
    float ax, tmp, r;                                    \
118
    size_t i;                                            \
119
    AIR_UNUSED(parm);                                    \
120
                                                         \
121
    for (i=0; i<len; i++) {                              \
122
      ax = x[i]; ax = AIR_ABS(ax);                       \
123
      macro(r, float, tmp, ax);                          \
124
      f[i] = r;                                          \
125
    }                                                    \
126
  }
127
128
#define BSPL_ODD_METHODS(basename, macro)                \
129
  static double                                          \
130
  basename##_1d(double x, const double *parm) {          \
131
    double ax, tmp, r;                                   \
132
    int sgn;                                             \
133
    AIR_UNUSED(parm);                                    \
134
                                                         \
135
    ABS_SGN(ax, sgn, x);                                 \
136
    macro(r, double, tmp, ax);                           \
137
    return sgn*r;                                        \
138
  }                                                      \
139
                                                         \
140
  static float                                           \
141
  basename##_1f(float x, const double *parm) {           \
142
    float sgn, ax, tmp, r;                               \
143
    AIR_UNUSED(parm);                                    \
144
                                                         \
145
    ABS_SGN(ax, sgn, x);                                 \
146
    macro(r, float, tmp, ax);                            \
147
    return sgn*r;                                        \
148
  }                                                      \
149
                                                         \
150
  static void                                            \
151
  basename##_Nd(double *f, const double *x, size_t len,  \
152
                const double *parm) {                    \
153
    double sgn, ax, tmp, r;                              \
154
    size_t i;                                            \
155
    AIR_UNUSED(parm);                                    \
156
                                                         \
157
    for (i=0; i<len; i++) {                              \
158
      ABS_SGN(ax, sgn, x[i]);                            \
159
      macro(r, double, tmp, ax);                         \
160
      f[i] = sgn*r;                                      \
161
    }                                                    \
162
  }                                                      \
163
                                                         \
164
  static void                                            \
165
  basename##_Nf(float *f, const float *x, size_t len,    \
166
                const double *parm) {                    \
167
    float sgn, ax, tmp, r;                               \
168
    size_t i;                                            \
169
    AIR_UNUSED(parm);                                    \
170
                                                         \
171
    for (i=0; i<len; i++) {                              \
172
      ABS_SGN(ax, sgn, x[i]);                            \
173
      macro(r, float, tmp, ax);                          \
174
      f[i] = sgn*r;                                      \
175
    }                                                    \
176
  }
177
178
/* ============================= order *1* ============================= */
179
180
static double
181
_bspl1_sup(const double *parm) {
182
  AIR_UNUSED(parm);
183
4
  return 1.0;
184
}
185
186
/* ---------------------- order *1* deriv *0* -------------------------- */
187
188
#define BSPL1D0(ret, TT, t, x)                 \
189
  AIR_UNUSED(t);                               \
190
  if (x < 1) {                                 \
191
    ret = AIR_CAST(TT, 1.0 - x);               \
192
  } else {                                     \
193
    ret = 0;                                   \
194
  }
195
196



2880024
BSPL_EVEN_METHODS(_bspl1d0, BSPL1D0)
197
198
static NrrdKernel
199
_nrrdKernelBSpline1 = {
200
  "bspl1",
201
  BSPL_DECL(1, 0)
202
};
203
NrrdKernel *const
204
nrrdKernelBSpline1 = &_nrrdKernelBSpline1;
205
206
/* ---------------------- order *1* deriv *1* -------------------------- */
207
208
#define BSPL1D1(ret, TT, t, x)                 \
209
  AIR_UNUSED(t);                               \
210
  if (x < 1) {                                 \
211
    ret = AIR_CAST(TT, -1.0);                  \
212
  } else {                                     \
213
    ret = 0;                                   \
214
  }
215
216





2640035
BSPL_ODD_METHODS(_bspl1d1, BSPL1D1)
217
218
static NrrdKernel
219
_nrrdKernelBSpline1D = {
220
  "bspl1d",
221
  BSPL_DECL(1, 1)
222
};
223
NrrdKernel *const
224
nrrdKernelBSpline1D = &_nrrdKernelBSpline1D;
225
226
/* ============================= order *2* ============================= */
227
228
static double
229
_bspl2_sup(const double *parm) {
230
  AIR_UNUSED(parm);
231
6
  return 1.5;
232
}
233
234
/* ---------------------- order *2* deriv *0* -------------------------- */
235
236
#define BSPL2D0(ret, TT, t, x)                 \
237
  if (x < 0.5) {                               \
238
    ret = AIR_CAST(TT, 3.0/4.0 - x*x);         \
239
  } else if (x < 1.5) {                        \
240
    t = (3 - 2*x);                             \
241
    ret = AIR_CAST(TT, t*t/8);                 \
242
  } else {                                     \
243
    ret = 0;                                   \
244
  }
245
246





3360030
BSPL_EVEN_METHODS(_bspl2d0, BSPL2D0)
247
248
static NrrdKernel
249
_nrrdKernelBSpline2 = {
250
  "bspl2",
251
  BSPL_DECL(2, 0)
252
};
253
NrrdKernel *const
254
nrrdKernelBSpline2 = &_nrrdKernelBSpline2;
255
256
/* ---------------------- order *2* deriv *1* -------------------------- */
257
258
#define BSPL2D1(ret, TT, t, x)                 \
259
  AIR_UNUSED(t);                               \
260
  if (x < 0.5) {                               \
261
    ret = AIR_CAST(TT, -2*x);                  \
262
  } else if (x < 1.5) {                        \
263
    ret = AIR_CAST(TT, -3.0/2.0 + x);          \
264
  } else {                                     \
265
    ret = 0;                                   \
266
  }
267
268







4440039
BSPL_ODD_METHODS(_bspl2d1, BSPL2D1)
269
270
static NrrdKernel
271
_nrrdKernelBSpline2D = {
272
  "bspl2d",
273
  BSPL_DECL(2, 1)
274
};
275
NrrdKernel *const
276
nrrdKernelBSpline2D = &_nrrdKernelBSpline2D;
277
278
/* ---------------------- order *2* deriv *2* -------------------------- */
279
280
#define BSPL2D2(ret, TT, t, x)                 \
281
  AIR_UNUSED(t);                               \
282
  if (x < 0.5) {                               \
283
    ret = AIR_CAST(TT, -2.0);                  \
284
  } else if (x < 1.5) {                        \
285
    ret = AIR_CAST(TT, 1.0);                   \
286
  } else {                                     \
287
    ret = 0;                                   \
288
  }
289
290





2240032
BSPL_EVEN_METHODS(_bspl2d2, BSPL2D2)
291
292
static NrrdKernel
293
_nrrdKernelBSpline2DD = {
294
  "bspl2dd",
295
  BSPL_DECL(2, 2)
296
};
297
NrrdKernel *const
298
nrrdKernelBSpline2DD = &_nrrdKernelBSpline2DD;
299
300
/* ============================= order *3* ============================= */
301
302
static double
303
_bspl3_sup(const double *parm) {
304
  AIR_UNUSED(parm);
305
20
  return 2.0;
306
}
307
308
/* ---------------------- order *3* deriv *0* -------------------------- */
309
310
#define BSPL3D0(ret, TT, t, x)                  \
311
  if (x < 1) {                                  \
312
    ret = AIR_CAST(TT, (4 + 3*(-2 + x)*x*x)/6); \
313
  } else if (x < 2) {                           \
314
    t = (-2 + x);                               \
315
    ret = AIR_CAST(TT, -t*t*t/6);               \
316
  } else {                                      \
317
    ret = 0;                                    \
318
  }
319
320





3340254
BSPL_EVEN_METHODS(_bspl3d0, BSPL3D0)
321
322
static NrrdKernel
323
_nrrdKernelBSpline3 = {
324
  "bspl3",
325
  BSPL_DECL(3, 0)
326
};
327
NrrdKernel *const
328
nrrdKernelBSpline3 = &_nrrdKernelBSpline3;
329
330
/* ---------------------- order *3* deriv *1* -------------------------- */
331
332
#define BSPL3D1(ret, TT, t, x)                 \
333
  if (x < 1) {                                 \
334
    ret = AIR_CAST(TT, (-4 + 3*x)*x/2);        \
335
  } else if (x < 2) {                          \
336
    t = (-2 + x);                              \
337
    ret = AIR_CAST(TT, -t*t/2);                \
338
  } else {                                     \
339
    ret = 0;                                   \
340
  }
341
342







4451367
BSPL_ODD_METHODS(_bspl3d1, BSPL3D1)
343
344
static NrrdKernel
345
_nrrdKernelBSpline3D = {
346
  "bspl3d",
347
  BSPL_DECL(3, 1)
348
};
349
NrrdKernel *const
350
nrrdKernelBSpline3D = &_nrrdKernelBSpline3D;
351
352
/* ---------------------- order *3* deriv *2* -------------------------- */
353
354
/* NOTE: the tmp variable wasn't actually needed here, and this will
355
** likely be optimized out.  But the tmp argument to the macro is kept
356
** here (and the macro uses it to avoid a unused variable warning) to
357
** facilitate copy-and-paste for higher-order splines
358
*/
359
#define BSPL3D2(ret, TT, t, x)                 \
360
  AIR_UNUSED(t);                               \
361
  if (x < 1) {                                 \
362
    ret = AIR_CAST(TT, -2 + 3*x);              \
363
  } else if (x < 2) {                          \
364
    ret = AIR_CAST(TT, 2 - x);                 \
365
  } else {                                     \
366
    ret = 0;                                   \
367
  }
368
369





3340254
BSPL_EVEN_METHODS(_bspl3d2, BSPL3D2)
370
371
static NrrdKernel
372
_nrrdKernelBSpline3DD = {
373
  "bspl3dd",
374
  BSPL_DECL(3, 2)
375
};
376
NrrdKernel *const
377
nrrdKernelBSpline3DD = &_nrrdKernelBSpline3DD;
378
379
/* ---------------------- order *3* deriv *3* -------------------------- */
380
381
#define BSPL3D3(ret, TT, t, x)                  \
382
  AIR_UNUSED(t);                               \
383
  if (x < 1) {                                 \
384
    ret = 3;                                   \
385
  } else if (x < 2) {                          \
386
    ret = -1;                                  \
387
  } else {                                     \
388
    ret = 0;                                   \
389
  }
390
391







2880041
BSPL_ODD_METHODS(_bspl3d3, BSPL3D3)
392
393
static NrrdKernel
394
_nrrdKernelBSpline3DDD = {
395
  "bspl3ddd",
396
  BSPL_DECL(3, 3)
397
};
398
NrrdKernel *const
399
nrrdKernelBSpline3DDD = &_nrrdKernelBSpline3DDD;
400
401
/* ------------- order *3* approximate numerical inverse -------------- */
402
/* still need to implement:
403
**   Unser et al B-Spline Signal Processing: Part I & II, IEEE
404
**   Transactions on Signal Processing, 1993, 41(2):821-833, 834--848
405
** but until then here's a slower way of approximating the prefiltering,
406
** which is still faster than doing iterative deconvolution.  These
407
** weights were determined by GLK with Mathematica, by inverting the
408
** matrix representing discrete convolution with the spline
409
**
410
** Note that with all the approx inverse kernels, the support really
411
** does end at a half-integer (they are piece-wise constant on unit
412
** intervals centered at integers)
413
*/
414
415
#define BSPL3_AI_LEN 12
416
static double
417
_bspl3_ANI_kvals[BSPL3_AI_LEN] = {
418
  2672279.0/1542841.0,
419
  -(716035.0/1542841.0),
420
  191861.0/1542841.0,
421
  -(51409.0/1542841.0),
422
  13775.0/1542841.0,
423
  -(3691.0/1542841.0),
424
  989.0/1542841.0,
425
  -(265.0/1542841.0),
426
  71.0/1542841.0,
427
  -(19.0/1542841.0),
428
  5.0/1542841.0,
429
  -(1.0/1542841.0)};
430
431
static double
432
_bspl3_ANI_sup(const double *parm) {
433
  AIR_UNUSED(parm);
434
2
  return BSPL3_AI_LEN + 0.5;
435
}
436
437
static double
438
_bspl3_ANI_int(const double *parm) {
439
  AIR_UNUSED(parm);
440
2
  return 1.0;
441
}
442
443
#define BSPL3_ANI(ret, tmp, x)                  \
444
  tmp = AIR_CAST(unsigned int, x+0.5);          \
445
  if (tmp < BSPL3_AI_LEN) {                     \
446
    ret = _bspl3_ANI_kvals[tmp];                \
447
  } else {                                      \
448
    ret = 0.0;                                  \
449
  }
450
451
static double
452
_bspl3_ANI_1d(double x, const double *parm) {
453
  double ax, r; unsigned int tmp;
454
  AIR_UNUSED(parm);
455
456
240012
  ax = AIR_ABS(x);
457
230406
  BSPL3_ANI(r, tmp, ax);
458
120006
  return r;
459
}
460
461
static float
462
_bspl3_ANI_1f(float x, const double *parm) {
463
  double ax, r; unsigned int tmp;
464
  AIR_UNUSED(parm);
465
466
240000
  ax = AIR_ABS(x);
467
230400
  BSPL3_ANI(r, tmp, ax);
468
120000
  return AIR_CAST(float, r);
469
}
470
471
static void
472
_bspl3_ANI_Nd(double *f, const double *x, size_t len, const double *parm) {
473
  double ax, r; unsigned int tmp;
474
  size_t i;
475
  AIR_UNUSED(parm);
476
477
240003
  for (i=0; i<len; i++) {
478
120000
    ax = x[i]; ax = AIR_ABS(ax);
479
230400
    BSPL3_ANI(r, tmp, ax);
480
120000
    f[i] = r;
481
  }
482
1
}
483
484
static void
485
_bspl3_ANI_Nf(float *f, const float *x, size_t len, const double *parm) {
486
  double ax, r; unsigned int tmp;
487
  size_t i;
488
  AIR_UNUSED(parm);
489
490
240003
  for (i=0; i<len; i++) {
491
120000
    ax = x[i]; ax = AIR_ABS(ax);
492
230400
    BSPL3_ANI(r, tmp, ax);
493
120000
    f[i] = AIR_CAST(float, r);
494
  }
495
1
}
496
497
static NrrdKernel
498
_nrrdKernelBSpline3ApproxInverse = {
499
  "bspl3ai", 0,
500
  _bspl3_ANI_sup, _bspl3_ANI_int,
501
  _bspl3_ANI_1f, _bspl3_ANI_Nf,
502
  _bspl3_ANI_1d, _bspl3_ANI_Nd
503
};
504
NrrdKernel *const
505
nrrdKernelBSpline3ApproxInverse = &_nrrdKernelBSpline3ApproxInverse;
506
507
/* ============================= order *4* ============================= */
508
509
static double
510
_bspl4_sup(const double *parm) {
511
  AIR_UNUSED(parm);
512
8
  return 2.5;
513
}
514
515
/* ---------------------- order *4* deriv *0* -------------------------- */
516
517
#define BSPL4D0(ret, TT, t, x)                                          \
518
  if (x < 0.5) {                                                        \
519
    t = x*x;                                                            \
520
    ret = AIR_CAST(TT, 115.0/192.0 - 5*t/8 + t*t/4);                    \
521
  } else if (x < 1.5) {                                                 \
522
    ret = AIR_CAST(TT, (55.0 + 4*x*(5.0 - 2*x*(15.0 + 2*(-5 + x)*x)))/96); \
523
  } else if (x < 2.5) {                                                 \
524
    t = 5 - 2*x;                                                        \
525
    ret = AIR_CAST(TT, t*t*t*t/384.0);                                  \
526
  } else {                                                              \
527
    ret = 0;                                                            \
528
  }
529
530







3744038
BSPL_EVEN_METHODS(_bspl4d0, BSPL4D0)
531
532
static NrrdKernel
533
_nrrdKernelBSpline4 = {
534
  "bspl4",
535
  BSPL_DECL(4, 0)
536
};
537
NrrdKernel *const
538
nrrdKernelBSpline4 = &_nrrdKernelBSpline4;
539
540
/* ---------------------- order *4* deriv *1* -------------------------- */
541
542
#define BSPL4D1(ret, TT, t, x)                                          \
543
  if (x < 0.5) {                                                        \
544
    ret = AIR_CAST(TT, x*(-5.0/4.0 + x*x));                             \
545
  } else if (x < 1.5) {                                                 \
546
    ret = AIR_CAST(TT, (5.0 - 4*x*(15.0 + x*(-15.0 + 4*x)))/24.0);      \
547
  } else if (x < 2.5) {                                                 \
548
    t = -5 + 2*x;                                                        \
549
    ret = AIR_CAST(TT, t*t*t/48.0);                                     \
550
  } else {                                                              \
551
    ret = 0;                                                            \
552
  }
553
554









4824047
BSPL_ODD_METHODS(_bspl4d1, BSPL4D1)
555
556
static NrrdKernel
557
_nrrdKernelBSpline4D = {
558
  "bspl4d",
559
  BSPL_DECL(4, 1)
560
};
561
NrrdKernel *const
562
nrrdKernelBSpline4D = &_nrrdKernelBSpline4D;
563
564
/* ---------------------- order *4* deriv *2* -------------------------- */
565
566
#define BSPL4D2(ret, TT, t, x)                                          \
567
  if (x < 0.5) {                                                        \
568
    ret = AIR_CAST(TT, -5.0/4.0 + 3*x*x);                               \
569
  } else if (x < 1.5) {                                                 \
570
    ret = AIR_CAST(TT, -5.0/2.0 + (5.0 - 2*x)*x);                       \
571
  } else if (x < 2.5) {                                                 \
572
    t = 5 - 2*x;                                                        \
573
    ret = AIR_CAST(TT, t*t/8.0);                                        \
574
  } else {                                                              \
575
    ret = 0;                                                            \
576
  }
577
578







3744038
BSPL_EVEN_METHODS(_bspl4d2, BSPL4D2)
579
580
static NrrdKernel
581
_nrrdKernelBSpline4DD = {
582
  "bspl4dd",
583
  BSPL_DECL(4, 2)
584
};
585
NrrdKernel *const
586
nrrdKernelBSpline4DD = &_nrrdKernelBSpline4DD;
587
588
/* ---------------------- order *4* deriv *3* -------------------------- */
589
590
#define BSPL4D3(ret, TT, t, x)                                          \
591
  AIR_UNUSED(t);                                                        \
592
  if (x < 0.5) {                                                        \
593
    ret = AIR_CAST(TT, 6*x);                                            \
594
  } else if (x < 1.5) {                                                 \
595
    ret = AIR_CAST(TT, 5 - 4*x);                                        \
596
  } else if (x < 2.5) {                                                 \
597
    ret = AIR_CAST(TT, -5.0/2.0 + x);                                   \
598
  } else {                                                              \
599
    ret = 0;                                                            \
600
  }
601
602









3216047
BSPL_ODD_METHODS(_bspl4d3, BSPL4D3)
603
604
static NrrdKernel
605
_nrrdKernelBSpline4DDD = {
606
  "bspl4ddd",
607
  BSPL_DECL(4, 3)
608
};
609
NrrdKernel *const
610
nrrdKernelBSpline4DDD = &_nrrdKernelBSpline4DDD;
611
612
/* ============================= order *5* ============================= */
613
614
static double
615
_bspl5_sup(const double *parm) {
616
  AIR_UNUSED(parm);
617
20
  return 3.0;
618
}
619
620
/* ---------------------- order *5* deriv *0* -------------------------- */
621
622
#define BSPL5D0(ret, TT, t, x)                                  \
623
  if (x < 1) {                                                  \
624
    t = x*x;                                                    \
625
    ret = AIR_CAST(TT, (33 - 5*t*(6 + (x-3)*t))/60);            \
626
  } else if (x < 2) {                                           \
627
    ret = AIR_CAST(TT, (51 + 5*x*(15 + x*(-42 + x*(30 + (-9 + x)*x))))/120); \
628
  } else if (x < 3) {                                                   \
629
    t = x - 3;                                                  \
630
    ret = AIR_CAST(TT, -t*t*t*t*t/120);                         \
631
  } else {                                                      \
632
    ret = 0;                                                    \
633
  }
634
635







3763334
BSPL_EVEN_METHODS(_bspl5d0, BSPL5D0)
636
637
static NrrdKernel
638
_nrrdKernelBSpline5 = {
639
  "bspl5",
640
  BSPL_DECL(5, 0)
641
};
642
NrrdKernel *const
643
nrrdKernelBSpline5 = &_nrrdKernelBSpline5;
644
645
/* ---------------------- order *5* deriv *1* -------------------------- */
646
647
#define BSPL5D1(ret, TT, t, x)                          \
648
  if (x < 1) {                                          \
649
    t = x*x*x;                                          \
650
    ret = AIR_CAST(TT, -x + t - (5*t*x)/12);             \
651
  } else if (x < 2) {                                   \
652
    ret = AIR_CAST(TT, (15 + x*(-84 + x*(90 + x*(-36 + 5*x))))/24);     \
653
  } else if (x < 3) {                                   \
654
    t = -3 + x;                                         \
655
    ret = AIR_CAST(TT, -t*t*t*t/24);                    \
656
  } else {                                              \
657
    ret = 0;                                            \
658
  }
659
660









4889999
BSPL_ODD_METHODS(_bspl5d1, BSPL5D1)
661
662
static NrrdKernel
663
_nrrdKernelBSpline5D = {
664
  "bspl5d",
665
  BSPL_DECL(5, 1)
666
};
667
NrrdKernel *const
668
nrrdKernelBSpline5D = &_nrrdKernelBSpline5D;
669
670
/* ---------------------- order *5* deriv *2* -------------------------- */
671
672
#define BSPL5D2(ret, TT, t, x)                  \
673
  if (x < 1) {                                  \
674
    t = x*x;                                    \
675
    ret = AIR_CAST(TT, -1 + 3*t - (5*t*x)/3);   \
676
  } else if (x < 2) {                           \
677
    ret = AIR_CAST(TT, (-21 + x*(45 + x*(-27 + 5*x)))/6);       \
678
  } else if (x < 3) {                                           \
679
    t = -3 + x;                                 \
680
    ret = AIR_CAST(TT, -t*t*t/6);               \
681
  } else {                                      \
682
    ret = 0;                                    \
683
  }
684
685







3763334
BSPL_EVEN_METHODS(_bspl5d2, BSPL5D2)
686
687
static NrrdKernel
688
_nrrdKernelBSpline5DD = {
689
  "bspl5dd",
690
  BSPL_DECL(5, 2)
691
};
692
NrrdKernel *const
693
nrrdKernelBSpline5DD = &_nrrdKernelBSpline5DD;
694
695
/* ---------------------- order *5* deriv *3* -------------------------- */
696
697
#define BSPL5D3(ret, TT, t, x)                          \
698
  if (x < 1) {                                          \
699
    ret = AIR_CAST(TT, (6 - 5*x)*x);                    \
700
  } else if (x < 2) {                                   \
701
    ret = AIR_CAST(TT, 15.0/2.0 - 9*x + 5*x*x/2);       \
702
  } else if (x < 3) {                                   \
703
    t = -3 + x;                                         \
704
    ret = AIR_CAST(TT, -t*t/2);                         \
705
  } else {                                              \
706
    ret = 0;                                            \
707
  }
708
709









3120047
BSPL_ODD_METHODS(_bspl5d3, BSPL5D3)
710
711
static NrrdKernel
712
_nrrdKernelBSpline5DDD = {
713
  "bspl5ddd",
714
  BSPL_DECL(5, 3)
715
};
716
NrrdKernel *const
717
nrrdKernelBSpline5DDD = &_nrrdKernelBSpline5DDD;
718
719
/* ------------- order *5* approximate numerical inverse -------------- */
720
721
#define BSPL5_AI_LEN 19
722
static double
723
_bspl5_ANI_kvals[BSPL5_AI_LEN] = {
724
  2.842170922021427870236333,
725
  -1.321729472987239796417307,
726
  0.5733258709611149890510146,
727
  -0.2470419274010479815114381,
728
  0.1063780046404650785440854,
729
  -0.04580408418467518130037713,
730
  0.01972212399699206014654736,
731
  -0.008491860984275658620122180,
732
  0.003656385950780789716770681,
733
  -0.001574349495225446217828165,
734
  0.0006778757185045443332966769,
735
  -0.0002918757322635763049702028,
736
  0.0001256725426338698784062181,
737
  -0.00005410696497728715841372199,
738
  0.00002328659592249373987497103,
739
  -0.00001000218170092531503506361,
740
  4.249940115067599514119408e-6,
741
  -1.698979738236873388431330e-6,
742
  4.475539012615912040164139e-7};
743
744
static double
745
_bspl5_ANI_sup(const double *parm) {
746
  AIR_UNUSED(parm);
747
2
  return BSPL5_AI_LEN + 0.5;
748
}
749
750
static double
751
_bspl5_ANI_int(const double *parm) {
752
  AIR_UNUSED(parm);
753
2
  return 1.0;
754
}
755
756
#define BSPL5_ANI_T(ret, TT, tmp, x)            \
757
  tmp = AIR_CAST(unsigned int, x+0.5);          \
758
  if (tmp < BSPL5_AI_LEN) {                     \
759
    ret = AIR_CAST(TT, _bspl5_ANI_kvals[tmp]);  \
760
  } else {                                      \
761
    ret = 0.0;                                  \
762
  }
763
764
static double
765
_bspl5_ANI_1d(double x, const double *parm) {
766
  double ax, r; unsigned int tmp;
767
  AIR_UNUSED(parm);
768
769
240012
  ax = AIR_ABS(x);
770
233852
  BSPL5_ANI_T(r, double, tmp, ax);
771
120006
  return r;
772
}
773
774
static float
775
_bspl5_ANI_1f(float x, const double *parm) {
776
  double ax, r; unsigned int tmp;
777
  AIR_UNUSED(parm);
778
779
240000
  ax = AIR_ABS(x);
780
233846
  BSPL5_ANI_T(r, float, tmp, ax);
781
120000
  return AIR_CAST(float, r);
782
}
783
784
static void
785
_bspl5_ANI_Nd(double *f, const double *x, size_t len, const double *parm) {
786
  double ax, r; unsigned int tmp;
787
  size_t i;
788
  AIR_UNUSED(parm);
789
790
240003
  for (i=0; i<len; i++) {
791
120000
    ax = x[i]; ax = AIR_ABS(ax);
792
233846
    BSPL5_ANI_T(r, double, tmp, ax);
793
120000
    f[i] = r;
794
  }
795
1
}
796
797
static void
798
_bspl5_ANI_Nf(float *f, const float *x, size_t len, const double *parm) {
799
  double ax, r; unsigned int tmp;
800
  size_t i;
801
  AIR_UNUSED(parm);
802
803
240003
  for (i=0; i<len; i++) {
804
120000
    ax = x[i]; ax = AIR_ABS(ax);
805
233846
    BSPL5_ANI_T(r, float, tmp, ax);
806
120000
    f[i] = AIR_CAST(float, r);
807
  }
808
1
}
809
810
static NrrdKernel
811
_nrrdKernelBSpline5ApproxInverse = {
812
  "bspl5ai", 0,
813
  _bspl5_ANI_sup, _bspl5_ANI_int,
814
  _bspl5_ANI_1f, _bspl5_ANI_Nf,
815
  _bspl5_ANI_1d, _bspl5_ANI_Nd
816
};
817
NrrdKernel *const
818
nrrdKernelBSpline5ApproxInverse = &_nrrdKernelBSpline5ApproxInverse;
819
820
/* ============================= order *6* ============================= */
821
822
static double
823
_bspl6_sup(const double *parm) {
824
  AIR_UNUSED(parm);
825
8
  return 3.5;
826
}
827
828
/* ---------------------- order *6* deriv *0* -------------------------- */
829
830
#define BSPL6D0_SEG0(x) 0.5110243055555555556 + x*x*(-0.40104166666666666667 + x*x*(0.14583333333333333333 - 0.027777777777777777778*x*x))
831
#define BSPL6D0_SEG1(x) 0.02083333333333333*(5.05890179802561 + (-4.47046426301056 + x)*x)*(5.07700929828288 + (-4.13708416717549 + x)*x)*(0.956452947962608 + x*(1.607548430186042 + x))
832
#define BSPL6D0_SEG2(x) -0.008333333333333*(-2.919623692889 + x)*(0.11036932382080 + x)*(8.451507829592 + (-5.787493668289 + x)*x)*(7.911791484411 + (-5.403251962643 + x)*x)
833
#define BSPL6D0(ret, TT, t, x)                                          \
834
  if (x < 0.5) {                                                        \
835
    ret = AIR_CAST(TT, BSPL6D0_SEG0(x));                                \
836
  } else if (x < 1.5) {                                                 \
837
    ret = AIR_CAST(TT, BSPL6D0_SEG1(x));                                \
838
  } else if (x < 2.5) {                                                 \
839
    ret = AIR_CAST(TT, BSPL6D0_SEG2(x));                                \
840
  } else if (x < 3.5) {                                                 \
841
    t = AIR_CAST(TT, x - 3.5);                                          \
842
    ret = AIR_CAST(TT, 0.00139*t*t*t*t*t*t );                           \
843
  } else {                                                              \
844
    ret = 0;                                                            \
845
  }
846
847









4114332
BSPL_EVEN_METHODS(_bspl6d0, BSPL6D0)
848
849
static NrrdKernel
850
_nrrdKernelBSpline6 = {
851
  "bspl6",
852
  BSPL_DECL(6, 0)
853
};
854
NrrdKernel *const
855
nrrdKernelBSpline6 = &_nrrdKernelBSpline6;
856
857
/* ---------------------- order *6* deriv *1* -------------------------- */
858
859
#define BSPL6D1_SEG0(x) x*(-0.8020833333333333333 + x*x*(0.5833333333333333333 - x*x*0.16666666666666666667))
860
#define BSPL6D1_SEG1(x) 0.1250000000000000*(-2.204221529535419 + x)*(0.01290998431413690 + x)*(0.5355244627388528 + x)*(4.784830284687429 + (-4.177546250850904 + x)*x)
861
#define BSPL6D1_SEG2(x) -0.050000000000000*(-0.39815802840054 + x)*(8.4005837632394 + (-5.7883654809137 + x)*x)*(7.8916975718499 + (-5.4801431573524 + x)*x)
862
#define BSPL6D1(ret, TT, t, x)                                          \
863
  if (x < 0.5) {                                                        \
864
    ret = AIR_CAST(TT, BSPL6D1_SEG0(x));                                \
865
  } else if (x < 1.5) {                                                 \
866
    ret = AIR_CAST(TT, BSPL6D1_SEG1(x));                                \
867
  } else if (x < 2.5) {                                                 \
868
    ret = AIR_CAST(TT, BSPL6D1_SEG2(x));                                \
869
  } else if (x < 3.5) {                                                 \
870
    t = AIR_CAST(TT, -3.5 + x);                                         \
871
    ret = AIR_CAST(TT, 0.00833*t*t*t*t*t);                              \
872
  } else {                                                              \
873
    ret = 0.0;                                                          \
874
  }
875
876











5194341
BSPL_ODD_METHODS(_bspl6d1, BSPL6D1)
877
878
static NrrdKernel
879
_nrrdKernelBSpline6D = {
880
  "bspl6d",
881
  BSPL_DECL(6, 1)
882
};
883
NrrdKernel *const
884
nrrdKernelBSpline6D = &_nrrdKernelBSpline6D;
885
886
/* ---------------------- order *6* deriv *2* -------------------------- */
887
888
#define BSPL6D2_SEG0(x) -0.80208333333333333333 + x*x*(1.75 - x*x*0.833333333333333333)
889
#define BSPL6D2_SEG1(x) 0.625*(-0.8093237825464294 + x)*(0.3133677888004832 + x)*(4.485127047744998 + (-4.170710672920720 + x)*x)
890
#define BSPL6D2_SEG2(x) -0.25*(-2.88072372021534 + x)*(-0.904025842763129 + x)*(7.89575131106459 + (-5.54858377035486 + x)*x)
891
#define BSPL6D2(ret, TT, t, x)                                          \
892
  if (x < 0.5) {                                                        \
893
    ret = AIR_CAST(TT, BSPL6D2_SEG0(x));                                \
894
  } else if (x < 1.5) {                                                 \
895
    ret = AIR_CAST(TT, BSPL6D2_SEG1(x));                                \
896
  } else if (x < 2.5) {                                                 \
897
    ret = AIR_CAST(TT, BSPL6D2_SEG2(x));                                \
898
  } else if (x < 3.5) {                                                 \
899
    t = AIR_CAST(TT, 7.0 - 2.0*x);                                      \
900
    ret = AIR_CAST(TT, 0.0026041666666666666667*t*t*t*t);               \
901
  } else {                                                              \
902
    ret = 0;                                                            \
903
  }
904
905









4114332
BSPL_EVEN_METHODS(_bspl6d2, BSPL6D2)
906
907
static NrrdKernel
908
_nrrdKernelBSpline6DD = {
909
  "bspl6dd",
910
  BSPL_DECL(6, 2)
911
};
912
NrrdKernel *const
913
nrrdKernelBSpline6DD = &_nrrdKernelBSpline6DD;
914
915
/* ---------------------- order *6* deriv *3* -------------------------- */
916
917
#define BSPL6D3(ret, TT, t, x)                                          \
918
  if (x < 0.5) {                                                        \
919
    ret = AIR_CAST(TT, x*(3.5 - 3.3333333333333333333*x*x));            \
920
  } else if (x < 1.5) {                                                 \
921
    ret = AIR_CAST(TT, 2.5*(-1.99263608511781188 + x)*(-1.40303873392913616 + x)*(-0.104325180953051958 + x)); \
922
  } else if (x < 2.5) {                                                 \
923
    ret = AIR_CAST(TT, -1*(-1.404627184534107 + x)*(7.890587235793465 + (-5.595372815465893 + x)*x)); \
924
  } else if (x < 3.5) {                                                 \
925
    t = AIR_CAST(TT, -7 + 2*x);                                         \
926
    ret = AIR_CAST(TT, 0.020833333333333333333*t*t*t);                  \
927
  } else {                                                              \
928
    ret = 0.0;                                                          \
929
  }
930
931











3462917
BSPL_ODD_METHODS(_bspl6d3, BSPL6D3)
932
933
static NrrdKernel
934
_nrrdKernelBSpline6DDD = {
935
  "bspl6ddd",
936
  BSPL_DECL(6, 3)
937
};
938
NrrdKernel *const
939
nrrdKernelBSpline6DDD = &_nrrdKernelBSpline6DDD;
940
941
/* ============================= order *7* ============================= */
942
943
static double
944
_bspl7_sup(const double *parm) {
945
  AIR_UNUSED(parm);
946
8
  return 4.0;
947
}
948
949
/* ---------------------- order *7* deriv *0* -------------------------- */
950
951
#define BSPL7D0(ret, TT, t, x)                                          \
952
  if (x < 1) {                                                          \
953
    ret = AIR_CAST(TT, 151.0/315.0 + x*x*(-48.0 + x*x*(16.0 + x*x*(-4 + x)))/144.0); \
954
  } else if (x < 2) {                                                   \
955
    ret = AIR_CAST(TT, (2472 - 7*x*(56 + x*(72 + x*(280 + 3*(-6 + x)*x*(20 + (-6 + x)*x)))))/5040.0); \
956
  } else if (x < 3) {                                                   \
957
    ret = AIR_CAST(TT, (-1112 + 7*x*(1736 + x*(-2760 + x*(1960 + x*(-760 + x*(168 + (-20 + x)*x))))))/5040.0); \
958
  } else if (x < 4) {                                                   \
959
    t = x - 4;                                                          \
960
    ret = AIR_CAST(TT, -t*t*t*t*t*t*t/5040);                            \
961
  } else {                                                              \
962
    ret = 0;                                                            \
963
  }
964
965









3960044
BSPL_EVEN_METHODS(_bspl7d0, BSPL7D0)
966
967
static NrrdKernel
968
_nrrdKernelBSpline7 = {
969
  "bspl7",
970
  BSPL_DECL(7, 0)
971
};
972
NrrdKernel *const
973
nrrdKernelBSpline7 = &_nrrdKernelBSpline7;
974
975
/* ---------------------- order *7* deriv *1* -------------------------- */
976
977
#define BSPL7D1(ret, TT, t, x)                                          \
978
  if (x < 1) {                                                          \
979
    ret = AIR_CAST(TT, x*(-96.0 + x*x*(64.0 + x*x*(-24.0 + 7.0*x)))/144.0); \
980
  } else if (x < 2) {                                                   \
981
    ret = AIR_CAST(TT, -7.0/90.0 - (-2 + x)*x*(-24 + (-2 + x)*x*(76 + x*(-44 + 7*x)))/240.0); \
982
  } else if (x < 3) {                                                   \
983
    ret = AIR_CAST(TT, (2 + (-4 + x)*x)*(868 + x*(-1024 + x*(458 + x*(-92 + 7*x))))/720.0); \
984
  } else if (x < 4) {                                                   \
985
    t = -4 + x;                                                         \
986
    ret = AIR_CAST(TT, -t*t*t*t*t*t/720);                               \
987
  } else {                                                              \
988
    ret = 0.0;                                                          \
989
  }
990
991











5040053
BSPL_ODD_METHODS(_bspl7d1, BSPL7D1)
992
993
static NrrdKernel
994
_nrrdKernelBSpline7D = {
995
  "bspl7d",
996
  BSPL_DECL(7, 1)
997
};
998
NrrdKernel *const
999
nrrdKernelBSpline7D = &_nrrdKernelBSpline7D;
1000
1001
/* ---------------------- order *7* deriv *2* -------------------------- */
1002
1003
#define BSPL7D2(ret, TT, t, x)                                          \
1004
  if (x < 1) {                                                          \
1005
    ret = AIR_CAST(TT, (-16.0 + x*x*(32 + x*x*(-20 + 7*x)))/24.0);      \
1006
  } else if (x < 2) {                                                   \
1007
    ret = AIR_CAST(TT, -1.0/5.0 - 7*x/3 + 6*x*x - 14*x*x*x/3 + 3*x*x*x*x/2 - 7*x*x*x*x*x/40); \
1008
  } else if (x < 3) {                                                   \
1009
    ret = AIR_CAST(TT, (-920 + x*(1960 + x*(-1520 + x*(560 + x*(-100 + 7*x)))))/120.0); \
1010
  } else if (x < 4) {                                                   \
1011
    t = -4 + x;                                                         \
1012
    ret = AIR_CAST(TT, -t*t*t*t*t/120);                                 \
1013
  } else {                                                              \
1014
    ret = 0;                                                            \
1015
  }
1016
1017









3960044
BSPL_EVEN_METHODS(_bspl7d2, BSPL7D2)
1018
1019
static NrrdKernel
1020
_nrrdKernelBSpline7DD = {
1021
  "bspl7dd",
1022
  BSPL_DECL(7, 2)
1023
};
1024
NrrdKernel *const
1025
nrrdKernelBSpline7DD = &_nrrdKernelBSpline7DD;
1026
1027
/* ---------------------- order *7* deriv *3* -------------------------- */
1028
1029
#define BSPL7D3(ret, TT, t, x)                                          \
1030
  if (x < 1) {                                                          \
1031
    ret = AIR_CAST(TT, x*(64 + 5*x*x*(-16 + 7*x))/24);                  \
1032
  } else if (x < 2) {                                                   \
1033
    ret = AIR_CAST(TT, -7.0/3.0 + x*(12 + x*(-14 + x*(6 - 7*x/8))));    \
1034
  } else if (x < 3) {                                                   \
1035
    ret = AIR_CAST(TT, (392 + x*(-608 + x*(336 + x*(-80 + 7*x))))/24);  \
1036
  } else if (x < 4) {                                                   \
1037
    t = -4 + x;                                                         \
1038
    ret = AIR_CAST(TT, -t*t*t*t/24);                                    \
1039
  } else {                                                              \
1040
    ret = 0.0;                                                          \
1041
  }
1042
1043











3360053
BSPL_ODD_METHODS(_bspl7d3, BSPL7D3)
1044
1045
static NrrdKernel
1046
_nrrdKernelBSpline7DDD = {
1047
  "bspl7ddd",
1048
  BSPL_DECL(7, 3)
1049
};
1050
NrrdKernel *const
1051
nrrdKernelBSpline7DDD = &_nrrdKernelBSpline7DDD;
1052
1053
/* ------------- order *7* approximate numerical inverse -------------- */
1054
1055
#define BSPL7_AI_LEN 26
1056
static double
1057
_bspl7_ANI_kvals[BSPL7_AI_LEN] = {
1058
  4.964732886301469059137801,
1059
  -3.091042499769118182213297,
1060
  1.707958936669135515487259,
1061
  -0.9207818274511302808978934,
1062
  0.4936786139601599067344824,
1063
  -0.2643548049418435742509870,
1064
  0.1415160014538524997926456,
1065
  -0.07575222270391683956827192,
1066
  0.04054886334181815702759984,
1067
  -0.02170503519322401084648773,
1068
  0.01161828326728242899507066,
1069
  -0.006219039932262414977444894,
1070
  0.003328930278070297807163008,
1071
  -0.001781910982713036390230280,
1072
  0.0009538216015244754251250379,
1073
  -0.0005105611456814427816916412,
1074
  0.0002732917233015012426069489,
1075
  -0.0001462845976614043380333786,
1076
  0.00007829746549013888268504229,
1077
  -0.00004190023413676309286922788,
1078
  0.00002240807576972098806040711,
1079
  -0.00001195669542335526044896263,
1080
  6.329480796176889498331054e-6,
1081
  -3.256910241436675950084186e-6,
1082
  1.506132735770447868981087e-6,
1083
  -4.260433183779953604188120e-7};
1084
1085
static double
1086
_bspl7_ANI_sup(const double *parm) {
1087
  AIR_UNUSED(parm);
1088
2
  return BSPL7_AI_LEN + 0.5;
1089
}
1090
1091
static double
1092
_bspl7_ANI_int(const double *parm) {
1093
  AIR_UNUSED(parm);
1094
2
  return 1.0;
1095
}
1096
1097
#define BSPL7_ANI(ret, tmp, x)                  \
1098
  tmp = AIR_CAST(unsigned int, x+0.5);          \
1099
  if (tmp < BSPL7_AI_LEN) {                     \
1100
    ret = _bspl7_ANI_kvals[tmp];                \
1101
  } else {                                      \
1102
    ret = 0.0;                                  \
1103
  }
1104
1105
static double
1106
_bspl7_ANI_1d(double x, const double *parm) {
1107
  double ax, r; unsigned int tmp;
1108
  AIR_UNUSED(parm);
1109
1110
240012
  ax = AIR_ABS(x);
1111
235478
  BSPL7_ANI(r, tmp, ax);
1112
120006
  return r;
1113
}
1114
1115
static float
1116
_bspl7_ANI_1f(float x, const double *parm) {
1117
  double ax, r; unsigned int tmp;
1118
  AIR_UNUSED(parm);
1119
1120
240000
  ax = AIR_ABS(x);
1121
235472
  BSPL7_ANI(r, tmp, ax);
1122
120000
  return AIR_CAST(float, r);
1123
}
1124
1125
static void
1126
_bspl7_ANI_Nd(double *f, const double *x, size_t len, const double *parm) {
1127
  double ax, r; unsigned int tmp;
1128
  size_t i;
1129
  AIR_UNUSED(parm);
1130
1131
240003
  for (i=0; i<len; i++) {
1132
120000
    ax = x[i]; ax = AIR_ABS(ax);
1133
235472
    BSPL7_ANI(r, tmp, ax);
1134
120000
    f[i] = r;
1135
  }
1136
1
}
1137
1138
static void
1139
_bspl7_ANI_Nf(float *f, const float *x, size_t len, const double *parm) {
1140
  double ax, r; unsigned int tmp;
1141
  size_t i;
1142
  AIR_UNUSED(parm);
1143
1144
240003
  for (i=0; i<len; i++) {
1145
120000
    ax = x[i]; ax = AIR_ABS(ax);
1146
235472
    BSPL7_ANI(r, tmp, ax);
1147
120000
    f[i] = AIR_CAST(float, r);
1148
  }
1149
1
}
1150
1151
static NrrdKernel
1152
_nrrdKernelBSpline7ApproxInverse = {
1153
  "bspl7ai", 0,
1154
  _bspl7_ANI_sup, _bspl7_ANI_int,
1155
  _bspl7_ANI_1f, _bspl7_ANI_Nf,
1156
  _bspl7_ANI_1d, _bspl7_ANI_Nd
1157
};
1158
NrrdKernel *const
1159
nrrdKernelBSpline7ApproxInverse = &_nrrdKernelBSpline7ApproxInverse;
1160