PageRenderTime 81ms CodeModel.GetById 32ms RepoModel.GetById 1ms app.codeStats 0ms

/pyxdr/xdrfile.c

https://bitbucket.org/mczwier/pyxdr
C | 2597 lines | 2015 code | 301 blank | 281 comment | 365 complexity | 7e4802bf040b41161dc992acdebacd2b MD5 | raw file
Possible License(s): LGPL-3.0

Large files files are truncated, but you can click here to view the full file

  1. /* -*- mode: c; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*-
  2. *
  3. * $Id$
  4. *
  5. * Copyright (c) Erik Lindahl, David van der Spoel 2003,2004.
  6. * Coordinate compression (c) by Frans van Hoesel.
  7. *
  8. * This program is free software; you can redistribute it and/or
  9. * modify it under the terms of the GNU Lesser General Public License
  10. * as published by the Free Software Foundation; either version 3
  11. * of the License, or (at your option) any later version.
  12. */
  13. /* Get HAVE_RPC_XDR_H, F77_FUNC from config.h if available */
  14. #ifdef HAVE_CONFIG_H
  15. #include <config.h>
  16. #endif
  17. #include <stdio.h>
  18. #include <stdlib.h>
  19. #include <string.h>
  20. #include <math.h>
  21. #include <limits.h>
  22. #define _FILE_OFFSET_BITS 64
  23. /* get fixed-width types if we are using ANSI C99 */
  24. #ifdef HAVE_STDINT_H
  25. # include <stdint.h>
  26. #elif (defined HAVE_INTTYPES_H)
  27. # include <inttypes.h>
  28. #endif
  29. #ifdef HAVE_RPC_XDR_H
  30. # include <rpc/rpc.h>
  31. # include <rpc/xdr.h>
  32. #endif
  33. #include "xdrfile.h"
  34. /* Default FORTRAN name mangling is: lower case name, append underscore */
  35. #ifndef F77_FUNC
  36. #define F77_FUNC(name,NAME) name ## _
  37. #endif
  38. char *exdr_message[exdrNR] = {
  39. "OK",
  40. "Header",
  41. "String",
  42. "Double",
  43. "Integer",
  44. "Float",
  45. "Unsigned integer",
  46. "Compressed 3D coordinate",
  47. "Closing file",
  48. "Magic number",
  49. "Not enough memory",
  50. "End of file",
  51. "File not found"
  52. };
  53. /*
  54. * Declare our own XDR routines statically if no libraries are present.
  55. * Actual implementation is at the end of this file.
  56. *
  57. * We don't want the low-level XDR implementation as part of the Gromacs
  58. * documentation, so skip it for doxygen too...
  59. */
  60. #if (!defined HAVE_RPC_XDR_H && !defined DOXYGEN)
  61. enum xdr_op
  62. {
  63. XDR_ENCODE = 0,
  64. XDR_DECODE = 1,
  65. XDR_FREE = 2
  66. };
  67. /* We need integer types that are guaranteed to be 4 bytes wide.
  68. * If ANSI C99 headers were included they are already defined
  69. * as int32_t and uint32_t. Check, and if not define them ourselves.
  70. * Since it is just our workaround for missing ANSI C99 types, avoid adding
  71. * it to the doxygen documentation.
  72. */
  73. #if !(defined INT32_MAX || defined DOXYGEN)
  74. # if (INT_MAX == 2147483647)
  75. # define int32_t int
  76. # define uint32_t unsigned int
  77. # define INT32_MAX 2147483647
  78. # elif (LONG_MAX == 2147483647)
  79. # define int32_t long
  80. # define uint32_t unsigned long
  81. # define INT32_MAX 2147483647L
  82. # else
  83. # error ERROR: No 32 bit wide integer type found!
  84. # error Use system XDR libraries instead, or update xdrfile.c
  85. # endif
  86. #endif
  87. typedef struct XDR XDR;
  88. struct XDR
  89. {
  90. enum xdr_op x_op;
  91. struct xdr_ops
  92. {
  93. int (*x_getlong) (XDR *__xdrs, int32_t *__lp);
  94. int (*x_putlong) (XDR *__xdrs, int32_t *__lp);
  95. int (*x_getbytes) (XDR *__xdrs, char *__addr, unsigned int __len);
  96. int (*x_putbytes) (XDR *__xdrs, char *__addr, unsigned int __len);
  97. /* two next routines are not 64-bit IO safe - don't use! */
  98. unsigned int (*x_getpostn) (XDR *__xdrs);
  99. int (*x_setpostn) (XDR *__xdrs, unsigned int __pos);
  100. void (*x_destroy) (XDR *__xdrs);
  101. }
  102. *x_ops;
  103. char *x_private;
  104. };
  105. static int xdr_char (XDR *xdrs, char *ip);
  106. static int xdr_u_char (XDR *xdrs, unsigned char *ip);
  107. static int xdr_short (XDR *xdrs, short *ip);
  108. static int xdr_u_short (XDR *xdrs, unsigned short *ip);
  109. static int xdr_int (XDR *xdrs, int *ip);
  110. static int xdr_u_int (XDR *xdrs, unsigned int *ip);
  111. static int xdr_float (XDR *xdrs, float *ip);
  112. static int xdr_double (XDR *xdrs, double *ip);
  113. static int xdr_string (XDR *xdrs, char **ip, unsigned int maxsize);
  114. static int xdr_opaque (XDR *xdrs, char *cp, unsigned int cnt);
  115. static void xdrstdio_create (XDR *xdrs, FILE *fp, enum xdr_op xop);
  116. #define xdr_getpos(xdrs) \
  117. (*(xdrs)->x_ops->x_getpostn)(xdrs)
  118. #define xdr_setpos(xdrs, pos) \
  119. (*(xdrs)->x_ops->x_setpostn)(xdrs, pos)
  120. #define xdr_destroy(xdrs) \
  121. do { \
  122. if ((xdrs)->x_ops->x_destroy) \
  123. (*(xdrs)->x_ops->x_destroy)(xdrs); \
  124. } while (0)
  125. #endif /* end of our own XDR declarations */
  126. /** Contents of the abstract XDRFILE data structure.
  127. *
  128. * @internal
  129. *
  130. * This structure is used to provide an XDR file interface that is
  131. * virtual identical to the standard UNIX fopen/fread/fwrite/fclose.
  132. */
  133. struct XDRFILE
  134. {
  135. FILE * fp; /**< pointer to standard C library file handle */
  136. XDR * xdr; /**< pointer to corresponding XDR handle */
  137. char mode; /**< r=read, w=write, a=append */
  138. int * buf1; /**< Buffer for internal use */
  139. int buf1size; /**< Current allocated length of buf1 */
  140. int * buf2; /**< Buffer for internal use */
  141. int buf2size; /**< Current allocated length of buf2 */
  142. };
  143. /*************************************************************
  144. * Implementation of higher-level routines to read/write *
  145. * portable data based on the XDR standard. These should be *
  146. * called from C - see further down for Fortran77 wrappers. *
  147. *************************************************************/
  148. XDRFILE *
  149. xdrfile_open(const char *path, const char *mode)
  150. {
  151. char newmode[5];
  152. enum xdr_op xdrmode;
  153. XDRFILE *xfp;
  154. /* make sure XDR files are opened in binary mode... */
  155. if(*mode=='w' || *mode=='W')
  156. {
  157. sprintf(newmode,"wb+");
  158. xdrmode=XDR_ENCODE;
  159. } else if(*mode == 'a' || *mode == 'A')
  160. {
  161. sprintf(newmode,"ab+");
  162. xdrmode = XDR_ENCODE;
  163. } else if(*mode == 'r' || *mode == 'R')
  164. {
  165. sprintf(newmode,"rb");
  166. xdrmode = XDR_DECODE;
  167. } else /* cannot determine mode */
  168. return NULL;
  169. if((xfp=(XDRFILE *)malloc(sizeof(XDRFILE)))==NULL)
  170. return NULL;
  171. if((xfp->fp=fopen(path,newmode))==NULL)
  172. {
  173. free(xfp);
  174. return NULL;
  175. }
  176. if((xfp->xdr=(XDR *)malloc(sizeof(XDR)))==NULL)
  177. {
  178. fclose(xfp->fp);
  179. free(xfp);
  180. return NULL;
  181. }
  182. xfp->mode=*mode;
  183. xdrstdio_create((XDR *)(xfp->xdr),xfp->fp,xdrmode);
  184. xfp->buf1 = xfp->buf2 = NULL;
  185. xfp->buf1size = xfp->buf2size = 0;
  186. return xfp;
  187. }
  188. int
  189. xdrfile_close(XDRFILE *xfp)
  190. {
  191. int ret=exdrCLOSE;
  192. if(xfp)
  193. {
  194. /* flush and destroy XDR stream */
  195. if(xfp->xdr)
  196. xdr_destroy((XDR *)(xfp->xdr));
  197. free(xfp->xdr);
  198. /* close the file */
  199. ret=fclose(xfp->fp);
  200. if(xfp->buf1size)
  201. free(xfp->buf1);
  202. if(xfp->buf2size)
  203. free(xfp->buf2);
  204. free(xfp);
  205. }
  206. return ret; /* return 0 if ok */
  207. }
  208. int
  209. xdrfile_read_int(int *ptr, int ndata, XDRFILE* xfp)
  210. {
  211. int i=0;
  212. /* read write is encoded in the XDR struct */
  213. while(i<ndata && xdr_int((XDR *)(xfp->xdr),ptr+i))
  214. i++;
  215. return i;
  216. }
  217. int
  218. xdrfile_write_int(int *ptr, int ndata, XDRFILE* xfp)
  219. {
  220. int i=0;
  221. /* read write is encoded in the XDR struct */
  222. while(i<ndata && xdr_int((XDR *)(xfp->xdr),ptr+i))
  223. i++;
  224. return i;
  225. }
  226. int
  227. xdrfile_read_uint(unsigned int *ptr, int ndata, XDRFILE* xfp)
  228. {
  229. int i=0;
  230. /* read write is encoded in the XDR struct */
  231. while(i<ndata && xdr_u_int((XDR *)(xfp->xdr),ptr+i))
  232. i++;
  233. return i;
  234. }
  235. int
  236. xdrfile_write_uint(unsigned int *ptr, int ndata, XDRFILE* xfp)
  237. {
  238. int i=0;
  239. /* read write is encoded in the XDR struct */
  240. while(i<ndata && xdr_u_int((XDR *)(xfp->xdr),ptr+i))
  241. i++;
  242. return i;
  243. }
  244. int
  245. xdrfile_read_char(char *ptr, int ndata, XDRFILE* xfp)
  246. {
  247. int i=0;
  248. /* read write is encoded in the XDR struct */
  249. while(i<ndata && xdr_char((XDR *)(xfp->xdr),ptr+i))
  250. i++;
  251. return i;
  252. }
  253. int
  254. xdrfile_write_char(char *ptr, int ndata, XDRFILE* xfp)
  255. {
  256. int i=0;
  257. /* read write is encoded in the XDR struct */
  258. while(i<ndata && xdr_char((XDR *)(xfp->xdr),ptr+i))
  259. i++;
  260. return i;
  261. }
  262. int
  263. xdrfile_read_uchar(unsigned char *ptr, int ndata, XDRFILE* xfp)
  264. {
  265. int i=0;
  266. /* read write is encoded in the XDR struct */
  267. while(i<ndata && xdr_u_char((XDR *)(xfp->xdr),ptr+i))
  268. i++;
  269. return i;
  270. }
  271. int
  272. xdrfile_write_uchar(unsigned char *ptr, int ndata, XDRFILE* xfp)
  273. {
  274. int i=0;
  275. /* read write is encoded in the XDR struct */
  276. while(i<ndata && xdr_u_char((XDR *)(xfp->xdr),ptr+i))
  277. i++;
  278. return i;
  279. }
  280. int
  281. xdrfile_read_short(short *ptr, int ndata, XDRFILE* xfp)
  282. {
  283. int i=0;
  284. /* read write is encoded in the XDR struct */
  285. while(i<ndata && xdr_short((XDR *)(xfp->xdr),ptr+i))
  286. i++;
  287. return i;
  288. }
  289. int
  290. xdrfile_write_short(short *ptr, int ndata, XDRFILE* xfp)
  291. {
  292. int i=0;
  293. /* read write is encoded in the XDR struct */
  294. while(i<ndata && xdr_short((XDR *)(xfp->xdr),ptr+i))
  295. i++;
  296. return i;
  297. }
  298. int
  299. xdrfile_read_ushort(unsigned short *ptr, int ndata, XDRFILE* xfp)
  300. {
  301. int i=0;
  302. /* read write is encoded in the XDR struct */
  303. while(i<ndata && xdr_u_short((XDR *)(xfp->xdr),ptr+i))
  304. i++;
  305. return i;
  306. }
  307. int
  308. xdrfile_write_ushort(unsigned short *ptr, int ndata, XDRFILE* xfp)
  309. {
  310. int i=0;
  311. /* read write is encoded in the XDR struct */
  312. while(i<ndata && xdr_u_short((XDR *)(xfp->xdr),ptr+i))
  313. i++;
  314. return i;
  315. }
  316. int
  317. xdrfile_read_float(float *ptr, int ndata, XDRFILE* xfp)
  318. {
  319. int i=0;
  320. /* read write is encoded in the XDR struct */
  321. while(i<ndata && xdr_float((XDR *)(xfp->xdr),ptr+i))
  322. i++;
  323. return i;
  324. }
  325. int
  326. xdrfile_write_float(float *ptr, int ndata, XDRFILE* xfp)
  327. {
  328. int i=0;
  329. /* read write is encoded in the XDR struct */
  330. while(i<ndata && xdr_float((XDR *)(xfp->xdr),ptr+i))
  331. i++;
  332. return i;
  333. }
  334. int
  335. xdrfile_read_double(double *ptr, int ndata, XDRFILE* xfp)
  336. {
  337. int i=0;
  338. /* read write is encoded in the XDR struct */
  339. while(i<ndata && xdr_double((XDR *)(xfp->xdr),ptr+i))
  340. i++;
  341. return i;
  342. }
  343. int
  344. xdrfile_write_double(double *ptr, int ndata, XDRFILE* xfp)
  345. {
  346. int i=0;
  347. /* read write is encoded in the XDR struct */
  348. while(i<ndata && xdr_double((XDR *)(xfp->xdr),ptr+i))
  349. i++;
  350. return i;
  351. }
  352. int
  353. xdrfile_read_string(char *ptr, int maxlen, XDRFILE* xfp)
  354. {
  355. int i;
  356. if(xdr_string((XDR *)(xfp->xdr),&ptr,maxlen)) {
  357. i=0;
  358. while(i<maxlen && ptr[i]!=0)
  359. i++;
  360. if(i==maxlen)
  361. return maxlen;
  362. else
  363. return i+1;
  364. } else
  365. return 0;
  366. }
  367. int
  368. xdrfile_write_string(char *ptr, XDRFILE* xfp)
  369. {
  370. int len=strlen(ptr)+1;
  371. if(xdr_string((XDR *)(xfp->xdr),&ptr,len))
  372. return len;
  373. else
  374. return 0;
  375. }
  376. int
  377. xdrfile_read_opaque(char *ptr, int cnt, XDRFILE* xfp)
  378. {
  379. if(xdr_opaque((XDR *)(xfp->xdr),ptr,cnt))
  380. return cnt;
  381. else
  382. return 0;
  383. }
  384. int
  385. xdrfile_write_opaque(char *ptr, int cnt, XDRFILE* xfp)
  386. {
  387. if(xdr_opaque((XDR *)(xfp->xdr),ptr,cnt))
  388. return cnt;
  389. else
  390. return 0;
  391. }
  392. /* Internal support routines for reading/writing compressed coordinates
  393. * sizeofint - calculate smallest number of bits necessary
  394. * to represent a certain integer.
  395. */
  396. static int
  397. sizeofint(int size) {
  398. unsigned int num = 1;
  399. int num_of_bits = 0;
  400. while (size >= num && num_of_bits < 32)
  401. {
  402. num_of_bits++;
  403. num <<= 1;
  404. }
  405. return num_of_bits;
  406. }
  407. /*
  408. * sizeofints - calculate 'bitsize' of compressed ints
  409. *
  410. * given a number of small unsigned integers and the maximum value
  411. * return the number of bits needed to read or write them with the
  412. * routines encodeints/decodeints. You need this parameter when
  413. * calling those routines.
  414. * (However, in some cases we can just use the variable 'smallidx'
  415. * which is the exact number of bits, and them we dont need to call
  416. * this routine).
  417. */
  418. static int
  419. sizeofints(int num_of_ints, unsigned int sizes[])
  420. {
  421. int i, num;
  422. unsigned int num_of_bytes, num_of_bits, bytes[32], bytecnt, tmp;
  423. num_of_bytes = 1;
  424. bytes[0] = 1;
  425. num_of_bits = 0;
  426. for (i=0; i < num_of_ints; i++)
  427. {
  428. tmp = 0;
  429. for (bytecnt = 0; bytecnt < num_of_bytes; bytecnt++)
  430. {
  431. tmp = bytes[bytecnt] * sizes[i] + tmp;
  432. bytes[bytecnt] = tmp & 0xff;
  433. tmp >>= 8;
  434. }
  435. while (tmp != 0)
  436. {
  437. bytes[bytecnt++] = tmp & 0xff;
  438. tmp >>= 8;
  439. }
  440. num_of_bytes = bytecnt;
  441. }
  442. num = 1;
  443. num_of_bytes--;
  444. while (bytes[num_of_bytes] >= num)
  445. {
  446. num_of_bits++;
  447. num *= 2;
  448. }
  449. return num_of_bits + num_of_bytes * 8;
  450. }
  451. /*
  452. * encodebits - encode num into buf using the specified number of bits
  453. *
  454. * This routines appends the value of num to the bits already present in
  455. * the array buf. You need to give it the number of bits to use and you had
  456. * better make sure that this number of bits is enough to hold the value.
  457. * Num must also be positive.
  458. */
  459. static void
  460. encodebits(int buf[], int num_of_bits, int num)
  461. {
  462. unsigned int cnt, lastbyte;
  463. int lastbits;
  464. unsigned char * cbuf;
  465. cbuf = ((unsigned char *)buf) + 3 * sizeof(*buf);
  466. cnt = (unsigned int) buf[0];
  467. lastbits = buf[1];
  468. lastbyte =(unsigned int) buf[2];
  469. while (num_of_bits >= 8)
  470. {
  471. lastbyte = (lastbyte << 8) | ((num >> (num_of_bits -8)) /* & 0xff*/);
  472. cbuf[cnt++] = lastbyte >> lastbits;
  473. num_of_bits -= 8;
  474. }
  475. if (num_of_bits > 0)
  476. {
  477. lastbyte = (lastbyte << num_of_bits) | num;
  478. lastbits += num_of_bits;
  479. if (lastbits >= 8)
  480. {
  481. lastbits -= 8;
  482. cbuf[cnt++] = lastbyte >> lastbits;
  483. }
  484. }
  485. buf[0] = cnt;
  486. buf[1] = lastbits;
  487. buf[2] = lastbyte;
  488. if (lastbits>0)
  489. {
  490. cbuf[cnt] = lastbyte << (8 - lastbits);
  491. }
  492. }
  493. /*
  494. * encodeints - encode a small set of small integers in compressed format
  495. *
  496. * this routine is used internally by xdr3dfcoord, to encode a set of
  497. * small integers to the buffer for writing to a file.
  498. * Multiplication with fixed (specified maximum) sizes is used to get
  499. * to one big, multibyte integer. Allthough the routine could be
  500. * modified to handle sizes bigger than 16777216, or more than just
  501. * a few integers, this is not done because the gain in compression
  502. * isn't worth the effort. Note that overflowing the multiplication
  503. * or the byte buffer (32 bytes) is unchecked and whould cause bad results.
  504. * THese things are checked in the calling routines, so make sure not
  505. * to remove those checks...
  506. */
  507. static void
  508. encodeints(int buf[], int num_of_ints, int num_of_bits,
  509. unsigned int sizes[], unsigned int nums[])
  510. {
  511. int i;
  512. unsigned int bytes[32], num_of_bytes, bytecnt, tmp;
  513. tmp = nums[0];
  514. num_of_bytes = 0;
  515. do
  516. {
  517. bytes[num_of_bytes++] = tmp & 0xff;
  518. tmp >>= 8;
  519. } while (tmp != 0);
  520. for (i = 1; i < num_of_ints; i++)
  521. {
  522. if (nums[i] >= sizes[i])
  523. {
  524. fprintf(stderr,"major breakdown in encodeints - num %u doesn't "
  525. "match size %u\n", nums[i], sizes[i]);
  526. abort();
  527. }
  528. /* use one step multiply */
  529. tmp = nums[i];
  530. for (bytecnt = 0; bytecnt < num_of_bytes; bytecnt++)
  531. {
  532. tmp = bytes[bytecnt] * sizes[i] + tmp;
  533. bytes[bytecnt] = tmp & 0xff;
  534. tmp >>= 8;
  535. }
  536. while (tmp != 0)
  537. {
  538. bytes[bytecnt++] = tmp & 0xff;
  539. tmp >>= 8;
  540. }
  541. num_of_bytes = bytecnt;
  542. }
  543. if (num_of_bits >= num_of_bytes * 8)
  544. {
  545. for (i = 0; i < num_of_bytes; i++)
  546. {
  547. encodebits(buf, 8, bytes[i]);
  548. }
  549. encodebits(buf, num_of_bits - num_of_bytes * 8, 0);
  550. }
  551. else
  552. {
  553. for (i = 0; i < num_of_bytes-1; i++)
  554. {
  555. encodebits(buf, 8, bytes[i]);
  556. }
  557. encodebits(buf, num_of_bits- (num_of_bytes -1) * 8, bytes[i]);
  558. }
  559. }
  560. /*
  561. * decodebits - decode number from buf using specified number of bits
  562. *
  563. * extract the number of bits from the array buf and construct an integer
  564. * from it. Return that value.
  565. *
  566. */
  567. static int
  568. decodebits(int buf[], int num_of_bits)
  569. {
  570. int cnt, num;
  571. unsigned int lastbits, lastbyte;
  572. unsigned char * cbuf;
  573. int mask = (1 << num_of_bits) -1;
  574. cbuf = ((unsigned char *)buf) + 3 * sizeof(*buf);
  575. cnt = buf[0];
  576. lastbits = (unsigned int) buf[1];
  577. lastbyte = (unsigned int) buf[2];
  578. num = 0;
  579. while (num_of_bits >= 8)
  580. {
  581. lastbyte = ( lastbyte << 8 ) | cbuf[cnt++];
  582. num |= (lastbyte >> lastbits) << (num_of_bits - 8);
  583. num_of_bits -=8;
  584. }
  585. if (num_of_bits > 0)
  586. {
  587. if (lastbits < num_of_bits)
  588. {
  589. lastbits += 8;
  590. lastbyte = (lastbyte << 8) | cbuf[cnt++];
  591. }
  592. lastbits -= num_of_bits;
  593. num |= (lastbyte >> lastbits) & ((1 << num_of_bits) -1);
  594. }
  595. num &= mask;
  596. buf[0] = cnt;
  597. buf[1] = lastbits;
  598. buf[2] = lastbyte;
  599. return num;
  600. }
  601. /*
  602. * decodeints - decode 'small' integers from the buf array
  603. *
  604. * this routine is the inverse from encodeints() and decodes the small integers
  605. * written to buf by calculating the remainder and doing divisions with
  606. * the given sizes[]. You need to specify the total number of bits to be
  607. * used from buf in num_of_bits.
  608. *
  609. */
  610. static void
  611. decodeints(int buf[], int num_of_ints, int num_of_bits,
  612. unsigned int sizes[], int nums[])
  613. {
  614. int bytes[32];
  615. int i, j, num_of_bytes, p, num;
  616. bytes[1] = bytes[2] = bytes[3] = 0;
  617. num_of_bytes = 0;
  618. while (num_of_bits > 8)
  619. {
  620. bytes[num_of_bytes++] = decodebits(buf, 8);
  621. num_of_bits -= 8;
  622. }
  623. if (num_of_bits > 0)
  624. {
  625. bytes[num_of_bytes++] = decodebits(buf, num_of_bits);
  626. }
  627. for (i = num_of_ints-1; i > 0; i--)
  628. {
  629. num = 0;
  630. for (j = num_of_bytes-1; j >=0; j--)
  631. {
  632. num = (num << 8) | bytes[j];
  633. p = num / sizes[i];
  634. bytes[j] = p;
  635. num = num - p * sizes[i];
  636. }
  637. nums[i] = num;
  638. }
  639. nums[0] = bytes[0] | (bytes[1] << 8) | (bytes[2] << 16) | (bytes[3] << 24);
  640. }
  641. static const int magicints[] =
  642. {
  643. 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 10, 12, 16, 20, 25, 32, 40, 50, 64,
  644. 80, 101, 128, 161, 203, 256, 322, 406, 512, 645, 812, 1024, 1290,
  645. 1625, 2048, 2580, 3250, 4096, 5060, 6501, 8192, 10321, 13003,
  646. 16384, 20642, 26007, 32768, 41285, 52015, 65536,82570, 104031,
  647. 131072, 165140, 208063, 262144, 330280, 416127, 524287, 660561,
  648. 832255, 1048576, 1321122, 1664510, 2097152, 2642245, 3329021,
  649. 4194304, 5284491, 6658042, 8388607, 10568983, 13316085, 16777216
  650. };
  651. #define FIRSTIDX 9
  652. /* note that magicints[FIRSTIDX-1] == 0 */
  653. #define LASTIDX (sizeof(magicints) / sizeof(*magicints))
  654. /* Compressed coordinate routines - modified from the original
  655. * implementation by Frans v. Hoesel to make them threadsafe.
  656. */
  657. int
  658. xdrfile_decompress_coord_float(float *ptr,
  659. int *size,
  660. float *precision,
  661. XDRFILE* xfp)
  662. {
  663. int minint[3], maxint[3], *lip;
  664. int smallidx, minidx, maxidx;
  665. unsigned sizeint[3], sizesmall[3], bitsizeint[3], size3;
  666. int k, *buf1, *buf2, lsize, flag;
  667. int smallnum, smaller, larger, i, is_smaller, run;
  668. float *lfp, inv_precision;
  669. int tmp, *thiscoord, prevcoord[3];
  670. unsigned int bitsize;
  671. bitsizeint[0] = 0;
  672. bitsizeint[1] = 0;
  673. bitsizeint[2] = 0;
  674. if(xfp==NULL || ptr==NULL)
  675. return -1;
  676. tmp=xdrfile_read_int(&lsize,1,xfp);
  677. if(tmp==0)
  678. return -1; /* return if we could not read size */
  679. if (*size < lsize)
  680. {
  681. fprintf(stderr, "Requested to decompress %d coords, file contains %d\n",
  682. *size, lsize);
  683. return -1;
  684. }
  685. *size = lsize;
  686. size3 = *size * 3;
  687. if(size3>xfp->buf1size)
  688. {
  689. if((xfp->buf1=(int *)malloc(sizeof(int)*size3))==NULL)
  690. {
  691. fprintf(stderr,"Cannot allocate memory for decompressing coordinates.\n");
  692. return -1;
  693. }
  694. xfp->buf1size=size3;
  695. xfp->buf2size=size3*1.2;
  696. if((xfp->buf2=(int *)malloc(sizeof(int)*xfp->buf2size))==NULL)
  697. {
  698. fprintf(stderr,"Cannot allocate memory for decompressing coordinates.\n");
  699. return -1;
  700. }
  701. }
  702. /* Dont bother with compression for three atoms or less */
  703. if(*size<=9)
  704. {
  705. return xdrfile_read_float(ptr,size3,xfp)/3;
  706. /* return number of coords, not floats */
  707. }
  708. /* Compression-time if we got here. Read precision first */
  709. xdrfile_read_float(precision,1,xfp);
  710. /* avoid repeated pointer dereferencing. */
  711. buf1=xfp->buf1;
  712. buf2=xfp->buf2;
  713. /* buf2[0-2] are special and do not contain actual data */
  714. buf2[0] = buf2[1] = buf2[2] = 0;
  715. xdrfile_read_int(minint,3,xfp);
  716. xdrfile_read_int(maxint,3,xfp);
  717. sizeint[0] = maxint[0] - minint[0]+1;
  718. sizeint[1] = maxint[1] - minint[1]+1;
  719. sizeint[2] = maxint[2] - minint[2]+1;
  720. /* check if one of the sizes is to big to be multiplied */
  721. if ((sizeint[0] | sizeint[1] | sizeint[2] ) > 0xffffff)
  722. {
  723. bitsizeint[0] = sizeofint(sizeint[0]);
  724. bitsizeint[1] = sizeofint(sizeint[1]);
  725. bitsizeint[2] = sizeofint(sizeint[2]);
  726. bitsize = 0; /* flag the use of large sizes */
  727. }
  728. else
  729. {
  730. bitsize = sizeofints(3, sizeint);
  731. }
  732. if (xdrfile_read_int(&smallidx,1,xfp) == 0)
  733. return 0; /* not sure what has happened here or why we return... */
  734. tmp=smallidx+8;
  735. maxidx = (LASTIDX<tmp) ? LASTIDX : tmp;
  736. minidx = maxidx - 8; /* often this equal smallidx */
  737. tmp = smallidx-1;
  738. tmp = (FIRSTIDX>tmp) ? FIRSTIDX : tmp;
  739. smaller = magicints[tmp] / 2;
  740. smallnum = magicints[smallidx] / 2;
  741. sizesmall[0] = sizesmall[1] = sizesmall[2] = magicints[smallidx] ;
  742. larger = magicints[maxidx];
  743. /* buf2[0] holds the length in bytes */
  744. if (xdrfile_read_int(buf2,1,xfp) == 0)
  745. return 0;
  746. if (xdrfile_read_opaque((char *)&(buf2[3]),(unsigned int)buf2[0],xfp) == 0)
  747. return 0;
  748. buf2[0] = buf2[1] = buf2[2] = 0;
  749. lfp = ptr;
  750. inv_precision = 1.0 / * precision;
  751. run = 0;
  752. i = 0;
  753. lip = buf1;
  754. while ( i < lsize )
  755. {
  756. thiscoord = (int *)(lip) + i * 3;
  757. if (bitsize == 0)
  758. {
  759. thiscoord[0] = decodebits(buf2, bitsizeint[0]);
  760. thiscoord[1] = decodebits(buf2, bitsizeint[1]);
  761. thiscoord[2] = decodebits(buf2, bitsizeint[2]);
  762. }
  763. else
  764. {
  765. decodeints(buf2, 3, bitsize, sizeint, thiscoord);
  766. }
  767. i++;
  768. thiscoord[0] += minint[0];
  769. thiscoord[1] += minint[1];
  770. thiscoord[2] += minint[2];
  771. prevcoord[0] = thiscoord[0];
  772. prevcoord[1] = thiscoord[1];
  773. prevcoord[2] = thiscoord[2];
  774. flag = decodebits(buf2, 1);
  775. is_smaller = 0;
  776. if (flag == 1)
  777. {
  778. run = decodebits(buf2, 5);
  779. is_smaller = run % 3;
  780. run -= is_smaller;
  781. is_smaller--;
  782. }
  783. if (run > 0)
  784. {
  785. thiscoord += 3;
  786. for (k = 0; k < run; k+=3)
  787. {
  788. decodeints(buf2, 3, smallidx, sizesmall, thiscoord);
  789. i++;
  790. thiscoord[0] += prevcoord[0] - smallnum;
  791. thiscoord[1] += prevcoord[1] - smallnum;
  792. thiscoord[2] += prevcoord[2] - smallnum;
  793. if (k == 0) {
  794. /* interchange first with second atom for better
  795. * compression of water molecules
  796. */
  797. tmp = thiscoord[0]; thiscoord[0] = prevcoord[0];
  798. prevcoord[0] = tmp;
  799. tmp = thiscoord[1]; thiscoord[1] = prevcoord[1];
  800. prevcoord[1] = tmp;
  801. tmp = thiscoord[2]; thiscoord[2] = prevcoord[2];
  802. prevcoord[2] = tmp;
  803. *lfp++ = prevcoord[0] * inv_precision;
  804. *lfp++ = prevcoord[1] * inv_precision;
  805. *lfp++ = prevcoord[2] * inv_precision;
  806. } else {
  807. prevcoord[0] = thiscoord[0];
  808. prevcoord[1] = thiscoord[1];
  809. prevcoord[2] = thiscoord[2];
  810. }
  811. *lfp++ = thiscoord[0] * inv_precision;
  812. *lfp++ = thiscoord[1] * inv_precision;
  813. *lfp++ = thiscoord[2] * inv_precision;
  814. }
  815. }
  816. else
  817. {
  818. *lfp++ = thiscoord[0] * inv_precision;
  819. *lfp++ = thiscoord[1] * inv_precision;
  820. *lfp++ = thiscoord[2] * inv_precision;
  821. }
  822. smallidx += is_smaller;
  823. if (is_smaller < 0)
  824. {
  825. smallnum = smaller;
  826. if (smallidx > FIRSTIDX)
  827. {
  828. smaller = magicints[smallidx - 1] /2;
  829. }
  830. else
  831. {
  832. smaller = 0;
  833. }
  834. }
  835. else if (is_smaller > 0)
  836. {
  837. smaller = smallnum;
  838. smallnum = magicints[smallidx] / 2;
  839. }
  840. sizesmall[0] = sizesmall[1] = sizesmall[2] = magicints[smallidx] ;
  841. }
  842. return *size;
  843. }
  844. int
  845. xdrfile_compress_coord_float(float *ptr,
  846. int size,
  847. float precision,
  848. XDRFILE* xfp)
  849. {
  850. int minint[3], maxint[3], mindiff, *lip, diff;
  851. int lint1, lint2, lint3, oldlint1, oldlint2, oldlint3, smallidx;
  852. int minidx, maxidx;
  853. unsigned sizeint[3], sizesmall[3], bitsizeint[3], size3, *luip;
  854. int k, *buf1, *buf2;
  855. int smallnum, smaller, larger, i, j, is_small, is_smaller, run, prevrun;
  856. float *lfp, lf;
  857. int tmp, tmpsum, *thiscoord, prevcoord[3];
  858. unsigned int tmpcoord[30];
  859. int errval=1;
  860. unsigned int bitsize;
  861. if(xfp==NULL)
  862. return -1;
  863. size3=3*size;
  864. bitsizeint[0] = 0;
  865. bitsizeint[1] = 0;
  866. bitsizeint[2] = 0;
  867. if(size3>xfp->buf1size)
  868. {
  869. if((xfp->buf1=(int *)malloc(sizeof(int)*size3))==NULL)
  870. {
  871. fprintf(stderr,"Cannot allocate memory for compressing coordinates.\n");
  872. return -1;
  873. }
  874. xfp->buf1size=size3;
  875. xfp->buf2size=size3*1.2;
  876. if((xfp->buf2=(int *)malloc(sizeof(int)*xfp->buf2size))==NULL)
  877. {
  878. fprintf(stderr,"Cannot allocate memory for compressing coordinates.\n");
  879. return -1;
  880. }
  881. }
  882. if(xdrfile_write_int(&size,1,xfp)==0)
  883. return -1; /* return if we could not write size */
  884. /* Dont bother with compression for three atoms or less */
  885. if(size<=9)
  886. {
  887. return xdrfile_write_float(ptr,size3,xfp)/3;
  888. /* return number of coords, not floats */
  889. }
  890. /* Compression-time if we got here. Write precision first */
  891. if (precision <= 0)
  892. precision = 1000;
  893. xdrfile_write_float(&precision,1,xfp);
  894. /* avoid repeated pointer dereferencing. */
  895. buf1=xfp->buf1;
  896. buf2=xfp->buf2;
  897. /* buf2[0-2] are special and do not contain actual data */
  898. buf2[0] = buf2[1] = buf2[2] = 0;
  899. minint[0] = minint[1] = minint[2] = INT_MAX;
  900. maxint[0] = maxint[1] = maxint[2] = INT_MIN;
  901. prevrun = -1;
  902. lfp = ptr;
  903. lip = buf1;
  904. mindiff = INT_MAX;
  905. oldlint1 = oldlint2 = oldlint3 = 0;
  906. while(lfp < ptr + size3 )
  907. {
  908. /* find nearest integer */
  909. if (*lfp >= 0.0)
  910. lf = *lfp * precision + 0.5;
  911. else
  912. lf = *lfp * precision - 0.5;
  913. if (fabs(lf) > INT_MAX-2)
  914. {
  915. /* scaling would cause overflow */
  916. fprintf(stderr,"Internal overflow compressing coordinates.\n");
  917. errval=0;
  918. }
  919. lint1 = lf;
  920. if (lint1 < minint[0]) minint[0] = lint1;
  921. if (lint1 > maxint[0]) maxint[0] = lint1;
  922. *lip++ = lint1;
  923. lfp++;
  924. if (*lfp >= 0.0)
  925. lf = *lfp * precision + 0.5;
  926. else
  927. lf = *lfp * precision - 0.5;
  928. if (fabs(lf) > INT_MAX-2)
  929. {
  930. /* scaling would cause overflow */
  931. fprintf(stderr,"Internal overflow compressing coordinates.\n");
  932. errval=0;
  933. }
  934. lint2 = lf;
  935. if (lint2 < minint[1]) minint[1] = lint2;
  936. if (lint2 > maxint[1]) maxint[1] = lint2;
  937. *lip++ = lint2;
  938. lfp++;
  939. if (*lfp >= 0.0)
  940. lf = *lfp * precision + 0.5;
  941. else
  942. lf = *lfp * precision - 0.5;
  943. if (fabs(lf) > INT_MAX-2)
  944. {
  945. errval=0;
  946. }
  947. lint3 = lf;
  948. if (lint3 < minint[2]) minint[2] = lint3;
  949. if (lint3 > maxint[2]) maxint[2] = lint3;
  950. *lip++ = lint3;
  951. lfp++;
  952. diff = abs(oldlint1-lint1)+abs(oldlint2-lint2)+abs(oldlint3-lint3);
  953. if (diff < mindiff && lfp > ptr + 3)
  954. mindiff = diff;
  955. oldlint1 = lint1;
  956. oldlint2 = lint2;
  957. oldlint3 = lint3;
  958. }
  959. xdrfile_write_int(minint,3,xfp);
  960. xdrfile_write_int(maxint,3,xfp);
  961. if ((float)maxint[0] - (float)minint[0] >= INT_MAX-2 ||
  962. (float)maxint[1] - (float)minint[1] >= INT_MAX-2 ||
  963. (float)maxint[2] - (float)minint[2] >= INT_MAX-2) {
  964. /* turning value in unsigned by subtracting minint
  965. * would cause overflow
  966. */
  967. fprintf(stderr,"Internal overflow compressing coordinates.\n");
  968. errval=0;
  969. }
  970. sizeint[0] = maxint[0] - minint[0]+1;
  971. sizeint[1] = maxint[1] - minint[1]+1;
  972. sizeint[2] = maxint[2] - minint[2]+1;
  973. /* check if one of the sizes is to big to be multiplied */
  974. if ((sizeint[0] | sizeint[1] | sizeint[2] ) > 0xffffff)
  975. {
  976. bitsizeint[0] = sizeofint(sizeint[0]);
  977. bitsizeint[1] = sizeofint(sizeint[1]);
  978. bitsizeint[2] = sizeofint(sizeint[2]);
  979. bitsize = 0; /* flag the use of large sizes */
  980. }
  981. else
  982. {
  983. bitsize = sizeofints(3, sizeint);
  984. }
  985. lip = buf1;
  986. luip = (unsigned int *) buf1;
  987. smallidx = FIRSTIDX;
  988. while (smallidx < LASTIDX && magicints[smallidx] < mindiff)
  989. {
  990. smallidx++;
  991. }
  992. xdrfile_write_int(&smallidx,1,xfp);
  993. tmp=smallidx+8;
  994. maxidx = (LASTIDX<tmp) ? LASTIDX : tmp;
  995. minidx = maxidx - 8; /* often this equal smallidx */
  996. tmp=smallidx-1;
  997. tmp= (FIRSTIDX>tmp) ? FIRSTIDX : tmp;
  998. smaller = magicints[tmp] / 2;
  999. smallnum = magicints[smallidx] / 2;
  1000. sizesmall[0] = sizesmall[1] = sizesmall[2] = magicints[smallidx];
  1001. larger = magicints[maxidx] / 2;
  1002. i = 0;
  1003. while (i < size)
  1004. {
  1005. is_small = 0;
  1006. thiscoord = (int *)(luip) + i * 3;
  1007. if (smallidx < maxidx && i >= 1 &&
  1008. abs(thiscoord[0] - prevcoord[0]) < larger &&
  1009. abs(thiscoord[1] - prevcoord[1]) < larger &&
  1010. abs(thiscoord[2] - prevcoord[2]) < larger) {
  1011. is_smaller = 1;
  1012. }
  1013. else if (smallidx > minidx)
  1014. {
  1015. is_smaller = -1;
  1016. }
  1017. else
  1018. {
  1019. is_smaller = 0;
  1020. }
  1021. if (i + 1 < size)
  1022. {
  1023. if (abs(thiscoord[0] - thiscoord[3]) < smallnum &&
  1024. abs(thiscoord[1] - thiscoord[4]) < smallnum &&
  1025. abs(thiscoord[2] - thiscoord[5]) < smallnum)
  1026. {
  1027. /* interchange first with second atom for better
  1028. * compression of water molecules
  1029. */
  1030. tmp = thiscoord[0]; thiscoord[0] = thiscoord[3];
  1031. thiscoord[3] = tmp;
  1032. tmp = thiscoord[1]; thiscoord[1] = thiscoord[4];
  1033. thiscoord[4] = tmp;
  1034. tmp = thiscoord[2]; thiscoord[2] = thiscoord[5];
  1035. thiscoord[5] = tmp;
  1036. is_small = 1;
  1037. }
  1038. }
  1039. tmpcoord[0] = thiscoord[0] - minint[0];
  1040. tmpcoord[1] = thiscoord[1] - minint[1];
  1041. tmpcoord[2] = thiscoord[2] - minint[2];
  1042. if (bitsize == 0)
  1043. {
  1044. encodebits(buf2, bitsizeint[0], tmpcoord[0]);
  1045. encodebits(buf2, bitsizeint[1], tmpcoord[1]);
  1046. encodebits(buf2, bitsizeint[2], tmpcoord[2]);
  1047. }
  1048. else
  1049. {
  1050. encodeints(buf2, 3, bitsize, sizeint, tmpcoord);
  1051. }
  1052. prevcoord[0] = thiscoord[0];
  1053. prevcoord[1] = thiscoord[1];
  1054. prevcoord[2] = thiscoord[2];
  1055. thiscoord = thiscoord + 3;
  1056. i++;
  1057. run = 0;
  1058. if (is_small == 0 && is_smaller == -1)
  1059. is_smaller = 0;
  1060. while (is_small && run < 8*3)
  1061. {
  1062. tmpsum=0;
  1063. for(j=0;j<3;j++)
  1064. {
  1065. tmp=thiscoord[j] - prevcoord[j];
  1066. tmpsum+=tmp*tmp;
  1067. }
  1068. if (is_smaller == -1 && tmpsum >= smaller * smaller)
  1069. {
  1070. is_smaller = 0;
  1071. }
  1072. tmpcoord[run++] = thiscoord[0] - prevcoord[0] + smallnum;
  1073. tmpcoord[run++] = thiscoord[1] - prevcoord[1] + smallnum;
  1074. tmpcoord[run++] = thiscoord[2] - prevcoord[2] + smallnum;
  1075. prevcoord[0] = thiscoord[0];
  1076. prevcoord[1] = thiscoord[1];
  1077. prevcoord[2] = thiscoord[2];
  1078. i++;
  1079. thiscoord = thiscoord + 3;
  1080. is_small = 0;
  1081. if (i < size &&
  1082. abs(thiscoord[0] - prevcoord[0]) < smallnum &&
  1083. abs(thiscoord[1] - prevcoord[1]) < smallnum &&
  1084. abs(thiscoord[2] - prevcoord[2]) < smallnum)
  1085. {
  1086. is_small = 1;
  1087. }
  1088. }
  1089. if (run != prevrun || is_smaller != 0)
  1090. {
  1091. prevrun = run;
  1092. encodebits(buf2, 1, 1); /* flag the change in run-length */
  1093. encodebits(buf2, 5, run+is_smaller+1);
  1094. }
  1095. else
  1096. {
  1097. encodebits(buf2, 1, 0); /* flag the fact that runlength did not change */
  1098. }
  1099. for (k=0; k < run; k+=3)
  1100. {
  1101. encodeints(buf2, 3, smallidx, sizesmall, &tmpcoord[k]);
  1102. }
  1103. if (is_smaller != 0)
  1104. {
  1105. smallidx += is_smaller;
  1106. if (is_smaller < 0)
  1107. {
  1108. smallnum = smaller;
  1109. smaller = magicints[smallidx-1] / 2;
  1110. }
  1111. else
  1112. {
  1113. smaller = smallnum;
  1114. smallnum = magicints[smallidx] / 2;
  1115. }
  1116. sizesmall[0] = sizesmall[1] = sizesmall[2] = magicints[smallidx];
  1117. }
  1118. }
  1119. if (buf2[1] != 0) buf2[0]++;
  1120. xdrfile_write_int(buf2,1,xfp); /* buf2[0] holds the length in bytes */
  1121. tmp=xdrfile_write_opaque((char *)&(buf2[3]),(unsigned int)buf2[0],xfp);
  1122. if(tmp==(unsigned int)buf2[0])
  1123. return size;
  1124. else
  1125. return -1;
  1126. }
  1127. int
  1128. xdrfile_decompress_coord_double(double *ptr,
  1129. int *size,
  1130. double *precision,
  1131. XDRFILE* xfp)
  1132. {
  1133. int minint[3], maxint[3], *lip;
  1134. int smallidx, minidx, maxidx;
  1135. unsigned sizeint[3], sizesmall[3], bitsizeint[3], size3;
  1136. int k, *buf1, *buf2, lsize, flag;
  1137. int smallnum, smaller, larger, i, is_smaller, run;
  1138. double *lfp, inv_precision;
  1139. float float_prec, tmpdata[30];
  1140. int tmp, *thiscoord, prevcoord[3];
  1141. unsigned int bitsize;
  1142. bitsizeint[0] = 0;
  1143. bitsizeint[1] = 0;
  1144. bitsizeint[2] = 0;
  1145. if(xfp==NULL || ptr==NULL)
  1146. return -1;
  1147. tmp=xdrfile_read_int(&lsize,1,xfp);
  1148. if(tmp==0)
  1149. return -1; /* return if we could not read size */
  1150. if (*size < lsize)
  1151. {
  1152. fprintf(stderr, "Requested to decompress %d coords, file contains %d\n",
  1153. *size, lsize);
  1154. return -1;
  1155. }
  1156. *size = lsize;
  1157. size3 = *size * 3;
  1158. if(size3>xfp->buf1size)
  1159. {
  1160. if((xfp->buf1=(int *)malloc(sizeof(int)*size3))==NULL)
  1161. {
  1162. fprintf(stderr,"Cannot allocate memory for decompression coordinates.\n");
  1163. return -1;
  1164. }
  1165. xfp->buf1size=size3;
  1166. xfp->buf2size=size3*1.2;
  1167. if((xfp->buf2=(int *)malloc(sizeof(int)*xfp->buf2size))==NULL)
  1168. {
  1169. fprintf(stderr,"Cannot allocate memory for decompressing coordinates.\n");
  1170. return -1;
  1171. }
  1172. }
  1173. /* Dont bother with compression for three atoms or less */
  1174. if(*size<=9)
  1175. {
  1176. tmp=xdrfile_read_float(tmpdata,size3,xfp);
  1177. for(i=0;i<9*3;i++)
  1178. ptr[i]=tmpdata[i];
  1179. return tmp/3;
  1180. /* return number of coords, not floats */
  1181. }
  1182. /* Compression-time if we got here. Read precision first */
  1183. xdrfile_read_float(&float_prec,1,xfp);
  1184. *precision=float_prec;
  1185. /* avoid repeated pointer dereferencing. */
  1186. buf1=xfp->buf1;
  1187. buf2=xfp->buf2;
  1188. /* buf2[0-2] are special and do not contain actual data */
  1189. buf2[0] = buf2[1] = buf2[2] = 0;
  1190. xdrfile_read_int(minint,3,xfp);
  1191. xdrfile_read_int(maxint,3,xfp);
  1192. sizeint[0] = maxint[0] - minint[0]+1;
  1193. sizeint[1] = maxint[1] - minint[1]+1;
  1194. sizeint[2] = maxint[2] - minint[2]+1;
  1195. /* check if one of the sizes is to big to be multiplied */
  1196. if ((sizeint[0] | sizeint[1] | sizeint[2] ) > 0xffffff)
  1197. {
  1198. bitsizeint[0] = sizeofint(sizeint[0]);
  1199. bitsizeint[1] = sizeofint(sizeint[1]);
  1200. bitsizeint[2] = sizeofint(sizeint[2]);
  1201. bitsize = 0; /* flag the use of large sizes */
  1202. }
  1203. else
  1204. {
  1205. bitsize = sizeofints(3, sizeint);
  1206. }
  1207. if (xdrfile_read_int(&smallidx,1,xfp) == 0)
  1208. return 0;
  1209. tmp=smallidx+8;
  1210. maxidx = (LASTIDX<tmp) ? LASTIDX : tmp;
  1211. minidx = maxidx - 8; /* often this equal smallidx */
  1212. tmp = smallidx-1;
  1213. tmp = (FIRSTIDX>tmp) ? FIRSTIDX : tmp;
  1214. smaller = magicints[tmp] / 2;
  1215. smallnum = magicints[smallidx] / 2;
  1216. sizesmall[0] = sizesmall[1] = sizesmall[2] = magicints[smallidx] ;
  1217. larger = magicints[maxidx];
  1218. /* buf2[0] holds the length in bytes */
  1219. if (xdrfile_read_int(buf2,1,xfp) == 0)
  1220. return 0;
  1221. if (xdrfile_read_opaque((char *)&(buf2[3]),(unsigned int)buf2[0],xfp) == 0)
  1222. return 0;
  1223. buf2[0] = buf2[1] = buf2[2] = 0;
  1224. lfp = ptr;
  1225. inv_precision = 1.0 / * precision;
  1226. run = 0;
  1227. i = 0;
  1228. lip = buf1;
  1229. while ( i < lsize )
  1230. {
  1231. thiscoord = (int *)(lip) + i * 3;
  1232. if (bitsize == 0)
  1233. {
  1234. thiscoord[0] = decodebits(buf2, bitsizeint[0]);
  1235. thiscoord[1] = decodebits(buf2, bitsizeint[1]);
  1236. thiscoord[2] = decodebits(buf2, bitsizeint[2]);
  1237. } else {
  1238. decodeints(buf2, 3, bitsize, sizeint, thiscoord);
  1239. }
  1240. i++;
  1241. thiscoord[0] += minint[0];
  1242. thiscoord[1] += minint[1];
  1243. thiscoord[2] += minint[2];
  1244. prevcoord[0] = thiscoord[0];
  1245. prevcoord[1] = thiscoord[1];
  1246. prevcoord[2] = thiscoord[2];
  1247. flag = decodebits(buf2, 1);
  1248. is_smaller = 0;
  1249. if (flag == 1)
  1250. {
  1251. run = decodebits(buf2, 5);
  1252. is_smaller = run % 3;
  1253. run -= is_smaller;
  1254. is_smaller--;
  1255. }
  1256. if (run > 0)
  1257. {
  1258. thiscoord += 3;
  1259. for (k = 0; k < run; k+=3)
  1260. {
  1261. decodeints(buf2, 3, smallidx, sizesmall, thiscoord);
  1262. i++;
  1263. thiscoord[0] += prevcoord[0] - smallnum;
  1264. thiscoord[1] += prevcoord[1] - smallnum;
  1265. thiscoord[2] += prevcoord[2] - smallnum;
  1266. if (k == 0)
  1267. {
  1268. /* interchange first with second atom for better
  1269. * compression of water molecules
  1270. */
  1271. tmp = thiscoord[0]; thiscoord[0] = prevcoord[0];
  1272. prevcoord[0] = tmp;
  1273. tmp = thiscoord[1]; thiscoord[1] = prevcoord[1];
  1274. prevcoord[1] = tmp;
  1275. tmp = thiscoord[2]; thiscoord[2] = prevcoord[2];
  1276. prevcoord[2] = tmp;
  1277. *lfp++ = prevcoord[0] * inv_precision;
  1278. *lfp++ = prevcoord[1] * inv_precision;
  1279. *lfp++ = prevcoord[2] * inv_precision;
  1280. }
  1281. else
  1282. {
  1283. prevcoord[0] = thiscoord[0];
  1284. prevcoord[1] = thiscoord[1];
  1285. prevcoord[2] = thiscoord[2];
  1286. }
  1287. *lfp++ = thiscoord[0] * inv_precision;
  1288. *lfp++ = thiscoord[1] * inv_precision;
  1289. *lfp++ = thiscoord[2] * inv_precision;
  1290. }
  1291. } else {
  1292. *lfp++ = thiscoord[0] * inv_precision;
  1293. *lfp++ = thiscoord[1] * inv_precision;
  1294. *lfp++ = thiscoord[2] * inv_precision;
  1295. }
  1296. smallidx += is_smaller;
  1297. if (is_smaller < 0) {
  1298. smallnum = smaller;
  1299. if (smallidx > FIRSTIDX) {
  1300. smaller = magicints[smallidx - 1] /2;
  1301. } else {
  1302. smaller = 0;
  1303. }
  1304. } else if (is_smaller > 0) {
  1305. smaller = smallnum;
  1306. smallnum = magicints[smallidx] / 2;
  1307. }
  1308. sizesmall[0] = sizesmall[1] = sizesmall[2] = magicints[smallidx] ;
  1309. }
  1310. return *size;
  1311. }
  1312. int
  1313. xdrfile_compress_coord_double(double *ptr,
  1314. int size,
  1315. double precision,
  1316. XDRFILE* xfp)
  1317. {
  1318. int minint[3], maxint[3], mindiff, *lip, diff;
  1319. int lint1, lint2, lint3, oldlint1, oldlint2, oldlint3, smallidx;
  1320. int minidx, maxidx;
  1321. unsigned sizeint[3], sizesmall[3], bitsizeint[3], size3, *luip;
  1322. int k, *buf1, *buf2;
  1323. int smallnum, smaller, larger, i, j, is_small, is_smaller, run, prevrun;
  1324. double *lfp;
  1325. float float_prec, lf,tmpdata[30];
  1326. int tmp, tmpsum, *thiscoord, prevcoord[3];
  1327. unsigned int tmpcoord[30];
  1328. int errval=1;
  1329. unsigned int bitsize;
  1330. bitsizeint[0] = 0;
  1331. bitsizeint[1] = 0;
  1332. bitsizeint[2] = 0;
  1333. if(xfp==NULL)
  1334. return -1;
  1335. size3=3*size;
  1336. if(size3>xfp->buf1size) {
  1337. if((xfp->buf1=(int *)malloc(sizeof(int)*size3))==NULL) {
  1338. fprintf(stderr,"Cannot allocate memory for compressing coordinates.\n");
  1339. return -1;
  1340. }
  1341. xfp->buf1size=size3;
  1342. xfp->buf2size=size3*1.2;
  1343. if((xfp->buf2=(int *)malloc(sizeof(int)*xfp->buf2size))==NULL) {
  1344. fprintf(stderr,"Cannot allocate memory for compressing coordinates.\n");
  1345. return -1;
  1346. }
  1347. }
  1348. if(xdrfile_write_int(&size,1,xfp)==0)
  1349. return -1; /* return if we could not write size */
  1350. /* Dont bother with compression for three atoms or less */
  1351. if(size<=9) {
  1352. for(i=0;i<9*3;i++)
  1353. tmpdata[i]=ptr[i];
  1354. return xdrfile_write_float(tmpdata,size3,xfp)/3;
  1355. /* return number of coords, not floats */
  1356. }
  1357. /* Compression-time if we got here. Write precision first */
  1358. if (precision <= 0)
  1359. precision = 1000;
  1360. float_prec=precision;
  1361. xdrfile_write_float(&float_prec,1,xfp);
  1362. /* avoid repeated pointer dereferencing. */
  1363. buf1=xfp->buf1;
  1364. buf2=xfp->buf2;
  1365. /* buf2[0-2] are special and do not contain actual data */
  1366. buf2[0] = buf2[1] = buf2[2] = 0;
  1367. minint[0] = minint[1] = minint[2] = INT_MAX;
  1368. maxint[0] = maxint[1] = maxint[2] = INT_MIN;
  1369. prevrun = -1;
  1370. lfp = ptr;
  1371. lip = buf1;
  1372. mindiff = INT_MAX;
  1373. oldlint1 = oldlint2 = oldlint3 = 0;
  1374. while(lfp < ptr + size3 ) {
  1375. /* find nearest integer */
  1376. if (*lfp >= 0.0)
  1377. lf = (float)*lfp * float_prec + 0.5;
  1378. else
  1379. lf = (float)*lfp * float_prec - 0.5;
  1380. if (fabs(lf) > INT_MAX-2) {
  1381. /* scaling would cause overflow */
  1382. fprintf(stderr,"Internal overflow compressing coordinates.\n");
  1383. errval=0;
  1384. }
  1385. lint1 = lf;
  1386. if (lint1 < minint[0]) minint[0] = lint1;
  1387. if (lint1 > maxint[0]) maxint[0] = lint1;
  1388. *lip++ = lint1;
  1389. lfp++;
  1390. if (*lfp >= 0.0)
  1391. lf = (float)*lfp * float_prec + 0.5;
  1392. else
  1393. lf = (float)*lfp * float_prec - 0.5;
  1394. if (fabs(lf) > INT_MAX-2) {
  1395. /* scaling would cause overflow */
  1396. fprintf(stderr,"Internal overflow compressing coordinates.\n");
  1397. errval=0;
  1398. }
  1399. lint2 = lf;
  1400. if (lint2 < minint[1]) minint[1] = lint2;
  1401. if (lint2 > maxint[1]) maxint[1] = lint2;
  1402. *lip++ = lint2;
  1403. lfp++;
  1404. if (*lfp >= 0.0)
  1405. lf = (float)*lfp * float_prec + 0.5;
  1406. else
  1407. lf = (float)*lfp * float_prec - 0.5;
  1408. if (fabs(lf) > INT_MAX-2) {
  1409. errval=0;
  1410. }
  1411. lint3 = lf;
  1412. if (lint3 < minint[2]) minint[2] = lint3;
  1413. if (lint3 > maxint[2]) maxint[2] = lint3;
  1414. *lip++ = lint3;
  1415. lfp++;
  1416. diff = abs(oldlint1-lint1)+abs(oldlint2-lint2)+abs(oldlint3-lint3);
  1417. if (diff < mindiff && lfp > ptr + 3)
  1418. mindiff = diff;
  1419. oldlint1 = lint1;
  1420. oldlint2 = lint2;
  1421. oldlint3 = lint3;
  1422. }
  1423. xdrfile_write_int(minint,3,xfp);
  1424. xdrfile_write_int(maxint,3,xfp);
  1425. if ((float)maxint[0] - (float)minint[0] >= INT_MAX-2 ||
  1426. (float)maxint[1] - (float)minint[1] >= INT_MAX-2 ||
  1427. (float)maxint[2] - (float)minint[2] >= INT_MAX-2) {
  1428. /* turning value in unsigned by subtracting minint
  1429. * would cause overflow
  1430. */
  1431. fprintf(stderr,"Internal overflow compressing coordinates.\n");
  1432. errval=0;
  1433. }
  1434. sizeint[0] = maxint[0] - minint[0]+1;
  1435. sizeint[1] = maxint[1] - minint[1]+1;
  1436. sizeint[2] = maxint[2] - minint[2]+1;
  1437. /* check if one of the sizes is to big to be multiplied */
  1438. if ((sizeint[0] | sizeint[1] | sizeint[2] ) > 0xffffff) {
  1439. bitsizeint[0] = sizeofint(sizeint[0]);
  1440. bitsizeint[1] = sizeofint(sizeint[1]);
  1441. bitsizeint[2] = sizeofint(sizeint[2]);
  1442. bitsize = 0; /* flag the use of large sizes */
  1443. } else {
  1444. bitsize = sizeofints(3, sizeint);
  1445. }
  1446. lip = buf1;
  1447. luip = (unsigned int *) buf1;
  1448. smallidx = FIRSTIDX;
  1449. while (smallidx < LASTIDX && magicints[smallidx] < mindiff) {
  1450. smallidx++;
  1451. }
  1452. xdrfile_write_int(&smallidx,1,xfp);
  1453. tmp=smallidx+8;
  1454. maxidx = (LASTIDX<tmp) ? LASTIDX : tmp;
  1455. minidx = maxidx - 8; /* often this equal smallidx */
  1456. tmp=smallidx-1;
  1457. tmp= (FIRSTIDX>tmp) ? FIRSTIDX : tmp;
  1458. smaller = magicints[tmp] / 2;
  1459. smallnum = magicints[smallidx] / 2;
  1460. sizesmall[0] = sizesmall[1] = sizesmall[2] = magicints[smallidx];
  1461. larger = magicints[maxidx] / 2;
  1462. i = 0;
  1463. while (i < size) {
  1464. is_small = 0;
  1465. thiscoord = (int *)(luip) + i * 3;
  1466. if (smallidx < maxidx && i >= 1 &&
  1467. abs(thiscoord[0] - prevcoord[0]) < larger &&
  1468. abs(thiscoord[1] - prevcoord[1]) < larger &&
  1469. abs(thiscoord[2] - prevcoord[2]) < larger) {
  1470. is_smaller = 1;
  1471. } else if (smallidx > minidx) {
  1472. is_smaller = -1;
  1473. } else {
  1474. is_smaller = 0;
  1475. }
  1476. if (i + 1 < size) {
  1477. if (abs(thiscoord[0] - thiscoord[3]) < smallnum &&
  1478. abs(thiscoord[1] - thiscoord[4]) < smallnum &&
  1479. abs(thiscoord[2] - thiscoord[5]) < smallnum) {
  1480. /* interchange first with second atom for better
  1481. * compression of water molecules
  1482. */
  1483. tmp = thiscoord[0]; thiscoord[0] = thiscoord[3];
  1484. thiscoord[3] = tmp;
  1485. tmp = thiscoord[1]; thiscoord[1] = thiscoord[4];
  1486. thiscoord[4] = tmp;
  1487. tmp = thiscoord[2]; thiscoord[2] = thiscoord[5];
  1488. thiscoord[5] = tmp;
  1489. is_small = 1;
  1490. }
  1491. }
  1492. tmpcoord[0] = thiscoord[0] - minint[0];
  1493. tmpcoord[1] = thiscoord[1] - minint[1];
  1494. tmpcoord[2] = thiscoord[2] - minint[2];
  1495. if (bitsize == 0) {
  1496. encodebits(buf2, bitsizeint[0], tmpcoord[0]);
  1497. encodebits(buf2, bitsizeint[1], tmpcoord[1]);
  1498. encodebits(buf2, bitsizeint[2], tmpcoord[2]);
  1499. } else {
  1500. encodeints(buf2, 3, bitsize, sizeint, tmpcoord);
  1501. }
  1502. prevcoord[0] = thiscoord[0];
  1503. prevcoord[1] = thiscoord[1];
  1504. prevcoord[2] = thiscoord[2];
  1505. thiscoord = thiscoord + 3;
  1506. i++;
  1507. run = 0;
  1508. if (is_small == 0 && is_smaller == -1)
  1509. is_smaller = 0;
  1510. while (is_small && run < 8*3) {
  1511. tmpsum=0;
  1512. for(j=0;j<3;j++) {
  1513. tmp=thiscoord[j] - prevcoord[j];
  1514. tmpsum+=tmp*tmp;
  1515. }
  1516. if (is_smaller == -1 && tmpsum >= smaller * smaller) {
  1517. is_smaller = 0;
  1518. }
  1519. tmpcoord[run++] = thiscoord[0] - prevcoord[0] + smallnum;
  1520. tmpcoord[run++] = thiscoord[1] - prevcoord[1] + smallnum;
  1521. tmpcoord[run++] = thiscoord[2] - prevcoord[2] + smallnum;
  1522. prevcoord[0] = thiscoord[0];
  1523. prevcoord[1] = thiscoord[1];
  1524. prevcoord[2] = thiscoord[2];
  1525. i++;
  1526. thiscoord = thiscoord + 3;
  1527. is_small = 0;
  1528. if (i < size &&
  1529. abs(thiscoord[0] - prevcoord[0]) < smallnum &&
  1530. abs(thiscoord[1] - prevcoord[1]) < smallnum &&
  1531. abs(thiscoord[2] - prevcoord[2]) < smallnum) {
  1532. is_small = 1;
  1533. }
  1534. }
  1535. if (run != prevrun || is_smaller != 0) {
  1536. prevrun = run;
  1537. encodebits(buf2, 1, 1); /* flag the change in run-length */
  1538. encodebits(buf2, 5, run+is_smaller+1);
  1539. } else {
  1540. encodebits(buf2, 1, 0); /* flag the fact that runlength did not change */
  1541. }
  1542. for (k=0; k < run; k+=3) {
  1543. encodeints(buf2, 3, smallidx, sizesmall, &tmpcoord[k]);
  1544. }
  1545. if (is_smaller != 0) {
  1546. smallidx += is_smaller;
  1547. if (is_smaller < 0) {
  1548. smallnum = smaller;
  1549. smaller = magicints[smallidx-1] / 2;
  1550. } else {
  1551. smaller = smallnum;
  1552. smallnum = magicints[smallidx] / 2;
  1553. }
  1554. sizesmall[0] = sizesmall[1] = sizesmall[2] = magicints[smallidx];
  1555. }
  1556. }
  1557. if (buf2[1] != 0) buf2[0]++;
  1558. xdrfile_write_int(buf2,1,xfp); /* buf2[0] holds the length in bytes */
  1559. tmp=xdrfile_write_opaque((char *)&(buf2[3]),(unsigned int)buf2[0],xfp);
  1560. if(tmp==(unsigned int)buf2[0])
  1561. return size;
  1562. else
  1563. return -1;
  1564. }
  1565. /* Dont try do document Fortran interface, since
  1566. * Doxygen barfs at the F77_FUNC macro
  1567. */
  1568. #ifndef DOXYGEN
  1569. /*************************************************************
  1570. * Fortran77 interface for reading/writing portable data *
  1571. * The routine are not threadsafe when called from Fortran *
  1572. * (as they are when called from C) unless you compile with *
  1573. * this file with posix thread support. *
  1574. * Note that these are not multithread-safe. *
  1575. *************************************************************/
  1576. #define MAX_FORTRAN_XDR 1024
  1577. static XDRFILE *f77xdr[MAX_FORTRAN_XDR]; /* array of file handles */
  1578. static int f77init = 1; /* zero array first time */
  1579. /* internal to this file: C<-->Fortran string conversion */
  1580. static int ftocstr(char *dest, int dest_len, char *src, int src_len);
  1581. static int ctofstr(char *dest, int dest_len, char *src);
  1582. void
  1583. F77_FUNC(xdropen,XDROPEN)(int *fid, char *filename, char *mode,
  1584. int fn_len, int mode_len)
  1585. {
  1586. char cfilename[512];
  1587. char cmode[5];
  1588. int i;
  1589. /* zero array at first invocation */
  1590. if(f77init) {
  1591. for(i=0;i<MAX_FORTRAN_XDR;i++)
  1592. f77xdr[i]=NULL;
  1593. f77init=0;
  1594. }
  1595. i=0;
  1596. /* nf77xdr is always smaller or equal to MAX_FORTRAN_XDR */
  1597. while(i<MAX_FORTRAN_XDR && f77xdr[i]!=NULL)
  1598. i++;
  1599. if(i==MAX_FORTRAN_XDR) {
  1600. *fid = -1;
  1601. } else if (ftocstr(cfilename, sizeof(cfilename), filename, fn_len)) {
  1602. *fid = -1;
  1603. } else if (ftocstr(cmode, sizeof(cmode), mode,mode_len)) {
  1604. *fid = -1;
  1605. } else {
  1606. f77xdr[i]=xdrfile_open(cfilename,cmode);
  1607. /* return the index in the array as a fortran file handle */
  1608. *fid=i;
  1609. }
  1610. }
  1611. void
  1612. F77_FUNC(xdrclose,XDRCLOSE)(int *fid)
  1613. {
  1614. /* first close it */
  1615. xdrfile_close(f77xdr[*fid]);
  1616. /* the remove it from file handle list */
  1617. f77xdr[*fid]=NULL;
  1618. }
  1619. void
  1620. F77_FUNC(xdrrint,XDRRINT)(int *fid, int *data, int *ndata, int *ret)
  1621. {
  1622. *ret = xdrfile_read_int(data,*ndata,f77xdr[*fid]);
  1623. }
  1624. void
  1625. F77_FUNC(xdrwint,XDRWINT)(int *fid, int *data, int *ndata, int *ret)
  1626. {
  1627. *ret = xdrfile_write_int(data,*ndata,f77xdr[*fid]);
  1628. }
  1629. void
  1630. F77_FUNC(xdrruint,XDRRUINT)(int *fid, unsigned int *data, int *ndata, int *ret)
  1631. {
  1632. *ret = xdrfile_read_uint(data,*ndata,f77xdr[*fid]);
  1633. }
  1634. void
  1635. F77_FUNC(xdrwuint,XDRWUINT)(int *fid, unsigned int *data, int *ndata, int *ret)
  1636. {
  1637. *ret = xdrfile_write_uint(data,*ndata,f77xdr[*fid]);
  1638. }
  1639. void
  1640. F77_FUNC(xdrrchar,XDRRCHAR)(int *fid, char *ip, int *ndata, int *ret)
  1641. {
  1642. *ret = xdrfile_read_char(ip,*ndata,f77xdr[*fid]);
  1643. }
  1644. void
  1645. F77_FUNC(xdrwchar,XDRWCHAR)(int *fid, char *ip, int *ndata, int *ret)
  1646. {
  1647. *ret = xdrfile_write_char(ip,*ndata,f77xdr[*fid]);
  1648. }
  1649. void
  1650. F77_FUNC(xdrruchar,XDRRUCHAR)(int *fid, unsigned char *ip, int *ndata, int *ret)
  1651. {
  1652. *ret = xdrfile_read_uchar(ip,*ndata,f77xdr[*fid]);
  1653. }
  1654. void
  1655. F77_FUNC(xdrwuchar,XDRWUCHAR)(int *fid, unsigned char *ip, int *ndata, int *ret)
  1656. {
  1657. *ret = xdrfile_write_uchar(ip,*ndata,f77xdr[*fid]);
  1658. }
  1659. void
  1660. F77_FUNC(xdrrshort,XDRRSHORT)(int *fid, short *ip, int *ndata, int *ret)
  1661. {
  1662. *ret = xdrfile_read_short(ip,*ndata,f77xdr[*fid]);
  1663. }
  1664. void
  1665. F77_FUNC(xdrwshort,XDRWSHORT)(int *fid, short *ip, int *ndata, int *ret)
  1666. {
  1667. *ret = xdrfile_write_short(ip,*ndata,f77xdr[*fid]);
  1668. }
  1669. void
  1670. F77_FUNC(xdrrushort,XDRRUSHORT)(int *fid, unsigned short *ip, int *ndata, int *ret)
  1671. {
  1672. *ret = xdrfile_read_ushort(ip,*ndata,f77xdr[*fid]);
  1673. }
  1674. void
  1675. F77_FUNC(xdrwushort,XDRWUSHORT)(int *fid, unsigned short *ip, int *ndata, int *ret)
  1676. {
  1677. *ret = xdrfile_write_ushort(ip,*ndata,f77xdr[*fid]);
  1678. }
  1679. void
  1680. F77_FUNC(xdrrsingle,XDRRSINGLE)(int *fid, float *data, int *ndata, int *ret)
  1681. {
  1682. *ret = xdrfile_read_float(data,*ndata,f77xdr[*fid]);
  1683. }
  1684. void
  1685. F77_FUNC(xdrwsingle,XDRWSINGLE)(int *fid, float *data, int *ndata, int *ret)
  1686. {
  1687. *ret = xdrfile_write_float(data,*ndata,f77xdr[*fid]);
  1688. }
  1689. void
  1690. F77_FUNC(xdrrdouble,XDRRDOUBLE)(int *fid, double *data, int *ndata, int *ret)
  1691. {
  1692. *ret = xdrfile_read_double(data,*ndata,f77xdr[*fid]);
  1693. }
  1694. void
  1695. F77_FUNC(xdrwdouble,XDRWDOUBLE)(int *fid, double *data, int *ndata, int *ret)
  1696. {
  1697. *ret = xdrfile_write_double(data,*ndata,f77xdr[*fid]);
  1698. }
  1699. static int ftocstr(char *dest, int destlen, char *src, int srclen)
  1700. {
  1701. char *p;
  1702. p = src + srclen;
  1703. while ( --p >= src && *p == ' ' );
  1704. srclen = p - src + 1;
  1705. destlen--;
  1706. dest[0] = 0;
  1707. if (srclen > destlen)
  1708. return 1;
  1709. while (srclen--)
  1710. (*dest++ = *src++);
  1711. *dest = '\0';
  1712. return 0;
  1713. }
  1714. static int ctofstr(char *dest, int destlen, char *src)
  1715. {
  1716. while (destlen && *src) {
  1717. *dest++ = *src++;
  1718. destlen--;
  1719. }
  1720. while (destlen--)
  1721. *dest++ = ' ';
  1722. return 0;
  1723. }
  1724. void
  1725. F77_FUNC(xdrrstring,XDRRSTRING)(int *fid, char *str, int *ret, int len)
  1726. {
  1727. char *cstr;
  1728. if((cstr=(char*)malloc((len+1)*sizeof(char)))==NULL) {
  1729. *ret = 0;
  1730. return;
  1731. }
  1732. if (ftocstr(cstr, len+1, str, len)) {
  1733. *ret = 0;
  1734. free(cstr);
  1735. return;
  1736. }
  1737. *ret = xdrfile_read_string(cstr, len+1,f77xdr[*fid]);
  1738. ctofstr( str, len , cstr);
  1739. free(cstr);
  1740. }
  1741. void
  1742. F77_FUNC(xdrwstring,XDRWSTRING)(int *fid, char *str, int *ret, int len)
  1743. {
  1744. char *cstr;
  1745. if((cstr=(char*)malloc((len+1)*sizeof(char)))==NULL) {
  1746. *ret = 0;
  1747. return;
  1748. }
  1749. if (ftocstr(cstr, len+1, str, len)) {
  1750. *ret = 0;
  1751. free(cstr);
  1752. return;
  1753. }
  1754. *ret = xdrfile_write_string(cstr, f77xdr[*fid]);
  1755. ctofstr( str, len , cstr);
  1756. free(cstr);
  1757. }
  1758. void
  1759. F77_FUNC(xdrropaque,XDRROPAQUE)(int *fid, char *data, int *ndata, int *ret)
  1760. {
  1761. *ret = xdrfile_read_opaque(data,*ndata,f77xdr[*fid]);
  1762. }
  1763. void
  1764. F77_FUNC(xdrwopaque,XDRWOPAQUE)(int *fid, char *data, int *ndata, int *ret)
  1765. {
  1766. *ret = xdrfile_write_opaque(data,*ndata,f77xdr[*fid]);
  1767. }
  1768. /* Write single-precision compressed 3d coordinates */
  1769. void
  1770. F77_FUNC(xdrccs,XDRCCS)(int *fid, float *data, i

Large files files are truncated, but you can click here to view the full file