maint: fix port to s390x
[gzip.git] / unlzh.c
blob25c05e34d142c57abc5a3f4f1208f534729f83e6
1 /* unlzh.c -- decompress files in SCO compress -H (LZH) format.
2 * The code in this file is directly derived from the public domain 'ar002'
3 * written by Haruhiko Okumura.
4 */
6 #include <config.h>
7 #include <stdio.h>
9 #include "tailor.h"
10 #include "gzip.h"
11 #include "lzw.h" /* just for consistency checking */
13 /* decode.c */
15 static unsigned decode (unsigned count, uch buffer[]);
16 static void decode_start (void);
18 /* huf.c */
19 static void huf_decode_start (void);
20 static unsigned decode_c (void);
21 static unsigned decode_p (void);
22 static void read_pt_len (int nn, int nbit, int i_special);
23 static void read_c_len (void);
25 /* io.c */
26 static void fillbuf (int n);
27 static unsigned getbits (int n);
28 static void init_getbits (void);
30 /* maketbl.c */
32 static void make_table (int nchar, uch bitlen[], int tablebits, ush table[]);
35 #define DICBIT 13 /* 12(-lh4-) or 13(-lh5-) */
36 #define DICSIZ ((unsigned) 1 << DICBIT)
38 #ifndef CHAR_BIT
39 # define CHAR_BIT 8
40 #endif
42 #ifndef UCHAR_MAX
43 # define UCHAR_MAX 255
44 #endif
46 #define BITBUFSIZ (CHAR_BIT * 2 * sizeof(char))
47 /* Do not use CHAR_BIT * sizeof(bitbuf), does not work on machines
48 * for which short is not on 16 bits (Cray).
51 /* encode.c and decode.c */
53 #define MAXMATCH 256 /* formerly F (not more than UCHAR_MAX + 1) */
54 #define THRESHOLD 3 /* choose optimal value */
56 /* huf.c */
58 #define NC (UCHAR_MAX + MAXMATCH + 2 - THRESHOLD)
59 /* alphabet = {0, 1, 2, ..., NC - 1} */
60 #define CBIT 9 /* $\lfloor \log_2 NC \rfloor + 1$ */
61 #define CODE_BIT 16 /* codeword length */
63 #define NP (DICBIT + 1)
64 #define NT (CODE_BIT + 3)
65 #define PBIT 4 /* smallest integer such that (1U << PBIT) > NP */
66 #define TBIT 5 /* smallest integer such that (1U << TBIT) > NT */
67 #define NPT (1 << TBIT)
69 /* static ush left[2 * NC - 1]; */
70 /* static ush right[2 * NC - 1]; */
71 #define left prev
72 #define right head
73 #if NC > (1<<(BITS-2))
74 error cannot overlay left+right and prev
75 #endif
77 /* static uch c_len[NC]; */
78 #define c_len outbuf
79 #if NC > OUTBUFSIZ
80 error cannot overlay c_len and outbuf
81 #endif
83 static uch pt_len[NPT];
84 static unsigned blocksize;
85 static ush pt_table[256];
87 /* static ush c_table[4096]; */
88 #define c_table d_buf
89 #if (DIST_BUFSIZE-1) < 4095
90 error cannot overlay c_table and d_buf
91 #endif
93 /***********************************************************
94 io.c -- input/output
95 ***********************************************************/
97 static ush bitbuf;
98 static unsigned subbitbuf;
99 static int bitcount;
101 /* Shift bitbuf N bits left, read N bits. */
102 static void
103 fillbuf (int n)
105 bitbuf <<= n;
106 while (n > bitcount) {
107 bitbuf |= subbitbuf << (n -= bitcount);
108 subbitbuf = (unsigned)try_byte();
109 if ((int)subbitbuf == EOF) subbitbuf = 0;
110 bitcount = CHAR_BIT;
112 bitbuf |= subbitbuf >> (bitcount -= n);
115 static unsigned
116 getbits (int n)
118 unsigned x;
120 x = bitbuf >> (BITBUFSIZ - n); fillbuf(n);
121 return x;
124 static void
125 init_getbits ()
127 bitbuf = 0; subbitbuf = 0; bitcount = 0;
128 fillbuf(BITBUFSIZ);
131 /***********************************************************
132 maketbl.c -- make table for decoding
133 ***********************************************************/
135 static void
136 make_table (int nchar, uch bitlen[], int tablebits, ush table[])
138 ush count[17], weight[17], start[18], *p;
139 unsigned i, k, len, ch, jutbits, avail, nextcode, mask;
141 for (i = 1; i <= 16; i++) count[i] = 0;
142 for (i = 0; i < (unsigned)nchar; i++) count[bitlen[i]]++;
144 start[1] = 0;
145 for (i = 1; i <= 16; i++)
146 start[i + 1] = start[i] + (count[i] << (16 - i));
147 if ((start[17] & 0xffff) != 0)
148 gzip_error ("Bad table\n");
150 jutbits = 16 - tablebits;
151 for (i = 1; i <= (unsigned)tablebits; i++) {
152 start[i] >>= jutbits;
153 weight[i] = (unsigned) 1 << (tablebits - i);
155 while (i <= 16) {
156 weight[i] = (unsigned) 1 << (16 - i);
157 i++;
160 i = start[tablebits + 1] >> jutbits;
161 if (i != 0) {
162 k = 1 << tablebits;
163 while (i != k) table[i++] = 0;
166 avail = nchar;
167 mask = (unsigned) 1 << (15 - tablebits);
168 for (ch = 0; ch < (unsigned)nchar; ch++) {
169 if ((len = bitlen[ch]) == 0) continue;
170 nextcode = start[len] + weight[len];
171 if (len <= (unsigned)tablebits) {
172 if ((unsigned) 1 << tablebits < nextcode)
173 gzip_error ("Bad table\n");
174 for (i = start[len]; i < nextcode; i++) table[i] = ch;
175 } else {
176 k = start[len];
177 p = &table[k >> jutbits];
178 i = len - tablebits;
179 while (i != 0) {
180 if (*p == 0) {
181 right[avail] = left[avail] = 0;
182 *p = avail++;
184 if (k & mask) p = &right[*p];
185 else p = &left[*p];
186 k <<= 1; i--;
188 *p = ch;
190 start[len] = nextcode;
194 /***********************************************************
195 huf.c -- static Huffman
196 ***********************************************************/
198 static void
199 read_pt_len (int nn, int nbit, int i_special)
201 int i, c, n;
202 unsigned mask;
204 n = getbits(nbit);
205 if (n == 0) {
206 c = getbits(nbit);
207 for (i = 0; i < nn; i++) pt_len[i] = 0;
208 for (i = 0; i < 256; i++) pt_table[i] = c;
209 } else {
210 i = 0;
211 while (i < n) {
212 c = bitbuf >> (BITBUFSIZ - 3);
213 if (c == 7) {
214 mask = (unsigned) 1 << (BITBUFSIZ - 1 - 3);
215 while (mask & bitbuf) { mask >>= 1; c++; }
216 if (16 < c)
217 gzip_error ("Bad table\n");
219 fillbuf((c < 7) ? 3 : c - 3);
220 pt_len[i++] = c;
221 if (i == i_special) {
222 c = getbits(2);
223 while (--c >= 0) pt_len[i++] = 0;
226 while (i < nn) pt_len[i++] = 0;
227 make_table(nn, pt_len, 8, pt_table);
231 static void
232 read_c_len ()
234 int i, c, n;
235 unsigned mask;
237 n = getbits(CBIT);
238 if (n == 0) {
239 c = getbits(CBIT);
240 for (i = 0; i < NC; i++) c_len[i] = 0;
241 for (i = 0; i < 4096; i++) c_table[i] = c;
242 } else {
243 i = 0;
244 while (i < n) {
245 c = pt_table[bitbuf >> (BITBUFSIZ - 8)];
246 if (c >= NT) {
247 mask = (unsigned) 1 << (BITBUFSIZ - 1 - 8);
248 do {
249 if (bitbuf & mask) c = right[c];
250 else c = left [c];
251 mask >>= 1;
252 } while (c >= NT);
254 fillbuf((int) pt_len[c]);
255 if (c <= 2) {
256 if (c == 0) c = 1;
257 else if (c == 1) c = getbits(4) + 3;
258 else c = getbits(CBIT) + 20;
259 while (--c >= 0) c_len[i++] = 0;
260 } else c_len[i++] = c - 2;
262 while (i < NC) c_len[i++] = 0;
263 make_table(NC, c_len, 12, c_table);
267 static unsigned
268 decode_c ()
270 unsigned j, mask;
272 if (blocksize == 0) {
273 blocksize = getbits(16);
274 if (blocksize == 0) {
275 return NC; /* end of file */
277 read_pt_len(NT, TBIT, 3);
278 read_c_len();
279 read_pt_len(NP, PBIT, -1);
281 blocksize--;
282 j = c_table[bitbuf >> (BITBUFSIZ - 12)];
283 if (j >= NC) {
284 mask = (unsigned) 1 << (BITBUFSIZ - 1 - 12);
285 do {
286 if (bitbuf & mask) j = right[j];
287 else j = left [j];
288 mask >>= 1;
289 } while (j >= NC);
291 fillbuf((int) c_len[j]);
292 return j;
295 static unsigned
296 decode_p ()
298 unsigned j, mask;
300 j = pt_table[bitbuf >> (BITBUFSIZ - 8)];
301 if (j >= NP) {
302 mask = (unsigned) 1 << (BITBUFSIZ - 1 - 8);
303 do {
304 if (bitbuf & mask) j = right[j];
305 else j = left [j];
306 mask >>= 1;
307 } while (j >= NP);
309 fillbuf((int) pt_len[j]);
310 if (j != 0) j = ((unsigned) 1 << (j - 1)) + getbits((int) (j - 1));
311 return j;
314 static void
315 huf_decode_start ()
317 init_getbits(); blocksize = 0;
320 /***********************************************************
321 decode.c
322 ***********************************************************/
324 static int j; /* remaining bytes to copy */
325 static int done; /* set at end of input */
327 static void
328 decode_start ()
330 huf_decode_start();
331 j = 0;
332 done = 0;
335 /* Decode the input and return the number of decoded bytes put in buffer
337 static unsigned
338 decode (unsigned count, uch buffer[])
339 /* The calling function must keep the number of
340 bytes to be processed. This function decodes
341 either 'count' bytes or 'DICSIZ' bytes, whichever
342 is smaller, into the array 'buffer[]' of size
343 'DICSIZ' or more.
344 Call decode_start() once for each new file
345 before calling this function.
348 static unsigned i;
349 unsigned r, c;
351 r = 0;
352 while (--j >= 0) {
353 buffer[r] = buffer[i];
354 i = (i + 1) & (DICSIZ - 1);
355 if (++r == count) return r;
357 for ( ; ; ) {
358 c = decode_c();
359 if (c == NC) {
360 done = 1;
361 return r;
363 if (c <= UCHAR_MAX) {
364 buffer[r] = c;
365 if (++r == count) return r;
366 } else {
367 j = c - (UCHAR_MAX + 1 - THRESHOLD);
368 i = (r - decode_p() - 1) & (DICSIZ - 1);
369 while (--j >= 0) {
370 buffer[r] = buffer[i];
371 i = (i + 1) & (DICSIZ - 1);
372 if (++r == count) return r;
379 /* ===========================================================================
380 * Unlzh in to out. Return OK or ERROR.
383 unlzh (int in, int out)
385 unsigned n;
386 ifd = in;
387 ofd = out;
389 decode_start();
390 while (!done) {
391 n = decode((unsigned) DICSIZ, window);
392 if (n > 0)
393 write_buf (out, window, n);
395 return OK;