1/* LzmaDec.c -- LZMA Decoder 22009-09-20 : Igor Pavlov : Public domain */ 3 4#include <config.h> 5#include <watchdog.h> 6#include "LzmaDec.h" 7 8#include <linux/string.h> 9 10#define kNumTopBits 24 11#define kTopValue ((UInt32)1 << kNumTopBits) 12 13#define kNumBitModelTotalBits 11 14#define kBitModelTotal (1 << kNumBitModelTotalBits) 15#define kNumMoveBits 5 16 17#define RC_INIT_SIZE 5 18 19#define NORMALIZE if (range < kTopValue) { range <<= 8; code = (code << 8) | (*buf++); } 20 21#define IF_BIT_0(p) ttt = *(p); NORMALIZE; bound = (range >> kNumBitModelTotalBits) * ttt; if (code < bound) 22#define UPDATE_0(p) range = bound; *(p) = (CLzmaProb)(ttt + ((kBitModelTotal - ttt) >> kNumMoveBits)); 23#define UPDATE_1(p) range -= bound; code -= bound; *(p) = (CLzmaProb)(ttt - (ttt >> kNumMoveBits)); 24#define GET_BIT2(p, i, A0, A1) IF_BIT_0(p) \ 25 { UPDATE_0(p); i = (i + i); A0; } else \ 26 { UPDATE_1(p); i = (i + i) + 1; A1; } 27#define GET_BIT(p, i) GET_BIT2(p, i, ; , ;) 28 29#define TREE_GET_BIT(probs, i) { GET_BIT((probs + i), i); } 30#define TREE_DECODE(probs, limit, i) \ 31 { i = 1; do { TREE_GET_BIT(probs, i); } while (i < limit); i -= limit; } 32 33/* #define _LZMA_SIZE_OPT */ 34 35#ifdef _LZMA_SIZE_OPT 36#define TREE_6_DECODE(probs, i) TREE_DECODE(probs, (1 << 6), i) 37#else 38#define TREE_6_DECODE(probs, i) \ 39 { i = 1; \ 40 TREE_GET_BIT(probs, i); \ 41 TREE_GET_BIT(probs, i); \ 42 TREE_GET_BIT(probs, i); \ 43 TREE_GET_BIT(probs, i); \ 44 TREE_GET_BIT(probs, i); \ 45 TREE_GET_BIT(probs, i); \ 46 i -= 0x40; } 47#endif 48 49#define NORMALIZE_CHECK if (range < kTopValue) { if (buf >= bufLimit) return DUMMY_ERROR; range <<= 8; code = (code << 8) | (*buf++); } 50 51#define IF_BIT_0_CHECK(p) ttt = *(p); NORMALIZE_CHECK; bound = (range >> kNumBitModelTotalBits) * ttt; if (code < bound) 52#define UPDATE_0_CHECK range = bound; 53#define UPDATE_1_CHECK range -= bound; code -= bound; 54#define GET_BIT2_CHECK(p, i, A0, A1) IF_BIT_0_CHECK(p) \ 55 { UPDATE_0_CHECK; i = (i + i); A0; } else \ 56 { UPDATE_1_CHECK; i = (i + i) + 1; A1; } 57#define GET_BIT_CHECK(p, i) GET_BIT2_CHECK(p, i, ; , ;) 58#define TREE_DECODE_CHECK(probs, limit, i) \ 59 { i = 1; do { GET_BIT_CHECK(probs + i, i) } while (i < limit); i -= limit; } 60 61 62#define kNumPosBitsMax 4 63#define kNumPosStatesMax (1 << kNumPosBitsMax) 64 65#define kLenNumLowBits 3 66#define kLenNumLowSymbols (1 << kLenNumLowBits) 67#define kLenNumMidBits 3 68#define kLenNumMidSymbols (1 << kLenNumMidBits) 69#define kLenNumHighBits 8 70#define kLenNumHighSymbols (1 << kLenNumHighBits) 71 72#define LenChoice 0 73#define LenChoice2 (LenChoice + 1) 74#define LenLow (LenChoice2 + 1) 75#define LenMid (LenLow + (kNumPosStatesMax << kLenNumLowBits)) 76#define LenHigh (LenMid + (kNumPosStatesMax << kLenNumMidBits)) 77#define kNumLenProbs (LenHigh + kLenNumHighSymbols) 78 79 80#define kNumStates 12 81#define kNumLitStates 7 82 83#define kStartPosModelIndex 4 84#define kEndPosModelIndex 14 85#define kNumFullDistances (1 << (kEndPosModelIndex >> 1)) 86 87#define kNumPosSlotBits 6 88#define kNumLenToPosStates 4 89 90#define kNumAlignBits 4 91#define kAlignTableSize (1 << kNumAlignBits) 92 93#define kMatchMinLen 2 94#define kMatchSpecLenStart (kMatchMinLen + kLenNumLowSymbols + kLenNumMidSymbols + kLenNumHighSymbols) 95 96#define IsMatch 0 97#define IsRep (IsMatch + (kNumStates << kNumPosBitsMax)) 98#define IsRepG0 (IsRep + kNumStates) 99#define IsRepG1 (IsRepG0 + kNumStates) 100#define IsRepG2 (IsRepG1 + kNumStates) 101#define IsRep0Long (IsRepG2 + kNumStates) 102#define PosSlot (IsRep0Long + (kNumStates << kNumPosBitsMax)) 103#define SpecPos (PosSlot + (kNumLenToPosStates << kNumPosSlotBits)) 104#define Align (SpecPos + kNumFullDistances - kEndPosModelIndex) 105#define LenCoder (Align + kAlignTableSize) 106#define RepLenCoder (LenCoder + kNumLenProbs) 107#define Literal (RepLenCoder + kNumLenProbs) 108 109#define LZMA_BASE_SIZE 1846 110#define LZMA_LIT_SIZE 768 111 112#define LzmaProps_GetNumProbs(p) ((UInt32)LZMA_BASE_SIZE + (LZMA_LIT_SIZE << ((p)->lc + (p)->lp))) 113 114#if Literal != LZMA_BASE_SIZE 115StopCompilingDueBUG 116#endif 117 118#define LZMA_DIC_MIN (1 << 12) 119 120/* First LZMA-symbol is always decoded. 121And it decodes new LZMA-symbols while (buf < bufLimit), but "buf" is without last normalization 122Out: 123 Result: 124 SZ_OK - OK 125 SZ_ERROR_DATA - Error 126 p->remainLen: 127 < kMatchSpecLenStart : normal remain 128 = kMatchSpecLenStart : finished 129 = kMatchSpecLenStart + 1 : Flush marker 130 = kMatchSpecLenStart + 2 : State Init Marker 131*/ 132 133static int MY_FAST_CALL LzmaDec_DecodeReal(CLzmaDec *p, SizeT limit, const Byte *bufLimit) 134{ 135 CLzmaProb *probs = p->probs; 136 137 unsigned state = p->state; 138 UInt32 rep0 = p->reps[0], rep1 = p->reps[1], rep2 = p->reps[2], rep3 = p->reps[3]; 139 unsigned pbMask = ((unsigned)1 << (p->prop.pb)) - 1; 140 unsigned lpMask = ((unsigned)1 << (p->prop.lp)) - 1; 141 unsigned lc = p->prop.lc; 142 143 Byte *dic = p->dic; 144 SizeT dicBufSize = p->dicBufSize; 145 SizeT dicPos = p->dicPos; 146 147 UInt32 processedPos = p->processedPos; 148 UInt32 checkDicSize = p->checkDicSize; 149 unsigned len = 0; 150 151 const Byte *buf = p->buf; 152 UInt32 range = p->range; 153 UInt32 code = p->code; 154 unsigned int loop = 0; 155 156 do 157 { 158 CLzmaProb *prob; 159 UInt32 bound; 160 unsigned ttt; 161 unsigned posState = processedPos & pbMask; 162 163 if (!(loop++ & 1023)) 164 schedule(); 165 166 prob = probs + IsMatch + (state << kNumPosBitsMax) + posState; 167 IF_BIT_0(prob) 168 { 169 unsigned symbol; 170 UPDATE_0(prob); 171 prob = probs + Literal; 172 if (checkDicSize != 0 || processedPos != 0) 173 prob += (LZMA_LIT_SIZE * (((processedPos & lpMask) << lc) + 174 (dic[(dicPos == 0 ? dicBufSize : dicPos) - 1] >> (8 - lc)))); 175 176 if (state < kNumLitStates) 177 { 178 state -= (state < 4) ? state : 3; 179 symbol = 1; 180 181 do { GET_BIT(prob + symbol, symbol) } while (symbol < 0x100); 182 } 183 else 184 { 185 unsigned matchByte = p->dic[(dicPos - rep0) + ((dicPos < rep0) ? dicBufSize : 0)]; 186 unsigned offs = 0x100; 187 state -= (state < 10) ? 3 : 6; 188 symbol = 1; 189 190 do 191 { 192 unsigned bit; 193 CLzmaProb *probLit; 194 matchByte <<= 1; 195 bit = (matchByte & offs); 196 probLit = prob + offs + bit + symbol; 197 GET_BIT2(probLit, symbol, offs &= ~bit, offs &= bit) 198 } 199 while (symbol < 0x100); 200 } 201 dic[dicPos++] = (Byte)symbol; 202 processedPos++; 203 continue; 204 } 205 else 206 { 207 UPDATE_1(prob); 208 prob = probs + IsRep + state; 209 IF_BIT_0(prob) 210 { 211 UPDATE_0(prob); 212 state += kNumStates; 213 prob = probs + LenCoder; 214 } 215 else 216 { 217 UPDATE_1(prob); 218 if (checkDicSize == 0 && processedPos == 0) 219 return SZ_ERROR_DATA; 220 prob = probs + IsRepG0 + state; 221 IF_BIT_0(prob) 222 { 223 UPDATE_0(prob); 224 prob = probs + IsRep0Long + (state << kNumPosBitsMax) + posState; 225 IF_BIT_0(prob) 226 { 227 UPDATE_0(prob); 228 dic[dicPos] = dic[(dicPos - rep0) + ((dicPos < rep0) ? dicBufSize : 0)]; 229 dicPos++; 230 processedPos++; 231 state = state < kNumLitStates ? 9 : 11; 232 continue; 233 } 234 UPDATE_1(prob); 235 } 236 else 237 { 238 UInt32 distance; 239 UPDATE_1(prob); 240 prob = probs + IsRepG1 + state; 241 IF_BIT_0(prob) 242 { 243 UPDATE_0(prob); 244 distance = rep1; 245 } 246 else 247 { 248 UPDATE_1(prob); 249 prob = probs + IsRepG2 + state; 250 IF_BIT_0(prob) 251 { 252 UPDATE_0(prob); 253 distance = rep2; 254 } 255 else 256 { 257 UPDATE_1(prob); 258 distance = rep3; 259 rep3 = rep2; 260 } 261 rep2 = rep1; 262 } 263 rep1 = rep0; 264 rep0 = distance; 265 } 266 state = state < kNumLitStates ? 8 : 11; 267 prob = probs + RepLenCoder; 268 } 269 { 270 unsigned limit, offset; 271 CLzmaProb *probLen = prob + LenChoice; 272 IF_BIT_0(probLen) 273 { 274 UPDATE_0(probLen); 275 probLen = prob + LenLow + (posState << kLenNumLowBits); 276 offset = 0; 277 limit = (1 << kLenNumLowBits); 278 } 279 else 280 { 281 UPDATE_1(probLen); 282 probLen = prob + LenChoice2; 283 IF_BIT_0(probLen) 284 { 285 UPDATE_0(probLen); 286 probLen = prob + LenMid + (posState << kLenNumMidBits); 287 offset = kLenNumLowSymbols; 288 limit = (1 << kLenNumMidBits); 289 } 290 else 291 { 292 UPDATE_1(probLen); 293 probLen = prob + LenHigh; 294 offset = kLenNumLowSymbols + kLenNumMidSymbols; 295 limit = (1 << kLenNumHighBits); 296 } 297 } 298 TREE_DECODE(probLen, limit, len); 299 len += offset; 300 } 301 302 if (state >= kNumStates) 303 { 304 UInt32 distance; 305 prob = probs + PosSlot + 306 ((len < kNumLenToPosStates ? len : kNumLenToPosStates - 1) << kNumPosSlotBits); 307 TREE_6_DECODE(prob, distance); 308 if (distance >= kStartPosModelIndex) 309 { 310 unsigned posSlot = (unsigned)distance; 311 int numDirectBits = (int)(((distance >> 1) - 1)); 312 distance = (2 | (distance & 1)); 313 if (posSlot < kEndPosModelIndex) 314 { 315 distance <<= numDirectBits; 316 prob = probs + SpecPos + distance - posSlot - 1; 317 { 318 UInt32 mask = 1; 319 unsigned i = 1; 320 321 do 322 { 323 GET_BIT2(prob + i, i, ; , distance |= mask); 324 mask <<= 1; 325 } 326 while (--numDirectBits != 0); 327 } 328 } 329 else 330 { 331 numDirectBits -= kNumAlignBits; 332 333 do 334 { 335 NORMALIZE 336 range >>= 1; 337 338 { 339 UInt32 t; 340 code -= range; 341 t = (0 - ((UInt32)code >> 31)); /* (UInt32)((Int32)code >> 31) */ 342 distance = (distance << 1) + (t + 1); 343 code += range & t; 344 } 345 /* 346 distance <<= 1; 347 if (code >= range) 348 { 349 code -= range; 350 distance |= 1; 351 } 352 */ 353 } 354 while (--numDirectBits != 0); 355 prob = probs + Align; 356 distance <<= kNumAlignBits; 357 { 358 unsigned i = 1; 359 GET_BIT2(prob + i, i, ; , distance |= 1); 360 GET_BIT2(prob + i, i, ; , distance |= 2); 361 GET_BIT2(prob + i, i, ; , distance |= 4); 362 GET_BIT2(prob + i, i, ; , distance |= 8); 363 } 364 if (distance == (UInt32)0xFFFFFFFF) 365 { 366 len += kMatchSpecLenStart; 367 state -= kNumStates; 368 break; 369 } 370 } 371 } 372 rep3 = rep2; 373 rep2 = rep1; 374 rep1 = rep0; 375 rep0 = distance + 1; 376 if (checkDicSize == 0) 377 { 378 if (distance >= processedPos) 379 return SZ_ERROR_DATA; 380 } 381 else if (distance >= checkDicSize) 382 return SZ_ERROR_DATA; 383 state = (state < kNumStates + kNumLitStates) ? kNumLitStates : kNumLitStates + 3; 384 } 385 386 len += kMatchMinLen; 387 388 if (limit == dicPos) 389 return SZ_ERROR_DATA; 390 { 391 SizeT rem = limit - dicPos; 392 unsigned curLen = ((rem < len) ? (unsigned)rem : len); 393 SizeT pos = (dicPos - rep0) + ((dicPos < rep0) ? dicBufSize : 0); 394 395 processedPos += curLen; 396 397 len -= curLen; 398 if (pos + curLen <= dicBufSize) 399 { 400 Byte *dest = dic + dicPos; 401 ptrdiff_t src = (ptrdiff_t)pos - (ptrdiff_t)dicPos; 402 const Byte *lim = dest + curLen; 403 dicPos += curLen; 404 405 do 406 *(dest) = (Byte)*(dest + src); 407 while (++dest != lim); 408 } 409 else 410 { 411 412 do 413 { 414 dic[dicPos++] = dic[pos]; 415 if (++pos == dicBufSize) 416 pos = 0; 417 } 418 while (--curLen != 0); 419 } 420 } 421 } 422 } 423 while (dicPos < limit && buf < bufLimit); 424 425 schedule(); 426 427 NORMALIZE; 428 p->buf = buf; 429 p->range = range; 430 p->code = code; 431 p->remainLen = len; 432 p->dicPos = dicPos; 433 p->processedPos = processedPos; 434 p->reps[0] = rep0; 435 p->reps[1] = rep1; 436 p->reps[2] = rep2; 437 p->reps[3] = rep3; 438 p->state = state; 439 440 return SZ_OK; 441} 442 443static void MY_FAST_CALL LzmaDec_WriteRem(CLzmaDec *p, SizeT limit) 444{ 445 if (p->remainLen != 0 && p->remainLen < kMatchSpecLenStart) 446 { 447 Byte *dic = p->dic; 448 SizeT dicPos = p->dicPos; 449 SizeT dicBufSize = p->dicBufSize; 450 unsigned len = p->remainLen; 451 UInt32 rep0 = p->reps[0]; 452 if (limit - dicPos < len) 453 len = (unsigned)(limit - dicPos); 454 455 if (p->checkDicSize == 0 && p->prop.dicSize - p->processedPos <= len) 456 p->checkDicSize = p->prop.dicSize; 457 458 p->processedPos += len; 459 p->remainLen -= len; 460 while (len-- != 0) 461 { 462 dic[dicPos] = dic[(dicPos - rep0) + ((dicPos < rep0) ? dicBufSize : 0)]; 463 dicPos++; 464 } 465 p->dicPos = dicPos; 466 } 467} 468 469static int MY_FAST_CALL LzmaDec_DecodeReal2(CLzmaDec *p, SizeT limit, const Byte *bufLimit) 470{ 471 do 472 { 473 SizeT limit2 = limit; 474 if (p->checkDicSize == 0) 475 { 476 UInt32 rem = p->prop.dicSize - p->processedPos; 477 if (limit - p->dicPos > rem) 478 limit2 = p->dicPos + rem; 479 } 480 RINOK(LzmaDec_DecodeReal(p, limit2, bufLimit)); 481 if (p->processedPos >= p->prop.dicSize) 482 p->checkDicSize = p->prop.dicSize; 483 LzmaDec_WriteRem(p, limit); 484 } 485 while (p->dicPos < limit && p->buf < bufLimit && p->remainLen < kMatchSpecLenStart); 486 487 if (p->remainLen > kMatchSpecLenStart) 488 { 489 p->remainLen = kMatchSpecLenStart; 490 } 491 return 0; 492} 493 494typedef enum 495{ 496 DUMMY_ERROR, /* unexpected end of input stream */ 497 DUMMY_LIT, 498 DUMMY_MATCH, 499 DUMMY_REP 500} ELzmaDummy; 501 502static ELzmaDummy LzmaDec_TryDummy(const CLzmaDec *p, const Byte *buf, SizeT inSize) 503{ 504 UInt32 range = p->range; 505 UInt32 code = p->code; 506 const Byte *bufLimit = buf + inSize; 507 CLzmaProb *probs = p->probs; 508 unsigned state = p->state; 509 ELzmaDummy res; 510 511 { 512 CLzmaProb *prob; 513 UInt32 bound; 514 unsigned ttt; 515 unsigned posState = (p->processedPos) & ((1 << p->prop.pb) - 1); 516 517 prob = probs + IsMatch + (state << kNumPosBitsMax) + posState; 518 IF_BIT_0_CHECK(prob) 519 { 520 UPDATE_0_CHECK 521 522 /* if (bufLimit - buf >= 7) return DUMMY_LIT; */ 523 524 prob = probs + Literal; 525 if (p->checkDicSize != 0 || p->processedPos != 0) 526 prob += (LZMA_LIT_SIZE * 527 ((((p->processedPos) & ((1 << (p->prop.lp)) - 1)) << p->prop.lc) + 528 (p->dic[(p->dicPos == 0 ? p->dicBufSize : p->dicPos) - 1] >> (8 - p->prop.lc)))); 529 530 if (state < kNumLitStates) 531 { 532 unsigned symbol = 1; 533 do { GET_BIT_CHECK(prob + symbol, symbol) } while (symbol < 0x100); 534 } 535 else 536 { 537 unsigned matchByte = p->dic[p->dicPos - p->reps[0] + 538 ((p->dicPos < p->reps[0]) ? p->dicBufSize : 0)]; 539 unsigned offs = 0x100; 540 unsigned symbol = 1; 541 do 542 { 543 unsigned bit; 544 CLzmaProb *probLit; 545 matchByte <<= 1; 546 bit = (matchByte & offs); 547 probLit = prob + offs + bit + symbol; 548 GET_BIT2_CHECK(probLit, symbol, offs &= ~bit, offs &= bit) 549 } 550 while (symbol < 0x100); 551 } 552 res = DUMMY_LIT; 553 } 554 else 555 { 556 unsigned len; 557 UPDATE_1_CHECK; 558 559 prob = probs + IsRep + state; 560 IF_BIT_0_CHECK(prob) 561 { 562 UPDATE_0_CHECK; 563 state = 0; 564 prob = probs + LenCoder; 565 res = DUMMY_MATCH; 566 } 567 else 568 { 569 UPDATE_1_CHECK; 570 res = DUMMY_REP; 571 prob = probs + IsRepG0 + state; 572 IF_BIT_0_CHECK(prob) 573 { 574 UPDATE_0_CHECK; 575 prob = probs + IsRep0Long + (state << kNumPosBitsMax) + posState; 576 IF_BIT_0_CHECK(prob) 577 { 578 UPDATE_0_CHECK; 579 NORMALIZE_CHECK; 580 return DUMMY_REP; 581 } 582 else 583 { 584 UPDATE_1_CHECK; 585 } 586 } 587 else 588 { 589 UPDATE_1_CHECK; 590 prob = probs + IsRepG1 + state; 591 IF_BIT_0_CHECK(prob) 592 { 593 UPDATE_0_CHECK; 594 } 595 else 596 { 597 UPDATE_1_CHECK; 598 prob = probs + IsRepG2 + state; 599 IF_BIT_0_CHECK(prob) 600 { 601 UPDATE_0_CHECK; 602 } 603 else 604 { 605 UPDATE_1_CHECK; 606 } 607 } 608 } 609 state = kNumStates; 610 prob = probs + RepLenCoder; 611 } 612 { 613 unsigned limit, offset; 614 CLzmaProb *probLen = prob + LenChoice; 615 IF_BIT_0_CHECK(probLen) 616 { 617 UPDATE_0_CHECK; 618 probLen = prob + LenLow + (posState << kLenNumLowBits); 619 offset = 0; 620 limit = 1 << kLenNumLowBits; 621 } 622 else 623 { 624 UPDATE_1_CHECK; 625 probLen = prob + LenChoice2; 626 IF_BIT_0_CHECK(probLen) 627 { 628 UPDATE_0_CHECK; 629 probLen = prob + LenMid + (posState << kLenNumMidBits); 630 offset = kLenNumLowSymbols; 631 limit = 1 << kLenNumMidBits; 632 } 633 else 634 { 635 UPDATE_1_CHECK; 636 probLen = prob + LenHigh; 637 offset = kLenNumLowSymbols + kLenNumMidSymbols; 638 limit = 1 << kLenNumHighBits; 639 } 640 } 641 TREE_DECODE_CHECK(probLen, limit, len); 642 len += offset; 643 } 644 645 if (state < 4) 646 { 647 unsigned posSlot; 648 prob = probs + PosSlot + 649 ((len < kNumLenToPosStates ? len : kNumLenToPosStates - 1) << 650 kNumPosSlotBits); 651 TREE_DECODE_CHECK(prob, 1 << kNumPosSlotBits, posSlot); 652 if (posSlot >= kStartPosModelIndex) 653 { 654 int numDirectBits = ((posSlot >> 1) - 1); 655 656 /* if (bufLimit - buf >= 8) return DUMMY_MATCH; */ 657 658 if (posSlot < kEndPosModelIndex) 659 { 660 prob = probs + SpecPos + ((2 | (posSlot & 1)) << numDirectBits) - posSlot - 1; 661 } 662 else 663 { 664 numDirectBits -= kNumAlignBits; 665 do 666 { 667 NORMALIZE_CHECK 668 range >>= 1; 669 code -= range & (((code - range) >> 31) - 1); 670 /* if (code >= range) code -= range; */ 671 } 672 while (--numDirectBits != 0); 673 prob = probs + Align; 674 numDirectBits = kNumAlignBits; 675 } 676 { 677 unsigned i = 1; 678 do 679 { 680 GET_BIT_CHECK(prob + i, i); 681 } 682 while (--numDirectBits != 0); 683 } 684 } 685 } 686 } 687 } 688 NORMALIZE_CHECK; 689 return res; 690} 691 692 693static void LzmaDec_InitRc(CLzmaDec *p, const Byte *data) 694{ 695 p->code = ((UInt32)data[1] << 24) | ((UInt32)data[2] << 16) | ((UInt32)data[3] << 8) | ((UInt32)data[4]); 696 p->range = 0xFFFFFFFF; 697 p->needFlush = 0; 698} 699 700void LzmaDec_InitDicAndState(CLzmaDec *p, Bool initDic, Bool initState) 701{ 702 p->needFlush = 1; 703 p->remainLen = 0; 704 p->tempBufSize = 0; 705 706 if (initDic) 707 { 708 p->processedPos = 0; 709 p->checkDicSize = 0; 710 p->needInitState = 1; 711 } 712 if (initState) 713 p->needInitState = 1; 714} 715 716void LzmaDec_Init(CLzmaDec *p) 717{ 718 p->dicPos = 0; 719 LzmaDec_InitDicAndState(p, True, True); 720} 721 722static void LzmaDec_InitStateReal(CLzmaDec *p) 723{ 724 UInt32 numProbs = Literal + ((UInt32)LZMA_LIT_SIZE << (p->prop.lc + p->prop.lp)); 725 UInt32 i; 726 CLzmaProb *probs = p->probs; 727 for (i = 0; i < numProbs; i++) 728 probs[i] = kBitModelTotal >> 1; 729 p->reps[0] = p->reps[1] = p->reps[2] = p->reps[3] = 1; 730 p->state = 0; 731 p->needInitState = 0; 732} 733 734SRes LzmaDec_DecodeToDic(CLzmaDec *p, SizeT dicLimit, const Byte *src, SizeT *srcLen, 735 ELzmaFinishMode finishMode, ELzmaStatus *status) 736{ 737 SizeT inSize = *srcLen; 738 (*srcLen) = 0; 739 LzmaDec_WriteRem(p, dicLimit); 740 741 *status = LZMA_STATUS_NOT_SPECIFIED; 742 743 while (p->remainLen != kMatchSpecLenStart) 744 { 745 int checkEndMarkNow; 746 747 if (p->needFlush != 0) 748 { 749 for (; inSize > 0 && p->tempBufSize < RC_INIT_SIZE; (*srcLen)++, inSize--) 750 p->tempBuf[p->tempBufSize++] = *src++; 751 if (p->tempBufSize < RC_INIT_SIZE) 752 { 753 *status = LZMA_STATUS_NEEDS_MORE_INPUT; 754 return SZ_OK; 755 } 756 if (p->tempBuf[0] != 0) 757 return SZ_ERROR_DATA; 758 759 LzmaDec_InitRc(p, p->tempBuf); 760 p->tempBufSize = 0; 761 } 762 763 checkEndMarkNow = 0; 764 if (p->dicPos >= dicLimit) 765 { 766 if (p->remainLen == 0 && p->code == 0) 767 { 768 *status = LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK; 769 return SZ_OK; 770 } 771 if (finishMode == LZMA_FINISH_ANY) 772 { 773 *status = LZMA_STATUS_NOT_FINISHED; 774 return SZ_OK; 775 } 776 if (p->remainLen != 0) 777 { 778 *status = LZMA_STATUS_NOT_FINISHED; 779 return SZ_ERROR_DATA; 780 } 781 checkEndMarkNow = 1; 782 } 783 784 if (p->needInitState) 785 LzmaDec_InitStateReal(p); 786 787 if (p->tempBufSize == 0) 788 { 789 SizeT processed; 790 const Byte *bufLimit; 791 if (inSize < LZMA_REQUIRED_INPUT_MAX || checkEndMarkNow) 792 { 793 int dummyRes = LzmaDec_TryDummy(p, src, inSize); 794 if (dummyRes == DUMMY_ERROR) 795 { 796 memcpy(p->tempBuf, src, inSize); 797 p->tempBufSize = (unsigned)inSize; 798 (*srcLen) += inSize; 799 *status = LZMA_STATUS_NEEDS_MORE_INPUT; 800 return SZ_OK; 801 } 802 if (checkEndMarkNow && dummyRes != DUMMY_MATCH) 803 { 804 *status = LZMA_STATUS_NOT_FINISHED; 805 return SZ_ERROR_DATA; 806 } 807 bufLimit = src; 808 } 809 else 810 bufLimit = src + inSize - LZMA_REQUIRED_INPUT_MAX; 811 p->buf = src; 812 if (LzmaDec_DecodeReal2(p, dicLimit, bufLimit) != 0) 813 return SZ_ERROR_DATA; 814 processed = (SizeT)(p->buf - src); 815 (*srcLen) += processed; 816 src += processed; 817 inSize -= processed; 818 } 819 else 820 { 821 unsigned rem = p->tempBufSize, lookAhead = 0; 822 while (rem < LZMA_REQUIRED_INPUT_MAX && lookAhead < inSize) 823 p->tempBuf[rem++] = src[lookAhead++]; 824 p->tempBufSize = rem; 825 if (rem < LZMA_REQUIRED_INPUT_MAX || checkEndMarkNow) 826 { 827 int dummyRes = LzmaDec_TryDummy(p, p->tempBuf, rem); 828 if (dummyRes == DUMMY_ERROR) 829 { 830 (*srcLen) += lookAhead; 831 *status = LZMA_STATUS_NEEDS_MORE_INPUT; 832 return SZ_OK; 833 } 834 if (checkEndMarkNow && dummyRes != DUMMY_MATCH) 835 { 836 *status = LZMA_STATUS_NOT_FINISHED; 837 return SZ_ERROR_DATA; 838 } 839 } 840 p->buf = p->tempBuf; 841 if (LzmaDec_DecodeReal2(p, dicLimit, p->buf) != 0) 842 return SZ_ERROR_DATA; 843 lookAhead -= (rem - (unsigned)(p->buf - p->tempBuf)); 844 (*srcLen) += lookAhead; 845 src += lookAhead; 846 inSize -= lookAhead; 847 p->tempBufSize = 0; 848 } 849 } 850 if (p->code == 0) 851 *status = LZMA_STATUS_FINISHED_WITH_MARK; 852 return (p->code == 0) ? SZ_OK : SZ_ERROR_DATA; 853} 854 855SRes LzmaDec_DecodeToBuf(CLzmaDec *p, Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen, ELzmaFinishMode finishMode, ELzmaStatus *status) 856{ 857 SizeT outSize = *destLen; 858 SizeT inSize = *srcLen; 859 *srcLen = *destLen = 0; 860 for (;;) 861 { 862 SizeT inSizeCur = inSize, outSizeCur, dicPos; 863 ELzmaFinishMode curFinishMode; 864 SRes res; 865 if (p->dicPos == p->dicBufSize) 866 p->dicPos = 0; 867 dicPos = p->dicPos; 868 if (outSize > p->dicBufSize - dicPos) 869 { 870 outSizeCur = p->dicBufSize; 871 curFinishMode = LZMA_FINISH_ANY; 872 } 873 else 874 { 875 outSizeCur = dicPos + outSize; 876 curFinishMode = finishMode; 877 } 878 879 res = LzmaDec_DecodeToDic(p, outSizeCur, src, &inSizeCur, curFinishMode, status); 880 src += inSizeCur; 881 inSize -= inSizeCur; 882 *srcLen += inSizeCur; 883 outSizeCur = p->dicPos - dicPos; 884 memcpy(dest, p->dic + dicPos, outSizeCur); 885 dest += outSizeCur; 886 outSize -= outSizeCur; 887 *destLen += outSizeCur; 888 if (res != 0) 889 return res; 890 if (outSizeCur == 0 || outSize == 0) 891 return SZ_OK; 892 } 893} 894 895void LzmaDec_FreeProbs(CLzmaDec *p, ISzAlloc *alloc) 896{ 897 alloc->Free(alloc, p->probs); 898 p->probs = 0; 899} 900 901static void LzmaDec_FreeDict(CLzmaDec *p, ISzAlloc *alloc) 902{ 903 alloc->Free(alloc, p->dic); 904 p->dic = 0; 905} 906 907void LzmaDec_Free(CLzmaDec *p, ISzAlloc *alloc) 908{ 909 LzmaDec_FreeProbs(p, alloc); 910 LzmaDec_FreeDict(p, alloc); 911} 912 913SRes LzmaProps_Decode(CLzmaProps *p, const Byte *data, unsigned size) 914{ 915 UInt32 dicSize; 916 Byte d; 917 918 if (size < LZMA_PROPS_SIZE) 919 return SZ_ERROR_UNSUPPORTED; 920 else 921 dicSize = data[1] | ((UInt32)data[2] << 8) | ((UInt32)data[3] << 16) | ((UInt32)data[4] << 24); 922 923 if (dicSize < LZMA_DIC_MIN) 924 dicSize = LZMA_DIC_MIN; 925 p->dicSize = dicSize; 926 927 d = data[0]; 928 if (d >= (9 * 5 * 5)) 929 return SZ_ERROR_UNSUPPORTED; 930 931 p->lc = d % 9; 932 d /= 9; 933 p->pb = d / 5; 934 p->lp = d % 5; 935 936 return SZ_OK; 937} 938 939static SRes LzmaDec_AllocateProbs2(CLzmaDec *p, const CLzmaProps *propNew, ISzAlloc *alloc) 940{ 941 UInt32 numProbs = LzmaProps_GetNumProbs(propNew); 942 if (p->probs == 0 || numProbs != p->numProbs) 943 { 944 LzmaDec_FreeProbs(p, alloc); 945 p->probs = (CLzmaProb *)alloc->Alloc(alloc, numProbs * sizeof(CLzmaProb)); 946 p->numProbs = numProbs; 947 if (p->probs == 0) 948 return SZ_ERROR_MEM; 949 } 950 return SZ_OK; 951} 952 953SRes LzmaDec_AllocateProbs(CLzmaDec *p, const Byte *props, unsigned propsSize, ISzAlloc *alloc) 954{ 955 CLzmaProps propNew; 956 RINOK(LzmaProps_Decode(&propNew, props, propsSize)); 957 RINOK(LzmaDec_AllocateProbs2(p, &propNew, alloc)); 958 p->prop = propNew; 959 return SZ_OK; 960} 961 962SRes LzmaDec_Allocate(CLzmaDec *p, const Byte *props, unsigned propsSize, ISzAlloc *alloc) 963{ 964 CLzmaProps propNew; 965 SizeT dicBufSize; 966 RINOK(LzmaProps_Decode(&propNew, props, propsSize)); 967 RINOK(LzmaDec_AllocateProbs2(p, &propNew, alloc)); 968 dicBufSize = propNew.dicSize; 969 if (p->dic == 0 || dicBufSize != p->dicBufSize) 970 { 971 LzmaDec_FreeDict(p, alloc); 972 p->dic = (Byte *)alloc->Alloc(alloc, dicBufSize); 973 if (p->dic == 0) 974 { 975 LzmaDec_FreeProbs(p, alloc); 976 return SZ_ERROR_MEM; 977 } 978 } 979 p->dicBufSize = dicBufSize; 980 p->prop = propNew; 981 return SZ_OK; 982} 983 984SRes LzmaDecode(Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen, 985 const Byte *propData, unsigned propSize, ELzmaFinishMode finishMode, 986 ELzmaStatus *status, ISzAlloc *alloc) 987{ 988 CLzmaDec p; 989 SRes res; 990 SizeT inSize = *srcLen; 991 SizeT outSize = *destLen; 992 *srcLen = *destLen = 0; 993 if (inSize < RC_INIT_SIZE) 994 return SZ_ERROR_INPUT_EOF; 995 996 LzmaDec_Construct(&p); 997 res = LzmaDec_AllocateProbs(&p, propData, propSize, alloc); 998 if (res != 0) 999 return res; 1000 p.dic = dest; 1001 p.dicBufSize = outSize; 1002 1003 LzmaDec_Init(&p); 1004 1005 *srcLen = inSize; 1006 res = LzmaDec_DecodeToDic(&p, outSize, src, srcLen, finishMode, status); 1007 1008 if (res == SZ_OK && *status == LZMA_STATUS_NEEDS_MORE_INPUT) 1009 res = SZ_ERROR_INPUT_EOF; 1010 1011 (*destLen) = p.dicPos; 1012 LzmaDec_FreeProbs(&p, alloc); 1013 return res; 1014} 1015