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_lzma1_encoder *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_lzma1_encoder *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_lzma1_encoder *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_lzma1_encoder *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_lzma1_encoder *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_lzma1_encoder *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_lzma1_encoder *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_lzma1_encoder *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_lzma1_encoder *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_lzma1_encoder *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 // NOTE: len_test_2 may be greater than limit so the call to 640 // lzma_memcmplen() must be done conditionally. 641 if (len_test_2 < limit) 642 len_test_2 = lzma_memcmplen(buf, buf_back, len_test_2, limit); 643 644 len_test_2 -= len_test + 1; 645 646 if (len_test_2 >= 2) { 647 lzma_lzma_state state_2 = state; 648 update_long_rep(state_2); 649 650 uint32_t pos_state_next = (position + len_test) & coder->pos_mask; 651 652 const uint32_t cur_and_len_literal_price = price 653 + get_len_price(&coder->rep_len_encoder, 654 len_test, pos_state) 655 + rc_bit_0_price(coder->is_match[state_2][pos_state_next]) 656 + get_literal_price(coder, position + len_test, 657 buf[len_test - 1], true, 658 buf_back[len_test], buf[len_test]); 659 660 update_literal(state_2); 661 662 pos_state_next = (position + len_test + 1) & coder->pos_mask; 663 664 const uint32_t next_rep_match_price = cur_and_len_literal_price 665 + rc_bit_1_price(coder->is_match[state_2][pos_state_next]) 666 + rc_bit_1_price(coder->is_rep[state_2]); 667 668 //for(; len_test_2 >= 2; len_test_2--) { 669 const uint32_t offset = cur + len_test + 1 + len_test_2; 670 671 while (len_end < offset) 672 coder->opts[++len_end].price = RC_INFINITY_PRICE; 673 674 const uint32_t cur_and_len_price = next_rep_match_price 675 + get_rep_price(coder, 0, len_test_2, 676 state_2, pos_state_next); 677 678 if (cur_and_len_price < coder->opts[offset].price) { 679 coder->opts[offset].price = cur_and_len_price; 680 coder->opts[offset].pos_prev = cur + len_test + 1; 681 coder->opts[offset].back_prev = 0; 682 coder->opts[offset].prev_1_is_literal = true; 683 coder->opts[offset].prev_2 = true; 684 coder->opts[offset].pos_prev_2 = cur; 685 coder->opts[offset].back_prev_2 = rep_index; 686 } 687 //} 688 } 689 } 690 691 692 //for (uint32_t len_test = 2; len_test <= new_len; ++len_test) 693 if (new_len > buf_avail) { 694 new_len = buf_avail; 695 696 matches_count = 0; 697 while (new_len > coder->matches[matches_count].len) 698 ++matches_count; 699 700 coder->matches[matches_count++].len = new_len; 701 } 702 703 704 if (new_len >= start_len) { 705 const uint32_t normal_match_price = match_price 706 + rc_bit_0_price(coder->is_rep[state]); 707 708 while (len_end < cur + new_len) 709 coder->opts[++len_end].price = RC_INFINITY_PRICE; 710 711 uint32_t i = 0; 712 while (start_len > coder->matches[i].len) 713 ++i; 714 715 for (uint32_t len_test = start_len; ; ++len_test) { 716 const uint32_t cur_back = coder->matches[i].dist; 717 uint32_t cur_and_len_price = normal_match_price 718 + get_dist_len_price(coder, 719 cur_back, len_test, pos_state); 720 721 if (cur_and_len_price < coder->opts[cur + len_test].price) { 722 coder->opts[cur + len_test].price = cur_and_len_price; 723 coder->opts[cur + len_test].pos_prev = cur; 724 coder->opts[cur + len_test].back_prev 725 = cur_back + REPS; 726 coder->opts[cur + len_test].prev_1_is_literal = false; 727 } 728 729 if (len_test == coder->matches[i].len) { 730 // Try Match + Literal + Rep0 731 const uint8_t *const buf_back = buf - cur_back - 1; 732 uint32_t len_test_2 = len_test + 1; 733 const uint32_t limit = my_min(buf_avail_full, 734 len_test_2 + nice_len); 735 736 // NOTE: len_test_2 may be greater than limit 737 // so the call to lzma_memcmplen() must be 738 // done conditionally. 739 if (len_test_2 < limit) 740 len_test_2 = lzma_memcmplen(buf, buf_back, 741 len_test_2, limit); 742 743 len_test_2 -= len_test + 1; 744 745 if (len_test_2 >= 2) { 746 lzma_lzma_state state_2 = state; 747 update_match(state_2); 748 uint32_t pos_state_next 749 = (position + len_test) & coder->pos_mask; 750 751 const uint32_t cur_and_len_literal_price = cur_and_len_price 752 + rc_bit_0_price( 753 coder->is_match[state_2][pos_state_next]) 754 + get_literal_price(coder, 755 position + len_test, 756 buf[len_test - 1], 757 true, 758 buf_back[len_test], 759 buf[len_test]); 760 761 update_literal(state_2); 762 pos_state_next = (pos_state_next + 1) & coder->pos_mask; 763 764 const uint32_t next_rep_match_price 765 = cur_and_len_literal_price 766 + rc_bit_1_price( 767 coder->is_match[state_2][pos_state_next]) 768 + rc_bit_1_price(coder->is_rep[state_2]); 769 770 // for(; len_test_2 >= 2; --len_test_2) { 771 const uint32_t offset = cur + len_test + 1 + len_test_2; 772 773 while (len_end < offset) 774 coder->opts[++len_end].price = RC_INFINITY_PRICE; 775 776 cur_and_len_price = next_rep_match_price 777 + get_rep_price(coder, 0, len_test_2, 778 state_2, pos_state_next); 779 780 if (cur_and_len_price < coder->opts[offset].price) { 781 coder->opts[offset].price = cur_and_len_price; 782 coder->opts[offset].pos_prev = cur + len_test + 1; 783 coder->opts[offset].back_prev = 0; 784 coder->opts[offset].prev_1_is_literal = true; 785 coder->opts[offset].prev_2 = true; 786 coder->opts[offset].pos_prev_2 = cur; 787 coder->opts[offset].back_prev_2 788 = cur_back + REPS; 789 } 790 //} 791 } 792 793 if (++i == matches_count) 794 break; 795 } 796 } 797 } 798 799 return len_end; 800} 801 802 803extern void 804lzma_lzma_optimum_normal(lzma_lzma1_encoder *restrict coder, 805 lzma_mf *restrict mf, 806 uint32_t *restrict back_res, uint32_t *restrict len_res, 807 uint32_t position) 808{ 809 // If we have symbols pending, return the next pending symbol. 810 if (coder->opts_end_index != coder->opts_current_index) { 811 assert(mf->read_ahead > 0); 812 *len_res = coder->opts[coder->opts_current_index].pos_prev 813 - coder->opts_current_index; 814 *back_res = coder->opts[coder->opts_current_index].back_prev; 815 coder->opts_current_index = coder->opts[ 816 coder->opts_current_index].pos_prev; 817 return; 818 } 819 820 // Update the price tables. In LZMA SDK <= 4.60 (and possibly later) 821 // this was done in both initialization function and in the main loop. 822 // In liblzma they were moved into this single place. 823 if (mf->read_ahead == 0) { 824 if (coder->match_price_count >= (1 << 7)) 825 fill_dist_prices(coder); 826 827 if (coder->align_price_count >= ALIGN_SIZE) 828 fill_align_prices(coder); 829 } 830 831 // TODO: This needs quite a bit of cleaning still. But splitting 832 // the original function into two pieces makes it at least a little 833 // more readable, since those two parts don't share many variables. 834 835 uint32_t len_end = helper1(coder, mf, back_res, len_res, position); 836 if (len_end == UINT32_MAX) 837 return; 838 839 uint32_t reps[REPS]; 840 memcpy(reps, coder->reps, sizeof(reps)); 841 842 uint32_t cur; 843 for (cur = 1; cur < len_end; ++cur) { 844 assert(cur < OPTS); 845 846 coder->longest_match_length = mf_find( 847 mf, &coder->matches_count, coder->matches); 848 849 if (coder->longest_match_length >= mf->nice_len) 850 break; 851 852 len_end = helper2(coder, reps, mf_ptr(mf) - 1, len_end, 853 position + cur, cur, mf->nice_len, 854 my_min(mf_avail(mf) + 1, OPTS - 1 - cur)); 855 } 856 857 backward(coder, len_res, back_res, cur); 858 return; 859} 860