s->update_hash = &update_hash_roll;
s->insert_string = &insert_string_roll;
s->quick_insert_string = &quick_insert_string_roll;
+ s->quick_insert_value = &quick_insert_value_roll;
} else {
s->update_hash = update_hash;
s->insert_string = insert_string;
s->quick_insert_string = quick_insert_string;
+ s->quick_insert_value = quick_insert_value;
}
s->level = level;
typedef uint32_t (* update_hash_cb) (uint32_t h, uint32_t val);
typedef void (* insert_string_cb) (deflate_state *const s, uint32_t str, uint32_t count);
typedef Pos (* quick_insert_string_cb)(deflate_state *const s, uint32_t str);
+typedef Pos (* quick_insert_value_cb) (deflate_state *const s, uint32_t str, uint32_t val);
uint32_t update_hash (uint32_t h, uint32_t val);
void insert_string (deflate_state *const s, uint32_t str, uint32_t count);
Pos quick_insert_string (deflate_state *const s, uint32_t str);
+Pos quick_insert_value (deflate_state *const s, uint32_t str, uint32_t val);
uint32_t update_hash_roll (uint32_t h, uint32_t val);
void insert_string_roll (deflate_state *const s, uint32_t str, uint32_t count);
Pos quick_insert_string_roll(deflate_state *const s, uint32_t str);
+Pos quick_insert_value_roll (deflate_state *const s, uint32_t str, uint32_t val);
/* Struct for memory allocation handling */
typedef struct deflate_allocs_s {
update_hash_cb update_hash;
insert_string_cb insert_string;
quick_insert_string_cb quick_insert_string;
+ quick_insert_value_cb quick_insert_value;
/* Hash function callbacks that can be configured depending on the deflate
* algorithm being used */
*/
#include "zbuild.h"
+#include "zmemory.h"
#include "deflate.h"
#include "deflate_p.h"
#include "functable.h"
uint32_t match_len = 0;
for (;;) {
+ uint8_t lc;
+
/* Make sure that we always have enough lookahead, except
* at the end of the input file. We need STD_MAX_MATCH bytes
* for the next match, plus WANT_MIN_MATCH bytes to insert the
* dictionary, and set hash_head to the head of the hash chain:
*/
if (s->lookahead >= WANT_MIN_MATCH) {
- Pos hash_head = quick_insert_string(s, s->strstart);
+#if BYTE_ORDER == LITTLE_ENDIAN
+ uint32_t str_val = zng_memread_4(&s->window[s->strstart]);
+#else
+ uint32_t str_val = ZSWAP32(zng_memread_4(&s->window[s->strstart]));
+#endif
+ Pos hash_head = quick_insert_value(s, s->strstart, str_val);
int64_t dist = (int64_t)s->strstart - hash_head;
+ lc = (uint8_t)str_val;
/* Find the longest match, discarding those <= prev_length.
* At this point we have always match length < WANT_MIN_MATCH
match_len = FUNCTABLE_CALL(longest_match)(s, hash_head);
/* longest_match() sets match_start */
}
+ } else {
+ lc = s->window[s->strstart];
}
if (match_len >= WANT_MIN_MATCH) {
match_len = 0;
} else {
/* No match, output a literal byte */
- bflush = zng_tr_tally_lit(s, s->window[s->strstart]);
+ bflush = zng_tr_tally_lit(s, lc);
s->lookahead--;
s->strstart++;
}
}
for (;;) {
+ uint8_t lc;
+
if (UNLIKELY(s->pending + ((BIT_BUF_SIZE + 7) >> 3) >= s->pending_buf_size)) {
PREFIX(flush_pending)(s->strm);
if (s->strm->avail_out == 0) {
}
if (LIKELY(s->lookahead >= WANT_MIN_MATCH)) {
- Pos hash_head = quick_insert_string(s, s->strstart);
+#if BYTE_ORDER == LITTLE_ENDIAN
+ uint32_t str_val = zng_memread_4(&s->window[s->strstart]);
+#else
+ uint32_t str_val = ZSWAP32(zng_memread_4(&s->window[s->strstart]));
+#endif
+ Pos hash_head = quick_insert_value(s, s->strstart, str_val);
int64_t dist = (int64_t)s->strstart - hash_head;
+ lc = (uint8_t)str_val;
if (dist <= MAX_DIST(s) && dist > 0) {
- const uint8_t *str_start = s->window + s->strstart;
const uint8_t *match_start = s->window + hash_head;
-
- if (zng_memcmp_2(str_start, match_start) == 0) {
+#if BYTE_ORDER == LITTLE_ENDIAN
+ uint32_t match_val = zng_memread_4(match_start);
+#else
+ uint32_t match_val = ZSWAP32(zng_memread_4(match_start));
+#endif
+
+ if (str_val == match_val) {
+ const uint8_t *str_start = s->window + s->strstart;
uint32_t match_len = FUNCTABLE_CALL(compare256)(str_start+2, match_start+2) + 2;
if (match_len >= WANT_MIN_MATCH) {
}
}
}
+ } else {
+ lc = s->window[s->strstart];
}
-
- zng_tr_emit_lit(s, static_ltree, s->window[s->strstart]);
+ zng_tr_emit_lit(s, static_ltree, lc);
s->strstart++;
s->lookahead--;
}
#define UPDATE_HASH update_hash
#define INSERT_STRING insert_string
#define QUICK_INSERT_STRING quick_insert_string
+#define QUICK_INSERT_VALUE quick_insert_value
#include "insert_string_tpl.h"
#define UPDATE_HASH update_hash_roll
#define INSERT_STRING insert_string_roll
#define QUICK_INSERT_STRING quick_insert_string_roll
+#define QUICK_INSERT_VALUE quick_insert_value_roll
#include "insert_string_tpl.h"
return h & HASH_CALC_MASK;
}
+/* ===========================================================================
+ * Quick insert string str in the dictionary using a pre-read value and set match_head
+ * to the previous head of the hash chain (the most recent string with same hash key).
+ * Return the previous length of the hash chain.
+ */
+Z_INTERNAL Pos QUICK_INSERT_VALUE(deflate_state *const s, uint32_t str, uint32_t val) {
+ uint32_t hm;
+ Pos head;
+
+ HASH_CALC_VAR_INIT;
+ HASH_CALC(HASH_CALC_VAR, val);
+ HASH_CALC_VAR &= HASH_CALC_MASK;
+ hm = HASH_CALC_VAR;
+
+ head = s->head[hm];
+ if (LIKELY(head != str)) {
+ s->prev[str & s->w_mask] = head;
+ s->head[hm] = (Pos)str;
+ }
+ return head;
+}
+
/* ===========================================================================
* Quick insert string str in the dictionary and set match_head to the previous head
* of the hash chain (the most recent string with same hash key). Return