summaryrefslogtreecommitdiff
path: root/adler32.c
diff options
context:
space:
mode:
Diffstat (limited to 'adler32.c')
-rw-r--r--adler32.c68
1 files changed, 39 insertions, 29 deletions
diff --git a/adler32.c b/adler32.c
index 65ad6a5..a868f07 100644
--- a/adler32.c
+++ b/adler32.c
@@ -1,5 +1,5 @@
1/* adler32.c -- compute the Adler-32 checksum of a data stream 1/* adler32.c -- compute the Adler-32 checksum of a data stream
2 * Copyright (C) 1995-2007 Mark Adler 2 * Copyright (C) 1995-2011 Mark Adler
3 * For conditions of distribution and use, see copyright notice in zlib.h 3 * For conditions of distribution and use, see copyright notice in zlib.h
4 */ 4 */
5 5
@@ -9,9 +9,9 @@
9 9
10#define local static 10#define local static
11 11
12local uLong adler32_combine_(uLong adler1, uLong adler2, z_off64_t len2); 12local uLong adler32_combine_ OF((uLong adler1, uLong adler2, z_off64_t len2));
13 13
14#define BASE 65521UL /* largest prime smaller than 65536 */ 14#define BASE 65521 /* largest prime smaller than 65536 */
15#define NMAX 5552 15#define NMAX 5552
16/* NMAX is the largest n such that 255n(n+1)/2 + (n+1)(BASE-1) <= 2^32-1 */ 16/* NMAX is the largest n such that 255n(n+1)/2 + (n+1)(BASE-1) <= 2^32-1 */
17 17
@@ -21,39 +21,44 @@ local uLong adler32_combine_(uLong adler1, uLong adler2, z_off64_t len2);
21#define DO8(buf,i) DO4(buf,i); DO4(buf,i+4); 21#define DO8(buf,i) DO4(buf,i); DO4(buf,i+4);
22#define DO16(buf) DO8(buf,0); DO8(buf,8); 22#define DO16(buf) DO8(buf,0); DO8(buf,8);
23 23
24/* use NO_DIVIDE if your processor does not do division in hardware */ 24/* use NO_DIVIDE if your processor does not do division in hardware --
25 try it both ways to see which is faster */
25#ifdef NO_DIVIDE 26#ifdef NO_DIVIDE
26# define MOD(a) \ 27/* note that this assumes BASE is 65521, where 65536 % 65521 == 15
28 (thank you to John Reiser for pointing this out) */
29# define CHOP(a) \
30 do { \
31 unsigned long tmp = a >> 16; \
32 a &= 0xffffUL; \
33 a += (tmp << 4) - tmp; \
34 } while (0)
35# define MOD28(a) \
27 do { \ 36 do { \
28 if (a >= (BASE << 16)) a -= (BASE << 16); \ 37 CHOP(a); \
29 if (a >= (BASE << 15)) a -= (BASE << 15); \
30 if (a >= (BASE << 14)) a -= (BASE << 14); \
31 if (a >= (BASE << 13)) a -= (BASE << 13); \
32 if (a >= (BASE << 12)) a -= (BASE << 12); \
33 if (a >= (BASE << 11)) a -= (BASE << 11); \
34 if (a >= (BASE << 10)) a -= (BASE << 10); \
35 if (a >= (BASE << 9)) a -= (BASE << 9); \
36 if (a >= (BASE << 8)) a -= (BASE << 8); \
37 if (a >= (BASE << 7)) a -= (BASE << 7); \
38 if (a >= (BASE << 6)) a -= (BASE << 6); \
39 if (a >= (BASE << 5)) a -= (BASE << 5); \
40 if (a >= (BASE << 4)) a -= (BASE << 4); \
41 if (a >= (BASE << 3)) a -= (BASE << 3); \
42 if (a >= (BASE << 2)) a -= (BASE << 2); \
43 if (a >= (BASE << 1)) a -= (BASE << 1); \
44 if (a >= BASE) a -= BASE; \ 38 if (a >= BASE) a -= BASE; \
45 } while (0) 39 } while (0)
46# define MOD4(a) \ 40# define MOD(a) \
47 do { \ 41 do { \
48 if (a >= (BASE << 4)) a -= (BASE << 4); \ 42 CHOP(a); \
49 if (a >= (BASE << 3)) a -= (BASE << 3); \ 43 MOD28(a); \
50 if (a >= (BASE << 2)) a -= (BASE << 2); \ 44 } while (0)
51 if (a >= (BASE << 1)) a -= (BASE << 1); \ 45# define MOD63(a) \
46 do { /* this assumes a is not negative */ \
47 z_off64_t tmp = a >> 32; \
48 a &= 0xffffffffL; \
49 a += (tmp << 8) - (tmp << 5) + tmp; \
50 tmp = a >> 16; \
51 a &= 0xffffL; \
52 a += (tmp << 4) - tmp; \
53 tmp = a >> 16; \
54 a &= 0xffffL; \
55 a += (tmp << 4) - tmp; \
52 if (a >= BASE) a -= BASE; \ 56 if (a >= BASE) a -= BASE; \
53 } while (0) 57 } while (0)
54#else 58#else
55# define MOD(a) a %= BASE 59# define MOD(a) a %= BASE
56# define MOD4(a) a %= BASE 60# define MOD28(a) a %= BASE
61# define MOD63(a) a %= BASE
57#endif 62#endif
58 63
59/* ========================================================================= */ 64/* ========================================================================= */
@@ -92,7 +97,7 @@ uLong ZEXPORT adler32(adler, buf, len)
92 } 97 }
93 if (adler >= BASE) 98 if (adler >= BASE)
94 adler -= BASE; 99 adler -= BASE;
95 MOD4(sum2); /* only added so many BASE's */ 100 MOD28(sum2); /* only added so many BASE's */
96 return adler | (sum2 << 16); 101 return adler | (sum2 << 16);
97 } 102 }
98 103
@@ -137,8 +142,13 @@ local uLong adler32_combine_(adler1, adler2, len2)
137 unsigned long sum2; 142 unsigned long sum2;
138 unsigned rem; 143 unsigned rem;
139 144
145 /* for negative len, return invalid adler32 as a clue for debugging */
146 if (len2 < 0)
147 return 0xffffffffUL;
148
140 /* the derivation of this formula is left as an exercise for the reader */ 149 /* the derivation of this formula is left as an exercise for the reader */
141 rem = (unsigned)(len2 % BASE); 150 MOD63(len2); /* assumes len2 >= 0 */
151 rem = (unsigned)len2;
142 sum1 = adler1 & 0xffff; 152 sum1 = adler1 & 0xffff;
143 sum2 = rem * sum1; 153 sum2 = rem * sum1;
144 MOD(sum2); 154 MOD(sum2);