diff options
author | Rob Landley <rob@landley.net> | 2006-04-10 17:07:15 +0000 |
---|---|---|
committer | Rob Landley <rob@landley.net> | 2006-04-10 17:07:15 +0000 |
commit | c57ec37959390ff2e43faa5e4dd5281b2923ced3 (patch) | |
tree | 8325e7bd6a9a270e931b383d33b5901751dd2a5e | |
parent | 998f4493756423877217239d2cc42eb8b83d50b3 (diff) | |
download | busybox-w32-c57ec37959390ff2e43faa5e4dd5281b2923ced3.tar.gz busybox-w32-c57ec37959390ff2e43faa5e4dd5281b2923ced3.tar.bz2 busybox-w32-c57ec37959390ff2e43faa5e4dd5281b2923ced3.zip |
Patch from Rob Sullivan to consolidate crc32 table generation.
-rw-r--r-- | archival/gzip.c | 35 | ||||
-rw-r--r-- | archival/libunarchive/decompress_bunzip2.c | 15 | ||||
-rw-r--r-- | archival/libunarchive/decompress_unzip.c | 42 | ||||
-rw-r--r-- | include/libbb.h | 2 | ||||
-rw-r--r-- | libbb/Makefile.in | 2 | ||||
-rw-r--r-- | libbb/crc32.c | 40 |
6 files changed, 65 insertions, 71 deletions
diff --git a/archival/gzip.c b/archival/gzip.c index fa6e85b66..41ed3a2c7 100644 --- a/archival/gzip.c +++ b/archival/gzip.c | |||
@@ -293,6 +293,7 @@ static int ofd; /* output file descriptor */ | |||
293 | static unsigned insize; /* valid bytes in inbuf */ | 293 | static unsigned insize; /* valid bytes in inbuf */ |
294 | static unsigned outcnt; /* bytes in output buffer */ | 294 | static unsigned outcnt; /* bytes in output buffer */ |
295 | 295 | ||
296 | static uint32_t *crc_32_tab; | ||
296 | 297 | ||
297 | /* Output a 16 bit value, lsb first */ | 298 | /* Output a 16 bit value, lsb first */ |
298 | static void put_short(ush w) | 299 | static void put_short(ush w) |
@@ -344,32 +345,13 @@ static void write_buf(int fd, void *buf, unsigned cnt) | |||
344 | * pointer, then initialize the crc shift register contents instead. | 345 | * pointer, then initialize the crc shift register contents instead. |
345 | * Return the current crc in either case. | 346 | * Return the current crc in either case. |
346 | */ | 347 | */ |
347 | static ulg updcrc(uch * s, unsigned n) | 348 | static uint32_t updcrc(uch * s, unsigned n) |
348 | { | 349 | { |
349 | static ulg crc = (ulg) 0xffffffffL; /* shift register contents */ | 350 | static uint32_t crc = ~0; /* shift register contents */ |
350 | register ulg c; /* temporary variable */ | 351 | uint32_t c; /* temporary variable */ |
351 | static unsigned long crc_32_tab[256]; | ||
352 | |||
353 | if (crc_32_tab[1] == 0x00000000L) { | ||
354 | unsigned long csr; /* crc shift register */ | ||
355 | const unsigned long e = 0xedb88320L; /* polynomial exclusive-or pattern */ | ||
356 | int i; /* counter for all possible eight bit values */ | ||
357 | int k; /* byte being shifted into crc apparatus */ | ||
358 | |||
359 | /* Compute table of CRC's. */ | ||
360 | for (i = 1; i < 256; i++) { | ||
361 | csr = i; | ||
362 | /* The idea to initialize the register with the byte instead of | ||
363 | * zero was stolen from Haruhiko Okumura's ar002 | ||
364 | */ | ||
365 | for (k = 8; k; k--) | ||
366 | csr = csr & 1 ? (csr >> 1) ^ e : csr >> 1; | ||
367 | crc_32_tab[i] = csr; | ||
368 | } | ||
369 | } | ||
370 | 352 | ||
371 | if (s == NULL) { | 353 | if (s == NULL) { |
372 | c = 0xffffffffL; | 354 | c = ~0; |
373 | } else { | 355 | } else { |
374 | c = crc; | 356 | c = crc; |
375 | if (n) | 357 | if (n) |
@@ -378,7 +360,7 @@ static ulg updcrc(uch * s, unsigned n) | |||
378 | } while (--n); | 360 | } while (--n); |
379 | } | 361 | } |
380 | crc = c; | 362 | crc = c; |
381 | return c ^ 0xffffffffL; /* (instead of ~c for 64-bit machines) */ | 363 | return ~c; |
382 | } | 364 | } |
383 | 365 | ||
384 | /* bits.c -- output variable-length bit strings | 366 | /* bits.c -- output variable-length bit strings |
@@ -1223,6 +1205,9 @@ int gzip_main(int argc, char **argv) | |||
1223 | ALLOC(uch, window, 2L * WSIZE); | 1205 | ALLOC(uch, window, 2L * WSIZE); |
1224 | ALLOC(ush, tab_prefix, 1L << BITS); | 1206 | ALLOC(ush, tab_prefix, 1L << BITS); |
1225 | 1207 | ||
1208 | /* Initialise the CRC32 table */ | ||
1209 | crc_32_tab = bb_crc32_filltable(0); | ||
1210 | |||
1226 | clear_bufs(); | 1211 | clear_bufs(); |
1227 | part_nb = 0; | 1212 | part_nb = 0; |
1228 | 1213 | ||
@@ -2416,7 +2401,7 @@ static void set_file_type(void) | |||
2416 | */ | 2401 | */ |
2417 | 2402 | ||
2418 | 2403 | ||
2419 | static ulg crc; /* crc on uncompressed file data */ | 2404 | static uint32_t crc; /* crc on uncompressed file data */ |
2420 | static long header_bytes; /* number of bytes in gzip header */ | 2405 | static long header_bytes; /* number of bytes in gzip header */ |
2421 | 2406 | ||
2422 | static void put_long(ulg n) | 2407 | static void put_long(ulg n) |
diff --git a/archival/libunarchive/decompress_bunzip2.c b/archival/libunarchive/decompress_bunzip2.c index 3d07d9e03..1879f7255 100644 --- a/archival/libunarchive/decompress_bunzip2.c +++ b/archival/libunarchive/decompress_bunzip2.c | |||
@@ -84,8 +84,8 @@ typedef struct { | |||
84 | 84 | ||
85 | /* The CRC values stored in the block header and calculated from the data */ | 85 | /* The CRC values stored in the block header and calculated from the data */ |
86 | 86 | ||
87 | unsigned int crc32Table[256],headerCRC, totalCRC, writeCRC; | 87 | uint32_t headerCRC, totalCRC, writeCRC; |
88 | 88 | uint32_t *crc32Table; | |
89 | /* Intermediate buffer and its size (in bytes) */ | 89 | /* Intermediate buffer and its size (in bytes) */ |
90 | 90 | ||
91 | unsigned int *dbuf, dbufSize; | 91 | unsigned int *dbuf, dbufSize; |
@@ -620,7 +620,7 @@ decode_next_byte: | |||
620 | bd->writeCount=previous; | 620 | bd->writeCount=previous; |
621 | return (previous!=RETVAL_LAST_BLOCK) ? previous : gotcount; | 621 | return (previous!=RETVAL_LAST_BLOCK) ? previous : gotcount; |
622 | } | 622 | } |
623 | bd->writeCRC=0xffffffffUL; | 623 | bd->writeCRC=~0; |
624 | pos=bd->writePos; | 624 | pos=bd->writePos; |
625 | current=bd->writeCurrent; | 625 | current=bd->writeCurrent; |
626 | goto decode_next_byte; | 626 | goto decode_next_byte; |
@@ -634,7 +634,7 @@ static int start_bunzip(bunzip_data **bdp, int in_fd, unsigned char *inbuf, | |||
634 | int len) | 634 | int len) |
635 | { | 635 | { |
636 | bunzip_data *bd; | 636 | bunzip_data *bd; |
637 | unsigned int i,j,c; | 637 | unsigned int i; |
638 | const unsigned int BZh0=(((unsigned int)'B')<<24)+(((unsigned int)'Z')<<16) | 638 | const unsigned int BZh0=(((unsigned int)'B')<<24)+(((unsigned int)'Z')<<16) |
639 | +(((unsigned int)'h')<<8)+(unsigned int)'0'; | 639 | +(((unsigned int)'h')<<8)+(unsigned int)'0'; |
640 | 640 | ||
@@ -657,12 +657,7 @@ static int start_bunzip(bunzip_data **bdp, int in_fd, unsigned char *inbuf, | |||
657 | 657 | ||
658 | /* Init the CRC32 table (big endian) */ | 658 | /* Init the CRC32 table (big endian) */ |
659 | 659 | ||
660 | for(i=0;i<256;i++) { | 660 | bd->crc32Table = bb_crc32_filltable(1); |
661 | c=i<<24; | ||
662 | for(j=8;j;j--) | ||
663 | c=c&0x80000000 ? (c<<1)^0x04c11db7 : (c<<1); | ||
664 | bd->crc32Table[i]=c; | ||
665 | } | ||
666 | 661 | ||
667 | /* Setup for I/O error handling via longjmp */ | 662 | /* Setup for I/O error handling via longjmp */ |
668 | 663 | ||
diff --git a/archival/libunarchive/decompress_unzip.c b/archival/libunarchive/decompress_unzip.c index 3215697aa..a589bdcd4 100644 --- a/archival/libunarchive/decompress_unzip.c +++ b/archival/libunarchive/decompress_unzip.c | |||
@@ -95,8 +95,8 @@ static unsigned int gunzip_outbuf_count; /* bytes in output buffer */ | |||
95 | enum { gunzip_wsize = 0x8000 }; | 95 | enum { gunzip_wsize = 0x8000 }; |
96 | static unsigned char *gunzip_window; | 96 | static unsigned char *gunzip_window; |
97 | 97 | ||
98 | static unsigned int *gunzip_crc_table; | 98 | static uint32_t *gunzip_crc_table; |
99 | unsigned int gunzip_crc; | 99 | uint32_t gunzip_crc; |
100 | 100 | ||
101 | /* If BMAX needs to be larger than 16, then h and x[] should be ulg. */ | 101 | /* If BMAX needs to be larger than 16, then h and x[] should be ulg. */ |
102 | #define BMAX 16 /* maximum bit length of any code (16 for explode) */ | 102 | #define BMAX 16 /* maximum bit length of any code (16 for explode) */ |
@@ -168,35 +168,6 @@ static unsigned int fill_bitbuffer(unsigned int bitbuffer, unsigned int *current | |||
168 | return(bitbuffer); | 168 | return(bitbuffer); |
169 | } | 169 | } |
170 | 170 | ||
171 | static void make_gunzip_crc_table(void) | ||
172 | { | ||
173 | const unsigned int poly = 0xedb88320; /* polynomial exclusive-or pattern */ | ||
174 | unsigned short i; /* counter for all possible eight bit values */ | ||
175 | |||
176 | /* initial shift register value */ | ||
177 | gunzip_crc = 0xffffffffL; | ||
178 | gunzip_crc_table = (unsigned int *) xmalloc(256 * sizeof(unsigned int)); | ||
179 | |||
180 | /* Compute and print table of CRC's, five per line */ | ||
181 | for (i = 0; i < 256; i++) { | ||
182 | unsigned int table_entry; /* crc shift register */ | ||
183 | unsigned char k; /* byte being shifted into crc apparatus */ | ||
184 | |||
185 | table_entry = i; | ||
186 | /* The idea to initialize the register with the byte instead of | ||
187 | * zero was stolen from Haruhiko Okumura's ar002 | ||
188 | */ | ||
189 | for (k = 8; k; k--) { | ||
190 | if (table_entry & 1) { | ||
191 | table_entry = (table_entry >> 1) ^ poly; | ||
192 | } else { | ||
193 | table_entry >>= 1; | ||
194 | } | ||
195 | } | ||
196 | gunzip_crc_table[i] = table_entry; | ||
197 | } | ||
198 | } | ||
199 | |||
200 | /* | 171 | /* |
201 | * Free the malloc'ed tables built by huft_build(), which makes a linked | 172 | * Free the malloc'ed tables built by huft_build(), which makes a linked |
202 | * list of the tables it made, with the links in a dummy first entry of | 173 | * list of the tables it made, with the links in a dummy first entry of |
@@ -922,8 +893,9 @@ int inflate_unzip(int in, int out) | |||
922 | gunzip_bb = 0; | 893 | gunzip_bb = 0; |
923 | 894 | ||
924 | /* Create the crc table */ | 895 | /* Create the crc table */ |
925 | make_gunzip_crc_table(); | 896 | gunzip_crc_table = bb_crc32_filltable(0); |
926 | 897 | gunzip_crc = ~0; | |
898 | |||
927 | /* Allocate space for buffer */ | 899 | /* Allocate space for buffer */ |
928 | bytebuffer = xmalloc(bytebuffer_max); | 900 | bytebuffer = xmalloc(bytebuffer_max); |
929 | 901 | ||
@@ -955,7 +927,7 @@ int inflate_unzip(int in, int out) | |||
955 | 927 | ||
956 | int inflate_gunzip(int in, int out) | 928 | int inflate_gunzip(int in, int out) |
957 | { | 929 | { |
958 | unsigned int stored_crc = 0; | 930 | uint32_t stored_crc = 0; |
959 | unsigned int count; | 931 | unsigned int count; |
960 | 932 | ||
961 | inflate_unzip(in, out); | 933 | inflate_unzip(in, out); |
@@ -972,7 +944,7 @@ int inflate_gunzip(int in, int out) | |||
972 | } | 944 | } |
973 | 945 | ||
974 | /* Validate decompression - crc */ | 946 | /* Validate decompression - crc */ |
975 | if (stored_crc != (gunzip_crc ^ 0xffffffffL)) { | 947 | if (stored_crc != (~gunzip_crc)) { |
976 | bb_error_msg("crc error"); | 948 | bb_error_msg("crc error"); |
977 | return -1; | 949 | return -1; |
978 | } | 950 | } |
diff --git a/include/libbb.h b/include/libbb.h index 64a235a9f..edbc58206 100644 --- a/include/libbb.h +++ b/include/libbb.h | |||
@@ -508,6 +508,8 @@ void md5_begin(md5_ctx_t *ctx); | |||
508 | void md5_hash(const void *data, size_t length, md5_ctx_t *ctx); | 508 | void md5_hash(const void *data, size_t length, md5_ctx_t *ctx); |
509 | void *md5_end(void *resbuf, md5_ctx_t *ctx); | 509 | void *md5_end(void *resbuf, md5_ctx_t *ctx); |
510 | 510 | ||
511 | extern uint32_t *bb_crc32_filltable (int endian); | ||
512 | |||
511 | /* busybox.h will include dmalloc later for us, else include it here. */ | 513 | /* busybox.h will include dmalloc later for us, else include it here. */ |
512 | #if !defined _BB_INTERNAL_H_ && defined DMALLOC | 514 | #if !defined _BB_INTERNAL_H_ && defined DMALLOC |
513 | #include <dmalloc.h> | 515 | #include <dmalloc.h> |
diff --git a/libbb/Makefile.in b/libbb/Makefile.in index 338a5be97..2d9a1745d 100644 --- a/libbb/Makefile.in +++ b/libbb/Makefile.in | |||
@@ -13,7 +13,7 @@ LIBBB-n:= | |||
13 | LIBBB-y:= \ | 13 | LIBBB-y:= \ |
14 | bb_asprintf.c ask_confirmation.c change_identity.c chomp.c \ | 14 | bb_asprintf.c ask_confirmation.c change_identity.c chomp.c \ |
15 | compare_string_array.c concat_path_file.c copy_file.c copyfd.c \ | 15 | compare_string_array.c concat_path_file.c copy_file.c copyfd.c \ |
16 | create_icmp_socket.c create_icmp6_socket.c \ | 16 | crc32.c create_icmp_socket.c create_icmp6_socket.c \ |
17 | device_open.c dump.c error_msg.c error_msg_and_die.c find_mount_point.c \ | 17 | device_open.c dump.c error_msg.c error_msg_and_die.c find_mount_point.c \ |
18 | find_pid_by_name.c find_root_device.c fgets_str.c full_read.c \ | 18 | find_pid_by_name.c find_root_device.c fgets_str.c full_read.c \ |
19 | full_write.c get_last_path_component.c get_line_from_file.c \ | 19 | full_write.c get_last_path_component.c get_line_from_file.c \ |
diff --git a/libbb/crc32.c b/libbb/crc32.c new file mode 100644 index 000000000..03609952d --- /dev/null +++ b/libbb/crc32.c | |||
@@ -0,0 +1,40 @@ | |||
1 | /* vi: set sw=4 ts=4: */ | ||
2 | /* | ||
3 | * CRC32 table fill function | ||
4 | * Copyright (C) 2006 by Rob Sullivan <cogito.ergo.cogito@gmail.com> | ||
5 | * (I can't really claim much credit however, as the algorithm is | ||
6 | * very well-known) | ||
7 | * | ||
8 | * The following function creates a CRC32 table depending on whether | ||
9 | * a big-endian (0x04c11db7) or little-endian (0xedb88320) CRC32 is | ||
10 | * required. Admittedly, there are other CRC32 polynomials floating | ||
11 | * around, but Busybox doesn't use them. | ||
12 | * | ||
13 | * endian = 1: big-endian | ||
14 | * endian = 0: little-endian | ||
15 | */ | ||
16 | |||
17 | #include <stdio.h> | ||
18 | #include <stdlib.h> | ||
19 | #include "libbb.h" | ||
20 | |||
21 | uint32_t *bb_crc32_filltable (int endian) { | ||
22 | |||
23 | uint32_t *crc_table = xmalloc(256 * sizeof(uint32_t)); | ||
24 | uint32_t polynomial = endian ? 0x04c11db7 : 0xedb88320; | ||
25 | uint32_t c; | ||
26 | int i, j; | ||
27 | |||
28 | for (i = 0; i < 256; i++) { | ||
29 | c = endian ? (i << 24) : i; | ||
30 | for (j = 8; j; j--) { | ||
31 | if (endian) | ||
32 | c = (c&0x80000000) ? ((c << 1) ^ polynomial) : (c << 1); | ||
33 | else | ||
34 | c = (c&1) ? ((c >> 1) ^ polynomial) : (c >> 1); | ||
35 | } | ||
36 | *crc_table++ = c; | ||
37 | } | ||
38 | |||
39 | return crc_table - 256; | ||
40 | } | ||