~ubuntu-branches/ubuntu/vivid/grass/vivid-proposed

« back to all changes in this revision

Viewing changes to lib/raster3d/fpcompress.c

  • Committer: Package Import Robot
  • Author(s): Bas Couwenberg
  • Date: 2015-02-20 23:12:08 UTC
  • mfrom: (8.2.6 experimental)
  • Revision ID: package-import@ubuntu.com-20150220231208-1u6qvqm84v430b10
Tags: 7.0.0-1~exp1
* New upstream release.
* Update python-ctypes-ternary.patch to use if/else instead of and/or.
* Drop check4dev patch, rely on upstream check.
* Add build dependency on libpq-dev to grass-dev for libpq-fe.h.
* Drop patches applied upstream, refresh remaining patches.
* Update symlinks for images switched from jpg to png.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
#include <stdio.h>
 
2
#include <stdlib.h>
 
3
#include <sys/types.h>
 
4
#include <unistd.h>
 
5
#include "raster3d_intern.h"
 
6
 
 
7
/*--------------------------------------------------------------------------*/
 
8
 
 
9
#define XDR_DOUBLE_LENGTH 8
 
10
#define XDR_DOUBLE_NOF_EXP_BYTES 2
 
11
#define XDR_FLOAT_LENGTH 4
 
12
#define XDR_FLOAT_NOF_EXP_BYTES 1
 
13
 
 
14
/*--------------------------------------------------------------------------*/
 
15
 
 
16
void Rast3d_fpcompress_print_binary(char *c, int numBits)
 
17
{
 
18
    unsigned char bit;
 
19
    int i;
 
20
 
 
21
    bit = 1 << (numBits - 1);
 
22
 
 
23
    for (i = 0; i < numBits; i++) {
 
24
        printf("%d", (*((unsigned char *)c) & bit) != 0);
 
25
        bit >>= 1;
 
26
    }
 
27
}
 
28
 
 
29
/*--------------------------------------------------------------------------*/
 
30
 
 
31
void Rast3d_fpcompress_dissect_xdr_double(unsigned char *numPointer)
 
32
{
 
33
    char sign, exponent;
 
34
 
 
35
    sign = *numPointer >> 7;
 
36
    exponent = (*numPointer << 1) | (*(numPointer + 1) >> 7);
 
37
 
 
38
    printf("%f: sign = ", *((float *)numPointer));
 
39
    Rast3d_fpcompress_print_binary(&sign, 1);
 
40
    printf("   exp = ");
 
41
    Rast3d_fpcompress_print_binary(&exponent, 8);
 
42
    printf("   mantissa = ");
 
43
    Rast3d_fpcompress_print_binary((char *)(numPointer + 1), 7);
 
44
    Rast3d_fpcompress_print_binary((char *)(numPointer + 2), 8);
 
45
    Rast3d_fpcompress_print_binary((char *)(numPointer + 3), 8);
 
46
    printf("\n");
 
47
}
 
48
 
 
49
/*--------------------------------------------------------------------------*/
 
50
 
 
51
static unsigned char clearMask[9] =
 
52
    { 255, 128, 192, 224, 240, 248, 252, 254, 255 };
 
53
 
 
54
/*--------------------------------------------------------------------------*/
 
55
 
 
56
#define ALL_NULL_CODE 2
 
57
#define ZERO_NULL_CODE 1
 
58
#define SOME_NULL_CODE 0
 
59
 
 
60
/*--------------------------------------------------------------------------*/
 
61
 
 
62
static void
 
63
G_fpcompress_rearrangeEncodeFloats(unsigned char *src, int size,
 
64
                                   int precision, unsigned char *dst,
 
65
                                   int *length, int *offsetMantissa)
 
