1 // SPDX-License-Identifier: 0BSD
3 ///////////////////////////////////////////////////////////////////////////////
5 /// \file lzma_encoder_optimum_normal.c
9 ///////////////////////////////////////////////////////////////////////////////
11 #include "lzma_encoder_private.h"
13 #include "memcmplen.h"
21 get_literal_price(const lzma_lzma1_encoder
*const coder
, const uint32_t pos
,
22 const uint32_t prev_byte
, const bool match_mode
,
23 uint32_t match_byte
, uint32_t symbol
)
25 const probability
*const subcoder
= literal_subcoder(coder
->literal
,
26 coder
->literal_context_bits
, coder
->literal_mask
,
32 price
= rc_bittree_price(subcoder
, 8, symbol
);
34 uint32_t offset
= 0x100;
35 symbol
+= UINT32_C(1) << 8;
40 const uint32_t match_bit
= match_byte
& offset
;
41 const uint32_t subcoder_index
42 = offset
+ match_bit
+ (symbol
>> 8);
43 const uint32_t bit
= (symbol
>> 7) & 1;
44 price
+= rc_bit_price(subcoder
[subcoder_index
], bit
);
47 offset
&= ~(match_byte
^ symbol
);
49 } while (symbol
< (UINT32_C(1) << 16));
56 static inline uint32_t
57 get_len_price(const lzma_length_encoder
*const lencoder
,
58 const uint32_t len
, const uint32_t pos_state
)
60 // NOTE: Unlike the other price tables, length prices are updated
62 return lencoder
->prices
[pos_state
][len
- MATCH_LEN_MIN
];
66 static inline uint32_t
67 get_short_rep_price(const lzma_lzma1_encoder
*const coder
,
68 const lzma_lzma_state state
, const uint32_t pos_state
)
70 return rc_bit_0_price(coder
->is_rep0
[state
])
71 + rc_bit_0_price(coder
->is_rep0_long
[state
][pos_state
]);
75 static inline uint32_t
76 get_pure_rep_price(const lzma_lzma1_encoder
*const coder
, const uint32_t rep_index
,
77 const lzma_lzma_state state
, uint32_t pos_state
)
82 price
= rc_bit_0_price(coder
->is_rep0
[state
]);
83 price
+= rc_bit_1_price(coder
->is_rep0_long
[state
][pos_state
]);
85 price
= rc_bit_1_price(coder
->is_rep0
[state
]);
88 price
+= rc_bit_0_price(coder
->is_rep1
[state
]);
90 price
+= rc_bit_1_price(coder
->is_rep1
[state
]);
91 price
+= rc_bit_price(coder
->is_rep2
[state
],
100 static inline uint32_t
101 get_rep_price(const lzma_lzma1_encoder
*const coder
, const uint32_t rep_index
,
102 const uint32_t len
, const lzma_lzma_state state
,
103 const uint32_t pos_state
)
105 return get_len_price(&coder
->rep_len_encoder
, len
, pos_state
)
106 + get_pure_rep_price(coder
, rep_index
, state
, pos_state
);
110 static inline uint32_t
111 get_dist_len_price(const lzma_lzma1_encoder
*const coder
, const uint32_t dist
,
112 const uint32_t len
, const uint32_t pos_state
)
114 const uint32_t dist_state
= get_dist_state(len
);
117 if (dist
< FULL_DISTANCES
) {
118 price
= coder
->dist_prices
[dist_state
][dist
];
120 const uint32_t dist_slot
= get_dist_slot_2(dist
);
121 price
= coder
->dist_slot_prices
[dist_state
][dist_slot
]
122 + coder
->align_prices
[dist
& ALIGN_MASK
];
125 price
+= get_len_price(&coder
->match_len_encoder
, len
, pos_state
);
132 fill_dist_prices(lzma_lzma1_encoder
*coder
)
134 for (uint32_t dist_state
= 0; dist_state
< DIST_STATES
; ++dist_state
) {
136 uint32_t *const dist_slot_prices
137 = coder
->dist_slot_prices
[dist_state
];
139 // Price to encode the dist_slot.
140 for (uint32_t dist_slot
= 0;
141 dist_slot
< coder
->dist_table_size
; ++dist_slot
)
142 dist_slot_prices
[dist_slot
] = rc_bittree_price(
143 coder
->dist_slot
[dist_state
],
144 DIST_SLOT_BITS
, dist_slot
);
146 // For matches with distance >= FULL_DISTANCES, add the price
147 // of the direct bits part of the match distance. (Align bits
148 // are handled by fill_align_prices()).
149 for (uint32_t dist_slot
= DIST_MODEL_END
;
150 dist_slot
< coder
->dist_table_size
;
152 dist_slot_prices
[dist_slot
] += rc_direct_price(
153 ((dist_slot
>> 1) - 1) - ALIGN_BITS
);
155 // Distances in the range [0, 3] are fully encoded with
156 // dist_slot, so they are used for coder->dist_prices
158 for (uint32_t i
= 0; i
< DIST_MODEL_START
; ++i
)
159 coder
->dist_prices
[dist_state
][i
]
160 = dist_slot_prices
[i
];
163 // Distances in the range [4, 127] depend on dist_slot and
164 // dist_special. We do this in a loop separate from the above
165 // loop to avoid redundant calls to get_dist_slot().
166 for (uint32_t i
= DIST_MODEL_START
; i
< FULL_DISTANCES
; ++i
) {
167 const uint32_t dist_slot
= get_dist_slot(i
);
168 const uint32_t footer_bits
= ((dist_slot
>> 1) - 1);
169 const uint32_t base
= (2 | (dist_slot
& 1)) << footer_bits
;
170 const uint32_t price
= rc_bittree_reverse_price(
171 coder
->dist_special
+ base
- dist_slot
- 1,
172 footer_bits
, i
- base
);
174 for (uint32_t dist_state
= 0; dist_state
< DIST_STATES
;
176 coder
->dist_prices
[dist_state
][i
]
177 = price
+ coder
->dist_slot_prices
[
178 dist_state
][dist_slot
];
181 coder
->match_price_count
= 0;
187 fill_align_prices(lzma_lzma1_encoder
*coder
)
189 for (uint32_t i
= 0; i
< ALIGN_SIZE
; ++i
)
190 coder
->align_prices
[i
] = rc_bittree_reverse_price(
191 coder
->dist_align
, ALIGN_BITS
, i
);
193 coder
->align_price_count
= 0;
203 make_literal(lzma_optimal
*optimal
)
205 optimal
->back_prev
= UINT32_MAX
;
206 optimal
->prev_1_is_literal
= false;
211 make_short_rep(lzma_optimal
*optimal
)
213 optimal
->back_prev
= 0;
214 optimal
->prev_1_is_literal
= false;
218 #define is_short_rep(optimal) \
219 ((optimal).back_prev == 0)
223 backward(lzma_lzma1_encoder
*restrict coder
, uint32_t *restrict len_res
,
224 uint32_t *restrict back_res
, uint32_t cur
)
226 coder
->opts_end_index
= cur
;
228 uint32_t pos_mem
= coder
->opts
[cur
].pos_prev
;
229 uint32_t back_mem
= coder
->opts
[cur
].back_prev
;
232 if (coder
->opts
[cur
].prev_1_is_literal
) {
233 make_literal(&coder
->opts
[pos_mem
]);
234 coder
->opts
[pos_mem
].pos_prev
= pos_mem
- 1;
236 if (coder
->opts
[cur
].prev_2
) {
237 coder
->opts
[pos_mem
- 1].prev_1_is_literal
239 coder
->opts
[pos_mem
- 1].pos_prev
240 = coder
->opts
[cur
].pos_prev_2
;
241 coder
->opts
[pos_mem
- 1].back_prev
242 = coder
->opts
[cur
].back_prev_2
;
246 const uint32_t pos_prev
= pos_mem
;
247 const uint32_t back_cur
= back_mem
;
249 back_mem
= coder
->opts
[pos_prev
].back_prev
;
250 pos_mem
= coder
->opts
[pos_prev
].pos_prev
;
252 coder
->opts
[pos_prev
].back_prev
= back_cur
;
253 coder
->opts
[pos_prev
].pos_prev
= cur
;
258 coder
->opts_current_index
= coder
->opts
[0].pos_prev
;
259 *len_res
= coder
->opts
[0].pos_prev
;
260 *back_res
= coder
->opts
[0].back_prev
;
270 static inline uint32_t
271 helper1(lzma_lzma1_encoder
*restrict coder
, lzma_mf
*restrict mf
,
272 uint32_t *restrict back_res
, uint32_t *restrict len_res
,
275 const uint32_t nice_len
= mf
->nice_len
;
278 uint32_t matches_count
;
280 if (mf
->read_ahead
== 0) {
281 len_main
= mf_find(mf
, &matches_count
, coder
->matches
);
283 assert(mf
->read_ahead
== 1);
284 len_main
= coder
->longest_match_length
;
285 matches_count
= coder
->matches_count
;
288 const uint32_t buf_avail
= my_min(mf_avail(mf
) + 1, MATCH_LEN_MAX
);
290 *back_res
= UINT32_MAX
;
295 const uint8_t *const buf
= mf_ptr(mf
) - 1;
297 uint32_t rep_lens
[REPS
];
298 uint32_t rep_max_index
= 0;
300 for (uint32_t i
= 0; i
< REPS
; ++i
) {
301 const uint8_t *const buf_back
= buf
- coder
->reps
[i
] - 1;
303 if (not_equal_16(buf
, buf_back
)) {
308 rep_lens
[i
] = lzma_memcmplen(buf
, buf_back
, 2, buf_avail
);
310 if (rep_lens
[i
] > rep_lens
[rep_max_index
])
314 if (rep_lens
[rep_max_index
] >= nice_len
) {
315 *back_res
= rep_max_index
;
316 *len_res
= rep_lens
[rep_max_index
];
317 mf_skip(mf
, *len_res
- 1);
322 if (len_main
>= nice_len
) {
323 *back_res
= coder
->matches
[matches_count
- 1].dist
+ REPS
;
325 mf_skip(mf
, len_main
- 1);
329 const uint8_t current_byte
= *buf
;
330 const uint8_t match_byte
= *(buf
- coder
->reps
[0] - 1);
332 if (len_main
< 2 && current_byte
!= match_byte
333 && rep_lens
[rep_max_index
] < 2) {
334 *back_res
= UINT32_MAX
;
339 coder
->opts
[0].state
= coder
->state
;
341 const uint32_t pos_state
= position
& coder
->pos_mask
;
343 coder
->opts
[1].price
= rc_bit_0_price(
344 coder
->is_match
[coder
->state
][pos_state
])
345 + get_literal_price(coder
, position
, buf
[-1],
346 !is_literal_state(coder
->state
),
347 match_byte
, current_byte
);
349 make_literal(&coder
->opts
[1]);
351 const uint32_t match_price
= rc_bit_1_price(
352 coder
->is_match
[coder
->state
][pos_state
]);
353 const uint32_t rep_match_price
= match_price
354 + rc_bit_1_price(coder
->is_rep
[coder
->state
]);
356 if (match_byte
== current_byte
) {
357 const uint32_t short_rep_price
= rep_match_price
358 + get_short_rep_price(
359 coder
, coder
->state
, pos_state
);
361 if (short_rep_price
< coder
->opts
[1].price
) {
362 coder
->opts
[1].price
= short_rep_price
;
363 make_short_rep(&coder
->opts
[1]);
367 const uint32_t len_end
= my_max(len_main
, rep_lens
[rep_max_index
]);
370 *back_res
= coder
->opts
[1].back_prev
;
375 coder
->opts
[1].pos_prev
= 0;
377 for (uint32_t i
= 0; i
< REPS
; ++i
)
378 coder
->opts
[0].backs
[i
] = coder
->reps
[i
];
380 uint32_t len
= len_end
;
382 coder
->opts
[len
].price
= RC_INFINITY_PRICE
;
383 } while (--len
>= 2);
386 for (uint32_t i
= 0; i
< REPS
; ++i
) {
387 uint32_t rep_len
= rep_lens
[i
];
391 const uint32_t price
= rep_match_price
+ get_pure_rep_price(
392 coder
, i
, coder
->state
, pos_state
);
395 const uint32_t cur_and_len_price
= price
397 &coder
->rep_len_encoder
,
400 if (cur_and_len_price
< coder
->opts
[rep_len
].price
) {
401 coder
->opts
[rep_len
].price
= cur_and_len_price
;
402 coder
->opts
[rep_len
].pos_prev
= 0;
403 coder
->opts
[rep_len
].back_prev
= i
;
404 coder
->opts
[rep_len
].prev_1_is_literal
= false;
406 } while (--rep_len
>= 2);
410 const uint32_t normal_match_price
= match_price
411 + rc_bit_0_price(coder
->is_rep
[coder
->state
]);
413 len
= rep_lens
[0] >= 2 ? rep_lens
[0] + 1 : 2;
414 if (len
<= len_main
) {
416 while (len
> coder
->matches
[i
].len
)
420 const uint32_t dist
= coder
->matches
[i
].dist
;
421 const uint32_t cur_and_len_price
= normal_match_price
422 + get_dist_len_price(coder
,
423 dist
, len
, pos_state
);
425 if (cur_and_len_price
< coder
->opts
[len
].price
) {
426 coder
->opts
[len
].price
= cur_and_len_price
;
427 coder
->opts
[len
].pos_prev
= 0;
428 coder
->opts
[len
].back_prev
= dist
+ REPS
;
429 coder
->opts
[len
].prev_1_is_literal
= false;
432 if (len
== coder
->matches
[i
].len
)
433 if (++i
== matches_count
)
442 static inline uint32_t
443 helper2(lzma_lzma1_encoder
*coder
, uint32_t *reps
, const uint8_t *buf
,
444 uint32_t len_end
, uint32_t position
, const uint32_t cur
,
445 const uint32_t nice_len
, const uint32_t buf_avail_full
)
447 uint32_t matches_count
= coder
->matches_count
;
448 uint32_t new_len
= coder
->longest_match_length
;
449 uint32_t pos_prev
= coder
->opts
[cur
].pos_prev
;
450 lzma_lzma_state state
;
452 if (coder
->opts
[cur
].prev_1_is_literal
) {
455 if (coder
->opts
[cur
].prev_2
) {
456 state
= coder
->opts
[coder
->opts
[cur
].pos_prev_2
].state
;
458 if (coder
->opts
[cur
].back_prev_2
< REPS
)
459 update_long_rep(state
);
464 state
= coder
->opts
[pos_prev
].state
;
467 update_literal(state
);
470 state
= coder
->opts
[pos_prev
].state
;
473 if (pos_prev
== cur
- 1) {
474 if (is_short_rep(coder
->opts
[cur
]))
475 update_short_rep(state
);
477 update_literal(state
);
480 if (coder
->opts
[cur
].prev_1_is_literal
481 && coder
->opts
[cur
].prev_2
) {
482 pos_prev
= coder
->opts
[cur
].pos_prev_2
;
483 pos
= coder
->opts
[cur
].back_prev_2
;
484 update_long_rep(state
);
486 pos
= coder
->opts
[cur
].back_prev
;
488 update_long_rep(state
);
494 reps
[0] = coder
->opts
[pos_prev
].backs
[pos
];
497 for (i
= 1; i
<= pos
; ++i
)
498 reps
[i
] = coder
->opts
[pos_prev
].backs
[i
- 1];
500 for (; i
< REPS
; ++i
)
501 reps
[i
] = coder
->opts
[pos_prev
].backs
[i
];
504 reps
[0] = pos
- REPS
;
506 for (uint32_t i
= 1; i
< REPS
; ++i
)
507 reps
[i
] = coder
->opts
[pos_prev
].backs
[i
- 1];
511 coder
->opts
[cur
].state
= state
;
513 for (uint32_t i
= 0; i
< REPS
; ++i
)
514 coder
->opts
[cur
].backs
[i
] = reps
[i
];
516 const uint32_t cur_price
= coder
->opts
[cur
].price
;
518 const uint8_t current_byte
= *buf
;
519 const uint8_t match_byte
= *(buf
- reps
[0] - 1);
521 const uint32_t pos_state
= position
& coder
->pos_mask
;
523 const uint32_t cur_and_1_price
= cur_price
524 + rc_bit_0_price(coder
->is_match
[state
][pos_state
])
525 + get_literal_price(coder
, position
, buf
[-1],
526 !is_literal_state(state
), match_byte
, current_byte
);
528 bool next_is_literal
= false;
530 if (cur_and_1_price
< coder
->opts
[cur
+ 1].price
) {
531 coder
->opts
[cur
+ 1].price
= cur_and_1_price
;
532 coder
->opts
[cur
+ 1].pos_prev
= cur
;
533 make_literal(&coder
->opts
[cur
+ 1]);
534 next_is_literal
= true;
537 const uint32_t match_price
= cur_price
538 + rc_bit_1_price(coder
->is_match
[state
][pos_state
]);
539 const uint32_t rep_match_price
= match_price
540 + rc_bit_1_price(coder
->is_rep
[state
]);
542 if (match_byte
== current_byte
543 && !(coder
->opts
[cur
+ 1].pos_prev
< cur
544 && coder
->opts
[cur
+ 1].back_prev
== 0)) {
546 const uint32_t short_rep_price
= rep_match_price
547 + get_short_rep_price(coder
, state
, pos_state
);
549 if (short_rep_price
<= coder
->opts
[cur
+ 1].price
) {
550 coder
->opts
[cur
+ 1].price
= short_rep_price
;
551 coder
->opts
[cur
+ 1].pos_prev
= cur
;
552 make_short_rep(&coder
->opts
[cur
+ 1]);
553 next_is_literal
= true;
557 if (buf_avail_full
< 2)
560 const uint32_t buf_avail
= my_min(buf_avail_full
, nice_len
);
562 if (!next_is_literal
&& match_byte
!= current_byte
) { // speed optimization
563 // try literal + rep0
564 const uint8_t *const buf_back
= buf
- reps
[0] - 1;
565 const uint32_t limit
= my_min(buf_avail_full
, nice_len
+ 1);
567 const uint32_t len_test
= lzma_memcmplen(buf
, buf_back
, 1, limit
) - 1;
570 lzma_lzma_state state_2
= state
;
571 update_literal(state_2
);
573 const uint32_t pos_state_next
= (position
+ 1) & coder
->pos_mask
;
574 const uint32_t next_rep_match_price
= cur_and_1_price
575 + rc_bit_1_price(coder
->is_match
[state_2
][pos_state_next
])
576 + rc_bit_1_price(coder
->is_rep
[state_2
]);
578 //for (; len_test >= 2; --len_test) {
579 const uint32_t offset
= cur
+ 1 + len_test
;
581 while (len_end
< offset
)
582 coder
->opts
[++len_end
].price
= RC_INFINITY_PRICE
;
584 const uint32_t cur_and_len_price
= next_rep_match_price
585 + get_rep_price(coder
, 0, len_test
,
586 state_2
, pos_state_next
);
588 if (cur_and_len_price
< coder
->opts
[offset
].price
) {
589 coder
->opts
[offset
].price
= cur_and_len_price
;
590 coder
->opts
[offset
].pos_prev
= cur
+ 1;
591 coder
->opts
[offset
].back_prev
= 0;
592 coder
->opts
[offset
].prev_1_is_literal
= true;
593 coder
->opts
[offset
].prev_2
= false;
600 uint32_t start_len
= 2; // speed optimization
602 for (uint32_t rep_index
= 0; rep_index
< REPS
; ++rep_index
) {
603 const uint8_t *const buf_back
= buf
- reps
[rep_index
] - 1;
604 if (not_equal_16(buf
, buf_back
))
607 uint32_t len_test
= lzma_memcmplen(buf
, buf_back
, 2, buf_avail
);
609 while (len_end
< cur
+ len_test
)
610 coder
->opts
[++len_end
].price
= RC_INFINITY_PRICE
;
612 const uint32_t len_test_temp
= len_test
;
613 const uint32_t price
= rep_match_price
+ get_pure_rep_price(
614 coder
, rep_index
, state
, pos_state
);
617 const uint32_t cur_and_len_price
= price
618 + get_len_price(&coder
->rep_len_encoder
,
619 len_test
, pos_state
);
621 if (cur_and_len_price
< coder
->opts
[cur
+ len_test
].price
) {
622 coder
->opts
[cur
+ len_test
].price
= cur_and_len_price
;
623 coder
->opts
[cur
+ len_test
].pos_prev
= cur
;
624 coder
->opts
[cur
+ len_test
].back_prev
= rep_index
;
625 coder
->opts
[cur
+ len_test
].prev_1_is_literal
= false;
627 } while (--len_test
>= 2);
629 len_test
= len_test_temp
;
632 start_len
= len_test
+ 1;
635 uint32_t len_test_2
= len_test
+ 1;
636 const uint32_t limit
= my_min(buf_avail_full
,
637 len_test_2
+ nice_len
);
638 // NOTE: len_test_2 may be greater than limit so the call to
639 // lzma_memcmplen() must be done conditionally.
640 if (len_test_2
< limit
)
641 len_test_2
= lzma_memcmplen(buf
, buf_back
, len_test_2
, limit
);
643 len_test_2
-= len_test
+ 1;
645 if (len_test_2
>= 2) {
646 lzma_lzma_state state_2
= state
;
647 update_long_rep(state_2
);
649 uint32_t pos_state_next
= (position
+ len_test
) & coder
->pos_mask
;
651 const uint32_t cur_and_len_literal_price
= price
652 + get_len_price(&coder
->rep_len_encoder
,
654 + rc_bit_0_price(coder
->is_match
[state_2
][pos_state_next
])
655 + get_literal_price(coder
, position
+ len_test
,
656 buf
[len_test
- 1], true,
657 buf_back
[len_test
], buf
[len_test
]);
659 update_literal(state_2
);
661 pos_state_next
= (position
+ len_test
+ 1) & coder
->pos_mask
;
663 const uint32_t next_rep_match_price
= cur_and_len_literal_price
664 + rc_bit_1_price(coder
->is_match
[state_2
][pos_state_next
])
665 + rc_bit_1_price(coder
->is_rep
[state_2
]);
667 //for(; len_test_2 >= 2; len_test_2--) {
668 const uint32_t offset
= cur
+ len_test
+ 1 + len_test_2
;
670 while (len_end
< offset
)
671 coder
->opts
[++len_end
].price
= RC_INFINITY_PRICE
;
673 const uint32_t cur_and_len_price
= next_rep_match_price
674 + get_rep_price(coder
, 0, len_test_2
,
675 state_2
, pos_state_next
);
677 if (cur_and_len_price
< coder
->opts
[offset
].price
) {
678 coder
->opts
[offset
].price
= cur_and_len_price
;
679 coder
->opts
[offset
].pos_prev
= cur
+ len_test
+ 1;
680 coder
->opts
[offset
].back_prev
= 0;
681 coder
->opts
[offset
].prev_1_is_literal
= true;
682 coder
->opts
[offset
].prev_2
= true;
683 coder
->opts
[offset
].pos_prev_2
= cur
;
684 coder
->opts
[offset
].back_prev_2
= rep_index
;
691 //for (uint32_t len_test = 2; len_test <= new_len; ++len_test)
692 if (new_len
> buf_avail
) {
696 while (new_len
> coder
->matches
[matches_count
].len
)
699 coder
->matches
[matches_count
++].len
= new_len
;
703 if (new_len
>= start_len
) {
704 const uint32_t normal_match_price
= match_price
705 + rc_bit_0_price(coder
->is_rep
[state
]);
707 while (len_end
< cur
+ new_len
)
708 coder
->opts
[++len_end
].price
= RC_INFINITY_PRICE
;
711 while (start_len
> coder
->matches
[i
].len
)
714 for (uint32_t len_test
= start_len
; ; ++len_test
) {
715 const uint32_t cur_back
= coder
->matches
[i
].dist
;
716 uint32_t cur_and_len_price
= normal_match_price
717 + get_dist_len_price(coder
,
718 cur_back
, len_test
, pos_state
);
720 if (cur_and_len_price
< coder
->opts
[cur
+ len_test
].price
) {
721 coder
->opts
[cur
+ len_test
].price
= cur_and_len_price
;
722 coder
->opts
[cur
+ len_test
].pos_prev
= cur
;
723 coder
->opts
[cur
+ len_test
].back_prev
725 coder
->opts
[cur
+ len_test
].prev_1_is_literal
= false;
728 if (len_test
== coder
->matches
[i
].len
) {
729 // Try Match + Literal + Rep0
730 const uint8_t *const buf_back
= buf
- cur_back
- 1;
731 uint32_t len_test_2
= len_test
+ 1;
732 const uint32_t limit
= my_min(buf_avail_full
,
733 len_test_2
+ nice_len
);
735 // NOTE: len_test_2 may be greater than limit
736 // so the call to lzma_memcmplen() must be
737 // done conditionally.
738 if (len_test_2
< limit
)
739 len_test_2
= lzma_memcmplen(buf
, buf_back
,
742 len_test_2
-= len_test
+ 1;
744 if (len_test_2
>= 2) {
745 lzma_lzma_state state_2
= state
;
746 update_match(state_2
);
747 uint32_t pos_state_next
748 = (position
+ len_test
) & coder
->pos_mask
;
750 const uint32_t cur_and_len_literal_price
= cur_and_len_price
752 coder
->is_match
[state_2
][pos_state_next
])
753 + get_literal_price(coder
,
760 update_literal(state_2
);
761 pos_state_next
= (pos_state_next
+ 1) & coder
->pos_mask
;
763 const uint32_t next_rep_match_price
764 = cur_and_len_literal_price
766 coder
->is_match
[state_2
][pos_state_next
])
767 + rc_bit_1_price(coder
->is_rep
[state_2
]);
769 // for(; len_test_2 >= 2; --len_test_2) {
770 const uint32_t offset
= cur
+ len_test
+ 1 + len_test_2
;
772 while (len_end
< offset
)
773 coder
->opts
[++len_end
].price
= RC_INFINITY_PRICE
;
775 cur_and_len_price
= next_rep_match_price
776 + get_rep_price(coder
, 0, len_test_2
,
777 state_2
, pos_state_next
);
779 if (cur_and_len_price
< coder
->opts
[offset
].price
) {
780 coder
->opts
[offset
].price
= cur_and_len_price
;
781 coder
->opts
[offset
].pos_prev
= cur
+ len_test
+ 1;
782 coder
->opts
[offset
].back_prev
= 0;
783 coder
->opts
[offset
].prev_1_is_literal
= true;
784 coder
->opts
[offset
].prev_2
= true;
785 coder
->opts
[offset
].pos_prev_2
= cur
;
786 coder
->opts
[offset
].back_prev_2
792 if (++i
== matches_count
)
803 lzma_lzma_optimum_normal(lzma_lzma1_encoder
*restrict coder
,
804 lzma_mf
*restrict mf
,
805 uint32_t *restrict back_res
, uint32_t *restrict len_res
,
808 // If we have symbols pending, return the next pending symbol.
809 if (coder
->opts_end_index
!= coder
->opts_current_index
) {
810 assert(mf
->read_ahead
> 0);
811 *len_res
= coder
->opts
[coder
->opts_current_index
].pos_prev
812 - coder
->opts_current_index
;
813 *back_res
= coder
->opts
[coder
->opts_current_index
].back_prev
;
814 coder
->opts_current_index
= coder
->opts
[
815 coder
->opts_current_index
].pos_prev
;
819 // Update the price tables. In LZMA SDK <= 4.60 (and possibly later)
820 // this was done in both initialization function and in the main loop.
821 // In liblzma they were moved into this single place.
822 if (mf
->read_ahead
== 0) {
823 if (coder
->match_price_count
>= (1 << 7))
824 fill_dist_prices(coder
);
826 if (coder
->align_price_count
>= ALIGN_SIZE
)
827 fill_align_prices(coder
);
830 // TODO: This needs quite a bit of cleaning still. But splitting
831 // the original function into two pieces makes it at least a little
832 // more readable, since those two parts don't share many variables.
834 uint32_t len_end
= helper1(coder
, mf
, back_res
, len_res
, position
);
835 if (len_end
== UINT32_MAX
)
839 memcpy(reps
, coder
->reps
, sizeof(reps
));
842 for (cur
= 1; cur
< len_end
; ++cur
) {
845 coder
->longest_match_length
= mf_find(
846 mf
, &coder
->matches_count
, coder
->matches
);
848 if (coder
->longest_match_length
>= mf
->nice_len
)
851 len_end
= helper2(coder
, reps
, mf_ptr(mf
) - 1, len_end
,
852 position
+ cur
, cur
, mf
->nice_len
,
853 my_min(mf_avail(mf
) + 1, OPTS
- 1 - cur
));
856 backward(coder
, len_res
, back_res
, cur
);