xref: /freebsd/contrib/xz/src/liblzma/check/crc32_small.c (revision 128836d304d93f2d00eb14069c27089ab46c38d4)
1 // SPDX-License-Identifier: 0BSD
2 
3 ///////////////////////////////////////////////////////////////////////////////
4 //
5 /// \file       crc32_small.c
6 /// \brief      CRC32 calculation (size-optimized)
7 //
8 //  Author:     Lasse Collin
9 //
10 ///////////////////////////////////////////////////////////////////////////////
11 
12 #include "check.h"
13 #include "crc_common.h"
14 
15 
16 // The table is used by the LZ encoder too, thus it's not static like
17 // in crc64_small.c.
18 uint32_t lzma_crc32_table[1][256];
19 
20 
21 #ifdef HAVE_FUNC_ATTRIBUTE_CONSTRUCTOR
22 __attribute__((__constructor__))
23 #endif
24 static void
crc32_init(void)25 crc32_init(void)
26 {
27 	static const uint32_t poly32 = UINT32_C(0xEDB88320);
28 
29 	for (size_t b = 0; b < 256; ++b) {
30 		uint32_t r = b;
31 		for (size_t i = 0; i < 8; ++i) {
32 			if (r & 1)
33 				r = (r >> 1) ^ poly32;
34 			else
35 				r >>= 1;
36 		}
37 
38 		lzma_crc32_table[0][b] = r;
39 	}
40 
41 	return;
42 }
43 
44 
45 #ifndef HAVE_FUNC_ATTRIBUTE_CONSTRUCTOR
46 extern void
lzma_crc32_init(void)47 lzma_crc32_init(void)
48 {
49 	mythread_once(crc32_init);
50 	return;
51 }
52 #endif
53 
54 
55 extern LZMA_API(uint32_t)
lzma_crc32(const uint8_t * buf,size_t size,uint32_t crc)56 lzma_crc32(const uint8_t *buf, size_t size, uint32_t crc)
57 {
58 #ifndef HAVE_FUNC_ATTRIBUTE_CONSTRUCTOR
59 	lzma_crc32_init();
60 #endif
61 
62 	crc = ~crc;
63 
64 	while (size != 0) {
65 		crc = lzma_crc32_table[0][*buf++ ^ (crc & 0xFF)] ^ (crc >> 8);
66 		--size;
67 	}
68 
69 	return ~crc;
70 }
71