From c57ec37959390ff2e43faa5e4dd5281b2923ced3 Mon Sep 17 00:00:00 2001 From: Rob Landley Date: Mon, 10 Apr 2006 17:07:15 +0000 Subject: [PATCH] Patch from Rob Sullivan to consolidate crc32 table generation. --- archival/gzip.c | 35 ++++++------------ archival/libunarchive/decompress_bunzip2.c | 15 +++----- archival/libunarchive/decompress_unzip.c | 42 ++++------------------ include/libbb.h | 2 ++ libbb/Makefile.in | 2 +- libbb/crc32.c | 40 +++++++++++++++++++++ 6 files changed, 65 insertions(+), 71 deletions(-) create mode 100644 libbb/crc32.c 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 */ static unsigned insize; /* valid bytes in inbuf */ static unsigned outcnt; /* bytes in output buffer */ +static uint32_t *crc_32_tab; /* Output a 16 bit value, lsb first */ static void put_short(ush w) @@ -344,32 +345,13 @@ static void write_buf(int fd, void *buf, unsigned cnt) * pointer, then initialize the crc shift register contents instead. * Return the current crc in either case. */ -static ulg updcrc(uch * s, unsigned n) +static uint32_t updcrc(uch * s, unsigned n) { - static ulg crc = (ulg) 0xffffffffL; /* shift register contents */ - register ulg c; /* temporary variable */ - static unsigned long crc_32_tab[256]; - - if (crc_32_tab[1] == 0x00000000L) { - unsigned long csr; /* crc shift register */ - const unsigned long e = 0xedb88320L; /* polynomial exclusive-or pattern */ - int i; /* counter for all possible eight bit values */ - int k; /* byte being shifted into crc apparatus */ - - /* Compute table of CRC's. */ - for (i = 1; i < 256; i++) { - csr = i; - /* The idea to initialize the register with the byte instead of - * zero was stolen from Haruhiko Okumura's ar002 - */ - for (k = 8; k; k--) - csr = csr & 1 ? (csr >> 1) ^ e : csr >> 1; - crc_32_tab[i] = csr; - } - } + static uint32_t crc = ~0; /* shift register contents */ + uint32_t c; /* temporary variable */ if (s == NULL) { - c = 0xffffffffL; + c = ~0; } else { c = crc; if (n) @@ -378,7 +360,7 @@ static ulg updcrc(uch * s, unsigned n) } while (--n); } crc = c; - return c ^ 0xffffffffL; /* (instead of ~c for 64-bit machines) */ + return ~c; } /* bits.c -- output variable-length bit strings @@ -1223,6 +1205,9 @@ int gzip_main(int argc, char **argv) ALLOC(uch, window, 2L * WSIZE); ALLOC(ush, tab_prefix, 1L << BITS); + /* Initialise the CRC32 table */ + crc_32_tab = bb_crc32_filltable(0); + clear_bufs(); part_nb = 0; @@ -2416,7 +2401,7 @@ static void set_file_type(void) */ -static ulg crc; /* crc on uncompressed file data */ +static uint32_t crc; /* crc on uncompressed file data */ static long header_bytes; /* number of bytes in gzip header */ 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 { /* The CRC values stored in the block header and calculated from the data */ - unsigned int crc32Table[256],headerCRC, totalCRC, writeCRC; - + uint32_t headerCRC, totalCRC, writeCRC; + uint32_t *crc32Table; /* Intermediate buffer and its size (in bytes) */ unsigned int *dbuf, dbufSize; @@ -620,7 +620,7 @@ decode_next_byte: bd->writeCount=previous; return (previous!=RETVAL_LAST_BLOCK) ? previous : gotcount; } - bd->writeCRC=0xffffffffUL; + bd->writeCRC=~0; pos=bd->writePos; current=bd->writeCurrent; goto decode_next_byte; @@ -634,7 +634,7 @@ static int start_bunzip(bunzip_data **bdp, int in_fd, unsigned char *inbuf, int len) { bunzip_data *bd; - unsigned int i,j,c; + unsigned int i; const unsigned int BZh0=(((unsigned int)'B')<<24)+(((unsigned int)'Z')<<16) +(((unsigned int)'h')<<8)+(unsigned int)'0'; @@ -657,12 +657,7 @@ static int start_bunzip(bunzip_data **bdp, int in_fd, unsigned char *inbuf, /* Init the CRC32 table (big endian) */ - for(i=0;i<256;i++) { - c=i<<24; - for(j=8;j;j--) - c=c&0x80000000 ? (c<<1)^0x04c11db7 : (c<<1); - bd->crc32Table[i]=c; - } + bd->crc32Table = bb_crc32_filltable(1); /* Setup for I/O error handling via longjmp */ 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 */ enum { gunzip_wsize = 0x8000 }; static unsigned char *gunzip_window; -static unsigned int *gunzip_crc_table; -unsigned int gunzip_crc; +static uint32_t *gunzip_crc_table; +uint32_t gunzip_crc; /* If BMAX needs to be larger than 16, then h and x[] should be ulg. */ #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 return(bitbuffer); } -static void make_gunzip_crc_table(void) -{ - const unsigned int poly = 0xedb88320; /* polynomial exclusive-or pattern */ - unsigned short i; /* counter for all possible eight bit values */ - - /* initial shift register value */ - gunzip_crc = 0xffffffffL; - gunzip_crc_table = (unsigned int *) xmalloc(256 * sizeof(unsigned int)); - - /* Compute and print table of CRC's, five per line */ - for (i = 0; i < 256; i++) { - unsigned int table_entry; /* crc shift register */ - unsigned char k; /* byte being shifted into crc apparatus */ - - table_entry = i; - /* The idea to initialize the register with the byte instead of - * zero was stolen from Haruhiko Okumura's ar002 - */ - for (k = 8; k; k--) { - if (table_entry & 1) { - table_entry = (table_entry >> 1) ^ poly; - } else { - table_entry >>= 1; - } - } - gunzip_crc_table[i] = table_entry; - } -} - /* * Free the malloc'ed tables built by huft_build(), which makes a linked * 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) gunzip_bb = 0; /* Create the crc table */ - make_gunzip_crc_table(); - + gunzip_crc_table = bb_crc32_filltable(0); + gunzip_crc = ~0; + /* Allocate space for buffer */ bytebuffer = xmalloc(bytebuffer_max); @@ -955,7 +927,7 @@ int inflate_unzip(int in, int out) int inflate_gunzip(int in, int out) { - unsigned int stored_crc = 0; + uint32_t stored_crc = 0; unsigned int count; inflate_unzip(in, out); @@ -972,7 +944,7 @@ int inflate_gunzip(int in, int out) } /* Validate decompression - crc */ - if (stored_crc != (gunzip_crc ^ 0xffffffffL)) { + if (stored_crc != (~gunzip_crc)) { bb_error_msg("crc error"); return -1; } 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); void md5_hash(const void *data, size_t length, md5_ctx_t *ctx); void *md5_end(void *resbuf, md5_ctx_t *ctx); +extern uint32_t *bb_crc32_filltable (int endian); + /* busybox.h will include dmalloc later for us, else include it here. */ #if !defined _BB_INTERNAL_H_ && defined DMALLOC #include 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:= LIBBB-y:= \ bb_asprintf.c ask_confirmation.c change_identity.c chomp.c \ compare_string_array.c concat_path_file.c copy_file.c copyfd.c \ - create_icmp_socket.c create_icmp6_socket.c \ + crc32.c create_icmp_socket.c create_icmp6_socket.c \ device_open.c dump.c error_msg.c error_msg_and_die.c find_mount_point.c \ find_pid_by_name.c find_root_device.c fgets_str.c full_read.c \ 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 @@ +/* vi: set sw=4 ts=4: */ +/* + * CRC32 table fill function + * Copyright (C) 2006 by Rob Sullivan + * (I can't really claim much credit however, as the algorithm is + * very well-known) + * + * The following function creates a CRC32 table depending on whether + * a big-endian (0x04c11db7) or little-endian (0xedb88320) CRC32 is + * required. Admittedly, there are other CRC32 polynomials floating + * around, but Busybox doesn't use them. + * + * endian = 1: big-endian + * endian = 0: little-endian + */ + +#include +#include +#include "libbb.h" + +uint32_t *bb_crc32_filltable (int endian) { + + uint32_t *crc_table = xmalloc(256 * sizeof(uint32_t)); + uint32_t polynomial = endian ? 0x04c11db7 : 0xedb88320; + uint32_t c; + int i, j; + + for (i = 0; i < 256; i++) { + c = endian ? (i << 24) : i; + for (j = 8; j; j--) { + if (endian) + c = (c&0x80000000) ? ((c << 1) ^ polynomial) : (c << 1); + else + c = (c&1) ? ((c >> 1) ^ polynomial) : (c >> 1); + } + *crc_table++ = c; + } + + return crc_table - 256; +}