66
{
 
67
    unsigned int nNullBits, nBits;
 
68
    register unsigned char *srcStop;
 
69
    register unsigned char *cp0, *cp1, *cp2, *cp3, *nullBits;
 
70
    unsigned char mask, isNull;
 
71
    int gt8, gt16, srcIncrement, nofNull;
 
72
    float *f;
 
73
 
 
74
    srcStop = src + size * XDR_FLOAT_LENGTH;
 
75
 
 
76
    if ((precision >= 23) || (precision == -1)) {
 
77
        cp3 = dst;
 
78
        cp2 = cp3 + size;
 
79
        cp1 = cp2 + size;
 
80
        cp0 = cp1 + size;
 
81
        while (srcStop != src) {
 
82
            *cp3++ = *src++;    /* sign + 7 exponent bits */
 
83
            *cp2++ = *src++;    /* 1 exponent bit + 7 ms mantissa bits */
 
84
            *cp1++ = *src++;    /* 8 mantissa bits */
 
85
            *cp0++ = *src++;    /* 8 ls mantissa bits */
 
86
        }
 
87
 
 
88
        *length = size * XDR_FLOAT_LENGTH;
 
89
        *offsetMantissa = size;
 
90
 
 
91
        return;
 
92
    }
 
93
 
 
94
    f = (float *)src;
 
95
    nofNull = 0;
 
96
    while (srcStop != (unsigned char *)f)
 
97
        nofNull += Rast3d_is_xdr_null_float(f++);
 
98
 
 
99
    if (nofNull == size) {
 
100
        *dst = (unsigned char)ALL_NULL_CODE;
 
101
 
 
102
        *length = 1;
 
103
        *offsetMantissa = 1;
 
104
 
 
105
        return;
 
106
    }
 
107
 
 
108
    precision += 1;             /* treat the ls exponent bit like an addl mantissa bit */
 
109
 
 
110
    *dst = (unsigned char)(nofNull == 0 ? ZERO_NULL_CODE : SOME_NULL_CODE);
 
111
 
 
112
    gt16 = precision > 16;
 
113
    gt8 = precision > 8;
 
114
    srcIncrement = 1 + (!gt8) + (!gt16);
 
115
 
 
116
    precision %= 8;
 
117
 
 
118
    nullBits = dst + 1;
 
119
    if (nofNull)
 
120
        cp0 = nullBits + size / 8 + ((size % 8) != 0);
 
121
    else
 
122
        cp0 = nullBits;
 
123
    cp3 = cp0 + size - nofNull;
 
124
    cp2 = cp3 + size - nofNull;
 
125
    cp1 = cp3 + (gt8 + gt16) * (size - nofNull);
 
126
 
 
127
    mask = clearMask[precision];
 
128
    nBits = nNullBits = 0;
 
129
 
 
130
    while (srcStop != src) {
 
131
        if (nofNull) {
 
132
            isNull = Rast3d_is_xdr_null_float((float *)src);
 
133
 
 
134
            if (nNullBits) {
 
135
                *nullBits |= ((unsigned char)isNull << nNullBits++);
 
136
                if (nNullBits == 8) {
 
137
                    nullBits++;
 
138
                    nNullBits = 0;
 
139
                }
 
140
            }
 
141
            else {
 
142
                *nullBits = (unsigned char)isNull;
 
143
                nNullBits++;
 
144
            }
 
145
 
 
146
            if (isNull) {
 
147
                src += XDR_FLOAT_LENGTH;
 
148
                continue;
 
149
            }
 
150
        }
 
151
 
 
152
        /* printf ("write src cp0 %d %d (%d %d) %d\n", *src, *cp0, src, cp0, nullBits); */
 
153
 
 
154
        *cp0++ = *src++;
 
155
        if (gt8)
 
156
            *cp3++ = *src++;
 
157
        if (gt16)
 
158
            *cp2++ = *src++;
 
159
 
 
160
        if (nBits && precision) {
 
161
            *cp1 |= (unsigned char)((unsigned char)(*src & mask) >> nBits);
 
162
 
 
163
            /*printf ("%d\n", ((*src & mask) >> nBits) << nBits); */
 
164
 
 
165
            if (8 - nBits < precision) {
 
166
                cp1++;
 
167
 
 
168
                /*printf ("%d %d\n", *cp1, (*src & mask) << (8 - nBits)); */
 
169
 
 
170
                *cp1 =
 
171
                    (unsigned char)((unsigned char)((*src & mask)) <<
 
172
                                    (8 - nBits));
 
173
                nBits += precision - 8;
 
174
            }
 
175
            else {
 
176
                nBits = (nBits + precision) % 8;
 
177
                if (!nBits)
 
178
                    cp1++;
 
179
            }
 
180
        }
 
181
        else {
 
182
            *cp1 = (unsigned char)(*src & mask);
 
183
            /* printf ("%d %d %d\n", *cp1, *src, nBits); */
 
184
            nBits = (nBits + precision) % 8;
 
185
            if (!nBits)
 
186
                cp1++;
 
187
        }
 
188
 
 
189
        src += srcIncrement;
 
190
    }
 
191
 
 
192
    *length = 1;                /* null-bit-vector indicator-byte */
 
193
 
 
194
    if (nofNull)                /* length of null-bit-vector */
 
195
        *length += size / 8 + ((size % 8) != 0);
 
196
 
 
197
    /* length of data */
 
198
    *length += (gt8 + gt16 + (precision == 0) + 1) * (size - nofNull) +
 
199
        ((precision * (size - nofNull)) / 8) +
 
200
        (((precision * (size - nofNull)) % 8) != 0);
 
201
 
 
202
    *offsetMantissa = size - nofNull;
 
203
}
 
