/* vi: set sw=4 ts=4: */
/*
 * Small bzip2 deflate implementation, by Rob Landley (rob@landley.net).
 *
 * Based on bzip2 decompression code by Julian R Seward (jseward@acm.org),
 * which also acknowledges contributions by Mike Burrows, David Wheeler,
 * Peter Fenwick, Alistair Moffat, Radford Neal, Ian H. Witten,
 * Robert Sedgewick, and Jon L. Bentley.
 *
 * Licensed under GPLv2 or later, see file LICENSE in this source tree.
 */
/*
	Size and speed optimizations by Manuel Novoa III  (mjn3@codepoet.org).

	More efficient reading of Huffman codes, a streamlined read_bunzip()
	function, and various other tweaks.  In (limited) tests, approximately
	20% faster than bzcat on x86 and about 10% faster on arm.

	Note that about 2/3 of the time is spent in read_bunzip() reversing
	the Burrows-Wheeler transformation.  Much of that time is delay
	resulting from cache misses.

	(2010 update by vda: profiled "bzcat <84mbyte.bz2 >/dev/null"
	on x86-64 CPU with L2 > 1M: get_next_block is hotter than read_bunzip:
	%time seconds   calls function
	71.01   12.69     444 get_next_block
	28.65    5.12   93065 read_bunzip
	00.22    0.04 7736490 get_bits
	00.11    0.02      47 dealloc_bunzip
	00.00    0.00   93018 full_write
	...)


	I would ask that anyone benefiting from this work, especially those
	using it in commercial products, consider making a donation to my local
	non-profit hospice organization (www.hospiceacadiana.com) in the name of
	the woman I loved, Toni W. Hagan, who passed away Feb. 12, 2003.

	Manuel
 */
#include "libbb.h"
#include "bb_archive.h"

#if 0
# define dbg(...) bb_error_msg(__VA_ARGS__)
#else
# define dbg(...) ((void)0)
#endif

/* Constants for Huffman coding */
#define MAX_GROUPS          6
#define GROUP_SIZE          50      /* 64 would have been more efficient */
#define MAX_HUFCODE_BITS    20      /* Longest Huffman code allowed */
#define MAX_SYMBOLS         258     /* 256 literals + RUNA + RUNB */
#define SYMBOL_RUNA         0
#define SYMBOL_RUNB         1

/* Status return values */
#define RETVAL_OK                       0
#define RETVAL_LAST_BLOCK               (dbg("%d", __LINE__), -1)
#define RETVAL_NOT_BZIP_DATA            (dbg("%d", __LINE__), -2)
#define RETVAL_UNEXPECTED_INPUT_EOF     (dbg("%d", __LINE__), -3)
#define RETVAL_SHORT_WRITE              (dbg("%d", __LINE__), -4)
#define RETVAL_DATA_ERROR               (dbg("%d", __LINE__), -5)
#define RETVAL_OUT_OF_MEMORY            (dbg("%d", __LINE__), -6)
#define RETVAL_OBSOLETE_INPUT           (dbg("%d", __LINE__), -7)

/* Other housekeeping constants */
#define IOBUF_SIZE          4096

/* This is what we know about each Huffman coding group */
struct group_data {
	/* We have an extra slot at the end of limit[] for a sentinel value. */
	int limit[MAX_HUFCODE_BITS+1], base[MAX_HUFCODE_BITS], permute[MAX_SYMBOLS];
	int minLen, maxLen;
};

/* Structure holding all the housekeeping data, including IO buffers and
 * memory that persists between calls to bunzip
 * Found the most used member:
 *  cat this_file.c | sed -e 's/"/ /g' -e "s/'/ /g" | xargs -n1 \
 *  | grep 'bd->' | sed 's/^.*bd->/bd->/' | sort | $PAGER
 * and moved it (inbufBitCount) to offset 0.
 */
struct bunzip_data {
	/* I/O tracking data (file handles, buffers, positions, etc.) */
	unsigned inbufBitCount, inbufBits;
	int in_fd, out_fd, inbufCount, inbufPos /*, outbufPos*/;
	uint8_t *inbuf /*,*outbuf*/;

	/* State for interrupting output loop */
	int writeCopies, writePos, writeRunCountdown, writeCount;
	int writeCurrent; /* actually a uint8_t */

	/* The CRC values stored in the block header and calculated from the data */
	uint32_t headerCRC, totalCRC, writeCRC;

