ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

adler32.c
Go to the documentation of this file.
00001 /* adler32.c -- compute the Adler-32 checksum of a data stream
00002  * Copyright (C) 1995-2007 Mark Adler
00003  * For conditions of distribution and use, see copyright notice in zlib.h
00004  */
00005 
00006 /* @(#) $Id: adler32.c 47691 2010-06-08 01:37:58Z tkreuzer $ */
00007 
00008 #include "zutil.h"
00009 
00010 #define local static
00011 
00012 local uLong adler32_combine_(uLong adler1, uLong adler2, z_off64_t len2);
00013 
00014 #define BASE 65521UL    /* largest prime smaller than 65536 */
00015 #define NMAX 5552
00016 /* NMAX is the largest n such that 255n(n+1)/2 + (n+1)(BASE-1) <= 2^32-1 */
00017 
00018 #define DO1(buf,i)  {adler += (buf)[i]; sum2 += adler;}
00019 #define DO2(buf,i)  DO1(buf,i); DO1(buf,i+1);
00020 #define DO4(buf,i)  DO2(buf,i); DO2(buf,i+2);
00021 #define DO8(buf,i)  DO4(buf,i); DO4(buf,i+4);
00022 #define DO16(buf)   DO8(buf,0); DO8(buf,8);
00023 
00024 /* use NO_DIVIDE if your processor does not do division in hardware */
00025 #ifdef NO_DIVIDE
00026 #  define MOD(a) \
00027     do { \
00028         if (a >= (BASE << 16)) a -= (BASE << 16); \
00029         if (a >= (BASE << 15)) a -= (BASE << 15); \
00030         if (a >= (BASE << 14)) a -= (BASE << 14); \
00031         if (a >= (BASE << 13)) a -= (BASE << 13); \
00032         if (a >= (BASE << 12)) a -= (BASE << 12); \
00033         if (a >= (BASE << 11)) a -= (BASE << 11); \
00034         if (a >= (BASE << 10)) a -= (BASE << 10); \
00035         if (a >= (BASE << 9)) a -= (BASE << 9); \
00036         if (a >= (BASE << 8)) a -= (BASE << 8); \
00037         if (a >= (BASE << 7)) a -= (BASE << 7); \
00038         if (a >= (BASE << 6)) a -= (BASE << 6); \
00039         if (a >= (BASE << 5)) a -= (BASE << 5); \
00040         if (a >= (BASE << 4)) a -= (BASE << 4); \
00041         if (a >= (BASE << 3)) a -= (BASE << 3); \
00042         if (a >= (BASE << 2)) a -= (BASE << 2); \
00043         if (a >= (BASE << 1)) a -= (BASE << 1); \
00044         if (a >= BASE) a -= BASE; \
00045     } while (0)
00046 #  define MOD4(a) \
00047     do { \
00048         if (a >= (BASE << 4)) a -= (BASE << 4); \
00049         if (a >= (BASE << 3)) a -= (BASE << 3); \
00050         if (a >= (BASE << 2)) a -= (BASE << 2); \
00051         if (a >= (BASE << 1)) a -= (BASE << 1); \
00052         if (a >= BASE) a -= BASE; \
00053     } while (0)
00054 #else
00055 #  define MOD(a) a %= BASE
00056 #  define MOD4(a) a %= BASE
00057 #endif
00058 
00059 /* ========================================================================= */
00060 uLong ZEXPORT adler32(adler, buf, len)
00061     uLong adler;
00062     const Bytef *buf;
00063     uInt len;
00064 {
00065     unsigned long sum2;
00066     unsigned n;
00067 
00068     /* split Adler-32 into component sums */
00069     sum2 = (adler >> 16) & 0xffff;
00070     adler &= 0xffff;
00071 
00072     /* in case user likes doing a byte at a time, keep it fast */
00073     if (len == 1) {
00074         adler += buf[0];
00075         if (adler >= BASE)
00076             adler -= BASE;
00077         sum2 += adler;
00078         if (sum2 >= BASE)
00079             sum2 -= BASE;
00080         return adler | (sum2 << 16);
00081     }
00082 
00083     /* initial Adler-32 value (deferred check for len == 1 speed) */
00084     if (buf == Z_NULL)
00085         return 1L;
00086 
00087     /* in case short lengths are provided, keep it somewhat fast */
00088     if (len < 16) {
00089         while (len--) {
00090             adler += *buf++;
00091             sum2 += adler;
00092         }
00093         if (adler >= BASE)
00094             adler -= BASE;
00095         MOD4(sum2);             /* only added so many BASE's */
00096         return adler | (sum2 << 16);
00097     }
00098 
00099     /* do length NMAX blocks -- requires just one modulo operation */
00100     while (len >= NMAX) {
00101         len -= NMAX;
00102         n = NMAX / 16;          /* NMAX is divisible by 16 */
00103         do {
00104             DO16(buf);          /* 16 sums unrolled */
00105             buf += 16;
00106         } while (--n);
00107         MOD(adler);
00108         MOD(sum2);
00109     }
00110 
00111     /* do remaining bytes (less than NMAX, still just one modulo) */
00112     if (len) {                  /* avoid modulos if none remaining */
00113         while (len >= 16) {
00114             len -= 16;
00115             DO16(buf);
00116             buf += 16;
00117         }
00118         while (len--) {
00119             adler += *buf++;
00120             sum2 += adler;
00121         }
00122         MOD(adler);
00123         MOD(sum2);
00124     }
00125 
00126     /* return recombined sums */
00127     return adler | (sum2 << 16);
00128 }
00129 
00130 /* ========================================================================= */
00131 local uLong adler32_combine_(adler1, adler2, len2)
00132     uLong adler1;
00133     uLong adler2;
00134     z_off64_t len2;
00135 {
00136     unsigned long sum1;
00137     unsigned long sum2;
00138     unsigned rem;
00139 
00140     /* the derivation of this formula is left as an exercise for the reader */
00141     rem = (unsigned)(len2 % BASE);
00142     sum1 = adler1 & 0xffff;
00143     sum2 = rem * sum1;
00144     MOD(sum2);
00145     sum1 += (adler2 & 0xffff) + BASE - 1;
00146     sum2 += ((adler1 >> 16) & 0xffff) + ((adler2 >> 16) & 0xffff) + BASE - rem;
00147     if (sum1 >= BASE) sum1 -= BASE;
00148     if (sum1 >= BASE) sum1 -= BASE;
00149     if (sum2 >= (BASE << 1)) sum2 -= (BASE << 1);
00150     if (sum2 >= BASE) sum2 -= BASE;
00151     return sum1 | (sum2 << 16);
00152 }
00153 
00154 /* ========================================================================= */
00155 uLong ZEXPORT adler32_combine(adler1, adler2, len2)
00156     uLong adler1;
00157     uLong adler2;
00158     z_off_t len2;
00159 {
00160     return adler32_combine_(adler1, adler2, len2);
00161 }
00162 
00163 uLong ZEXPORT adler32_combine64(adler1, adler2, len2)
00164     uLong adler1;
00165     uLong adler2;
00166     z_off64_t len2;
00167 {
00168     return adler32_combine_(adler1, adler2, len2);
00169 }

Generated on Sat May 26 2012 04:32:44 for ReactOS by doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.