From 1c766dbf67fdae3f1f7be25b4af9995e00adcd35 Mon Sep 17 00:00:00 2001 From: Nathan Moinvaziri Date: Mon, 14 Jun 2021 17:36:55 -0700 Subject: [PATCH] Setup hash functions to be switched based on compression level. --- deflate.c | 33 ++++++++++++++++++++++----------- deflate.h | 16 ++++++++++++++-- deflate_slow.c | 5 ++--- 3 files changed, 38 insertions(+), 16 deletions(-) diff --git a/deflate.c b/deflate.c index 466e6e9b..e361b383 100644 --- a/deflate.c +++ b/deflate.c @@ -113,6 +113,7 @@ Z_INTERNAL block_state deflate_medium(deflate_state *s, int flush); Z_INTERNAL block_state deflate_slow (deflate_state *s, int flush); Z_INTERNAL block_state deflate_rle (deflate_state *s, int flush); Z_INTERNAL block_state deflate_huff (deflate_state *s, int flush); +static void lm_set_level (deflate_state *s, int level); static void lm_init (deflate_state *s); Z_INTERNAL unsigned read_buf (PREFIX3(stream) *strm, unsigned char *buf, unsigned size); @@ -602,11 +603,8 @@ int32_t Z_EXPORT PREFIX(deflateParams)(PREFIX3(stream) *strm, int32_t level, int } s->matches = 0; } - s->level = level; - s->max_lazy_match = configuration_table[level].max_lazy; - s->good_match = configuration_table[level].good_length; - s->nice_match = configuration_table[level].nice_length; - s->max_chain_length = configuration_table[level].max_chain; + + lm_set_level(s, level); } s->strategy = strategy; return Z_OK; @@ -1140,6 +1138,22 @@ Z_INTERNAL unsigned read_buf(PREFIX3(stream) *strm, unsigned char *buf, unsigned return len; } +/* =========================================================================== + * Set longest match variables based on level configuration + */ +static void lm_set_level(deflate_state *s, int level) { + s->max_lazy_match = configuration_table[level].max_lazy; + s->good_match = configuration_table[level].good_length; + s->nice_match = configuration_table[level].nice_length; + s->max_chain_length = configuration_table[level].max_chain; + + s->update_hash = functable.update_hash; + s->insert_string = functable.insert_string; + s->quick_insert_string = functable.quick_insert_string; + + s->level = level; +} + /* =========================================================================== * Initialize the "longest match" routines for a new zlib stream */ @@ -1150,10 +1164,7 @@ static void lm_init(deflate_state *s) { /* Set the default configuration parameters: */ - s->max_lazy_match = configuration_table[s->level].max_lazy; - s->good_match = configuration_table[s->level].good_length; - s->nice_match = configuration_table[s->level].nice_length; - s->max_chain_length = configuration_table[s->level].max_chain; + lm_set_level(s, s->level); s->strstart = 0; s->block_start = 0; @@ -1227,7 +1238,7 @@ void Z_INTERNAL fill_window(deflate_state *s) { if (s->lookahead + s->insert >= STD_MIN_MATCH) { unsigned int str = s->strstart - s->insert; if (str >= 1) - functable.quick_insert_string(s, str + 2 - STD_MIN_MATCH); + s->quick_insert_string(s, str + 2 - STD_MIN_MATCH); unsigned int count; if (UNLIKELY(s->lookahead == 1)) { count = s->insert - 1; @@ -1235,7 +1246,7 @@ void Z_INTERNAL fill_window(deflate_state *s) { count = s->insert; } if (count > 0) { - functable.insert_string(s, str, count); + s->insert_string(s, str, count); s->insert -= count; } } diff --git a/deflate.h b/deflate.h index 808060a3..0a50afe2 100644 --- a/deflate.h +++ b/deflate.h @@ -99,8 +99,14 @@ typedef uint16_t Pos; /* A Pos is an index in the character window. We use short instead of int to * save space in the various tables. */ +/* Type definitions for hash callbacks */ +typedef struct internal_state deflate_state; -typedef struct internal_state { +typedef uint32_t (* update_hash_cb) (deflate_state *const s, 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); + +struct internal_state { PREFIX3(stream) *strm; /* pointer back to this zlib stream */ unsigned char *pending_buf; /* output still pending */ unsigned char *pending_out; /* next pending byte to output to the stream */ @@ -188,6 +194,12 @@ typedef struct internal_state { * max_insert_length is used only for compression levels <= 3. */ + update_hash_cb update_hash; + insert_string_cb insert_string; + quick_insert_string_cb quick_insert_string; + /* Hash function callbacks that can be configured depending on the deflate + * algorithm being used */ + int level; /* compression level (1..9) */ int strategy; /* favor or force Huffman coding*/ @@ -269,7 +281,7 @@ typedef struct internal_state { /* Reserved for future use and alignment purposes */ int32_t reserved[11]; -} ALIGNED_(8) deflate_state; +} ALIGNED_(8); typedef enum { need_more, /* block not completed, need more input or more output */ diff --git a/deflate_slow.c b/deflate_slow.c index ac7e87ee..0cb40f5c 100644 --- a/deflate_slow.c +++ b/deflate_slow.c @@ -41,7 +41,7 @@ Z_INTERNAL block_state deflate_slow(deflate_state *s, int flush) { */ hash_head = 0; if (LIKELY(s->lookahead >= WANT_MIN_MATCH)) { - hash_head = functable.quick_insert_string(s, s->strstart); + hash_head = s->quick_insert_string(s, s->strstart); } /* Find the longest match, discarding those <= prev_length. @@ -88,8 +88,7 @@ Z_INTERNAL block_state deflate_slow(deflate_state *s, int flush) { unsigned int insert_cnt = mov_fwd; if (UNLIKELY(insert_cnt > max_insert - s->strstart)) insert_cnt = max_insert - s->strstart; - - functable.insert_string(s, s->strstart + 1, insert_cnt); + s->insert_string(s, s->strstart + 1, insert_cnt); } s->prev_length = 0; s->match_available = 0; -- 2.47.3