/* vi: set sw=4 ts=4: */
/*
 * gunzip implementation for busybox
 *
 * Based on GNU gzip v1.2.4 Copyright (C) 1992-1993 Jean-loup Gailly.
 *
 * Originally adjusted for busybox by Sven Rudolph <sr1@inf.tu-dresden.de>
 * based on gzip sources
 *
 * Adjusted further by Erik Andersen <andersen@codepoet.org> to support
 * files as well as stdin/stdout, and to generally behave itself wrt
 * command line handling.
 *
 * General cleanup to better adhere to the style guide and make use of standard
 * busybox functions by Glenn McGrath <bug1@iinet.net.au>
 *
 * read_gz interface + associated hacking by Laurence Anderson
 *
 * Fixed huft_build() so decoding end-of-block code does not grab more bits
 * than necessary (this is required by unzip applet), added inflate_cleanup()
 * to free leaked bytebuffer memory (used in unzip.c), and some minor style
 * guide cleanups by Ed Clark
 *
 * gzip (GNU zip) -- compress files with zip algorithm and 'compress' interface
 * Copyright (C) 1992-1993 Jean-loup Gailly
 * The unzip code was written and put in the public domain by Mark Adler.
 * Portions of the lzw code are derived from the public domain 'compress'
 * written by Spencer Thomas, Joe Orost, James Woods, Jim McKie, Steve Davies,
 * Ken Turkowski, Dave Mack and Peter Jannesen.
 *
 * See the file algorithm.doc for the compression algorithms and file formats.
 *
 * Licensed under GPLv2 or later, see file LICENSE in this tarball for details.
 */

#include "libbb.h"
#include "unarchive.h"

typedef struct huft_s {
	unsigned char e;	/* number of extra bits or operation */
	unsigned char b;	/* number of bits in this code or subcode */
	union {
		unsigned short n;	/* literal, length base, or distance base */
		struct huft_s *t;	/* pointer to next level of table */
	} v;
} huft_t;

static int gunzip_src_fd;
unsigned int gunzip_bytes_out;	/* number of output bytes */
static unsigned int gunzip_outbuf_count;	/* bytes in output buffer */

/* gunzip_window size--must be a power of two, and
 *  at least 32K for zip's deflate method */
enum { gunzip_wsize = 0x8000 };
static unsigned char *gunzip_window;

static uint32_t *gunzip_crc_table;
uint32_t gunzip_crc;

/* If BMAX needs to be larger than 16, then h and x[] should be ulg. */
#define BMAX 16	/* maximum bit length of any code (16 for explode) */
#define N_MAX 288	/* maximum number of codes in any set */

/* bitbuffer */
static unsigned int gunzip_bb;	/* bit buffer */
static unsigned char gunzip_bk;	/* bits in bit buffer */

/* These control the size of the bytebuffer */
static unsigned int bytebuffer_max = 0x8000;
static unsigned char *bytebuffer = NULL;
static unsigned int bytebuffer_offset = 0;
static unsigned int bytebuffer_size = 0;

static const unsigned short mask_bits[] = {
	0x0000, 0x0001, 0x0003, 0x0007, 0x000f, 0x001f, 0x003f, 0x007f, 0x00ff,
	0x01ff, 0x03ff, 0x07ff, 0x0fff, 0x1fff, 0x3fff, 0x7fff, 0xffff
};

/* Copy lengths for literal codes 257..285 */
static const unsigned short cplens[] = {
	3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31, 35, 43, 51, 59,
	67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0
};

/* note: see note #13 above about the 258 in this list. */
/* Extra bits for literal codes 257..285 */
static const unsigned char cplext[] = {
	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,
	5, 5, 5, 0, 99, 99
};						/* 99==invalid */

/* Copy offsets for distance codes 0..29 */
static const unsigned short cpdist[] = {
	1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193, 257, 385, 513,
	769, 1025, 1537, 2049, 3073, 4097, 6145, 8193, 12289, 16385, 24577
};

