TNG version 1.7.3
[alexxy/gromacs.git] / src / external / tng_io / src / compression / rle.c
1 /* This code is part of the tng compression routines.
2  *
3  * Written by Daniel Spangberg
4  * Copyright (c) 2010, 2013, The GROMACS development team.
5  *
6  *
7  * This program is free software; you can redistribute it and/or
8  * modify it under the terms of the Revised BSD License.
9  */
10
11
12 #include "../../include/compression/rle.h"
13
14 static void add_rle(unsigned int *rle,
15                     const int v, int nsim,
16                     int *j, const int min_rle)
17 {
18   if (nsim>min_rle)
19     {
20       /* Insert run-length */
21       unsigned int run=((unsigned int)nsim);
22       while (run>1)
23         {
24           if (run&0x1U)
25             rle[(*j)++]=1;
26           else
27             rle[(*j)++]=0;
28           run>>=1;
29         }
30       nsim=1;
31     }
32   while (nsim--)
33     rle[(*j)++]=v+2;
34 }
35
36 /* Run length encoding.
37    Acceptable inputs are about 16 bits (0-0xFFFF)
38    If input is 0-N output will be be values of 0-(N+2) */
39 void Ptngc_comp_conv_to_rle(unsigned int *vals, const int nvals,
40                             unsigned int *rle, int *nrle,
41                             const int min_rle)
42 {
43   int i;
44   int j=0;
45   int nsim=0;
46   int v=-1;
47   for (i=0; i<nvals; i++)
48     {
49       if (!nsim)
50         {
51           v=vals[i];
52           nsim=1;
53         }
54       else
55         {
56           if (v==vals[i])
57             nsim++;
58           else
59             {
60               add_rle(rle,v,nsim,&j,min_rle);
61               nsim=1;
62               v=vals[i];
63             }
64         }
65     }
66   if (nsim!=0)
67     add_rle(rle,v,nsim,&j,min_rle);
68   *nrle=j;
69 }
70
71 void Ptngc_comp_conv_from_rle(unsigned int *rle,
72                               unsigned int *vals, const int nvals)
73 {
74   int i=0;
75   int j=0;
76   while (i<nvals)
77     {
78       int k;
79       unsigned int len=0;
80       unsigned int mask=0x1;
81       unsigned int v=rle[j++];
82       unsigned int hasrle=0;
83       while (v<2)
84         {
85           if (v)
86             len|=mask;
87           mask<<=1;
88           hasrle=1;
89           v=rle[j++];
90         }
91       if (!hasrle)
92         len=1;
93       else
94         len|=mask;
95       for (k=0; k<(int)len; k++)
96         vals[i++]=v-2;
97     }
98 }
99