204
 
 
205
/*--------------------------------------------------------------------------*/
 
206
 
 
207
static void
 
208
G_fpcompress_rearrangeEncodeDoubles(unsigned char *src, int size,
 
209
                                    int precision, unsigned char *dst,
 
210
                                    int *length, int *offsetMantissa)
 
211
{
 
212
    unsigned int nNullBits, nBits;
 
213
    unsigned char isNull;
 
214
    register unsigned char *srcStop;
 
215
    register unsigned char *cp0, *cp1, *cp2, *cp3;
 
216
    register unsigned char *cp4, *cp5, *cp6, *cp7, *nullBits;
 
217
    unsigned char mask;
 
218
    int gt8, gt16, gt24, gt32, gt40, gt48, srcIncrement, nofNull;
 
219
    double *d;
 
220
 
 
221
    srcStop = src + size * XDR_DOUBLE_LENGTH;
 
222
 
 
223
    if ((precision >= 52) || (precision == -1)) {
 
224
        cp7 = dst;
 
225
        cp6 = cp7 + size;
 
226
        cp5 = cp6 + size;
 
227
        cp4 = cp5 + size;
 
228
        cp3 = cp4 + size;
 
229
        cp2 = cp3 + size;
 
230
        cp1 = cp2 + size;
 
231
        cp0 = cp1 + size;
 
232
 
 
233
        while (srcStop != src) {
 
234
            *cp7++ = *src++;    /* sign + 7 ms exponent bits */
 
235
            *cp6++ = *src++;    /* 4 exponent bits + 4 ms mantissa bits */
 
236
            *cp5++ = *src++;    /* 8 mantissa bits */
 
237
            *cp4++ = *src++;
 
238
            *cp3++ = *src++;
 
239
            *cp2++ = *src++;
 
240
            *cp1++ = *src++;
 
241
            *cp0++ = *src++;    /* 8 ls mantissa bits */
 
242
        }
 
243
 
 
244
        *length = size * XDR_DOUBLE_LENGTH;
 
245
        *offsetMantissa = size;
 
246
 
 
247
        return;
 
248
    }
 
249
 
 
250
    precision += 4;             /* treat the 4 ls exponent bits like addl mantissa bits */
 
251
 
 
252
    d = (double *)src;
 
253
    nofNull = 0;
 
254
    while (srcStop != (unsigned char *)d)
 
255
        nofNull += Rast3d_is_xdr_null_double(d++);
 
256
 
 
257
    if (nofNull == size) {
 
258
        *dst = (unsigned char)ALL_NULL_CODE;
 
259
 
 
260
        *length = 1;
 
261
        *offsetMantissa = 1;
 
262
 
 
263
        return;
 
264
    }
 
265
 
 
266
    *dst = (unsigned char)(nofNull == 0 ? ZERO_NULL_CODE : SOME_NULL_CODE);
 
267
 
 
268
    gt48 = precision > 48;
 
269
    gt40 = precision > 40;
 
270
    gt32 = precision > 32;
 
271
    gt24 = precision > 24;
 
272
    gt16 = precision > 16;
 
273
    gt8 = precision > 8;
 
274
    srcIncrement =
 
275
        1 + (!gt8) + (!gt16) + (!gt24) + (!gt32) + (!gt40) + (!gt48);
 
276
 
 
277
    precision %= 8;
 
278
 
 
279
    nullBits = dst + 1;
 
280
    if (nofNull)
 
281
        cp0 = nullBits + size / 8 + ((size % 8) != 0);
 
282
    else
 
283
        cp0 = nullBits;
 
284
    cp7 = cp0 + size - nofNull;
 
285
    cp6 = cp7 + size - nofNull;
 
286
    cp5 = cp6 + size - nofNull;
 
287
    cp4 = cp5 + size - nofNull;
 
288
    cp3 = cp4 + size - nofNull;
 
289
    cp2 = cp3 + size - nofNull;
 
290
    cp1 = cp7 + (gt8 + gt16 + gt24 + gt32 + gt40 + gt48) * (size - nofNull);
 
291
 
 
292
    mask = clearMask[precision];
 
293
    nBits = nNullBits = 0;
 
294
 
 
295
    while (srcStop != src) {
 
296
        if (nofNull) {
 
297
            isNull = Rast3d_is_xdr_null_double((double *)src);
 
298
 
 
299
            if (nNullBits) {
 
300
                *nullBits |= ((unsigned char)isNull << nNullBits++);
 
301
                if (nNullBits == 8) {
 
302
                    nullBits++;
 
303
                    nNullBits = 0;
 
304
                }
 
305
            }
 
306
            else {
 
307
                *nullBits = (unsigned char)isNull;
 
308
                nNullBits++;
 
309
            }
 
310
 
 
311
            if (isNull) {
 
312
                src += XDR_DOUBLE_LENGTH;
 
313
                continue;
 
314
            }
 
315
        }
 
316
 
 
317
        *cp0++ = *src++;
 
318
        if (gt32) {
 
319
            *cp7++ = *src++;
 
320
            *cp6++ = *src++;
 
321
            *cp5++ = *src++;
 
322
 
 
323
            if (gt32)
 
324
                *cp4++ = *src++;
 
325
            if (gt40)
 
326
                *cp3++ = *src++;
 
327
            if (gt48)
 
328
                *cp2++ = *src++;
 
329
        }
 
330
        else {
 
331
            if (gt8)
 
332
                *cp7++ = *src++;
 
333
            if (gt16)
 
334
                *cp6++ = *src++;
 
335
            if (gt24)
 
336
                *cp5++ = *src++;
 
337
        }
 
338
 
 
339
        if (nBits && precision) {
 
340
            *cp1 |= (unsigned char)((unsigned char)(*src & mask) >> nBits);
 
341
            if (8 - nBits < precision) {
 
342
                cp1++;
 
343
                *cp1 =
 
344
                    (unsigned char)(((unsigned char)(*src & mask)) <<
 
345
                                    (8 - nBits));
 
346
                nBits += precision - 8;
 
347
            }
 
348
            else {
 
349
                nBits = (nBits + precision) % 8;
 
350
                if (!nBits)
 
351
                    cp1++;
 
352
            }
 
353
        }
 
354
        else {
 
355
            *cp1 = (unsigned char)(*src & mask);
 
356
            nBits = (nBits + precision) % 8;
 
357
            if (!nBits)
 
358
                cp1++;
 
359
        }
 
360
 
 
361
        src += srcIncrement;
 
362
    }
 
363
 
 
364
    *length = 1;
 
365
 
 
366
    if (nofNull)
 
367
        *length += size / 8 + ((size % 8) != 0);
 
368
 
 
369
    *length +=
 
370
        (1 + gt8 + gt16 + gt24 + gt32 + gt40 + gt48 +
 
371
         (precision ==
 
372
          0)) * (size - nofNull) + ((precision * (size - nofNull)) / 8) +
 
373
        (((precision * (size - nofNull)) % 8) != 0);
 
374
 
 
375
    if (gt8)
 
376
        *offsetMantissa = 2 * (size - nofNull);
 
377
    else
 
378
        *offsetMantissa = *length;
 
379
}
 
