1/*
2 * Copyright (c) 2008 Apple Inc. All rights reserved.
3 *
4 * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
5 *
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. The rights granted to you under the License
10 * may not be used to create, or enable the creation or redistribution of,
11 * unlawful or unlicensed copies of an Apple operating system, or to
12 * circumvent, violate, or enable the circumvention or violation of, any
13 * terms of an Apple operating system software license agreement.
14 *
15 * Please obtain a copy of the License at
16 * http://www.opensource.apple.com/apsl/ and read it before using this file.
17 *
18 * The Original Code and all software distributed under the License are
19 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
20 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
21 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
22 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
23 * Please see the License for the specific language governing rights and
24 * limitations under the License.
25 *
26 * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
27 */
28/* adler32.c -- compute the Adler-32 checksum of a data stream
29 * Copyright (C) 1995-2004 Mark Adler
30 * For conditions of distribution and use, see copyright notice in zlib.h
31 */
32
33/* @(#) $Id$ */
34
35
36#define ZLIB_INTERNAL
37#if KERNEL
38    #include <libkern/zlib.h>
39#else
40    #include "zlib.h"
41#endif /* KERNEL */
42
43#if defined __x86_64__ || defined __i386__ || defined _ARM_ARCH_6
44#include <stdint.h> // For uintptr_t.
45    extern uLong adler32_vec(uLong adler, uLong sum2, const Bytef *buf, uInt len);
46#endif
47
48#define BASE 65521UL    /* largest prime smaller than 65536 */
49#define NMAX 5552
50/* NMAX is the largest n such that 255n(n+1)/2 + (n+1)(BASE-1) <= 2^32-1 */
51
52#define DO1(buf,i)  {adler += (buf)[i]; sum2 += adler;}
53#define DO2(buf,i)  DO1(buf,i); DO1(buf,i+1);
54#define DO4(buf,i)  DO2(buf,i); DO2(buf,i+2);
55#define DO8(buf,i)  DO4(buf,i); DO4(buf,i+4);
56#define DO16(buf)   DO8(buf,0); DO8(buf,8);
57
58/* use NO_DIVIDE if your processor does not do division in hardware */
59#ifdef NO_DIVIDE
60#  define MOD(a) \
61    do { \
62        if (a >= (BASE << 16)) a -= (BASE << 16); \
63        if (a >= (BASE << 15)) a -= (BASE << 15); \
64        if (a >= (BASE << 14)) a -= (BASE << 14); \
65        if (a >= (BASE << 13)) a -= (BASE << 13); \
66        if (a >= (BASE << 12)) a -= (BASE << 12); \
67        if (a >= (BASE << 11)) a -= (BASE << 11); \
68        if (a >= (BASE << 10)) a -= (BASE << 10); \
69        if (a >= (BASE << 9)) a -= (BASE << 9); \
70        if (a >= (BASE << 8)) a -= (BASE << 8); \
71        if (a >= (BASE << 7)) a -= (BASE << 7); \
72        if (a >= (BASE << 6)) a -= (BASE << 6); \
73        if (a >= (BASE << 5)) a -= (BASE << 5); \
74        if (a >= (BASE << 4)) a -= (BASE << 4); \
75        if (a >= (BASE << 3)) a -= (BASE << 3); \
76        if (a >= (BASE << 2)) a -= (BASE << 2); \
77        if (a >= (BASE << 1)) a -= (BASE << 1); \
78        if (a >= BASE) a -= BASE; \
79    } while (0)
80#  define MOD4(a) \
81    do { \
82        if (a >= (BASE << 4)) a -= (BASE << 4); \
83        if (a >= (BASE << 3)) a -= (BASE << 3); \
84        if (a >= (BASE << 2)) a -= (BASE << 2); \
85        if (a >= (BASE << 1)) a -= (BASE << 1); \
86        if (a >= BASE) a -= BASE; \
87    } while (0)
88#else
89#  define MOD(a) a %= BASE
90#  define MOD4(a) a %= BASE
91#endif
92
93/* ========================================================================= */
94uLong ZEXPORT adler32(adler, buf, len)
95    uLong adler;
96    const Bytef *buf;
97    uInt len;
98{
99    unsigned long sum2;
100    unsigned n;
101
102    /* split Adler-32 into component sums */
103    sum2 = (adler >> 16) & 0xffff;
104    adler &= 0xffff;
105
106    /* in case user likes doing a byte at a time, keep it fast */
107    if (len == 1) {
108        adler += buf[0];
109        if (adler >= BASE)
110            adler -= BASE;
111        sum2 += adler;
112        if (sum2 >= BASE)
113            sum2 -= BASE;
114        return adler | (sum2 << 16);
115    }
116
117    /* initial Adler-32 value (deferred check for len == 1 speed) */
118    if (buf == Z_NULL)
119        return 1L;
120
121    /* in case short lengths are provided, keep it somewhat fast */
122    if (len < 16) {
123        while (len--) {
124            adler += *buf++;
125            sum2 += adler;
126        }
127        if (adler >= BASE)
128            adler -= BASE;
129        MOD4(sum2);             /* only added so many BASE's */
130        return adler | (sum2 << 16);
131    }
132
133#if defined __x86_64__ || defined __i386__ || defined _ARM_ARCH_6
134
135	if (len>=32000) {	/* use vector code only if len is sufficiently large to compensate registers save/restore */
136	/* align buf to 16-byte boundary */
137    while (((uintptr_t)buf)&15) { /* not on a 16-byte boundary */
138        len--;
139        adler += *buf++;
140        sum2 += adler;
141        if (adler >= BASE) adler -= BASE;
142        MOD4(sum2);             /* only added so many BASE's */
143    }
144
145    return adler32_vec(adler, sum2, buf, len);      // x86_64 or i386 (up to SSE3) or armv6 or up
146	}
147
148#endif	// defined __x86_64__ || defined __i386__ || defined _ARM_ARCH_6
149
150    /* do length NMAX blocks -- requires just one modulo operation */
151    while (len >= NMAX) {
152        len -= NMAX;
153        n = NMAX / 16;          /* NMAX is divisible by 16 */
154        do {
155            DO16(buf);          /* 16 sums unrolled */
156            buf += 16;
157        } while (--n);
158        MOD(adler);
159        MOD(sum2);
160    }
161
162    /* do remaining bytes (less than NMAX, still just one modulo) */
163    if (len) {                  /* avoid modulos if none remaining */
164        while (len >= 16) {
165            len -= 16;
166            DO16(buf);
167            buf += 16;
168        }
169        while (len--) {
170            adler += *buf++;
171            sum2 += adler;
172        }
173        MOD(adler);
174        MOD(sum2);
175    }
176
177    /* return recombined sums */
178    return adler | (sum2 << 16);
179}
180
181/* ========================================================================= */
182uLong ZEXPORT adler32_combine(adler1, adler2, len2)
183    uLong adler1;
184    uLong adler2;
185    z_off_t len2;
186{
187    unsigned long sum1;
188    unsigned long sum2;
189    unsigned rem;
190
191    /* the derivation of this formula is left as an exercise for the reader */
192    rem = (unsigned)(len2 % BASE);
193    sum1 = adler1 & 0xffff;
194    sum2 = rem * sum1;
195    MOD(sum2);
196    sum1 += (adler2 & 0xffff) + BASE - 1;
197    sum2 += ((adler1 >> 16) & 0xffff) + ((adler2 >> 16) & 0xffff) + BASE - rem;
198    if (sum1 > BASE) sum1 -= BASE;
199    if (sum1 > BASE) sum1 -= BASE;
200    if (sum2 > (BASE << 1)) sum2 -= (BASE << 1);
201    if (sum2 > BASE) sum2 -= BASE;
202    return sum1 | (sum2 << 16);
203}
204