Patch from Rob Sullivan to consolidate crc32 table generation.
authorRob Landley <rob@landley.net>
Mon, 10 Apr 2006 17:07:15 +0000 (17:07 -0000)
committerRob Landley <rob@landley.net>
Mon, 10 Apr 2006 17:07:15 +0000 (17:07 -0000)
archival/gzip.c
archival/libunarchive/decompress_bunzip2.c
archival/libunarchive/decompress_unzip.c
include/libbb.h
libbb/Makefile.in
libbb/crc32.c [new file with mode: 0644]

index fa6e85b666761bbbb18345a684390107e2486e07..41ed3a2c7c0fabbb6731a66966d969c51c88aaae 100644 (file)
@@ -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)
index 3d07d9e03bad84e9d99e5c05be28fb2fc0da962b..1879f7255799006f271396bafdbb69c4332479f7 100644 (file)
@@ -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 */
 
index 3215697aa70ed0aa6af4a667a9c681766c6793d2..a589bdcd445f5d273d1c6c4553000c79f44bc6c2 100644 (file)
@@ -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;
        }
index 64a235a9fe147b21540c9524242c3d39999e35eb..edbc582062ba0027bd74d480e2c5e68aa40e4b81 100644 (file)
@@ -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 <dmalloc.h>
index 338a5be974022354abad52fd2fbdd259bd12b0ff..2d9a1745de225f3b645a0250fabcf9ae169b1c21 100644 (file)
@@ -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 (file)
index 0000000..0360995
--- /dev/null
@@ -0,0 +1,40 @@
+/* vi: set sw=4 ts=4: */
+/*
+ * CRC32 table fill function
+ * Copyright (C) 2006 by Rob Sullivan <cogito.ergo.cogito@gmail.com>
+ * (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 <stdio.h>
+#include <stdlib.h>
+#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;
+}