00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #ifdef MAKECRCH
00023 # include <stdio.h>
00024 # ifndef DYNAMIC_CRC_TABLE
00025 # define DYNAMIC_CRC_TABLE
00026 # endif
00027 #endif
00028
00029 #include "zutil.h"
00030
00031 #define local static
00032
00033
00034 #ifndef NOBYFOUR
00035 # ifdef STDC
00036 # include <limits.h>
00037 # define BYFOUR
00038 # if (UINT_MAX == 0xffffffffUL)
00039 typedef unsigned int u4;
00040 # else
00041 # if (ULONG_MAX == 0xffffffffUL)
00042 typedef unsigned long u4;
00043 # else
00044 # if (USHRT_MAX == 0xffffffffUL)
00045 typedef unsigned short u4;
00046 # else
00047 # undef BYFOUR
00048 # endif
00049 # endif
00050 # endif
00051 # endif
00052 #endif
00053
00054
00055 #ifdef BYFOUR
00056 # define REV(w) ((((w)>>24)&0xff)+(((w)>>8)&0xff00)+ \
00057 (((w)&0xff00)<<8)+(((w)&0xff)<<24))
00058 local unsigned long crc32_little OF((unsigned long,
00059 const unsigned char FAR *, unsigned));
00060 local unsigned long crc32_big OF((unsigned long,
00061 const unsigned char FAR *, unsigned));
00062 # define TBLS 8
00063 #else
00064 # define TBLS 1
00065 #endif
00066
00067
00068 local unsigned long gf2_matrix_times OF((unsigned long *mat,
00069 unsigned long vec));
00070 local void gf2_matrix_square OF((unsigned long *square, unsigned long *mat));
00071 local uLong crc32_combine_(uLong crc1, uLong crc2, z_off64_t len2);
00072
00073
00074 #ifdef DYNAMIC_CRC_TABLE
00075
00076 local volatile int crc_table_empty = 1;
00077 local unsigned long FAR crc_table[TBLS][256];
00078 local void make_crc_table OF((void));
00079 #ifdef MAKECRCH
00080 local void write_table OF((FILE *, const unsigned long FAR *));
00081 #endif
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108 local void make_crc_table()
00109 {
00110 unsigned long c;
00111 int n, k;
00112 unsigned long poly;
00113
00114 static volatile int first = 1;
00115 static const unsigned char p[] = {0,1,2,4,5,7,8,10,11,12,16,22,23,26};
00116
00117
00118
00119
00120 if (first) {
00121 first = 0;
00122
00123
00124 poly = 0UL;
00125 for (n = 0; n < sizeof(p)/sizeof(unsigned char); n++)
00126 poly |= 1UL << (31 - p[n]);
00127
00128
00129 for (n = 0; n < 256; n++) {
00130 c = (unsigned long)n;
00131 for (k = 0; k < 8; k++)
00132 c = c & 1 ? poly ^ (c >> 1) : c >> 1;
00133 crc_table[0][n] = c;
00134 }
00135
00136 #ifdef BYFOUR
00137
00138
00139 for (n = 0; n < 256; n++) {
00140 c = crc_table[0][n];
00141 crc_table[4][n] = REV(c);
00142 for (k = 1; k < 4; k++) {
00143 c = crc_table[0][c & 0xff] ^ (c >> 8);
00144 crc_table[k][n] = c;
00145 crc_table[k + 4][n] = REV(c);
00146 }
00147 }
00148 #endif
00149
00150 crc_table_empty = 0;
00151 }
00152 else {
00153
00154 while (crc_table_empty)
00155 ;
00156 }
00157
00158 #ifdef MAKECRCH
00159
00160 {
00161 FILE *out;
00162
00163 out = fopen("crc32.h", "w");
00164 if (out == NULL) return;
00165 fprintf(out, "/* crc32.h -- tables for rapid CRC calculation\n");
00166 fprintf(out, " * Generated automatically by crc32.c\n */\n\n");
00167 fprintf(out, "local const unsigned long FAR ");
00168 fprintf(out, "crc_table[TBLS][256] =\n{\n {\n");
00169 write_table(out, crc_table[0]);
00170 # ifdef BYFOUR
00171 fprintf(out, "#ifdef BYFOUR\n");
00172 for (k = 1; k < 8; k++) {
00173 fprintf(out, " },\n {\n");
00174 write_table(out, crc_table[k]);
00175 }
00176 fprintf(out, "#endif\n");
00177 # endif
00178 fprintf(out, " }\n};\n");
00179 fclose(out);
00180 }
00181 #endif
00182 }
00183
00184 #ifdef MAKECRCH
00185 local void write_table(out, table)
00186 FILE *out;
00187 const unsigned long FAR *table;
00188 {
00189 int n;
00190
00191 for (n = 0; n < 256; n++)
00192 fprintf(out, "%s0x%08lxUL%s", n % 5 ? "" : " ", table[n],
00193 n == 255 ? "\n" : (n % 5 == 4 ? ",\n" : ", "));
00194 }
00195 #endif
00196
00197 #else
00198
00199
00200
00201 #include "crc32.h"
00202 #endif
00203
00204
00205
00206
00207 const unsigned long FAR * ZEXPORT get_crc_table()
00208 {
00209 #ifdef DYNAMIC_CRC_TABLE
00210 if (crc_table_empty)
00211 make_crc_table();
00212 #endif
00213 return (const unsigned long FAR *)crc_table;
00214 }
00215
00216
00217 #define DO1 crc = crc_table[0][((int)crc ^ (*buf++)) & 0xff] ^ (crc >> 8)
00218 #define DO8 DO1; DO1; DO1; DO1; DO1; DO1; DO1; DO1
00219
00220
00221 unsigned long ZEXPORT crc32(crc, buf, len)
00222 unsigned long crc;
00223 const unsigned char FAR *buf;
00224 uInt len;
00225 {
00226 if (buf == Z_NULL) return 0UL;
00227
00228 #ifdef DYNAMIC_CRC_TABLE
00229 if (crc_table_empty)
00230 make_crc_table();
00231 #endif
00232
00233 #ifdef BYFOUR
00234 if (sizeof(void *) == sizeof(ptrdiff_t)) {
00235 u4 endian;
00236
00237 endian = 1;
00238 if (*((unsigned char *)(&endian)))
00239 return crc32_little(crc, buf, len);
00240 else
00241 return crc32_big(crc, buf, len);
00242 }
00243 #endif
00244 crc = crc ^ 0xffffffffUL;
00245 while (len >= 8) {
00246 DO8;
00247 len -= 8;
00248 }
00249 if (len) do {
00250 DO1;
00251 } while (--len);
00252 return crc ^ 0xffffffffUL;
00253 }
00254
00255 #ifdef BYFOUR
00256
00257
00258 #define DOLIT4 c ^= *buf4++; \
00259 c = crc_table[3][c & 0xff] ^ crc_table[2][(c >> 8) & 0xff] ^ \
00260 crc_table[1][(c >> 16) & 0xff] ^ crc_table[0][c >> 24]
00261 #define DOLIT32 DOLIT4; DOLIT4; DOLIT4; DOLIT4; DOLIT4; DOLIT4; DOLIT4; DOLIT4
00262
00263
00264 local unsigned long crc32_little(crc, buf, len)
00265 unsigned long crc;
00266 const unsigned char FAR *buf;
00267 unsigned len;
00268 {
00269 register u4 c;
00270 register const u4 FAR *buf4;
00271
00272 c = (u4)crc;
00273 c = ~c;
00274 while (len && ((ptrdiff_t)buf & 3)) {
00275 c = crc_table[0][(c ^ *buf++) & 0xff] ^ (c >> 8);
00276 len--;
00277 }
00278
00279 buf4 = (const u4 FAR *)(const void FAR *)buf;
00280 while (len >= 32) {
00281 DOLIT32;
00282 len -= 32;
00283 }
00284 while (len >= 4) {
00285 DOLIT4;
00286 len -= 4;
00287 }
00288 buf = (const unsigned char FAR *)buf4;
00289
00290 if (len) do {
00291 c = crc_table[0][(c ^ *buf++) & 0xff] ^ (c >> 8);
00292 } while (--len);
00293 c = ~c;
00294 return (unsigned long)c;
00295 }
00296
00297
00298 #define DOBIG4 c ^= *++buf4; \
00299 c = crc_table[4][c & 0xff] ^ crc_table[5][(c >> 8) & 0xff] ^ \
00300 crc_table[6][(c >> 16) & 0xff] ^ crc_table[7][c >> 24]
00301 #define DOBIG32 DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4
00302
00303
00304 local unsigned long crc32_big(crc, buf, len)
00305 unsigned long crc;
00306 const unsigned char FAR *buf;
00307 unsigned len;
00308 {
00309 register u4 c;
00310 register const u4 FAR *buf4;
00311
00312 c = REV((u4)crc);
00313 c = ~c;
00314 while (len && ((ptrdiff_t)buf & 3)) {
00315 c = crc_table[4][(c >> 24) ^ *buf++] ^ (c << 8);
00316 len--;
00317 }
00318
00319 buf4 = (const u4 FAR *)(const void FAR *)buf;
00320 buf4--;
00321 while (len >= 32) {
00322 DOBIG32;
00323 len -= 32;
00324 }
00325 while (len >= 4) {
00326 DOBIG4;
00327 len -= 4;
00328 }
00329 buf4++;
00330 buf = (const unsigned char FAR *)buf4;
00331
00332 if (len) do {
00333 c = crc_table[4][(c >> 24) ^ *buf++] ^ (c << 8);
00334 } while (--len);
00335 c = ~c;
00336 return (unsigned long)(REV(c));
00337 }
00338
00339 #endif
00340
00341 #define GF2_DIM 32
00342
00343
00344 local unsigned long gf2_matrix_times(mat, vec)
00345 unsigned long *mat;
00346 unsigned long vec;
00347 {
00348 unsigned long sum;
00349
00350 sum = 0;
00351 while (vec) {
00352 if (vec & 1)
00353 sum ^= *mat;
00354 vec >>= 1;
00355 mat++;
00356 }
00357 return sum;
00358 }
00359
00360
00361 local void gf2_matrix_square(square, mat)
00362 unsigned long *square;
00363 unsigned long *mat;
00364 {
00365 int n;
00366
00367 for (n = 0; n < GF2_DIM; n++)
00368 square[n] = gf2_matrix_times(mat, mat[n]);
00369 }
00370
00371
00372 local uLong crc32_combine_(crc1, crc2, len2)
00373 uLong crc1;
00374 uLong crc2;
00375 z_off64_t len2;
00376 {
00377 int n;
00378 unsigned long row;
00379 unsigned long even[GF2_DIM];
00380 unsigned long odd[GF2_DIM];
00381
00382
00383 if (len2 <= 0)
00384 return crc1;
00385
00386
00387 odd[0] = 0xedb88320UL;
00388 row = 1;
00389 for (n = 1; n < GF2_DIM; n++) {
00390 odd[n] = row;
00391 row <<= 1;
00392 }
00393
00394
00395 gf2_matrix_square(even, odd);
00396
00397
00398 gf2_matrix_square(odd, even);
00399
00400
00401
00402 do {
00403
00404 gf2_matrix_square(even, odd);
00405 if (len2 & 1)
00406 crc1 = gf2_matrix_times(even, crc1);
00407 len2 >>= 1;
00408
00409
00410 if (len2 == 0)
00411 break;
00412
00413
00414 gf2_matrix_square(odd, even);
00415 if (len2 & 1)
00416 crc1 = gf2_matrix_times(odd, crc1);
00417 len2 >>= 1;
00418
00419
00420 } while (len2 != 0);
00421
00422
00423 crc1 ^= crc2;
00424 return crc1;
00425 }
00426
00427
00428 uLong ZEXPORT crc32_combine(crc1, crc2, len2)
00429 uLong crc1;
00430 uLong crc2;
00431 z_off_t len2;
00432 {
00433 return crc32_combine_(crc1, crc2, len2);
00434 }
00435
00436 uLong ZEXPORT crc32_combine64(crc1, crc2, len2)
00437 uLong crc1;
00438 uLong crc2;
00439 z_off64_t len2;
00440 {
00441 return crc32_combine_(crc1, crc2, len2);
00442 }