	/* Intermediate buffer and its size (in bytes) */
	uint32_t *dbuf;
	unsigned dbufSize;

	/* For I/O error handling */
	jmp_buf *jmpbuf;

	/* Big things go last (register-relative addressing can be larger for big offsets) */
	uint32_t crc32Table[256];
	uint8_t selectors[32768];  /* nSelectors=15 bits */
	struct group_data groups[MAX_GROUPS];  /* Huffman coding tables */
};
typedef struct bunzip_data bunzip_data;


/* Return the next nnn bits of input.  All reads from the compressed input
   are done through this function.  All reads are big endian */
static unsigned get_bits(bunzip_data *bd, int bits_wanted)
{
	unsigned bits = 0;
	/* Cache bd->inbufBitCount in a CPU register (hopefully): */
	int bit_count = bd->inbufBitCount;

	/* If we need to get more data from the byte buffer, do so.  (Loop getting
	   one byte at a time to enforce endianness and avoid unaligned access.) */
	while (bit_count < bits_wanted) {

		/* If we need to read more data from file into byte buffer, do so */
		if (bd->inbufPos == bd->inbufCount) {
			/* if "no input fd" case: in_fd == -1, read fails, we jump */
			bd->inbufCount = read(bd->in_fd, bd->inbuf, IOBUF_SIZE);
			if (bd->inbufCount <= 0)
				longjmp(*bd->jmpbuf, RETVAL_UNEXPECTED_INPUT_EOF);
			bd->inbufPos = 0;
		}

		/* Avoid 32-bit overflow (dump bit buffer to top of output) */
		if (bit_count >= 24) {
			bits = bd->inbufBits & ((1U << bit_count) - 1);
			bits_wanted -= bit_count;
			bits <<= bits_wanted;
			bit_count = 0;
		}

		/* Grab next 8 bits of input from buffer. */
		bd->inbufBits = (bd->inbufBits << 8) | bd->inbuf[bd->inbufPos++];
		bit_count += 8;
	}

	/* Calculate result */
	bit_count -= bits_wanted;
	bd->inbufBitCount = bit_count;
	bits |= (bd->inbufBits >> bit_count) & ((1 << bits_wanted) - 1);

	return bits;
}
//#define get_bits(bd, n) (dbg("%d:get_bits()", __LINE__), get_bits(bd, n))

