GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: src/air/math.c Lines: 172 398 43.2 %
Date: 2017-05-26 Branches: 76 168 45.2 %

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
25
#include "air.h"
26
27
/*
28
** by the way, the organization of functions into files is a little
29
** arbitrary around here
30
*/
31
32
/*
33
** from: Gavin C Cawley, "On a Fast, Compact Approximation of the
34
** Exponential Function" Neural Computation, 2000, 12(9), 2009-2012.
35
**
36
** which in turn is based on: N N Schraudolph, "A fast, compact approximation
37
** of the exponential function." Neural Computation, 1999, 11(4), 853-862.
38
** http://cnl.salk.edu/~schraudo/pubs/Schraudolph99.pdf
39
**
40
** some possible code which does not depend on endian
41
** http://www.machinedlearnings.com/2011/06/fast-approximate-logarithm-exponential.html
42
*/
43
44
typedef union {
45
  double dd;
46
  int nn[2];
47
} eco_t;
48
49
#define EXPA (1048576/0.69314718055994530942)
50
#define EXPC 60801
51
double
52
airFastExp(double val) {
53
  eco_t eco;
54
  double ret;
55
  int tmpI, EXPI;
56
57
  /* HEY: COPY AND PASTE from airMyEndian */
58
  tmpI = 1;
59
  EXPI = *(AIR_CAST(char*, &tmpI));
60
  eco.nn[EXPI] = AIR_CAST(int, (EXPA*(val)) + (1072693248 - EXPC));
61
  eco.nn[1-EXPI] = 0;
62
  ret = (eco.dd > 0.0
63
         ? eco.dd
64
         /* seems that only times this happens is when the real exp()
65
            returns either 0 or +inf */
66
         : (val < 0 ? 0 : AIR_POS_INF));
67
  return ret;
68
}
69
#undef EXPA
70
#undef EXPC
71
72
/*
73
** based on MiniMaxApproximation, but this has failed in its goal
74
** of being faster than libc's exp(), so should be considered
75
** a work-in-progress
76
*/
77
double
78
airExp(double x) {
79
  double num, den, ee;
80
  unsigned int pp;
81
82
  if (AIR_IN_CL(-1, x, 1)) {
83
    num = 1 + x*(0.500241 + x*(0.107193 + (0.0118938 + 0.000591457*x)*x));
84
    den = 1 + x*(-0.499759 + x*(0.106952 + (-0.0118456 + 0.000587495*x)*x));
85
    ee = num/den;
86
  } else if (x > 1) {
87
    pp = 0;
88
    while (x > 2) {
89
      x /= 2;
90
      pp += 1;
91
    }
92
    num = 1 + x*(0.552853 + x*(0.135772 + (0.0183685 + 0.00130944*x)*x));
93
    den = 1 + x*(-0.44714 + x*(0.0828937 + (-0.00759541 + 0.000291662*x)*x));
94
    ee = num/den;
95
    while (pp) {
96
      ee *= ee;
97
      pp -= 1;
98
    }
99
  } else if (x < -1) {
100
    pp = 0;
101
    while (x < -2) {
102
      x /= 2;
103
      pp += 1;
104
    }
105
    num = 0.999999+x*(0.44726+x*(0.0829439 + (0.00760326 + 0.000292122*x)*x));
106
    den = 1 + x*(-0.552732 + x*(0.135702 + (-0.0183511 + 0.00130689*x)*x));
107
    ee = num/den;
108
    while (pp) {
109
      ee *= ee;
110
      pp -= 1;
111
    }
112
  } else {
113
    /* x is probably not finite */
114
    ee = exp(x);
115
  }
116
  return ee;
117
}
118
119
/*
120
******** airNormalRand
121
**
122
** generates two numbers with normal distribution (mean 0, stdv 1)
123
** using the Box-Muller transform.
124
**
125
** on (seemingly sound) advice of
126
** <http://www.taygeta.com/random/gaussian.html>,
127
** I'm using the polar form of the Box-Muller transform, instead of the
128
** Cartesian one described at
129
** <http://mathworld.wolfram.com/Box-MullerTransformation.html>
130
**
131
** this is careful to not write into given NULL pointers
132
*/
133
void
134
airNormalRand(double *z1, double *z2) {
135
  double w, x1, x2;
136
137
11084580
  do {
138
7057819
    x1 = 2*airDrandMT() - 1;
139
7057819
    x2 = 2*airDrandMT() - 1;
140
7057819
    w = x1*x1 + x2*x2;
141
7057819
  } while ( w >= 1 );
142
5542290
  w = sqrt((-2*log(w))/w);
143
5542290
  if (z1) {
144
5532290
    *z1 = x1*w;
145
5532290
  }
146
5542290
  if (z2) {
147
84050
    *z2 = x2*w;
148
84050
  }
149
  return;
150
5542290
}
151
152
void
153
airNormalRand_r(double *z1, double *z2, airRandMTState *state) {
154
  double w, x1, x2;
155
156
10532
  do {
157
6713
    x1 = 2*airDrandMT_r(state) - 1;
158
6713
    x2 = 2*airDrandMT_r(state) - 1;
159
6713
    w = x1*x1 + x2*x2;
160
6713
  } while ( w >= 1 );
161
5266
  w = sqrt((-2*log(w))/w);
162
5266
  if (z1) {
163
5266
    *z1 = x1*w;
164
5266
  }
165
5266
  if (z2) {
166
3389
    *z2 = x2*w;
167
3389
  }
168
  return;
169
5266
}
170
171
/*
172
******** airShuffle()
173
**
174
** generates a random permutation of integers [0..N-1] if perm is non-zero,
175
** otherwise, just fills buff with [0..N-1] in order
176
**
177
** see http://en.wikipedia.org/wiki/Knuth_shuffle
178
*/
179
void
180
airShuffle(unsigned int *buff, unsigned int N, int perm) {
181
  unsigned int i;
182
183
  if (!(buff && N > 0)) {
184
    return;
185
  }
186
187
  for (i=0; i<N; i++) {
188
    buff[i] = i;
189
  }
190
  if (perm) {
191
    unsigned int swp, tmp;
192
    while (N > 1) {
193
      swp = airRandInt(N);
194
      N--;
195
      tmp = buff[N];
196
      buff[N] = buff[swp];
197
      buff[swp] = tmp;
198
    }
199
  }
200
}
201
202
void
203
airShuffle_r(airRandMTState *state,
204
             unsigned int *buff, unsigned int N, int perm) {
205
  unsigned int i;
206
207
  /* HEY !!! COPY AND PASTE !!!! */
208
  if (!(buff && N > 0)) {
209
    return;
210
  }
211
212
  for (i=0; i<N; i++) {
213
    buff[i] = i;
214
  }
215
  if (perm) {
216
    unsigned int swp, tmp;
217
    while (N > 1) {
218
      swp = airRandInt_r(state, N);
219
      N--;
220
      tmp = buff[N];
221
      buff[N] = buff[swp];
222
      buff[swp] = tmp;
223
    }
224
  }
225
  /* HEY !!! COPY AND PASTE !!!! */
226
}
227
228
double
229
airSgnPow(double v, double p) {
230
231
  return (p == 1
232
          ? v
233
          : (v >= 0
234
             ? pow(v, p)
235
             : -pow(-v, p)));
236
}
237
238
double
239
airFlippedSgnPow(double vv, double pp) {
240
  double sn=1.0;
241
242
  if (1.0 == pp) {
243
    return vv;
244
  }
245
  if (vv < 0) {
246
    sn = -1.0;
247
    vv = -vv;
248
  }
249
  return sn*(1.0 - pow(1.0 - AIR_MIN(1.0, vv), pp));
250
}
251
252
double
253
airIntPow(double v, int p) {
254
  double sq, ret;
255
256
2064960
  if (p > 0) {
257
    sq = v;
258
3438720
    while (!(p & 1)) {
259
      /* while the low bit is zero */
260
686880
      p >>= 1;
261
686880
      sq *= sq;
262
    }
263
    /* must terminate because we know p != 0, and when
264
       it terminates we know that the low bit is 1 */
265
    ret = sq;
266
2064960
    while (p >>= 1) {
267
      /* while there are any non-zero bits in p left */
268
      sq *= sq;
269
      if (p & 1) {
270
        ret *= sq;
271
      }
272
    }
273
  } else if (p < 0) {
274
    ret = airIntPow(1.0/v, -p);
275
  } else {
276
    ret = 1.0;
277
  }
278
279
1032480
  return ret;
280
}
281
282
/*
283
******** airLog2()
284
**
285
** silly little function which returns log_2(n) if n is exactly a power of 2,
286
** and -1 otherwise
287
*/
288
int
289
airLog2(size_t _nn) {
290
  size_t nn;
291
  int ret;
292
293
  nn = _nn;
294
122
  if (0 == nn) {
295
    /* 0 is not a power of 2 */
296
    ret = -1;
297
  } else {
298
    int alog = 0;
299
    /* divide by 2 while its non-zero and the low bit is off */
300

1578
    while (!!nn && !(nn & 1)) {
301
465
      alog += 1;
302
465
      nn /= 2;
303
    }
304
61
    if (1 == nn) {
305
      ret = alog;
306
31
    } else {
307
      ret = -1;
308
    }
309
  }
310
61
  return ret;
311
}
312
313
int
314
airSgn(double v) {
315
630
  return (v > 0
316
          ? 1
317
90
          : (v < 0
318
             ? -1
319
             : 0));
320
}
321
322
/*
323
******** airCbrt
324
**
325
** cbrt() isn't in C89, so any hacks to create a stand-in for cbrt()
326
** are done here.
327
*/
328
double
329
airCbrt(double v) {
330
#if defined(_WIN32) || defined(__STRICT_ANSI__)
331
  return (v < 0.0 ? -pow(-v,1.0/3.0) : pow(v,1.0/3.0));
332
#else
333
8000
  return cbrt(v);
334
#endif
335
}
336
337
/*
338
** skewness of three numbers, scaled to fit in [-1,+1]
339
** -1: small, big, big
340
** +1: small, small, big
341
*/
342
double
343
airMode3_d(const double _v[3]) {
344
  double num, den, mean, v[3];
345
346
  mean = (_v[0] + _v[1] + _v[2])/3;
347
  v[0] = _v[0] - mean;
348
  v[1] = _v[1] - mean;
349
  v[2] = _v[2] - mean;
350
  num = (v[0] + v[1] - 2*v[2])*(2*v[0] - v[1] - v[2])*(v[0] - 2*v[1] + v[2]);
351
  den = v[0]*v[0] + v[1]*v[1] + v[2]*v[2] - v[1]*v[2] - v[0]*v[1] - v[0]*v[2];
352
  den = sqrt(den);
353
  return (den ? num/(2*den*den*den) : 0);
354
}
355
356
double
357
airMode3(double v0, double v1, double v2) {
358
  double v[3];
359
360
  v[0] = v0;
361
  v[1] = v1;
362
  v[2] = v2;
363
  return airMode3_d(v);
364
}
365
366
double
367
airGaussian(double x, double mean, double stdv) {
368
369
  x = x - mean;
370
  return exp(-(x*x)/(2*stdv*stdv))/(stdv*sqrt(2*AIR_PI));
371
}
372
373
/*
374
** The function approximations below were done by GLK in Mathematica,
375
** using its MiniMaxApproximation[] function.  The functional forms
376
** used for the Bessel functions were copied from Numerical Recipes
377
** (which were in turn copied from the "Handbook of Mathematical
378
** Functions with Formulas, Graphs, and Mathematical Tables" by
379
** Abramowitz and Stegun), but the coefficients here represent
380
** an increase in accuracy.
381
**
382
** The rational functions (crudely copy/paste from Mathematica into
383
** this file) upon which the approximations are based have a relative
384
** error of less than 10^-9, at least on the intervals on which they
385
** were created (in the case of the second branch of the
386
** approximation, the lower end of the interval was chosen as close to
387
** zero as possible). The relative error of the total approximation
388
** may be greater.
389
*/
390
391
double
392
airErfc(double x) {
393
  double ax, y, b;
394
395
1560110
  ax = AIR_ABS(x);
396
780055
  if (ax < 0.9820789566638689) {
397
94640
    b = (0.9999999999995380997 + ax*(-1.0198241793287349401 +
398
94640
        ax*(0.37030717279808919457 + ax*(-0.15987839763633308864 +
399
189280
        ax*(0.12416682580357861661 + (-0.04829622197742573233 +
400
283920
        0.0066094852952188890901*ax)*ax)))))/
401
94640
        (1 + ax*(0.1085549876246959456 + ax*(0.49279836663925410323 +
402
94640
        ax*(0.020058474597886988472 + ax*(0.10597158000597863862 +
403
94640
        (-0.0012466514192679810876 + 0.0099475501252703646772*ax)*ax)))));
404
780055
  } else if (ax < 2.020104167011169) {
405
101331
    y = ax - 1;
406
101331
    b = (0.15729920705029613528 + y*(-0.37677358667097191131 +
407
101331
        y*(0.3881956571123873123 + y*(-0.22055886537359936478 +
408
202662
        y*(0.073002666454740425451 + (-0.013369369366972563804 +
409
303993
        0.0010602024397541548717*y)*y)))))/
410
101331
        (1 + y*(0.243700597525225235 + y*(0.47203101881562848941 +
411
101331
        y*(0.080051054975943863026 + y*(0.083879049958465759886 +
412
101331
        (0.0076905426306038205308 + 0.0058528196473365970129*y)*y)))));
413
101331
  } else {
414
584084
    y = 2/ax;
415
584084
    b = (-2.7460876468061399519e-14 + y*(0.28209479188874503125 +
416
584084
        y*(0.54260398586720212019 + y*(0.68145162781305697748 +
417
1168168
        (0.44324741856237800393 + 0.13869182273440856508*y)*y))))/
418
584084
        (1 + y*(1.9234811027995435174 + y*(2.5406810534399069812 +
419
1168168
        y*(1.8117409273494093139 + (0.76205066033991530997 +
420
1168168
        0.13794679143736608167*y)*y))));
421
584084
    b *= exp(-x*x);
422
  }
423
780055
  if (x < 0) {
424
322496
    b = 2-b;
425
322496
  }
426
780055
  return b;
427
}
428
429
double
430
airErf(double x) {
431
1560110
  return 1.0 - airErfc(x);
432
}
433
434
/*
435
******** airBesselI0
436
**
437
** modified Bessel function of the first kind, order 0
438
*/
439
double
440
airBesselI0(double x) {
441
  double b, ax, y;
442
443
  ax = AIR_ABS(x);
444
  if (ax < 5.664804810929075) {
445
    y = x/5.7;
446
    y *= y;
447
    b = (0.9999999996966272 + y*(7.7095783675529646 +
448
        y*(13.211021909077445 + y*(8.648398832703904 +
449
        (2.5427099920536578 + 0.3103650754941674*y)*y))))/
450
        (1 + y*(-0.41292170755003793 + (0.07122966874756179
451
        - 0.005182728492608365*y)*y));
452
  } else {
453
    y = 5.7/ax;
454
    b = (0.398942280546057 + y*(-0.749709626164583 +
455
        y*(0.507462772839054 + y*(-0.0918770649691261 +
456
        (-0.00135238228377743 - 0.0000897561853670307*y)*y))))/
457
        (1 + y*(-1.90117313211089 + (1.31154807540649
458
        - 0.255339661975509*y)*y));
459
    b *= (exp(ax)/sqrt(ax));
460
  }
461
  return b;
462
}
463
464
/*
465
******** airBesselI0ExpScaled
466
**
467
** modified Bessel function of the first kind, order 0,
468
** scaled by exp(-abs(x)).
469
*/
470
double
471
airBesselI0ExpScaled(double x) {
472
  double b, ax, y;
473
474
4318780
  ax = AIR_ABS(x);
475
2159390
  if (ax < 5.664804810929075) {
476
2159390
    y = x/5.7;
477
2159390
    y *= y;
478
2159390
    b = (0.9999999996966272 + y*(7.7095783675529646 +
479
2159390
        y*(13.211021909077445 + y*(8.648398832703904 +
480
4318780
        (2.5427099920536578 + 0.3103650754941674*y)*y))))/
481
2159390
        (1 + y*(-0.41292170755003793 + (0.07122966874756179
482
2159390
        - 0.005182728492608365*y)*y));
483
2159390
    b *= exp(-ax);
484
2159390
  } else {
485
    y = 5.7/ax;
486
    b = (0.398942280546057 + y*(-0.749709626164583 +
487
        y*(0.507462772839054 + y*(-0.0918770649691261 +
488
        (-0.00135238228377743 - 0.0000897561853670307*y)*y))))/
489
        (1 + y*(-1.90117313211089 + (1.31154807540649
490
        - 0.255339661975509*y)*y));
491
    b *= (1/sqrt(ax));
492
  }
493
2159390
  return b;
494
}
495
496
497
/*
498
******** airBesselI1
499
**
500
** modified Bessel function of the first kind, order 1
501
*/
502
double
503
airBesselI1(double x) {
504
  double b, ax, y;
505
506
  ax = AIR_ABS(x);
507
  if (ax < 6.449305566387246) {
508
    y = x/6.45;
509
    y *= y;
510
    b = ax*(0.4999999998235554 + y*(2.370331499358438 +
511
        y*(3.3554331305863787 + y*(2.0569974969268707 +
512
        (0.6092719473097832 + 0.0792323006694466*y)*y))))/
513
        (1 + y*(-0.4596495788370524 + (0.08677361454866868 \
514
        - 0.006777712190188699*y)*y));
515
  } else {
516
    y = 6.45/ax;
517
    b = (0.398942280267484 + y*(-0.669339325353065 +
518
        y*(0.40311772245257 + y*(-0.0766281832045885 +
519
        (0.00248933264397244 + 0.0000703849046144657*y)*y))))/
520
        (1 + y*(-1.61964537617937 + (0.919118239717915 -
521
        0.142824922601647*y)*y));
522
    b *= exp(ax)/sqrt(ax);
523
  }
524
  return x < 0.0 ? -b : b;
525
}
526
527
/*
528
******** airBesselI1ExpScaled
529
**
530
** modified Bessel function of the first kind, order 1,
531
** scaled by exp(-abs(x))
532
*/
533
double
534
airBesselI1ExpScaled(double x) {
535
  double b, ax, y;
536
537
1441352
  ax = AIR_ABS(x);
538
720676
  if (ax < 6.449305566387246) {
539
720676
    y = x/6.45;
540
720676
    y *= y;
541
720676
    b = ax*(0.4999999998235554 + y*(2.370331499358438 +
542
720676
        y*(3.3554331305863787 + y*(2.0569974969268707 +
543
1441352
        (0.6092719473097832 + 0.0792323006694466*y)*y))))/
544
720676
        (1 + y*(-0.4596495788370524 + (0.08677361454866868 \
545
720676
        - 0.006777712190188699*y)*y));
546
720676
    b *= exp(-ax);
547
720676
  } else {
548
    y = 6.45/ax;
549
    b = (0.398942280267484 + y*(-0.669339325353065 +
550
        y*(0.40311772245257 + y*(-0.0766281832045885 +
551
        (0.00248933264397244 + 0.0000703849046144657*y)*y))))/
552
        (1 + y*(-1.61964537617937 + (0.919118239717915 -
553
        0.142824922601647*y)*y));
554
    b *= 1/sqrt(ax);
555
  }
556
720676
  return x < 0.0 ? -b : b;
557
}
558
559
/*
560
******** airLogBesselI0
561
**
562
** natural logarithm of airBesselI0
563
*/
564
double
565
airLogBesselI0(double x) {
566
  double b, ax, y;
567
568
  ax = AIR_ABS(x);
569
  if (ax < 4.985769687853781) {
570
    y = x/5.0;
571
    y *= y;
572
    b = (5.86105592521167098e-27 + y*(6.2499999970669017 +
573
        y*(41.1327842713925212 + y*(80.9030404787605539 +
574
        y*(50.7576267390706893 + 6.88231907401413133*y)))))/
575
        (1 + y*(8.14374525361325784 + y*(21.3288286560361152 +
576
        y*(20.0880670952325953 + (5.5138982784800139 +
577
        0.186784275148079847*y)*y))));
578
  } else {
579
    y = 5.0/ax;
580
    b = (-0.91893853280169872884 + y*(2.7513907055333657679 +
581
        y*(-3.369024122613176551 + y*(1.9164545708124343838 +
582
        (-0.46136261965797010108 + 0.029092365715948197066*y)*y))))/
583
        (1 + y*(-2.9668913151685312745 + y*(3.5882191453626541066 +
584
        y*(-1.9954040017063882247 + (0.45606687718126481603 -
585
        0.0231678041994100784*y)*y))));
586
    b += ax - log(ax)/2;
587
  }
588
  return b;
589
}
590
591
/*
592
******** airLogRician
593
**
594
** natural logarithm of Rician distribution
595
** mes is measured value
596
** tru is "true" underlying value
597
** sig is sigma of 2-D Gaussian
598
*/
599
double
600
airLogRician(double mes, double tru, double sig) {
601
  double lb, ss;
602
603
  ss = sig*sig;
604
  lb = airLogBesselI0(mes*tru/ss);
605
  return lb + log(mes/ss) - (mes*mes + tru*tru)/(2*ss);
606
}
607
608
double
609
airRician(double mes, double tru, double sig) {
610
  return exp(airLogRician(mes, tru, sig));
611
}
612
613
/*
614
******** airBesselI1By0
615
**
616
** the quotient airBesselI1(x)/airBesselI0(x)
617
*/
618
double
619
airBesselI1By0(double x) {
620
  double q, ax, y;
621
622
  ax = AIR_ABS(x);
623
  if (ax < 2.2000207427754046) {
624
    y = ax/2.2;
625
    q = (1.109010375603908e-29 + y*(1.0999999994454934 +
626
        y*(0.05256560007682146 + y*(0.3835178789165919 +
627
        (0.011328636410807382 + 0.009066934622942833*y)*y))))/
628
        (1 + y*(0.047786822784523904 + y*(0.9536550439261017 +
629
        (0.03918380275938573 + 0.09730715527121027*y)*y)));
630
  } else if (ax < 5.888258985638512) {
631
    y = (ax-2.2)/3.68;
632
    q = (0.7280299135046744 + y*(2.5697382341657002 +
633
        y*(3.69819451510548 + y*(3.131374238190916 +
634
        (1.2811958061688737 + 0.003601218043466571*y)*y))))/
635
        (1 + y*(2.8268553393021527 + y*(4.164742157157812 +
636
        y*(3.2377768820326756 + 1.3051900460060342*y))));
637
  } else {
638
    y = 5.88/ax;
639
    q = (1.000000000646262020372530870790956088593 +
640
         y*(-2.012513842496824157039372120680781513697 +
641
         y*(1.511644590219033259220408231325838531123 +
642
         (-0.3966391319921114140077576390415605232003 +
643
         0.02651815520696779849352690755529178056941*y)*y)))/
644
         (1 + y*(-1.927479858946526082413004924812844224781 +
645
         y*(1.351359456116228102988125069310621733956 +
646
         (-0.288087717540546638165144937495654019162 +
647
         0.005906535730887518966127383058238522133819*y)*y)));
648
  }
649
  return x < 0.0 ? -q : q;
650
}
651
652
/*
653
******** airBesselIn
654
**
655
** modified Bessel function of the first kind, order n.
656
**
657
*/
658
double
659
airBesselIn(int nn, double xx) {
660
  double tax, bb, bi, bim, bip;
661
  int ii, an, top;
662
663
  an = AIR_ABS(nn);
664
  if (0 == an) {
665
    return airBesselI0(xx);
666
  } else if (1 == an) {
667
    return airBesselI1(xx);
668
  }
669
670
  if (0.0 == xx) {
671
    return 0.0;
672
  }
673
674
  tax = 2.0/AIR_ABS(xx);
675
  bip = bb = 0.0;
676
  bi = 1.0;
677
  top = 2*(an + AIR_CAST(int, sqrt(40.0*an)));
678
  for (ii=top; ii > 0; ii--) {
679
    bim = bip + ii*tax*bi;
680
    bip = bi;
681
    bi = bim;
682
    if (AIR_ABS(bi) > 1.0e10) {
683
      bb *= 1.0e-10;
684
      bi *= 1.0e-10;
685
      bip*= 1.0e-10;
686
    }
687
    if (ii == an) {
688
      bb = bip;
689
    }
690
  }
691
  bb *= airBesselI0(xx)/bi;
692
  return (xx < 0.0 ? -bb : bb);
693
}
694
695
/*
696
******** airBesselInExpScaled
697
**
698
** modified Bessel function of the first kind, order n,
699
** scaled by exp(-abs(x))
700
**
701
*/
702
double
703
airBesselInExpScaled(int nn, double xx) {
704
  double tax, bb, bi, bim, bip, eps;
705
  int top, ii, an;
706
707
5760132
  an = AIR_ABS(nn);
708
2880066
  if (0 == an) {
709
360334
    return airBesselI0ExpScaled(xx);
710
2519732
  } else if (1 == an) {
711
720676
    return airBesselI1ExpScaled(xx);
712
  }
713
714
1799056
  if (0 == xx) {
715
    return 0.0;
716
  }
717
718
1799056
  tax = 2.0/AIR_ABS(xx);
719
  bip = bb = 0.0;
720
  bi = 1.0;
721
  /* HEY: GLK tried to increase sqrt(40.0*an) to sqrt(100.0*an) to avoid
722
     jagged discontinuities in (e.g.) airBesselInExpScaled(n, 17*17); the
723
     problem was detected because of glitches in the highest blurring
724
     levels for scale-space feature detection; but that didn't quite
725
     work either; this will have to be debugged further! */
726
1799056
  top = 2*(an + AIR_CAST(int, sqrt(40.0*an)));
727
  eps = 1.0e-10;
728
113254144
  for (ii=top; ii > 0; ii--) {
729
54828016
    bim = bip + ii*tax*bi;
730
    bip = bi;
731
    bi = bim;
732
54828016
    if (AIR_ABS(bi) > 1.0/eps) {
733
6297098
      bb *= eps;
734
6297098
      bi *= eps;
735
6297098
      bip*= eps;
736
6297098
    }
737
54828016
    if (ii == an) {
738
      bb = bip;
739
1799056
    }
740
  }
741
1799056
  bb *= airBesselI0ExpScaled(xx)/bi;
742
1799056
  return (xx < 0.0 ? -bb : bb);
743
2880066
}
744
745
/*
746
** based on: T. Lindeberg. "Effective Scale: A Natural Unit For
747
** Measuring Scale-Space Lifetime" IEEE PAMI, 15:1068-1074 (1993)
748
**
749
** which includes tau(tee) as equation (29),
750
** here taking A'' == 0 and B'' == 1, with
751
** a0 and a1 as defined by eqs (22) and (23)
752
**
753
** Used MiniMaxApproximation[] from Mathematica (see
754
** ~gk/papers/ssp/nb/effective-scale-TauOfTee.nb) to get functions,
755
** but the specific functions and their domains could certainly be
756
** improved upon.  Also, the absence of conversions directly between
757
** tau and sigma is quite unfortunate: going through tee loses
758
** precision and takes more time.
759
**
760
** ACCURATE: can set this to 0 or 1:
761
** 0: use a quick-and-dirty approximation to tau(tee), which
762
** uses a straight line segment for small scales, and then
763
** has a C^1-continuous transition to the large-scale approximation eq (33)
764
** 1: careful approximation based on the MiniMaxApproximation[]s
765
*/
766
#define ACCURATE 1
767
double
768
airTauOfTime(double tee) {
769
  double tau;
770
771
12
  if (tee < 0) {
772
    tau = 0;
773
#if ACCURATE
774
6
  } else if (tee < 1.49807) {
775
    /* mmtau0tweaked */
776
6
    tau = (tee*(0.2756644487429131 + tee*(0.10594329088466668 + tee*(0.05514331911165778 + (0.021449249669475232 + 0.004417835440932558*tee)*tee))))/
777
3
      (1.0 + tee*(-0.08684532328108877 + tee*(0.1792830876099199 + tee*(0.07468999631784223 + (0.012123550696192354 + 0.0021535864222409365*tee)*tee))));
778
6
  } else if (tee < 4.96757) {
779
    /* mmtau1 */
780
    tau = (0.0076145275813930356 + tee*(0.24811886965997867 + tee*(0.048329025380584194 +
781
                                                                   tee*(0.04227260554167517 + (0.0084221516844712 + 0.0092075782656669*tee)*tee))))/
782
      (1.0 + tee*(-0.43596678272093764 + tee*(0.38077975530585234 + tee*(-0.049133766853683175 + (0.030319379462443567 + 0.0034126333151669654*tee)*tee))));
783
3
  } else if (tee < 15.4583) {
784
    /* mmtau2 */
785
    tau = (-0.2897145176074084 + tee*(1.3527948686285203 + tee*(-0.47099157589904095 +
786
           tee*(-0.16031981786376195 + (-0.004820970155881798 - 4.149777202275125e-6*tee)*tee))))/
787
      (1.0 + tee*(0.3662508612514773 + tee*(-0.5357849572367938 + (-0.0805122462310566 - 0.0015558889784971902*tee)*tee)));
788
3
  } else if (tee < 420.787) {
789
    /* mmtau3 */
790
6
    tau = (-4.2037874383990445e9 + tee*(2.838805157541766e9 + tee*(4.032410315406513e8 + tee*(5.392017876788518e6 + tee*(9135.49750298428 + tee)))))/
791
3
      (tee*(2.326563899563907e9 + tee*(1.6920560224321905e8 + tee*(1.613645012626063e6 + (2049.748257887103 + 0.1617034516398788*tee)*tee))));
792
#else /* quick and dirty approximation */
793
  } else if (tee < 1.3741310015234351) {
794
    tau = 0.600069568241882*tee/1.3741310015234351;
795
#endif
796
3
  } else {
797
    /* lindtau = eq (33) in paper */
798
    tau = 0.53653222368715360118 + log(tee)/2.0 + log(1.0 - 1.0/(8.0*tee));
799
  }
800
6
  return tau;
801
}
802
803
double
804
airTimeOfTau(double tau) {
805
  double tee;
806
807
  /* the number of branches here is not good; needs re-working */
808
26
  if (tau < 0) {
809
    tee = 0;
810
#if ACCURATE
811
  } else
812
13
    if (tau < 0.611262) {
813
    /* mmtee0tweaked */
814
8
    tee = (tau*(3.6275987317285265 + tau*(11.774700160760132 + tau*(4.52406587856803 + tau*(-14.125688866786549 + tau*(-0.725387283317479 + 3.5113122862478865*tau))))))/
815
4
      (1.0 + tau*(4.955066250765395 + tau*(4.6850073321973404 + tau*(-6.407987550661679 + tau*(-6.398430668865182 + 5.213709282093169*tau)))));
816
13
  } else if (tau < 1.31281) {
817
    /* mmtee1 */
818
6
    tee = (1.9887378739371435e49 + tau*(-2.681749984485673e50 + tau*(-4.23360463718195e50 + tau*(2.09694591123974e51 + tau*(-2.7561518523389087e51 + (1.661629137055526e51 - 4.471073383223687e50*tau)*tau)))))/
819
3
      (1.0 + tau*(-5.920734745050949e50 + tau*(1.580953446553531e51 + tau*(-1.799463907469813e51 + tau*(1.0766702953985062e51 + tau*(-3.57278667155516e50 + 5.008335824520649e49*tau))))));
820
9
  } else if (tau < 1.64767) {
821
    /* mmtee2 */
822
2
    tee = (7.929177830383403 + tau*(-26.12773195115971 + tau*(40.13296225515305 + tau*(-25.041659428733585 + 11.357596970027744*tau))))/
823
1
      (1.0 + tau*(-2.3694595653302377 + tau*(7.324354882915464 + (-3.5335141717471314 + 0.4916661013041915*tau)*tau)));
824
6
  } else if (tau < 1.88714) {
825
    /* mmtee3 */
826
2
    tee = (0.8334252264680793 + tau*(-0.2388940380698891 + (0.6057616935583752 - 0.01610044688317929*tau)*tau))/(1.0 + tau*(-0.7723301124908083 + (0.21283962841683607 - 0.020834957466407206*tau)*tau));
827
5
  } else if (tau < 2.23845) {
828
    /* mmtee4 */
829
1
    tee = (0.6376900379835665 + tau*(0.3177131886056259 + (0.1844114646774132 + 0.2001613331260136*tau)*tau))/(1.0 + tau*(-0.6685635461372561 + (0.15860524381878136 - 0.013304300252332686*tau)*tau));
830
3
  } else if (tau < 2.6065) {
831
    /* mmtee5 */
832
    tee = (1.3420027677612982 + (-0.939215712453483 + 0.9586140009249253*tau)*tau)/(1.0 + tau*(-0.6923014141351673 + (0.16834190074776287 - 0.014312833444962668*tau)*tau));
833
2
  } else if (tau < 3.14419) {
834
    /* mmtee6 */
835
2
    tee = (tau*(190.2181493338235 + tau*(-120.16652155353106 + 60.*tau)))/(76.13355144582292 + tau*(-42.019121363472614 + (8.023304636521623 - 0.5281725039404653*tau)*tau));
836
#else /* quick and dirty approximation */
837
  } else if (tau < 0.600069568241882) {
838
    tee = 1.3741310015234351*tau/0.600069568241882;
839
#endif
840
2
  } else {
841
    /* lindtee = lindtau^{-1} */
842
    double ee;
843
    ee = exp(2.0*tau);
844
    tee = 0.0063325739776461107152*(27.0*ee + 2*AIR_PI*AIR_PI + 3.0*sqrt(81.0*ee*ee + 12*ee*AIR_PI*AIR_PI));
845
  }
846
13
  return tee;
847
}
848
849
double
850
airSigmaOfTau(double tau) {
851
852
26
  return sqrt(airTimeOfTau(tau));
853
}
854
855
double
856
airTauOfSigma(double sig) {
857
858
12
  return airTauOfTime(sig*sig);
859
}
860
861
/*  http://en.wikipedia.org/wiki/Halton_sequences */
862
double
863
airVanDerCorput(unsigned int indx, unsigned int base) {
864
  double result=0.0, ff;
865
  unsigned int ii;
866
867
  ff = 1.0/base;
868
  ii = indx;
869
  while (ii) {
870
    result += ff*(ii % base);
871
    ii /= base;
872
    ff /= base;
873
  }
874
  return result;
875
}
876
877
void
878
airHalton(double *out, unsigned int indx,
879
          const unsigned int *base, unsigned int num) {
880
  unsigned int nn, bb;
881
882
267300
  for (nn=0; nn<num; nn++) {
883
    double ff, result = 0.0;
884
    unsigned int ii;
885
89100
    bb = base[nn];
886
89100
    ff = 1.0/bb;
887
    ii = indx;
888
1408728
    while (ii) {
889
615264
      result += ff*(ii % bb);
890
615264
      ii /= bb;
891
615264
      ff /= bb;
892
    }
893
89100
    out[nn] = result;
894
  }
895
  return;
896
29700
}
897
898
/* via "Table[Prime[n], {n, 1000}]" in Mathematica */
899
const unsigned int airPrimeList[AIR_PRIME_NUM] = {
900
  2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61,
901
  67, 71, 73, 79, 83, 89, 97, 101, 103, 107, 109, 113, 127, 131, 137,
902
  139, 149, 151, 157, 163, 167, 173, 179, 181, 191, 193, 197, 199, 211,
903
  223, 227, 229, 233, 239, 241, 251, 257, 263, 269, 271, 277, 281, 283,
904
  293, 307, 311, 313, 317, 331, 337, 347, 349, 353, 359, 367, 373, 379,
905
  383, 389, 397, 401, 409, 419, 421, 431, 433, 439, 443, 449, 457, 461,
906
  463, 467, 479, 487, 491, 499, 503, 509, 521, 523, 541, 547, 557, 563,
907
  569, 571, 577, 587, 593, 599, 601, 607, 613, 617, 619, 631, 641, 643,
908
  647, 653, 659, 661, 673, 677, 683, 691, 701, 709, 719, 727, 733, 739,
909
  743, 751, 757, 761, 769, 773, 787, 797, 809, 811, 821, 823, 827, 829,
910
  839, 853, 857, 859, 863, 877, 881, 883, 887, 907, 911, 919, 929, 937,
911
  941, 947, 953, 967, 971, 977, 983, 991, 997, 1009, 1013, 1019, 1021,
912
  1031, 1033, 1039, 1049, 1051, 1061, 1063, 1069, 1087, 1091, 1093,
913
  1097, 1103, 1109, 1117, 1123, 1129, 1151, 1153, 1163, 1171, 1181,
914
  1187, 1193, 1201, 1213, 1217, 1223, 1229, 1231, 1237, 1249, 1259,
915
  1277, 1279, 1283, 1289, 1291, 1297, 1301, 1303, 1307, 1319, 1321,
916
  1327, 1361, 1367, 1373, 1381, 1399, 1409, 1423, 1427, 1429, 1433,
917
  1439, 1447, 1451, 1453, 1459, 1471, 1481, 1483, 1487, 1489, 1493,
918
  1499, 1511, 1523, 1531, 1543, 1549, 1553, 1559, 1567, 1571, 1579,
919
  1583, 1597, 1601, 1607, 1609, 1613, 1619, 1621, 1627, 1637, 1657,
920
  1663, 1667, 1669, 1693, 1697, 1699, 1709, 1721, 1723, 1733, 1741,
921
  1747, 1753, 1759, 1777, 1783, 1787, 1789, 1801, 1811, 1823, 1831,
922
  1847, 1861, 1867, 1871, 1873, 1877, 1879, 1889, 1901, 1907, 1913,
923
  1931, 1933, 1949, 1951, 1973, 1979, 1987, 1993, 1997, 1999, 2003,
924
  2011, 2017, 2027, 2029, 2039, 2053, 2063, 2069, 2081, 2083, 2087,
925
  2089, 2099, 2111, 2113, 2129, 2131, 2137, 2141, 2143, 2153, 2161,
926
  2179, 2203, 2207, 2213, 2221, 2237, 2239, 2243, 2251, 2267, 2269,
927
  2273, 2281, 2287, 2293, 2297, 2309, 2311, 2333, 2339, 2341, 2347,
928
  2351, 2357, 2371, 2377, 2381, 2383, 2389, 2393, 2399, 2411, 2417,
929
  2423, 2437, 2441, 2447, 2459, 2467, 2473, 2477, 2503, 2521, 2531,
930
  2539, 2543, 2549, 2551, 2557, 2579, 2591, 2593, 2609, 2617, 2621,
931
  2633, 2647, 2657, 2659, 2663, 2671, 2677, 2683, 2687, 2689, 2693,
932
  2699, 2707, 2711, 2713, 2719, 2729, 2731, 2741, 2749, 2753, 2767,
933
  2777, 2789, 2791, 2797, 2801, 2803, 2819, 2833, 2837, 2843, 2851,
934
  2857, 2861, 2879, 2887, 2897, 2903, 2909, 2917, 2927, 2939, 2953,
935
  2957, 2963, 2969, 2971, 2999, 3001, 3011, 3019, 3023, 3037, 3041,
936
  3049, 3061, 3067, 3079, 3083, 3089, 3109, 3119, 3121, 3137, 3163,
937
  3167, 3169, 3181, 3187, 3191, 3203, 3209, 3217, 3221, 3229, 3251,
938
  3253, 3257, 3259, 3271, 3299, 3301, 3307, 3313, 3319, 3323, 3329,
939
  3331, 3343, 3347, 3359, 3361, 3371, 3373, 3389, 3391, 3407, 3413,
940
  3433, 3449, 3457, 3461, 3463, 3467, 3469, 3491, 3499, 3511, 3517,
941
  3527, 3529, 3533, 3539, 3541, 3547, 3557, 3559, 3571, 3581, 3583,
942
  3593, 3607, 3613, 3617, 3623, 3631, 3637, 3643, 3659, 3671, 3673,
943
  3677, 3691, 3697, 3701, 3709, 3719, 3727, 3733, 3739, 3761, 3767,
944
  3769, 3779, 3793, 3797, 3803, 3821, 3823, 3833, 3847, 3851, 3853,
945
  3863, 3877, 3881, 3889, 3907, 3911, 3917, 3919, 3923, 3929, 3931,
946
  3943, 3947, 3967, 3989, 4001, 4003, 4007, 4013, 4019, 4021, 4027,
947
  4049, 4051, 4057, 4073, 4079, 4091, 4093, 4099, 4111, 4127, 4129,
948
  4133, 4139, 4153, 4157, 4159, 4177, 4201, 4211, 4217, 4219, 4229,
949
  4231, 4241, 4243, 4253, 4259, 4261, 4271, 4273, 4283, 4289, 4297,
950
  4327, 4337, 4339, 4349, 4357, 4363, 4373, 4391, 4397, 4409, 4421,
951
  4423, 4441, 4447, 4451, 4457, 4463, 4481, 4483, 4493, 4507, 4513,
952
  4517, 4519, 4523, 4547, 4549, 4561, 4567, 4583, 4591, 4597, 4603,
953
  4621, 4637, 4639, 4643, 4649, 4651, 4657, 4663, 4673, 4679, 4691,
954
  4703, 4721, 4723, 4729, 4733, 4751, 4759, 4783, 4787, 4789, 4793,
955
  4799, 4801, 4813, 4817, 4831, 4861, 4871, 4877, 4889, 4903, 4909,
956
  4919, 4931, 4933, 4937, 4943, 4951, 4957, 4967, 4969, 4973, 4987,
957
  4993, 4999, 5003, 5009, 5011, 5021, 5023, 5039, 5051, 5059, 5077,
958
  5081, 5087, 5099, 5101, 5107, 5113, 5119, 5147, 5153, 5167, 5171,
959
  5179, 5189, 5197, 5209, 5227, 5231, 5233, 5237, 5261, 5273, 5279,
960
  5281, 5297, 5303, 5309, 5323, 5333, 5347, 5351, 5381, 5387, 5393,
961
  5399, 5407, 5413, 5417, 5419, 5431, 5437, 5441, 5443, 5449, 5471,
962
  5477, 5479, 5483, 5501, 5503, 5507, 5519, 5521, 5527, 5531, 5557,
963
  5563, 5569, 5573, 5581, 5591, 5623, 5639, 5641, 5647, 5651, 5653,
964
  5657, 5659, 5669, 5683, 5689, 5693, 5701, 5711, 5717, 5737, 5741,
965
  5743, 5749, 5779, 5783, 5791, 5801, 5807, 5813, 5821, 5827, 5839,
966
  5843, 5849, 5851, 5857, 5861, 5867, 5869, 5879, 5881, 5897, 5903,
967
  5923, 5927, 5939, 5953, 5981, 5987, 6007, 6011, 6029, 6037, 6043,
968
  6047, 6053, 6067, 6073, 6079, 6089, 6091, 6101, 6113, 6121, 6131,
969
  6133, 6143, 6151, 6163, 6173, 6197, 6199, 6203, 6211, 6217, 6221,
970
  6229, 6247, 6257, 6263, 6269, 6271, 6277, 6287, 6299, 6301, 6311,
971
  6317, 6323, 6329, 6337, 6343, 6353, 6359, 6361, 6367, 6373, 6379,
972
  6389, 6397, 6421, 6427, 6449, 6451, 6469, 6473, 6481, 6491, 6521,
973
  6529, 6547, 6551, 6553, 6563, 6569, 6571, 6577, 6581, 6599, 6607,
974
  6619, 6637, 6653, 6659, 6661, 6673, 6679, 6689, 6691, 6701, 6703,
975
  6709, 6719, 6733, 6737, 6761, 6763, 6779, 6781, 6791, 6793, 6803,
976
  6823, 6827, 6829, 6833, 6841, 6857, 6863, 6869, 6871, 6883, 6899,
977
  6907, 6911, 6917, 6947, 6949, 6959, 6961, 6967, 6971, 6977, 6983,
978
  6991, 6997, 7001, 7013, 7019, 7027, 7039, 7043, 7057, 7069, 7079,
979
  7103, 7109, 7121, 7127, 7129, 7151, 7159, 7177, 7187, 7193, 7207,
980
  7211, 7213, 7219, 7229, 7237, 7243, 7247, 7253, 7283, 7297, 7307,
981
  7309, 7321, 7331, 7333, 7349, 7351, 7369, 7393, 7411, 7417, 7433,
982
  7451, 7457, 7459, 7477, 7481, 7487, 7489, 7499, 7507, 7517, 7523,
983
  7529, 7537, 7541, 7547, 7549, 7559, 7561, 7573, 7577, 7583, 7589,
984
  7591, 7603, 7607, 7621, 7639, 7643, 7649, 7669, 7673, 7681, 7687,
985
  7691, 7699, 7703, 7717, 7723, 7727, 7741, 7753, 7757, 7759, 7789,
986
  7793, 7817, 7823, 7829, 7841, 7853, 7867, 7873, 7877, 7879, 7883,
987
  7901, 7907, 7919};
