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

View File

@ -113,64 +113,43 @@ void GAME_EXPORT CRC32_ProcessBuffer( dword *pulCRC, const void *pBuffer, int nB
{ {
dword ulCrc = *pulCRC, tmp; dword ulCrc = *pulCRC, tmp;
byte *pb = (byte *)pBuffer; byte *pb = (byte *)pBuffer;
uint nFront;
int nMain; while( nBuffer >= sizeof( uint64_t ))
JustAfew:
switch( nBuffer )
{ {
case 7: ulCrc = crc32table[*pb++ ^ (byte)ulCrc] ^ (ulCrc >> 8); // fallthrough memcpy( &tmp, pb, sizeof( tmp ));
case 6: ulCrc = crc32table[*pb++ ^ (byte)ulCrc] ^ (ulCrc >> 8); // fallthrough ulCrc ^= LittleLong( tmp );
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.
ulCrc = crc32table[(byte)ulCrc] ^ (ulCrc >> 8); ulCrc = crc32table[(byte)ulCrc] ^ (ulCrc >> 8);
ulCrc = crc32table[(byte)ulCrc] ^ (ulCrc >> 8); ulCrc = crc32table[(byte)ulCrc] ^ (ulCrc >> 8);
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; memcpy( &tmp, pb + sizeof( tmp ), sizeof( tmp ));
return; ulCrc ^= LittleLong( tmp );
case 3: ulCrc = crc32table[*pb++ ^ (byte)ulCrc] ^ (ulCrc >> 8); // fallthrough ulCrc = crc32table[(byte)ulCrc] ^ (ulCrc >> 8);
case 2: ulCrc = crc32table[*pb++ ^ (byte)ulCrc] ^ (ulCrc >> 8); // fallthrough ulCrc = crc32table[(byte)ulCrc] ^ (ulCrc >> 8);
case 1: ulCrc = crc32table[*pb++ ^ (byte)ulCrc] ^ (ulCrc >> 8); // fallthrough ulCrc = crc32table[(byte)ulCrc] ^ (ulCrc >> 8);
case 0: *pulCRC = ulCrc; ulCrc = crc32table[(byte)ulCrc] ^ (ulCrc >> 8);
return; nBuffer -= sizeof( uint64_t );
pb += sizeof( uint64_t );
} }
// We may need to do some alignment work up front, and at the end, so that if( nBuffer & sizeof( uint32_t ))
// 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 )
{ {
case 3: ulCrc = crc32table[*pb++ ^ (byte)ulCrc] ^ (ulCrc >> 8); // fallthrough memcpy( &tmp, pb, sizeof( tmp ));
case 2: ulCrc = crc32table[*pb++ ^ (byte)ulCrc] ^ (ulCrc >> 8); // fallthrough ulCrc ^= LittleLong( tmp );
case 1: ulCrc = crc32table[*pb++ ^ (byte)ulCrc] ^ (ulCrc >> 8); // fallthrough 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( nBuffer-- )
while( nMain-- )
{ {
memcpy( &tmp, pb, sizeof(dword)); ulCrc = crc32table[((byte)ulCrc ^ *pb++)] ^ (ulCrc >> 8);
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;
} }
nBuffer &= 7; *pulCRC = ulCrc;
goto JustAfew;
} }
/* /*