aboutsummaryrefslogtreecommitdiff
path: root/src/liblzma/lzma/lzma_encoder_getoptimum.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/liblzma/lzma/lzma_encoder_getoptimum.c')
-rw-r--r--src/liblzma/lzma/lzma_encoder_getoptimum.c59
1 files changed, 47 insertions, 12 deletions
diff --git a/src/liblzma/lzma/lzma_encoder_getoptimum.c b/src/liblzma/lzma/lzma_encoder_getoptimum.c
index 535508ee..b175e4cb 100644
--- a/src/liblzma/lzma/lzma_encoder_getoptimum.c
+++ b/src/liblzma/lzma/lzma_encoder_getoptimum.c
@@ -104,6 +104,36 @@ do { \
static void
+fill_length_prices(lzma_length_encoder *lc, uint32_t pos_state)
+{
+ const uint32_t num_symbols = lc->table_size;
+ const uint32_t a0 = bit_get_price_0(lc->choice);
+ const uint32_t a1 = bit_get_price_1(lc->choice);
+ const uint32_t b0 = a1 + bit_get_price_0(lc->choice2);
+ const uint32_t b1 = a1 + bit_get_price_1(lc->choice2);
+
+ uint32_t *prices = lc->prices[pos_state];
+ uint32_t i = 0;
+
+ for (i = 0; i < num_symbols && i < LEN_LOW_SYMBOLS; ++i)
+ prices[i] = a0 + bittree_get_price(lc->low[pos_state],
+ LEN_LOW_BITS, i);
+
+ for (; i < num_symbols && i < LEN_LOW_SYMBOLS + LEN_MID_SYMBOLS; ++i)
+ prices[i] = b0 + bittree_get_price(lc->mid[pos_state],
+ LEN_MID_BITS, i - LEN_LOW_SYMBOLS);
+
+ for (; i < num_symbols; ++i)
+ prices[i] = b1 + bittree_get_price(lc->high, LEN_HIGH_BITS,
+ i - LEN_LOW_SYMBOLS - LEN_MID_SYMBOLS);
+
+ lc->counters[pos_state] = num_symbols;
+
+ return;
+}
+
+
+static void
fill_distances_prices(lzma_coder *coder)
{
uint32_t temp_prices[FULL_DISTANCES];
@@ -254,6 +284,9 @@ extern void
lzma_get_optimum(lzma_coder *restrict coder,
uint32_t *restrict back_res, uint32_t *restrict len_res)
{
+ uint32_t position = coder->now_pos;
+ uint32_t pos_state = position & coder->pos_mask;
+
// Update the price tables. In the C++ LZMA SDK 4.42 this was done in both
// initialization function and in the main loop. In liblzma they were
// moved into this single place.
@@ -265,6 +298,13 @@ lzma_get_optimum(lzma_coder *restrict coder,
fill_align_prices(coder);
}
+ if (coder->prev_len_encoder != NULL) {
+ if (--coder->prev_len_encoder->counters[pos_state] == 0)
+ fill_length_prices(coder->prev_len_encoder, pos_state);
+
+ coder->prev_len_encoder = NULL;
+ }
+
if (coder->optimum_end_index != coder->optimum_current_index) {
*len_res = coder->optimum[coder->optimum_current_index].pos_prev
@@ -312,7 +352,7 @@ lzma_get_optimum(lzma_coder *restrict coder,
uint32_t rep_max_index = 0;
for (uint32_t i = 0; i < REP_DISTANCES; ++i) {
- reps[i] = coder->rep_distances[i];
+ reps[i] = coder->reps[i];
const uint32_t back_offset = reps[i] + 1;
if (buf[0] != *(buf - back_offset)
@@ -356,13 +396,8 @@ lzma_get_optimum(lzma_coder *restrict coder,
return;
}
- const uint32_t pos_mask = coder->pos_mask;
-
coder->optimum[0].state = coder->state;
- uint32_t position = coder->now_pos;
- uint32_t pos_state = (position & pos_mask);
-
coder->optimum[1].price = bit_get_price_0(
coder->is_match[coder->state][pos_state])
+ literal_get_price(
@@ -575,7 +610,7 @@ lzma_get_optimum(lzma_coder *restrict coder,
current_byte = *buf;
match_byte = *(buf - reps[0] - 1);
- pos_state = position & pos_mask;
+ pos_state = position & coder->pos_mask;
const uint32_t cur_and_1_price = cur_price
+ bit_get_price_0(coder->is_match[state][pos_state])
@@ -640,7 +675,7 @@ lzma_get_optimum(lzma_coder *restrict coder,
uint32_t state_2 = state;
update_literal(state_2);
- const uint32_t pos_state_next = (position + 1) & pos_mask;
+ const uint32_t pos_state_next = (position + 1) & coder->pos_mask;
const uint32_t next_rep_match_price = cur_and_1_price
+ bit_get_price_1(coder->is_match[state_2][pos_state_next])
+ bit_get_price_1(coder->is_rep[state_2]);
@@ -719,7 +754,7 @@ lzma_get_optimum(lzma_coder *restrict coder,
uint32_t state_2 = state;
update_long_rep(state_2);
- uint32_t pos_state_next = (position + len_test) & pos_mask;
+ uint32_t pos_state_next = (position + len_test) & coder->pos_mask;
const uint32_t cur_and_len_char_price = price
+ length_get_price(coder->rep_len_encoder,
@@ -732,7 +767,7 @@ lzma_get_optimum(lzma_coder *restrict coder,
update_literal(state_2);
- pos_state_next = (position + len_test + 1) & pos_mask;
+ pos_state_next = (position + len_test + 1) & coder->pos_mask;
const uint32_t next_rep_match_price = cur_and_len_char_price
+ bit_get_price_1(coder->is_match[state_2][pos_state_next])
@@ -829,7 +864,7 @@ lzma_get_optimum(lzma_coder *restrict coder,
uint32_t state_2 = state;
update_match(state_2);
uint32_t pos_state_next
- = (position + len_test) & pos_mask;
+ = (position + len_test) & coder->pos_mask;
const uint32_t cur_and_len_char_price = cur_and_len_price
+ bit_get_price_0(
@@ -844,7 +879,7 @@ lzma_get_optimum(lzma_coder *restrict coder,
buf[len_test]);
update_literal(state_2);
- pos_state_next = (pos_state_next + 1) & pos_mask;
+ pos_state_next = (pos_state_next + 1) & coder->pos_mask;
const uint32_t next_rep_match_price
= cur_and_len_char_price