X-Git-Url: https://wimlib.net/git/?a=blobdiff_plain;f=src%2Flzms-compress.c;h=0567ea392fd46ea9ad23ef9739aa619764f22a2a;hb=41c221c509deed7dc9c2bd8eb8c7e93563b21199;hp=c6592a9f605598e02a25fd306570333decf23d88;hpb=cf8e2becfde288f6adb700a64d673b76791fbff2;p=wimlib diff --git a/src/lzms-compress.c b/src/lzms-compress.c index c6592a9f..0567ea39 100644 --- a/src/lzms-compress.c +++ b/src/lzms-compress.c @@ -175,7 +175,7 @@ struct lzms_compressor { struct lz_bt mf; /* Temporary space to store found matches. */ - struct raw_match *matches; + struct lz_match *matches; /* Match-chooser data. */ struct lzms_mc_pos_data *optimum; @@ -726,7 +726,7 @@ lzms_offset_cost(const struct lzms_huffman_encoder *enc, u32 offset) } static u32 -lzms_length_cost(const struct lzms_huffman_encoder *enc, u32 length) +lzms_get_length_cost(const struct lzms_huffman_encoder *enc, u32 length) { u32 slot; u32 num_extra_bits; @@ -744,7 +744,7 @@ lzms_length_cost(const struct lzms_huffman_encoder *enc, u32 length) } static u32 -lzms_get_matches(struct lzms_compressor *ctx, struct raw_match **matches_ret) +lzms_get_matches(struct lzms_compressor *ctx, struct lz_match **matches_ret) { *matches_ret = ctx->matches; return lz_bt_get_matches(&ctx->mf, ctx->matches); @@ -774,9 +774,8 @@ lzms_get_literal_cost(struct lzms_compressor *ctx, } static u32 -lzms_get_lz_match_cost(struct lzms_compressor *ctx, - struct lzms_adaptive_state *state, - u32 length, u32 offset) +lzms_get_lz_match_cost_nolen(struct lzms_compressor *ctx, + struct lzms_adaptive_state *state, u32 offset) { u32 cost = 0; int recent_offset_idx; @@ -819,7 +818,6 @@ lzms_get_lz_match_cost(struct lzms_compressor *ctx, state->lru.recent_offsets[i] = state->lru.recent_offsets[i + 1]; } - cost += lzms_length_cost(&ctx->length_encoder, length); state->lru.upcoming_offset = offset; lzms_update_lz_lru_queues(&state->lru); @@ -827,7 +825,16 @@ lzms_get_lz_match_cost(struct lzms_compressor *ctx, return cost; } -static struct raw_match +static u32 +lzms_get_lz_match_cost(struct lzms_compressor *ctx, + struct lzms_adaptive_state *state, + u32 length, u32 offset) +{ + return lzms_get_lz_match_cost_nolen(ctx, state, offset) + + lzms_get_length_cost(&ctx->length_encoder, length); +} + +static struct lz_match lzms_match_chooser_reverse_list(struct lzms_compressor *ctx, unsigned cur_pos) { unsigned prev_link, saved_prev_link; @@ -853,7 +860,7 @@ lzms_match_chooser_reverse_list(struct lzms_compressor *ctx, unsigned cur_pos) ctx->optimum_cur_idx = ctx->optimum[0].next.link; - return (struct raw_match) + return (struct lz_match) { .len = ctx->optimum_cur_idx, .offset = ctx->optimum[0].next.match_offset, }; @@ -861,16 +868,15 @@ lzms_match_chooser_reverse_list(struct lzms_compressor *ctx, unsigned cur_pos) /* This is similar to lzx_get_near_optimal_match() in lzx-compress.c. * Read that one if you want to understand it. */ -static struct raw_match +static struct lz_match lzms_get_near_optimal_match(struct lzms_compressor *ctx) { u32 num_matches; - struct raw_match *matches; - struct raw_match match; + struct lz_match *matches; + struct lz_match match; u32 longest_len; u32 longest_rep_len; u32 longest_rep_offset; - struct raw_match *matchptr; unsigned cur_pos; unsigned end_pos; struct lzms_adaptive_state initial_state; @@ -907,7 +913,7 @@ lzms_get_near_optimal_match(struct lzms_compressor *ctx) if (longest_rep_len >= ctx->params.nice_match_length) { lzms_skip_bytes(ctx, longest_rep_len); - return (struct raw_match) { + return (struct lz_match) { .len = longest_rep_len, .offset = longest_rep_offset, }; @@ -938,18 +944,26 @@ lzms_get_near_optimal_match(struct lzms_compressor *ctx) *(lz_bt_get_window_ptr(&ctx->mf) - 1)); ctx->optimum[1].prev.link = 0; - matchptr = matches; - for (u32 len = 2; len <= longest_len; len++) { - u32 offset = matchptr->offset; - - ctx->optimum[len].state = initial_state; - ctx->optimum[len].prev.link = 0; - ctx->optimum[len].prev.match_offset = offset; - ctx->optimum[len].cost = lzms_get_lz_match_cost(ctx, - &ctx->optimum[len].state, - len, offset); - if (len == matchptr->len) - matchptr++; + for (u32 i = 0, len = 2; i < num_matches; i++) { + u32 offset = matches[i].offset; + struct lzms_adaptive_state state; + u32 position_cost; + + state = initial_state; + position_cost = 0; + position_cost += lzms_get_lz_match_cost_nolen(ctx, &state, offset); + + do { + u32 cost; + + cost = position_cost; + cost += lzms_get_length_cost(&ctx->length_encoder, len); + + ctx->optimum[len].state = state; + ctx->optimum[len].prev.link = 0; + ctx->optimum[len].prev.match_offset = offset; + ctx->optimum[len].cost = cost; + } while (++len <= matches[i].len); } end_pos = longest_len; @@ -1047,23 +1061,28 @@ lzms_get_near_optimal_match(struct lzms_compressor *ctx) ctx->optimum[cur_pos + 1].prev.link = cur_pos; } - matchptr = matches; - for (u32 len = 2; len <= longest_len; len++) { - u32 offset; + for (u32 i = 0, len = 2; i < num_matches; i++) { + u32 offset = matches[i].offset; + struct lzms_adaptive_state state; + u32 position_cost; - offset = matchptr->offset; state = ctx->optimum[cur_pos].state; + position_cost = ctx->optimum[cur_pos].cost; + position_cost += lzms_get_lz_match_cost_nolen(ctx, &state, offset); - cost = ctx->optimum[cur_pos].cost + - lzms_get_lz_match_cost(ctx, &state, len, offset); - if (cost < ctx->optimum[cur_pos + len].cost) { - ctx->optimum[cur_pos + len].state = state; - ctx->optimum[cur_pos + len].prev.link = cur_pos; - ctx->optimum[cur_pos + len].prev.match_offset = offset; - ctx->optimum[cur_pos + len].cost = cost; - } - if (len == matchptr->len) - matchptr++; + do { + u32 cost; + + cost = position_cost; + cost += lzms_get_length_cost(&ctx->length_encoder, len); + + if (cost < ctx->optimum[cur_pos + len].cost) { + ctx->optimum[cur_pos + len].state = state; + ctx->optimum[cur_pos + len].prev.link = cur_pos; + ctx->optimum[cur_pos + len].prev.match_offset = offset; + ctx->optimum[cur_pos + len].cost = cost; + } + } while (++len <= matches[i].len); } if (longest_rep_len >= ctx->params.min_match_length) { @@ -1112,7 +1131,7 @@ lzms_get_near_optimal_match(struct lzms_compressor *ctx) static void lzms_encode(struct lzms_compressor *ctx) { - struct raw_match match; + struct lz_match match; /* Load window into the binary tree match-finder. */ lz_bt_load_window(&ctx->mf, ctx->window, ctx->window_size);