380
 
 
381
/*--------------------------------------------------------------------------*/
 
382
 
 
383
static void
 
384
G_fpcompress_rearrangeDecodeFloats(unsigned char *src, int size,
 
385
                                   int precision, unsigned char *dst)
 
386
{
 
387
    unsigned int nNullBits, nBits;
 
388
    register unsigned char *dstStop;
 
389
    register unsigned char *cp0, *cp1, *cp2, *cp3, *nullBits;
 
390
    unsigned char mask, isNull;
 
391
    int gt8, gt16, dstIncrement, nofNull;
 
392
    float *f, *fStop;
 
393
 
 
394
    if ((precision != -1) && (precision <= 15)) {       /* 23 - 8 */
 
395
        cp3 = dst + 3;
 
396
        dstStop = dst + XDR_FLOAT_LENGTH * size + 3;
 
397
        while (dstStop != cp3) {
 
398
            *cp3 = 0;
 
399
            cp3 += XDR_FLOAT_LENGTH;
 
400
        }
 
401
 
 
402
        if (precision <= 7) {
 
403
            cp3 = dst + 2;
 
404
            dstStop = dst + XDR_FLOAT_LENGTH * size + 2;
 
405
            while (dstStop != cp3) {
 
406
                *cp3 = 0;
 
407
                cp3 += XDR_FLOAT_LENGTH;
 
408
            }
 
409
        }
 
410
    }
 
411
 
 
412
    dstStop = dst + size * XDR_FLOAT_LENGTH;
 
413
 
 
414
    if ((precision >= 23) || (precision == -1)) {
 
415
        cp3 = src;
 
416
        cp2 = cp3 + size;
 
417
        cp1 = cp2 + size;
 
418
        cp0 = cp1 + size;
 
419
        while (dstStop != dst) {
 
420
            *dst++ = *cp3++;
 
421
            *dst++ = *cp2++;
 
422
            *dst++ = *cp1++;
 
423
            *dst++ = *cp0++;
 
424
        }
 
425
 
 
426
        return;
 
427
    }
 
428
 
 
429
    if (*src == (unsigned char)ALL_NULL_CODE) {
 
430
        f = (float *)dst;
 
431
        while (dstStop != (unsigned char *)f)
 
432
            Rast3d_set_xdr_null_float(f++);
 
433
 
 
434
        return;
 
435
    }
 
436
 
 
437
    precision += 1;             /* treat the ls exponent bit like an addl mantissa bit */
 
438
 
 
439
    gt16 = precision > 16;
 
440
    gt8 = precision > 8;
 
441
    dstIncrement = 1 + (!gt8) + (!gt16);
 
442
 
 
443
    precision %= 8;
 
444
 
 
445
    nofNull = 0;
 
446
    nullBits = src + 1;
 
447
    nNullBits = 0;
 
448
    if (*src == (unsigned char)SOME_NULL_CODE) {
 
449
        f = (float *)src;
 
450
        fStop = (float *)(src + size * XDR_FLOAT_LENGTH);
 
451
        while (fStop != f++) {
 
452
            nofNull += ((*nullBits & ((unsigned char)1 << nNullBits++)) != 0);
 
453
            if (nNullBits == 8) {
 
454
                nullBits++;
 
455
                nNullBits = 0;
 
456
            }
 
457
        }
 
458
    }
 
459
 
 
460
    nullBits = src + 1;
 
461
    if (nofNull)
 
462
        cp0 = nullBits + size / 8 + ((size % 8) != 0);
 
463
    else
 
464
        cp0 = nullBits;
 
465
    cp3 = cp0 + size - nofNull;
 
466
    cp2 = cp3 + size - nofNull;
 
467
    cp1 = cp3 + (gt8 + gt16) * (size - nofNull);
 
468
 
 
469
    mask = clearMask[precision];
 
470
    nBits = nNullBits = 0;
 
471
 
 
472
    while (dstStop != dst) {
 
473
        if (nofNull) {
 
474
            isNull = *nullBits & ((unsigned char)1 << nNullBits++);
 
475
 
 
476
            if (nNullBits == 8) {
 
477
                nullBits++;
 
478
                nNullBits = 0;
 
479
            }
 
480
 
 
481
            if (isNull) {
 
482
                Rast3d_set_xdr_null_float((float *)dst);
 
483
                dst += XDR_FLOAT_LENGTH;
 
484
                continue;
 
485
            }
 
486
        }
 
487
 
 
488
        *dst++ = *cp0++;
 
489
        if (gt8)
 
490
            *dst++ = *cp3++;
 
491
        if (gt16)
 
492
            *dst++ = *cp2++;
 
493
 
 
494
        if (nBits && precision) {
 
495
            *dst = (unsigned char)((*cp1 << nBits) & mask);
 
496
 
 
497
            if (8 - nBits < precision) {
 
498
                cp1++;
 
499
                *dst |= (unsigned char)((*cp1 >> (8 - nBits)) & mask);
 
500
                nBits += precision - 8;
 
501
            }
 
502
            else {
 
503
                nBits = (nBits + precision) % 8;
 
504
                if (!nBits)
 
505
                    cp1++;
 
506
            }
 
507
        }
 
508
        else {
 
509
            *dst = (unsigned char)(*cp1 & mask);
 
510
            nBits = (nBits + precision) % 8;
 
511
            if (!nBits)
 
512
                cp1++;
 
513
        }
 
514
 
 
515
        dst += dstIncrement;
 
516
    }
 
517
}
 