/* Extra bits for distance codes */
static const unsigned char cpdext[] = {
	0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10,
	11, 11, 12, 12, 13, 13
};

/* Tables for deflate from PKZIP's appnote.txt. */
/* Order of the bit length code lengths */
static const unsigned char border[] = {
	16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15
};

static unsigned int fill_bitbuffer(unsigned int bitbuffer, unsigned int *current, const unsigned int required)
{
	while (*current < required) {
		if (bytebuffer_offset >= bytebuffer_size) {
			/* Leave the first 4 bytes empty so we can always unwind the bitbuffer
			 * to the front of the bytebuffer, leave 4 bytes free at end of tail
			 * so we can easily top up buffer in check_trailer_gzip() */
			if (1 > (bytebuffer_size = safe_read(gunzip_src_fd, &bytebuffer[4], bytebuffer_max - 8)))
				bb_error_msg_and_die("unexpected end of file");
			bytebuffer_size += 4;
			bytebuffer_offset = 4;
		}
		bitbuffer |= ((unsigned int) bytebuffer[bytebuffer_offset]) << *current;
		bytebuffer_offset++;
		*current += 8;
	}
	return bitbuffer;
}

/*
 * Free the malloc'ed tables built by huft_build(), which makes a linked
 * list of the tables it made, with the links in a dummy first entry of
 * each table.
 * t: table to free
 */
static int huft_free(huft_t * t)
{
	huft_t *p;
	huft_t *q;

	/* Go through linked list, freeing from the malloced (t[-1]) address. */
	p = t;
	while (p != (huft_t *) NULL) {
		q = (--p)->v.t;
		free((char *) p);
		p = q;
	}
	return 0;
}

/* Given a list of code lengths and a maximum table size, make a set of
 * tables to decode that set of codes.  Return zero on success, one if
 * the given code set is incomplete (the tables are still built in this
 * case), two if the input is invalid (all zero length codes or an
 * oversubscribed set of lengths), and three if not enough memory.
 *
 * b:	code lengths in bits (all assumed <= BMAX)
 * n:	number of codes (assumed <= N_MAX)
 * s:	number of simple-valued codes (0..s-1)
 * d:	list of base values for non-simple codes
 * e:	list of extra bits for non-simple codes
 * t:	result: starting table
 * m:	maximum lookup bits, returns actual
 */
