GRASS Programmer's Manual
6.4.2(2012)
|
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 }