blob: 1b2d587d606f8a5ba38f957d24af5b79240b7902 [file] [log] [blame]
Glenn L McGrath7fd92942001-04-11 03:11:33 +00001/* vi: set sw=4 ts=4: */
2/*
3 * gunzip implementation for busybox
4 *
5 * Based on GNU gzip v1.2.4 Copyright (C) 1992-1993 Jean-loup Gailly.
6 *
7 * Originally adjusted for busybox by Sven Rudolph <sr1@inf.tu-dresden.de>
8 * based on gzip sources
9 *
Eric Andersendb930942001-12-06 08:20:14 +000010 * Adjusted further by Erik Andersen <andersee@debian.org> to support
11 * files as well as stdin/stdout, and to generally behave itself wrt
Glenn L McGrath7fd92942001-04-11 03:11:33 +000012 * command line handling.
13 *
14 * General cleanup to better adhere to the style guide and make use of standard
15 * busybox functions by Glenn McGrath <bug1@optushome.com.au>
16 *
Glenn L McGrath83bf47c2002-11-20 22:00:31 +000017 * read_gz interface + associated hacking by Laurence Anderson
18 *
Glenn L McGrath7fd92942001-04-11 03:11:33 +000019 * This program is free software; you can redistribute it and/or modify
20 * it under the terms of the GNU General Public License as published by
21 * the Free Software Foundation; either version 2 of the License, or
22 * (at your option) any later version.
23 *
24 * This program is distributed in the hope that it will be useful,
25 * but WITHOUT ANY WARRANTY; without even the implied warranty of
26 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
27 * General Public License for more details.
28 *
29 * You should have received a copy of the GNU General Public License
30 * along with this program; if not, write to the Free Software
31 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
32 *
33 *
34 * gzip (GNU zip) -- compress files with zip algorithm and 'compress' interface
35 * Copyright (C) 1992-1993 Jean-loup Gailly
36 * The unzip code was written and put in the public domain by Mark Adler.
37 * Portions of the lzw code are derived from the public domain 'compress'
38 * written by Spencer Thomas, Joe Orost, James Woods, Jim McKie, Steve Davies,
39 * Ken Turkowski, Dave Mack and Peter Jannesen.
40 *
41 * See the license_msg below and the file COPYING for the software license.
42 * See the file algorithm.doc for the compression algorithms and file formats.
43 */
44
45#if 0
46static char *license_msg[] = {
47 " Copyright (C) 1992-1993 Jean-loup Gailly",
48 " This program is free software; you can redistribute it and/or modify",
49 " it under the terms of the GNU General Public License as published by",
50 " the Free Software Foundation; either version 2, or (at your option)",
51 " any later version.",
52 "",
53 " This program is distributed in the hope that it will be useful,",
54 " but WITHOUT ANY WARRANTY; without even the implied warranty of",
55 " MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the",
56 " GNU General Public License for more details.",
57 "",
58 " You should have received a copy of the GNU General Public License",
59 " along with this program; if not, write to the Free Software",
60 " Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.",
61 0
62};
63#endif
64
65#include <sys/types.h>
66#include <sys/wait.h>
67#include <signal.h>
68#include <stdlib.h>
Manuel Novoa III a2949aa2001-06-29 18:59:32 +000069#include <string.h>
Glenn L McGrath7ca04f32002-09-25 02:47:48 +000070#include <unistd.h>
71#include <fcntl.h>
Robert Grieblf6495eb2002-05-15 22:13:47 +000072#include "config.h"
Glenn L McGrath7ca04f32002-09-25 02:47:48 +000073#include "busybox.h"
74#include "unarchive.h"
Glenn L McGrath7fd92942001-04-11 03:11:33 +000075
76typedef struct huft_s {
Glenn L McGrath9fef17d2002-08-22 18:41:20 +000077 unsigned char e; /* number of extra bits or operation */
78 unsigned char b; /* number of bits in this code or subcode */
Glenn L McGrath7fd92942001-04-11 03:11:33 +000079 union {
Glenn L McGrath9fef17d2002-08-22 18:41:20 +000080 unsigned short n; /* literal, length base, or distance base */
Glenn L McGrath7fd92942001-04-11 03:11:33 +000081 struct huft_s *t; /* pointer to next level of table */
82 } v;
83} huft_t;
84
Glenn L McGrath7ca04f32002-09-25 02:47:48 +000085static int gunzip_src_fd;
Glenn L McGrath7ca04f32002-09-25 02:47:48 +000086unsigned int gunzip_bytes_out; /* number of output bytes */
87static unsigned int gunzip_outbuf_count; /* bytes in output buffer */
88
89/* This is used to sanify any unused bits from the bitbuffer
90 * so they arent skipped when reading trailers (trailing headers) */
Glenn L McGratheda4f532002-11-24 06:01:20 +000091//unsigned char gunzip_in_buffer_count;
92//unsigned char *gunzip_in_buffer;
Glenn L McGrath7ca04f32002-09-25 02:47:48 +000093
94/* gunzip_window size--must be a power of two, and
95 * at least 32K for zip's deflate method */
96static const int gunzip_wsize = 0x8000;
97
98static unsigned char *gunzip_window;
99static unsigned int *gunzip_crc_table;
100unsigned int gunzip_crc;
101
102/* If BMAX needs to be larger than 16, then h and x[] should be ulg. */
103#define BMAX 16 /* maximum bit length of any code (16 for explode) */
104#define N_MAX 288 /* maximum number of codes in any set */
105
Glenn L McGrath7ca04f32002-09-25 02:47:48 +0000106static unsigned int gunzip_bb; /* bit buffer */
107static unsigned char gunzip_bk; /* bits in bit buffer */
108
Eric Andersen044228d2001-07-17 01:12:36 +0000109static const unsigned short mask_bits[] = {
Glenn L McGrath7ca04f32002-09-25 02:47:48 +0000110 0x0000, 0x0001, 0x0003, 0x0007, 0x000f, 0x001f, 0x003f, 0x007f, 0x00ff,
Glenn L McGrath7fd92942001-04-11 03:11:33 +0000111 0x01ff, 0x03ff, 0x07ff, 0x0fff, 0x1fff, 0x3fff, 0x7fff, 0xffff
112};
113
Glenn L McGrath7ca04f32002-09-25 02:47:48 +0000114/* Copy lengths for literal codes 257..285 */
115static const unsigned short cplens[] = {
116 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31, 35, 43, 51, 59,
117 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0
118};
119
120/* note: see note #13 above about the 258 in this list. */
121/* Extra bits for literal codes 257..285 */
122static const unsigned char cplext[] = {
123 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 5,
124 5, 5, 5, 0, 99, 99
125}; /* 99==invalid */
126
127/* Copy offsets for distance codes 0..29 */
128static const unsigned short cpdist[] = {
129 1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193, 257, 385, 513,
130 769, 1025, 1537, 2049, 3073, 4097, 6145, 8193, 12289, 16385, 24577
131};
132
133/* Extra bits for distance codes */
134static const unsigned char cpdext[] = {
135 0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10,
136 11, 11, 12, 12, 13, 13
137};
138
139/* Tables for deflate from PKZIP's appnote.txt. */
140/* Order of the bit length code lengths */
141static const unsigned char border[] = {
142 16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15
143};
144
Glenn L McGratheda4f532002-11-24 06:01:20 +0000145#define BYTEBUFFER_MAX 0x8000
146unsigned char *bytebuffer = NULL;
147unsigned int bytebuffer_offset = 0;
148unsigned int bytebuffer_size = 0;
149
Glenn L McGrathf3faf412002-12-01 21:52:40 +0000150static void fill_bytebuffer(void)
Glenn L McGratheda4f532002-11-24 06:01:20 +0000151{
152 if (bytebuffer_offset >= bytebuffer_size) {
153 /* Leave the first 4 bytes empty so we can always unwind the bitbuffer
154 * to the front of the bytebuffer, leave 4 bytes free at end of tail
155 * so we can easily top up buffer in check_trailer_gzip() */
156 bytebuffer_size = 4 + xread(gunzip_src_fd, &bytebuffer[4], BYTEBUFFER_MAX - 8);
157 bytebuffer_offset = 4;
158 }
159}
160
Glenn L McGrath7ca04f32002-09-25 02:47:48 +0000161static unsigned int fill_bitbuffer(unsigned int bitbuffer, unsigned int *current, const unsigned int required)
162{
163 while (*current < required) {
Glenn L McGratheda4f532002-11-24 06:01:20 +0000164 fill_bytebuffer();
165 bitbuffer |= ((unsigned int) bytebuffer[bytebuffer_offset]) << *current;
166 bytebuffer_offset++;
Glenn L McGrath7ca04f32002-09-25 02:47:48 +0000167 *current += 8;
168 }
Glenn L McGrath7ca04f32002-09-25 02:47:48 +0000169 return(bitbuffer);
170}
Glenn L McGrath9fef17d2002-08-22 18:41:20 +0000171
Glenn L McGrath7ca04f32002-09-25 02:47:48 +0000172static void make_gunzip_crc_table(void)
Glenn L McGrath7fd92942001-04-11 03:11:33 +0000173{
Glenn L McGrath7ca04f32002-09-25 02:47:48 +0000174 const unsigned int poly = 0xedb88320; /* polynomial exclusive-or pattern */
Glenn L McGrath9fef17d2002-08-22 18:41:20 +0000175 unsigned short i; /* counter for all possible eight bit values */
Glenn L McGrath7fd92942001-04-11 03:11:33 +0000176
Eric Andersen89de1e72002-03-20 13:30:40 +0000177 /* initial shift register value */
Glenn L McGrath7ca04f32002-09-25 02:47:48 +0000178 gunzip_crc = 0xffffffffL;
179 gunzip_crc_table = (unsigned int *) malloc(256 * sizeof(unsigned int));
Glenn L McGrath7fd92942001-04-11 03:11:33 +0000180
Glenn L McGrath7fd92942001-04-11 03:11:33 +0000181 /* Compute and print table of CRC's, five per line */
182 for (i = 0; i < 256; i++) {
Glenn L McGrath7ca04f32002-09-25 02:47:48 +0000183 unsigned int table_entry; /* crc shift register */
184 unsigned char k; /* byte being shifted into crc apparatus */
Glenn L McGrathef03dbc2001-12-05 13:08:03 +0000185
Glenn L McGrath7fd92942001-04-11 03:11:33 +0000186 table_entry = i;
Glenn L McGrath9fef17d2002-08-22 18:41:20 +0000187 /* The idea to initialize the register with the byte instead of
188 * zero was stolen from Haruhiko Okumura's ar002
189 */
Glenn L McGrath7fd92942001-04-11 03:11:33 +0000190 for (k = 8; k; k--) {
Glenn L McGrath7ca04f32002-09-25 02:47:48 +0000191 if (table_entry & 1) {
192 table_entry = (table_entry >> 1) ^ poly;
193 } else {
194 table_entry >>= 1;
Glenn L McGrath7fd92942001-04-11 03:11:33 +0000195 }
Glenn L McGrath7fd92942001-04-11 03:11:33 +0000196 }
Glenn L McGrath7ca04f32002-09-25 02:47:48 +0000197 gunzip_crc_table[i] = table_entry;
Glenn L McGrath7fd92942001-04-11 03:11:33 +0000198 }
Glenn L McGrath7fd92942001-04-11 03:11:33 +0000199}
200
201/*
202 * Free the malloc'ed tables built by huft_build(), which makes a linked
203 * list of the tables it made, with the links in a dummy first entry of
204 * each table.
205 * t: table to free
206 */
Glenn L McGrath9fef17d2002-08-22 18:41:20 +0000207static int huft_free(huft_t * t)
Glenn L McGrath7fd92942001-04-11 03:11:33 +0000208{
Glenn L McGrath7ca04f32002-09-25 02:47:48 +0000209 huft_t *p;
210 huft_t *q;
Glenn L McGrath7fd92942001-04-11 03:11:33 +0000211
212 /* Go through linked list, freeing from the malloced (t[-1]) address. */
213 p = t;
214 while (p != (huft_t *) NULL) {
215 q = (--p)->v.t;
216 free((char *) p);
217 p = q;
218 }
219 return 0;
220}
221
222/* Given a list of code lengths and a maximum table size, make a set of
223 * tables to decode that set of codes. Return zero on success, one if
224 * the given code set is incomplete (the tables are still built in this
225 * case), two if the input is invalid (all zero length codes or an
226 * oversubscribed set of lengths), and three if not enough memory.
227 *
228 * b: code lengths in bits (all assumed <= BMAX)
229 * n: number of codes (assumed <= N_MAX)
230 * s: number of simple-valued codes (0..s-1)
231 * d: list of base values for non-simple codes
232 * e: list of extra bits for non-simple codes
233 * t: result: starting table
234 * m: maximum lookup bits, returns actual
235 */
Glenn L McGrath9fef17d2002-08-22 18:41:20 +0000236static int huft_build(unsigned int *b, const unsigned int n,
237 const unsigned int s, const unsigned short *d,
Glenn L McGrath7ca04f32002-09-25 02:47:48 +0000238 const unsigned char *e, huft_t ** t, int *m)
Glenn L McGrath7fd92942001-04-11 03:11:33 +0000239{
Glenn L McGrath9fef17d2002-08-22 18:41:20 +0000240 unsigned a; /* counter for codes of length k */
Glenn L McGrath7fd92942001-04-11 03:11:33 +0000241 unsigned c[BMAX + 1]; /* bit length count table */
Glenn L McGrath9fef17d2002-08-22 18:41:20 +0000242 unsigned f; /* i repeats in table every f entries */
243 int g; /* maximum code length */
244 int h; /* table level */
Glenn L McGrath7fd92942001-04-11 03:11:33 +0000245 register unsigned i; /* counter, current code */
246 register unsigned j; /* counter */
247 register int k; /* number of bits in current code */
Glenn L McGrath9fef17d2002-08-22 18:41:20 +0000248 int l; /* bits per table (returned in m) */
249 register unsigned *p; /* pointer into c[], b[], or v[] */
Glenn L McGrath7fd92942001-04-11 03:11:33 +0000250 register huft_t *q; /* points to current table */
Glenn L McGrath9fef17d2002-08-22 18:41:20 +0000251 huft_t r; /* table entry for structure assignment */
Glenn L McGrath7fd92942001-04-11 03:11:33 +0000252 huft_t *u[BMAX]; /* table stack */
253 unsigned v[N_MAX]; /* values in order of bit length */
254 register int w; /* bits before this table == (l * h) */
255 unsigned x[BMAX + 1]; /* bit offsets, then code stack */
256 unsigned *xp; /* pointer into x */
Glenn L McGrath9fef17d2002-08-22 18:41:20 +0000257 int y; /* number of dummy codes added */
258 unsigned z; /* number of entries in current table */
Glenn L McGrath7fd92942001-04-11 03:11:33 +0000259
260 /* Generate counts for each bit length */
Glenn L McGrath9fef17d2002-08-22 18:41:20 +0000261 memset((void *) (c), 0, sizeof(c));
Glenn L McGrath7fd92942001-04-11 03:11:33 +0000262 p = b;
263 i = n;
264 do {
Glenn L McGrath9fef17d2002-08-22 18:41:20 +0000265 c[*p]++; /* assume all entries <= BMAX */
266 p++; /* Can't combine with above line (Solaris bug) */
Glenn L McGrath7fd92942001-04-11 03:11:33 +0000267 } while (--i);
268 if (c[0] == n) { /* null input--all zero length codes */
269 *t = (huft_t *) NULL;
270 *m = 0;
271 return 0;
272 }
273
274 /* Find minimum and maximum length, bound *m by those */
275 l = *m;
Glenn L McGrath7ca04f32002-09-25 02:47:48 +0000276 for (j = 1; j <= BMAX; j++) {
277 if (c[j]) {
Glenn L McGrath7fd92942001-04-11 03:11:33 +0000278 break;
Glenn L McGrath7ca04f32002-09-25 02:47:48 +0000279 }
280 }
Glenn L McGrath7fd92942001-04-11 03:11:33 +0000281 k = j; /* minimum code length */
Glenn L McGrath7ca04f32002-09-25 02:47:48 +0000282 if ((unsigned) l < j) {
Glenn L McGrath7fd92942001-04-11 03:11:33 +0000283 l = j;
Glenn L McGrath7ca04f32002-09-25 02:47:48 +0000284 }
285 for (i = BMAX; i; i--) {
286 if (c[i]) {
Glenn L McGrath7fd92942001-04-11 03:11:33 +0000287 break;
Glenn L McGrath7ca04f32002-09-25 02:47:48 +0000288 }
289 }
Glenn L McGrath7fd92942001-04-11 03:11:33 +0000290 g = i; /* maximum code length */
Glenn L McGrath7ca04f32002-09-25 02:47:48 +0000291 if ((unsigned) l > i) {
Glenn L McGrath7fd92942001-04-11 03:11:33 +0000292 l = i;
Glenn L McGrath7ca04f32002-09-25 02:47:48 +0000293 }
Glenn L McGrath7fd92942001-04-11 03:11:33 +0000294 *m = l;
295
296 /* Adjust last length count to fill out codes, if needed */
Glenn L McGrath7ca04f32002-09-25 02:47:48 +0000297 for (y = 1 << j; j < i; j++, y <<= 1) {
298 if ((y -= c[j]) < 0) {
Glenn L McGrath7fd92942001-04-11 03:11:33 +0000299 return 2; /* bad input: more codes than bits */
Glenn L McGrath7ca04f32002-09-25 02:47:48 +0000300 }
301 }
302 if ((y -= c[i]) < 0) {
Glenn L McGrath7fd92942001-04-11 03:11:33 +0000303 return 2;
Glenn L McGrath7ca04f32002-09-25 02:47:48 +0000304 }
Glenn L McGrath7fd92942001-04-11 03:11:33 +0000305 c[i] += y;
306
307 /* Generate starting offsets into the value table for each length */
308 x[1] = j = 0;
309 p = c + 1;
310 xp = x + 2;
Glenn L McGrath9fef17d2002-08-22 18:41:20 +0000311 while (--i) { /* note that i == g from above */
Glenn L McGrath7fd92942001-04-11 03:11:33 +0000312 *xp++ = (j += *p++);
313 }
314
315 /* Make a table of values in order of bit lengths */
316 p = b;
317 i = 0;
318 do {
Glenn L McGrath7ca04f32002-09-25 02:47:48 +0000319 if ((j = *p++) != 0) {
Glenn L McGrath7fd92942001-04-11 03:11:33 +0000320 v[x[j]++] = i;
Glenn L McGrath7ca04f32002-09-25 02:47:48 +0000321 }
Glenn L McGrath7fd92942001-04-11 03:11:33 +0000322 } while (++i < n);
323
324 /* Generate the Huffman codes and for each, make the table entries */
Glenn L McGrath9fef17d2002-08-22 18:41:20 +0000325 x[0] = i = 0; /* first Huffman code is zero */
Glenn L McGrath7fd92942001-04-11 03:11:33 +0000326 p = v; /* grab values in bit order */
327 h = -1; /* no tables yet--level -1 */
328 w = -l; /* bits decoded == (l * h) */
329 u[0] = (huft_t *) NULL; /* just to keep compilers happy */
330 q = (huft_t *) NULL; /* ditto */
331 z = 0; /* ditto */
332
333 /* go through the bit lengths (k already is bits in shortest code) */
334 for (; k <= g; k++) {
335 a = c[k];
336 while (a--) {
337 /* here i is the Huffman code of length k bits for value *p */
338 /* make tables up to required level */
339 while (k > w + l) {
340 h++;
Glenn L McGrath9fef17d2002-08-22 18:41:20 +0000341 w += l; /* previous table always l bits */
Glenn L McGrath7fd92942001-04-11 03:11:33 +0000342
343 /* compute minimum size table less than or equal to l bits */
344 z = (z = g - w) > (unsigned) l ? l : z; /* upper limit on table size */
345 if ((f = 1 << (j = k - w)) > a + 1) { /* try a k-w bit table *//* too few codes for k-w bit table */
346 f -= a + 1; /* deduct codes from patterns left */
347 xp = c + k;
348 while (++j < z) { /* try smaller tables up to z bits */
Glenn L McGrath7ca04f32002-09-25 02:47:48 +0000349 if ((f <<= 1) <= *++xp) {
Glenn L McGrath7fd92942001-04-11 03:11:33 +0000350 break; /* enough codes to use up j bits */
Glenn L McGrath7ca04f32002-09-25 02:47:48 +0000351 }
Glenn L McGrath7fd92942001-04-11 03:11:33 +0000352 f -= *xp; /* else deduct codes from patterns */
353 }
354 }
Glenn L McGrath9fef17d2002-08-22 18:41:20 +0000355 z = 1 << j; /* table entries for j-bit table */
Glenn L McGrath7fd92942001-04-11 03:11:33 +0000356
357 /* allocate and link in new table */
Glenn L McGrath249f39a2001-12-05 16:01:02 +0000358 q = (huft_t *) xmalloc((z + 1) * sizeof(huft_t));
359
Glenn L McGrath9fef17d2002-08-22 18:41:20 +0000360 *t = q + 1; /* link to list for huft_free() */
Glenn L McGrath7fd92942001-04-11 03:11:33 +0000361 *(t = &(q->v.t)) = NULL;
Glenn L McGrath9fef17d2002-08-22 18:41:20 +0000362 u[h] = ++q; /* table starts after link */
Glenn L McGrath7fd92942001-04-11 03:11:33 +0000363
364 /* connect to last table, if there is one */
365 if (h) {
366 x[h] = i; /* save pattern for backing up */
367 r.b = (unsigned char) l; /* bits to dump before this table */
368 r.e = (unsigned char) (16 + j); /* bits in this table */
369 r.v.t = q; /* pointer to this table */
370 j = i >> (w - l); /* (get around Turbo C bug) */
371 u[h - 1][j] = r; /* connect to last table */
372 }
373 }
374
375 /* set up table entry in r */
376 r.b = (unsigned char) (k - w);
Glenn L McGrath7ca04f32002-09-25 02:47:48 +0000377 if (p >= v + n) {
Glenn L McGrath9fef17d2002-08-22 18:41:20 +0000378 r.e = 99; /* out of values--invalid code */
Glenn L McGrath7ca04f32002-09-25 02:47:48 +0000379 } else if (*p < s) {
Glenn L McGrath7fd92942001-04-11 03:11:33 +0000380 r.e = (unsigned char) (*p < 256 ? 16 : 15); /* 256 is end-of-block code */
381 r.v.n = (unsigned short) (*p); /* simple code is just the value */
Glenn L McGrath9fef17d2002-08-22 18:41:20 +0000382 p++; /* one compiler does not like *p++ */
Glenn L McGrath7fd92942001-04-11 03:11:33 +0000383 } else {
384 r.e = (unsigned char) e[*p - s]; /* non-simple--look up in lists */
385 r.v.n = d[*p++ - s];
386 }
387
388 /* fill code-like entries with r */
389 f = 1 << (k - w);
Glenn L McGrath7ca04f32002-09-25 02:47:48 +0000390 for (j = i >> w; j < z; j += f) {
Glenn L McGrath7fd92942001-04-11 03:11:33 +0000391 q[j] = r;
Glenn L McGrath7ca04f32002-09-25 02:47:48 +0000392 }
Glenn L McGrath7fd92942001-04-11 03:11:33 +0000393
394 /* backwards increment the k-bit code i */
Glenn L McGrath7ca04f32002-09-25 02:47:48 +0000395 for (j = 1 << (k - 1); i & j; j >>= 1) {
Glenn L McGrath7fd92942001-04-11 03:11:33 +0000396 i ^= j;
Glenn L McGrath7ca04f32002-09-25 02:47:48 +0000397 }
Glenn L McGrath7fd92942001-04-11 03:11:33 +0000398 i ^= j;
399
400 /* backup over finished tables */
401 while ((i & ((1 << w) - 1)) != x[h]) {
Glenn L McGrath9fef17d2002-08-22 18:41:20 +0000402 h--; /* don't need to update q */
Glenn L McGrath7fd92942001-04-11 03:11:33 +0000403 w -= l;
404 }
405 }
406 }
407 /* Return true (1) if we were given an incomplete table */
408 return y != 0 && g != 1;
409}
410
411/*
412 * inflate (decompress) the codes in a deflated (compressed) block.
413 * Return an error code or zero if it all goes ok.
414 *
415 * tl, td: literal/length and distance decoder tables
416 * bl, bd: number of bits decoded by tl[] and td[]
417 */
Glenn L McGrath0126fda2002-11-20 06:46:46 +0000418static int inflate_codes(huft_t * my_tl, huft_t * my_td, const unsigned int my_bl, const unsigned int my_bd, int setup)
Glenn L McGrath7fd92942001-04-11 03:11:33 +0000419{
Glenn L McGrath0126fda2002-11-20 06:46:46 +0000420 static unsigned int e; /* table entry flag/number of extra bits */
421 static unsigned int n, d; /* length and index for copy */
422 static unsigned int w; /* current gunzip_window position */
423 static huft_t *t; /* pointer to table entry */
424 static unsigned int ml, md; /* masks for bl and bd bits */
425 static unsigned int b; /* bit buffer */
426 static unsigned int k; /* number of bits in bit buffer */
427 static huft_t *tl, *td;
428 static unsigned int bl, bd;
429 static int resumeCopy = 0;
Glenn L McGrath7fd92942001-04-11 03:11:33 +0000430
Glenn L McGrath0126fda2002-11-20 06:46:46 +0000431 if (setup) { // 1st time we are called, copy in variables
432 tl = my_tl;
433 td = my_td;
434 bl = my_bl;
435 bd = my_bd;
436 /* make local copies of globals */
437 b = gunzip_bb; /* initialize bit buffer */
438 k = gunzip_bk;
439 w = gunzip_outbuf_count; /* initialize gunzip_window position */
Glenn L McGrath7fd92942001-04-11 03:11:33 +0000440
Glenn L McGrath0126fda2002-11-20 06:46:46 +0000441 /* inflate the coded data */
442 ml = mask_bits[bl]; /* precompute masks for speed */
443 md = mask_bits[bd];
444 return 0; // Don't actually do anything the first time
445 }
446
447 if (resumeCopy) goto do_copy;
448
Glenn L McGrath7ca04f32002-09-25 02:47:48 +0000449 while (1) { /* do until end of block */
450 b = fill_bitbuffer(b, &k, bl);
Glenn L McGrath7fd92942001-04-11 03:11:33 +0000451 if ((e = (t = tl + ((unsigned) b & ml))->e) > 16)
Glenn L McGrath9fef17d2002-08-22 18:41:20 +0000452 do {
453 if (e == 99) {
Glenn L McGrath83bf47c2002-11-20 22:00:31 +0000454 error_msg_and_die("inflate_codes error 1");;
Glenn L McGrath9fef17d2002-08-22 18:41:20 +0000455 }
456 b >>= t->b;
457 k -= t->b;
458 e -= 16;
Glenn L McGrath7ca04f32002-09-25 02:47:48 +0000459 b = fill_bitbuffer(b, &k, e);
Glenn L McGrath9fef17d2002-08-22 18:41:20 +0000460 } while ((e =
461 (t = t->v.t + ((unsigned) b & mask_bits[e]))->e) > 16);
Glenn L McGrath7fd92942001-04-11 03:11:33 +0000462 b >>= t->b;
463 k -= t->b;
Glenn L McGrath9fef17d2002-08-22 18:41:20 +0000464 if (e == 16) { /* then it's a literal */
Glenn L McGrath7ca04f32002-09-25 02:47:48 +0000465 gunzip_window[w++] = (unsigned char) t->v.n;
466 if (w == gunzip_wsize) {
467 gunzip_outbuf_count = (w);
Glenn L McGrath0126fda2002-11-20 06:46:46 +0000468 //flush_gunzip_window();
Glenn L McGrath7fd92942001-04-11 03:11:33 +0000469 w = 0;
Glenn L McGrath83bf47c2002-11-20 22:00:31 +0000470 return 1; // We have a block to read
Glenn L McGrath7fd92942001-04-11 03:11:33 +0000471 }
Glenn L McGrath9fef17d2002-08-22 18:41:20 +0000472 } else { /* it's an EOB or a length */
Glenn L McGrath7fd92942001-04-11 03:11:33 +0000473
474 /* exit if end of block */
475 if (e == 15) {
476 break;
477 }
478
479 /* get length of block to copy */
Glenn L McGrath7ca04f32002-09-25 02:47:48 +0000480 b = fill_bitbuffer(b, &k, e);
Glenn L McGrath7fd92942001-04-11 03:11:33 +0000481 n = t->v.n + ((unsigned) b & mask_bits[e]);
482 b >>= e;
483 k -= e;
484
485 /* decode distance of block to copy */
Glenn L McGrath7ca04f32002-09-25 02:47:48 +0000486 b = fill_bitbuffer(b, &k, bd);
Glenn L McGrath7fd92942001-04-11 03:11:33 +0000487 if ((e = (t = td + ((unsigned) b & md))->e) > 16)
488 do {
489 if (e == 99)
Glenn L McGrath83bf47c2002-11-20 22:00:31 +0000490 error_msg_and_die("inflate_codes error 2");;
Glenn L McGrath7fd92942001-04-11 03:11:33 +0000491 b >>= t->b;
492 k -= t->b;
493 e -= 16;
Glenn L McGrath7ca04f32002-09-25 02:47:48 +0000494 b = fill_bitbuffer(b, &k, e);
Glenn L McGrath9fef17d2002-08-22 18:41:20 +0000495 } while ((e =
496 (t =
497 t->v.t + ((unsigned) b & mask_bits[e]))->e) > 16);
Glenn L McGrath7fd92942001-04-11 03:11:33 +0000498 b >>= t->b;
499 k -= t->b;
Glenn L McGrath7ca04f32002-09-25 02:47:48 +0000500 b = fill_bitbuffer(b, &k, e);
Glenn L McGrath7fd92942001-04-11 03:11:33 +0000501 d = w - t->v.n - ((unsigned) b & mask_bits[e]);
502 b >>= e;
503 k -= e;
504
505 /* do the copy */
Glenn L McGrath0126fda2002-11-20 06:46:46 +0000506do_copy: do {
Glenn L McGrath9fef17d2002-08-22 18:41:20 +0000507 n -= (e =
508 (e =
Glenn L McGrath7ca04f32002-09-25 02:47:48 +0000509 gunzip_wsize - ((d &= gunzip_wsize - 1) > w ? d : w)) > n ? n : e);
510 /* copy to new buffer to prevent possible overwrite */
Glenn L McGrath7fd92942001-04-11 03:11:33 +0000511 if (w - d >= e) { /* (this test assumes unsigned comparison) */
Glenn L McGrath7ca04f32002-09-25 02:47:48 +0000512 memcpy(gunzip_window + w, gunzip_window + d, e);
Glenn L McGrath7fd92942001-04-11 03:11:33 +0000513 w += e;
514 d += e;
Glenn L McGrath7ca04f32002-09-25 02:47:48 +0000515 } else {
516 /* do it slow to avoid memcpy() overlap */
517 /* !NOMEMCPY */
Glenn L McGrath7fd92942001-04-11 03:11:33 +0000518 do {
Glenn L McGrath7ca04f32002-09-25 02:47:48 +0000519 gunzip_window[w++] = gunzip_window[d++];
Glenn L McGrath7fd92942001-04-11 03:11:33 +0000520 } while (--e);
Glenn L McGrath7ca04f32002-09-25 02:47:48 +0000521 }
522 if (w == gunzip_wsize) {
523 gunzip_outbuf_count = (w);
Glenn L McGrath0126fda2002-11-20 06:46:46 +0000524 if (n) resumeCopy = 1;
525 else resumeCopy = 0;
526 //flush_gunzip_window();
Glenn L McGrath7fd92942001-04-11 03:11:33 +0000527 w = 0;
Glenn L McGrath83bf47c2002-11-20 22:00:31 +0000528 return 1;
Glenn L McGrath7fd92942001-04-11 03:11:33 +0000529 }
530 } while (n);
Glenn L McGrath0126fda2002-11-20 06:46:46 +0000531 resumeCopy = 0;
Glenn L McGrath7fd92942001-04-11 03:11:33 +0000532 }
533 }
534
535 /* restore the globals from the locals */
Glenn L McGrath7ca04f32002-09-25 02:47:48 +0000536 gunzip_outbuf_count = w; /* restore global gunzip_window pointer */
537 gunzip_bb = b; /* restore global bit buffer */
538 gunzip_bk = k;
Glenn L McGrath7fd92942001-04-11 03:11:33 +0000539
Glenn L McGrath0126fda2002-11-20 06:46:46 +0000540 /* normally just after call to inflate_codes, but save code by putting it here */
541 /* free the decoding tables, return */
542 huft_free(tl);
543 huft_free(td);
544
Glenn L McGrath7fd92942001-04-11 03:11:33 +0000545 /* done */
546 return 0;
547}
548
Glenn L McGrath83bf47c2002-11-20 22:00:31 +0000549static int inflate_stored(int my_n, int my_b_stored, int my_k_stored, int setup)
Glenn L McGrath0126fda2002-11-20 06:46:46 +0000550{
551 static int n, b_stored, k_stored, w;
552 if (setup) {
553 n = my_n;
554 b_stored = my_b_stored;
555 k_stored = my_k_stored;
556 w = gunzip_outbuf_count; /* initialize gunzip_window position */
557 return 0; // Don't do anything first time
558 }
559
560 /* read and output the compressed data */
561 while (n--) {
562 b_stored = fill_bitbuffer(b_stored, &k_stored, 8);
563 gunzip_window[w++] = (unsigned char) b_stored;
564 if (w == (unsigned int) gunzip_wsize) {
565 gunzip_outbuf_count = (w);
566 //flush_gunzip_window();
567 w = 0;
568 b_stored >>= 8;
569 k_stored -= 8;
Glenn L McGrath83bf47c2002-11-20 22:00:31 +0000570 return 1; // We have a block
Glenn L McGrath0126fda2002-11-20 06:46:46 +0000571 }
572 b_stored >>= 8;
573 k_stored -= 8;
574 }
575
576 /* restore the globals from the locals */
577 gunzip_outbuf_count = w; /* restore global gunzip_window pointer */
578 gunzip_bb = b_stored; /* restore global bit buffer */
579 gunzip_bk = k_stored;
580 return 0; // Finished
581}
582
Glenn L McGrath7fd92942001-04-11 03:11:33 +0000583/*
584 * decompress an inflated block
585 * e: last block flag
586 *
587 * GLOBAL VARIABLES: bb, kk,
588 */
Glenn L McGrath0126fda2002-11-20 06:46:46 +0000589 // Return values: -1 = inflate_stored, -2 = inflate_codes
Glenn L McGrath7fd92942001-04-11 03:11:33 +0000590static int inflate_block(int *e)
591{
592 unsigned t; /* block type */
Glenn L McGrath7ca04f32002-09-25 02:47:48 +0000593 register unsigned int b; /* bit buffer */
594 unsigned int k; /* number of bits in bit buffer */
Glenn L McGrath7fd92942001-04-11 03:11:33 +0000595
596 /* make local bit buffer */
Glenn L McGrath7ca04f32002-09-25 02:47:48 +0000597
598 b = gunzip_bb;
599 k = gunzip_bk;
Glenn L McGrath7fd92942001-04-11 03:11:33 +0000600
601 /* read in last block bit */
Glenn L McGrath7ca04f32002-09-25 02:47:48 +0000602 b = fill_bitbuffer(b, &k, 1);
Glenn L McGrath7fd92942001-04-11 03:11:33 +0000603 *e = (int) b & 1;
604 b >>= 1;
605 k -= 1;
606
607 /* read in block type */
Glenn L McGrath7ca04f32002-09-25 02:47:48 +0000608 b = fill_bitbuffer(b, &k, 2);
Glenn L McGrath7fd92942001-04-11 03:11:33 +0000609 t = (unsigned) b & 3;
610 b >>= 2;
611 k -= 2;
612
613 /* restore the global bit buffer */
Glenn L McGrath7ca04f32002-09-25 02:47:48 +0000614 gunzip_bb = b;
615 gunzip_bk = k;
Glenn L McGrath7fd92942001-04-11 03:11:33 +0000616
617 /* inflate that block type */
618 switch (t) {
Glenn L McGrath9fef17d2002-08-22 18:41:20 +0000619 case 0: /* Inflate stored */
620 {
Glenn L McGrath7ca04f32002-09-25 02:47:48 +0000621 unsigned int n; /* number of bytes in block */
Glenn L McGrath7ca04f32002-09-25 02:47:48 +0000622 unsigned int b_stored; /* bit buffer */
623 unsigned int k_stored; /* number of bits in bit buffer */
Glenn L McGrath7fd92942001-04-11 03:11:33 +0000624
Glenn L McGrath9fef17d2002-08-22 18:41:20 +0000625 /* make local copies of globals */
Glenn L McGrath7ca04f32002-09-25 02:47:48 +0000626 b_stored = gunzip_bb; /* initialize bit buffer */
627 k_stored = gunzip_bk;
Glenn L McGrath7fd92942001-04-11 03:11:33 +0000628
Glenn L McGrath9fef17d2002-08-22 18:41:20 +0000629 /* go to byte boundary */
630 n = k_stored & 7;
631 b_stored >>= n;
632 k_stored -= n;
Glenn L McGrath7fd92942001-04-11 03:11:33 +0000633
Glenn L McGrath9fef17d2002-08-22 18:41:20 +0000634 /* get the length and its complement */
Glenn L McGrath7ca04f32002-09-25 02:47:48 +0000635 b_stored = fill_bitbuffer(b_stored, &k_stored, 16);
Glenn L McGrath9fef17d2002-08-22 18:41:20 +0000636 n = ((unsigned) b_stored & 0xffff);
637 b_stored >>= 16;
638 k_stored -= 16;
Glenn L McGrath7ca04f32002-09-25 02:47:48 +0000639
640 b_stored = fill_bitbuffer(b_stored, &k_stored, 16);
Glenn L McGrath9fef17d2002-08-22 18:41:20 +0000641 if (n != (unsigned) ((~b_stored) & 0xffff)) {
642 return 1; /* error in compressed data */
643 }
644 b_stored >>= 16;
645 k_stored -= 16;
Glenn L McGrath7fd92942001-04-11 03:11:33 +0000646
Glenn L McGrath0126fda2002-11-20 06:46:46 +0000647 inflate_stored(n, b_stored, k_stored, 1); // Setup inflate_stored
648 return -1;
Glenn L McGrath9fef17d2002-08-22 18:41:20 +0000649 }
650 case 1: /* Inflate fixed
651 * decompress an inflated type 1 (fixed Huffman codes) block. We should
652 * either replace this with a custom decoder, or at least precompute the
653 * Huffman tables.
654 */
655 {
656 int i; /* temporary variable */
657 huft_t *tl; /* literal/length code table */
658 huft_t *td; /* distance code table */
Glenn L McGrath7ca04f32002-09-25 02:47:48 +0000659 unsigned int bl; /* lookup bits for tl */
660 unsigned int bd; /* lookup bits for td */
Glenn L McGrath9fef17d2002-08-22 18:41:20 +0000661 unsigned int l[288]; /* length list for huft_build */
Glenn L McGrath7fd92942001-04-11 03:11:33 +0000662
Glenn L McGrath9fef17d2002-08-22 18:41:20 +0000663 /* set up literal table */
664 for (i = 0; i < 144; i++) {
665 l[i] = 8;
666 }
667 for (; i < 256; i++) {
668 l[i] = 9;
669 }
670 for (; i < 280; i++) {
671 l[i] = 7;
672 }
673 for (; i < 288; i++) { /* make a complete, but wrong code set */
674 l[i] = 8;
675 }
676 bl = 7;
677 if ((i = huft_build(l, 288, 257, cplens, cplext, &tl, &bl)) != 0) {
678 return i;
679 }
Glenn L McGrath7fd92942001-04-11 03:11:33 +0000680
Glenn L McGrath9fef17d2002-08-22 18:41:20 +0000681 /* set up distance table */
682 for (i = 0; i < 30; i++) { /* make an incomplete code set */
683 l[i] = 5;
684 }
685 bd = 5;
686 if ((i = huft_build(l, 30, 0, cpdist, cpdext, &td, &bd)) > 1) {
Glenn L McGrath7fd92942001-04-11 03:11:33 +0000687 huft_free(tl);
Glenn L McGrath9fef17d2002-08-22 18:41:20 +0000688 return i;
Glenn L McGrath7fd92942001-04-11 03:11:33 +0000689 }
Glenn L McGrath7fd92942001-04-11 03:11:33 +0000690
Glenn L McGrath9fef17d2002-08-22 18:41:20 +0000691 /* decompress until an end-of-block code */
Glenn L McGrath0126fda2002-11-20 06:46:46 +0000692 inflate_codes(tl, td, bl, bd, 1); // Setup inflate_codes
693
694 /* huft_free code moved into inflate_codes */
695
696 return -2;
Glenn L McGrath9fef17d2002-08-22 18:41:20 +0000697 }
698 case 2: /* Inflate dynamic */
699 {
700 const int dbits = 6; /* bits in base distance lookup table */
701 const int lbits = 9; /* bits in base literal/length lookup table */
Glenn L McGrath7fd92942001-04-11 03:11:33 +0000702
Glenn L McGrath9fef17d2002-08-22 18:41:20 +0000703 huft_t *tl; /* literal/length code table */
704 huft_t *td; /* distance code table */
Glenn L McGrath7ca04f32002-09-25 02:47:48 +0000705 unsigned int i; /* temporary variables */
706 unsigned int j;
707 unsigned int l; /* last length */
708 unsigned int m; /* mask for bit lengths table */
709 unsigned int n; /* number of lengths to get */
710 unsigned int bl; /* lookup bits for tl */
711 unsigned int bd; /* lookup bits for td */
712 unsigned int nb; /* number of bit length codes */
713 unsigned int nl; /* number of literal/length codes */
714 unsigned int nd; /* number of distance codes */
Glenn L McGrath7fd92942001-04-11 03:11:33 +0000715
Glenn L McGrath7ca04f32002-09-25 02:47:48 +0000716 unsigned int ll[286 + 30]; /* literal/length and distance code lengths */
717 unsigned int b_dynamic; /* bit buffer */
718 unsigned int k_dynamic; /* number of bits in bit buffer */
Glenn L McGrath9fef17d2002-08-22 18:41:20 +0000719
720 /* make local bit buffer */
Glenn L McGrath7ca04f32002-09-25 02:47:48 +0000721 b_dynamic = gunzip_bb;
722 k_dynamic = gunzip_bk;
Glenn L McGrath9fef17d2002-08-22 18:41:20 +0000723
724 /* read in table lengths */
Glenn L McGrath7ca04f32002-09-25 02:47:48 +0000725 b_dynamic = fill_bitbuffer(b_dynamic, &k_dynamic, 5);
726 nl = 257 + ((unsigned int) b_dynamic & 0x1f); /* number of literal/length codes */
727
Glenn L McGrath9fef17d2002-08-22 18:41:20 +0000728 b_dynamic >>= 5;
729 k_dynamic -= 5;
Glenn L McGrath7ca04f32002-09-25 02:47:48 +0000730 b_dynamic = fill_bitbuffer(b_dynamic, &k_dynamic, 5);
731 nd = 1 + ((unsigned int) b_dynamic & 0x1f); /* number of distance codes */
732
Glenn L McGrath9fef17d2002-08-22 18:41:20 +0000733 b_dynamic >>= 5;
734 k_dynamic -= 5;
Glenn L McGrath7ca04f32002-09-25 02:47:48 +0000735 b_dynamic = fill_bitbuffer(b_dynamic, &k_dynamic, 4);
736 nb = 4 + ((unsigned int) b_dynamic & 0xf); /* number of bit length codes */
737
Glenn L McGrath9fef17d2002-08-22 18:41:20 +0000738 b_dynamic >>= 4;
739 k_dynamic -= 4;
740 if (nl > 286 || nd > 30) {
741 return 1; /* bad lengths */
742 }
743
744 /* read in bit-length-code lengths */
745 for (j = 0; j < nb; j++) {
Glenn L McGrath7ca04f32002-09-25 02:47:48 +0000746 b_dynamic = fill_bitbuffer(b_dynamic, &k_dynamic, 3);
747 ll[border[j]] = (unsigned int) b_dynamic & 7;
Glenn L McGrath9fef17d2002-08-22 18:41:20 +0000748 b_dynamic >>= 3;
749 k_dynamic -= 3;
750 }
751 for (; j < 19; j++) {
752 ll[border[j]] = 0;
753 }
Glenn L McGrath7fd92942001-04-11 03:11:33 +0000754
Glenn L McGrath9fef17d2002-08-22 18:41:20 +0000755 /* build decoding table for trees--single level, 7 bit lookup */
756 bl = 7;
Glenn L McGrath7ca04f32002-09-25 02:47:48 +0000757 i = huft_build(ll, 19, 19, NULL, NULL, &tl, &bl);
758 if (i != 0) {
Glenn L McGrath9fef17d2002-08-22 18:41:20 +0000759 if (i == 1) {
760 huft_free(tl);
761 }
762 return i; /* incomplete code set */
763 }
764
765 /* read in literal and distance code lengths */
766 n = nl + nd;
767 m = mask_bits[bl];
768 i = l = 0;
Glenn L McGrath7ca04f32002-09-25 02:47:48 +0000769 while ((unsigned int) i < n) {
770 b_dynamic = fill_bitbuffer(b_dynamic, &k_dynamic, (unsigned int)bl);
771 j = (td = tl + ((unsigned int) b_dynamic & m))->b;
Glenn L McGrath9fef17d2002-08-22 18:41:20 +0000772 b_dynamic >>= j;
773 k_dynamic -= j;
774 j = td->v.n;
775 if (j < 16) { /* length of code in bits (0..15) */
776 ll[i++] = l = j; /* save last length in l */
777 } else if (j == 16) { /* repeat last length 3 to 6 times */
Glenn L McGrath7ca04f32002-09-25 02:47:48 +0000778 b_dynamic = fill_bitbuffer(b_dynamic, &k_dynamic, 2);
779 j = 3 + ((unsigned int) b_dynamic & 3);
Glenn L McGrath9fef17d2002-08-22 18:41:20 +0000780 b_dynamic >>= 2;
781 k_dynamic -= 2;
Glenn L McGrath7ca04f32002-09-25 02:47:48 +0000782 if ((unsigned int) i + j > n) {
Glenn L McGrath9fef17d2002-08-22 18:41:20 +0000783 return 1;
784 }
785 while (j--) {
786 ll[i++] = l;
787 }
788 } else if (j == 17) { /* 3 to 10 zero length codes */
Glenn L McGrath7ca04f32002-09-25 02:47:48 +0000789 b_dynamic = fill_bitbuffer(b_dynamic, &k_dynamic, 3);
790 j = 3 + ((unsigned int) b_dynamic & 7);
Glenn L McGrath7fd92942001-04-11 03:11:33 +0000791 b_dynamic >>= 3;
792 k_dynamic -= 3;
Glenn L McGrath7ca04f32002-09-25 02:47:48 +0000793 if ((unsigned int) i + j > n) {
Glenn L McGrath9fef17d2002-08-22 18:41:20 +0000794 return 1;
Glenn L McGrath7fd92942001-04-11 03:11:33 +0000795 }
Glenn L McGrath9fef17d2002-08-22 18:41:20 +0000796 while (j--) {
797 ll[i++] = 0;
798 }
799 l = 0;
800 } else { /* j == 18: 11 to 138 zero length codes */
Glenn L McGrath7ca04f32002-09-25 02:47:48 +0000801 b_dynamic = fill_bitbuffer(b_dynamic, &k_dynamic, 7);
802 j = 11 + ((unsigned int) b_dynamic & 0x7f);
Glenn L McGrath9fef17d2002-08-22 18:41:20 +0000803 b_dynamic >>= 7;
804 k_dynamic -= 7;
Glenn L McGrath7ca04f32002-09-25 02:47:48 +0000805 if ((unsigned int) i + j > n) {
Glenn L McGrath9fef17d2002-08-22 18:41:20 +0000806 return 1;
Glenn L McGrath7fd92942001-04-11 03:11:33 +0000807 }
Glenn L McGrath9fef17d2002-08-22 18:41:20 +0000808 while (j--) {
809 ll[i++] = 0;
Glenn L McGrath7fd92942001-04-11 03:11:33 +0000810 }
Glenn L McGrath9fef17d2002-08-22 18:41:20 +0000811 l = 0;
Glenn L McGrath7fd92942001-04-11 03:11:33 +0000812 }
Glenn L McGrath7fd92942001-04-11 03:11:33 +0000813 }
Glenn L McGrath9fef17d2002-08-22 18:41:20 +0000814
815 /* free decoding table for trees */
816 huft_free(tl);
817
818 /* restore the global bit buffer */
Glenn L McGrath7ca04f32002-09-25 02:47:48 +0000819 gunzip_bb = b_dynamic;
820 gunzip_bk = k_dynamic;
Glenn L McGrath9fef17d2002-08-22 18:41:20 +0000821
822 /* build the decoding tables for literal/length and distance codes */
823 bl = lbits;
Glenn L McGrath7ca04f32002-09-25 02:47:48 +0000824
Glenn L McGrath9fef17d2002-08-22 18:41:20 +0000825 if ((i = huft_build(ll, nl, 257, cplens, cplext, &tl, &bl)) != 0) {
826 if (i == 1) {
Glenn L McGrath7ca04f32002-09-25 02:47:48 +0000827 error_msg_and_die("Incomplete literal tree");
Glenn L McGrath9fef17d2002-08-22 18:41:20 +0000828 huft_free(tl);
829 }
830 return i; /* incomplete code set */
831 }
Glenn L McGrath7ca04f32002-09-25 02:47:48 +0000832
Glenn L McGrath9fef17d2002-08-22 18:41:20 +0000833 bd = dbits;
834 if ((i = huft_build(ll + nl, nd, 0, cpdist, cpdext, &td, &bd)) != 0) {
835 if (i == 1) {
Glenn L McGrath7ca04f32002-09-25 02:47:48 +0000836 error_msg_and_die("incomplete distance tree");
Glenn L McGrath9fef17d2002-08-22 18:41:20 +0000837 huft_free(td);
838 }
839 huft_free(tl);
840 return i; /* incomplete code set */
841 }
842
843 /* decompress until an end-of-block code */
Glenn L McGrath0126fda2002-11-20 06:46:46 +0000844 inflate_codes(tl, td, bl, bd, 1); // Setup inflate_codes
Glenn L McGrath9fef17d2002-08-22 18:41:20 +0000845
Glenn L McGrath0126fda2002-11-20 06:46:46 +0000846 /* huft_free code moved into inflate_codes */
847
848 return -2;
Glenn L McGrath9fef17d2002-08-22 18:41:20 +0000849 }
Glenn L McGrath7fd92942001-04-11 03:11:33 +0000850 default:
851 /* bad block type */
Glenn L McGrath83bf47c2002-11-20 22:00:31 +0000852 error_msg_and_die("bad block type %d\n", t);
853 }
854}
855
856static void calculate_gunzip_crc(void)
857{
858 int n;
859 for (n = 0; n < gunzip_outbuf_count; n++) {
860 gunzip_crc = gunzip_crc_table[((int) gunzip_crc ^ (gunzip_window[n])) & 0xff] ^ (gunzip_crc >> 8);
861 }
862 gunzip_bytes_out += gunzip_outbuf_count;
863}
864
865static int inflate_get_next_window(void)
866{
867 static int needAnotherBlock = 1;
868 static int method = -1; // Method == -1 for stored, -2 for codes
869 static int e = 0;
870
871 gunzip_outbuf_count = 0;
872
873 while(1) {
874 int ret;
875
876 if (needAnotherBlock) {
Glenn L McGratheda4f532002-11-24 06:01:20 +0000877 if(e) {
878 calculate_gunzip_crc();
879 return 0;
880 } // Last block
Glenn L McGrath83bf47c2002-11-20 22:00:31 +0000881 method = inflate_block(&e);
882 needAnotherBlock = 0;
883 }
884
885 switch (method) {
886 case -1: ret = inflate_stored(0,0,0,0);
887 break;
888 case -2: ret = inflate_codes(0,0,0,0,0);
889 break;
890 default: error_msg_and_die("inflate error %d", method);
891 }
892
893 if (ret == 1) {
894 calculate_gunzip_crc();
895 return 1; // More data left
896 } else needAnotherBlock = 1; // End of that block
Glenn L McGrath7fd92942001-04-11 03:11:33 +0000897 }
Glenn L McGratheda4f532002-11-24 06:01:20 +0000898 /* Doesnt get here */
Glenn L McGrath7fd92942001-04-11 03:11:33 +0000899}
900
901/*
Glenn L McGrath83bf47c2002-11-20 22:00:31 +0000902 * User functions
Glenn L McGrath7fd92942001-04-11 03:11:33 +0000903 *
Glenn L McGrath83bf47c2002-11-20 22:00:31 +0000904 * read_gz, GZ_gzReadOpen, GZ_gzReadClose, inflate
Glenn L McGrath7fd92942001-04-11 03:11:33 +0000905 */
Glenn L McGrathfd73b8c2002-11-17 21:33:30 +0000906
907extern ssize_t read_gz(int fd, void *buf, size_t count)
Glenn L McGrath7fd92942001-04-11 03:11:33 +0000908{
Glenn L McGrath83bf47c2002-11-20 22:00:31 +0000909 static int morebytes = 0, finished = 0;
910
911 if (morebytes) {
912 int bytesRead = morebytes > count ? count : morebytes;
913 memcpy(buf, gunzip_window + (gunzip_outbuf_count - morebytes), bytesRead);
914 morebytes -= bytesRead;
915 return bytesRead;
916 } else if (finished) {
917 return 0;
918 } else if (count >= 0x8000) { // We can decompress direcly to the buffer, 32k at a time
919 // Could decompress to larger buffer, but it must be a power of 2, and calculating that is probably more expensive than the benefit
920 unsigned char *old_gunzip_window = gunzip_window; // Save old window
921 gunzip_window = buf;
922 if (inflate_get_next_window() == 0) finished = 1;
923 gunzip_window = old_gunzip_window; // Restore old window
924 return gunzip_outbuf_count;
925 } else { // Oh well, need to split up the gunzip_window
926 int bytesRead;
927 if (inflate_get_next_window() == 0) finished = 1;
928 morebytes = gunzip_outbuf_count;
929 bytesRead = morebytes > count ? count : morebytes;
930 memcpy(buf, gunzip_window, bytesRead);
931 morebytes -= bytesRead;
932 return bytesRead;
Glenn L McGrathfd73b8c2002-11-17 21:33:30 +0000933 }
Glenn L McGrath83bf47c2002-11-20 22:00:31 +0000934
Glenn L McGrathfd73b8c2002-11-17 21:33:30 +0000935}
936
937extern void GZ_gzReadOpen(int fd, void *unused, int nUnused)
938{
939 typedef void (*sig_type) (int);
Glenn L McGrath7fd92942001-04-11 03:11:33 +0000940
Glenn L McGrath87ac7022002-01-02 13:52:26 +0000941 /* Allocate all global buffers (for DYN_ALLOC option) */
Glenn L McGrathfd73b8c2002-11-17 21:33:30 +0000942 gunzip_window = xmalloc(gunzip_wsize);
Glenn L McGrath7ca04f32002-09-25 02:47:48 +0000943 gunzip_outbuf_count = 0;
944 gunzip_bytes_out = 0;
Glenn L McGrathfd73b8c2002-11-17 21:33:30 +0000945 gunzip_src_fd = fd;
Glenn L McGrath249f39a2001-12-05 16:01:02 +0000946
Glenn L McGratheda4f532002-11-24 06:01:20 +0000947 /* Input buffer */
948 bytebuffer = xmalloc(BYTEBUFFER_MAX);
Glenn L McGrath7fd92942001-04-11 03:11:33 +0000949
Glenn L McGrath7ca04f32002-09-25 02:47:48 +0000950 /* initialize gunzip_window, bit buffer */
951 gunzip_bk = 0;
952 gunzip_bb = 0;
Glenn L McGrath9fef17d2002-08-22 18:41:20 +0000953
Glenn L McGrath7ca04f32002-09-25 02:47:48 +0000954 /* Create the crc table */
955 make_gunzip_crc_table();
Glenn L McGrathfd73b8c2002-11-17 21:33:30 +0000956}
Glenn L McGrath7ca04f32002-09-25 02:47:48 +0000957
Glenn L McGrathfd73b8c2002-11-17 21:33:30 +0000958extern void GZ_gzReadClose(void)
959{
Glenn L McGrath7ca04f32002-09-25 02:47:48 +0000960 /* Cleanup */
Glenn L McGrathfd73b8c2002-11-17 21:33:30 +0000961 free(gunzip_window);
Glenn L McGrath7ca04f32002-09-25 02:47:48 +0000962 free(gunzip_crc_table);
963
964 /* Store unused bytes in a global buffer so calling applets can access it */
Glenn L McGrath7ca04f32002-09-25 02:47:48 +0000965 if (gunzip_bk >= 8) {
966 /* Undo too much lookahead. The next read will be byte aligned
967 * so we can discard unused bits in the last meaningful byte. */
Glenn L McGratheda4f532002-11-24 06:01:20 +0000968 bytebuffer_offset--;
969 bytebuffer[bytebuffer_offset] = gunzip_bb & 0xff;
Glenn L McGrath7ca04f32002-09-25 02:47:48 +0000970 gunzip_bb >>= 8;
971 gunzip_bk -= 8;
Glenn L McGrath7fd92942001-04-11 03:11:33 +0000972 }
Glenn L McGrathfd73b8c2002-11-17 21:33:30 +0000973}
Glenn L McGrath7fd92942001-04-11 03:11:33 +0000974
Glenn L McGrath83bf47c2002-11-20 22:00:31 +0000975/*extern int inflate(int in, int out) // Useful for testing read_gz
Glenn L McGrathfd73b8c2002-11-17 21:33:30 +0000976{
977 char buf[8192];
978 ssize_t nread, nwrote;
Glenn L McGrathfd73b8c2002-11-17 21:33:30 +0000979
980 GZ_gzReadOpen(in, 0, 0);
981 while(1) { // Robbed from copyfd.c
982 nread = read_gz(in, buf, sizeof(buf));
983 if (nread == 0) break; // no data to write
984 else if (nread == -1) {
985 perror_msg("read");
986 return -1;
987 }
988 nwrote = full_write(out, buf, nread);
989 if (nwrote == -1) {
990 perror_msg("write");
991 return -1;
992 }
Glenn L McGrath83bf47c2002-11-20 22:00:31 +0000993 }
994 GZ_gzReadClose();
995 return 0;
996}*/
997
998extern int inflate(int in, int out)
999{
1000 ssize_t nwrote;
1001 GZ_gzReadOpen(in, 0, 0);
1002 while(1) {
1003 int ret = inflate_get_next_window();
1004 nwrote = full_write(out, gunzip_window, gunzip_outbuf_count);
1005 if (nwrote == -1) {
1006 perror_msg("write");
1007 return -1;
1008 }
1009 if (ret == 0) break;
Glenn L McGrathfd73b8c2002-11-17 21:33:30 +00001010 }
1011 GZ_gzReadClose();
Glenn L McGrath7fd92942001-04-11 03:11:33 +00001012 return 0;
1013}