static
int huft_build(unsigned int *b, const unsigned int n,
			   const unsigned int s, const unsigned short *d,
			   const unsigned char *e, huft_t ** t, unsigned int *m)
{
	unsigned a;				/* counter for codes of length k */
	unsigned c[BMAX + 1];	/* bit length count table */
	unsigned eob_len;		/* length of end-of-block code (value 256) */
	unsigned f;				/* i repeats in table every f entries */
	int g;					/* maximum code length */
	int htl;				/* table level */
	unsigned i;				/* counter, current code */
	unsigned j;				/* counter */
	int k;					/* number of bits in current code */
	unsigned *p;			/* pointer into c[], b[], or v[] */
	huft_t *q;				/* points to current table */
	huft_t r;				/* table entry for structure assignment */
	huft_t *u[BMAX];		/* table stack */
	unsigned v[N_MAX];		/* values in order of bit length */
	int ws[BMAX+1];			/* bits decoded stack */
	int w;					/* bits decoded */
	unsigned x[BMAX + 1];	/* bit offsets, then code stack */
	unsigned *xp;			/* pointer into x */
	int y;					/* number of dummy codes added */
	unsigned z;				/* number of entries in current table */

	/* Length of EOB code, if any */
	eob_len = n > 256 ? b[256] : BMAX;

	/* Generate counts for each bit length */
	memset((void *)c, 0, sizeof(c));
	p = b;
	i = n;
	do {
		c[*p]++; /* assume all entries <= BMAX */
		p++; /* Can't combine with above line (Solaris bug) */
	} while (--i);
	if (c[0] == n) { /* null input--all zero length codes */
		*t = (huft_t *) NULL;
		*m = 0;
		return 2;
	}

	/* Find minimum and maximum length, bound *m by those */
	for (j = 1; (c[j] == 0) && (j <= BMAX); j++);
	k = j; /* minimum code length */
	for (i = BMAX; (c[i] == 0) && i; i--);
	g = i; /* maximum code length */
	*m = (*m < j) ? j : ((*m > i) ? i : *m);

	/* Adjust last length count to fill out codes, if needed */
	for (y = 1 << j; j < i; j++, y <<= 1) {
		if ((y -= c[j]) < 0) {
			return 2; /* bad input: more codes than bits */
		}
	}
	if ((y -= c[i]) < 0) {
		return 2;
	}
	c[i] += y;

	/* Generate starting offsets into the value table for each length */
	x[1] = j = 0;
	p = c + 1;
	xp = x + 2;
	while (--i) { /* note that i == g from above */
		*xp++ = (j += *p++);
	}

	/* Make a table of values in order of bit lengths */
	p = b;
	i = 0;
	do {
		if ((j = *p++) != 0) {
			v[x[j]++] = i;
		}
	} while (++i < n);

	/* Generate the Huffman codes and for each, make the table entries */
	x[0] = i = 0;			/* first Huffman code is zero */
	p = v;					/* grab values in bit order */
	htl = -1;				/* no tables yet--level -1 */
	w = ws[0] = 0;			/* bits decoded */
	u[0] = (huft_t *) NULL;	/* just to keep compilers happy */
	q = (huft_t *) NULL;	/* ditto */
	z = 0;					/* ditto */

	/* go through the bit lengths (k already is bits in shortest code) */
	for (; k <= g; k++) {
		a = c[k];
		while (a--) {
			/* here i is the Huffman code of length k bits for value *p */
			/* make tables up to required level */
			while (k > ws[htl + 1]) {
				w = ws[++htl];

				/* compute minimum size table less than or equal to *m bits */
				z = (z = g - w) > *m ? *m : z; /* upper limit on table size */
				if ((f = 1 << (j = k - w)) > a + 1) { /* try a k-w bit table */
					/* too few codes for k-w bit table */
					f -= a + 1; /* deduct codes from patterns left */
					xp = c + k;
					while (++j < z) { /* try smaller tables up to z bits */
						if ((f <<= 1) <= *++xp) {
							break; /* enough codes to use up j bits */
						}
						f -= *xp; /* else deduct codes from patterns */
					}
				}
				j = (w + j > eob_len && w < eob_len) ? eob_len - w : j;	/* make EOB code end at table */
				z = 1 << j;	/* table entries for j-bit table */
				ws[htl+1] = w + j;	/* set bits decoded in stack */

				/* allocate and link in new table */
				q = (huft_t *) xzalloc((z + 1) * sizeof(huft_t));
				*t = q + 1;	/* link to list for huft_free() */
				t = &(q->v.t);
				u[htl] = ++q;	/* table starts after link */

				/* connect to last table, if there is one */
				if (htl) {
					x[htl] = i; /* save pattern for backing up */
					r.b = (unsigned char) (w - ws[htl - 1]); /* bits to dump before this table */
					r.e = (unsigned char) (16 + j); /* bits in this table */
					r.v.t = q; /* pointer to this table */
					j = (i & ((1 << w) - 1)) >> ws[htl - 1];
					u[htl - 1][j] = r; /* connect to last table */
				}
			}

			/* set up table entry in r */
			r.b = (unsigned char) (k - w);
			if (p >= v + n) {
				r.e = 99; /* out of values--invalid code */
			} else if (*p < s) {
				r.e = (unsigned char) (*p < 256 ? 16 : 15);	/* 256 is EOB code */
				r.v.n = (unsigned short) (*p++); /* simple code is just the value */
			} else {
				r.e = (unsigned char) e[*p - s]; /* non-simple--look up in lists */
				r.v.n = d[*p++ - s];
			}

			/* fill code-like entries with r */
			f = 1 << (k - w);
			for (j = i >> w; j < z; j += f) {
				q[j] = r;
			}

			/* backwards increment the k-bit code i */
			for (j = 1 << (k - 1); i & j; j >>= 1) {
				i ^= j;
			}
			i ^= j;

			/* backup over finished tables */
			while ((i & ((1 << w) - 1)) != x[htl]) {
				w = ws[--htl];
			}
		}
	}

	/* return actual size of base table */
	*m = ws[1];

	/* Return true (1) if we were given an incomplete table */
	return y != 0 && g != 1;
}

