LzmaDec.c (31943B)
1 /* LzmaDec.c -- LZMA Decoder 2 2018-07-04 : Igor Pavlov : Public domain */ 3 4 #include "Precomp.h" 5 6 #include <string.h> 7 8 /* #include "CpuArch.h" */ 9 #include "LzmaDec.h" 10 11 #define kNumTopBits 24 12 #define kTopValue ((UInt32)1 << kNumTopBits) 13 14 #define kNumBitModelTotalBits 11 15 #define kBitModelTotal (1 << kNumBitModelTotalBits) 16 #define kNumMoveBits 5 17 18 #define RC_INIT_SIZE 5 19 20 #define NORMALIZE if (range < kTopValue) { range <<= 8; code = (code << 8) | (*buf++); } 21 22 #define IF_BIT_0(p) ttt = *(p); NORMALIZE; bound = (range >> kNumBitModelTotalBits) * (UInt32)ttt; if (code < bound) 23 #define UPDATE_0(p) range = bound; *(p) = (CLzmaProb)(ttt + ((kBitModelTotal - ttt) >> kNumMoveBits)); 24 #define UPDATE_1(p) range -= bound; code -= bound; *(p) = (CLzmaProb)(ttt - (ttt >> kNumMoveBits)); 25 #define GET_BIT2(p, i, A0, A1) IF_BIT_0(p) \ 26 { UPDATE_0(p); i = (i + i); A0; } else \ 27 { UPDATE_1(p); i = (i + i) + 1; A1; } 28 29 #define TREE_GET_BIT(probs, i) { GET_BIT2(probs + i, i, ;, ;); } 30 31 #define REV_BIT(p, i, A0, A1) IF_BIT_0(p + i) \ 32 { UPDATE_0(p + i); A0; } else \ 33 { UPDATE_1(p + i); A1; } 34 #define REV_BIT_VAR( p, i, m) REV_BIT(p, i, i += m; m += m, m += m; i += m; ) 35 #define REV_BIT_CONST(p, i, m) REV_BIT(p, i, i += m; , i += m * 2; ) 36 #define REV_BIT_LAST( p, i, m) REV_BIT(p, i, i -= m , ; ) 37 38 #define TREE_DECODE(probs, limit, i) \ 39 { i = 1; do { TREE_GET_BIT(probs, i); } while (i < limit); i -= limit; } 40 41 /* #define _LZMA_SIZE_OPT */ 42 43 #ifdef _LZMA_SIZE_OPT 44 #define TREE_6_DECODE(probs, i) TREE_DECODE(probs, (1 << 6), i) 45 #else 46 #define TREE_6_DECODE(probs, i) \ 47 { i = 1; \ 48 TREE_GET_BIT(probs, i); \ 49 TREE_GET_BIT(probs, i); \ 50 TREE_GET_BIT(probs, i); \ 51 TREE_GET_BIT(probs, i); \ 52 TREE_GET_BIT(probs, i); \ 53 TREE_GET_BIT(probs, i); \ 54 i -= 0x40; } 55 #endif 56 57 #define NORMAL_LITER_DEC TREE_GET_BIT(prob, symbol) 58 #define MATCHED_LITER_DEC \ 59 matchByte += matchByte; \ 60 bit = offs; \ 61 offs &= matchByte; \ 62 probLit = prob + (offs + bit + symbol); \ 63 GET_BIT2(probLit, symbol, offs ^= bit; , ;) 64 65 66 67 #define NORMALIZE_CHECK if (range < kTopValue) { if (buf >= bufLimit) return DUMMY_ERROR; range <<= 8; code = (code << 8) | (*buf++); } 68 69 #define IF_BIT_0_CHECK(p) ttt = *(p); NORMALIZE_CHECK; bound = (range >> kNumBitModelTotalBits) * (UInt32)ttt; if (code < bound) 70 #define UPDATE_0_CHECK range = bound; 71 #define UPDATE_1_CHECK range -= bound; code -= bound; 72 #define GET_BIT2_CHECK(p, i, A0, A1) IF_BIT_0_CHECK(p) \ 73 { UPDATE_0_CHECK; i = (i + i); A0; } else \ 74 { UPDATE_1_CHECK; i = (i + i) + 1; A1; } 75 #define GET_BIT_CHECK(p, i) GET_BIT2_CHECK(p, i, ; , ;) 76 #define TREE_DECODE_CHECK(probs, limit, i) \ 77 { i = 1; do { GET_BIT_CHECK(probs + i, i) } while (i < limit); i -= limit; } 78 79 80 #define REV_BIT_CHECK(p, i, m) IF_BIT_0_CHECK(p + i) \ 81 { UPDATE_0_CHECK; i += m; m += m; } else \ 82 { UPDATE_1_CHECK; m += m; i += m; } 83 84 85 #define kNumPosBitsMax 4 86 #define kNumPosStatesMax (1 << kNumPosBitsMax) 87 88 #define kLenNumLowBits 3 89 #define kLenNumLowSymbols (1 << kLenNumLowBits) 90 #define kLenNumHighBits 8 91 #define kLenNumHighSymbols (1 << kLenNumHighBits) 92 93 #define LenLow 0 94 #define LenHigh (LenLow + 2 * (kNumPosStatesMax << kLenNumLowBits)) 95 #define kNumLenProbs (LenHigh + kLenNumHighSymbols) 96 97 #define LenChoice LenLow 98 #define LenChoice2 (LenLow + (1 << kLenNumLowBits)) 99 100 #define kNumStates 12 101 #define kNumStates2 16 102 #define kNumLitStates 7 103 104 #define kStartPosModelIndex 4 105 #define kEndPosModelIndex 14 106 #define kNumFullDistances (1 << (kEndPosModelIndex >> 1)) 107 108 #define kNumPosSlotBits 6 109 #define kNumLenToPosStates 4 110 111 #define kNumAlignBits 4 112 #define kAlignTableSize (1 << kNumAlignBits) 113 114 #define kMatchMinLen 2 115 #define kMatchSpecLenStart (kMatchMinLen + kLenNumLowSymbols * 2 + kLenNumHighSymbols) 116 117 /* External ASM code needs same CLzmaProb array layout. So don't change it. */ 118 119 /* (probs_1664) is faster and better for code size at some platforms */ 120 /* 121 #ifdef MY_CPU_X86_OR_AMD64 122 */ 123 #define kStartOffset 1664 124 #define GET_PROBS p->probs_1664 125 /* 126 #define GET_PROBS p->probs + kStartOffset 127 #else 128 #define kStartOffset 0 129 #define GET_PROBS p->probs 130 #endif 131 */ 132 133 #define SpecPos (-kStartOffset) 134 #define IsRep0Long (SpecPos + kNumFullDistances) 135 #define RepLenCoder (IsRep0Long + (kNumStates2 << kNumPosBitsMax)) 136 #define LenCoder (RepLenCoder + kNumLenProbs) 137 #define IsMatch (LenCoder + kNumLenProbs) 138 #define Align (IsMatch + (kNumStates2 << kNumPosBitsMax)) 139 #define IsRep (Align + kAlignTableSize) 140 #define IsRepG0 (IsRep + kNumStates) 141 #define IsRepG1 (IsRepG0 + kNumStates) 142 #define IsRepG2 (IsRepG1 + kNumStates) 143 #define PosSlot (IsRepG2 + kNumStates) 144 #define Literal (PosSlot + (kNumLenToPosStates << kNumPosSlotBits)) 145 #define NUM_BASE_PROBS (Literal + kStartOffset) 146 147 #if Align != 0 && kStartOffset != 0 148 #error Stop_Compiling_Bad_LZMA_kAlign 149 #endif 150 151 #if NUM_BASE_PROBS != 1984 152 #error Stop_Compiling_Bad_LZMA_PROBS 153 #endif 154 155 156 #define LZMA_LIT_SIZE 0x300 157 158 #define LzmaProps_GetNumProbs(p) (NUM_BASE_PROBS + ((UInt32)LZMA_LIT_SIZE << ((p)->lc + (p)->lp))) 159 160 161 #define CALC_POS_STATE(processedPos, pbMask) (((processedPos) & (pbMask)) << 4) 162 #define COMBINED_PS_STATE (posState + state) 163 #define GET_LEN_STATE (posState) 164 165 #define LZMA_DIC_MIN (1 << 12) 166 167 /* 168 p->remainLen : shows status of LZMA decoder: 169 < kMatchSpecLenStart : normal remain 170 = kMatchSpecLenStart : finished 171 = kMatchSpecLenStart + 1 : need init range coder 172 = kMatchSpecLenStart + 2 : need init range coder and state 173 */ 174 175 /* ---------- LZMA_DECODE_REAL ---------- */ 176 /* 177 LzmaDec_DecodeReal_3() can be implemented in external ASM file. 178 3 - is the code compatibility version of that function for check at link time. 179 */ 180 181 #define LZMA_DECODE_REAL LzmaDec_DecodeReal_3 182 183 /* 184 LZMA_DECODE_REAL() 185 In: 186 RangeCoder is normalized 187 if (p->dicPos == limit) 188 { 189 LzmaDec_TryDummy() was called before to exclude LITERAL and MATCH-REP cases. 190 So first symbol can be only MATCH-NON-REP. And if that MATCH-NON-REP symbol 191 is not END_OF_PAYALOAD_MARKER, then function returns error code. 192 } 193 194 Processing: 195 first LZMA symbol will be decoded in any case 196 All checks for limits are at the end of main loop, 197 It will decode new LZMA-symbols while (p->buf < bufLimit && dicPos < limit), 198 RangeCoder is still without last normalization when (p->buf < bufLimit) is being checked. 199 200 Out: 201 RangeCoder is normalized 202 Result: 203 SZ_OK - OK 204 SZ_ERROR_DATA - Error 205 p->remainLen: 206 < kMatchSpecLenStart : normal remain 207 = kMatchSpecLenStart : finished 208 */ 209 210 211 #ifdef _LZMA_DEC_OPT 212 213 int MY_FAST_CALL LZMA_DECODE_REAL(CLzmaDec *p, SizeT limit, const Byte *bufLimit); 214 215 #else 216 217 static 218 int MY_FAST_CALL LZMA_DECODE_REAL(CLzmaDec *p, SizeT limit, const Byte *bufLimit) 219 { 220 CLzmaProb *probs = GET_PROBS; 221 unsigned state = (unsigned)p->state; 222 UInt32 rep0 = p->reps[0], rep1 = p->reps[1], rep2 = p->reps[2], rep3 = p->reps[3]; 223 unsigned pbMask = ((unsigned)1 << (p->prop.pb)) - 1; 224 unsigned lc = p->prop.lc; 225 unsigned lpMask = ((unsigned)0x100 << p->prop.lp) - ((unsigned)0x100 >> lc); 226 227 Byte *dic = p->dic; 228 SizeT dicBufSize = p->dicBufSize; 229 SizeT dicPos = p->dicPos; 230 231 UInt32 processedPos = p->processedPos; 232 UInt32 checkDicSize = p->checkDicSize; 233 unsigned len = 0; 234 235 const Byte *buf = p->buf; 236 UInt32 range = p->range; 237 UInt32 code = p->code; 238 239 do 240 { 241 CLzmaProb *prob; 242 UInt32 bound; 243 unsigned ttt; 244 unsigned posState = CALC_POS_STATE(processedPos, pbMask); 245 246 prob = probs + IsMatch + COMBINED_PS_STATE; 247 IF_BIT_0(prob) 248 { 249 unsigned symbol; 250 UPDATE_0(prob); 251 prob = probs + Literal; 252 if (processedPos != 0 || checkDicSize != 0) 253 prob += (UInt32)3 * ((((processedPos << 8) + dic[(dicPos == 0 ? dicBufSize : dicPos) - 1]) & lpMask) << lc); 254 processedPos++; 255 256 if (state < kNumLitStates) 257 { 258 state -= (state < 4) ? state : 3; 259 symbol = 1; 260 #ifdef _LZMA_SIZE_OPT 261 do { NORMAL_LITER_DEC } while (symbol < 0x100); 262 #else 263 NORMAL_LITER_DEC 264 NORMAL_LITER_DEC 265 NORMAL_LITER_DEC 266 NORMAL_LITER_DEC 267 NORMAL_LITER_DEC 268 NORMAL_LITER_DEC 269 NORMAL_LITER_DEC 270 NORMAL_LITER_DEC 271 #endif 272 } 273 else 274 { 275 unsigned matchByte = dic[dicPos - rep0 + (dicPos < rep0 ? dicBufSize : 0)]; 276 unsigned offs = 0x100; 277 state -= (state < 10) ? 3 : 6; 278 symbol = 1; 279 #ifdef _LZMA_SIZE_OPT 280 do 281 { 282 unsigned bit; 283 CLzmaProb *probLit; 284 MATCHED_LITER_DEC 285 } 286 while (symbol < 0x100); 287 #else 288 { 289 unsigned bit; 290 CLzmaProb *probLit; 291 MATCHED_LITER_DEC 292 MATCHED_LITER_DEC 293 MATCHED_LITER_DEC 294 MATCHED_LITER_DEC 295 MATCHED_LITER_DEC 296 MATCHED_LITER_DEC 297 MATCHED_LITER_DEC 298 MATCHED_LITER_DEC 299 } 300 #endif 301 } 302 303 dic[dicPos++] = (Byte)symbol; 304 continue; 305 } 306 307 { 308 UPDATE_1(prob); 309 prob = probs + IsRep + state; 310 IF_BIT_0(prob) 311 { 312 UPDATE_0(prob); 313 state += kNumStates; 314 prob = probs + LenCoder; 315 } 316 else 317 { 318 UPDATE_1(prob); 319 /* 320 // that case was checked before with kBadRepCode 321 if (checkDicSize == 0 && processedPos == 0) 322 return SZ_ERROR_DATA; 323 */ 324 prob = probs + IsRepG0 + state; 325 IF_BIT_0(prob) 326 { 327 UPDATE_0(prob); 328 prob = probs + IsRep0Long + COMBINED_PS_STATE; 329 IF_BIT_0(prob) 330 { 331 UPDATE_0(prob); 332 dic[dicPos] = dic[dicPos - rep0 + (dicPos < rep0 ? dicBufSize : 0)]; 333 dicPos++; 334 processedPos++; 335 state = state < kNumLitStates ? 9 : 11; 336 continue; 337 } 338 UPDATE_1(prob); 339 } 340 else 341 { 342 UInt32 distance; 343 UPDATE_1(prob); 344 prob = probs + IsRepG1 + state; 345 IF_BIT_0(prob) 346 { 347 UPDATE_0(prob); 348 distance = rep1; 349 } 350 else 351 { 352 UPDATE_1(prob); 353 prob = probs + IsRepG2 + state; 354 IF_BIT_0(prob) 355 { 356 UPDATE_0(prob); 357 distance = rep2; 358 } 359 else 360 { 361 UPDATE_1(prob); 362 distance = rep3; 363 rep3 = rep2; 364 } 365 rep2 = rep1; 366 } 367 rep1 = rep0; 368 rep0 = distance; 369 } 370 state = state < kNumLitStates ? 8 : 11; 371 prob = probs + RepLenCoder; 372 } 373 374 #ifdef _LZMA_SIZE_OPT 375 { 376 unsigned lim, offset; 377 CLzmaProb *probLen = prob + LenChoice; 378 IF_BIT_0(probLen) 379 { 380 UPDATE_0(probLen); 381 probLen = prob + LenLow + GET_LEN_STATE; 382 offset = 0; 383 lim = (1 << kLenNumLowBits); 384 } 385 else 386 { 387 UPDATE_1(probLen); 388 probLen = prob + LenChoice2; 389 IF_BIT_0(probLen) 390 { 391 UPDATE_0(probLen); 392 probLen = prob + LenLow + GET_LEN_STATE + (1 << kLenNumLowBits); 393 offset = kLenNumLowSymbols; 394 lim = (1 << kLenNumLowBits); 395 } 396 else 397 { 398 UPDATE_1(probLen); 399 probLen = prob + LenHigh; 400 offset = kLenNumLowSymbols * 2; 401 lim = (1 << kLenNumHighBits); 402 } 403 } 404 TREE_DECODE(probLen, lim, len); 405 len += offset; 406 } 407 #else 408 { 409 CLzmaProb *probLen = prob + LenChoice; 410 IF_BIT_0(probLen) 411 { 412 UPDATE_0(probLen); 413 probLen = prob + LenLow + GET_LEN_STATE; 414 len = 1; 415 TREE_GET_BIT(probLen, len); 416 TREE_GET_BIT(probLen, len); 417 TREE_GET_BIT(probLen, len); 418 len -= 8; 419 } 420 else 421 { 422 UPDATE_1(probLen); 423 probLen = prob + LenChoice2; 424 IF_BIT_0(probLen) 425 { 426 UPDATE_0(probLen); 427 probLen = prob + LenLow + GET_LEN_STATE + (1 << kLenNumLowBits); 428 len = 1; 429 TREE_GET_BIT(probLen, len); 430 TREE_GET_BIT(probLen, len); 431 TREE_GET_BIT(probLen, len); 432 } 433 else 434 { 435 UPDATE_1(probLen); 436 probLen = prob + LenHigh; 437 TREE_DECODE(probLen, (1 << kLenNumHighBits), len); 438 len += kLenNumLowSymbols * 2; 439 } 440 } 441 } 442 #endif 443 444 if (state >= kNumStates) 445 { 446 UInt32 distance; 447 prob = probs + PosSlot + 448 ((len < kNumLenToPosStates ? len : kNumLenToPosStates - 1) << kNumPosSlotBits); 449 TREE_6_DECODE(prob, distance); 450 if (distance >= kStartPosModelIndex) 451 { 452 unsigned posSlot = (unsigned)distance; 453 unsigned numDirectBits = (unsigned)(((distance >> 1) - 1)); 454 distance = (2 | (distance & 1)); 455 if (posSlot < kEndPosModelIndex) 456 { 457 distance <<= numDirectBits; 458 prob = probs + SpecPos; 459 { 460 UInt32 m = 1; 461 distance++; 462 do 463 { 464 REV_BIT_VAR(prob, distance, m); 465 } 466 while (--numDirectBits); 467 distance -= m; 468 } 469 } 470 else 471 { 472 numDirectBits -= kNumAlignBits; 473 do 474 { 475 NORMALIZE 476 range >>= 1; 477 478 { 479 UInt32 t; 480 code -= range; 481 t = (0 - ((UInt32)code >> 31)); /* (UInt32)((Int32)code >> 31) */ 482 distance = (distance << 1) + (t + 1); 483 code += range & t; 484 } 485 /* 486 distance <<= 1; 487 if (code >= range) 488 { 489 code -= range; 490 distance |= 1; 491 } 492 */ 493 } 494 while (--numDirectBits); 495 prob = probs + Align; 496 distance <<= kNumAlignBits; 497 { 498 unsigned i = 1; 499 REV_BIT_CONST(prob, i, 1); 500 REV_BIT_CONST(prob, i, 2); 501 REV_BIT_CONST(prob, i, 4); 502 REV_BIT_LAST (prob, i, 8); 503 distance |= i; 504 } 505 if (distance == (UInt32)0xFFFFFFFF) 506 { 507 len = kMatchSpecLenStart; 508 state -= kNumStates; 509 break; 510 } 511 } 512 } 513 514 rep3 = rep2; 515 rep2 = rep1; 516 rep1 = rep0; 517 rep0 = distance + 1; 518 state = (state < kNumStates + kNumLitStates) ? kNumLitStates : kNumLitStates + 3; 519 if (distance >= (checkDicSize == 0 ? processedPos: checkDicSize)) 520 { 521 p->dicPos = dicPos; 522 return SZ_ERROR_DATA; 523 } 524 } 525 526 len += kMatchMinLen; 527 528 { 529 SizeT rem; 530 unsigned curLen; 531 SizeT pos; 532 533 if ((rem = limit - dicPos) == 0) 534 { 535 p->dicPos = dicPos; 536 return SZ_ERROR_DATA; 537 } 538 539 curLen = ((rem < len) ? (unsigned)rem : len); 540 pos = dicPos - rep0 + (dicPos < rep0 ? dicBufSize : 0); 541 542 processedPos += (UInt32)curLen; 543 544 len -= curLen; 545 if (curLen <= dicBufSize - pos) 546 { 547 Byte *dest = dic + dicPos; 548 ptrdiff_t src = (ptrdiff_t)pos - (ptrdiff_t)dicPos; 549 const Byte *lim = dest + curLen; 550 dicPos += (SizeT)curLen; 551 do 552 *(dest) = (Byte)*(dest + src); 553 while (++dest != lim); 554 } 555 else 556 { 557 do 558 { 559 dic[dicPos++] = dic[pos]; 560 if (++pos == dicBufSize) 561 pos = 0; 562 } 563 while (--curLen != 0); 564 } 565 } 566 } 567 } 568 while (dicPos < limit && buf < bufLimit); 569 570 NORMALIZE; 571 572 p->buf = buf; 573 p->range = range; 574 p->code = code; 575 p->remainLen = (UInt32)len; 576 p->dicPos = dicPos; 577 p->processedPos = processedPos; 578 p->reps[0] = rep0; 579 p->reps[1] = rep1; 580 p->reps[2] = rep2; 581 p->reps[3] = rep3; 582 p->state = (UInt32)state; 583 584 return SZ_OK; 585 } 586 #endif 587 588 static void MY_FAST_CALL LzmaDec_WriteRem(CLzmaDec *p, SizeT limit) 589 { 590 if (p->remainLen != 0 && p->remainLen < kMatchSpecLenStart) 591 { 592 Byte *dic = p->dic; 593 SizeT dicPos = p->dicPos; 594 SizeT dicBufSize = p->dicBufSize; 595 unsigned len = (unsigned)p->remainLen; 596 SizeT rep0 = p->reps[0]; /* we use SizeT to avoid the BUG of VC14 for AMD64 */ 597 SizeT rem = limit - dicPos; 598 if (rem < len) 599 len = (unsigned)(rem); 600 601 if (p->checkDicSize == 0 && p->prop.dicSize - p->processedPos <= len) 602 p->checkDicSize = p->prop.dicSize; 603 604 p->processedPos += (UInt32)len; 605 p->remainLen -= (UInt32)len; 606 while (len != 0) 607 { 608 len--; 609 dic[dicPos] = dic[dicPos - rep0 + (dicPos < rep0 ? dicBufSize : 0)]; 610 dicPos++; 611 } 612 p->dicPos = dicPos; 613 } 614 } 615 616 617 #define kRange0 0xFFFFFFFF 618 #define kBound0 ((kRange0 >> kNumBitModelTotalBits) << (kNumBitModelTotalBits - 1)) 619 #define kBadRepCode (kBound0 + (((kRange0 - kBound0) >> kNumBitModelTotalBits) << (kNumBitModelTotalBits - 1))) 620 #if kBadRepCode != (0xC0000000 - 0x400) 621 #error Stop_Compiling_Bad_LZMA_Check 622 #endif 623 624 static int MY_FAST_CALL LzmaDec_DecodeReal2(CLzmaDec *p, SizeT limit, const Byte *bufLimit) 625 { 626 do 627 { 628 SizeT limit2 = limit; 629 if (p->checkDicSize == 0) 630 { 631 UInt32 rem = p->prop.dicSize - p->processedPos; 632 if (limit - p->dicPos > rem) 633 limit2 = p->dicPos + rem; 634 635 if (p->processedPos == 0) 636 if (p->code >= kBadRepCode) 637 return SZ_ERROR_DATA; 638 } 639 640 RINOK(LZMA_DECODE_REAL(p, limit2, bufLimit)); 641 642 if (p->checkDicSize == 0 && p->processedPos >= p->prop.dicSize) 643 p->checkDicSize = p->prop.dicSize; 644 645 LzmaDec_WriteRem(p, limit); 646 } 647 while (p->dicPos < limit && p->buf < bufLimit && p->remainLen < kMatchSpecLenStart); 648 649 return 0; 650 } 651 652 typedef enum 653 { 654 DUMMY_ERROR, /* unexpected end of input stream */ 655 DUMMY_LIT, 656 DUMMY_MATCH, 657 DUMMY_REP 658 } ELzmaDummy; 659 660 static ELzmaDummy LzmaDec_TryDummy(const CLzmaDec *p, const Byte *buf, SizeT inSize) 661 { 662 UInt32 range = p->range; 663 UInt32 code = p->code; 664 const Byte *bufLimit = buf + inSize; 665 const CLzmaProb *probs = GET_PROBS; 666 unsigned state = (unsigned)p->state; 667 ELzmaDummy res; 668 669 { 670 const CLzmaProb *prob; 671 UInt32 bound; 672 unsigned ttt; 673 unsigned posState = CALC_POS_STATE(p->processedPos, (1 << p->prop.pb) - 1); 674 675 prob = probs + IsMatch + COMBINED_PS_STATE; 676 IF_BIT_0_CHECK(prob) 677 { 678 UPDATE_0_CHECK 679 680 /* if (bufLimit - buf >= 7) return DUMMY_LIT; */ 681 682 prob = probs + Literal; 683 if (p->checkDicSize != 0 || p->processedPos != 0) 684 prob += ((UInt32)LZMA_LIT_SIZE * 685 ((((p->processedPos) & ((1 << (p->prop.lp)) - 1)) << p->prop.lc) + 686 (p->dic[(p->dicPos == 0 ? p->dicBufSize : p->dicPos) - 1] >> (8 - p->prop.lc)))); 687 688 if (state < kNumLitStates) 689 { 690 unsigned symbol = 1; 691 do { GET_BIT_CHECK(prob + symbol, symbol) } while (symbol < 0x100); 692 } 693 else 694 { 695 unsigned matchByte = p->dic[p->dicPos - p->reps[0] + 696 (p->dicPos < p->reps[0] ? p->dicBufSize : 0)]; 697 unsigned offs = 0x100; 698 unsigned symbol = 1; 699 do 700 { 701 unsigned bit; 702 const CLzmaProb *probLit; 703 matchByte += matchByte; 704 bit = offs; 705 offs &= matchByte; 706 probLit = prob + (offs + bit + symbol); 707 GET_BIT2_CHECK(probLit, symbol, offs ^= bit; , ; ) 708 } 709 while (symbol < 0x100); 710 } 711 res = DUMMY_LIT; 712 } 713 else 714 { 715 unsigned len; 716 UPDATE_1_CHECK; 717 718 prob = probs + IsRep + state; 719 IF_BIT_0_CHECK(prob) 720 { 721 UPDATE_0_CHECK; 722 state = 0; 723 prob = probs + LenCoder; 724 res = DUMMY_MATCH; 725 } 726 else 727 { 728 UPDATE_1_CHECK; 729 res = DUMMY_REP; 730 prob = probs + IsRepG0 + state; 731 IF_BIT_0_CHECK(prob) 732 { 733 UPDATE_0_CHECK; 734 prob = probs + IsRep0Long + COMBINED_PS_STATE; 735 IF_BIT_0_CHECK(prob) 736 { 737 UPDATE_0_CHECK; 738 NORMALIZE_CHECK; 739 return DUMMY_REP; 740 } 741 else 742 { 743 UPDATE_1_CHECK; 744 } 745 } 746 else 747 { 748 UPDATE_1_CHECK; 749 prob = probs + IsRepG1 + state; 750 IF_BIT_0_CHECK(prob) 751 { 752 UPDATE_0_CHECK; 753 } 754 else 755 { 756 UPDATE_1_CHECK; 757 prob = probs + IsRepG2 + state; 758 IF_BIT_0_CHECK(prob) 759 { 760 UPDATE_0_CHECK; 761 } 762 else 763 { 764 UPDATE_1_CHECK; 765 } 766 } 767 } 768 state = kNumStates; 769 prob = probs + RepLenCoder; 770 } 771 { 772 unsigned limit, offset; 773 const CLzmaProb *probLen = prob + LenChoice; 774 IF_BIT_0_CHECK(probLen) 775 { 776 UPDATE_0_CHECK; 777 probLen = prob + LenLow + GET_LEN_STATE; 778 offset = 0; 779 limit = 1 << kLenNumLowBits; 780 } 781 else 782 { 783 UPDATE_1_CHECK; 784 probLen = prob + LenChoice2; 785 IF_BIT_0_CHECK(probLen) 786 { 787 UPDATE_0_CHECK; 788 probLen = prob + LenLow + GET_LEN_STATE + (1 << kLenNumLowBits); 789 offset = kLenNumLowSymbols; 790 limit = 1 << kLenNumLowBits; 791 } 792 else 793 { 794 UPDATE_1_CHECK; 795 probLen = prob + LenHigh; 796 offset = kLenNumLowSymbols * 2; 797 limit = 1 << kLenNumHighBits; 798 } 799 } 800 TREE_DECODE_CHECK(probLen, limit, len); 801 len += offset; 802 } 803 804 if (state < 4) 805 { 806 unsigned posSlot; 807 prob = probs + PosSlot + 808 ((len < kNumLenToPosStates - 1 ? len : kNumLenToPosStates - 1) << 809 kNumPosSlotBits); 810 TREE_DECODE_CHECK(prob, 1 << kNumPosSlotBits, posSlot); 811 if (posSlot >= kStartPosModelIndex) 812 { 813 unsigned numDirectBits = ((posSlot >> 1) - 1); 814 815 /* if (bufLimit - buf >= 8) return DUMMY_MATCH; */ 816 817 if (posSlot < kEndPosModelIndex) 818 { 819 prob = probs + SpecPos + ((2 | (posSlot & 1)) << numDirectBits); 820 } 821 else 822 { 823 numDirectBits -= kNumAlignBits; 824 do 825 { 826 NORMALIZE_CHECK 827 range >>= 1; 828 code -= range & (((code - range) >> 31) - 1); 829 /* if (code >= range) code -= range; */ 830 } 831 while (--numDirectBits); 832 prob = probs + Align; 833 numDirectBits = kNumAlignBits; 834 } 835 { 836 unsigned i = 1; 837 unsigned m = 1; 838 do 839 { 840 REV_BIT_CHECK(prob, i, m); 841 } 842 while (--numDirectBits); 843 } 844 } 845 } 846 } 847 } 848 NORMALIZE_CHECK; 849 return res; 850 } 851 852 853 void LzmaDec_InitDicAndState(CLzmaDec *p, BoolInt initDic, BoolInt initState) 854 { 855 p->remainLen = kMatchSpecLenStart + 1; 856 p->tempBufSize = 0; 857 858 if (initDic) 859 { 860 p->processedPos = 0; 861 p->checkDicSize = 0; 862 p->remainLen = kMatchSpecLenStart + 2; 863 } 864 if (initState) 865 p->remainLen = kMatchSpecLenStart + 2; 866 } 867 868 void LzmaDec_Init(CLzmaDec *p) 869 { 870 p->dicPos = 0; 871 LzmaDec_InitDicAndState(p, True, True); 872 } 873 874 875 SRes LzmaDec_DecodeToDic(CLzmaDec *p, SizeT dicLimit, const Byte *src, SizeT *srcLen, 876 ELzmaFinishMode finishMode, ELzmaStatus *status) 877 { 878 SizeT inSize = *srcLen; 879 (*srcLen) = 0; 880 881 *status = LZMA_STATUS_NOT_SPECIFIED; 882 883 if (p->remainLen > kMatchSpecLenStart) 884 { 885 for (; inSize > 0 && p->tempBufSize < RC_INIT_SIZE; (*srcLen)++, inSize--) 886 p->tempBuf[p->tempBufSize++] = *src++; 887 if (p->tempBufSize != 0 && p->tempBuf[0] != 0) 888 return SZ_ERROR_DATA; 889 if (p->tempBufSize < RC_INIT_SIZE) 890 { 891 *status = LZMA_STATUS_NEEDS_MORE_INPUT; 892 return SZ_OK; 893 } 894 p->code = 895 ((UInt32)p->tempBuf[1] << 24) 896 | ((UInt32)p->tempBuf[2] << 16) 897 | ((UInt32)p->tempBuf[3] << 8) 898 | ((UInt32)p->tempBuf[4]); 899 p->range = 0xFFFFFFFF; 900 p->tempBufSize = 0; 901 902 if (p->remainLen > kMatchSpecLenStart + 1) 903 { 904 SizeT numProbs = LzmaProps_GetNumProbs(&p->prop); 905 SizeT i; 906 CLzmaProb *probs = p->probs; 907 for (i = 0; i < numProbs; i++) 908 probs[i] = kBitModelTotal >> 1; 909 p->reps[0] = p->reps[1] = p->reps[2] = p->reps[3] = 1; 910 p->state = 0; 911 } 912 913 p->remainLen = 0; 914 } 915 916 LzmaDec_WriteRem(p, dicLimit); 917 918 while (p->remainLen != kMatchSpecLenStart) 919 { 920 int checkEndMarkNow = 0; 921 922 if (p->dicPos >= dicLimit) 923 { 924 if (p->remainLen == 0 && p->code == 0) 925 { 926 *status = LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK; 927 return SZ_OK; 928 } 929 if (finishMode == LZMA_FINISH_ANY) 930 { 931 *status = LZMA_STATUS_NOT_FINISHED; 932 return SZ_OK; 933 } 934 if (p->remainLen != 0) 935 { 936 *status = LZMA_STATUS_NOT_FINISHED; 937 return SZ_ERROR_DATA; 938 } 939 checkEndMarkNow = 1; 940 } 941 942 if (p->tempBufSize == 0) 943 { 944 SizeT processed; 945 const Byte *bufLimit; 946 if (inSize < LZMA_REQUIRED_INPUT_MAX || checkEndMarkNow) 947 { 948 int dummyRes = LzmaDec_TryDummy(p, src, inSize); 949 if (dummyRes == DUMMY_ERROR) 950 { 951 memcpy(p->tempBuf, src, inSize); 952 p->tempBufSize = (unsigned)inSize; 953 (*srcLen) += inSize; 954 *status = LZMA_STATUS_NEEDS_MORE_INPUT; 955 return SZ_OK; 956 } 957 if (checkEndMarkNow && dummyRes != DUMMY_MATCH) 958 { 959 *status = LZMA_STATUS_NOT_FINISHED; 960 return SZ_ERROR_DATA; 961 } 962 bufLimit = src; 963 } 964 else 965 bufLimit = src + inSize - LZMA_REQUIRED_INPUT_MAX; 966 p->buf = src; 967 if (LzmaDec_DecodeReal2(p, dicLimit, bufLimit) != 0) 968 return SZ_ERROR_DATA; 969 processed = (SizeT)(p->buf - src); 970 (*srcLen) += processed; 971 src += processed; 972 inSize -= processed; 973 } 974 else 975 { 976 unsigned rem = p->tempBufSize, lookAhead = 0; 977 while (rem < LZMA_REQUIRED_INPUT_MAX && lookAhead < inSize) 978 p->tempBuf[rem++] = src[lookAhead++]; 979 p->tempBufSize = rem; 980 if (rem < LZMA_REQUIRED_INPUT_MAX || checkEndMarkNow) 981 { 982 int dummyRes = LzmaDec_TryDummy(p, p->tempBuf, (SizeT)rem); 983 if (dummyRes == DUMMY_ERROR) 984 { 985 (*srcLen) += (SizeT)lookAhead; 986 *status = LZMA_STATUS_NEEDS_MORE_INPUT; 987 return SZ_OK; 988 } 989 if (checkEndMarkNow && dummyRes != DUMMY_MATCH) 990 { 991 *status = LZMA_STATUS_NOT_FINISHED; 992 return SZ_ERROR_DATA; 993 } 994 } 995 p->buf = p->tempBuf; 996 if (LzmaDec_DecodeReal2(p, dicLimit, p->buf) != 0) 997 return SZ_ERROR_DATA; 998 999 { 1000 unsigned kkk = (unsigned)(p->buf - p->tempBuf); 1001 if (rem < kkk) 1002 return SZ_ERROR_FAIL; /* some internal error */ 1003 rem -= kkk; 1004 if (lookAhead < rem) 1005 return SZ_ERROR_FAIL; /* some internal error */ 1006 lookAhead -= rem; 1007 } 1008 (*srcLen) += (SizeT)lookAhead; 1009 src += lookAhead; 1010 inSize -= (SizeT)lookAhead; 1011 p->tempBufSize = 0; 1012 } 1013 } 1014 1015 if (p->code != 0) 1016 return SZ_ERROR_DATA; 1017 *status = LZMA_STATUS_FINISHED_WITH_MARK; 1018 return SZ_OK; 1019 } 1020 1021 1022 SRes LzmaDec_DecodeToBuf(CLzmaDec *p, Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen, ELzmaFinishMode finishMode, ELzmaStatus *status) 1023 { 1024 SizeT outSize = *destLen; 1025 SizeT inSize = *srcLen; 1026 *srcLen = *destLen = 0; 1027 for (;;) 1028 { 1029 SizeT inSizeCur = inSize, outSizeCur, dicPos; 1030 ELzmaFinishMode curFinishMode; 1031 SRes res; 1032 if (p->dicPos == p->dicBufSize) 1033 p->dicPos = 0; 1034 dicPos = p->dicPos; 1035 if (outSize > p->dicBufSize - dicPos) 1036 { 1037 outSizeCur = p->dicBufSize; 1038 curFinishMode = LZMA_FINISH_ANY; 1039 } 1040 else 1041 { 1042 outSizeCur = dicPos + outSize; 1043 curFinishMode = finishMode; 1044 } 1045 1046 res = LzmaDec_DecodeToDic(p, outSizeCur, src, &inSizeCur, curFinishMode, status); 1047 src += inSizeCur; 1048 inSize -= inSizeCur; 1049 *srcLen += inSizeCur; 1050 outSizeCur = p->dicPos - dicPos; 1051 memcpy(dest, p->dic + dicPos, outSizeCur); 1052 dest += outSizeCur; 1053 outSize -= outSizeCur; 1054 *destLen += outSizeCur; 1055 if (res != 0) 1056 return res; 1057 if (outSizeCur == 0 || outSize == 0) 1058 return SZ_OK; 1059 } 1060 } 1061 1062 void LzmaDec_FreeProbs(CLzmaDec *p, ISzAllocPtr alloc) 1063 { 1064 ISzAlloc_Free(alloc, p->probs); 1065 p->probs = NULL; 1066 } 1067 1068 static void LzmaDec_FreeDict(CLzmaDec *p, ISzAllocPtr alloc) 1069 { 1070 ISzAlloc_Free(alloc, p->dic); 1071 p->dic = NULL; 1072 } 1073 1074 void LzmaDec_Free(CLzmaDec *p, ISzAllocPtr alloc) 1075 { 1076 LzmaDec_FreeProbs(p, alloc); 1077 LzmaDec_FreeDict(p, alloc); 1078 } 1079 1080 SRes LzmaProps_Decode(CLzmaProps *p, const Byte *data, unsigned size) 1081 { 1082 UInt32 dicSize; 1083 Byte d; 1084 1085 if (size < LZMA_PROPS_SIZE) 1086 return SZ_ERROR_UNSUPPORTED; 1087 else 1088 dicSize = data[1] | ((UInt32)data[2] << 8) | ((UInt32)data[3] << 16) | ((UInt32)data[4] << 24); 1089 1090 if (dicSize < LZMA_DIC_MIN) 1091 dicSize = LZMA_DIC_MIN; 1092 p->dicSize = dicSize; 1093 1094 d = data[0]; 1095 if (d >= (9 * 5 * 5)) 1096 return SZ_ERROR_UNSUPPORTED; 1097 1098 p->lc = (Byte)(d % 9); 1099 d /= 9; 1100 p->pb = (Byte)(d / 5); 1101 p->lp = (Byte)(d % 5); 1102 1103 return SZ_OK; 1104 } 1105 1106 static SRes LzmaDec_AllocateProbs2(CLzmaDec *p, const CLzmaProps *propNew, ISzAllocPtr alloc) 1107 { 1108 UInt32 numProbs = LzmaProps_GetNumProbs(propNew); 1109 if (!p->probs || numProbs != p->numProbs) 1110 { 1111 LzmaDec_FreeProbs(p, alloc); 1112 p->probs = (CLzmaProb *)ISzAlloc_Alloc(alloc, numProbs * sizeof(CLzmaProb)); 1113 if (!p->probs) 1114 return SZ_ERROR_MEM; 1115 p->probs_1664 = p->probs + 1664; 1116 p->numProbs = numProbs; 1117 } 1118 return SZ_OK; 1119 } 1120 1121 SRes LzmaDec_AllocateProbs(CLzmaDec *p, const Byte *props, unsigned propsSize, ISzAllocPtr alloc) 1122 { 1123 CLzmaProps propNew; 1124 RINOK(LzmaProps_Decode(&propNew, props, propsSize)); 1125 RINOK(LzmaDec_AllocateProbs2(p, &propNew, alloc)); 1126 p->prop = propNew; 1127 return SZ_OK; 1128 } 1129 1130 SRes LzmaDec_Allocate(CLzmaDec *p, const Byte *props, unsigned propsSize, ISzAllocPtr alloc) 1131 { 1132 CLzmaProps propNew; 1133 SizeT dicBufSize; 1134 RINOK(LzmaProps_Decode(&propNew, props, propsSize)); 1135 RINOK(LzmaDec_AllocateProbs2(p, &propNew, alloc)); 1136 1137 { 1138 UInt32 dictSize = propNew.dicSize; 1139 SizeT mask = ((UInt32)1 << 12) - 1; 1140 if (dictSize >= ((UInt32)1 << 30)) mask = ((UInt32)1 << 22) - 1; 1141 else if (dictSize >= ((UInt32)1 << 22)) mask = ((UInt32)1 << 20) - 1;; 1142 dicBufSize = ((SizeT)dictSize + mask) & ~mask; 1143 if (dicBufSize < dictSize) 1144 dicBufSize = dictSize; 1145 } 1146 1147 if (!p->dic || dicBufSize != p->dicBufSize) 1148 { 1149 LzmaDec_FreeDict(p, alloc); 1150 p->dic = (Byte *)ISzAlloc_Alloc(alloc, dicBufSize); 1151 if (!p->dic) 1152 { 1153 LzmaDec_FreeProbs(p, alloc); 1154 return SZ_ERROR_MEM; 1155 } 1156 } 1157 p->dicBufSize = dicBufSize; 1158 p->prop = propNew; 1159 return SZ_OK; 1160 } 1161 1162 SRes LzmaDecode(Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen, 1163 const Byte *propData, unsigned propSize, ELzmaFinishMode finishMode, 1164 ELzmaStatus *status, ISzAllocPtr alloc) 1165 { 1166 CLzmaDec p; 1167 SRes res; 1168 SizeT outSize = *destLen, inSize = *srcLen; 1169 *destLen = *srcLen = 0; 1170 *status = LZMA_STATUS_NOT_SPECIFIED; 1171 if (inSize < RC_INIT_SIZE) 1172 return SZ_ERROR_INPUT_EOF; 1173 LzmaDec_Construct(&p); 1174 RINOK(LzmaDec_AllocateProbs(&p, propData, propSize, alloc)); 1175 p.dic = dest; 1176 p.dicBufSize = outSize; 1177 LzmaDec_Init(&p); 1178 *srcLen = inSize; 1179 res = LzmaDec_DecodeToDic(&p, outSize, src, srcLen, finishMode, status); 1180 *destLen = p.dicPos; 1181 if (res == SZ_OK && *status == LZMA_STATUS_NEEDS_MORE_INPUT) 1182 res = SZ_ERROR_INPUT_EOF; 1183 LzmaDec_FreeProbs(&p, alloc); 1184 return res; 1185 }