summaryrefslogtreecommitdiff
path: root/lib/rbcodec/codecs/libayumi/lzh.c
diff options
context:
space:
mode:
Diffstat (limited to 'lib/rbcodec/codecs/libayumi/lzh.c')
-rw-r--r--lib/rbcodec/codecs/libayumi/lzh.c420
1 files changed, 420 insertions, 0 deletions
diff --git a/lib/rbcodec/codecs/libayumi/lzh.c b/lib/rbcodec/codecs/libayumi/lzh.c
new file mode 100644
index 0000000000..786d3bbafe
--- /dev/null
+++ b/lib/rbcodec/codecs/libayumi/lzh.c
@@ -0,0 +1,420 @@
1#include "lzh.h"
2
3#include <string.h>
4
5#define BUFSIZE (1024 * 4)
6
7typedef unsigned char uchar;
8typedef unsigned short ushort;
9typedef unsigned int uint;
10typedef unsigned long ulong;
11
12#ifndef CHAR_BIT
13#define CHAR_BIT 8
14#endif
15
16#ifndef UCHAR_MAX
17#define UCHAR_MAX 255
18#endif
19
20typedef ushort BITBUFTYPE;
21
22#define BITBUFSIZ (CHAR_BIT * sizeof(BITBUFTYPE))
23#define DICBIT 13 /* 12(-lh4-) or 13(-lh5-) */
24#define DICSIZ (1U << DICBIT)
25#define MAXMATCH 256 /* formerly F (not more than UCHAR_MAX + 1) */
26#define THRESHOLD 3 /* choose optimal value */
27#define NC (UCHAR_MAX + MAXMATCH + 2 - THRESHOLD) /* alphabet = {0, 1, 2, ..., NC - 1} */
28#define CBIT 9 /* $\lfloor \log_2 NC \rfloor + 1$ */
29#define CODE_BIT 16 /* codeword length */
30
31#define MAX_HASH_VAL (3 * DICSIZ + (DICSIZ / 512 + 1) * UCHAR_MAX)
32
33#define NP (DICBIT + 1)
34#define NT (CODE_BIT + 3)
35#define PBIT 4 /* smallest integer such that (1U << PBIT) > NP */
36#define TBIT 5 /* smallest integer such that (1U << TBIT) > NT */
37#if NT > NP
38#define NPT NT
39#else
40#define NPT NP
41#endif
42
43uchar *m_pSrc;
44int m_srcSize;
45uchar *m_pDst;
46int m_dstSize;
47
48int DataIn(void *pBuffer, int nBytes);
49int DataOut(void *pOut, int nBytes);
50
51void fillbuf(int n);
52ushort getbits(int n);
53void init_getbits(void);
54int make_table(int nchar, uchar *bitlen, int tablebits, ushort *table);
55void read_pt_len(int nn, int nbit, int i_special);
56void read_c_len(void);
57ushort decode_c(void);
58ushort decode_p(void);
59void huf_decode_start(void);
60void decode_start(void);
61void decode(uint count, uchar buffer[]);
62
63int fillbufsize;
64uchar buf[BUFSIZE];
65uchar outbuf[DICSIZ];
66ushort left[2 * NC - 1];
67ushort right[2 * NC - 1];
68BITBUFTYPE bitbuf;
69uint subbitbuf;
70int bitcount;
71int decode_j; /* remaining bytes to copy */
72uchar c_len[NC];
73uchar pt_len[NPT];
74uint blocksize;
75ushort c_table[4096];
76ushort pt_table[256];
77int with_error;
78
79uint fillbuf_i; /* NOTE: these ones are not initialized at constructor time but inside the fillbuf and decode func. */
80uint decode_i;
81
82/* Additions */
83
84int DataIn(void *pBuffer, int nBytes)
85{
86 const int np = (nBytes <= m_srcSize) ? nBytes : m_srcSize;
87 if (np > 0) {
88 memcpy(pBuffer, m_pSrc, np);
89 m_pSrc += np;
90 m_srcSize -= np;
91 }
92 return np;
93}
94
95int DataOut(void *pBuffer, int nBytes)
96{
97 const int np = (nBytes <= m_dstSize) ? nBytes : m_dstSize;
98 if (np > 0) {
99 memcpy(m_pDst, pBuffer, np);
100 m_pDst += np;
101 m_dstSize -= np;
102 }
103 return np;
104}
105
106/* io.c */
107
108/* Shift bitbuf n bits left, read n bits */
109void fillbuf(int n)
110{
111 bitbuf = (bitbuf << n) & 0xffff;
112 while (n > bitcount) {
113 bitbuf |= subbitbuf << (n -= bitcount);
114 if (fillbufsize == 0) {
115 fillbuf_i = 0;
116 fillbufsize = DataIn(buf, BUFSIZE - 32);
117 }
118 if (fillbufsize > 0)
119 fillbufsize--, subbitbuf = buf[fillbuf_i++];
120 else
121 subbitbuf = 0;
122 bitcount = CHAR_BIT;
123 }
124 bitbuf |= subbitbuf >> (bitcount -= n);
125}
126
127ushort getbits(int n)
128{
129 ushort x;
130 x = bitbuf >> (BITBUFSIZ - n);
131 fillbuf(n);
132 return x;
133}
134
135void init_getbits(void)
136{
137 bitbuf = 0;
138 subbitbuf = 0;
139 bitcount = 0;
140 fillbuf(BITBUFSIZ);
141}
142
143/* maketbl.c */
144
145int make_table(int nchar, uchar * bitlen, int tablebits, ushort * table)
146{
147 ushort count[17], weight[17], start[18], *p;
148 uint jutbits, avail, mask;
149 int i, ch, len, nextcode;
150
151 for (i = 1; i <= 16; i++)
152 count[i] = 0;
153 for (i = 0; i < nchar; i++)
154 count[bitlen[i]]++;
155
156 start[1] = 0;
157 for (i = 1; i <= 16; i++)
158 start[i + 1] = start[i] + (count[i] << (16 - i));
159 if (start[17] != (ushort) (1U << 16))
160 return (1); /* error: bad table */
161
162 jutbits = 16 - tablebits;
163 for (i = 1; i <= tablebits; i++) {
164 start[i] >>= jutbits;
165 weight[i] = 1U << (tablebits - i);
166 }
167 while (i <= 16) {
168 weight[i] = 1U << (16 - i);
169 i++;
170 }
171
172 i = start[tablebits + 1] >> jutbits;
173 if (i != (ushort) (1U << 16)) {
174 int k = 1U << tablebits;
175 while (i != k)
176 table[i++] = 0;
177 }
178
179 avail = nchar;
180 mask = 1U << (15 - tablebits);
181 for (ch = 0; ch < nchar; ch++) {
182 if ((len = bitlen[ch]) == 0)
183 continue;
184 nextcode = start[len] + weight[len];
185 if (len <= tablebits) {
186 for (i = start[len]; i < nextcode; i++)
187 table[i] = ch;
188 } else {
189 uint k = start[len];
190 p = &table[k >> jutbits];
191 i = len - tablebits;
192 while (i != 0) {
193 if (*p == 0) {
194 right[avail] = left[avail] = 0;
195 *p = avail++;
196 }
197 if (k & mask)
198 p = &right[*p];
199 else
200 p = &left[*p];
201 k <<= 1;
202 i--;
203 }
204 *p = ch;
205 }
206 start[len] = nextcode;
207 }
208 return (0);
209}
210
211/* huf.c */
212
213void read_pt_len(int nn, int nbit, int i_special)
214{
215 int i, n;
216 short c;
217 ushort mask;
218
219 n = getbits(nbit);
220 if (n == 0) {
221 c = getbits(nbit);
222 for (i = 0; i < nn; i++)
223 pt_len[i] = 0;
224 for (i = 0; i < 256; i++)
225 pt_table[i] = c;
226 } else {
227 i = 0;
228 while (i < n) {
229 c = bitbuf >> (BITBUFSIZ - 3);
230 if (c == 7) {
231 mask = 1U << (BITBUFSIZ - 1 - 3);
232 while (mask & bitbuf) {
233 mask >>= 1;
234 c++;
235 }
236 }
237 fillbuf((c < 7) ? 3 : c - 3);
238 pt_len[i++] = (unsigned char) (c);
239 if (i == i_special) {
240 c = getbits(2);
241 while (--c >= 0)
242 pt_len[i++] = 0;
243 }
244 }
245 while (i < nn)
246 pt_len[i++] = 0;
247 make_table(nn, pt_len, 8, pt_table);
248 }
249}
250
251void read_c_len(void)
252{
253 short i, c, n;
254 ushort mask;
255
256 n = getbits(CBIT);
257 if (n == 0) {
258 c = getbits(CBIT);
259 for (i = 0; i < NC; i++)
260 c_len[i] = 0;
261 for (i = 0; i < 4096; i++)
262 c_table[i] = c;
263 } else {
264 i = 0;
265 while (i < n) {
266 c = pt_table[bitbuf >> (BITBUFSIZ - 8)];
267 if (c >= NT) {
268 mask = 1U << (BITBUFSIZ - 1 - 8);
269 do {
270 if (bitbuf & mask)
271 c = right[c];
272 else
273 c = left[c];
274 mask >>= 1;
275 } while (c >= NT);
276 }
277 fillbuf(pt_len[c]);
278 if (c <= 2) {
279 if (c == 0)
280 c = 1;
281 else if (c == 1)
282 c = getbits(4) + 3;
283 else
284 c = getbits(CBIT) + 20;
285 while (--c >= 0)
286 c_len[i++] = 0;
287 } else
288 c_len[i++] = c - 2;
289 }
290 while (i < NC)
291 c_len[i++] = 0;
292 make_table(NC, c_len, 12, c_table);
293 }
294}
295
296ushort decode_c(void)
297{
298 ushort j, mask;
299
300 if (blocksize == 0) {
301 blocksize = getbits(16);
302 read_pt_len(NT, TBIT, 3);
303 read_c_len();
304 read_pt_len(NP, PBIT, -1);
305 }
306 blocksize--;
307 j = c_table[bitbuf >> (BITBUFSIZ - 12)];
308 if (j >= NC) {
309 mask = 1U << (BITBUFSIZ - 1 - 12);
310 do {
311 if (bitbuf & mask)
312 j = right[j];
313 else
314 j = left[j];
315 mask >>= 1;
316 }
317 while (j >= NC);
318 }
319 fillbuf(c_len[j]);
320 return j;
321}
322
323ushort decode_p(void)
324{
325 ushort j, mask;
326
327 j = pt_table[bitbuf >> (BITBUFSIZ - 8)];
328 if (j >= NP) {
329 mask = 1U << (BITBUFSIZ - 1 - 8);
330 do {
331 if (bitbuf & mask)
332 j = right[j];
333 else
334 j = left[j];
335 mask >>= 1;
336 } while (j >= NP);
337 }
338 fillbuf(pt_len[j]);
339 if (j != 0)
340 j = (1U << (j - 1)) + getbits(j - 1);
341 return j;
342}
343
344void huf_decode_start(void)
345{
346 init_getbits();
347 blocksize = 0;
348}
349
350/* decode.c */
351
352void decode_start(void)
353{
354 fillbufsize = 0;
355 huf_decode_start();
356 decode_j = 0;
357}
358
359/*
360 * The calling function must keep the number of bytes to be processed. This
361 * function decodes either 'count' bytes or 'DICSIZ' bytes, whichever is
362 * smaller, into the array 'buffer[]' of size 'DICSIZ' or more. Call
363 * decode_start() once for each new file before calling this function.
364 */
365void decode(uint count, uchar buffer[])
366{
367 uint r, c;
368
369 r = 0;
370 while (--decode_j >= 0) {
371 buffer[r] = buffer[decode_i];
372 decode_i = (decode_i + 1) & (DICSIZ - 1);
373 if (++r == count)
374 return;
375 }
376 for (;;) {
377 c = decode_c();
378 if (c <= UCHAR_MAX) {
379 buffer[r] = c;
380 if (++r == count)
381 return;
382 } else {
383 decode_j = c - (UCHAR_MAX + 1 - THRESHOLD);
384 decode_i = (r - decode_p() - 1) & (DICSIZ - 1);
385 while (--decode_j >= 0) {
386 buffer[r] = buffer[decode_i];
387 decode_i = (decode_i + 1) & (DICSIZ - 1);
388 if (++r == count)
389 return;
390 }
391 }
392 }
393}
394
395int LzUnpack(void *pSrc, int srcSize, void *pDst, int dstSize)
396{
397 with_error = 0;
398
399 m_pSrc = (uchar *) pSrc;
400 m_srcSize = srcSize;
401 m_pDst = (uchar *) pDst;
402 m_dstSize = dstSize;
403
404 decode_start();
405
406 unsigned int origsize = dstSize;
407 while (origsize != 0) {
408 int n = (uint) ((origsize > DICSIZ) ? DICSIZ : origsize);
409 decode(n, outbuf);
410 if (with_error)
411 break;
412
413 DataOut(outbuf, n);
414 origsize -= n;
415 if (with_error)
416 break;
417 }
418
419 return (with_error);
420}