/*
 * inflate (decompress) the codes in a deflated (compressed) block.
 * Return an error code or zero if it all goes ok.
 *
 * tl, td: literal/length and distance decoder tables
 * bl, bd: number of bits decoded by tl[] and td[]
 */
static int inflate_codes(huft_t * my_tl, huft_t * my_td, const unsigned int my_bl, const unsigned int my_bd, int setup)
{
	static unsigned int e;	/* table entry flag/number of extra bits */
	static unsigned int n, d;	/* length and index for copy */
	static unsigned int w;	/* current gunzip_window position */
	static huft_t *t;			/* pointer to table entry */
	static unsigned int ml, md;	/* masks for bl and bd bits */
	static unsigned int b;	/* bit buffer */
	static unsigned int k;			/* number of bits in bit buffer */
	static huft_t *tl, *td;
	static unsigned int bl, bd;
	static int resumeCopy = 0;

	if (setup) { // 1st time we are called, copy in variables
		tl = my_tl;
		td = my_td;
		bl = my_bl;
		bd = my_bd;
		/* make local copies of globals */
		b = gunzip_bb;				/* initialize bit buffer */
		k = gunzip_bk;
		w = gunzip_outbuf_count;			/* initialize gunzip_window position */

		/* inflate the coded data */
		ml = mask_bits[bl];	/* precompute masks for speed */
		md = mask_bits[bd];
		return 0; // Don't actually do anything the first time
	}

	if (resumeCopy) goto do_copy;

	while (1) {			/* do until end of block */
		b = fill_bitbuffer(b, &k, bl);
		if ((e = (t = tl + ((unsigned) b & ml))->e) > 16)
			do {
				if (e == 99) {
					bb_error_msg_and_die("inflate_codes error 1");
				}
				b >>= t->b;
				k -= t->b;
				e -= 16;
				b = fill_bitbuffer(b, &k, e);
			} while ((e =
					  (t = t->v.t + ((unsigned) b & mask_bits[e]))->e) > 16);
		b >>= t->b;
		k -= t->b;
		if (e == 16) {	/* then it's a literal */
			gunzip_window[w++] = (unsigned char) t->v.n;
			if (w == gunzip_wsize) {
				gunzip_outbuf_count = (w);
				//flush_gunzip_window();
				w = 0;
				return 1; // We have a block to read
			}
		} else {		/* it's an EOB or a length */

			/* exit if end of block */
			if (e == 15) {
				break;
			}

			/* get length of block to copy */
			b = fill_bitbuffer(b, &k, e);
			n = t->v.n + ((unsigned) b & mask_bits[e]);
			b >>= e;
			k -= e;

			/* decode distance of block to copy */
			b = fill_bitbuffer(b, &k, bd);
			if ((e = (t = td + ((unsigned) b & md))->e) > 16)
				do {
					if (e == 99)
						bb_error_msg_and_die("inflate_codes error 2");
					b >>= t->b;
					k -= t->b;
					e -= 16;
					b = fill_bitbuffer(b, &k, e);
				} while ((e =
						  (t =
						   t->v.t + ((unsigned) b & mask_bits[e]))->e) > 16);
			b >>= t->b;
			k -= t->b;
			b = fill_bitbuffer(b, &k, e);
			d = w - t->v.n - ((unsigned) b & mask_bits[e]);
			b >>= e;
			k -= e;

			/* do the copy */
do_copy:		do {
				n -= (e =
					  (e =
					   gunzip_wsize - ((d &= gunzip_wsize - 1) > w ? d : w)) > n ? n : e);
			   /* copy to new buffer to prevent possible overwrite */
				if (w - d >= e) {	/* (this test assumes unsigned comparison) */
					memcpy(gunzip_window + w, gunzip_window + d, e);
					w += e;
					d += e;
				} else {
				   /* do it slow to avoid memcpy() overlap */
				   /* !NOMEMCPY */
					do {
						gunzip_window[w++] = gunzip_window[d++];
					} while (--e);
				}
				if (w == gunzip_wsize) {
					gunzip_outbuf_count = (w);
					if (n) resumeCopy = 1;
					else resumeCopy = 0;
					//flush_gunzip_window();
					w = 0;
					return 1;
				}
			} while (n);
			resumeCopy = 0;
		}
	}

	/* restore the globals from the locals */
	gunzip_outbuf_count = w;			/* restore global gunzip_window pointer */
	gunzip_bb = b;				/* restore global bit buffer */
	gunzip_bk = k;

	/* normally just after call to inflate_codes, but save code by putting it here */
	/* free the decoding tables, return */
	huft_free(tl);
	huft_free(td);

	/* done */
	return 0;
}