/* Unpacks the next block and sets up for the inverse Burrows-Wheeler step. */
static int get_next_block(bunzip_data *bd)
{
	int groupCount, selector,
		i, j, symCount, symTotal, nSelectors, byteCount[256];
	uint8_t uc, symToByte[256], mtfSymbol[256], *selectors;
	uint32_t *dbuf;
	unsigned origPtr, t;
	unsigned dbufCount, runPos;
	unsigned runCnt = runCnt; /* for compiler */

	dbuf = bd->dbuf;
	selectors = bd->selectors;

/* In bbox, we are ok with aborting through setjmp which is set up in start_bunzip */
#if 0
	/* Reset longjmp I/O error handling */
	i = setjmp(bd->jmpbuf);
	if (i) return i;
#endif

	/* Read in header signature and CRC, then validate signature.
	   (last block signature means CRC is for whole file, return now) */
	i = get_bits(bd, 24);
	j = get_bits(bd, 24);
	bd->headerCRC = get_bits(bd, 32);
	if ((i == 0x177245) && (j == 0x385090))
		return RETVAL_LAST_BLOCK;
	if ((i != 0x314159) || (j != 0x265359))
		return RETVAL_NOT_BZIP_DATA;

	/* We can add support for blockRandomised if anybody complains.  There was
	   some code for this in busybox 1.0.0-pre3, but nobody ever noticed that
	   it didn't actually work. */
	if (get_bits(bd, 1))
		return RETVAL_OBSOLETE_INPUT;
	origPtr = get_bits(bd, 24);
	if (origPtr > bd->dbufSize)
		return RETVAL_DATA_ERROR;

	/* mapping table: if some byte values are never used (encoding things
	   like ascii text), the compression code removes the gaps to have fewer
	   symbols to deal with, and writes a sparse bitfield indicating which
	   values were present.  We make a translation table to convert the symbols
	   back to the corresponding bytes. */
	symTotal = 0;
	i = 0;
	t = get_bits(bd, 16);
	do {
		if (t & (1 << 15)) {
			unsigned inner_map = get_bits(bd, 16);
			do {
				if (inner_map & (1 << 15))
					symToByte[symTotal++] = i;
				inner_map <<= 1;
				i++;
			} while (i & 15);
			i -= 16;
		}
		t <<= 1;
		i += 16;
	} while (i < 256);

	/* How many different Huffman coding groups does this block use? */
	groupCount = get_bits(bd, 3);
	if (groupCount < 2 || groupCount > MAX_GROUPS)
		return RETVAL_DATA_ERROR;

	/* nSelectors: Every GROUP_SIZE many symbols we select a new Huffman coding
	   group.  Read in the group selector list, which is stored as MTF encoded
	   bit runs.  (MTF=Move To Front, as each value is used it's moved to the
	   start of the list.) */
	for (i = 0; i < groupCount; i++)
		mtfSymbol[i] = i;
	nSelectors = get_bits(bd, 15);
	if (!nSelectors)
		return RETVAL_DATA_ERROR;
	for (i = 0; i < nSelectors; i++) {
		uint8_t tmp_byte;
		/* Get next value */
		int n = 0;
		while (get_bits(bd, 1)) {
			n++;
			if (n >= groupCount)
				return RETVAL_DATA_ERROR;
		}
		/* Decode MTF to get the next selector */
		tmp_byte = mtfSymbol[n];
		while (--n >= 0)
			mtfSymbol[n + 1] = mtfSymbol[n];
//We catch it later, in the second loop where we use selectors[i].
//Maybe this is a better place, though?
//		if (tmp_byte >= groupCount) {
//			dbg("%d: selectors[%d]:%d groupCount:%d",
//					__LINE__, i, tmp_byte, groupCount);
//			return RETVAL_DATA_ERROR;
//		}
		mtfSymbol[0] = selectors[i] = tmp_byte;
	}

	/* Read the Huffman coding tables for each group, which code for symTotal
	   literal symbols, plus two run symbols (RUNA, RUNB) */
	symCount = symTotal + 2;
	for (j = 0; j < groupCount; j++) {
		uint8_t length[MAX_SYMBOLS];
		/* 8 bits is ALMOST enough for temp[], see below */
		unsigned temp[MAX_HUFCODE_BITS+1];
		struct group_data *hufGroup;
		int *base, *limit;
		int minLen, maxLen, pp, len_m1;

		/* Read Huffman code lengths for each symbol.  They're stored in
		   a way similar to mtf; record a starting value for the first symbol,
		   and an offset from the previous value for every symbol after that.
		   (Subtracting 1 before the loop and then adding it back at the end is
		   an optimization that makes the test inside the loop simpler: symbol
		   length 0 becomes negative, so an unsigned inequality catches it.) */
		len_m1 = get_bits(bd, 5) - 1;
		for (i = 0; i < symCount; i++) {
			for (;;) {
				int two_bits;
				if ((unsigned)len_m1 > (MAX_HUFCODE_BITS-1))
					return RETVAL_DATA_ERROR;

				/* If first bit is 0, stop.  Else second bit indicates whether
				   to increment or decrement the value.  Optimization: grab 2
				   bits and unget the second if the first was 0. */
				two_bits = get_bits(bd, 2);
				if (two_bits < 2) {
					bd->inbufBitCount++;
					break;
				}

				/* Add one if second bit 1, else subtract 1.  Avoids if/else */
				len_m1 += (((two_bits+1) & 2) - 1);
			}

			/* Correct for the initial -1, to get the final symbol length */
			length[i] = len_m1 + 1;
		}

		/* Find largest and smallest lengths in this group */
		minLen = maxLen = length[0];
		for (i = 1; i < symCount; i++) {
			if (length[i] > maxLen)
				maxLen = length[i];
			else if (length[i] < minLen)
				minLen = length[i];
		}

		/* Calculate permute[], base[], and limit[] tables from length[].
		 *
		 * permute[] is the lookup table for converting Huffman coded symbols
		 * into decoded symbols.  base[] is the amount to subtract from the
		 * value of a Huffman symbol of a given length when using permute[].
		 *
		 * limit[] indicates the largest numerical value a symbol with a given
		 * number of bits can have.  This is how the Huffman codes can vary in
		 * length: each code with a value>limit[length] needs another bit.
		 */
		hufGroup = bd->groups + j;
		hufGroup->minLen = minLen;
		hufGroup->maxLen = maxLen;

		/* Note that minLen can't be smaller than 1, so we adjust the base
		   and limit array pointers so we're not always wasting the first
		   entry.  We do this again when using them (during symbol decoding). */
		base = hufGroup->base - 1;
		limit = hufGroup->limit - 1;

		/* Calculate permute[].  Concurrently, initialize temp[] and limit[]. */
		pp = 0;
		for (i = minLen; i <= maxLen; i++) {
			int k;
			temp[i] = limit[i] = 0;
			for (k = 0; k < symCount; k++)
				if (length[k] == i)
					hufGroup->permute[pp++] = k;
		}

		/* Count symbols coded for at each bit length */
		/* NB: in pathological cases, temp[8] can end ip being 256.
		 * That's why uint8_t is too small for temp[]. */
		for (i = 0; i < symCount; i++)
			temp[length[i]]++;

		/* Calculate limit[] (the largest symbol-coding value at each bit
		 * length, which is (previous limit<<1)+symbols at this level), and
		 * base[] (number of symbols to ignore at each bit length, which is
		 * limit minus the cumulative count of symbols coded for already). */
		pp = t = 0;
		for (i = minLen; i < maxLen;) {
			unsigned temp_i = temp[i];

			pp += temp_i;

			/* We read the largest possible symbol size and then unget bits
			   after determining how many we need, and those extra bits could
			   be set to anything.  (They're noise from future symbols.)  At
			   each level we're really only interested in the first few bits,
			   so here we set all the trailing to-be-ignored bits to 1 so they
			   don't affect the value>limit[length] comparison. */
			limit[i] = (pp << (maxLen - i)) - 1;
			pp <<= 1;
			t += temp_i;
			base[++i] = pp - t;
		}
		limit[maxLen] = pp + temp[maxLen] - 1;
		limit[maxLen+1] = INT_MAX; /* Sentinel value for reading next sym. */
		base[minLen] = 0;
	}

	/* We've finished reading and digesting the block header.  Now read this
	   block's Huffman coded symbols from the file and undo the Huffman coding
	   and run length encoding, saving the result into dbuf[dbufCount++] = uc */

	/* Initialize symbol occurrence counters and symbol Move To Front table */
	/*memset(byteCount, 0, sizeof(byteCount)); - smaller, but slower */
	for (i = 0; i < 256; i++) {
		byteCount[i] = 0;
		mtfSymbol[i] = (uint8_t)i;
	}

	/* Loop through compressed symbols. */

	runPos = dbufCount = selector = 0;
	for (;;) {
		struct group_data *hufGroup;
		int *base, *limit;
		int nextSym;
		uint8_t ngrp;

		/* Fetch next Huffman coding group from list. */
		symCount = GROUP_SIZE - 1;
		if (selector >= nSelectors)
			return RETVAL_DATA_ERROR;
		ngrp = selectors[selector++];
		if (ngrp >= groupCount) {
			dbg("%d selectors[%d]:%d groupCount:%d",
				__LINE__, selector-1, ngrp, groupCount);
			return RETVAL_DATA_ERROR;
		}
		hufGroup = bd->groups + ngrp;
		base = hufGroup->base - 1;
		limit = hufGroup->limit - 1;

 continue_this_group:
		/* Read next Huffman-coded symbol. */

		/* Note: It is far cheaper to read maxLen bits and back up than it is
		   to read minLen bits and then add additional bit at a time, testing
		   as we go.  Because there is a trailing last block (with file CRC),
		   there is no danger of the overread causing an unexpected EOF for a
		   valid compressed file.
		 */
		if (1) {
			/* As a further optimization, we do the read inline
			   (falling back to a call to get_bits if the buffer runs dry).
			 */
			int new_cnt;
			while ((new_cnt = bd->inbufBitCount - hufGroup->maxLen) < 0) {
				/* bd->inbufBitCount < hufGroup->maxLen */
				if (bd->inbufPos == bd->inbufCount) {
					nextSym = get_bits(bd, hufGroup->maxLen);
					goto got_huff_bits;
				}
				bd->inbufBits = (bd->inbufBits << 8) | bd->inbuf[bd->inbufPos++];
				bd->inbufBitCount += 8;
			};
			bd->inbufBitCount = new_cnt; /* "bd->inbufBitCount -= hufGroup->maxLen;" */
			nextSym = (bd->inbufBits >> new_cnt) & ((1 << hufGroup->maxLen) - 1);
 got_huff_bits: ;
		} else { /* unoptimized equivalent */
			nextSym = get_bits(bd, hufGroup->maxLen);
		}
		/* Figure how many bits are in next symbol and unget extras */
		i = hufGroup->minLen;
		while (nextSym > limit[i])
			++i;
		j = hufGroup->maxLen - i;
		if (j < 0)
			return RETVAL_DATA_ERROR;
		bd->inbufBitCount += j;

		/* Huffman decode value to get nextSym (with bounds checking) */
		nextSym = (nextSym >> j) - base[i];
		if ((unsigned)nextSym >= MAX_SYMBOLS)
			return RETVAL_DATA_ERROR;
		nextSym = hufGroup->permute[nextSym];

		/* We have now decoded the symbol, which indicates either a new literal
		   byte, or a repeated run of the most recent literal byte.  First,
		   check if nextSym indicates a repeated run, and if so loop collecting
		   how many times to repeat the last literal. */
		if ((unsigned)nextSym <= SYMBOL_RUNB) { /* RUNA or RUNB */

			/* If this is the start of a new run, zero out counter */
			if (runPos == 0) {
				runPos = 1;
				runCnt = 0;
			}

			/* Neat trick that saves 1 symbol: instead of or-ing 0 or 1 at
			   each bit position, add 1 or 2 instead.  For example,
			   1011 is 1<<0 + 1<<1 + 2<<2.  1010 is 2<<0 + 2<<1 + 1<<2.
			   You can make any bit pattern that way using 1 less symbol than
			   the basic or 0/1 method (except all bits 0, which would use no
			   symbols, but a run of length 0 doesn't mean anything in this
			   context).  Thus space is saved. */
			runCnt += (runPos << nextSym); /* +runPos if RUNA; +2*runPos if RUNB */
//The 32-bit overflow of runCnt wasn't yet seen, but probably can happen.
//This would be the fix (catches too large count way before it can overflow):
//			if (runCnt > bd->dbufSize) {
//				dbg("runCnt:%u > dbufSize:%u RETVAL_DATA_ERROR",
//						runCnt, bd->dbufSize);
//				return RETVAL_DATA_ERROR;
//			}
			if (runPos < bd->dbufSize) runPos <<= 1;
			goto end_of_huffman_loop;
		}

		/* When we hit the first non-run symbol after a run, we now know
		   how many times to repeat the last literal, so append that many
		   copies to our buffer of decoded symbols (dbuf) now.  (The last
		   literal used is the one at the head of the mtfSymbol array.) */
		if (runPos != 0) {
			uint8_t tmp_byte;
			if (dbufCount + runCnt > bd->dbufSize) {
				dbg("dbufCount:%u+runCnt:%u %u > dbufSize:%u RETVAL_DATA_ERROR",
						dbufCount, runCnt, dbufCount + runCnt, bd->dbufSize);
				return RETVAL_DATA_ERROR;
			}
			tmp_byte = symToByte[mtfSymbol[0]];
			byteCount[tmp_byte] += runCnt;
			while ((int)--runCnt >= 0)
				dbuf[dbufCount++] = (uint32_t)tmp_byte;
			runPos = 0;
		}

		/* Is this the terminating symbol? */
		if (nextSym > symTotal) break;

		/* At this point, nextSym indicates a new literal character.  Subtract
		   one to get the position in the MTF array at which this literal is
		   currently to be found.  (Note that the result can't be -1 or 0,
		   because 0 and 1 are RUNA and RUNB.  But another instance of the
		   first symbol in the mtf array, position 0, would have been handled
		   as part of a run above.  Therefore 1 unused mtf position minus
		   2 non-literal nextSym values equals -1.) */
		if (dbufCount >= bd->dbufSize) return RETVAL_DATA_ERROR;
		i = nextSym - 1;
		uc = mtfSymbol[i];

		/* Adjust the MTF array.  Since we typically expect to move only a
		 * small number of symbols, and are bound by 256 in any case, using
		 * memmove here would typically be bigger and slower due to function
		 * call overhead and other assorted setup costs. */
		do {
			mtfSymbol[i] = mtfSymbol[i-1];
		} while (--i);
		mtfSymbol[0] = uc;
		uc = symToByte[uc];

		/* We have our literal byte.  Save it into dbuf. */
		byteCount[uc]++;
		dbuf[dbufCount++] = (uint32_t)uc;

		/* Skip group initialization if we're not done with this group.  Done
		 * this way to avoid compiler warning. */
 end_of_huffman_loop:
		if (--symCount >= 0) goto continue_this_group;
	}

	/* At this point, we've read all the Huffman-coded symbols (and repeated
	   runs) for this block from the input stream, and decoded them into the
	   intermediate buffer.  There are dbufCount many decoded bytes in dbuf[].
	   Now undo the Burrows-Wheeler transform on dbuf.
	   See http://dogma.net/markn/articles/bwt/bwt.htm
	 */

	/* Turn byteCount into cumulative occurrence counts of 0 to n-1. */
	j = 0;
	for (i = 0; i < 256; i++) {
		int tmp_count = j + byteCount[i];
		byteCount[i] = j;
		j = tmp_count;
	}

	/* Figure out what order dbuf would be in if we sorted it. */
	for (i = 0; i < dbufCount; i++) {
		uint8_t tmp_byte = (uint8_t)dbuf[i];
		int tmp_count = byteCount[tmp_byte];
		dbuf[tmp_count] |= (i << 8);
		byteCount[tmp_byte] = tmp_count + 1;
	}

	/* Decode first byte by hand to initialize "previous" byte.  Note that it
	   doesn't get output, and if the first three characters are identical
	   it doesn't qualify as a run (hence writeRunCountdown=5). */
	if (dbufCount) {
		uint32_t tmp;
		if ((int)origPtr >= dbufCount) return RETVAL_DATA_ERROR;
		tmp = dbuf[origPtr];
		bd->writeCurrent = (uint8_t)tmp;
		bd->writePos = (tmp >> 8);
		bd->writeRunCountdown = 5;
	}
	bd->writeCount = dbufCount;

	return RETVAL_OK;
}

