1///////////////////////////////////////////////////////////////////////////////
2//
3/// \file       lzma_encoder_optimum_normal.c
4//
5//  Author:     Igor Pavlov
6//
7//  This file has been put into the public domain.
8//  You can do whatever you want with this file.
9//
10///////////////////////////////////////////////////////////////////////////////
11
12#include "lzma_encoder_private.h"
13#include "fastpos.h"
14
15
16////////////
17// Prices //
18////////////
19
20static uint32_t
21get_literal_price(const lzma_coder *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_pos_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
56static inline uint32_t
57get_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
66static inline uint32_t
67get_short_rep_price(const lzma_coder *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
75static inline uint32_t
76get_pure_rep_price(const lzma_coder *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
100static inline uint32_t
101get_rep_price(const lzma_coder *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
110static inline uint32_t
111get_pos_len_price(const lzma_coder *const coder, const uint32_t pos,
112		const uint32_t len, const uint32_t pos_state)
113{
114	const uint32_t len_to_pos_state = get_len_to_pos_state(len);
115	uint32_t price;
116
117	if (pos < FULL_DISTANCES) {
118		price = coder->distances_prices[len_to_pos_state][pos];
119	} else {
120		const uint32_t pos_slot = get_pos_slot_2(pos);
121		price = coder->pos_slot_prices[len_to_pos_state][pos_slot]
122				+ coder->align_prices[pos & ALIGN_MASK];
123	}
124
125	price += get_len_price(&coder->match_len_encoder, len, pos_state);
126
127	return price;
128}
129
130
131static void
132fill_distances_prices(lzma_coder *coder)
133{
134	for (uint32_t len_to_pos_state = 0;
135			len_to_pos_state < LEN_TO_POS_STATES;
136			++len_to_pos_state) {
137
138		uint32_t *const pos_slot_prices
139				= coder->pos_slot_prices[len_to_pos_state];
140
141		// Price to encode the pos_slot.
142		for (uint32_t pos_slot = 0;
143				pos_slot < coder->dist_table_size; ++pos_slot)
144			pos_slot_prices[pos_slot] = rc_bittree_price(
145					coder->pos_slot[len_to_pos_state],
146					POS_SLOT_BITS, pos_slot);
147
148		// For matches with distance >= FULL_DISTANCES, add the price
149		// of the direct bits part of the match distance. (Align bits
150		// are handled by fill_align_prices()).
151		for (uint32_t pos_slot = END_POS_MODEL_INDEX;
152				pos_slot < coder->dist_table_size; ++pos_slot)
153			pos_slot_prices[pos_slot] += rc_direct_price(
154					((pos_slot >> 1) - 1) - ALIGN_BITS);
155
156		// Distances in the range [0, 3] are fully encoded with
157		// pos_slot, so they are used for coder->distances_prices
158		// as is.
159		for (uint32_t i = 0; i < START_POS_MODEL_INDEX; ++i)
160			coder->distances_prices[len_to_pos_state][i]
161					= pos_slot_prices[i];
162	}
163
164	// Distances in the range [4, 127] depend on pos_slot and pos_special.
165	// We do this in a loop separate from the above loop to avoid
166	// redundant calls to get_pos_slot().
167	for (uint32_t i = START_POS_MODEL_INDEX; i < FULL_DISTANCES; ++i) {
168		const uint32_t pos_slot = get_pos_slot(i);
169		const uint32_t footer_bits = ((pos_slot >> 1) - 1);
170		const uint32_t base = (2 | (pos_slot & 1)) << footer_bits;
171		const uint32_t price = rc_bittree_reverse_price(
172				coder->pos_special + base - pos_slot - 1,
173				footer_bits, i - base);
174
175		for (uint32_t len_to_pos_state = 0;
176				len_to_pos_state < LEN_TO_POS_STATES;
177				++len_to_pos_state)
178			coder->distances_prices[len_to_pos_state][i]
179					= price + coder->pos_slot_prices[
180						len_to_pos_state][pos_slot];
181	}
182
183	coder->match_price_count = 0;
184	return;
185}
186
187
188static void
189fill_align_prices(lzma_coder *coder)
190{
191	for (uint32_t i = 0; i < ALIGN_TABLE_SIZE; ++i)
192		coder->align_prices[i] = rc_bittree_reverse_price(
193				coder->pos_align, ALIGN_BITS, i);
194
195	coder->align_price_count = 0;
196	return;
197}
198
199
200/////////////
201// Optimal //
202/////////////
203
204static inline void
205make_literal(lzma_optimal *optimal)
206{
207	optimal->back_prev = UINT32_MAX;
208	optimal->prev_1_is_literal = false;
209}
210
211
212static inline void
213make_short_rep(lzma_optimal *optimal)
214{
215	optimal->back_prev = 0;
216	optimal->prev_1_is_literal = false;
217}
218
219
220#define is_short_rep(optimal) \
221	((optimal).back_prev == 0)
222
223
224static void
225backward(lzma_coder *restrict coder, uint32_t *restrict len_res,
226		uint32_t *restrict back_res, uint32_t cur)
227{
228	coder->opts_end_index = cur;
229
230	uint32_t pos_mem = coder->opts[cur].pos_prev;
231	uint32_t back_mem = coder->opts[cur].back_prev;
232
233	do {
234		if (coder->opts[cur].prev_1_is_literal) {
235			make_literal(&coder->opts[pos_mem]);
236			coder->opts[pos_mem].pos_prev = pos_mem - 1;
237
238			if (coder->opts[cur].prev_2) {
239				coder->opts[pos_mem - 1].prev_1_is_literal
240						= false;
241				coder->opts[pos_mem - 1].pos_prev
242						= coder->opts[cur].pos_prev_2;
243				coder->opts[pos_mem - 1].back_prev
244						= coder->opts[cur].back_prev_2;
245			}
246		}
247
248		const uint32_t pos_prev = pos_mem;
249		const uint32_t back_cur = back_mem;
250
251		back_mem = coder->opts[pos_prev].back_prev;
252		pos_mem = coder->opts[pos_prev].pos_prev;
253
254		coder->opts[pos_prev].back_prev = back_cur;
255		coder->opts[pos_prev].pos_prev = cur;
256		cur = pos_prev;
257
258	} while (cur != 0);
259
260	coder->opts_current_index = coder->opts[0].pos_prev;
261	*len_res = coder->opts[0].pos_prev;
262	*back_res = coder->opts[0].back_prev;
263
264	return;
265}
266
267
268//////////
269// Main //
270//////////
271
272static inline uint32_t
273helper1(lzma_coder *restrict coder, lzma_mf *restrict mf,
274		uint32_t *restrict back_res, uint32_t *restrict len_res,
275		uint32_t position)
276{
277	const uint32_t nice_len = mf->nice_len;
278
279	uint32_t len_main;
280	uint32_t matches_count;
281
282	if (mf->read_ahead == 0) {
283		len_main = mf_find(mf, &matches_count, coder->matches);
284	} else {
285		assert(mf->read_ahead == 1);
286		len_main = coder->longest_match_length;
287		matches_count = coder->matches_count;
288	}
289
290	const uint32_t buf_avail = my_min(mf_avail(mf) + 1, MATCH_LEN_MAX);
291	if (buf_avail < 2) {
292		*back_res = UINT32_MAX;
293		*len_res = 1;
294		return UINT32_MAX;
295	}
296
297	const uint8_t *const buf = mf_ptr(mf) - 1;
298
299	uint32_t rep_lens[REP_DISTANCES];
300	uint32_t rep_max_index = 0;
301
302	for (uint32_t i = 0; i < REP_DISTANCES; ++i) {
303		const uint8_t *const buf_back = buf - coder->reps[i] - 1;
304
305		if (not_equal_16(buf, buf_back)) {
306			rep_lens[i] = 0;
307			continue;
308		}
309
310		uint32_t len_test;
311		for (len_test = 2; len_test < buf_avail
312				&& buf[len_test] == buf_back[len_test];
313				++len_test) ;
314
315		rep_lens[i] = len_test;
316		if (len_test > rep_lens[rep_max_index])
317			rep_max_index = i;
318	}
319
320	if (rep_lens[rep_max_index] >= nice_len) {
321		*back_res = rep_max_index;
322		*len_res = rep_lens[rep_max_index];
323		mf_skip(mf, *len_res - 1);
324		return UINT32_MAX;
325	}
326
327
328	if (len_main >= nice_len) {
329		*back_res = coder->matches[matches_count - 1].dist
330				+ REP_DISTANCES;
331		*len_res = len_main;
332		mf_skip(mf, len_main - 1);
333		return UINT32_MAX;
334	}
335
336	const uint8_t current_byte = *buf;
337	const uint8_t match_byte = *(buf - coder->reps[0] - 1);
338
339	if (len_main < 2 && current_byte != match_byte
340			&& rep_lens[rep_max_index] < 2) {
341		*back_res = UINT32_MAX;
342		*len_res = 1;
343		return UINT32_MAX;
344	}
345
346	coder->opts[0].state = coder->state;
347
348	const uint32_t pos_state = position & coder->pos_mask;
349
350	coder->opts[1].price = rc_bit_0_price(
351				coder->is_match[coder->state][pos_state])
352			+ get_literal_price(coder, position, buf[-1],
353				!is_literal_state(coder->state),
354				match_byte, current_byte);
355
356	make_literal(&coder->opts[1]);
357
358	const uint32_t match_price = rc_bit_1_price(
359			coder->is_match[coder->state][pos_state]);
360	const uint32_t rep_match_price = match_price
361			+ rc_bit_1_price(coder->is_rep[coder->state]);
362
363	if (match_byte == current_byte) {
364		const uint32_t short_rep_price = rep_match_price
365				+ get_short_rep_price(
366					coder, coder->state, pos_state);
367
368		if (short_rep_price < coder->opts[1].price) {
369			coder->opts[1].price = short_rep_price;
370			make_short_rep(&coder->opts[1]);
371		}
372	}
373
374	const uint32_t len_end = my_max(len_main, rep_lens[rep_max_index]);
375
376	if (len_end < 2) {
377		*back_res = coder->opts[1].back_prev;
378		*len_res = 1;
379		return UINT32_MAX;
380	}
381
382	coder->opts[1].pos_prev = 0;
383
384	for (uint32_t i = 0; i < REP_DISTANCES; ++i)
385		coder->opts[0].backs[i] = coder->reps[i];
386
387	uint32_t len = len_end;
388	do {
389		coder->opts[len].price = RC_INFINITY_PRICE;
390	} while (--len >= 2);
391
392
393	for (uint32_t i = 0; i < REP_DISTANCES; ++i) {
394		uint32_t rep_len = rep_lens[i];
395		if (rep_len < 2)
396			continue;
397
398		const uint32_t price = rep_match_price + get_pure_rep_price(
399				coder, i, coder->state, pos_state);
400
401		do {
402			const uint32_t cur_and_len_price = price
403					+ get_len_price(
404						&coder->rep_len_encoder,
405						rep_len, pos_state);
406
407			if (cur_and_len_price < coder->opts[rep_len].price) {
408				coder->opts[rep_len].price = cur_and_len_price;
409				coder->opts[rep_len].pos_prev = 0;
410				coder->opts[rep_len].back_prev = i;
411				coder->opts[rep_len].prev_1_is_literal = false;
412			}
413		} while (--rep_len >= 2);
414	}
415
416
417	const uint32_t normal_match_price = match_price
418			+ rc_bit_0_price(coder->is_rep[coder->state]);
419
420	len = rep_lens[0] >= 2 ? rep_lens[0] + 1 : 2;
421	if (len <= len_main) {
422		uint32_t i = 0;
423		while (len > coder->matches[i].len)
424			++i;
425
426		for(; ; ++len) {
427			const uint32_t dist = coder->matches[i].dist;
428			const uint32_t cur_and_len_price = normal_match_price
429					+ get_pos_len_price(coder,
430						dist, len, pos_state);
431
432			if (cur_and_len_price < coder->opts[len].price) {
433				coder->opts[len].price = cur_and_len_price;
434				coder->opts[len].pos_prev = 0;
435				coder->opts[len].back_prev
436						= dist + REP_DISTANCES;
437				coder->opts[len].prev_1_is_literal = false;
438			}
439
440			if (len == coder->matches[i].len)
441				if (++i == matches_count)
442					break;
443		}
444	}
445
446	return len_end;
447}
448
449
450static inline uint32_t
451helper2(lzma_coder *coder, uint32_t *reps, const uint8_t *buf,
452		uint32_t len_end, uint32_t position, const uint32_t cur,
453		const uint32_t nice_len, const uint32_t buf_avail_full)
454{
455	uint32_t matches_count = coder->matches_count;
456	uint32_t new_len = coder->longest_match_length;
457	uint32_t pos_prev = coder->opts[cur].pos_prev;
458	lzma_lzma_state state;
459
460	if (coder->opts[cur].prev_1_is_literal) {
461		--pos_prev;
462
463		if (coder->opts[cur].prev_2) {
464			state = coder->opts[coder->opts[cur].pos_prev_2].state;
465
466			if (coder->opts[cur].back_prev_2 < REP_DISTANCES)
467				update_long_rep(state);
468			else
469				update_match(state);
470
471		} else {
472			state = coder->opts[pos_prev].state;
473		}
474
475		update_literal(state);
476
477	} else {
478		state = coder->opts[pos_prev].state;
479	}
480
481	if (pos_prev == cur - 1) {
482		if (is_short_rep(coder->opts[cur]))
483			update_short_rep(state);
484		else
485			update_literal(state);
486	} else {
487		uint32_t pos;
488		if (coder->opts[cur].prev_1_is_literal
489				&& coder->opts[cur].prev_2) {
490			pos_prev = coder->opts[cur].pos_prev_2;
491			pos = coder->opts[cur].back_prev_2;
492			update_long_rep(state);
493		} else {
494			pos = coder->opts[cur].back_prev;
495			if (pos < REP_DISTANCES)
496				update_long_rep(state);
497			else
498				update_match(state);
499		}
500
501		if (pos < REP_DISTANCES) {
502			reps[0] = coder->opts[pos_prev].backs[pos];
503
504			uint32_t i;
505			for (i = 1; i <= pos; ++i)
506				reps[i] = coder->opts[pos_prev].backs[i - 1];
507
508			for (; i < REP_DISTANCES; ++i)
509				reps[i] = coder->opts[pos_prev].backs[i];
510
511		} else {
512			reps[0] = pos - REP_DISTANCES;
513
514			for (uint32_t i = 1; i < REP_DISTANCES; ++i)
515				reps[i] = coder->opts[pos_prev].backs[i - 1];
516		}
517	}
518
519	coder->opts[cur].state = state;
520
521	for (uint32_t i = 0; i < REP_DISTANCES; ++i)
522		coder->opts[cur].backs[i] = reps[i];
523
524	const uint32_t cur_price = coder->opts[cur].price;
525
526	const uint8_t current_byte = *buf;
527	const uint8_t match_byte = *(buf - reps[0] - 1);
528
529	const uint32_t pos_state = position & coder->pos_mask;
530
531	const uint32_t cur_and_1_price = cur_price
532			+ rc_bit_0_price(coder->is_match[state][pos_state])
533			+ get_literal_price(coder, position, buf[-1],
534			!is_literal_state(state), match_byte, current_byte);
535
536	bool next_is_literal = false;
537
538	if (cur_and_1_price < coder->opts[cur + 1].price) {
539		coder->opts[cur + 1].price = cur_and_1_price;
540		coder->opts[cur + 1].pos_prev = cur;
541		make_literal(&coder->opts[cur + 1]);
542		next_is_literal = true;
543	}
544
545	const uint32_t match_price = cur_price
546			+ rc_bit_1_price(coder->is_match[state][pos_state]);
547	const uint32_t rep_match_price = match_price
548			+ rc_bit_1_price(coder->is_rep[state]);
549
550	if (match_byte == current_byte
551			&& !(coder->opts[cur + 1].pos_prev < cur
552				&& coder->opts[cur + 1].back_prev == 0)) {
553
554		const uint32_t short_rep_price = rep_match_price
555				+ get_short_rep_price(coder, state, pos_state);
556
557		if (short_rep_price <= coder->opts[cur + 1].price) {
558			coder->opts[cur + 1].price = short_rep_price;
559			coder->opts[cur + 1].pos_prev = cur;
560			make_short_rep(&coder->opts[cur + 1]);
561			next_is_literal = true;
562		}
563	}
564
565	if (buf_avail_full < 2)
566		return len_end;
567
568	const uint32_t buf_avail = my_min(buf_avail_full, nice_len);
569
570	if (!next_is_literal && match_byte != current_byte) { // speed optimization
571		// try literal + rep0
572		const uint8_t *const buf_back = buf - reps[0] - 1;
573		const uint32_t limit = my_min(buf_avail_full, nice_len + 1);
574
575		uint32_t len_test = 1;
576		while (len_test < limit && buf[len_test] == buf_back[len_test])
577			++len_test;
578
579		--len_test;
580
581		if (len_test >= 2) {
582			lzma_lzma_state state_2 = state;
583			update_literal(state_2);
584
585			const uint32_t pos_state_next = (position + 1) & coder->pos_mask;
586			const uint32_t next_rep_match_price = cur_and_1_price
587					+ rc_bit_1_price(coder->is_match[state_2][pos_state_next])
588					+ rc_bit_1_price(coder->is_rep[state_2]);
589
590			//for (; len_test >= 2; --len_test) {
591			const uint32_t offset = cur + 1 + len_test;
592
593			while (len_end < offset)
594				coder->opts[++len_end].price = RC_INFINITY_PRICE;
595
596			const uint32_t cur_and_len_price = next_rep_match_price
597					+ get_rep_price(coder, 0, len_test,
598						state_2, pos_state_next);
599
600			if (cur_and_len_price < coder->opts[offset].price) {
601				coder->opts[offset].price = cur_and_len_price;
602				coder->opts[offset].pos_prev = cur + 1;
603				coder->opts[offset].back_prev = 0;
604				coder->opts[offset].prev_1_is_literal = true;
605				coder->opts[offset].prev_2 = false;
606			}
607			//}
608		}
609	}
610
611
612	uint32_t start_len = 2; // speed optimization
613
614	for (uint32_t rep_index = 0; rep_index < REP_DISTANCES; ++rep_index) {
615		const uint8_t *const buf_back = buf - reps[rep_index] - 1;
616		if (not_equal_16(buf, buf_back))
617			continue;
618
619		uint32_t len_test;
620		for (len_test = 2; len_test < buf_avail
621				&& buf[len_test] == buf_back[len_test];
622				++len_test) ;
623
624		while (len_end < cur + len_test)
625			coder->opts[++len_end].price = RC_INFINITY_PRICE;
626
627		const uint32_t len_test_temp = len_test;
628		const uint32_t price = rep_match_price + get_pure_rep_price(
629				coder, rep_index, state, pos_state);
630
631		do {
632			const uint32_t cur_and_len_price = price
633					+ get_len_price(&coder->rep_len_encoder,
634							len_test, pos_state);
635
636			if (cur_and_len_price < coder->opts[cur + len_test].price) {
637				coder->opts[cur + len_test].price = cur_and_len_price;
638				coder->opts[cur + len_test].pos_prev = cur;
639				coder->opts[cur + len_test].back_prev = rep_index;
640				coder->opts[cur + len_test].prev_1_is_literal = false;
641			}
642		} while (--len_test >= 2);
643
644		len_test = len_test_temp;
645
646		if (rep_index == 0)
647			start_len = len_test + 1;
648
649
650		uint32_t len_test_2 = len_test + 1;
651		const uint32_t limit = my_min(buf_avail_full,
652				len_test_2 + nice_len);
653		for (; len_test_2 < limit
654				&& buf[len_test_2] == buf_back[len_test_2];
655				++len_test_2) ;
656
657		len_test_2 -= len_test + 1;
658
659		if (len_test_2 >= 2) {
660			lzma_lzma_state state_2 = state;
661			update_long_rep(state_2);
662
663			uint32_t pos_state_next = (position + len_test) & coder->pos_mask;
664
665			const uint32_t cur_and_len_literal_price = price
666					+ get_len_price(&coder->rep_len_encoder,
667						len_test, pos_state)
668					+ rc_bit_0_price(coder->is_match[state_2][pos_state_next])
669					+ get_literal_price(coder, position + len_test,
670						buf[len_test - 1], true,
671						buf_back[len_test], buf[len_test]);
672
673			update_literal(state_2);
674
675			pos_state_next = (position + len_test + 1) & coder->pos_mask;
676
677			const uint32_t next_rep_match_price = cur_and_len_literal_price
678					+ rc_bit_1_price(coder->is_match[state_2][pos_state_next])
679					+ rc_bit_1_price(coder->is_rep[state_2]);
680
681			//for(; len_test_2 >= 2; len_test_2--) {
682			const uint32_t offset = cur + len_test + 1 + len_test_2;
683
684			while (len_end < offset)
685				coder->opts[++len_end].price = RC_INFINITY_PRICE;
686
687			const uint32_t cur_and_len_price = next_rep_match_price
688					+ get_rep_price(coder, 0, len_test_2,
689						state_2, pos_state_next);
690
691			if (cur_and_len_price < coder->opts[offset].price) {
692				coder->opts[offset].price = cur_and_len_price;
693				coder->opts[offset].pos_prev = cur + len_test + 1;
694				coder->opts[offset].back_prev = 0;
695				coder->opts[offset].prev_1_is_literal = true;
696				coder->opts[offset].prev_2 = true;
697				coder->opts[offset].pos_prev_2 = cur;
698				coder->opts[offset].back_prev_2 = rep_index;
699			}
700			//}
701		}
702	}
703
704
705	//for (uint32_t len_test = 2; len_test <= new_len; ++len_test)
706	if (new_len > buf_avail) {
707		new_len = buf_avail;
708
709		matches_count = 0;
710		while (new_len > coder->matches[matches_count].len)
711			++matches_count;
712
713		coder->matches[matches_count++].len = new_len;
714	}
715
716
717	if (new_len >= start_len) {
718		const uint32_t normal_match_price = match_price
719				+ rc_bit_0_price(coder->is_rep[state]);
720
721		while (len_end < cur + new_len)
722			coder->opts[++len_end].price = RC_INFINITY_PRICE;
723
724		uint32_t i = 0;
725		while (start_len > coder->matches[i].len)
726			++i;
727
728		for (uint32_t len_test = start_len; ; ++len_test) {
729			const uint32_t cur_back = coder->matches[i].dist;
730			uint32_t cur_and_len_price = normal_match_price
731					+ get_pos_len_price(coder,
732						cur_back, len_test, pos_state);
733
734			if (cur_and_len_price < coder->opts[cur + len_test].price) {
735				coder->opts[cur + len_test].price = cur_and_len_price;
736				coder->opts[cur + len_test].pos_prev = cur;
737				coder->opts[cur + len_test].back_prev
738						= cur_back + REP_DISTANCES;
739				coder->opts[cur + len_test].prev_1_is_literal = false;
740			}
741
742			if (len_test == coder->matches[i].len) {
743				// Try Match + Literal + Rep0
744				const uint8_t *const buf_back = buf - cur_back - 1;
745				uint32_t len_test_2 = len_test + 1;
746				const uint32_t limit = my_min(buf_avail_full,
747						len_test_2 + nice_len);
748
749				for (; len_test_2 < limit &&
750						buf[len_test_2] == buf_back[len_test_2];
751						++len_test_2) ;
752
753				len_test_2 -= len_test + 1;
754
755				if (len_test_2 >= 2) {
756					lzma_lzma_state state_2 = state;
757					update_match(state_2);
758					uint32_t pos_state_next
759							= (position + len_test) & coder->pos_mask;
760
761					const uint32_t cur_and_len_literal_price = cur_and_len_price
762							+ rc_bit_0_price(
763								coder->is_match[state_2][pos_state_next])
764							+ get_literal_price(coder,
765								position + len_test,
766								buf[len_test - 1],
767								true,
768								buf_back[len_test],
769								buf[len_test]);
770
771					update_literal(state_2);
772					pos_state_next = (pos_state_next + 1) & coder->pos_mask;
773
774					const uint32_t next_rep_match_price
775							= cur_and_len_literal_price
776							+ rc_bit_1_price(
777								coder->is_match[state_2][pos_state_next])
778							+ rc_bit_1_price(coder->is_rep[state_2]);
779
780					// for(; len_test_2 >= 2; --len_test_2) {
781					const uint32_t offset = cur + len_test + 1 + len_test_2;
782
783					while (len_end < offset)
784						coder->opts[++len_end].price = RC_INFINITY_PRICE;
785
786					cur_and_len_price = next_rep_match_price
787							+ get_rep_price(coder, 0, len_test_2,
788								state_2, pos_state_next);
789
790					if (cur_and_len_price < coder->opts[offset].price) {
791						coder->opts[offset].price = cur_and_len_price;
792						coder->opts[offset].pos_prev = cur + len_test + 1;
793						coder->opts[offset].back_prev = 0;
794						coder->opts[offset].prev_1_is_literal = true;
795						coder->opts[offset].prev_2 = true;
796						coder->opts[offset].pos_prev_2 = cur;
797						coder->opts[offset].back_prev_2
798								= cur_back + REP_DISTANCES;
799					}
800					//}
801				}
802
803				if (++i == matches_count)
804					break;
805			}
806		}
807	}
808
809	return len_end;
810}
811
812
813extern void
814lzma_lzma_optimum_normal(lzma_coder *restrict coder, lzma_mf *restrict mf,
815		uint32_t *restrict back_res, uint32_t *restrict len_res,
816		uint32_t position)
817{
818	// If we have symbols pending, return the next pending symbol.
819	if (coder->opts_end_index != coder->opts_current_index) {
820		assert(mf->read_ahead > 0);
821		*len_res = coder->opts[coder->opts_current_index].pos_prev
822				- coder->opts_current_index;
823		*back_res = coder->opts[coder->opts_current_index].back_prev;
824		coder->opts_current_index = coder->opts[
825				coder->opts_current_index].pos_prev;
826		return;
827	}
828
829	// Update the price tables. In LZMA SDK <= 4.60 (and possibly later)
830	// this was done in both initialization function and in the main loop.
831	// In liblzma they were moved into this single place.
832	if (mf->read_ahead == 0) {
833		if (coder->match_price_count >= (1 << 7))
834			fill_distances_prices(coder);
835
836		if (coder->align_price_count >= ALIGN_TABLE_SIZE)
837			fill_align_prices(coder);
838	}
839
840	// TODO: This needs quite a bit of cleaning still. But splitting
841	// the original function into two pieces makes it at least a little
842	// more readable, since those two parts don't share many variables.
843
844	uint32_t len_end = helper1(coder, mf, back_res, len_res, position);
845	if (len_end == UINT32_MAX)
846		return;
847
848	uint32_t reps[REP_DISTANCES];
849	memcpy(reps, coder->reps, sizeof(reps));
850
851	uint32_t cur;
852	for (cur = 1; cur < len_end; ++cur) {
853		assert(cur < OPTS);
854
855		coder->longest_match_length = mf_find(
856				mf, &coder->matches_count, coder->matches);
857
858		if (coder->longest_match_length >= mf->nice_len)
859			break;
860
861		len_end = helper2(coder, reps, mf_ptr(mf) - 1, len_end,
862				position + cur, cur, mf->nice_len,
863				my_min(mf_avail(mf) + 1, OPTS - 1 - cur));
864	}
865
866	backward(coder, len_res, back_res, cur);
867	return;
868}
869