xref: /nrf52832-nimble/rt-thread/components/dfs/filesystems/jffs2/cyg/compress/src/adler32.c (revision 104654410c56c573564690304ae786df310c91fc)
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