/* Undo Burrows-Wheeler transform on intermediate buffer to produce output.
   If start_bunzip was initialized with out_fd=-1, then up to len bytes of
   data are written to outbuf.  Return value is number of bytes written or
   error (all errors are negative numbers).  If out_fd!=-1, outbuf and len
   are ignored, data is written to out_fd and return is RETVAL_OK or error.

   NB: read_bunzip returns < 0 on error, or the number of *unfilled* bytes
   in outbuf. IOW: on EOF returns len ("all bytes are not filled"), not 0.
   (Why? This allows to get rid of one local variable)
*/
static int read_bunzip(bunzip_data *bd, char *outbuf, int len)
{
	const uint32_t *dbuf;
	int pos, current, previous;
	uint32_t CRC;

	/* If we already have error/end indicator, return it */
	if (bd->writeCount < 0)
		return bd->writeCount;

	dbuf = bd->dbuf;

	/* Register-cached state (hopefully): */
	pos = bd->writePos;
	current = bd->writeCurrent;
	CRC = bd->writeCRC; /* small loss on x86-32 (not enough regs), win on x86-64 */

	/* We will always have pending decoded data to write into the output
	   buffer unless this is the very first call (in which case we haven't
	   Huffman-decoded a block into the intermediate buffer yet). */
	if (bd->writeCopies) {

 dec_writeCopies:
		/* Inside the loop, writeCopies means extra copies (beyond 1) */
		--bd->writeCopies;

		/* Loop outputting bytes */
		for (;;) {

			/* If the output buffer is full, save cached state and return */
			if (--len < 0) {
				/* Unlikely branch.
				 * Use of "goto" instead of keeping code here
				 * helps compiler to realize this. */
				goto outbuf_full;
			}

			/* Write next byte into output buffer, updating CRC */
			*outbuf++ = current;
			CRC = (CRC << 8) ^ bd->crc32Table[(CRC >> 24) ^ current];

			/* Loop now if we're outputting multiple copies of this byte */
			if (bd->writeCopies) {
				/* Unlikely branch */
				/*--bd->writeCopies;*/
				/*continue;*/
				/* Same, but (ab)using other existing --writeCopies operation
				 * (and this if() compiles into just test+branch pair): */
				goto dec_writeCopies;
			}
 decode_next_byte:
			if (--bd->writeCount < 0)
				break; /* input block is fully consumed, need next one */

			/* Follow sequence vector to undo Burrows-Wheeler transform */
			previous = current;
			pos = dbuf[pos];
			current = (uint8_t)pos;
			pos >>= 8;

			/* After 3 consecutive copies of the same byte, the 4th
			 * is a repeat count.  We count down from 4 instead
			 * of counting up because testing for non-zero is faster */
			if (--bd->writeRunCountdown != 0) {
				if (current != previous)
					bd->writeRunCountdown = 4;
			} else {
				/* Unlikely branch */
				/* We have a repeated run, this byte indicates the count */
				bd->writeCopies = current;
				current = previous;
				bd->writeRunCountdown = 5;

				/* Sometimes there are just 3 bytes (run length 0) */
				if (!bd->writeCopies) goto decode_next_byte;

				/* Subtract the 1 copy we'd output anyway to get extras */
				--bd->writeCopies;
			}
		} /* for(;;) */

		/* Decompression of this input block completed successfully */
		bd->writeCRC = CRC = ~CRC;
		bd->totalCRC = ((bd->totalCRC << 1) | (bd->totalCRC >> 31)) ^ CRC;

		/* If this block had a CRC error, force file level CRC error */
		if (CRC != bd->headerCRC) {
			bd->totalCRC = bd->headerCRC + 1;
			return RETVAL_LAST_BLOCK;
		}
	}

	/* Refill the intermediate buffer by Huffman-decoding next block of input */
	{
		int r = get_next_block(bd);
		if (r) { /* error/end */
			bd->writeCount = r;
			return (r != RETVAL_LAST_BLOCK) ? r : len;
		}
	}

	CRC = ~0;
	pos = bd->writePos;
	current = bd->writeCurrent;
	goto decode_next_byte;

 outbuf_full:
	/* Output buffer is full, save cached state and return */
	bd->writePos = pos;
	bd->writeCurrent = current;
	bd->writeCRC = CRC;

	bd->writeCopies++;

	return 0;
}

