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