static int inflate_stored(int my_n, int my_b_stored, int my_k_stored, int setup)
{
	static unsigned int n, b_stored, k_stored, w;
	if (setup) {
		n = my_n;
		b_stored = my_b_stored;
		k_stored = my_k_stored;
		w = gunzip_outbuf_count;		/* initialize gunzip_window position */
		return 0; // Don't do anything first time
	}

	/* read and output the compressed data */
	while (n--) {
		b_stored = fill_bitbuffer(b_stored, &k_stored, 8);
		gunzip_window[w++] = (unsigned char) b_stored;
		if (w == gunzip_wsize) {
			gunzip_outbuf_count = (w);
			//flush_gunzip_window();
			w = 0;
			b_stored >>= 8;
			k_stored -= 8;
			return 1; // We have a block
		}
		b_stored >>= 8;
		k_stored -= 8;
	}

	/* restore the globals from the locals */
	gunzip_outbuf_count = w;		/* restore global gunzip_window pointer */
	gunzip_bb = b_stored;	/* restore global bit buffer */
	gunzip_bk = k_stored;
	return 0; // Finished
}

/*
 * decompress an inflated block
 * e: last block flag
 *
 * GLOBAL VARIABLES: bb, kk,
 */
 // Return values: -1 = inflate_stored, -2 = inflate_codes
