4 * This source code is part of
8 * GROningen MAchine for Chemical Simulations
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
34 * GROningen Mixture of Alchemy and Childrens' Stories
51 static FILE *xdrfiles
[MAXID
];
52 static XDR
*xdridptr
[MAXID
];
53 static char xdrmodes
[MAXID
];
54 static unsigned int cnt
;
59 typedef void (* F77_FUNC(xdrfproc
,XDRFPROC
))(int *, void *, int *);
61 int ftocstr(char *ds
, int dl
, char *ss
, int sl
)
69 while ( --p
>= ss
&& *p
== ' ' );
82 int ctofstr(char *ds
, int dl
, char *ss
)
85 /* src string (0-term) */
97 F77_FUNC(xdrfbool
,XDRFBOOL
)(int *xdrid
, int *pb
, int *ret
)
99 *ret
= xdr_bool(xdridptr
[*xdrid
], pb
);
104 F77_FUNC(xdrfchar
,XDRFCHAR
)(int *xdrid
, char *cp
, int *ret
)
106 *ret
= xdr_char(xdridptr
[*xdrid
], cp
);
111 F77_FUNC(xdrfdouble
,XDRFDOUBLE
)(int *xdrid
, double *dp
, int *ret
)
113 *ret
= xdr_double(xdridptr
[*xdrid
], dp
);
114 cnt
+= sizeof(double);
118 F77_FUNC(xdrffloat
,XDRFFLOAT
)(int *xdrid
, float *fp
, int *ret
)
120 *ret
= xdr_float(xdridptr
[*xdrid
], fp
);
121 cnt
+= sizeof(float);
125 F77_FUNC(xdrfint
,XDRFINT
)(int *xdrid
, int *ip
, int *ret
)
127 *ret
= xdr_int(xdridptr
[*xdrid
], ip
);
132 F77_FUNC(xdrflong
,XDRFLONG
)(int *xdrid
, long *lp
, int *ret
)
134 *ret
= xdr_long(xdridptr
[*xdrid
], lp
);
139 F77_FUNC(xdrfshort
,XDRFSHORT
)(int *xdrid
, short *sp
, int *ret
)
141 *ret
= xdr_short(xdridptr
[*xdrid
], sp
);
146 F77_FUNC(xdrfuchar
,XDRFUCHAR
)(int *xdrid
, unsigned char *ucp
, int *ret
)
148 *ret
= xdr_u_char(xdridptr
[*xdrid
], (u_char
*)ucp
);
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);
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);
167 F77_FUNC(xdrf3dfcoord
,XDRF3DFCOORD
)(int *xdrid
, float *fp
, int *size
, float *precision
, int *ret
)
169 *ret
= xdr3dfcoord(xdridptr
[*xdrid
], fp
, size
, precision
);
173 F77_FUNC(xdrfstring
,XDRFSTRING
)(int *xdrid
, char * sp_ptr
,
174 int *maxsize
, int *ret
, int sp_len
)
178 tsp
= (char*) malloc((size_t)(((sp_len
) + 1) * sizeof(char)));
183 if (ftocstr(tsp
, *maxsize
+1, sp_ptr
, sp_len
)) {
188 *ret
= xdr_string(xdridptr
[*xdrid
], (char **) &tsp
, (unsigned int) *maxsize
);
189 ctofstr( sp_ptr
, sp_len
, tsp
);
195 F77_FUNC(xdrfwrapstring
,XDRFWRAPSTRING
)(int *xdrid
, char *sp_ptr
,
196 int *ret
, int sp_len
)
200 maxsize
= (sp_len
) + 1;
201 tsp
= (char*) malloc((size_t)(maxsize
* sizeof(char)));
206 if (ftocstr(tsp
, maxsize
, sp_ptr
, sp_len
)) {
211 *ret
= xdr_string(xdridptr
[*xdrid
], (char **) &tsp
, (u_int
)maxsize
);
212 ctofstr( sp_ptr
, sp_len
, tsp
);
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
);
225 F77_FUNC(xdrfsetpos
,XDRFSETPOS
)(int *xdrid
, int *pos
, int *ret
)
227 *ret
= xdr_setpos(xdridptr
[*xdrid
], (u_int
) *pos
);
232 F77_FUNC(xdrf
,XDRF
)(int *xdrid
, int *pos
)
234 *pos
= xdr_getpos(xdridptr
[*xdrid
]);
238 F77_FUNC(xdrfvector
,XDRFVECTOR
)(int *xdrid
, char *cp
, int *size
, F77_FUNC(xdrfproc
,XDRFPROC
) elproc
, int *ret
)
242 for (lcnt
= 0; lcnt
< *size
; lcnt
++) {
243 elproc(xdrid
, (cp
+cnt
) , ret
);
249 F77_FUNC(xdrfclose
,XDRFCLOSE
)(int *xdrid
, int *ret
)
251 *ret
= xdrclose(xdridptr
[*xdrid
]);
256 F77_FUNC(xdrfopen
,XDRFOPEN
)(int *xdrid
, char *fp_ptr
, char *mode_ptr
,
257 int *ret
, int fp_len
, int mode_len
)
262 if (ftocstr(fname
, sizeof(fname
), fp_ptr
, fp_len
)) {
265 if (ftocstr(fmode
, sizeof(fmode
), mode_ptr
,
270 *xdrid
= xdropen(NULL
, fname
, fmode
);
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
288 #define MIN(x,y) ((x) < (y) ? (x):(y))
291 #define MAX(x,y) ((x) > (y) ? (x):(y))
294 #define SQR(x) ((x)*(x))
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 };
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;
328 if (init_done
== 0) {
329 for (xdrid
= 1; xdrid
< MAXID
; xdrid
++) {
330 xdridptr
[xdrid
] = NULL
;
335 while (xdrid
< MAXID
&& xdridptr
[xdrid
] != NULL
) {
338 if (xdrid
== MAXID
) {
341 if (*type
== 'w' || *type
== 'W') {
342 strcpy(newtype
,"wb+");
344 } else if (*type
== 'a' || *type
== 'A') {
345 strcpy(newtype
,"ab+");
348 strcpy(newtype
,"rb");
351 xdrfiles
[xdrid
] = fopen(filename
, newtype
);
352 if (xdrfiles
[xdrid
] == NULL
) {
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
363 xdridptr
[xdrid
] = (XDR
*) malloc((size_t)sizeof(XDR
));
364 xdrstdio_create(xdridptr
[xdrid
], xdrfiles
[xdrid
], lmode
);
366 xdridptr
[xdrid
] = xdrs
;
367 xdrstdio_create(xdrs
, xdrfiles
[xdrid
], lmode
);
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
) {
386 fprintf(stderr
, "xdrclose: passed a NULL pointer\n");
389 for (xdrid
= 1; xdrid
< MAXID
; xdrid
++) {
390 if (xdridptr
[xdrid
] == xdrs
) {
393 fclose(xdrfiles
[xdrid
]);
394 xdridptr
[xdrid
] = NULL
;
398 fprintf(stderr
, "xdrclose: no such open xdr file\n");
401 /* to make some compilers happy: */
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
;
420 unsigned char * cbuf
;
422 cbuf
= ((unsigned char *)buf
) + 3 * sizeof(*buf
);
423 cnt
= (unsigned int) buf
[0];
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
;
431 if (num_of_bits
> 0) {
432 lastbyte
= (lastbyte
<< num_of_bits
) | num
;
433 lastbits
+= num_of_bits
;
436 cbuf
[cnt
++] = lastbyte
>> lastbits
;
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;
459 while (size
>= num
&& num_of_bits
< 32) {
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
[]) {
480 unsigned int num_of_bytes
, num_of_bits
, bytes
[32], bytecnt
, tmp
;
484 for (i
=0; i
< num_of_ints
; i
++) {
486 for (bytecnt
= 0; bytecnt
< num_of_bytes
; bytecnt
++) {
487 tmp
= bytes
[bytecnt
] * sizes
[i
] + tmp
;
488 bytes
[bytecnt
] = tmp
& 0xff;
492 bytes
[bytecnt
++] = tmp
& 0xff;
495 num_of_bytes
= bytecnt
;
499 while (bytes
[num_of_bytes
] >= num
) {
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
[]) {
526 unsigned int bytes
[32], num_of_bytes
, bytecnt
, tmp
;
531 bytes
[num_of_bytes
++] = tmp
& 0xff;
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
]);
541 /* use one step multiply */
543 for (bytecnt
= 0; bytecnt
< num_of_bytes
; bytecnt
++) {
544 tmp
= bytes
[bytecnt
] * sizes
[i
] + tmp
;
545 bytes
[bytecnt
] = tmp
& 0xff;
549 bytes
[bytecnt
++] = tmp
& 0xff;
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);
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
) {
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
);
586 lastbits
= (unsigned int) buf
[1];
587 lastbyte
= (unsigned int) buf
[2];
590 while (num_of_bits
>= 8) {
591 lastbyte
= ( lastbyte
<< 8 ) | cbuf
[cnt
++];
592 num
|= (lastbyte
>> lastbits
) << (num_of_bits
- 8);
595 if (num_of_bits
> 0) {
596 if (lastbits
< num_of_bits
) {
598 lastbyte
= (lastbyte
<< 8) | cbuf
[cnt
++];
600 lastbits
-= num_of_bits
;
601 num
|= (lastbyte
>> lastbits
) & ((1 << num_of_bits
) -1);
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
[]) {
624 int i
, j
, num_of_bytes
, p
, num
;
626 bytes
[1] = bytes
[2] = bytes
[3] = 0;
628 while (num_of_bits
> 8) {
629 bytes
[num_of_bytes
++] = receivebits(buf
, 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
--) {
637 for (j
= num_of_bytes
-1; j
>=0; j
--) {
638 num
= (num
<< 8) | bytes
[j
];
641 num
= num
- p
* sizes
[i
];
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
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
;
682 int minint
[3], maxint
[3], mindiff
, *lip
, diff
;
683 int lint1
, lint2
, lint3
, oldlint1
, oldlint2
, oldlint3
, smallidx
;
685 unsigned sizeint
[3], sizesmall
[3], bitsizeint
[3], size3
, *luip
;
687 int smallnum
, smaller
, larger
, i
, is_small
, is_smaller
, run
, prevrun
;
689 int tmp
, *thiscoord
, prevcoord
[3];
690 unsigned int tmpcoord
[30];
692 int bufsize
, xdrid
, lsize
;
693 unsigned int bitsize
;
697 /* find out if xdrs is opened for reading or for writing */
699 while (xdridptr
[xdrid
] != xdrs
) {
701 if (xdrid
>= MAXID
) {
702 fprintf(stderr
, "xdr error. no open xdr stream\n");
706 if ((xdrmodes
[xdrid
] == 'w') || (xdrmodes
[xdrid
] == 'a')) {
708 /* xdrs is open for writing */
710 if (xdr_int(xdrs
, size
) == 0)
713 /* when the number of coordinates is small, don't try to compress; just
714 * write them as floats using xdr_vector
717 return (xdr_vector(xdrs
, (char *) fp
, (unsigned int)size3
,
718 (unsigned int)sizeof(*fp
), (xdrproc_t
)xdr_float
));
721 xdr_float(xdrs
, precision
);
723 ip
= (int *)malloc((size_t)(size3
* sizeof(*ip
)));
725 fprintf(stderr
,"malloc failed\n");
728 bufsize
= size3
* 1.2;
729 buf
= (int *)malloc((size_t)(bufsize
* sizeof(*buf
)));
731 fprintf(stderr
,"malloc failed\n");
735 } else if (*size
> oldsize
) {
736 ip
= (int *)realloc(ip
, (size_t)(size3
* sizeof(*ip
)));
738 fprintf(stderr
,"malloc failed\n");
741 bufsize
= size3
* 1.2;
742 buf
= (int *)realloc(buf
, (size_t)(bufsize
* sizeof(*buf
)));
744 fprintf(stderr
,"realloc failed\n");
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
;
757 oldlint1
= oldlint2
= oldlint3
= 0;
758 while(lfp
< fp
+ size3
) {
759 /* find nearest integer */
761 lf
= *lfp
* *precision
+ 0.5;
763 lf
= *lfp
* *precision
- 0.5;
764 if (fabs(lf
) > MAXABS
) {
765 /* scaling would cause overflow */
769 if (lint1
< minint
[0]) minint
[0] = lint1
;
770 if (lint1
> maxint
[0]) maxint
[0] = lint1
;
774 lf
= *lfp
* *precision
+ 0.5;
776 lf
= *lfp
* *precision
- 0.5;
777 if (fabs(lf
) > MAXABS
) {
778 /* scaling would cause overflow */
782 if (lint2
< minint
[1]) minint
[1] = lint2
;
783 if (lint2
> maxint
[1]) maxint
[1] = lint2
;
787 lf
= *lfp
* *precision
+ 0.5;
789 lf
= *lfp
* *precision
- 0.5;
790 if (fabs(lf
) > MAXABS
) {
791 /* scaling would cause overflow */
795 if (lint3
< minint
[2]) minint
[2] = lint3
;
796 if (lint3
> maxint
[2]) maxint
[2] = lint3
;
799 diff
= abs(oldlint1
-lint1
)+abs(oldlint2
-lint2
)+abs(oldlint3
-lint3
);
800 if (diff
< mindiff
&& lfp
> fp
+ 3)
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
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 */
833 bitsize
= sizeofints(3, sizeint
);
836 luip
= (unsigned int *) ip
;
838 while (smallidx
< LASTIDX
&& magicints
[smallidx
] < mindiff
) {
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;
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
) {
857 } else if (smallidx
> minidx
) {
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];
871 tmp
= thiscoord
[1]; thiscoord
[1] = thiscoord
[4];
873 tmp
= thiscoord
[2]; thiscoord
[2] = thiscoord
[5];
879 tmpcoord
[0] = thiscoord
[0] - minint
[0];
880 tmpcoord
[1] = thiscoord
[1] - minint
[1];
881 tmpcoord
[2] = thiscoord
[2] - minint
[2];
883 sendbits(buf
, bitsizeint
[0], tmpcoord
[0]);
884 sendbits(buf
, bitsizeint
[1], tmpcoord
[1]);
885 sendbits(buf
, bitsizeint
[2], tmpcoord
[2]);
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;
896 if (is_small
== 0 && is_smaller
== -1)
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
)) {
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];
915 thiscoord
= thiscoord
+ 3;
918 abs(thiscoord
[0] - prevcoord
[0]) < smallnum
&&
919 abs(thiscoord
[1] - prevcoord
[1]) < smallnum
&&
920 abs(thiscoord
[2] - prevcoord
[2]) < smallnum
) {
924 if (run
!= prevrun
|| is_smaller
!= 0) {
926 sendbits(buf
, 1, 1); /* flag the change in run-length */
927 sendbits(buf
, 5, run
+is_smaller
+1);
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) {
938 smaller
= magicints
[smallidx
-1] / 2;
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]));
951 /* xdrs is open for reading */
953 if (xdr_int(xdrs
, &lsize
) == 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
);
962 return (xdr_vector(xdrs
, (char *) fp
, (unsigned int)size3
,
963 (unsigned int)sizeof(*fp
), (xdrproc_t
)xdr_float
));
965 xdr_float(xdrs
, precision
);
967 ip
= (int *)malloc((size_t)(size3
* sizeof(*ip
)));
969 fprintf(stderr
,"malloc failed\n");
972 bufsize
= size3
* 1.2;
973 buf
= (int *)malloc((size_t)(bufsize
* sizeof(*buf
)));
975 fprintf(stderr
,"malloc failed\n");
979 } else if (*size
> oldsize
) {
980 ip
= (int *)realloc(ip
, (size_t)(size3
* sizeof(*ip
)));
982 fprintf(stderr
,"malloc failed\n");
985 bufsize
= size3
* 1.2;
986 buf
= (int *)realloc(buf
, (size_t)(bufsize
* sizeof(*buf
)));
988 fprintf(stderr
,"malloc failed\n");
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 */
1014 bitsize
= sizeofints(3, sizeint
);
1017 if (xdr_int(xdrs
, &smallidx
) == 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)
1030 if (xdr_opaque(xdrs
, (char *)&(buf
[3]), (unsigned int)buf
[0]) == 0)
1032 buf
[0] = buf
[1] = buf
[2] = 0;
1035 inv_precision
= 1.0 / * precision
;
1039 while ( i
< lsize
) {
1040 thiscoord
= (int *)(lip
) + i
* 3;
1043 thiscoord
[0] = receivebits(buf
, bitsizeint
[0]);
1044 thiscoord
[1] = receivebits(buf
, bitsizeint
[1]);
1045 thiscoord
[2] = receivebits(buf
, bitsizeint
[2]);
1047 receiveints(buf
, 3, bitsize
, sizeint
, thiscoord
);
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);
1063 run
= receivebits(buf
, 5);
1064 is_smaller
= run
% 3;
1070 for (k
= 0; k
< run
; k
+=3) {
1071 receiveints(buf
, 3, smallidx
, sizesmall
, thiscoord
);
1073 thiscoord
[0] += prevcoord
[0] - smallnum
;
1074 thiscoord
[1] += prevcoord
[1] - smallnum
;
1075 thiscoord
[2] += prevcoord
[2] - smallnum
;
1077 /* interchange first with second atom for better
1078 * compression of water molecules
1080 tmp
= thiscoord
[0]; thiscoord
[0] = prevcoord
[0];
1082 tmp
= thiscoord
[1]; thiscoord
[1] = prevcoord
[1];
1084 tmp
= thiscoord
[2]; thiscoord
[2] = prevcoord
[2];
1086 *lfp
++ = prevcoord
[0] * inv_precision
;
1087 *lfp
++ = prevcoord
[1] * inv_precision
;
1088 *lfp
++ = prevcoord
[2] * inv_precision
;
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
;
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) {
1106 if (smallidx
> FIRSTIDX
) {
1107 smaller
= magicints
[smallidx
- 1] /2;
1111 } else if (is_smaller
> 0) {
1113 smallnum
= magicints
[smallidx
] / 2;
1115 sizesmall
[0] = sizesmall
[1] = sizesmall
[2] = magicints
[smallidx
] ;