lzma_encoder_optimum_normal.c revision 292588
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#include "memcmplen.h"
15
16
17////////////
18// Prices //
19////////////
20
21static uint32_t
22get_literal_price(const lzma_coder *const coder, const uint32_t pos,
23		const uint32_t prev_byte, const bool match_mode,
24		uint32_t match_byte, uint32_t symbol)
25{
26	const probability *const subcoder = literal_subcoder(coder->literal,
27			coder->literal_context_bits, coder->literal_pos_mask,
28			pos, prev_byte);
29
30	uint32_t price = 0;
31
32	if (!match_mode) {
33		price = rc_bittree_price(subcoder, 8, symbol);
34	} else {
35		uint32_t offset = 0x100;
36		symbol += UINT32_C(1) << 8;
37
38		do {
39			match_byte <<= 1;
40
41			const uint32_t match_bit = match_byte & offset;
42			const uint32_t subcoder_index
43					= offset + match_bit + (symbol >> 8);
44			const uint32_t bit = (symbol >> 7) & 1;
45			price += rc_bit_price(subcoder[subcoder_index], bit);
46
47			symbol <<= 1;
48			offset &= ~(match_byte ^ symbol);
49
50		} while (symbol < (UINT32_C(1) << 16));
51	}
52
53	return price;
54}
55
56
57static inline uint32_t
58get_len_price(const lzma_length_encoder *const lencoder,
59		const uint32_t len, const uint32_t pos_state)
60{
61	// NOTE: Unlike the other price tables, length prices are updated
62	// in lzma_encoder.c
63	return lencoder->prices[pos_state][len - MATCH_LEN_MIN];
64}
65
66
67static inline uint32_t
68get_short_rep_price(const lzma_coder *const coder,
69		const lzma_lzma_state state, const uint32_t pos_state)
70{
71	return rc_bit_0_price(coder->is_rep0[state])
72		+ rc_bit_0_price(coder->is_rep0_long[state][pos_state]);
73}
74
75
76static inline uint32_t
77get_pure_rep_price(const lzma_coder *const coder, const uint32_t rep_index,
78		const lzma_lzma_state state, uint32_t pos_state)
79{
80	uint32_t price;
81
82	if (rep_index == 0) {
83		price = rc_bit_0_price(coder->is_rep0[state]);
84		price += rc_bit_1_price(coder->is_rep0_long[state][pos_state]);
85	} else {
86		price = rc_bit_1_price(coder->is_rep0[state]);
87
88		if (rep_index == 1) {
89			price += rc_bit_0_price(coder->is_rep1[state]);
90		} else {
91			price += rc_bit_1_price(coder->is_rep1[state]);
92			price += rc_bit_price(coder->is_rep2[state],
93					rep_index - 2);
94		}
95	}
96
97	return price;
98}
99
100
101static inline uint32_t
102get_rep_price(const lzma_coder *const coder, const uint32_t rep_index,
103		const uint32_t len, const lzma_lzma_state state,
104		const uint32_t pos_state)
105{
106	return get_len_price(&coder->rep_len_encoder, len, pos_state)
107		+ get_pure_rep_price(coder, rep_index, state, pos_state);
108}
109
110
111static inline uint32_t
112get_dist_len_price(const lzma_coder *const coder, const uint32_t dist,
113		const uint32_t len, const uint32_t pos_state)
114{
115	const uint32_t dist_state = get_dist_state(len);
116	uint32_t price;
117
118	if (dist < FULL_DISTANCES) {
119		price = coder->dist_prices[dist_state][dist];
120	} else {
121		const uint32_t dist_slot = get_dist_slot_2(dist);
122		price = coder->dist_slot_prices[dist_state][dist_slot]
123				+ coder->align_prices[dist & ALIGN_MASK];
124	}
125
126	price += get_len_price(&coder->match_len_encoder, len, pos_state);
127
128	return price;
129}
130
131
132static void
133fill_dist_prices(lzma_coder *coder)
134{
135	for (uint32_t dist_state = 0; dist_state < DIST_STATES; ++dist_state) {
136
137		uint32_t *const dist_slot_prices
138				= coder->dist_slot_prices[dist_state];
139
140		// Price to encode the dist_slot.
141		for (uint32_t dist_slot = 0;
142				dist_slot < coder->dist_table_size; ++dist_slot)
143			dist_slot_prices[dist_slot] = rc_bittree_price(
144					coder->dist_slot[dist_state],
145					DIST_SLOT_BITS, dist_slot);
146
147		// For matches with distance >= FULL_DISTANCES, add the price
148		// of the direct bits part of the match distance. (Align bits
149		// are handled by fill_align_prices()).
150		for (uint32_t dist_slot = DIST_MODEL_END;
151				dist_slot < coder->dist_table_size;
152				++dist_slot)
153			dist_slot_prices[dist_slot] += rc_direct_price(
154					((dist_slot >> 1) - 1) - ALIGN_BITS);
155
156		// Distances in the range [0, 3] are fully encoded with
157		// dist_slot, so they are used for coder->dist_prices
158		// as is.
159		for (uint32_t i = 0; i < DIST_MODEL_START; ++i)
160			coder->dist_prices[dist_state][i]
161					= dist_slot_prices[i];
162	}
163
164	// Distances in the range [4, 127] depend on dist_slot and
165	// dist_special. We do this in a loop separate from the above
166	// loop to avoid redundant calls to get_dist_slot().
167	for (uint32_t i = DIST_MODEL_START; i < FULL_DISTANCES; ++i) {
168		const uint32_t dist_slot = get_dist_slot(i);
169		const uint32_t footer_bits = ((dist_slot >> 1) - 1);
170		const uint32_t base = (2 | (dist_slot & 1)) << footer_bits;
171		const uint32_t price = rc_bittree_reverse_price(
172				coder->dist_special + base - dist_slot - 1,
173				footer_bits, i - base);
174
175		for (uint32_t dist_state = 0; dist_state < DIST_STATES;
176				++dist_state)
177			coder->dist_prices[dist_state][i]
178					= price + coder->dist_slot_prices[
179						dist_state][dist_slot];
180	}
181
182	coder->match_price_count = 0;
183	return;
184}
185
186
187static void
188fill_align_prices(lzma_coder *coder)
189{
190	for (uint32_t i = 0; i < ALIGN_SIZE; ++i)
191		coder->align_prices[i] = rc_bittree_reverse_price(
192				coder->dist_align, ALIGN_BITS, i);
193
194	coder->align_price_count = 0;
195	return;
196}
197
198
199/////////////
200// Optimal //
201/////////////
202
203static inline void
204make_literal(lzma_optimal *optimal)
205{
206	optimal->back_prev = UINT32_MAX;
207	optimal->prev_1_is_literal = false;
208}
209
210
211static inline void
212make_short_rep(lzma_optimal *optimal)
213{
214	optimal->back_prev = 0;
215	optimal->prev_1_is_literal = false;
216}
217
218
219#define is_short_rep(optimal) \
220	((optimal).back_prev == 0)
221
222
223static void
224backward(lzma_coder *restrict coder, uint32_t *restrict len_res,
225		uint32_t *restrict back_res, uint32_t cur)
226{
227	coder->opts_end_index = cur;
228
229	uint32_t pos_mem = coder->opts[cur].pos_prev;
230	uint32_t back_mem = coder->opts[cur].back_prev;
231
232	do {
233		if (coder->opts[cur].prev_1_is_literal) {
234			make_literal(&coder->opts[pos_mem]);
235			coder->opts[pos_mem].pos_prev = pos_mem - 1;
236
237			if (coder->opts[cur].prev_2) {
238				coder->opts[pos_mem - 1].prev_1_is_literal
239						= false;
240				coder->opts[pos_mem - 1].pos_prev
241						= coder->opts[cur].pos_prev_2;
242				coder->opts[pos_mem - 1].back_prev
243						= coder->opts[cur].back_prev_2;
244			}
245		}
246
247		const uint32_t pos_prev = pos_mem;
248		const uint32_t back_cur = back_mem;
249
250		back_mem = coder->opts[pos_prev].back_prev;
251		pos_mem = coder->opts[pos_prev].pos_prev;
252
253		coder->opts[pos_prev].back_prev = back_cur;
254		coder->opts[pos_prev].pos_prev = cur;
255		cur = pos_prev;
256
257	} while (cur != 0);
258
259	coder->opts_current_index = coder->opts[0].pos_prev;
260	*len_res = coder->opts[0].pos_prev;
261	*back_res = coder->opts[0].back_prev;
262
263	return;
264}
265
266
267//////////
268// Main //
269//////////
270
271static inline uint32_t
272helper1(lzma_coder *restrict coder, lzma_mf *restrict mf,
273		uint32_t *restrict back_res, uint32_t *restrict len_res,
274		uint32_t position)
275{
276	const uint32_t nice_len = mf->nice_len;
277
278	uint32_t len_main;
279	uint32_t matches_count;
280
281	if (mf->read_ahead == 0) {
282		len_main = mf_find(mf, &matches_count, coder->matches);
283	} else {
284		assert(mf->read_ahead == 1);
285		len_main = coder->longest_match_length;
286		matches_count = coder->matches_count;
287	}
288
289	const uint32_t buf_avail = my_min(mf_avail(mf) + 1, MATCH_LEN_MAX);
290	if (buf_avail < 2) {
291		*back_res = UINT32_MAX;
292		*len_res = 1;
293		return UINT32_MAX;
294	}
295
296	const uint8_t *const buf = mf_ptr(mf) - 1;
297
298	uint32_t rep_lens[REPS];
299	uint32_t rep_max_index = 0;
300
301	for (uint32_t i = 0; i < REPS; ++i) {
302		const uint8_t *const buf_back = buf - coder->reps[i] - 1;
303
304		if (not_equal_16(buf, buf_back)) {
305			rep_lens[i] = 0;
306			continue;
307		}
308
309		rep_lens[i] = lzma_memcmplen(buf, buf_back, 2, buf_avail);
310
311		if (rep_lens[i] > rep_lens[rep_max_index])
312			rep_max_index = i;
313	}
314
315	if (rep_lens[rep_max_index] >= nice_len) {
316		*back_res = rep_max_index;
317		*len_res = rep_lens[rep_max_index];
318		mf_skip(mf, *len_res - 1);
319		return UINT32_MAX;
320	}
321
322
323	if (len_main >= nice_len) {
324		*back_res = coder->matches[matches_count - 1].dist + REPS;
325		*len_res = len_main;
326		mf_skip(mf, len_main - 1);
327		return UINT32_MAX;
328	}
329
330	const uint8_t current_byte = *buf;
331	const uint8_t match_byte = *(buf - coder->reps[0] - 1);
332
333	if (len_main < 2 && current_byte != match_byte
334			&& rep_lens[rep_max_index] < 2) {
335		*back_res = UINT32_MAX;
336		*len_res = 1;
337		return UINT32_MAX;
338	}
339
340	coder->opts[0].state = coder->state;
341
342	const uint32_t pos_state = position & coder->pos_mask;
343
344	coder->opts[1].price = rc_bit_0_price(
345				coder->is_match[coder->state][pos_state])
346			+ get_literal_price(coder, position, buf[-1],
347				!is_literal_state(coder->state),
348				match_byte, current_byte);
349
350	make_literal(&coder->opts[1]);
351
352	const uint32_t match_price = rc_bit_1_price(
353			coder->is_match[coder->state][pos_state]);
354	const uint32_t rep_match_price = match_price
355			+ rc_bit_1_price(coder->is_rep[coder->state]);
356
357	if (match_byte == current_byte) {
358		const uint32_t short_rep_price = rep_match_price
359				+ get_short_rep_price(
360					coder, coder->state, pos_state);
361
362		if (short_rep_price < coder->opts[1].price) {
363			coder->opts[1].price = short_rep_price;
364			make_short_rep(&coder->opts[1]);
365		}
366	}
367
368	const uint32_t len_end = my_max(len_main, rep_lens[rep_max_index]);
369
370	if (len_end < 2) {
371		*back_res = coder->opts[1].back_prev;
372		*len_res = 1;
373		return UINT32_MAX;
374	}
375
376	coder->opts[1].pos_prev = 0;
377
378	for (uint32_t i = 0; i < REPS; ++i)
379		coder->opts[0].backs[i] = coder->reps[i];
380
381	uint32_t len = len_end;
382	do {
383		coder->opts[len].price = RC_INFINITY_PRICE;
384	} while (--len >= 2);
385
386
387	for (uint32_t i = 0; i < REPS; ++i) {
388		uint32_t rep_len = rep_lens[i];
389		if (rep_len < 2)
390			continue;
391
392		const uint32_t price = rep_match_price + get_pure_rep_price(
393				coder, i, coder->state, pos_state);
394
395		do {
396			const uint32_t cur_and_len_price = price
397					+ get_len_price(
398						&coder->rep_len_encoder,
399						rep_len, pos_state);
400
401			if (cur_and_len_price < coder->opts[rep_len].price) {
402				coder->opts[rep_len].price = cur_and_len_price;
403				coder->opts[rep_len].pos_prev = 0;
404				coder->opts[rep_len].back_prev = i;
405				coder->opts[rep_len].prev_1_is_literal = false;
406			}
407		} while (--rep_len >= 2);
408	}
409
410
411	const uint32_t normal_match_price = match_price
412			+ rc_bit_0_price(coder->is_rep[coder->state]);
413
414	len = rep_lens[0] >= 2 ? rep_lens[0] + 1 : 2;
415	if (len <= len_main) {
416		uint32_t i = 0;
417		while (len > coder->matches[i].len)
418			++i;
419
420		for(; ; ++len) {
421			const uint32_t dist = coder->matches[i].dist;
422			const uint32_t cur_and_len_price = normal_match_price
423					+ get_dist_len_price(coder,
424						dist, len, pos_state);
425
426			if (cur_and_len_price < coder->opts[len].price) {
427				coder->opts[len].price = cur_and_len_price;
428				coder->opts[len].pos_prev = 0;
429				coder->opts[len].back_prev = dist + REPS;
430				coder->opts[len].prev_1_is_literal = false;
431			}
432
433			if (len == coder->matches[i].len)
434				if (++i == matches_count)
435					break;
436		}
437	}
438
439	return len_end;
440}
441
442
443static inline uint32_t
444helper2(lzma_coder *coder, uint32_t *reps, const uint8_t *buf,
445		uint32_t len_end, uint32_t position, const uint32_t cur,
446		const uint32_t nice_len, const uint32_t buf_avail_full)
447{
448	uint32_t matches_count = coder->matches_count;
449	uint32_t new_len = coder->longest_match_length;
450	uint32_t pos_prev = coder->opts[cur].pos_prev;
451	lzma_lzma_state state;
452
453	if (coder->opts[cur].prev_1_is_literal) {
454		--pos_prev;
455
456		if (coder->opts[cur].prev_2) {
457			state = coder->opts[coder->opts[cur].pos_prev_2].state;
458
459			if (coder->opts[cur].back_prev_2 < REPS)
460				update_long_rep(state);
461			else
462				update_match(state);
463
464		} else {
465			state = coder->opts[pos_prev].state;
466		}
467
468		update_literal(state);
469
470	} else {
471		state = coder->opts[pos_prev].state;
472	}
473
474	if (pos_prev == cur - 1) {
475		if (is_short_rep(coder->opts[cur]))
476			update_short_rep(state);
477		else
478			update_literal(state);
479	} else {
480		uint32_t pos;
481		if (coder->opts[cur].prev_1_is_literal
482				&& coder->opts[cur].prev_2) {
483			pos_prev = coder->opts[cur].pos_prev_2;
484			pos = coder->opts[cur].back_prev_2;
485			update_long_rep(state);
486		} else {
487			pos = coder->opts[cur].back_prev;
488			if (pos < REPS)
489				update_long_rep(state);
490			else
491				update_match(state);
492		}
493
494		if (pos < REPS) {
495			reps[0] = coder->opts[pos_prev].backs[pos];
496
497			uint32_t i;
498			for (i = 1; i <= pos; ++i)
499				reps[i] = coder->opts[pos_prev].backs[i - 1];
500
501			for (; i < REPS; ++i)
502				reps[i] = coder->opts[pos_prev].backs[i];
503
504		} else {
505			reps[0] = pos - REPS;
506
507			for (uint32_t i = 1; i < REPS; ++i)
508				reps[i] = coder->opts[pos_prev].backs[i - 1];
509		}
510	}
511
512	coder->opts[cur].state = state;
513
514	for (uint32_t i = 0; i < REPS; ++i)
515		coder->opts[cur].backs[i] = reps[i];
516
517	const uint32_t cur_price = coder->opts[cur].price;
518
519	const uint8_t current_byte = *buf;
520	const uint8_t match_byte = *(buf - reps[0] - 1);
521
522	const uint32_t pos_state = position & coder->pos_mask;
523
524	const uint32_t cur_and_1_price = cur_price
525			+ rc_bit_0_price(coder->is_match[state][pos_state])
526			+ get_literal_price(coder, position, buf[-1],
527			!is_literal_state(state), match_byte, current_byte);
528
529	bool next_is_literal = false;
530
531	if (cur_and_1_price < coder->opts[cur + 1].price) {
532		coder->opts[cur + 1].price = cur_and_1_price;
533		coder->opts[cur + 1].pos_prev = cur;
534		make_literal(&coder->opts[cur + 1]);
535		next_is_literal = true;
536	}
537
538	const uint32_t match_price = cur_price
539			+ rc_bit_1_price(coder->is_match[state][pos_state]);
540	const uint32_t rep_match_price = match_price
541			+ rc_bit_1_price(coder->is_rep[state]);
542
543	if (match_byte == current_byte
544			&& !(coder->opts[cur + 1].pos_prev < cur
545				&& coder->opts[cur + 1].back_prev == 0)) {
546
547		const uint32_t short_rep_price = rep_match_price
548				+ get_short_rep_price(coder, state, pos_state);
549
550		if (short_rep_price <= coder->opts[cur + 1].price) {
551			coder->opts[cur + 1].price = short_rep_price;
552			coder->opts[cur + 1].pos_prev = cur;
553			make_short_rep(&coder->opts[cur + 1]);
554			next_is_literal = true;
555		}
556	}
557
558	if (buf_avail_full < 2)
559		return len_end;
560
561	const uint32_t buf_avail = my_min(buf_avail_full, nice_len);
562
563	if (!next_is_literal && match_byte != current_byte) { // speed optimization
564		// try literal + rep0
565		const uint8_t *const buf_back = buf - reps[0] - 1;
566		const uint32_t limit = my_min(buf_avail_full, nice_len + 1);
567
568		const uint32_t len_test = lzma_memcmplen(buf, buf_back, 1, limit) - 1;
569
570		if (len_test >= 2) {
571			lzma_lzma_state state_2 = state;
572			update_literal(state_2);
573
574			const uint32_t pos_state_next = (position + 1) & coder->pos_mask;
575			const uint32_t next_rep_match_price = cur_and_1_price
576					+ rc_bit_1_price(coder->is_match[state_2][pos_state_next])
577					+ rc_bit_1_price(coder->is_rep[state_2]);
578
579			//for (; len_test >= 2; --len_test) {
580			const uint32_t offset = cur + 1 + len_test;
581
582			while (len_end < offset)
583				coder->opts[++len_end].price = RC_INFINITY_PRICE;
584
585			const uint32_t cur_and_len_price = next_rep_match_price
586					+ get_rep_price(coder, 0, len_test,
587						state_2, pos_state_next);
588
589			if (cur_and_len_price < coder->opts[offset].price) {
590				coder->opts[offset].price = cur_and_len_price;
591				coder->opts[offset].pos_prev = cur + 1;
592				coder->opts[offset].back_prev = 0;
593				coder->opts[offset].prev_1_is_literal = true;
594				coder->opts[offset].prev_2 = false;
595			}
596			//}
597		}
598	}
599
600
601	uint32_t start_len = 2; // speed optimization
602
603	for (uint32_t rep_index = 0; rep_index < REPS; ++rep_index) {
604		const uint8_t *const buf_back = buf - reps[rep_index] - 1;
605		if (not_equal_16(buf, buf_back))
606			continue;
607
608		uint32_t len_test = lzma_memcmplen(buf, buf_back, 2, buf_avail);
609
610		while (len_end < cur + len_test)
611			coder->opts[++len_end].price = RC_INFINITY_PRICE;
612
613		const uint32_t len_test_temp = len_test;
614		const uint32_t price = rep_match_price + get_pure_rep_price(
615				coder, rep_index, state, pos_state);
616
617		do {
618			const uint32_t cur_and_len_price = price
619					+ get_len_price(&coder->rep_len_encoder,
620							len_test, pos_state);
621
622			if (cur_and_len_price < coder->opts[cur + len_test].price) {
623				coder->opts[cur + len_test].price = cur_and_len_price;
624				coder->opts[cur + len_test].pos_prev = cur;
625				coder->opts[cur + len_test].back_prev = rep_index;
626				coder->opts[cur + len_test].prev_1_is_literal = false;
627			}
628		} while (--len_test >= 2);
629
630		len_test = len_test_temp;
631
632		if (rep_index == 0)
633			start_len = len_test + 1;
634
635
636		uint32_t len_test_2 = len_test + 1;
637		const uint32_t limit = my_min(buf_avail_full,
638				len_test_2 + nice_len);
639		for (; len_test_2 < limit
640				&& buf[len_test_2] == buf_back[len_test_2];
641				++len_test_2) ;
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				for (; len_test_2 < limit &&
736						buf[len_test_2] == buf_back[len_test_2];
737						++len_test_2) ;
738
739				len_test_2 -= len_test + 1;
740
741				if (len_test_2 >= 2) {
742					lzma_lzma_state state_2 = state;
743					update_match(state_2);
744					uint32_t pos_state_next
745							= (position + len_test) & coder->pos_mask;
746
747					const uint32_t cur_and_len_literal_price = cur_and_len_price
748							+ rc_bit_0_price(
749								coder->is_match[state_2][pos_state_next])
750							+ get_literal_price(coder,
751								position + len_test,
752								buf[len_test - 1],
753								true,
754								buf_back[len_test],
755								buf[len_test]);
756
757					update_literal(state_2);
758					pos_state_next = (pos_state_next + 1) & coder->pos_mask;
759
760					const uint32_t next_rep_match_price
761							= cur_and_len_literal_price
762							+ rc_bit_1_price(
763								coder->is_match[state_2][pos_state_next])
764							+ rc_bit_1_price(coder->is_rep[state_2]);
765
766					// for(; len_test_2 >= 2; --len_test_2) {
767					const uint32_t offset = cur + len_test + 1 + len_test_2;
768
769					while (len_end < offset)
770						coder->opts[++len_end].price = RC_INFINITY_PRICE;
771
772					cur_and_len_price = next_rep_match_price
773							+ get_rep_price(coder, 0, len_test_2,
774								state_2, pos_state_next);
775
776					if (cur_and_len_price < coder->opts[offset].price) {
777						coder->opts[offset].price = cur_and_len_price;
778						coder->opts[offset].pos_prev = cur + len_test + 1;
779						coder->opts[offset].back_prev = 0;
780						coder->opts[offset].prev_1_is_literal = true;
781						coder->opts[offset].prev_2 = true;
782						coder->opts[offset].pos_prev_2 = cur;
783						coder->opts[offset].back_prev_2
784								= cur_back + REPS;
785					}
786					//}
787				}
788
789				if (++i == matches_count)
790					break;
791			}
792		}
793	}
794
795	return len_end;
796}
797
798
799extern void
800lzma_lzma_optimum_normal(lzma_coder *restrict coder, lzma_mf *restrict mf,
801		uint32_t *restrict back_res, uint32_t *restrict len_res,
802		uint32_t position)
803{
804	// If we have symbols pending, return the next pending symbol.
805	if (coder->opts_end_index != coder->opts_current_index) {
806		assert(mf->read_ahead > 0);
807		*len_res = coder->opts[coder->opts_current_index].pos_prev
808				- coder->opts_current_index;
809		*back_res = coder->opts[coder->opts_current_index].back_prev;
810		coder->opts_current_index = coder->opts[
811				coder->opts_current_index].pos_prev;
812		return;
813	}
814
815	// Update the price tables. In LZMA SDK <= 4.60 (and possibly later)
816	// this was done in both initialization function and in the main loop.
817	// In liblzma they were moved into this single place.
818	if (mf->read_ahead == 0) {
819		if (coder->match_price_count >= (1 << 7))
820			fill_dist_prices(coder);
821
822		if (coder->align_price_count >= ALIGN_SIZE)
823			fill_align_prices(coder);
824	}
825
826	// TODO: This needs quite a bit of cleaning still. But splitting
827	// the original function into two pieces makes it at least a little
828	// more readable, since those two parts don't share many variables.
829
830	uint32_t len_end = helper1(coder, mf, back_res, len_res, position);
831	if (len_end == UINT32_MAX)
832		return;
833
834	uint32_t reps[REPS];
835	memcpy(reps, coder->reps, sizeof(reps));
836
837	uint32_t cur;
838	for (cur = 1; cur < len_end; ++cur) {
839		assert(cur < OPTS);
840
841		coder->longest_match_length = mf_find(
842				mf, &coder->matches_count, coder->matches);
843
844		if (coder->longest_match_length >= mf->nice_len)
845			break;
846
847		len_end = helper2(coder, reps, mf_ptr(mf) - 1, len_end,
848				position + cur, cur, mf->nice_len,
849				my_min(mf_avail(mf) + 1, OPTS - 1 - cur));
850	}
851
852	backward(coder, len_res, back_res, cur);
853	return;
854}
855