From 56bcb184fac036a45cb8937238d51778d0a796aa Mon Sep 17 00:00:00 2001 From: Mark Adler Date: Fri, 9 Sep 2011 23:11:37 -0700 Subject: zlib 0.99 --- crc32.c | 60 +++++++++++++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 51 insertions(+), 9 deletions(-) (limited to 'crc32.c') diff --git a/crc32.c b/crc32.c index 4089255..7d6aa02 100644 --- a/crc32.c +++ b/crc32.c @@ -1,5 +1,5 @@ /* crc32.c -- compute the CRC-32 of a data stream - * Copyright (C) 1995 Mark Adler + * Copyright (C) 1995-1996 Mark Adler * For conditions of distribution and use, see copyright notice in zlib.h */ @@ -10,23 +10,53 @@ #define local static #ifdef DYNAMIC_CRC_TABLE -/* ========================================================================= - * Make the crc table. This function is needed only if you want to compute - * the table dynamically. - */ + local int crc_table_empty = 1; -local uLong crc_table[256]; +local uLongf crc_table[256]; +local void make_crc_table OF((void)); + +/* + Generate a table for a byte-wise 32-bit CRC calculation on the polynomial: + x^32+x^26+x^23+x^22+x^16+x^12+x^11+x^10+x^8+x^7+x^5+x^4+x^2+x+1. + Polynomials over GF(2) are represented in binary, one bit per coefficient, + with the lowest powers in the most significant bit. Then adding polynomials + is just exclusive-or, and multiplying a polynomial by x is a right shift by + one. If we call the above polynomial p, and represent a byte as the + polynomial q, also with the lowest power in the most significant bit (so the + byte 0xb1 is the polynomial x^7+x^3+x+1), then the CRC is (q*x^32) mod p, + where a mod b means the remainder after dividing a by b. + + This calculation is done using the shift-register method of multiplying and + taking the remainder. The register is initialized to zero, and for each + incoming bit, x^32 is added mod p to the register if the bit is a one (where + x^32 mod p is p+x^32 = x^26+...+1), and the register is multiplied mod p by + x (which is shifting right by one and adding x^32 mod p if the bit shifted + out is a one). We start with the highest power (least significant bit) of + q and repeat for all eight bits of q. + + The table is simply the CRC of all possible eight bit values. This is all + the information needed to generate CRC's on data a byte at a time for all + combinations of CRC register values and incoming bytes. +*/ local void make_crc_table() { uLong c; int n, k; + uLong poly; /* polynomial exclusive-or pattern */ + /* terms of polynomial defining this crc (except x^32): */ + static Byte p[] = {0,1,2,4,5,7,8,10,11,12,16,22,23,26}; + + /* make exclusive-or pattern from polynomial (0xedb88320L) */ + poly = 0L; + for (n = 0; n < sizeof(p)/sizeof(Byte); n++) + poly |= 1L << (31 - p[n]); for (n = 0; n < 256; n++) { c = (uLong)n; for (k = 0; k < 8; k++) - c = c & 1 ? 0xedb88320L ^ (c >> 1) : c >> 1; + c = c & 1 ? poly ^ (c >> 1) : c >> 1; crc_table[n] = c; } crc_table_empty = 0; @@ -35,7 +65,7 @@ local void make_crc_table() /* ======================================================================== * Table of CRC-32's of all single-byte values (made by make_crc_table) */ -local uLong crc_table[] = { +local uLongf crc_table[256] = { 0x00000000L, 0x77073096L, 0xee0e612cL, 0x990951baL, 0x076dc419L, 0x706af48fL, 0xe963a535L, 0x9e6495a3L, 0x0edb8832L, 0x79dcb8a4L, 0xe0d5e91eL, 0x97d2d988L, 0x09b64c2bL, 0x7eb17cbdL, 0xe7b82d07L, @@ -91,6 +121,18 @@ local uLong crc_table[] = { }; #endif +/* ========================================================================= + * This function can be used by asm versions of crc32() + */ +uLongf *get_crc_table() +{ +#ifdef DYNAMIC_CRC_TABLE + if (crc_table_empty) make_crc_table(); +#endif + return (uLongf *)crc_table; +} + +/* ========================================================================= */ #define DO1(buf) crc = crc_table[((int)crc ^ (*buf++)) & 0xff] ^ (crc >> 8); #define DO2(buf) DO1(buf); DO1(buf); #define DO4(buf) DO2(buf); DO2(buf); @@ -99,7 +141,7 @@ local uLong crc_table[] = { /* ========================================================================= */ uLong crc32(crc, buf, len) uLong crc; - Bytef *buf; + const Bytef *buf; uInt len; { if (buf == Z_NULL) return 0L; -- cgit v1.2.3-55-g6feb