988
989
/*
990
** CRC code available in various places, including:
991
** http://pubs.opengroup.org/onlinepubs/007904875/utilities/cksum.html
992
** which curiously has no copyright declaration?
993
*/
994
995
static unsigned int
996
crcTable[] = {
997
  0x00000000,
998
  0x04c11db7, 0x09823b6e, 0x0d4326d9, 0x130476dc, 0x17c56b6b,
999
  0x1a864db2, 0x1e475005, 0x2608edb8, 0x22c9f00f, 0x2f8ad6d6,
1000
  0x2b4bcb61, 0x350c9b64, 0x31cd86d3, 0x3c8ea00a, 0x384fbdbd,
1001
  0x4c11db70, 0x48d0c6c7, 0x4593e01e, 0x4152fda9, 0x5f15adac,
1002
  0x5bd4b01b, 0x569796c2, 0x52568b75, 0x6a1936c8, 0x6ed82b7f,
1003
  0x639b0da6, 0x675a1011, 0x791d4014, 0x7ddc5da3, 0x709f7b7a,
1004
  0x745e66cd, 0x9823b6e0, 0x9ce2ab57, 0x91a18d8e, 0x95609039,
1005
  0x8b27c03c, 0x8fe6dd8b, 0x82a5fb52, 0x8664e6e5, 0xbe2b5b58,
1006
  0xbaea46ef, 0xb7a96036, 0xb3687d81, 0xad2f2d84, 0xa9ee3033,
1007
  0xa4ad16ea, 0xa06c0b5d, 0xd4326d90, 0xd0f37027, 0xddb056fe,
1008
  0xd9714b49, 0xc7361b4c, 0xc3f706fb, 0xceb42022, 0xca753d95,
1009
  0xf23a8028, 0xf6fb9d9f, 0xfbb8bb46, 0xff79a6f1, 0xe13ef6f4,
1010
  0xe5ffeb43, 0xe8bccd9a, 0xec7dd02d, 0x34867077, 0x30476dc0,
1011
  0x3d044b19, 0x39c556ae, 0x278206ab, 0x23431b1c, 0x2e003dc5,
1012
  0x2ac12072, 0x128e9dcf, 0x164f8078, 0x1b0ca6a1, 0x1fcdbb16,
1013
  0x018aeb13, 0x054bf6a4, 0x0808d07d, 0x0cc9cdca, 0x7897ab07,
1014
  0x7c56b6b0, 0x71159069, 0x75d48dde, 0x6b93dddb, 0x6f52c06c,
1015
  0x6211e6b5, 0x66d0fb02, 0x5e9f46bf, 0x5a5e5b08, 0x571d7dd1,
1016
  0x53dc6066, 0x4d9b3063, 0x495a2dd4, 0x44190b0d, 0x40d816ba,
1017
  0xaca5c697, 0xa864db20, 0xa527fdf9, 0xa1e6e04e, 0xbfa1b04b,
1018
  0xbb60adfc, 0xb6238b25, 0xb2e29692, 0x8aad2b2f, 0x8e6c3698,
1019
  0x832f1041, 0x87ee0df6, 0x99a95df3, 0x9d684044, 0x902b669d,
1020
  0x94ea7b2a, 0xe0b41de7, 0xe4750050, 0xe9362689, 0xedf73b3e,
1021
  0xf3b06b3b, 0xf771768c, 0xfa325055, 0xfef34de2, 0xc6bcf05f,
1022
  0xc27dede8, 0xcf3ecb31, 0xcbffd686, 0xd5b88683, 0xd1799b34,
1023
  0xdc3abded, 0xd8fba05a, 0x690ce0ee, 0x6dcdfd59, 0x608edb80,
1024
  0x644fc637, 0x7a089632, 0x7ec98b85, 0x738aad5c, 0x774bb0eb,
1025
  0x4f040d56, 0x4bc510e1, 0x46863638, 0x42472b8f, 0x5c007b8a,
1026
  0x58c1663d, 0x558240e4, 0x51435d53, 0x251d3b9e, 0x21dc2629,
1027
  0x2c9f00f0, 0x285e1d47, 0x36194d42, 0x32d850f5, 0x3f9b762c,
1028
  0x3b5a6b9b, 0x0315d626, 0x07d4cb91, 0x0a97ed48, 0x0e56f0ff,
1029
  0x1011a0fa, 0x14d0bd4d, 0x19939b94, 0x1d528623, 0xf12f560e,
1030
  0xf5ee4bb9, 0xf8ad6d60, 0xfc6c70d7, 0xe22b20d2, 0xe6ea3d65,
1031
  0xeba91bbc, 0xef68060b, 0xd727bbb6, 0xd3e6a601, 0xdea580d8,
1032
  0xda649d6f, 0xc423cd6a, 0xc0e2d0dd, 0xcda1f604, 0xc960ebb3,
1033
  0xbd3e8d7e, 0xb9ff90c9, 0xb4bcb610, 0xb07daba7, 0xae3afba2,
1034
  0xaafbe615, 0xa7b8c0cc, 0xa379dd7b, 0x9b3660c6, 0x9ff77d71,
1035
  0x92b45ba8, 0x9675461f, 0x8832161a, 0x8cf30bad, 0x81b02d74,
1036
  0x857130c3, 0x5d8a9099, 0x594b8d2e, 0x5408abf7, 0x50c9b640,
1037
  0x4e8ee645, 0x4a4ffbf2, 0x470cdd2b, 0x43cdc09c, 0x7b827d21,
1038
  0x7f436096, 0x7200464f, 0x76c15bf8, 0x68860bfd, 0x6c47164a,
1039
  0x61043093, 0x65c52d24, 0x119b4be9, 0x155a565e, 0x18197087,
1040
  0x1cd86d30, 0x029f3d35, 0x065e2082, 0x0b1d065b, 0x0fdc1bec,
1041
  0x3793a651, 0x3352bbe6, 0x3e119d3f, 0x3ad08088, 0x2497d08d,
1042
  0x2056cd3a, 0x2d15ebe3, 0x29d4f654, 0xc5a92679, 0xc1683bce,
1043
  0xcc2b1d17, 0xc8ea00a0, 0xd6ad50a5, 0xd26c4d12, 0xdf2f6bcb,
1044
  0xdbee767c, 0xe3a1cbc1, 0xe760d676, 0xea23f0af, 0xeee2ed18,
1045
  0xf0a5bd1d, 0xf464a0aa, 0xf9278673, 0xfde69bc4, 0x89b8fd09,
1046
  0x8d79e0be, 0x803ac667, 0x84fbdbd0, 0x9abc8bd5, 0x9e7d9662,
1047
  0x933eb0bb, 0x97ffad0c, 0xafb010b1, 0xab710d06, 0xa6322bdf,
1048
  0xa2f33668, 0xbcb4666d, 0xb8757bda, 0xb5365d03, 0xb1f740b4
1049
};
1050
1051
/* note "c" is used once */
1052
#define CRC32(crc, c) (crc) = (((crc) << 8) ^ crcTable[((crc) >> 24) ^ (c)])
1053
1054
unsigned int
1055
airCRC32(const unsigned char *cdata, size_t len, size_t unit, int swap) {
1056
  unsigned int crc=0;
1057
  size_t ii, jj, nn, mm;
1058
  const unsigned char *crev;
1059
1060
24
  if (!(cdata && len)) {
1061
    return 0;
1062
  }
1063
12
  if (swap) {
1064
    /* if doing swapping, we need make sure we have a unit size,
1065
       and that it divides into len */
1066

24
    if (!(unit && !(len % unit))) {
1067
      return 0;
1068
    }
1069
  }
1070
  nn = len;
1071
1072
12
  if (!swap) {
1073
    /* simple case: feed "len" bytes from "cdata" into CRC32 */
1074
    for (ii=0; ii<nn; ii++) {
1075
      CRC32(crc, *(cdata++));
1076
    }
1077
  } else {
1078
    /* have to swap, work "unit" bytes at a time, working down
1079
       the bytes within each unit */
1080
12
    mm = len / unit;
1081
25466568
    for (jj=0; jj<mm; jj++) {
1082
12733272
      crev = cdata + jj*unit + unit-1;
1083
127332720
      for (ii=0; ii<unit; ii++) {
1084
50933088
        CRC32(crc, *(crev--));
1085
      }
1086
    }
1087
  }
1088
1089
  /* include length of data in result */
1090
84
  for (; nn; nn >>= 8) {
1091
36
    CRC32(crc, (nn & 0xff));
1092
  }
1093
1094
12
  return ~crc;
1095
12
}