public: crclib: rework CRC32 code (thanks to @Mr0maks for implementation)

This commit is contained in:
Alibek Omarov 2023-06-13 06:43:28 +03:00
parent 61c75b9809
commit c0c8119040
1 changed files with 24 additions and 45 deletions

View File

@ -113,64 +113,43 @@ void GAME_EXPORT CRC32_ProcessBuffer( dword *pulCRC, const void *pBuffer, int nB
{
dword ulCrc = *pulCRC, tmp;
byte *pb = (byte *)pBuffer;
uint nFront;
int nMain;
JustAfew:
switch( nBuffer )
while( nBuffer >= sizeof( uint64_t ))
{
case 7: ulCrc = crc32table[*pb++ ^ (byte)ulCrc] ^ (ulCrc >> 8); // fallthrough
case 6: ulCrc = crc32table[*pb++ ^ (byte)ulCrc] ^ (ulCrc >> 8); // fallthrough
case 5: ulCrc = crc32table[*pb++ ^ (byte)ulCrc] ^ (ulCrc >> 8); // fallthrough
case 4:
memcpy( &tmp, pb, sizeof(dword));
ulCrc ^= tmp; // warning, this only works on little-endian.
memcpy( &tmp, pb, sizeof( tmp ));
ulCrc ^= LittleLong( tmp );
ulCrc = crc32table[(byte)ulCrc] ^ (ulCrc >> 8);
ulCrc = crc32table[(byte)ulCrc] ^ (ulCrc >> 8);
ulCrc = crc32table[(byte)ulCrc] ^ (ulCrc >> 8);
ulCrc = crc32table[(byte)ulCrc] ^ (ulCrc >> 8);
*pulCRC = ulCrc;
return;
case 3: ulCrc = crc32table[*pb++ ^ (byte)ulCrc] ^ (ulCrc >> 8); // fallthrough
case 2: ulCrc = crc32table[*pb++ ^ (byte)ulCrc] ^ (ulCrc >> 8); // fallthrough
case 1: ulCrc = crc32table[*pb++ ^ (byte)ulCrc] ^ (ulCrc >> 8); // fallthrough
case 0: *pulCRC = ulCrc;
return;
memcpy( &tmp, pb + sizeof( tmp ), sizeof( tmp ));
ulCrc ^= LittleLong( tmp );
ulCrc = crc32table[(byte)ulCrc] ^ (ulCrc >> 8);
ulCrc = crc32table[(byte)ulCrc] ^ (ulCrc >> 8);
ulCrc = crc32table[(byte)ulCrc] ^ (ulCrc >> 8);
ulCrc = crc32table[(byte)ulCrc] ^ (ulCrc >> 8);
nBuffer -= sizeof( uint64_t );
pb += sizeof( uint64_t );
}
// We may need to do some alignment work up front, and at the end, so that
// the main loop is aligned and only has to worry about 8 byte at a time.
// The low-order two bits of pb and nBuffer in total control the
// upfront work.
nFront = ((uint)pb) & 3;
nBuffer -= nFront;
switch( nFront )
if( nBuffer & sizeof( uint32_t ))
{
case 3: ulCrc = crc32table[*pb++ ^ (byte)ulCrc] ^ (ulCrc >> 8); // fallthrough
case 2: ulCrc = crc32table[*pb++ ^ (byte)ulCrc] ^ (ulCrc >> 8); // fallthrough
case 1: ulCrc = crc32table[*pb++ ^ (byte)ulCrc] ^ (ulCrc >> 8); // fallthrough
memcpy( &tmp, pb, sizeof( tmp ));
ulCrc ^= LittleLong( tmp );
ulCrc = crc32table[(byte)ulCrc] ^ (ulCrc >> 8);
ulCrc = crc32table[(byte)ulCrc] ^ (ulCrc >> 8);
ulCrc = crc32table[(byte)ulCrc] ^ (ulCrc >> 8);
ulCrc = crc32table[(byte)ulCrc] ^ (ulCrc >> 8);
nBuffer -= sizeof( uint32_t );
pb += sizeof( uint32_t );
}
nMain = nBuffer >> 3;
while( nMain-- )
while( nBuffer-- )
{
memcpy( &tmp, pb, sizeof(dword));
ulCrc ^= tmp; // warning, this only works on little-endian.
ulCrc = crc32table[(byte)ulCrc] ^ (ulCrc >> 8);
ulCrc = crc32table[(byte)ulCrc] ^ (ulCrc >> 8);
ulCrc = crc32table[(byte)ulCrc] ^ (ulCrc >> 8);
ulCrc = crc32table[(byte)ulCrc] ^ (ulCrc >> 8);
memcpy( &tmp, pb + 4, sizeof(dword));
ulCrc ^= tmp; // warning, this only works on little-endian.
ulCrc = crc32table[(byte)ulCrc] ^ (ulCrc >> 8);
ulCrc = crc32table[(byte)ulCrc] ^ (ulCrc >> 8);
ulCrc = crc32table[(byte)ulCrc] ^ (ulCrc >> 8);
ulCrc = crc32table[(byte)ulCrc] ^ (ulCrc >> 8);
pb += 8;
ulCrc = crc32table[((byte)ulCrc ^ *pb++)] ^ (ulCrc >> 8);
}
nBuffer &= 7;
goto JustAfew;
*pulCRC = ulCrc;
}
/*