Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
att
GitHub Repository: att/ast
Path: blob/master/src/lib/libvcodex/Vchuff/vchtrie.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 "vchhdr.h"
21
22
23
/* Decoding Huffman-encoded data amounts to taking a sequence of
24
** bits and computing the longest bit-string representing bytes that
25
** matches a prefix of this bit sequence, then emitting the byte.
26
** For fast prefix matching, we use a recursive trie similar to
27
** the Retrie structure described in "Fast Prefix Matching of
28
** Bounded Strings" (Proceedings of ALENEX 2003).
29
**
30
** Written by Kiem-Phong Vo ([email protected])
31
*/
32
33
#define TRIE_TOP 8 /* max #bits for top level */
34
#define TRIE_SUB 4 /* max #bits for sub levels */
35
36
typedef struct _node_s
37
{ short node;
38
short size;
39
} Node_t;
40
41
#if __STD_C
42
static int bldtrie(Vchtrie_t* trie, ssize_t* clen, Vcbit_t* bits,
43
Node_t* root, ssize_t len, Vcbit_t** sort, ssize_t ns, ssize_t lev)
44
#else
45
static int bldtrie(trie, clen, bits, root, len, sort, ns, lev)
46
Vchtrie_t* trie; /* handle holding entire trie */
47
ssize_t* clen; /* table of code lengths */
48
Vcbit_t* bits; /* table of prefix codes */
49
Node_t* root; /* parent node of the new table */
50
ssize_t len; /* prefix len already processed */
51
Vcbit_t** sort; /* list of codes sharing prefix */
52
ssize_t ns; /* # of elts in sort[] */
53
ssize_t lev; /* level in the trie */
54
#endif
55
{
56
ssize_t k, m, p, s, e, z, msk, olen;
57
short *node, *size;
58
Node_t nd;
59
60
/* compute the max prefix length for this set */
61
for(m = 0, k = 0; k < ns; ++k)
62
if((s = clen[sort[k]-bits]) > m)
63
m = s;
64
65
/* # of bits to pick out at this level */
66
if((p = lev == 0 ? TRIE_TOP : TRIE_SUB) > (m - len) )
67
p = m - len;
68
69
if((trie->next + (1<<p)) > trie->trsz)
70
{ s = trie->next + ((1<<p) < (1<<8) ? (1<<8) : (1<<p));
71
if(!(node = (short*)malloc(2*s*sizeof(short))) )
72
return -1;
73
size = node+s;
74
memcpy(node, trie->node, trie->next*sizeof(short));
75
memcpy(size, trie->size, trie->next*sizeof(short));
76
if(trie->node)
77
free(trie->node);
78
trie->node = node;
79
trie->size = size;
80
trie->trsz = s;
81
}
82
83
/* set data for parent node of the new table */
84
root->node = trie->next;
85
root->size = -p;
86
trie->next += (1<<p);
87
88
/* now point trie to the new table */
89
node = trie->node + root->node;
90
size = trie->size + root->node;
91
memset(size, 0, (1<<p)*sizeof(short));
92
93
olen = len;
94
len += p;
95
msk = (1<<p)-1;
96
for(k = 0; k < ns; )
97
{ /* starting index of this code in the table */
98
s = (*sort[k] >> (VC_BITSIZE-len)) & msk;
99
100
z = clen[m = sort[k]-bits];
101
if((p = len - z) >= 0) /* data nodes */
102
{ for(e = s + (1<<p); s < e; ++s)
103
{ node[s] = m; /* the byte to be decoded */
104
size[s] = z-olen; /* # bits to consume */
105
}
106
k += 1;
107
}
108
else /* internal node, find all codes sharing same prefix */
109
{ for(m = k+1; m < ns; ++m)
110
{ if(len >= clen[sort[m]-bits])
111
break;
112
if(s != ((*sort[m] >> (VC_BITSIZE-len)) & msk) )
113
break;
114
}
115
116
/* recurse to process this group */
117
if(bldtrie(trie,clen,bits,&nd,len,sort+k,m-k,lev+1) < 0 )
118
return -1;
119
120
/* reset in case these were relocated in recursion */
121
node = trie->node + root->node;
122
size = trie->size + root->node;
123
124
/* now set data for this internal node */
125
node[s] = nd.node; /* base of next level table */
126
size[s] = nd.size; /* #bits needed to index it */
127
128
k = m;
129
}
130
}
131
132
return 0;
133
}
134
135
/* sort by prefix bits */
136
#if __STD_C
137
static int bitscmp(Void_t* one, Void_t* two, Void_t* disc)
138
#else
139
static int bitscmp(one, two, disc)
140
Void_t* one;
141
Void_t* two;
142
Void_t* disc;
143
#endif
144
{
145
Vcbit_t *o = *((Vcbit_t**)one), *t = *((Vcbit_t**)two);
146
return *o < *t ? -1 : 1;
147
}
148
149
#if __STD_C
150
Vchtrie_t* vchbldtrie(ssize_t nsym, ssize_t* size, Vcbit_t* bits)
151
#else
152
Vchtrie_t* vchbldtrie(nsym, size, bits)
153
ssize_t nsym; /* alphabet size or #symbols */
154
ssize_t* size; /* array of code lengths */
155
Vcbit_t* bits; /* array of code bits */
156
#endif
157
{
158
ssize_t k, ns;
159
Vcbit_t **sort;
160
Vchtrie_t *trie;
161
Node_t root;
162
163
if(!(sort = (Vcbit_t**)malloc(nsym*sizeof(Vcbit_t*))) )
164
return NIL(Vchtrie_t*);
165
166
if(!(trie = (Vchtrie_t*)malloc(sizeof(Vchtrie_t))) )
167
{ free(sort);
168
return NIL(Vchtrie_t*);
169
}
170
trie->next = 0;
171
trie->trsz = 0;
172
trie->node = NIL(short*);
173
trie->size = NIL(short*);
174
175
/* compute list of weighted elements */
176
for(ns = 0, k = 0; k < nsym; ++k)
177
if(size[k] > 0)
178
sort[ns++] = bits+k;
179
vcqsort(sort, ns, sizeof(Vcbit_t*), bitscmp, 0);
180
181
if(bldtrie(trie, size, bits, &root, 0, sort, ns, 0) < 0 )
182
return NIL(Vchtrie_t*);
183
184
free(sort);
185
186
trie->ntop = -root.size;
187
return trie;
188
}
189
190
#if __STD_C
191
Void_t vchdeltrie(Vchtrie_t* trie)
192
#else
193
Void_t vchdeltrie(trie)
194
Vchtrie_t* trie;
195
#endif
196
{
197
if(trie)
198
{ if(trie->node)
199
free(trie->node);
200
free(trie);
201
}
202
}
203
204