1 // SPDX-License-Identifier: 0BSD
2 
3 ///////////////////////////////////////////////////////////////////////////////
4 //
5 /// \file       lzma_encoder_optimum_normal.c
6 //
7 //  Author:     Igor Pavlov
8 //
9 ///////////////////////////////////////////////////////////////////////////////
10 
11 #include "lzma_encoder_private.h"
12 #include "fastpos.h"
13 #include "memcmplen.h"
14 
15 
16 ////////////
17 // Prices //
18 ////////////
19 
20 static uint32_t
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)
24 {
25 	const probability *const subcoder = literal_subcoder(coder->literal,
26 			coder->literal_context_bits, coder->literal_mask,
27 			pos, prev_byte);
28 
29 	uint32_t price = 0;
30 
31 	if (!match_mode) {
32 		price = rc_bittree_price(subcoder, 8, symbol);
33 	} else {
34 		uint32_t offset = 0x100;
35 		symbol += UINT32_C(1) << 8;
36 
37 		do {
38 			match_byte <<= 1;
39 
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);
45 
46 			symbol <<= 1;
47 			offset &= ~(match_byte ^ symbol);
48 
49 		} while (symbol < (UINT32_C(1) << 16));
50 	}
51 
52 	return price;
53 }
54 
55 
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)
59 {
60 	// NOTE: Unlike the other price tables, length prices are updated
61 	// in lzma_encoder.c
62 	return lencoder->prices[pos_state][len - MATCH_LEN_MIN];
63 }
64 
65 
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)
69 {
70 	return rc_bit_0_price(coder->is_rep0[state])
71 		+ rc_bit_0_price(coder->is_rep0_long[state][pos_state]);
72 }
73 
74 
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)
78 {
79 	uint32_t price;
80 
81 	if (rep_index == 0) {
82 		price = rc_bit_0_price(coder->is_rep0[state]);
83 		price += rc_bit_1_price(coder->is_rep0_long[state][pos_state]);
84 	} else {
85 		price = rc_bit_1_price(coder->is_rep0[state]);
86 
87 		if (rep_index == 1) {
88 			price += rc_bit_0_price(coder->is_rep1[state]);
89 		} else {
90 			price += rc_bit_1_price(coder->is_rep1[state]);
91 			price += rc_bit_price(coder->is_rep2[state],
92 					rep_index - 2);
93 		}
94 	}
95 
96 	return price;
97 }
98 
99 
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)
104 {
105 	return get_len_price(&coder->rep_len_encoder, len, pos_state)
106 		+ get_pure_rep_price(coder, rep_index, state, pos_state);
107 }
108 
109 
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)
113 {
114 	const uint32_t dist_state = get_dist_state(len);
115 	uint32_t price;
116 
117 	if (dist < FULL_DISTANCES) {
118 		price = coder->dist_prices[dist_state][dist];
119 	} else {
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];
123 	}
124 
125 	price += get_len_price(&coder->match_len_encoder, len, pos_state);
126 
127 	return price;
128 }
129 
130 
131 static void
132 fill_dist_prices(lzma_lzma1_encoder *coder)
133 {
134 	for (uint32_t dist_state = 0; dist_state < DIST_STATES; ++dist_state) {
135 
136 		uint32_t *const dist_slot_prices
137 				= coder->dist_slot_prices[dist_state];
138 
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);
145 
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;
151 				++dist_slot)
152 			dist_slot_prices[dist_slot] += rc_direct_price(
153 					((dist_slot >> 1) - 1) - ALIGN_BITS);
154 
155 		// Distances in the range [0, 3] are fully encoded with
156 		// dist_slot, so they are used for coder->dist_prices
157 		// as is.
158 		for (uint32_t i = 0; i < DIST_MODEL_START; ++i)
159 			coder->dist_prices[dist_state][i]
160 					= dist_slot_prices[i];
161 	}
162 
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);
173 
174 		for (uint32_t dist_state = 0; dist_state < DIST_STATES;
175 				++dist_state)
176 			coder->dist_prices[dist_state][i]
177 					= price + coder->dist_slot_prices[
178 						dist_state][dist_slot];
179 	}
180 
181 	coder->match_price_count = 0;
182 	return;
183 }
184 
185 
186 static void
187 fill_align_prices(lzma_lzma1_encoder *coder)
188 {
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);
192 
193 	coder->align_price_count = 0;
194 	return;
195 }
196 
197 
198 /////////////
199 // Optimal //
200 /////////////
201 
202 static inline void
203 make_literal(lzma_optimal *optimal)
204 {
205 	optimal->back_prev = UINT32_MAX;
206 	optimal->prev_1_is_literal = false;
207 }
208 
209 
210 static inline void
211 make_short_rep(lzma_optimal *optimal)
212 {
213 	optimal->back_prev = 0;
214 	optimal->prev_1_is_literal = false;
215 }
216 
217 
218 #define is_short_rep(optimal) \
219 	((optimal).back_prev == 0)
220 
221 
222 static void
223 backward(lzma_lzma1_encoder *restrict coder, uint32_t *restrict len_res,
224 		uint32_t *restrict back_res, uint32_t cur)
225 {
226 	coder->opts_end_index = cur;
227 
228 	uint32_t pos_mem = coder->opts[cur].pos_prev;
229 	uint32_t back_mem = coder->opts[cur].back_prev;
230 
231 	do {
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;
235 
236 			if (coder->opts[cur].prev_2) {
237 				coder->opts[pos_mem - 1].prev_1_is_literal
238 						= false;
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;
243 			}
244 		}
245 
246 		const uint32_t pos_prev = pos_mem;
247 		const uint32_t back_cur = back_mem;
248 
249 		back_mem = coder->opts[pos_prev].back_prev;
250 		pos_mem = coder->opts[pos_prev].pos_prev;
251 
252 		coder->opts[pos_prev].back_prev = back_cur;
253 		coder->opts[pos_prev].pos_prev = cur;
254 		cur = pos_prev;
255 
256 	} while (cur != 0);
257 
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;
261 
262 	return;
263 }
264 
265 
266 //////////
267 // Main //
268 //////////
269 
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,
273 		uint32_t position)
274 {
275 	const uint32_t nice_len = mf->nice_len;
276 
277 	uint32_t len_main;
278 	uint32_t matches_count;
279 
280 	if (mf->read_ahead == 0) {
281 		len_main = mf_find(mf, &matches_count, coder->matches);
282 	} else {
283 		assert(mf->read_ahead == 1);
284 		len_main = coder->longest_match_length;
285 		matches_count = coder->matches_count;
286 	}
287 
288 	const uint32_t buf_avail = my_min(mf_avail(mf) + 1, MATCH_LEN_MAX);
289 	if (buf_avail < 2) {
290 		*back_res = UINT32_MAX;
291 		*len_res = 1;
292 		return UINT32_MAX;
293 	}
294 
295 	const uint8_t *const buf = mf_ptr(mf) - 1;
296 
297 	uint32_t rep_lens[REPS];
298 	uint32_t rep_max_index = 0;
299 
300 	for (uint32_t i = 0; i < REPS; ++i) {
301 		const uint8_t *const buf_back = buf - coder->reps[i] - 1;
302 
303 		if (not_equal_16(buf, buf_back)) {
304 			rep_lens[i] = 0;
305 			continue;
306 		}
307 
308 		rep_lens[i] = lzma_memcmplen(buf, buf_back, 2, buf_avail);
309 
310 		if (rep_lens[i] > rep_lens[rep_max_index])
311 			rep_max_index = i;
312 	}
313 
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);
318 		return UINT32_MAX;
319 	}
320 
321 
322 	if (len_main >= nice_len) {
323 		*back_res = coder->matches[matches_count - 1].dist + REPS;
324 		*len_res = len_main;
325 		mf_skip(mf, len_main - 1);
326 		return UINT32_MAX;
327 	}
328 
329 	const uint8_t current_byte = *buf;
330 	const uint8_t match_byte = *(buf - coder->reps[0] - 1);
331 
332 	if (len_main < 2 && current_byte != match_byte
333 			&& rep_lens[rep_max_index] < 2) {
334 		*back_res = UINT32_MAX;
335 		*len_res = 1;
336 		return UINT32_MAX;
337 	}
338 
339 	coder->opts[0].state = coder->state;
340 
341 	const uint32_t pos_state = position & coder->pos_mask;
342 
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);
348 
349 	make_literal(&coder->opts[1]);
350 
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]);
355 
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);
360 
361 		if (short_rep_price < coder->opts[1].price) {
362 			coder->opts[1].price = short_rep_price;
363 			make_short_rep(&coder->opts[1]);
364 		}
365 	}
366 
367 	const uint32_t len_end = my_max(len_main, rep_lens[rep_max_index]);
368 
369 	if (len_end < 2) {
370 		*back_res = coder->opts[1].back_prev;
371 		*len_res = 1;
372 		return UINT32_MAX;
373 	}
374 
375 	coder->opts[1].pos_prev = 0;
376 
377 	for (uint32_t i = 0; i < REPS; ++i)
378 		coder->opts[0].backs[i] = coder->reps[i];
379 
380 	uint32_t len = len_end;
381 	do {
382 		coder->opts[len].price = RC_INFINITY_PRICE;
383 	} while (--len >= 2);
384 
385 
386 	for (uint32_t i = 0; i < REPS; ++i) {
387 		uint32_t rep_len = rep_lens[i];
388 		if (rep_len < 2)
389 			continue;
390 
391 		const uint32_t price = rep_match_price + get_pure_rep_price(
392 				coder, i, coder->state, pos_state);
393 
394 		do {
395 			const uint32_t cur_and_len_price = price
396 					+ get_len_price(
397 						&coder->rep_len_encoder,
398 						rep_len, pos_state);
399 
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;
405 			}
406 		} while (--rep_len >= 2);
407 	}
408 
409 
410 	const uint32_t normal_match_price = match_price
411 			+ rc_bit_0_price(coder->is_rep[coder->state]);
412 
413 	len = rep_lens[0] >= 2 ? rep_lens[0] + 1 : 2;
414 	if (len <= len_main) {
415 		uint32_t i = 0;
416 		while (len > coder->matches[i].len)
417 			++i;
418 
419 		for(; ; ++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);
424 
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;
430 			}
431 
432 			if (len == coder->matches[i].len)
433 				if (++i == matches_count)
434 					break;
435 		}
436 	}
437 
438 	return len_end;
439 }
440 
441 
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)
446 {
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;
451 
452 	if (coder->opts[cur].prev_1_is_literal) {
453 		--pos_prev;
454 
455 		if (coder->opts[cur].prev_2) {
456 			state = coder->opts[coder->opts[cur].pos_prev_2].state;
457 
458 			if (coder->opts[cur].back_prev_2 < REPS)
459 				update_long_rep(state);
460 			else
461 				update_match(state);
462 
463 		} else {
464 			state = coder->opts[pos_prev].state;
465 		}
466 
467 		update_literal(state);
468 
469 	} else {
470 		state = coder->opts[pos_prev].state;
471 	}
472 
473 	if (pos_prev == cur - 1) {
474 		if (is_short_rep(coder->opts[cur]))
475 			update_short_rep(state);
476 		else
477 			update_literal(state);
478 	} else {
479 		uint32_t pos;
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);
485 		} else {
486 			pos = coder->opts[cur].back_prev;
487 			if (pos < REPS)
488 				update_long_rep(state);
489 			else
490 				update_match(state);
491 		}
492 
493 		if (pos < REPS) {
494 			reps[0] = coder->opts[pos_prev].backs[pos];
495 
496 			uint32_t i;
497 			for (i = 1; i <= pos; ++i)
498 				reps[i] = coder->opts[pos_prev].backs[i - 1];
499 
500 			for (; i < REPS; ++i)
501 				reps[i] = coder->opts[pos_prev].backs[i];
502 
503 		} else {
504 			reps[0] = pos - REPS;
505 
506 			for (uint32_t i = 1; i < REPS; ++i)
507 				reps[i] = coder->opts[pos_prev].backs[i - 1];
508 		}
509 	}
510 
511 	coder->opts[cur].state = state;
512 
513 	for (uint32_t i = 0; i < REPS; ++i)
514 		coder->opts[cur].backs[i] = reps[i];
515 
516 	const uint32_t cur_price = coder->opts[cur].price;
517 
518 	const uint8_t current_byte = *buf;
519 	const uint8_t match_byte = *(buf - reps[0] - 1);
520 
521 	const uint32_t pos_state = position & coder->pos_mask;
522 
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);
527 
528 	bool next_is_literal = false;
529 
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;
535 	}
536 
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]);
541 
542 	if (match_byte == current_byte
543 			&& !(coder->opts[cur + 1].pos_prev < cur
544 				&& coder->opts[cur + 1].back_prev == 0)) {
545 
546 		const uint32_t short_rep_price = rep_match_price
547 				+ get_short_rep_price(coder, state, pos_state);
548 
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;
554 		}
555 	}
556 
557 	if (buf_avail_full < 2)
558 		return len_end;
559 
560 	const uint32_t buf_avail = my_min(buf_avail_full, nice_len);
561 
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);
566 
567 		const uint32_t len_test = lzma_memcmplen(buf, buf_back, 1, limit) - 1;
568 
569 		if (len_test >= 2) {
570 			lzma_lzma_state state_2 = state;
571 			update_literal(state_2);
572 
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]);
577 
578 			//for (; len_test >= 2; --len_test) {
579 			const uint32_t offset = cur + 1 + len_test;
580 
581 			while (len_end < offset)
582 				coder->opts[++len_end].price = RC_INFINITY_PRICE;
583 
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);
587 
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;
594 			}
595 			//}
596 		}
597 	}
598 
599 
600 	uint32_t start_len = 2; // speed optimization
601 
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))
605 			continue;
606 
607 		uint32_t len_test = lzma_memcmplen(buf, buf_back, 2, buf_avail);
608 
609 		while (len_end < cur + len_test)
610 			coder->opts[++len_end].price = RC_INFINITY_PRICE;
611 
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);
615 
616 		do {
617 			const uint32_t cur_and_len_price = price
618 					+ get_len_price(&coder->rep_len_encoder,
619 							len_test, pos_state);
620 
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;
626 			}
627 		} while (--len_test >= 2);
628 
629 		len_test = len_test_temp;
630 
631 		if (rep_index == 0)
632 			start_len = len_test + 1;
633 
634 
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);
642 
643 		len_test_2 -= len_test + 1;
644 
645 		if (len_test_2 >= 2) {
646 			lzma_lzma_state state_2 = state;
647 			update_long_rep(state_2);
648 
649 			uint32_t pos_state_next = (position + len_test) & coder->pos_mask;
650 
651 			const uint32_t cur_and_len_literal_price = price
652 					+ get_len_price(&coder->rep_len_encoder,
653 						len_test, pos_state)
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]);
658 
659 			update_literal(state_2);
660 
661 			pos_state_next = (position + len_test + 1) & coder->pos_mask;
662 
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]);
666 
667 			//for(; len_test_2 >= 2; len_test_2--) {
668 			const uint32_t offset = cur + len_test + 1 + len_test_2;
669 
670 			while (len_end < offset)
671 				coder->opts[++len_end].price = RC_INFINITY_PRICE;
672 
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);
676 
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;
685 			}
686 			//}
687 		}
688 	}
689 
690 
691 	//for (uint32_t len_test = 2; len_test <= new_len; ++len_test)
692 	if (new_len > buf_avail) {
693 		new_len = buf_avail;
694 
695 		matches_count = 0;
696 		while (new_len > coder->matches[matches_count].len)
697 			++matches_count;
698 
699 		coder->matches[matches_count++].len = new_len;
700 	}
701 
702 
703 	if (new_len >= start_len) {
704 		const uint32_t normal_match_price = match_price
705 				+ rc_bit_0_price(coder->is_rep[state]);
706 
707 		while (len_end < cur + new_len)
708 			coder->opts[++len_end].price = RC_INFINITY_PRICE;
709 
710 		uint32_t i = 0;
711 		while (start_len > coder->matches[i].len)
712 			++i;
713 
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);
719 
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
724 						= cur_back + REPS;
725 				coder->opts[cur + len_test].prev_1_is_literal = false;
726 			}
727 
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);
734 
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,
740 							len_test_2, limit);
741 
742 				len_test_2 -= len_test + 1;
743 
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;
749 
750 					const uint32_t cur_and_len_literal_price = cur_and_len_price
751 							+ rc_bit_0_price(
752 								coder->is_match[state_2][pos_state_next])
753 							+ get_literal_price(coder,
754 								position + len_test,
755 								buf[len_test - 1],
756 								true,
757 								buf_back[len_test],
758 								buf[len_test]);
759 
760 					update_literal(state_2);
761 					pos_state_next = (pos_state_next + 1) & coder->pos_mask;
762 
763 					const uint32_t next_rep_match_price
764 							= cur_and_len_literal_price
765 							+ rc_bit_1_price(
766 								coder->is_match[state_2][pos_state_next])
767 							+ rc_bit_1_price(coder->is_rep[state_2]);
768 
769 					// for(; len_test_2 >= 2; --len_test_2) {
770 					const uint32_t offset = cur + len_test + 1 + len_test_2;
771 
772 					while (len_end < offset)
773 						coder->opts[++len_end].price = RC_INFINITY_PRICE;
774 
775 					cur_and_len_price = next_rep_match_price
776 							+ get_rep_price(coder, 0, len_test_2,
777 								state_2, pos_state_next);
778 
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
787 								= cur_back + REPS;
788 					}
789 					//}
790 				}
791 
792 				if (++i == matches_count)
793 					break;
794 			}
795 		}
796 	}
797 
798 	return len_end;
799 }
800 
801 
802 extern void
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,
806 		uint32_t position)
807 {
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;
816 		return;
817 	}
818 
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);
825 
826 		if (coder->align_price_count >= ALIGN_SIZE)
827 			fill_align_prices(coder);
828 	}
829 
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.
833 
834 	uint32_t len_end = helper1(coder, mf, back_res, len_res, position);
835 	if (len_end == UINT32_MAX)
836 		return;
837 
838 	uint32_t reps[REPS];
839 	memcpy(reps, coder->reps, sizeof(reps));
840 
841 	uint32_t cur;
842 	for (cur = 1; cur < len_end; ++cur) {
843 		assert(cur < OPTS);
844 
845 		coder->longest_match_length = mf_find(
846 				mf, &coder->matches_count, coder->matches);
847 
848 		if (coder->longest_match_length >= mf->nice_len)
849 			break;
850 
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));
854 	}
855 
856 	backward(coder, len_res, back_res, cur);
857 	return;
858 }
859