summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--match_tpl.h39
1 files changed, 22 insertions, 17 deletions
diff --git a/match_tpl.h b/match_tpl.h
index c8c2cad8e2..f321f700e2 100644
--- a/match_tpl.h
+++ b/match_tpl.h
@@ -29,20 +29,25 @@
* matches once a match has already been found.
*/
Z_INTERNAL uint32_t LONGEST_MATCH(deflate_state *const s, Pos cur_match) {
- unsigned int strstart = s->strstart;
const unsigned wmask = W_MASK(s);
- unsigned char *window = s->window;
- unsigned char *scan = window + strstart;
- Z_REGISTER unsigned char *mbase_start = window;
- Z_REGISTER unsigned char *mbase_end;
+ unsigned int strstart = s->strstart;
+ const unsigned char *window = s->window;
const Pos *prev = s->prev;
+#ifdef LONGEST_MATCH_SLOW
+ const Pos *head = s->head;
+#endif
+ const unsigned char *scan;
+ const unsigned char *mbase_start = window;
+ const unsigned char *mbase_end;
Pos limit;
#ifdef LONGEST_MATCH_SLOW
Pos limit_base;
#else
int32_t early_exit;
#endif
- uint32_t chain_length, nice_match, best_len, offset;
+ uint32_t chain_length = s->max_chain_length;
+ uint32_t nice_match = (uint32_t)s->nice_match;
+ uint32_t best_len, offset;
uint32_t lookahead = s->lookahead;
Pos match_offset = 0;
uint64_t scan_start;
@@ -51,6 +56,7 @@ Z_INTERNAL uint32_t LONGEST_MATCH(deflate_state *const s, Pos cur_match) {
/* The code is optimized for STD_MAX_MATCH-2 multiple of 16. */
Assert(STD_MAX_MATCH == 258, "Code too clever");
+ scan = window + strstart;
best_len = s->prev_length ? s->prev_length : STD_MIN_MATCH-1;
/* Calculate read offset which should only extend an extra byte
@@ -68,10 +74,8 @@ Z_INTERNAL uint32_t LONGEST_MATCH(deflate_state *const s, Pos cur_match) {
mbase_end = (mbase_start+offset);
/* Do not waste too much time if we already have a good match */
- chain_length = s->max_chain_length;
if (best_len >= s->good_match)
chain_length >>= 2;
- nice_match = (uint32_t)s->nice_match;
/* Stop when cur_match becomes <= limit. To simplify the code,
* we prevent matches with the string of window index 0
@@ -81,7 +85,7 @@ Z_INTERNAL uint32_t LONGEST_MATCH(deflate_state *const s, Pos cur_match) {
limit_base = limit;
if (best_len >= STD_MIN_MATCH) {
/* We're continuing search (lazy evaluation). */
- uint32_t i, hash;
+ uint32_t hash;
Pos pos;
/* Find a most distant chain starting from scan with index=1 (index=0 corresponds
@@ -92,11 +96,11 @@ Z_INTERNAL uint32_t LONGEST_MATCH(deflate_state *const s, Pos cur_match) {
hash = update_hash_roll(0, scan[1]);
hash = update_hash_roll(hash, scan[2]);
- for (i = 3; i <= best_len; i++) {
+ for (uint32_t i = 3; i <= best_len; i++) {
// use update_hash_roll for deflate_slow
hash = update_hash_roll(hash, scan[i]);
/* If we're starting with best_len >= 3, we can use offset search. */
- pos = s->head[hash];
+ pos = head[hash];
if (pos < cur_match) {
match_offset = (Pos)(i - 2);
cur_match = pos;
@@ -157,9 +161,10 @@ Z_INTERNAL uint32_t LONGEST_MATCH(deflate_state *const s, Pos cur_match) {
/* Do not look for matches beyond the end of the input. */
if (len > lookahead)
return lookahead;
+ if (len >= nice_match)
+ return len;
+
best_len = len;
- if (best_len >= nice_match)
- return best_len;
offset = best_len-1;
if (best_len >= sizeof(uint32_t)) {
@@ -173,15 +178,15 @@ Z_INTERNAL uint32_t LONGEST_MATCH(deflate_state *const s, Pos cur_match) {
#ifdef LONGEST_MATCH_SLOW
/* Look for a better string offset */
if (UNLIKELY(len > STD_MIN_MATCH && match_start + len < strstart)) {
+ const unsigned char *scan_endstr;
+ uint32_t hash;
Pos pos, next_pos;
- uint32_t i, hash;
- unsigned char *scan_endstr;
/* Go back to offset 0 */
cur_match -= match_offset;
match_offset = 0;
next_pos = cur_match;
- for (i = 0; i <= len - STD_MIN_MATCH; i++) {
+ for (uint32_t i = 0; i <= len - STD_MIN_MATCH; i++) {
pos = prev[(cur_match + i) & wmask];
if (pos < next_pos) {
/* Hash chain is more distant, use it */
@@ -206,7 +211,7 @@ Z_INTERNAL uint32_t LONGEST_MATCH(deflate_state *const s, Pos cur_match) {
hash = update_hash_roll(hash, scan_endstr[1]);
hash = update_hash_roll(hash, scan_endstr[2]);
- pos = s->head[hash];
+ pos = head[hash];
if (pos < cur_match) {
match_offset = (Pos)(len - (STD_MIN_MATCH+1));
if (pos <= limit_base + match_offset)