static int inflate_block(int *e)
{
	unsigned t;			/* block type */
	unsigned int b;	/* bit buffer */
	unsigned int k;	/* number of bits in bit buffer */

	/* make local bit buffer */

	b = gunzip_bb;
	k = gunzip_bk;

	/* read in last block bit */
	b = fill_bitbuffer(b, &k, 1);
	*e = (int) b & 1;
	b >>= 1;
	k -= 1;

	/* read in block type */
	b = fill_bitbuffer(b, &k, 2);
	t = (unsigned) b & 3;
	b >>= 2;
	k -= 2;

	/* restore the global bit buffer */
	gunzip_bb = b;
	gunzip_bk = k;

	/* inflate that block type */
	switch (t) {
	case 0:			/* Inflate stored */
	{
		unsigned int n;	/* number of bytes in block */
		unsigned int b_stored;	/* bit buffer */
		unsigned int k_stored;	/* number of bits in bit buffer */

		/* make local copies of globals */
		b_stored = gunzip_bb;	/* initialize bit buffer */
		k_stored = gunzip_bk;

		/* go to byte boundary */
		n = k_stored & 7;
		b_stored >>= n;
		k_stored -= n;

		/* get the length and its complement */
		b_stored = fill_bitbuffer(b_stored, &k_stored, 16);
		n = ((unsigned) b_stored & 0xffff);
		b_stored >>= 16;
		k_stored -= 16;

		b_stored = fill_bitbuffer(b_stored, &k_stored, 16);
		if (n != (unsigned) ((~b_stored) & 0xffff)) {
			return 1;	/* error in compressed data */
		}
		b_stored >>= 16;
		k_stored -= 16;

		inflate_stored(n, b_stored, k_stored, 1); // Setup inflate_stored
		return -1;
	}
	case 1:			/* Inflate fixed
						   * decompress an inflated type 1 (fixed Huffman codes) block.  We should
						   * either replace this with a custom decoder, or at least precompute the
						   * Huffman tables.
						 */
	{
		int i;			/* temporary variable */
		huft_t *tl;		/* literal/length code table */
		huft_t *td;		/* distance code table */
		unsigned int bl;			/* lookup bits for tl */
		unsigned int bd;			/* lookup bits for td */
		unsigned int l[288];	/* length list for huft_build */

		/* set up literal table */
		for (i = 0; i < 144; i++) {
			l[i] = 8;
		}
		for (; i < 256; i++) {
			l[i] = 9;
		}
		for (; i < 280; i++) {
			l[i] = 7;
		}
		for (; i < 288; i++) {	/* make a complete, but wrong code set */
			l[i] = 8;
		}
		bl = 7;
		if ((i = huft_build(l, 288, 257, cplens, cplext, &tl, &bl)) != 0) {
			return i;
		}

		/* set up distance table */
		for (i = 0; i < 30; i++) {	/* make an incomplete code set */
			l[i] = 5;
		}
		bd = 5;
		if ((i = huft_build(l, 30, 0, cpdist, cpdext, &td, &bd)) > 1) {
			huft_free(tl);
			return i;
		}

		/* decompress until an end-of-block code */
		inflate_codes(tl, td, bl, bd, 1); // Setup inflate_codes

		/* huft_free code moved into inflate_codes */

		return -2;
	}
	case 2:			/* Inflate dynamic */
	{
		const int dbits = 6;	/* bits in base distance lookup table */
		const int lbits = 9;	/* bits in base literal/length lookup table */

		huft_t *tl;		/* literal/length code table */
		huft_t *td;		/* distance code table */
		unsigned int i;			/* temporary variables */
		unsigned int j;
		unsigned int l;		/* last length */
		unsigned int m;		/* mask for bit lengths table */
		unsigned int n;		/* number of lengths to get */
		unsigned int bl;			/* lookup bits for tl */
		unsigned int bd;			/* lookup bits for td */
		unsigned int nb;	/* number of bit length codes */
		unsigned int nl;	/* number of literal/length codes */
		unsigned int nd;	/* number of distance codes */

		unsigned int ll[286 + 30];	/* literal/length and distance code lengths */
		unsigned int b_dynamic;	/* bit buffer */
		unsigned int k_dynamic;	/* number of bits in bit buffer */

		/* make local bit buffer */
		b_dynamic = gunzip_bb;
		k_dynamic = gunzip_bk;

		/* read in table lengths */
		b_dynamic = fill_bitbuffer(b_dynamic, &k_dynamic, 5);
		nl = 257 + ((unsigned int) b_dynamic & 0x1f);	/* number of literal/length codes */

		b_dynamic >>= 5;
		k_dynamic -= 5;
		b_dynamic = fill_bitbuffer(b_dynamic, &k_dynamic, 5);
		nd = 1 + ((unsigned int) b_dynamic & 0x1f);	/* number of distance codes */

		b_dynamic >>= 5;
		k_dynamic -= 5;
		b_dynamic = fill_bitbuffer(b_dynamic, &k_dynamic, 4);
		nb = 4 + ((unsigned int) b_dynamic & 0xf);	/* number of bit length codes */

		b_dynamic >>= 4;
		k_dynamic -= 4;
		if (nl > 286 || nd > 30) {
			return 1;	/* bad lengths */
		}

		/* read in bit-length-code lengths */
		for (j = 0; j < nb; j++) {
			b_dynamic = fill_bitbuffer(b_dynamic, &k_dynamic, 3);
			ll[border[j]] = (unsigned int) b_dynamic & 7;
			b_dynamic >>= 3;
			k_dynamic -= 3;
		}
		for (; j < 19; j++) {
			ll[border[j]] = 0;
		}

		/* build decoding table for trees--single level, 7 bit lookup */
		bl = 7;
		i = huft_build(ll, 19, 19, NULL, NULL, &tl, &bl);
		if (i != 0) {
			if (i == 1) {
				huft_free(tl);
			}
			return i;	/* incomplete code set */
		}

		/* read in literal and distance code lengths */
		n = nl + nd;
		m = mask_bits[bl];
		i = l = 0;
		while ((unsigned int) i < n) {
			b_dynamic = fill_bitbuffer(b_dynamic, &k_dynamic, (unsigned int)bl);
			j = (td = tl + ((unsigned int) b_dynamic & m))->b;
			b_dynamic >>= j;
			k_dynamic -= j;
			j = td->v.n;
			if (j < 16) {	/* length of code in bits (0..15) */
				ll[i++] = l = j;	/* save last length in l */
			} else if (j == 16) {	/* repeat last length 3 to 6 times */
				b_dynamic = fill_bitbuffer(b_dynamic, &k_dynamic, 2);
				j = 3 + ((unsigned int) b_dynamic & 3);
				b_dynamic >>= 2;
				k_dynamic -= 2;
				if ((unsigned int) i + j > n) {
					return 1;
				}
				while (j--) {
					ll[i++] = l;
				}
			} else if (j == 17) {	/* 3 to 10 zero length codes */
				b_dynamic = fill_bitbuffer(b_dynamic, &k_dynamic, 3);
				j = 3 + ((unsigned int) b_dynamic & 7);
				b_dynamic >>= 3;
				k_dynamic -= 3;
				if ((unsigned int) i + j > n) {
					return 1;
				}
				while (j--) {
					ll[i++] = 0;
				}
				l = 0;
			} else {	/* j == 18: 11 to 138 zero length codes */
				b_dynamic = fill_bitbuffer(b_dynamic, &k_dynamic, 7);
				j = 11 + ((unsigned int) b_dynamic & 0x7f);
				b_dynamic >>= 7;
				k_dynamic -= 7;
				if ((unsigned int) i + j > n) {
					return 1;
				}
				while (j--) {
					ll[i++] = 0;
				}
				l = 0;
			}
		}

		/* free decoding table for trees */
		huft_free(tl);

		/* restore the global bit buffer */
		gunzip_bb = b_dynamic;
		gunzip_bk = k_dynamic;

		/* build the decoding tables for literal/length and distance codes */
		bl = lbits;

		if ((i = huft_build(ll, nl, 257, cplens, cplext, &tl, &bl)) != 0) {
			if (i == 1) {
				bb_error_msg_and_die("incomplete literal tree");
				huft_free(tl);
			}
			return i;	/* incomplete code set */
		}

		bd = dbits;
		if ((i = huft_build(ll + nl, nd, 0, cpdist, cpdext, &td, &bd)) != 0) {
			if (i == 1) {
				bb_error_msg_and_die("incomplete distance tree");
				huft_free(td);
			}
			huft_free(tl);
			return i;	/* incomplete code set */
		}

		/* decompress until an end-of-block code */
		inflate_codes(tl, td, bl, bd, 1); // Setup inflate_codes

		/* huft_free code moved into inflate_codes */

		return -2;
	}
	default:
		/* bad block type */
		bb_error_msg_and_die("bad block type %d", t);
	}
}

