1
2 /*
3 * xDMS v1.3 - Portable DMS archive unpacker - Public Domain
4 * Written by Andre Rodrigues de la Rocha <adlroc@usa.net>
5 *
6 * Makes decoding table for Heavy LZH decompression
7 * From UNIX LHA made by Masaru Oki
8 *
9 */
10
11
12 #include "cdata.h"
13 #include "maketbl.h"
14
15
16 static SHORT c;
17 static USHORT n, tblsiz, len, depth, maxdepth, avail;
18 static USHORT codeword, bit, *tbl, TabErr;
19 static UCHAR *blen;
20
21
22 static USHORT mktbl(void);
23
24
25
dms_make_table(USHORT nchar,UCHAR bitlen[],USHORT tablebits,USHORT table[])26 USHORT dms_make_table(USHORT nchar, UCHAR bitlen[],USHORT tablebits, USHORT table[]){
27 n = avail = nchar;
28 blen = bitlen;
29 tbl = table;
30 tblsiz = (USHORT) (1U << tablebits);
31 bit = (USHORT) (tblsiz / 2);
32 maxdepth = (USHORT)(tablebits + 1);
33 depth = len = 1;
34 c = -1;
35 codeword = 0;
36 TabErr = 0;
37 mktbl(); /* left subtree */
38 if (TabErr) return TabErr;
39 mktbl(); /* right subtree */
40 if (TabErr) return TabErr;
41 if (codeword != tblsiz) return 5;
42 return 0;
43 }
44
45
46
mktbl(void)47 static USHORT mktbl(void){
48 USHORT i=0;
49
50 if (TabErr) return 0;
51
52 if (len == depth) {
53 while (++c < n)
54 if (blen[c] == len) {
55 i = codeword;
56 codeword += bit;
57 if (codeword > tblsiz) {
58 TabErr=1;
59 return 0;
60 }
61 while (i < codeword) tbl[i++] = (USHORT)c;
62 return (USHORT)c;
63 }
64 c = -1;
65 len++;
66 bit >>= 1;
67 }
68 depth++;
69 if (depth < maxdepth) {
70 mktbl();
71 mktbl();
72 } else if (depth > 32) {
73 TabErr = 2;
74 return 0;
75 } else {
76 if ((i = avail++) >= 2 * n - 1) {
77 TabErr = 3;
78 return 0;
79 }
80 dms_left[i] = mktbl();
81 dms_right[i] = mktbl();
82 if (codeword >= tblsiz) {
83 TabErr = 4;
84 return 0;
85 }
86 if (depth == maxdepth) tbl[codeword++] = i;
87 }
88 depth--;
89 return i;
90 }
91
92
93