HRESULT CEncoder::Encode( DECL_EXTERNAL_CODECS_LOC_VARS ISequentialInStream *inStream, const UInt64 *inStreamSize, const UInt64 *inSizeForReduce, CFolder &folderItem, ISequentialOutStream *outStream, CRecordVector<UInt64> &packSizes, ICompressProgressInfo *compressProgress) { RINOK(EncoderConstr()); if (_mixerCoderSpec == NULL) { RINOK(CreateMixerCoder(EXTERNAL_CODECS_LOC_VARS inSizeForReduce)); } _mixerCoderSpec->ReInit(); // _mixerCoderSpec->SetCoderInfo(0, NULL, NULL, progress); CObjectVector<CInOutTempBuffer> inOutTempBuffers; CObjectVector<CSequentialOutTempBufferImp *> tempBufferSpecs; CObjectVector<CMyComPtr<ISequentialOutStream> > tempBuffers; int numMethods = _bindInfo.Coders.Size(); int i; for (i = 1; i < _bindInfo.OutStreams.Size(); i++) { inOutTempBuffers.Add(CInOutTempBuffer()); inOutTempBuffers.Back().Create(); inOutTempBuffers.Back().InitWriting(); } for (i = 1; i < _bindInfo.OutStreams.Size(); i++) { CSequentialOutTempBufferImp *tempBufferSpec = new CSequentialOutTempBufferImp; CMyComPtr<ISequentialOutStream> tempBuffer = tempBufferSpec; tempBufferSpec->Init(&inOutTempBuffers[i - 1]); tempBuffers.Add(tempBuffer); tempBufferSpecs.Add(tempBufferSpec); } for (i = 0; i < numMethods; i++) _mixerCoderSpec->SetCoderInfo(i, NULL, NULL); if (_bindInfo.InStreams.IsEmpty()) return E_FAIL; UInt32 mainCoderIndex, mainStreamIndex; _bindInfo.FindInStream(_bindInfo.InStreams[0], mainCoderIndex, mainStreamIndex); if (inStreamSize != NULL) { CRecordVector<const UInt64 *> sizePointers; for (UInt32 i = 0; i < _bindInfo.Coders[mainCoderIndex].NumInStreams; i++) if (i == mainStreamIndex) sizePointers.Add(inStreamSize); else sizePointers.Add(NULL); _mixerCoderSpec->SetCoderInfo(mainCoderIndex, &sizePointers.Front(), NULL); } // UInt64 outStreamStartPos; // RINOK(stream->Seek(0, STREAM_SEEK_CUR, &outStreamStartPos)); CSequentialInStreamSizeCount2 *inStreamSizeCountSpec = new CSequentialInStreamSizeCount2; CMyComPtr<ISequentialInStream> inStreamSizeCount = inStreamSizeCountSpec; CSequentialOutStreamSizeCount *outStreamSizeCountSpec = new CSequentialOutStreamSizeCount; CMyComPtr<ISequentialOutStream> outStreamSizeCount = outStreamSizeCountSpec; inStreamSizeCountSpec->Init(inStream); outStreamSizeCountSpec->SetStream(outStream); outStreamSizeCountSpec->Init(); CRecordVector<ISequentialInStream *> inStreamPointers; CRecordVector<ISequentialOutStream *> outStreamPointers; inStreamPointers.Add(inStreamSizeCount); outStreamPointers.Add(outStreamSizeCount); for (i = 1; i < _bindInfo.OutStreams.Size(); i++) outStreamPointers.Add(tempBuffers[i - 1]); for (i = 0; i < _codersInfo.Size(); i++) { CCoderInfo &encodingInfo = _codersInfo[i]; CMyComPtr<ICryptoResetInitVector> resetInitVector; _mixerCoderSpec->_coders[i].QueryInterface(IID_ICryptoResetInitVector, (void **)&resetInitVector); if (resetInitVector != NULL) { resetInitVector->ResetInitVector(); } CMyComPtr<ICompressWriteCoderProperties> writeCoderProperties; _mixerCoderSpec->_coders[i].QueryInterface(IID_ICompressWriteCoderProperties, (void **)&writeCoderProperties); if (writeCoderProperties != NULL) { CSequentialOutStreamImp *outStreamSpec = new CSequentialOutStreamImp; CMyComPtr<ISequentialOutStream> outStream(outStreamSpec); outStreamSpec->Init(); writeCoderProperties->WriteCoderProperties(outStream); size_t size = outStreamSpec->GetSize(); encodingInfo.Props.SetCapacity(size); memmove(encodingInfo.Props, outStreamSpec->GetBuffer(), size); } } UInt32 progressIndex = mainCoderIndex; for (i = 0; i + 1 < _codersInfo.Size(); i++) { UInt64 m = _codersInfo[i].MethodID; if (m == k_Delta || m == k_BCJ || m == k_BCJ2) progressIndex = i + 1; } _mixerCoderSpec->SetProgressCoderIndex(progressIndex); RINOK(_mixerCoder->Code(&inStreamPointers.Front(), NULL, 1, &outStreamPointers.Front(), NULL, outStreamPointers.Size(), compressProgress)); ConvertBindInfoToFolderItemInfo(_decompressBindInfo, _decompressionMethods, folderItem); packSizes.Add(outStreamSizeCountSpec->GetSize()); for (i = 1; i < _bindInfo.OutStreams.Size(); i++) { CInOutTempBuffer &inOutTempBuffer = inOutTempBuffers[i - 1]; RINOK(inOutTempBuffer.WriteToStream(outStream)); packSizes.Add(inOutTempBuffer.GetDataSize()); } for (i = 0; i < (int)_bindReverseConverter->NumSrcInStreams; i++) { int binder = _bindInfo.FindBinderForInStream( _bindReverseConverter->DestOutToSrcInMap[i]); UInt64 streamSize; if (binder < 0) streamSize = inStreamSizeCountSpec->GetSize(); else streamSize = _mixerCoderSpec->GetWriteProcessedSize(binder); folderItem.UnpackSizes.Add(streamSize); } for (i = numMethods - 1; i >= 0; i--) folderItem.Coders[numMethods - 1 - i].Props = _codersInfo[i].Props; return S_OK; }
HRESULT CEncoder::Encode(ISequentialInStream *inStream, const UInt64 *inStreamSize, const UInt64 *inSizeForReduce, CFolder &folderItem, ISequentialOutStream *outStream, CRecordVector<UInt64> &packSizes, ICompressProgressInfo *compressProgress) { if (_mixerCoderSpec == NULL) { RINOK(CreateMixerCoder(inSizeForReduce)); } _mixerCoderSpec->ReInit(); // _mixerCoderSpec->SetCoderInfo(0, NULL, NULL, progress); CObjectVector<CInOutTempBuffer> inOutTempBuffers; CObjectVector<CSequentialOutTempBufferImp *> tempBufferSpecs; CObjectVector<CMyComPtr<ISequentialOutStream> > tempBuffers; int numMethods = _bindInfo.Coders.Size(); int i; for (i = 1; i < _bindInfo.OutStreams.Size(); i++) { inOutTempBuffers.Add(CInOutTempBuffer()); inOutTempBuffers.Back().Create(); inOutTempBuffers.Back().InitWriting(); } for (i = 1; i < _bindInfo.OutStreams.Size(); i++) { CSequentialOutTempBufferImp *tempBufferSpec = new CSequentialOutTempBufferImp; CMyComPtr<ISequentialOutStream> tempBuffer = tempBufferSpec; tempBufferSpec->Init(&inOutTempBuffers[i - 1]); tempBuffers.Add(tempBuffer); tempBufferSpecs.Add(tempBufferSpec); } for (i = 0; i < numMethods; i++) _mixerCoderSpec->SetCoderInfo(i, NULL, NULL); if (_bindInfo.InStreams.IsEmpty()) return E_FAIL; UInt32 mainCoderIndex, mainStreamIndex; _bindInfo.FindInStream(_bindInfo.InStreams[0], mainCoderIndex, mainStreamIndex); _mixerCoderSpec->SetProgressCoderIndex(mainCoderIndex); if (inStreamSize != NULL) { CRecordVector<const UInt64 *> sizePointers; for (UInt32 i = 0; i < _bindInfo.Coders[mainCoderIndex].NumInStreams; i++) if (i == mainStreamIndex) sizePointers.Add(inStreamSize); else sizePointers.Add(NULL); _mixerCoderSpec->SetCoderInfo(mainCoderIndex, &sizePointers.Front(), NULL); } // UInt64 outStreamStartPos; // RINOK(stream->Seek(0, STREAM_SEEK_CUR, &outStreamStartPos)); CSequentialInStreamSizeCount2 *inStreamSizeCountSpec = new CSequentialInStreamSizeCount2; CMyComPtr<ISequentialInStream> inStreamSizeCount = inStreamSizeCountSpec; CSequentialOutStreamSizeCount *outStreamSizeCountSpec = new CSequentialOutStreamSizeCount; CMyComPtr<ISequentialOutStream> outStreamSizeCount = outStreamSizeCountSpec; inStreamSizeCountSpec->Init(inStream); outStreamSizeCountSpec->SetStream(outStream); outStreamSizeCountSpec->Init(); CRecordVector<ISequentialInStream *> inStreamPointers; CRecordVector<ISequentialOutStream *> outStreamPointers; inStreamPointers.Add(inStreamSizeCount); outStreamPointers.Add(outStreamSizeCount); for (i = 1; i < _bindInfo.OutStreams.Size(); i++) outStreamPointers.Add(tempBuffers[i - 1]); RINOK(_mixerCoder->Code(&inStreamPointers.Front(), NULL, 1, &outStreamPointers.Front(), NULL, outStreamPointers.Size(), compressProgress)); ConvertBindInfoToFolderItemInfo(_decompressBindInfo, _decompressionMethods, folderItem); packSizes.Add(outStreamSizeCountSpec->GetSize()); for (i = 1; i < _bindInfo.OutStreams.Size(); i++) { CInOutTempBuffer &inOutTempBuffer = inOutTempBuffers[i - 1]; inOutTempBuffer.FlushWrite(); inOutTempBuffer.InitReading(); inOutTempBuffer.WriteToStream(outStream); packSizes.Add(inOutTempBuffer.GetDataSize()); } for (i = 0; i < (int)_bindReverseConverter->NumSrcInStreams; i++) { int binder = _bindInfo.FindBinderForInStream( _bindReverseConverter->DestOutToSrcInMap[i]); UInt64 streamSize; if (binder < 0) streamSize = inStreamSizeCountSpec->GetSize(); else streamSize = _mixerCoderSpec->GetWriteProcessedSize(binder); folderItem.UnPackSizes.Add(streamSize); } for (i = numMethods - 1; i >= 0; i--) { // folderItem.Coders[numMethods - 1 - i].Properties = _codersInfo[i].Properties; for (int j = 0; j < _codersInfo[i].AltCoders.Size(); j++) folderItem.Coders[numMethods - 1 - i].AltCoders[j].Properties = _codersInfo[i].AltCoders[j].Properties; } return S_OK; }