Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | RSS feed

  1. /* 7zCrc.c -- CRC32 init
  2. 2015-03-10 : Igor Pavlov : Public domain */
  3.  
  4. #include "Precomp.h"
  5.  
  6. #include "7zCrc.h"
  7. #include "CpuArch.h"
  8.  
  9. #define kCrcPoly 0xEDB88320
  10.  
  11. #ifdef MY_CPU_LE
  12.   #define CRC_NUM_TABLES 8
  13. #else
  14.   #define CRC_NUM_TABLES 9
  15.  
  16.   #define CRC_UINT32_SWAP(v) ((v >> 24) | ((v >> 8) & 0xFF00) | ((v << 8) & 0xFF0000) | (v << 24))
  17.  
  18.   UInt32 MY_FAST_CALL CrcUpdateT1_BeT4(UInt32 v, const void *data, size_t size, const UInt32 *table);
  19.   UInt32 MY_FAST_CALL CrcUpdateT1_BeT8(UInt32 v, const void *data, size_t size, const UInt32 *table);
  20. #endif
  21.  
  22. #ifndef MY_CPU_BE
  23.   UInt32 MY_FAST_CALL CrcUpdateT4(UInt32 v, const void *data, size_t size, const UInt32 *table);
  24.   UInt32 MY_FAST_CALL CrcUpdateT8(UInt32 v, const void *data, size_t size, const UInt32 *table);
  25. #endif
  26.  
  27. typedef UInt32 (MY_FAST_CALL *CRC_FUNC)(UInt32 v, const void *data, size_t size, const UInt32 *table);
  28.  
  29. CRC_FUNC g_CrcUpdateT4;
  30. CRC_FUNC g_CrcUpdateT8;
  31. CRC_FUNC g_CrcUpdate;
  32.  
  33. UInt32 g_CrcTable[256 * CRC_NUM_TABLES];
  34.  
  35. UInt32 MY_FAST_CALL CrcUpdate(UInt32 v, const void *data, size_t size)
  36. {
  37.   return g_CrcUpdate(v, data, size, g_CrcTable);
  38. }
  39.  
  40. UInt32 MY_FAST_CALL CrcCalc(const void *data, size_t size)
  41. {
  42.   return g_CrcUpdate(CRC_INIT_VAL, data, size, g_CrcTable) ^ CRC_INIT_VAL;
  43. }
  44.  
  45. #define CRC_UPDATE_BYTE_2(crc, b) (table[((crc) ^ (b)) & 0xFF] ^ ((crc) >> 8))
  46.  
  47. UInt32 MY_FAST_CALL CrcUpdateT1(UInt32 v, const void *data, size_t size, const UInt32 *table)
  48. {
  49.   const Byte *p = (const Byte *)data;
  50.   const Byte *pEnd = p + size;
  51.   for (; p != pEnd; p++)
  52.     v = CRC_UPDATE_BYTE_2(v, *p);
  53.   return v;
  54. }
  55.  
  56. void MY_FAST_CALL CrcGenerateTable()
  57. {
  58.   UInt32 i;
  59.   for (i = 0; i < 256; i++)
  60.   {
  61.     UInt32 r = i;
  62.     unsigned j;
  63.     for (j = 0; j < 8; j++)
  64.       r = (r >> 1) ^ (kCrcPoly & ~((r & 1) - 1));
  65.     g_CrcTable[i] = r;
  66.   }
  67.   for (; i < 256 * CRC_NUM_TABLES; i++)
  68.   {
  69.     UInt32 r = g_CrcTable[i - 256];
  70.     g_CrcTable[i] = g_CrcTable[r & 0xFF] ^ (r >> 8);
  71.   }
  72.  
  73.   #if CRC_NUM_TABLES < 4
  74.  
  75.   g_CrcUpdate = CrcUpdateT1;
  76.  
  77.   #else
  78.  
  79.   #ifdef MY_CPU_LE
  80.  
  81.     g_CrcUpdateT4 = CrcUpdateT4;
  82.     g_CrcUpdate = CrcUpdateT4;
  83.  
  84.     #if CRC_NUM_TABLES >= 8
  85.       g_CrcUpdateT8 = CrcUpdateT8;
  86.  
  87.       #ifdef MY_CPU_X86_OR_AMD64
  88.       if (!CPU_Is_InOrder())
  89.         g_CrcUpdate = CrcUpdateT8;
  90.       #endif
  91.     #endif
  92.  
  93.   #else
  94.   {
  95.     #ifndef MY_CPU_BE
  96.     UInt32 k = 0x01020304;
  97.     const Byte *p = (const Byte *)&k;
  98.     if (p[0] == 4 && p[1] == 3)
  99.     {
  100.       g_CrcUpdateT4 = CrcUpdateT4;
  101.       g_CrcUpdate = CrcUpdateT4;
  102.       #if CRC_NUM_TABLES >= 8
  103.       g_CrcUpdateT8 = CrcUpdateT8;
  104.       // g_CrcUpdate = CrcUpdateT8;
  105.       #endif
  106.     }
  107.     else if (p[0] != 1 || p[1] != 2)
  108.       g_CrcUpdate = CrcUpdateT1;
  109.     else
  110.     #endif
  111.     {
  112.       for (i = 256 * CRC_NUM_TABLES - 1; i >= 256; i--)
  113.       {
  114.         UInt32 x = g_CrcTable[i - 256];
  115.         g_CrcTable[i] = CRC_UINT32_SWAP(x);
  116.       }
  117.       g_CrcUpdateT4 = CrcUpdateT1_BeT4;
  118.       g_CrcUpdate = CrcUpdateT1_BeT4;
  119.       #if CRC_NUM_TABLES >= 8
  120.       g_CrcUpdateT8 = CrcUpdateT1_BeT8;
  121.       // g_CrcUpdate = CrcUpdateT1_BeT8;
  122.       #endif
  123.     }
  124.   }
  125.   #endif
  126.  
  127.   #endif
  128. }
  129.