15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* 7zCrc.c -- CRC32 calculation 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)2009-11-23 : Igor Pavlov : Public domain */ 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "7zCrc.h" 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "CpuArch.h" 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define kCrcPoly 0xEDB88320 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef MY_CPU_LE 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define CRC_NUM_TABLES 8 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#else 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define CRC_NUM_TABLES 1 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)typedef UInt32 (MY_FAST_CALL *CRC_FUNC)(UInt32 v, const void *data, size_t size, const UInt32 *table); 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static CRC_FUNC g_CrcUpdate; 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)UInt32 g_CrcTable[256 * CRC_NUM_TABLES]; 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if CRC_NUM_TABLES == 1 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define CRC_UPDATE_BYTE_2(crc, b) (table[((crc) ^ (b)) & 0xFF] ^ ((crc) >> 8)) 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static UInt32 MY_FAST_CALL CrcUpdateT1(UInt32 v, const void *data, size_t size, const UInt32 *table) 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const Byte *p = (const Byte *)data; 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (; size > 0; size--, p++) 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) v = CRC_UPDATE_BYTE_2(v, *p); 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return v; 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#else 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)UInt32 MY_FAST_CALL CrcUpdateT4(UInt32 v, const void *data, size_t size, const UInt32 *table); 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)UInt32 MY_FAST_CALL CrcUpdateT8(UInt32 v, const void *data, size_t size, const UInt32 *table); 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)UInt32 MY_FAST_CALL CrcUpdate(UInt32 v, const void *data, size_t size) 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return g_CrcUpdate(v, data, size, g_CrcTable); 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)UInt32 MY_FAST_CALL CrcCalc(const void *data, size_t size) 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return g_CrcUpdate(CRC_INIT_VAL, data, size, g_CrcTable) ^ CRC_INIT_VAL; 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void MY_FAST_CALL CrcGenerateTable() 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) UInt32 i; 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (i = 0; i < 256; i++) 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) UInt32 r = i; 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned j; 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (j = 0; j < 8; j++) 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) r = (r >> 1) ^ (kCrcPoly & ~((r & 1) - 1)); 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) g_CrcTable[i] = r; 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #if CRC_NUM_TABLES == 1 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) g_CrcUpdate = CrcUpdateT1; 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #else 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (; i < 256 * CRC_NUM_TABLES; i++) 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) UInt32 r = g_CrcTable[i - 256]; 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) g_CrcTable[i] = g_CrcTable[r & 0xFF] ^ (r >> 8); 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) g_CrcUpdate = CrcUpdateT4; 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #ifdef MY_CPU_X86_OR_AMD64 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!CPU_Is_InOrder()) 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) g_CrcUpdate = CrcUpdateT8; 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #endif 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #endif 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 75