typedef uint32_t (*crc32_copy_func)(uint32_t crc, uint8_t *dst, const uint8_t *src, size_t len);
typedef void (*slide_hash_func)(deflate_state *s);
+uint32_t crc32_small(uint32_t crc, const uint8_t *buf, size_t len);
+
#ifdef ADLER32_FALLBACK
uint32_t adler32_c(uint32_t adler, const uint8_t *buf, size_t len);
uint32_t adler32_copy_c(uint32_t adler, uint8_t *dst, const uint8_t *src, size_t len);
#include "zbuild.h"
#include "functable.h"
-#include "crc32_braid_tbl.h"
+#include "crc32_p.h"
/* ========================================================================= */
return (const uint32_t *)crc_table;
}
+/* crc32 function meant for short buffers like gzip headers */
+Z_INTERNAL uint32_t crc32_small(uint32_t crc, const uint8_t *buf, size_t len) {
+ if (UNLIKELY(len >= 32)){
+ return FUNCTABLE_CALL(crc32)(crc, buf, len);
+ }
+
+ return ~crc32_copy_small(~crc, NULL, buf, len, 32, 0);
+}
+
#ifdef ZLIB_COMPAT
unsigned long Z_EXPORT PREFIX(crc32_z)(unsigned long crc, const unsigned char *buf, size_t len) {
if (buf == NULL)
#ifndef CRC32_P_H
#define CRC32_P_H
+#include "crc32_braid_tbl.h"
+
#define CRC_DO1(c, buf, i) c = crc_table[(c ^ buf[i]) & 0xff] ^ (c >> 8)
#define CRC_DO2(c, buf, i) {CRC_DO1(c, buf, i); CRC_DO1(c, buf, i+1);}
#define CRC_DO4(c, buf, i) {CRC_DO2(c, buf, i); CRC_DO2(c, buf, i+2);}
#include "deflate.h"
#include "deflate_p.h"
#include "insert_string_p.h"
+#include "arch_functions.h"
/* Avoid conflicts with zlib.h macros */
#ifdef ZLIB_COMPAT
#define HCRC_UPDATE(beg) \
do { \
if (s->gzhead->hcrc && s->pending > (beg)) \
- strm->adler = PREFIX(crc32)(strm->adler, s->pending_buf + (beg), s->pending - (beg)); \
+ strm->adler = crc32_small((uint32_t)strm->adler, s->pending_buf + (beg), s->pending - (beg)); \
} while (0)
/* ========================================================================= */
if (s->gzhead->extra != NULL)
put_short(s, (uint16_t)s->gzhead->extra_len);
if (s->gzhead->hcrc)
- strm->adler = PREFIX(crc32)(strm->adler, s->pending_buf, s->pending);
+ strm->adler = crc32_small((uint32_t)strm->adler, s->pending_buf, s->pending);
s->gzindex = 0;
s->status = EXTRA_STATE;
}
#include "inflate_p.h"
#include "inffixed_tbl.h"
#include "functable.h"
+#include "arch_functions.h"
/* Avoid conflicts with zlib.h macros */
#ifdef ZLIB_COMPAT
}
}
if ((state->flags & 0x0200) && (state->wrap & 4)) {
- state->check = PREFIX(crc32)(state->check, next, copy);
+ state->check = crc32_small((uint32_t)state->check, next, copy);
}
have -= copy;
next += copy;
state->head->name[state->length++] = (unsigned char)len;
} while (len && copy < have);
if ((state->flags & 0x0200) && (state->wrap & 4))
- state->check = PREFIX(crc32)(state->check, next, copy);
+ state->check = crc32_small((uint32_t)state->check, next, copy);
have -= copy;
next += copy;
if (len)
state->head->comment[state->length++] = (unsigned char)len;
} while (len && copy < have);
if ((state->flags & 0x0200) && (state->wrap & 4))
- state->check = PREFIX(crc32)(state->check, next, copy);
+ state->check = crc32_small((uint32_t)state->check, next, copy);
have -= copy;
next += copy;
if (len)
#include "zendian.h"
#include "zmemory.h"
+#include "crc32_braid_tbl.h"
/* Architecture-specific hooks. */
#ifdef S390_DFLTCC_INFLATE
* Macros shared by inflate() and inflateBack()
*/
-/* check function to use adler32() for zlib or crc32() for gzip */
-#ifdef GUNZIP
-# define UPDATE(check, buf, len) \
- (state->flags ? PREFIX(crc32)(check, buf, len) : FUNCTABLE_CALL(adler32)(check, buf, len))
-#else
-# define UPDATE(check, buf, len) FUNCTABLE_CALL(adler32)(check, buf, len)
-#endif
-
/* check macros for header crc */
#ifdef GUNZIP
+# define CRC_DO1_B(c, b) c = crc_table[(c ^ (b)) & 0xff] ^ (c >> 8)
+
# define CRC2(check, word) \
do { \
- uint16_t tmp = Z_U16_TO_LE((uint16_t)(word)); \
- check = PREFIX(crc32)(check, (const unsigned char *)&tmp, 2); \
+ uint32_t crc = ~(uint32_t)(check); \
+ CRC_DO1_B(crc, (word) ); \
+ CRC_DO1_B(crc, (word) >> 8); \
+ (check) = ~crc; \
} while (0)
# define CRC4(check, word) \
do { \
- uint32_t tmp = Z_U32_TO_LE((uint32_t)(word)); \
- check = PREFIX(crc32)(check, (const unsigned char *)&tmp, 4); \
+ uint32_t crc = ~(uint32_t)(check); \
+ CRC_DO1_B(crc, (word) ); \
+ CRC_DO1_B(crc, (word) >> 8); \
+ CRC_DO1_B(crc, (word) >> 16); \
+ CRC_DO1_B(crc, (word) >> 24); \
+ (check) = ~crc; \
} while (0)
#endif