summaryrefslogtreecommitdiff
path: root/crc32.c
diff options
context:
space:
mode:
authorMark Adler <madler@alumni.caltech.edu>2011-09-09 23:14:39 -0700
committerMark Adler <madler@alumni.caltech.edu>2011-09-09 23:14:39 -0700
commit423eb40306489f9c88f7dba32c2f69179166730b (patch)
treeb5a83b0b1e52bbe0de973dcbc7ec008c1d7cf7d9 /crc32.c
parent8a2acbffc86012de3523ecf91db2c4ea1b1c4ea2 (diff)
downloadzlib-423eb40306489f9c88f7dba32c2f69179166730b.tar.gz
zlib 1.0.1v1.0.1
Diffstat (limited to 'crc32.c')
-rw-r--r--crc32.c62
1 files changed, 52 insertions, 10 deletions
diff --git a/crc32.c b/crc32.c
index 4089255..58fc60e 100644
--- a/crc32.c
+++ b/crc32.c
@@ -1,32 +1,62 @@
/* 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
*/
-/* $Id: crc32.c,v 1.4 1995/04/14 14:55:12 jloup Exp $ */
+/* $Id: crc32.c,v 1.8 1996/01/30 21:59:10 me Exp $ */
#include "zlib.h"
#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;