19e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project/* crc32.c -- compute the CRC-32 of a data stream
209eb358bbbb9aad3fe48dd3368c8a7a481cbda1cElliott Hughes * Copyright (C) 1995-2006, 2010, 2011, 2012 Mark Adler
39e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project * For conditions of distribution and use, see copyright notice in zlib.h
49e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project *
59e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project * Thanks to Rodney Brown <rbrown64@csc.com.au> for his contribution of faster
69e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project * CRC methods: exclusive-oring 32 bits of data at a time, and pre-computing
79e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project * tables for updating the shift register in one step with three exclusive-ors
89e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project * instead of four steps with four exclusive-ors.  This results in about a
99e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project * factor of two increase in speed on a Power PC G4 (PPC7455) using gcc -O3.
109e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project */
119e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
129e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project/* @(#) $Id$ */
139e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
149e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project/*
159e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project  Note on the use of DYNAMIC_CRC_TABLE: there is no mutex or semaphore
169e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project  protection on the static variables used to control the first-use generation
179e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project  of the crc tables.  Therefore, if you #define DYNAMIC_CRC_TABLE, you should
189e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project  first call get_crc_table() to initialize the tables before allowing more than
199e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project  one thread to use crc32().
20ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes
21ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes  DYNAMIC_CRC_TABLE and MAKECRCH can be #defined to write out crc32.h.
229e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project */
239e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
249e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project#ifdef MAKECRCH
259e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project#  include <stdio.h>
269e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project#  ifndef DYNAMIC_CRC_TABLE
279e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project#    define DYNAMIC_CRC_TABLE
289e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project#  endif /* !DYNAMIC_CRC_TABLE */
299e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project#endif /* MAKECRCH */
309e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
319e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project#include "zutil.h"      /* for STDC and FAR definitions */
329e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
339e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project#define local static
349e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
359e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project/* Definitions for doing the crc four data bytes at a time. */
3609eb358bbbb9aad3fe48dd3368c8a7a481cbda1cElliott Hughes#if !defined(NOBYFOUR) && defined(Z_U4)
3709eb358bbbb9aad3fe48dd3368c8a7a481cbda1cElliott Hughes#  define BYFOUR
3809eb358bbbb9aad3fe48dd3368c8a7a481cbda1cElliott Hughes#endif
399e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project#ifdef BYFOUR
409e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project   local unsigned long crc32_little OF((unsigned long,
419e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project                        const unsigned char FAR *, unsigned));
429e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project   local unsigned long crc32_big OF((unsigned long,
439e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project                        const unsigned char FAR *, unsigned));
449e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project#  define TBLS 8
459e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project#else
469e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project#  define TBLS 1
479e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project#endif /* BYFOUR */
489e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
499e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project/* Local functions for crc concatenation */
509e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Projectlocal unsigned long gf2_matrix_times OF((unsigned long *mat,
519e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project                                         unsigned long vec));
529e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Projectlocal void gf2_matrix_square OF((unsigned long *square, unsigned long *mat));
53ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hugheslocal uLong crc32_combine_ OF((uLong crc1, uLong crc2, z_off64_t len2));
54381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes
559e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
569e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project#ifdef DYNAMIC_CRC_TABLE
579e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
589e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Projectlocal volatile int crc_table_empty = 1;
5909eb358bbbb9aad3fe48dd3368c8a7a481cbda1cElliott Hugheslocal z_crc_t FAR crc_table[TBLS][256];
609e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Projectlocal void make_crc_table OF((void));
619e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project#ifdef MAKECRCH
6209eb358bbbb9aad3fe48dd3368c8a7a481cbda1cElliott Hughes   local void write_table OF((FILE *, const z_crc_t FAR *));
639e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project#endif /* MAKECRCH */
649e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project/*
659e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project  Generate tables for a byte-wise 32-bit CRC calculation on the polynomial:
669e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project  x^32+x^26+x^23+x^22+x^16+x^12+x^11+x^10+x^8+x^7+x^5+x^4+x^2+x+1.
679e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
689e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project  Polynomials over GF(2) are represented in binary, one bit per coefficient,
699e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project  with the lowest powers in the most significant bit.  Then adding polynomials
709e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project  is just exclusive-or, and multiplying a polynomial by x is a right shift by
719e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project  one.  If we call the above polynomial p, and represent a byte as the
729e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project  polynomial q, also with the lowest power in the most significant bit (so the
739e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project  byte 0xb1 is the polynomial x^7+x^3+x+1), then the CRC is (q*x^32) mod p,
749e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project  where a mod b means the remainder after dividing a by b.
759e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
769e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project  This calculation is done using the shift-register method of multiplying and
779e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project  taking the remainder.  The register is initialized to zero, and for each
789e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project  incoming bit, x^32 is added mod p to the register if the bit is a one (where
799e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project  x^32 mod p is p+x^32 = x^26+...+1), and the register is multiplied mod p by
809e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project  x (which is shifting right by one and adding x^32 mod p if the bit shifted
819e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project  out is a one).  We start with the highest power (least significant bit) of
829e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project  q and repeat for all eight bits of q.
839e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
849e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project  The first table is simply the CRC of all possible eight bit values.  This is
859e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project  all the information needed to generate CRCs on data a byte at a time for all
869e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project  combinations of CRC register values and incoming bytes.  The remaining tables
879e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project  allow for word-at-a-time CRC calculation for both big-endian and little-
889e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project  endian machines, where a word is four bytes.
899e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project*/
909e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Projectlocal void make_crc_table()
919e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project{
9209eb358bbbb9aad3fe48dd3368c8a7a481cbda1cElliott Hughes    z_crc_t c;
939e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    int n, k;
9409eb358bbbb9aad3fe48dd3368c8a7a481cbda1cElliott Hughes    z_crc_t poly;                       /* polynomial exclusive-or pattern */
959e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    /* terms of polynomial defining this crc (except x^32): */
969e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    static volatile int first = 1;      /* flag to limit concurrent making */
979e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    static const unsigned char p[] = {0,1,2,4,5,7,8,10,11,12,16,22,23,26};
989e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
999e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    /* See if another task is already doing this (not thread-safe, but better
1009e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project       than nothing -- significantly reduces duration of vulnerability in
1019e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project       case the advice about DYNAMIC_CRC_TABLE is ignored) */
1029e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    if (first) {
1039e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        first = 0;
1049e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
1059e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        /* make exclusive-or pattern from polynomial (0xedb88320UL) */
106ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes        poly = 0;
107ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes        for (n = 0; n < (int)(sizeof(p)/sizeof(unsigned char)); n++)
10809eb358bbbb9aad3fe48dd3368c8a7a481cbda1cElliott Hughes            poly |= (z_crc_t)1 << (31 - p[n]);
1099e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
1109e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        /* generate a crc for every 8-bit value */
1119e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        for (n = 0; n < 256; n++) {
11209eb358bbbb9aad3fe48dd3368c8a7a481cbda1cElliott Hughes            c = (z_crc_t)n;
1139e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project            for (k = 0; k < 8; k++)
1149e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project                c = c & 1 ? poly ^ (c >> 1) : c >> 1;
1159e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project            crc_table[0][n] = c;
1169e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        }
1179e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
1189e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project#ifdef BYFOUR
1199e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        /* generate crc for each value followed by one, two, and three zeros,
1209e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project           and then the byte reversal of those as well as the first table */
1219e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        for (n = 0; n < 256; n++) {
1229e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project            c = crc_table[0][n];
12309eb358bbbb9aad3fe48dd3368c8a7a481cbda1cElliott Hughes            crc_table[4][n] = ZSWAP32(c);
1249e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project            for (k = 1; k < 4; k++) {
1259e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project                c = crc_table[0][c & 0xff] ^ (c >> 8);
1269e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project                crc_table[k][n] = c;
12709eb358bbbb9aad3fe48dd3368c8a7a481cbda1cElliott Hughes                crc_table[k + 4][n] = ZSWAP32(c);
1289e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project            }
1299e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        }
1309e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project#endif /* BYFOUR */
1319e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
1329e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        crc_table_empty = 0;
1339e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    }
1349e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    else {      /* not first */
1359e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        /* wait for the other guy to finish (not efficient, but rare) */
1369e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        while (crc_table_empty)
1379e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project            ;
1389e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    }
1399e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
1409e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project#ifdef MAKECRCH
1419e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    /* write out CRC tables to crc32.h */
1429e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    {
1439e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        FILE *out;
1449e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
1459e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        out = fopen("crc32.h", "w");
1469e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        if (out == NULL) return;
1479e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        fprintf(out, "/* crc32.h -- tables for rapid CRC calculation\n");
1489e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        fprintf(out, " * Generated automatically by crc32.c\n */\n\n");
14909eb358bbbb9aad3fe48dd3368c8a7a481cbda1cElliott Hughes        fprintf(out, "local const z_crc_t FAR ");
1509e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        fprintf(out, "crc_table[TBLS][256] =\n{\n  {\n");
1519e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        write_table(out, crc_table[0]);
1529e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project#  ifdef BYFOUR
1539e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        fprintf(out, "#ifdef BYFOUR\n");
1549e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        for (k = 1; k < 8; k++) {
1559e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project            fprintf(out, "  },\n  {\n");
1569e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project            write_table(out, crc_table[k]);
1579e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        }
1589e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        fprintf(out, "#endif\n");
1599e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project#  endif /* BYFOUR */
1609e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        fprintf(out, "  }\n};\n");
1619e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        fclose(out);
1629e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    }
1639e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project#endif /* MAKECRCH */
1649e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project}
1659e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
1669e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project#ifdef MAKECRCH
1679e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Projectlocal void write_table(out, table)
1689e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    FILE *out;
16909eb358bbbb9aad3fe48dd3368c8a7a481cbda1cElliott Hughes    const z_crc_t FAR *table;
1709e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project{
1719e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    int n;
1729e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
1739e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    for (n = 0; n < 256; n++)
174ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes        fprintf(out, "%s0x%08lxUL%s", n % 5 ? "" : "    ",
175ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes                (unsigned long)(table[n]),
1769e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project                n == 255 ? "\n" : (n % 5 == 4 ? ",\n" : ", "));
1779e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project}
1789e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project#endif /* MAKECRCH */
1799e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
1809e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project#else /* !DYNAMIC_CRC_TABLE */
1819e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project/* ========================================================================
1829e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project * Tables of CRC-32s of all single-byte values, made by make_crc_table().
1839e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project */
1849e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project#include "crc32.h"
1859e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project#endif /* DYNAMIC_CRC_TABLE */
1869e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
1879e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project/* =========================================================================
1889e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project * This function can be used by asm versions of crc32()
1899e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project */
19009eb358bbbb9aad3fe48dd3368c8a7a481cbda1cElliott Hughesconst z_crc_t FAR * ZEXPORT get_crc_table()
1919e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project{
1929e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project#ifdef DYNAMIC_CRC_TABLE
1939e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    if (crc_table_empty)
1949e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        make_crc_table();
1959e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project#endif /* DYNAMIC_CRC_TABLE */
19609eb358bbbb9aad3fe48dd3368c8a7a481cbda1cElliott Hughes    return (const z_crc_t FAR *)crc_table;
1979e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project}
1989e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
1999e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project/* ========================================================================= */
2009e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project#define DO1 crc = crc_table[0][((int)crc ^ (*buf++)) & 0xff] ^ (crc >> 8)
2019e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project#define DO8 DO1; DO1; DO1; DO1; DO1; DO1; DO1; DO1
2029e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
2039e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project/* ========================================================================= */
2049e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Projectunsigned long ZEXPORT crc32(crc, buf, len)
2059e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    unsigned long crc;
2069e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    const unsigned char FAR *buf;
207381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    uInt len;
2089e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project{
2099e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    if (buf == Z_NULL) return 0UL;
2109e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
2119e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project#ifdef DYNAMIC_CRC_TABLE
2129e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    if (crc_table_empty)
2139e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        make_crc_table();
2149e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project#endif /* DYNAMIC_CRC_TABLE */
2159e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
2169e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project#ifdef BYFOUR
2179e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    if (sizeof(void *) == sizeof(ptrdiff_t)) {
21809eb358bbbb9aad3fe48dd3368c8a7a481cbda1cElliott Hughes        z_crc_t endian;
2199e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
2209e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        endian = 1;
2219e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        if (*((unsigned char *)(&endian)))
2229e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project            return crc32_little(crc, buf, len);
2239e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        else
2249e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project            return crc32_big(crc, buf, len);
2259e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    }
2269e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project#endif /* BYFOUR */
2279e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    crc = crc ^ 0xffffffffUL;
2289e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    while (len >= 8) {
2299e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        DO8;
2309e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        len -= 8;
2319e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    }
2329e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    if (len) do {
2339e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        DO1;
2349e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    } while (--len);
2359e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    return crc ^ 0xffffffffUL;
2369e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project}
2379e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
2389e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project#ifdef BYFOUR
2399e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
2409e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project/* ========================================================================= */
2419e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project#define DOLIT4 c ^= *buf4++; \
2429e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        c = crc_table[3][c & 0xff] ^ crc_table[2][(c >> 8) & 0xff] ^ \
2439e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project            crc_table[1][(c >> 16) & 0xff] ^ crc_table[0][c >> 24]
2449e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project#define DOLIT32 DOLIT4; DOLIT4; DOLIT4; DOLIT4; DOLIT4; DOLIT4; DOLIT4; DOLIT4
2459e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
2469e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project/* ========================================================================= */
2479e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Projectlocal unsigned long crc32_little(crc, buf, len)
2489e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    unsigned long crc;
2499e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    const unsigned char FAR *buf;
2509e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    unsigned len;
2519e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project{
25209eb358bbbb9aad3fe48dd3368c8a7a481cbda1cElliott Hughes    register z_crc_t c;
25309eb358bbbb9aad3fe48dd3368c8a7a481cbda1cElliott Hughes    register const z_crc_t FAR *buf4;
2549e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
25509eb358bbbb9aad3fe48dd3368c8a7a481cbda1cElliott Hughes    c = (z_crc_t)crc;
2569e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    c = ~c;
2579e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    while (len && ((ptrdiff_t)buf & 3)) {
2589e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        c = crc_table[0][(c ^ *buf++) & 0xff] ^ (c >> 8);
2599e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        len--;
2609e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    }
2619e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
26209eb358bbbb9aad3fe48dd3368c8a7a481cbda1cElliott Hughes    buf4 = (const z_crc_t FAR *)(const void FAR *)buf;
2639e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    while (len >= 32) {
2649e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        DOLIT32;
2659e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        len -= 32;
2669e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    }
2679e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    while (len >= 4) {
2689e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        DOLIT4;
2699e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        len -= 4;
2709e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    }
2719e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    buf = (const unsigned char FAR *)buf4;
2729e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
2739e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    if (len) do {
2749e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        c = crc_table[0][(c ^ *buf++) & 0xff] ^ (c >> 8);
2759e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    } while (--len);
2769e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    c = ~c;
2779e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    return (unsigned long)c;
2789e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project}
2799e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
2809e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project/* ========================================================================= */
2819e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project#define DOBIG4 c ^= *++buf4; \
2829e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        c = crc_table[4][c & 0xff] ^ crc_table[5][(c >> 8) & 0xff] ^ \
2839e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project            crc_table[6][(c >> 16) & 0xff] ^ crc_table[7][c >> 24]
2849e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project#define DOBIG32 DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4
2859e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
2869e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project/* ========================================================================= */
2879e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Projectlocal unsigned long crc32_big(crc, buf, len)
2889e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    unsigned long crc;
2899e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    const unsigned char FAR *buf;
2909e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    unsigned len;
2919e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project{
29209eb358bbbb9aad3fe48dd3368c8a7a481cbda1cElliott Hughes    register z_crc_t c;
29309eb358bbbb9aad3fe48dd3368c8a7a481cbda1cElliott Hughes    register const z_crc_t FAR *buf4;
2949e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
29509eb358bbbb9aad3fe48dd3368c8a7a481cbda1cElliott Hughes    c = ZSWAP32((z_crc_t)crc);
2969e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    c = ~c;
2979e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    while (len && ((ptrdiff_t)buf & 3)) {
2989e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        c = crc_table[4][(c >> 24) ^ *buf++] ^ (c << 8);
2999e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        len--;
3009e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    }
3019e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
30209eb358bbbb9aad3fe48dd3368c8a7a481cbda1cElliott Hughes    buf4 = (const z_crc_t FAR *)(const void FAR *)buf;
3039e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    buf4--;
3049e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    while (len >= 32) {
3059e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        DOBIG32;
3069e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        len -= 32;
3079e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    }
3089e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    while (len >= 4) {
3099e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        DOBIG4;
3109e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        len -= 4;
3119e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    }
3129e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    buf4++;
3139e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    buf = (const unsigned char FAR *)buf4;
3149e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
3159e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    if (len) do {
3169e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        c = crc_table[4][(c >> 24) ^ *buf++] ^ (c << 8);
3179e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    } while (--len);
3189e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    c = ~c;
31909eb358bbbb9aad3fe48dd3368c8a7a481cbda1cElliott Hughes    return (unsigned long)(ZSWAP32(c));
3209e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project}
3219e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
3229e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project#endif /* BYFOUR */
3239e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
3249e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project#define GF2_DIM 32      /* dimension of GF(2) vectors (length of CRC) */
3259e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
3269e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project/* ========================================================================= */
3279e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Projectlocal unsigned long gf2_matrix_times(mat, vec)
3289e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    unsigned long *mat;
3299e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    unsigned long vec;
3309e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project{
3319e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    unsigned long sum;
3329e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
3339e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    sum = 0;
3349e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    while (vec) {
3359e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        if (vec & 1)
3369e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project            sum ^= *mat;
3379e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        vec >>= 1;
3389e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        mat++;
3399e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    }
3409e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    return sum;
3419e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project}
3429e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
3439e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project/* ========================================================================= */
3449e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Projectlocal void gf2_matrix_square(square, mat)
3459e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    unsigned long *square;
3469e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    unsigned long *mat;
3479e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project{
3489e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    int n;
3499e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
3509e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    for (n = 0; n < GF2_DIM; n++)
3519e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        square[n] = gf2_matrix_times(mat, mat[n]);
3529e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project}
3539e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
3549e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project/* ========================================================================= */
355381716e9396b55b1adb8235b020c37344f60ab07Elliott Hugheslocal uLong crc32_combine_(crc1, crc2, len2)
3569e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    uLong crc1;
3579e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    uLong crc2;
358381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    z_off64_t len2;
3599e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project{
3609e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    int n;
3619e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    unsigned long row;
3629e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    unsigned long even[GF2_DIM];    /* even-power-of-two zeros operator */
3639e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    unsigned long odd[GF2_DIM];     /* odd-power-of-two zeros operator */
3649e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
365381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    /* degenerate case (also disallow negative lengths) */
366381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    if (len2 <= 0)
3679e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        return crc1;
3689e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
3699e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    /* put operator for one zero bit in odd */
370381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    odd[0] = 0xedb88320UL;          /* CRC-32 polynomial */
3719e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    row = 1;
3729e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    for (n = 1; n < GF2_DIM; n++) {
3739e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        odd[n] = row;
3749e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        row <<= 1;
3759e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    }
3769e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
3779e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    /* put operator for two zero bits in even */
3789e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    gf2_matrix_square(even, odd);
3799e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
3809e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    /* put operator for four zero bits in odd */
3819e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    gf2_matrix_square(odd, even);
3829e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
3839e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    /* apply len2 zeros to crc1 (first square will put the operator for one
3849e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project       zero byte, eight zero bits, in even) */
3859e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    do {
3869e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        /* apply zeros operator for this bit of len2 */
3879e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        gf2_matrix_square(even, odd);
3889e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        if (len2 & 1)
3899e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project            crc1 = gf2_matrix_times(even, crc1);
3909e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        len2 >>= 1;
3919e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
3929e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        /* if no more bits set, then done */
3939e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        if (len2 == 0)
3949e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project            break;
3959e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
3969e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        /* another iteration of the loop with odd and even swapped */
3979e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        gf2_matrix_square(odd, even);
3989e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        if (len2 & 1)
3999e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project            crc1 = gf2_matrix_times(odd, crc1);
4009e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        len2 >>= 1;
4019e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
4029e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        /* if no more bits set, then done */
4039e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    } while (len2 != 0);
4049e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
4059e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    /* return combined crc */
4069e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    crc1 ^= crc2;
4079e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    return crc1;
4089e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project}
409381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes
410381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes/* ========================================================================= */
411381716e9396b55b1adb8235b020c37344f60ab07Elliott HughesuLong ZEXPORT crc32_combine(crc1, crc2, len2)
412381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    uLong crc1;
413381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    uLong crc2;
414381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    z_off_t len2;
415381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes{
416381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    return crc32_combine_(crc1, crc2, len2);
417381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes}
418381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes
419381716e9396b55b1adb8235b020c37344f60ab07Elliott HughesuLong ZEXPORT crc32_combine64(crc1, crc2, len2)
420381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    uLong crc1;
421381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    uLong crc2;
422381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    z_off64_t len2;
423381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes{
424381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    return crc32_combine_(crc1, crc2, len2);
425381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes}
426