Lzma2DecMt.c (24366B)
1 /* Lzma2DecMt.c -- LZMA2 Decoder Multi-thread 2 2018-03-02 : Igor Pavlov : Public domain */ 3 4 #include "Precomp.h" 5 6 // #define SHOW_DEBUG_INFO 7 8 #ifdef SHOW_DEBUG_INFO 9 #include <stdio.h> 10 #endif 11 12 #ifdef SHOW_DEBUG_INFO 13 #define PRF(x) x 14 #else 15 #define PRF(x) 16 #endif 17 18 #define PRF_STR(s) PRF(printf("\n" s "\n")) 19 #define PRF_STR_INT(s, d) PRF(printf("\n" s " %d\n", (unsigned)d)) 20 #define PRF_STR_INT_2(s, d1, d2) PRF(printf("\n" s " %d %d\n", (unsigned)d1, (unsigned)d2)) 21 22 // #define _7ZIP_ST 23 24 #include "Alloc.h" 25 26 #include "Lzma2Dec.h" 27 #include "Lzma2DecMt.h" 28 29 #ifndef _7ZIP_ST 30 #include "MtDec.h" 31 #endif 32 33 34 #define LZMA2DECMT_OUT_BLOCK_MAX_DEFAULT (1 << 28) 35 36 void Lzma2DecMtProps_Init(CLzma2DecMtProps *p) 37 { 38 p->inBufSize_ST = 1 << 20; 39 p->outStep_ST = 1 << 20; 40 41 #ifndef _7ZIP_ST 42 p->numThreads = 1; 43 p->inBufSize_MT = 1 << 18; 44 p->outBlockMax = LZMA2DECMT_OUT_BLOCK_MAX_DEFAULT; 45 p->inBlockMax = p->outBlockMax + p->outBlockMax / 16; 46 #endif 47 } 48 49 50 51 #ifndef _7ZIP_ST 52 53 /* ---------- CLzma2DecMtThread ---------- */ 54 55 typedef struct 56 { 57 CLzma2Dec dec; 58 Byte dec_created; 59 Byte needInit; 60 61 Byte *outBuf; 62 size_t outBufSize; 63 64 EMtDecParseState state; 65 ELzma2ParseStatus parseStatus; 66 67 size_t inPreSize; 68 size_t outPreSize; 69 70 size_t inCodeSize; 71 size_t outCodeSize; 72 SRes codeRes; 73 74 CAlignOffsetAlloc alloc; 75 76 Byte mtPad[1 << 7]; 77 } CLzma2DecMtThread; 78 79 #endif 80 81 82 /* ---------- CLzma2DecMt ---------- */ 83 84 typedef struct 85 { 86 // ISzAllocPtr alloc; 87 ISzAllocPtr allocMid; 88 89 CAlignOffsetAlloc alignOffsetAlloc; 90 CLzma2DecMtProps props; 91 Byte prop; 92 93 ISeqInStream *inStream; 94 ISeqOutStream *outStream; 95 ICompressProgress *progress; 96 97 Bool finishMode; 98 Bool outSize_Defined; 99 UInt64 outSize; 100 101 UInt64 outProcessed; 102 UInt64 inProcessed; 103 Bool readWasFinished; 104 SRes readRes; 105 106 Byte *inBuf; 107 size_t inBufSize; 108 Byte dec_created; 109 CLzma2Dec dec; 110 111 size_t inPos; 112 size_t inLim; 113 114 #ifndef _7ZIP_ST 115 UInt64 outProcessed_Parse; 116 Bool mtc_WasConstructed; 117 CMtDec mtc; 118 CLzma2DecMtThread coders[MTDEC__THREADS_MAX]; 119 #endif 120 121 } CLzma2DecMt; 122 123 124 125 CLzma2DecMtHandle Lzma2DecMt_Create(ISzAllocPtr alloc, ISzAllocPtr allocMid) 126 { 127 CLzma2DecMt *p = (CLzma2DecMt *)ISzAlloc_Alloc(alloc, sizeof(CLzma2DecMt)); 128 if (!p) 129 return NULL; 130 131 // p->alloc = alloc; 132 p->allocMid = allocMid; 133 134 AlignOffsetAlloc_CreateVTable(&p->alignOffsetAlloc); 135 p->alignOffsetAlloc.numAlignBits = 7; 136 p->alignOffsetAlloc.offset = 0; 137 p->alignOffsetAlloc.baseAlloc = alloc; 138 139 p->inBuf = NULL; 140 p->inBufSize = 0; 141 p->dec_created = False; 142 143 // Lzma2DecMtProps_Init(&p->props); 144 145 #ifndef _7ZIP_ST 146 p->mtc_WasConstructed = False; 147 { 148 unsigned i; 149 for (i = 0; i < MTDEC__THREADS_MAX; i++) 150 { 151 CLzma2DecMtThread *t = &p->coders[i]; 152 t->dec_created = False; 153 t->outBuf = NULL; 154 t->outBufSize = 0; 155 } 156 } 157 #endif 158 159 return p; 160 } 161 162 163 #ifndef _7ZIP_ST 164 165 static void Lzma2DecMt_FreeOutBufs(CLzma2DecMt *p) 166 { 167 unsigned i; 168 for (i = 0; i < MTDEC__THREADS_MAX; i++) 169 { 170 CLzma2DecMtThread *t = &p->coders[i]; 171 if (t->outBuf) 172 { 173 ISzAlloc_Free(p->allocMid, t->outBuf); 174 t->outBuf = NULL; 175 t->outBufSize = 0; 176 } 177 } 178 } 179 180 #endif 181 182 183 static void Lzma2DecMt_FreeSt(CLzma2DecMt *p) 184 { 185 if (p->dec_created) 186 { 187 Lzma2Dec_Free(&p->dec, &p->alignOffsetAlloc.vt); 188 p->dec_created = False; 189 } 190 if (p->inBuf) 191 { 192 ISzAlloc_Free(p->allocMid, p->inBuf); 193 p->inBuf = NULL; 194 } 195 p->inBufSize = 0; 196 } 197 198 199 void Lzma2DecMt_Destroy(CLzma2DecMtHandle pp) 200 { 201 CLzma2DecMt *p = (CLzma2DecMt *)pp; 202 203 Lzma2DecMt_FreeSt(p); 204 205 #ifndef _7ZIP_ST 206 207 if (p->mtc_WasConstructed) 208 { 209 MtDec_Destruct(&p->mtc); 210 p->mtc_WasConstructed = False; 211 } 212 { 213 unsigned i; 214 for (i = 0; i < MTDEC__THREADS_MAX; i++) 215 { 216 CLzma2DecMtThread *t = &p->coders[i]; 217 if (t->dec_created) 218 { 219 // we don't need to free dict here 220 Lzma2Dec_FreeProbs(&t->dec, &t->alloc.vt); // p->alloc !!! 221 t->dec_created = False; 222 } 223 } 224 } 225 Lzma2DecMt_FreeOutBufs(p); 226 227 #endif 228 229 ISzAlloc_Free(p->alignOffsetAlloc.baseAlloc, pp); 230 } 231 232 233 234 #ifndef _7ZIP_ST 235 236 static void Lzma2DecMt_MtCallback_Parse(void *obj, unsigned coderIndex, CMtDecCallbackInfo *cc) 237 { 238 CLzma2DecMt *me = (CLzma2DecMt *)obj; 239 CLzma2DecMtThread *t = &me->coders[coderIndex]; 240 241 PRF_STR_INT_2("Parse", coderIndex, cc->srcSize); 242 243 cc->state = MTDEC_PARSE_CONTINUE; 244 245 if (cc->startCall) 246 { 247 if (!t->dec_created) 248 { 249 Lzma2Dec_Construct(&t->dec); 250 t->dec_created = True; 251 AlignOffsetAlloc_CreateVTable(&t->alloc); 252 { 253 /* (1 << 12) is expected size of one way in data cache. 254 We optimize alignment for cache line size of 128 bytes and smaller */ 255 const unsigned kNumAlignBits = 12; 256 const unsigned kNumCacheLineBits = 7; /* <= kNumAlignBits */ 257 t->alloc.numAlignBits = kNumAlignBits; 258 t->alloc.offset = ((UInt32)coderIndex * ((1 << 11) + (1 << 8) + (1 << 6))) & ((1 << kNumAlignBits) - (1 << kNumCacheLineBits)); 259 t->alloc.baseAlloc = me->alignOffsetAlloc.baseAlloc; 260 } 261 } 262 Lzma2Dec_Init(&t->dec); 263 264 t->inPreSize = 0; 265 t->outPreSize = 0; 266 // t->blockWasFinished = False; 267 // t->finishedWithMark = False; 268 t->parseStatus = LZMA_STATUS_NOT_SPECIFIED; 269 t->state = MTDEC_PARSE_CONTINUE; 270 271 t->inCodeSize = 0; 272 t->outCodeSize = 0; 273 t->codeRes = SZ_OK; 274 275 // (cc->srcSize == 0) is allowed 276 } 277 278 { 279 ELzma2ParseStatus status; 280 Bool overflow; 281 UInt32 unpackRem = 0; 282 283 int checkFinishBlock = True; 284 size_t limit = me->props.outBlockMax; 285 if (me->outSize_Defined) 286 { 287 UInt64 rem = me->outSize - me->outProcessed_Parse; 288 if (limit >= rem) 289 { 290 limit = (size_t)rem; 291 if (!me->finishMode) 292 checkFinishBlock = False; 293 } 294 } 295 296 // checkFinishBlock = False, if we want to decode partial data 297 // that must be finished at position <= outBlockMax. 298 299 { 300 const SizeT srcOrig = cc->srcSize; 301 SizeT srcSize_Point = 0; 302 SizeT dicPos_Point = 0; 303 304 cc->srcSize = 0; 305 overflow = False; 306 307 for (;;) 308 { 309 SizeT srcCur = srcOrig - cc->srcSize; 310 311 status = Lzma2Dec_Parse(&t->dec, 312 limit - t->dec.decoder.dicPos, 313 cc->src + cc->srcSize, &srcCur, 314 checkFinishBlock); 315 316 cc->srcSize += srcCur; 317 318 if (status == LZMA2_PARSE_STATUS_NEW_CHUNK) 319 { 320 if (t->dec.unpackSize > me->props.outBlockMax - t->dec.decoder.dicPos) 321 { 322 overflow = True; 323 break; 324 } 325 continue; 326 } 327 328 if (status == LZMA2_PARSE_STATUS_NEW_BLOCK) 329 { 330 if (t->dec.decoder.dicPos == 0) 331 continue; 332 // we decode small blocks in one thread 333 if (t->dec.decoder.dicPos >= (1 << 14)) 334 break; 335 dicPos_Point = t->dec.decoder.dicPos; 336 srcSize_Point = cc->srcSize; 337 continue; 338 } 339 340 if ((int)status == LZMA_STATUS_NOT_FINISHED && checkFinishBlock 341 // && limit == t->dec.decoder.dicPos 342 // && limit == me->props.outBlockMax 343 ) 344 { 345 overflow = True; 346 break; 347 } 348 349 unpackRem = Lzma2Dec_GetUnpackExtra(&t->dec); 350 break; 351 } 352 353 if (dicPos_Point != 0 354 && (int)status != LZMA2_PARSE_STATUS_NEW_BLOCK 355 && (int)status != LZMA_STATUS_FINISHED_WITH_MARK 356 && (int)status != LZMA_STATUS_NOT_SPECIFIED) 357 { 358 // we revert to latest newBlock state 359 status = LZMA2_PARSE_STATUS_NEW_BLOCK; 360 unpackRem = 0; 361 t->dec.decoder.dicPos = dicPos_Point; 362 cc->srcSize = srcSize_Point; 363 overflow = False; 364 } 365 } 366 367 t->inPreSize += cc->srcSize; 368 t->parseStatus = status; 369 370 if (overflow) 371 cc->state = MTDEC_PARSE_OVERFLOW; 372 else 373 { 374 size_t dicPos = t->dec.decoder.dicPos; 375 376 if ((int)status != LZMA_STATUS_NEEDS_MORE_INPUT) 377 { 378 if (status == LZMA2_PARSE_STATUS_NEW_BLOCK) 379 { 380 cc->state = MTDEC_PARSE_NEW; 381 cc->srcSize--; // we don't need control byte of next block 382 t->inPreSize--; 383 } 384 else 385 { 386 cc->state = MTDEC_PARSE_END; 387 if ((int)status != LZMA_STATUS_FINISHED_WITH_MARK) 388 { 389 // (status == LZMA_STATUS_NOT_SPECIFIED) 390 // (status == LZMA_STATUS_NOT_FINISHED) 391 if (unpackRem != 0) 392 { 393 /* we also reserve space for max possible number of output bytes of current LZMA chunk */ 394 SizeT rem = limit - dicPos; 395 if (rem > unpackRem) 396 rem = unpackRem; 397 dicPos += rem; 398 } 399 } 400 } 401 402 me->outProcessed_Parse += dicPos; 403 } 404 405 cc->outPos = dicPos; 406 t->outPreSize = (size_t)dicPos; 407 } 408 409 t->state = cc->state; 410 return; 411 } 412 } 413 414 415 static SRes Lzma2DecMt_MtCallback_PreCode(void *pp, unsigned coderIndex) 416 { 417 CLzma2DecMt *me = (CLzma2DecMt *)pp; 418 CLzma2DecMtThread *t = &me->coders[coderIndex]; 419 Byte *dest = t->outBuf; 420 421 if (t->inPreSize == 0) 422 { 423 t->codeRes = SZ_ERROR_DATA; 424 return t->codeRes; 425 } 426 427 if (!dest || t->outBufSize < t->outPreSize) 428 { 429 if (dest) 430 { 431 ISzAlloc_Free(me->allocMid, dest); 432 t->outBuf = NULL; 433 t->outBufSize = 0; 434 } 435 436 dest = (Byte *)ISzAlloc_Alloc(me->allocMid, t->outPreSize 437 // + (1 << 28) 438 ); 439 // Sleep(200); 440 if (!dest) 441 return SZ_ERROR_MEM; 442 t->outBuf = dest; 443 t->outBufSize = t->outPreSize; 444 } 445 446 t->dec.decoder.dic = dest; 447 t->dec.decoder.dicBufSize = t->outPreSize; 448 449 t->needInit = True; 450 451 return Lzma2Dec_AllocateProbs(&t->dec, me->prop, &t->alloc.vt); // alloc.vt 452 } 453 454 455 static SRes Lzma2DecMt_MtCallback_Code(void *pp, unsigned coderIndex, 456 const Byte *src, size_t srcSize, int srcFinished, 457 // int finished, int blockFinished, 458 UInt64 *inCodePos, UInt64 *outCodePos, int *stop) 459 { 460 CLzma2DecMt *me = (CLzma2DecMt *)pp; 461 CLzma2DecMtThread *t = &me->coders[coderIndex]; 462 463 UNUSED_VAR(srcFinished) 464 465 PRF_STR_INT_2("Code", coderIndex, srcSize); 466 467 *inCodePos = t->inCodeSize; 468 *outCodePos = 0; 469 *stop = True; 470 471 if (t->needInit) 472 { 473 Lzma2Dec_Init(&t->dec); 474 t->needInit = False; 475 } 476 477 { 478 ELzmaStatus status; 479 size_t srcProcessed = srcSize; 480 Bool blockWasFinished = 481 ((int)t->parseStatus == LZMA_STATUS_FINISHED_WITH_MARK 482 || t->parseStatus == LZMA2_PARSE_STATUS_NEW_BLOCK); 483 484 SRes res = Lzma2Dec_DecodeToDic(&t->dec, 485 t->outPreSize, 486 src, &srcProcessed, 487 blockWasFinished ? LZMA_FINISH_END : LZMA_FINISH_ANY, 488 &status); 489 490 t->codeRes = res; 491 492 t->inCodeSize += srcProcessed; 493 *inCodePos = t->inCodeSize; 494 t->outCodeSize = t->dec.decoder.dicPos; 495 *outCodePos = t->dec.decoder.dicPos; 496 497 if (res != SZ_OK) 498 return res; 499 500 if (srcProcessed == srcSize) 501 *stop = False; 502 503 if (blockWasFinished) 504 { 505 if (srcSize != srcProcessed) 506 return SZ_ERROR_FAIL; 507 508 if (t->inPreSize == t->inCodeSize) 509 { 510 if (t->outPreSize != t->outCodeSize) 511 return SZ_ERROR_FAIL; 512 *stop = True; 513 } 514 } 515 else 516 { 517 if (t->outPreSize == t->outCodeSize) 518 *stop = True; 519 } 520 521 return SZ_OK; 522 } 523 } 524 525 526 #define LZMA2DECMT_STREAM_WRITE_STEP (1 << 24) 527 528 static SRes Lzma2DecMt_MtCallback_Write(void *pp, unsigned coderIndex, 529 Bool needWriteToStream, 530 const Byte *src, size_t srcSize, 531 Bool *needContinue, Bool *canRecode) 532 { 533 CLzma2DecMt *me = (CLzma2DecMt *)pp; 534 const CLzma2DecMtThread *t = &me->coders[coderIndex]; 535 size_t size = t->outCodeSize; 536 const Byte *data = t->outBuf; 537 Bool needContinue2 = True; 538 539 PRF_STR_INT_2("Write", coderIndex, srcSize); 540 541 *needContinue = False; 542 *canRecode = True; 543 UNUSED_VAR(src) 544 UNUSED_VAR(srcSize) 545 546 if ( 547 // t->parseStatus == LZMA_STATUS_FINISHED_WITH_MARK 548 t->state == MTDEC_PARSE_OVERFLOW 549 || t->state == MTDEC_PARSE_END) 550 needContinue2 = False; 551 552 553 if (!needWriteToStream) 554 return SZ_OK; 555 556 me->mtc.inProcessed += t->inCodeSize; 557 558 if (t->codeRes == SZ_OK) 559 if ((int)t->parseStatus == LZMA_STATUS_FINISHED_WITH_MARK 560 || t->parseStatus == LZMA2_PARSE_STATUS_NEW_BLOCK) 561 if (t->outPreSize != t->outCodeSize 562 || t->inPreSize != t->inCodeSize) 563 return SZ_ERROR_FAIL; 564 565 *canRecode = False; 566 567 if (me->outStream) 568 { 569 for (;;) 570 { 571 size_t cur = size; 572 size_t written; 573 if (cur > LZMA2DECMT_STREAM_WRITE_STEP) 574 cur = LZMA2DECMT_STREAM_WRITE_STEP; 575 576 written = ISeqOutStream_Write(me->outStream, data, cur); 577 578 me->outProcessed += written; 579 // me->mtc.writtenTotal += written; 580 if (written != cur) 581 return SZ_ERROR_WRITE; 582 data += cur; 583 size -= cur; 584 if (size == 0) 585 { 586 *needContinue = needContinue2; 587 return SZ_OK; 588 } 589 RINOK(MtProgress_ProgressAdd(&me->mtc.mtProgress, 0, 0)); 590 } 591 } 592 593 return SZ_ERROR_FAIL; 594 /* 595 if (size > me->outBufSize) 596 return SZ_ERROR_OUTPUT_EOF; 597 memcpy(me->outBuf, data, size); 598 me->outBufSize -= size; 599 me->outBuf += size; 600 *needContinue = needContinue2; 601 return SZ_OK; 602 */ 603 } 604 605 #endif 606 607 608 static SRes Lzma2Dec_Prepare_ST(CLzma2DecMt *p) 609 { 610 if (!p->dec_created) 611 { 612 Lzma2Dec_Construct(&p->dec); 613 p->dec_created = True; 614 } 615 616 RINOK(Lzma2Dec_Allocate(&p->dec, p->prop, &p->alignOffsetAlloc.vt)); 617 618 if (!p->inBuf || p->inBufSize != p->props.inBufSize_ST) 619 { 620 ISzAlloc_Free(p->allocMid, p->inBuf); 621 p->inBufSize = 0; 622 p->inBuf = (Byte *)ISzAlloc_Alloc(p->allocMid, p->props.inBufSize_ST); 623 if (!p->inBuf) 624 return SZ_ERROR_MEM; 625 p->inBufSize = p->props.inBufSize_ST; 626 } 627 628 Lzma2Dec_Init(&p->dec); 629 630 return SZ_OK; 631 } 632 633 634 static SRes Lzma2Dec_Decode_ST(CLzma2DecMt *p 635 #ifndef _7ZIP_ST 636 , Bool tMode 637 #endif 638 ) 639 { 640 SizeT wrPos; 641 size_t inPos, inLim; 642 const Byte *inData; 643 UInt64 inPrev, outPrev; 644 645 CLzma2Dec *dec; 646 647 #ifndef _7ZIP_ST 648 if (tMode) 649 { 650 Lzma2DecMt_FreeOutBufs(p); 651 tMode = MtDec_PrepareRead(&p->mtc); 652 } 653 #endif 654 655 RINOK(Lzma2Dec_Prepare_ST(p)); 656 657 dec = &p->dec; 658 659 inPrev = p->inProcessed; 660 outPrev = p->outProcessed; 661 662 inPos = 0; 663 inLim = 0; 664 inData = NULL; 665 wrPos = dec->decoder.dicPos; 666 667 for (;;) 668 { 669 SizeT dicPos; 670 SizeT size; 671 ELzmaFinishMode finishMode; 672 SizeT inProcessed; 673 ELzmaStatus status; 674 SRes res; 675 676 SizeT outProcessed; 677 Bool outFinished; 678 Bool needStop; 679 680 if (inPos == inLim) 681 { 682 #ifndef _7ZIP_ST 683 if (tMode) 684 { 685 inData = MtDec_Read(&p->mtc, &inLim); 686 inPos = 0; 687 if (inData) 688 continue; 689 tMode = False; 690 inLim = 0; 691 } 692 #endif 693 694 if (!p->readWasFinished) 695 { 696 inPos = 0; 697 inLim = p->inBufSize; 698 inData = p->inBuf; 699 p->readRes = ISeqInStream_Read(p->inStream, (void *)inData, &inLim); 700 // p->readProcessed += inLim; 701 // inLim -= 5; p->readWasFinished = True; // for test 702 if (inLim == 0 || p->readRes != SZ_OK) 703 p->readWasFinished = True; 704 } 705 } 706 707 dicPos = dec->decoder.dicPos; 708 { 709 SizeT next = dec->decoder.dicBufSize; 710 if (next - wrPos > p->props.outStep_ST) 711 next = wrPos + p->props.outStep_ST; 712 size = next - dicPos; 713 } 714 715 finishMode = LZMA_FINISH_ANY; 716 if (p->outSize_Defined) 717 { 718 const UInt64 rem = p->outSize - p->outProcessed; 719 if (size >= rem) 720 { 721 size = (SizeT)rem; 722 if (p->finishMode) 723 finishMode = LZMA_FINISH_END; 724 } 725 } 726 727 inProcessed = inLim - inPos; 728 729 res = Lzma2Dec_DecodeToDic(dec, dicPos + size, inData + inPos, &inProcessed, finishMode, &status); 730 731 inPos += inProcessed; 732 p->inProcessed += inProcessed; 733 outProcessed = dec->decoder.dicPos - dicPos; 734 p->outProcessed += outProcessed; 735 736 outFinished = (p->outSize_Defined && p->outSize <= p->outProcessed); 737 738 needStop = (res != SZ_OK 739 || (inProcessed == 0 && outProcessed == 0) 740 || status == LZMA_STATUS_FINISHED_WITH_MARK 741 || (!p->finishMode && outFinished)); 742 743 if (needStop || outProcessed >= size) 744 { 745 SRes res2; 746 { 747 size_t writeSize = dec->decoder.dicPos - wrPos; 748 size_t written = ISeqOutStream_Write(p->outStream, dec->decoder.dic + wrPos, writeSize); 749 res2 = (written == writeSize) ? SZ_OK : SZ_ERROR_WRITE; 750 } 751 752 if (dec->decoder.dicPos == dec->decoder.dicBufSize) 753 dec->decoder.dicPos = 0; 754 wrPos = dec->decoder.dicPos; 755 756 RINOK(res2); 757 758 if (needStop) 759 { 760 if (res != SZ_OK) 761 return res; 762 763 if (status == LZMA_STATUS_FINISHED_WITH_MARK) 764 { 765 if (p->finishMode) 766 { 767 if (p->outSize_Defined && p->outSize != p->outProcessed) 768 return SZ_ERROR_DATA; 769 } 770 return SZ_OK; 771 } 772 773 if (!p->finishMode && outFinished) 774 return SZ_OK; 775 776 if (status == LZMA_STATUS_NEEDS_MORE_INPUT) 777 return SZ_ERROR_INPUT_EOF; 778 779 return SZ_ERROR_DATA; 780 } 781 } 782 783 if (p->progress) 784 { 785 UInt64 inDelta = p->inProcessed - inPrev; 786 UInt64 outDelta = p->outProcessed - outPrev; 787 if (inDelta >= (1 << 22) || outDelta >= (1 << 22)) 788 { 789 RINOK(ICompressProgress_Progress(p->progress, p->inProcessed, p->outProcessed)); 790 inPrev = p->inProcessed; 791 outPrev = p->outProcessed; 792 } 793 } 794 } 795 } 796 797 798 799 SRes Lzma2DecMt_Decode(CLzma2DecMtHandle pp, 800 Byte prop, 801 const CLzma2DecMtProps *props, 802 ISeqOutStream *outStream, const UInt64 *outDataSize, int finishMode, 803 // Byte *outBuf, size_t *outBufSize, 804 ISeqInStream *inStream, 805 // const Byte *inData, size_t inDataSize, 806 UInt64 *inProcessed, 807 // UInt64 *outProcessed, 808 int *isMT, 809 ICompressProgress *progress) 810 { 811 CLzma2DecMt *p = (CLzma2DecMt *)pp; 812 #ifndef _7ZIP_ST 813 Bool tMode; 814 #endif 815 816 *inProcessed = 0; 817 818 if (prop > 40) 819 return SZ_ERROR_UNSUPPORTED; 820 821 p->prop = prop; 822 p->props = *props; 823 824 p->inStream = inStream; 825 p->outStream = outStream; 826 p->progress = progress; 827 828 p->outSize = 0; 829 p->outSize_Defined = False; 830 if (outDataSize) 831 { 832 p->outSize_Defined = True; 833 p->outSize = *outDataSize; 834 } 835 p->finishMode = finishMode; 836 837 p->outProcessed = 0; 838 p->inProcessed = 0; 839 840 p->readWasFinished = False; 841 842 *isMT = False; 843 844 845 #ifndef _7ZIP_ST 846 847 tMode = False; 848 849 // p->mtc.parseRes = SZ_OK; 850 851 // p->mtc.numFilledThreads = 0; 852 // p->mtc.crossStart = 0; 853 // p->mtc.crossEnd = 0; 854 // p->mtc.allocError_for_Read_BlockIndex = 0; 855 // p->mtc.isAllocError = False; 856 857 if (p->props.numThreads > 1) 858 { 859 IMtDecCallback vt; 860 861 Lzma2DecMt_FreeSt(p); 862 863 p->outProcessed_Parse = 0; 864 865 if (!p->mtc_WasConstructed) 866 { 867 p->mtc_WasConstructed = True; 868 MtDec_Construct(&p->mtc); 869 } 870 871 p->mtc.progress = progress; 872 p->mtc.inStream = inStream; 873 874 // p->outBuf = NULL; 875 // p->outBufSize = 0; 876 /* 877 if (!outStream) 878 { 879 // p->outBuf = outBuf; 880 // p->outBufSize = *outBufSize; 881 // *outBufSize = 0; 882 return SZ_ERROR_PARAM; 883 } 884 */ 885 886 // p->mtc.inBlockMax = p->props.inBlockMax; 887 p->mtc.alloc = &p->alignOffsetAlloc.vt; 888 // p->alignOffsetAlloc.baseAlloc; 889 // p->mtc.inData = inData; 890 // p->mtc.inDataSize = inDataSize; 891 p->mtc.mtCallback = &vt; 892 p->mtc.mtCallbackObject = p; 893 894 p->mtc.inBufSize = p->props.inBufSize_MT; 895 896 p->mtc.numThreadsMax = p->props.numThreads; 897 898 *isMT = True; 899 900 vt.Parse = Lzma2DecMt_MtCallback_Parse; 901 vt.PreCode = Lzma2DecMt_MtCallback_PreCode; 902 vt.Code = Lzma2DecMt_MtCallback_Code; 903 vt.Write = Lzma2DecMt_MtCallback_Write; 904 905 { 906 Bool needContinue = False; 907 908 SRes res = MtDec_Code(&p->mtc); 909 910 /* 911 if (!outStream) 912 *outBufSize = p->outBuf - outBuf; 913 */ 914 915 *inProcessed = p->mtc.inProcessed; 916 917 needContinue = False; 918 919 if (res == SZ_OK) 920 { 921 if (p->mtc.mtProgress.res != SZ_OK) 922 res = p->mtc.mtProgress.res; 923 else 924 needContinue = p->mtc.needContinue; 925 } 926 927 if (!needContinue) 928 { 929 if (res == SZ_OK) 930 return p->mtc.readRes; 931 return res; 932 } 933 934 tMode = True; 935 p->readRes = p->mtc.readRes; 936 p->readWasFinished = p->mtc.readWasFinished; 937 p->inProcessed = p->mtc.inProcessed; 938 939 PRF_STR("----- decoding ST -----"); 940 } 941 } 942 943 #endif 944 945 946 *isMT = False; 947 948 { 949 SRes res = Lzma2Dec_Decode_ST(p 950 #ifndef _7ZIP_ST 951 , tMode 952 #endif 953 ); 954 955 *inProcessed = p->inProcessed; 956 957 // res = SZ_OK; // for test 958 if (res == SZ_OK && p->readRes != SZ_OK) 959 res = p->readRes; 960 961 /* 962 #ifndef _7ZIP_ST 963 if (res == SZ_OK && tMode && p->mtc.parseRes != SZ_OK) 964 res = p->mtc.parseRes; 965 #endif 966 */ 967 968 return res; 969 } 970 } 971 972 973 /* ---------- Read from CLzma2DecMtHandle Interface ---------- */ 974 975 SRes Lzma2DecMt_Init(CLzma2DecMtHandle pp, 976 Byte prop, 977 const CLzma2DecMtProps *props, 978 const UInt64 *outDataSize, int finishMode, 979 ISeqInStream *inStream) 980 { 981 CLzma2DecMt *p = (CLzma2DecMt *)pp; 982 983 if (prop > 40) 984 return SZ_ERROR_UNSUPPORTED; 985 986 p->prop = prop; 987 p->props = *props; 988 989 p->inStream = inStream; 990 991 p->outSize = 0; 992 p->outSize_Defined = False; 993 if (outDataSize) 994 { 995 p->outSize_Defined = True; 996 p->outSize = *outDataSize; 997 } 998 p->finishMode = finishMode; 999 1000 p->outProcessed = 0; 1001 p->inProcessed = 0; 1002 1003 p->inPos = 0; 1004 p->inLim = 0; 1005 1006 return Lzma2Dec_Prepare_ST(p); 1007 } 1008 1009 1010 SRes Lzma2DecMt_Read(CLzma2DecMtHandle pp, 1011 Byte *data, size_t *outSize, 1012 UInt64 *inStreamProcessed) 1013 { 1014 CLzma2DecMt *p = (CLzma2DecMt *)pp; 1015 ELzmaFinishMode finishMode; 1016 SRes readRes; 1017 size_t size = *outSize; 1018 1019 *outSize = 0; 1020 *inStreamProcessed = 0; 1021 1022 finishMode = LZMA_FINISH_ANY; 1023 if (p->outSize_Defined) 1024 { 1025 const UInt64 rem = p->outSize - p->outProcessed; 1026 if (size >= rem) 1027 { 1028 size = (size_t)rem; 1029 if (p->finishMode) 1030 finishMode = LZMA_FINISH_END; 1031 } 1032 } 1033 1034 readRes = SZ_OK; 1035 1036 for (;;) 1037 { 1038 SizeT inCur; 1039 SizeT outCur; 1040 ELzmaStatus status; 1041 SRes res; 1042 1043 if (p->inPos == p->inLim && readRes == SZ_OK) 1044 { 1045 p->inPos = 0; 1046 p->inLim = p->props.inBufSize_ST; 1047 readRes = ISeqInStream_Read(p->inStream, p->inBuf, &p->inLim); 1048 } 1049 1050 inCur = p->inLim - p->inPos; 1051 outCur = size; 1052 1053 res = Lzma2Dec_DecodeToBuf(&p->dec, data, &outCur, 1054 p->inBuf + p->inPos, &inCur, finishMode, &status); 1055 1056 p->inPos += inCur; 1057 p->inProcessed += inCur; 1058 *inStreamProcessed += inCur; 1059 p->outProcessed += outCur; 1060 *outSize += outCur; 1061 size -= outCur; 1062 data += outCur; 1063 1064 if (res != 0) 1065 return res; 1066 1067 /* 1068 if (status == LZMA_STATUS_FINISHED_WITH_MARK) 1069 return readRes; 1070 1071 if (size == 0 && status != LZMA_STATUS_NEEDS_MORE_INPUT) 1072 { 1073 if (p->finishMode && p->outSize_Defined && p->outProcessed >= p->outSize) 1074 return SZ_ERROR_DATA; 1075 return readRes; 1076 } 1077 */ 1078 1079 if (inCur == 0 && outCur == 0) 1080 return readRes; 1081 } 1082 }