bunzip2: big style cleanup. No code changes apart from one s/write/safe_write/
(verified with objdump).
This commit is contained in:
parent
a9d7d24e1f
commit
b38cf3ff8a
@ -71,7 +71,7 @@ typedef struct {
|
|||||||
|
|
||||||
int in_fd, out_fd, inbufCount, inbufPos /*, outbufPos*/;
|
int in_fd, out_fd, inbufCount, inbufPos /*, outbufPos*/;
|
||||||
unsigned char *inbuf /*,*outbuf*/;
|
unsigned char *inbuf /*,*outbuf*/;
|
||||||
unsigned int inbufBitCount, inbufBits;
|
unsigned inbufBitCount, inbufBits;
|
||||||
|
|
||||||
/* The CRC values stored in the block header and calculated from the data */
|
/* The CRC values stored in the block header and calculated from the data */
|
||||||
|
|
||||||
@ -79,7 +79,7 @@ typedef struct {
|
|||||||
uint32_t *crc32Table;
|
uint32_t *crc32Table;
|
||||||
/* Intermediate buffer and its size (in bytes) */
|
/* Intermediate buffer and its size (in bytes) */
|
||||||
|
|
||||||
unsigned int *dbuf, dbufSize;
|
unsigned *dbuf, dbufSize;
|
||||||
|
|
||||||
/* These things are a bit too big to go on the stack */
|
/* These things are a bit too big to go on the stack */
|
||||||
|
|
||||||
@ -94,9 +94,9 @@ typedef struct {
|
|||||||
/* Return the next nnn bits of input. All reads from the compressed input
|
/* Return the next nnn bits of input. All reads from the compressed input
|
||||||
are done through this function. All reads are big endian */
|
are done through this function. All reads are big endian */
|
||||||
|
|
||||||
static unsigned int get_bits(bunzip_data *bd, char bits_wanted)
|
static unsigned get_bits(bunzip_data *bd, char bits_wanted)
|
||||||
{
|
{
|
||||||
unsigned int bits=0;
|
unsigned bits = 0;
|
||||||
|
|
||||||
/* If we need to get more data from the byte buffer, do so. (Loop getting
|
/* 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.) */
|
one byte at a time to enforce endianness and avoid unaligned access.) */
|
||||||
@ -106,7 +106,8 @@ static unsigned int get_bits(bunzip_data *bd, char bits_wanted)
|
|||||||
/* If we need to read more data from file into byte buffer, do so */
|
/* If we need to read more data from file into byte buffer, do so */
|
||||||
|
|
||||||
if (bd->inbufPos == bd->inbufCount) {
|
if (bd->inbufPos == bd->inbufCount) {
|
||||||
if((bd->inbufCount = read(bd->in_fd, bd->inbuf, IOBUF_SIZE)) <= 0)
|
bd->inbufCount = read(bd->in_fd, bd->inbuf, IOBUF_SIZE);
|
||||||
|
if (bd->inbufCount <= 0)
|
||||||
longjmp(bd->jmpbuf, RETVAL_UNEXPECTED_INPUT_EOF);
|
longjmp(bd->jmpbuf, RETVAL_UNEXPECTED_INPUT_EOF);
|
||||||
bd->inbufPos = 0;
|
bd->inbufPos = 0;
|
||||||
}
|
}
|
||||||
@ -142,7 +143,7 @@ static int get_next_block(bunzip_data *bd)
|
|||||||
int dbufCount, nextSym, dbufSize, groupCount, *base, *limit, selector,
|
int dbufCount, nextSym, dbufSize, groupCount, *base, *limit, selector,
|
||||||
i, j, k, t, runPos, symCount, symTotal, nSelectors, byteCount[256];
|
i, j, k, t, runPos, symCount, symTotal, nSelectors, byteCount[256];
|
||||||
unsigned char uc, symToByte[256], mtfSymbol[256], *selectors;
|
unsigned char uc, symToByte[256], mtfSymbol[256], *selectors;
|
||||||
unsigned int *dbuf,origPtr;
|
unsigned *dbuf, origPtr;
|
||||||
|
|
||||||
dbuf = bd->dbuf;
|
dbuf = bd->dbuf;
|
||||||
dbufSize = bd->dbufSize;
|
dbufSize = bd->dbufSize;
|
||||||
@ -167,7 +168,8 @@ static int get_next_block(bunzip_data *bd)
|
|||||||
it didn't actually work. */
|
it didn't actually work. */
|
||||||
|
|
||||||
if (get_bits(bd, 1)) return RETVAL_OBSOLETE_INPUT;
|
if (get_bits(bd, 1)) return RETVAL_OBSOLETE_INPUT;
|
||||||
if ((origPtr=get_bits(bd,24)) > dbufSize) return RETVAL_DATA_ERROR;
|
origPtr = get_bits(bd, 24);
|
||||||
|
if (origPtr > dbufSize) return RETVAL_DATA_ERROR;
|
||||||
|
|
||||||
/* mapping table: if some byte values are never used (encoding things
|
/* mapping table: if some byte values are never used (encoding things
|
||||||
like ascii text), the compression code removes the gaps to have fewer
|
like ascii text), the compression code removes the gaps to have fewer
|
||||||
@ -181,27 +183,31 @@ static int get_next_block(bunzip_data *bd)
|
|||||||
if (t & (1 << (15-i))) {
|
if (t & (1 << (15-i))) {
|
||||||
k = get_bits(bd, 16);
|
k = get_bits(bd, 16);
|
||||||
for (j = 0; j < 16; j++)
|
for (j = 0; j < 16; j++)
|
||||||
if(k&(1<<(15-j))) symToByte[symTotal++]=(16*i)+j;
|
if (k & (1 << (15-j)))
|
||||||
|
symToByte[symTotal++] = (16*i) + j;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* How many different Huffman coding groups does this block use? */
|
/* How many different Huffman coding groups does this block use? */
|
||||||
|
|
||||||
groupCount = get_bits(bd, 3);
|
groupCount = get_bits(bd, 3);
|
||||||
if (groupCount<2 || groupCount>MAX_GROUPS) return RETVAL_DATA_ERROR;
|
if (groupCount < 2 || groupCount > MAX_GROUPS)
|
||||||
|
return RETVAL_DATA_ERROR;
|
||||||
|
|
||||||
/* nSelectors: Every GROUP_SIZE many symbols we select a new Huffman coding
|
/* 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
|
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
|
bit runs. (MTF=Move To Front, as each value is used it's moved to the
|
||||||
start of the list.) */
|
start of the list.) */
|
||||||
|
|
||||||
if(!(nSelectors=get_bits(bd, 15))) return RETVAL_DATA_ERROR;
|
nSelectors = get_bits(bd, 15);
|
||||||
|
if (!nSelectors) return RETVAL_DATA_ERROR;
|
||||||
for (i = 0; i < groupCount; i++) mtfSymbol[i] = i;
|
for (i = 0; i < groupCount; i++) mtfSymbol[i] = i;
|
||||||
for (i = 0; i < nSelectors; i++) {
|
for (i = 0; i < nSelectors; i++) {
|
||||||
|
|
||||||
/* Get next value */
|
/* Get next value */
|
||||||
|
|
||||||
for (j=0;get_bits(bd,1);j++) if (j>=groupCount) return RETVAL_DATA_ERROR;
|
for (j = 0; get_bits(bd, 1); j++)
|
||||||
|
if (j>=groupCount) return RETVAL_DATA_ERROR;
|
||||||
|
|
||||||
/* Decode MTF to get the next selector */
|
/* Decode MTF to get the next selector */
|
||||||
|
|
||||||
@ -228,7 +234,7 @@ static int get_next_block(bunzip_data *bd)
|
|||||||
t = get_bits(bd, 5) - 1;
|
t = get_bits(bd, 5) - 1;
|
||||||
for (i = 0; i < symCount; i++) {
|
for (i = 0; i < symCount; i++) {
|
||||||
for (;;) {
|
for (;;) {
|
||||||
if (((unsigned)t) > (MAX_HUFCODE_BITS-1))
|
if ((unsigned)t > (MAX_HUFCODE_BITS-1))
|
||||||
return RETVAL_DATA_ERROR;
|
return RETVAL_DATA_ERROR;
|
||||||
|
|
||||||
/* If first bit is 0, stop. Else second bit indicates whether
|
/* If first bit is 0, stop. Else second bit indicates whether
|
||||||
@ -287,7 +293,8 @@ static int get_next_block(bunzip_data *bd)
|
|||||||
for (i = minLen; i <= maxLen; i++) {
|
for (i = minLen; i <= maxLen; i++) {
|
||||||
temp[i] = limit[i] = 0;
|
temp[i] = limit[i] = 0;
|
||||||
for (t = 0; t < symCount; t++)
|
for (t = 0; t < symCount; t++)
|
||||||
if(length[t]==i) hufGroup->permute[pp++] = t;
|
if (length[t] == i)
|
||||||
|
hufGroup->permute[pp++] = t;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Count symbols coded for at each bit length */
|
/* Count symbols coded for at each bit length */
|
||||||
@ -312,7 +319,8 @@ static int get_next_block(bunzip_data *bd)
|
|||||||
|
|
||||||
limit[i] = (pp << (maxLen - i)) - 1;
|
limit[i] = (pp << (maxLen - i)) - 1;
|
||||||
pp <<= 1;
|
pp <<= 1;
|
||||||
base[i+1]=pp-(t+=temp[i]);
|
t += temp[i];
|
||||||
|
base[i+1] = pp - t;
|
||||||
}
|
}
|
||||||
limit[maxLen+1] = INT_MAX; /* Sentinal value for reading next sym. */
|
limit[maxLen+1] = INT_MAX; /* Sentinal value for reading next sym. */
|
||||||
limit[maxLen] = pp + temp[maxLen] - 1;
|
limit[maxLen] = pp + temp[maxLen] - 1;
|
||||||
@ -377,9 +385,10 @@ got_huff_bits:
|
|||||||
|
|
||||||
/* Huffman decode value to get nextSym (with bounds checking) */
|
/* Huffman decode value to get nextSym (with bounds checking) */
|
||||||
|
|
||||||
if ((i > hufGroup->maxLen)
|
if (i > hufGroup->maxLen)
|
||||||
|| (((unsigned)(j=(j>>(hufGroup->maxLen-i))-base[i]))
|
return RETVAL_DATA_ERROR;
|
||||||
>= MAX_SYMBOLS))
|
j = (j >> (hufGroup->maxLen - i)) - base[i];
|
||||||
|
if ((unsigned)j >= MAX_SYMBOLS)
|
||||||
return RETVAL_DATA_ERROR;
|
return RETVAL_DATA_ERROR;
|
||||||
nextSym = hufGroup->permute[j];
|
nextSym = hufGroup->permute[j];
|
||||||
|
|
||||||
@ -388,7 +397,7 @@ got_huff_bits:
|
|||||||
check if nextSym indicates a repeated run, and if so loop collecting
|
check if nextSym indicates a repeated run, and if so loop collecting
|
||||||
how many times to repeat the last literal. */
|
how many times to repeat the last literal. */
|
||||||
|
|
||||||
if (((unsigned)nextSym) <= SYMBOL_RUNB) { /* RUNA or RUNB */
|
if ((unsigned)nextSym <= SYMBOL_RUNB) { /* RUNA or RUNB */
|
||||||
|
|
||||||
/* If this is the start of a new run, zero out counter */
|
/* If this is the start of a new run, zero out counter */
|
||||||
|
|
||||||
@ -454,7 +463,7 @@ got_huff_bits:
|
|||||||
/* We have our literal byte. Save it into dbuf. */
|
/* We have our literal byte. Save it into dbuf. */
|
||||||
|
|
||||||
byteCount[uc]++;
|
byteCount[uc]++;
|
||||||
dbuf[dbufCount++] = (unsigned int)uc;
|
dbuf[dbufCount++] = (unsigned)uc;
|
||||||
|
|
||||||
/* Skip group initialization if we're not done with this group. Done
|
/* Skip group initialization if we're not done with this group. Done
|
||||||
* this way to avoid compiler warning. */
|
* this way to avoid compiler warning. */
|
||||||
@ -512,7 +521,7 @@ end_of_huffman_loop:
|
|||||||
|
|
||||||
static int read_bunzip(bunzip_data *bd, char *outbuf, int len)
|
static int read_bunzip(bunzip_data *bd, char *outbuf, int len)
|
||||||
{
|
{
|
||||||
const unsigned int *dbuf;
|
const unsigned *dbuf;
|
||||||
int pos, current, previous, gotcount;
|
int pos, current, previous, gotcount;
|
||||||
|
|
||||||
/* If last read was short due to end of file, return last block now */
|
/* If last read was short due to end of file, return last block now */
|
||||||
@ -549,8 +558,8 @@ static int read_bunzip(bunzip_data *bd, char *outbuf, int len)
|
|||||||
/* Write next byte into output buffer, updating CRC */
|
/* Write next byte into output buffer, updating CRC */
|
||||||
|
|
||||||
outbuf[gotcount++] = current;
|
outbuf[gotcount++] = current;
|
||||||
bd->writeCRC=(((bd->writeCRC)<<8)
|
bd->writeCRC = (bd->writeCRC << 8)
|
||||||
^bd->crc32Table[((bd->writeCRC)>>24)^current]);
|
^ bd->crc32Table[(bd->writeCRC >> 24) ^ current];
|
||||||
|
|
||||||
/* Loop now if we're outputting multiple copies of this byte */
|
/* Loop now if we're outputting multiple copies of this byte */
|
||||||
|
|
||||||
@ -571,7 +580,8 @@ decode_next_byte:
|
|||||||
* of counting up because testing for non-zero is faster */
|
* of counting up because testing for non-zero is faster */
|
||||||
|
|
||||||
if (--bd->writeRunCountdown) {
|
if (--bd->writeRunCountdown) {
|
||||||
if(current!=previous) bd->writeRunCountdown=4;
|
if (current != previous)
|
||||||
|
bd->writeRunCountdown = 4;
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
/* We have a repeated run, this byte indicates the count */
|
/* We have a repeated run, this byte indicates the count */
|
||||||
@ -625,9 +635,10 @@ static int start_bunzip(bunzip_data **bdp, int in_fd, unsigned char *inbuf,
|
|||||||
int len)
|
int len)
|
||||||
{
|
{
|
||||||
bunzip_data *bd;
|
bunzip_data *bd;
|
||||||
unsigned int i;
|
unsigned i;
|
||||||
const unsigned int BZh0=(((unsigned int)'B')<<24)+(((unsigned int)'Z')<<16)
|
enum {
|
||||||
+(((unsigned int)'h')<<8)+(unsigned int)'0';
|
BZh0 = ('B' << 24) + ('Z' << 16) + ('h' << 8) + '0'
|
||||||
|
};
|
||||||
|
|
||||||
/* Figure out how much data to allocate */
|
/* Figure out how much data to allocate */
|
||||||
|
|
||||||
@ -640,10 +651,12 @@ static int start_bunzip(bunzip_data **bdp, int in_fd, unsigned char *inbuf,
|
|||||||
|
|
||||||
/* Setup input buffer */
|
/* Setup input buffer */
|
||||||
|
|
||||||
if(-1==(bd->in_fd=in_fd)) {
|
bd->in_fd = in_fd;
|
||||||
|
if (-1 == in_fd) {
|
||||||
bd->inbuf = inbuf;
|
bd->inbuf = inbuf;
|
||||||
bd->inbufCount = len;
|
bd->inbufCount = len;
|
||||||
} else bd->inbuf=(unsigned char *)(bd+1);
|
} else
|
||||||
|
bd->inbuf = (unsigned char *)(bd + 1);
|
||||||
|
|
||||||
/* Init the CRC32 table (big endian) */
|
/* Init the CRC32 table (big endian) */
|
||||||
|
|
||||||
@ -657,7 +670,7 @@ static int start_bunzip(bunzip_data **bdp, int in_fd, unsigned char *inbuf,
|
|||||||
/* Ensure that file starts with "BZh['1'-'9']." */
|
/* Ensure that file starts with "BZh['1'-'9']." */
|
||||||
|
|
||||||
i = get_bits(bd, 32);
|
i = get_bits(bd, 32);
|
||||||
if (((unsigned int)(i-BZh0-1)) >= 9) return RETVAL_NOT_BZIP_DATA;
|
if (((unsigned)(i - BZh0 - 1)) >= 9) return RETVAL_NOT_BZIP_DATA;
|
||||||
|
|
||||||
/* Fourth byte (ascii '1'-'9'), indicates block size in units of 100k of
|
/* Fourth byte (ascii '1'-'9'), indicates block size in units of 100k of
|
||||||
uncompressed data. Allocate intermediate buffer for block. */
|
uncompressed data. Allocate intermediate buffer for block. */
|
||||||
@ -683,8 +696,9 @@ uncompressStream(int src_fd, int dst_fd)
|
|||||||
i = start_bunzip(&bd, src_fd, 0, 0);
|
i = start_bunzip(&bd, src_fd, 0, 0);
|
||||||
if (!i) {
|
if (!i) {
|
||||||
for (;;) {
|
for (;;) {
|
||||||
if((i=read_bunzip(bd,outbuf,IOBUF_SIZE)) <= 0) break;
|
i = read_bunzip(bd, outbuf, IOBUF_SIZE);
|
||||||
if(i!=write(dst_fd,outbuf,i)) {
|
if (i <= 0) break;
|
||||||
|
if (i != safe_write(dst_fd, outbuf, i)) {
|
||||||
i = RETVAL_UNEXPECTED_OUTPUT_EOF;
|
i = RETVAL_UNEXPECTED_OUTPUT_EOF;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -714,9 +728,11 @@ uncompressStream(int src_fd, int dst_fd)
|
|||||||
|
|
||||||
#ifdef TESTING
|
#ifdef TESTING
|
||||||
|
|
||||||
static char * const bunzip_errors[]={NULL,"Bad file checksum","Not bzip data",
|
static char *const bunzip_errors[] = {
|
||||||
|
NULL, "Bad file checksum", "Not bzip data",
|
||||||
"Unexpected input EOF", "Unexpected output EOF", "Data error",
|
"Unexpected input EOF", "Unexpected output EOF", "Data error",
|
||||||
"Out of memory","Obsolete (pre 0.9.5) bzip format not supported."};
|
"Out of memory", "Obsolete (pre 0.9.5) bzip format not supported"
|
||||||
|
};
|
||||||
|
|
||||||
/* Dumb little test thing, decompress stdin to stdout */
|
/* Dumb little test thing, decompress stdin to stdout */
|
||||||
int main(int argc, char **argv)
|
int main(int argc, char **argv)
|
||||||
@ -724,8 +740,10 @@ int main(int argc, char **argv)
|
|||||||
int i = uncompressStream(0, 1);
|
int i = uncompressStream(0, 1);
|
||||||
char c;
|
char c;
|
||||||
|
|
||||||
if(i<0) fprintf(stderr,"%s\n", bunzip_errors[-i]);
|
if (i < 0)
|
||||||
else if(read(0,&c,1)) fprintf(stderr,"Trailing garbage ignored\n");
|
fprintf(stderr,"%s\n", bunzip_errors[-i]);
|
||||||
|
else if (read(0, &c, 1))
|
||||||
|
fprintf(stderr,"Trailing garbage ignored\n");
|
||||||
return -i;
|
return -i;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
Loading…
Reference in New Issue
Block a user