mirror of
https://github.com/DrBeef/Raze.git
synced 2024-12-15 15:11:01 +00:00
17906349b4
git-svn-id: https://svn.eduke32.com/eduke32@5037 1a8010ca-5511-0410-912e-c29ae57300e0
102 lines
3.2 KiB
C
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, size_t length, uint32_t crc)
|
|
{
|
|
const uint32_t* current = (const uint32_t*) data;
|
|
uint8_t *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*) 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
|
|
}
|
|
}
|