/* 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 tarball for details.
*/

/*
	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_unzip() reversing
	the Burrows-Wheeler transformation.  Much of that time is delay
	resulting from cache misses.

	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 "unarchive.h"

/* 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				(-1)
#define RETVAL_NOT_BZIP_DATA			(-2)
#define RETVAL_UNEXPECTED_INPUT_EOF		(-3)
#define RETVAL_UNEXPECTED_OUTPUT_EOF	(-4)
#define RETVAL_DATA_ERROR				(-5)
#define RETVAL_OUT_OF_MEMORY			(-6)
#define RETVAL_OBSOLETE_INPUT			(-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 sentinal 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 */

typedef struct {
	/* State for interrupting output loop */

	int writeCopies,writePos,writeRunCountdown,writeCount,writeCurrent;

	/* I/O tracking data (file handles, buffers, positions, etc.) */

	int in_fd,out_fd,inbufCount,inbufPos /*,outbufPos*/;
	unsigned char *inbuf /*,*outbuf*/;
	unsigned int inbufBitCount, inbufBits;

	/* The CRC values stored in the block header and calculated from the data */

	uint32_t headerCRC, totalCRC, writeCRC;
	uint32_t *crc32Table;
	/* Intermediate buffer and its size (in bytes) */

	unsigned int *dbuf, dbufSize;

	/* These things are a bit too big to go on the stack */

	unsigned char selectors[32768];			/* nSelectors=15 bits */
	struct group_data groups[MAX_GROUPS];	/* Huffman coding tables */

	/* For I/O error handling */

	jmp_buf jmpbuf;
} 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 int get_bits(bunzip_data *bd, char bits_wanted)
{
	unsigned int bits=0;

	/* 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 (bd->inbufBitCount<bits_wanted) {

		/* If we need to read more data from file into byte buffer, do so */

		if(bd->inbufPos==bd->inbufCount) {
			if((bd->inbufCount = read(bd->in_fd, bd->inbuf, IOBUF_SIZE)) <= 0)
				longjmp(bd->jmpbuf,RETVAL_UNEXPECTED_INPUT_EOF);
			bd->inbufPos=0;
		}

		/* Avoid 32-bit overflow (dump bit buffer to top of output) */

		if(bd->inbufBitCount>=24) {
			bits=bd->inbufBits&((1<<bd->inbufBitCount)-1);
			bits_wanted-=bd->inbufBitCount;
			bits<<=bits_wanted;
			bd->inbufBitCount=0;
		}

		/* Grab next 8 bits of input from buffer. */

		bd->inbufBits=(bd->inbufBits<<8)|bd->inbuf[bd->inbufPos++];
		bd->inbufBitCount+=8;
	}

	/* Calculate result */

	bd->inbufBitCount-=bits_wanted;
	bits|=(bd->inbufBits>>bd->inbufBitCount)&((1<<bits_wanted)-1);

	return bits;
}

/* Unpacks the next block and sets up for the inverse burrows-wheeler step. */

