modules/zlib/src/adler32.c

changeset 0
6474c204b198
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/modules/zlib/src/adler32.c	Wed Dec 31 06:09:35 2014 +0100
     1.3 @@ -0,0 +1,179 @@
     1.4 +/* adler32.c -- compute the Adler-32 checksum of a data stream
     1.5 + * Copyright (C) 1995-2011 Mark Adler
     1.6 + * For conditions of distribution and use, see copyright notice in zlib.h
     1.7 + */
     1.8 +
     1.9 +/* @(#) $Id$ */
    1.10 +
    1.11 +#include "zutil.h"
    1.12 +
    1.13 +#define local static
    1.14 +
    1.15 +local uLong adler32_combine_ OF((uLong adler1, uLong adler2, z_off64_t len2));
    1.16 +
    1.17 +#define BASE 65521      /* largest prime smaller than 65536 */
    1.18 +#define NMAX 5552
    1.19 +/* NMAX is the largest n such that 255n(n+1)/2 + (n+1)(BASE-1) <= 2^32-1 */
    1.20 +
    1.21 +#define DO1(buf,i)  {adler += (buf)[i]; sum2 += adler;}
    1.22 +#define DO2(buf,i)  DO1(buf,i); DO1(buf,i+1);
    1.23 +#define DO4(buf,i)  DO2(buf,i); DO2(buf,i+2);
    1.24 +#define DO8(buf,i)  DO4(buf,i); DO4(buf,i+4);
    1.25 +#define DO16(buf)   DO8(buf,0); DO8(buf,8);
    1.26 +
    1.27 +/* use NO_DIVIDE if your processor does not do division in hardware --
    1.28 +   try it both ways to see which is faster */
    1.29 +#ifdef NO_DIVIDE
    1.30 +/* note that this assumes BASE is 65521, where 65536 % 65521 == 15
    1.31 +   (thank you to John Reiser for pointing this out) */
    1.32 +#  define CHOP(a) \
    1.33 +    do { \
    1.34 +        unsigned long tmp = a >> 16; \
    1.35 +        a &= 0xffffUL; \
    1.36 +        a += (tmp << 4) - tmp; \
    1.37 +    } while (0)
    1.38 +#  define MOD28(a) \
    1.39 +    do { \
    1.40 +        CHOP(a); \
    1.41 +        if (a >= BASE) a -= BASE; \
    1.42 +    } while (0)
    1.43 +#  define MOD(a) \
    1.44 +    do { \
    1.45 +        CHOP(a); \
    1.46 +        MOD28(a); \
    1.47 +    } while (0)
    1.48 +#  define MOD63(a) \
    1.49 +    do { /* this assumes a is not negative */ \
    1.50 +        z_off64_t tmp = a >> 32; \
    1.51 +        a &= 0xffffffffL; \
    1.52 +        a += (tmp << 8) - (tmp << 5) + tmp; \
    1.53 +        tmp = a >> 16; \
    1.54 +        a &= 0xffffL; \
    1.55 +        a += (tmp << 4) - tmp; \
    1.56 +        tmp = a >> 16; \
    1.57 +        a &= 0xffffL; \
    1.58 +        a += (tmp << 4) - tmp; \
    1.59 +        if (a >= BASE) a -= BASE; \
    1.60 +    } while (0)
    1.61 +#else
    1.62 +#  define MOD(a) a %= BASE
    1.63 +#  define MOD28(a) a %= BASE
    1.64 +#  define MOD63(a) a %= BASE
    1.65 +#endif
    1.66 +
    1.67 +/* ========================================================================= */
    1.68 +uLong ZEXPORT adler32(adler, buf, len)
    1.69 +    uLong adler;
    1.70 +    const Bytef *buf;
    1.71 +    uInt len;
    1.72 +{
    1.73 +    unsigned long sum2;
    1.74 +    unsigned n;
    1.75 +
    1.76 +    /* split Adler-32 into component sums */
    1.77 +    sum2 = (adler >> 16) & 0xffff;
    1.78 +    adler &= 0xffff;
    1.79 +
    1.80 +    /* in case user likes doing a byte at a time, keep it fast */
    1.81 +    if (len == 1) {
    1.82 +        adler += buf[0];
    1.83 +        if (adler >= BASE)
    1.84 +            adler -= BASE;
    1.85 +        sum2 += adler;
    1.86 +        if (sum2 >= BASE)
    1.87 +            sum2 -= BASE;
    1.88 +        return adler | (sum2 << 16);
    1.89 +    }
    1.90 +
    1.91 +    /* initial Adler-32 value (deferred check for len == 1 speed) */
    1.92 +    if (buf == Z_NULL)
    1.93 +        return 1L;
    1.94 +
    1.95 +    /* in case short lengths are provided, keep it somewhat fast */
    1.96 +    if (len < 16) {
    1.97 +        while (len--) {
    1.98 +            adler += *buf++;
    1.99 +            sum2 += adler;
   1.100 +        }
   1.101 +        if (adler >= BASE)
   1.102 +            adler -= BASE;
   1.103 +        MOD28(sum2);            /* only added so many BASE's */
   1.104 +        return adler | (sum2 << 16);
   1.105 +    }
   1.106 +
   1.107 +    /* do length NMAX blocks -- requires just one modulo operation */
   1.108 +    while (len >= NMAX) {
   1.109 +        len -= NMAX;
   1.110 +        n = NMAX / 16;          /* NMAX is divisible by 16 */
   1.111 +        do {
   1.112 +            DO16(buf);          /* 16 sums unrolled */
   1.113 +            buf += 16;
   1.114 +        } while (--n);
   1.115 +        MOD(adler);
   1.116 +        MOD(sum2);
   1.117 +    }
   1.118 +
   1.119 +    /* do remaining bytes (less than NMAX, still just one modulo) */
   1.120 +    if (len) {                  /* avoid modulos if none remaining */
   1.121 +        while (len >= 16) {
   1.122 +            len -= 16;
   1.123 +            DO16(buf);
   1.124 +            buf += 16;
   1.125 +        }
   1.126 +        while (len--) {
   1.127 +            adler += *buf++;
   1.128 +            sum2 += adler;
   1.129 +        }
   1.130 +        MOD(adler);
   1.131 +        MOD(sum2);
   1.132 +    }
   1.133 +
   1.134 +    /* return recombined sums */
   1.135 +    return adler | (sum2 << 16);
   1.136 +}
   1.137 +
   1.138 +/* ========================================================================= */
   1.139 +local uLong adler32_combine_(adler1, adler2, len2)
   1.140 +    uLong adler1;
   1.141 +    uLong adler2;
   1.142 +    z_off64_t len2;
   1.143 +{
   1.144 +    unsigned long sum1;
   1.145 +    unsigned long sum2;
   1.146 +    unsigned rem;
   1.147 +
   1.148 +    /* for negative len, return invalid adler32 as a clue for debugging */
   1.149 +    if (len2 < 0)
   1.150 +        return 0xffffffffUL;
   1.151 +
   1.152 +    /* the derivation of this formula is left as an exercise for the reader */
   1.153 +    MOD63(len2);                /* assumes len2 >= 0 */
   1.154 +    rem = (unsigned)len2;
   1.155 +    sum1 = adler1 & 0xffff;
   1.156 +    sum2 = rem * sum1;
   1.157 +    MOD(sum2);
   1.158 +    sum1 += (adler2 & 0xffff) + BASE - 1;
   1.159 +    sum2 += ((adler1 >> 16) & 0xffff) + ((adler2 >> 16) & 0xffff) + BASE - rem;
   1.160 +    if (sum1 >= BASE) sum1 -= BASE;
   1.161 +    if (sum1 >= BASE) sum1 -= BASE;
   1.162 +    if (sum2 >= (BASE << 1)) sum2 -= (BASE << 1);
   1.163 +    if (sum2 >= BASE) sum2 -= BASE;
   1.164 +    return sum1 | (sum2 << 16);
   1.165 +}
   1.166 +
   1.167 +/* ========================================================================= */
   1.168 +uLong ZEXPORT adler32_combine(adler1, adler2, len2)
   1.169 +    uLong adler1;
   1.170 +    uLong adler2;
   1.171 +    z_off_t len2;
   1.172 +{
   1.173 +    return adler32_combine_(adler1, adler2, len2);
   1.174 +}
   1.175 +
   1.176 +uLong ZEXPORT adler32_combine64(adler1, adler2, len2)
   1.177 +    uLong adler1;
   1.178 +    uLong adler2;
   1.179 +    z_off64_t len2;
   1.180 +{
   1.181 +    return adler32_combine_(adler1, adler2, len2);
   1.182 +}

mercurial