Dependencies:   emwin_lib

Fork of DMemWin by Embedded Artists

Committer:
destinyXfate
Date:
Thu Jun 02 04:52:54 2016 +0000
Revision:
2:0e2ef1edf01b
;

Who changed what in which revision?

UserRevisionLine numberNew contents of line
destinyXfate 2:0e2ef1edf01b 1 /* crc32.c -- compute the CRC-32 of a data stream
destinyXfate 2:0e2ef1edf01b 2 * Copyright (C) 1995-2005 Mark Adler
destinyXfate 2:0e2ef1edf01b 3 * For conditions of distribution and use, see copyright notice in zlib.h
destinyXfate 2:0e2ef1edf01b 4 *
destinyXfate 2:0e2ef1edf01b 5 * Thanks to Rodney Brown <rbrown64@csc.com.au> for his contribution of faster
destinyXfate 2:0e2ef1edf01b 6 * CRC methods: exclusive-oring 32 bits of data at a time, and pre-computing
destinyXfate 2:0e2ef1edf01b 7 * tables for updating the shift register in one step with three exclusive-ors
destinyXfate 2:0e2ef1edf01b 8 * instead of four steps with four exclusive-ors. This results in about a
destinyXfate 2:0e2ef1edf01b 9 * factor of two increase in speed on a Power PC G4 (PPC7455) using gcc -O3.
destinyXfate 2:0e2ef1edf01b 10 */
destinyXfate 2:0e2ef1edf01b 11
destinyXfate 2:0e2ef1edf01b 12 /* @(#) $Id$ */
destinyXfate 2:0e2ef1edf01b 13
destinyXfate 2:0e2ef1edf01b 14 /*
destinyXfate 2:0e2ef1edf01b 15 Note on the use of DYNAMIC_CRC_TABLE: there is no mutex or semaphore
destinyXfate 2:0e2ef1edf01b 16 protection on the static variables used to control the first-use generation
destinyXfate 2:0e2ef1edf01b 17 of the crc tables. Therefore, if you #define DYNAMIC_CRC_TABLE, you should
destinyXfate 2:0e2ef1edf01b 18 first call get_crc_table() to initialize the tables before allowing more than
destinyXfate 2:0e2ef1edf01b 19 one thread to use crc32().
destinyXfate 2:0e2ef1edf01b 20 */
destinyXfate 2:0e2ef1edf01b 21
destinyXfate 2:0e2ef1edf01b 22 #ifdef MAKECRCH
destinyXfate 2:0e2ef1edf01b 23 # include <stdio.h>
destinyXfate 2:0e2ef1edf01b 24 # ifndef DYNAMIC_CRC_TABLE
destinyXfate 2:0e2ef1edf01b 25 # define DYNAMIC_CRC_TABLE
destinyXfate 2:0e2ef1edf01b 26 # endif /* !DYNAMIC_CRC_TABLE */
destinyXfate 2:0e2ef1edf01b 27 #endif /* MAKECRCH */
destinyXfate 2:0e2ef1edf01b 28
destinyXfate 2:0e2ef1edf01b 29 #include "zutil.h" /* for STDC and FAR definitions */
destinyXfate 2:0e2ef1edf01b 30
destinyXfate 2:0e2ef1edf01b 31 #define local static
destinyXfate 2:0e2ef1edf01b 32
destinyXfate 2:0e2ef1edf01b 33 /* Find a four-byte integer type for crc32_little() and crc32_big(). */
destinyXfate 2:0e2ef1edf01b 34 #ifndef NOBYFOUR
destinyXfate 2:0e2ef1edf01b 35 # ifdef STDC /* need ANSI C limits.h to determine sizes */
destinyXfate 2:0e2ef1edf01b 36 # include <limits.h>
destinyXfate 2:0e2ef1edf01b 37 # define BYFOUR
destinyXfate 2:0e2ef1edf01b 38 # if (UINT_MAX == 0xffffffffUL)
destinyXfate 2:0e2ef1edf01b 39 typedef unsigned int u4;
destinyXfate 2:0e2ef1edf01b 40 # else
destinyXfate 2:0e2ef1edf01b 41 # if (ULONG_MAX == 0xffffffffUL)
destinyXfate 2:0e2ef1edf01b 42 typedef unsigned long u4;
destinyXfate 2:0e2ef1edf01b 43 # else
destinyXfate 2:0e2ef1edf01b 44 # if (USHRT_MAX == 0xffffffffUL)
destinyXfate 2:0e2ef1edf01b 45 typedef unsigned short u4;
destinyXfate 2:0e2ef1edf01b 46 # else
destinyXfate 2:0e2ef1edf01b 47 # undef BYFOUR /* can't find a four-byte integer type! */
destinyXfate 2:0e2ef1edf01b 48 # endif
destinyXfate 2:0e2ef1edf01b 49 # endif
destinyXfate 2:0e2ef1edf01b 50 # endif
destinyXfate 2:0e2ef1edf01b 51 # endif /* STDC */
destinyXfate 2:0e2ef1edf01b 52 #endif /* !NOBYFOUR */
destinyXfate 2:0e2ef1edf01b 53
destinyXfate 2:0e2ef1edf01b 54 /* Definitions for doing the crc four data bytes at a time. */
destinyXfate 2:0e2ef1edf01b 55 #ifdef BYFOUR
destinyXfate 2:0e2ef1edf01b 56 # define REV(w) (((w)>>24)+(((w)>>8)&0xff00)+ \
destinyXfate 2:0e2ef1edf01b 57 (((w)&0xff00)<<8)+(((w)&0xff)<<24))
destinyXfate 2:0e2ef1edf01b 58 local unsigned long crc32_little OF((unsigned long,
destinyXfate 2:0e2ef1edf01b 59 const unsigned char FAR *, unsigned));
destinyXfate 2:0e2ef1edf01b 60 local unsigned long crc32_big OF((unsigned long,
destinyXfate 2:0e2ef1edf01b 61 const unsigned char FAR *, unsigned));
destinyXfate 2:0e2ef1edf01b 62 # define TBLS 8
destinyXfate 2:0e2ef1edf01b 63 #else
destinyXfate 2:0e2ef1edf01b 64 # define TBLS 1
destinyXfate 2:0e2ef1edf01b 65 #endif /* BYFOUR */
destinyXfate 2:0e2ef1edf01b 66
destinyXfate 2:0e2ef1edf01b 67 /* Local functions for crc concatenation */
destinyXfate 2:0e2ef1edf01b 68 local unsigned long gf2_matrix_times OF((unsigned long *mat,
destinyXfate 2:0e2ef1edf01b 69 unsigned long vec));
destinyXfate 2:0e2ef1edf01b 70 local void gf2_matrix_square OF((unsigned long *square, unsigned long *mat));
destinyXfate 2:0e2ef1edf01b 71
destinyXfate 2:0e2ef1edf01b 72 #ifdef DYNAMIC_CRC_TABLE
destinyXfate 2:0e2ef1edf01b 73
destinyXfate 2:0e2ef1edf01b 74 local volatile int crc_table_empty = 1;
destinyXfate 2:0e2ef1edf01b 75 local unsigned long FAR crc_table[TBLS][256];
destinyXfate 2:0e2ef1edf01b 76 local void make_crc_table OF((void));
destinyXfate 2:0e2ef1edf01b 77 #ifdef MAKECRCH
destinyXfate 2:0e2ef1edf01b 78 local void write_table OF((FILE *, const unsigned long FAR *));
destinyXfate 2:0e2ef1edf01b 79 #endif /* MAKECRCH */
destinyXfate 2:0e2ef1edf01b 80 /*
destinyXfate 2:0e2ef1edf01b 81 Generate tables for a byte-wise 32-bit CRC calculation on the polynomial:
destinyXfate 2:0e2ef1edf01b 82 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.
destinyXfate 2:0e2ef1edf01b 83
destinyXfate 2:0e2ef1edf01b 84 Polynomials over GF(2) are represented in binary, one bit per coefficient,
destinyXfate 2:0e2ef1edf01b 85 with the lowest powers in the most significant bit. Then adding polynomials
destinyXfate 2:0e2ef1edf01b 86 is just exclusive-or, and multiplying a polynomial by x is a right shift by
destinyXfate 2:0e2ef1edf01b 87 one. If we call the above polynomial p, and represent a byte as the
destinyXfate 2:0e2ef1edf01b 88 polynomial q, also with the lowest power in the most significant bit (so the
destinyXfate 2:0e2ef1edf01b 89 byte 0xb1 is the polynomial x^7+x^3+x+1), then the CRC is (q*x^32) mod p,
destinyXfate 2:0e2ef1edf01b 90 where a mod b means the remainder after dividing a by b.
destinyXfate 2:0e2ef1edf01b 91
destinyXfate 2:0e2ef1edf01b 92 This calculation is done using the shift-register method of multiplying and
destinyXfate 2:0e2ef1edf01b 93 taking the remainder. The register is initialized to zero, and for each
destinyXfate 2:0e2ef1edf01b 94 incoming bit, x^32 is added mod p to the register if the bit is a one (where
destinyXfate 2:0e2ef1edf01b 95 x^32 mod p is p+x^32 = x^26+...+1), and the register is multiplied mod p by
destinyXfate 2:0e2ef1edf01b 96 x (which is shifting right by one and adding x^32 mod p if the bit shifted
destinyXfate 2:0e2ef1edf01b 97 out is a one). We start with the highest power (least significant bit) of
destinyXfate 2:0e2ef1edf01b 98 q and repeat for all eight bits of q.
destinyXfate 2:0e2ef1edf01b 99
destinyXfate 2:0e2ef1edf01b 100 The first table is simply the CRC of all possible eight bit values. This is
destinyXfate 2:0e2ef1edf01b 101 all the information needed to generate CRCs on data a byte at a time for all
destinyXfate 2:0e2ef1edf01b 102 combinations of CRC register values and incoming bytes. The remaining tables
destinyXfate 2:0e2ef1edf01b 103 allow for word-at-a-time CRC calculation for both big-endian and little-
destinyXfate 2:0e2ef1edf01b 104 endian machines, where a word is four bytes.
destinyXfate 2:0e2ef1edf01b 105 */
destinyXfate 2:0e2ef1edf01b 106 local void make_crc_table()
destinyXfate 2:0e2ef1edf01b 107 {
destinyXfate 2:0e2ef1edf01b 108 unsigned long c;
destinyXfate 2:0e2ef1edf01b 109 int n, k;
destinyXfate 2:0e2ef1edf01b 110 unsigned long poly; /* polynomial exclusive-or pattern */
destinyXfate 2:0e2ef1edf01b 111 /* terms of polynomial defining this crc (except x^32): */
destinyXfate 2:0e2ef1edf01b 112 static volatile int first = 1; /* flag to limit concurrent making */
destinyXfate 2:0e2ef1edf01b 113 static const unsigned char p[] = {0,1,2,4,5,7,8,10,11,12,16,22,23,26};
destinyXfate 2:0e2ef1edf01b 114
destinyXfate 2:0e2ef1edf01b 115 /* See if another task is already doing this (not thread-safe, but better
destinyXfate 2:0e2ef1edf01b 116 than nothing -- significantly reduces duration of vulnerability in
destinyXfate 2:0e2ef1edf01b 117 case the advice about DYNAMIC_CRC_TABLE is ignored) */
destinyXfate 2:0e2ef1edf01b 118 if (first) {
destinyXfate 2:0e2ef1edf01b 119 first = 0;
destinyXfate 2:0e2ef1edf01b 120
destinyXfate 2:0e2ef1edf01b 121 /* make exclusive-or pattern from polynomial (0xedb88320UL) */
destinyXfate 2:0e2ef1edf01b 122 poly = 0UL;
destinyXfate 2:0e2ef1edf01b 123 for (n = 0; n < sizeof(p)/sizeof(unsigned char); n++)
destinyXfate 2:0e2ef1edf01b 124 poly |= 1UL << (31 - p[n]);
destinyXfate 2:0e2ef1edf01b 125
destinyXfate 2:0e2ef1edf01b 126 /* generate a crc for every 8-bit value */
destinyXfate 2:0e2ef1edf01b 127 for (n = 0; n < 256; n++) {
destinyXfate 2:0e2ef1edf01b 128 c = (unsigned long)n;
destinyXfate 2:0e2ef1edf01b 129 for (k = 0; k < 8; k++)
destinyXfate 2:0e2ef1edf01b 130 c = c & 1 ? poly ^ (c >> 1) : c >> 1;
destinyXfate 2:0e2ef1edf01b 131 crc_table[0][n] = c;
destinyXfate 2:0e2ef1edf01b 132 }
destinyXfate 2:0e2ef1edf01b 133
destinyXfate 2:0e2ef1edf01b 134 #ifdef BYFOUR
destinyXfate 2:0e2ef1edf01b 135 /* generate crc for each value followed by one, two, and three zeros,
destinyXfate 2:0e2ef1edf01b 136 and then the byte reversal of those as well as the first table */
destinyXfate 2:0e2ef1edf01b 137 for (n = 0; n < 256; n++) {
destinyXfate 2:0e2ef1edf01b 138 c = crc_table[0][n];
destinyXfate 2:0e2ef1edf01b 139 crc_table[4][n] = REV(c);
destinyXfate 2:0e2ef1edf01b 140 for (k = 1; k < 4; k++) {
destinyXfate 2:0e2ef1edf01b 141 c = crc_table[0][c & 0xff] ^ (c >> 8);
destinyXfate 2:0e2ef1edf01b 142 crc_table[k][n] = c;
destinyXfate 2:0e2ef1edf01b 143 crc_table[k + 4][n] = REV(c);
destinyXfate 2:0e2ef1edf01b 144 }
destinyXfate 2:0e2ef1edf01b 145 }
destinyXfate 2:0e2ef1edf01b 146 #endif /* BYFOUR */
destinyXfate 2:0e2ef1edf01b 147
destinyXfate 2:0e2ef1edf01b 148 crc_table_empty = 0;
destinyXfate 2:0e2ef1edf01b 149 }
destinyXfate 2:0e2ef1edf01b 150 else { /* not first */
destinyXfate 2:0e2ef1edf01b 151 /* wait for the other guy to finish (not efficient, but rare) */
destinyXfate 2:0e2ef1edf01b 152 while (crc_table_empty)
destinyXfate 2:0e2ef1edf01b 153 ;
destinyXfate 2:0e2ef1edf01b 154 }
destinyXfate 2:0e2ef1edf01b 155
destinyXfate 2:0e2ef1edf01b 156 #ifdef MAKECRCH
destinyXfate 2:0e2ef1edf01b 157 /* write out CRC tables to crc32.h */
destinyXfate 2:0e2ef1edf01b 158 {
destinyXfate 2:0e2ef1edf01b 159 FILE *out;
destinyXfate 2:0e2ef1edf01b 160
destinyXfate 2:0e2ef1edf01b 161 out = fopen("crc32.h", "w");
destinyXfate 2:0e2ef1edf01b 162 if (out == NULL) return;
destinyXfate 2:0e2ef1edf01b 163 fprintf(out, "/* crc32.h -- tables for rapid CRC calculation\n");
destinyXfate 2:0e2ef1edf01b 164 fprintf(out, " * Generated automatically by crc32.c\n */\n\n");
destinyXfate 2:0e2ef1edf01b 165 fprintf(out, "local const unsigned long FAR ");
destinyXfate 2:0e2ef1edf01b 166 fprintf(out, "crc_table[TBLS][256] =\n{\n {\n");
destinyXfate 2:0e2ef1edf01b 167 write_table(out, crc_table[0]);
destinyXfate 2:0e2ef1edf01b 168 # ifdef BYFOUR
destinyXfate 2:0e2ef1edf01b 169 fprintf(out, "#ifdef BYFOUR\n");
destinyXfate 2:0e2ef1edf01b 170 for (k = 1; k < 8; k++) {
destinyXfate 2:0e2ef1edf01b 171 fprintf(out, " },\n {\n");
destinyXfate 2:0e2ef1edf01b 172 write_table(out, crc_table[k]);
destinyXfate 2:0e2ef1edf01b 173 }
destinyXfate 2:0e2ef1edf01b 174 fprintf(out, "#endif\n");
destinyXfate 2:0e2ef1edf01b 175 # endif /* BYFOUR */
destinyXfate 2:0e2ef1edf01b 176 fprintf(out, " }\n};\n");
destinyXfate 2:0e2ef1edf01b 177 fclose(out);
destinyXfate 2:0e2ef1edf01b 178 }
destinyXfate 2:0e2ef1edf01b 179 #endif /* MAKECRCH */
destinyXfate 2:0e2ef1edf01b 180 }
destinyXfate 2:0e2ef1edf01b 181
destinyXfate 2:0e2ef1edf01b 182 #ifdef MAKECRCH
destinyXfate 2:0e2ef1edf01b 183 local void write_table(out, table)
destinyXfate 2:0e2ef1edf01b 184 FILE *out;
destinyXfate 2:0e2ef1edf01b 185 const unsigned long FAR *table;
destinyXfate 2:0e2ef1edf01b 186 {
destinyXfate 2:0e2ef1edf01b 187 int n;
destinyXfate 2:0e2ef1edf01b 188
destinyXfate 2:0e2ef1edf01b 189 for (n = 0; n < 256; n++)
destinyXfate 2:0e2ef1edf01b 190 fprintf(out, "%s0x%08lxUL%s", n % 5 ? "" : " ", table[n],
destinyXfate 2:0e2ef1edf01b 191 n == 255 ? "\n" : (n % 5 == 4 ? ",\n" : ", "));
destinyXfate 2:0e2ef1edf01b 192 }
destinyXfate 2:0e2ef1edf01b 193 #endif /* MAKECRCH */
destinyXfate 2:0e2ef1edf01b 194
destinyXfate 2:0e2ef1edf01b 195 #else /* !DYNAMIC_CRC_TABLE */
destinyXfate 2:0e2ef1edf01b 196 /* ========================================================================
destinyXfate 2:0e2ef1edf01b 197 * Tables of CRC-32s of all single-byte values, made by make_crc_table().
destinyXfate 2:0e2ef1edf01b 198 */
destinyXfate 2:0e2ef1edf01b 199 #include "crc32.h"
destinyXfate 2:0e2ef1edf01b 200 #endif /* DYNAMIC_CRC_TABLE */
destinyXfate 2:0e2ef1edf01b 201
destinyXfate 2:0e2ef1edf01b 202 /* =========================================================================
destinyXfate 2:0e2ef1edf01b 203 * This function can be used by asm versions of crc32()
destinyXfate 2:0e2ef1edf01b 204 */
destinyXfate 2:0e2ef1edf01b 205 const unsigned long FAR * ZEXPORT get_crc_table()
destinyXfate 2:0e2ef1edf01b 206 {
destinyXfate 2:0e2ef1edf01b 207 #ifdef DYNAMIC_CRC_TABLE
destinyXfate 2:0e2ef1edf01b 208 if (crc_table_empty)
destinyXfate 2:0e2ef1edf01b 209 make_crc_table();
destinyXfate 2:0e2ef1edf01b 210 #endif /* DYNAMIC_CRC_TABLE */
destinyXfate 2:0e2ef1edf01b 211 return (const unsigned long FAR *)crc_table;
destinyXfate 2:0e2ef1edf01b 212 }
destinyXfate 2:0e2ef1edf01b 213
destinyXfate 2:0e2ef1edf01b 214 /* ========================================================================= */
destinyXfate 2:0e2ef1edf01b 215 #define DO1 crc = crc_table[0][((int)crc ^ (*buf++)) & 0xff] ^ (crc >> 8)
destinyXfate 2:0e2ef1edf01b 216 #define DO8 DO1; DO1; DO1; DO1; DO1; DO1; DO1; DO1
destinyXfate 2:0e2ef1edf01b 217
destinyXfate 2:0e2ef1edf01b 218 /* ========================================================================= */
destinyXfate 2:0e2ef1edf01b 219 unsigned long ZEXPORT crc32(crc, buf, len)
destinyXfate 2:0e2ef1edf01b 220 unsigned long crc;
destinyXfate 2:0e2ef1edf01b 221 const unsigned char FAR *buf;
destinyXfate 2:0e2ef1edf01b 222 unsigned len;
destinyXfate 2:0e2ef1edf01b 223 {
destinyXfate 2:0e2ef1edf01b 224 if (buf == Z_NULL) return 0UL;
destinyXfate 2:0e2ef1edf01b 225
destinyXfate 2:0e2ef1edf01b 226 #ifdef DYNAMIC_CRC_TABLE
destinyXfate 2:0e2ef1edf01b 227 if (crc_table_empty)
destinyXfate 2:0e2ef1edf01b 228 make_crc_table();
destinyXfate 2:0e2ef1edf01b 229 #endif /* DYNAMIC_CRC_TABLE */
destinyXfate 2:0e2ef1edf01b 230
destinyXfate 2:0e2ef1edf01b 231 #ifdef BYFOUR
destinyXfate 2:0e2ef1edf01b 232 if (sizeof(void *) == sizeof(ptrdiff_t)) {
destinyXfate 2:0e2ef1edf01b 233 u4 endian;
destinyXfate 2:0e2ef1edf01b 234
destinyXfate 2:0e2ef1edf01b 235 endian = 1;
destinyXfate 2:0e2ef1edf01b 236 if (*((unsigned char *)(&endian)))
destinyXfate 2:0e2ef1edf01b 237 return crc32_little(crc, buf, len);
destinyXfate 2:0e2ef1edf01b 238 else
destinyXfate 2:0e2ef1edf01b 239 return crc32_big(crc, buf, len);
destinyXfate 2:0e2ef1edf01b 240 }
destinyXfate 2:0e2ef1edf01b 241 #endif /* BYFOUR */
destinyXfate 2:0e2ef1edf01b 242 crc = crc ^ 0xffffffffUL;
destinyXfate 2:0e2ef1edf01b 243 while (len >= 8) {
destinyXfate 2:0e2ef1edf01b 244 DO8;
destinyXfate 2:0e2ef1edf01b 245 len -= 8;
destinyXfate 2:0e2ef1edf01b 246 }
destinyXfate 2:0e2ef1edf01b 247 if (len) do {
destinyXfate 2:0e2ef1edf01b 248 DO1;
destinyXfate 2:0e2ef1edf01b 249 } while (--len);
destinyXfate 2:0e2ef1edf01b 250 return crc ^ 0xffffffffUL;
destinyXfate 2:0e2ef1edf01b 251 }
destinyXfate 2:0e2ef1edf01b 252
destinyXfate 2:0e2ef1edf01b 253 #ifdef BYFOUR
destinyXfate 2:0e2ef1edf01b 254
destinyXfate 2:0e2ef1edf01b 255 /* ========================================================================= */
destinyXfate 2:0e2ef1edf01b 256 #define DOLIT4 c ^= *buf4++; \
destinyXfate 2:0e2ef1edf01b 257 c = crc_table[3][c & 0xff] ^ crc_table[2][(c >> 8) & 0xff] ^ \
destinyXfate 2:0e2ef1edf01b 258 crc_table[1][(c >> 16) & 0xff] ^ crc_table[0][c >> 24]
destinyXfate 2:0e2ef1edf01b 259 #define DOLIT32 DOLIT4; DOLIT4; DOLIT4; DOLIT4; DOLIT4; DOLIT4; DOLIT4; DOLIT4
destinyXfate 2:0e2ef1edf01b 260
destinyXfate 2:0e2ef1edf01b 261 /* ========================================================================= */
destinyXfate 2:0e2ef1edf01b 262 local unsigned long crc32_little(crc, buf, len)
destinyXfate 2:0e2ef1edf01b 263 unsigned long crc;
destinyXfate 2:0e2ef1edf01b 264 const unsigned char FAR *buf;
destinyXfate 2:0e2ef1edf01b 265 unsigned len;
destinyXfate 2:0e2ef1edf01b 266 {
destinyXfate 2:0e2ef1edf01b 267 register u4 c;
destinyXfate 2:0e2ef1edf01b 268 register const u4 FAR *buf4;
destinyXfate 2:0e2ef1edf01b 269
destinyXfate 2:0e2ef1edf01b 270 c = (u4)crc;
destinyXfate 2:0e2ef1edf01b 271 c = ~c;
destinyXfate 2:0e2ef1edf01b 272 while (len && ((ptrdiff_t)buf & 3)) {
destinyXfate 2:0e2ef1edf01b 273 c = crc_table[0][(c ^ *buf++) & 0xff] ^ (c >> 8);
destinyXfate 2:0e2ef1edf01b 274 len--;
destinyXfate 2:0e2ef1edf01b 275 }
destinyXfate 2:0e2ef1edf01b 276
destinyXfate 2:0e2ef1edf01b 277 buf4 = (const u4 FAR *)(const void FAR *)buf;
destinyXfate 2:0e2ef1edf01b 278 while (len >= 32) {
destinyXfate 2:0e2ef1edf01b 279 DOLIT32;
destinyXfate 2:0e2ef1edf01b 280 len -= 32;
destinyXfate 2:0e2ef1edf01b 281 }
destinyXfate 2:0e2ef1edf01b 282 while (len >= 4) {
destinyXfate 2:0e2ef1edf01b 283 DOLIT4;
destinyXfate 2:0e2ef1edf01b 284 len -= 4;
destinyXfate 2:0e2ef1edf01b 285 }
destinyXfate 2:0e2ef1edf01b 286 buf = (const unsigned char FAR *)buf4;
destinyXfate 2:0e2ef1edf01b 287
destinyXfate 2:0e2ef1edf01b 288 if (len) do {
destinyXfate 2:0e2ef1edf01b 289 c = crc_table[0][(c ^ *buf++) & 0xff] ^ (c >> 8);
destinyXfate 2:0e2ef1edf01b 290 } while (--len);
destinyXfate 2:0e2ef1edf01b 291 c = ~c;
destinyXfate 2:0e2ef1edf01b 292 return (unsigned long)c;
destinyXfate 2:0e2ef1edf01b 293 }
destinyXfate 2:0e2ef1edf01b 294
destinyXfate 2:0e2ef1edf01b 295 /* ========================================================================= */
destinyXfate 2:0e2ef1edf01b 296 #define DOBIG4 c ^= *++buf4; \
destinyXfate 2:0e2ef1edf01b 297 c = crc_table[4][c & 0xff] ^ crc_table[5][(c >> 8) & 0xff] ^ \
destinyXfate 2:0e2ef1edf01b 298 crc_table[6][(c >> 16) & 0xff] ^ crc_table[7][c >> 24]
destinyXfate 2:0e2ef1edf01b 299 #define DOBIG32 DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4
destinyXfate 2:0e2ef1edf01b 300
destinyXfate 2:0e2ef1edf01b 301 /* ========================================================================= */
destinyXfate 2:0e2ef1edf01b 302 local unsigned long crc32_big(crc, buf, len)
destinyXfate 2:0e2ef1edf01b 303 unsigned long crc;
destinyXfate 2:0e2ef1edf01b 304 const unsigned char FAR *buf;
destinyXfate 2:0e2ef1edf01b 305 unsigned len;
destinyXfate 2:0e2ef1edf01b 306 {
destinyXfate 2:0e2ef1edf01b 307 register u4 c;
destinyXfate 2:0e2ef1edf01b 308 register const u4 FAR *buf4;
destinyXfate 2:0e2ef1edf01b 309
destinyXfate 2:0e2ef1edf01b 310 c = REV((u4)crc);
destinyXfate 2:0e2ef1edf01b 311 c = ~c;
destinyXfate 2:0e2ef1edf01b 312 while (len && ((ptrdiff_t)buf & 3)) {
destinyXfate 2:0e2ef1edf01b 313 c = crc_table[4][(c >> 24) ^ *buf++] ^ (c << 8);
destinyXfate 2:0e2ef1edf01b 314 len--;
destinyXfate 2:0e2ef1edf01b 315 }
destinyXfate 2:0e2ef1edf01b 316
destinyXfate 2:0e2ef1edf01b 317 buf4 = (const u4 FAR *)(const void FAR *)buf;
destinyXfate 2:0e2ef1edf01b 318 buf4--;
destinyXfate 2:0e2ef1edf01b 319 while (len >= 32) {
destinyXfate 2:0e2ef1edf01b 320 DOBIG32;
destinyXfate 2:0e2ef1edf01b 321 len -= 32;
destinyXfate 2:0e2ef1edf01b 322 }
destinyXfate 2:0e2ef1edf01b 323 while (len >= 4) {
destinyXfate 2:0e2ef1edf01b 324 DOBIG4;
destinyXfate 2:0e2ef1edf01b 325 len -= 4;
destinyXfate 2:0e2ef1edf01b 326 }
destinyXfate 2:0e2ef1edf01b 327 buf4++;
destinyXfate 2:0e2ef1edf01b 328 buf = (const unsigned char FAR *)buf4;
destinyXfate 2:0e2ef1edf01b 329
destinyXfate 2:0e2ef1edf01b 330 if (len) do {
destinyXfate 2:0e2ef1edf01b 331 c = crc_table[4][(c >> 24) ^ *buf++] ^ (c << 8);
destinyXfate 2:0e2ef1edf01b 332 } while (--len);
destinyXfate 2:0e2ef1edf01b 333 c = ~c;
destinyXfate 2:0e2ef1edf01b 334 return (unsigned long)(REV(c));
destinyXfate 2:0e2ef1edf01b 335 }
destinyXfate 2:0e2ef1edf01b 336
destinyXfate 2:0e2ef1edf01b 337 #endif /* BYFOUR */
destinyXfate 2:0e2ef1edf01b 338
destinyXfate 2:0e2ef1edf01b 339 #define GF2_DIM 32 /* dimension of GF(2) vectors (length of CRC) */
destinyXfate 2:0e2ef1edf01b 340
destinyXfate 2:0e2ef1edf01b 341 /* ========================================================================= */
destinyXfate 2:0e2ef1edf01b 342 local unsigned long gf2_matrix_times(mat, vec)
destinyXfate 2:0e2ef1edf01b 343 unsigned long *mat;
destinyXfate 2:0e2ef1edf01b 344 unsigned long vec;
destinyXfate 2:0e2ef1edf01b 345 {
destinyXfate 2:0e2ef1edf01b 346 unsigned long sum;
destinyXfate 2:0e2ef1edf01b 347
destinyXfate 2:0e2ef1edf01b 348 sum = 0;
destinyXfate 2:0e2ef1edf01b 349 while (vec) {
destinyXfate 2:0e2ef1edf01b 350 if (vec & 1)
destinyXfate 2:0e2ef1edf01b 351 sum ^= *mat;
destinyXfate 2:0e2ef1edf01b 352 vec >>= 1;
destinyXfate 2:0e2ef1edf01b 353 mat++;
destinyXfate 2:0e2ef1edf01b 354 }
destinyXfate 2:0e2ef1edf01b 355 return sum;
destinyXfate 2:0e2ef1edf01b 356 }
destinyXfate 2:0e2ef1edf01b 357
destinyXfate 2:0e2ef1edf01b 358 /* ========================================================================= */
destinyXfate 2:0e2ef1edf01b 359 local void gf2_matrix_square(square, mat)
destinyXfate 2:0e2ef1edf01b 360 unsigned long *square;
destinyXfate 2:0e2ef1edf01b 361 unsigned long *mat;
destinyXfate 2:0e2ef1edf01b 362 {
destinyXfate 2:0e2ef1edf01b 363 int n;
destinyXfate 2:0e2ef1edf01b 364
destinyXfate 2:0e2ef1edf01b 365 for (n = 0; n < GF2_DIM; n++)
destinyXfate 2:0e2ef1edf01b 366 square[n] = gf2_matrix_times(mat, mat[n]);
destinyXfate 2:0e2ef1edf01b 367 }
destinyXfate 2:0e2ef1edf01b 368
destinyXfate 2:0e2ef1edf01b 369 /* ========================================================================= */
destinyXfate 2:0e2ef1edf01b 370 uLong ZEXPORT crc32_combine(crc1, crc2, len2)
destinyXfate 2:0e2ef1edf01b 371 uLong crc1;
destinyXfate 2:0e2ef1edf01b 372 uLong crc2;
destinyXfate 2:0e2ef1edf01b 373 z_off_t len2;
destinyXfate 2:0e2ef1edf01b 374 {
destinyXfate 2:0e2ef1edf01b 375 int n;
destinyXfate 2:0e2ef1edf01b 376 unsigned long row;
destinyXfate 2:0e2ef1edf01b 377 unsigned long even[GF2_DIM]; /* even-power-of-two zeros operator */
destinyXfate 2:0e2ef1edf01b 378 unsigned long odd[GF2_DIM]; /* odd-power-of-two zeros operator */
destinyXfate 2:0e2ef1edf01b 379
destinyXfate 2:0e2ef1edf01b 380 /* degenerate case */
destinyXfate 2:0e2ef1edf01b 381 if (len2 == 0)
destinyXfate 2:0e2ef1edf01b 382 return crc1;
destinyXfate 2:0e2ef1edf01b 383
destinyXfate 2:0e2ef1edf01b 384 /* put operator for one zero bit in odd */
destinyXfate 2:0e2ef1edf01b 385 odd[0] = 0xedb88320L; /* CRC-32 polynomial */
destinyXfate 2:0e2ef1edf01b 386 row = 1;
destinyXfate 2:0e2ef1edf01b 387 for (n = 1; n < GF2_DIM; n++) {
destinyXfate 2:0e2ef1edf01b 388 odd[n] = row;
destinyXfate 2:0e2ef1edf01b 389 row <<= 1;
destinyXfate 2:0e2ef1edf01b 390 }
destinyXfate 2:0e2ef1edf01b 391
destinyXfate 2:0e2ef1edf01b 392 /* put operator for two zero bits in even */
destinyXfate 2:0e2ef1edf01b 393 gf2_matrix_square(even, odd);
destinyXfate 2:0e2ef1edf01b 394
destinyXfate 2:0e2ef1edf01b 395 /* put operator for four zero bits in odd */
destinyXfate 2:0e2ef1edf01b 396 gf2_matrix_square(odd, even);
destinyXfate 2:0e2ef1edf01b 397
destinyXfate 2:0e2ef1edf01b 398 /* apply len2 zeros to crc1 (first square will put the operator for one
destinyXfate 2:0e2ef1edf01b 399 zero byte, eight zero bits, in even) */
destinyXfate 2:0e2ef1edf01b 400 do {
destinyXfate 2:0e2ef1edf01b 401 /* apply zeros operator for this bit of len2 */
destinyXfate 2:0e2ef1edf01b 402 gf2_matrix_square(even, odd);
destinyXfate 2:0e2ef1edf01b 403 if (len2 & 1)
destinyXfate 2:0e2ef1edf01b 404 crc1 = gf2_matrix_times(even, crc1);
destinyXfate 2:0e2ef1edf01b 405 len2 >>= 1;
destinyXfate 2:0e2ef1edf01b 406
destinyXfate 2:0e2ef1edf01b 407 /* if no more bits set, then done */
destinyXfate 2:0e2ef1edf01b 408 if (len2 == 0)
destinyXfate 2:0e2ef1edf01b 409 break;
destinyXfate 2:0e2ef1edf01b 410
destinyXfate 2:0e2ef1edf01b 411 /* another iteration of the loop with odd and even swapped */
destinyXfate 2:0e2ef1edf01b 412 gf2_matrix_square(odd, even);
destinyXfate 2:0e2ef1edf01b 413 if (len2 & 1)
destinyXfate 2:0e2ef1edf01b 414 crc1 = gf2_matrix_times(odd, crc1);
destinyXfate 2:0e2ef1edf01b 415 len2 >>= 1;
destinyXfate 2:0e2ef1edf01b 416
destinyXfate 2:0e2ef1edf01b 417 /* if no more bits set, then done */
destinyXfate 2:0e2ef1edf01b 418 } while (len2 != 0);
destinyXfate 2:0e2ef1edf01b 419
destinyXfate 2:0e2ef1edf01b 420 /* return combined crc */
destinyXfate 2:0e2ef1edf01b 421 crc1 ^= crc2;
destinyXfate 2:0e2ef1edf01b 422 return crc1;
destinyXfate 2:0e2ef1edf01b 423 }
destinyXfate 2:0e2ef1edf01b 424