aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--archival/libunarchive/decompress_bunzip2.c50
1 files changed, 28 insertions, 22 deletions
diff --git a/archival/libunarchive/decompress_bunzip2.c b/archival/libunarchive/decompress_bunzip2.c
index 17b87e2c1..c1b12732c 100644
--- a/archival/libunarchive/decompress_bunzip2.c
+++ b/archival/libunarchive/decompress_bunzip2.c
@@ -44,7 +44,7 @@
44#define RETVAL_LAST_BLOCK (-1) 44#define RETVAL_LAST_BLOCK (-1)
45#define RETVAL_NOT_BZIP_DATA (-2) 45#define RETVAL_NOT_BZIP_DATA (-2)
46#define RETVAL_UNEXPECTED_INPUT_EOF (-3) 46#define RETVAL_UNEXPECTED_INPUT_EOF (-3)
47#define RETVAL_UNEXPECTED_OUTPUT_EOF (-4) 47#define RETVAL_SHORT_WRITE (-4)
48#define RETVAL_DATA_ERROR (-5) 48#define RETVAL_DATA_ERROR (-5)
49#define RETVAL_OUT_OF_MEMORY (-6) 49#define RETVAL_OUT_OF_MEMORY (-6)
50#define RETVAL_OBSOLETE_INPUT (-7) 50#define RETVAL_OBSOLETE_INPUT (-7)
@@ -54,22 +54,27 @@
54 54
55/* This is what we know about each Huffman coding group */ 55/* This is what we know about each Huffman coding group */
56struct group_data { 56struct group_data {
57 /* We have an extra slot at the end of limit[] for a sentinal value. */ 57 /* We have an extra slot at the end of limit[] for a sentinel value. */
58 int limit[MAX_HUFCODE_BITS+1], base[MAX_HUFCODE_BITS], permute[MAX_SYMBOLS]; 58 int limit[MAX_HUFCODE_BITS+1], base[MAX_HUFCODE_BITS], permute[MAX_SYMBOLS];
59 int minLen, maxLen; 59 int minLen, maxLen;
60}; 60};
61 61
62/* Structure holding all the housekeeping data, including IO buffers and 62/* Structure holding all the housekeeping data, including IO buffers and
63 memory that persists between calls to bunzip */ 63 * memory that persists between calls to bunzip
64 * Found the most used member:
65 * cat this_file.c | sed -e 's/"/ /g' -e "s/'/ /g" | xargs -n1 \
66 * | grep 'bd->' | sed 's/^.*bd->/bd->/' | sort | $PAGER
67 * and moved it (inbufBitCount) to offset 0.
68 */
64 69
65struct bunzip_data { 70struct bunzip_data {
66 /* State for interrupting output loop */
67 int writeCopies, writePos, writeRunCountdown, writeCount, writeCurrent;
68
69 /* I/O tracking data (file handles, buffers, positions, etc.) */ 71 /* I/O tracking data (file handles, buffers, positions, etc.) */
72 unsigned inbufBitCount, inbufBits;
70 int in_fd, out_fd, inbufCount, inbufPos /*, outbufPos*/; 73 int in_fd, out_fd, inbufCount, inbufPos /*, outbufPos*/;
71 unsigned char *inbuf /*,*outbuf*/; 74 unsigned char *inbuf /*,*outbuf*/;
72 unsigned inbufBitCount, inbufBits; 75
76 /* State for interrupting output loop */
77 int writeCopies, writePos, writeRunCountdown, writeCount, writeCurrent;
73 78
74 /* The CRC values stored in the block header and calculated from the data */ 79 /* The CRC values stored in the block header and calculated from the data */
75 uint32_t headerCRC, totalCRC, writeCRC; 80 uint32_t headerCRC, totalCRC, writeCRC;
@@ -80,7 +85,7 @@ struct bunzip_data {
80 /* For I/O error handling */ 85 /* For I/O error handling */
81 jmp_buf jmpbuf; 86 jmp_buf jmpbuf;
82 87
83 /* Big things go last (register-relative addressing can be larger for big offsets */ 88 /* Big things go last (register-relative addressing can be larger for big offsets) */
84 uint32_t crc32Table[256]; 89 uint32_t crc32Table[256];
85 unsigned char selectors[32768]; /* nSelectors=15 bits */ 90 unsigned char selectors[32768]; /* nSelectors=15 bits */
86 struct group_data groups[MAX_GROUPS]; /* Huffman coding tables */ 91 struct group_data groups[MAX_GROUPS]; /* Huffman coding tables */
@@ -91,7 +96,7 @@ struct bunzip_data {
91/* Return the next nnn bits of input. All reads from the compressed input 96/* Return the next nnn bits of input. All reads from the compressed input
92 are done through this function. All reads are big endian */ 97 are done through this function. All reads are big endian */
93 98
94static unsigned get_bits(bunzip_data *bd, char bits_wanted) 99static unsigned get_bits(bunzip_data *bd, int bits_wanted)
95{ 100{
96 unsigned bits = 0; 101 unsigned bits = 0;
97 102
@@ -121,7 +126,7 @@ static unsigned get_bits(bunzip_data *bd, char bits_wanted)
121 126
122 /* Grab next 8 bits of input from buffer. */ 127 /* Grab next 8 bits of input from buffer. */
123 128
124 bd->inbufBits = (bd->inbufBits<<8) | bd->inbuf[bd->inbufPos++]; 129 bd->inbufBits = (bd->inbufBits << 8) | bd->inbuf[bd->inbufPos++];
125 bd->inbufBitCount += 8; 130 bd->inbufBitCount += 8;
126 } 131 }
127 132
@@ -205,7 +210,7 @@ static int get_next_block(bunzip_data *bd)
205 /* Get next value */ 210 /* Get next value */
206 211
207 for (j = 0; get_bits(bd, 1); j++) 212 for (j = 0; get_bits(bd, 1); j++)
208 if (j>=groupCount) return RETVAL_DATA_ERROR; 213 if (j >= groupCount) return RETVAL_DATA_ERROR;
209 214
210 /* Decode MTF to get the next selector */ 215 /* Decode MTF to get the next selector */
211 216
@@ -320,19 +325,20 @@ static int get_next_block(bunzip_data *bd)
320 t += temp[i]; 325 t += temp[i];
321 base[i+1] = pp - t; 326 base[i+1] = pp - t;
322 } 327 }
323 limit[maxLen+1] = INT_MAX; /* Sentinal value for reading next sym. */ 328 limit[maxLen+1] = INT_MAX; /* Sentinel value for reading next sym. */
324 limit[maxLen] = pp + temp[maxLen] - 1; 329 limit[maxLen] = pp + temp[maxLen] - 1;
325 base[minLen] = 0; 330 base[minLen] = 0;
326 } 331 }
327 332
328 /* We've finished reading and digesting the block header. Now read this 333 /* We've finished reading and digesting the block header. Now read this
329 block's Huffman coded symbols from the file and undo the Huffman coding 334 block's Huffman coded symbols from the file and undo the Huffman coding
330 and run length encoding, saving the result into dbuf[dbufCount++]=uc */ 335 and run length encoding, saving the result into dbuf[dbufCount++] = uc */
331 336
332 /* Initialize symbol occurrence counters and symbol Move To Front table */ 337 /* Initialize symbol occurrence counters and symbol Move To Front table */
333 338
339 memset(byteCount, 0, sizeof(byteCount)); /* smaller, maybe slower? */
334 for (i = 0; i < 256; i++) { 340 for (i = 0; i < 256; i++) {
335 byteCount[i] = 0; 341 //byteCount[i] = 0;
336 mtfSymbol[i] = (unsigned char)i; 342 mtfSymbol[i] = (unsigned char)i;
337 } 343 }
338 344
@@ -547,7 +553,7 @@ int read_bunzip(bunzip_data *bd, char *outbuf, int len)
547 /* If the output buffer is full, snapshot state and return */ 553 /* If the output buffer is full, snapshot state and return */
548 554
549 if (gotcount >= len) { 555 if (gotcount >= len) {
550 bd->writePos =pos; 556 bd->writePos = pos;
551 bd->writeCurrent = current; 557 bd->writeCurrent = current;
552 bd->writeCopies++; 558 bd->writeCopies++;
553 return len; 559 return len;
@@ -573,8 +579,8 @@ int read_bunzip(bunzip_data *bd, char *outbuf, int len)
573 current = pos & 0xff; 579 current = pos & 0xff;
574 pos >>= 8; 580 pos >>= 8;
575 581
576 /* After 3 consecutive copies of the same byte, the 4th is a repeat 582 /* After 3 consecutive copies of the same byte, the 4th
577 count. We count down from 4 instead 583 * is a repeat count. We count down from 4 instead
578 * of counting up because testing for non-zero is faster */ 584 * of counting up because testing for non-zero is faster */
579 585
580 if (--bd->writeRunCountdown) { 586 if (--bd->writeRunCountdown) {
@@ -606,7 +612,7 @@ int read_bunzip(bunzip_data *bd, char *outbuf, int len)
606 /* If this block had a CRC error, force file level CRC error. */ 612 /* If this block had a CRC error, force file level CRC error. */
607 613
608 if (bd->writeCRC != bd->headerCRC) { 614 if (bd->writeCRC != bd->headerCRC) {
609 bd->totalCRC = bd->headerCRC+1; 615 bd->totalCRC = bd->headerCRC + 1;
610 return RETVAL_LAST_BLOCK; 616 return RETVAL_LAST_BLOCK;
611 } 617 }
612 } 618 }
@@ -713,8 +719,8 @@ unpack_bz2_stream(int src_fd, int dst_fd)
713 for (;;) { 719 for (;;) {
714 i = read_bunzip(bd, outbuf, IOBUF_SIZE); 720 i = read_bunzip(bd, outbuf, IOBUF_SIZE);
715 if (i <= 0) break; 721 if (i <= 0) break;
716 if (i != safe_write(dst_fd, outbuf, i)) { 722 if (i != full_write(dst_fd, outbuf, i)) {
717 i = RETVAL_UNEXPECTED_OUTPUT_EOF; 723 i = RETVAL_SHORT_WRITE;
718 break; 724 break;
719 } 725 }
720 USE_DESKTOP(total_written += i;) 726 USE_DESKTOP(total_written += i;)
@@ -729,8 +735,8 @@ unpack_bz2_stream(int src_fd, int dst_fd)
729 } else { 735 } else {
730 i = RETVAL_OK; 736 i = RETVAL_OK;
731 } 737 }
732 } else if (i == RETVAL_UNEXPECTED_OUTPUT_EOF) { 738 } else if (i == RETVAL_SHORT_WRITE) {
733 bb_error_msg("unexpected EOF"); 739 bb_error_msg("short write");
734 } else { 740 } else {
735 bb_error_msg("bunzip error %d", i); 741 bb_error_msg("bunzip error %d", i);
736 } 742 }