1baa3858d3f5d128a5c8466b700098109edcad5f2repo sync// 7zDecode.cpp 2baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 3baa3858d3f5d128a5c8466b700098109edcad5f2repo sync#include "StdAfx.h" 4baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 5baa3858d3f5d128a5c8466b700098109edcad5f2repo sync#include "../../Common/LimitedStreams.h" 6baa3858d3f5d128a5c8466b700098109edcad5f2repo sync#include "../../Common/LockedStream.h" 7baa3858d3f5d128a5c8466b700098109edcad5f2repo sync#include "../../Common/ProgressUtils.h" 8baa3858d3f5d128a5c8466b700098109edcad5f2repo sync#include "../../Common/StreamObjects.h" 9baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 10baa3858d3f5d128a5c8466b700098109edcad5f2repo sync#include "7zDecode.h" 11baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 12baa3858d3f5d128a5c8466b700098109edcad5f2repo syncnamespace NArchive { 13baa3858d3f5d128a5c8466b700098109edcad5f2repo syncnamespace N7z { 14baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 15baa3858d3f5d128a5c8466b700098109edcad5f2repo syncstatic void ConvertFolderItemInfoToBindInfo(const CFolder &folder, 16baa3858d3f5d128a5c8466b700098109edcad5f2repo sync CBindInfoEx &bindInfo) 17baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{ 18baa3858d3f5d128a5c8466b700098109edcad5f2repo sync bindInfo.Clear(); 19cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky bindInfo.BindPairs.ClearAndSetSize(folder.BindPairs.Size()); 20cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky unsigned i; 21baa3858d3f5d128a5c8466b700098109edcad5f2repo sync for (i = 0; i < folder.BindPairs.Size(); i++) 22baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 23cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky NCoderMixer::CBindPair &bindPair = bindInfo.BindPairs[i]; 24baa3858d3f5d128a5c8466b700098109edcad5f2repo sync bindPair.InIndex = (UInt32)folder.BindPairs[i].InIndex; 25baa3858d3f5d128a5c8466b700098109edcad5f2repo sync bindPair.OutIndex = (UInt32)folder.BindPairs[i].OutIndex; 26baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 27cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky 28cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky bindInfo.Coders.ClearAndSetSize(folder.Coders.Size()); 29cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky bindInfo.CoderMethodIDs.ClearAndSetSize(folder.Coders.Size()); 30cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky 31baa3858d3f5d128a5c8466b700098109edcad5f2repo sync UInt32 outStreamIndex = 0; 32baa3858d3f5d128a5c8466b700098109edcad5f2repo sync for (i = 0; i < folder.Coders.Size(); i++) 33baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 34cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky NCoderMixer::CCoderStreamsInfo &coderStreamsInfo = bindInfo.Coders[i]; 35baa3858d3f5d128a5c8466b700098109edcad5f2repo sync const CCoderInfo &coderInfo = folder.Coders[i]; 36baa3858d3f5d128a5c8466b700098109edcad5f2repo sync coderStreamsInfo.NumInStreams = (UInt32)coderInfo.NumInStreams; 37baa3858d3f5d128a5c8466b700098109edcad5f2repo sync coderStreamsInfo.NumOutStreams = (UInt32)coderInfo.NumOutStreams; 38cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky bindInfo.CoderMethodIDs[i] = coderInfo.MethodID; 39baa3858d3f5d128a5c8466b700098109edcad5f2repo sync for (UInt32 j = 0; j < coderStreamsInfo.NumOutStreams; j++, outStreamIndex++) 40baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (folder.FindBindPairForOutStream(outStreamIndex) < 0) 41baa3858d3f5d128a5c8466b700098109edcad5f2repo sync bindInfo.OutStreams.Add(outStreamIndex); 42baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 43cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky bindInfo.InStreams.ClearAndSetSize(folder.PackStreams.Size()); 44baa3858d3f5d128a5c8466b700098109edcad5f2repo sync for (i = 0; i < folder.PackStreams.Size(); i++) 45cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky bindInfo.InStreams[i] = (UInt32)folder.PackStreams[i]; 46baa3858d3f5d128a5c8466b700098109edcad5f2repo sync} 47baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 48baa3858d3f5d128a5c8466b700098109edcad5f2repo syncstatic bool AreCodersEqual(const NCoderMixer::CCoderStreamsInfo &a1, 49baa3858d3f5d128a5c8466b700098109edcad5f2repo sync const NCoderMixer::CCoderStreamsInfo &a2) 50baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{ 51baa3858d3f5d128a5c8466b700098109edcad5f2repo sync return (a1.NumInStreams == a2.NumInStreams) && 52baa3858d3f5d128a5c8466b700098109edcad5f2repo sync (a1.NumOutStreams == a2.NumOutStreams); 53baa3858d3f5d128a5c8466b700098109edcad5f2repo sync} 54baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 55baa3858d3f5d128a5c8466b700098109edcad5f2repo syncstatic bool AreBindPairsEqual(const NCoderMixer::CBindPair &a1, const NCoderMixer::CBindPair &a2) 56baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{ 57baa3858d3f5d128a5c8466b700098109edcad5f2repo sync return (a1.InIndex == a2.InIndex) && 58baa3858d3f5d128a5c8466b700098109edcad5f2repo sync (a1.OutIndex == a2.OutIndex); 59baa3858d3f5d128a5c8466b700098109edcad5f2repo sync} 60baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 61baa3858d3f5d128a5c8466b700098109edcad5f2repo syncstatic bool AreBindInfoExEqual(const CBindInfoEx &a1, const CBindInfoEx &a2) 62baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{ 63baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (a1.Coders.Size() != a2.Coders.Size()) 64baa3858d3f5d128a5c8466b700098109edcad5f2repo sync return false; 65cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky unsigned i; 66baa3858d3f5d128a5c8466b700098109edcad5f2repo sync for (i = 0; i < a1.Coders.Size(); i++) 67baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (!AreCodersEqual(a1.Coders[i], a2.Coders[i])) 68baa3858d3f5d128a5c8466b700098109edcad5f2repo sync return false; 69baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (a1.BindPairs.Size() != a2.BindPairs.Size()) 70baa3858d3f5d128a5c8466b700098109edcad5f2repo sync return false; 71baa3858d3f5d128a5c8466b700098109edcad5f2repo sync for (i = 0; i < a1.BindPairs.Size(); i++) 72baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (!AreBindPairsEqual(a1.BindPairs[i], a2.BindPairs[i])) 73baa3858d3f5d128a5c8466b700098109edcad5f2repo sync return false; 74baa3858d3f5d128a5c8466b700098109edcad5f2repo sync for (i = 0; i < a1.CoderMethodIDs.Size(); i++) 75baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (a1.CoderMethodIDs[i] != a2.CoderMethodIDs[i]) 76baa3858d3f5d128a5c8466b700098109edcad5f2repo sync return false; 77baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (a1.InStreams.Size() != a2.InStreams.Size()) 78baa3858d3f5d128a5c8466b700098109edcad5f2repo sync return false; 79baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (a1.OutStreams.Size() != a2.OutStreams.Size()) 80baa3858d3f5d128a5c8466b700098109edcad5f2repo sync return false; 81baa3858d3f5d128a5c8466b700098109edcad5f2repo sync return true; 82baa3858d3f5d128a5c8466b700098109edcad5f2repo sync} 83baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 84baa3858d3f5d128a5c8466b700098109edcad5f2repo syncCDecoder::CDecoder(bool multiThread) 85baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{ 86baa3858d3f5d128a5c8466b700098109edcad5f2repo sync #ifndef _ST_MODE 87baa3858d3f5d128a5c8466b700098109edcad5f2repo sync multiThread = true; 88baa3858d3f5d128a5c8466b700098109edcad5f2repo sync #endif 89baa3858d3f5d128a5c8466b700098109edcad5f2repo sync _multiThread = multiThread; 90baa3858d3f5d128a5c8466b700098109edcad5f2repo sync _bindInfoExPrevIsDefined = false; 91baa3858d3f5d128a5c8466b700098109edcad5f2repo sync} 92baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 93baa3858d3f5d128a5c8466b700098109edcad5f2repo syncHRESULT CDecoder::Decode( 94baa3858d3f5d128a5c8466b700098109edcad5f2repo sync DECL_EXTERNAL_CODECS_LOC_VARS 95baa3858d3f5d128a5c8466b700098109edcad5f2repo sync IInStream *inStream, 96baa3858d3f5d128a5c8466b700098109edcad5f2repo sync UInt64 startPos, 97cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky const CFolders &folders, int folderIndex, 98baa3858d3f5d128a5c8466b700098109edcad5f2repo sync ISequentialOutStream *outStream, 99baa3858d3f5d128a5c8466b700098109edcad5f2repo sync ICompressProgressInfo *compressProgress 100cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky _7Z_DECODER_CRYPRO_VARS_DECL 101baa3858d3f5d128a5c8466b700098109edcad5f2repo sync #if !defined(_7ZIP_ST) && !defined(_SFX) 102baa3858d3f5d128a5c8466b700098109edcad5f2repo sync , bool mtMode, UInt32 numThreads 103baa3858d3f5d128a5c8466b700098109edcad5f2repo sync #endif 104baa3858d3f5d128a5c8466b700098109edcad5f2repo sync ) 105baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{ 106cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky const UInt64 *packPositions = &folders.PackPositions[folders.FoStartPackStreamIndex[folderIndex]]; 107cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky CFolder folderInfo; 108cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky folders.ParseFolderInfo(folderIndex, folderInfo); 109cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky 110cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky if (!folderInfo.CheckStructure(folders.GetNumFolderUnpackSizes(folderIndex))) 111baa3858d3f5d128a5c8466b700098109edcad5f2repo sync return E_NOTIMPL; 112cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky 113cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky /* 114cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky We don't need to init isEncrypted and passwordIsDefined 115cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky We must upgrade them only 116baa3858d3f5d128a5c8466b700098109edcad5f2repo sync #ifndef _NO_CRYPTO 117cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky isEncrypted = false; 118baa3858d3f5d128a5c8466b700098109edcad5f2repo sync passwordIsDefined = false; 119baa3858d3f5d128a5c8466b700098109edcad5f2repo sync #endif 120cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky */ 121cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky 122baa3858d3f5d128a5c8466b700098109edcad5f2repo sync CObjectVector< CMyComPtr<ISequentialInStream> > inStreams; 123baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 124baa3858d3f5d128a5c8466b700098109edcad5f2repo sync CLockedInStream lockedInStream; 125baa3858d3f5d128a5c8466b700098109edcad5f2repo sync lockedInStream.Init(inStream); 126baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 127cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky for (unsigned j = 0; j < folderInfo.PackStreams.Size(); j++) 128baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 129cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky CLockedSequentialInStreamImp *lockedStreamImpSpec = new CLockedSequentialInStreamImp; 130baa3858d3f5d128a5c8466b700098109edcad5f2repo sync CMyComPtr<ISequentialInStream> lockedStreamImp = lockedStreamImpSpec; 131cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky lockedStreamImpSpec->Init(&lockedInStream, startPos + packPositions[j]); 132cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky CLimitedSequentialInStream *streamSpec = new CLimitedSequentialInStream; 133baa3858d3f5d128a5c8466b700098109edcad5f2repo sync CMyComPtr<ISequentialInStream> inStream = streamSpec; 134baa3858d3f5d128a5c8466b700098109edcad5f2repo sync streamSpec->SetStream(lockedStreamImp); 135cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky streamSpec->Init(packPositions[j + 1] - packPositions[j]); 136baa3858d3f5d128a5c8466b700098109edcad5f2repo sync inStreams.Add(inStream); 137baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 138baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 139cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky unsigned numCoders = folderInfo.Coders.Size(); 140baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 141baa3858d3f5d128a5c8466b700098109edcad5f2repo sync CBindInfoEx bindInfo; 142baa3858d3f5d128a5c8466b700098109edcad5f2repo sync ConvertFolderItemInfoToBindInfo(folderInfo, bindInfo); 143baa3858d3f5d128a5c8466b700098109edcad5f2repo sync bool createNewCoders; 144baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (!_bindInfoExPrevIsDefined) 145baa3858d3f5d128a5c8466b700098109edcad5f2repo sync createNewCoders = true; 146baa3858d3f5d128a5c8466b700098109edcad5f2repo sync else 147baa3858d3f5d128a5c8466b700098109edcad5f2repo sync createNewCoders = !AreBindInfoExEqual(bindInfo, _bindInfoExPrev); 148baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (createNewCoders) 149baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 150cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky unsigned i; 151baa3858d3f5d128a5c8466b700098109edcad5f2repo sync _decoders.Clear(); 152baa3858d3f5d128a5c8466b700098109edcad5f2repo sync // _decoders2.Clear(); 153baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 154baa3858d3f5d128a5c8466b700098109edcad5f2repo sync _mixerCoder.Release(); 155baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 156baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (_multiThread) 157baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 158baa3858d3f5d128a5c8466b700098109edcad5f2repo sync _mixerCoderMTSpec = new NCoderMixer::CCoderMixer2MT; 159baa3858d3f5d128a5c8466b700098109edcad5f2repo sync _mixerCoder = _mixerCoderMTSpec; 160baa3858d3f5d128a5c8466b700098109edcad5f2repo sync _mixerCoderCommon = _mixerCoderMTSpec; 161baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 162baa3858d3f5d128a5c8466b700098109edcad5f2repo sync else 163baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 164baa3858d3f5d128a5c8466b700098109edcad5f2repo sync #ifdef _ST_MODE 165baa3858d3f5d128a5c8466b700098109edcad5f2repo sync _mixerCoderSTSpec = new NCoderMixer::CCoderMixer2ST; 166baa3858d3f5d128a5c8466b700098109edcad5f2repo sync _mixerCoder = _mixerCoderSTSpec; 167baa3858d3f5d128a5c8466b700098109edcad5f2repo sync _mixerCoderCommon = _mixerCoderSTSpec; 168baa3858d3f5d128a5c8466b700098109edcad5f2repo sync #endif 169baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 170baa3858d3f5d128a5c8466b700098109edcad5f2repo sync RINOK(_mixerCoderCommon->SetBindInfo(bindInfo)); 171baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 172baa3858d3f5d128a5c8466b700098109edcad5f2repo sync for (i = 0; i < numCoders; i++) 173baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 174baa3858d3f5d128a5c8466b700098109edcad5f2repo sync const CCoderInfo &coderInfo = folderInfo.Coders[i]; 175baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 176baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 177baa3858d3f5d128a5c8466b700098109edcad5f2repo sync CMyComPtr<ICompressCoder> decoder; 178baa3858d3f5d128a5c8466b700098109edcad5f2repo sync CMyComPtr<ICompressCoder2> decoder2; 179baa3858d3f5d128a5c8466b700098109edcad5f2repo sync RINOK(CreateCoder( 180baa3858d3f5d128a5c8466b700098109edcad5f2repo sync EXTERNAL_CODECS_LOC_VARS 181baa3858d3f5d128a5c8466b700098109edcad5f2repo sync coderInfo.MethodID, decoder, decoder2, false)); 182baa3858d3f5d128a5c8466b700098109edcad5f2repo sync CMyComPtr<IUnknown> decoderUnknown; 183baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (coderInfo.IsSimpleCoder()) 184baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 185baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (decoder == 0) 186baa3858d3f5d128a5c8466b700098109edcad5f2repo sync return E_NOTIMPL; 187baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 188baa3858d3f5d128a5c8466b700098109edcad5f2repo sync decoderUnknown = (IUnknown *)decoder; 189baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 190baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (_multiThread) 191baa3858d3f5d128a5c8466b700098109edcad5f2repo sync _mixerCoderMTSpec->AddCoder(decoder); 192baa3858d3f5d128a5c8466b700098109edcad5f2repo sync #ifdef _ST_MODE 193baa3858d3f5d128a5c8466b700098109edcad5f2repo sync else 194baa3858d3f5d128a5c8466b700098109edcad5f2repo sync _mixerCoderSTSpec->AddCoder(decoder, false); 195baa3858d3f5d128a5c8466b700098109edcad5f2repo sync #endif 196baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 197baa3858d3f5d128a5c8466b700098109edcad5f2repo sync else 198baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 199baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (decoder2 == 0) 200baa3858d3f5d128a5c8466b700098109edcad5f2repo sync return E_NOTIMPL; 201baa3858d3f5d128a5c8466b700098109edcad5f2repo sync decoderUnknown = (IUnknown *)decoder2; 202baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (_multiThread) 203baa3858d3f5d128a5c8466b700098109edcad5f2repo sync _mixerCoderMTSpec->AddCoder2(decoder2); 204baa3858d3f5d128a5c8466b700098109edcad5f2repo sync #ifdef _ST_MODE 205baa3858d3f5d128a5c8466b700098109edcad5f2repo sync else 206baa3858d3f5d128a5c8466b700098109edcad5f2repo sync _mixerCoderSTSpec->AddCoder2(decoder2, false); 207baa3858d3f5d128a5c8466b700098109edcad5f2repo sync #endif 208baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 209baa3858d3f5d128a5c8466b700098109edcad5f2repo sync _decoders.Add(decoderUnknown); 210baa3858d3f5d128a5c8466b700098109edcad5f2repo sync #ifdef EXTERNAL_CODECS 211baa3858d3f5d128a5c8466b700098109edcad5f2repo sync CMyComPtr<ISetCompressCodecsInfo> setCompressCodecsInfo; 212baa3858d3f5d128a5c8466b700098109edcad5f2repo sync decoderUnknown.QueryInterface(IID_ISetCompressCodecsInfo, (void **)&setCompressCodecsInfo); 213baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (setCompressCodecsInfo) 214baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 215cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky RINOK(setCompressCodecsInfo->SetCompressCodecsInfo(__externalCodecs->GetCodecs)); 216baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 217baa3858d3f5d128a5c8466b700098109edcad5f2repo sync #endif 218baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 219baa3858d3f5d128a5c8466b700098109edcad5f2repo sync _bindInfoExPrev = bindInfo; 220baa3858d3f5d128a5c8466b700098109edcad5f2repo sync _bindInfoExPrevIsDefined = true; 221baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 222cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky unsigned i; 223baa3858d3f5d128a5c8466b700098109edcad5f2repo sync _mixerCoderCommon->ReInit(); 224baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 225cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky UInt32 packStreamIndex = 0; 226cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky UInt32 unpackStreamIndexStart = folders.FoToCoderUnpackSizes[folderIndex]; 227cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky UInt32 unpackStreamIndex = unpackStreamIndexStart; 228baa3858d3f5d128a5c8466b700098109edcad5f2repo sync UInt32 coderIndex = 0; 229baa3858d3f5d128a5c8466b700098109edcad5f2repo sync // UInt32 coder2Index = 0; 230baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 231baa3858d3f5d128a5c8466b700098109edcad5f2repo sync for (i = 0; i < numCoders; i++) 232baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 233baa3858d3f5d128a5c8466b700098109edcad5f2repo sync const CCoderInfo &coderInfo = folderInfo.Coders[i]; 234baa3858d3f5d128a5c8466b700098109edcad5f2repo sync CMyComPtr<IUnknown> &decoder = _decoders[coderIndex]; 235baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 236baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 237baa3858d3f5d128a5c8466b700098109edcad5f2repo sync CMyComPtr<ICompressSetDecoderProperties2> setDecoderProperties; 238baa3858d3f5d128a5c8466b700098109edcad5f2repo sync decoder.QueryInterface(IID_ICompressSetDecoderProperties2, &setDecoderProperties); 239baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (setDecoderProperties) 240baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 241baa3858d3f5d128a5c8466b700098109edcad5f2repo sync const CByteBuffer &props = coderInfo.Props; 242cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky size_t size = props.Size(); 243baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (size > 0xFFFFFFFF) 244baa3858d3f5d128a5c8466b700098109edcad5f2repo sync return E_NOTIMPL; 245baa3858d3f5d128a5c8466b700098109edcad5f2repo sync // if (size > 0) 246baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 247baa3858d3f5d128a5c8466b700098109edcad5f2repo sync RINOK(setDecoderProperties->SetDecoderProperties2((const Byte *)props, (UInt32)size)); 248baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 249baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 250baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 251baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 252baa3858d3f5d128a5c8466b700098109edcad5f2repo sync #if !defined(_7ZIP_ST) && !defined(_SFX) 253baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (mtMode) 254baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 255baa3858d3f5d128a5c8466b700098109edcad5f2repo sync CMyComPtr<ICompressSetCoderMt> setCoderMt; 256baa3858d3f5d128a5c8466b700098109edcad5f2repo sync decoder.QueryInterface(IID_ICompressSetCoderMt, &setCoderMt); 257baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (setCoderMt) 258baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 259baa3858d3f5d128a5c8466b700098109edcad5f2repo sync RINOK(setCoderMt->SetNumberOfThreads(numThreads)); 260baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 261baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 262baa3858d3f5d128a5c8466b700098109edcad5f2repo sync #endif 263baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 264baa3858d3f5d128a5c8466b700098109edcad5f2repo sync #ifndef _NO_CRYPTO 265baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 266baa3858d3f5d128a5c8466b700098109edcad5f2repo sync CMyComPtr<ICryptoSetPassword> cryptoSetPassword; 267baa3858d3f5d128a5c8466b700098109edcad5f2repo sync decoder.QueryInterface(IID_ICryptoSetPassword, &cryptoSetPassword); 268baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (cryptoSetPassword) 269baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 270cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky isEncrypted = true; 271cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky if (!getTextPassword) 272cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky return E_NOTIMPL; 273baa3858d3f5d128a5c8466b700098109edcad5f2repo sync CMyComBSTR passwordBSTR; 274baa3858d3f5d128a5c8466b700098109edcad5f2repo sync RINOK(getTextPassword->CryptoGetTextPassword(&passwordBSTR)); 275baa3858d3f5d128a5c8466b700098109edcad5f2repo sync passwordIsDefined = true; 276cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky size_t len = 0; 277cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky if (passwordBSTR) 278cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky len = MyStringLen((BSTR)passwordBSTR); 279cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky CByteBuffer buffer(len * 2); 280cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky for (size_t i = 0; i < len; i++) 281baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 282cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky wchar_t c = passwordBSTR[i]; 283baa3858d3f5d128a5c8466b700098109edcad5f2repo sync ((Byte *)buffer)[i * 2] = (Byte)c; 284baa3858d3f5d128a5c8466b700098109edcad5f2repo sync ((Byte *)buffer)[i * 2 + 1] = (Byte)(c >> 8); 285baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 286cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky RINOK(cryptoSetPassword->CryptoSetPassword((const Byte *)buffer, (UInt32)buffer.Size())); 287baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 288baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 289baa3858d3f5d128a5c8466b700098109edcad5f2repo sync #endif 290baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 291baa3858d3f5d128a5c8466b700098109edcad5f2repo sync coderIndex++; 292baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 293baa3858d3f5d128a5c8466b700098109edcad5f2repo sync UInt32 numInStreams = (UInt32)coderInfo.NumInStreams; 294baa3858d3f5d128a5c8466b700098109edcad5f2repo sync UInt32 numOutStreams = (UInt32)coderInfo.NumOutStreams; 295cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky CObjArray<UInt64> packSizes(numInStreams); 296cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky CObjArray<const UInt64 *> packSizesPointers(numInStreams); 297cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky CObjArray<const UInt64 *> unpackSizesPointers(numOutStreams); 298baa3858d3f5d128a5c8466b700098109edcad5f2repo sync UInt32 j; 299cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky 300baa3858d3f5d128a5c8466b700098109edcad5f2repo sync for (j = 0; j < numOutStreams; j++, unpackStreamIndex++) 301cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky unpackSizesPointers[j] = &folders.CoderUnpackSizes[unpackStreamIndex]; 302baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 303baa3858d3f5d128a5c8466b700098109edcad5f2repo sync for (j = 0; j < numInStreams; j++, packStreamIndex++) 304baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 305baa3858d3f5d128a5c8466b700098109edcad5f2repo sync int bindPairIndex = folderInfo.FindBindPairForInStream(packStreamIndex); 306baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (bindPairIndex >= 0) 307cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky packSizesPointers[j] = &folders.CoderUnpackSizes[unpackStreamIndexStart + (UInt32)folderInfo.BindPairs[bindPairIndex].OutIndex]; 308baa3858d3f5d128a5c8466b700098109edcad5f2repo sync else 309baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 310baa3858d3f5d128a5c8466b700098109edcad5f2repo sync int index = folderInfo.FindPackStreamArrayIndex(packStreamIndex); 311baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (index < 0) 312cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky return S_FALSE; // check it 313cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky packSizes[j] = packPositions[index + 1] - packPositions[index]; 314cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky packSizesPointers[j] = &packSizes[j]; 315baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 316baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 317baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 318cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky _mixerCoderCommon->SetCoderInfo(i, packSizesPointers, unpackSizesPointers); 319baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 320baa3858d3f5d128a5c8466b700098109edcad5f2repo sync UInt32 mainCoder, temp; 321baa3858d3f5d128a5c8466b700098109edcad5f2repo sync bindInfo.FindOutStream(bindInfo.OutStreams[0], mainCoder, temp); 322baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 323baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (_multiThread) 324baa3858d3f5d128a5c8466b700098109edcad5f2repo sync _mixerCoderMTSpec->SetProgressCoderIndex(mainCoder); 325baa3858d3f5d128a5c8466b700098109edcad5f2repo sync /* 326baa3858d3f5d128a5c8466b700098109edcad5f2repo sync else 327baa3858d3f5d128a5c8466b700098109edcad5f2repo sync _mixerCoderSTSpec->SetProgressCoderIndex(mainCoder);; 328baa3858d3f5d128a5c8466b700098109edcad5f2repo sync */ 329baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 330baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (numCoders == 0) 331baa3858d3f5d128a5c8466b700098109edcad5f2repo sync return 0; 332cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky unsigned num = inStreams.Size(); 333cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky CObjArray<ISequentialInStream *> inStreamPointers(num); 334cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky for (i = 0; i < num; i++) 335cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky inStreamPointers[i] = inStreams[i]; 336baa3858d3f5d128a5c8466b700098109edcad5f2repo sync ISequentialOutStream *outStreamPointer = outStream; 337cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky return _mixerCoder->Code( 338cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky inStreamPointers, NULL, num, 339cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky &outStreamPointer, NULL, 1, 340cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky compressProgress); 341baa3858d3f5d128a5c8466b700098109edcad5f2repo sync} 342baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 343baa3858d3f5d128a5c8466b700098109edcad5f2repo sync}} 344