xref: /plan9/sys/src/cmd/gs/zlib/adler32.c (revision 593dc095aefb2a85c828727bbfa9da139a49bdf4)
17dd7cddfSDavid du Colombier /* adler32.c -- compute the Adler-32 checksum of a data stream
2*593dc095SDavid du Colombier  * Copyright (C) 1995-2003 Mark Adler
37dd7cddfSDavid du Colombier  * For conditions of distribution and use, see copyright notice in zlib.h
47dd7cddfSDavid du Colombier  */
57dd7cddfSDavid du Colombier 
6*593dc095SDavid du Colombier /* @(#) $Id: adler32.c,v 1.1.1.1 2005/04/24 21:39:38 giles Exp $ */
77dd7cddfSDavid du Colombier 
8*593dc095SDavid du Colombier #define ZLIB_INTERNAL
97dd7cddfSDavid du Colombier #include "zlib.h"
107dd7cddfSDavid du Colombier 
11*593dc095SDavid du Colombier #define BASE 65521UL    /* largest prime smaller than 65536 */
127dd7cddfSDavid du Colombier #define NMAX 5552
137dd7cddfSDavid du Colombier /* NMAX is the largest n such that 255n(n+1)/2 + (n+1)(BASE-1) <= 2^32-1 */
147dd7cddfSDavid du Colombier 
157dd7cddfSDavid du Colombier #define DO1(buf,i)  {s1 += buf[i]; s2 += s1;}
167dd7cddfSDavid du Colombier #define DO2(buf,i)  DO1(buf,i); DO1(buf,i+1);
177dd7cddfSDavid du Colombier #define DO4(buf,i)  DO2(buf,i); DO2(buf,i+2);
187dd7cddfSDavid du Colombier #define DO8(buf,i)  DO4(buf,i); DO4(buf,i+4);
197dd7cddfSDavid du Colombier #define DO16(buf)   DO8(buf,0); DO8(buf,8);
207dd7cddfSDavid du Colombier 
21*593dc095SDavid du Colombier #ifdef NO_DIVIDE
22*593dc095SDavid du Colombier #  define MOD(a) \
23*593dc095SDavid du Colombier     do { \
24*593dc095SDavid du Colombier         if (a >= (BASE << 16)) a -= (BASE << 16); \
25*593dc095SDavid du Colombier         if (a >= (BASE << 15)) a -= (BASE << 15); \
26*593dc095SDavid du Colombier         if (a >= (BASE << 14)) a -= (BASE << 14); \
27*593dc095SDavid du Colombier         if (a >= (BASE << 13)) a -= (BASE << 13); \
28*593dc095SDavid du Colombier         if (a >= (BASE << 12)) a -= (BASE << 12); \
29*593dc095SDavid du Colombier         if (a >= (BASE << 11)) a -= (BASE << 11); \
30*593dc095SDavid du Colombier         if (a >= (BASE << 10)) a -= (BASE << 10); \
31*593dc095SDavid du Colombier         if (a >= (BASE << 9)) a -= (BASE << 9); \
32*593dc095SDavid du Colombier         if (a >= (BASE << 8)) a -= (BASE << 8); \
33*593dc095SDavid du Colombier         if (a >= (BASE << 7)) a -= (BASE << 7); \
34*593dc095SDavid du Colombier         if (a >= (BASE << 6)) a -= (BASE << 6); \
35*593dc095SDavid du Colombier         if (a >= (BASE << 5)) a -= (BASE << 5); \
36*593dc095SDavid du Colombier         if (a >= (BASE << 4)) a -= (BASE << 4); \
37*593dc095SDavid du Colombier         if (a >= (BASE << 3)) a -= (BASE << 3); \
38*593dc095SDavid du Colombier         if (a >= (BASE << 2)) a -= (BASE << 2); \
39*593dc095SDavid du Colombier         if (a >= (BASE << 1)) a -= (BASE << 1); \
40*593dc095SDavid du Colombier         if (a >= BASE) a -= BASE; \
41*593dc095SDavid du Colombier     } while (0)
42*593dc095SDavid du Colombier #else
43*593dc095SDavid du Colombier #  define MOD(a) a %= BASE
44*593dc095SDavid du Colombier #endif
45*593dc095SDavid du Colombier 
467dd7cddfSDavid du Colombier /* ========================================================================= */
adler32(adler,buf,len)47*593dc095SDavid du Colombier uLong ZEXPORT adler32(adler, buf, len)
487dd7cddfSDavid du Colombier     uLong adler;
497dd7cddfSDavid du Colombier     const Bytef *buf;
507dd7cddfSDavid du Colombier     uInt len;
517dd7cddfSDavid du Colombier {
527dd7cddfSDavid du Colombier     unsigned long s1 = adler & 0xffff;
537dd7cddfSDavid du Colombier     unsigned long s2 = (adler >> 16) & 0xffff;
547dd7cddfSDavid du Colombier     int k;
557dd7cddfSDavid du Colombier 
567dd7cddfSDavid du Colombier     if (buf == Z_NULL) return 1L;
577dd7cddfSDavid du Colombier 
587dd7cddfSDavid du Colombier     while (len > 0) {
59*593dc095SDavid du Colombier         k = len < NMAX ? (int)len : NMAX;
607dd7cddfSDavid du Colombier         len -= k;
617dd7cddfSDavid du Colombier         while (k >= 16) {
627dd7cddfSDavid du Colombier             DO16(buf);
637dd7cddfSDavid du Colombier             buf += 16;
647dd7cddfSDavid du Colombier             k -= 16;
657dd7cddfSDavid du Colombier         }
667dd7cddfSDavid du Colombier         if (k != 0) do {
677dd7cddfSDavid du Colombier             s1 += *buf++;
687dd7cddfSDavid du Colombier             s2 += s1;
697dd7cddfSDavid du Colombier         } while (--k);
70*593dc095SDavid du Colombier         MOD(s1);
71*593dc095SDavid du Colombier         MOD(s2);
727dd7cddfSDavid du Colombier     }
737dd7cddfSDavid du Colombier     return (s2 << 16) | s1;
747dd7cddfSDavid du Colombier }
75