raze/source/build/src/crc32.cpp
terminx b0a4b6a1ee Convert loops using unsigned integers as iterators to use regular signed ints instead
https://kristerw.blogspot.com/2016/02/how-undefined-signed-overflow-enables.html

Doing this as cleanly as possible involved demoting several function parameters concerning object sizes and counts from size_t to int--I'm fine with this change as the functions in question are not actually capable of handling input with sizes larger than what can be stored in a signed 32-bit integer, making the use of size_t here misleading at best.

git-svn-id: https://svn.eduke32.com/eduke32@7673 1a8010ca-5511-0410-912e-c29ae57300e0

# Conflicts:
#	source/build/src/polymost.cpp
#	source/build/src/texcache.cpp
#	source/build/src/tilepacker.cpp
2019-09-20 10:04:24 +02:00

102 lines
3.2 KiB
C++

// based on http://create.stephan-brumme.com/crc32/Crc32.cpp, zlib license
#include "compat.h"
#include "crc32.h"
uint32_t Bcrc32(const void* data, int length, uint32_t crc)
{
const uint32_t* current = (const uint32_t*) data;
uint8_t const * currentChar;
crc = ~crc;
#ifdef BITNESS64
// process eight bytes at once (Slicing-by-8)
while (length >= 8)
{
#if B_BIG_ENDIAN != 0
uint32_t one = *current ^ B_SWAP32(crc);
uint32_t two = *(current+1);
crc = crc32table[0][two & 0xFF] ^
crc32table[1][(two>> 8) & 0xFF] ^
crc32table[2][(two>>16) & 0xFF] ^
crc32table[3][(two>>24) & 0xFF] ^
crc32table[4][one & 0xFF] ^
crc32table[5][(one>> 8) & 0xFF] ^
crc32table[6][(one>>16) & 0xFF] ^
crc32table[7][(one>>24) & 0xFF];
#else
uint32_t one = *current ^ crc;
uint32_t two = *(current+1);
crc = crc32table[0][(two>>24) & 0xFF] ^
crc32table[1][(two>>16) & 0xFF] ^
crc32table[2][(two>> 8) & 0xFF] ^
crc32table[3][two & 0xFF] ^
crc32table[4][(one>>24) & 0xFF] ^
crc32table[5][(one>>16) & 0xFF] ^
crc32table[6][(one>> 8) & 0xFF] ^
crc32table[7][one & 0xFF];
#endif
current += 2;
length -= 8;
}
#else
// process four bytes at once (Slicing-by-4)
while (length >= 4)
{
#if B_BIG_ENDIAN != 0
uint32_t one = *current++ ^ B_SWAP32(crc);
crc = crc32table[0][one & 0xFF] ^
crc32table[1][(one>> 8) & 0xFF] ^
crc32table[2][(one>>16) & 0xFF] ^
crc32table[3][(one>>24) & 0xFF];
#else
uint32_t one = *current++ ^ crc;
crc = crc32table[0][(one>>24) & 0xFF] ^
crc32table[1][(one>>16) & 0xFF] ^
crc32table[2][(one>> 8) & 0xFF] ^
crc32table[3][one & 0xFF];
#endif
length -= 4;
}
#endif
currentChar = (uint8_t const *) current;
// remaining 1 to 7 bytes (standard algorithm)
while (length-- > 0)
crc = (crc >> 8) ^ crc32table[0][(crc & 0xFF) ^ *currentChar++];
return ~crc;
}
#ifdef BITNESS64
uint32_t crc32table[8][256];
#else
uint32_t crc32table[4][256];
#endif
void initcrc32table(void)
{
int i;
for (i = 0; i <= 0xFF; i++)
{
uint32_t j, crc = i;
for (j = 0; j < 8; j++)
crc = (crc >> 1) ^ ((crc & 1) * POLY);
crc32table[0][i] = crc;
}
for (i = 0; i <= 0xFF; i++)
{
crc32table[1][i] = (crc32table[0][i] >> 8) ^ crc32table[0][crc32table[0][i] & 0xFF];
crc32table[2][i] = (crc32table[1][i] >> 8) ^ crc32table[0][crc32table[1][i] & 0xFF];
crc32table[3][i] = (crc32table[2][i] >> 8) ^ crc32table[0][crc32table[2][i] & 0xFF];
#ifdef BITNESS64
crc32table[4][i] = (crc32table[3][i] >> 8) ^ crc32table[0][crc32table[3][i] & 0xFF];
crc32table[5][i] = (crc32table[4][i] >> 8) ^ crc32table[0][crc32table[4][i] & 0xFF];
crc32table[6][i] = (crc32table[5][i] >> 8) ^ crc32table[0][crc32table[5][i] & 0xFF];
crc32table[7][i] = (crc32table[6][i] >> 8) ^ crc32table[0][crc32table[6][i] & 0xFF];
#endif
}
}