518
 
 
519
/*--------------------------------------------------------------------------*/
 
520
 
 
521
static void
 
522
G_fpcompress_rearrangeDecodeDoubles(unsigned char *src, int size,
 
523
                                    int precision, unsigned char *dst)
 
524
{
 
525
    unsigned int nNullBits, nBits;
 
526
    register unsigned char *dstStop;
 
527
    register unsigned char *cp0, *cp1, *cp2, *cp3;
 
528
    register unsigned char *cp4, *cp5, *cp6, *cp7, *nullBits;
 
529
    unsigned char mask, isNull;
 
530
    int gt8, gt16, gt24, gt32, gt40, gt48, dstIncrement, offs, nofNull;
 
531
    double *d, *dStop;
 
532
 
 
533
    if ((precision != -1) && (precision <= 44)) {
 
534
        for (offs = 7; offs >= (precision + 19) / 8; offs--) {
 
535
            cp7 = dst + offs;
 
536
            dstStop = dst + XDR_DOUBLE_LENGTH * size + offs;
 
537
            while (dstStop != cp7) {
 
538
                *cp7 = 0;
 
539
                cp7 += XDR_DOUBLE_LENGTH;
 
540
            }
 
541
        }
 
542
    }
 
543
 
 
544
    dstStop = dst + size * XDR_DOUBLE_LENGTH;
 
545
 
 
546
    if ((precision >= 52) || (precision == -1)) {
 
547
        cp7 = src;
 
548
        cp6 = cp7 + size;
 
549
        cp5 = cp6 + size;
 
550
        cp4 = cp5 + size;
 
551
        cp3 = cp4 + size;
 
552
        cp2 = cp3 + size;
 
553
        cp1 = cp2 + size;
 
554
        cp0 = cp1 + size;
 
555
 
 
556
        while (dstStop != dst) {
 
557
            *dst++ = *cp7++;
 
558
            *dst++ = *cp6++;
 
559
            *dst++ = *cp5++;
 
560
            *dst++ = *cp4++;
 
561
            *dst++ = *cp3++;
 
562
            *dst++ = *cp2++;
 
563
            *dst++ = *cp1++;
 
564
            *dst++ = *cp0++;
 
565
        }
 
566
 
 
567
        return;
 
568
    }
 
569
 
 
570
    if (*src == (unsigned char)ALL_NULL_CODE) {
 
571
        /*printf ("all null\n"); */
 
572
        d = (double *)dst;
 
573
        while (dstStop != (unsigned char *)d)
 
574
            Rast3d_set_xdr_null_double(d++);
 
575
 
 
576
        return;
 
577
    }
 
578
 
 
579
    precision += 4;             /* treat the 4 ls exponent bits like addl mantissa bits */
 
580
 
 
581
    gt48 = precision > 48;
 
582
    gt40 = precision > 40;
 
583
    gt32 = precision > 32;
 
584
    gt24 = precision > 24;
 
585
    gt16 = precision > 16;
 
586
    gt8 = precision > 8;
 
587
 
 
588
    dstIncrement =
 
589
        1 + (!gt8) + (!gt16) + (!gt24) + (!gt32) + (!gt40) + (!gt48);
 
590
 
 
591
    precision %= 8;
 
592
 
 
593
    nofNull = 0;
 
594
    nullBits = src + 1;
 
595
    nNullBits = 0;
 
596
    if (*src == (unsigned char)SOME_NULL_CODE) {
 
597
        d = (double *)src;
 
598
        dStop = (double *)(src + size * XDR_DOUBLE_LENGTH);
 
599
        while (dStop != d++) {
 
600
            nofNull += ((*nullBits & ((unsigned char)1 << nNullBits++)) != 0);
 
601
            if (nNullBits == 8) {
 
602
                nullBits++;
 
603
                nNullBits = 0;
 
604
            }
 
605
        }
 
606
    }
 
607
 
 
608
    nullBits = src + 1;
 
609
    if (nofNull)
 
610
        cp0 = nullBits + size / 8 + ((size % 8) != 0);
 
611
    else
 
612
        cp0 = nullBits;
 
613
    cp7 = cp0 + size - nofNull;
 
614
    cp6 = cp7 + size - nofNull;
 
615
    cp5 = cp6 + size - nofNull;
 
616
    cp4 = cp5 + size - nofNull;
 
617
    cp3 = cp4 + size - nofNull;
 
618
    cp2 = cp3 + size - nofNull;
 
619
    cp1 = cp7 + (gt8 + gt16 + gt24 + gt32 + gt40 + gt48) * (size - nofNull);
 
620
 
 
621
    mask = clearMask[precision];
 
622
    nBits = nNullBits = 0;
 
623
 
 
624
    while (dstStop != dst) {
 
625
        if (nofNull) {
 
626
            isNull = *nullBits & ((unsigned char)1 << nNullBits++);
 
627
 
 
628
            if (nNullBits == 8) {
 
629
                nullBits++;
 
630
                nNullBits = 0;
 
631
            }
 
632
 
 
633
            if (isNull) {
 
634
                Rast3d_set_xdr_null_double((double *)dst);
 
635
                dst += XDR_DOUBLE_LENGTH;
 
636
                continue;
 
637
            }
 
638
        }
 
639
 
 
640
        *dst++ = *cp0++;
 
641
        if (gt32) {
 
642
            *dst++ = *cp7++;
 
643
            *dst++ = *cp6++;
 
644
            *dst++ = *cp5++;
 
645
 
 
646
            if (gt32)
 
647
                *dst++ = *cp4++;
 
648
            if (gt40)
 
649
                *dst++ = *cp3++;
 
650
            if (gt48)
 
651
                *dst++ = *cp2++;
 
652
        }
 
653
        else {
 
654
            if (gt8)
 
655
                *dst++ = *cp7++;
 
656
            if (gt16)
 
657
                *dst++ = *cp6++;
 
658
            if (gt24)
 
659
                *dst++ = *cp5++;
 
660
        }
 
661
 
 
662
        if (nBits && precision) {
 
663
            *dst = (unsigned char)((*cp1 << nBits) & mask);
 
664
 
 
665
            if (8 - nBits < precision) {
 
666
                cp1++;
 
667
                *dst |= (unsigned char)((*cp1 >> (8 - nBits)) & mask);
 
668
                nBits += precision - 8;
 
669
            }
 
670
            else {
 
671
                nBits = (nBits + precision) % 8;
 
672
                if (!nBits)
 
673
                    cp1++;
 
674
            }
 
675
        }
 
676
        else {
 
677
            *dst = (unsigned char)(*cp1 & mask);
 
678
            nBits = (nBits + precision) % 8;
 
679
            if (!nBits)
 
680
                cp1++;
 
681
        }
 
682
 
 
683
        dst += dstIncrement;
 
684
    }
 
685
}
 
