diff options
author | Glenn L McGrath <bug1@ihug.co.nz> | 2002-11-24 06:01:20 +0000 |
---|---|---|
committer | Glenn L McGrath <bug1@ihug.co.nz> | 2002-11-24 06:01:20 +0000 |
commit | eda4f53f2ebf3d9565c3d7aa500a2e1d9cfd9774 (patch) | |
tree | 99673f3463db19e020a3c44c8cf24de526c43769 | |
parent | 7b1eca265a023dd09da5161588ddd50f3c0ec263 (diff) | |
download | busybox-w32-eda4f53f2ebf3d9565c3d7aa500a2e1d9cfd9774.tar.gz busybox-w32-eda4f53f2ebf3d9565c3d7aa500a2e1d9cfd9774.tar.bz2 busybox-w32-eda4f53f2ebf3d9565c3d7aa500a2e1d9cfd9774.zip |
Add an input buffer (currently 32kB) to speed things up heaps, it still requires 25% longer to decompress as compared to upstream.
-rw-r--r-- | archival/libunarchive/check_trailer_gzip.c | 27 | ||||
-rw-r--r-- | archival/libunarchive/decompress_unzip.c | 39 | ||||
-rw-r--r-- | 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 @@ | |||
32 | 32 | ||
33 | extern unsigned int gunzip_crc; | 33 | extern unsigned int gunzip_crc; |
34 | extern unsigned int gunzip_bytes_out; | 34 | extern unsigned int gunzip_bytes_out; |
35 | extern unsigned char *gunzip_in_buffer; | 35 | extern unsigned char *bytebuffer; |
36 | extern unsigned char gunzip_in_buffer_count; | 36 | extern unsigned short bytebuffer_offset; |
37 | extern unsigned short bytebuffer_size; | ||
38 | //extern unsigned char *gunzip_in_buffer; | ||
39 | //extern unsigned char gunzip_in_buffer_count; | ||
37 | 40 | ||
38 | extern void check_trailer_gzip(int src_fd) | 41 | extern void check_trailer_gzip(int src_fd) |
39 | { | 42 | { |
40 | |||
41 | unsigned int stored_crc = 0; | 43 | unsigned int stored_crc = 0; |
42 | unsigned char count; | 44 | unsigned char count; |
43 | 45 | ||
44 | /* top up the input buffer with the rest of the trailer */ | 46 | /* top up the input buffer with the rest of the trailer */ |
45 | xread_all(src_fd, &gunzip_in_buffer[gunzip_in_buffer_count], 8 - gunzip_in_buffer_count); | 47 | count = bytebuffer_size - bytebuffer_offset; |
48 | if (count < 8) { | ||
49 | xread_all(src_fd, &bytebuffer[bytebuffer_size], 8 - count); | ||
50 | bytebuffer_size += 8 - count; | ||
51 | } | ||
46 | for (count = 0; count != 4; count++) { | 52 | for (count = 0; count != 4; count++) { |
47 | stored_crc |= (gunzip_in_buffer[count] << (count * 8)); | 53 | stored_crc |= (bytebuffer[bytebuffer_offset] << (count * 8)); |
54 | bytebuffer_offset++; | ||
48 | } | 55 | } |
49 | 56 | ||
50 | /* Validate decompression - crc */ | 57 | /* Validate decompression - crc */ |
51 | if (stored_crc != (gunzip_crc ^ 0xffffffffL)) { | 58 | if (stored_crc != (gunzip_crc ^ 0xffffffffL)) { |
52 | error_msg_and_die("invalid compressed data--crc error"); | 59 | error_msg_and_die("crc error"); |
53 | } | 60 | } |
54 | 61 | ||
55 | /* Validate decompression - size */ | 62 | /* Validate decompression - size */ |
56 | if (gunzip_bytes_out != | 63 | if (gunzip_bytes_out != |
57 | (gunzip_in_buffer[4] | (gunzip_in_buffer[5] << 8) | | 64 | (bytebuffer[bytebuffer_offset] | (bytebuffer[bytebuffer_offset+1] << 8) | |
58 | (gunzip_in_buffer[6] << 16) | (gunzip_in_buffer[7] << 24))) { | 65 | (bytebuffer[bytebuffer_offset+2] << 16) | (bytebuffer[bytebuffer_offset+3] << 24))) { |
59 | error_msg_and_die("invalid compressed data--length error"); | 66 | error_msg_and_die("Incorrect length, but crc is correct"); |
60 | } | 67 | } |
61 | 68 | ||
62 | } | 69 | } |
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 */ | |||
88 | 88 | ||
89 | /* This is used to sanify any unused bits from the bitbuffer | 89 | /* This is used to sanify any unused bits from the bitbuffer |
90 | * so they arent skipped when reading trailers (trailing headers) */ | 90 | * so they arent skipped when reading trailers (trailing headers) */ |
91 | unsigned char gunzip_in_buffer_count; | 91 | //unsigned char gunzip_in_buffer_count; |
92 | unsigned char *gunzip_in_buffer; | 92 | //unsigned char *gunzip_in_buffer; |
93 | 93 | ||
94 | /* gunzip_window size--must be a power of two, and | 94 | /* gunzip_window size--must be a power of two, and |
95 | * at least 32K for zip's deflate method */ | 95 | * at least 32K for zip's deflate method */ |
@@ -142,13 +142,30 @@ static const unsigned char border[] = { | |||
142 | 16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15 | 142 | 16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15 |
143 | }; | 143 | }; |
144 | 144 | ||
145 | #define BYTEBUFFER_MAX 0x8000 | ||
146 | unsigned char *bytebuffer = NULL; | ||
147 | unsigned int bytebuffer_offset = 0; | ||
148 | unsigned int bytebuffer_size = 0; | ||
149 | |||
150 | static void fill_bytebuffer() | ||
151 | { | ||
152 | if (bytebuffer_offset >= bytebuffer_size) { | ||
153 | /* Leave the first 4 bytes empty so we can always unwind the bitbuffer | ||
154 | * to the front of the bytebuffer, leave 4 bytes free at end of tail | ||
155 | * so we can easily top up buffer in check_trailer_gzip() */ | ||
156 | bytebuffer_size = 4 + xread(gunzip_src_fd, &bytebuffer[4], BYTEBUFFER_MAX - 8); | ||
157 | bytebuffer_offset = 4; | ||
158 | } | ||
159 | } | ||
160 | |||
145 | static unsigned int fill_bitbuffer(unsigned int bitbuffer, unsigned int *current, const unsigned int required) | 161 | static unsigned int fill_bitbuffer(unsigned int bitbuffer, unsigned int *current, const unsigned int required) |
146 | { | 162 | { |
147 | while (*current < required) { | 163 | while (*current < required) { |
148 | bitbuffer |= ((unsigned int) xread_char(gunzip_src_fd)) << *current; | 164 | fill_bytebuffer(); |
165 | bitbuffer |= ((unsigned int) bytebuffer[bytebuffer_offset]) << *current; | ||
166 | bytebuffer_offset++; | ||
149 | *current += 8; | 167 | *current += 8; |
150 | } | 168 | } |
151 | |||
152 | return(bitbuffer); | 169 | return(bitbuffer); |
153 | } | 170 | } |
154 | 171 | ||
@@ -857,7 +874,10 @@ static int inflate_get_next_window(void) | |||
857 | int ret; | 874 | int ret; |
858 | 875 | ||
859 | if (needAnotherBlock) { | 876 | if (needAnotherBlock) { |
860 | if(e) { calculate_gunzip_crc(); return 0; } // Last block | 877 | if(e) { |
878 | calculate_gunzip_crc(); | ||
879 | return 0; | ||
880 | } // Last block | ||
861 | method = inflate_block(&e); | 881 | method = inflate_block(&e); |
862 | needAnotherBlock = 0; | 882 | needAnotherBlock = 0; |
863 | } | 883 | } |
@@ -875,6 +895,7 @@ static int inflate_get_next_window(void) | |||
875 | return 1; // More data left | 895 | return 1; // More data left |
876 | } else needAnotherBlock = 1; // End of that block | 896 | } else needAnotherBlock = 1; // End of that block |
877 | } | 897 | } |
898 | /* Doesnt get here */ | ||
878 | } | 899 | } |
879 | 900 | ||
880 | /* | 901 | /* |
@@ -923,7 +944,8 @@ extern void GZ_gzReadOpen(int fd, void *unused, int nUnused) | |||
923 | gunzip_bytes_out = 0; | 944 | gunzip_bytes_out = 0; |
924 | gunzip_src_fd = fd; | 945 | gunzip_src_fd = fd; |
925 | 946 | ||
926 | gunzip_in_buffer = malloc(8); | 947 | /* Input buffer */ |
948 | bytebuffer = xmalloc(BYTEBUFFER_MAX); | ||
927 | 949 | ||
928 | /* initialize gunzip_window, bit buffer */ | 950 | /* initialize gunzip_window, bit buffer */ |
929 | gunzip_bk = 0; | 951 | gunzip_bk = 0; |
@@ -940,12 +962,11 @@ extern void GZ_gzReadClose(void) | |||
940 | free(gunzip_crc_table); | 962 | free(gunzip_crc_table); |
941 | 963 | ||
942 | /* Store unused bytes in a global buffer so calling applets can access it */ | 964 | /* Store unused bytes in a global buffer so calling applets can access it */ |
943 | gunzip_in_buffer_count = 0; | ||
944 | if (gunzip_bk >= 8) { | 965 | if (gunzip_bk >= 8) { |
945 | /* Undo too much lookahead. The next read will be byte aligned | 966 | /* Undo too much lookahead. The next read will be byte aligned |
946 | * so we can discard unused bits in the last meaningful byte. */ | 967 | * so we can discard unused bits in the last meaningful byte. */ |
947 | gunzip_in_buffer[gunzip_in_buffer_count] = gunzip_bb & 0xff; | 968 | bytebuffer_offset--; |
948 | gunzip_in_buffer_count++; | 969 | bytebuffer[bytebuffer_offset] = gunzip_bb & 0xff; |
949 | gunzip_bb >>= 8; | 970 | gunzip_bb >>= 8; |
950 | gunzip_bk -= 8; | 971 | gunzip_bk -= 8; |
951 | } | 972 | } |
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 */ | |||
88 | 88 | ||
89 | /* This is used to sanify any unused bits from the bitbuffer | 89 | /* This is used to sanify any unused bits from the bitbuffer |
90 | * so they arent skipped when reading trailers (trailing headers) */ | 90 | * so they arent skipped when reading trailers (trailing headers) */ |
91 | unsigned char gunzip_in_buffer_count; | 91 | //unsigned char gunzip_in_buffer_count; |
92 | unsigned char *gunzip_in_buffer; | 92 | //unsigned char *gunzip_in_buffer; |
93 | 93 | ||
94 | /* gunzip_window size--must be a power of two, and | 94 | /* gunzip_window size--must be a power of two, and |
95 | * at least 32K for zip's deflate method */ | 95 | * at least 32K for zip's deflate method */ |
@@ -142,13 +142,30 @@ static const unsigned char border[] = { | |||
142 | 16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15 | 142 | 16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15 |
143 | }; | 143 | }; |
144 | 144 | ||
145 | #define BYTEBUFFER_MAX 0x8000 | ||
146 | unsigned char *bytebuffer = NULL; | ||
147 | unsigned int bytebuffer_offset = 0; | ||
148 | unsigned int bytebuffer_size = 0; | ||
149 | |||
150 | static void fill_bytebuffer() | ||
151 | { | ||
152 | if (bytebuffer_offset >= bytebuffer_size) { | ||
153 | /* Leave the first 4 bytes empty so we can always unwind the bitbuffer | ||
154 | * to the front of the bytebuffer, leave 4 bytes free at end of tail | ||
155 | * so we can easily top up buffer in check_trailer_gzip() */ | ||
156 | bytebuffer_size = 4 + xread(gunzip_src_fd, &bytebuffer[4], BYTEBUFFER_MAX - 8); | ||
157 | bytebuffer_offset = 4; | ||
158 | } | ||
159 | } | ||
160 | |||
145 | static unsigned int fill_bitbuffer(unsigned int bitbuffer, unsigned int *current, const unsigned int required) | 161 | static unsigned int fill_bitbuffer(unsigned int bitbuffer, unsigned int *current, const unsigned int required) |
146 | { | 162 | { |
147 | while (*current < required) { | 163 | while (*current < required) { |
148 | bitbuffer |= ((unsigned int) xread_char(gunzip_src_fd)) << *current; | 164 | fill_bytebuffer(); |
165 | bitbuffer |= ((unsigned int) bytebuffer[bytebuffer_offset]) << *current; | ||
166 | bytebuffer_offset++; | ||
149 | *current += 8; | 167 | *current += 8; |
150 | } | 168 | } |
151 | |||
152 | return(bitbuffer); | 169 | return(bitbuffer); |
153 | } | 170 | } |
154 | 171 | ||
@@ -857,7 +874,10 @@ static int inflate_get_next_window(void) | |||
857 | int ret; | 874 | int ret; |
858 | 875 | ||
859 | if (needAnotherBlock) { | 876 | if (needAnotherBlock) { |
860 | if(e) { calculate_gunzip_crc(); return 0; } // Last block | 877 | if(e) { |
878 | calculate_gunzip_crc(); | ||
879 | return 0; | ||
880 | } // Last block | ||
861 | method = inflate_block(&e); | 881 | method = inflate_block(&e); |
862 | needAnotherBlock = 0; | 882 | needAnotherBlock = 0; |
863 | } | 883 | } |
@@ -875,6 +895,7 @@ static int inflate_get_next_window(void) | |||
875 | return 1; // More data left | 895 | return 1; // More data left |
876 | } else needAnotherBlock = 1; // End of that block | 896 | } else needAnotherBlock = 1; // End of that block |
877 | } | 897 | } |
898 | /* Doesnt get here */ | ||
878 | } | 899 | } |
879 | 900 | ||
880 | /* | 901 | /* |
@@ -923,7 +944,8 @@ extern void GZ_gzReadOpen(int fd, void *unused, int nUnused) | |||
923 | gunzip_bytes_out = 0; | 944 | gunzip_bytes_out = 0; |
924 | gunzip_src_fd = fd; | 945 | gunzip_src_fd = fd; |
925 | 946 | ||
926 | gunzip_in_buffer = malloc(8); | 947 | /* Input buffer */ |
948 | bytebuffer = xmalloc(BYTEBUFFER_MAX); | ||
927 | 949 | ||
928 | /* initialize gunzip_window, bit buffer */ | 950 | /* initialize gunzip_window, bit buffer */ |
929 | gunzip_bk = 0; | 951 | gunzip_bk = 0; |
@@ -940,12 +962,11 @@ extern void GZ_gzReadClose(void) | |||
940 | free(gunzip_crc_table); | 962 | free(gunzip_crc_table); |
941 | 963 | ||
942 | /* Store unused bytes in a global buffer so calling applets can access it */ | 964 | /* Store unused bytes in a global buffer so calling applets can access it */ |
943 | gunzip_in_buffer_count = 0; | ||
944 | if (gunzip_bk >= 8) { | 965 | if (gunzip_bk >= 8) { |
945 | /* Undo too much lookahead. The next read will be byte aligned | 966 | /* Undo too much lookahead. The next read will be byte aligned |
946 | * so we can discard unused bits in the last meaningful byte. */ | 967 | * so we can discard unused bits in the last meaningful byte. */ |
947 | gunzip_in_buffer[gunzip_in_buffer_count] = gunzip_bb & 0xff; | 968 | bytebuffer_offset--; |
948 | gunzip_in_buffer_count++; | 969 | bytebuffer[bytebuffer_offset] = gunzip_bb & 0xff; |
949 | gunzip_bb >>= 8; | 970 | gunzip_bb >>= 8; |
950 | gunzip_bk -= 8; | 971 | gunzip_bk -= 8; |
951 | } | 972 | } |