adler32.c revision 199767f8919635c4928607450d9e0abb932109ce
199767f8919635c4928607450d9e0abb932109ceToomas Soome/* adler32.c -- compute the Adler-32 checksum of a data stream
199767f8919635c4928607450d9e0abb932109ceToomas Soome * Copyright (C) 1995-2011 Mark Adler
199767f8919635c4928607450d9e0abb932109ceToomas Soome * For conditions of distribution and use, see copyright notice in zlib.h
199767f8919635c4928607450d9e0abb932109ceToomas Soome/* @(#) $Id$ */
199767f8919635c4928607450d9e0abb932109ceToomas Soome#define local static
199767f8919635c4928607450d9e0abb932109ceToomas Soomelocal uLong adler32_combine_ OF((uLong adler1, uLong adler2, z_off64_t len2));
199767f8919635c4928607450d9e0abb932109ceToomas Soome#define BASE 65521 /* largest prime smaller than 65536 */
199767f8919635c4928607450d9e0abb932109ceToomas Soome/* NMAX is the largest n such that 255n(n+1)/2 + (n+1)(BASE-1) <= 2^32-1 */
199767f8919635c4928607450d9e0abb932109ceToomas Soome#define DO1(buf,i) {adler += (buf)[i]; sum2 += adler;}
199767f8919635c4928607450d9e0abb932109ceToomas Soome/* use NO_DIVIDE if your processor does not do division in hardware --
199767f8919635c4928607450d9e0abb932109ceToomas Soome try it both ways to see which is faster */
199767f8919635c4928607450d9e0abb932109ceToomas Soome/* note that this assumes BASE is 65521, where 65536 % 65521 == 15
199767f8919635c4928607450d9e0abb932109ceToomas Soome (thank you to John Reiser for pointing this out) */
199767f8919635c4928607450d9e0abb932109ceToomas Soome# define CHOP(a) \
199767f8919635c4928607450d9e0abb932109ceToomas Soome a &= 0xffffUL; \
199767f8919635c4928607450d9e0abb932109ceToomas Soome# define MOD(a) \
199767f8919635c4928607450d9e0abb932109ceToomas Soome do { /* this assumes a is not negative */ \
199767f8919635c4928607450d9e0abb932109ceToomas Soome a &= 0xffffffffL; \
199767f8919635c4928607450d9e0abb932109ceToomas Soome a &= 0xffffL; \
199767f8919635c4928607450d9e0abb932109ceToomas Soome a &= 0xffffL; \
199767f8919635c4928607450d9e0abb932109ceToomas Soome/* ========================================================================= */
199767f8919635c4928607450d9e0abb932109ceToomas Soome unsigned long sum2;
199767f8919635c4928607450d9e0abb932109ceToomas Soome /* split Adler-32 into component sums */
199767f8919635c4928607450d9e0abb932109ceToomas Soome /* in case user likes doing a byte at a time, keep it fast */
199767f8919635c4928607450d9e0abb932109ceToomas Soome /* initial Adler-32 value (deferred check for len == 1 speed) */
199767f8919635c4928607450d9e0abb932109ceToomas Soome /* in case short lengths are provided, keep it somewhat fast */
199767f8919635c4928607450d9e0abb932109ceToomas Soome /* do length NMAX blocks -- requires just one modulo operation */
199767f8919635c4928607450d9e0abb932109ceToomas Soome } while (--n);
199767f8919635c4928607450d9e0abb932109ceToomas Soome /* do remaining bytes (less than NMAX, still just one modulo) */
199767f8919635c4928607450d9e0abb932109ceToomas Soome if (len) { /* avoid modulos if none remaining */
199767f8919635c4928607450d9e0abb932109ceToomas Soome /* return recombined sums */
199767f8919635c4928607450d9e0abb932109ceToomas Soome/* ========================================================================= */
199767f8919635c4928607450d9e0abb932109ceToomas Soomelocal uLong adler32_combine_(adler1, adler2, len2)
199767f8919635c4928607450d9e0abb932109ceToomas Soome unsigned long sum1;
199767f8919635c4928607450d9e0abb932109ceToomas Soome unsigned long sum2;
199767f8919635c4928607450d9e0abb932109ceToomas Soome /* for negative len, return invalid adler32 as a clue for debugging */
199767f8919635c4928607450d9e0abb932109ceToomas Soome return 0xffffffffUL;
199767f8919635c4928607450d9e0abb932109ceToomas Soome /* the derivation of this formula is left as an exercise for the reader */
199767f8919635c4928607450d9e0abb932109ceToomas Soome sum2 += ((adler1 >> 16) & 0xffff) + ((adler2 >> 16) & 0xffff) + BASE - rem;
199767f8919635c4928607450d9e0abb932109ceToomas Soome/* ========================================================================= */
199767f8919635c4928607450d9e0abb932109ceToomas SoomeuLong ZEXPORT adler32_combine(adler1, adler2, len2)