From: Eric Biggers Date: Sun, 8 Jun 2014 02:32:06 +0000 (-0500) Subject: lzms-compress.c: Don't underrun window when checking recent offsets X-Git-Tag: v1.7.0~53 X-Git-Url: https://wimlib.net/git/?p=wimlib;a=commitdiff_plain;h=cf8e2becfde288f6adb700a64d673b76791fbff2 lzms-compress.c: Don't underrun window when checking recent offsets In LZMS, not all recent offsets are initialized to 1, unlike in LZX. --- diff --git a/include/wimlib/lzms.h b/include/wimlib/lzms.h index 798b339c..76381a41 100644 --- a/include/wimlib/lzms.h +++ b/include/wimlib/lzms.h @@ -16,6 +16,7 @@ #endif #define LZMS_NUM_RECENT_OFFSETS 3 +#define LZMS_MAX_INIT_RECENT_OFFSET (LZMS_NUM_RECENT_OFFSETS + 1) #define LZMS_PROBABILITY_BITS 6 #define LZMS_PROBABILITY_MAX (1U << LZMS_PROBABILITY_BITS) diff --git a/src/lzms-compress.c b/src/lzms-compress.c index a4d45300..c6592a9f 100644 --- a/src/lzms-compress.c +++ b/src/lzms-compress.c @@ -888,7 +888,7 @@ lzms_get_near_optimal_match(struct lzms_compressor *ctx) ctx->optimum_end_idx = 0; longest_rep_len = ctx->params.min_match_length - 1; - if (lz_bt_get_position(&ctx->mf) >= 1) { + if (lz_bt_get_position(&ctx->mf) >= LZMS_MAX_INIT_RECENT_OFFSET) { u32 limit = min(ctx->params.max_match_length, lz_bt_get_remaining_size(&ctx->mf)); for (int i = 0; i < LZMS_NUM_RECENT_OFFSETS; i++) { @@ -984,18 +984,20 @@ lzms_get_near_optimal_match(struct lzms_compressor *ctx) return lzms_match_chooser_reverse_list(ctx, cur_pos); longest_rep_len = ctx->params.min_match_length - 1; - u32 limit = min(ctx->params.max_match_length, - lz_bt_get_remaining_size(&ctx->mf)); - for (int i = 0; i < LZMS_NUM_RECENT_OFFSETS; i++) { - u32 offset = ctx->optimum[cur_pos].state.lru.recent_offsets[i]; - const u8 *strptr = lz_bt_get_window_ptr(&ctx->mf); - const u8 *matchptr = strptr - offset; - u32 len = 0; - while (len < limit && strptr[len] == matchptr[len]) - len++; - if (len > longest_rep_len) { - longest_rep_len = len; - longest_rep_offset = offset; + if (lz_bt_get_position(&ctx->mf) >= LZMS_MAX_INIT_RECENT_OFFSET) { + u32 limit = min(ctx->params.max_match_length, + lz_bt_get_remaining_size(&ctx->mf)); + for (int i = 0; i < LZMS_NUM_RECENT_OFFSETS; i++) { + u32 offset = ctx->optimum[cur_pos].state.lru.recent_offsets[i]; + const u8 *strptr = lz_bt_get_window_ptr(&ctx->mf); + const u8 *matchptr = strptr - offset; + u32 len = 0; + while (len < limit && strptr[len] == matchptr[len]) + len++; + if (len > longest_rep_len) { + longest_rep_len = len; + longest_rep_offset = offset; + } } }