HRESULT CDecoder::Code(const CHeader &header, ISequentialOutStream *outStream, ICompressProgressInfo *progress) { if (header.FilterID > 1) return E_NOTIMPL; { CMyComPtr<ICompressSetDecoderProperties2> setDecoderProperties; _lzmaDecoder.QueryInterface(IID_ICompressSetDecoderProperties2, &setDecoderProperties); if (!setDecoderProperties) return E_NOTIMPL; RINOK(setDecoderProperties->SetDecoderProperties2(header.LzmaProps, 5)); } CMyComPtr<ICompressSetOutStream> setOutStream; bool filteredMode = (header.FilterID == 1); if (filteredMode) { _bcjStream.QueryInterface(IID_ICompressSetOutStream, &setOutStream); if (!setOutStream) return E_NOTIMPL; RINOK(setOutStream->SetOutStream(outStream)); outStream = _bcjStream; } const UInt64 *Size = header.HasSize() ? &header.Size : NULL; HRESULT res = _lzmaDecoderSpec->CodeResume(outStream, Size, progress); if (filteredMode) { CMyComPtr<IOutStreamFlush> flush; _bcjStream.QueryInterface(IID_IOutStreamFlush, &flush); if (flush) { HRESULT res2 = flush->Flush(); if (res == S_OK) res = res2; } HRESULT res2 = setOutStream->ReleaseOutStream(); if (res == S_OK) res = res2; } RINOK(res); if (header.HasSize()) if (_lzmaDecoderSpec->GetOutputProcessedSize() != header.Size) return S_FALSE; return S_OK; }
HRESULT CCoderMixer2ST::GetOutStream( ISequentialOutStream **outStreams, const UInt64 **outSizes, UInt32 streamIndex, ISequentialOutStream **outStreamRes) { CMyComPtr<ISequentialOutStream> seqOutStream; int i; for(i = 0; i < _bindInfo.OutStreams.Size(); i++) if (_bindInfo.OutStreams[i] == streamIndex) { seqOutStream = outStreams[i]; *outStreamRes = seqOutStream.Detach(); return S_OK; } int binderIndex = _bindInfo.FindBinderForOutStream(streamIndex); if (binderIndex < 0) return E_INVALIDARG; UInt32 coderIndex, coderStreamIndex; _bindInfo.FindInStream(_bindInfo.BindPairs[binderIndex].InIndex, coderIndex, coderStreamIndex); CCoderInfo &coder = _coders[coderIndex]; if (!coder.Coder) return E_NOTIMPL; coder.Coder.QueryInterface(IID_ISequentialOutStream, &seqOutStream); if (!seqOutStream) return E_NOTIMPL; UInt32 startIndex = _bindInfo.GetCoderOutStreamIndex(coderIndex); CMyComPtr<ICompressSetOutStream> setOutStream; if (!coder.Coder) return E_NOTIMPL; coder.Coder.QueryInterface(IID_ICompressSetOutStream, &setOutStream); if (!setOutStream) return E_NOTIMPL; if (coder.NumOutStreams > 1) return E_NOTIMPL; for (i = 0; i < (int)coder.NumOutStreams; i++) { CMyComPtr<ISequentialOutStream> seqOutStream2; RINOK(GetOutStream(outStreams, outSizes, startIndex + i, &seqOutStream2)); RINOK(setOutStream->SetOutStream(seqOutStream2)); } *outStreamRes = seqOutStream.Detach(); return S_OK; }