diff options
Diffstat (limited to '')
-rw-r--r-- | src/liblzma/check/crc32_small.c | 68 |
1 files changed, 68 insertions, 0 deletions
diff --git a/src/liblzma/check/crc32_small.c b/src/liblzma/check/crc32_small.c new file mode 100644 index 0000000..186966e --- /dev/null +++ b/src/liblzma/check/crc32_small.c @@ -0,0 +1,68 @@ +/////////////////////////////////////////////////////////////////////////////// +// +/// \file crc32_small.c +/// \brief CRC32 calculation (size-optimized) +// +// Author: Lasse Collin +// +// This file has been put into the public domain. +// You can do whatever you want with this file. +// +/////////////////////////////////////////////////////////////////////////////// + +#include "check.h" + + +uint32_t lzma_crc32_table[1][256]; + + +#ifdef HAVE_FUNC_ATTRIBUTE_CONSTRUCTOR +__attribute__((__constructor__)) +#endif +static void +crc32_init(void) +{ + static const uint32_t poly32 = UINT32_C(0xEDB88320); + + for (size_t b = 0; b < 256; ++b) { + uint32_t r = b; + for (size_t i = 0; i < 8; ++i) { + if (r & 1) + r = (r >> 1) ^ poly32; + else + r >>= 1; + } + + lzma_crc32_table[0][b] = r; + } + + return; +} + + +#ifndef HAVE_FUNC_ATTRIBUTE_CONSTRUCTOR +extern void +lzma_crc32_init(void) +{ + mythread_once(crc32_init); + return; +} +#endif + + +extern LZMA_API(uint32_t) +lzma_crc32(const uint8_t *buf, size_t size, uint32_t crc) +{ +#ifndef HAVE_FUNC_ATTRIBUTE_CONSTRUCTOR + lzma_crc32_init(); +#endif + + crc = ~crc; + + while (size != 0) { + crc = lzma_crc32_table[0][*buf++ ^ (crc & 0xFF)] ^ (crc >> 8); + --size; + } + + return ~crc; +} |