/* Allocate the structure, read file header.  If in_fd==-1, inbuf must contain
   a complete bunzip file (len bytes long).  If in_fd!=-1, inbuf and len are
   ignored, and data is read from file handle into temporary buffer. */

/* Because bunzip2 is used for help text unpacking, and because bb_show_usage()
   should work for NOFORK applets too, we must be extremely careful to not leak
   any allocations! */
static int FAST_FUNC start_bunzip(
		void *jmpbuf,
		bunzip_data **bdp,
		int in_fd,
		const void *inbuf, int len)
{
	bunzip_data *bd;
	unsigned i;
	enum {
		BZh0 = ('B' << 24) + ('Z' << 16) + ('h' << 8) + '0',
		h0 = ('h' << 8) + '0',
	};

	/* Figure out how much data to allocate */
	i = sizeof(bunzip_data);
	if (in_fd != -1)
		i += IOBUF_SIZE;

	/* Allocate bunzip_data.  Most fields initialize to zero. */
	bd = *bdp = xzalloc(i);

	bd->jmpbuf = jmpbuf;

	/* Setup input buffer */
	bd->in_fd = in_fd;
	if (-1 == in_fd) {
		/* in this case, bd->inbuf is read-only */
		bd->inbuf = (void*)inbuf; /* cast away const-ness */
	} else {
		bd->inbuf = (uint8_t*)(bd + 1);
		memcpy(bd->inbuf, inbuf, len);
	}
	bd->inbufCount = len;

	/* Init the CRC32 table (big endian) */
	crc32_filltable(bd->crc32Table, 1);

	/* Ensure that file starts with "BZh['1'-'9']." */
	/* Update: now caller verifies 1st two bytes, makes .gz/.bz2
	 * integration easier */
	/* was: */
	/* i = get_bits(bd, 32); */
	/* if ((unsigned)(i - BZh0 - 1) >= 9) return RETVAL_NOT_BZIP_DATA; */
	i = get_bits(bd, 16);
	if ((unsigned)(i - h0 - 1) >= 9) return RETVAL_NOT_BZIP_DATA;

	/* Fourth byte (ascii '1'-'9') indicates block size in units of 100k of
	   uncompressed data.  Allocate intermediate buffer for block. */
	/* bd->dbufSize = 100000 * (i - BZh0); */
	bd->dbufSize = 100000 * (i - h0);

	/* Cannot use xmalloc - may leak bd in NOFORK case! */
	bd->dbuf = malloc_or_warn(bd->dbufSize * sizeof(bd->dbuf[0]));
	if (!bd->dbuf) {
		free(bd);
		xfunc_die();
	}
	return RETVAL_OK;
}

