Coverage Report

Created: 2025-07-18 06:47

/src/c-blosc2/internal-complibs/zlib-ng-2.0.7/crc32.c
Line
Count
Source (jump to first uncovered line)
1
/* crc32.c -- compute the CRC-32 of a data stream
2
 * Copyright (C) 1995-2006, 2010, 2011, 2012, 2016, 2018 Mark Adler
3
 * For conditions of distribution and use, see copyright notice in zlib.h
4
 *
5
 * Thanks to Rodney Brown <rbrown64@csc.com.au> for his contribution of faster
6
 * CRC methods: exclusive-oring 32 bits of data at a time, and pre-computing
7
 * tables for updating the shift register in one step with three exclusive-ors
8
 * instead of four steps with four exclusive-ors.  This results in about a
9
 * factor of two increase in speed on a Power PC G4 (PPC7455) using gcc -O3.
10
 */
11
12
#include "zbuild.h"
13
#include "zendian.h"
14
#include <inttypes.h>
15
#include "deflate.h"
16
#include "functable.h"
17
#include "crc32_tbl.h"
18
19
/* =========================================================================
20
 * This function can be used by asm versions of crc32()
21
 */
22
0
const uint32_t * Z_EXPORT PREFIX(get_crc_table)(void) {
23
0
    return (const uint32_t *)crc_table;
24
0
}
25
26
#ifdef ZLIB_COMPAT
27
0
unsigned long Z_EXPORT PREFIX(crc32_z)(unsigned long crc, const unsigned char *buf, size_t len) {
28
0
    if (buf == NULL) return 0;
29
30
0
    return (unsigned long)functable.crc32((uint32_t)crc, buf, len);
31
0
}
32
#else
33
uint32_t Z_EXPORT PREFIX(crc32_z)(uint32_t crc, const unsigned char *buf, size_t len) {
34
    if (buf == NULL) return 0;
35
36
    return functable.crc32(crc, buf, len);
37
}
38
#endif
39
/* ========================================================================= */
40
0
#define DO1 crc = crc_table[0][((int)crc ^ (*buf++)) & 0xff] ^ (crc >> 8)
41
#define DO8 DO1; DO1; DO1; DO1; DO1; DO1; DO1; DO1
42
0
#define DO4 DO1; DO1; DO1; DO1
43
44
/* ========================================================================= */
45
0
Z_INTERNAL uint32_t crc32_generic(uint32_t crc, const unsigned char *buf, uint64_t len) {
46
0
    crc = crc ^ 0xffffffff;
47
48
#ifdef UNROLL_MORE
49
    while (len >= 8) {
50
        DO8;
51
        len -= 8;
52
    }
53
#else
54
0
    while (len >= 4) {
55
0
        DO4;
56
0
        len -= 4;
57
0
    }
58
0
#endif
59
60
0
    if (len) do {
61
0
        DO1;
62
0
    } while (--len);
63
0
    return crc ^ 0xffffffff;
64
0
}
65
66
#ifdef ZLIB_COMPAT
67
0
unsigned long Z_EXPORT PREFIX(crc32)(unsigned long crc, const unsigned char *buf, unsigned int len) {
68
0
    return (unsigned long)PREFIX(crc32_z)((uint32_t)crc, buf, len);
69
0
}
70
#else
71
uint32_t Z_EXPORT PREFIX(crc32)(uint32_t crc, const unsigned char *buf, uint32_t len) {
72
    return PREFIX(crc32_z)(crc, buf, len);
73
}
74
#endif
75
76
/*
77
   This BYFOUR code accesses the passed unsigned char * buffer with a 32-bit
78
   integer pointer type. This violates the strict aliasing rule, where a
79
   compiler can assume, for optimization purposes, that two pointers to
80
   fundamentally different types won't ever point to the same memory. This can
81
   manifest as a problem only if one of the pointers is written to. This code
82
   only reads from those pointers. So long as this code remains isolated in
83
   this compilation unit, there won't be a problem. For this reason, this code
84
   should not be copied and pasted into a compilation unit in which other code
85
   writes to the buffer that is passed to these routines.
86
 */
87
88
/* ========================================================================= */
89
#if BYTE_ORDER == LITTLE_ENDIAN
90
0
#define DOLIT4 c ^= *buf4++; \
91
0
        c = crc_table[3][c & 0xff] ^ crc_table[2][(c >> 8) & 0xff] ^ \
92
0
            crc_table[1][(c >> 16) & 0xff] ^ crc_table[0][c >> 24]
