2 * xDMS v1.3 - Portable DMS archive unpacker - Public Domain
3 * Written by Andre Rodrigues de la Rocha <adlroc@usa.net>
5 * Lempel-Ziv-Huffman decompression functions used in Heavy 1 & 2
6 * compression modes. Based on LZH decompression functions from
7 * UNIX LHA made by Masaru Oki
19 UWORD left
[2 * NC
- 1], right
[2 * NC
- 1 + 9];
20 static UBYTE c_len
[NC
], pt_len
[NPT
];
21 static UWORD c_table
[4096], pt_table
[256];
22 static UWORD lastlen
, np
;
25 static UWORD
read_tree_c (struct xdms_data
*xdms
);
26 static UWORD
read_tree_p (struct xdms_data
*xdms
);
27 static inline UWORD
decode_c (struct xdms_data
*xdms
);
28 static inline UWORD
decode_p (struct xdms_data
*xdms
);
30 UWORD
Unpack_HEAVY (struct xdms_data
*xdms
, UBYTE
*in
, UBYTE
*out
, UBYTE flags
, UWORD origsize
) {
31 UWORD heavy_text_loc
= xdms
->heavy_text_loc
;
32 UBYTE
*text
= xdms
->text
;
33 UWORD j
, i
, c
, bitmask
;
36 /* Heavy 1 uses a 4Kb dictionary, Heavy 2 uses 8Kb */
39 xdms
->u_heavy
.np
= 15;
42 xdms
->u_heavy
.np
= 14;
49 if (read_tree_c(xdms
)) return 1;
50 if (read_tree_p(xdms
)) return 2;
53 outend
= out
+origsize
;
58 *out
++ = text
[heavy_text_loc
++ & bitmask
] = (UBYTE
)c
;
60 j
= (UWORD
)(c
- OFFSET
);
61 i
= (UWORD
)(heavy_text_loc
- decode_p(xdms
) - 1);
62 while(j
--) *out
++ = text
[heavy_text_loc
++ & bitmask
] = text
[i
++ & bitmask
];
66 xdms
->heavy_text_loc
= heavy_text_loc
;
71 static UWORD
decode_c (struct xdms_data
*xdms
) {
72 const UWORD
* const left
= xdms
->u_heavy
.left
;
73 const UWORD
* const right
= xdms
->u_heavy
.right
;
74 UWORD
* const c_table
= xdms
->u_heavy
.c_table
;
75 UBYTE
* const c_len
= xdms
->u_heavy
.c_len
;
78 j
= c_table
[GETBITS(12)];
86 if (i
& m
) j
= right
[j
];
90 DROPBITS(c_len
[j
] - 12);
95 static UWORD
decode_p (struct xdms_data
*xdms
) {
96 const UWORD
* const left
= xdms
->u_heavy
.left
;
97 const UWORD
* const right
= xdms
->u_heavy
.right
;
98 UWORD
* const pt_table
= xdms
->u_heavy
.pt_table
;
99 UBYTE
* const pt_len
= xdms
->u_heavy
.pt_len
;
100 const UWORD np
= xdms
->u_heavy
.np
;
103 j
= pt_table
[GETBITS(8)];
111 if (i
& m
) j
= right
[j
];
115 DROPBITS(pt_len
[j
] - 8);
120 j
= (UWORD
)(GETBITS(i
=(UWORD
)(j
-1)) | (1U << (j
-1)));
123 xdms
->u_heavy
.lastlen
=j
;
126 return xdms
->u_heavy
.lastlen
;
130 static UWORD
read_tree_c (struct xdms_data
*xdms
) {
131 UWORD
* const c_table
= xdms
->u_heavy
.c_table
;
132 UBYTE
* const c_len
= xdms
->u_heavy
.c_len
;
138 for (i
=0; i
<n
; i
++) {
139 c_len
[i
] = (UBYTE
)GETBITS(5);
142 for (i
=n
; i
<510; i
++) c_len
[i
] = 0;
143 if (make_table(xdms
,510,c_len
,12,c_table
)) return 1;
147 for (i
=0; i
<510; i
++) c_len
[i
] = 0;
148 for (i
=0; i
<4096; i
++) c_table
[i
] = n
;
153 static UWORD
read_tree_p (struct xdms_data
*xdms
) {
154 UWORD
* const pt_table
= xdms
->u_heavy
.pt_table
;
155 UBYTE
* const pt_len
= xdms
->u_heavy
.pt_len
;
156 const UWORD np
= xdms
->u_heavy
.np
;
162 for (i
=0; i
<n
; i
++) {
163 pt_len
[i
] = (UBYTE
)GETBITS(4);
166 for (i
=n
; i
<np
; i
++) pt_len
[i
] = 0;
167 if (make_table(xdms
,np
,pt_len
,8,pt_table
)) return 1;
171 for (i
=0; i
<np
; i
++) pt_len
[i
] = 0;
172 for (i
=0; i
<256; i
++) pt_table
[i
] = n
;