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