fpcompress.c 17 KB

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