686
 
 
687
/*--------------------------------------------------------------------------*/
 
688
 
 
689
int
 
690
Rast3d_fpcompress_write_xdr_nums(int fd, char *src, int nofNum, int precision,
 
691
                          char *compressBuf, int isFloat)
 
692
{
 
693
    int status;
 
694
    int nBytes;
 
695
    int offsetMantissa;
 
696
 
 
697
    if (isFloat)
 
698
        G_fpcompress_rearrangeEncodeFloats((unsigned char *)src, nofNum, precision,
 
699
                        (unsigned char *)(compressBuf + 1),
 
700
                                           &nBytes, &offsetMantissa);
 
701
    else
 
702
        G_fpcompress_rearrangeEncodeDoubles((unsigned char *)src, nofNum, precision,
 
703
                                (unsigned char *)(compressBuf + 1),
 
704
                                            &nBytes, &offsetMantissa);
 
705
 
 
706
        *compressBuf = 0;
 
707
        status = G_zlib_write(fd, (unsigned char *)compressBuf, nBytes + 1);
 
708
 
 
709
    if (status < 0) {
 
710
        Rast3d_error("Rast3d_fpcompress_write_xdr_nums: write error");
 
711
        return 0;
 
712
    }
 
713
 
 
714
    return 1;
 
715
}
 
