From c0c81190406e18b2eda9346612c749614c29c770 Mon Sep 17 00:00:00 2001 From: Alibek Omarov Date: Tue, 13 Jun 2023 06:43:28 +0300 Subject: [PATCH] public: crclib: rework CRC32 code (thanks to @Mr0maks for implementation) --- public/crclib.c | 65 +++++++++++++++++-------------------------------- 1 file changed, 22 insertions(+), 43 deletions(-) diff --git a/public/crclib.c b/public/crclib.c index 0312f820..ec57576b 100644 --- a/public/crclib.c +++ b/public/crclib.c @@ -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; - } - - // 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 ) - { - 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 - } - - nMain = nBuffer >> 3; - while( nMain-- ) - { - memcpy( &tmp, pb, sizeof(dword)); - ulCrc ^= tmp; // warning, this only works on little-endian. + 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); - memcpy( &tmp, pb + 4, sizeof(dword)); - ulCrc ^= tmp; // warning, this only works on little-endian. + nBuffer -= sizeof( uint64_t ); + pb += sizeof( uint64_t ); + } + + if( nBuffer & sizeof( uint32_t )) + { + 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); - pb += 8; + nBuffer -= sizeof( uint32_t ); + pb += sizeof( uint32_t ); } - nBuffer &= 7; - goto JustAfew; + while( nBuffer-- ) + { + ulCrc = crc32table[((byte)ulCrc ^ *pb++)] ^ (ulCrc >> 8); + } + + *pulCRC = ulCrc; } /*