1 ///////////////////////////////////////////////////////////////////////////////
3 /// \file lzma_encoder_getoptimum.c
5 // Copyright (C) 1999-2006 Igor Pavlov
6 // Copyright (C) 2007 Lasse Collin
8 // This library is free software; you can redistribute it and/or
9 // modify it under the terms of the GNU Lesser General Public
10 // License as published by the Free Software Foundation; either
11 // version 2.1 of the License, or (at your option) any later version.
13 // This library is distributed in the hope that it will be useful,
14 // but WITHOUT ANY WARRANTY; without even the implied warranty of
15 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 // Lesser General Public License for more details.
18 ///////////////////////////////////////////////////////////////////////////////
20 // NOTE: If you want to keep the line length in 80 characters, set
21 // tab width to 4 or less in your editor when editing this file.
24 // "Would you love the monster code?
25 // Could you understand beauty of the beast?"
26 // --Adapted from Lordi's "Would you love a monster man".
29 #include "lzma_encoder_private.h"
32 #define length_get_price(length_encoder, symbol, pos_state) \
33 (length_encoder).prices[pos_state][symbol]
36 #define get_rep_len_1_price(state, pos_state) \
37 bit_get_price_0(coder->is_rep0[state]) \
38 + bit_get_price_0(coder->is_rep0_long[state][pos_state])
41 // Adds to price_target.
42 #define get_pure_rep_price(price_target, rep_index, state, pos_state) \
44 if ((rep_index) == 0) { \
45 price_target += bit_get_price_0(coder->is_rep0[state]); \
46 price_target += bit_get_price_1( \
47 coder->is_rep0_long[state][pos_state]); \
49 price_target += bit_get_price_1(coder->is_rep0[state]); \
50 if ((rep_index) == 1) { \
51 price_target += bit_get_price_0(coder->is_rep1[state]); \
53 price_target += bit_get_price_1(coder->is_rep1[state]); \
54 price_target += bit_get_price( \
55 coder->is_rep2[state], (rep_index) - 2); \
61 // Adds to price_target.
62 #define get_rep_price(price_target, rep_index, len, state, pos_state) \
64 get_pure_rep_price(price_target, rep_index, state, pos_state); \
65 price_target += length_get_price(coder->rep_match_len_encoder, \
66 (len) - MATCH_MIN_LEN, pos_state); \
70 // Adds to price_target.
71 #define get_pos_len_price(price_target, pos, len, pos_state) \
73 const uint32_t len_to_pos_state_tmp = get_len_to_pos_state(len); \
74 if ((pos) < FULL_DISTANCES) { \
75 price_target += distances_prices[len_to_pos_state_tmp][pos]; \
78 += pos_slot_prices[len_to_pos_state_tmp][get_pos_slot_2(pos)] \
79 + align_prices[(pos) & ALIGN_MASK]; \
81 price_target += length_get_price( \
82 coder->len_encoder, (len) - MATCH_MIN_LEN, pos_state); \
86 // Three macros to manipulate lzma_optimal structures:
87 #define make_as_char(opt) \
89 (opt).back_prev = UINT32_MAX; \
90 (opt).prev_1_is_char = false; \
94 #define make_as_short_rep(opt) \
96 (opt).back_prev = 0; \
97 (opt).prev_1_is_char = false; \
101 #define is_short_rep(opt) \
102 ((opt).back_prev == 0)
106 fill_distances_prices(lzma_coder *coder)
108 uint32_t temp_prices[FULL_DISTANCES];
110 for (uint32_t i = START_POS_MODEL_INDEX; i < FULL_DISTANCES; ++i) {
111 const uint32_t pos_slot = get_pos_slot(i);
112 const uint32_t footer_bits = ((pos_slot >> 1) - 1);
113 const uint32_t base = (2 | (pos_slot & 1)) << footer_bits;
115 bittree_reverse_get_price(temp_prices[i],
116 coder->pos_encoders + base - pos_slot - 1,
117 footer_bits, i - base);
120 const uint32_t dist_table_size = coder->dist_table_size;
122 for (uint32_t len_to_pos_state = 0;
123 len_to_pos_state < LEN_TO_POS_STATES;
124 ++len_to_pos_state) {
126 const probability *encoder = coder->pos_slot_encoder[len_to_pos_state];
127 uint32_t *pos_slot_prices = coder->pos_slot_prices[len_to_pos_state];
129 for (uint32_t pos_slot = 0;
130 pos_slot < dist_table_size;
132 pos_slot_prices[pos_slot] = 0;
133 bittree_get_price(pos_slot_prices[pos_slot], encoder,
134 POS_SLOT_BITS, pos_slot);
137 for (uint32_t pos_slot = END_POS_MODEL_INDEX;
138 pos_slot < dist_table_size;
140 pos_slot_prices[pos_slot] += (((pos_slot >> 1) - 1)
141 - ALIGN_BITS) << BIT_PRICE_SHIFT_BITS;
144 uint32_t *distances_prices
145 = coder->distances_prices[len_to_pos_state];
148 for (i = 0; i < START_POS_MODEL_INDEX; ++i)
149 distances_prices[i] = pos_slot_prices[i];
151 for (; i < FULL_DISTANCES; ++i)
152 distances_prices[i] = pos_slot_prices[get_pos_slot(i)]
156 coder->match_price_count = 0;
163 fill_align_prices(lzma_coder *coder)
165 for (uint32_t i = 0; i < ALIGN_TABLE_SIZE; ++i) {
167 bittree_reverse_get_price(tmp, coder->pos_align_encoder,
169 coder->align_prices[i] = tmp;
172 coder->align_price_count = 0;
176 // The first argument is a pointer returned by literal_get_subcoder().
178 literal_get_price(const probability *encoders, const bool match_mode,
179 const uint8_t match_byte, const uint8_t symbol)
182 uint32_t context = 1;
188 const uint32_t match_bit = (match_byte >> i) & 1;
189 const uint32_t bit = (symbol >> i) & 1;
190 const uint32_t subcoder_index
191 = 0x100 + (match_bit << 8) + context;
193 price += bit_get_price(encoders[subcoder_index], bit);
194 context = (context << 1) | bit;
196 if (match_bit != bit)
204 const uint32_t bit = (symbol >> i) & 1;
205 price += bit_get_price(encoders[context], bit);
206 context = (context << 1) | bit;
214 backward(lzma_coder *restrict coder, uint32_t *restrict len_res,
215 uint32_t *restrict back_res, uint32_t cur)
217 coder->optimum_end_index = cur;
219 uint32_t pos_mem = coder->optimum[cur].pos_prev;
220 uint32_t back_mem = coder->optimum[cur].back_prev;
223 if (coder->optimum[cur].prev_1_is_char) {
224 make_as_char(coder->optimum[pos_mem]);
225 coder->optimum[pos_mem].pos_prev = pos_mem - 1;
227 if (coder->optimum[cur].prev_2) {
228 coder->optimum[pos_mem - 1].prev_1_is_char = false;
229 coder->optimum[pos_mem - 1].pos_prev
230 = coder->optimum[cur].pos_prev_2;
231 coder->optimum[pos_mem - 1].back_prev
232 = coder->optimum[cur].back_prev_2;
236 uint32_t pos_prev = pos_mem;
237 uint32_t back_cur = back_mem;
239 back_mem = coder->optimum[pos_prev].back_prev;
240 pos_mem = coder->optimum[pos_prev].pos_prev;
242 coder->optimum[pos_prev].back_prev = back_cur;
243 coder->optimum[pos_prev].pos_prev = cur;
248 coder->optimum_current_index = coder->optimum[0].pos_prev;
249 *len_res = coder->optimum[0].pos_prev;
250 *back_res = coder->optimum[0].back_prev;
257 lzma_get_optimum(lzma_coder *restrict coder,
258 uint32_t *restrict back_res, uint32_t *restrict len_res)
260 // Update the price tables. In the C++ LZMA SDK 4.42 this was done in both
261 // initialization function and in the main loop. In liblzma they were
262 // moved into this single place.
263 if (coder->additional_offset == 0) {
264 if (coder->match_price_count >= (1 << 7))
265 fill_distances_prices(coder);
267 if (coder->align_price_count >= ALIGN_TABLE_SIZE)
268 fill_align_prices(coder);
272 if (coder->optimum_end_index != coder->optimum_current_index) {
273 *len_res = coder->optimum[coder->optimum_current_index].pos_prev
274 - coder->optimum_current_index;
275 *back_res = coder->optimum[coder->optimum_current_index].back_prev;
276 coder->optimum_current_index = coder->optimum[
277 coder->optimum_current_index].pos_prev;
281 coder->optimum_current_index = 0;
282 coder->optimum_end_index = 0;
285 const uint32_t fast_bytes = coder->fast_bytes;
286 uint32_t *match_distances = coder->match_distances;
289 uint32_t num_distance_pairs;
291 if (!coder->longest_match_was_found) {
292 lzma_read_match_distances(coder, &len_main, &num_distance_pairs);
294 len_main = coder->longest_match_length;
295 num_distance_pairs = coder->num_distance_pairs;
296 coder->longest_match_was_found = false;
300 const uint8_t *buf = coder->lz.buffer + coder->lz.read_pos - 1;
301 uint32_t num_available_bytes
302 = coder->lz.write_pos - coder->lz.read_pos + 1;
303 if (num_available_bytes < 2) {
304 *back_res = UINT32_MAX;
309 if (num_available_bytes > MATCH_MAX_LEN)
310 num_available_bytes = MATCH_MAX_LEN;
313 uint32_t reps[REP_DISTANCES];
314 uint32_t rep_lens[REP_DISTANCES];
315 uint32_t rep_max_index = 0;
317 for (uint32_t i = 0; i < REP_DISTANCES; ++i) {
318 reps[i] = coder->rep_distances[i];
319 const uint32_t back_offset = reps[i] + 1;
321 if (buf[0] != *(buf - back_offset)
322 || buf[1] != *(buf + 1 - back_offset)) {
328 for (len_test = 2; len_test < num_available_bytes
329 && buf[len_test] == *(buf + len_test - back_offset);
332 rep_lens[i] = len_test;
333 if (len_test > rep_lens[rep_max_index])
337 if (rep_lens[rep_max_index] >= fast_bytes) {
338 *back_res = rep_max_index;
339 *len_res = rep_lens[rep_max_index];
340 move_pos(*len_res - 1);
345 if (len_main >= fast_bytes) {
346 *back_res = match_distances[num_distance_pairs] + REP_DISTANCES;
348 move_pos(len_main - 1);
352 uint8_t current_byte = *buf;
353 uint8_t match_byte = *(buf - reps[0] - 1);
355 if (len_main < 2 && current_byte != match_byte
356 && rep_lens[rep_max_index] < 2) {
357 *back_res = UINT32_MAX;
362 const uint32_t pos_mask = coder->pos_mask;
364 coder->optimum[0].state = coder->state;
366 uint32_t position = coder->now_pos;
367 uint32_t pos_state = (position & pos_mask);
369 coder->optimum[1].price = bit_get_price_0(
370 coder->is_match[coder->state][pos_state])
372 literal_get_subcoder(coder->literal_coder,
373 position, coder->previous_byte),
374 !is_char_state(coder->state), match_byte, current_byte);
376 make_as_char(coder->optimum[1]);
379 = bit_get_price_1(coder->is_match[coder->state][pos_state]);
380 uint32_t rep_match_price
381 = match_price + bit_get_price_1(coder->is_rep[coder->state]);
384 if (match_byte == current_byte) {
385 const uint32_t short_rep_price = rep_match_price
386 + get_rep_len_1_price(coder->state, pos_state);
388 if (short_rep_price < coder->optimum[1].price) {
389 coder->optimum[1].price = short_rep_price;
390 make_as_short_rep(coder->optimum[1]);
394 uint32_t len_end = (len_main >= rep_lens[rep_max_index])
396 : rep_lens[rep_max_index];
399 *back_res = coder->optimum[1].back_prev;
404 coder->optimum[1].pos_prev = 0;
406 for (uint32_t i = 0; i < REP_DISTANCES; ++i)
407 coder->optimum[0].backs[i] = reps[i];
409 uint32_t len = len_end;
411 coder->optimum[len].price = INFINITY_PRICE;
412 } while (--len >= 2);
415 uint32_t (*distances_prices)[FULL_DISTANCES] = coder->distances_prices;
416 uint32_t (*pos_slot_prices)[DIST_TABLE_SIZE_MAX] = coder->pos_slot_prices;
417 uint32_t *align_prices = coder->align_prices;
419 for (uint32_t i = 0; i < REP_DISTANCES; ++i) {
420 uint32_t rep_len = rep_lens[i];
424 uint32_t price = rep_match_price;
425 get_pure_rep_price(price, i, coder->state, pos_state);
428 const uint32_t cur_and_len_price = price
430 coder->rep_match_len_encoder,
431 rep_len - 2, pos_state);
433 if (cur_and_len_price < coder->optimum[rep_len].price) {
434 coder->optimum[rep_len].price = cur_and_len_price;
435 coder->optimum[rep_len].pos_prev = 0;
436 coder->optimum[rep_len].back_prev = i;
437 coder->optimum[rep_len].prev_1_is_char = false;
439 } while (--rep_len >= 2);
443 uint32_t normal_match_price = match_price
444 + bit_get_price_0(coder->is_rep[coder->state]);
446 len = (rep_lens[0] >= 2) ? rep_lens[0] + 1 : 2;
448 if (len <= len_main) {
451 while (len > match_distances[offs + 1])
455 const uint32_t distance = match_distances[offs + 2];
456 uint32_t cur_and_len_price = normal_match_price;
457 get_pos_len_price(cur_and_len_price, distance, len, pos_state);
459 if (cur_and_len_price < coder->optimum[len].price) {
460 coder->optimum[len].price = cur_and_len_price;
461 coder->optimum[len].pos_prev = 0;
462 coder->optimum[len].back_prev = distance + REP_DISTANCES;
463 coder->optimum[len].prev_1_is_char = false;
466 if (len == match_distances[offs + 1]) {
468 if (offs == num_distance_pairs)
481 // The rest of this function is a huge while-loop. To avoid extreme
482 // indentation, the indentation level is not increased here.
489 if (cur == len_end) {
490 backward(coder, len_res, back_res, cur);
496 lzma_read_match_distances(coder, &new_len, &num_distance_pairs);
498 if (new_len >= fast_bytes) {
499 coder->num_distance_pairs = num_distance_pairs;
500 coder->longest_match_length = new_len;
501 coder->longest_match_was_found = true;
502 backward(coder, len_res, back_res, cur);
509 uint32_t pos_prev = coder->optimum[cur].pos_prev;
512 if (coder->optimum[cur].prev_1_is_char) {
515 if (coder->optimum[cur].prev_2) {
516 state = coder->optimum[coder->optimum[cur].pos_prev_2].state;
518 if (coder->optimum[cur].back_prev_2 < REP_DISTANCES)
524 state = coder->optimum[pos_prev].state;
530 state = coder->optimum[pos_prev].state;
533 if (pos_prev == cur - 1) {
534 if (is_short_rep(coder->optimum[cur]))
535 update_short_rep(state);
540 if (coder->optimum[cur].prev_1_is_char && coder->optimum[cur].prev_2) {
541 pos_prev = coder->optimum[cur].pos_prev_2;
542 pos = coder->optimum[cur].back_prev_2;
545 pos = coder->optimum[cur].back_prev;
546 if (pos < REP_DISTANCES)
552 if (pos < REP_DISTANCES) {
553 reps[0] = coder->optimum[pos_prev].backs[pos];
556 for (i = 1; i <= pos; ++i)
557 reps[i] = coder->optimum[pos_prev].backs[i - 1];
559 for (; i < REP_DISTANCES; ++i)
560 reps[i] = coder->optimum[pos_prev].backs[i];
563 reps[0] = pos - REP_DISTANCES;
565 for (uint32_t i = 1; i < REP_DISTANCES; ++i)
566 reps[i] = coder->optimum[pos_prev].backs[i - 1];
570 coder->optimum[cur].state = state;
572 for (uint32_t i = 0; i < REP_DISTANCES; ++i)
573 coder->optimum[cur].backs[i] = reps[i];
575 const uint32_t cur_price = coder->optimum[cur].price;
577 buf = coder->lz.buffer + coder->lz.read_pos - 1;
579 match_byte = *(buf - reps[0] - 1);
581 pos_state = position & pos_mask;
583 const uint32_t cur_and_1_price = cur_price
584 + bit_get_price_0(coder->is_match[state][pos_state])
586 literal_get_subcoder(coder->literal_coder,
588 !is_char_state(state), match_byte, current_byte);
590 bool next_is_char = false;
592 if (cur_and_1_price < coder->optimum[cur + 1].price) {
593 coder->optimum[cur + 1].price = cur_and_1_price;
594 coder->optimum[cur + 1].pos_prev = cur;
595 make_as_char(coder->optimum[cur + 1]);
599 match_price = cur_price
600 + bit_get_price_1(coder->is_match[state][pos_state]);
601 rep_match_price = match_price
602 + bit_get_price_1(coder->is_rep[state]);
604 if (match_byte == current_byte
605 && !(coder->optimum[cur + 1].pos_prev < cur
606 && coder->optimum[cur + 1].back_prev == 0)) {
608 const uint32_t short_rep_price = rep_match_price
609 + get_rep_len_1_price(state, pos_state);
611 if (short_rep_price <= coder->optimum[cur + 1].price) {
612 coder->optimum[cur + 1].price = short_rep_price;
613 coder->optimum[cur + 1].pos_prev = cur;
614 make_as_short_rep(coder->optimum[cur + 1]);
619 uint32_t num_available_bytes_full
620 = coder->lz.write_pos - coder->lz.read_pos + 1;
621 num_available_bytes_full = MIN(OPTS - 1 - cur, num_available_bytes_full);
622 num_available_bytes = num_available_bytes_full;
624 if (num_available_bytes < 2)
627 if (num_available_bytes > fast_bytes)
628 num_available_bytes = fast_bytes;
630 if (!next_is_char && match_byte != current_byte) { // speed optimization
631 // try literal + rep0
632 const uint32_t back_offset = reps[0] + 1;
633 const uint32_t limit = MIN(num_available_bytes_full, fast_bytes + 1);
636 for (temp = 1; temp < limit
637 && buf[temp] == *(buf + temp - back_offset);
640 const uint32_t len_test_2 = temp - 1;
642 if (len_test_2 >= 2) {
643 uint32_t state_2 = state;
644 update_char(state_2);
646 const uint32_t pos_state_next = (position + 1) & pos_mask;
647 const uint32_t next_rep_match_price = cur_and_1_price
648 + bit_get_price_1(coder->is_match[state_2][pos_state_next])
649 + bit_get_price_1(coder->is_rep[state_2]);
651 // for (; len_test_2 >= 2; --len_test_2) {
652 const uint32_t offset = cur + 1 + len_test_2;
654 while (len_end < offset)
655 coder->optimum[++len_end].price = INFINITY_PRICE;
657 uint32_t cur_and_len_price = next_rep_match_price;
658 get_rep_price(cur_and_len_price,
659 0, len_test_2, state_2, pos_state_next);
661 if (cur_and_len_price < coder->optimum[offset].price) {
662 coder->optimum[offset].price = cur_and_len_price;
663 coder->optimum[offset].pos_prev = cur + 1;
664 coder->optimum[offset].back_prev = 0;
665 coder->optimum[offset].prev_1_is_char = true;
666 coder->optimum[offset].prev_2 = false;
673 uint32_t start_len = 2; // speed optimization
675 for (uint32_t rep_index = 0; rep_index < REP_DISTANCES; ++rep_index) {
676 const uint32_t back_offset = reps[rep_index] + 1;
678 if (buf[0] != *(buf - back_offset) || buf[1] != *(buf + 1 - back_offset))
682 for (len_test = 2; len_test < num_available_bytes
683 && buf[len_test] == *(buf + len_test - back_offset);
686 while (len_end < cur + len_test)
687 coder->optimum[++len_end].price = INFINITY_PRICE;
689 const uint32_t len_test_temp = len_test;
690 uint32_t price = rep_match_price;
691 get_pure_rep_price(price, rep_index, state, pos_state);
694 const uint32_t cur_and_len_price = price
695 + length_get_price(coder->rep_match_len_encoder,
696 len_test - 2, pos_state);
698 if (cur_and_len_price < coder->optimum[cur + len_test].price) {
699 coder->optimum[cur + len_test].price = cur_and_len_price;
700 coder->optimum[cur + len_test].pos_prev = cur;
701 coder->optimum[cur + len_test].back_prev = rep_index;
702 coder->optimum[cur + len_test].prev_1_is_char = false;
704 } while (--len_test >= 2);
706 len_test = len_test_temp;
709 start_len = len_test + 1;
712 uint32_t len_test_2 = len_test + 1;
713 const uint32_t limit = MIN(num_available_bytes_full,
714 len_test_2 + fast_bytes);
715 for (; len_test_2 < limit
716 && buf[len_test_2] == *(buf + len_test_2 - back_offset);
719 len_test_2 -= len_test + 1;
721 if (len_test_2 >= 2) {
722 uint32_t state_2 = state;
725 uint32_t pos_state_next = (position + len_test) & pos_mask;
727 const uint32_t cur_and_len_char_price = price
728 + length_get_price(coder->rep_match_len_encoder,
729 len_test - 2, pos_state)
730 + bit_get_price_0(coder->is_match[state_2][pos_state_next])
732 literal_get_subcoder(coder->literal_coder,
733 position + len_test, buf[len_test - 1]),
734 true, *(buf + len_test - back_offset), buf[len_test]);
736 update_char(state_2);
738 pos_state_next = (position + len_test + 1) & pos_mask;
740 const uint32_t next_rep_match_price = cur_and_len_char_price
741 + bit_get_price_1(coder->is_match[state_2][pos_state_next])
742 + bit_get_price_1(coder->is_rep[state_2]);
744 // for(; len_test_2 >= 2; len_test_2--) {
745 const uint32_t offset = cur + len_test + 1 + len_test_2;
747 while (len_end < offset)
748 coder->optimum[++len_end].price = INFINITY_PRICE;
750 uint32_t cur_and_len_price = next_rep_match_price;
751 get_rep_price(cur_and_len_price,
752 0, len_test_2, state_2, pos_state_next);
754 if (cur_and_len_price < coder->optimum[offset].price) {
755 coder->optimum[offset].price = cur_and_len_price;
756 coder->optimum[offset].pos_prev = cur + len_test + 1;
757 coder->optimum[offset].back_prev = 0;
758 coder->optimum[offset].prev_1_is_char = true;
759 coder->optimum[offset].prev_2 = true;
760 coder->optimum[offset].pos_prev_2 = cur;
761 coder->optimum[offset].back_prev_2 = rep_index;
768 // for (uint32_t len_test = 2; len_test <= new_len; ++len_test)
769 if (new_len > num_available_bytes) {
770 new_len = num_available_bytes;
772 for (num_distance_pairs = 0;
773 new_len > match_distances[num_distance_pairs + 1];
774 num_distance_pairs += 2) ;
776 match_distances[num_distance_pairs + 1] = new_len;
777 num_distance_pairs += 2;
781 if (new_len >= start_len) {
782 normal_match_price = match_price
783 + bit_get_price_0(coder->is_rep[state]);
785 while (len_end < cur + new_len)
786 coder->optimum[++len_end].price = INFINITY_PRICE;
789 while (start_len > match_distances[offs + 1])
792 uint32_t cur_back = match_distances[offs + 2];
793 uint32_t pos_slot = get_pos_slot_2(cur_back);
795 for (uint32_t len_test = start_len; ; ++len_test) {
796 uint32_t cur_and_len_price = normal_match_price;
797 const uint32_t len_to_pos_state = get_len_to_pos_state(len_test);
799 if (cur_back < FULL_DISTANCES)
800 cur_and_len_price += distances_prices[
801 len_to_pos_state][cur_back];
803 cur_and_len_price += pos_slot_prices[
804 len_to_pos_state][pos_slot]
805 + align_prices[cur_back & ALIGN_MASK];
807 cur_and_len_price += length_get_price(coder->len_encoder,
808 len_test - MATCH_MIN_LEN, pos_state);
810 if (cur_and_len_price < coder->optimum[cur + len_test].price) {
811 coder->optimum[cur + len_test].price = cur_and_len_price;
812 coder->optimum[cur + len_test].pos_prev = cur;
813 coder->optimum[cur + len_test].back_prev
814 = cur_back + REP_DISTANCES;
815 coder->optimum[cur + len_test].prev_1_is_char = false;
818 if (len_test == match_distances[offs + 1]) {
819 // Try Match + Literal + Rep0
820 const uint32_t back_offset = cur_back + 1;
821 uint32_t len_test_2 = len_test + 1;
822 const uint32_t limit = MIN(num_available_bytes_full,
823 len_test_2 + fast_bytes);
825 for (; len_test_2 < limit &&
826 buf[len_test_2] == *(buf + len_test_2 - back_offset);
829 len_test_2 -= len_test + 1;
831 if (len_test_2 >= 2) {
832 uint32_t state_2 = state;
833 update_match(state_2);
834 uint32_t pos_state_next
835 = (position + len_test) & pos_mask;
837 const uint32_t cur_and_len_char_price = cur_and_len_price
839 coder->is_match[state_2][pos_state_next])
841 literal_get_subcoder(
842 coder->literal_coder,
846 *(buf + len_test - back_offset),
849 update_char(state_2);
850 pos_state_next = (pos_state_next + 1) & pos_mask;
852 const uint32_t next_rep_match_price
853 = cur_and_len_char_price
855 coder->is_match[state_2][pos_state_next])
856 + bit_get_price_1(coder->is_rep[state_2]);
858 // for(; len_test_2 >= 2; --len_test_2) {
859 const uint32_t offset = cur + len_test + 1 + len_test_2;
861 while (len_end < offset)
862 coder->optimum[++len_end].price = INFINITY_PRICE;
864 cur_and_len_price = next_rep_match_price;
865 get_rep_price(cur_and_len_price,
866 0, len_test_2, state_2, pos_state_next);
868 if (cur_and_len_price < coder->optimum[offset].price) {
869 coder->optimum[offset].price = cur_and_len_price;
870 coder->optimum[offset].pos_prev = cur + len_test + 1;
871 coder->optimum[offset].back_prev = 0;
872 coder->optimum[offset].prev_1_is_char = true;
873 coder->optimum[offset].prev_2 = true;
874 coder->optimum[offset].pos_prev_2 = cur;
875 coder->optimum[offset].back_prev_2
876 = cur_back + REP_DISTANCES;
882 if (offs == num_distance_pairs)
885 cur_back = match_distances[offs + 2];
886 if (cur_back >= FULL_DISTANCES)
887 pos_slot = get_pos_slot_2(cur_back);
892 } // Closes: while (true)