716
 
 
717
/*--------------------------------------------------------------------------*/
 
718
 
 
719
int
 
720
Rast3d_fpcompress_read_xdr_nums(int fd, char *dst, int nofNum, int fileBytes,
 
721
                         int precision, char *compressBuf, int isFloat)
 
722
{
 
723
    int status;
 
724
    int lengthEncode, lengthDecode;
 
725
    int nBytes;
 
726
    char *src, *dest, *srcStop;
 
727
    nBytes = (isFloat ? XDR_FLOAT_LENGTH : XDR_DOUBLE_LENGTH);
 
728
 
 
729
    status = G_zlib_read(fd, fileBytes, (unsigned char *)compressBuf,
 
730
                         nofNum * nBytes + 1);
 
731
 
 
732
    if (status < 0) {
 
733
        Rast3d_error("Rast3d_fpcompress_read_xdr_nums: read error");
 
734
        return 0;
 
735
    }
 
736
 
 
737
    /* This code is kept for backward compatibility */
 
738
    if (*compressBuf++ == 1) {
 
739
        status--;
 
740
        Rast3d_rle_decode(compressBuf, dst, nofNum * nBytes, 1,
 
741
                     &lengthEncode, &lengthDecode);
 
742
        if (*dst == ALL_NULL_CODE)
 
743
            Rast3d_fatal_error("Rast3d_fpcompress_read_xdr_nums: wrong code");
 
744
 
 
745
        if (status == nofNum * nBytes)
 
746
            status -= lengthDecode - lengthEncode;
 
747
 
 
748
        src = compressBuf + status - 1;
 
749
        srcStop = compressBuf + lengthEncode - 1;
 
750
        dest = compressBuf + (status - lengthEncode) + lengthDecode - 1;
 
751
        while (src != srcStop)
 
752
            *dest-- = *src--;
 
753
 
 
754
        src = dst;
 
755
        srcStop = src + lengthDecode;
 
756
        dest = compressBuf;
 
757
        while (src != srcStop)
 
758
            *dest++ = *src++;
 
759
    }
 
760
 
 
761
    if (isFloat)
 
762
        G_fpcompress_rearrangeDecodeFloats((unsigned char *)compressBuf, nofNum, precision,
 
763
                        (unsigned char *)dst);
 
764
    else
 
765
        G_fpcompress_rearrangeDecodeDoubles((unsigned char *)compressBuf, nofNum, precision,
 
766
                        (unsigned char *)dst);
 
767
 
 
768
    return 1;
 
769
}