1/* 7zCrc.c -- CRC32 calculation 22009-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 15typedef UInt32 (MY_FAST_CALL *CRC_FUNC)(UInt32 v, const void *data, size_t size, const UInt32 *table); 16 17static CRC_FUNC g_CrcUpdate; 18UInt32 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 24static 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 34UInt32 MY_FAST_CALL CrcUpdateT4(UInt32 v, const void *data, size_t size, const UInt32 *table); 35UInt32 MY_FAST_CALL CrcUpdateT8(UInt32 v, const void *data, size_t size, const UInt32 *table); 36 37#endif 38 39UInt32 MY_FAST_CALL CrcUpdate(UInt32 v, const void *data, size_t size) 40{ 41 return g_CrcUpdate(v, data, size, g_CrcTable); 42} 43 44UInt32 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 49void 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