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
add_rle(unsigned int * rle,const int v,int nsim,int * j,const int min_rle)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) */
Ptngc_comp_conv_to_rle(unsigned int * vals,const int nvals,unsigned int * rle,int * nrle,const int min_rle)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
Ptngc_comp_conv_from_rle(unsigned int * rle,unsigned int * vals,const int nvals)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
100