summaryrefslogtreecommitdiff
path: root/src/compression/xtc3.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/compression/xtc3.c')
-rw-r--r--src/compression/xtc3.c91
1 files changed, 47 insertions, 44 deletions
diff --git a/src/compression/xtc3.c b/src/compression/xtc3.c
index 8c742a2..c26d7aa 100644
--- a/src/compression/xtc3.c
+++ b/src/compression/xtc3.c
@@ -10,9 +10,9 @@
* of the License, or (at your option) any later version.
*/
-/* This code is heavily influenced by
+/* This code is heavily influenced by
http://hpcv100.rc.rug.nl/xdrf.html
- Based on coordinate compression (c) by Frans van Hoesel.
+ Based on coordinate compression (c) by Frans van Hoesel.
and GROMACS xtc files (http://www.gromacs.org)
(c) Copyright (c) Erik Lindahl, David van der Spoel
*/
@@ -101,9 +101,9 @@ static int unpositive_int(int val)
struct xtc3_context
{
unsigned int *instructions;
- int ninstr, ninstr_alloc;
+ int ninstr, ninstr_alloc;
unsigned int *rle;
- int nrle, nrle_alloc;
+ int nrle, nrle_alloc;
unsigned int *large_direct;
int nlargedir, nlargedir_alloc;
unsigned int *large_intra_delta;
@@ -117,17 +117,17 @@ struct xtc3_context
int has_large_ints[MAX_LARGE_RLE*3]; /* Large cache. */
int has_large_type[MAX_LARGE_RLE]; /* What kind of type this large
int is. */
- int current_large_type;
+ int current_large_type;
};
static void init_xtc3_context(struct xtc3_context *xtc3_context)
{
xtc3_context->instructions=NULL;
xtc3_context->ninstr=0;
- xtc3_context->ninstr_alloc=0;
+ xtc3_context->ninstr_alloc=0;
xtc3_context->rle=NULL;
xtc3_context->nrle=0;
- xtc3_context->nrle_alloc=0;
+ xtc3_context->nrle_alloc=0;
xtc3_context->large_direct=NULL;
xtc3_context->nlargedir=0;
xtc3_context->nlargedir_alloc=0;
@@ -208,7 +208,7 @@ static void insert_value_in_array(unsigned int **ptr, int *nele, int *nele_alloc
allocate_enough_memory(ptr,nele,nele_alloc);
#ifdef SHOWIT
fprintf(stderr,"Inserting value %u into array %s @ %d\n",value,arrayname,(*nele)-1);
-#endif
+#endif
(*ptr)[(*nele)-1]=value;
}
@@ -228,7 +228,7 @@ static void swapdecide(struct xtc3_context *xtc3_context, int *input,int *swapat
*/
#ifdef SHOWIT
fprintf(stderr,"Trying Flip: %g %g\n",(double)swapped/normal, (double)normal/swapped);
-#endif
+#endif
if (((swapped<normal) && (fabs((double)swapped/normal)<iflipgaincheck)) ||
((normal<swapped) && (fabs((double)normal/swapped)<iflipgaincheck)))
{
@@ -291,7 +291,7 @@ static void insert_batch(int *input_ptr, int ntriplets_left, int *prevcoord, int
{
int nencode=startenc*3;
int tmp_prevcoord[3];
-
+
tmp_prevcoord[0]=prevcoord[0];
tmp_prevcoord[1]=prevcoord[1];
tmp_prevcoord[2]=prevcoord[2];
@@ -313,13 +313,13 @@ static void insert_batch(int *input_ptr, int ntriplets_left, int *prevcoord, int
positive_int(encode_ints[i*3]),
positive_int(encode_ints[i*3+1]),
positive_int(encode_ints[i*3+2]));
-#endif
+#endif
}
}
#ifdef SHOWIT
fprintf(stderr,"New batch\n");
-#endif
+#endif
while ((nencode<3+MAX_SMALL_RLE*3) && (nencode<ntriplets_left*3))
{
encode_ints[nencode]=input_ptr[nencode]-tmp_prevcoord[0];
@@ -336,7 +336,7 @@ static void insert_batch(int *input_ptr, int ntriplets_left, int *prevcoord, int
positive_int(encode_ints[nencode]),
positive_int(encode_ints[nencode+1]),
positive_int(encode_ints[nencode+2]));
-#endif
+#endif
tmp_prevcoord[0]=input_ptr[nencode];
tmp_prevcoord[1]=input_ptr[nencode+1];
tmp_prevcoord[2]=input_ptr[nencode+2];
@@ -663,7 +663,7 @@ static void base_compress(unsigned int *data, int len, unsigned char *output, in
{
#ifdef SHOWIT
fprintf(stderr,"Writing largeint: ");
-#endif
+#endif
for (j=0; j<numbytes; j++)
{
int ilarge=j/4;
@@ -671,11 +671,11 @@ static void base_compress(unsigned int *data, int len, unsigned char *output, in
output[nwrittenout++]=(unsigned char)((largeint[ilarge]>>(ibyte*8))&(0xFFU));
#ifdef SHOWIT
fprintf(stderr,"%02x",(unsigned int)output[nwrittenout-1]);
-#endif
+#endif
}
#ifdef SHOWIT
fprintf(stderr,"\n");
-#endif
+#endif
nvals=0;
for (j=0; j<MAXBASEVALS+1; j++)
largeint[j]=0U;
@@ -692,7 +692,7 @@ static void base_compress(unsigned int *data, int len, unsigned char *output, in
int ilarge=j/4;
int ibyte=j%4;
output[nwrittenout++]=(unsigned char)((largeint[ilarge]>>(ibyte*8))&(0xFFU));
- }
+ }
}
}
*outlen=nwrittenout;
@@ -750,7 +750,7 @@ static void base_decompress(unsigned char *input, int len, unsigned int *output)
largeint[j]=0U;
#ifdef SHOWIT
fprintf(stderr,"Reading largeint: ");
-#endif
+#endif
for (j=0; j<numbytes; j++)
{
int ilarge=j/4;
@@ -758,11 +758,11 @@ static void base_decompress(unsigned char *input, int len, unsigned int *output)
largeint[ilarge]|=((unsigned int)input[j])<<(ibyte*8);
#ifdef SHOWIT
fprintf(stderr,"%02x",(unsigned int)input[j]);
-#endif
+#endif
}
#ifdef SHOWIT
fprintf(stderr,"\n");
-#endif
+#endif
input+=numbytes;
/* Do the long division required to get the output values. */
n=maxbasevals;
@@ -800,10 +800,10 @@ static int heuristic_bwlzh(unsigned int *ints, int nints)
}
/* Speed selects how careful to try to find the most efficient compression. The BWLZH algo is expensive!
- Speed <=2 always avoids BWLZH everywhere it is possible.
+ Speed <=2 always avoids BWLZH everywhere it is possible.
Speed 3 and 4 and 5 use heuristics (check proportion of large value). This should mostly be safe.
Speed 5 enables the LZ77 component of BWLZH.
- Speed 6 always tests if BWLZH is better and if it is uses it. This can be very slow.
+ Speed 6 always tests if BWLZH is better and if it is uses it. This can be very slow.
*/
unsigned char *Ptngc_pack_array_xtc3(int *input, int *length, int natoms, int speed)
{
@@ -833,7 +833,7 @@ unsigned char *Ptngc_pack_array_xtc3(int *input, int *length, int natoms, int sp
int bwlzh_buf_len;
unsigned char *base_buf=NULL;
int base_buf_len;
-
+
struct xtc3_context xtc3_context;
init_xtc3_context(&xtc3_context);
@@ -852,7 +852,10 @@ unsigned char *Ptngc_pack_array_xtc3(int *input, int *length, int natoms, int sp
nvalues_sum=0;
#endif
/* Allocate enough memory for output */
- output=warnmalloc(8* *length*sizeof *output);
+ if (*length < 48)
+ output=warnmalloc(8*48*sizeof *output);
+ else
+ output=warnmalloc(8* *length*sizeof *output);
for (i=1; i<ntriplets; i++)
@@ -955,7 +958,7 @@ unsigned char *Ptngc_pack_array_xtc3(int *input, int *length, int natoms, int sp
/* Insert the next batch of integers to be encoded into the buffer */
#ifdef SHOWIT
fprintf(stderr,"Initial batch\n");
-#endif
+#endif
insert_batch(input+inpdata,ntriplets_left,prevcoord,encode_ints,0,&nencode);
/* First we must decide if the next value is large (does not reasonably fit in current small encoding)
@@ -1044,8 +1047,8 @@ unsigned char *Ptngc_pack_array_xtc3(int *input, int *length, int natoms, int sp
positive_int(encode_ints[i*3]),
positive_int(encode_ints[i*3+1]),
positive_int(encode_ints[i*3+2]));
-
-#endif
+
+#endif
min_runlength=2;
}
}
@@ -1076,11 +1079,11 @@ unsigned char *Ptngc_pack_array_xtc3(int *input, int *length, int natoms, int sp
ntriplets_left--;
refused=0;
-
+
/* Insert the next batch of integers to be encoded into the buffer */
#ifdef SHOWIT
fprintf(stderr,"Update batch due to large int.\n");
-#endif
+#endif
if ((swapatoms) && (didswap))
{
/* Keep swapped values. */
@@ -1139,7 +1142,7 @@ unsigned char *Ptngc_pack_array_xtc3(int *input, int *length, int natoms, int sp
new_runlength=1;
new_small_index=small_index;
}
-
+
iter_runlength=new_runlength;
iter_small_index=new_small_index;
@@ -1152,7 +1155,7 @@ unsigned char *Ptngc_pack_array_xtc3(int *input, int *length, int natoms, int sp
do {
new_runlength=iter_runlength;
new_small_index=iter_small_index;
-
+
#ifdef SHOWIT
fprintf(stderr,"Test new_small_index=%d Base=%d\n",new_small_index,Ptngc_magic(new_small_index));
#endif
@@ -1205,7 +1208,7 @@ unsigned char *Ptngc_pack_array_xtc3(int *input, int *length, int natoms, int sp
else if (new_runlength<6)
rle_index_dep=QUITE_LARGE;
if ((min_runlength)
- || ((new_small_index<small_index+IS_LARGE) && (new_small_index+rle_index_dep<max_large_index))
+ || ((new_small_index<small_index+IS_LARGE) && (new_small_index+rle_index_dep<max_large_index))
#if 1
|| (new_small_index+IS_LARGE<max_large_index)
#endif
@@ -1254,7 +1257,7 @@ unsigned char *Ptngc_pack_array_xtc3(int *input, int *length, int natoms, int sp
if ((new_runlength!=runlength) || (new_small_index!=small_index))
{
int change=new_small_index-small_index;
-
+
if (new_small_index<=0)
change=0;
@@ -1276,12 +1279,12 @@ unsigned char *Ptngc_pack_array_xtc3(int *input, int *length, int natoms, int sp
rejected=0;
#ifdef SHOWIT
fprintf(stderr,"Tested decrease %d of index: %g>=%g?\n",change,isum,(double)Ptngc_magic(small_index+change)*(double)Ptngc_magic(small_index+change));
-#endif
+#endif
if (isum>(double)Ptngc_magic(small_index+change)*(double)Ptngc_magic(small_index+change))
{
#ifdef SHOWIT
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));
-#endif
+#endif
rejected=1;
change++;
}
@@ -1308,7 +1311,7 @@ unsigned char *Ptngc_pack_array_xtc3(int *input, int *length, int natoms, int sp
}
#ifdef SHOWIT
fprintf(stderr,"Current small index: %d Base=%d\n",small_index,Ptngc_magic(small_index));
-#endif
+#endif
}
/* If we have a large previous integer we can combine it with a sequence of small ints. */
if (xtc3_context.has_large)
@@ -1336,14 +1339,14 @@ unsigned char *Ptngc_pack_array_xtc3(int *input, int *length, int natoms, int sp
}
else
{
-
+
#ifdef SHOWIT
fprintf(stderr,"Sequence of one large and small integers (good compression).\n");
#endif
/* Flush all large atoms but one! */
if (xtc3_context.has_large>1)
flush_large(&xtc3_context,xtc3_context.has_large-1);
-
+
/* Here we must check if we should emit a large
type change instruction. */
large_instruction_change(&xtc3_context,0);
@@ -1352,7 +1355,7 @@ unsigned char *Ptngc_pack_array_xtc3(int *input, int *length, int natoms, int sp
&xtc3_context.ninstr,
&xtc3_context.ninstr_alloc,
INSTR_DEFAULT,"instr");
-
+
write_three_large(&xtc3_context,0);
xtc3_context.has_large=0;
}
@@ -1396,7 +1399,7 @@ unsigned char *Ptngc_pack_array_xtc3(int *input, int *length, int natoms, int sp
fprintf(stderr,"Prevcoord in packing: %d %d %d\n",
prevcoord[0],prevcoord[1],prevcoord[2]);
#endif
-
+
inpdata+=3*runlength;
ntriplets_left-=runlength;
#if 1
@@ -1408,13 +1411,13 @@ unsigned char *Ptngc_pack_array_xtc3(int *input, int *length, int natoms, int sp
#ifdef SHOWIT
fprintf(stderr,"Refused value: %d old is %d max is %d\n",new_small_index,small_index,max_large_index);
fflush(stderr);
-#endif
+#endif
refused=1;
}
}
#ifdef SHOWIT
fprintf(stderr,"Number of triplets left is %d\n",ntriplets_left);
-#endif
+#endif
}
/* If we have large previous integers we must flush them now. */
@@ -1726,7 +1729,7 @@ static void unpack_one_large(struct xtc3_context *xtc3_context,
fprintf(stderr,"Unpack one large: %d %d %d\n",prevcoord[0],prevcoord[1],prevcoord[2]);
#endif
}
-
+
int Ptngc_unpack_array_xtc3(unsigned char *packed,int *output, int length, int natoms)
{
@@ -1812,7 +1815,7 @@ int Ptngc_unpack_array_xtc3(unsigned char *packed,int *output, int length, int n
else
decompress_base_block(&ptr,xtc3_context.nlargeinter,&xtc3_context.large_inter_delta);
}
-
+
xtc3_context.nsmallintra=(int)(((unsigned int)ptr[0]) |
(((unsigned int)ptr[1])<<8) |
(((unsigned int)ptr[2])<<16) |
contact: Jan Huwald // Impressum