GRASS Programmer's Manual  6.4.2(2012)
fpcompress.c
Go to the documentation of this file.
00001 #include <stdio.h>
00002 #include <stdlib.h>
00003 #include <sys/types.h>
00004 #include <unistd.h>
00005 #include "G3d_intern.h"
00006 
00007 /*--------------------------------------------------------------------------*/
00008 
00009 #define XDR_DOUBLE_LENGTH 8
00010 #define XDR_DOUBLE_NOF_EXP_BYTES 2
00011 #define XDR_FLOAT_LENGTH 4
00012 #define XDR_FLOAT_NOF_EXP_BYTES 1
00013 
00014 /*************
00015  * Only needed for transition */
00016 /* #define USE_LZW_COMPRESSION */
00017 
00018 /**************/
00019 
00020 /*--------------------------------------------------------------------------*/
00021 
00022 void G_fpcompress_printBinary(char *c, int numBits)
00023 {
00024     unsigned char bit;
00025     int i;
00026 
00027     bit = 1 << (numBits - 1);
00028 
00029     for (i = 0; i < numBits; i++) {
00030         printf("%d", (*((unsigned char *)c) & bit) != 0);
00031         bit >>= 1;
00032     }
00033 }
00034 
00035 /*--------------------------------------------------------------------------*/
00036 
00037 void G_fpcompress_dissectXdrDouble(unsigned char *numPointer)
00038 {
00039     char sign, exponent;
00040 
00041     sign = *numPointer >> 7;
00042     exponent = (*numPointer << 1) | (*(numPointer + 1) >> 7);
00043 
00044     printf("%f: sign = ", *((float *)numPointer));
00045     G_fpcompress_printBinary(&sign, 1);
00046     printf("   exp = ");
00047     G_fpcompress_printBinary(&exponent, 8);
00048     printf("   mantissa = ");
00049     G_fpcompress_printBinary((char *)(numPointer + 1), 7);
00050     G_fpcompress_printBinary((char *)(numPointer + 2), 8);
00051     G_fpcompress_printBinary((char *)(numPointer + 3), 8);
00052     printf("\n");
00053 }
00054 
00055 /*--------------------------------------------------------------------------*/
00056 
00057 static unsigned char clearMask[9] =
00058     { 255, 128, 192, 224, 240, 248, 252, 254, 255 };
00059 
00060 /*--------------------------------------------------------------------------*/
00061 
00062 #define ALL_NULL_CODE 2
00063 #define ZERO_NULL_CODE 1
00064 #define SOME_NULL_CODE 0
00065 
00066 /*--------------------------------------------------------------------------*/
00067 
00068 static void
00069 G_fpcompress_rearrangeEncodeFloats(unsigned char *src, int size,
00070                                    int precision, unsigned char *dst,
00071                                    int *length, int *offsetMantissa)
00072 {
00073     unsigned int nNullBits, nBits;
00074     register unsigned char *srcStop;
00075     register unsigned char *cp0, *cp1, *cp2, *cp3, *nullBits;
00076     unsigned char mask, isNull;
00077     int gt8, gt16, srcIncrement, nofNull;
00078     float *f;
00079 
00080     srcStop = src + size * XDR_FLOAT_LENGTH;
00081 
00082     if ((precision >= 23) || (precision == -1)) {
00083         cp3 = dst;
00084         cp2 = cp3 + size;
00085         cp1 = cp2 + size;
00086         cp0 = cp1 + size;
00087         while (srcStop != src) {
00088             *cp3++ = *src++;    /* sign + 7 exponent bits */
00089             *cp2++ = *src++;    /* 1 exponent bit + 7 ms mantissa bits */
00090             *cp1++ = *src++;    /* 8 mantissa bits */
00091             *cp0++ = *src++;    /* 8 ls mantissa bits */
00092         }
00093 
00094         *length = size * XDR_FLOAT_LENGTH;
00095         *offsetMantissa = size;
00096 
00097         return;
00098     }
00099 
00100     f = (float *)src;
00101     nofNull = 0;
00102     while (srcStop != (unsigned char *)f)
00103         nofNull += G3d_isXdrNullFloat(f++);
00104 
00105     if (nofNull == size) {
00106         *dst = (unsigned char)ALL_NULL_CODE;
00107 
00108         *length = 1;
00109         *offsetMantissa = 1;
00110 
00111         return;
00112     }
00113 
00114     precision += 1;             /* treat the ls exponent bit like an addl mantissa bit */
00115 
00116     *dst = (unsigned char)(nofNull == 0 ? ZERO_NULL_CODE : SOME_NULL_CODE);
00117 
00118     gt16 = precision > 16;
00119     gt8 = precision > 8;
00120     srcIncrement = 1 + (!gt8) + (!gt16);
00121 
00122     precision %= 8;
00123 
00124     nullBits = dst + 1;
00125     if (nofNull)
00126         cp0 = nullBits + size / 8 + ((size % 8) != 0);
00127     else
00128         cp0 = nullBits;
00129     cp3 = cp0 + size - nofNull;
00130     cp2 = cp3 + size - nofNull;
00131     cp1 = cp3 + (gt8 + gt16) * (size - nofNull);
00132 
00133     mask = clearMask[precision];
00134     nBits = nNullBits = 0;
00135 
00136     while (srcStop != src) {
00137         if (nofNull) {
00138             isNull = G3d_isXdrNullFloat((float *)src);
00139 
00140             if (nNullBits) {
00141                 *nullBits |= ((unsigned char)isNull << nNullBits++);
00142                 if (nNullBits == 8) {
00143                     nullBits++;
00144                     nNullBits = 0;
00145                 }
00146             }
00147             else {
00148                 *nullBits = (unsigned char)isNull;
00149                 nNullBits++;
00150             }
00151 
00152             if (isNull) {
00153                 src += XDR_FLOAT_LENGTH;
00154                 continue;
00155             }
00156         }
00157 
00158         /* printf ("write src cp0 %d %d (%d %d) %d\n", *src, *cp0, src, cp0, nullBits); */
00159 
00160         *cp0++ = *src++;
00161         if (gt8)
00162             *cp3++ = *src++;
00163         if (gt16)
00164             *cp2++ = *src++;
00165 
00166         if (nBits && precision) {
00167             *cp1 |= (unsigned char)((unsigned char)(*src & mask) >> nBits);
00168 
00169             /*printf ("%d\n", ((*src & mask) >> nBits) << nBits); */
00170 
00171             if (8 - nBits < precision) {
00172                 cp1++;
00173 
00174                 /*printf ("%d %d\n", *cp1, (*src & mask) << (8 - nBits)); */
00175 
00176                 *cp1 =
00177                     (unsigned char)((unsigned char)((*src & mask)) <<
00178                                     (8 - nBits));
00179                 nBits += precision - 8;
00180             }
00181             else {
00182                 nBits = (nBits + precision) % 8;
00183                 if (!nBits)
00184                     cp1++;
00185             }
00186         }
00187         else {
00188             *cp1 = (unsigned char)(*src & mask);
00189             /* printf ("%d %d %d\n", *cp1, *src, nBits); */
00190             nBits = (nBits + precision) % 8;
00191             if (!nBits)
00192                 cp1++;
00193         }
00194 
00195         src += srcIncrement;
00196     }
00197 
00198     *length = 1;                /* null-bit-vector indicator-byte */
00199 
00200     if (nofNull)                /* length of null-bit-vector */
00201         *length += size / 8 + ((size % 8) != 0);
00202 
00203     /* length of data */
00204     *length += (gt8 + gt16 + (precision == 0) + 1) * (size - nofNull) +
00205         ((precision * (size - nofNull)) / 8) +
00206         (((precision * (size - nofNull)) % 8) != 0);
00207 
00208     *offsetMantissa = size - nofNull;
00209 }
00210 
00211 /*--------------------------------------------------------------------------*/
00212 
00213 static void
00214 G_fpcompress_rearrangeEncodeDoubles(unsigned char *src, int size,
00215                                     int precision, unsigned char *dst,
00216                                     int *length, int *offsetMantissa)
00217 {
00218     unsigned int nNullBits, nBits;
00219     unsigned char isNull;
00220     register unsigned char *srcStop;
00221     register unsigned char *cp0, *cp1, *cp2, *cp3;
00222     register unsigned char *cp4, *cp5, *cp6, *cp7, *nullBits;
00223     unsigned char mask;
00224     int gt8, gt16, gt24, gt32, gt40, gt48, srcIncrement, nofNull;
00225     double *d;
00226 
00227     srcStop = src + size * XDR_DOUBLE_LENGTH;
00228 
00229     if ((precision >= 52) || (precision == -1)) {
00230         cp7 = dst;
00231         cp6 = cp7 + size;
00232         cp5 = cp6 + size;
00233         cp4 = cp5 + size;
00234         cp3 = cp4 + size;
00235         cp2 = cp3 + size;
00236         cp1 = cp2 + size;
00237         cp0 = cp1 + size;
00238 
00239         while (srcStop != src) {
00240             *cp7++ = *src++;    /* sign + 7 ms exponent bits */
00241             *cp6++ = *src++;    /* 4 exponent bits + 4 ms mantissa bits */
00242             *cp5++ = *src++;    /* 8 mantissa bits */
00243             *cp4++ = *src++;
00244             *cp3++ = *src++;
00245             *cp2++ = *src++;
00246             *cp1++ = *src++;
00247             *cp0++ = *src++;    /* 8 ls mantissa bits */
00248         }
00249 
00250         *length = size * XDR_DOUBLE_LENGTH;
00251         *offsetMantissa = size;
00252 
00253         return;
00254     }
00255 
00256     precision += 4;             /* treat the 4 ls exponent bits like addl mantissa bits */
00257 
00258     d = (double *)src;
00259     nofNull = 0;
00260     while (srcStop != (unsigned char *)d)
00261         nofNull += G3d_isXdrNullDouble(d++);
00262 
00263     if (nofNull == size) {
00264         *dst = (unsigned char)ALL_NULL_CODE;
00265 
00266         *length = 1;
00267         *offsetMantissa = 1;
00268 
00269         return;
00270     }
00271 
00272     *dst = (unsigned char)(nofNull == 0 ? ZERO_NULL_CODE : SOME_NULL_CODE);
00273 
00274     gt48 = precision > 48;
00275     gt40 = precision > 40;
00276     gt32 = precision > 32;
00277     gt24 = precision > 24;
00278     gt16 = precision > 16;
00279     gt8 = precision > 8;
00280     srcIncrement =
00281         1 + (!gt8) + (!gt16) + (!gt24) + (!gt32) + (!gt40) + (!gt48);
00282 
00283     precision %= 8;
00284 
00285     nullBits = dst + 1;
00286     if (nofNull)
00287         cp0 = nullBits + size / 8 + ((size % 8) != 0);
00288     else
00289         cp0 = nullBits;
00290     cp7 = cp0 + size - nofNull;
00291     cp6 = cp7 + size - nofNull;
00292     cp5 = cp6 + size - nofNull;
00293     cp4 = cp5 + size - nofNull;
00294     cp3 = cp4 + size - nofNull;
00295     cp2 = cp3 + size - nofNull;
00296     cp1 = cp7 + (gt8 + gt16 + gt24 + gt32 + gt40 + gt48) * (size - nofNull);
00297 
00298     mask = clearMask[precision];
00299     nBits = nNullBits = 0;
00300 
00301     while (srcStop != src) {
00302         if (nofNull) {
00303             isNull = G3d_isXdrNullDouble((double *)src);
00304 
00305             if (nNullBits) {
00306                 *nullBits |= ((unsigned char)isNull << nNullBits++);
00307                 if (nNullBits == 8) {
00308                     nullBits++;
00309                     nNullBits = 0;
00310                 }
00311             }
00312             else {
00313                 *nullBits = (unsigned char)isNull;
00314                 nNullBits++;
00315             }
00316 
00317             if (isNull) {
00318                 src += XDR_DOUBLE_LENGTH;
00319                 continue;
00320             }
00321         }
00322 
00323         *cp0++ = *src++;
00324         if (gt32) {
00325             *cp7++ = *src++;
00326             *cp6++ = *src++;
00327             *cp5++ = *src++;
00328 
00329             if (gt32)
00330                 *cp4++ = *src++;
00331             if (gt40)
00332                 *cp3++ = *src++;
00333             if (gt48)
00334                 *cp2++ = *src++;
00335         }
00336         else {
00337             if (gt8)
00338                 *cp7++ = *src++;
00339             if (gt16)
00340                 *cp6++ = *src++;
00341             if (gt24)
00342                 *cp5++ = *src++;
00343         }
00344 
00345         if (nBits && precision) {
00346             *cp1 |= (unsigned char)((unsigned char)(*src & mask) >> nBits);
00347             if (8 - nBits < precision) {
00348                 cp1++;
00349                 *cp1 =
00350                     (unsigned char)(((unsigned char)(*src & mask)) <<
00351                                     (8 - nBits));
00352                 nBits += precision - 8;
00353             }
00354             else {
00355                 nBits = (nBits + precision) % 8;
00356                 if (!nBits)
00357                     cp1++;
00358             }
00359         }
00360         else {
00361             *cp1 = (unsigned char)(*src & mask);
00362             nBits = (nBits + precision) % 8;
00363             if (!nBits)
00364                 cp1++;
00365         }
00366 
00367         src += srcIncrement;
00368     }
00369 
00370     *length = 1;
00371 
00372     if (nofNull)
00373         *length += size / 8 + ((size % 8) != 0);
00374 
00375     *length +=
00376         (1 + gt8 + gt16 + gt24 + gt32 + gt40 + gt48 +
00377          (precision ==
00378           0)) * (size - nofNull) + ((precision * (size - nofNull)) / 8) +
00379         (((precision * (size - nofNull)) % 8) != 0);
00380 
00381     if (gt8)
00382         *offsetMantissa = 2 * (size - nofNull);
00383     else
00384         *offsetMantissa = *length;
00385 }
00386 
00387 /*--------------------------------------------------------------------------*/
00388 
00389 static void
00390 G_fpcompress_rearrangeDecodeFloats(unsigned char *src, int size,
00391                                    int precision, unsigned char *dst)
00392 {
00393     unsigned int nNullBits, nBits;
00394     register unsigned char *dstStop;
00395     register unsigned char *cp0, *cp1, *cp2, *cp3, *nullBits;
00396     unsigned char mask, isNull;
00397     int gt8, gt16, dstIncrement, nofNull;
00398     float *f, *fStop;
00399 
00400     if ((precision != -1) && (precision <= 15)) {       /* 23 - 8 */
00401         cp3 = dst + 3;
00402         dstStop = dst + XDR_FLOAT_LENGTH * size + 3;
00403         while (dstStop != cp3) {
00404             *cp3 = 0;
00405             cp3 += XDR_FLOAT_LENGTH;
00406         }
00407 
00408         if (precision <= 7) {
00409             cp3 = dst + 2;
00410             dstStop = dst + XDR_FLOAT_LENGTH * size + 2;
00411             while (dstStop != cp3) {
00412                 *cp3 = 0;
00413                 cp3 += XDR_FLOAT_LENGTH;
00414             }
00415         }
00416     }
00417 
00418     dstStop = dst + size * XDR_FLOAT_LENGTH;
00419 
00420     if ((precision >= 23) || (precision == -1)) {
00421         cp3 = src;
00422         cp2 = cp3 + size;
00423         cp1 = cp2 + size;
00424         cp0 = cp1 + size;
00425         while (dstStop != dst) {
00426             *dst++ = *cp3++;
00427             *dst++ = *cp2++;
00428             *dst++ = *cp1++;
00429             *dst++ = *cp0++;
00430         }
00431 
00432         return;
00433     }
00434 
00435     if (*src == (unsigned char)ALL_NULL_CODE) {
00436         f = (float *)dst;
00437         while (dstStop != (unsigned char *)f)
00438             G3d_setXdrNullFloat(f++);
00439 
00440         return;
00441     }
00442 
00443     precision += 1;             /* treat the ls exponent bit like an addl mantissa bit */
00444 
00445     gt16 = precision > 16;
00446     gt8 = precision > 8;
00447     dstIncrement = 1 + (!gt8) + (!gt16);
00448 
00449     precision %= 8;
00450 
00451     nofNull = 0;
00452     nullBits = src + 1;
00453     nNullBits = 0;
00454     if (*src == (unsigned char)SOME_NULL_CODE) {
00455         f = (float *)src;
00456         fStop = (float *)(src + size * XDR_FLOAT_LENGTH);
00457         while (fStop != f++) {
00458             nofNull += ((*nullBits & ((unsigned char)1 << nNullBits++)) != 0);
00459             if (nNullBits == 8) {
00460                 nullBits++;
00461                 nNullBits = 0;
00462             }
00463         }
00464     }
00465 
00466     nullBits = src + 1;
00467     if (nofNull)
00468         cp0 = nullBits + size / 8 + ((size % 8) != 0);
00469     else
00470         cp0 = nullBits;
00471     cp3 = cp0 + size - nofNull;
00472     cp2 = cp3 + size - nofNull;
00473     cp1 = cp3 + (gt8 + gt16) * (size - nofNull);
00474 
00475     mask = clearMask[precision];
00476     nBits = nNullBits = 0;
00477 
00478     while (dstStop != dst) {
00479         if (nofNull) {
00480             isNull = *nullBits & ((unsigned char)1 << nNullBits++);
00481 
00482             if (nNullBits == 8) {
00483                 nullBits++;
00484                 nNullBits = 0;
00485             }
00486 
00487             if (isNull) {
00488                 G3d_setXdrNullFloat((float *)dst);
00489                 dst += XDR_FLOAT_LENGTH;
00490                 continue;
00491             }
00492         }
00493 
00494         *dst++ = *cp0++;
00495         if (gt8)
00496             *dst++ = *cp3++;
00497         if (gt16)
00498             *dst++ = *cp2++;
00499 
00500         if (nBits && precision) {
00501             *dst = (unsigned char)((*cp1 << nBits) & mask);
00502 
00503             if (8 - nBits < precision) {
00504                 cp1++;
00505                 *dst |= (unsigned char)((*cp1 >> (8 - nBits)) & mask);
00506                 nBits += precision - 8;
00507             }
00508             else {
00509                 nBits = (nBits + precision) % 8;
00510                 if (!nBits)
00511                     cp1++;
00512             }
00513         }
00514         else {
00515             *dst = (unsigned char)(*cp1 & mask);
00516             nBits = (nBits + precision) % 8;
00517             if (!nBits)
00518                 cp1++;
00519         }
00520 
00521         dst += dstIncrement;
00522     }
00523 }
00524 
00525 /*--------------------------------------------------------------------------*/
00526 
00527 static void
00528 G_fpcompress_rearrangeDecodeDoubles(unsigned char *src, int size,
00529                                     int precision, unsigned char *dst)
00530 {
00531     unsigned int nNullBits, nBits;
00532     register unsigned char *dstStop;
00533     register unsigned char *cp0, *cp1, *cp2, *cp3;
00534     register unsigned char *cp4, *cp5, *cp6, *cp7, *nullBits;
00535     unsigned char mask, isNull;
00536     int gt8, gt16, gt24, gt32, gt40, gt48, dstIncrement, offs, nofNull;
00537     double *d, *dStop;
00538 
00539     if ((precision != -1) && (precision <= 44)) {
00540         for (offs = 7; offs >= (precision + 19) / 8; offs--) {
00541             cp7 = dst + offs;
00542             dstStop = dst + XDR_DOUBLE_LENGTH * size + offs;
00543             while (dstStop != cp7) {
00544                 *cp7 = 0;
00545                 cp7 += XDR_DOUBLE_LENGTH;
00546             }
00547         }
00548     }
00549 
00550     dstStop = dst + size * XDR_DOUBLE_LENGTH;
00551 
00552     if ((precision >= 52) || (precision == -1)) {
00553         cp7 = src;
00554         cp6 = cp7 + size;
00555         cp5 = cp6 + size;
00556         cp4 = cp5 + size;
00557         cp3 = cp4 + size;
00558         cp2 = cp3 + size;
00559         cp1 = cp2 + size;
00560         cp0 = cp1 + size;
00561 
00562         while (dstStop != dst) {
00563             *dst++ = *cp7++;
00564             *dst++ = *cp6++;
00565             *dst++ = *cp5++;
00566             *dst++ = *cp4++;
00567             *dst++ = *cp3++;
00568             *dst++ = *cp2++;
00569             *dst++ = *cp1++;
00570             *dst++ = *cp0++;
00571         }
00572 
00573         return;
00574     }
00575 
00576     if (*src == (unsigned char)ALL_NULL_CODE) {
00577         /*printf ("all null\n"); */
00578         d = (double *)dst;
00579         while (dstStop != (unsigned char *)d)
00580             G3d_setXdrNullDouble(d++);
00581 
00582         return;
00583     }
00584 
00585     precision += 4;             /* treat the 4 ls exponent bits like addl mantissa bits */
00586 
00587     gt48 = precision > 48;
00588     gt40 = precision > 40;
00589     gt32 = precision > 32;
00590     gt24 = precision > 24;
00591     gt16 = precision > 16;
00592     gt8 = precision > 8;
00593 
00594     dstIncrement =
00595         1 + (!gt8) + (!gt16) + (!gt24) + (!gt32) + (!gt40) + (!gt48);
00596 
00597     precision %= 8;
00598 
00599     nofNull = 0;
00600     nullBits = src + 1;
00601     nNullBits = 0;
00602     if (*src == (unsigned char)SOME_NULL_CODE) {
00603         d = (double *)src;
00604         dStop = (double *)(src + size * XDR_DOUBLE_LENGTH);
00605         while (dStop != d++) {
00606             nofNull += ((*nullBits & ((unsigned char)1 << nNullBits++)) != 0);
00607             if (nNullBits == 8) {
00608                 nullBits++;
00609                 nNullBits = 0;
00610             }
00611         }
00612     }
00613 
00614     nullBits = src + 1;
00615     if (nofNull)
00616         cp0 = nullBits + size / 8 + ((size % 8) != 0);
00617     else
00618         cp0 = nullBits;
00619     cp7 = cp0 + size - nofNull;
00620     cp6 = cp7 + size - nofNull;
00621     cp5 = cp6 + size - nofNull;
00622     cp4 = cp5 + size - nofNull;
00623     cp3 = cp4 + size - nofNull;
00624     cp2 = cp3 + size - nofNull;
00625     cp1 = cp7 + (gt8 + gt16 + gt24 + gt32 + gt40 + gt48) * (size - nofNull);
00626 
00627     mask = clearMask[precision];
00628     nBits = nNullBits = 0;
00629 
00630     while (dstStop != dst) {
00631         if (nofNull) {
00632             isNull = *nullBits & ((unsigned char)1 << nNullBits++);
00633 
00634             if (nNullBits == 8) {
00635                 nullBits++;
00636                 nNullBits = 0;
00637             }
00638 
00639             if (isNull) {
00640                 G3d_setXdrNullDouble((double *)dst);
00641                 dst += XDR_DOUBLE_LENGTH;
00642                 continue;
00643             }
00644         }
00645 
00646         *dst++ = *cp0++;
00647         if (gt32) {
00648             *dst++ = *cp7++;
00649             *dst++ = *cp6++;
00650             *dst++ = *cp5++;
00651 
00652             if (gt32)
00653                 *dst++ = *cp4++;
00654             if (gt40)
00655                 *dst++ = *cp3++;
00656             if (gt48)
00657                 *dst++ = *cp2++;
00658         }
00659         else {
00660             if (gt8)
00661                 *dst++ = *cp7++;
00662             if (gt16)
00663                 *dst++ = *cp6++;
00664             if (gt24)
00665                 *dst++ = *cp5++;
00666         }
00667 
00668         if (nBits && precision) {
00669             *dst = (unsigned char)((*cp1 << nBits) & mask);
00670 
00671             if (8 - nBits < precision) {
00672                 cp1++;
00673                 *dst |= (unsigned char)((*cp1 >> (8 - nBits)) & mask);
00674                 nBits += precision - 8;
00675             }
00676             else {
00677                 nBits = (nBits + precision) % 8;
00678                 if (!nBits)
00679                     cp1++;
00680             }
00681         }
00682         else {
00683             *dst = (unsigned char)(*cp1 & mask);
00684             nBits = (nBits + precision) % 8;
00685             if (!nBits)
00686                 cp1++;
00687         }
00688 
00689         dst += dstIncrement;
00690     }
00691 }
00692 
00693 /*--------------------------------------------------------------------------*/
00694 
00695 /* IMPORTANT!!! this function changes the "src". */
00696 
00697 int
00698 G_fpcompress_writeXdrNums(int fd, char *src, int nofNum, int precision,
00699                           char *compressBuf, int isFloat, int useRle,
00700                           int useLzw)
00701 {
00702     /* this table is used to determine the number of bits that should be used */
00703     /* with G_lzw_write (), since a too large number of bits may reduce the */
00704     /* compression. the values in the table are either based on experience for */
00705     /* the small values, or guesses for the larger values. */
00706 
00707     int status, rleLength, nBytes, offsetMantissa;
00708     char *dst, *srcStop;
00709 
00710     if (isFloat)
00711         G_fpcompress_rearrangeEncodeFloats(src, nofNum, precision,
00712                                            compressBuf + 1,
00713                                            &nBytes, &offsetMantissa);
00714     else
00715         G_fpcompress_rearrangeEncodeDoubles(src, nofNum, precision,
00716                                             compressBuf + 1,
00717                                             &nBytes, &offsetMantissa);
00718 
00719 #ifdef USE_LZW_COMPRESSION
00720     G_lzw_set_bits(9);
00721 #endif
00722 
00723     if (useRle == G3D_USE_RLE)
00724         rleLength = G_rle_count_only(compressBuf + 1, offsetMantissa, 1);
00725 
00726     if ((useRle == G3D_USE_RLE) && (rleLength < offsetMantissa)) {
00727 
00728         G_rle_encode(compressBuf + 1, src, offsetMantissa, 1);
00729         srcStop = src + rleLength;
00730         dst = compressBuf + 1 + offsetMantissa - rleLength;
00731         while (src != srcStop)
00732             *dst++ = *src++;
00733 
00734         *(compressBuf + offsetMantissa - rleLength) = 1;
00735 
00736         if (useLzw == G3D_USE_LZW)
00737 #ifdef USE_LZW_COMPRESSION
00738             status = G_lzw_write(fd, compressBuf + offsetMantissa - rleLength,
00739                                  nBytes - offsetMantissa + rleLength + 1);
00740 #else
00741             status = G_zlib_write(fd,
00742                                   (unsigned char *)(compressBuf +
00743                                                     offsetMantissa -
00744                                                     rleLength),
00745                                   nBytes - offsetMantissa + rleLength + 1);
00746 #endif
00747         else
00748 #ifdef USE_LZW_COMPRESSION
00749             status =
00750                 G_lzw_write_noCompress(fd,
00751                                        compressBuf + offsetMantissa -
00752                                        rleLength,
00753                                        nBytes - offsetMantissa + rleLength +
00754                                        1);
00755 #else
00756             status = G_zlib_write_noCompress(fd,
00757                                              (unsigned char *)(compressBuf +
00758                                                                offsetMantissa
00759                                                                - rleLength),
00760                                              nBytes - offsetMantissa +
00761                                              rleLength + 1);
00762 #endif
00763     }
00764     else {
00765 
00766         *compressBuf = 0;
00767         if (useLzw == G3D_USE_LZW)
00768 #ifdef USE_LZW_COMPRESSION
00769             status = G_lzw_write(fd, compressBuf, nBytes + 1);
00770 #else
00771             status =
00772                 G_zlib_write(fd, (unsigned char *)compressBuf, nBytes + 1);
00773 #endif
00774         else
00775 #ifdef USE_LZW_COMPRESSION
00776             status = G_lzw_write_noCompress(fd, compressBuf, nBytes + 1);
00777 #else
00778             status =
00779                 G_zlib_write_noCompress(fd, (unsigned char *)compressBuf,
00780                                         nBytes + 1);
00781 #endif
00782     }
00783 
00784     if (status < 0) {
00785         G3d_error("G_fpcompress_writeXdrNums: write error");
00786         return 0;
00787     }
00788 
00789     return 1;
00790 }
00791 
00792 /*--------------------------------------------------------------------------*/
00793 
00794 int
00795 G_fpcompress_writeXdrFloats(int fd, char *src, int nofNum, int precision,
00796                             char *compressBuf, int useRle, int useLzw)
00797 {
00798     if (!G_fpcompress_writeXdrNums(fd, src, nofNum, precision, compressBuf, 1,
00799                                    useRle, useLzw)) {
00800         G3d_error
00801             ("G_fpcompress_writeXdrFloats: error in G_fpcompress_writeXdrNums");
00802         return 0;
00803     }
00804 
00805     return 1;
00806 }
00807 
00808 /*--------------------------------------------------------------------------*/
00809 
00810 int
00811 G_fpcompress_writeXdrDouble(int fd, char *src, int nofNum, int precision,
00812                             char *compressBuf, int useRle, int useLzw)
00813 {
00814     if (!G_fpcompress_writeXdrNums(fd, src, nofNum, precision, compressBuf, 0,
00815                                    useRle, useLzw)) {
00816         G3d_error
00817             ("G_fpcompress_writeXdrDouble: error in G_fpcompress_writeXdrNums");
00818         return 0;
00819     }
00820 
00821     return 1;
00822 }
00823 
00824 /*--------------------------------------------------------------------------*/
00825 
00826 int
00827 G_fpcompress_readXdrNums(int fd, char *dst, int nofNum, int fileBytes,
00828                          int precision, char *compressBuf, int isFloat)
00829 {
00830     int status, lengthEncode, lengthDecode;
00831     int nBytes;
00832     char *src, *dest, *srcStop;
00833 
00834     nBytes = (isFloat ? XDR_FLOAT_LENGTH : XDR_DOUBLE_LENGTH);
00835 
00836 #ifdef USE_LZW_COMPRESSION
00837     status = G_lzw_read2(fd, compressBuf, nofNum * nBytes + 1, fileBytes);
00838 #else
00839     status = G_zlib_read(fd, fileBytes, (unsigned char *)compressBuf,
00840                          nofNum * nBytes + 1);
00841 #endif
00842     if (status < 0) {
00843         G3d_error("G_fpcompress_readXdrNums: read error");
00844         return 0;
00845     }
00846 
00847     if (*compressBuf++ == 1) {
00848         status--;
00849         G_rle_decode(compressBuf, dst, nofNum * nBytes, 1,
00850                      &lengthEncode, &lengthDecode);
00851         if (*dst == ALL_NULL_CODE)
00852             G3d_fatalError("G_fpcompress_readXdrNums: wrong code");
00853 
00854         if (status == nofNum * nBytes)
00855             status -= lengthDecode - lengthEncode;
00856 
00857         src = compressBuf + status - 1;
00858         srcStop = compressBuf + lengthEncode - 1;
00859         dest = compressBuf + (status - lengthEncode) + lengthDecode - 1;
00860         while (src != srcStop)
00861             *dest-- = *src--;
00862 
00863         src = dst;
00864         srcStop = src + lengthDecode;
00865         dest = compressBuf;
00866         while (src != srcStop)
00867             *dest++ = *src++;
00868     }
00869 
00870     if (isFloat)
00871         G_fpcompress_rearrangeDecodeFloats(compressBuf, nofNum, precision,
00872                                            dst);
00873     else
00874         G_fpcompress_rearrangeDecodeDoubles(compressBuf, nofNum, precision,
00875                                             dst);
00876 
00877     return 1;
00878 }
00879 
00880 /*--------------------------------------------------------------------------*/
00881 
00882 int
00883 G_fpcompress_readXdrFloats(int fd, char *dst, int nofNum, int fileBytes,
00884                            int precision, char *compressBuf)
00885 {
00886     if (!G_fpcompress_readXdrNums(fd, dst, nofNum, fileBytes, precision,
00887                                   compressBuf, 1)) {
00888         G3d_error
00889             ("G_fpcompress_readXdrFloats: error in G_fpcompress_readXdrNums");
00890         return 0;
00891     }
00892 
00893     return 1;
00894 }
00895 
00896 /*--------------------------------------------------------------------------*/
00897 
00898 int
00899 G_fpcompress_readXdrDoubles(int fd, char *dst, int nofNum, int fileBytes,
00900                             int precision, char *compressBuf)
00901 {
00902     if (!G_fpcompress_readXdrNums(fd, dst, nofNum, fileBytes, precision,
00903                                   compressBuf, 0)) {
00904         G3d_error
00905             ("G_fpcompress_readXdrDouble: error in G_fpcompress_readXdrNums");
00906         return 0;
00907     }
00908 
00909     return 1;
00910 }
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines