blob: ff7d64d83d8fe41476590c0fb6f90a6bc4210e9b [file] [log] [blame]
Eric Andersen0d6d88a2003-10-18 01:58:35 +00001/* vi: set sw=4 ts=4: */
Rob Landleye66c7ef2006-04-14 19:25:01 +00002/* Small bzip2 deflate implementation, by Rob Landley (rob@landley.net).
Glenn L McGrath60bce492002-11-03 07:28:38 +00003
Rob Landleye66c7ef2006-04-14 19:25:01 +00004 Based on bzip2 decompression code by Julian R Seward (jseward@acm.org),
5 which also acknowledges contributions by Mike Burrows, David Wheeler,
6 Peter Fenwick, Alistair Moffat, Radford Neal, Ian H. Witten,
7 Robert Sedgewick, and Jon L. Bentley.
Glenn L McGrath60bce492002-11-03 07:28:38 +00008
Rob Landleye66c7ef2006-04-14 19:25:01 +00009 Licensed under GPLv2 or later, see file LICENSE in this tarball for details.
Eric Andersen0d6d88a2003-10-18 01:58:35 +000010*/
Glenn L McGrath60bce492002-11-03 07:28:38 +000011
Eric Andersen5fa4db22003-10-23 06:52:01 +000012/*
13 Size and speed optimizations by Manuel Novoa III (mjn3@codepoet.org).
14
Eric Andersenaff114c2004-04-14 17:51:38 +000015 More efficient reading of Huffman codes, a streamlined read_bunzip()
Eric Andersen5fa4db22003-10-23 06:52:01 +000016 function, and various other tweaks. In (limited) tests, approximately
17 20% faster than bzcat on x86 and about 10% faster on arm.
18
19 Note that about 2/3 of the time is spent in read_unzip() reversing
20 the Burrows-Wheeler transformation. Much of that time is delay
21 resulting from cache misses.
22
23 I would ask that anyone benefiting from this work, especially those
24 using it in commercial products, consider making a donation to my local
Rob Landleyf856eab2006-02-17 03:43:49 +000025 non-profit hospice organization (www.hospiceacadiana.com) in the name of
Bernhard Reutner-Fischercfb53df2006-04-02 21:50:01 +000026 the woman I loved, Toni W. Hagan, who passed away Feb. 12, 2003.
Eric Andersen5fa4db22003-10-23 06:52:01 +000027
28 Manuel
29 */
30
Glenn L McGrath1c834402003-10-28 23:32:12 +000031#include "libbb.h"
Bernhard Reutner-Fischercfb53df2006-04-02 21:50:01 +000032#include "unarchive.h"
33
Eric Andersenaff114c2004-04-14 17:51:38 +000034/* Constants for Huffman coding */
Denis Vlasenkobf0a2012006-12-26 10:42:51 +000035#define MAX_GROUPS 6
36#define GROUP_SIZE 50 /* 64 would have been more efficient */
37#define MAX_HUFCODE_BITS 20 /* Longest Huffman code allowed */
38#define MAX_SYMBOLS 258 /* 256 literals + RUNA + RUNB */
39#define SYMBOL_RUNA 0
40#define SYMBOL_RUNB 1
Glenn L McGrath60bce492002-11-03 07:28:38 +000041
Eric Andersen0d6d88a2003-10-18 01:58:35 +000042/* Status return values */
Denis Vlasenkobf0a2012006-12-26 10:42:51 +000043#define RETVAL_OK 0
44#define RETVAL_LAST_BLOCK (-1)
45#define RETVAL_NOT_BZIP_DATA (-2)
46#define RETVAL_UNEXPECTED_INPUT_EOF (-3)
47#define RETVAL_UNEXPECTED_OUTPUT_EOF (-4)
48#define RETVAL_DATA_ERROR (-5)
49#define RETVAL_OUT_OF_MEMORY (-6)
50#define RETVAL_OBSOLETE_INPUT (-7)
Glenn L McGrath60bce492002-11-03 07:28:38 +000051
Eric Andersen0d6d88a2003-10-18 01:58:35 +000052/* Other housekeeping constants */
Denis Vlasenkobf0a2012006-12-26 10:42:51 +000053#define IOBUF_SIZE 4096
Glenn L McGrath60bce492002-11-03 07:28:38 +000054
Eric Andersenaff114c2004-04-14 17:51:38 +000055/* This is what we know about each Huffman coding group */
Eric Andersen0d6d88a2003-10-18 01:58:35 +000056struct group_data {
Eric Andersen1acfb722003-10-18 01:59:46 +000057 /* We have an extra slot at the end of limit[] for a sentinal value. */
58 int limit[MAX_HUFCODE_BITS+1],base[MAX_HUFCODE_BITS],permute[MAX_SYMBOLS];
Eric Andersen5fa4db22003-10-23 06:52:01 +000059 int minLen, maxLen;
Glenn L McGrath60bce492002-11-03 07:28:38 +000060};
61
Eric Andersen0d6d88a2003-10-18 01:58:35 +000062/* Structure holding all the housekeeping data, including IO buffers and
63 memory that persists between calls to bunzip */
Rob Landleyf856eab2006-02-17 03:43:49 +000064
Eric Andersen0d6d88a2003-10-18 01:58:35 +000065typedef struct {
Eric Andersen5fa4db22003-10-23 06:52:01 +000066 /* State for interrupting output loop */
Rob Landley2c98c402006-02-17 05:12:03 +000067
Eric Andersen5fa4db22003-10-23 06:52:01 +000068 int writeCopies,writePos,writeRunCountdown,writeCount,writeCurrent;
Rob Landleyf856eab2006-02-17 03:43:49 +000069
Eric Andersen5fa4db22003-10-23 06:52:01 +000070 /* I/O tracking data (file handles, buffers, positions, etc.) */
Rob Landleyf856eab2006-02-17 03:43:49 +000071
Eric Andersen5fa4db22003-10-23 06:52:01 +000072 int in_fd,out_fd,inbufCount,inbufPos /*,outbufPos*/;
73 unsigned char *inbuf /*,*outbuf*/;
Eric Andersen0d6d88a2003-10-18 01:58:35 +000074 unsigned int inbufBitCount, inbufBits;
Rob Landleyf856eab2006-02-17 03:43:49 +000075
Eric Andersen0d6d88a2003-10-18 01:58:35 +000076 /* The CRC values stored in the block header and calculated from the data */
Rob Landleyf856eab2006-02-17 03:43:49 +000077
Rob Landleyc57ec372006-04-10 17:07:15 +000078 uint32_t headerCRC, totalCRC, writeCRC;
79 uint32_t *crc32Table;
Eric Andersen0d6d88a2003-10-18 01:58:35 +000080 /* Intermediate buffer and its size (in bytes) */
Rob Landleyf856eab2006-02-17 03:43:49 +000081
Eric Andersen0d6d88a2003-10-18 01:58:35 +000082 unsigned int *dbuf, dbufSize;
Rob Landleyf856eab2006-02-17 03:43:49 +000083
Eric Andersen0d6d88a2003-10-18 01:58:35 +000084 /* These things are a bit too big to go on the stack */
Rob Landleyf856eab2006-02-17 03:43:49 +000085
Eric Andersen0d6d88a2003-10-18 01:58:35 +000086 unsigned char selectors[32768]; /* nSelectors=15 bits */
Eric Andersenaff114c2004-04-14 17:51:38 +000087 struct group_data groups[MAX_GROUPS]; /* Huffman coding tables */
Rob Landleyf856eab2006-02-17 03:43:49 +000088
Eric Andersen5fa4db22003-10-23 06:52:01 +000089 /* For I/O error handling */
Rob Landleyf856eab2006-02-17 03:43:49 +000090
Eric Andersen5fa4db22003-10-23 06:52:01 +000091 jmp_buf jmpbuf;
Eric Andersen0d6d88a2003-10-18 01:58:35 +000092} bunzip_data;
93
94/* Return the next nnn bits of input. All reads from the compressed input
95 are done through this function. All reads are big endian */
Rob Landleyf856eab2006-02-17 03:43:49 +000096
Eric Andersen0d6d88a2003-10-18 01:58:35 +000097static unsigned int get_bits(bunzip_data *bd, char bits_wanted)
Glenn L McGrath60bce492002-11-03 07:28:38 +000098{
Eric Andersen0d6d88a2003-10-18 01:58:35 +000099 unsigned int bits=0;
100
101 /* If we need to get more data from the byte buffer, do so. (Loop getting
102 one byte at a time to enforce endianness and avoid unaligned access.) */
Rob Landleyf856eab2006-02-17 03:43:49 +0000103
Eric Andersen0d6d88a2003-10-18 01:58:35 +0000104 while (bd->inbufBitCount<bits_wanted) {
Rob Landleyf856eab2006-02-17 03:43:49 +0000105
Eric Andersen0d6d88a2003-10-18 01:58:35 +0000106 /* If we need to read more data from file into byte buffer, do so */
Rob Landleyf856eab2006-02-17 03:43:49 +0000107
Eric Andersen0d6d88a2003-10-18 01:58:35 +0000108 if(bd->inbufPos==bd->inbufCount) {
Eric Andersen1acfb722003-10-18 01:59:46 +0000109 if((bd->inbufCount = read(bd->in_fd, bd->inbuf, IOBUF_SIZE)) <= 0)
Eric Andersen0d6d88a2003-10-18 01:58:35 +0000110 longjmp(bd->jmpbuf,RETVAL_UNEXPECTED_INPUT_EOF);
111 bd->inbufPos=0;
Glenn L McGrath60bce492002-11-03 07:28:38 +0000112 }
Rob Landleyf856eab2006-02-17 03:43:49 +0000113
Eric Andersen0d6d88a2003-10-18 01:58:35 +0000114 /* Avoid 32-bit overflow (dump bit buffer to top of output) */
Rob Landleyf856eab2006-02-17 03:43:49 +0000115
Eric Andersen0d6d88a2003-10-18 01:58:35 +0000116 if(bd->inbufBitCount>=24) {
117 bits=bd->inbufBits&((1<<bd->inbufBitCount)-1);
118 bits_wanted-=bd->inbufBitCount;
119 bits<<=bits_wanted;
120 bd->inbufBitCount=0;
121 }
Rob Landleyf856eab2006-02-17 03:43:49 +0000122
Eric Andersen0d6d88a2003-10-18 01:58:35 +0000123 /* Grab next 8 bits of input from buffer. */
Rob Landleyf856eab2006-02-17 03:43:49 +0000124
Eric Andersen0d6d88a2003-10-18 01:58:35 +0000125 bd->inbufBits=(bd->inbufBits<<8)|bd->inbuf[bd->inbufPos++];
126 bd->inbufBitCount+=8;
Glenn L McGrath60bce492002-11-03 07:28:38 +0000127 }
Rob Landleyf856eab2006-02-17 03:43:49 +0000128
Eric Andersen0d6d88a2003-10-18 01:58:35 +0000129 /* Calculate result */
Rob Landleyf856eab2006-02-17 03:43:49 +0000130
Eric Andersen0d6d88a2003-10-18 01:58:35 +0000131 bd->inbufBitCount-=bits_wanted;
132 bits|=(bd->inbufBits>>bd->inbufBitCount)&((1<<bits_wanted)-1);
133
134 return bits;
Glenn L McGrath60bce492002-11-03 07:28:38 +0000135}
136
Eric Andersen5fa4db22003-10-23 06:52:01 +0000137/* Unpacks the next block and sets up for the inverse burrows-wheeler step. */
Eric Andersen1acfb722003-10-18 01:59:46 +0000138
Eric Andersen5fa4db22003-10-23 06:52:01 +0000139static int get_next_block(bunzip_data *bd)
Glenn L McGrath60bce492002-11-03 07:28:38 +0000140{
Eric Andersen0d6d88a2003-10-18 01:58:35 +0000141 struct group_data *hufGroup;
Eric Andersen5fa4db22003-10-23 06:52:01 +0000142 int dbufCount,nextSym,dbufSize,groupCount,*base,*limit,selector,
Eric Andersen0d6d88a2003-10-18 01:58:35 +0000143 i,j,k,t,runPos,symCount,symTotal,nSelectors,byteCount[256];
144 unsigned char uc, symToByte[256], mtfSymbol[256], *selectors;
Eric Andersen5fa4db22003-10-23 06:52:01 +0000145 unsigned int *dbuf,origPtr;
Eric Andersen0d6d88a2003-10-18 01:58:35 +0000146
147 dbuf=bd->dbuf;
148 dbufSize=bd->dbufSize;
149 selectors=bd->selectors;
Rob Landley2c98c402006-02-17 05:12:03 +0000150
Eric Andersen5fa4db22003-10-23 06:52:01 +0000151 /* Reset longjmp I/O error handling */
Rob Landley2c98c402006-02-17 05:12:03 +0000152
Eric Andersen5fa4db22003-10-23 06:52:01 +0000153 i=setjmp(bd->jmpbuf);
Denis Vlasenkobf0a2012006-12-26 10:42:51 +0000154 if (i) return i;
Rob Landley2c98c402006-02-17 05:12:03 +0000155
Eric Andersen5fa4db22003-10-23 06:52:01 +0000156 /* Read in header signature and CRC, then validate signature.
157 (last block signature means CRC is for whole file, return now) */
Rob Landley2c98c402006-02-17 05:12:03 +0000158
Eric Andersen5fa4db22003-10-23 06:52:01 +0000159 i = get_bits(bd,24);
160 j = get_bits(bd,24);
161 bd->headerCRC=get_bits(bd,32);
162 if ((i == 0x177245) && (j == 0x385090)) return RETVAL_LAST_BLOCK;
163 if ((i != 0x314159) || (j != 0x265359)) return RETVAL_NOT_BZIP_DATA;
Rob Landley2c98c402006-02-17 05:12:03 +0000164
Eric Andersen0d6d88a2003-10-18 01:58:35 +0000165 /* We can add support for blockRandomised if anybody complains. There was
166 some code for this in busybox 1.0.0-pre3, but nobody ever noticed that
167 it didn't actually work. */
Rob Landley2c98c402006-02-17 05:12:03 +0000168
Denis Vlasenkobf0a2012006-12-26 10:42:51 +0000169 if (get_bits(bd,1)) return RETVAL_OBSOLETE_INPUT;
170 if ((origPtr=get_bits(bd,24)) > dbufSize) return RETVAL_DATA_ERROR;
Rob Landley2c98c402006-02-17 05:12:03 +0000171
Eric Andersen0d6d88a2003-10-18 01:58:35 +0000172 /* mapping table: if some byte values are never used (encoding things
173 like ascii text), the compression code removes the gaps to have fewer
174 symbols to deal with, and writes a sparse bitfield indicating which
175 values were present. We make a translation table to convert the symbols
176 back to the corresponding bytes. */
Rob Landley2c98c402006-02-17 05:12:03 +0000177
Eric Andersen0d6d88a2003-10-18 01:58:35 +0000178 t=get_bits(bd, 16);
Eric Andersen0d6d88a2003-10-18 01:58:35 +0000179 symTotal=0;
180 for (i=0;i<16;i++) {
181 if(t&(1<<(15-i))) {
182 k=get_bits(bd,16);
Denis Vlasenkobf0a2012006-12-26 10:42:51 +0000183 for (j=0;j<16;j++)
Eric Andersen0d6d88a2003-10-18 01:58:35 +0000184 if(k&(1<<(15-j))) symToByte[symTotal++]=(16*i)+j;
Glenn L McGrath60bce492002-11-03 07:28:38 +0000185 }
186 }
Rob Landley2c98c402006-02-17 05:12:03 +0000187
Eric Andersenaff114c2004-04-14 17:51:38 +0000188 /* How many different Huffman coding groups does this block use? */
Rob Landley2c98c402006-02-17 05:12:03 +0000189
Eric Andersen0d6d88a2003-10-18 01:58:35 +0000190 groupCount=get_bits(bd,3);
191 if (groupCount<2 || groupCount>MAX_GROUPS) return RETVAL_DATA_ERROR;
Rob Landley2c98c402006-02-17 05:12:03 +0000192
Eric Andersenaff114c2004-04-14 17:51:38 +0000193 /* nSelectors: Every GROUP_SIZE many symbols we select a new Huffman coding
Eric Andersen0d6d88a2003-10-18 01:58:35 +0000194 group. Read in the group selector list, which is stored as MTF encoded
Eric Andersen5fa4db22003-10-23 06:52:01 +0000195 bit runs. (MTF=Move To Front, as each value is used it's moved to the
196 start of the list.) */
Rob Landley2c98c402006-02-17 05:12:03 +0000197
Eric Andersen0d6d88a2003-10-18 01:58:35 +0000198 if(!(nSelectors=get_bits(bd, 15))) return RETVAL_DATA_ERROR;
Denis Vlasenkobf0a2012006-12-26 10:42:51 +0000199 for (i=0; i<groupCount; i++) mtfSymbol[i] = i;
200 for (i=0; i<nSelectors; i++) {
Rob Landley2c98c402006-02-17 05:12:03 +0000201
Eric Andersen0d6d88a2003-10-18 01:58:35 +0000202 /* Get next value */
Rob Landley2c98c402006-02-17 05:12:03 +0000203
Denis Vlasenkobf0a2012006-12-26 10:42:51 +0000204 for (j=0;get_bits(bd,1);j++) if (j>=groupCount) return RETVAL_DATA_ERROR;
Rob Landley2c98c402006-02-17 05:12:03 +0000205
Eric Andersen0d6d88a2003-10-18 01:58:35 +0000206 /* Decode MTF to get the next selector */
Rob Landley2c98c402006-02-17 05:12:03 +0000207
Eric Andersen0d6d88a2003-10-18 01:58:35 +0000208 uc = mtfSymbol[j];
Denis Vlasenkobf0a2012006-12-26 10:42:51 +0000209 for (;j;j--) mtfSymbol[j] = mtfSymbol[j-1];
Eric Andersen0d6d88a2003-10-18 01:58:35 +0000210 mtfSymbol[0]=selectors[i]=uc;
Glenn L McGrath60bce492002-11-03 07:28:38 +0000211 }
Rob Landley2c98c402006-02-17 05:12:03 +0000212
Eric Andersenaff114c2004-04-14 17:51:38 +0000213 /* Read the Huffman coding tables for each group, which code for symTotal
Eric Andersen0d6d88a2003-10-18 01:58:35 +0000214 literal symbols, plus two run symbols (RUNA, RUNB) */
Rob Landley2c98c402006-02-17 05:12:03 +0000215
Eric Andersen0d6d88a2003-10-18 01:58:35 +0000216 symCount=symTotal+2;
217 for (j=0; j<groupCount; j++) {
218 unsigned char length[MAX_SYMBOLS],temp[MAX_HUFCODE_BITS+1];
219 int minLen, maxLen, pp;
Rob Landley2c98c402006-02-17 05:12:03 +0000220
Eric Andersenaff114c2004-04-14 17:51:38 +0000221 /* Read Huffman code lengths for each symbol. They're stored in
Eric Andersen5fa4db22003-10-23 06:52:01 +0000222 a way similar to mtf; record a starting value for the first symbol,
223 and an offset from the previous value for everys symbol after that.
224 (Subtracting 1 before the loop and then adding it back at the end is
225 an optimization that makes the test inside the loop simpler: symbol
226 length 0 becomes negative, so an unsigned inequality catches it.) */
Rob Landley2c98c402006-02-17 05:12:03 +0000227
Eric Andersen5fa4db22003-10-23 06:52:01 +0000228 t=get_bits(bd, 5)-1;
Eric Andersen0d6d88a2003-10-18 01:58:35 +0000229 for (i = 0; i < symCount; i++) {
Denis Vlasenkobf0a2012006-12-26 10:42:51 +0000230 for (;;) {
Eric Andersen5fa4db22003-10-23 06:52:01 +0000231 if (((unsigned)t) > (MAX_HUFCODE_BITS-1))
232 return RETVAL_DATA_ERROR;
Rob Landley2c98c402006-02-17 05:12:03 +0000233
Eric Andersen5fa4db22003-10-23 06:52:01 +0000234 /* If first bit is 0, stop. Else second bit indicates whether
235 to increment or decrement the value. Optimization: grab 2
236 bits and unget the second if the first was 0. */
Rob Landley2c98c402006-02-17 05:12:03 +0000237
Eric Andersen5fa4db22003-10-23 06:52:01 +0000238 k = get_bits(bd,2);
239 if (k < 2) {
240 bd->inbufBitCount++;
241 break;
242 }
Rob Landley2c98c402006-02-17 05:12:03 +0000243
Eric Andersen5fa4db22003-10-23 06:52:01 +0000244 /* Add one if second bit 1, else subtract 1. Avoids if/else */
Rob Landley2c98c402006-02-17 05:12:03 +0000245
Eric Andersen5fa4db22003-10-23 06:52:01 +0000246 t+=(((k+1)&2)-1);
Eric Andersen0d6d88a2003-10-18 01:58:35 +0000247 }
Rob Landley2c98c402006-02-17 05:12:03 +0000248
Eric Andersen5fa4db22003-10-23 06:52:01 +0000249 /* Correct for the initial -1, to get the final symbol length */
Rob Landley2c98c402006-02-17 05:12:03 +0000250
Eric Andersen5fa4db22003-10-23 06:52:01 +0000251 length[i]=t+1;
Glenn L McGrath60bce492002-11-03 07:28:38 +0000252 }
Rob Landley2c98c402006-02-17 05:12:03 +0000253
Eric Andersen0d6d88a2003-10-18 01:58:35 +0000254 /* Find largest and smallest lengths in this group */
Rob Landley2c98c402006-02-17 05:12:03 +0000255
Eric Andersen0d6d88a2003-10-18 01:58:35 +0000256 minLen=maxLen=length[0];
Denis Vlasenkobf0a2012006-12-26 10:42:51 +0000257 for (i = 1; i < symCount; i++) {
Eric Andersen0d6d88a2003-10-18 01:58:35 +0000258 if(length[i] > maxLen) maxLen = length[i];
259 else if(length[i] < minLen) minLen = length[i];
Glenn L McGrath60bce492002-11-03 07:28:38 +0000260 }
Rob Landley2c98c402006-02-17 05:12:03 +0000261
Eric Andersen0d6d88a2003-10-18 01:58:35 +0000262 /* Calculate permute[], base[], and limit[] tables from length[].
263 *
Eric Andersenaff114c2004-04-14 17:51:38 +0000264 * permute[] is the lookup table for converting Huffman coded symbols
Eric Andersen0d6d88a2003-10-18 01:58:35 +0000265 * into decoded symbols. base[] is the amount to subtract from the
Eric Andersenaff114c2004-04-14 17:51:38 +0000266 * value of a Huffman symbol of a given length when using permute[].
Eric Andersen0d6d88a2003-10-18 01:58:35 +0000267 *
268 * limit[] indicates the largest numerical value a symbol with a given
Eric Andersenaff114c2004-04-14 17:51:38 +0000269 * number of bits can have. This is how the Huffman codes can vary in
Eric Andersen5fa4db22003-10-23 06:52:01 +0000270 * length: each code with a value>limit[length] needs another bit.
Eric Andersen0d6d88a2003-10-18 01:58:35 +0000271 */
Rob Landley2c98c402006-02-17 05:12:03 +0000272
Eric Andersen0d6d88a2003-10-18 01:58:35 +0000273 hufGroup=bd->groups+j;
274 hufGroup->minLen = minLen;
275 hufGroup->maxLen = maxLen;
Rob Landley2c98c402006-02-17 05:12:03 +0000276
Eric Andersen0d6d88a2003-10-18 01:58:35 +0000277 /* Note that minLen can't be smaller than 1, so we adjust the base
278 and limit array pointers so we're not always wasting the first
279 entry. We do this again when using them (during symbol decoding).*/
Rob Landley2c98c402006-02-17 05:12:03 +0000280
Eric Andersen0d6d88a2003-10-18 01:58:35 +0000281 base=hufGroup->base-1;
282 limit=hufGroup->limit-1;
Rob Landley2c98c402006-02-17 05:12:03 +0000283
Eric Andersen5fa4db22003-10-23 06:52:01 +0000284 /* Calculate permute[]. Concurently, initialize temp[] and limit[]. */
Rob Landley2c98c402006-02-17 05:12:03 +0000285
Eric Andersen5fa4db22003-10-23 06:52:01 +0000286 pp=0;
Denis Vlasenkobf0a2012006-12-26 10:42:51 +0000287 for (i=minLen;i<=maxLen;i++) {
Eric Andersen5fa4db22003-10-23 06:52:01 +0000288 temp[i]=limit[i]=0;
Denis Vlasenkobf0a2012006-12-26 10:42:51 +0000289 for (t=0;t<symCount;t++)
Eric Andersen0d6d88a2003-10-18 01:58:35 +0000290 if(length[t]==i) hufGroup->permute[pp++] = t;
Eric Andersen5fa4db22003-10-23 06:52:01 +0000291 }
Rob Landley2c98c402006-02-17 05:12:03 +0000292
Eric Andersen5fa4db22003-10-23 06:52:01 +0000293 /* Count symbols coded for at each bit length */
Rob Landley2c98c402006-02-17 05:12:03 +0000294
Eric Andersen0d6d88a2003-10-18 01:58:35 +0000295 for (i=0;i<symCount;i++) temp[length[i]]++;
Rob Landley2c98c402006-02-17 05:12:03 +0000296
Eric Andersen0d6d88a2003-10-18 01:58:35 +0000297 /* Calculate limit[] (the largest symbol-coding value at each bit
298 * length, which is (previous limit<<1)+symbols at this level), and
299 * base[] (number of symbols to ignore at each bit length, which is
Eric Andersen5fa4db22003-10-23 06:52:01 +0000300 * limit minus the cumulative count of symbols coded for already). */
Rob Landley2c98c402006-02-17 05:12:03 +0000301
Eric Andersen0d6d88a2003-10-18 01:58:35 +0000302 pp=t=0;
303 for (i=minLen; i<maxLen; i++) {
304 pp+=temp[i];
Rob Landley2c98c402006-02-17 05:12:03 +0000305
Eric Andersen5fa4db22003-10-23 06:52:01 +0000306 /* We read the largest possible symbol size and then unget bits
307 after determining how many we need, and those extra bits could
308 be set to anything. (They're noise from future symbols.) At
309 each level we're really only interested in the first few bits,
310 so here we set all the trailing to-be-ignored bits to 1 so they
311 don't affect the value>limit[length] comparison. */
Rob Landley2c98c402006-02-17 05:12:03 +0000312
Eric Andersen5fa4db22003-10-23 06:52:01 +0000313 limit[i]= (pp << (maxLen - i)) - 1;
Eric Andersen0d6d88a2003-10-18 01:58:35 +0000314 pp<<=1;
315 base[i+1]=pp-(t+=temp[i]);
316 }
Eric Andersen1acfb722003-10-18 01:59:46 +0000317 limit[maxLen+1] = INT_MAX; /* Sentinal value for reading next sym. */
Eric Andersen0d6d88a2003-10-18 01:58:35 +0000318 limit[maxLen]=pp+temp[maxLen]-1;
319 base[minLen]=0;
Glenn L McGrath60bce492002-11-03 07:28:38 +0000320 }
Rob Landley2c98c402006-02-17 05:12:03 +0000321
Eric Andersen0d6d88a2003-10-18 01:58:35 +0000322 /* We've finished reading and digesting the block header. Now read this
Eric Andersenaff114c2004-04-14 17:51:38 +0000323 block's Huffman coded symbols from the file and undo the Huffman coding
Eric Andersen0d6d88a2003-10-18 01:58:35 +0000324 and run length encoding, saving the result into dbuf[dbufCount++]=uc */
Glenn L McGrath60bce492002-11-03 07:28:38 +0000325
Eric Andersen5fa4db22003-10-23 06:52:01 +0000326 /* Initialize symbol occurrence counters and symbol Move To Front table */
Rob Landley2c98c402006-02-17 05:12:03 +0000327
Denis Vlasenkobf0a2012006-12-26 10:42:51 +0000328 for (i=0;i<256;i++) {
Eric Andersen5fa4db22003-10-23 06:52:01 +0000329 byteCount[i] = 0;
330 mtfSymbol[i]=(unsigned char)i;
331 }
Rob Landley2c98c402006-02-17 05:12:03 +0000332
Eric Andersen5fa4db22003-10-23 06:52:01 +0000333 /* Loop through compressed symbols. */
Rob Landley2c98c402006-02-17 05:12:03 +0000334
Rob Landleya8b98d62004-11-16 12:07:04 +0000335 runPos=dbufCount=selector=0;
Denis Vlasenkobf0a2012006-12-26 10:42:51 +0000336 for (;;) {
Rob Landley2c98c402006-02-17 05:12:03 +0000337
Rob Landleya8b98d62004-11-16 12:07:04 +0000338 /* fetch next Huffman coding group from list. */
Rob Landley2c98c402006-02-17 05:12:03 +0000339
Rob Landleya8b98d62004-11-16 12:07:04 +0000340 symCount=GROUP_SIZE-1;
341 if(selector>=nSelectors) return RETVAL_DATA_ERROR;
342 hufGroup=bd->groups+selectors[selector++];
343 base=hufGroup->base-1;
344 limit=hufGroup->limit-1;
345continue_this_group:
Rob Landley2c98c402006-02-17 05:12:03 +0000346
Eric Andersenaff114c2004-04-14 17:51:38 +0000347 /* Read next Huffman-coded symbol. */
Rob Landley2c98c402006-02-17 05:12:03 +0000348
Eric Andersen5fa4db22003-10-23 06:52:01 +0000349 /* Note: It is far cheaper to read maxLen bits and back up than it is
350 to read minLen bits and then an additional bit at a time, testing
351 as we go. Because there is a trailing last block (with file CRC),
352 there is no danger of the overread causing an unexpected EOF for a
353 valid compressed file. As a further optimization, we do the read
354 inline (falling back to a call to get_bits if the buffer runs
355 dry). The following (up to got_huff_bits:) is equivalent to
356 j=get_bits(bd,hufGroup->maxLen);
357 */
Rob Landley2c98c402006-02-17 05:12:03 +0000358
Eric Andersen5fa4db22003-10-23 06:52:01 +0000359 while (bd->inbufBitCount<hufGroup->maxLen) {
360 if(bd->inbufPos==bd->inbufCount) {
361 j = get_bits(bd,hufGroup->maxLen);
362 goto got_huff_bits;
363 }
364 bd->inbufBits=(bd->inbufBits<<8)|bd->inbuf[bd->inbufPos++];
365 bd->inbufBitCount+=8;
366 };
367 bd->inbufBitCount-=hufGroup->maxLen;
368 j = (bd->inbufBits>>bd->inbufBitCount)&((1<<hufGroup->maxLen)-1);
Rob Landley2c98c402006-02-17 05:12:03 +0000369
Eric Andersen5fa4db22003-10-23 06:52:01 +0000370got_huff_bits:
Rob Landley2c98c402006-02-17 05:12:03 +0000371
Eric Andersen5fa4db22003-10-23 06:52:01 +0000372 /* Figure how how many bits are in next symbol and unget extras */
Rob Landley2c98c402006-02-17 05:12:03 +0000373
Eric Andersen5fa4db22003-10-23 06:52:01 +0000374 i=hufGroup->minLen;
Denis Vlasenkobf0a2012006-12-26 10:42:51 +0000375 while (j>limit[i]) ++i;
Eric Andersen5fa4db22003-10-23 06:52:01 +0000376 bd->inbufBitCount += (hufGroup->maxLen - i);
Rob Landley2c98c402006-02-17 05:12:03 +0000377
Eric Andersen5fa4db22003-10-23 06:52:01 +0000378 /* Huffman decode value to get nextSym (with bounds checking) */
Rob Landley2c98c402006-02-17 05:12:03 +0000379
Eric Andersen5fa4db22003-10-23 06:52:01 +0000380 if ((i > hufGroup->maxLen)
381 || (((unsigned)(j=(j>>(hufGroup->maxLen-i))-base[i]))
382 >= MAX_SYMBOLS))
383 return RETVAL_DATA_ERROR;
Eric Andersen0d6d88a2003-10-18 01:58:35 +0000384 nextSym = hufGroup->permute[j];
Rob Landley2c98c402006-02-17 05:12:03 +0000385
Eric Andersen5fa4db22003-10-23 06:52:01 +0000386 /* We have now decoded the symbol, which indicates either a new literal
387 byte, or a repeated run of the most recent literal byte. First,
388 check if nextSym indicates a repeated run, and if so loop collecting
389 how many times to repeat the last literal. */
Rob Landley2c98c402006-02-17 05:12:03 +0000390
Eric Andersen1acfb722003-10-18 01:59:46 +0000391 if (((unsigned)nextSym) <= SYMBOL_RUNB) { /* RUNA or RUNB */
Rob Landley2c98c402006-02-17 05:12:03 +0000392
Eric Andersen0d6d88a2003-10-18 01:58:35 +0000393 /* If this is the start of a new run, zero out counter */
Rob Landley2c98c402006-02-17 05:12:03 +0000394
Eric Andersen0d6d88a2003-10-18 01:58:35 +0000395 if(!runPos) {
396 runPos = 1;
397 t = 0;
Glenn L McGrath60bce492002-11-03 07:28:38 +0000398 }
Rob Landley2c98c402006-02-17 05:12:03 +0000399
Eric Andersen0d6d88a2003-10-18 01:58:35 +0000400 /* Neat trick that saves 1 symbol: instead of or-ing 0 or 1 at
401 each bit position, add 1 or 2 instead. For example,
402 1011 is 1<<0 + 1<<1 + 2<<2. 1010 is 2<<0 + 2<<1 + 1<<2.
403 You can make any bit pattern that way using 1 less symbol than
404 the basic or 0/1 method (except all bits 0, which would use no
405 symbols, but a run of length 0 doesn't mean anything in this
406 context). Thus space is saved. */
Rob Landley2c98c402006-02-17 05:12:03 +0000407
Eric Andersen1acfb722003-10-18 01:59:46 +0000408 t += (runPos << nextSym); /* +runPos if RUNA; +2*runPos if RUNB */
Rob Landleyefae2942006-02-17 05:19:40 +0000409 if(runPos < dbufSize) runPos <<= 1;
Rob Landleya8b98d62004-11-16 12:07:04 +0000410 goto end_of_huffman_loop;
Glenn L McGrath60bce492002-11-03 07:28:38 +0000411 }
Rob Landley2c98c402006-02-17 05:12:03 +0000412
Eric Andersen0d6d88a2003-10-18 01:58:35 +0000413 /* When we hit the first non-run symbol after a run, we now know
414 how many times to repeat the last literal, so append that many
415 copies to our buffer of decoded symbols (dbuf) now. (The last
416 literal used is the one at the head of the mtfSymbol array.) */
Rob Landley2c98c402006-02-17 05:12:03 +0000417
Eric Andersen0d6d88a2003-10-18 01:58:35 +0000418 if(runPos) {
419 runPos=0;
420 if(dbufCount+t>=dbufSize) return RETVAL_DATA_ERROR;
421
422 uc = symToByte[mtfSymbol[0]];
423 byteCount[uc] += t;
Denis Vlasenkobf0a2012006-12-26 10:42:51 +0000424 while (t--) dbuf[dbufCount++]=uc;
Eric Andersen0d6d88a2003-10-18 01:58:35 +0000425 }
Rob Landley2c98c402006-02-17 05:12:03 +0000426
Eric Andersen0d6d88a2003-10-18 01:58:35 +0000427 /* Is this the terminating symbol? */
Rob Landley2c98c402006-02-17 05:12:03 +0000428
Eric Andersen0d6d88a2003-10-18 01:58:35 +0000429 if(nextSym>symTotal) break;
Rob Landley2c98c402006-02-17 05:12:03 +0000430
Eric Andersen5fa4db22003-10-23 06:52:01 +0000431 /* At this point, nextSym indicates a new literal character. Subtract
432 one to get the position in the MTF array at which this literal is
433 currently to be found. (Note that the result can't be -1 or 0,
434 because 0 and 1 are RUNA and RUNB. But another instance of the
435 first symbol in the mtf array, position 0, would have been handled
436 as part of a run above. Therefore 1 unused mtf position minus
437 2 non-literal nextSym values equals -1.) */
Rob Landley2c98c402006-02-17 05:12:03 +0000438
Eric Andersen0d6d88a2003-10-18 01:58:35 +0000439 if(dbufCount>=dbufSize) return RETVAL_DATA_ERROR;
440 i = nextSym - 1;
441 uc = mtfSymbol[i];
Rob Landley2c98c402006-02-17 05:12:03 +0000442
Eric Andersen5fa4db22003-10-23 06:52:01 +0000443 /* Adjust the MTF array. Since we typically expect to move only a
444 * small number of symbols, and are bound by 256 in any case, using
445 * memmove here would typically be bigger and slower due to function
446 * call overhead and other assorted setup costs. */
Rob Landley2c98c402006-02-17 05:12:03 +0000447
Eric Andersen1acfb722003-10-18 01:59:46 +0000448 do {
449 mtfSymbol[i] = mtfSymbol[i-1];
450 } while (--i);
Eric Andersen0d6d88a2003-10-18 01:58:35 +0000451 mtfSymbol[0] = uc;
452 uc=symToByte[uc];
Rob Landley2c98c402006-02-17 05:12:03 +0000453
Eric Andersen0d6d88a2003-10-18 01:58:35 +0000454 /* We have our literal byte. Save it into dbuf. */
Rob Landley2c98c402006-02-17 05:12:03 +0000455
Eric Andersen0d6d88a2003-10-18 01:58:35 +0000456 byteCount[uc]++;
457 dbuf[dbufCount++] = (unsigned int)uc;
Rob Landley2c98c402006-02-17 05:12:03 +0000458
Rob Landleyf856eab2006-02-17 03:43:49 +0000459 /* Skip group initialization if we're not done with this group. Done
460 * this way to avoid compiler warning. */
Rob Landley2c98c402006-02-17 05:12:03 +0000461
Rob Landleya8b98d62004-11-16 12:07:04 +0000462end_of_huffman_loop:
463 if(symCount--) goto continue_this_group;
Glenn L McGrath60bce492002-11-03 07:28:38 +0000464 }
Rob Landleyf856eab2006-02-17 03:43:49 +0000465
Eric Andersenaff114c2004-04-14 17:51:38 +0000466 /* At this point, we've read all the Huffman-coded symbols (and repeated
Eric Andersen5fa4db22003-10-23 06:52:01 +0000467 runs) for this block from the input stream, and decoded them into the
468 intermediate buffer. There are dbufCount many decoded bytes in dbuf[].
469 Now undo the Burrows-Wheeler transform on dbuf.
Eric Andersen0d6d88a2003-10-18 01:58:35 +0000470 See http://dogma.net/markn/articles/bwt/bwt.htm
471 */
Rob Landley2c98c402006-02-17 05:12:03 +0000472
Eric Andersen0d6d88a2003-10-18 01:58:35 +0000473 /* Turn byteCount into cumulative occurrence counts of 0 to n-1. */
Rob Landleyf856eab2006-02-17 03:43:49 +0000474
Eric Andersen0d6d88a2003-10-18 01:58:35 +0000475 j=0;
Denis Vlasenkobf0a2012006-12-26 10:42:51 +0000476 for (i=0;i<256;i++) {
Eric Andersen0d6d88a2003-10-18 01:58:35 +0000477 k=j+byteCount[i];
478 byteCount[i] = j;
479 j=k;
Glenn L McGrath60bce492002-11-03 07:28:38 +0000480 }
Rob Landleyf856eab2006-02-17 03:43:49 +0000481
Eric Andersen0d6d88a2003-10-18 01:58:35 +0000482 /* Figure out what order dbuf would be in if we sorted it. */
Rob Landleyf856eab2006-02-17 03:43:49 +0000483
Eric Andersen0d6d88a2003-10-18 01:58:35 +0000484 for (i=0;i<dbufCount;i++) {
Eric Andersen5fa4db22003-10-23 06:52:01 +0000485 uc=(unsigned char)(dbuf[i] & 0xff);
Eric Andersen0d6d88a2003-10-18 01:58:35 +0000486 dbuf[byteCount[uc]] |= (i << 8);
487 byteCount[uc]++;
Glenn L McGrath60bce492002-11-03 07:28:38 +0000488 }
Rob Landleyf856eab2006-02-17 03:43:49 +0000489
Eric Andersen0d6d88a2003-10-18 01:58:35 +0000490 /* Decode first byte by hand to initialize "previous" byte. Note that it
491 doesn't get output, and if the first three characters are identical
Eric Andersen5fa4db22003-10-23 06:52:01 +0000492 it doesn't qualify as a run (hence writeRunCountdown=5). */
Rob Landley2c98c402006-02-17 05:12:03 +0000493
Eric Andersen0d6d88a2003-10-18 01:58:35 +0000494 if(dbufCount) {
Eric Andersen5fa4db22003-10-23 06:52:01 +0000495 if(origPtr>=dbufCount) return RETVAL_DATA_ERROR;
Eric Andersen0d6d88a2003-10-18 01:58:35 +0000496 bd->writePos=dbuf[origPtr];
497 bd->writeCurrent=(unsigned char)(bd->writePos&0xff);
498 bd->writePos>>=8;
Eric Andersen5fa4db22003-10-23 06:52:01 +0000499 bd->writeRunCountdown=5;
Glenn L McGrath60bce492002-11-03 07:28:38 +0000500 }
Eric Andersen0d6d88a2003-10-18 01:58:35 +0000501 bd->writeCount=dbufCount;
Glenn L McGrath60bce492002-11-03 07:28:38 +0000502
Eric Andersen0d6d88a2003-10-18 01:58:35 +0000503 return RETVAL_OK;
Glenn L McGrath60bce492002-11-03 07:28:38 +0000504}
505
Eric Andersen0d6d88a2003-10-18 01:58:35 +0000506/* Undo burrows-wheeler transform on intermediate buffer to produce output.
Eric Andersen5fa4db22003-10-23 06:52:01 +0000507 If start_bunzip was initialized with out_fd=-1, then up to len bytes of
508 data are written to outbuf. Return value is number of bytes written or
509 error (all errors are negative numbers). If out_fd!=-1, outbuf and len
510 are ignored, data is written to out_fd and return is RETVAL_OK or error.
511*/
Eric Andersen0d6d88a2003-10-18 01:58:35 +0000512
Glenn L McGrath5699b852003-11-15 23:19:05 +0000513static int read_bunzip(bunzip_data *bd, char *outbuf, int len)
Eric Andersen5fa4db22003-10-23 06:52:01 +0000514{
515 const unsigned int *dbuf;
516 int pos,current,previous,gotcount;
517
518 /* If last read was short due to end of file, return last block now */
519 if(bd->writeCount<0) return bd->writeCount;
520
521 gotcount = 0;
522 dbuf=bd->dbuf;
523 pos=bd->writePos;
524 current=bd->writeCurrent;
525
526 /* We will always have pending decoded data to write into the output
527 buffer unless this is the very first call (in which case we haven't
Eric Andersenaff114c2004-04-14 17:51:38 +0000528 Huffman-decoded a block into the intermediate buffer yet). */
Eric Andersen5fa4db22003-10-23 06:52:01 +0000529
530 if (bd->writeCopies) {
Rob Landleyf856eab2006-02-17 03:43:49 +0000531
Eric Andersen5fa4db22003-10-23 06:52:01 +0000532 /* Inside the loop, writeCopies means extra copies (beyond 1) */
Rob Landleyf856eab2006-02-17 03:43:49 +0000533
Eric Andersen5fa4db22003-10-23 06:52:01 +0000534 --bd->writeCopies;
Rob Landleyf856eab2006-02-17 03:43:49 +0000535
Eric Andersen5fa4db22003-10-23 06:52:01 +0000536 /* Loop outputting bytes */
Rob Landleyf856eab2006-02-17 03:43:49 +0000537
Denis Vlasenkobf0a2012006-12-26 10:42:51 +0000538 for (;;) {
Rob Landleyf856eab2006-02-17 03:43:49 +0000539
Eric Andersen5fa4db22003-10-23 06:52:01 +0000540 /* If the output buffer is full, snapshot state and return */
Rob Landleyf856eab2006-02-17 03:43:49 +0000541
Eric Andersen5fa4db22003-10-23 06:52:01 +0000542 if(gotcount >= len) {
543 bd->writePos=pos;
544 bd->writeCurrent=current;
545 bd->writeCopies++;
546 return len;
Eric Andersen0d6d88a2003-10-18 01:58:35 +0000547 }
Rob Landleyf856eab2006-02-17 03:43:49 +0000548
Eric Andersen5fa4db22003-10-23 06:52:01 +0000549 /* Write next byte into output buffer, updating CRC */
Rob Landleyf856eab2006-02-17 03:43:49 +0000550
Eric Andersen5fa4db22003-10-23 06:52:01 +0000551 outbuf[gotcount++] = current;
552 bd->writeCRC=(((bd->writeCRC)<<8)
553 ^bd->crc32Table[((bd->writeCRC)>>24)^current]);
Rob Landleyf856eab2006-02-17 03:43:49 +0000554
Eric Andersen5fa4db22003-10-23 06:52:01 +0000555 /* Loop now if we're outputting multiple copies of this byte */
Rob Landleyf856eab2006-02-17 03:43:49 +0000556
Eric Andersen5fa4db22003-10-23 06:52:01 +0000557 if (bd->writeCopies) {
558 --bd->writeCopies;
559 continue;
560 }
561decode_next_byte:
562 if (!bd->writeCount--) break;
Eric Andersen0d6d88a2003-10-18 01:58:35 +0000563 /* Follow sequence vector to undo Burrows-Wheeler transform */
564 previous=current;
565 pos=dbuf[pos];
566 current=pos&0xff;
567 pos>>=8;
Rob Landleyf856eab2006-02-17 03:43:49 +0000568
Eric Andersen5fa4db22003-10-23 06:52:01 +0000569 /* After 3 consecutive copies of the same byte, the 4th is a repeat
570 count. We count down from 4 instead
571 * of counting up because testing for non-zero is faster */
Rob Landleyf856eab2006-02-17 03:43:49 +0000572
Eric Andersen5fa4db22003-10-23 06:52:01 +0000573 if(--bd->writeRunCountdown) {
574 if(current!=previous) bd->writeRunCountdown=4;
Glenn L McGrath60bce492002-11-03 07:28:38 +0000575 } else {
Rob Landleyf856eab2006-02-17 03:43:49 +0000576
Eric Andersen5fa4db22003-10-23 06:52:01 +0000577 /* We have a repeated run, this byte indicates the count */
Rob Landleyf856eab2006-02-17 03:43:49 +0000578
Eric Andersen5fa4db22003-10-23 06:52:01 +0000579 bd->writeCopies=current;
580 current=previous;
581 bd->writeRunCountdown=5;
Rob Landleyf856eab2006-02-17 03:43:49 +0000582
Eric Andersen5fa4db22003-10-23 06:52:01 +0000583 /* Sometimes there are just 3 bytes (run length 0) */
Rob Landleyf856eab2006-02-17 03:43:49 +0000584
Eric Andersen5fa4db22003-10-23 06:52:01 +0000585 if(!bd->writeCopies) goto decode_next_byte;
Rob Landleyf856eab2006-02-17 03:43:49 +0000586
Eric Andersen5fa4db22003-10-23 06:52:01 +0000587 /* Subtract the 1 copy we'd output anyway to get extras */
Rob Landleyf856eab2006-02-17 03:43:49 +0000588
Eric Andersen5fa4db22003-10-23 06:52:01 +0000589 --bd->writeCopies;
Glenn L McGrath60bce492002-11-03 07:28:38 +0000590 }
591 }
Rob Landleyf856eab2006-02-17 03:43:49 +0000592
Eric Andersen0d6d88a2003-10-18 01:58:35 +0000593 /* Decompression of this block completed successfully */
Rob Landleyf856eab2006-02-17 03:43:49 +0000594
Eric Andersen5fa4db22003-10-23 06:52:01 +0000595 bd->writeCRC=~bd->writeCRC;
596 bd->totalCRC=((bd->totalCRC<<1) | (bd->totalCRC>>31)) ^ bd->writeCRC;
Rob Landleyf856eab2006-02-17 03:43:49 +0000597
Eric Andersen0d6d88a2003-10-18 01:58:35 +0000598 /* If this block had a CRC error, force file level CRC error. */
Rob Landleyf856eab2006-02-17 03:43:49 +0000599
Eric Andersen5fa4db22003-10-23 06:52:01 +0000600 if(bd->writeCRC!=bd->headerCRC) {
Eric Andersen0d6d88a2003-10-18 01:58:35 +0000601 bd->totalCRC=bd->headerCRC+1;
602 return RETVAL_LAST_BLOCK;
603 }
Glenn L McGrath60bce492002-11-03 07:28:38 +0000604 }
Eric Andersen5fa4db22003-10-23 06:52:01 +0000605
Eric Andersenaff114c2004-04-14 17:51:38 +0000606 /* Refill the intermediate buffer by Huffman-decoding next block of input */
Eric Andersen5fa4db22003-10-23 06:52:01 +0000607 /* (previous is just a convenient unused temp variable here) */
Rob Landleyf856eab2006-02-17 03:43:49 +0000608
Eric Andersen5fa4db22003-10-23 06:52:01 +0000609 previous=get_next_block(bd);
610 if(previous) {
611 bd->writeCount=previous;
612 return (previous!=RETVAL_LAST_BLOCK) ? previous : gotcount;
613 }
Rob Landleyc57ec372006-04-10 17:07:15 +0000614 bd->writeCRC=~0;
Eric Andersen5fa4db22003-10-23 06:52:01 +0000615 pos=bd->writePos;
616 current=bd->writeCurrent;
617 goto decode_next_byte;
Glenn L McGrath60bce492002-11-03 07:28:38 +0000618}
619
Eric Andersen5fa4db22003-10-23 06:52:01 +0000620/* Allocate the structure, read file header. If in_fd==-1, inbuf must contain
621 a complete bunzip file (len bytes long). If in_fd!=-1, inbuf and len are
622 ignored, and data is read from file handle into temporary buffer. */
Rob Landleyf856eab2006-02-17 03:43:49 +0000623
Rob Landley1ff789c2005-09-25 03:12:26 +0000624static int start_bunzip(bunzip_data **bdp, int in_fd, unsigned char *inbuf,
625 int len)
Eric Andersen0d6d88a2003-10-18 01:58:35 +0000626{
627 bunzip_data *bd;
Rob Landleyc57ec372006-04-10 17:07:15 +0000628 unsigned int i;
Eric Andersen5fa4db22003-10-23 06:52:01 +0000629 const unsigned int BZh0=(((unsigned int)'B')<<24)+(((unsigned int)'Z')<<16)
630 +(((unsigned int)'h')<<8)+(unsigned int)'0';
Eric Andersen0d6d88a2003-10-18 01:58:35 +0000631
632 /* Figure out how much data to allocate */
Rob Landleyf856eab2006-02-17 03:43:49 +0000633
Eric Andersen0d6d88a2003-10-18 01:58:35 +0000634 i=sizeof(bunzip_data);
Eric Andersen5fa4db22003-10-23 06:52:01 +0000635 if(in_fd!=-1) i+=IOBUF_SIZE;
Rob Landleyf856eab2006-02-17 03:43:49 +0000636
Eric Andersen0d6d88a2003-10-18 01:58:35 +0000637 /* Allocate bunzip_data. Most fields initialize to zero. */
Rob Landleyf856eab2006-02-17 03:43:49 +0000638
Rob Landley1ec5b292006-05-29 07:42:02 +0000639 bd=*bdp=xzalloc(i);
Rob Landleyf856eab2006-02-17 03:43:49 +0000640
Eric Andersen5fa4db22003-10-23 06:52:01 +0000641 /* Setup input buffer */
Rob Landleyf856eab2006-02-17 03:43:49 +0000642
Eric Andersen5fa4db22003-10-23 06:52:01 +0000643 if(-1==(bd->in_fd=in_fd)) {
Eric Andersen0d6d88a2003-10-18 01:58:35 +0000644 bd->inbuf=inbuf;
645 bd->inbufCount=len;
Eric Andersen5fa4db22003-10-23 06:52:01 +0000646 } else bd->inbuf=(unsigned char *)(bd+1);
Rob Landleyf856eab2006-02-17 03:43:49 +0000647
Eric Andersen0d6d88a2003-10-18 01:58:35 +0000648 /* Init the CRC32 table (big endian) */
Rob Landleyf856eab2006-02-17 03:43:49 +0000649
Rob Landleyd921b2e2006-08-03 15:41:12 +0000650 bd->crc32Table = crc32_filltable(1);
Rob Landleyf856eab2006-02-17 03:43:49 +0000651
Eric Andersen0d6d88a2003-10-18 01:58:35 +0000652 /* Setup for I/O error handling via longjmp */
Rob Landleyf856eab2006-02-17 03:43:49 +0000653
Eric Andersen0d6d88a2003-10-18 01:58:35 +0000654 i=setjmp(bd->jmpbuf);
655 if(i) return i;
Eric Andersen5fa4db22003-10-23 06:52:01 +0000656
657 /* Ensure that file starts with "BZh['1'-'9']." */
Rob Landleyf856eab2006-02-17 03:43:49 +0000658
Eric Andersen5fa4db22003-10-23 06:52:01 +0000659 i = get_bits(bd,32);
660 if (((unsigned int)(i-BZh0-1)) >= 9) return RETVAL_NOT_BZIP_DATA;
661
662 /* Fourth byte (ascii '1'-'9'), indicates block size in units of 100k of
Eric Andersen0d6d88a2003-10-18 01:58:35 +0000663 uncompressed data. Allocate intermediate buffer for block. */
Rob Landleyf856eab2006-02-17 03:43:49 +0000664
Eric Andersen5fa4db22003-10-23 06:52:01 +0000665 bd->dbufSize=100000*(i-BZh0);
666
Glenn L McGrath1c834402003-10-28 23:32:12 +0000667 bd->dbuf=xmalloc(bd->dbufSize * sizeof(int));
Eric Andersen0d6d88a2003-10-18 01:58:35 +0000668 return RETVAL_OK;
669}
670
Eric Andersen5fa4db22003-10-23 06:52:01 +0000671/* Example usage: decompress src_fd to dst_fd. (Stops at end of bzip data,
672 not end of file.) */
Rob Landleyf856eab2006-02-17 03:43:49 +0000673
Denis Vlasenko97a8dd32006-10-01 15:55:11 +0000674USE_DESKTOP(long long) int
675uncompressStream(int src_fd, int dst_fd)
Eric Andersen0d6d88a2003-10-18 01:58:35 +0000676{
Denis Vlasenko97a8dd32006-10-01 15:55:11 +0000677 USE_DESKTOP(long long total_written = 0;)
Eric Andersen5fa4db22003-10-23 06:52:01 +0000678 char *outbuf;
Eric Andersen0d6d88a2003-10-18 01:58:35 +0000679 bunzip_data *bd;
680 int i;
681
Glenn L McGrath1c834402003-10-28 23:32:12 +0000682 outbuf=xmalloc(IOBUF_SIZE);
Denis Vlasenko97a8dd32006-10-01 15:55:11 +0000683 i=start_bunzip(&bd,src_fd,0,0);
684 if(!i) {
Denis Vlasenkobf0a2012006-12-26 10:42:51 +0000685 for (;;) {
Eric Andersen5fa4db22003-10-23 06:52:01 +0000686 if((i=read_bunzip(bd,outbuf,IOBUF_SIZE)) <= 0) break;
687 if(i!=write(dst_fd,outbuf,i)) {
688 i=RETVAL_UNEXPECTED_OUTPUT_EOF;
689 break;
690 }
Denis Vlasenko97a8dd32006-10-01 15:55:11 +0000691 USE_DESKTOP(total_written += i;)
Eric Andersen5fa4db22003-10-23 06:52:01 +0000692 }
Eric Andersen0d6d88a2003-10-18 01:58:35 +0000693 }
Rob Landleyf856eab2006-02-17 03:43:49 +0000694
Eric Andersen5fa4db22003-10-23 06:52:01 +0000695 /* Check CRC and release memory */
Rob Landleyf856eab2006-02-17 03:43:49 +0000696
Glenn L McGrath1c834402003-10-28 23:32:12 +0000697 if(i==RETVAL_LAST_BLOCK) {
698 if (bd->headerCRC!=bd->totalCRC) {
Denis Vlasenko97a8dd32006-10-01 15:55:11 +0000699 bb_error_msg("data integrity error when decompressing");
Glenn L McGrath1c834402003-10-28 23:32:12 +0000700 } else {
701 i=RETVAL_OK;
702 }
Rob Landleyf856eab2006-02-17 03:43:49 +0000703 } else if (i==RETVAL_UNEXPECTED_OUTPUT_EOF) {
Denis Vlasenko97a8dd32006-10-01 15:55:11 +0000704 bb_error_msg("compressed file ends unexpectedly");
Glenn L McGrath1c834402003-10-28 23:32:12 +0000705 } else {
Denis Vlasenko97a8dd32006-10-01 15:55:11 +0000706 bb_error_msg("decompression failed");
Glenn L McGrath1c834402003-10-28 23:32:12 +0000707 }
Rob Landleye7c43b62006-03-01 16:39:45 +0000708 free(bd->dbuf);
Eric Andersen0d6d88a2003-10-18 01:58:35 +0000709 free(bd);
Eric Andersen5fa4db22003-10-23 06:52:01 +0000710 free(outbuf);
Glenn L McGrath1c834402003-10-28 23:32:12 +0000711
Denis Vlasenko97a8dd32006-10-01 15:55:11 +0000712 return i ? i : USE_DESKTOP(total_written) + 0;
Eric Andersen0d6d88a2003-10-18 01:58:35 +0000713}
714
Eric Andersen5fa4db22003-10-23 06:52:01 +0000715#ifdef TESTING
Glenn L McGrath60bce492002-11-03 07:28:38 +0000716
Eric Andersen5fa4db22003-10-23 06:52:01 +0000717static char * const bunzip_errors[]={NULL,"Bad file checksum","Not bzip data",
718 "Unexpected input EOF","Unexpected output EOF","Data error",
Denis Vlasenko97a8dd32006-10-01 15:55:11 +0000719 "Out of memory","Obsolete (pre 0.9.5) bzip format not supported."};
Glenn L McGrath237ae422002-11-03 14:05:15 +0000720
Eric Andersen0d6d88a2003-10-18 01:58:35 +0000721/* Dumb little test thing, decompress stdin to stdout */
722int main(int argc, char *argv[])
723{
Eric Andersen5fa4db22003-10-23 06:52:01 +0000724 int i=uncompressStream(0,1);
725 char c;
726
Denis Vlasenko97a8dd32006-10-01 15:55:11 +0000727 if(i<0) fprintf(stderr,"%s\n", bunzip_errors[-i]);
728 else if(read(0,&c,1)) fprintf(stderr,"Trailing garbage ignored\n");
Eric Andersen5fa4db22003-10-23 06:52:01 +0000729 return -i;
Eric Andersen0d6d88a2003-10-18 01:58:35 +0000730}
731#endif