fpcompress.c 21 KB

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