summaryrefslogtreecommitdiff
path: root/lib/uzlib/lz77.c
diff options
context:
space:
mode:
authorDamien George <damien@micropython.org>2023-11-29 11:40:21 +1100
committerDamien George <damien@micropython.org>2023-11-30 12:13:29 +1100
commit6ba57f760cfcfed64157ef7dd030d76738cb0e24 (patch)
tree5fa7f55dda61a96a1374e7f15733a230d9aae9c4 /lib/uzlib/lz77.c
parente182f3862e2c8ab731d169b70e83a6535c01a3f2 (diff)
lib/uzlib: For matches of the same length, take the closest one.
Signed-off-by: Damien George <damien@micropython.org>
Diffstat (limited to 'lib/uzlib/lz77.c')
-rw-r--r--lib/uzlib/lz77.c8
1 files changed, 6 insertions, 2 deletions
diff --git a/lib/uzlib/lz77.c b/lib/uzlib/lz77.c
index 117ce50f7..8d6920665 100644
--- a/lib/uzlib/lz77.c
+++ b/lib/uzlib/lz77.c
@@ -28,13 +28,13 @@ void uzlib_lz77_init(uzlib_lz77_state_t *state, uint8_t *hist, size_t hist_max)
state->hist_len = 0;
}
-// Push the given byte to the history.
// Search back in the history for the maximum match of the given src data,
// with support for searching beyond the end of the history and into the src buffer
// (effectively the history and src buffer are concatenated).
static size_t uzlib_lz77_search_max_match(uzlib_lz77_state_t *state, const uint8_t *src, size_t len, size_t *longest_offset) {
size_t longest_len = 0;
for (size_t hist_search = 0; hist_search < state->hist_len; ++hist_search) {
+ // Search for a match.
size_t match_len;
for (match_len = 0; match_len <= MATCH_LEN_MAX && match_len < len; ++match_len) {
uint8_t hist;
@@ -47,7 +47,11 @@ static size_t uzlib_lz77_search_max_match(uzlib_lz77_state_t *state, const uint8
break;
}
}
- if (match_len >= MATCH_LEN_MIN && match_len > longest_len) {
+
+ // Take this match if its length is at least the minimum, and larger than previous matches.
+ // If the length is the same as the previous longest then take this match as well, because
+ // this match will be closer (more recent in the history) and take less bits to encode.
+ if (match_len >= MATCH_LEN_MIN && match_len >= longest_len) {
longest_len = match_len;
*longest_offset = state->hist_len - hist_search;
}