1 /* 7zCrc.c -- CRC32 calculation 2 2009-11-23 : Igor Pavlov : Public domain */ 3 4 #include "7zCrc.h" 5 #include "CpuArch.h" 6 7 #define kCrcPoly 0xEDB88320 8 9 #ifdef MY_CPU_LE 10 #define CRC_NUM_TABLES 8 11 #else 12 #define CRC_NUM_TABLES 1 13 #endif 14 15 typedef UInt32 (MY_FAST_CALL *CRC_FUNC)(UInt32 v, const void *data, size_t size, const UInt32 *table); 16 17 static CRC_FUNC g_CrcUpdate; 18 UInt32 g_CrcTable[256 * CRC_NUM_TABLES]; 19 20 #if CRC_NUM_TABLES == 1 21 22 #define CRC_UPDATE_BYTE_2(crc, b) (table[((crc) ^ (b)) & 0xFF] ^ ((crc) >> 8)) 23 24 static UInt32 MY_FAST_CALL CrcUpdateT1(UInt32 v, const void *data, size_t size, const UInt32 *table) 25 { 26 const Byte *p = (const Byte *)data; 27 for (; size > 0; size--, p++) 28 v = CRC_UPDATE_BYTE_2(v, *p); 29 return v; 30 } 31 32 #else 33 34 UInt32 MY_FAST_CALL CrcUpdateT4(UInt32 v, const void *data, size_t size, const UInt32 *table); 35 UInt32 MY_FAST_CALL CrcUpdateT8(UInt32 v, const void *data, size_t size, const UInt32 *table); 36 37 #endif 38 39 UInt32 MY_FAST_CALL CrcUpdate(UInt32 v, const void *data, size_t size) 40 { 41 return g_CrcUpdate(v, data, size, g_CrcTable); 42 } 43 44 UInt32 MY_FAST_CALL CrcCalc(const void *data, size_t size) 45 { 46 return g_CrcUpdate(CRC_INIT_VAL, data, size, g_CrcTable) ^ CRC_INIT_VAL; 47 } 48 49 void MY_FAST_CALL CrcGenerateTable() 50 { 51 UInt32 i; 52 for (i = 0; i < 256; i++) 53 { 54 UInt32 r = i; 55 unsigned j; 56 for (j = 0; j < 8; j++) 57 r = (r >> 1) ^ (kCrcPoly & ~((r & 1) - 1)); 58 g_CrcTable[i] = r; 59 } 60 #if CRC_NUM_TABLES == 1 61 g_CrcUpdate = CrcUpdateT1; 62 #else 63 for (; i < 256 * CRC_NUM_TABLES; i++) 64 { 65 UInt32 r = g_CrcTable[i - 256]; 66 g_CrcTable[i] = g_CrcTable[r & 0xFF] ^ (r >> 8); 67 } 68 g_CrcUpdate = CrcUpdateT4; 69 #ifdef MY_CPU_X86_OR_AMD64 70 if (!CPU_Is_InOrder()) 71 g_CrcUpdate = CrcUpdateT8; 72 #endif 73 #endif 74 } 75