Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
att
GitHub Repository: att/ast
Path: blob/master/src/lib/libvcodex/Vchuff/vchcode.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
/* Read/write the code lengths of a Huffman code.
23
**
24
** Written by Kiem-Phong Vo
25
*/
26
27
#if __STD_C
28
static ssize_t rlcode(ssize_t nsym, ssize_t* clen, ssize_t cmax, Vcchar_t* rle, ssize_t rlsz, int encode)
29
#else
30
static ssize_t rlcode(nsym, clen, cmax, rle, rlsz, encode)
31
ssize_t nsym; /* alphabet size */
32
ssize_t* clen; /* code lengths to be encoded */
33
ssize_t cmax; /* max size of any code */
34
Vcchar_t* rle; /* buffer to store rle sequence */
35
ssize_t rlsz;
36
int encode;
37
#endif
38
{
39
ssize_t k, n, r, d, esc1, esc2;
40
Vcchar_t *rl = rle, *endr = rle+rlsz;
41
Vcio_t io;
42
43
esc1 = cmax+1; esc2 = cmax+2;
44
if(encode)
45
{ for(k = 0; k < nsym; k = n)
46
{ d = clen[k];
47
for(n = k+1; n < nsym; ++n)
48
if(clen[n] != d)
49
break;
50
if((r = n-k) >= 3)
51
{ vcioinit(&io, rl, 8*sizeof(ssize_t));
52
vcioput2(&io, r-3, esc1, esc2);
53
rl = vcionext(&io);
54
*rl++ = d;
55
}
56
else for(r = k; r < n; ++r)
57
*rl++ = clen[r];
58
}
59
}
60
else
61
{ for(k = 0; k < nsym && rl < endr; )
62
{ if((d = *rl++) == esc1 || d == esc2)
63
{ vcioinit(&io, rl-1, (endr-rl)+1);
64
r = vcioget2(&io, esc1, esc2) + 3;
65
rl = vcionext(&io);
66
for(d = *rl++; k < nsym && r > 0; --r)
67
clen[k++] = d;
68
if(r > 0)
69
return -1;
70
}
71
else if(d <= cmax)
72
clen[k++] = d;
73
else return -1;
74
}
75
76
if(k != nsym || rl != endr)
77
return -1;
78
}
79
80
return rl-rle;
81
}
82
83
#if __STD_C
84
ssize_t vchputcode(ssize_t nsym, ssize_t* clen, ssize_t maxs, Vcchar_t* data, size_t dtsz)
85
#else
86
ssize_t vchputcode(nsym, clen, maxs, data, dtsz)
87
ssize_t nsym; /* alphabet size or #symbols */
88
ssize_t* clen; /* code lengths to be output */
89
ssize_t maxs; /* max length of any code */
90
Vcchar_t* data; /* data buffer for output */
91
size_t dtsz; /* buffer size (need >= 256) */
92
#endif
93
{
94
reg ssize_t n, k, nl, cs;
95
Vcchar_t *len;
96
Vcbit_t b;
97
Vcio_t io;
98
99
nl = 2*nsym;
100
if(!(len = (Vcchar_t*)malloc(nl*sizeof(Vcchar_t*))) )
101
return -1;
102
103
/* # of bits used to output the code table for this coding */
104
cs = maxs+2;
105
cs = cs < 2 ? 1 : cs < 4 ? 2 : cs < 8 ? 3 : cs < 16 ? 4 : cs < 32 ? 5 : 6;
106
107
/* run-length-encode the code table in the alphabet [0...maxs+2] */
108
if((nl = rlcode(nsym, clen, maxs, len, nl, 1)) < 0 )
109
{ free(len);
110
return -1;
111
}
112
113
vcioinit(&io,data,dtsz);
114
vcioputu(&io, nl); /**/DEBUG_PRINT(2,"Runlength=%d\n",nl);
115
116
vciosetb(&io, b, n, VC_ENCODE);
117
for(k = 0; k < nl; ++k)
118
{ if((n + cs) > VC_BITSIZE)
119
vcioflsb(&io, b, n);
120
vcioaddb(&io, b, n, (((Vcbit_t)len[k]) << (VC_BITSIZE-cs)), cs);
121
}
122
vcioendb(&io, b, n, VC_ENCODE);
123
124
free(len);
125
return vciosize(&io);
126
}
127
128
#if __STD_C
129
ssize_t vchgetcode(ssize_t nsym, ssize_t* clen, ssize_t maxs, Vcchar_t* data, size_t dtsz)
130
#else
131
ssize_t vchgetcode(nsym, clen, maxs, data, dtsz)
132
ssize_t nsym; /* alphabet size or #symbols */
133
ssize_t* clen; /* code lengths to be reconstructed */
134
ssize_t maxs; /* max length of any code */
135
Vcchar_t* data; /* data that encodes the code table */
136
size_t dtsz; /* size of above data buffer */
137
#endif
138
{
139
ssize_t i, n, k, nl, cs;
140
Vcchar_t *len;
141
Vcbit_t b;
142
Vcio_t io;
143
144
if(!(len = (Vcchar_t*)malloc(nsym*sizeof(Vcchar_t*))) )
145
return -1;
146
147
/* # of bits used to output the code table for this coding */
148
cs = maxs+2;
149
cs = cs < 2 ? 1 : cs < 4 ? 2 : cs < 8 ? 3 : cs < 16 ? 4 : cs < 32 ? 5 : 6;
150
151
/* The length of the rle sequence should have been coded with vcioputu()
152
** so it could be decoded by simply using vciogetu(). However, an older
153
** and buggy version used vcioputc() and could not handle values >= 256.
154
** The below loop tries to detect and handle those old cases.
155
*/
156
for(i = 0; i < 2; i += 1)
157
{ vcioinit(&io, data, dtsz);
158
if(i == 0) /* try the current coding first */
159
{ if((nl = vciogetu(&io)) > nsym)
160
continue; /* likely old data */
161
}
162
else /* could be the old buggy coding */
163
{ if((nl = vciogetc(&io)) == 0)
164
nl = 256; /* fix a simple wrap-around */
165
}
166
167
vciosetb(&io, b, n, VC_DECODE);
168
for(k = 0; k < nl; ++k) /* read the rle sequence */
169
{ vciofilb(&io, b, n, cs);
170
len[k] = b >> (VC_BITSIZE-cs);
171
vciodelb(&io, b, n, cs);
172
}
173
vcioendb(&io, b, n, VC_DECODE);
174
175
/* now see if clen[] can be reconstructed */
176
if(rlcode(nsym, clen, maxs, len, nl, 0) >= 0)
177
{ free(len);
178
return vciosize(&io);
179
}
180
}
181
182
free(len);
183
return -1;
184
}
185
186