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 
20 static uint32_t
21 get_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 
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_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 
75 static inline uint32_t
76 get_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 
100 static inline uint32_t
101 get_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 
110 static inline uint32_t
111 get_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 
131 static void
132 fill_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 
188 static void
189 fill_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 
204 static inline void
205 make_literal(lzma_optimal *optimal)
206 {
207 	optimal->back_prev = UINT32_MAX;
208 	optimal->prev_1_is_literal = false;
209 }
210 
211 
212 static inline void
213 make_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 
224 static void
225 backward(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 
272 static inline uint32_t
273 helper1(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 
450 static inline uint32_t
451 helper2(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 
813 extern void
814 lzma_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