This commit is contained in:
2026-02-13 14:42:07 -08:00
parent df0527b123
commit fbc02af589
670 changed files with 55968 additions and 51275 deletions

View File

@@ -8,13 +8,24 @@
#include "inflate.h"
#include "inffast.h"
#if (INTPTR_MAX == INT64_MAX) || defined(HAL_ESP32_HAL_H_) || defined(TEENSYDUINO) || defined(ARM_MATH_CM4) || defined(ARM_MATH_CM7)
#define ALLOWS_UNALIGNED
#endif
#if INTPTR_MAX == INT64_MAX
#define REGISTER_WIDTH 64
typedef uint64_t BIGUINT;
typedef uint32_t SMALLUINT;
#else
#define REGISTER_WIDTH 32
typedef uint32_t BIGUINT;
typedef uint16_t SMALLUINT;
#endif // native register size
#ifdef ASMINF
# pragma message("Assembler code may have bugs -- use at your own risk")
#else
#if ((INTPTR_MAX == INT64_MAX) || defined(HAL_ESP32_HAL_H_) || defined(TEENSYDUINO) || defined(ARM_MATH_CM4) || defined(ARM_MATH_CM7)) && !defined(ARDUINO_ARCH_RP2040)
#define ALLOWS_UNALIGNED
#endif
/*
Decode literal, length, and distance codes and write out the resulting
literal and match bytes until either not enough input or output is
@@ -50,7 +61,10 @@
requires strm->avail_out >= 258 for each loop to avoid checking for
output space.
*/
void ZLIB_INTERNAL inflate_fast(z_streamp strm, unsigned start) {
void ZLIB_INTERNAL inflate_fast(strm, start)
z_streamp strm;
unsigned start; /* inflate()'s starting value for strm->avail_out */
{
struct inflate_state FAR *state;
z_const unsigned char FAR *in; /* local strm->next_in */
z_const unsigned char FAR *last; /* have enough input while in < last */
@@ -64,13 +78,14 @@ void ZLIB_INTERNAL inflate_fast(z_streamp strm, unsigned start) {
unsigned whave; /* valid bytes in the window */
unsigned wnext; /* window write index */
unsigned char FAR *window; /* allocated sliding window, if wsize != 0 */
unsigned long hold; /* local strm->hold */
BIGUINT hold, tmpbits; /* local strm->hold */
// unsigned long hold; /* local strm->hold */
unsigned bits; /* local strm->bits */
code const FAR *lcode; /* local strm->lencode */
code const FAR *dcode; /* local strm->distcode */
unsigned lmask; /* mask for first level of length codes */
unsigned dmask; /* mask for first level of distance codes */
code const *here; /* retrieved table entry */
code here; /* retrieved table entry */
unsigned op; /* code bits, operation, extra bits, or */
/* window position, window bytes to copy */
unsigned len; /* match length, unused bytes */
@@ -101,60 +116,84 @@ void ZLIB_INTERNAL inflate_fast(z_streamp strm, unsigned start) {
/* decode literals and length/distances until end-of-block or not enough
input data or output space */
do {
if (bits < 15) {
if (bits < (REGISTER_WIDTH/2)) { // helps on 32 and 64-bit CPUs
#ifdef ALLOWS_UNALIGNED
tmpbits = *(SMALLUINT *)in;
hold |= (BIGUINT)(tmpbits << bits);
in += sizeof(SMALLUINT);
bits += (REGISTER_WIDTH / 2);
#else
hold += (unsigned long)(*in++) << bits;
bits += 8;
hold += (unsigned long)(*in++) << bits;
bits += 8;
#endif
}
here = lcode + (hold & lmask);
here = lcode[hold & lmask];
dolen:
op = (unsigned)(here->bits);
op = (unsigned)(here.bits);
hold >>= op;
bits -= op;
op = (unsigned)(here->op);
op = (unsigned)(here.op);
if (op == 0) { /* literal */
Tracevv((stderr, here->val >= 0x20 && here->val < 0x7f ?
Tracevv((stderr, here.val >= 0x20 && here.val < 0x7f ?
"inflate: literal '%c'\n" :
"inflate: literal 0x%02x\n", here->val));
*out++ = (unsigned char)(here->val);
"inflate: literal 0x%02x\n", here.val));
*out++ = (unsigned char)(here.val);
}
else if (op & 16) { /* length base */
len = (unsigned)(here->val);
len = (unsigned)(here.val);
op &= 15; /* number of extra bits */
if (op) {
#if REGISTER_WIDTH == 32
if (bits < op) {
hold += (unsigned long)(*in++) << bits;
hold += (uint32_t)(*in++) << bits;
bits += 8;
}
#endif
len += (unsigned)hold & ((1U << op) - 1);
hold >>= op;
bits -= op;
}
Tracevv((stderr, "inflate: length %u\n", len));
if (bits < 15) {
if (bits < (REGISTER_WIDTH/2)) { // helps on 32 and 64-bit CPUs
#ifdef UNALIGNED_OK
tmpbits = *(SMALLUINT *)in;
hold |= (BIGUINT)(tmpbits << bits);
in += sizeof(SMALLUINT);
bits += (REGISTER_WIDTH / 2);
#else
hold += (unsigned long)(*in++) << bits;
bits += 8;
hold += (unsigned long)(*in++) << bits;
bits += 8;
#endif
}
here = dcode + (hold & dmask);
here = dcode[hold & dmask];
dodist:
op = (unsigned)(here->bits);
op = (unsigned)(here.bits);
hold >>= op;
bits -= op;
op = (unsigned)(here->op);
op = (unsigned)(here.op);
if (op & 16) { /* distance base */
dist = (unsigned)(here->val);
dist = (unsigned)(here.val);
op &= 15; /* number of extra bits */
#if REGISTER_WIDTH == 32
if (bits < op) {
#ifdef ALLOWS_UNALIGNED
hold |= (*(uint16_t *)in << bits);
bits += 16;
in += 2;
#else
hold += (unsigned long)(*in++) << bits;
bits += 8;
if (bits < op) {
if (bits < op) { // this is NEVER true
hold += (unsigned long)(*in++) << bits;
bits += 8;
}
#endif // ALLOWS_UNALIGNED
}
#endif // 32-bit CPU
dist += (unsigned)hold & ((1U << op) - 1);
#ifdef INFLATE_STRICT
if (dist > dmax) {
@@ -267,7 +306,7 @@ void ZLIB_INTERNAL inflate_fast(z_streamp strm, unsigned start) {
{
uint8_t *pEnd = out+len;
int overlap = (int)(intptr_t)(out-from);
if (overlap > 4) { // overlap of source/dest won't impede normal copy
if (overlap >= 4) { // overlap of source/dest won't impede normal copy
while (out < pEnd) {
*(uint32_t *)out = *(uint32_t *)from;
out += 4;
@@ -275,15 +314,10 @@ void ZLIB_INTERNAL inflate_fast(z_streamp strm, unsigned start) {
}
// correct for possible overshoot of destination ptr
out = pEnd;
} else if (overlap == 1 || overlap == 4) { // copy 1/4-byte patterns
uint32_t pattern;
if (overlap == 1) {
pattern = *from;
pattern = pattern | (pattern << 8);
pattern = pattern | (pattern << 16);
} else {
pattern = *(uint32_t *)from;
}
} else if (overlap == 1) { // copy 1-byte pattern
uint32_t pattern = *from;
pattern = pattern | (pattern << 8);
pattern = pattern | (pattern << 16);
while (out < pEnd) {
*(uint32_t *)out = pattern;
out += 4;
@@ -311,7 +345,7 @@ void ZLIB_INTERNAL inflate_fast(z_streamp strm, unsigned start) {
}
}
else if ((op & 64) == 0) { /* 2nd level distance code */
here = dcode + here->val + (hold & ((1U << op) - 1));
here = dcode[here.val + (hold & ((1U << op) - 1))];
goto dodist;
}
else {
@@ -321,7 +355,7 @@ void ZLIB_INTERNAL inflate_fast(z_streamp strm, unsigned start) {
}
}
else if ((op & 64) == 0) { /* 2nd level length code */
here = lcode + here->val + (hold & ((1U << op) - 1));
here = lcode[here.val + (hold & ((1U << op) - 1))];
goto dolen;
}
else if (op & 32) { /* end-of-block */
@@ -337,10 +371,10 @@ void ZLIB_INTERNAL inflate_fast(z_streamp strm, unsigned start) {
} while (in < last && out < end);
/* return unused bytes (on entry, bits < 8, so in won't go too far back) */
len = bits >> 3;
in -= len;
bits -= len << 3;
hold &= (1U << bits) - 1;
// len = bits >> 3;
// in -= len;
// bits -= len << 3;
// hold &= (1 << bits) - 1;
/* update state and return */
strm->next_in = in;