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