Added conditional inclusion of config.h to source files
[gromacs.git] / src / gmxlib / libxdrf.c
blob522cc3804850c33e89ac7dbd209679f172a5c2ab
1 /*
2 * $Id$
3 *
4 * This source code is part of
5 *
6 * G R O M A C S
7 *
8 * GROningen MAchine for Chemical Simulations
9 *
10 * VERSION 3.2.0
11 * Written by David van der Spoel, Erik Lindahl, Berk Hess, and others.
12 * Copyright (c) 1991-2000, University of Groningen, The Netherlands.
13 * Copyright (c) 2001-2004, The GROMACS development team,
14 * check out http://www.gromacs.org for more information.
16 * This program is free software; you can redistribute it and/or
17 * modify it under the terms of the GNU General Public License
18 * as published by the Free Software Foundation; either version 2
19 * of the License, or (at your option) any later version.
21 * If you want to redistribute modifications, please consider that
22 * scientific software is very special. Version control is crucial -
23 * bugs must be traceable. We will be happy to consider code for
24 * inclusion in the official distribution, but derived work must not
25 * be called official GROMACS. Details are found in the README & COPYING
26 * files - if they are missing, get the official version at www.gromacs.org.
28 * To help us fund GROMACS development, we humbly ask that you cite
29 * the papers on the package - you can find them in the top README file.
31 * For more info, check our website at http://www.gromacs.org
33 * And Hey:
34 * GROningen Mixture of Alchemy and Childrens' Stories
36 #ifdef HAVE_CONFIG_H
37 #include <config.h>
38 #endif
40 #include <limits.h>
41 #include <math.h>
42 #include <stdio.h>
43 #include <stdlib.h>
44 #include <string.h>
45 #include "xdrf.h"
46 #include <callf77.h>
50 #define MAXID 256
51 static FILE *xdrfiles[MAXID];
52 static XDR *xdridptr[MAXID];
53 static char xdrmodes[MAXID];
54 static unsigned int cnt;
57 #ifdef USE_FORTRAN
59 typedef void (* F77_FUNC(xdrfproc,XDRFPROC))(int *, void *, int *);
61 int ftocstr(char *ds, int dl, char *ss, int sl)
62 /* dst, src ptrs */
63 /* dst max len */
64 /* src len */
66 char *p;
68 p = ss + sl;
69 while ( --p >= ss && *p == ' ' );
70 sl = p - ss + 1;
71 dl--;
72 ds[0] = 0;
73 if (sl > dl)
74 return 1;
75 while (sl--)
76 (*ds++ = *ss++);
77 *ds = '\0';
78 return 0;
82 int ctofstr(char *ds, int dl, char *ss)
83 /* dest space */
84 /* max dest length */
85 /* src string (0-term) */
87 while (dl && *ss) {
88 *ds++ = *ss++;
89 dl--;
91 while (dl--)
92 *ds++ = ' ';
93 return 0;
96 void
97 F77_FUNC(xdrfbool,XDRFBOOL)(int *xdrid, int *pb, int *ret)
99 *ret = xdr_bool(xdridptr[*xdrid], pb);
100 cnt += sizeof(int);
103 void
104 F77_FUNC(xdrfchar,XDRFCHAR)(int *xdrid, char *cp, int *ret)
106 *ret = xdr_char(xdridptr[*xdrid], cp);
107 cnt += sizeof(char);
110 void
111 F77_FUNC(xdrfdouble,XDRFDOUBLE)(int *xdrid, double *dp, int *ret)
113 *ret = xdr_double(xdridptr[*xdrid], dp);
114 cnt += sizeof(double);
117 void
118 F77_FUNC(xdrffloat,XDRFFLOAT)(int *xdrid, float *fp, int *ret)
120 *ret = xdr_float(xdridptr[*xdrid], fp);
121 cnt += sizeof(float);
124 void
125 F77_FUNC(xdrfint,XDRFINT)(int *xdrid, int *ip, int *ret)
127 *ret = xdr_int(xdridptr[*xdrid], ip);
128 cnt += sizeof(int);
131 void
132 F77_FUNC(xdrflong,XDRFLONG)(int *xdrid, long *lp, int *ret)
134 *ret = xdr_long(xdridptr[*xdrid], lp);
135 cnt += sizeof(long);
138 void
139 F77_FUNC(xdrfshort,XDRFSHORT)(int *xdrid, short *sp, int *ret)
141 *ret = xdr_short(xdridptr[*xdrid], sp);
142 cnt += sizeof(sp);
145 void
146 F77_FUNC(xdrfuchar,XDRFUCHAR)(int *xdrid, unsigned char *ucp, int *ret)
148 *ret = xdr_u_char(xdridptr[*xdrid], (u_char *)ucp);
149 cnt += sizeof(char);
152 void
153 F77_FUNC(xdrfulong,XDRFULONG)(int *xdrid, unsigned long *ulp, int *ret)
155 *ret = xdr_u_long(xdridptr[*xdrid], (u_long *)ulp);
156 cnt += sizeof(unsigned long);
159 void
160 F77_FUNC(xdrfushort,XDRFUSHORT)(int *xdrid, unsigned short *usp, int *ret)
162 *ret = xdr_u_short(xdridptr[*xdrid], (unsigned short *)usp);
163 cnt += sizeof(unsigned short);
166 void
167 F77_FUNC(xdrf3dfcoord,XDRF3DFCOORD)(int *xdrid, float *fp, int *size, float *precision, int *ret)
169 *ret = xdr3dfcoord(xdridptr[*xdrid], fp, size, precision);
172 void
173 F77_FUNC(xdrfstring,XDRFSTRING)(int *xdrid, char * sp_ptr,
174 int *maxsize, int *ret, int sp_len)
176 char *tsp;
178 tsp = (char*) malloc((size_t)(((sp_len) + 1) * sizeof(char)));
179 if (tsp == NULL) {
180 *ret = -1;
181 return;
183 if (ftocstr(tsp, *maxsize+1, sp_ptr, sp_len)) {
184 *ret = -1;
185 free(tsp);
186 return;
188 *ret = xdr_string(xdridptr[*xdrid], (char **) &tsp, (unsigned int) *maxsize);
189 ctofstr( sp_ptr, sp_len , tsp);
190 cnt += *maxsize;
191 free(tsp);
194 void
195 F77_FUNC(xdrfwrapstring,XDRFWRAPSTRING)(int *xdrid, char *sp_ptr,
196 int *ret, int sp_len)
198 char *tsp;
199 int maxsize;
200 maxsize = (sp_len) + 1;
201 tsp = (char*) malloc((size_t)(maxsize * sizeof(char)));
202 if (tsp == NULL) {
203 *ret = -1;
204 return;
206 if (ftocstr(tsp, maxsize, sp_ptr, sp_len)) {
207 *ret = -1;
208 free(tsp);
209 return;
211 *ret = xdr_string(xdridptr[*xdrid], (char **) &tsp, (u_int)maxsize);
212 ctofstr( sp_ptr, sp_len, tsp);
213 cnt += maxsize;
214 free(tsp);
217 void
218 F77_FUNC(xdrfopaque,XDRFOPAQUE)(int *xdrid, caddr_t *cp, int *ccnt, int *ret)
220 *ret = xdr_opaque(xdridptr[*xdrid], (caddr_t)*cp, (u_int)*ccnt);
221 cnt += *ccnt;
224 void
225 F77_FUNC(xdrfsetpos,XDRFSETPOS)(int *xdrid, int *pos, int *ret)
227 *ret = xdr_setpos(xdridptr[*xdrid], (u_int) *pos);
231 void
232 F77_FUNC(xdrf,XDRF)(int *xdrid, int *pos)
234 *pos = xdr_getpos(xdridptr[*xdrid]);
237 void
238 F77_FUNC(xdrfvector,XDRFVECTOR)(int *xdrid, char *cp, int *size, F77_FUNC(xdrfproc,XDRFPROC) elproc, int *ret)
240 int lcnt;
241 cnt = 0;
242 for (lcnt = 0; lcnt < *size; lcnt++) {
243 elproc(xdrid, (cp+cnt) , ret);
248 void
249 F77_FUNC(xdrfclose,XDRFCLOSE)(int *xdrid, int *ret)
251 *ret = xdrclose(xdridptr[*xdrid]);
252 cnt = 0;
255 void
256 F77_FUNC(xdrfopen,XDRFOPEN)(int *xdrid, char *fp_ptr, char *mode_ptr,
257 int *ret, int fp_len, int mode_len)
259 char fname[512];
260 char fmode[3];
262 if (ftocstr(fname, sizeof(fname), fp_ptr, fp_len)) {
263 *ret = 0;
265 if (ftocstr(fmode, sizeof(fmode), mode_ptr,
266 mode_len)) {
267 *ret = 0;
270 *xdrid = xdropen(NULL, fname, fmode);
271 if (*xdrid == 0)
272 *ret = 0;
273 else
274 *ret = 1;
276 #endif /* USE_FORTRAN */
278 /*___________________________________________________________________________
280 | what follows are the C routines for opening, closing xdr streams
281 | and the routine to read/write compressed coordinates together
282 | with some routines to assist in this task (those are marked
283 | static and cannot be called from user programs)
285 #define MAXABS INT_MAX-2
287 #ifndef MIN
288 #define MIN(x,y) ((x) < (y) ? (x):(y))
289 #endif
290 #ifndef MAX
291 #define MAX(x,y) ((x) > (y) ? (x):(y))
292 #endif
293 #ifndef SQR
294 #define SQR(x) ((x)*(x))
295 #endif
296 static int magicints[] = {
297 0, 0, 0, 0, 0, 0, 0, 0, 0,
298 8, 10, 12, 16, 20, 25, 32, 40, 50, 64,
299 80, 101, 128, 161, 203, 256, 322, 406, 512, 645,
300 812, 1024, 1290, 1625, 2048, 2580, 3250, 4096, 5060, 6501,
301 8192, 10321, 13003, 16384, 20642, 26007, 32768, 41285, 52015, 65536,
302 82570, 104031, 131072, 165140, 208063, 262144, 330280, 416127, 524287, 660561,
303 832255, 1048576, 1321122, 1664510, 2097152, 2642245, 3329021, 4194304, 5284491, 6658042,
304 8388607, 10568983, 13316085, 16777216 };
306 #define FIRSTIDX 9
307 /* note that magicints[FIRSTIDX-1] == 0 */
308 #define LASTIDX (sizeof(magicints) / sizeof(*magicints))
311 /*__________________________________________________________________________
313 | xdropen - open xdr file
315 | This versions differs from xdrstdio_create, because I need to know
316 | the state of the file (read or write) so I can use xdr3dfcoord
317 | in eigther read or write mode, and the file descriptor
318 | so I can close the file (something xdr_destroy doesn't do).
322 int xdropen(XDR *xdrs, const char *filename, const char *type) {
323 static int init_done = 0;
324 enum xdr_op lmode;
325 int xdrid;
326 char newtype[5];
328 if (init_done == 0) {
329 for (xdrid = 1; xdrid < MAXID; xdrid++) {
330 xdridptr[xdrid] = NULL;
332 init_done = 1;
334 xdrid = 1;
335 while (xdrid < MAXID && xdridptr[xdrid] != NULL) {
336 xdrid++;
338 if (xdrid == MAXID) {
339 return 0;
341 if (*type == 'w' || *type == 'W') {
342 strcpy(newtype,"wb+");
343 lmode = XDR_ENCODE;
344 } else if (*type == 'a' || *type == 'A') {
345 strcpy(newtype,"ab+");
346 lmode = XDR_ENCODE;
347 } else {
348 strcpy(newtype,"rb");
349 lmode = XDR_DECODE;
351 xdrfiles[xdrid] = fopen(filename, newtype);
352 if (xdrfiles[xdrid] == NULL) {
353 xdrs = NULL;
354 return 0;
356 xdrmodes[xdrid] = *type;
357 /* next test isn't usefull in the case of C language
358 * but is used for the Fortran interface
359 * (C users are expected to pass the address of an already allocated
360 * XDR staructure)
362 if (xdrs == NULL) {
363 xdridptr[xdrid] = (XDR *) malloc((size_t)sizeof(XDR));
364 xdrstdio_create(xdridptr[xdrid], xdrfiles[xdrid], lmode);
365 } else {
366 xdridptr[xdrid] = xdrs;
367 xdrstdio_create(xdrs, xdrfiles[xdrid], lmode);
369 return xdrid;
372 /*_________________________________________________________________________
374 | xdrclose - close a xdr file
376 | This will flush the xdr buffers, and destroy the xdr stream.
377 | It also closes the associated file descriptor (this is *not*
378 | done by xdr_destroy).
382 int xdrclose(XDR *xdrs) {
383 int xdrid;
385 if (xdrs == NULL) {
386 fprintf(stderr, "xdrclose: passed a NULL pointer\n");
387 exit(1);
389 for (xdrid = 1; xdrid < MAXID; xdrid++) {
390 if (xdridptr[xdrid] == xdrs) {
392 xdr_destroy(xdrs);
393 fclose(xdrfiles[xdrid]);
394 xdridptr[xdrid] = NULL;
395 return 1;
398 fprintf(stderr, "xdrclose: no such open xdr file\n");
399 exit(1);
401 /* to make some compilers happy: */
402 return 0;
405 /*____________________________________________________________________________
407 | sendbits - encode num into buf using the specified number of bits
409 | This routines appends the value of num to the bits already present in
410 | the array buf. You need to give it the number of bits to use and you
411 | better make sure that this number of bits is enough to hold the value
412 | Also num must be positive.
416 static void sendbits(int buf[], int num_of_bits, int num) {
418 unsigned int cnt, lastbyte;
419 int lastbits;
420 unsigned char * cbuf;
422 cbuf = ((unsigned char *)buf) + 3 * sizeof(*buf);
423 cnt = (unsigned int) buf[0];
424 lastbits = buf[1];
425 lastbyte =(unsigned int) buf[2];
426 while (num_of_bits >= 8) {
427 lastbyte = (lastbyte << 8) | ((num >> (num_of_bits -8)) /* & 0xff*/);
428 cbuf[cnt++] = lastbyte >> lastbits;
429 num_of_bits -= 8;
431 if (num_of_bits > 0) {
432 lastbyte = (lastbyte << num_of_bits) | num;
433 lastbits += num_of_bits;
434 if (lastbits >= 8) {
435 lastbits -= 8;
436 cbuf[cnt++] = lastbyte >> lastbits;
439 buf[0] = cnt;
440 buf[1] = lastbits;
441 buf[2] = lastbyte;
442 if (lastbits>0) {
443 cbuf[cnt] = lastbyte << (8 - lastbits);
447 /*_________________________________________________________________________
449 | sizeofint - calculate bitsize of an integer
451 | return the number of bits needed to store an integer with given max size
455 static int sizeofint(const int size) {
456 unsigned int num = 1;
457 int num_of_bits = 0;
459 while (size >= num && num_of_bits < 32) {
460 num_of_bits++;
461 num <<= 1;
463 return num_of_bits;
466 /*___________________________________________________________________________
468 | sizeofints - calculate 'bitsize' of compressed ints
470 | given the number of small unsigned integers and the maximum value
471 | return the number of bits needed to read or write them with the
472 | routines receiveints and sendints. You need this parameter when
473 | calling these routines. Note that for many calls I can use
474 | the variable 'smallidx' which is exactly the number of bits, and
475 | So I don't need to call 'sizeofints for those calls.
478 static int sizeofints( const int num_of_ints, unsigned int sizes[]) {
479 int i, num;
480 unsigned int num_of_bytes, num_of_bits, bytes[32], bytecnt, tmp;
481 num_of_bytes = 1;
482 bytes[0] = 1;
483 num_of_bits = 0;
484 for (i=0; i < num_of_ints; i++) {
485 tmp = 0;
486 for (bytecnt = 0; bytecnt < num_of_bytes; bytecnt++) {
487 tmp = bytes[bytecnt] * sizes[i] + tmp;
488 bytes[bytecnt] = tmp & 0xff;
489 tmp >>= 8;
491 while (tmp != 0) {
492 bytes[bytecnt++] = tmp & 0xff;
493 tmp >>= 8;
495 num_of_bytes = bytecnt;
497 num = 1;
498 num_of_bytes--;
499 while (bytes[num_of_bytes] >= num) {
500 num_of_bits++;
501 num *= 2;
503 return num_of_bits + num_of_bytes * 8;
507 /*____________________________________________________________________________
509 | sendints - send a small set of small integers in compressed format
511 | this routine is used internally by xdr3dfcoord, to send a set of
512 | small integers to the buffer.
513 | Multiplication with fixed (specified maximum ) sizes is used to get
514 | to one big, multibyte integer. Allthough the routine could be
515 | modified to handle sizes bigger than 16777216, or more than just
516 | a few integers, this is not done, because the gain in compression
517 | isn't worth the effort. Note that overflowing the multiplication
518 | or the byte buffer (32 bytes) is unchecked and causes bad results.
522 static void sendints(int buf[], const int num_of_ints, const int num_of_bits,
523 unsigned int sizes[], unsigned int nums[]) {
525 int i;
526 unsigned int bytes[32], num_of_bytes, bytecnt, tmp;
528 tmp = nums[0];
529 num_of_bytes = 0;
530 do {
531 bytes[num_of_bytes++] = tmp & 0xff;
532 tmp >>= 8;
533 } while (tmp != 0);
535 for (i = 1; i < num_of_ints; i++) {
536 if (nums[i] >= sizes[i]) {
537 fprintf(stderr,"major breakdown in sendints num %u doesn't "
538 "match size %u\n", nums[i], sizes[i]);
539 exit(1);
541 /* use one step multiply */
542 tmp = nums[i];
543 for (bytecnt = 0; bytecnt < num_of_bytes; bytecnt++) {
544 tmp = bytes[bytecnt] * sizes[i] + tmp;
545 bytes[bytecnt] = tmp & 0xff;
546 tmp >>= 8;
548 while (tmp != 0) {
549 bytes[bytecnt++] = tmp & 0xff;
550 tmp >>= 8;
552 num_of_bytes = bytecnt;
554 if (num_of_bits >= num_of_bytes * 8) {
555 for (i = 0; i < num_of_bytes; i++) {
556 sendbits(buf, 8, bytes[i]);
558 sendbits(buf, num_of_bits - num_of_bytes * 8, 0);
559 } else {
560 for (i = 0; i < num_of_bytes-1; i++) {
561 sendbits(buf, 8, bytes[i]);
563 sendbits(buf, num_of_bits- (num_of_bytes -1) * 8, bytes[i]);
568 /*___________________________________________________________________________
570 | receivebits - decode number from buf using specified number of bits
572 | extract the number of bits from the array buf and construct an integer
573 | from it. Return that value.
577 static int receivebits(int buf[], int num_of_bits) {
579 int cnt, num;
580 unsigned int lastbits, lastbyte;
581 unsigned char * cbuf;
582 int mask = (1 << num_of_bits) -1;
584 cbuf = ((unsigned char *)buf) + 3 * sizeof(*buf);
585 cnt = buf[0];
586 lastbits = (unsigned int) buf[1];
587 lastbyte = (unsigned int) buf[2];
589 num = 0;
590 while (num_of_bits >= 8) {
591 lastbyte = ( lastbyte << 8 ) | cbuf[cnt++];
592 num |= (lastbyte >> lastbits) << (num_of_bits - 8);
593 num_of_bits -=8;
595 if (num_of_bits > 0) {
596 if (lastbits < num_of_bits) {
597 lastbits += 8;
598 lastbyte = (lastbyte << 8) | cbuf[cnt++];
600 lastbits -= num_of_bits;
601 num |= (lastbyte >> lastbits) & ((1 << num_of_bits) -1);
603 num &= mask;
604 buf[0] = cnt;
605 buf[1] = lastbits;
606 buf[2] = lastbyte;
607 return num;
610 /*____________________________________________________________________________
612 | receiveints - decode 'small' integers from the buf array
614 | this routine is the inverse from sendints() and decodes the small integers
615 | written to buf by calculating the remainder and doing divisions with
616 | the given sizes[]. You need to specify the total number of bits to be
617 | used from buf in num_of_bits.
621 static void receiveints(int buf[], const int num_of_ints, int num_of_bits,
622 unsigned int sizes[], int nums[]) {
623 int bytes[32];
624 int i, j, num_of_bytes, p, num;
626 bytes[1] = bytes[2] = bytes[3] = 0;
627 num_of_bytes = 0;
628 while (num_of_bits > 8) {
629 bytes[num_of_bytes++] = receivebits(buf, 8);
630 num_of_bits -= 8;
632 if (num_of_bits > 0) {
633 bytes[num_of_bytes++] = receivebits(buf, num_of_bits);
635 for (i = num_of_ints-1; i > 0; i--) {
636 num = 0;
637 for (j = num_of_bytes-1; j >=0; j--) {
638 num = (num << 8) | bytes[j];
639 p = num / sizes[i];
640 bytes[j] = p;
641 num = num - p * sizes[i];
643 nums[i] = num;
645 nums[0] = bytes[0] | (bytes[1] << 8) | (bytes[2] << 16) | (bytes[3] << 24);
648 /*____________________________________________________________________________
650 | xdr3dfcoord - read or write compressed 3d coordinates to xdr file.
652 | this routine reads or writes (depending on how you opened the file with
653 | xdropen() ) a large number of 3d coordinates (stored in *fp).
654 | The number of coordinates triplets to write is given by *size. On
655 | read this number may be zero, in which case it reads as many as were written
656 | or it may specify the number if triplets to read (which should match the
657 | number written).
658 | Compression is achieved by first converting all floating numbers to integer
659 | using multiplication by *precision and rounding to the nearest integer.
660 | Then the minimum and maximum value are calculated to determine the range.
661 | The limited range of integers so found, is used to compress the coordinates.
662 | In addition the differences between succesive coordinates is calculated.
663 | If the difference happens to be 'small' then only the difference is saved,
664 | compressing the data even more. The notion of 'small' is changed dynamically
665 | and is enlarged or reduced whenever needed or possible.
666 | Extra compression is achieved in the case of GROMOS and coordinates of
667 | water molecules. GROMOS first writes out the Oxygen position, followed by
668 | the two hydrogens. In order to make the differences smaller (and thereby
669 | compression the data better) the order is changed into first one hydrogen
670 | then the oxygen, followed by the other hydrogen. This is rather special, but
671 | it shouldn't harm in the general case.
675 int xdr3dfcoord(XDR *xdrs, float *fp, int *size, float *precision) {
678 static int *ip = NULL;
679 static int oldsize;
680 static int *buf;
682 int minint[3], maxint[3], mindiff, *lip, diff;
683 int lint1, lint2, lint3, oldlint1, oldlint2, oldlint3, smallidx;
684 int minidx, maxidx;
685 unsigned sizeint[3], sizesmall[3], bitsizeint[3], size3, *luip;
686 int flag, k;
687 int smallnum, smaller, larger, i, is_small, is_smaller, run, prevrun;
688 float *lfp, lf;
689 int tmp, *thiscoord, prevcoord[3];
690 unsigned int tmpcoord[30];
692 int bufsize, xdrid, lsize;
693 unsigned int bitsize;
694 float inv_precision;
695 int errval = 1;
697 /* find out if xdrs is opened for reading or for writing */
698 xdrid = 0;
699 while (xdridptr[xdrid] != xdrs) {
700 xdrid++;
701 if (xdrid >= MAXID) {
702 fprintf(stderr, "xdr error. no open xdr stream\n");
703 exit (1);
706 if ((xdrmodes[xdrid] == 'w') || (xdrmodes[xdrid] == 'a')) {
708 /* xdrs is open for writing */
710 if (xdr_int(xdrs, size) == 0)
711 return 0;
712 size3 = *size * 3;
713 /* when the number of coordinates is small, don't try to compress; just
714 * write them as floats using xdr_vector
716 if (*size <= 9 ) {
717 return (xdr_vector(xdrs, (char *) fp, (unsigned int)size3,
718 (unsigned int)sizeof(*fp), (xdrproc_t)xdr_float));
721 xdr_float(xdrs, precision);
722 if (ip == NULL) {
723 ip = (int *)malloc((size_t)(size3 * sizeof(*ip)));
724 if (ip == NULL) {
725 fprintf(stderr,"malloc failed\n");
726 exit(1);
728 bufsize = size3 * 1.2;
729 buf = (int *)malloc((size_t)(bufsize * sizeof(*buf)));
730 if (buf == NULL) {
731 fprintf(stderr,"malloc failed\n");
732 exit(1);
734 oldsize = *size;
735 } else if (*size > oldsize) {
736 ip = (int *)realloc(ip, (size_t)(size3 * sizeof(*ip)));
737 if (ip == NULL) {
738 fprintf(stderr,"malloc failed\n");
739 exit(1);
741 bufsize = size3 * 1.2;
742 buf = (int *)realloc(buf, (size_t)(bufsize * sizeof(*buf)));
743 if (buf == NULL) {
744 fprintf(stderr,"realloc failed\n");
745 exit(1);
747 oldsize = *size;
749 /* buf[0-2] are special and do not contain actual data */
750 buf[0] = buf[1] = buf[2] = 0;
751 minint[0] = minint[1] = minint[2] = INT_MAX;
752 maxint[0] = maxint[1] = maxint[2] = INT_MIN;
753 prevrun = -1;
754 lfp = fp;
755 lip = ip;
756 mindiff = INT_MAX;
757 oldlint1 = oldlint2 = oldlint3 = 0;
758 while(lfp < fp + size3 ) {
759 /* find nearest integer */
760 if (*lfp >= 0.0)
761 lf = *lfp * *precision + 0.5;
762 else
763 lf = *lfp * *precision - 0.5;
764 if (fabs(lf) > MAXABS) {
765 /* scaling would cause overflow */
766 errval = 0;
768 lint1 = lf;
769 if (lint1 < minint[0]) minint[0] = lint1;
770 if (lint1 > maxint[0]) maxint[0] = lint1;
771 *lip++ = lint1;
772 lfp++;
773 if (*lfp >= 0.0)
774 lf = *lfp * *precision + 0.5;
775 else
776 lf = *lfp * *precision - 0.5;
777 if (fabs(lf) > MAXABS) {
778 /* scaling would cause overflow */
779 errval = 0;
781 lint2 = lf;
782 if (lint2 < minint[1]) minint[1] = lint2;
783 if (lint2 > maxint[1]) maxint[1] = lint2;
784 *lip++ = lint2;
785 lfp++;
786 if (*lfp >= 0.0)
787 lf = *lfp * *precision + 0.5;
788 else
789 lf = *lfp * *precision - 0.5;
790 if (fabs(lf) > MAXABS) {
791 /* scaling would cause overflow */
792 errval = 0;
794 lint3 = lf;
795 if (lint3 < minint[2]) minint[2] = lint3;
796 if (lint3 > maxint[2]) maxint[2] = lint3;
797 *lip++ = lint3;
798 lfp++;
799 diff = abs(oldlint1-lint1)+abs(oldlint2-lint2)+abs(oldlint3-lint3);
800 if (diff < mindiff && lfp > fp + 3)
801 mindiff = diff;
802 oldlint1 = lint1;
803 oldlint2 = lint2;
804 oldlint3 = lint3;
806 xdr_int(xdrs, &(minint[0]));
807 xdr_int(xdrs, &(minint[1]));
808 xdr_int(xdrs, &(minint[2]));
810 xdr_int(xdrs, &(maxint[0]));
811 xdr_int(xdrs, &(maxint[1]));
812 xdr_int(xdrs, &(maxint[2]));
814 if ((float)maxint[0] - (float)minint[0] >= MAXABS ||
815 (float)maxint[1] - (float)minint[1] >= MAXABS ||
816 (float)maxint[2] - (float)minint[2] >= MAXABS) {
817 /* turning value in unsigned by subtracting minint
818 * would cause overflow
820 errval = 0;
822 sizeint[0] = maxint[0] - minint[0]+1;
823 sizeint[1] = maxint[1] - minint[1]+1;
824 sizeint[2] = maxint[2] - minint[2]+1;
826 /* check if one of the sizes is to big to be multiplied */
827 if ((sizeint[0] | sizeint[1] | sizeint[2] ) > 0xffffff) {
828 bitsizeint[0] = sizeofint(sizeint[0]);
829 bitsizeint[1] = sizeofint(sizeint[1]);
830 bitsizeint[2] = sizeofint(sizeint[2]);
831 bitsize = 0; /* flag the use of large sizes */
832 } else {
833 bitsize = sizeofints(3, sizeint);
835 lip = ip;
836 luip = (unsigned int *) ip;
837 smallidx = FIRSTIDX;
838 while (smallidx < LASTIDX && magicints[smallidx] < mindiff) {
839 smallidx++;
841 xdr_int(xdrs, &smallidx);
842 maxidx = MIN(LASTIDX, smallidx + 8) ;
843 minidx = maxidx - 8; /* often this equal smallidx */
844 smaller = magicints[MAX(FIRSTIDX, smallidx-1)] / 2;
845 smallnum = magicints[smallidx] / 2;
846 sizesmall[0] = sizesmall[1] = sizesmall[2] = magicints[smallidx];
847 larger = magicints[maxidx] / 2;
848 i = 0;
849 while (i < *size) {
850 is_small = 0;
851 thiscoord = (int *)(luip) + i * 3;
852 if (smallidx < maxidx && i >= 1 &&
853 abs(thiscoord[0] - prevcoord[0]) < larger &&
854 abs(thiscoord[1] - prevcoord[1]) < larger &&
855 abs(thiscoord[2] - prevcoord[2]) < larger) {
856 is_smaller = 1;
857 } else if (smallidx > minidx) {
858 is_smaller = -1;
859 } else {
860 is_smaller = 0;
862 if (i + 1 < *size) {
863 if (abs(thiscoord[0] - thiscoord[3]) < smallnum &&
864 abs(thiscoord[1] - thiscoord[4]) < smallnum &&
865 abs(thiscoord[2] - thiscoord[5]) < smallnum) {
866 /* interchange first with second atom for better
867 * compression of water molecules
869 tmp = thiscoord[0]; thiscoord[0] = thiscoord[3];
870 thiscoord[3] = tmp;
871 tmp = thiscoord[1]; thiscoord[1] = thiscoord[4];
872 thiscoord[4] = tmp;
873 tmp = thiscoord[2]; thiscoord[2] = thiscoord[5];
874 thiscoord[5] = tmp;
875 is_small = 1;
879 tmpcoord[0] = thiscoord[0] - minint[0];
880 tmpcoord[1] = thiscoord[1] - minint[1];
881 tmpcoord[2] = thiscoord[2] - minint[2];
882 if (bitsize == 0) {
883 sendbits(buf, bitsizeint[0], tmpcoord[0]);
884 sendbits(buf, bitsizeint[1], tmpcoord[1]);
885 sendbits(buf, bitsizeint[2], tmpcoord[2]);
886 } else {
887 sendints(buf, 3, bitsize, sizeint, tmpcoord);
889 prevcoord[0] = thiscoord[0];
890 prevcoord[1] = thiscoord[1];
891 prevcoord[2] = thiscoord[2];
892 thiscoord = thiscoord + 3;
893 i++;
895 run = 0;
896 if (is_small == 0 && is_smaller == -1)
897 is_smaller = 0;
898 while (is_small && run < 8*3) {
899 if (is_smaller == -1 && (
900 SQR(thiscoord[0] - prevcoord[0]) +
901 SQR(thiscoord[1] - prevcoord[1]) +
902 SQR(thiscoord[2] - prevcoord[2]) >= smaller * smaller)) {
903 is_smaller = 0;
906 tmpcoord[run++] = thiscoord[0] - prevcoord[0] + smallnum;
907 tmpcoord[run++] = thiscoord[1] - prevcoord[1] + smallnum;
908 tmpcoord[run++] = thiscoord[2] - prevcoord[2] + smallnum;
910 prevcoord[0] = thiscoord[0];
911 prevcoord[1] = thiscoord[1];
912 prevcoord[2] = thiscoord[2];
914 i++;
915 thiscoord = thiscoord + 3;
916 is_small = 0;
917 if (i < *size &&
918 abs(thiscoord[0] - prevcoord[0]) < smallnum &&
919 abs(thiscoord[1] - prevcoord[1]) < smallnum &&
920 abs(thiscoord[2] - prevcoord[2]) < smallnum) {
921 is_small = 1;
924 if (run != prevrun || is_smaller != 0) {
925 prevrun = run;
926 sendbits(buf, 1, 1); /* flag the change in run-length */
927 sendbits(buf, 5, run+is_smaller+1);
928 } else {
929 sendbits(buf, 1, 0); /* flag the fact that runlength did not change */
931 for (k=0; k < run; k+=3) {
932 sendints(buf, 3, smallidx, sizesmall, &tmpcoord[k]);
934 if (is_smaller != 0) {
935 smallidx += is_smaller;
936 if (is_smaller < 0) {
937 smallnum = smaller;
938 smaller = magicints[smallidx-1] / 2;
939 } else {
940 smaller = smallnum;
941 smallnum = magicints[smallidx] / 2;
943 sizesmall[0] = sizesmall[1] = sizesmall[2] = magicints[smallidx];
946 if (buf[1] != 0) buf[0]++;
947 xdr_int(xdrs, &(buf[0])); /* buf[0] holds the length in bytes */
948 return errval * (xdr_opaque(xdrs, (char *)&(buf[3]), (unsigned int)buf[0]));
949 } else {
951 /* xdrs is open for reading */
953 if (xdr_int(xdrs, &lsize) == 0)
954 return 0;
955 if (*size != 0 && lsize != *size) {
956 fprintf(stderr, "wrong number of coordinates in xdr3dfcoord; "
957 "%d arg vs %d in file", *size, lsize);
959 *size = lsize;
960 size3 = *size * 3;
961 if (*size <= 9) {
962 return (xdr_vector(xdrs, (char *) fp, (unsigned int)size3,
963 (unsigned int)sizeof(*fp), (xdrproc_t)xdr_float));
965 xdr_float(xdrs, precision);
966 if (ip == NULL) {
967 ip = (int *)malloc((size_t)(size3 * sizeof(*ip)));
968 if (ip == NULL) {
969 fprintf(stderr,"malloc failed\n");
970 exit(1);
972 bufsize = size3 * 1.2;
973 buf = (int *)malloc((size_t)(bufsize * sizeof(*buf)));
974 if (buf == NULL) {
975 fprintf(stderr,"malloc failed\n");
976 exit(1);
978 oldsize = *size;
979 } else if (*size > oldsize) {
980 ip = (int *)realloc(ip, (size_t)(size3 * sizeof(*ip)));
981 if (ip == NULL) {
982 fprintf(stderr,"malloc failed\n");
983 exit(1);
985 bufsize = size3 * 1.2;
986 buf = (int *)realloc(buf, (size_t)(bufsize * sizeof(*buf)));
987 if (buf == NULL) {
988 fprintf(stderr,"malloc failed\n");
989 exit(1);
991 oldsize = *size;
993 buf[0] = buf[1] = buf[2] = 0;
995 xdr_int(xdrs, &(minint[0]));
996 xdr_int(xdrs, &(minint[1]));
997 xdr_int(xdrs, &(minint[2]));
999 xdr_int(xdrs, &(maxint[0]));
1000 xdr_int(xdrs, &(maxint[1]));
1001 xdr_int(xdrs, &(maxint[2]));
1003 sizeint[0] = maxint[0] - minint[0]+1;
1004 sizeint[1] = maxint[1] - minint[1]+1;
1005 sizeint[2] = maxint[2] - minint[2]+1;
1007 /* check if one of the sizes is to big to be multiplied */
1008 if ((sizeint[0] | sizeint[1] | sizeint[2] ) > 0xffffff) {
1009 bitsizeint[0] = sizeofint(sizeint[0]);
1010 bitsizeint[1] = sizeofint(sizeint[1]);
1011 bitsizeint[2] = sizeofint(sizeint[2]);
1012 bitsize = 0; /* flag the use of large sizes */
1013 } else {
1014 bitsize = sizeofints(3, sizeint);
1017 if (xdr_int(xdrs, &smallidx) == 0)
1018 return 0;
1019 maxidx = MIN(LASTIDX, smallidx + 8) ;
1020 minidx = maxidx - 8; /* often this equal smallidx */
1021 smaller = magicints[MAX(FIRSTIDX, smallidx-1)] / 2;
1022 smallnum = magicints[smallidx] / 2;
1023 sizesmall[0] = sizesmall[1] = sizesmall[2] = magicints[smallidx] ;
1024 larger = magicints[maxidx];
1026 /* buf[0] holds the length in bytes */
1028 if (xdr_int(xdrs, &(buf[0])) == 0)
1029 return 0;
1030 if (xdr_opaque(xdrs, (char *)&(buf[3]), (unsigned int)buf[0]) == 0)
1031 return 0;
1032 buf[0] = buf[1] = buf[2] = 0;
1034 lfp = fp;
1035 inv_precision = 1.0 / * precision;
1036 run = 0;
1037 i = 0;
1038 lip = ip;
1039 while ( i < lsize ) {
1040 thiscoord = (int *)(lip) + i * 3;
1042 if (bitsize == 0) {
1043 thiscoord[0] = receivebits(buf, bitsizeint[0]);
1044 thiscoord[1] = receivebits(buf, bitsizeint[1]);
1045 thiscoord[2] = receivebits(buf, bitsizeint[2]);
1046 } else {
1047 receiveints(buf, 3, bitsize, sizeint, thiscoord);
1050 i++;
1051 thiscoord[0] += minint[0];
1052 thiscoord[1] += minint[1];
1053 thiscoord[2] += minint[2];
1055 prevcoord[0] = thiscoord[0];
1056 prevcoord[1] = thiscoord[1];
1057 prevcoord[2] = thiscoord[2];
1060 flag = receivebits(buf, 1);
1061 is_smaller = 0;
1062 if (flag == 1) {
1063 run = receivebits(buf, 5);
1064 is_smaller = run % 3;
1065 run -= is_smaller;
1066 is_smaller--;
1068 if (run > 0) {
1069 thiscoord += 3;
1070 for (k = 0; k < run; k+=3) {
1071 receiveints(buf, 3, smallidx, sizesmall, thiscoord);
1072 i++;
1073 thiscoord[0] += prevcoord[0] - smallnum;
1074 thiscoord[1] += prevcoord[1] - smallnum;
1075 thiscoord[2] += prevcoord[2] - smallnum;
1076 if (k == 0) {
1077 /* interchange first with second atom for better
1078 * compression of water molecules
1080 tmp = thiscoord[0]; thiscoord[0] = prevcoord[0];
1081 prevcoord[0] = tmp;
1082 tmp = thiscoord[1]; thiscoord[1] = prevcoord[1];
1083 prevcoord[1] = tmp;
1084 tmp = thiscoord[2]; thiscoord[2] = prevcoord[2];
1085 prevcoord[2] = tmp;
1086 *lfp++ = prevcoord[0] * inv_precision;
1087 *lfp++ = prevcoord[1] * inv_precision;
1088 *lfp++ = prevcoord[2] * inv_precision;
1089 } else {
1090 prevcoord[0] = thiscoord[0];
1091 prevcoord[1] = thiscoord[1];
1092 prevcoord[2] = thiscoord[2];
1094 *lfp++ = thiscoord[0] * inv_precision;
1095 *lfp++ = thiscoord[1] * inv_precision;
1096 *lfp++ = thiscoord[2] * inv_precision;
1098 } else {
1099 *lfp++ = thiscoord[0] * inv_precision;
1100 *lfp++ = thiscoord[1] * inv_precision;
1101 *lfp++ = thiscoord[2] * inv_precision;
1103 smallidx += is_smaller;
1104 if (is_smaller < 0) {
1105 smallnum = smaller;
1106 if (smallidx > FIRSTIDX) {
1107 smaller = magicints[smallidx - 1] /2;
1108 } else {
1109 smaller = 0;
1111 } else if (is_smaller > 0) {
1112 smaller = smallnum;
1113 smallnum = magicints[smallidx] / 2;
1115 sizesmall[0] = sizesmall[1] = sizesmall[2] = magicints[smallidx] ;
1118 return 1;