93
#define DOLIT32 DOLIT4; DOLIT4; DOLIT4; DOLIT4; DOLIT4; DOLIT4; DOLIT4; DOLIT4
94
95
/* ========================================================================= */
96
0
Z_INTERNAL uint32_t crc32_little(uint32_t crc, const unsigned char *buf, uint64_t len) {
97
0
    Z_REGISTER uint32_t c;
98
0
    Z_REGISTER const uint32_t *buf4;
99
100
0
    c = crc;
101
0
    c = ~c;
102
0
    while (len && ((ptrdiff_t)buf & 3)) {
103
0
        c = crc_table[0][(c ^ *buf++) & 0xff] ^ (c >> 8);
104
0
        len--;
105
0
    }
106
107
0
    buf4 = (const uint32_t *)(const void *)buf;
108
109
#ifdef UNROLL_MORE
110
    while (len >= 32) {
111
        DOLIT32;
112
        len -= 32;
113
    }
114
#endif
115
116
0
    while (len >= 4) {
117
0
        DOLIT4;
118
0
        len -= 4;
119
0
    }
120
0
    buf = (const unsigned char *)buf4;
121
122
0
    if (len) do {
123
0
        c = crc_table[0][(c ^ *buf++) & 0xff] ^ (c >> 8);
124
0
    } while (--len);
125
0
    c = ~c;
126
0
    return c;
127
0
}
128
#endif /* BYTE_ORDER == LITTLE_ENDIAN */
129
130
/* ========================================================================= */
131
#if BYTE_ORDER == BIG_ENDIAN
132
#define DOBIG4 c ^= *buf4++; \
133
        c = crc_table[4][c & 0xff] ^ crc_table[5][(c >> 8) & 0xff] ^ \
134
            crc_table[6][(c >> 16) & 0xff] ^ crc_table[7][c >> 24]
135
#define DOBIG32 DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4
136
137
/* ========================================================================= */
138
Z_INTERNAL uint32_t crc32_big(uint32_t crc, const unsigned char *buf, uint64_t len) {
139
    Z_REGISTER uint32_t c;
140
    Z_REGISTER const uint32_t *buf4;
141
142
    c = ZSWAP32(crc);
143
    c = ~c;
144
    while (len && ((ptrdiff_t)buf & 3)) {
145
        c = crc_table[4][(c >> 24) ^ *buf++] ^ (c << 8);
146
        len--;
147
    }
148
149
    buf4 = (const uint32_t *)(const void *)buf;
150
151
#ifdef UNROLL_MORE
152
    while (len >= 32) {
153
        DOBIG32;
154
        len -= 32;
155
    }
156
#endif
157
158
    while (len >= 4) {
159
        DOBIG4;
160
        len -= 4;
161
    }
162
    buf = (const unsigned char *)buf4;
163
164
    if (len) do {
165
        c = crc_table[4][(c >> 24) ^ *buf++] ^ (c << 8);
166
    } while (--len);
167
    c = ~c;
168
    return ZSWAP32(c);
169
}
170
#endif /* BYTE_ORDER == BIG_ENDIAN */
171
172
#ifdef X86_PCLMULQDQ_CRC
173
#include "arch/x86/x86.h"
174
#include "arch/x86/crc_folding.h"
175
176
Z_INTERNAL void crc_finalize(deflate_state *const s) {
177
    if (x86_cpu_has_pclmulqdq)
178
        s->strm->adler = crc_fold_512to32(s);
179
}
180
#endif
181
182
0
Z_INTERNAL void crc_reset(deflate_state *const s) {
183
#ifdef X86_PCLMULQDQ_CRC
184
    x86_check_features();
185
    if (x86_cpu_has_pclmulqdq) {
186
        crc_fold_init(s);
187
        return;
188
    }
189
#endif
190
0
    s->strm->adler = PREFIX(crc32)(0L, NULL, 0);
191
0
}
192
193
0
Z_INTERNAL void copy_with_crc(PREFIX3(stream) *strm, unsigned char *dst, unsigned long size) {
194
#ifdef X86_PCLMULQDQ_CRC
195
    if (x86_cpu_has_pclmulqdq) {
196
        crc_fold_copy(strm->state, dst, strm->next_in, size);
197
        return;
198
    }
199
#endif
200
0
    memcpy(dst, strm->next_in, size);
201
0
    strm->adler = PREFIX(crc32)(strm->adler, dst, size);
202
0
}