1*10465441SEvalZero /* adler32.c -- compute the Adler-32 checksum of a data stream
2*10465441SEvalZero * Copyright (C) 1995-2004 Mark Adler
3*10465441SEvalZero * For conditions of distribution and use, see copyright notice in zlib.h
4*10465441SEvalZero */
5*10465441SEvalZero
6*10465441SEvalZero /* @(#) $Id$ */
7*10465441SEvalZero
8*10465441SEvalZero #define ZLIB_INTERNAL
9*10465441SEvalZero #ifdef __ECOS__
10*10465441SEvalZero #include <cyg/compress/zlib.h>
11*10465441SEvalZero #else
12*10465441SEvalZero #include "zlib.h"
13*10465441SEvalZero #endif // __ECOS__
14*10465441SEvalZero
15*10465441SEvalZero #define BASE 65521UL /* largest prime smaller than 65536 */
16*10465441SEvalZero #define NMAX 5552
17*10465441SEvalZero /* NMAX is the largest n such that 255n(n+1)/2 + (n+1)(BASE-1) <= 2^32-1 */
18*10465441SEvalZero
19*10465441SEvalZero #define DO1(buf,i) {adler += (buf)[i]; sum2 += adler;}
20*10465441SEvalZero #define DO2(buf,i) DO1(buf,i); DO1(buf,i+1);
21*10465441SEvalZero #define DO4(buf,i) DO2(buf,i); DO2(buf,i+2);
22*10465441SEvalZero #define DO8(buf,i) DO4(buf,i); DO4(buf,i+4);
23*10465441SEvalZero #define DO16(buf) DO8(buf,0); DO8(buf,8);
24*10465441SEvalZero
25*10465441SEvalZero /* use NO_DIVIDE if your processor does not do division in hardware */
26*10465441SEvalZero #ifdef NO_DIVIDE
27*10465441SEvalZero # define MOD(a) \
28*10465441SEvalZero do { \
29*10465441SEvalZero if (a >= (BASE << 16)) a -= (BASE << 16); \
30*10465441SEvalZero if (a >= (BASE << 15)) a -= (BASE << 15); \
31*10465441SEvalZero if (a >= (BASE << 14)) a -= (BASE << 14); \
32*10465441SEvalZero if (a >= (BASE << 13)) a -= (BASE << 13); \
33*10465441SEvalZero if (a >= (BASE << 12)) a -= (BASE << 12); \
34*10465441SEvalZero if (a >= (BASE << 11)) a -= (BASE << 11); \
35*10465441SEvalZero if (a >= (BASE << 10)) a -= (BASE << 10); \
36*10465441SEvalZero if (a >= (BASE << 9)) a -= (BASE << 9); \
37*10465441SEvalZero if (a >= (BASE << 8)) a -= (BASE << 8); \
38*10465441SEvalZero if (a >= (BASE << 7)) a -= (BASE << 7); \
39*10465441SEvalZero if (a >= (BASE << 6)) a -= (BASE << 6); \
40*10465441SEvalZero if (a >= (BASE << 5)) a -= (BASE << 5); \
41*10465441SEvalZero if (a >= (BASE << 4)) a -= (BASE << 4); \
42*10465441SEvalZero if (a >= (BASE << 3)) a -= (BASE << 3); \
43*10465441SEvalZero if (a >= (BASE << 2)) a -= (BASE << 2); \
44*10465441SEvalZero if (a >= (BASE << 1)) a -= (BASE << 1); \
45*10465441SEvalZero if (a >= BASE) a -= BASE; \
46*10465441SEvalZero } while (0)
47*10465441SEvalZero # define MOD4(a) \
48*10465441SEvalZero do { \
49*10465441SEvalZero if (a >= (BASE << 4)) a -= (BASE << 4); \
50*10465441SEvalZero if (a >= (BASE << 3)) a -= (BASE << 3); \
51*10465441SEvalZero if (a >= (BASE << 2)) a -= (BASE << 2); \
52*10465441SEvalZero if (a >= (BASE << 1)) a -= (BASE << 1); \
53*10465441SEvalZero if (a >= BASE) a -= BASE; \
54*10465441SEvalZero } while (0)
55*10465441SEvalZero #else
56*10465441SEvalZero # define MOD(a) a %= BASE
57*10465441SEvalZero # define MOD4(a) a %= BASE
58*10465441SEvalZero #endif
59*10465441SEvalZero
60*10465441SEvalZero /* ========================================================================= */
adler32(adler,buf,len)61*10465441SEvalZero uLong ZEXPORT adler32(adler, buf, len)
62*10465441SEvalZero uLong adler;
63*10465441SEvalZero const Bytef *buf;
64*10465441SEvalZero uInt len;
65*10465441SEvalZero {
66*10465441SEvalZero unsigned long sum2;
67*10465441SEvalZero unsigned n;
68*10465441SEvalZero
69*10465441SEvalZero /* split Adler-32 into component sums */
70*10465441SEvalZero sum2 = (adler >> 16) & 0xffff;
71*10465441SEvalZero adler &= 0xffff;
72*10465441SEvalZero
73*10465441SEvalZero /* in case user likes doing a byte at a time, keep it fast */
74*10465441SEvalZero if (len == 1) {
75*10465441SEvalZero adler += buf[0];
76*10465441SEvalZero if (adler >= BASE)
77*10465441SEvalZero adler -= BASE;
78*10465441SEvalZero sum2 += adler;
79*10465441SEvalZero if (sum2 >= BASE)
80*10465441SEvalZero sum2 -= BASE;
81*10465441SEvalZero return adler | (sum2 << 16);
82*10465441SEvalZero }
83*10465441SEvalZero
84*10465441SEvalZero /* initial Adler-32 value (deferred check for len == 1 speed) */
85*10465441SEvalZero if (buf == Z_NULL)
86*10465441SEvalZero return 1L;
87*10465441SEvalZero
88*10465441SEvalZero /* in case short lengths are provided, keep it somewhat fast */
89*10465441SEvalZero if (len < 16) {
90*10465441SEvalZero while (len--) {
91*10465441SEvalZero adler += *buf++;
92*10465441SEvalZero sum2 += adler;
93*10465441SEvalZero }
94*10465441SEvalZero if (adler >= BASE)
95*10465441SEvalZero adler -= BASE;
96*10465441SEvalZero MOD4(sum2); /* only added so many BASE's */
97*10465441SEvalZero return adler | (sum2 << 16);
98*10465441SEvalZero }
99*10465441SEvalZero
100*10465441SEvalZero /* do length NMAX blocks -- requires just one modulo operation */
101*10465441SEvalZero while (len >= NMAX) {
102*10465441SEvalZero len -= NMAX;
103*10465441SEvalZero n = NMAX / 16; /* NMAX is divisible by 16 */
104*10465441SEvalZero do {
105*10465441SEvalZero DO16(buf); /* 16 sums unrolled */
106*10465441SEvalZero buf += 16;
107*10465441SEvalZero } while (--n);
108*10465441SEvalZero MOD(adler);
109*10465441SEvalZero MOD(sum2);
110*10465441SEvalZero }
111*10465441SEvalZero
112*10465441SEvalZero /* do remaining bytes (less than NMAX, still just one modulo) */
113*10465441SEvalZero if (len) { /* avoid modulos if none remaining */
114*10465441SEvalZero while (len >= 16) {
115*10465441SEvalZero len -= 16;
116*10465441SEvalZero DO16(buf);
117*10465441SEvalZero buf += 16;
118*10465441SEvalZero }
119*10465441SEvalZero while (len--) {
120*10465441SEvalZero adler += *buf++;
121*10465441SEvalZero sum2 += adler;
122*10465441SEvalZero }
123*10465441SEvalZero MOD(adler);
124*10465441SEvalZero MOD(sum2);
125*10465441SEvalZero }
126*10465441SEvalZero
127*10465441SEvalZero /* return recombined sums */
128*10465441SEvalZero return adler | (sum2 << 16);
129*10465441SEvalZero }
130*10465441SEvalZero
131*10465441SEvalZero /* ========================================================================= */
adler32_combine(adler1,adler2,len2)132*10465441SEvalZero uLong ZEXPORT adler32_combine(adler1, adler2, len2)
133*10465441SEvalZero uLong adler1;
134*10465441SEvalZero uLong adler2;
135*10465441SEvalZero z_off_t len2;
136*10465441SEvalZero {
137*10465441SEvalZero unsigned long sum1;
138*10465441SEvalZero unsigned long sum2;
139*10465441SEvalZero unsigned rem;
140*10465441SEvalZero
141*10465441SEvalZero /* the derivation of this formula is left as an exercise for the reader */
142*10465441SEvalZero rem = (unsigned)(len2 % BASE);
143*10465441SEvalZero sum1 = adler1 & 0xffff;
144*10465441SEvalZero sum2 = rem * sum1;
145*10465441SEvalZero MOD(sum2);
146*10465441SEvalZero sum1 += (adler2 & 0xffff) + BASE - 1;
147*10465441SEvalZero sum2 += ((adler1 >> 16) & 0xffff) + ((adler2 >> 16) & 0xffff) + BASE - rem;
148*10465441SEvalZero if (sum1 > BASE) sum1 -= BASE;
149*10465441SEvalZero if (sum1 > BASE) sum1 -= BASE;
150*10465441SEvalZero if (sum2 > (BASE << 1)) sum2 -= (BASE << 1);
151*10465441SEvalZero if (sum2 > BASE) sum2 -= BASE;
152*10465441SEvalZero return sum1 | (sum2 << 16);
153*10465441SEvalZero }
154