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)+(((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 #ifdef DYNAMIC_CRC_TABLE
00068
00069 local volatile int crc_table_empty = 1;
00070 local unsigned long FAR crc_table[TBLS][256];
00071 local void make_crc_table OF((void));
00072 #ifdef MAKECRCH
00073 local void write_table OF((FILE *, const unsigned long FAR *));
00074 #endif
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102 local void make_crc_table()
00103 {
00104 unsigned long c;
00105 int n, k;
00106 unsigned long poly;
00107
00108 static volatile int first = 1;
00109 static const unsigned char p[] = {0,1,2,4,5,7,8,10,11,12,16,22,23,26};
00110
00111
00112
00113
00114 if (first) {
00115 first = 0;
00116
00117
00118 poly = 0UL;
00119 for (n = 0; n < sizeof(p)/sizeof(unsigned char); n++)
00120 poly |= 1UL << (31 - p[n]);
00121
00122
00123 for (n = 0; n < 256; n++) {
00124 c = (unsigned long)n;
00125 for (k = 0; k < 8; k++)
00126 c = c & 1 ? poly ^ (c >> 1) : c >> 1;
00127 crc_table[0][n] = c;
00128 }
00129
00130 #ifdef BYFOUR
00131
00132
00133 for (n = 0; n < 256; n++) {
00134 c = crc_table[0][n];
00135 crc_table[4][n] = REV(c);
00136 for (k = 1; k < 4; k++) {
00137 c = crc_table[0][c & 0xff] ^ (c >> 8);
00138 crc_table[k][n] = c;
00139 crc_table[k + 4][n] = REV(c);
00140 }
00141 }
00142 #endif
00143
00144 crc_table_empty = 0;
00145 }
00146 else {
00147
00148 while (crc_table_empty)
00149 ;
00150 }
00151
00152 #ifdef MAKECRCH
00153
00154 {
00155 FILE *out;
00156
00157 out = fopen("crc32.h", "w");
00158 if (out == NULL) return;
00159 fprintf(out, "/* crc32.h -- tables for rapid CRC calculation\n");
00160 fprintf(out, " * Generated automatically by crc32.c\n */\n\n");
00161 fprintf(out, "local const unsigned long FAR ");
00162 fprintf(out, "crc_table[TBLS][256] =\n{\n {\n");
00163 write_table(out, crc_table[0]);
00164 # ifdef BYFOUR
00165 fprintf(out, "#ifdef BYFOUR\n");
00166 for (k = 1; k < 8; k++) {
00167 fprintf(out, " },\n {\n");
00168 write_table(out, crc_table[k]);
00169 }
00170 fprintf(out, "#endif\n");
00171 # endif
00172 fprintf(out, " }\n};\n");
00173 fclose(out);
00174 }
00175 #endif
00176 }
00177
00178 #ifdef MAKECRCH
00179 local void write_table(FILE *out, const unsigned long FAR *table)
00180 {
00181 int n;
00182
00183 for (n = 0; n < 256; n++)
00184 fprintf(out, "%s0x%08lxUL%s", n % 5 ? "" : " ", table[n],
00185 n == 255 ? "\n" : (n % 5 == 4 ? ",\n" : ", "));
00186 }
00187 #endif
00188
00189 #else
00190
00191
00192
00193 #include "crc32.h"
00194 #endif
00195
00196
00197
00198
00199 const unsigned long FAR * ZEXPORT get_crc_table()
00200 {
00201 #ifdef DYNAMIC_CRC_TABLE
00202 if (crc_table_empty)
00203 make_crc_table();
00204 #endif
00205 return (const unsigned long FAR *)crc_table;
00206 }
00207
00208
00209 #define DO1 crc = crc_table[0][((int)crc ^ (*buf++)) & 0xff] ^ (crc >> 8)
00210 #define DO8 DO1; DO1; DO1; DO1; DO1; DO1; DO1; DO1
00211
00212
00213 unsigned long ZEXPORT crc32(unsigned long crc, const unsigned char FAR *buf, unsigned len)
00214 {
00215 if (buf == Z_NULL) return 0UL;
00216
00217 #ifdef DYNAMIC_CRC_TABLE
00218 if (crc_table_empty)
00219 make_crc_table();
00220 #endif
00221
00222 #ifdef BYFOUR
00223 if (sizeof(void *) == sizeof(ptrdiff_t)) {
00224 u4 endian;
00225
00226 endian = 1;
00227 if (*((unsigned char *)(&endian)))
00228 return crc32_little(crc, buf, len);
00229 else
00230 return crc32_big(crc, buf, len);
00231 }
00232 #endif
00233 crc = crc ^ 0xffffffffUL;
00234 while (len >= 8) {
00235 DO8;
00236 len -= 8;
00237 }
00238 if (len) do {
00239 DO1;
00240 } while (--len);
00241 return crc ^ 0xffffffffUL;
00242 }
00243
00244 #ifdef BYFOUR
00245
00246
00247 #define DOLIT4 c ^= *buf4++; \
00248 c = crc_table[3][c & 0xff] ^ crc_table[2][(c >> 8) & 0xff] ^ \
00249 crc_table[1][(c >> 16) & 0xff] ^ crc_table[0][c >> 24]
00250 #define DOLIT32 DOLIT4; DOLIT4; DOLIT4; DOLIT4; DOLIT4; DOLIT4; DOLIT4; DOLIT4
00251
00252
00253 local unsigned long crc32_little(unsigned long crc, const unsigned char FAR *buf, unsigned len)
00254 {
00255 register u4 c;
00256 register const u4 FAR *buf4;
00257
00258 c = (u4)crc;
00259 c = ~c;
00260 while (len && ((ptrdiff_t)buf & 3)) {
00261 c = crc_table[0][(c ^ *buf++) & 0xff] ^ (c >> 8);
00262 len--;
00263 }
00264
00265 buf4 = (const u4 FAR *)buf;
00266 while (len >= 32) {
00267 DOLIT32;
00268 len -= 32;
00269 }
00270 while (len >= 4) {
00271 DOLIT4;
00272 len -= 4;
00273 }
00274 buf = (const unsigned char FAR *)buf4;
00275
00276 if (len) do {
00277 c = crc_table[0][(c ^ *buf++) & 0xff] ^ (c >> 8);
00278 } while (--len);
00279 c = ~c;
00280 return (unsigned long)c;
00281 }
00282
00283
00284 #define DOBIG4 c ^= *++buf4; \
00285 c = crc_table[4][c & 0xff] ^ crc_table[5][(c >> 8) & 0xff] ^ \
00286 crc_table[6][(c >> 16) & 0xff] ^ crc_table[7][c >> 24]
00287 #define DOBIG32 DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4
00288
00289
00290 local unsigned long crc32_big(unsigned long crc, const unsigned char FAR *buf, unsigned len)
00291 {
00292 register u4 c;
00293 register const u4 FAR *buf4;
00294
00295 c = REV((u4)crc);
00296 c = ~c;
00297 while (len && ((ptrdiff_t)buf & 3)) {
00298 c = crc_table[4][(c >> 24) ^ *buf++] ^ (c << 8);
00299 len--;
00300 }
00301
00302 buf4 = (const u4 FAR *)buf;
00303 buf4--;
00304 while (len >= 32) {
00305 DOBIG32;
00306 len -= 32;
00307 }
00308 while (len >= 4) {
00309 DOBIG4;
00310 len -= 4;
00311 }
00312 buf4++;
00313 buf = (const unsigned char FAR *)buf4;
00314
00315 if (len) do {
00316 c = crc_table[4][(c >> 24) ^ *buf++] ^ (c << 8);
00317 } while (--len);
00318 c = ~c;
00319 return (unsigned long)(REV(c));
00320 }
00321
00322 #endif