From eda4f53f2ebf3d9565c3d7aa500a2e1d9cfd9774 Mon Sep 17 00:00:00 2001 From: Glenn L McGrath Date: Sun, 24 Nov 2002 06:01:20 +0000 Subject: [PATCH] Add an input buffer (currently 32kB) to speed things up heaps, it still requires 25% longer to decompress as compared to upstream. --- archival/libunarchive/check_trailer_gzip.c | 27 +++++++++++++-------- archival/libunarchive/decompress_unzip.c | 39 +++++++++++++++++++++++------- archival/libunarchive/unzip.c | 39 +++++++++++++++++++++++------- 3 files changed, 77 insertions(+), 28 deletions(-) diff --git a/archival/libunarchive/check_trailer_gzip.c b/archival/libunarchive/check_trailer_gzip.c index 2d6ceaeda..b30db71ae 100644 --- a/archival/libunarchive/check_trailer_gzip.c +++ b/archival/libunarchive/check_trailer_gzip.c @@ -32,31 +32,38 @@ extern unsigned int gunzip_crc; extern unsigned int gunzip_bytes_out; -extern unsigned char *gunzip_in_buffer; -extern unsigned char gunzip_in_buffer_count; +extern unsigned char *bytebuffer; +extern unsigned short bytebuffer_offset; +extern unsigned short bytebuffer_size; +//extern unsigned char *gunzip_in_buffer; +//extern unsigned char gunzip_in_buffer_count; extern void check_trailer_gzip(int src_fd) { - unsigned int stored_crc = 0; unsigned char count; /* top up the input buffer with the rest of the trailer */ - xread_all(src_fd, &gunzip_in_buffer[gunzip_in_buffer_count], 8 - gunzip_in_buffer_count); + count = bytebuffer_size - bytebuffer_offset; + if (count < 8) { + xread_all(src_fd, &bytebuffer[bytebuffer_size], 8 - count); + bytebuffer_size += 8 - count; + } for (count = 0; count != 4; count++) { - stored_crc |= (gunzip_in_buffer[count] << (count * 8)); + stored_crc |= (bytebuffer[bytebuffer_offset] << (count * 8)); + bytebuffer_offset++; } /* Validate decompression - crc */ if (stored_crc != (gunzip_crc ^ 0xffffffffL)) { - error_msg_and_die("invalid compressed data--crc error"); + error_msg_and_die("crc error"); } /* Validate decompression - size */ - if (gunzip_bytes_out != - (gunzip_in_buffer[4] | (gunzip_in_buffer[5] << 8) | - (gunzip_in_buffer[6] << 16) | (gunzip_in_buffer[7] << 24))) { - error_msg_and_die("invalid compressed data--length error"); + if (gunzip_bytes_out != + (bytebuffer[bytebuffer_offset] | (bytebuffer[bytebuffer_offset+1] << 8) | + (bytebuffer[bytebuffer_offset+2] << 16) | (bytebuffer[bytebuffer_offset+3] << 24))) { + error_msg_and_die("Incorrect length, but crc is correct"); } } diff --git a/archival/libunarchive/decompress_unzip.c b/archival/libunarchive/decompress_unzip.c index d8d5b77b1..770e4141d 100644 --- a/archival/libunarchive/decompress_unzip.c +++ b/archival/libunarchive/decompress_unzip.c @@ -88,8 +88,8 @@ static unsigned int gunzip_outbuf_count; /* bytes in output buffer */ /* This is used to sanify any unused bits from the bitbuffer * so they arent skipped when reading trailers (trailing headers) */ -unsigned char gunzip_in_buffer_count; -unsigned char *gunzip_in_buffer; +//unsigned char gunzip_in_buffer_count; +//unsigned char *gunzip_in_buffer; /* gunzip_window size--must be a power of two, and * at least 32K for zip's deflate method */ @@ -142,13 +142,30 @@ static const unsigned char border[] = { 16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15 }; +#define BYTEBUFFER_MAX 0x8000 +unsigned char *bytebuffer = NULL; +unsigned int bytebuffer_offset = 0; +unsigned int bytebuffer_size = 0; + +static void fill_bytebuffer() +{ + if (bytebuffer_offset >= bytebuffer_size) { + /* Leave the first 4 bytes empty so we can always unwind the bitbuffer + * to the front of the bytebuffer, leave 4 bytes free at end of tail + * so we can easily top up buffer in check_trailer_gzip() */ + bytebuffer_size = 4 + xread(gunzip_src_fd, &bytebuffer[4], BYTEBUFFER_MAX - 8); + bytebuffer_offset = 4; + } +} + static unsigned int fill_bitbuffer(unsigned int bitbuffer, unsigned int *current, const unsigned int required) { while (*current < required) { - bitbuffer |= ((unsigned int) xread_char(gunzip_src_fd)) << *current; + fill_bytebuffer(); + bitbuffer |= ((unsigned int) bytebuffer[bytebuffer_offset]) << *current; + bytebuffer_offset++; *current += 8; } - return(bitbuffer); } @@ -857,7 +874,10 @@ static int inflate_get_next_window(void) int ret; if (needAnotherBlock) { - if(e) { calculate_gunzip_crc(); return 0; } // Last block + if(e) { + calculate_gunzip_crc(); + return 0; + } // Last block method = inflate_block(&e); needAnotherBlock = 0; } @@ -875,6 +895,7 @@ static int inflate_get_next_window(void) return 1; // More data left } else needAnotherBlock = 1; // End of that block } + /* Doesnt get here */ } /* @@ -923,7 +944,8 @@ extern void GZ_gzReadOpen(int fd, void *unused, int nUnused) gunzip_bytes_out = 0; gunzip_src_fd = fd; - gunzip_in_buffer = malloc(8); + /* Input buffer */ + bytebuffer = xmalloc(BYTEBUFFER_MAX); /* initialize gunzip_window, bit buffer */ gunzip_bk = 0; @@ -940,12 +962,11 @@ extern void GZ_gzReadClose(void) free(gunzip_crc_table); /* Store unused bytes in a global buffer so calling applets can access it */ - gunzip_in_buffer_count = 0; if (gunzip_bk >= 8) { /* Undo too much lookahead. The next read will be byte aligned * so we can discard unused bits in the last meaningful byte. */ - gunzip_in_buffer[gunzip_in_buffer_count] = gunzip_bb & 0xff; - gunzip_in_buffer_count++; + bytebuffer_offset--; + bytebuffer[bytebuffer_offset] = gunzip_bb & 0xff; gunzip_bb >>= 8; gunzip_bk -= 8; } diff --git a/archival/libunarchive/unzip.c b/archival/libunarchive/unzip.c index d8d5b77b1..770e4141d 100644 --- a/archival/libunarchive/unzip.c +++ b/archival/libunarchive/unzip.c @@ -88,8 +88,8 @@ static unsigned int gunzip_outbuf_count; /* bytes in output buffer */ /* This is used to sanify any unused bits from the bitbuffer * so they arent skipped when reading trailers (trailing headers) */ -unsigned char gunzip_in_buffer_count; -unsigned char *gunzip_in_buffer; +//unsigned char gunzip_in_buffer_count; +//unsigned char *gunzip_in_buffer; /* gunzip_window size--must be a power of two, and * at least 32K for zip's deflate method */ @@ -142,13 +142,30 @@ static const unsigned char border[] = { 16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15 }; +#define BYTEBUFFER_MAX 0x8000 +unsigned char *bytebuffer = NULL; +unsigned int bytebuffer_offset = 0; +unsigned int bytebuffer_size = 0; + +static void fill_bytebuffer() +{ + if (bytebuffer_offset >= bytebuffer_size) { + /* Leave the first 4 bytes empty so we can always unwind the bitbuffer + * to the front of the bytebuffer, leave 4 bytes free at end of tail + * so we can easily top up buffer in check_trailer_gzip() */ + bytebuffer_size = 4 + xread(gunzip_src_fd, &bytebuffer[4], BYTEBUFFER_MAX - 8); + bytebuffer_offset = 4; + } +} + static unsigned int fill_bitbuffer(unsigned int bitbuffer, unsigned int *current, const unsigned int required) { while (*current < required) { - bitbuffer |= ((unsigned int) xread_char(gunzip_src_fd)) << *current; + fill_bytebuffer(); + bitbuffer |= ((unsigned int) bytebuffer[bytebuffer_offset]) << *current; + bytebuffer_offset++; *current += 8; } - return(bitbuffer); } @@ -857,7 +874,10 @@ static int inflate_get_next_window(void) int ret; if (needAnotherBlock) { - if(e) { calculate_gunzip_crc(); return 0; } // Last block + if(e) { + calculate_gunzip_crc(); + return 0; + } // Last block method = inflate_block(&e); needAnotherBlock = 0; } @@ -875,6 +895,7 @@ static int inflate_get_next_window(void) return 1; // More data left } else needAnotherBlock = 1; // End of that block } + /* Doesnt get here */ } /* @@ -923,7 +944,8 @@ extern void GZ_gzReadOpen(int fd, void *unused, int nUnused) gunzip_bytes_out = 0; gunzip_src_fd = fd; - gunzip_in_buffer = malloc(8); + /* Input buffer */ + bytebuffer = xmalloc(BYTEBUFFER_MAX); /* initialize gunzip_window, bit buffer */ gunzip_bk = 0; @@ -940,12 +962,11 @@ extern void GZ_gzReadClose(void) free(gunzip_crc_table); /* Store unused bytes in a global buffer so calling applets can access it */ - gunzip_in_buffer_count = 0; if (gunzip_bk >= 8) { /* Undo too much lookahead. The next read will be byte aligned * so we can discard unused bits in the last meaningful byte. */ - gunzip_in_buffer[gunzip_in_buffer_count] = gunzip_bb & 0xff; - gunzip_in_buffer_count++; + bytebuffer_offset--; + bytebuffer[bytebuffer_offset] = gunzip_bb & 0xff; gunzip_bb >>= 8; gunzip_bk -= 8; } -- 2.11.0