1 /* This code is part of the tng compression routines.
3 * Written by Daniel Spangberg and Magnus Lundborg
4 * Copyright (c) 2010, 2013-2014 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.
14 #include "../../include/compression/warnmalloc.h"
15 #include "../../include/compression/mtf.h"
17 /* "Partial" MTF. Byte based. */
18 /* Move to front coding.
19 Acceptable inputs are max 8 bits (0-0xFF) */
20 static void comp_conv_to_mtf_byte(unsigned char *vals
, const int nvals
,
21 unsigned char *valsmtf
)
24 /* Indices into a linked list */
27 /* Head of the linked list */
33 list
[255]=-1; /* end. */
35 for (i
=0; i
<nvals
; i
++)
38 /* Find how early in the dict the value is */
48 valsmtf
[i
]=(unsigned char)r
;
49 /* Move it to front in list */
50 /* Is it the head? Then it is already at the front. */
53 /* Remove it from inside the list */
54 list
[oldptr
]=list
[ptr
];
55 /* Move it to the front. */
62 void Ptngc_comp_conv_to_mtf_partial(unsigned int *vals
, const int nvals
,
63 unsigned int *valsmtf
)
65 unsigned char *tmp
=warnmalloc(nvals
*2);
68 memset(valsmtf
, 0U, sizeof(unsigned int) * nvals
);
72 for (i
=0; i
<nvals
; i
++)
73 tmp
[i
]=(unsigned char)((vals
[i
]>>(8*j
))&0xFF);
74 comp_conv_to_mtf_byte(tmp
,nvals
,tmp
+nvals
);
75 for (i
=0; i
<nvals
; i
++)
76 valsmtf
[i
]|=(((unsigned int)(tmp
[nvals
+i
]))<<(8*j
));
81 void Ptngc_comp_conv_to_mtf_partial3(unsigned int *vals
, const int nvals
,
82 unsigned char *valsmtf
)
84 unsigned char *tmp
=warnmalloc(nvals
);
88 for (i
=0; i
<nvals
; i
++)
89 tmp
[i
]=(unsigned char)((vals
[i
]>>(8*j
))&0xFF);
90 comp_conv_to_mtf_byte(tmp
,nvals
,valsmtf
+j
*nvals
);
95 /* Move to front decoding */
96 static void comp_conv_from_mtf_byte(unsigned char *valsmtf
, const int nvals
,
100 /* Indices into a linked list */
103 /* Head of the linked list */
105 for (i
=0; i
<256; i
++)
107 for (i
=0; i
<255; i
++)
109 list
[255]=-1; /* end. */
111 for (i
=0; i
<nvals
; i
++)
113 int r
=(int)valsmtf
[i
];
114 /* Find value at position r in the list */
124 vals
[i
]=(unsigned int)dict
[ptr
];
125 /* Move it to front in list */
126 /* Is it the head? Then it is already at the front. */
129 /* Remove it from inside the list */
130 list
[oldptr
]=list
[ptr
];
131 /* Move it to the front. */
138 void Ptngc_comp_conv_from_mtf_partial(unsigned int *valsmtf
, const int nvals
,
141 unsigned char *tmp
=warnmalloc(nvals
*2);
144 memset(vals
, 0U, sizeof(unsigned int) * nvals
);
148 for (i
=0; i
<nvals
; i
++)
149 tmp
[i
]=(unsigned char)((valsmtf
[i
]>>(8*j
))&0xFF);
150 comp_conv_from_mtf_byte(tmp
,nvals
,tmp
+nvals
);
151 for (i
=0; i
<nvals
; i
++)
152 vals
[i
]|=(((unsigned int)(tmp
[nvals
+i
]))<<(8*j
));
157 void Ptngc_comp_conv_from_mtf_partial3(unsigned char *valsmtf
, const int nvals
,
160 unsigned char *tmp
=warnmalloc(nvals
);
163 memset(vals
, 0U, sizeof(unsigned int) * nvals
);
167 comp_conv_from_mtf_byte(valsmtf
+j
*nvals
,nvals
,tmp
);
168 for (i
=0; i
<nvals
; i
++)
169 vals
[i
]|=(((unsigned int)(tmp
[i
]))<<(8*j
));
174 /* Move to front coding.
175 Acceptable inputs are max 24 bits (0-0xFFFFFF) */
176 void Ptngc_comp_conv_to_mtf(unsigned int *vals
, const int nvals
,
177 unsigned int *dict
, const int ndict
,
178 unsigned int *valsmtf
)
181 /* Indices into a linked list */
182 int *list
=warnmalloc(ndict
*sizeof *list
);
183 /* Head of the linked list */
185 for (i
=0; i
<ndict
-1; i
++)
187 list
[ndict
-1]=-1; /* end. */
189 for (i
=0; i
<nvals
; i
++)
192 /* Find how early in the dict the value is */
203 /* Move it to front in list */
204 /* Is it the head? Then it is already at the front. */
207 /* Remove it from inside the list */
208 list
[oldptr
]=list
[ptr
];
209 /* Move it to the front. */
217 /* Move to front decoding */
218 void Ptngc_comp_conv_from_mtf(unsigned int *valsmtf
, const int nvals
,
219 unsigned int *dict
, const int ndict
,
223 /* Indices into a linked list */
224 int *list
=warnmalloc(ndict
*sizeof *list
);
225 /* Head of the linked list */
227 for (i
=0; i
<ndict
-1; i
++)
229 list
[ndict
-1]=-1; /* end. */
231 for (i
=0; i
<nvals
; i
++)
234 /* Find value at position r in the list */
245 /* Move it to front in list */
246 /* Is it the head? Then it is already at the front. */
249 /* Remove it from inside the list */
250 list
[oldptr
]=list
[ptr
];
251 /* Move it to the front. */