static void calculate_gunzip_crc(void)
{
	int n;
	for (n = 0; n < gunzip_outbuf_count; n++) {
		gunzip_crc = gunzip_crc_table[((int) gunzip_crc ^ (gunzip_window[n])) & 0xff] ^ (gunzip_crc >> 8);
	}
	gunzip_bytes_out += gunzip_outbuf_count;
}

static int inflate_get_next_window(void)
{
	static int method = -1; // Method == -1 for stored, -2 for codes
	static int e = 0;
	static int needAnotherBlock = 1;

	gunzip_outbuf_count = 0;

	while(1) {
		int ret;

		if (needAnotherBlock) {
			if(e) {
				calculate_gunzip_crc();
				e = 0;
				needAnotherBlock = 1;
				return 0;
			} // Last block
			method = inflate_block(&e);
			needAnotherBlock = 0;
		}

		switch (method) {
		case -1:	ret = inflate_stored(0,0,0,0);
				break;
		case -2:	ret = inflate_codes(0,0,0,0,0);
				break;
		default:	bb_error_msg_and_die("inflate error %d", method);
		}

		if (ret == 1) {
			calculate_gunzip_crc();
			return 1; // More data left
		} else needAnotherBlock = 1; // End of that block
	}
	/* Doesnt get here */
}

