18b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* crc32.c -- compute the CRC-32 of a data stream
217b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner * Copyright (C) 1995-2006, 2010, 2011, 2012 Mark Adler
38b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * For conditions of distribution and use, see copyright notice in zlib.h
48b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project *
58b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * Thanks to Rodney Brown <rbrown64@csc.com.au> for his contribution of faster
68b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * CRC methods: exclusive-oring 32 bits of data at a time, and pre-computing
78b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * tables for updating the shift register in one step with three exclusive-ors
88b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * instead of four steps with four exclusive-ors.  This results in about a
98b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * factor of two increase in speed on a Power PC G4 (PPC7455) using gcc -O3.
108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project */
118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* @(#) $Id$ */
138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/*
158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project  Note on the use of DYNAMIC_CRC_TABLE: there is no mutex or semaphore
168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project  protection on the static variables used to control the first-use generation
178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project  of the crc tables.  Therefore, if you #define DYNAMIC_CRC_TABLE, you should
188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project  first call get_crc_table() to initialize the tables before allowing more than
198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project  one thread to use crc32().
2017b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner
2117b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner  DYNAMIC_CRC_TABLE and MAKECRCH can be #defined to write out crc32.h.
228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project */
238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#ifdef MAKECRCH
258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#  include <stdio.h>
268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#  ifndef DYNAMIC_CRC_TABLE
278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#    define DYNAMIC_CRC_TABLE
288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#  endif /* !DYNAMIC_CRC_TABLE */
298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif /* MAKECRCH */
308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#include "zutil.h"      /* for STDC and FAR definitions */
328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define local static
348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* Definitions for doing the crc four data bytes at a time. */
3617b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner#if !defined(NOBYFOUR) && defined(Z_U4)
3717b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner#  define BYFOUR
3817b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner#endif
398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#ifdef BYFOUR
408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   local unsigned long crc32_little OF((unsigned long,
418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                        const unsigned char FAR *, unsigned));
428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   local unsigned long crc32_big OF((unsigned long,
438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                        const unsigned char FAR *, unsigned));
448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#  define TBLS 8
458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#else
468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#  define TBLS 1
478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif /* BYFOUR */
488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* Local functions for crc concatenation */
508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectlocal unsigned long gf2_matrix_times OF((unsigned long *mat,
518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                                         unsigned long vec));
528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectlocal void gf2_matrix_square OF((unsigned long *square, unsigned long *mat));
5317b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turnerlocal uLong crc32_combine_ OF((uLong crc1, uLong crc2, z_off64_t len2));
5417b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner
558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#ifdef DYNAMIC_CRC_TABLE
578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectlocal volatile int crc_table_empty = 1;
5917b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turnerlocal z_crc_t FAR crc_table[TBLS][256];
608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectlocal void make_crc_table OF((void));
618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#ifdef MAKECRCH
6217b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner   local void write_table OF((FILE *, const z_crc_t FAR *));
638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif /* MAKECRCH */
648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/*
658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project  Generate tables for a byte-wise 32-bit CRC calculation on the polynomial:
668b23a6c7e1aee255004dd19098d4c2462b61b849The 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.
678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project  Polynomials over GF(2) are represented in binary, one bit per coefficient,
698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project  with the lowest powers in the most significant bit.  Then adding polynomials
708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project  is just exclusive-or, and multiplying a polynomial by x is a right shift by
718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project  one.  If we call the above polynomial p, and represent a byte as the
728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project  polynomial q, also with the lowest power in the most significant bit (so the
738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project  byte 0xb1 is the polynomial x^7+x^3+x+1), then the CRC is (q*x^32) mod p,
748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project  where a mod b means the remainder after dividing a by b.
758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project  This calculation is done using the shift-register method of multiplying and
778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project  taking the remainder.  The register is initialized to zero, and for each
788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project  incoming bit, x^32 is added mod p to the register if the bit is a one (where
798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project  x^32 mod p is p+x^32 = x^26+...+1), and the register is multiplied mod p by
808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project  x (which is shifting right by one and adding x^32 mod p if the bit shifted
818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project  out is a one).  We start with the highest power (least significant bit) of
828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project  q and repeat for all eight bits of q.
838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project  The first table is simply the CRC of all possible eight bit values.  This is
858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project  all the information needed to generate CRCs on data a byte at a time for all
868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project  combinations of CRC register values and incoming bytes.  The remaining tables
878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project  allow for word-at-a-time CRC calculation for both big-endian and little-
888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project  endian machines, where a word is four bytes.
898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project*/
908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectlocal void make_crc_table()
918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
9217b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner    z_crc_t c;
938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int n, k;
9417b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner    z_crc_t poly;                       /* polynomial exclusive-or pattern */
958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    /* terms of polynomial defining this crc (except x^32): */
968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    static volatile int first = 1;      /* flag to limit concurrent making */
978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    static const unsigned char p[] = {0,1,2,4,5,7,8,10,11,12,16,22,23,26};
988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    /* See if another task is already doing this (not thread-safe, but better
1008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project       than nothing -- significantly reduces duration of vulnerability in
1018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project       case the advice about DYNAMIC_CRC_TABLE is ignored) */
1028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (first) {
1038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        first = 0;
1048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        /* make exclusive-or pattern from polynomial (0xedb88320UL) */
10617b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner        poly = 0;
10717b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner        for (n = 0; n < (int)(sizeof(p)/sizeof(unsigned char)); n++)
10817b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner            poly |= (z_crc_t)1 << (31 - p[n]);
1098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        /* generate a crc for every 8-bit value */
1118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        for (n = 0; n < 256; n++) {
11217b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner            c = (z_crc_t)n;
1138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            for (k = 0; k < 8; k++)
1148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                c = c & 1 ? poly ^ (c >> 1) : c >> 1;
1158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            crc_table[0][n] = c;
1168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
1178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#ifdef BYFOUR
1198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        /* generate crc for each value followed by one, two, and three zeros,
1208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project           and then the byte reversal of those as well as the first table */
1218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        for (n = 0; n < 256; n++) {
1228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            c = crc_table[0][n];
12317b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner            crc_table[4][n] = ZSWAP32(c);
1248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            for (k = 1; k < 4; k++) {
1258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                c = crc_table[0][c & 0xff] ^ (c >> 8);
1268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                crc_table[k][n] = c;
12717b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner                crc_table[k + 4][n] = ZSWAP32(c);
1288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            }
1298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
1308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif /* BYFOUR */
1318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        crc_table_empty = 0;
1338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
1348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    else {      /* not first */
1358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        /* wait for the other guy to finish (not efficient, but rare) */
1368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        while (crc_table_empty)
1378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            ;
1388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
1398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#ifdef MAKECRCH
1418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    /* write out CRC tables to crc32.h */
1428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    {
1438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        FILE *out;
1448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        out = fopen("crc32.h", "w");
1468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if (out == NULL) return;
1478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        fprintf(out, "/* crc32.h -- tables for rapid CRC calculation\n");
1488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        fprintf(out, " * Generated automatically by crc32.c\n */\n\n");
14917b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner        fprintf(out, "local const z_crc_t FAR ");
1508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        fprintf(out, "crc_table[TBLS][256] =\n{\n  {\n");
1518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        write_table(out, crc_table[0]);
1528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#  ifdef BYFOUR
1538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        fprintf(out, "#ifdef BYFOUR\n");
1548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        for (k = 1; k < 8; k++) {
1558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            fprintf(out, "  },\n  {\n");
1568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            write_table(out, crc_table[k]);
1578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
1588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        fprintf(out, "#endif\n");
1598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#  endif /* BYFOUR */
1608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        fprintf(out, "  }\n};\n");
1618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        fclose(out);
1628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
1638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif /* MAKECRCH */
1648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
1658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#ifdef MAKECRCH
1678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectlocal void write_table(out, table)
1688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    FILE *out;
16917b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner    const z_crc_t FAR *table;
1708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
1718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int n;
1728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    for (n = 0; n < 256; n++)
17417b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner        fprintf(out, "%s0x%08lxUL%s", n % 5 ? "" : "    ",
17517b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner                (unsigned long)(table[n]),
1768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                n == 255 ? "\n" : (n % 5 == 4 ? ",\n" : ", "));
1778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
1788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif /* MAKECRCH */
1798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#else /* !DYNAMIC_CRC_TABLE */
1818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* ========================================================================
1828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * Tables of CRC-32s of all single-byte values, made by make_crc_table().
1838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project */
1848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#include "crc32.h"
1858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif /* DYNAMIC_CRC_TABLE */
1868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* =========================================================================
1888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * This function can be used by asm versions of crc32()
1898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project */
19017b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turnerconst z_crc_t FAR * ZEXPORT get_crc_table()
1918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
1928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#ifdef DYNAMIC_CRC_TABLE
1938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (crc_table_empty)
1948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        make_crc_table();
1958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif /* DYNAMIC_CRC_TABLE */
19617b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner    return (const z_crc_t FAR *)crc_table;
1978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
1988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* ========================================================================= */
2008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define DO1 crc = crc_table[0][((int)crc ^ (*buf++)) & 0xff] ^ (crc >> 8)
2018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define DO8 DO1; DO1; DO1; DO1; DO1; DO1; DO1; DO1
2028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
2038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* ========================================================================= */
2048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectunsigned long ZEXPORT crc32(crc, buf, len)
2058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    unsigned long crc;
2068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    const unsigned char FAR *buf;
20717b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner    uInt len;
2088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
2098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (buf == Z_NULL) return 0UL;
2108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
2118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#ifdef DYNAMIC_CRC_TABLE
2128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (crc_table_empty)
2138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        make_crc_table();
2148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif /* DYNAMIC_CRC_TABLE */
2158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
2168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#ifdef BYFOUR
2178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (sizeof(void *) == sizeof(ptrdiff_t)) {
21817b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner        z_crc_t endian;
2198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
2208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        endian = 1;
2218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if (*((unsigned char *)(&endian)))
2228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            return crc32_little(crc, buf, len);
2238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        else
2248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            return crc32_big(crc, buf, len);
2258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
2268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif /* BYFOUR */
2278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    crc = crc ^ 0xffffffffUL;
2288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    while (len >= 8) {
2298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        DO8;
2308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        len -= 8;
2318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
2328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (len) do {
2338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        DO1;
2348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    } while (--len);
2358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return crc ^ 0xffffffffUL;
2368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
2378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
2388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#ifdef BYFOUR
2398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
2408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* ========================================================================= */
2418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define DOLIT4 c ^= *buf4++; \
2428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        c = crc_table[3][c & 0xff] ^ crc_table[2][(c >> 8) & 0xff] ^ \
2438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            crc_table[1][(c >> 16) & 0xff] ^ crc_table[0][c >> 24]
2448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define DOLIT32 DOLIT4; DOLIT4; DOLIT4; DOLIT4; DOLIT4; DOLIT4; DOLIT4; DOLIT4
2458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
2468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* ========================================================================= */
2478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectlocal unsigned long crc32_little(crc, buf, len)
2488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    unsigned long crc;
2498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    const unsigned char FAR *buf;
2508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    unsigned len;
2518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
25217b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner    register z_crc_t c;
25317b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner    register const z_crc_t FAR *buf4;
2548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
25517b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner    c = (z_crc_t)crc;
2568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    c = ~c;
2578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    while (len && ((ptrdiff_t)buf & 3)) {
2588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        c = crc_table[0][(c ^ *buf++) & 0xff] ^ (c >> 8);
2598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        len--;
2608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
2618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
26217b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner    buf4 = (const z_crc_t FAR *)(const void FAR *)buf;
2638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    while (len >= 32) {
2648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        DOLIT32;
2658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        len -= 32;
2668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
2678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    while (len >= 4) {
2688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        DOLIT4;
2698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        len -= 4;
2708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
2718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    buf = (const unsigned char FAR *)buf4;
2728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
2738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (len) do {
2748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        c = crc_table[0][(c ^ *buf++) & 0xff] ^ (c >> 8);
2758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    } while (--len);
2768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    c = ~c;
2778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return (unsigned long)c;
2788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
2798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
2808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* ========================================================================= */
2818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define DOBIG4 c ^= *++buf4; \
2828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        c = crc_table[4][c & 0xff] ^ crc_table[5][(c >> 8) & 0xff] ^ \
2838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            crc_table[6][(c >> 16) & 0xff] ^ crc_table[7][c >> 24]
2848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define DOBIG32 DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4
2858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
2868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* ========================================================================= */
2878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectlocal unsigned long crc32_big(crc, buf, len)
2888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    unsigned long crc;
2898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    const unsigned char FAR *buf;
2908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    unsigned len;
2918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
29217b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner    register z_crc_t c;
29317b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner    register const z_crc_t FAR *buf4;
2948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
29517b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner    c = ZSWAP32((z_crc_t)crc);
2968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    c = ~c;
2978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    while (len && ((ptrdiff_t)buf & 3)) {
2988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        c = crc_table[4][(c >> 24) ^ *buf++] ^ (c << 8);
2998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        len--;
3008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
3018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
30217b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner    buf4 = (const z_crc_t FAR *)(const void FAR *)buf;
3038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    buf4--;
3048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    while (len >= 32) {
3058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        DOBIG32;
3068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        len -= 32;
3078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
3088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    while (len >= 4) {
3098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        DOBIG4;
3108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        len -= 4;
3118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
3128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    buf4++;
3138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    buf = (const unsigned char FAR *)buf4;
3148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
3158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (len) do {
3168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        c = crc_table[4][(c >> 24) ^ *buf++] ^ (c << 8);
3178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    } while (--len);
3188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    c = ~c;
31917b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner    return (unsigned long)(ZSWAP32(c));
3208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
3218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
3228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif /* BYFOUR */
3238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
3248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define GF2_DIM 32      /* dimension of GF(2) vectors (length of CRC) */
3258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
3268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* ========================================================================= */
3278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectlocal unsigned long gf2_matrix_times(mat, vec)
3288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    unsigned long *mat;
3298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    unsigned long vec;
3308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
3318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    unsigned long sum;
3328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
3338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    sum = 0;
3348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    while (vec) {
3358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if (vec & 1)
3368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            sum ^= *mat;
3378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        vec >>= 1;
3388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        mat++;
3398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
3408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return sum;
3418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
3428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
3438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* ========================================================================= */
3448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectlocal void gf2_matrix_square(square, mat)
3458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    unsigned long *square;
3468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    unsigned long *mat;
3478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
3488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int n;
3498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
3508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    for (n = 0; n < GF2_DIM; n++)
3518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        square[n] = gf2_matrix_times(mat, mat[n]);
3528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
3538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
3548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* ========================================================================= */
35517b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turnerlocal uLong crc32_combine_(crc1, crc2, len2)
3568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    uLong crc1;
3578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    uLong crc2;
35817b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner    z_off64_t len2;
3598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
3608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int n;
3618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    unsigned long row;
3628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    unsigned long even[GF2_DIM];    /* even-power-of-two zeros operator */
3638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    unsigned long odd[GF2_DIM];     /* odd-power-of-two zeros operator */
3648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
36517b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner    /* degenerate case (also disallow negative lengths) */
36617b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner    if (len2 <= 0)
3678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return crc1;
3688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
3698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    /* put operator for one zero bit in odd */
37017b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner    odd[0] = 0xedb88320UL;          /* CRC-32 polynomial */
3718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    row = 1;
3728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    for (n = 1; n < GF2_DIM; n++) {
3738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        odd[n] = row;
3748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        row <<= 1;
3758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
3768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
3778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    /* put operator for two zero bits in even */
3788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    gf2_matrix_square(even, odd);
3798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
3808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    /* put operator for four zero bits in odd */
3818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    gf2_matrix_square(odd, even);
3828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
3838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    /* apply len2 zeros to crc1 (first square will put the operator for one
3848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project       zero byte, eight zero bits, in even) */
3858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    do {
3868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        /* apply zeros operator for this bit of len2 */
3878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        gf2_matrix_square(even, odd);
3888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if (len2 & 1)
3898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            crc1 = gf2_matrix_times(even, crc1);
3908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        len2 >>= 1;
3918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
3928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        /* if no more bits set, then done */
3938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if (len2 == 0)
3948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            break;
3958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
3968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        /* another iteration of the loop with odd and even swapped */
3978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        gf2_matrix_square(odd, even);
3988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if (len2 & 1)
3998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            crc1 = gf2_matrix_times(odd, crc1);
4008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        len2 >>= 1;
4018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
4028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        /* if no more bits set, then done */
4038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    } while (len2 != 0);
4048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
4058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    /* return combined crc */
4068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    crc1 ^= crc2;
4078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return crc1;
4088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
40917b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner
41017b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner/* ========================================================================= */
41117b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' TurneruLong ZEXPORT crc32_combine(crc1, crc2, len2)
41217b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner    uLong crc1;
41317b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner    uLong crc2;
41417b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner    z_off_t len2;
41517b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner{
41617b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner    return crc32_combine_(crc1, crc2, len2);
41717b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner}
41817b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner
41917b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' TurneruLong ZEXPORT crc32_combine64(crc1, crc2, len2)
42017b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner    uLong crc1;
42117b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner    uLong crc2;
42217b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner    z_off64_t len2;
42317b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner{
42417b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner    return crc32_combine_(crc1, crc2, len2);
42517b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner}
426