diff options
Diffstat (limited to '3rdparty/lzma/CPP/7zip/Archive/7z/7zDecode.cpp')
-rw-r--r-- | 3rdparty/lzma/CPP/7zip/Archive/7z/7zDecode.cpp | 569 |
1 files changed, 390 insertions, 179 deletions
diff --git a/3rdparty/lzma/CPP/7zip/Archive/7z/7zDecode.cpp b/3rdparty/lzma/CPP/7zip/Archive/7z/7zDecode.cpp index 425a341577d..bfe1b24e923 100644 --- a/3rdparty/lzma/CPP/7zip/Archive/7z/7zDecode.cpp +++ b/3rdparty/lzma/CPP/7zip/Archive/7z/7zDecode.cpp @@ -3,7 +3,6 @@ #include "StdAfx.h" #include "../../Common/LimitedStreams.h" -#include "../../Common/LockedStream.h" #include "../../Common/ProgressUtils.h" #include "../../Common/StreamObjects.h" @@ -12,230 +11,364 @@ namespace NArchive { namespace N7z { -static void ConvertFolderItemInfoToBindInfo(const CFolder &folder, - CBindInfoEx &bindInfo) +class CDecProgress: + public ICompressProgressInfo, + public CMyUnknownImp { - bindInfo.Clear(); - int i; - for (i = 0; i < folder.BindPairs.Size(); i++) + CMyComPtr<ICompressProgressInfo> _progress; +public: + CDecProgress(ICompressProgressInfo *progress): _progress(progress) {} + + MY_UNKNOWN_IMP1(ICompressProgressInfo) + STDMETHOD(SetRatioInfo)(const UInt64 *inSize, const UInt64 *outSize); +}; + +STDMETHODIMP CDecProgress::SetRatioInfo(const UInt64 * /* inSize */, const UInt64 *outSize) +{ + return _progress->SetRatioInfo(NULL, outSize); +} + +static void Convert_FolderInfo_to_BindInfo(const CFolderEx &folder, CBindInfoEx &bi) +{ + bi.Clear(); + + bi.Bonds.ClearAndSetSize(folder.Bonds.Size()); + unsigned i; + for (i = 0; i < folder.Bonds.Size(); i++) { - NCoderMixer::CBindPair bindPair; - bindPair.InIndex = (UInt32)folder.BindPairs[i].InIndex; - bindPair.OutIndex = (UInt32)folder.BindPairs[i].OutIndex; - bindInfo.BindPairs.Add(bindPair); + NCoderMixer2::CBond &bond = bi.Bonds[i]; + const N7z::CBond &folderBond = folder.Bonds[i]; + bond.PackIndex = folderBond.PackIndex; + bond.UnpackIndex = folderBond.UnpackIndex; } - UInt32 outStreamIndex = 0; + + bi.Coders.ClearAndSetSize(folder.Coders.Size()); + bi.CoderMethodIDs.ClearAndSetSize(folder.Coders.Size()); for (i = 0; i < folder.Coders.Size(); i++) { - NCoderMixer::CCoderStreamsInfo coderStreamsInfo; const CCoderInfo &coderInfo = folder.Coders[i]; - coderStreamsInfo.NumInStreams = (UInt32)coderInfo.NumInStreams; - coderStreamsInfo.NumOutStreams = (UInt32)coderInfo.NumOutStreams; - bindInfo.Coders.Add(coderStreamsInfo); - bindInfo.CoderMethodIDs.Add(coderInfo.MethodID); - for (UInt32 j = 0; j < coderStreamsInfo.NumOutStreams; j++, outStreamIndex++) - if (folder.FindBindPairForOutStream(outStreamIndex) < 0) - bindInfo.OutStreams.Add(outStreamIndex); + bi.Coders[i].NumStreams = coderInfo.NumStreams; + bi.CoderMethodIDs[i] = coderInfo.MethodID; } + + /* + if (!bi.SetUnpackCoder()) + throw 1112; + */ + bi.UnpackCoder = folder.UnpackCoder; + bi.PackStreams.ClearAndSetSize(folder.PackStreams.Size()); for (i = 0; i < folder.PackStreams.Size(); i++) - bindInfo.InStreams.Add((UInt32)folder.PackStreams[i]); + bi.PackStreams[i] = folder.PackStreams[i]; } -static bool AreCodersEqual(const NCoderMixer::CCoderStreamsInfo &a1, - const NCoderMixer::CCoderStreamsInfo &a2) +static inline bool AreCodersEqual( + const NCoderMixer2::CCoderStreamsInfo &a1, + const NCoderMixer2::CCoderStreamsInfo &a2) { - return (a1.NumInStreams == a2.NumInStreams) && - (a1.NumOutStreams == a2.NumOutStreams); + return (a1.NumStreams == a2.NumStreams); } -static bool AreBindPairsEqual(const NCoderMixer::CBindPair &a1, const NCoderMixer::CBindPair &a2) +static inline bool AreBondsEqual( + const NCoderMixer2::CBond &a1, + const NCoderMixer2::CBond &a2) { - return (a1.InIndex == a2.InIndex) && - (a1.OutIndex == a2.OutIndex); + return + (a1.PackIndex == a2.PackIndex) && + (a1.UnpackIndex == a2.UnpackIndex); } static bool AreBindInfoExEqual(const CBindInfoEx &a1, const CBindInfoEx &a2) { if (a1.Coders.Size() != a2.Coders.Size()) return false; - int i; + unsigned i; for (i = 0; i < a1.Coders.Size(); i++) if (!AreCodersEqual(a1.Coders[i], a2.Coders[i])) return false; - if (a1.BindPairs.Size() != a2.BindPairs.Size()) + + if (a1.Bonds.Size() != a2.Bonds.Size()) return false; - for (i = 0; i < a1.BindPairs.Size(); i++) - if (!AreBindPairsEqual(a1.BindPairs[i], a2.BindPairs[i])) + for (i = 0; i < a1.Bonds.Size(); i++) + if (!AreBondsEqual(a1.Bonds[i], a2.Bonds[i])) return false; + for (i = 0; i < a1.CoderMethodIDs.Size(); i++) if (a1.CoderMethodIDs[i] != a2.CoderMethodIDs[i]) return false; - if (a1.InStreams.Size() != a2.InStreams.Size()) + + if (a1.PackStreams.Size() != a2.PackStreams.Size()) return false; - if (a1.OutStreams.Size() != a2.OutStreams.Size()) + for (i = 0; i < a1.PackStreams.Size(); i++) + if (a1.PackStreams[i] != a2.PackStreams[i]) + return false; + + /* + if (a1.UnpackCoder != a2.UnpackCoder) return false; + */ return true; } -CDecoder::CDecoder(bool multiThread) +CDecoder::CDecoder(bool useMixerMT): + _bindInfoPrev_Defined(false), + _useMixerMT(useMixerMT) +{} + + +struct CLockedInStream: + public IUnknown, + public CMyUnknownImp { - #ifndef _ST_MODE - multiThread = true; + CMyComPtr<IInStream> Stream; + UInt64 Pos; + + MY_UNKNOWN_IMP + + #ifdef USE_MIXER_MT + NWindows::NSynchronization::CCriticalSection CriticalSection; #endif - _multiThread = multiThread; - _bindInfoExPrevIsDefined = false; +}; + + +#ifdef USE_MIXER_MT + +class CLockedSequentialInStreamMT: + public ISequentialInStream, + public CMyUnknownImp +{ + CLockedInStream *_glob; + UInt64 _pos; + CMyComPtr<IUnknown> _globRef; +public: + void Init(CLockedInStream *lockedInStream, UInt64 startPos) + { + _globRef = lockedInStream; + _glob = lockedInStream; + _pos = startPos; + } + + MY_UNKNOWN_IMP1(ISequentialInStream) + + STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize); +}; + +STDMETHODIMP CLockedSequentialInStreamMT::Read(void *data, UInt32 size, UInt32 *processedSize) +{ + NWindows::NSynchronization::CCriticalSectionLock lock(_glob->CriticalSection); + + if (_pos != _glob->Pos) + { + RINOK(_glob->Stream->Seek(_pos, STREAM_SEEK_SET, NULL)); + _glob->Pos = _pos; + } + + UInt32 realProcessedSize = 0; + HRESULT res = _glob->Stream->Read(data, size, &realProcessedSize); + _pos += realProcessedSize; + _glob->Pos = _pos; + if (processedSize) + *processedSize = realProcessedSize; + return res; } +#endif + + +#ifdef USE_MIXER_ST + +class CLockedSequentialInStreamST: + public ISequentialInStream, + public CMyUnknownImp +{ + CLockedInStream *_glob; + UInt64 _pos; + CMyComPtr<IUnknown> _globRef; +public: + void Init(CLockedInStream *lockedInStream, UInt64 startPos) + { + _globRef = lockedInStream; + _glob = lockedInStream; + _pos = startPos; + } + + MY_UNKNOWN_IMP1(ISequentialInStream) + + STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize); +}; + +STDMETHODIMP CLockedSequentialInStreamST::Read(void *data, UInt32 size, UInt32 *processedSize) +{ + if (_pos != _glob->Pos) + { + RINOK(_glob->Stream->Seek(_pos, STREAM_SEEK_SET, NULL)); + _glob->Pos = _pos; + } + + UInt32 realProcessedSize = 0; + HRESULT res = _glob->Stream->Read(data, size, &realProcessedSize); + _pos += realProcessedSize; + _glob->Pos = _pos; + if (processedSize) + *processedSize = realProcessedSize; + return res; +} + +#endif + + + HRESULT CDecoder::Decode( DECL_EXTERNAL_CODECS_LOC_VARS IInStream *inStream, UInt64 startPos, - const UInt64 *packSizes, - const CFolder &folderInfo, - ISequentialOutStream *outStream, - ICompressProgressInfo *compressProgress - #ifndef _NO_CRYPTO - , ICryptoGetTextPassword *getTextPassword, bool &passwordIsDefined + const CFolders &folders, unsigned folderIndex, + const UInt64 *unpackSize + + , ISequentialOutStream *outStream + , ICompressProgressInfo *compressProgress + , ISequentialInStream ** + + #ifdef USE_MIXER_ST + inStreamMainRes #endif + + _7Z_DECODER_CRYPRO_VARS_DECL + #if !defined(_7ZIP_ST) && !defined(_SFX) , bool mtMode, UInt32 numThreads #endif ) { - if (!folderInfo.CheckStructure()) + const UInt64 *packPositions = &folders.PackPositions[folders.FoStartPackStreamIndex[folderIndex]]; + CFolderEx folderInfo; + folders.ParseFolderEx(folderIndex, folderInfo); + + if (!folderInfo.IsDecodingSupported()) + return E_NOTIMPL; + + CBindInfoEx bindInfo; + Convert_FolderInfo_to_BindInfo(folderInfo, bindInfo); + if (!bindInfo.CalcMapsAndCheck()) return E_NOTIMPL; - #ifndef _NO_CRYPTO - passwordIsDefined = false; - #endif - CObjectVector< CMyComPtr<ISequentialInStream> > inStreams; - - CLockedInStream lockedInStream; - lockedInStream.Init(inStream); - for (int j = 0; j < folderInfo.PackStreams.Size(); j++) + UInt64 folderUnpackSize = folders.GetFolderUnpackSize(folderIndex); + bool fullUnpack = true; + if (unpackSize) { - CLockedSequentialInStreamImp *lockedStreamImpSpec = new - CLockedSequentialInStreamImp; - CMyComPtr<ISequentialInStream> lockedStreamImp = lockedStreamImpSpec; - lockedStreamImpSpec->Init(&lockedInStream, startPos); - startPos += packSizes[j]; - - CLimitedSequentialInStream *streamSpec = new - CLimitedSequentialInStream; - CMyComPtr<ISequentialInStream> inStream = streamSpec; - streamSpec->SetStream(lockedStreamImp); - streamSpec->Init(packSizes[j]); - inStreams.Add(inStream); + if (*unpackSize > folderUnpackSize) + return E_FAIL; + fullUnpack = (*unpackSize == folderUnpackSize); } + + /* + We don't need to init isEncrypted and passwordIsDefined + We must upgrade them only - int numCoders = folderInfo.Coders.Size(); + #ifndef _NO_CRYPTO + isEncrypted = false; + passwordIsDefined = false; + #endif + */ - CBindInfoEx bindInfo; - ConvertFolderItemInfoToBindInfo(folderInfo, bindInfo); - bool createNewCoders; - if (!_bindInfoExPrevIsDefined) - createNewCoders = true; - else - createNewCoders = !AreBindInfoExEqual(bindInfo, _bindInfoExPrev); - if (createNewCoders) + if (!_bindInfoPrev_Defined || !AreBindInfoExEqual(bindInfo, _bindInfoPrev)) { - int i; - _decoders.Clear(); - // _decoders2.Clear(); - - _mixerCoder.Release(); + _mixerRef.Release(); - if (_multiThread) + #ifdef USE_MIXER_MT + #ifdef USE_MIXER_ST + if (_useMixerMT) + #endif { - _mixerCoderMTSpec = new NCoderMixer::CCoderMixer2MT; - _mixerCoder = _mixerCoderMTSpec; - _mixerCoderCommon = _mixerCoderMTSpec; + _mixerMT = new NCoderMixer2::CMixerMT(false); + _mixerRef = _mixerMT; + _mixer = _mixerMT; } + #ifdef USE_MIXER_ST else + #endif + #endif { - #ifdef _ST_MODE - _mixerCoderSTSpec = new NCoderMixer::CCoderMixer2ST; - _mixerCoder = _mixerCoderSTSpec; - _mixerCoderCommon = _mixerCoderSTSpec; + #ifdef USE_MIXER_ST + _mixerST = new NCoderMixer2::CMixerST(false); + _mixerRef = _mixerST; + _mixer = _mixerST; #endif } - RINOK(_mixerCoderCommon->SetBindInfo(bindInfo)); - for (i = 0; i < numCoders; i++) + RINOK(_mixer->SetBindInfo(bindInfo)); + + FOR_VECTOR(i, folderInfo.Coders) { const CCoderInfo &coderInfo = folderInfo.Coders[i]; + #ifndef _SFX + // we don't support RAR codecs here + if ((coderInfo.MethodID >> 8) == 0x403) + return E_NOTIMPL; + #endif - CMyComPtr<ICompressCoder> decoder; - CMyComPtr<ICompressCoder2> decoder2; + CCreatedCoder cod; RINOK(CreateCoder( EXTERNAL_CODECS_LOC_VARS - coderInfo.MethodID, decoder, decoder2, false)); - CMyComPtr<IUnknown> decoderUnknown; + coderInfo.MethodID, false, cod)); + if (coderInfo.IsSimpleCoder()) { - if (decoder == 0) + if (!cod.Coder) return E_NOTIMPL; - - decoderUnknown = (IUnknown *)decoder; - - if (_multiThread) - _mixerCoderMTSpec->AddCoder(decoder); - #ifdef _ST_MODE - else - _mixerCoderSTSpec->AddCoder(decoder, false); - #endif + // CMethodId m = coderInfo.MethodID; + // isFilter = (IsFilterMethod(m) || m == k_AES); } else { - if (decoder2 == 0) + if (!cod.Coder2 || cod.NumStreams != coderInfo.NumStreams) return E_NOTIMPL; - decoderUnknown = (IUnknown *)decoder2; - if (_multiThread) - _mixerCoderMTSpec->AddCoder2(decoder2); - #ifdef _ST_MODE - else - _mixerCoderSTSpec->AddCoder2(decoder2, false); - #endif } - _decoders.Add(decoderUnknown); + _mixer->AddCoder(cod); + + // now there is no codec that uses another external codec + /* #ifdef EXTERNAL_CODECS CMyComPtr<ISetCompressCodecsInfo> setCompressCodecsInfo; decoderUnknown.QueryInterface(IID_ISetCompressCodecsInfo, (void **)&setCompressCodecsInfo); if (setCompressCodecsInfo) { - RINOK(setCompressCodecsInfo->SetCompressCodecsInfo(codecsInfo)); + // we must use g_ExternalCodecs also + RINOK(setCompressCodecsInfo->SetCompressCodecsInfo(__externalCodecs->GetCodecs)); } #endif + */ } - _bindInfoExPrev = bindInfo; - _bindInfoExPrevIsDefined = true; + + _bindInfoPrev = bindInfo; + _bindInfoPrev_Defined = true; } - int i; - _mixerCoderCommon->ReInit(); - - UInt32 packStreamIndex = 0, unpackStreamIndex = 0; - UInt32 coderIndex = 0; - // UInt32 coder2Index = 0; + + _mixer->ReInit(); - for (i = 0; i < numCoders; i++) + UInt32 packStreamIndex = 0; + UInt32 unpackStreamIndexStart = folders.FoToCoderUnpackSizes[folderIndex]; + + unsigned i; + + for (i = 0; i < folderInfo.Coders.Size(); i++) { const CCoderInfo &coderInfo = folderInfo.Coders[i]; - CMyComPtr<IUnknown> &decoder = _decoders[coderIndex]; - + IUnknown *decoder = _mixer->GetCoder(i).GetUnknown(); + { CMyComPtr<ICompressSetDecoderProperties2> setDecoderProperties; - decoder.QueryInterface(IID_ICompressSetDecoderProperties2, &setDecoderProperties); + decoder->QueryInterface(IID_ICompressSetDecoderProperties2, (void **)&setDecoderProperties); if (setDecoderProperties) { const CByteBuffer &props = coderInfo.Props; - size_t size = props.GetCapacity(); + size_t size = props.Size(); if (size > 0xFFFFFFFF) return E_NOTIMPL; - // if (size > 0) - { - RINOK(setDecoderProperties->SetDecoderProperties2((const Byte *)props, (UInt32)size)); - } + HRESULT res = setDecoderProperties->SetDecoderProperties2((const Byte *)props, (UInt32)size); + if (res == E_INVALIDARG) + res = E_NOTIMPL; + RINOK(res); } } @@ -243,7 +376,7 @@ HRESULT CDecoder::Decode( if (mtMode) { CMyComPtr<ICompressSetCoderMt> setCoderMt; - decoder.QueryInterface(IID_ICompressSetCoderMt, &setCoderMt); + decoder->QueryInterface(IID_ICompressSetCoderMt, (void **)&setCoderMt); if (setCoderMt) { RINOK(setCoderMt->SetNumberOfThreads(numThreads)); @@ -254,79 +387,157 @@ HRESULT CDecoder::Decode( #ifndef _NO_CRYPTO { CMyComPtr<ICryptoSetPassword> cryptoSetPassword; - decoder.QueryInterface(IID_ICryptoSetPassword, &cryptoSetPassword); + decoder->QueryInterface(IID_ICryptoSetPassword, (void **)&cryptoSetPassword); if (cryptoSetPassword) { - if (getTextPassword == 0) - return E_FAIL; + isEncrypted = true; + if (!getTextPassword) + return E_NOTIMPL; CMyComBSTR passwordBSTR; RINOK(getTextPassword->CryptoGetTextPassword(&passwordBSTR)); - CByteBuffer buffer; passwordIsDefined = true; - const UString password(passwordBSTR); - const UInt32 sizeInBytes = password.Length() * 2; - buffer.SetCapacity(sizeInBytes); - for (int i = 0; i < password.Length(); i++) + password.Empty(); + size_t len = 0; + if (passwordBSTR) + { + password = passwordBSTR; + len = password.Len(); + } + CByteBuffer buffer(len * 2); + for (size_t i = 0; i < len; i++) { - wchar_t c = password[i]; + wchar_t c = passwordBSTR[i]; ((Byte *)buffer)[i * 2] = (Byte)c; ((Byte *)buffer)[i * 2 + 1] = (Byte)(c >> 8); } - RINOK(cryptoSetPassword->CryptoSetPassword((const Byte *)buffer, sizeInBytes)); + RINOK(cryptoSetPassword->CryptoSetPassword((const Byte *)buffer, (UInt32)buffer.Size())); } } #endif - coderIndex++; + { + CMyComPtr<ICompressSetFinishMode> setFinishMode; + decoder->QueryInterface(IID_ICompressSetFinishMode, (void **)&setFinishMode); + if (setFinishMode) + { + RINOK(setFinishMode->SetFinishMode(BoolToInt(fullUnpack))); + } + } - UInt32 numInStreams = (UInt32)coderInfo.NumInStreams; - UInt32 numOutStreams = (UInt32)coderInfo.NumOutStreams; - CRecordVector<const UInt64 *> packSizesPointers; - CRecordVector<const UInt64 *> unpackSizesPointers; - packSizesPointers.Reserve(numInStreams); - unpackSizesPointers.Reserve(numOutStreams); - UInt32 j; - for (j = 0; j < numOutStreams; j++, unpackStreamIndex++) - unpackSizesPointers.Add(&folderInfo.UnpackSizes[unpackStreamIndex]); + UInt32 numStreams = (UInt32)coderInfo.NumStreams; - for (j = 0; j < numInStreams; j++, packStreamIndex++) + CObjArray<UInt64> packSizes(numStreams); + CObjArray<const UInt64 *> packSizesPointers(numStreams); + + for (UInt32 j = 0; j < numStreams; j++, packStreamIndex++) { - int bindPairIndex = folderInfo.FindBindPairForInStream(packStreamIndex); - if (bindPairIndex >= 0) - packSizesPointers.Add( - &folderInfo.UnpackSizes[(UInt32)folderInfo.BindPairs[bindPairIndex].OutIndex]); + int bond = folderInfo.FindBond_for_PackStream(packStreamIndex); + + if (bond >= 0) + packSizesPointers[j] = &folders.CoderUnpackSizes[unpackStreamIndexStart + folderInfo.Bonds[(unsigned)bond].UnpackIndex]; else { - int index = folderInfo.FindPackStreamArrayIndex(packStreamIndex); + int index = folderInfo.Find_in_PackStreams(packStreamIndex); if (index < 0) - return E_FAIL; - packSizesPointers.Add(&packSizes[index]); + return E_NOTIMPL; + packSizes[j] = packPositions[(unsigned)index + 1] - packPositions[(unsigned)index]; + packSizesPointers[j] = &packSizes[j]; } } + + const UInt64 *unpackSizesPointer = + (unpackSize && i == bindInfo.UnpackCoder) ? + unpackSize : + &folders.CoderUnpackSizes[unpackStreamIndexStart + i]; - _mixerCoderCommon->SetCoderInfo(i, - &packSizesPointers.Front(), - &unpackSizesPointers.Front()); + _mixer->SetCoderInfo(i, unpackSizesPointer, packSizesPointers); } - UInt32 mainCoder, temp; - bindInfo.FindOutStream(bindInfo.OutStreams[0], mainCoder, temp); - if (_multiThread) - _mixerCoderMTSpec->SetProgressCoderIndex(mainCoder); - /* - else - _mixerCoderSTSpec->SetProgressCoderIndex(mainCoder);; - */ + if (outStream) + { + _mixer->SelectMainCoder(!fullUnpack); + } + + CObjectVector< CMyComPtr<ISequentialInStream> > inStreams; - if (numCoders == 0) - return 0; - CRecordVector<ISequentialInStream *> inStreamPointers; - inStreamPointers.Reserve(inStreams.Size()); - for (i = 0; i < inStreams.Size(); i++) - inStreamPointers.Add(inStreams[i]); - ISequentialOutStream *outStreamPointer = outStream; - return _mixerCoder->Code(&inStreamPointers.Front(), NULL, - inStreams.Size(), &outStreamPointer, NULL, 1, compressProgress); + CLockedInStream *lockedInStreamSpec = new CLockedInStream; + CMyComPtr<IUnknown> lockedInStream = lockedInStreamSpec; + + bool needMtLock = false; + + if (folderInfo.PackStreams.Size() > 1) + { + // lockedInStream.Pos = (UInt64)(Int64)-1; + // RINOK(inStream->Seek(0, STREAM_SEEK_CUR, &lockedInStream.Pos)); + RINOK(inStream->Seek(startPos + packPositions[0], STREAM_SEEK_SET, &lockedInStreamSpec->Pos)); + lockedInStreamSpec->Stream = inStream; + + #ifdef USE_MIXER_ST + if (_mixer->IsThere_ExternalCoder_in_PackTree(_mixer->MainCoderIndex)) + #endif + needMtLock = true; + } + + for (unsigned j = 0; j < folderInfo.PackStreams.Size(); j++) + { + CMyComPtr<ISequentialInStream> packStream; + UInt64 packPos = startPos + packPositions[j]; + + if (folderInfo.PackStreams.Size() == 1) + { + RINOK(inStream->Seek(packPos, STREAM_SEEK_SET, NULL)); + packStream = inStream; + } + else + { + #ifdef USE_MIXER_MT + #ifdef USE_MIXER_ST + if (_useMixerMT || needMtLock) + #endif + { + CLockedSequentialInStreamMT *lockedStreamImpSpec = new CLockedSequentialInStreamMT; + packStream = lockedStreamImpSpec; + lockedStreamImpSpec->Init(lockedInStreamSpec, packPos); + } + #ifdef USE_MIXER_ST + else + #endif + #endif + { + #ifdef USE_MIXER_ST + CLockedSequentialInStreamST *lockedStreamImpSpec = new CLockedSequentialInStreamST; + packStream = lockedStreamImpSpec; + lockedStreamImpSpec->Init(lockedInStreamSpec, packPos); + #endif + } + } + + CLimitedSequentialInStream *streamSpec = new CLimitedSequentialInStream; + inStreams.AddNew() = streamSpec; + streamSpec->SetStream(packStream); + streamSpec->Init(packPositions[j + 1] - packPositions[j]); + } + + unsigned num = inStreams.Size(); + CObjArray<ISequentialInStream *> inStreamPointers(num); + for (i = 0; i < num; i++) + inStreamPointers[i] = inStreams[i]; + + if (outStream) + { + CMyComPtr<ICompressProgressInfo> progress2; + if (compressProgress && !_mixer->Is_PackSize_Correct_for_Coder(_mixer->MainCoderIndex)) + progress2 = new CDecProgress(compressProgress); + + ISequentialOutStream *outStreamPointer = outStream; + return _mixer->Code(inStreamPointers, &outStreamPointer, progress2 ? (ICompressProgressInfo *)progress2 : compressProgress); + } + + #ifdef USE_MIXER_ST + return _mixerST->GetMainUnpackStream(inStreamPointers, inStreamMainRes); + #else + return E_FAIL; + #endif } }} |