1*f6dc9357SAndroid Build Coastguard Worker // 7zDecode.cpp 2*f6dc9357SAndroid Build Coastguard Worker 3*f6dc9357SAndroid Build Coastguard Worker #include "StdAfx.h" 4*f6dc9357SAndroid Build Coastguard Worker 5*f6dc9357SAndroid Build Coastguard Worker #include "../../Common/LimitedStreams.h" 6*f6dc9357SAndroid Build Coastguard Worker #include "../../Common/ProgressUtils.h" 7*f6dc9357SAndroid Build Coastguard Worker #include "../../Common/StreamObjects.h" 8*f6dc9357SAndroid Build Coastguard Worker #include "../../Common/StreamUtils.h" 9*f6dc9357SAndroid Build Coastguard Worker 10*f6dc9357SAndroid Build Coastguard Worker #include "7zDecode.h" 11*f6dc9357SAndroid Build Coastguard Worker 12*f6dc9357SAndroid Build Coastguard Worker namespace NArchive { 13*f6dc9357SAndroid Build Coastguard Worker namespace N7z { 14*f6dc9357SAndroid Build Coastguard Worker 15*f6dc9357SAndroid Build Coastguard Worker Z7_CLASS_IMP_COM_1( 16*f6dc9357SAndroid Build Coastguard Worker CDecProgress 17*f6dc9357SAndroid Build Coastguard Worker , ICompressProgressInfo 18*f6dc9357SAndroid Build Coastguard Worker ) 19*f6dc9357SAndroid Build Coastguard Worker CMyComPtr<ICompressProgressInfo> _progress; 20*f6dc9357SAndroid Build Coastguard Worker public: 21*f6dc9357SAndroid Build Coastguard Worker CDecProgress(ICompressProgressInfo *progress): _progress(progress) {} 22*f6dc9357SAndroid Build Coastguard Worker }; 23*f6dc9357SAndroid Build Coastguard Worker 24*f6dc9357SAndroid Build Coastguard Worker Z7_COM7F_IMF(CDecProgress::SetRatioInfo(const UInt64 * /* inSize */, const UInt64 *outSize)) 25*f6dc9357SAndroid Build Coastguard Worker { 26*f6dc9357SAndroid Build Coastguard Worker return _progress->SetRatioInfo(NULL, outSize); 27*f6dc9357SAndroid Build Coastguard Worker } 28*f6dc9357SAndroid Build Coastguard Worker 29*f6dc9357SAndroid Build Coastguard Worker static void Convert_FolderInfo_to_BindInfo(const CFolderEx &folder, CBindInfoEx &bi) 30*f6dc9357SAndroid Build Coastguard Worker { 31*f6dc9357SAndroid Build Coastguard Worker bi.Clear(); 32*f6dc9357SAndroid Build Coastguard Worker 33*f6dc9357SAndroid Build Coastguard Worker bi.Bonds.ClearAndSetSize(folder.Bonds.Size()); 34*f6dc9357SAndroid Build Coastguard Worker unsigned i; 35*f6dc9357SAndroid Build Coastguard Worker for (i = 0; i < folder.Bonds.Size(); i++) 36*f6dc9357SAndroid Build Coastguard Worker { 37*f6dc9357SAndroid Build Coastguard Worker NCoderMixer2::CBond &bond = bi.Bonds[i]; 38*f6dc9357SAndroid Build Coastguard Worker const N7z::CBond &folderBond = folder.Bonds[i]; 39*f6dc9357SAndroid Build Coastguard Worker bond.PackIndex = folderBond.PackIndex; 40*f6dc9357SAndroid Build Coastguard Worker bond.UnpackIndex = folderBond.UnpackIndex; 41*f6dc9357SAndroid Build Coastguard Worker } 42*f6dc9357SAndroid Build Coastguard Worker 43*f6dc9357SAndroid Build Coastguard Worker bi.Coders.ClearAndSetSize(folder.Coders.Size()); 44*f6dc9357SAndroid Build Coastguard Worker bi.CoderMethodIDs.ClearAndSetSize(folder.Coders.Size()); 45*f6dc9357SAndroid Build Coastguard Worker for (i = 0; i < folder.Coders.Size(); i++) 46*f6dc9357SAndroid Build Coastguard Worker { 47*f6dc9357SAndroid Build Coastguard Worker const CCoderInfo &coderInfo = folder.Coders[i]; 48*f6dc9357SAndroid Build Coastguard Worker bi.Coders[i].NumStreams = coderInfo.NumStreams; 49*f6dc9357SAndroid Build Coastguard Worker bi.CoderMethodIDs[i] = coderInfo.MethodID; 50*f6dc9357SAndroid Build Coastguard Worker } 51*f6dc9357SAndroid Build Coastguard Worker 52*f6dc9357SAndroid Build Coastguard Worker /* 53*f6dc9357SAndroid Build Coastguard Worker if (!bi.SetUnpackCoder()) 54*f6dc9357SAndroid Build Coastguard Worker throw 1112; 55*f6dc9357SAndroid Build Coastguard Worker */ 56*f6dc9357SAndroid Build Coastguard Worker bi.UnpackCoder = folder.UnpackCoder; 57*f6dc9357SAndroid Build Coastguard Worker bi.PackStreams.ClearAndSetSize(folder.PackStreams.Size()); 58*f6dc9357SAndroid Build Coastguard Worker for (i = 0; i < folder.PackStreams.Size(); i++) 59*f6dc9357SAndroid Build Coastguard Worker bi.PackStreams[i] = folder.PackStreams[i]; 60*f6dc9357SAndroid Build Coastguard Worker } 61*f6dc9357SAndroid Build Coastguard Worker 62*f6dc9357SAndroid Build Coastguard Worker static inline bool AreCodersEqual( 63*f6dc9357SAndroid Build Coastguard Worker const NCoderMixer2::CCoderStreamsInfo &a1, 64*f6dc9357SAndroid Build Coastguard Worker const NCoderMixer2::CCoderStreamsInfo &a2) 65*f6dc9357SAndroid Build Coastguard Worker { 66*f6dc9357SAndroid Build Coastguard Worker return (a1.NumStreams == a2.NumStreams); 67*f6dc9357SAndroid Build Coastguard Worker } 68*f6dc9357SAndroid Build Coastguard Worker 69*f6dc9357SAndroid Build Coastguard Worker static inline bool AreBondsEqual( 70*f6dc9357SAndroid Build Coastguard Worker const NCoderMixer2::CBond &a1, 71*f6dc9357SAndroid Build Coastguard Worker const NCoderMixer2::CBond &a2) 72*f6dc9357SAndroid Build Coastguard Worker { 73*f6dc9357SAndroid Build Coastguard Worker return 74*f6dc9357SAndroid Build Coastguard Worker (a1.PackIndex == a2.PackIndex) && 75*f6dc9357SAndroid Build Coastguard Worker (a1.UnpackIndex == a2.UnpackIndex); 76*f6dc9357SAndroid Build Coastguard Worker } 77*f6dc9357SAndroid Build Coastguard Worker 78*f6dc9357SAndroid Build Coastguard Worker static bool AreBindInfoExEqual(const CBindInfoEx &a1, const CBindInfoEx &a2) 79*f6dc9357SAndroid Build Coastguard Worker { 80*f6dc9357SAndroid Build Coastguard Worker if (a1.Coders.Size() != a2.Coders.Size()) 81*f6dc9357SAndroid Build Coastguard Worker return false; 82*f6dc9357SAndroid Build Coastguard Worker unsigned i; 83*f6dc9357SAndroid Build Coastguard Worker for (i = 0; i < a1.Coders.Size(); i++) 84*f6dc9357SAndroid Build Coastguard Worker if (!AreCodersEqual(a1.Coders[i], a2.Coders[i])) 85*f6dc9357SAndroid Build Coastguard Worker return false; 86*f6dc9357SAndroid Build Coastguard Worker 87*f6dc9357SAndroid Build Coastguard Worker if (a1.Bonds.Size() != a2.Bonds.Size()) 88*f6dc9357SAndroid Build Coastguard Worker return false; 89*f6dc9357SAndroid Build Coastguard Worker for (i = 0; i < a1.Bonds.Size(); i++) 90*f6dc9357SAndroid Build Coastguard Worker if (!AreBondsEqual(a1.Bonds[i], a2.Bonds[i])) 91*f6dc9357SAndroid Build Coastguard Worker return false; 92*f6dc9357SAndroid Build Coastguard Worker 93*f6dc9357SAndroid Build Coastguard Worker for (i = 0; i < a1.CoderMethodIDs.Size(); i++) 94*f6dc9357SAndroid Build Coastguard Worker if (a1.CoderMethodIDs[i] != a2.CoderMethodIDs[i]) 95*f6dc9357SAndroid Build Coastguard Worker return false; 96*f6dc9357SAndroid Build Coastguard Worker 97*f6dc9357SAndroid Build Coastguard Worker if (a1.PackStreams.Size() != a2.PackStreams.Size()) 98*f6dc9357SAndroid Build Coastguard Worker return false; 99*f6dc9357SAndroid Build Coastguard Worker for (i = 0; i < a1.PackStreams.Size(); i++) 100*f6dc9357SAndroid Build Coastguard Worker if (a1.PackStreams[i] != a2.PackStreams[i]) 101*f6dc9357SAndroid Build Coastguard Worker return false; 102*f6dc9357SAndroid Build Coastguard Worker 103*f6dc9357SAndroid Build Coastguard Worker /* 104*f6dc9357SAndroid Build Coastguard Worker if (a1.UnpackCoder != a2.UnpackCoder) 105*f6dc9357SAndroid Build Coastguard Worker return false; 106*f6dc9357SAndroid Build Coastguard Worker */ 107*f6dc9357SAndroid Build Coastguard Worker return true; 108*f6dc9357SAndroid Build Coastguard Worker } 109*f6dc9357SAndroid Build Coastguard Worker 110*f6dc9357SAndroid Build Coastguard Worker CDecoder::CDecoder(bool useMixerMT): 111*f6dc9357SAndroid Build Coastguard Worker _bindInfoPrev_Defined(false) 112*f6dc9357SAndroid Build Coastguard Worker { 113*f6dc9357SAndroid Build Coastguard Worker #if defined(USE_MIXER_ST) && defined(USE_MIXER_MT) 114*f6dc9357SAndroid Build Coastguard Worker _useMixerMT = useMixerMT; 115*f6dc9357SAndroid Build Coastguard Worker #else 116*f6dc9357SAndroid Build Coastguard Worker UNUSED_VAR(useMixerMT) 117*f6dc9357SAndroid Build Coastguard Worker #endif 118*f6dc9357SAndroid Build Coastguard Worker } 119*f6dc9357SAndroid Build Coastguard Worker 120*f6dc9357SAndroid Build Coastguard Worker 121*f6dc9357SAndroid Build Coastguard Worker Z7_CLASS_IMP_COM_0( 122*f6dc9357SAndroid Build Coastguard Worker CLockedInStream 123*f6dc9357SAndroid Build Coastguard Worker ) 124*f6dc9357SAndroid Build Coastguard Worker public: 125*f6dc9357SAndroid Build Coastguard Worker CMyComPtr<IInStream> Stream; 126*f6dc9357SAndroid Build Coastguard Worker UInt64 Pos; 127*f6dc9357SAndroid Build Coastguard Worker 128*f6dc9357SAndroid Build Coastguard Worker #ifdef USE_MIXER_MT 129*f6dc9357SAndroid Build Coastguard Worker NWindows::NSynchronization::CCriticalSection CriticalSection; 130*f6dc9357SAndroid Build Coastguard Worker #endif 131*f6dc9357SAndroid Build Coastguard Worker }; 132*f6dc9357SAndroid Build Coastguard Worker 133*f6dc9357SAndroid Build Coastguard Worker 134*f6dc9357SAndroid Build Coastguard Worker #ifdef USE_MIXER_MT 135*f6dc9357SAndroid Build Coastguard Worker 136*f6dc9357SAndroid Build Coastguard Worker Z7_CLASS_IMP_COM_1( 137*f6dc9357SAndroid Build Coastguard Worker CLockedSequentialInStreamMT 138*f6dc9357SAndroid Build Coastguard Worker , ISequentialInStream 139*f6dc9357SAndroid Build Coastguard Worker ) 140*f6dc9357SAndroid Build Coastguard Worker CLockedInStream *_glob; 141*f6dc9357SAndroid Build Coastguard Worker UInt64 _pos; 142*f6dc9357SAndroid Build Coastguard Worker CMyComPtr<IUnknown> _globRef; 143*f6dc9357SAndroid Build Coastguard Worker public: 144*f6dc9357SAndroid Build Coastguard Worker void Init(CLockedInStream *lockedInStream, UInt64 startPos) 145*f6dc9357SAndroid Build Coastguard Worker { 146*f6dc9357SAndroid Build Coastguard Worker _globRef = lockedInStream; 147*f6dc9357SAndroid Build Coastguard Worker _glob = lockedInStream; 148*f6dc9357SAndroid Build Coastguard Worker _pos = startPos; 149*f6dc9357SAndroid Build Coastguard Worker } 150*f6dc9357SAndroid Build Coastguard Worker }; 151*f6dc9357SAndroid Build Coastguard Worker 152*f6dc9357SAndroid Build Coastguard Worker Z7_COM7F_IMF(CLockedSequentialInStreamMT::Read(void *data, UInt32 size, UInt32 *processedSize)) 153*f6dc9357SAndroid Build Coastguard Worker { 154*f6dc9357SAndroid Build Coastguard Worker NWindows::NSynchronization::CCriticalSectionLock lock(_glob->CriticalSection); 155*f6dc9357SAndroid Build Coastguard Worker 156*f6dc9357SAndroid Build Coastguard Worker if (_pos != _glob->Pos) 157*f6dc9357SAndroid Build Coastguard Worker { 158*f6dc9357SAndroid Build Coastguard Worker RINOK(InStream_SeekSet(_glob->Stream, _pos)) 159*f6dc9357SAndroid Build Coastguard Worker _glob->Pos = _pos; 160*f6dc9357SAndroid Build Coastguard Worker } 161*f6dc9357SAndroid Build Coastguard Worker 162*f6dc9357SAndroid Build Coastguard Worker UInt32 realProcessedSize = 0; 163*f6dc9357SAndroid Build Coastguard Worker const HRESULT res = _glob->Stream->Read(data, size, &realProcessedSize); 164*f6dc9357SAndroid Build Coastguard Worker _pos += realProcessedSize; 165*f6dc9357SAndroid Build Coastguard Worker _glob->Pos = _pos; 166*f6dc9357SAndroid Build Coastguard Worker if (processedSize) 167*f6dc9357SAndroid Build Coastguard Worker *processedSize = realProcessedSize; 168*f6dc9357SAndroid Build Coastguard Worker return res; 169*f6dc9357SAndroid Build Coastguard Worker } 170*f6dc9357SAndroid Build Coastguard Worker 171*f6dc9357SAndroid Build Coastguard Worker #endif 172*f6dc9357SAndroid Build Coastguard Worker 173*f6dc9357SAndroid Build Coastguard Worker 174*f6dc9357SAndroid Build Coastguard Worker #ifdef USE_MIXER_ST 175*f6dc9357SAndroid Build Coastguard Worker 176*f6dc9357SAndroid Build Coastguard Worker Z7_CLASS_IMP_COM_1( 177*f6dc9357SAndroid Build Coastguard Worker CLockedSequentialInStreamST 178*f6dc9357SAndroid Build Coastguard Worker , ISequentialInStream 179*f6dc9357SAndroid Build Coastguard Worker ) 180*f6dc9357SAndroid Build Coastguard Worker CLockedInStream *_glob; 181*f6dc9357SAndroid Build Coastguard Worker UInt64 _pos; 182*f6dc9357SAndroid Build Coastguard Worker CMyComPtr<IUnknown> _globRef; 183*f6dc9357SAndroid Build Coastguard Worker public: 184*f6dc9357SAndroid Build Coastguard Worker void Init(CLockedInStream *lockedInStream, UInt64 startPos) 185*f6dc9357SAndroid Build Coastguard Worker { 186*f6dc9357SAndroid Build Coastguard Worker _globRef = lockedInStream; 187*f6dc9357SAndroid Build Coastguard Worker _glob = lockedInStream; 188*f6dc9357SAndroid Build Coastguard Worker _pos = startPos; 189*f6dc9357SAndroid Build Coastguard Worker } 190*f6dc9357SAndroid Build Coastguard Worker }; 191*f6dc9357SAndroid Build Coastguard Worker 192*f6dc9357SAndroid Build Coastguard Worker Z7_COM7F_IMF(CLockedSequentialInStreamST::Read(void *data, UInt32 size, UInt32 *processedSize)) 193*f6dc9357SAndroid Build Coastguard Worker { 194*f6dc9357SAndroid Build Coastguard Worker if (_pos != _glob->Pos) 195*f6dc9357SAndroid Build Coastguard Worker { 196*f6dc9357SAndroid Build Coastguard Worker RINOK(InStream_SeekSet(_glob->Stream, _pos)) 197*f6dc9357SAndroid Build Coastguard Worker _glob->Pos = _pos; 198*f6dc9357SAndroid Build Coastguard Worker } 199*f6dc9357SAndroid Build Coastguard Worker 200*f6dc9357SAndroid Build Coastguard Worker UInt32 realProcessedSize = 0; 201*f6dc9357SAndroid Build Coastguard Worker const HRESULT res = _glob->Stream->Read(data, size, &realProcessedSize); 202*f6dc9357SAndroid Build Coastguard Worker _pos += realProcessedSize; 203*f6dc9357SAndroid Build Coastguard Worker _glob->Pos = _pos; 204*f6dc9357SAndroid Build Coastguard Worker if (processedSize) 205*f6dc9357SAndroid Build Coastguard Worker *processedSize = realProcessedSize; 206*f6dc9357SAndroid Build Coastguard Worker return res; 207*f6dc9357SAndroid Build Coastguard Worker } 208*f6dc9357SAndroid Build Coastguard Worker 209*f6dc9357SAndroid Build Coastguard Worker #endif 210*f6dc9357SAndroid Build Coastguard Worker 211*f6dc9357SAndroid Build Coastguard Worker 212*f6dc9357SAndroid Build Coastguard Worker 213*f6dc9357SAndroid Build Coastguard Worker HRESULT CDecoder::Decode( 214*f6dc9357SAndroid Build Coastguard Worker DECL_EXTERNAL_CODECS_LOC_VARS 215*f6dc9357SAndroid Build Coastguard Worker IInStream *inStream, 216*f6dc9357SAndroid Build Coastguard Worker UInt64 startPos, 217*f6dc9357SAndroid Build Coastguard Worker const CFolders &folders, unsigned folderIndex, 218*f6dc9357SAndroid Build Coastguard Worker const UInt64 *unpackSize 219*f6dc9357SAndroid Build Coastguard Worker 220*f6dc9357SAndroid Build Coastguard Worker , ISequentialOutStream *outStream 221*f6dc9357SAndroid Build Coastguard Worker , ICompressProgressInfo *compressProgress 222*f6dc9357SAndroid Build Coastguard Worker 223*f6dc9357SAndroid Build Coastguard Worker , ISequentialInStream ** 224*f6dc9357SAndroid Build Coastguard Worker #ifdef USE_MIXER_ST 225*f6dc9357SAndroid Build Coastguard Worker inStreamMainRes 226*f6dc9357SAndroid Build Coastguard Worker #endif 227*f6dc9357SAndroid Build Coastguard Worker 228*f6dc9357SAndroid Build Coastguard Worker , bool &dataAfterEnd_Error 229*f6dc9357SAndroid Build Coastguard Worker 230*f6dc9357SAndroid Build Coastguard Worker Z7_7Z_DECODER_CRYPRO_VARS_DECL 231*f6dc9357SAndroid Build Coastguard Worker 232*f6dc9357SAndroid Build Coastguard Worker #if !defined(Z7_ST) 233*f6dc9357SAndroid Build Coastguard Worker , bool mtMode, UInt32 numThreads, UInt64 memUsage 234*f6dc9357SAndroid Build Coastguard Worker #endif 235*f6dc9357SAndroid Build Coastguard Worker ) 236*f6dc9357SAndroid Build Coastguard Worker { 237*f6dc9357SAndroid Build Coastguard Worker dataAfterEnd_Error = false; 238*f6dc9357SAndroid Build Coastguard Worker 239*f6dc9357SAndroid Build Coastguard Worker const UInt64 *packPositions = &folders.PackPositions[folders.FoStartPackStreamIndex[folderIndex]]; 240*f6dc9357SAndroid Build Coastguard Worker CFolderEx folderInfo; 241*f6dc9357SAndroid Build Coastguard Worker folders.ParseFolderEx(folderIndex, folderInfo); 242*f6dc9357SAndroid Build Coastguard Worker 243*f6dc9357SAndroid Build Coastguard Worker if (!folderInfo.IsDecodingSupported()) 244*f6dc9357SAndroid Build Coastguard Worker return E_NOTIMPL; 245*f6dc9357SAndroid Build Coastguard Worker 246*f6dc9357SAndroid Build Coastguard Worker CBindInfoEx bindInfo; 247*f6dc9357SAndroid Build Coastguard Worker Convert_FolderInfo_to_BindInfo(folderInfo, bindInfo); 248*f6dc9357SAndroid Build Coastguard Worker if (!bindInfo.CalcMapsAndCheck()) 249*f6dc9357SAndroid Build Coastguard Worker return E_NOTIMPL; 250*f6dc9357SAndroid Build Coastguard Worker 251*f6dc9357SAndroid Build Coastguard Worker UInt64 folderUnpackSize = folders.GetFolderUnpackSize(folderIndex); 252*f6dc9357SAndroid Build Coastguard Worker bool fullUnpack = true; 253*f6dc9357SAndroid Build Coastguard Worker if (unpackSize) 254*f6dc9357SAndroid Build Coastguard Worker { 255*f6dc9357SAndroid Build Coastguard Worker if (*unpackSize > folderUnpackSize) 256*f6dc9357SAndroid Build Coastguard Worker return E_FAIL; 257*f6dc9357SAndroid Build Coastguard Worker fullUnpack = (*unpackSize == folderUnpackSize); 258*f6dc9357SAndroid Build Coastguard Worker } 259*f6dc9357SAndroid Build Coastguard Worker 260*f6dc9357SAndroid Build Coastguard Worker /* 261*f6dc9357SAndroid Build Coastguard Worker We don't need to init isEncrypted and passwordIsDefined 262*f6dc9357SAndroid Build Coastguard Worker We must upgrade them only 263*f6dc9357SAndroid Build Coastguard Worker 264*f6dc9357SAndroid Build Coastguard Worker #ifndef Z7_NO_CRYPTO 265*f6dc9357SAndroid Build Coastguard Worker isEncrypted = false; 266*f6dc9357SAndroid Build Coastguard Worker passwordIsDefined = false; 267*f6dc9357SAndroid Build Coastguard Worker #endif 268*f6dc9357SAndroid Build Coastguard Worker */ 269*f6dc9357SAndroid Build Coastguard Worker 270*f6dc9357SAndroid Build Coastguard Worker if (!_bindInfoPrev_Defined || !AreBindInfoExEqual(bindInfo, _bindInfoPrev)) 271*f6dc9357SAndroid Build Coastguard Worker { 272*f6dc9357SAndroid Build Coastguard Worker _bindInfoPrev_Defined = false; 273*f6dc9357SAndroid Build Coastguard Worker _mixerRef.Release(); 274*f6dc9357SAndroid Build Coastguard Worker 275*f6dc9357SAndroid Build Coastguard Worker #ifdef USE_MIXER_MT 276*f6dc9357SAndroid Build Coastguard Worker #ifdef USE_MIXER_ST 277*f6dc9357SAndroid Build Coastguard Worker if (_useMixerMT) 278*f6dc9357SAndroid Build Coastguard Worker #endif 279*f6dc9357SAndroid Build Coastguard Worker { 280*f6dc9357SAndroid Build Coastguard Worker _mixerMT = new NCoderMixer2::CMixerMT(false); 281*f6dc9357SAndroid Build Coastguard Worker _mixerRef = _mixerMT; 282*f6dc9357SAndroid Build Coastguard Worker _mixer = _mixerMT; 283*f6dc9357SAndroid Build Coastguard Worker } 284*f6dc9357SAndroid Build Coastguard Worker #ifdef USE_MIXER_ST 285*f6dc9357SAndroid Build Coastguard Worker else 286*f6dc9357SAndroid Build Coastguard Worker #endif 287*f6dc9357SAndroid Build Coastguard Worker #endif 288*f6dc9357SAndroid Build Coastguard Worker { 289*f6dc9357SAndroid Build Coastguard Worker #ifdef USE_MIXER_ST 290*f6dc9357SAndroid Build Coastguard Worker _mixerST = new NCoderMixer2::CMixerST(false); 291*f6dc9357SAndroid Build Coastguard Worker _mixerRef = _mixerST; 292*f6dc9357SAndroid Build Coastguard Worker _mixer = _mixerST; 293*f6dc9357SAndroid Build Coastguard Worker #endif 294*f6dc9357SAndroid Build Coastguard Worker } 295*f6dc9357SAndroid Build Coastguard Worker 296*f6dc9357SAndroid Build Coastguard Worker RINOK(_mixer->SetBindInfo(bindInfo)) 297*f6dc9357SAndroid Build Coastguard Worker 298*f6dc9357SAndroid Build Coastguard Worker FOR_VECTOR(i, folderInfo.Coders) 299*f6dc9357SAndroid Build Coastguard Worker { 300*f6dc9357SAndroid Build Coastguard Worker const CCoderInfo &coderInfo = folderInfo.Coders[i]; 301*f6dc9357SAndroid Build Coastguard Worker 302*f6dc9357SAndroid Build Coastguard Worker #ifndef Z7_SFX 303*f6dc9357SAndroid Build Coastguard Worker // we don't support RAR codecs here 304*f6dc9357SAndroid Build Coastguard Worker if ((coderInfo.MethodID >> 8) == 0x403) 305*f6dc9357SAndroid Build Coastguard Worker return E_NOTIMPL; 306*f6dc9357SAndroid Build Coastguard Worker #endif 307*f6dc9357SAndroid Build Coastguard Worker 308*f6dc9357SAndroid Build Coastguard Worker CCreatedCoder cod; 309*f6dc9357SAndroid Build Coastguard Worker RINOK(CreateCoder_Id( 310*f6dc9357SAndroid Build Coastguard Worker EXTERNAL_CODECS_LOC_VARS 311*f6dc9357SAndroid Build Coastguard Worker coderInfo.MethodID, false, cod)) 312*f6dc9357SAndroid Build Coastguard Worker 313*f6dc9357SAndroid Build Coastguard Worker if (coderInfo.IsSimpleCoder()) 314*f6dc9357SAndroid Build Coastguard Worker { 315*f6dc9357SAndroid Build Coastguard Worker if (!cod.Coder) 316*f6dc9357SAndroid Build Coastguard Worker return E_NOTIMPL; 317*f6dc9357SAndroid Build Coastguard Worker // CMethodId m = coderInfo.MethodID; 318*f6dc9357SAndroid Build Coastguard Worker // isFilter = (IsFilterMethod(m) || m == k_AES); 319*f6dc9357SAndroid Build Coastguard Worker } 320*f6dc9357SAndroid Build Coastguard Worker else 321*f6dc9357SAndroid Build Coastguard Worker { 322*f6dc9357SAndroid Build Coastguard Worker if (!cod.Coder2 || cod.NumStreams != coderInfo.NumStreams) 323*f6dc9357SAndroid Build Coastguard Worker return E_NOTIMPL; 324*f6dc9357SAndroid Build Coastguard Worker } 325*f6dc9357SAndroid Build Coastguard Worker _mixer->AddCoder(cod); 326*f6dc9357SAndroid Build Coastguard Worker 327*f6dc9357SAndroid Build Coastguard Worker // now there is no codec that uses another external codec 328*f6dc9357SAndroid Build Coastguard Worker /* 329*f6dc9357SAndroid Build Coastguard Worker #ifdef Z7_EXTERNAL_CODECS 330*f6dc9357SAndroid Build Coastguard Worker CMyComPtr<ISetCompressCodecsInfo> setCompressCodecsInfo; 331*f6dc9357SAndroid Build Coastguard Worker decoderUnknown.QueryInterface(IID_ISetCompressCodecsInfo, (void **)&setCompressCodecsInfo); 332*f6dc9357SAndroid Build Coastguard Worker if (setCompressCodecsInfo) 333*f6dc9357SAndroid Build Coastguard Worker { 334*f6dc9357SAndroid Build Coastguard Worker // we must use g_ExternalCodecs also 335*f6dc9357SAndroid Build Coastguard Worker RINOK(setCompressCodecsInfo->SetCompressCodecsInfo(_externalCodecs->GetCodecs)); 336*f6dc9357SAndroid Build Coastguard Worker } 337*f6dc9357SAndroid Build Coastguard Worker #endif 338*f6dc9357SAndroid Build Coastguard Worker */ 339*f6dc9357SAndroid Build Coastguard Worker } 340*f6dc9357SAndroid Build Coastguard Worker 341*f6dc9357SAndroid Build Coastguard Worker _bindInfoPrev = bindInfo; 342*f6dc9357SAndroid Build Coastguard Worker _bindInfoPrev_Defined = true; 343*f6dc9357SAndroid Build Coastguard Worker } 344*f6dc9357SAndroid Build Coastguard Worker 345*f6dc9357SAndroid Build Coastguard Worker RINOK(_mixer->ReInit2()) 346*f6dc9357SAndroid Build Coastguard Worker 347*f6dc9357SAndroid Build Coastguard Worker UInt32 packStreamIndex = 0; 348*f6dc9357SAndroid Build Coastguard Worker UInt32 unpackStreamIndexStart = folders.FoToCoderUnpackSizes[folderIndex]; 349*f6dc9357SAndroid Build Coastguard Worker 350*f6dc9357SAndroid Build Coastguard Worker unsigned i; 351*f6dc9357SAndroid Build Coastguard Worker 352*f6dc9357SAndroid Build Coastguard Worker #if !defined(Z7_ST) 353*f6dc9357SAndroid Build Coastguard Worker bool mt_wasUsed = false; 354*f6dc9357SAndroid Build Coastguard Worker #endif 355*f6dc9357SAndroid Build Coastguard Worker 356*f6dc9357SAndroid Build Coastguard Worker for (i = 0; i < folderInfo.Coders.Size(); i++) 357*f6dc9357SAndroid Build Coastguard Worker { 358*f6dc9357SAndroid Build Coastguard Worker const CCoderInfo &coderInfo = folderInfo.Coders[i]; 359*f6dc9357SAndroid Build Coastguard Worker IUnknown *decoder = _mixer->GetCoder(i).GetUnknown(); 360*f6dc9357SAndroid Build Coastguard Worker 361*f6dc9357SAndroid Build Coastguard Worker // now there is no codec that uses another external codec 362*f6dc9357SAndroid Build Coastguard Worker /* 363*f6dc9357SAndroid Build Coastguard Worker #ifdef Z7_EXTERNAL_CODECS 364*f6dc9357SAndroid Build Coastguard Worker { 365*f6dc9357SAndroid Build Coastguard Worker Z7_DECL_CMyComPtr_QI_FROM(ISetCompressCodecsInfo, 366*f6dc9357SAndroid Build Coastguard Worker setCompressCodecsInfo, decoder) 367*f6dc9357SAndroid Build Coastguard Worker if (setCompressCodecsInfo) 368*f6dc9357SAndroid Build Coastguard Worker { 369*f6dc9357SAndroid Build Coastguard Worker // we must use g_ExternalCodecs also 370*f6dc9357SAndroid Build Coastguard Worker RINOK(setCompressCodecsInfo->SetCompressCodecsInfo(_externalCodecs->GetCodecs)) 371*f6dc9357SAndroid Build Coastguard Worker } 372*f6dc9357SAndroid Build Coastguard Worker } 373*f6dc9357SAndroid Build Coastguard Worker #endif 374*f6dc9357SAndroid Build Coastguard Worker */ 375*f6dc9357SAndroid Build Coastguard Worker 376*f6dc9357SAndroid Build Coastguard Worker #if !defined(Z7_ST) 377*f6dc9357SAndroid Build Coastguard Worker if (!mt_wasUsed) 378*f6dc9357SAndroid Build Coastguard Worker { 379*f6dc9357SAndroid Build Coastguard Worker if (mtMode) 380*f6dc9357SAndroid Build Coastguard Worker { 381*f6dc9357SAndroid Build Coastguard Worker Z7_DECL_CMyComPtr_QI_FROM(ICompressSetCoderMt, 382*f6dc9357SAndroid Build Coastguard Worker setCoderMt, decoder) 383*f6dc9357SAndroid Build Coastguard Worker if (setCoderMt) 384*f6dc9357SAndroid Build Coastguard Worker { 385*f6dc9357SAndroid Build Coastguard Worker mt_wasUsed = true; 386*f6dc9357SAndroid Build Coastguard Worker RINOK(setCoderMt->SetNumberOfThreads(numThreads)) 387*f6dc9357SAndroid Build Coastguard Worker } 388*f6dc9357SAndroid Build Coastguard Worker } 389*f6dc9357SAndroid Build Coastguard Worker // if (memUsage != 0) 390*f6dc9357SAndroid Build Coastguard Worker { 391*f6dc9357SAndroid Build Coastguard Worker Z7_DECL_CMyComPtr_QI_FROM(ICompressSetMemLimit, 392*f6dc9357SAndroid Build Coastguard Worker setMemLimit, decoder) 393*f6dc9357SAndroid Build Coastguard Worker if (setMemLimit) 394*f6dc9357SAndroid Build Coastguard Worker { 395*f6dc9357SAndroid Build Coastguard Worker mt_wasUsed = true; 396*f6dc9357SAndroid Build Coastguard Worker RINOK(setMemLimit->SetMemLimit(memUsage)) 397*f6dc9357SAndroid Build Coastguard Worker } 398*f6dc9357SAndroid Build Coastguard Worker } 399*f6dc9357SAndroid Build Coastguard Worker } 400*f6dc9357SAndroid Build Coastguard Worker #endif 401*f6dc9357SAndroid Build Coastguard Worker 402*f6dc9357SAndroid Build Coastguard Worker { 403*f6dc9357SAndroid Build Coastguard Worker Z7_DECL_CMyComPtr_QI_FROM( 404*f6dc9357SAndroid Build Coastguard Worker ICompressSetDecoderProperties2, 405*f6dc9357SAndroid Build Coastguard Worker setDecoderProperties, decoder) 406*f6dc9357SAndroid Build Coastguard Worker const CByteBuffer &props = coderInfo.Props; 407*f6dc9357SAndroid Build Coastguard Worker const UInt32 size32 = (UInt32)props.Size(); 408*f6dc9357SAndroid Build Coastguard Worker if (props.Size() != size32) 409*f6dc9357SAndroid Build Coastguard Worker return E_NOTIMPL; 410*f6dc9357SAndroid Build Coastguard Worker if (setDecoderProperties) 411*f6dc9357SAndroid Build Coastguard Worker { 412*f6dc9357SAndroid Build Coastguard Worker HRESULT res = setDecoderProperties->SetDecoderProperties2((const Byte *)props, size32); 413*f6dc9357SAndroid Build Coastguard Worker if (res == E_INVALIDARG) 414*f6dc9357SAndroid Build Coastguard Worker res = E_NOTIMPL; 415*f6dc9357SAndroid Build Coastguard Worker RINOK(res) 416*f6dc9357SAndroid Build Coastguard Worker } 417*f6dc9357SAndroid Build Coastguard Worker else if (size32 != 0) 418*f6dc9357SAndroid Build Coastguard Worker { 419*f6dc9357SAndroid Build Coastguard Worker // v23: we fail, if decoder doesn't support properties 420*f6dc9357SAndroid Build Coastguard Worker return E_NOTIMPL; 421*f6dc9357SAndroid Build Coastguard Worker } 422*f6dc9357SAndroid Build Coastguard Worker } 423*f6dc9357SAndroid Build Coastguard Worker 424*f6dc9357SAndroid Build Coastguard Worker #ifndef Z7_NO_CRYPTO 425*f6dc9357SAndroid Build Coastguard Worker { 426*f6dc9357SAndroid Build Coastguard Worker Z7_DECL_CMyComPtr_QI_FROM( 427*f6dc9357SAndroid Build Coastguard Worker ICryptoSetPassword, 428*f6dc9357SAndroid Build Coastguard Worker cryptoSetPassword, decoder) 429*f6dc9357SAndroid Build Coastguard Worker if (cryptoSetPassword) 430*f6dc9357SAndroid Build Coastguard Worker { 431*f6dc9357SAndroid Build Coastguard Worker isEncrypted = true; 432*f6dc9357SAndroid Build Coastguard Worker if (!getTextPassword) 433*f6dc9357SAndroid Build Coastguard Worker return E_NOTIMPL; 434*f6dc9357SAndroid Build Coastguard Worker CMyComBSTR_Wipe passwordBSTR; 435*f6dc9357SAndroid Build Coastguard Worker RINOK(getTextPassword->CryptoGetTextPassword(&passwordBSTR)) 436*f6dc9357SAndroid Build Coastguard Worker passwordIsDefined = true; 437*f6dc9357SAndroid Build Coastguard Worker password.Wipe_and_Empty(); 438*f6dc9357SAndroid Build Coastguard Worker size_t len = 0; 439*f6dc9357SAndroid Build Coastguard Worker if (passwordBSTR) 440*f6dc9357SAndroid Build Coastguard Worker { 441*f6dc9357SAndroid Build Coastguard Worker password = passwordBSTR; 442*f6dc9357SAndroid Build Coastguard Worker len = password.Len(); 443*f6dc9357SAndroid Build Coastguard Worker } 444*f6dc9357SAndroid Build Coastguard Worker CByteBuffer_Wipe buffer(len * 2); 445*f6dc9357SAndroid Build Coastguard Worker const LPCOLESTR psw = passwordBSTR; 446*f6dc9357SAndroid Build Coastguard Worker for (size_t k = 0; k < len; k++) 447*f6dc9357SAndroid Build Coastguard Worker { 448*f6dc9357SAndroid Build Coastguard Worker const wchar_t c = psw[k]; 449*f6dc9357SAndroid Build Coastguard Worker ((Byte *)buffer)[k * 2] = (Byte)c; 450*f6dc9357SAndroid Build Coastguard Worker ((Byte *)buffer)[k * 2 + 1] = (Byte)(c >> 8); 451*f6dc9357SAndroid Build Coastguard Worker } 452*f6dc9357SAndroid Build Coastguard Worker RINOK(cryptoSetPassword->CryptoSetPassword((const Byte *)buffer, (UInt32)buffer.Size())) 453*f6dc9357SAndroid Build Coastguard Worker } 454*f6dc9357SAndroid Build Coastguard Worker } 455*f6dc9357SAndroid Build Coastguard Worker #endif 456*f6dc9357SAndroid Build Coastguard Worker 457*f6dc9357SAndroid Build Coastguard Worker bool finishMode = false; 458*f6dc9357SAndroid Build Coastguard Worker { 459*f6dc9357SAndroid Build Coastguard Worker Z7_DECL_CMyComPtr_QI_FROM( 460*f6dc9357SAndroid Build Coastguard Worker ICompressSetFinishMode, 461*f6dc9357SAndroid Build Coastguard Worker setFinishMode, decoder) 462*f6dc9357SAndroid Build Coastguard Worker if (setFinishMode) 463*f6dc9357SAndroid Build Coastguard Worker { 464*f6dc9357SAndroid Build Coastguard Worker finishMode = fullUnpack; 465*f6dc9357SAndroid Build Coastguard Worker RINOK(setFinishMode->SetFinishMode(BoolToUInt(finishMode))) 466*f6dc9357SAndroid Build Coastguard Worker } 467*f6dc9357SAndroid Build Coastguard Worker } 468*f6dc9357SAndroid Build Coastguard Worker 469*f6dc9357SAndroid Build Coastguard Worker UInt32 numStreams = (UInt32)coderInfo.NumStreams; 470*f6dc9357SAndroid Build Coastguard Worker 471*f6dc9357SAndroid Build Coastguard Worker CObjArray<UInt64> packSizes(numStreams); 472*f6dc9357SAndroid Build Coastguard Worker CObjArray<const UInt64 *> packSizesPointers(numStreams); 473*f6dc9357SAndroid Build Coastguard Worker 474*f6dc9357SAndroid Build Coastguard Worker for (UInt32 j = 0; j < numStreams; j++, packStreamIndex++) 475*f6dc9357SAndroid Build Coastguard Worker { 476*f6dc9357SAndroid Build Coastguard Worker int bond = folderInfo.FindBond_for_PackStream(packStreamIndex); 477*f6dc9357SAndroid Build Coastguard Worker 478*f6dc9357SAndroid Build Coastguard Worker if (bond >= 0) 479*f6dc9357SAndroid Build Coastguard Worker packSizesPointers[j] = &folders.CoderUnpackSizes[unpackStreamIndexStart + folderInfo.Bonds[(unsigned)bond].UnpackIndex]; 480*f6dc9357SAndroid Build Coastguard Worker else 481*f6dc9357SAndroid Build Coastguard Worker { 482*f6dc9357SAndroid Build Coastguard Worker int index = folderInfo.Find_in_PackStreams(packStreamIndex); 483*f6dc9357SAndroid Build Coastguard Worker if (index < 0) 484*f6dc9357SAndroid Build Coastguard Worker return E_NOTIMPL; 485*f6dc9357SAndroid Build Coastguard Worker packSizes[j] = packPositions[(unsigned)index + 1] - packPositions[(unsigned)index]; 486*f6dc9357SAndroid Build Coastguard Worker packSizesPointers[j] = &packSizes[j]; 487*f6dc9357SAndroid Build Coastguard Worker } 488*f6dc9357SAndroid Build Coastguard Worker } 489*f6dc9357SAndroid Build Coastguard Worker 490*f6dc9357SAndroid Build Coastguard Worker const UInt64 *unpackSizesPointer = 491*f6dc9357SAndroid Build Coastguard Worker (unpackSize && i == bindInfo.UnpackCoder) ? 492*f6dc9357SAndroid Build Coastguard Worker unpackSize : 493*f6dc9357SAndroid Build Coastguard Worker &folders.CoderUnpackSizes[unpackStreamIndexStart + i]; 494*f6dc9357SAndroid Build Coastguard Worker 495*f6dc9357SAndroid Build Coastguard Worker _mixer->SetCoderInfo(i, unpackSizesPointer, packSizesPointers, finishMode); 496*f6dc9357SAndroid Build Coastguard Worker } 497*f6dc9357SAndroid Build Coastguard Worker 498*f6dc9357SAndroid Build Coastguard Worker if (outStream) 499*f6dc9357SAndroid Build Coastguard Worker { 500*f6dc9357SAndroid Build Coastguard Worker _mixer->SelectMainCoder(!fullUnpack); 501*f6dc9357SAndroid Build Coastguard Worker } 502*f6dc9357SAndroid Build Coastguard Worker 503*f6dc9357SAndroid Build Coastguard Worker CObjectVector< CMyComPtr<ISequentialInStream> > inStreams; 504*f6dc9357SAndroid Build Coastguard Worker 505*f6dc9357SAndroid Build Coastguard Worker CMyComPtr2_Create<IUnknown, CLockedInStream> lockedInStream; 506*f6dc9357SAndroid Build Coastguard Worker 507*f6dc9357SAndroid Build Coastguard Worker #ifdef USE_MIXER_MT 508*f6dc9357SAndroid Build Coastguard Worker #ifdef USE_MIXER_ST 509*f6dc9357SAndroid Build Coastguard Worker bool needMtLock = _useMixerMT; 510*f6dc9357SAndroid Build Coastguard Worker #endif 511*f6dc9357SAndroid Build Coastguard Worker #endif 512*f6dc9357SAndroid Build Coastguard Worker 513*f6dc9357SAndroid Build Coastguard Worker if (folderInfo.PackStreams.Size() > 1) 514*f6dc9357SAndroid Build Coastguard Worker { 515*f6dc9357SAndroid Build Coastguard Worker // lockedInStream.Pos = (UInt64)(Int64)-1; 516*f6dc9357SAndroid Build Coastguard Worker // RINOK(InStream_GetPos(inStream, lockedInStream.Pos)) 517*f6dc9357SAndroid Build Coastguard Worker RINOK(inStream->Seek((Int64)(startPos + packPositions[0]), STREAM_SEEK_SET, &lockedInStream->Pos)) 518*f6dc9357SAndroid Build Coastguard Worker lockedInStream->Stream = inStream; 519*f6dc9357SAndroid Build Coastguard Worker 520*f6dc9357SAndroid Build Coastguard Worker #ifdef USE_MIXER_MT 521*f6dc9357SAndroid Build Coastguard Worker #ifdef USE_MIXER_ST 522*f6dc9357SAndroid Build Coastguard Worker /* 523*f6dc9357SAndroid Build Coastguard Worker For ST-mixer mode: 524*f6dc9357SAndroid Build Coastguard Worker If parallel input stream reading from pack streams is possible, 525*f6dc9357SAndroid Build Coastguard Worker we must use MT-lock for packed streams. 526*f6dc9357SAndroid Build Coastguard Worker Internal decoders in 7-Zip will not read pack streams in parallel in ST-mixer mode. 527*f6dc9357SAndroid Build Coastguard Worker So we force to needMtLock mode only if there is unknown (external) decoder. 528*f6dc9357SAndroid Build Coastguard Worker */ 529*f6dc9357SAndroid Build Coastguard Worker if (!needMtLock && _mixer->IsThere_ExternalCoder_in_PackTree(_mixer->MainCoderIndex)) 530*f6dc9357SAndroid Build Coastguard Worker needMtLock = true; 531*f6dc9357SAndroid Build Coastguard Worker #endif 532*f6dc9357SAndroid Build Coastguard Worker #endif 533*f6dc9357SAndroid Build Coastguard Worker } 534*f6dc9357SAndroid Build Coastguard Worker 535*f6dc9357SAndroid Build Coastguard Worker for (unsigned j = 0; j < folderInfo.PackStreams.Size(); j++) 536*f6dc9357SAndroid Build Coastguard Worker { 537*f6dc9357SAndroid Build Coastguard Worker CMyComPtr<ISequentialInStream> packStream; 538*f6dc9357SAndroid Build Coastguard Worker const UInt64 packPos = startPos + packPositions[j]; 539*f6dc9357SAndroid Build Coastguard Worker 540*f6dc9357SAndroid Build Coastguard Worker if (folderInfo.PackStreams.Size() == 1) 541*f6dc9357SAndroid Build Coastguard Worker { 542*f6dc9357SAndroid Build Coastguard Worker RINOK(InStream_SeekSet(inStream, packPos)) 543*f6dc9357SAndroid Build Coastguard Worker packStream = inStream; 544*f6dc9357SAndroid Build Coastguard Worker } 545*f6dc9357SAndroid Build Coastguard Worker else 546*f6dc9357SAndroid Build Coastguard Worker { 547*f6dc9357SAndroid Build Coastguard Worker #ifdef USE_MIXER_MT 548*f6dc9357SAndroid Build Coastguard Worker #ifdef USE_MIXER_ST 549*f6dc9357SAndroid Build Coastguard Worker if (needMtLock) 550*f6dc9357SAndroid Build Coastguard Worker #endif 551*f6dc9357SAndroid Build Coastguard Worker { 552*f6dc9357SAndroid Build Coastguard Worker CLockedSequentialInStreamMT *lockedStreamImpSpec = new CLockedSequentialInStreamMT; 553*f6dc9357SAndroid Build Coastguard Worker packStream = lockedStreamImpSpec; 554*f6dc9357SAndroid Build Coastguard Worker lockedStreamImpSpec->Init(lockedInStream.ClsPtr(), packPos); 555*f6dc9357SAndroid Build Coastguard Worker } 556*f6dc9357SAndroid Build Coastguard Worker #ifdef USE_MIXER_ST 557*f6dc9357SAndroid Build Coastguard Worker else 558*f6dc9357SAndroid Build Coastguard Worker #endif 559*f6dc9357SAndroid Build Coastguard Worker #endif 560*f6dc9357SAndroid Build Coastguard Worker { 561*f6dc9357SAndroid Build Coastguard Worker #ifdef USE_MIXER_ST 562*f6dc9357SAndroid Build Coastguard Worker CLockedSequentialInStreamST *lockedStreamImpSpec = new CLockedSequentialInStreamST; 563*f6dc9357SAndroid Build Coastguard Worker packStream = lockedStreamImpSpec; 564*f6dc9357SAndroid Build Coastguard Worker lockedStreamImpSpec->Init(lockedInStream.ClsPtr(), packPos); 565*f6dc9357SAndroid Build Coastguard Worker #endif 566*f6dc9357SAndroid Build Coastguard Worker } 567*f6dc9357SAndroid Build Coastguard Worker } 568*f6dc9357SAndroid Build Coastguard Worker 569*f6dc9357SAndroid Build Coastguard Worker CLimitedSequentialInStream *streamSpec = new CLimitedSequentialInStream; 570*f6dc9357SAndroid Build Coastguard Worker inStreams.AddNew() = streamSpec; 571*f6dc9357SAndroid Build Coastguard Worker streamSpec->SetStream(packStream); 572*f6dc9357SAndroid Build Coastguard Worker streamSpec->Init(packPositions[j + 1] - packPositions[j]); 573*f6dc9357SAndroid Build Coastguard Worker } 574*f6dc9357SAndroid Build Coastguard Worker 575*f6dc9357SAndroid Build Coastguard Worker const unsigned num = inStreams.Size(); 576*f6dc9357SAndroid Build Coastguard Worker CObjArray<ISequentialInStream *> inStreamPointers(num); 577*f6dc9357SAndroid Build Coastguard Worker for (i = 0; i < num; i++) 578*f6dc9357SAndroid Build Coastguard Worker inStreamPointers[i] = inStreams[i]; 579*f6dc9357SAndroid Build Coastguard Worker 580*f6dc9357SAndroid Build Coastguard Worker if (outStream) 581*f6dc9357SAndroid Build Coastguard Worker { 582*f6dc9357SAndroid Build Coastguard Worker CMyComPtr<ICompressProgressInfo> progress2; 583*f6dc9357SAndroid Build Coastguard Worker if (compressProgress && !_mixer->Is_PackSize_Correct_for_Coder(_mixer->MainCoderIndex)) 584*f6dc9357SAndroid Build Coastguard Worker progress2 = new CDecProgress(compressProgress); 585*f6dc9357SAndroid Build Coastguard Worker 586*f6dc9357SAndroid Build Coastguard Worker ISequentialOutStream *outStreamPointer = outStream; 587*f6dc9357SAndroid Build Coastguard Worker return _mixer->Code(inStreamPointers, &outStreamPointer, 588*f6dc9357SAndroid Build Coastguard Worker progress2 ? (ICompressProgressInfo *)progress2 : compressProgress, 589*f6dc9357SAndroid Build Coastguard Worker dataAfterEnd_Error); 590*f6dc9357SAndroid Build Coastguard Worker } 591*f6dc9357SAndroid Build Coastguard Worker 592*f6dc9357SAndroid Build Coastguard Worker #ifdef USE_MIXER_ST 593*f6dc9357SAndroid Build Coastguard Worker return _mixerST->GetMainUnpackStream(inStreamPointers, inStreamMainRes); 594*f6dc9357SAndroid Build Coastguard Worker #else 595*f6dc9357SAndroid Build Coastguard Worker return E_FAIL; 596*f6dc9357SAndroid Build Coastguard Worker #endif 597*f6dc9357SAndroid Build Coastguard Worker } 598*f6dc9357SAndroid Build Coastguard Worker 599*f6dc9357SAndroid Build Coastguard Worker }} 600