1207753Smm/////////////////////////////////////////////////////////////////////////////// 2207753Smm// 3207753Smm/// \file crc32.c 4207753Smm/// \brief CRC32 calculation 5207753Smm/// 6207753Smm/// Calculate the CRC32 using the slice-by-eight algorithm. 7207753Smm/// It is explained in this document: 8207753Smm/// http://www.intel.com/technology/comms/perfnet/download/CRC_generators.pdf 9207753Smm/// The code in this file is not the same as in Intel's paper, but 10207753Smm/// the basic principle is identical. 11207753Smm// 12207753Smm// Author: Lasse Collin 13207753Smm// 14207753Smm// This file has been put into the public domain. 15207753Smm// You can do whatever you want with this file. 16207753Smm// 17207753Smm/////////////////////////////////////////////////////////////////////////////// 18207753Smm 19207753Smm#include "check.h" 20207753Smm#include "crc_macros.h" 21207753Smm 22207753Smm 23207753Smm// If you make any changes, do some bench marking! Seemingly unrelated 24207753Smm// changes can very easily ruin the performance (and very probably is 25207753Smm// very compiler dependent). 26207753Smmextern LZMA_API(uint32_t) 27207753Smmlzma_crc32(const uint8_t *buf, size_t size, uint32_t crc) 28207753Smm{ 29207753Smm crc = ~crc; 30207753Smm 31207753Smm#ifdef WORDS_BIGENDIAN 32207753Smm crc = bswap32(crc); 33207753Smm#endif 34207753Smm 35207753Smm if (size > 8) { 36207753Smm // Fix the alignment, if needed. The if statement above 37207753Smm // ensures that this won't read past the end of buf[]. 38207753Smm while ((uintptr_t)(buf) & 7) { 39207753Smm crc = lzma_crc32_table[0][*buf++ ^ A(crc)] ^ S8(crc); 40207753Smm --size; 41207753Smm } 42207753Smm 43207753Smm // Calculate the position where to stop. 44207753Smm const uint8_t *const limit = buf + (size & ~(size_t)(7)); 45207753Smm 46207753Smm // Calculate how many bytes must be calculated separately 47207753Smm // before returning the result. 48207753Smm size &= (size_t)(7); 49207753Smm 50207753Smm // Calculate the CRC32 using the slice-by-eight algorithm. 51207753Smm while (buf < limit) { 52207753Smm crc ^= *(const uint32_t *)(buf); 53207753Smm buf += 4; 54207753Smm 55207753Smm crc = lzma_crc32_table[7][A(crc)] 56207753Smm ^ lzma_crc32_table[6][B(crc)] 57207753Smm ^ lzma_crc32_table[5][C(crc)] 58207753Smm ^ lzma_crc32_table[4][D(crc)]; 59207753Smm 60207753Smm const uint32_t tmp = *(const uint32_t *)(buf); 61207753Smm buf += 4; 62207753Smm 63207753Smm // At least with some compilers, it is critical for 64207753Smm // performance, that the crc variable is XORed 65207753Smm // between the two table-lookup pairs. 66207753Smm crc = lzma_crc32_table[3][A(tmp)] 67207753Smm ^ lzma_crc32_table[2][B(tmp)] 68207753Smm ^ crc 69207753Smm ^ lzma_crc32_table[1][C(tmp)] 70207753Smm ^ lzma_crc32_table[0][D(tmp)]; 71207753Smm } 72207753Smm } 73207753Smm 74207753Smm while (size-- != 0) 75207753Smm crc = lzma_crc32_table[0][*buf++ ^ A(crc)] ^ S8(crc); 76207753Smm 77207753Smm#ifdef WORDS_BIGENDIAN 78207753Smm crc = bswap32(crc); 79207753Smm#endif 80207753Smm 81207753Smm return ~crc; 82207753Smm} 83