diff options
| author | SND\edgbla_cp <SND\edgbla_cp@e17a0e51-4ae3-4d35-97c3-1a29b211df97> | 2014-02-15 23:13:33 +0000 |
|---|---|---|
| committer | SND\edgbla_cp <SND\edgbla_cp@e17a0e51-4ae3-4d35-97c3-1a29b211df97> | 2014-02-15 23:13:33 +0000 |
| commit | 02c4d998f4fc2c9ac27fa5db6a35ee68c848b24d (patch) | |
| tree | c7a6df9d6a0bfcb618eca56813d18c9d01f98f68 /win32/zlib/adler32.c | |
| parent | a1d083bf2b5fb01bf0a4a94ad7bd2751f6e4fe34 (diff) | |
| download | pcsxr-02c4d998f4fc2c9ac27fa5db6a35ee68c848b24d.tar.gz | |
Patch 15812 (Cyrez);
git-svn-id: https://pcsxr.svn.codeplex.com/svn/pcsxr@89133 e17a0e51-4ae3-4d35-97c3-1a29b211df97
Diffstat (limited to 'win32/zlib/adler32.c')
| -rwxr-xr-x | win32/zlib/adler32.c | 170 |
1 files changed, 144 insertions, 26 deletions
diff --git a/win32/zlib/adler32.c b/win32/zlib/adler32.c index fae88b65..61f79ab0 100755 --- a/win32/zlib/adler32.c +++ b/win32/zlib/adler32.c @@ -1,48 +1,166 @@ /* adler32.c -- compute the Adler-32 checksum of a data stream - * Copyright (C) 1995-2002 Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h + * Copyright (C) 1995-2011 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h */ /* @(#) $Id$ */ -#include "zlib.h" +#include "zutil.h" -#define BASE 65521L /* largest prime smaller than 65536 */ +#define local static + +// local uLong adler32_combine_ OF((uLong adler1, uLong adler2, z_off64_t len2)); + +#define BASE 65521 /* largest prime smaller than 65536 */ #define NMAX 5552 /* NMAX is the largest n such that 255n(n+1)/2 + (n+1)(BASE-1) <= 2^32-1 */ -#define DO1(buf,i) {s1 += buf[i]; s2 += s1;} +#define DO1(buf,i) {adler += (buf)[i]; sum2 += adler;} #define DO2(buf,i) DO1(buf,i); DO1(buf,i+1); #define DO4(buf,i) DO2(buf,i); DO2(buf,i+2); #define DO8(buf,i) DO4(buf,i); DO4(buf,i+4); #define DO16(buf) DO8(buf,0); DO8(buf,8); +/* use NO_DIVIDE if your processor does not do division in hardware -- + try it both ways to see which is faster */ +#ifdef NO_DIVIDE +/* note that this assumes BASE is 65521, where 65536 % 65521 == 15 + (thank you to John Reiser for pointing this out) */ +# define CHOP(a) \ + do { \ + unsigned long tmp = a >> 16; \ + a &= 0xffffUL; \ + a += (tmp << 4) - tmp; \ + } while (0) +# define MOD28(a) \ + do { \ + CHOP(a); \ + if (a >= BASE) a -= BASE; \ + } while (0) +# define MOD(a) \ + do { \ + CHOP(a); \ + MOD28(a); \ + } while (0) +# define MOD63(a) \ + do { /* this assumes a is not negative */ \ + z_off64_t tmp = a >> 32; \ + a &= 0xffffffffL; \ + a += (tmp << 8) - (tmp << 5) + tmp; \ + tmp = a >> 16; \ + a &= 0xffffL; \ + a += (tmp << 4) - tmp; \ + tmp = a >> 16; \ + a &= 0xffffL; \ + a += (tmp << 4) - tmp; \ + if (a >= BASE) a -= BASE; \ + } while (0) +#else +# define MOD(a) a %= BASE +# define MOD28(a) a %= BASE +# define MOD63(a) a %= BASE +#endif + /* ========================================================================= */ -uLong ZEXPORT adler32(adler, buf, len) - uLong adler; - const Bytef *buf; - uInt len; +uLong ZEXPORT adler32(uLong adler, const Bytef *buf, uInt len) { - unsigned long s1 = adler & 0xffff; - unsigned long s2 = (adler >> 16) & 0xffff; - int k; + unsigned long sum2; + unsigned n; + + /* split Adler-32 into component sums */ + sum2 = (adler >> 16) & 0xffff; + adler &= 0xffff; + + /* in case user likes doing a byte at a time, keep it fast */ + if (len == 1) { + adler += buf[0]; + if (adler >= BASE) + adler -= BASE; + sum2 += adler; + if (sum2 >= BASE) + sum2 -= BASE; + return adler | (sum2 << 16); + } + + /* initial Adler-32 value (deferred check for len == 1 speed) */ + if (buf == Z_NULL) + return 1L; + + /* in case short lengths are provided, keep it somewhat fast */ + if (len < 16) { + while (len--) { + adler += *buf++; + sum2 += adler; + } + if (adler >= BASE) + adler -= BASE; + MOD28(sum2); /* only added so many BASE's */ + return adler | (sum2 << 16); + } - if (buf == Z_NULL) return 1L; + /* do length NMAX blocks -- requires just one modulo operation */ + while (len >= NMAX) { + len -= NMAX; + n = NMAX / 16; /* NMAX is divisible by 16 */ + do { + DO16(buf); /* 16 sums unrolled */ + buf += 16; + } while (--n); + MOD(adler); + MOD(sum2); + } - while (len > 0) { - k = len < NMAX ? len : NMAX; - len -= k; - while (k >= 16) { + /* do remaining bytes (less than NMAX, still just one modulo) */ + if (len) { /* avoid modulos if none remaining */ + while (len >= 16) { + len -= 16; DO16(buf); - buf += 16; - k -= 16; + buf += 16; + } + while (len--) { + adler += *buf++; + sum2 += adler; } - if (k != 0) do { - s1 += *buf++; - s2 += s1; - } while (--k); - s1 %= BASE; - s2 %= BASE; + MOD(adler); + MOD(sum2); } - return (s2 << 16) | s1; + + /* return recombined sums */ + return adler | (sum2 << 16); } + +/* ========================================================================= */ +// local uLong adler32_combine_(uLong adler1, uLong adler2, z_off64_t len2) +// { +// unsigned long sum1; +// unsigned long sum2; +// unsigned rem; + + /* for negative len, return invalid adler32 as a clue for debugging */ +// if (len2 < 0) +// return 0xffffffffUL; + + /* the derivation of this formula is left as an exercise for the reader */ +// MOD63(len2); /* assumes len2 >= 0 */ +// rem = (unsigned)len2; +// sum1 = adler1 & 0xffff; +// sum2 = rem * sum1; +// MOD(sum2); +// sum2 += ((adler1 >> 16) & 0xffff) + ((adler2 >> 16) & 0xffff) + BASE - rem; +// if (sum1 >= BASE) sum1 -= BASE; +// if (sum1 >= BASE) sum1 -= BASE; +// if (sum2 >= (BASE << 1)) sum2 -= (BASE << 1); +// if (sum2 >= BASE) sum2 -= BASE; +// return sum1 | (sum2 << 16); +//} + +/* ========================================================================= */ +// uLong ZEXPORT adler32_combine(uLong adler1, uLong adler2, z_off_t len2) +// { +// return adler32_combine_(adler1, adler2, len2); +// } + +// uLong ZEXPORT adler32_combine64(uLong adler1, uLong adler2, z_off64_t len2) +// { +// return adler32_combine_(adler1, adler2, len2); +// } |
