Add an input buffer (currently 32kB) to speed things up heaps, it still requires 25% longer to decompress as compared to upstream.
No binary (build failed)
—
(log yok)
| @@ -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"); |
| } | |
| } | |
| @@ -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; | |
| } | |
| @@ -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; | |
| } | |