static int get_next_block(bunzip_data *bd)
{
	struct group_data *hufGroup;
	int dbufCount,nextSym,dbufSize,groupCount,*base,*limit,selector,
		i,j,k,t,runPos,symCount,symTotal,nSelectors,byteCount[256];
	unsigned char uc, symToByte[256], mtfSymbol[256], *selectors;
	unsigned int *dbuf,origPtr;

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

	/* Reset longjmp I/O error handling */

	i=setjmp(bd->jmpbuf);
	if(i) return i;

	/* 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;
	if((origPtr=get_bits(bd,24)) > 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. */

	t=get_bits(bd, 16);
	symTotal=0;
	for (i=0;i<16;i++) {
		if(t&(1<<(15-i))) {
			k=get_bits(bd,16);
			for(j=0;j<16;j++)
				if(k&(1<<(15-j))) symToByte[symTotal++]=(16*i)+j;
		}
	}

	/* 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.) */

	if(!(nSelectors=get_bits(bd, 15))) return RETVAL_DATA_ERROR;
	for(i=0; i<groupCount; i++) mtfSymbol[i] = i;
	for(i=0; i<nSelectors; i++) {

		/* Get next value */

		for(j=0;get_bits(bd,1);j++) if (j>=groupCount) return RETVAL_DATA_ERROR;

		/* Decode MTF to get the next selector */

		uc = mtfSymbol[j];
		for(;j;j--) mtfSymbol[j] = mtfSymbol[j-1];
		mtfSymbol[0]=selectors[i]=uc;
	}

	/* 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++) {
		unsigned char length[MAX_SYMBOLS],temp[MAX_HUFCODE_BITS+1];
		int	minLen,	maxLen, pp;

		/* 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 everys 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.) */

		t=get_bits(bd, 5)-1;
		for (i = 0; i < symCount; i++) {
			for(;;) {
				if (((unsigned)t) > (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. */

				k = get_bits(bd,2);
				if (k < 2) {
					bd->inbufBitCount++;
					break;
				}

				/* Add one if second bit 1, else subtract 1.  Avoids if/else */

				t+=(((k+1)&2)-1);
			}

			/* Correct for the initial -1, to get the final symbol length */

			length[i]=t+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[].  Concurently, initialize temp[] and limit[]. */

		pp=0;
		for(i=minLen;i<=maxLen;i++) {
			temp[i]=limit[i]=0;
			for(t=0;t<symCount;t++)
				if(length[t]==i) hufGroup->permute[pp++] = t;
		}

		/* Count symbols coded for at each bit length */

		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; 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;
			base[i+1]=pp-(t+=temp[i]);
		}
		limit[maxLen+1] = INT_MAX; /* Sentinal value for reading next sym. */
		limit[maxLen]=pp+temp[maxLen]-1;
		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 */

	for(i=0;i<256;i++) {
		byteCount[i] = 0;
		mtfSymbol[i]=(unsigned char)i;
	}

	/* Loop through compressed symbols. */

	runPos=dbufCount=selector=0;
	for(;;) {

		/* fetch next Huffman coding group from list. */

		symCount=GROUP_SIZE-1;
		if(selector>=nSelectors) return RETVAL_DATA_ERROR;
		hufGroup=bd->groups+selectors[selector++];
		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 an 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.  As a further optimization, we do the read
		   inline (falling back to a call to get_bits if the buffer runs
		   dry).  The following (up to got_huff_bits:) is equivalent to
		   j=get_bits(bd,hufGroup->maxLen);
		 */

		while (bd->inbufBitCount<hufGroup->maxLen) {
			if(bd->inbufPos==bd->inbufCount) {
				j = get_bits(bd,hufGroup->maxLen);
				goto got_huff_bits;
			}
			bd->inbufBits=(bd->inbufBits<<8)|bd->inbuf[bd->inbufPos++];
			bd->inbufBitCount+=8;
		};
		bd->inbufBitCount-=hufGroup->maxLen;
		j = (bd->inbufBits>>bd->inbufBitCount)&((1<<hufGroup->maxLen)-1);

got_huff_bits:

		/* Figure how how many bits are in next symbol and unget extras */

		i=hufGroup->minLen;
		while(j>limit[i]) ++i;
		bd->inbufBitCount += (hufGroup->maxLen - i);

		/* Huffman decode value to get nextSym (with bounds checking) */

		if ((i > hufGroup->maxLen)
			|| (((unsigned)(j=(j>>(hufGroup->maxLen-i))-base[i]))
				>= MAX_SYMBOLS))
			return RETVAL_DATA_ERROR;
		nextSym = hufGroup->permute[j];

		/* 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) {
				runPos = 1;
				t = 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. */

			t += (runPos << nextSym); /* +runPos if RUNA; +2*runPos if RUNB */
			if(runPos < 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) {
			runPos=0;
			if(dbufCount+t>=dbufSize) return RETVAL_DATA_ERROR;

			uc = symToByte[mtfSymbol[0]];
			byteCount[uc] += t;
			while(t--) dbuf[dbufCount++]=uc;
		}

		/* 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>=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++] = (unsigned int)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--) 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++) {
		k=j+byteCount[i];
		byteCount[i] = j;
		j=k;
	}

	/* Figure out what order dbuf would be in if we sorted it. */

	for (i=0;i<dbufCount;i++) {
		uc=(unsigned char)(dbuf[i] & 0xff);
		dbuf[byteCount[uc]] |= (i << 8);
		byteCount[uc]++;
	}

	/* 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) {
		if(origPtr>=dbufCount) return RETVAL_DATA_ERROR;
		bd->writePos=dbuf[origPtr];
	    bd->writeCurrent=(unsigned char)(bd->writePos&0xff);
		bd->writePos>>=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.
*/

static int read_bunzip(bunzip_data *bd, char *outbuf, int len)
{
	const unsigned int *dbuf;
	int pos,current,previous,gotcount;

	/* If last read was short due to end of file, return last block now */
	if(bd->writeCount<0) return bd->writeCount;

	gotcount = 0;
	dbuf=bd->dbuf;
	pos=bd->writePos;
	current=bd->writeCurrent;

	/* 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) {

		/* Inside the loop, writeCopies means extra copies (beyond 1) */

		--bd->writeCopies;

		/* Loop outputting bytes */

		for(;;) {

			/* If the output buffer is full, snapshot state and return */

			if(gotcount >= len) {
				bd->writePos=pos;
				bd->writeCurrent=current;
				bd->writeCopies++;
				return len;
			}

			/* Write next byte into output buffer, updating CRC */

			outbuf[gotcount++] = current;
			bd->writeCRC=(((bd->writeCRC)<<8)
						  ^bd->crc32Table[((bd->writeCRC)>>24)^current]);

			/* Loop now if we're outputting multiple copies of this byte */

			if (bd->writeCopies) {
				--bd->writeCopies;
				continue;
			}
decode_next_byte:
			if (!bd->writeCount--) break;
			/* Follow sequence vector to undo Burrows-Wheeler transform */
			previous=current;
			pos=dbuf[pos];
			current=pos&0xff;
			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) {
				if(current!=previous) bd->writeRunCountdown=4;
			} else {

				/* 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;
			}
		}

		/* Decompression of this block completed successfully */

		bd->writeCRC=~bd->writeCRC;
		bd->totalCRC=((bd->totalCRC<<1) | (bd->totalCRC>>31)) ^ bd->writeCRC;

		/* If this block had a CRC error, force file level CRC error. */

		if(bd->writeCRC!=bd->headerCRC) {
			bd->totalCRC=bd->headerCRC+1;
			return RETVAL_LAST_BLOCK;
		}
	}

	/* Refill the intermediate buffer by Huffman-decoding next block of input */
	/* (previous is just a convenient unused temp variable here) */

	previous=get_next_block(bd);
	if(previous) {
		bd->writeCount=previous;
		return (previous!=RETVAL_LAST_BLOCK) ? previous : gotcount;
	}
	bd->writeCRC=~0;
	pos=bd->writePos;
	current=bd->writeCurrent;
	goto decode_next_byte;
}

/* 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. */

static int start_bunzip(bunzip_data **bdp, int in_fd, unsigned char *inbuf,
						int len)
{
	bunzip_data *bd;
	unsigned int i;
	const unsigned int BZh0=(((unsigned int)'B')<<24)+(((unsigned int)'Z')<<16)
							+(((unsigned int)'h')<<8)+(unsigned int)'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);

	/* Setup input buffer */

	if(-1==(bd->in_fd=in_fd)) {
		bd->inbuf=inbuf;
		bd->inbufCount=len;
	} else bd->inbuf=(unsigned char *)(bd+1);

	/* Init the CRC32 table (big endian) */

	bd->crc32Table = crc32_filltable(1);

	/* Setup for I/O error handling via longjmp */

	i=setjmp(bd->jmpbuf);
	if(i) return i;

	/* Ensure that file starts with "BZh['1'-'9']." */

	i = get_bits(bd,32);
	if (((unsigned int)(i-BZh0-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->dbuf=xmalloc(bd->dbufSize * sizeof(int));
	return RETVAL_OK;
}

/* Example usage: decompress src_fd to dst_fd.  (Stops at end of bzip data,
   not end of file.) */

USE_DESKTOP(long long) int
uncompressStream(int src_fd, int dst_fd)
{
	USE_DESKTOP(long long total_written = 0;)
	char *outbuf;
	bunzip_data *bd;
	int i;

	outbuf=xmalloc(IOBUF_SIZE);
	i=start_bunzip(&bd,src_fd,0,0);
	if(!i) {
		for(;;) {
			if((i=read_bunzip(bd,outbuf,IOBUF_SIZE)) <= 0) break;
			if(i!=write(dst_fd,outbuf,i)) {
				i=RETVAL_UNEXPECTED_OUTPUT_EOF;
				break;
			}
			USE_DESKTOP(total_written += i;)
		}
	}

	/* Check CRC and release memory */

	if(i==RETVAL_LAST_BLOCK) {
		if (bd->headerCRC!=bd->totalCRC) {
			bb_error_msg("data integrity error when decompressing");
		} else {
			i=RETVAL_OK;
		}
	} else if (i==RETVAL_UNEXPECTED_OUTPUT_EOF) {
		bb_error_msg("compressed file ends unexpectedly");
	} else {
		bb_error_msg("decompression failed");
	}
	free(bd->dbuf);
	free(bd);
	free(outbuf);

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

#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[])
{
	int i=uncompressStream(0,1);
	char c;

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