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