crc32.c (muscle7.61) | : | crc32.c (muscle7.62) | ||
---|---|---|---|---|
/* crc32.c -- compute the CRC-32 of a data stream | /* crc32.c -- compute the CRC-32 of a data stream | |||
* Copyright (C) 1995-2006, 2010, 2011, 2012 Mark Adler | * Copyright (C) 1995-2006, 2010, 2011, 2012, 2016 Mark Adler | |||
* For conditions of distribution and use, see copyright notice in zlib.h | * For conditions of distribution and use, see copyright notice in zlib.h | |||
* | * | |||
* Thanks to Rodney Brown <rbrown64@csc.com.au> for his contribution of faster | * Thanks to Rodney Brown <rbrown64@csc.com.au> for his contribution of faster | |||
* CRC methods: exclusive-oring 32 bits of data at a time, and pre-computing | * CRC methods: exclusive-oring 32 bits of data at a time, and pre-computing | |||
* tables for updating the shift register in one step with three exclusive-ors | * tables for updating the shift register in one step with three exclusive-ors | |||
* instead of four steps with four exclusive-ors. This results in about a | * instead of four steps with four exclusive-ors. This results in about a | |||
* factor of two increase in speed on a Power PC G4 (PPC7455) using gcc -O3. | * factor of two increase in speed on a Power PC G4 (PPC7455) using gcc -O3. | |||
*/ | */ | |||
/* @(#) $Id$ */ | /* @(#) $Id$ */ | |||
skipping to change at line 33 | skipping to change at line 33 | |||
#ifdef MAKECRCH | #ifdef MAKECRCH | |||
# include <stdio.h> | # include <stdio.h> | |||
# ifndef DYNAMIC_CRC_TABLE | # ifndef DYNAMIC_CRC_TABLE | |||
# define DYNAMIC_CRC_TABLE | # define DYNAMIC_CRC_TABLE | |||
# endif /* !DYNAMIC_CRC_TABLE */ | # endif /* !DYNAMIC_CRC_TABLE */ | |||
#endif /* MAKECRCH */ | #endif /* MAKECRCH */ | |||
#include "zutil.h" /* for STDC and FAR definitions */ | #include "zutil.h" /* for STDC and FAR definitions */ | |||
#define local static | ||||
/* Definitions for doing the crc four data bytes at a time. */ | /* Definitions for doing the crc four data bytes at a time. */ | |||
#if !defined(NOBYFOUR) && defined(Z_U4) | #if !defined(NOBYFOUR) && defined(Z_U4) | |||
# define BYFOUR | # define BYFOUR | |||
#endif | #endif | |||
#ifdef BYFOUR | #ifdef BYFOUR | |||
local unsigned long crc32_little OF((unsigned long, | local unsigned long crc32_little OF((unsigned long, | |||
const unsigned char FAR *, unsigned)); | const unsigned char FAR *, z_size_t)); | |||
local unsigned long crc32_big OF((unsigned long, | local unsigned long crc32_big OF((unsigned long, | |||
const unsigned char FAR *, unsigned)); | const unsigned char FAR *, z_size_t)); | |||
# define TBLS 8 | # define TBLS 8 | |||
#else | #else | |||
# define TBLS 1 | # define TBLS 1 | |||
#endif /* BYFOUR */ | #endif /* BYFOUR */ | |||
/* Local functions for crc concatenation */ | /* Local functions for crc concatenation */ | |||
local unsigned long gf2_matrix_times OF((unsigned long *mat, | local unsigned long gf2_matrix_times OF((unsigned long *mat, | |||
unsigned long vec)); | unsigned long vec)); | |||
local void gf2_matrix_square OF((unsigned long *square, unsigned long *mat)); | local void gf2_matrix_square OF((unsigned long *square, unsigned long *mat)); | |||
local uLong crc32_combine_ OF((uLong crc1, uLong crc2, z_off64_t len2)); | local uLong crc32_combine_ OF((uLong crc1, uLong crc2, z_off64_t len2)); | |||
skipping to change at line 203 | skipping to change at line 201 | |||
make_crc_table(); | make_crc_table(); | |||
#endif /* DYNAMIC_CRC_TABLE */ | #endif /* DYNAMIC_CRC_TABLE */ | |||
return (const z_crc_t FAR *)crc_table; | return (const z_crc_t FAR *)crc_table; | |||
} | } | |||
/* ========================================================================= */ | /* ========================================================================= */ | |||
#define DO1 crc = crc_table[0][((int)crc ^ (*buf++)) & 0xff] ^ (crc >> 8) | #define DO1 crc = crc_table[0][((int)crc ^ (*buf++)) & 0xff] ^ (crc >> 8) | |||
#define DO8 DO1; DO1; DO1; DO1; DO1; DO1; DO1; DO1 | #define DO8 DO1; DO1; DO1; DO1; DO1; DO1; DO1; DO1 | |||
/* ========================================================================= */ | /* ========================================================================= */ | |||
unsigned long ZEXPORT crc32(crc, buf, len) | unsigned long ZEXPORT crc32_z(crc, buf, len) | |||
unsigned long crc; | unsigned long crc; | |||
const unsigned char FAR *buf; | const unsigned char FAR *buf; | |||
uInt len; | z_size_t len; | |||
{ | { | |||
if (buf == Z_NULL) return 0UL; | if (buf == Z_NULL) return 0UL; | |||
#ifdef DYNAMIC_CRC_TABLE | #ifdef DYNAMIC_CRC_TABLE | |||
if (crc_table_empty) | if (crc_table_empty) | |||
make_crc_table(); | make_crc_table(); | |||
#endif /* DYNAMIC_CRC_TABLE */ | #endif /* DYNAMIC_CRC_TABLE */ | |||
#ifdef BYFOUR | #ifdef BYFOUR | |||
if (sizeof(void *) == sizeof(ptrdiff_t)) { | if (sizeof(void *) == sizeof(ptrdiff_t)) { | |||
skipping to change at line 237 | skipping to change at line 235 | |||
while (len >= 8) { | while (len >= 8) { | |||
DO8; | DO8; | |||
len -= 8; | len -= 8; | |||
} | } | |||
if (len) do { | if (len) do { | |||
DO1; | DO1; | |||
} while (--len); | } while (--len); | |||
return crc ^ 0xffffffffUL; | return crc ^ 0xffffffffUL; | |||
} | } | |||
/* ========================================================================= */ | ||||
unsigned long ZEXPORT crc32(crc, buf, len) | ||||
unsigned long crc; | ||||
const unsigned char FAR *buf; | ||||
uInt len; | ||||
{ | ||||
return crc32_z(crc, buf, len); | ||||
} | ||||
#ifdef BYFOUR | #ifdef BYFOUR | |||
/* | ||||
This BYFOUR code accesses the passed unsigned char * buffer with a 32-bit | ||||
integer pointer type. This violates the strict aliasing rule, where a | ||||
compiler can assume, for optimization purposes, that two pointers to | ||||
fundamentally different types won't ever point to the same memory. This can | ||||
manifest as a problem only if one of the pointers is written to. This code | ||||
only reads from those pointers. So long as this code remains isolated in | ||||
this compilation unit, there won't be a problem. For this reason, this code | ||||
should not be copied and pasted into a compilation unit in which other code | ||||
writes to the buffer that is passed to these routines. | ||||
*/ | ||||
/* ========================================================================= */ | /* ========================================================================= */ | |||
#define DOLIT4 c ^= *buf4++; \ | #define DOLIT4 c ^= *buf4++; \ | |||
c = crc_table[3][c & 0xff] ^ crc_table[2][(c >> 8) & 0xff] ^ \ | c = crc_table[3][c & 0xff] ^ crc_table[2][(c >> 8) & 0xff] ^ \ | |||
crc_table[1][(c >> 16) & 0xff] ^ crc_table[0][c >> 24] | crc_table[1][(c >> 16) & 0xff] ^ crc_table[0][c >> 24] | |||
#define DOLIT32 DOLIT4; DOLIT4; DOLIT4; DOLIT4; DOLIT4; DOLIT4; DOLIT4; DOLIT4 | #define DOLIT32 DOLIT4; DOLIT4; DOLIT4; DOLIT4; DOLIT4; DOLIT4; DOLIT4; DOLIT4 | |||
/* ========================================================================= */ | /* ========================================================================= */ | |||
local unsigned long crc32_little(crc, buf, len) | local unsigned long crc32_little(crc, buf, len) | |||
unsigned long crc; | unsigned long crc; | |||
const unsigned char FAR *buf; | const unsigned char FAR *buf; | |||
unsigned len; | z_size_t len; | |||
{ | { | |||
register z_crc_t c; | register z_crc_t c; | |||
register const z_crc_t FAR *buf4; | register const z_crc_t FAR *buf4; | |||
c = (z_crc_t)crc; | c = (z_crc_t)crc; | |||
c = ~c; | c = ~c; | |||
while (len && ((ptrdiff_t)buf & 3)) { | while (len && ((ptrdiff_t)buf & 3)) { | |||
c = crc_table[0][(c ^ *buf++) & 0xff] ^ (c >> 8); | c = crc_table[0][(c ^ *buf++) & 0xff] ^ (c >> 8); | |||
len--; | len--; | |||
} | } | |||
skipping to change at line 280 | skipping to change at line 299 | |||
buf = (const unsigned char FAR *)buf4; | buf = (const unsigned char FAR *)buf4; | |||
if (len) do { | if (len) do { | |||
c = crc_table[0][(c ^ *buf++) & 0xff] ^ (c >> 8); | c = crc_table[0][(c ^ *buf++) & 0xff] ^ (c >> 8); | |||
} while (--len); | } while (--len); | |||
c = ~c; | c = ~c; | |||
return (unsigned long)c; | return (unsigned long)c; | |||
} | } | |||
/* ========================================================================= */ | /* ========================================================================= */ | |||
#define DOBIG4 c ^= *++buf4; \ | #define DOBIG4 c ^= *buf4++; \ | |||
c = crc_table[4][c & 0xff] ^ crc_table[5][(c >> 8) & 0xff] ^ \ | c = crc_table[4][c & 0xff] ^ crc_table[5][(c >> 8) & 0xff] ^ \ | |||
crc_table[6][(c >> 16) & 0xff] ^ crc_table[7][c >> 24] | crc_table[6][(c >> 16) & 0xff] ^ crc_table[7][c >> 24] | |||
#define DOBIG32 DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4 | #define DOBIG32 DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4 | |||
/* ========================================================================= */ | /* ========================================================================= */ | |||
local unsigned long crc32_big(crc, buf, len) | local unsigned long crc32_big(crc, buf, len) | |||
unsigned long crc; | unsigned long crc; | |||
const unsigned char FAR *buf; | const unsigned char FAR *buf; | |||
unsigned len; | z_size_t len; | |||
{ | { | |||
register z_crc_t c; | register z_crc_t c; | |||
register const z_crc_t FAR *buf4; | register const z_crc_t FAR *buf4; | |||
c = ZSWAP32((z_crc_t)crc); | c = ZSWAP32((z_crc_t)crc); | |||
c = ~c; | c = ~c; | |||
while (len && ((ptrdiff_t)buf & 3)) { | while (len && ((ptrdiff_t)buf & 3)) { | |||
c = crc_table[4][(c >> 24) ^ *buf++] ^ (c << 8); | c = crc_table[4][(c >> 24) ^ *buf++] ^ (c << 8); | |||
len--; | len--; | |||
} | } | |||
buf4 = (const z_crc_t FAR *)(const void FAR *)buf; | buf4 = (const z_crc_t FAR *)(const void FAR *)buf; | |||
buf4--; | ||||
while (len >= 32) { | while (len >= 32) { | |||
DOBIG32; | DOBIG32; | |||
len -= 32; | len -= 32; | |||
} | } | |||
while (len >= 4) { | while (len >= 4) { | |||
DOBIG4; | DOBIG4; | |||
len -= 4; | len -= 4; | |||
} | } | |||
buf4++; | ||||
buf = (const unsigned char FAR *)buf4; | buf = (const unsigned char FAR *)buf4; | |||
if (len) do { | if (len) do { | |||
c = crc_table[4][(c >> 24) ^ *buf++] ^ (c << 8); | c = crc_table[4][(c >> 24) ^ *buf++] ^ (c << 8); | |||
} while (--len); | } while (--len); | |||
c = ~c; | c = ~c; | |||
return (unsigned long)(ZSWAP32(c)); | return (unsigned long)(ZSWAP32(c)); | |||
} | } | |||
#endif /* BYFOUR */ | #endif /* BYFOUR */ | |||
End of changes. 13 change blocks. | ||||
12 lines changed or deleted | 29 lines changed or added |