1 /* This code is part of the tng compression routines.
3 * Written by Daniel Spangberg
4 * Copyright (c) 2010, 2013, The GROMACS development team.
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the Revised BSD License.
11 /* This code is heavily influenced by
12 http://hpcv100.rc.rug.nl/xdrf.html
13 Based on coordinate compression (c) by Frans van Hoesel.
14 and GROMACS xtc files (http://www.gromacs.org)
15 (c) Copyright (c) Erik Lindahl, David van der Spoel
18 /* The cost estimates are ripped right out of xtc2.c, so take these
19 with a grain (truckload) of salt. */
26 #include "../../include/compression/warnmalloc.h"
27 #include "../../include/compression/widemuldiv.h"
28 #include "../../include/compression/bwlzh.h"
30 static const double iflipgaincheck=0.89089871814033927; /* 1./(2**(1./6)) */
32 #define MAX_LARGE_RLE 1024 /* Maximum number of large atoms for large RLE. */
33 #define MAX_SMALL_RLE 12 /* Maximum number of small atoms in one group. */
35 #define TRESHOLD_INTRA_INTER_DIRECT 1.5 /* How much larger can the direct
36 frame deltas for the small
37 triplets be and be accepted anyway
38 as better than the intra/inter frame
39 deltas. For better instructions/RLEs. */
41 #define TRESHOLD_INTER_INTRA 5.0 /* How much larger can the intra
42 frame deltas for the small
43 triplets be and be accepted anyway
44 as better than the inter frame
47 /* Difference in indices used for determining whether to store as
48 large or small. A fun detail in this compression algorithm is that
49 if everything works fine, large can often be smaller than small, or
50 at least not as large as is large in magic.c. This is a key idea of
63 /* These routines are in xtc2.c */
64 int Ptngc_magic(unsigned int i);
65 int Ptngc_find_magic_index(unsigned int maxval);
67 static unsigned int positive_int(int item)
77 static int unpositive_int(int val)
86 /* Sequence instructions */
87 #define INSTR_DEFAULT 0U
88 #define INSTR_SMALL_RUNLENGTH 1U
89 #define INSTR_ONLY_LARGE 2U
90 #define INSTR_ONLY_SMALL 3U
92 #define INSTR_LARGE_RLE 5U
93 #define INSTR_LARGE_DIRECT 6U
94 #define INSTR_LARGE_INTRA_DELTA 7U
95 #define INSTR_LARGE_INTER_DELTA 8U
101 unsigned int *instructions;
102 int ninstr, ninstr_alloc;
104 int nrle, nrle_alloc;
105 unsigned int *large_direct;
106 int nlargedir, nlargedir_alloc;
107 unsigned int *large_intra_delta;
108 int nlargeintra, nlargeintra_alloc;
109 unsigned int *large_inter_delta;
110 int nlargeinter, nlargeinter_alloc;
111 unsigned int *smallintra;
112 int nsmallintra, nsmallintra_alloc;
113 int minint[3],maxint[3];
115 int has_large_ints[MAX_LARGE_RLE*3]; /* Large cache. */
116 int has_large_type[MAX_LARGE_RLE]; /* What kind of type this large
118 int current_large_type;
121 static void init_xtc3_context(struct xtc3_context *xtc3_context)
123 xtc3_context->instructions=NULL;
124 xtc3_context->ninstr=0;
125 xtc3_context->ninstr_alloc=0;
126 xtc3_context->rle=NULL;
127 xtc3_context->nrle=0;
128 xtc3_context->nrle_alloc=0;
129 xtc3_context->large_direct=NULL;
130 xtc3_context->nlargedir=0;
131 xtc3_context->nlargedir_alloc=0;
132 xtc3_context->large_intra_delta=NULL;
133 xtc3_context->nlargeintra=0;
134 xtc3_context->nlargeintra_alloc=0;
135 xtc3_context->large_inter_delta=NULL;
136 xtc3_context->nlargeinter=0;
137 xtc3_context->nlargeinter_alloc=0;
138 xtc3_context->smallintra=NULL;
139 xtc3_context->nsmallintra=0;
140 xtc3_context->nsmallintra_alloc=0;
141 xtc3_context->has_large=0;
142 xtc3_context->current_large_type=0;
145 static void free_xtc3_context(struct xtc3_context *xtc3_context)
147 free(xtc3_context->instructions);
148 free(xtc3_context->rle);
149 free(xtc3_context->large_direct);
150 free(xtc3_context->large_intra_delta);
151 free(xtc3_context->large_inter_delta);
152 free(xtc3_context->smallintra);
155 /* Modifies three integer values for better compression of water */
156 static void swap_ints(int *in, int *out)
163 static void swap_is_better(int *input, int *minint, int *sum_normal, int *sum_swapped)
172 normal[0]=input[i]-minint[i];
173 normal[1]=input[3+i]-input[i]; /* minint[i]-minint[i] cancels out */
174 normal[2]=input[6+i]-input[3+i]; /* minint[i]-minint[i] cancels out */
175 swap_ints(normal,swapped);
178 if (positive_int(normal[j])>(unsigned int)normal_max)
179 normal_max=positive_int(normal[j]);
180 if (positive_int(swapped[j])>(unsigned int)swapped_max)
181 swapped_max=positive_int(swapped[j]);
188 *sum_normal=normal_max;
189 *sum_swapped=swapped_max;
192 static void allocate_enough_memory(unsigned int **ptr, int *nele, int *nele_alloc)
195 if (*nele>*nele_alloc)
197 *nele_alloc=*nele + *nele/2;
198 *ptr=warnrealloc(*ptr,*nele_alloc*sizeof **ptr);
202 static void insert_value_in_array(unsigned int **ptr, int *nele, int *nele_alloc,
209 allocate_enough_memory(ptr,nele,nele_alloc);
211 fprintf(stderr,"Inserting value %u into array %s @ %d\n",value,arrayname,(*nele)-1);
213 (*ptr)[(*nele)-1]=value;
218 static void swapdecide(struct xtc3_context *xtc3_context, int *input,int *swapatoms, int *large_index, int *minint)
223 swap_is_better(input,minint,&normal,&swapped);
224 /* We have to determine if it is worth to change the behaviour.
225 If diff is positive it means that it is worth something to
226 swap. But it costs 4 bits to do the change. If we assume that
227 we gain 0.17 bit by the swap per value, and the runlength>2
228 for four molecules in a row, we gain something. So check if we
229 gain at least 0.17 bits to even attempt the swap.
232 fprintf(stderr,"Trying Flip: %g %g\n",(double)swapped/normal, (double)normal/swapped);
234 if (((swapped<normal) && (fabs((double)swapped/normal)<iflipgaincheck)) ||
235 ((normal<swapped) && (fabs((double)normal/swapped)<iflipgaincheck)))
257 fprintf(stderr,"Flip. Swapatoms is now %d\n",*swapatoms);
259 insert_value_in_array(&xtc3_context->instructions,
260 &xtc3_context->ninstr,
261 &xtc3_context->ninstr_alloc,
266 /* It is "large" if we have to increase the small index quite a
267 bit. Not so much to be rejected by the not very large check
269 static int is_quite_large(int *input, int small_index, int max_large_index)
273 if (small_index+QUITE_LARGE>=max_large_index)
278 if (positive_int(input[i])>(unsigned int)Ptngc_magic(small_index+QUITE_LARGE))
292 static void insert_batch(int *input_ptr, int ntriplets_left, int *prevcoord, int *encode_ints, int startenc, int *nenc)
294 int nencode=startenc*3;
295 int tmp_prevcoord[3];
297 tmp_prevcoord[0]=prevcoord[0];
298 tmp_prevcoord[1]=prevcoord[1];
299 tmp_prevcoord[2]=prevcoord[2];
304 for (i=0; i<startenc; i++)
306 tmp_prevcoord[0]+=encode_ints[i*3];
307 tmp_prevcoord[1]+=encode_ints[i*3+1];
308 tmp_prevcoord[2]+=encode_ints[i*3+2];
310 fprintf(stderr,"%6d: %6d %6d %6d\t\t%6d %6d %6d\t\t%6d %6d %6d\n",i*3,
311 tmp_prevcoord[0],tmp_prevcoord[1],tmp_prevcoord[2],
315 positive_int(encode_ints[i*3]),
316 positive_int(encode_ints[i*3+1]),
317 positive_int(encode_ints[i*3+2]));
323 fprintf(stderr,"New batch\n");
325 while ((nencode<3+MAX_SMALL_RLE*3) && (nencode<ntriplets_left*3))
327 encode_ints[nencode]=input_ptr[nencode]-tmp_prevcoord[0];
328 encode_ints[nencode+1]=input_ptr[nencode+1]-tmp_prevcoord[1];
329 encode_ints[nencode+2]=input_ptr[nencode+2]-tmp_prevcoord[2];
331 fprintf(stderr,"%6d: %6d %6d %6d\t\t%6d %6d %6d\t\t%6d %6d %6d\n",nencode,
333 input_ptr[nencode+1],
334 input_ptr[nencode+2],
335 encode_ints[nencode],
336 encode_ints[nencode+1],
337 encode_ints[nencode+2],
338 positive_int(encode_ints[nencode]),
339 positive_int(encode_ints[nencode+1]),
340 positive_int(encode_ints[nencode+2]));
342 tmp_prevcoord[0]=input_ptr[nencode];
343 tmp_prevcoord[1]=input_ptr[nencode+1];
344 tmp_prevcoord[2]=input_ptr[nencode+2];
350 static void large_instruction_change(struct xtc3_context *xtc3_context, int i)
352 /* If the first large is of a different kind than the currently used we must
353 emit an "instruction" to change the large type. */
354 if (xtc3_context->has_large_type[i]!=xtc3_context->current_large_type)
357 xtc3_context->current_large_type=xtc3_context->has_large_type[i];
358 if (xtc3_context->current_large_type==0)
359 instr=INSTR_LARGE_DIRECT;
360 else if (xtc3_context->current_large_type==1)
361 instr=INSTR_LARGE_INTRA_DELTA;
363 instr=INSTR_LARGE_INTER_DELTA;
364 insert_value_in_array(&xtc3_context->instructions,
365 &xtc3_context->ninstr,
366 &xtc3_context->ninstr_alloc,
371 static void write_three_large(struct xtc3_context *xtc3_context,
375 if (xtc3_context->current_large_type==0)
378 insert_value_in_array(&xtc3_context->large_direct,
379 &xtc3_context->nlargedir,
380 &xtc3_context->nlargedir_alloc,
381 xtc3_context->has_large_ints[i*3+m],"large direct");
383 else if (xtc3_context->current_large_type==1)
386 insert_value_in_array(&xtc3_context->large_intra_delta,
387 &xtc3_context->nlargeintra,
388 &xtc3_context->nlargeintra_alloc,
389 xtc3_context->has_large_ints[i*3+m],"large intra");
394 insert_value_in_array(&xtc3_context->large_inter_delta,
395 &xtc3_context->nlargeinter,
396 &xtc3_context->nlargeinter_alloc,
397 xtc3_context->has_large_ints[i*3+m],"large inter");
401 static void flush_large(struct xtc3_context *xtc3_context,
402 int n) /* How many to flush. */
409 /* If the first large is of a different kind than the currently used we must
410 emit an "instruction" to change the large type. */
411 large_instruction_change(xtc3_context,i);
412 /* How many large of the same kind in a row? */
415 (xtc3_context->has_large_type[i+j]==xtc3_context->has_large_type[i]);
421 insert_value_in_array(&xtc3_context->instructions,
422 &xtc3_context->ninstr,
423 &xtc3_context->ninstr_alloc,
424 INSTR_ONLY_LARGE,"instr");
425 write_three_large(xtc3_context,i+k);
430 insert_value_in_array(&xtc3_context->instructions,
431 &xtc3_context->ninstr,
432 &xtc3_context->ninstr_alloc,
433 INSTR_LARGE_RLE,"instr");
434 insert_value_in_array(&xtc3_context->rle,
436 &xtc3_context->nrle_alloc,
437 (unsigned int)j,"rle (large)");
439 write_three_large(xtc3_context,i+k);
443 if ((xtc3_context->has_large-n)!=0)
446 for (i=0; i<xtc3_context->has_large-n; i++)
448 xtc3_context->has_large_type[i]=xtc3_context->has_large_type[i+n];
450 xtc3_context->has_large_ints[i*3+j]=xtc3_context->has_large_ints[(i+n)*3+j];
453 xtc3_context->has_large-=n; /* Number of remaining large atoms in buffer */
456 static double compute_intlen(unsigned int *ints)
458 /* The largest value. */
459 unsigned int m=ints[0];
467 static void buffer_large(struct xtc3_context *xtc3_context, int *input, int inpdata,
468 int natoms, int intradelta_ok)
470 unsigned int direct[3], intradelta[3]={0,}, interdelta[3]={0,};
473 int frame=inpdata/(natoms*3);
474 int atomframe=inpdata%(natoms*3);
475 /* If it is full we must write them all. */
476 if (xtc3_context->has_large==MAX_LARGE_RLE)
477 flush_large(xtc3_context,xtc3_context->has_large); /* Flush all. */
478 /* Find out which is the best choice for the large integer. Direct coding, or some
479 kind of delta coding? */
480 /* First create direct coding. */
481 direct[0]=(unsigned int)(input[inpdata]-xtc3_context->minint[0]);
482 direct[1]=(unsigned int)(input[inpdata+1]-xtc3_context->minint[1]);
483 direct[2]=(unsigned int)(input[inpdata+2]-xtc3_context->minint[2]);
484 minlen=compute_intlen(direct);
485 best_type=0; /* Direct. */
487 /* Then try intra coding if we can. */
488 if ((intradelta_ok) && (atomframe>=3))
491 intradelta[0]=positive_int(input[inpdata]-input[inpdata-3]);
492 intradelta[1]=positive_int(input[inpdata+1]-input[inpdata-2]);
493 intradelta[2]=positive_int(input[inpdata+2]-input[inpdata-1]);
494 thislen=compute_intlen(intradelta);
495 if (thislen*TRESHOLD_INTRA_INTER_DIRECT<minlen)
498 best_type=1; /* Intra delta */
503 /* Then try inter coding if we can. */
507 interdelta[0]=positive_int(input[inpdata]-input[inpdata-natoms*3]);
508 interdelta[1]=positive_int(input[inpdata+1]-input[inpdata-natoms*3+1]);
509 interdelta[2]=positive_int(input[inpdata+2]-input[inpdata-natoms*3+2]);
510 thislen=compute_intlen(interdelta);
511 if (thislen*TRESHOLD_INTRA_INTER_DIRECT<minlen)
513 best_type=2; /* Inter delta */
517 xtc3_context->has_large_type[xtc3_context->has_large]=best_type;
520 xtc3_context->has_large_ints[xtc3_context->has_large*3]=direct[0];
521 xtc3_context->has_large_ints[xtc3_context->has_large*3+1]=direct[1];
522 xtc3_context->has_large_ints[xtc3_context->has_large*3+2]=direct[2];
524 else if (best_type==1)
526 xtc3_context->has_large_ints[xtc3_context->has_large*3]=intradelta[0];
527 xtc3_context->has_large_ints[xtc3_context->has_large*3+1]=intradelta[1];
528 xtc3_context->has_large_ints[xtc3_context->has_large*3+2]=intradelta[2];
530 else if (best_type==2)
532 xtc3_context->has_large_ints[xtc3_context->has_large*3]=interdelta[0];
533 xtc3_context->has_large_ints[xtc3_context->has_large*3+1]=interdelta[1];
534 xtc3_context->has_large_ints[xtc3_context->has_large*3+2]=interdelta[2];
536 xtc3_context->has_large++;
539 static void output_int(unsigned char *output,int *outdata, unsigned int n)
541 output[(*outdata)++]=((unsigned int)n)&0xFFU;
542 output[(*outdata)++]=(((unsigned int)n)>>8)&0xFFU;
543 output[(*outdata)++]=(((unsigned int)n)>>16)&0xFFU;
544 output[(*outdata)++]=(((unsigned int)n)>>24)&0xFFU;
548 static void printarray(unsigned int *a, int n, char *name)
552 fprintf(stderr,"%u %s\n",a[i],name);
556 /* The base_compress routine first compresses all x coordinates, then
557 y and finally z. The bases used for each can be different. The
558 MAXBASEVALS value determines how many coordinates are compressed
559 into a single number. Only resulting whole bytes are dealt with for
560 simplicity. MAXMAXBASEVALS is the insanely large value to accept
561 files written with that value. BASEINTERVAL determines how often a
562 new base is actually computed and stored in the output
563 file. MAXBASEVALS*BASEINTERVAL values are stored using the same
564 base in BASEINTERVAL different integers. Note that the primarily
565 the decompression using a large MAXBASEVALS becomes very slow. */
566 #define MAXMAXBASEVALS 16384U
567 #define MAXBASEVALS 24U
568 #define BASEINTERVAL 8
570 /* How many bytes are needed to store n values in base base */
571 static int base_bytes(unsigned int base, int n)
574 unsigned int largeint[MAXMAXBASEVALS+1];
575 unsigned int largeint_tmp[MAXMAXBASEVALS+1];
577 for (i=0; i<n+1; i++)
583 Ptngc_largeint_mul(base,largeint,largeint_tmp,n+1);
584 for (j=0; j<n+1; j++)
585 largeint[j]=largeint_tmp[j];
587 Ptngc_largeint_add(base-1U,largeint,n+1);
592 if ((largeint[i]>>(j*8))&0xFFU)
597 static void base_compress(unsigned int *data, int len, unsigned char *output, int *outlen)
599 unsigned int largeint[MAXBASEVALS+1];
600 unsigned int largeint_tmp[MAXBASEVALS+1];
604 unsigned int numbytes=0;
605 /* Store the MAXBASEVALS value in the output. */
606 output[nwrittenout++]=(unsigned char)(MAXBASEVALS&0xFFU);
607 output[nwrittenout++]=(unsigned char)((MAXBASEVALS>>8)&0xFFU);
608 /* Store the BASEINTERVAL value in the output. */
609 output[nwrittenout++]=(unsigned char)(BASEINTERVAL&0xFFU);
610 for (ixyz=0; ixyz<3; ixyz++)
612 unsigned int base=0U;
615 for (j=0; j<MAXBASEVALS+1; j++)
617 for (i=ixyz; i<len; i+=3)
626 /* Find the largest value for this particular coordinate. */
627 for (k=i; k<len; k+=3)
632 if (basecheckvals==MAXBASEVALS*BASEINTERVAL)
635 /* The base is one larger than the largest values. */
639 /* Store the base in the output. */
640 output[nwrittenout++]=(unsigned char)(base&0xFFU);
641 output[nwrittenout++]=(unsigned char)((base>>8)&0xFFU);
642 output[nwrittenout++]=(unsigned char)((base>>16)&0xFFU);
643 output[nwrittenout++]=(unsigned char)((base>>24)&0xFFU);
644 basegiven=BASEINTERVAL;
645 /* How many bytes is needed to store MAXBASEVALS values using this base? */
646 numbytes=base_bytes(base,MAXBASEVALS);
650 fprintf(stderr,"Base for %d is %u. I need %d bytes for %d values.\n",ixyz,base,numbytes,MAXBASEVALS);
655 Ptngc_largeint_mul(base,largeint,largeint_tmp,MAXBASEVALS+1);
656 for (j=0; j<MAXBASEVALS+1; j++)
657 largeint[j]=largeint_tmp[j];
659 Ptngc_largeint_add(data[i],largeint,MAXBASEVALS+1);
661 fprintf(stderr,"outputting value %u\n",data[i]);
664 if (nvals==MAXBASEVALS)
667 fprintf(stderr,"Writing largeint: ");
669 for (j=0; j<numbytes; j++)
673 output[nwrittenout++]=(unsigned char)((largeint[ilarge]>>(ibyte*8))&(0xFFU));
675 fprintf(stderr,"%02x",(unsigned int)output[nwrittenout-1]);
679 fprintf(stderr,"\n");
682 for (j=0; j<MAXBASEVALS+1; j++)
688 numbytes=base_bytes(base,nvals);
690 fprintf(stderr,"Base for %d is %u. I need %d bytes for %d values.\n",ixyz,base,numbytes,nvals);
692 for (j=0; j<numbytes; j++)
696 output[nwrittenout++]=(unsigned char)((largeint[ilarge]>>(ibyte*8))&(0xFFU));
703 static void base_decompress(unsigned char *input, int len, unsigned int *output)
705 unsigned int largeint[MAXMAXBASEVALS+1];
706 unsigned int largeint_tmp[MAXMAXBASEVALS+1];
708 int maxbasevals=(int)((unsigned int)(input[0])|(((unsigned int)(input[1]))<<8));
709 int baseinterval=(int)input[2];
710 if (maxbasevals>(int)MAXMAXBASEVALS)
712 fprintf(stderr,"Read a larger maxbasevals value from the file than I can handle. Fix"
713 " by increasing MAXMAXBASEVALS to at least %d. Although, this is"
714 " probably a bug in TRAJNG, since MAXMAXBASEVALS should already be insanely large enough.\n",maxbasevals);
718 for (ixyz=0; ixyz<3; ixyz++)
721 int nvals_left=len/3;
724 unsigned int base=0U;
726 fprintf(stderr,"Base for %d is %u. I need %d bytes for %d values.\n",ixyz,base,numbytes,maxbasevals);
733 base=(unsigned int)(input[0])|
734 (((unsigned int)(input[1]))<<8)|
735 (((unsigned int)(input[2]))<<16)|
736 (((unsigned int)(input[3]))<<24);
738 basegiven=baseinterval;
739 /* How many bytes is needed to store maxbasevals values using this base? */
740 numbytes=base_bytes(base,maxbasevals);
743 if (nvals_left<maxbasevals)
745 numbytes=base_bytes(base,nvals_left);
747 fprintf(stderr,"Base for %d is %u. I need %d bytes for %d values.\n",ixyz,base,numbytes,nvals_left);
750 for (j=0; j<maxbasevals+1; j++)
753 fprintf(stderr,"Reading largeint: ");
755 if (numbytes/4 < maxbasevals+1)
757 for (j=0; j<numbytes; j++)
761 largeint[ilarge]|=((unsigned int)input[j])<<(ibyte*8);
763 fprintf(stderr,"%02x",(unsigned int)input[j]);
768 fprintf(stderr,"\n");
771 /* Do the long division required to get the output values. */
775 for (i=n-1; i>=0; i--)
777 output[outvals+i*3]=Ptngc_largeint_div(base,largeint,largeint_tmp,maxbasevals+1);
778 for (j=0; j<maxbasevals+1; j++)
779 largeint[j]=largeint_tmp[j];
783 fprintf(stderr,"outputting value %u\n",output[outvals+i*3]);
791 /* If a large proportion of the integers are large (More than 10\% are >14 bits) we return 0, otherwise 1 */
792 static int heuristic_bwlzh(unsigned int *ints, int nints)
796 for (i=0; i<nints; i++)
805 /* Speed selects how careful to try to find the most efficient compression. The BWLZH algo is expensive!
806 Speed <=2 always avoids BWLZH everywhere it is possible.
807 Speed 3 and 4 and 5 use heuristics (check proportion of large value). This should mostly be safe.
808 Speed 5 enables the LZ77 component of BWLZH.
809 Speed 6 always tests if BWLZH is better and if it is uses it. This can be very slow.
811 unsigned char *Ptngc_pack_array_xtc3(int *input, int *length, int natoms, int speed)
813 unsigned char *output=NULL;
817 int ntriplets=*length/3;
824 int runlength=0; /* Initial runlength. "Stupidly" set to zero for
825 simplicity and explicity */
826 int swapatoms=0; /* Initial guess is that we should not swap the
827 first two atoms in each large+small
829 int didswap; /* Whether swapping was actually done. */
831 int encode_ints[3+MAX_SMALL_RLE*3]; /* Up to 3 large + 24 small ints can be encoded at once */
833 int ntriplets_left=ntriplets;
835 unsigned char *bwlzh_buf=NULL;
837 unsigned char *base_buf=NULL;
840 struct xtc3_context xtc3_context;
841 init_xtc3_context(&xtc3_context);
843 xtc3_context.maxint[0]=xtc3_context.minint[0]=input[0];
844 xtc3_context.maxint[1]=xtc3_context.minint[1]=input[1];
845 xtc3_context.maxint[2]=xtc3_context.minint[2]=input[2];
847 /* Values of speed should be sane. */
857 /* Allocate enough memory for output */
859 output=warnmalloc(8*48*sizeof *output);
861 output=warnmalloc(8* *length*sizeof *output);
864 for (i=1; i<ntriplets; i++)
867 if (input[i*3+j]>xtc3_context.maxint[j])
868 xtc3_context.maxint[j]=input[i*3+j];
869 if (input[i*3+j]<xtc3_context.minint[j])
870 xtc3_context.minint[j]=input[i*3+j];
873 large_index[0]=Ptngc_find_magic_index(xtc3_context.maxint[0]-xtc3_context.minint[0]+1);
874 large_index[1]=Ptngc_find_magic_index(xtc3_context.maxint[1]-xtc3_context.minint[1]+1);
875 large_index[2]=Ptngc_find_magic_index(xtc3_context.maxint[2]-xtc3_context.minint[2]+1);
876 max_large_index=large_index[0];
877 if (large_index[1]>max_large_index)
878 max_large_index=large_index[1];
879 if (large_index[2]>max_large_index)
880 max_large_index=large_index[2];
884 fprintf(stderr,"minint[%d]=%d. maxint[%d]=%d large_index[%d]=%d value=%d\n",j,xtc3_context.minint[j],j,xtc3_context.maxint[j],
885 j,large_index[j],Ptngc_magic(large_index[j]));
888 /* Guess initial small index */
889 small_index=max_large_index/2;
891 /* Find the largest value that is not large. Not large is half index of
893 max_small=Ptngc_magic(small_index);
895 for (i=0; i<*length; i++)
898 int s=positive_int(item);
903 /* This value is not critical, since if I guess wrong, the code will
904 just insert instructions to increase this value. */
905 small_index=Ptngc_find_magic_index(intmax);
907 fprintf(stderr,"initial small_index=%d value=%d\n",small_index,Ptngc_magic(small_index));
910 output_int(output,&outdata,positive_int(xtc3_context.minint[0]));
911 output_int(output,&outdata,positive_int(xtc3_context.minint[1]));
912 output_int(output,&outdata,positive_int(xtc3_context.minint[2]));
916 for (i=0; i<ntriplets_left; i++)
917 fprintf(stderr,"VALUE:%d %6d %6d %6d\n",
920 input[inpdata+i*3+1],
921 input[inpdata+i*3+2]);
925 /* Initial prevcoord is the minimum integers. */
926 prevcoord[0]=xtc3_context.minint[0];
927 prevcoord[1]=xtc3_context.minint[1];
928 prevcoord[2]=xtc3_context.minint[2];
930 while (ntriplets_left)
932 if (ntriplets_left<0)
934 fprintf(stderr,"TRAJNG: BUG! ntriplets_left<0!\n");
937 /* If only less than three atoms left we just write them all as large integers. Here no swapping is done! */
938 if (ntriplets_left<3)
940 for (ienc=0; ienc<ntriplets_left; ienc++)
942 buffer_large(&xtc3_context,input,inpdata,natoms,1);
946 flush_large(&xtc3_context,xtc3_context.has_large); /* Flush all */
951 int largest_required_base;
952 int largest_runlength_base;
953 int largest_required_index;
954 int largest_runlength_index;
958 int iter_small_index;
961 /* Insert the next batch of integers to be encoded into the buffer */
963 fprintf(stderr,"Initial batch\n");
965 insert_batch(input+inpdata,ntriplets_left,prevcoord,encode_ints,0,&nencode);
967 /* First we must decide if the next value is large (does not reasonably fit in current small encoding)
968 Also, if we have not written any values yet, we must begin by writing a large atom. */
969 if ((inpdata==0) || (is_quite_large(encode_ints,small_index,max_large_index)) || (refused))
971 /* If any of the next two atoms are large we should probably write them as large and not swap them */
973 if ((is_quite_large(encode_ints+3,small_index,max_large_index)) || (is_quite_large(encode_ints+6,small_index,max_large_index)))
978 /* If doing inter-frame coding results in smaller values we should not do any swapping either. */
979 int frame=inpdata/(natoms*3);
982 unsigned int delta[3], delta2[3];
983 delta[0]=positive_int(input[inpdata+3]-input[inpdata-natoms*3+3]);
984 delta[1]=positive_int(input[inpdata+4]-input[inpdata-natoms*3+4]);
985 delta[2]=positive_int(input[inpdata+5]-input[inpdata-natoms*3+5]);
986 delta2[0]=positive_int(encode_ints[3]);
987 delta2[1]=positive_int(encode_ints[4]);
988 delta2[2]=positive_int(encode_ints[5]);
990 fprintf(stderr,"A1: inter delta: %u %u %u. intra delta=%u %u %u\n",
991 delta[0],delta[1],delta[2],
992 delta2[0],delta2[1],delta2[2]);
994 if (compute_intlen(delta)*TRESHOLD_INTER_INTRA<compute_intlen(delta2))
996 delta[0]=positive_int(input[inpdata+6]-input[inpdata-natoms*3+6]);
997 delta[1]=positive_int(input[inpdata+7]-input[inpdata-natoms*3+7]);
998 delta[2]=positive_int(input[inpdata+8]-input[inpdata-natoms*3+8]);
999 delta2[0]=positive_int(encode_ints[6]);
1000 delta2[1]=positive_int(encode_ints[7]);
1001 delta2[2]=positive_int(encode_ints[8]);
1003 fprintf(stderr,"A2: inter delta: %u %u %u. intra delta=%u %u %u\n",
1004 delta[0],delta[1],delta[2],
1005 delta2[0],delta2[1],delta2[2]);
1007 if (compute_intlen(delta)*TRESHOLD_INTER_INTRA<compute_intlen(delta2))
1011 fprintf(stderr,"SETTING NO SWAP!\n");
1020 /* Next we must decide if we should swap the first
1023 swapdecide(&xtc3_context,input+inpdata,&swapatoms,large_index,xtc3_context.minint);
1027 /* If we should do the integer swapping manipulation we should do it now */
1034 in[0]=input[inpdata+i];
1035 in[1]=input[inpdata+3+i]-input[inpdata+i];
1036 in[2]=input[inpdata+6+i]-input[inpdata+3+i];
1038 encode_ints[i]=out[0];
1039 encode_ints[3+i]=out[1];
1040 encode_ints[6+i]=out[2];
1042 /* We have swapped atoms, so the minimum run-length is 2 */
1044 fprintf(stderr,"Swap atoms results in:\n");
1046 fprintf(stderr,"%d: %6d %6d %6d\t\t%6d %6d %6d\n",i*3,
1050 positive_int(encode_ints[i*3]),
1051 positive_int(encode_ints[i*3+1]),
1052 positive_int(encode_ints[i*3+2]));
1058 /* Cache large value for later possible combination with
1059 a sequence of small integers. */
1060 if ((swapatoms) && (didswap))
1062 buffer_large(&xtc3_context,input,inpdata+3,natoms,0); /* This is a swapped integer, so inpdata is one atom later and
1063 intra coding is not ok. */
1064 for (ienc=0; ienc<3; ienc++)
1065 prevcoord[ienc]=input[inpdata+3+ienc];
1069 buffer_large(&xtc3_context,input,inpdata,natoms,1);
1070 for (ienc=0; ienc<3; ienc++)
1071 prevcoord[ienc]=input[inpdata+ienc];
1076 fprintf(stderr,"Prevcoord after packing of large: %d %d %d\n",
1077 prevcoord[0],prevcoord[1],prevcoord[2]);
1080 /* We have written a large integer so we have one less atoms to worry about */
1086 /* Insert the next batch of integers to be encoded into the buffer */
1088 fprintf(stderr,"Update batch due to large int.\n");
1090 if ((swapatoms) && (didswap))
1092 /* Keep swapped values. */
1094 for (ienc=0; ienc<3; ienc++)
1095 encode_ints[i*3+ienc]=encode_ints[(i+1)*3+ienc];
1097 insert_batch(input+inpdata,ntriplets_left,prevcoord,encode_ints,min_runlength,&nencode);
1099 /* Here we should only have differences for the atom coordinates. */
1100 /* Convert the ints to positive ints */
1101 for (ienc=0; ienc<nencode; ienc++)
1103 int pint=positive_int(encode_ints[ienc]);
1104 encode_ints[ienc]=pint;
1106 /* Now we must decide what base and runlength to do. If we have swapped atoms it will be at least 2.
1107 If even the next atom is large, we will not do anything. */
1108 largest_required_base=0;
1109 /* Determine required base */
1110 for (ienc=0; ienc<min_runlength*3; ienc++)
1111 if (encode_ints[ienc]>largest_required_base)
1112 largest_required_base=encode_ints[ienc];
1113 /* Also compute what the largest base is for the current runlength setting! */
1114 largest_runlength_base=0;
1115 for (ienc=0; (ienc<runlength*3) && (ienc<nencode); ienc++)
1116 if (encode_ints[ienc]>largest_runlength_base)
1117 largest_runlength_base=encode_ints[ienc];
1119 largest_required_index=Ptngc_find_magic_index(largest_required_base);
1120 largest_runlength_index=Ptngc_find_magic_index(largest_runlength_base);
1122 if (largest_required_index<largest_runlength_index)
1124 new_runlength=min_runlength;
1125 new_small_index=largest_required_index;
1129 new_runlength=runlength;
1130 new_small_index=largest_runlength_index;
1133 /* Only allow increase of runlength wrt min_runlength */
1134 if (new_runlength<min_runlength)
1135 new_runlength=min_runlength;
1137 /* If the current runlength is longer than the number of
1138 triplets left stop it from being so. */
1139 if (new_runlength>ntriplets_left)
1140 new_runlength=ntriplets_left;
1142 /* We must at least try to get some small integers going. */
1143 if (new_runlength==0)
1146 new_small_index=small_index;
1149 iter_runlength=new_runlength;
1150 iter_small_index=new_small_index;
1152 /* Iterate to find optimal encoding and runlength */
1154 fprintf(stderr,"Entering iterative loop.\n");
1159 new_runlength=iter_runlength;
1160 new_small_index=iter_small_index;
1163 fprintf(stderr,"Test new_small_index=%d Base=%d\n",new_small_index,Ptngc_magic(new_small_index));
1165 /* What is the largest runlength
1166 we can do with the currently
1167 selected encoding? Also the max supported runlength is MAX_SMALL_RLE triplets! */
1168 for (ienc=0; ienc<nencode && ienc<MAX_SMALL_RLE*3; ienc++)
1170 int test_index=Ptngc_find_magic_index(encode_ints[ienc]);
1171 if (test_index>new_small_index)
1174 if (ienc/3>new_runlength)
1176 iter_runlength=ienc/3;
1178 fprintf(stderr,"I found a new possible runlength: %d\n",iter_runlength);
1182 /* How large encoding do we have to use? */
1183 largest_runlength_base=0;
1184 for (ienc=0; ienc<iter_runlength*3; ienc++)
1185 if (encode_ints[ienc]>largest_runlength_base)
1186 largest_runlength_base=encode_ints[ienc];
1187 largest_runlength_index=Ptngc_find_magic_index(largest_runlength_base);
1188 if (largest_runlength_index!=new_small_index)
1190 iter_small_index=largest_runlength_index;
1192 fprintf(stderr,"I found a new possible small index: %d Base=%d\n",iter_small_index,Ptngc_magic(iter_small_index));
1195 } while ((new_runlength!=iter_runlength) ||
1196 (new_small_index!=iter_small_index));
1199 fprintf(stderr,"Exit iterative loop.\n");
1203 /* Verify that we got something good. We may have caught a
1204 substantially larger atom. If so we should just bail
1205 out and let the loop get on another lap. We may have a
1206 minimum runlength though and then we have to fulfill
1207 the request to write out these atoms! */
1209 if (new_runlength<3)
1210 rle_index_dep=IS_LARGE;
1211 else if (new_runlength<6)
1212 rle_index_dep=QUITE_LARGE;
1214 || ((new_small_index<small_index+IS_LARGE) && (new_small_index+rle_index_dep<max_large_index))
1216 || (new_small_index+IS_LARGE<max_large_index)
1220 /* If doing inter-frame coding of large integers results
1221 in smaller values than the small value we should not
1222 produce a sequence of small values here. */
1223 int frame=inpdata/(natoms*3);
1226 if ((!swapatoms) && (frame>0))
1228 for (i=0; i<new_runlength; i++)
1230 unsigned int delta[3];
1231 unsigned int delta2[3];
1232 delta[0]=positive_int(input[inpdata+i*3]-input[inpdata-natoms*3+i*3]);
1233 delta[1]=positive_int(input[inpdata+i*3+1]-input[inpdata-natoms*3+i*3+1]);
1234 delta[2]=positive_int(input[inpdata+i*3+2]-input[inpdata-natoms*3+i*3+2]);
1235 delta2[0]=positive_int(encode_ints[i*3]);
1236 delta2[1]=positive_int(encode_ints[i*3+1]);
1237 delta2[2]=positive_int(encode_ints[i*3+2]);
1238 if (compute_intlen(delta)*TRESHOLD_INTER_INTRA<compute_intlen(delta2))
1243 /* Most of the values should become smaller, otherwise
1244 we should encode them with intra coding. */
1245 if ((!swapatoms) && (numsmaller>=2*new_runlength/3))
1247 /* Put all the values in large arrays, instead of the small array */
1250 for (i=0; i<new_runlength; i++)
1251 buffer_large(&xtc3_context,input,inpdata+i*3,natoms,1);
1253 prevcoord[i]=input[inpdata+(new_runlength-1)*3+i];
1254 inpdata+=3*new_runlength;
1255 ntriplets_left-=new_runlength;
1260 if ((new_runlength!=runlength) || (new_small_index!=small_index))
1262 int change=new_small_index-small_index;
1264 if (new_small_index<=0)
1270 for (ixx=0; ixx<new_runlength; ixx++)
1275 double isum=0.; /* ints can be almost 32 bit so multiplication will overflow. So do doubles. */
1276 for (ixyz=0; ixyz<3; ixyz++)
1278 /* encode_ints is already positive (and multiplied by 2 versus the original, just as magic ints) */
1279 double id=encode_ints[ixx*3+ixyz];
1284 fprintf(stderr,"Tested decrease %d of index: %g>=%g?\n",change,isum,(double)Ptngc_magic(small_index+change)*(double)Ptngc_magic(small_index+change));
1286 if (isum>(double)Ptngc_magic(small_index+change)*(double)Ptngc_magic(small_index+change))
1289 fprintf(stderr,"Rejected decrease %d of index due to length of vector: %g>=%g\n",change,isum,(double)Ptngc_magic(small_index+change)*(double)Ptngc_magic(small_index+change));
1294 } while ((change<0) && (rejected));
1300 /* Always accept the new small indices here. */
1301 small_index=new_small_index;
1302 /* If we have a new runlength emit it */
1303 if (runlength!=new_runlength)
1305 runlength=new_runlength;
1306 insert_value_in_array(&xtc3_context.instructions,
1307 &xtc3_context.ninstr,
1308 &xtc3_context.ninstr_alloc,
1309 INSTR_SMALL_RUNLENGTH,"instr");
1310 insert_value_in_array(&xtc3_context.rle,
1312 &xtc3_context.nrle_alloc,
1313 (unsigned int)runlength,"rle (small)");
1316 fprintf(stderr,"Current small index: %d Base=%d\n",small_index,Ptngc_magic(small_index));
1319 /* If we have a large previous integer we can combine it with a sequence of small ints. */
1320 if (xtc3_context.has_large)
1322 /* If swapatoms is set to 1 but we did actually not
1323 do any swapping, we must first write out the
1324 large atom and then the small. If swapatoms is 1
1325 and we did swapping we can use the efficient
1327 if ((swapatoms) && (!didswap))
1330 fprintf(stderr,"Swapatoms was set to 1 but we did not do swapping!\n");
1331 fprintf(stderr,"Only one large integer.\n");
1333 /* Flush all large atoms. */
1334 flush_large(&xtc3_context,xtc3_context.has_large);
1336 fprintf(stderr,"Sequence of only small integers.\n");
1338 insert_value_in_array(&xtc3_context.instructions,
1339 &xtc3_context.ninstr,
1340 &xtc3_context.ninstr_alloc,
1341 INSTR_ONLY_SMALL,"instr");
1347 fprintf(stderr,"Sequence of one large and small integers (good compression).\n");
1349 /* Flush all large atoms but one! */
1350 if (xtc3_context.has_large>1)
1351 flush_large(&xtc3_context,xtc3_context.has_large-1);
1353 /* Here we must check if we should emit a large
1354 type change instruction. */
1355 large_instruction_change(&xtc3_context,0);
1357 insert_value_in_array(&xtc3_context.instructions,
1358 &xtc3_context.ninstr,
1359 &xtc3_context.ninstr_alloc,
1360 INSTR_DEFAULT,"instr");
1362 write_three_large(&xtc3_context,0);
1363 xtc3_context.has_large=0;
1369 fprintf(stderr,"Sequence of only small integers.\n");
1371 insert_value_in_array(&xtc3_context.instructions,
1372 &xtc3_context.ninstr,
1373 &xtc3_context.ninstr_alloc,
1374 INSTR_ONLY_SMALL,"instr");
1376 /* Insert the small integers into the small integer array. */
1377 for (ienc=0; ienc<runlength*3; ienc++)
1378 insert_value_in_array(&xtc3_context.smallintra,
1379 &xtc3_context.nsmallintra,
1380 &xtc3_context.nsmallintra_alloc,
1381 (unsigned int)encode_ints[ienc],"smallintra");
1384 for (ienc=0; ienc<runlength; ienc++)
1385 fprintf(stderr,"Small: %d %d %d\n",
1386 encode_ints[ienc*3],
1387 encode_ints[ienc*3+1],
1388 encode_ints[ienc*3+2]);
1390 /* Update prevcoord. */
1391 for (ienc=0; ienc<runlength; ienc++)
1394 fprintf(stderr,"Prevcoord in packing: %d %d %d\n",
1395 prevcoord[0],prevcoord[1],prevcoord[2]);
1397 prevcoord[0]+=unpositive_int(encode_ints[ienc*3]);
1398 prevcoord[1]+=unpositive_int(encode_ints[ienc*3+1]);
1399 prevcoord[2]+=unpositive_int(encode_ints[ienc*3+2]);
1402 fprintf(stderr,"Prevcoord in packing: %d %d %d\n",
1403 prevcoord[0],prevcoord[1],prevcoord[2]);
1406 inpdata+=3*runlength;
1407 ntriplets_left-=runlength;
1415 fprintf(stderr,"Refused value: %d old is %d max is %d\n",new_small_index,small_index,max_large_index);
1422 fprintf(stderr,"Number of triplets left is %d\n",ntriplets_left);
1426 /* If we have large previous integers we must flush them now. */
1427 if (xtc3_context.has_large)
1428 flush_large(&xtc3_context,xtc3_context.has_large);
1430 /* Now it is time to compress all the data in the buffers with the bwlzh or base algo. */
1433 /* Inspect the data. */
1434 printarray(xtc3_context.instructions,xtc3_context.ninstr,"A instr");
1435 printarray(xtc3_context.rle,xtc3_context.nrle,"A rle");
1436 printarray(xtc3_context.large_direct,xtc3_context.nlargedir,"A largedir");
1437 printarray(xtc3_context.large_intra_delta,xtc3_context.nlargeintra,"A largeintra");
1438 printarray(xtc3_context.large_inter_delta,xtc3_context.nlargeinter,"A largeinter");
1439 printarray(xtc3_context.smallintra,xtc3_context.nsmallintra,"A smallintra");
1443 #if defined(SHOWIT) || defined(SHOWIT_LIGHT)
1444 fprintf(stderr,"instructions: %d\n",xtc3_context.ninstr);
1447 #if defined(SHOWIT) || defined(SHOWIT_LIGHT)
1448 #define bwlzh_compress bwlzh_compress_verbose
1449 #define bwlzh_compress_no_lz77 bwlzh_compress_no_lz77_verbose
1452 output_int(output,&outdata,(unsigned int)xtc3_context.ninstr);
1453 if (xtc3_context.ninstr)
1455 bwlzh_buf=warnmalloc(bwlzh_get_buflen(xtc3_context.ninstr));
1457 bwlzh_compress(xtc3_context.instructions,xtc3_context.ninstr,bwlzh_buf,&bwlzh_buf_len);
1459 bwlzh_compress_no_lz77(xtc3_context.instructions,xtc3_context.ninstr,bwlzh_buf,&bwlzh_buf_len);
1460 output_int(output,&outdata,(unsigned int)bwlzh_buf_len);
1461 memcpy(output+outdata,bwlzh_buf,bwlzh_buf_len);
1462 outdata+=bwlzh_buf_len;
1466 #if defined(SHOWIT) || defined(SHOWIT_LIGHT)
1467 fprintf(stderr,"rle: %d\n",xtc3_context.nrle);
1470 output_int(output,&outdata,(unsigned int)xtc3_context.nrle);
1471 if (xtc3_context.nrle)
1473 bwlzh_buf=warnmalloc(bwlzh_get_buflen(xtc3_context.nrle));
1475 bwlzh_compress(xtc3_context.rle,xtc3_context.nrle,bwlzh_buf,&bwlzh_buf_len);
1477 bwlzh_compress_no_lz77(xtc3_context.rle,xtc3_context.nrle,bwlzh_buf,&bwlzh_buf_len);
1478 output_int(output,&outdata,(unsigned int)bwlzh_buf_len);
1479 memcpy(output+outdata,bwlzh_buf,bwlzh_buf_len);
1480 outdata+=bwlzh_buf_len;
1484 #if defined(SHOWIT) || defined(SHOWIT_LIGHT)
1485 fprintf(stderr,"large direct: %d\n",xtc3_context.nlargedir);
1488 output_int(output,&outdata,(unsigned int)xtc3_context.nlargedir);
1489 if (xtc3_context.nlargedir)
1491 if ((speed<=2) || ((speed<=5) && (!heuristic_bwlzh(xtc3_context.large_direct,xtc3_context.nlargedir))))
1494 bwlzh_buf_len=INT_MAX;
1498 bwlzh_buf=warnmalloc(bwlzh_get_buflen(xtc3_context.nlargedir));
1500 bwlzh_compress(xtc3_context.large_direct,xtc3_context.nlargedir,bwlzh_buf,&bwlzh_buf_len);
1502 bwlzh_compress_no_lz77(xtc3_context.large_direct,xtc3_context.nlargedir,bwlzh_buf,&bwlzh_buf_len);
1504 /* If this can be written smaller using base compression we should do that. */
1505 base_buf=warnmalloc((xtc3_context.nlargedir+3)*sizeof(int));
1506 base_compress(xtc3_context.large_direct,xtc3_context.nlargedir,base_buf,&base_buf_len);
1507 #if defined(SHOWIT) || defined(SHOWIT_LIGHT)
1508 fprintf(stderr,"Large direct: Base len=%d. BWLZH len=%d\n",base_buf_len,bwlzh_buf_len);
1510 if (base_buf_len<bwlzh_buf_len)
1512 output[outdata++]=0U;
1513 output_int(output,&outdata,(unsigned int)base_buf_len);
1514 memcpy(output+outdata,base_buf,base_buf_len);
1515 outdata+=base_buf_len;
1519 output[outdata++]=1U;
1520 output_int(output,&outdata,(unsigned int)bwlzh_buf_len);
1521 memcpy(output+outdata,bwlzh_buf,bwlzh_buf_len);
1522 outdata+=bwlzh_buf_len;
1528 #if defined(SHOWIT) || defined(SHOWIT_LIGHT)
1529 fprintf(stderr,"large intra: %d\n",xtc3_context.nlargeintra);
1532 output_int(output,&outdata,(unsigned int)xtc3_context.nlargeintra);
1533 if (xtc3_context.nlargeintra)
1535 if ((speed<=2) || ((speed<=5) && (!heuristic_bwlzh(xtc3_context.large_intra_delta,xtc3_context.nlargeintra))))
1538 bwlzh_buf_len=INT_MAX;
1542 bwlzh_buf=warnmalloc(bwlzh_get_buflen(xtc3_context.nlargeintra));
1544 bwlzh_compress(xtc3_context.large_intra_delta,xtc3_context.nlargeintra,bwlzh_buf,&bwlzh_buf_len);
1546 bwlzh_compress_no_lz77(xtc3_context.large_intra_delta,xtc3_context.nlargeintra,bwlzh_buf,&bwlzh_buf_len);
1548 /* If this can be written smaller using base compression we should do that. */
1549 base_buf=warnmalloc((xtc3_context.nlargeintra+3)*sizeof(int));
1550 base_compress(xtc3_context.large_intra_delta,xtc3_context.nlargeintra,base_buf,&base_buf_len);
1551 #if defined(SHOWIT) || defined(SHOWIT_LIGHT)
1552 fprintf(stderr,"Large intra: Base len=%d. BWLZH len=%d\n",base_buf_len,bwlzh_buf_len);
1554 if (base_buf_len<bwlzh_buf_len)
1556 output[outdata++]=0U;
1557 output_int(output,&outdata,(unsigned int)base_buf_len);
1558 memcpy(output+outdata,base_buf,base_buf_len);
1559 outdata+=base_buf_len;
1563 output[outdata++]=1U;
1564 output_int(output,&outdata,(unsigned int)bwlzh_buf_len);
1565 memcpy(output+outdata,bwlzh_buf,bwlzh_buf_len);
1566 outdata+=bwlzh_buf_len;
1572 #if defined(SHOWIT) || defined(SHOWIT_LIGHT)
1573 fprintf(stderr,"large inter: %d\n",xtc3_context.nlargeinter);
1576 output_int(output,&outdata,(unsigned int)xtc3_context.nlargeinter);
1577 if (xtc3_context.nlargeinter)
1579 if ((speed<=2) || ((speed<=5) && (!heuristic_bwlzh(xtc3_context.large_inter_delta,xtc3_context.nlargeinter))))
1582 bwlzh_buf_len=INT_MAX;
1586 bwlzh_buf=warnmalloc(bwlzh_get_buflen(xtc3_context.nlargeinter));
1588 bwlzh_compress(xtc3_context.large_inter_delta,xtc3_context.nlargeinter,bwlzh_buf,&bwlzh_buf_len);
1590 bwlzh_compress_no_lz77(xtc3_context.large_inter_delta,xtc3_context.nlargeinter,bwlzh_buf,&bwlzh_buf_len);
1592 /* If this can be written smaller using base compression we should do that. */
1593 base_buf=warnmalloc((xtc3_context.nlargeinter+3)*sizeof(int));
1594 base_compress(xtc3_context.large_inter_delta,xtc3_context.nlargeinter,base_buf,&base_buf_len);
1595 #if defined(SHOWIT) || defined(SHOWIT_LIGHT)
1596 fprintf(stderr,"Large inter: Base len=%d. BWLZH len=%d\n",base_buf_len,bwlzh_buf_len);
1598 if (base_buf_len<bwlzh_buf_len)
1600 output[outdata++]=0U;
1601 output_int(output,&outdata,(unsigned int)base_buf_len);
1602 memcpy(output+outdata,base_buf,base_buf_len);
1603 outdata+=base_buf_len;
1607 output[outdata++]=1U;
1608 output_int(output,&outdata,(unsigned int)bwlzh_buf_len);
1609 memcpy(output+outdata,bwlzh_buf,bwlzh_buf_len);
1610 outdata+=bwlzh_buf_len;
1616 #if defined(SHOWIT) || defined(SHOWIT_LIGHT)
1617 fprintf(stderr,"small intra: %d\n",xtc3_context.nsmallintra);
1620 output_int(output,&outdata,(unsigned int)xtc3_context.nsmallintra);
1621 if (xtc3_context.nsmallintra)
1623 if ((speed<=2) || ((speed<=5) && (!heuristic_bwlzh(xtc3_context.smallintra,xtc3_context.nsmallintra))))
1626 bwlzh_buf_len=INT_MAX;
1630 bwlzh_buf=warnmalloc(bwlzh_get_buflen(xtc3_context.nsmallintra));
1632 bwlzh_compress(xtc3_context.smallintra,xtc3_context.nsmallintra,bwlzh_buf,&bwlzh_buf_len);
1634 bwlzh_compress_no_lz77(xtc3_context.smallintra,xtc3_context.nsmallintra,bwlzh_buf,&bwlzh_buf_len);
1636 /* If this can be written smaller using base compression we should do that. */
1637 base_buf=warnmalloc((xtc3_context.nsmallintra+3)*sizeof(int));
1638 base_compress(xtc3_context.smallintra,xtc3_context.nsmallintra,base_buf,&base_buf_len);
1639 #if defined(SHOWIT) || defined(SHOWIT_LIGHT)
1640 fprintf(stderr,"Small intra: Base len=%d. BWLZH len=%d\n",base_buf_len,bwlzh_buf_len);
1642 if (base_buf_len<bwlzh_buf_len)
1644 output[outdata++]=0U;
1645 output_int(output,&outdata,(unsigned int)base_buf_len);
1646 memcpy(output+outdata,base_buf,base_buf_len);
1647 outdata+=base_buf_len;
1651 output[outdata++]=1U;
1652 output_int(output,&outdata,(unsigned int)bwlzh_buf_len);
1653 memcpy(output+outdata,bwlzh_buf,bwlzh_buf_len);
1654 outdata+=bwlzh_buf_len;
1661 free_xtc3_context(&xtc3_context);
1665 static void decompress_bwlzh_block(unsigned char **ptr,
1667 unsigned int **vals)
1669 int bwlzh_buf_len=(int)(((unsigned int)(*ptr)[0]) |
1670 (((unsigned int)(*ptr)[1])<<8) |
1671 (((unsigned int)(*ptr)[2])<<16) |
1672 (((unsigned int)(*ptr)[3])<<24));
1674 *vals=warnmalloc(nvals*sizeof (**vals));
1675 bwlzh_decompress(*ptr,nvals,*vals);
1676 (*ptr)+=bwlzh_buf_len;
1679 static void decompress_base_block(unsigned char **ptr,
1681 unsigned int **vals)
1683 int base_buf_len=(int)(((unsigned int)(*ptr)[0]) |
1684 (((unsigned int)(*ptr)[1])<<8) |
1685 (((unsigned int)(*ptr)[2])<<16) |
1686 (((unsigned int)(*ptr)[3])<<24));
1688 *vals=warnmalloc(nvals*sizeof (**vals));
1689 base_decompress(*ptr,nvals,*vals);
1690 (*ptr)+=base_buf_len;
1693 static void unpack_one_large(struct xtc3_context *xtc3_context,
1694 int *ilargedir, int *ilargeintra,
1695 int *ilargeinter, int *prevcoord,
1696 int *minint, int *output,
1697 int outdata, int didswap,
1698 int natoms, int current_large_type)
1700 int large_ints[3]={0,0,0};
1701 if (current_large_type==0 && xtc3_context->large_direct)
1703 large_ints[0]=(int)xtc3_context->large_direct[(*ilargedir)]+minint[0];
1704 large_ints[1]=(int)xtc3_context->large_direct[(*ilargedir)+1]+minint[1];
1705 large_ints[2]=(int)xtc3_context->large_direct[(*ilargedir)+2]+minint[2];
1708 else if (current_large_type==1 && xtc3_context->large_intra_delta)
1710 large_ints[0]=unpositive_int(xtc3_context->large_intra_delta[(*ilargeintra)])+prevcoord[0];
1711 large_ints[1]=unpositive_int(xtc3_context->large_intra_delta[(*ilargeintra)+1])+prevcoord[1];
1712 large_ints[2]=unpositive_int(xtc3_context->large_intra_delta[(*ilargeintra)+2])+prevcoord[2];
1715 else if (xtc3_context->large_inter_delta)
1717 large_ints[0]=unpositive_int(xtc3_context->large_inter_delta[(*ilargeinter)])
1718 +output[outdata-natoms*3+didswap*3];
1719 large_ints[1]=unpositive_int(xtc3_context->large_inter_delta[(*ilargeinter)+1])
1720 +output[outdata-natoms*3+1+didswap*3];
1721 large_ints[2]=unpositive_int(xtc3_context->large_inter_delta[(*ilargeinter)+2])
1722 +output[outdata-natoms*3+2+didswap*3];
1725 prevcoord[0]=large_ints[0];
1726 prevcoord[1]=large_ints[1];
1727 prevcoord[2]=large_ints[2];
1728 output[outdata]=large_ints[0];
1729 output[outdata+1]=large_ints[1];
1730 output[outdata+2]=large_ints[2];
1732 fprintf(stderr,"Unpack one large: %d %d %d\n",prevcoord[0],prevcoord[1],prevcoord[2]);
1737 int Ptngc_unpack_array_xtc3(unsigned char *packed,int *output, int length, int natoms)
1741 unsigned char *ptr=packed;
1744 int ntriplets_left=length/3;
1747 int current_large_type=0;
1755 struct xtc3_context xtc3_context;
1756 init_xtc3_context(&xtc3_context);
1760 minint[i]=unpositive_int((int)(((unsigned int)ptr[0]) |
1761 (((unsigned int)ptr[1])<<8) |
1762 (((unsigned int)ptr[2])<<16) |
1763 (((unsigned int)ptr[3])<<24)));
1767 xtc3_context.ninstr=(int)(((unsigned int)ptr[0]) |
1768 (((unsigned int)ptr[1])<<8) |
1769 (((unsigned int)ptr[2])<<16) |
1770 (((unsigned int)ptr[3])<<24));
1772 if (xtc3_context.ninstr)
1773 decompress_bwlzh_block(&ptr,xtc3_context.ninstr,&xtc3_context.instructions);
1775 xtc3_context.nrle=(int)(((unsigned int)ptr[0]) |
1776 (((unsigned int)ptr[1])<<8) |
1777 (((unsigned int)ptr[2])<<16) |
1778 (((unsigned int)ptr[3])<<24));
1780 if (xtc3_context.nrle)
1781 decompress_bwlzh_block(&ptr,xtc3_context.nrle,&xtc3_context.rle);
1783 xtc3_context.nlargedir=(int)(((unsigned int)ptr[0]) |
1784 (((unsigned int)ptr[1])<<8) |
1785 (((unsigned int)ptr[2])<<16) |
1786 (((unsigned int)ptr[3])<<24));
1788 if (xtc3_context.nlargedir)
1791 decompress_bwlzh_block(&ptr,xtc3_context.nlargedir,&xtc3_context.large_direct);
1793 decompress_base_block(&ptr,xtc3_context.nlargedir,&xtc3_context.large_direct);
1796 xtc3_context.nlargeintra=(int)(((unsigned int)ptr[0]) |
1797 (((unsigned int)ptr[1])<<8) |
1798 (((unsigned int)ptr[2])<<16) |
1799 (((unsigned int)ptr[3])<<24));
1801 if (xtc3_context.nlargeintra)
1804 decompress_bwlzh_block(&ptr,xtc3_context.nlargeintra,&xtc3_context.large_intra_delta);
1806 decompress_base_block(&ptr,xtc3_context.nlargeintra,&xtc3_context.large_intra_delta);
1809 xtc3_context.nlargeinter=(int)(((unsigned int)ptr[0]) |
1810 (((unsigned int)ptr[1])<<8) |
1811 (((unsigned int)ptr[2])<<16) |
1812 (((unsigned int)ptr[3])<<24));
1814 if (xtc3_context.nlargeinter)
1817 decompress_bwlzh_block(&ptr,xtc3_context.nlargeinter,&xtc3_context.large_inter_delta);
1819 decompress_base_block(&ptr,xtc3_context.nlargeinter,&xtc3_context.large_inter_delta);
1822 xtc3_context.nsmallintra=(int)(((unsigned int)ptr[0]) |
1823 (((unsigned int)ptr[1])<<8) |
1824 (((unsigned int)ptr[2])<<16) |
1825 (((unsigned int)ptr[3])<<24));
1827 if (xtc3_context.nsmallintra)
1830 decompress_bwlzh_block(&ptr,xtc3_context.nsmallintra,&xtc3_context.smallintra);
1832 decompress_base_block(&ptr,xtc3_context.nsmallintra,&xtc3_context.smallintra);
1835 /* Initial prevcoord is the minimum integers. */
1836 prevcoord[0]=minint[0];
1837 prevcoord[1]=minint[1];
1838 prevcoord[2]=minint[2];
1840 while (ntriplets_left>0 && iinstr<xtc3_context.ninstr)
1842 int instr=xtc3_context.instructions[iinstr++];
1844 fprintf(stderr,"instr=%d @ %d\n",instr,iinstr-1);
1847 fprintf(stderr,"ntriplets left=%d\n",ntriplets_left);
1849 if ((instr==INSTR_DEFAULT) /* large+small */
1850 || (instr==INSTR_ONLY_LARGE) /* only large */
1851 || (instr==INSTR_ONLY_SMALL)) /* only small */
1853 if (instr!=INSTR_ONLY_SMALL)
1856 if ((instr==INSTR_DEFAULT) && (swapatoms))
1858 unpack_one_large(&xtc3_context,&ilargedir, &ilargeintra, &ilargeinter,
1859 prevcoord, minint, output, outdata, didswap,
1860 natoms, current_large_type);
1864 if (instr!=INSTR_ONLY_LARGE)
1866 for (i=0; i<runlength; i++)
1868 prevcoord[0]+=unpositive_int(xtc3_context.smallintra[ismallintra]);
1869 prevcoord[1]+=unpositive_int(xtc3_context.smallintra[ismallintra+1]);
1870 prevcoord[2]+=unpositive_int(xtc3_context.smallintra[ismallintra+2]);
1872 output[outdata+i*3]=prevcoord[0];
1873 output[outdata+i*3+1]=prevcoord[1];
1874 output[outdata+i*3+2]=prevcoord[2];
1876 fprintf(stderr,"Unpack small: %d %d %d\n",prevcoord[0],prevcoord[1],prevcoord[2]);
1879 if ((instr==INSTR_DEFAULT) && (swapatoms))
1883 int tmp=output[outdata-3+i];
1884 output[outdata-3+i]=output[outdata+i];
1885 output[outdata+i]=tmp;
1888 fprintf(stderr,"Unswap results in\n");
1890 fprintf(stderr,"%d %d %d\n",output[outdata-3+i*3],output[outdata-2+i*3],output[outdata-1+i*3]);
1893 ntriplets_left-=runlength;
1894 outdata+=runlength*3;
1897 else if (instr==INSTR_LARGE_RLE && irle<xtc3_context.nrle)
1899 int large_rle=xtc3_context.rle[irle++];
1901 fprintf(stderr,"large_rle=%d @ %d\n",large_rle,irle-1);
1903 for (i=0; i<large_rle; i++)
1905 unpack_one_large(&xtc3_context,&ilargedir, &ilargeintra, &ilargeinter,
1906 prevcoord, minint, output, outdata, 0,
1907 natoms, current_large_type);
1912 else if (instr==INSTR_SMALL_RUNLENGTH && irle<xtc3_context.nrle)
1914 runlength=xtc3_context.rle[irle++];
1916 fprintf(stderr,"small_rle=%d @ %d\n",runlength,irle-1);
1919 else if (instr==INSTR_FLIP)
1921 swapatoms=1-swapatoms;
1923 fprintf(stderr,"new flip=%d\n",swapatoms);
1926 else if (instr==INSTR_LARGE_DIRECT)
1928 current_large_type=0;
1930 fprintf(stderr,"large direct\n");
1933 else if (instr==INSTR_LARGE_INTRA_DELTA)
1935 current_large_type=1;
1937 fprintf(stderr,"large intra delta\n");
1940 else if (instr==INSTR_LARGE_INTER_DELTA)
1942 current_large_type=2;
1944 fprintf(stderr,"large inter delta\n");
1948 if (ntriplets_left<0)
1950 fprintf(stderr,"TRAJNG XTC3: A bug has been found. At end ntriplets_left<0\n");
1953 free_xtc3_context(&xtc3_context);