2009-01-05 00:46:16 +03:00
/* 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 .
This code is licensed under the LGPLv2 :
LGPL ( http : //www.gnu.org/copyleft/lgpl.html
*/
/*
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 in the name of the woman I loved , who
passed away Feb . 12 , 2003.
In memory of Toni W . Hagan
Hospice of Acadiana , Inc .
2600 Johnston St . , Suite 200
Lafayette , LA 70503 - 3240
Phone ( 337 ) 232 - 1234 or 1 - 800 - 738 - 2226
Fax ( 337 ) 232 - 1297
http : //www.hospiceacadiana.com/
Manuel
*/
/*
Made it fit for running in Linux Kernel by Alain Knaff ( alain @ knaff . lu )
*/
2009-08-07 02:09:31 +04:00
# ifdef STATIC
# define PREBOOT
# else
2009-01-05 00:46:16 +03:00
# include <linux/decompress/bunzip2.h>
2009-08-07 02:09:32 +04:00
# include <linux/slab.h>
2009-08-07 02:09:31 +04:00
# endif /* STATIC */
2009-01-05 00:46:16 +03:00
# include <linux/decompress/mm.h>
# ifndef INT_MAX
# define INT_MAX 0x7fffffff
# 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 (-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 BZIP2_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 ] ;
int base [ MAX_HUFCODE_BITS ] ;
int permute [ MAX_SYMBOLS ] ;
int minLen , maxLen ;
} ;
/* Structure holding all the housekeeping data, including IO buffers and
memory that persists between calls to bunzip */
struct bunzip_data {
/* State for interrupting output loop */
int writeCopies , writePos , writeRunCountdown , writeCount , writeCurrent ;
/* I/O tracking data (file handles, buffers, positions, etc.) */
int ( * fill ) ( void * , unsigned int ) ;
int inbufCount , inbufPos /*, outbufPos*/ ;
unsigned char * inbuf /*,*outbuf*/ ;
unsigned int inbufBitCount , inbufBits ;
/* The CRC values stored in the block header and calculated from the
data */
unsigned int crc32Table [ 256 ] , headerCRC , totalCRC , writeCRC ;
/* 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 */
int io_error ; /* non-zero if we have IO error */
} ;
/* 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 INIT get_bits ( struct 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 - > io_error )
return 0 ;
bd - > inbufCount = bd - > fill ( bd - > inbuf , BZIP2_IOBUF_SIZE ) ;
if ( bd - > inbufCount < = 0 ) {
bd - > io_error = RETVAL_UNEXPECTED_INPUT_EOF ;
return 0 ;
}
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 INIT get_next_block ( struct bunzip_data * bd )
{
struct group_data * hufGroup = NULL ;
int * base = NULL ;
int * limit = NULL ;
int dbufCount , nextSym , dbufSize , groupCount , 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 ;
/* 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 > 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 . ) */
nSelectors = get_bits ( bd , 15 ) ;
if ( ! nSelectors )
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 ;
tree-wide: fix assorted typos all over the place
That is "success", "unknown", "through", "performance", "[re|un]mapping"
, "access", "default", "reasonable", "[con]currently", "temperature"
, "channel", "[un]used", "application", "example","hierarchy", "therefore"
, "[over|under]flow", "contiguous", "threshold", "enough" and others.
Signed-off-by: André Goddard Rosa <andre.goddard@gmail.com>
Signed-off-by: Jiri Kosina <jkosina@suse.cz>
2009-11-14 18:09:05 +03:00
/* Calculate permute[]. Concurrently, initialize
2009-01-05 00:46:16 +03:00
* 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 = symCount = selector = 0 ;
for ( ; ; ) {
/* Determine which Huffman coding group to use. */
if ( ! ( symCount - - ) ) {
symCount = GROUP_SIZE - 1 ;
if ( selector > = nSelectors )
return RETVAL_DATA_ERROR ;
hufGroup = bd - > groups + selectors [ selector + + ] ;
base = hufGroup - > base - 1 ;
limit = hufGroup - > limit - 1 ;
}
/* 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 */
runPos < < = 1 ;
continue ;
}
/* 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 ;
}
/* 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 INIT read_bunzip ( struct bunzip_data * bd , char * outbuf , int len )
{
const unsigned int * dbuf ;
int pos , xcurrent , 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 ;
xcurrent = 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 = xcurrent ;
bd - > writeCopies + + ;
return len ;
}
/* Write next byte into output buffer, updating CRC */
outbuf [ gotcount + + ] = xcurrent ;
bd - > writeCRC = ( ( ( bd - > writeCRC ) < < 8 )
^ bd - > crc32Table [ ( ( bd - > writeCRC ) > > 24 )
^ xcurrent ] ) ;
/* 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 = xcurrent ;
pos = dbuf [ pos ] ;
xcurrent = pos & 0xff ;
pos > > = 8 ;
/* After 3 consecutive copies of the same
byte , the 4 th is a repeat count . We count
down from 4 instead * of counting up because
testing for non - zero is faster */
if ( - - bd - > writeRunCountdown ) {
if ( xcurrent ! = previous )
bd - > writeRunCountdown = 4 ;
} else {
/* We have a repeated run, this byte
* indicates the count */
bd - > writeCopies = xcurrent ;
xcurrent = 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 = 0xffffffffUL ;
pos = bd - > writePos ;
xcurrent = bd - > writeCurrent ;
goto decode_next_byte ;
}
static int INIT nofill ( void * buf , unsigned int len )
{
return - 1 ;
}
/* 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 INIT start_bunzip ( struct bunzip_data * * bdp , void * inbuf , int len ,
int ( * fill ) ( void * , unsigned int ) )
{
struct bunzip_data * bd ;
unsigned int i , j , c ;
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 ( struct bunzip_data ) ;
/* Allocate bunzip_data. Most fields initialize to zero. */
bd = * bdp = malloc ( i ) ;
2009-12-15 00:45:19 +03:00
if ( ! bd )
return RETVAL_OUT_OF_MEMORY ;
2009-01-05 00:46:16 +03:00
memset ( bd , 0 , sizeof ( struct bunzip_data ) ) ;
/* Setup input buffer */
bd - > inbuf = inbuf ;
bd - > inbufCount = len ;
if ( fill ! = NULL )
bd - > fill = fill ;
else
bd - > fill = nofill ;
/* Init the CRC32 table (big endian) */
for ( i = 0 ; i < 256 ; i + + ) {
c = i < < 24 ;
for ( j = 8 ; j ; j - - )
c = c & 0x80000000 ? ( c < < 1 ) ^ 0x04c11db7 : ( c < < 1 ) ;
bd - > crc32Table [ i ] = c ;
}
/* 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 = large_malloc ( bd - > dbufSize * sizeof ( int ) ) ;
2009-12-15 00:45:19 +03:00
if ( ! bd - > dbuf )
return RETVAL_OUT_OF_MEMORY ;
2009-01-05 00:46:16 +03:00
return RETVAL_OK ;
}
/* Example usage: decompress src_fd to dst_fd. (Stops at end of bzip2 data,
not end of file . ) */
STATIC int INIT bunzip2 ( unsigned char * buf , int len ,
int ( * fill ) ( void * , unsigned int ) ,
int ( * flush ) ( void * , unsigned int ) ,
unsigned char * outbuf ,
int * pos ,
void ( * error_fn ) ( char * x ) )
{
struct bunzip_data * bd ;
int i = - 1 ;
unsigned char * inbuf ;
set_error_fn ( error_fn ) ;
if ( flush )
outbuf = malloc ( BZIP2_IOBUF_SIZE ) ;
2009-08-07 02:09:31 +04:00
2009-01-05 00:46:16 +03:00
if ( ! outbuf ) {
error ( " Could not allocate output bufer " ) ;
2009-12-15 00:45:19 +03:00
return RETVAL_OUT_OF_MEMORY ;
2009-01-05 00:46:16 +03:00
}
if ( buf )
inbuf = buf ;
else
inbuf = malloc ( BZIP2_IOBUF_SIZE ) ;
if ( ! inbuf ) {
error ( " Could not allocate input bufer " ) ;
2009-12-15 00:45:19 +03:00
i = RETVAL_OUT_OF_MEMORY ;
2009-01-05 00:46:16 +03:00
goto exit_0 ;
}
i = start_bunzip ( & bd , inbuf , len , fill ) ;
if ( ! i ) {
for ( ; ; ) {
i = read_bunzip ( bd , outbuf , BZIP2_IOBUF_SIZE ) ;
if ( i < = 0 )
break ;
if ( ! flush )
outbuf + = i ;
else
if ( i ! = flush ( outbuf , i ) ) {
i = RETVAL_UNEXPECTED_OUTPUT_EOF ;
break ;
}
}
}
/* Check CRC and release memory */
if ( i = = RETVAL_LAST_BLOCK ) {
if ( bd - > headerCRC ! = bd - > totalCRC )
error ( " Data integrity error when decompressing. " ) ;
else
i = RETVAL_OK ;
} else if ( i = = RETVAL_UNEXPECTED_OUTPUT_EOF ) {
error ( " Compressed file ends unexpectedly " ) ;
}
2009-12-15 00:45:19 +03:00
if ( ! bd )
goto exit_1 ;
2009-01-05 00:46:16 +03:00
if ( bd - > dbuf )
large_free ( bd - > dbuf ) ;
if ( pos )
* pos = bd - > inbufPos ;
free ( bd ) ;
2009-12-15 00:45:19 +03:00
exit_1 :
2009-01-05 00:46:16 +03:00
if ( ! buf )
free ( inbuf ) ;
exit_0 :
if ( flush )
free ( outbuf ) ;
return i ;
}
2009-08-07 02:09:31 +04:00
# ifdef PREBOOT
STATIC int INIT decompress ( unsigned char * buf , int len ,
int ( * fill ) ( void * , unsigned int ) ,
int ( * flush ) ( void * , unsigned int ) ,
unsigned char * outbuf ,
int * pos ,
void ( * error_fn ) ( char * x ) )
{
return bunzip2 ( buf , len - 4 , fill , flush , outbuf , pos , error_fn ) ;
}
# endif