Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
att
GitHub Repository: att/ast
Path: blob/master/src/lib/libvcodex/Vcmisc/vcmtf.c
1810 views
1
/***********************************************************************
2
* *
3
* This software is part of the ast package *
4
* Copyright (c) 2003-2011 AT&T Intellectual Property *
5
* and is licensed under the *
6
* Eclipse Public License, Version 1.0 *
7
* by AT&T Intellectual Property *
8
* *
9
* A copy of the License is available at *
10
* http://www.eclipse.org/org/documents/epl-v10.html *
11
* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
12
* *
13
* Information and Software Systems Research *
14
* AT&T Research *
15
* Florham Park NJ *
16
* *
17
* Phong Vo <[email protected]> *
18
* *
19
***********************************************************************/
20
#include <vclib.h>
21
22
/* Move-to-front transformers.
23
**
24
** Written by Kiem-Phong Vo ([email protected])
25
*/
26
27
typedef ssize_t (*Mtf_f)_ARG_((Vcchar_t*, Vcchar_t*, Vcchar_t*, int));
28
static ssize_t mtfp _ARG_((Vcchar_t*, Vcchar_t*, Vcchar_t*, int));
29
static ssize_t mtf0 _ARG_((Vcchar_t*, Vcchar_t*, Vcchar_t*, int));
30
31
#define MTFC(c,p,m,n) /* know byte, need to compute position */ \
32
{ m = mtf[p = 0]; \
33
while(m != c) \
34
{ n = mtf[p += 1]; mtf[p] = m; m = n; } \
35
mtf[0] = c; \
36
}
37
38
#define MTFP(c,p,m,n) /* know position, need to compute byte */ \
39
{ c = mtf[m = 0]; \
40
while(m != p) \
41
{ n = mtf[m += 1]; mtf[m] = c; c = n; } \
42
mtf[0] = c; \
43
}
44
45
/* arguments to select move-to-front coder */
46
static Vcmtarg_t _Mtfargs[] =
47
{ { "0", "Pure move-to-front strategy.", (Void_t*)mtf0 },
48
{ 0 , "Move-to-front with prediction.", (Void_t*)mtfp }
49
};
50
51
#if __STD_C
52
static ssize_t mtfp(Vcchar_t* dt, Vcchar_t* enddt, Vcchar_t* output, int encoding)
53
#else
54
static ssize_t mtfp(dt, enddt, output, encoding)
55
Vcchar_t* dt; /* data to be un/mtf-ed */
56
Vcchar_t* enddt;
57
Vcchar_t* output; /* output array */
58
int encoding; /* !=0 if encoding */
59
#endif
60
{
61
reg int c, p, m, n, predc;
62
reg Vcchar_t *o;
63
Vcchar_t mtf[256], succ[256];
64
size_t wght[256];
65
66
predc = 0;
67
for(p = 0; p < 256; ++p)
68
mtf[p] = succ[p] = p;
69
memset(wght,0,sizeof(wght));
70
71
/* weight increases slightly but decreases quickly */
72
#define SUCC(c,p,m,n) \
73
{ if(succ[predc] == c) wght[predc] += 4; \
74
else if((wght[predc] >>= 1) <= 0) \
75
{ succ[predc] = c; wght[predc] = 1; } \
76
predc = c; \
77
if(wght[c] > 1 && (c = succ[c]) != mtf[0] ) \
78
MTFC(c,p,m,n); /* predicting succ[c] is next */ \
79
}
80
81
if(encoding)
82
{ for(o = output; dt < enddt; ++dt, ++o )
83
{ c = *dt; MTFC(c,p,m,n); *o = p;
84
SUCC(c,p,m,n);
85
}
86
}
87
else
88
{ for(o = output; dt < enddt; ++dt, ++o )
89
{ p = *dt; MTFP(c,p,m,n); *o = c;
90
SUCC(c,p,m,n);
91
}
92
}
93
94
return o-output;
95
}
96
97
98
/* move to zeroth location */
99
#if __STD_C
100
static ssize_t mtf0(Vcchar_t* dt, Vcchar_t* enddt, Vcchar_t* output, int encoding)
101
#else
102
static ssize_t mtf0(dt, enddt, output, encoding)
103
Vcchar_t* dt; /* data to be un/mtf-ed */
104
Vcchar_t* enddt;
105
Vcchar_t* output; /* output array */
106
int encoding; /* !=0 if encoding */
107
#endif
108
{
109
reg int c, p, m, n;
110
reg Vcchar_t *o;
111
Vcchar_t mtf[256];
112
113
for(p = 0; p < 256; ++p)
114
mtf[p] = p;
115
if(encoding)
116
{ for(o = output; dt < enddt; ++dt, ++o )
117
{ c = *dt; MTFC(c,p,m,n); *o = p;
118
}
119
}
120
else
121
{ for(o = output; dt < enddt; ++dt, ++o )
122
{ p = *dt; MTFP(c,p,m,n); *o = c;
123
}
124
}
125
126
return o-output;
127
}
128
129
#if __STD_C
130
static ssize_t vcmtf(Vcodex_t* vc, const Void_t* data, size_t size, Void_t** out)
131
#else
132
static ssize_t vcmtf(vc, data, size, out)
133
Vcodex_t* vc;
134
Void_t* data;
135
size_t size;
136
Void_t** out;
137
#endif
138
{
139
Vcchar_t *output, *dt;
140
ssize_t sz;
141
Mtf_f mtff = vcgetmtdata(vc, Mtf_f);
142
143
if((sz = size) == 0)
144
return 0;
145
146
if(!(output = vcbuffer(vc, NIL(Vcchar_t*), sz, 0)) )
147
RETURN(-1);
148
149
if((*mtff)((Vcchar_t*)data, ((Vcchar_t*)data)+sz, output, 1) != sz)
150
RETURN(-1);
151
152
dt = output;
153
if(vcrecode(vc, &output, &sz, 0, 0) < 0)
154
RETURN(-1);
155
if(dt != output)
156
vcbuffer(vc, dt, -1, -1);
157
158
if(out)
159
*out = output;
160
return sz;
161
}
162
163
#if __STD_C
164
static ssize_t vcunmtf(Vcodex_t* vc, const Void_t* data, size_t size, Void_t** out)
165
#else
166
static ssize_t vcunmtf(vc, data, size, out)
167
Vcodex_t* vc;
168
Void_t* data;
169
size_t size;
170
Void_t** out;
171
#endif
172
{
173
Vcchar_t *dt, *output;
174
ssize_t sz;
175
Mtf_f mtff = vcgetmtdata(vc, Mtf_f);
176
177
if(size == 0)
178
return 0;
179
180
dt = (Vcchar_t*)data; sz = size;
181
if(vcrecode(vc, &dt, &sz, 0, 0) < 0 )
182
RETURN(-1);
183
184
if(!(output = vcbuffer(vc, NIL(Vcchar_t*), sz, 0)) )
185
RETURN(-1);
186
187
if((*mtff)(dt, dt+sz, output, 0) != sz)
188
RETURN(-1);
189
190
if(dt != (Vcchar_t*)data)
191
vcbuffer(vc, dt, -1, -1);
192
193
if(out)
194
*out = output;
195
return sz;
196
}
197
198
#if __STD_C
199
static ssize_t mtfextract(Vcodex_t* vc, Vcchar_t** datap)
200
#else
201
static ssize_t mtfextract(vc, datap)
202
Vcodex_t* vc;
203
Vcchar_t** datap; /* basis string for persistence */
204
#endif
205
{
206
Vcmtarg_t *arg;
207
char *ident;
208
ssize_t n;
209
Void_t *mtdt = vcgetmtdata(vc, Void_t*);
210
211
for(arg = _Mtfargs;; ++arg)
212
if(!arg->name || arg->data == mtdt)
213
break;
214
if(!arg->name)
215
return 0;
216
217
n = strlen(arg->name);
218
if(!(ident = (char*)vcbuffer(vc, NIL(Vcchar_t*), sizeof(int)*n+1, 0)) )
219
RETURN(-1);
220
if(!(ident = vcstrcode(arg->name, ident, sizeof(int)*n+1)) )
221
RETURN(-1);
222
if(datap)
223
*datap = (Void_t*)ident;
224
return n;
225
}
226
227
#if __STD_C
228
static Vcodex_t* mtfrestore(Vcchar_t* data, ssize_t dtsz)
229
#else
230
static Vcodex_t* mtfrestore(data, dtsz)
231
Vcchar_t* data; /* persistence data */
232
ssize_t dtsz; /* its length */
233
#endif
234
{
235
Vcmtarg_t *arg;
236
char *ident, buf[1024];
237
238
for(arg = _Mtfargs; arg->name; ++arg)
239
{ if(!(ident = vcstrcode(arg->name, buf, sizeof(buf))) )
240
return NIL(Vcodex_t*);
241
if(dtsz == strlen(ident) && strncmp(ident, (Void_t*)data, dtsz) == 0)
242
break;
243
}
244
return vcopen(0, Vcmtf, (Void_t*)arg->name, 0, VC_DECODE);
245
}
246
247
#if __STD_C
248
static int mtfevent(Vcodex_t* vc, int type, Void_t* params)
249
#else
250
static int mtfevent(vc, type, params)
251
Vcodex_t* vc;
252
int type;
253
Void_t* params;
254
#endif
255
{
256
Vcmtarg_t *arg;
257
Vcmtcode_t *mtcd;
258
char *data;
259
260
if(type == VC_OPENING )
261
{ for(arg = NIL(Vcmtarg_t*), data = (char*)params; data && *data; )
262
{ data = vcgetmtarg(data, 0, 0, _Mtfargs, &arg);
263
if(arg && arg->name)
264
break;
265
}
266
if(!arg) /* get the default argument */
267
for(arg = _Mtfargs;; ++arg)
268
if(!arg->name)
269
break;
270
vcsetmtdata(vc, arg->data);
271
return 0;
272
}
273
else if(type == VC_EXTRACT)
274
{ if(!(mtcd = (Vcmtcode_t*)params) )
275
RETURN(-1);
276
if((mtcd->size = mtfextract(vc, &mtcd->data)) < 0 )
277
RETURN(-1);
278
return 1;
279
}
280
else if(type == VC_RESTORE)
281
{ if(!(mtcd = (Vcmtcode_t*)params) )
282
RETURN(-1);
283
if(!(mtcd->coder = mtfrestore(mtcd->data, mtcd->size)) )
284
RETURN(-1);
285
return 1;
286
}
287
288
return 0;
289
}
290
291
Vcmethod_t _Vcmtf =
292
{ vcmtf,
293
vcunmtf,
294
mtfevent,
295
"mtf", "Move-to-front transform.",
296
"[-version?mtf (AT&T Research) 2003-01-01]" USAGE_LICENSE,
297
_Mtfargs,
298
1024*1024,
299
0
300
};
301
302
VCLIB(Vcmtf)
303
304