This source file includes following definitions.
- make_crc_table
- write_table
- get_crc_table
- crc32
- crc32_little
- crc32_big
- gf2_matrix_times
- gf2_matrix_square
- crc32_combine
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 #ifdef MAKECRCH
23 # include <stdio.h>
24 # ifndef DYNAMIC_CRC_TABLE
25 # define DYNAMIC_CRC_TABLE
26 # endif
27 #endif
28
29 #include "zutil.h"
30
31 #define local static
32
33
34 #ifndef NOBYFOUR
35 # ifdef STDC
36 # include <limits.h>
37 # define BYFOUR
38 # if (UINT_MAX == 0xffffffffUL)
39 typedef unsigned int u4;
40 # else
41 # if (ULONG_MAX == 0xffffffffUL)
42 typedef unsigned long u4;
43 # else
44 # if (USHRT_MAX == 0xffffffffUL)
45 typedef unsigned short u4;
46 # else
47 # undef BYFOUR
48 # endif
49 # endif
50 # endif
51 # endif
52 #endif
53
54
55 #ifdef BYFOUR
56 # define REV(w) (((w)>>24)+(((w)>>8)&0xff00)+ \
57 (((w)&0xff00)<<8)+(((w)&0xff)<<24))
58 local unsigned long crc32_little OF((unsigned long,
59 const unsigned char FAR *, unsigned));
60 local unsigned long crc32_big OF((unsigned long,
61 const unsigned char FAR *, unsigned));
62 # define TBLS 8
63 #else
64 # define TBLS 1
65 #endif
66
67
68 local unsigned long gf2_matrix_times OF((unsigned long *mat,
69 unsigned long vec));
70 local void gf2_matrix_square OF((unsigned long *square, unsigned long *mat));
71
72 #ifdef DYNAMIC_CRC_TABLE
73
74 local volatile int crc_table_empty = 1;
75 local unsigned long FAR crc_table[TBLS][256];
76 local void make_crc_table OF((void));
77 #ifdef MAKECRCH
78 local void write_table OF((FILE *, const unsigned long FAR *));
79 #endif
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106 local void make_crc_table()
107 {
108 unsigned long c;
109 int n, k;
110 unsigned long poly;
111
112 static volatile int first = 1;
113 static const unsigned char p[] = {0,1,2,4,5,7,8,10,11,12,16,22,23,26};
114
115
116
117
118 if (first) {
119 first = 0;
120
121
122 poly = 0UL;
123 for (n = 0; n < sizeof(p)/sizeof(unsigned char); n++)
124 poly |= 1UL << (31 - p[n]);
125
126
127 for (n = 0; n < 256; n++) {
128 c = (unsigned long)n;
129 for (k = 0; k < 8; k++)
130 c = c & 1 ? poly ^ (c >> 1) : c >> 1;
131 crc_table[0][n] = c;
132 }
133
134 #ifdef BYFOUR
135
136
137 for (n = 0; n < 256; n++) {
138 c = crc_table[0][n];
139 crc_table[4][n] = REV(c);
140 for (k = 1; k < 4; k++) {
141 c = crc_table[0][c & 0xff] ^ (c >> 8);
142 crc_table[k][n] = c;
143 crc_table[k + 4][n] = REV(c);
144 }
145 }
146 #endif
147
148 crc_table_empty = 0;
149 }
150 else {
151
152 while (crc_table_empty)
153 ;
154 }
155
156 #ifdef MAKECRCH
157
158 {
159 FILE *out;
160
161 out = fopen("crc32.h", "w");
162 if (out == NULL) return;
163 fprintf(out, "/* crc32.h -- tables for rapid CRC calculation\n");
164 fprintf(out, " * Generated automatically by crc32.c\n */\n\n");
165 fprintf(out, "local const unsigned long FAR ");
166 fprintf(out, "crc_table[TBLS][256] =\n{\n {\n");
167 write_table(out, crc_table[0]);
168 # ifdef BYFOUR
169 fprintf(out, "#ifdef BYFOUR\n");
170 for (k = 1; k < 8; k++) {
171 fprintf(out, " },\n {\n");
172 write_table(out, crc_table[k]);
173 }
174 fprintf(out, "#endif\n");
175 # endif
176 fprintf(out, " }\n};\n");
177 fclose(out);
178 }
179 #endif
180 }
181
182 #ifdef MAKECRCH
183 local void write_table(out, table)
184 FILE *out;
185 const unsigned long FAR *table;
186 {
187 int n;
188
189 for (n = 0; n < 256; n++)
190 fprintf(out, "%s0x%08lxUL%s", n % 5 ? "" : " ", table[n],
191 n == 255 ? "\n" : (n % 5 == 4 ? ",\n" : ", "));
192 }
193 #endif
194
195 #else
196
197
198
199 #include "crc32.h"
200 #endif
201
202
203
204
205 const unsigned long FAR * ZEXPORT get_crc_table()
206 {
207 #ifdef DYNAMIC_CRC_TABLE
208 if (crc_table_empty)
209 make_crc_table();
210 #endif
211 return (const unsigned long FAR *)crc_table;
212 }
213
214
215 #define DO1 crc = crc_table[0][((int)crc ^ (*buf++)) & 0xff] ^ (crc >> 8)
216 #define DO8 DO1; DO1; DO1; DO1; DO1; DO1; DO1; DO1
217
218
219 unsigned long ZEXPORT crc32(crc, buf, len)
220 unsigned long crc;
221 const unsigned char FAR *buf;
222 unsigned len;
223 {
224 if (buf == Z_NULL) return 0UL;
225
226 #ifdef DYNAMIC_CRC_TABLE
227 if (crc_table_empty)
228 make_crc_table();
229 #endif
230
231 #ifdef BYFOUR
232 if (sizeof(void *) == sizeof(ptrdiff_t)) {
233 u4 endian;
234
235 endian = 1;
236 if (*((unsigned char *)(&endian)))
237 return crc32_little(crc, buf, len);
238 else
239 return crc32_big(crc, buf, len);
240 }
241 #endif
242 crc = crc ^ 0xffffffffUL;
243 while (len >= 8) {
244 DO8;
245 len -= 8;
246 }
247 if (len) do {
248 DO1;
249 } while (--len);
250 return crc ^ 0xffffffffUL;
251 }
252
253 #ifdef BYFOUR
254
255
256 #define DOLIT4 c ^= *buf4++; \
257 c = crc_table[3][c & 0xff] ^ crc_table[2][(c >> 8) & 0xff] ^ \
258 crc_table[1][(c >> 16) & 0xff] ^ crc_table[0][c >> 24]
259 #define DOLIT32 DOLIT4; DOLIT4; DOLIT4; DOLIT4; DOLIT4; DOLIT4; DOLIT4; DOLIT4
260
261
262 local unsigned long crc32_little(crc, buf, len)
263 unsigned long crc;
264 const unsigned char FAR *buf;
265 unsigned len;
266 {
267 register u4 c;
268 register const u4 FAR *buf4;
269
270 c = (u4)crc;
271 c = ~c;
272 while (len && ((ptrdiff_t)buf & 3)) {
273 c = crc_table[0][(c ^ *buf++) & 0xff] ^ (c >> 8);
274 len--;
275 }
276
277 buf4 = (const u4 FAR *)(const void FAR *)buf;
278 while (len >= 32) {
279 DOLIT32;
280 len -= 32;
281 }
282 while (len >= 4) {
283 DOLIT4;
284 len -= 4;
285 }
286 buf = (const unsigned char FAR *)buf4;
287
288 if (len) do {
289 c = crc_table[0][(c ^ *buf++) & 0xff] ^ (c >> 8);
290 } while (--len);
291 c = ~c;
292 return (unsigned long)c;
293 }
294
295
296 #define DOBIG4 c ^= *++buf4; \
297 c = crc_table[4][c & 0xff] ^ crc_table[5][(c >> 8) & 0xff] ^ \
298 crc_table[6][(c >> 16) & 0xff] ^ crc_table[7][c >> 24]
299 #define DOBIG32 DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4
300
301
302 local unsigned long crc32_big(crc, buf, len)
303 unsigned long crc;
304 const unsigned char FAR *buf;
305 unsigned len;
306 {
307 register u4 c;
308 register const u4 FAR *buf4;
309
310 c = REV((u4)crc);
311 c = ~c;
312 while (len && ((ptrdiff_t)buf & 3)) {
313 c = crc_table[4][(c >> 24) ^ *buf++] ^ (c << 8);
314 len--;
315 }
316
317 buf4 = (const u4 FAR *)(const void FAR *)buf;
318 buf4--;
319 while (len >= 32) {
320 DOBIG32;
321 len -= 32;
322 }
323 while (len >= 4) {
324 DOBIG4;
325 len -= 4;
326 }
327 buf4++;
328 buf = (const unsigned char FAR *)buf4;
329
330 if (len) do {
331 c = crc_table[4][(c >> 24) ^ *buf++] ^ (c << 8);
332 } while (--len);
333 c = ~c;
334 return (unsigned long)(REV(c));
335 }
336
337 #endif
338
339 #define GF2_DIM 32
340
341
342 local unsigned long gf2_matrix_times(mat, vec)
343 unsigned long *mat;
344 unsigned long vec;
345 {
346 unsigned long sum;
347
348 sum = 0;
349 while (vec) {
350 if (vec & 1)
351 sum ^= *mat;
352 vec >>= 1;
353 mat++;
354 }
355 return sum;
356 }
357
358
359 local void gf2_matrix_square(square, mat)
360 unsigned long *square;
361 unsigned long *mat;
362 {
363 int n;
364
365 for (n = 0; n < GF2_DIM; n++)
366 square[n] = gf2_matrix_times(mat, mat[n]);
367 }
368
369
370 uLong ZEXPORT crc32_combine(crc1, crc2, len2)
371 uLong crc1;
372 uLong crc2;
373 z_off_t len2;
374 {
375 int n;
376 unsigned long row;
377 unsigned long even[GF2_DIM];
378 unsigned long odd[GF2_DIM];
379
380
381 if (len2 == 0)
382 return crc1;
383
384
385 odd[0] = 0xedb88320L;
386 row = 1;
387 for (n = 1; n < GF2_DIM; n++) {
388 odd[n] = row;
389 row <<= 1;
390 }
391
392
393 gf2_matrix_square(even, odd);
394
395
396 gf2_matrix_square(odd, even);
397
398
399
400 do {
401
402 gf2_matrix_square(even, odd);
403 if (len2 & 1)
404 crc1 = gf2_matrix_times(even, crc1);
405 len2 >>= 1;
406
407
408 if (len2 == 0)
409 break;
410
411
412 gf2_matrix_square(odd, even);
413 if (len2 & 1)
414 crc1 = gf2_matrix_times(odd, crc1);
415 len2 >>= 1;
416
417
418 } while (len2 != 0);
419
420
421 crc1 ^= crc2;
422 return crc1;
423 }