static void FAST_FUNC dealloc_bunzip(bunzip_data *bd)
{
	free(bd->dbuf);
	free(bd);
}


/* Decompress src_fd to dst_fd.  Stops at end of bzip data, not end of file. */
IF_DESKTOP(long long) int FAST_FUNC
unpack_bz2_stream(transformer_state_t *xstate)
{
	IF_DESKTOP(long long total_written = 0;)
	bunzip_data *bd;
	char *outbuf;
	int i;
	unsigned len;

	if (check_signature16(xstate, BZIP2_MAGIC))
		return -1;

	outbuf = xmalloc(IOBUF_SIZE);
	len = 0;
	while (1) { /* "Process one BZ... stream" loop */
		jmp_buf jmpbuf;

		/* Setup for I/O error handling via longjmp */
		i = setjmp(jmpbuf);
		if (i == 0)
			i = start_bunzip(&jmpbuf, &bd, xstate->src_fd, outbuf + 2, len);

		if (i == 0) {
			while (1) { /* "Produce some output bytes" loop */
				i = read_bunzip(bd, outbuf, IOBUF_SIZE);
				if (i < 0) /* error? */
					break;
				i = IOBUF_SIZE - i; /* number of bytes produced */
				if (i == 0) /* EOF? */
					break;
				if (i != transformer_write(xstate, outbuf, i)) {
					i = RETVAL_SHORT_WRITE;
					goto release_mem;
				}
				IF_DESKTOP(total_written += i;)
			}
		}

		if (i != RETVAL_LAST_BLOCK
		/* Observed case when i == RETVAL_OK:
		 * "bzcat z.bz2", where "z.bz2" is a bzipped zero-length file
		 * (to be exact, z.bz2 is exactly these 14 bytes:
		 * 42 5a 68 39 17 72 45 38 50 90 00 00 00 00).
		 */
		 && i != RETVAL_OK
		) {
			bb_error_msg("bunzip error %d", i);
			break;
		}
		if (bd->headerCRC != bd->totalCRC) {
			bb_simple_error_msg("CRC error");
			break;
		}

		/* Successfully unpacked one BZ stream */
		i = RETVAL_OK;

		/* Do we have "BZ..." after last processed byte?
		 * pbzip2 (parallelized bzip2) produces such files.
		 */
		len = bd->inbufCount - bd->inbufPos;
		memcpy(outbuf, &bd->inbuf[bd->inbufPos], len);
		if (len < 2) {
			if (safe_read(xstate->src_fd, outbuf + len, 2 - len) != 2 - len)
				break;
			len = 2;
		}
		if (*(uint16_t*)outbuf != BZIP2_MAGIC) /* "BZ"? */
			break;
		dealloc_bunzip(bd);
		len -= 2;
	}

 release_mem:
	dealloc_bunzip(bd);
	free(outbuf);

	return i ? i : IF_DESKTOP(total_written) + 0;
}