/* Initialise bytebuffer, be careful not to overfill the buffer */
void inflate_init(unsigned int bufsize)
{
	/* Set the bytebuffer size, default is same as gunzip_wsize */
	bytebuffer_max = bufsize + 8;
	bytebuffer_offset = 4;
	bytebuffer_size = 0;
}

void inflate_cleanup(void)
{
	free(bytebuffer);
}

USE_DESKTOP(long long) int
inflate_unzip(int in, int out)
{
	USE_DESKTOP(long long total = 0;)
	ssize_t nwrote;
	typedef void (*sig_type) (int);

	/* Allocate all global buffers (for DYN_ALLOC option) */
	gunzip_window = xmalloc(gunzip_wsize);
	gunzip_outbuf_count = 0;
	gunzip_bytes_out = 0;
	gunzip_src_fd = in;

	/* initialize gunzip_window, bit buffer */
	gunzip_bk = 0;
	gunzip_bb = 0;

	/* Create the crc table */
	gunzip_crc_table = crc32_filltable(0);
	gunzip_crc = ~0;

	/* Allocate space for buffer */
	bytebuffer = xmalloc(bytebuffer_max);

	while(1) {
		int ret = inflate_get_next_window();
		nwrote = full_write(out, gunzip_window, gunzip_outbuf_count);
		if (nwrote == -1) {
			bb_perror_msg("write");
			return -1;
		}
		USE_DESKTOP(total += nwrote;)
		if (ret == 0) break;
	}

	/* Cleanup */
	free(gunzip_window);
	free(gunzip_crc_table);

	/* Store unused bytes in a global buffer so calling applets can access it */
	if (gunzip_bk >= 8) {
		/* Undo too much lookahead. The next read will be byte aligned
		 * so we can discard unused bits in the last meaningful byte. */
		bytebuffer_offset--;
		bytebuffer[bytebuffer_offset] = gunzip_bb & 0xff;
		gunzip_bb >>= 8;
		gunzip_bk -= 8;
	}
	return USE_DESKTOP(total) + 0;
}

USE_DESKTOP(long long) int
inflate_gunzip(int in, int out)
{
	uint32_t stored_crc = 0;
	unsigned int count;
	USE_DESKTOP(long long total = )inflate_unzip(in, out);

	USE_DESKTOP(if (total < 0) return total;)

	/* top up the input buffer with the rest of the trailer */
	count = bytebuffer_size - bytebuffer_offset;
	if (count < 8) {
		xread(in, &bytebuffer[bytebuffer_size], 8 - count);
		bytebuffer_size += 8 - count;
	}
	for (count = 0; count != 4; count++) {
		stored_crc |= (bytebuffer[bytebuffer_offset] << (count * 8));
		bytebuffer_offset++;
	}

	/* Validate decompression - crc */
	if (stored_crc != (~gunzip_crc)) {
		bb_error_msg("crc error");
		return -1;
	}

	/* Validate decompression - size */
	if (gunzip_bytes_out !=
		(bytebuffer[bytebuffer_offset] | (bytebuffer[bytebuffer_offset+1] << 8) |
		(bytebuffer[bytebuffer_offset+2] << 16) | (bytebuffer[bytebuffer_offset+3] << 24))) {
		bb_error_msg("incorrect length");
		return -1;
	}

	return USE_DESKTOP(total) + 0;
}
