X-Git-Url: http://git.zerfleddert.de/cgi-bin/gitweb.cgi/proxmark3-svn/blobdiff_plain/f39198789b82c1dd545743778f9d2633a2af8bd8..refs/pull/649/head:/zlib/deflate.c diff --git a/zlib/deflate.c b/zlib/deflate.c index 69695770..8e9a3e65 100644 --- a/zlib/deflate.c +++ b/zlib/deflate.c @@ -52,7 +52,7 @@ #include "deflate.h" const char deflate_copyright[] = - " deflate 1.2.8 Copyright 1995-2013 Jean-loup Gailly and Mark Adler "; + " deflate 1.2.8.f-Proxmark3 Copyright 1995-2013 Jean-loup Gailly and Mark Adler "; /* If you use the zlib library in a product, an acknowledgment is welcome in the documentation of your product. If for some reason you cannot @@ -60,6 +60,15 @@ const char deflate_copyright[] = copyright string in the executable of your product. */ +//----------------------------------------------------------------------------- +// This version of zlib is modified for use within the Proxmark3 project. +// Files from the original distribution which are not required for this +// purpose are not included. All modifications can easily be found +// by searching for #ifdef ZLIB_PM3_TUNED and #ifndef ZLIB_PM3_TUNED. +//----------------------------------------------------------------------------- + + + /* =========================================================================== * Function prototypes. */ @@ -1153,7 +1162,11 @@ local uInt longest_match(s, cur_match) register Bytef *scan = s->window + s->strstart; /* current string */ register Bytef *match; /* matched string */ register int len; /* length of current match */ +#ifdef ZLIB_PM3_TUNED + int best_len = MIN_MATCH-1; // lift the restriction on prev-length +#else int best_len = s->prev_length; /* best match length so far */ +#endif int nice_match = s->nice_match; /* stop if match long enough */ IPos limit = s->strstart > (IPos)MAX_DIST(s) ? s->strstart - (IPos)MAX_DIST(s) : NIL; @@ -1721,6 +1734,81 @@ local block_state deflate_fast(s, flush) return block_done; } + +#ifdef ZLIB_PM3_TUNED +local uInt try_harder(s, strstart, lookahead, hash_head) + deflate_state *s; + uInt strstart; + uInt lookahead; + IPos hash_head; +{ + uInt strstart_save = s->strstart; + s->strstart = strstart; + uInt lookahead_save = s->lookahead; + s->lookahead = lookahead; + uInt ins_h_save = s->ins_h; + uInt combined_gain; + uInt best_combined_gain = 0; + uInt match_length; + uInt prev_length = s->prev_length < MIN_MATCH ? 1 : s->prev_length; + uInt best_prev_length = prev_length; + uInt current_match_start = s->match_start; + uInt current_match_length = s->match_length; + + do { + if (hash_head != NIL && s->strstart - hash_head <= MAX_DIST(s)) { + match_length = longest_match (s, hash_head); + /* longest_match() sets match_start */ + } else { + match_length = MIN_MATCH - 1; + } +#if TOO_FAR <= 32767 + if (match_length == MIN_MATCH && s->strstart - s->match_start > TOO_FAR) { + match_length = MIN_MATCH-1; + } +#endif + if (s->strstart == strstart) { // store match at current position + current_match_length = match_length; + current_match_start = s->match_start; + } + if (s->strstart - strstart + 1 < MIN_MATCH) { // previous match reduced to one or two literals + combined_gain = 0; // need one literal per byte: no gain (assuming 8 bits per literal) + } else { + combined_gain = s->strstart - strstart + 1 - MIN_MATCH; // (possibly truncated) previous_length - 3 literals + } + if (match_length < MIN_MATCH) { + combined_gain += 0; // no gain + } else { + combined_gain += match_length - MIN_MATCH; // match_length bytes are coded as three literals + } + if (combined_gain >= best_combined_gain) { // in case of a tie we prefer the longer prev_length + best_combined_gain = combined_gain; + best_prev_length = s->strstart - strstart + 1; + } + s->strstart++; + s->lookahead--; + UPDATE_HASH(s, s->ins_h, s->window[(s->strstart) + (MIN_MATCH-1)]); + hash_head = s->head[s->ins_h]; + } while (s->strstart <= strstart-1 + prev_length // try to truncate the previous match to 1, 3, ... prev_length + && s->strstart <= s->window_size - MIN_LOOKAHEAD); // watch out for the end of the input + + s->strstart = strstart_save; + s->lookahead = lookahead_save; + s->ins_h = ins_h_save; + s->match_length = current_match_length; + s->match_start = current_match_start; + if (best_prev_length >= MIN_MATCH) { + s->prev_length = best_prev_length; + s->match_length = MIN_MATCH - 1; + } else { + s->prev_length = MIN_MATCH - 1; + } + return best_combined_gain; +} +#endif + + + #ifndef FASTEST /* =========================================================================== * Same as above, but achieves better compression. We use a lazy @@ -1757,11 +1845,16 @@ local block_state deflate_slow(s, flush) INSERT_STRING(s, s->strstart, hash_head); } - /* Find the longest match, discarding those <= prev_length. - */ + /* Find the longest match, discarding those <= prev_length. */ s->prev_length = s->match_length, s->prev_match = s->match_start; s->match_length = MIN_MATCH-1; +#ifdef ZLIB_PM3_TUNED + if (s->prev_length < s->max_lazy_match) { + try_harder(s, s->strstart, s->lookahead, hash_head); + } + +#else if (hash_head != NIL && s->prev_length < s->max_lazy_match && s->strstart - hash_head <= MAX_DIST(s)) { /* To simplify the code, we prevent matches with the string @@ -1784,6 +1877,7 @@ local block_state deflate_slow(s, flush) s->match_length = MIN_MATCH-1; } } +#endif /* ZLIB_PM3_TUNED */ /* If there was a match at the previous step and the current * match is not better, output the previous match: */