char* FAST_FUNC
unpack_bz2_data(const char *packed, int packed_len, int unpacked_len)
{
	char *outbuf = NULL;
	bunzip_data *bd;
	int i;
	jmp_buf jmpbuf;

	/* Setup for I/O error handling via longjmp */
	i = setjmp(jmpbuf);
	if (i == 0) {
		i = start_bunzip(&jmpbuf,
			&bd,
			/* src_fd: */ -1,
			/* inbuf:  */ packed,
			/* len:    */ packed_len
		);
	}
	/* read_bunzip can longjmp and end up here with i != 0
	 * on read data errors! Not trivial */
	if (i == 0) {
		/* Cannot use xmalloc: will leak bd in NOFORK case! */
		outbuf = malloc_or_warn(unpacked_len);
		if (outbuf)
			read_bunzip(bd, outbuf, unpacked_len);
	}
	dealloc_bunzip(bd);
	return outbuf;
}

#ifdef TESTING

static char *const bunzip_errors[] = {
	NULL, "Bad file checksum", "Not bzip data",
	"Unexpected input EOF", "Unexpected output EOF", "Data error",
	"Out of memory", "Obsolete (pre 0.9.5) bzip format not supported"
};

/* Dumb little test thing, decompress stdin to stdout */
int main(int argc, char **argv)
{
	char c;

	int i = unpack_bz2_stream(0, 1);
	if (i < 0)
		fprintf(stderr, "%s\n", bunzip_errors[-i]);
	else if (read(STDIN_FILENO, &c, 1))
		fprintf(stderr, "Trailing garbage ignored\n");
	return -i;
}
#endif
