1370b324cSopenharmony_ci// 7zEncode.cpp 2370b324cSopenharmony_ci 3370b324cSopenharmony_ci#include "StdAfx.h" 4370b324cSopenharmony_ci 5370b324cSopenharmony_ci#include "../../../Common/ComTry.h" 6370b324cSopenharmony_ci 7370b324cSopenharmony_ci#include "../../Common/CreateCoder.h" 8370b324cSopenharmony_ci#include "../../Common/FilterCoder.h" 9370b324cSopenharmony_ci#include "../../Common/LimitedStreams.h" 10370b324cSopenharmony_ci#include "../../Common/InOutTempBuffer.h" 11370b324cSopenharmony_ci#include "../../Common/ProgressUtils.h" 12370b324cSopenharmony_ci#include "../../Common/StreamObjects.h" 13370b324cSopenharmony_ci 14370b324cSopenharmony_ci#include "7zEncode.h" 15370b324cSopenharmony_ci#include "7zSpecStream.h" 16370b324cSopenharmony_ci 17370b324cSopenharmony_cinamespace NArchive { 18370b324cSopenharmony_cinamespace N7z { 19370b324cSopenharmony_ci 20370b324cSopenharmony_civoid CEncoder::InitBindConv() 21370b324cSopenharmony_ci{ 22370b324cSopenharmony_ci unsigned numIn = _bindInfo.Coders.Size(); 23370b324cSopenharmony_ci 24370b324cSopenharmony_ci SrcIn_to_DestOut.ClearAndSetSize(numIn); 25370b324cSopenharmony_ci DestOut_to_SrcIn.ClearAndSetSize(numIn); 26370b324cSopenharmony_ci 27370b324cSopenharmony_ci unsigned numOut = _bindInfo.GetNum_Bonds_and_PackStreams(); 28370b324cSopenharmony_ci SrcOut_to_DestIn.ClearAndSetSize(numOut); 29370b324cSopenharmony_ci // _DestIn_to_SrcOut.ClearAndSetSize(numOut); 30370b324cSopenharmony_ci 31370b324cSopenharmony_ci UInt32 destIn = 0; 32370b324cSopenharmony_ci UInt32 destOut = 0; 33370b324cSopenharmony_ci 34370b324cSopenharmony_ci for (unsigned i = _bindInfo.Coders.Size(); i != 0;) 35370b324cSopenharmony_ci { 36370b324cSopenharmony_ci i--; 37370b324cSopenharmony_ci 38370b324cSopenharmony_ci const NCoderMixer2::CCoderStreamsInfo &coder = _bindInfo.Coders[i]; 39370b324cSopenharmony_ci 40370b324cSopenharmony_ci numIn--; 41370b324cSopenharmony_ci numOut -= coder.NumStreams; 42370b324cSopenharmony_ci 43370b324cSopenharmony_ci SrcIn_to_DestOut[numIn] = destOut; 44370b324cSopenharmony_ci DestOut_to_SrcIn[destOut] = numIn; 45370b324cSopenharmony_ci 46370b324cSopenharmony_ci destOut++; 47370b324cSopenharmony_ci 48370b324cSopenharmony_ci for (UInt32 j = 0; j < coder.NumStreams; j++, destIn++) 49370b324cSopenharmony_ci { 50370b324cSopenharmony_ci UInt32 index = numOut + j; 51370b324cSopenharmony_ci SrcOut_to_DestIn[index] = destIn; 52370b324cSopenharmony_ci // _DestIn_to_SrcOut[destIn] = index; 53370b324cSopenharmony_ci } 54370b324cSopenharmony_ci } 55370b324cSopenharmony_ci} 56370b324cSopenharmony_ci 57370b324cSopenharmony_civoid CEncoder::SetFolder(CFolder &folder) 58370b324cSopenharmony_ci{ 59370b324cSopenharmony_ci folder.Bonds.SetSize(_bindInfo.Bonds.Size()); 60370b324cSopenharmony_ci 61370b324cSopenharmony_ci unsigned i; 62370b324cSopenharmony_ci 63370b324cSopenharmony_ci for (i = 0; i < _bindInfo.Bonds.Size(); i++) 64370b324cSopenharmony_ci { 65370b324cSopenharmony_ci CBond &fb = folder.Bonds[i]; 66370b324cSopenharmony_ci const NCoderMixer2::CBond &mixerBond = _bindInfo.Bonds[_bindInfo.Bonds.Size() - 1 - i]; 67370b324cSopenharmony_ci fb.PackIndex = SrcOut_to_DestIn[mixerBond.PackIndex]; 68370b324cSopenharmony_ci fb.UnpackIndex = SrcIn_to_DestOut[mixerBond.UnpackIndex]; 69370b324cSopenharmony_ci } 70370b324cSopenharmony_ci 71370b324cSopenharmony_ci folder.Coders.SetSize(_bindInfo.Coders.Size()); 72370b324cSopenharmony_ci 73370b324cSopenharmony_ci for (i = 0; i < _bindInfo.Coders.Size(); i++) 74370b324cSopenharmony_ci { 75370b324cSopenharmony_ci CCoderInfo &coderInfo = folder.Coders[i]; 76370b324cSopenharmony_ci const NCoderMixer2::CCoderStreamsInfo &coderStreamsInfo = _bindInfo.Coders[_bindInfo.Coders.Size() - 1 - i]; 77370b324cSopenharmony_ci 78370b324cSopenharmony_ci coderInfo.NumStreams = coderStreamsInfo.NumStreams; 79370b324cSopenharmony_ci coderInfo.MethodID = _decompressionMethods[i]; 80370b324cSopenharmony_ci // we don't free coderInfo.Props here. So coderInfo.Props can be non-empty. 81370b324cSopenharmony_ci } 82370b324cSopenharmony_ci 83370b324cSopenharmony_ci folder.PackStreams.SetSize(_bindInfo.PackStreams.Size()); 84370b324cSopenharmony_ci 85370b324cSopenharmony_ci for (i = 0; i < _bindInfo.PackStreams.Size(); i++) 86370b324cSopenharmony_ci folder.PackStreams[i] = SrcOut_to_DestIn[_bindInfo.PackStreams[i]]; 87370b324cSopenharmony_ci} 88370b324cSopenharmony_ci 89370b324cSopenharmony_ci 90370b324cSopenharmony_ci 91370b324cSopenharmony_cistatic HRESULT SetCoderProps2(const CProps &props, const UInt64 *dataSizeReduce, IUnknown *coder) 92370b324cSopenharmony_ci{ 93370b324cSopenharmony_ci Z7_DECL_CMyComPtr_QI_FROM( 94370b324cSopenharmony_ci ICompressSetCoderProperties, 95370b324cSopenharmony_ci setCoderProperties, coder) 96370b324cSopenharmony_ci if (setCoderProperties) 97370b324cSopenharmony_ci return props.SetCoderProps(setCoderProperties, dataSizeReduce); 98370b324cSopenharmony_ci return props.AreThereNonOptionalProps() ? E_INVALIDARG : S_OK; 99370b324cSopenharmony_ci} 100370b324cSopenharmony_ci 101370b324cSopenharmony_ci 102370b324cSopenharmony_ci 103370b324cSopenharmony_civoid CMtEncMultiProgress::Init(ICompressProgressInfo *progress) 104370b324cSopenharmony_ci{ 105370b324cSopenharmony_ci _progress = progress; 106370b324cSopenharmony_ci OutSize = 0; 107370b324cSopenharmony_ci} 108370b324cSopenharmony_ci 109370b324cSopenharmony_ciZ7_COM7F_IMF(CMtEncMultiProgress::SetRatioInfo(const UInt64 *inSize, const UInt64 * /* outSize */)) 110370b324cSopenharmony_ci{ 111370b324cSopenharmony_ci UInt64 outSize2; 112370b324cSopenharmony_ci { 113370b324cSopenharmony_ci #ifndef Z7_ST 114370b324cSopenharmony_ci NWindows::NSynchronization::CCriticalSectionLock lock(CriticalSection); 115370b324cSopenharmony_ci #endif 116370b324cSopenharmony_ci outSize2 = OutSize; 117370b324cSopenharmony_ci } 118370b324cSopenharmony_ci 119370b324cSopenharmony_ci if (_progress) 120370b324cSopenharmony_ci return _progress->SetRatioInfo(inSize, &outSize2); 121370b324cSopenharmony_ci 122370b324cSopenharmony_ci return S_OK; 123370b324cSopenharmony_ci} 124370b324cSopenharmony_ci 125370b324cSopenharmony_ci 126370b324cSopenharmony_ci 127370b324cSopenharmony_ciHRESULT CEncoder::CreateMixerCoder( 128370b324cSopenharmony_ci DECL_EXTERNAL_CODECS_LOC_VARS 129370b324cSopenharmony_ci const UInt64 *inSizeForReduce) 130370b324cSopenharmony_ci{ 131370b324cSopenharmony_ci #ifdef USE_MIXER_MT 132370b324cSopenharmony_ci #ifdef USE_MIXER_ST 133370b324cSopenharmony_ci if (_options.MultiThreadMixer) 134370b324cSopenharmony_ci #endif 135370b324cSopenharmony_ci { 136370b324cSopenharmony_ci _mixerMT = new NCoderMixer2::CMixerMT(true); 137370b324cSopenharmony_ci _mixerRef = _mixerMT; 138370b324cSopenharmony_ci _mixer = _mixerMT; 139370b324cSopenharmony_ci } 140370b324cSopenharmony_ci #ifdef USE_MIXER_ST 141370b324cSopenharmony_ci else 142370b324cSopenharmony_ci #endif 143370b324cSopenharmony_ci #endif 144370b324cSopenharmony_ci { 145370b324cSopenharmony_ci #ifdef USE_MIXER_ST 146370b324cSopenharmony_ci _mixerST = new NCoderMixer2::CMixerST(true); 147370b324cSopenharmony_ci _mixerRef = _mixerST; 148370b324cSopenharmony_ci _mixer = _mixerST; 149370b324cSopenharmony_ci #endif 150370b324cSopenharmony_ci } 151370b324cSopenharmony_ci 152370b324cSopenharmony_ci RINOK(_mixer->SetBindInfo(_bindInfo)) 153370b324cSopenharmony_ci 154370b324cSopenharmony_ci FOR_VECTOR (m, _options.Methods) 155370b324cSopenharmony_ci { 156370b324cSopenharmony_ci const CMethodFull &methodFull = _options.Methods[m]; 157370b324cSopenharmony_ci 158370b324cSopenharmony_ci CCreatedCoder cod; 159370b324cSopenharmony_ci 160370b324cSopenharmony_ci if (methodFull.CodecIndex >= 0) 161370b324cSopenharmony_ci { 162370b324cSopenharmony_ci RINOK(CreateCoder_Index( 163370b324cSopenharmony_ci EXTERNAL_CODECS_LOC_VARS 164370b324cSopenharmony_ci (unsigned)methodFull.CodecIndex, true, cod)) 165370b324cSopenharmony_ci } 166370b324cSopenharmony_ci else 167370b324cSopenharmony_ci { 168370b324cSopenharmony_ci RINOK(CreateCoder_Id( 169370b324cSopenharmony_ci EXTERNAL_CODECS_LOC_VARS 170370b324cSopenharmony_ci methodFull.Id, true, cod)) 171370b324cSopenharmony_ci } 172370b324cSopenharmony_ci 173370b324cSopenharmony_ci if (!cod.Coder && !cod.Coder2) 174370b324cSopenharmony_ci { 175370b324cSopenharmony_ci return E_NOTIMPL; // unsupported method, if encoder 176370b324cSopenharmony_ci // return E_FAIL; 177370b324cSopenharmony_ci } 178370b324cSopenharmony_ci 179370b324cSopenharmony_ci if (cod.NumStreams != methodFull.NumStreams) 180370b324cSopenharmony_ci return E_FAIL; 181370b324cSopenharmony_ci 182370b324cSopenharmony_ci CMyComPtr<IUnknown> encoderCommon = cod.Coder ? (IUnknown *)cod.Coder : (IUnknown *)cod.Coder2; 183370b324cSopenharmony_ci 184370b324cSopenharmony_ci #ifndef Z7_ST 185370b324cSopenharmony_ci if (methodFull.Set_NumThreads) 186370b324cSopenharmony_ci { 187370b324cSopenharmony_ci CMyComPtr<ICompressSetCoderMt> setCoderMt; 188370b324cSopenharmony_ci encoderCommon.QueryInterface(IID_ICompressSetCoderMt, &setCoderMt); 189370b324cSopenharmony_ci if (setCoderMt) 190370b324cSopenharmony_ci { 191370b324cSopenharmony_ci RINOK(setCoderMt->SetNumberOfThreads( 192370b324cSopenharmony_ci /* _options.NumThreads */ 193370b324cSopenharmony_ci methodFull.NumThreads 194370b324cSopenharmony_ci )) 195370b324cSopenharmony_ci } 196370b324cSopenharmony_ci } 197370b324cSopenharmony_ci #endif 198370b324cSopenharmony_ci 199370b324cSopenharmony_ci RINOK(SetCoderProps2(methodFull, inSizeForReduce, encoderCommon)) 200370b324cSopenharmony_ci 201370b324cSopenharmony_ci /* 202370b324cSopenharmony_ci CMyComPtr<ICryptoResetSalt> resetSalt; 203370b324cSopenharmony_ci encoderCommon.QueryInterface(IID_ICryptoResetSalt, (void **)&resetSalt); 204370b324cSopenharmony_ci if (resetSalt) 205370b324cSopenharmony_ci { 206370b324cSopenharmony_ci resetSalt->ResetSalt(); 207370b324cSopenharmony_ci } 208370b324cSopenharmony_ci */ 209370b324cSopenharmony_ci 210370b324cSopenharmony_ci // now there is no codec that uses another external codec 211370b324cSopenharmony_ci /* 212370b324cSopenharmony_ci #ifdef Z7_EXTERNAL_CODECS 213370b324cSopenharmony_ci CMyComPtr<ISetCompressCodecsInfo> setCompressCodecsInfo; 214370b324cSopenharmony_ci encoderCommon.QueryInterface(IID_ISetCompressCodecsInfo, (void **)&setCompressCodecsInfo); 215370b324cSopenharmony_ci if (setCompressCodecsInfo) 216370b324cSopenharmony_ci { 217370b324cSopenharmony_ci // we must use g_ExternalCodecs also 218370b324cSopenharmony_ci RINOK(setCompressCodecsInfo->SetCompressCodecsInfo(_externalCodecs->GetCodecs)); 219370b324cSopenharmony_ci } 220370b324cSopenharmony_ci #endif 221370b324cSopenharmony_ci */ 222370b324cSopenharmony_ci 223370b324cSopenharmony_ci CMyComPtr<ICryptoSetPassword> cryptoSetPassword; 224370b324cSopenharmony_ci encoderCommon.QueryInterface(IID_ICryptoSetPassword, &cryptoSetPassword); 225370b324cSopenharmony_ci 226370b324cSopenharmony_ci if (cryptoSetPassword) 227370b324cSopenharmony_ci { 228370b324cSopenharmony_ci const unsigned sizeInBytes = _options.Password.Len() * 2; 229370b324cSopenharmony_ci CByteBuffer_Wipe buffer(sizeInBytes); 230370b324cSopenharmony_ci for (unsigned i = 0; i < _options.Password.Len(); i++) 231370b324cSopenharmony_ci { 232370b324cSopenharmony_ci wchar_t c = _options.Password[i]; 233370b324cSopenharmony_ci ((Byte *)buffer)[i * 2] = (Byte)c; 234370b324cSopenharmony_ci ((Byte *)buffer)[i * 2 + 1] = (Byte)(c >> 8); 235370b324cSopenharmony_ci } 236370b324cSopenharmony_ci RINOK(cryptoSetPassword->CryptoSetPassword((const Byte *)buffer, (UInt32)sizeInBytes)) 237370b324cSopenharmony_ci } 238370b324cSopenharmony_ci 239370b324cSopenharmony_ci _mixer->AddCoder(cod); 240370b324cSopenharmony_ci } 241370b324cSopenharmony_ci return S_OK; 242370b324cSopenharmony_ci} 243370b324cSopenharmony_ci 244370b324cSopenharmony_ci 245370b324cSopenharmony_ci 246370b324cSopenharmony_ciZ7_CLASS_IMP_COM_1( 247370b324cSopenharmony_ci CSequentialOutTempBufferImp2 248370b324cSopenharmony_ci , ISequentialOutStream 249370b324cSopenharmony_ci) 250370b324cSopenharmony_cipublic: 251370b324cSopenharmony_ci CInOutTempBuffer TempBuffer; 252370b324cSopenharmony_ci CMtEncMultiProgress *_mtProgressSpec; 253370b324cSopenharmony_ci 254370b324cSopenharmony_ci CSequentialOutTempBufferImp2(): _mtProgressSpec(NULL) {} 255370b324cSopenharmony_ci}; 256370b324cSopenharmony_ci 257370b324cSopenharmony_ciZ7_COM7F_IMF(CSequentialOutTempBufferImp2::Write(const void *data, UInt32 size, UInt32 *processed)) 258370b324cSopenharmony_ci{ 259370b324cSopenharmony_ci COM_TRY_BEGIN 260370b324cSopenharmony_ci if (processed) 261370b324cSopenharmony_ci *processed = 0; 262370b324cSopenharmony_ci RINOK(TempBuffer.Write_HRESULT(data, size)) 263370b324cSopenharmony_ci if (processed) 264370b324cSopenharmony_ci *processed = size; 265370b324cSopenharmony_ci if (_mtProgressSpec) 266370b324cSopenharmony_ci _mtProgressSpec->AddOutSize(size); 267370b324cSopenharmony_ci return S_OK; 268370b324cSopenharmony_ci COM_TRY_END 269370b324cSopenharmony_ci} 270370b324cSopenharmony_ci 271370b324cSopenharmony_ci 272370b324cSopenharmony_ciZ7_CLASS_IMP_COM_1( 273370b324cSopenharmony_ci CSequentialOutMtNotify 274370b324cSopenharmony_ci , ISequentialOutStream 275370b324cSopenharmony_ci) 276370b324cSopenharmony_cipublic: 277370b324cSopenharmony_ci CMyComPtr<ISequentialOutStream> _stream; 278370b324cSopenharmony_ci CMtEncMultiProgress *_mtProgressSpec; 279370b324cSopenharmony_ci 280370b324cSopenharmony_ci CSequentialOutMtNotify(): _mtProgressSpec(NULL) {} 281370b324cSopenharmony_ci}; 282370b324cSopenharmony_ci 283370b324cSopenharmony_ciZ7_COM7F_IMF(CSequentialOutMtNotify::Write(const void *data, UInt32 size, UInt32 *processed)) 284370b324cSopenharmony_ci{ 285370b324cSopenharmony_ci UInt32 realProcessed = 0; 286370b324cSopenharmony_ci HRESULT res = _stream->Write(data, size, &realProcessed); 287370b324cSopenharmony_ci if (processed) 288370b324cSopenharmony_ci *processed = realProcessed; 289370b324cSopenharmony_ci if (_mtProgressSpec) 290370b324cSopenharmony_ci _mtProgressSpec->AddOutSize(size); 291370b324cSopenharmony_ci return res; 292370b324cSopenharmony_ci} 293370b324cSopenharmony_ci 294370b324cSopenharmony_ci 295370b324cSopenharmony_cistatic HRESULT FillProps_from_Coder(IUnknown *coder, CByteBuffer &props) 296370b324cSopenharmony_ci{ 297370b324cSopenharmony_ci Z7_DECL_CMyComPtr_QI_FROM( 298370b324cSopenharmony_ci ICompressWriteCoderProperties, 299370b324cSopenharmony_ci writeCoderProperties, coder) 300370b324cSopenharmony_ci if (writeCoderProperties) 301370b324cSopenharmony_ci { 302370b324cSopenharmony_ci CDynBufSeqOutStream *outStreamSpec = new CDynBufSeqOutStream; 303370b324cSopenharmony_ci CMyComPtr<ISequentialOutStream> dynOutStream(outStreamSpec); 304370b324cSopenharmony_ci outStreamSpec->Init(); 305370b324cSopenharmony_ci RINOK(writeCoderProperties->WriteCoderProperties(dynOutStream)) 306370b324cSopenharmony_ci outStreamSpec->CopyToBuffer(props); 307370b324cSopenharmony_ci } 308370b324cSopenharmony_ci else 309370b324cSopenharmony_ci props.Free(); 310370b324cSopenharmony_ci return S_OK; 311370b324cSopenharmony_ci} 312370b324cSopenharmony_ci 313370b324cSopenharmony_ciHRESULT CEncoder::Encode1( 314370b324cSopenharmony_ci DECL_EXTERNAL_CODECS_LOC_VARS 315370b324cSopenharmony_ci ISequentialInStream *inStream, 316370b324cSopenharmony_ci // const UInt64 *inStreamSize, 317370b324cSopenharmony_ci const UInt64 *inSizeForReduce, 318370b324cSopenharmony_ci UInt64 expectedDataSize, 319370b324cSopenharmony_ci CFolder &folderItem, 320370b324cSopenharmony_ci // CRecordVector<UInt64> &coderUnpackSizes, 321370b324cSopenharmony_ci // UInt64 &unpackSize, 322370b324cSopenharmony_ci ISequentialOutStream *outStream, 323370b324cSopenharmony_ci CRecordVector<UInt64> &packSizes, 324370b324cSopenharmony_ci ICompressProgressInfo *compressProgress) 325370b324cSopenharmony_ci{ 326370b324cSopenharmony_ci RINOK(EncoderConstr()) 327370b324cSopenharmony_ci 328370b324cSopenharmony_ci if (!_mixerRef) 329370b324cSopenharmony_ci { 330370b324cSopenharmony_ci RINOK(CreateMixerCoder(EXTERNAL_CODECS_LOC_VARS inSizeForReduce)) 331370b324cSopenharmony_ci } 332370b324cSopenharmony_ci 333370b324cSopenharmony_ci RINOK(_mixer->ReInit2()) 334370b324cSopenharmony_ci 335370b324cSopenharmony_ci CMtEncMultiProgress *mtProgressSpec = NULL; 336370b324cSopenharmony_ci CMyComPtr<ICompressProgressInfo> mtProgress; 337370b324cSopenharmony_ci 338370b324cSopenharmony_ci CSequentialOutMtNotify *mtOutStreamNotifySpec = NULL; 339370b324cSopenharmony_ci CMyComPtr<ISequentialOutStream> mtOutStreamNotify; 340370b324cSopenharmony_ci 341370b324cSopenharmony_ci CRecordVector<CSequentialOutTempBufferImp2 *> tempBufferSpecs; 342370b324cSopenharmony_ci CObjectVector<CMyComPtr<ISequentialOutStream> > tempBuffers; 343370b324cSopenharmony_ci 344370b324cSopenharmony_ci unsigned i; 345370b324cSopenharmony_ci 346370b324cSopenharmony_ci for (i = 1; i < _bindInfo.PackStreams.Size(); i++) 347370b324cSopenharmony_ci { 348370b324cSopenharmony_ci CSequentialOutTempBufferImp2 *tempBufferSpec = new CSequentialOutTempBufferImp2(); 349370b324cSopenharmony_ci CMyComPtr<ISequentialOutStream> tempBuffer = tempBufferSpec; 350370b324cSopenharmony_ci tempBufferSpecs.Add(tempBufferSpec); 351370b324cSopenharmony_ci tempBuffers.Add(tempBuffer); 352370b324cSopenharmony_ci } 353370b324cSopenharmony_ci 354370b324cSopenharmony_ci const unsigned numMethods = _bindInfo.Coders.Size(); 355370b324cSopenharmony_ci 356370b324cSopenharmony_ci for (i = 0; i < numMethods; i++) 357370b324cSopenharmony_ci _mixer->SetCoderInfo(i, NULL, NULL, false); 358370b324cSopenharmony_ci 359370b324cSopenharmony_ci 360370b324cSopenharmony_ci /* inStreamSize can be used by BCJ2 to set optimal range of conversion. 361370b324cSopenharmony_ci But current BCJ2 encoder uses also another way to check exact size of current file. 362370b324cSopenharmony_ci So inStreamSize is not required. */ 363370b324cSopenharmony_ci 364370b324cSopenharmony_ci /* 365370b324cSopenharmony_ci if (inStreamSize) 366370b324cSopenharmony_ci _mixer->SetCoderInfo(_bindInfo.UnpackCoder, inStreamSize, NULL); 367370b324cSopenharmony_ci */ 368370b324cSopenharmony_ci 369370b324cSopenharmony_ci 370370b324cSopenharmony_ci /* 371370b324cSopenharmony_ci CSequentialInStreamSizeCount2 *inStreamSizeCountSpec = new CSequentialInStreamSizeCount2; 372370b324cSopenharmony_ci CMyComPtr<ISequentialInStream> inStreamSizeCount = inStreamSizeCountSpec; 373370b324cSopenharmony_ci */ 374370b324cSopenharmony_ci 375370b324cSopenharmony_ci CSequentialOutStreamSizeCount *outStreamSizeCountSpec = NULL; 376370b324cSopenharmony_ci CMyComPtr<ISequentialOutStream> outStreamSizeCount; 377370b324cSopenharmony_ci 378370b324cSopenharmony_ci // inStreamSizeCountSpec->Init(inStream); 379370b324cSopenharmony_ci 380370b324cSopenharmony_ci // ISequentialInStream *inStreamPointer = inStreamSizeCount; 381370b324cSopenharmony_ci ISequentialInStream *inStreamPointer = inStream; 382370b324cSopenharmony_ci 383370b324cSopenharmony_ci CRecordVector<ISequentialOutStream *> outStreamPointers; 384370b324cSopenharmony_ci 385370b324cSopenharmony_ci SetFolder(folderItem); 386370b324cSopenharmony_ci 387370b324cSopenharmony_ci for (i = 0; i < numMethods; i++) 388370b324cSopenharmony_ci { 389370b324cSopenharmony_ci IUnknown *coder = _mixer->GetCoder(i).GetUnknown(); 390370b324cSopenharmony_ci /* 391370b324cSopenharmony_ci { 392370b324cSopenharmony_ci CEncoder *sfEncoder = NULL; 393370b324cSopenharmony_ci Z7_DECL_CMyComPtr_QI_FROM( 394370b324cSopenharmony_ci IGetSfEncoderInternal, 395370b324cSopenharmony_ci sf, coder) 396370b324cSopenharmony_ci if (sf) 397370b324cSopenharmony_ci { 398370b324cSopenharmony_ci RINOK(sf->GetSfEncoder(&sfEncoder)); 399370b324cSopenharmony_ci if (!sfEncoder) 400370b324cSopenharmony_ci return E_FAIL; 401370b324cSopenharmony_ci 402370b324cSopenharmony_ci } 403370b324cSopenharmony_ci } 404370b324cSopenharmony_ci */ 405370b324cSopenharmony_ci /* 406370b324cSopenharmony_ci #ifdef Z7_EXTERNAL_CODECS 407370b324cSopenharmony_ci { 408370b324cSopenharmony_ci Z7_DECL_CMyComPtr_QI_FROM( 409370b324cSopenharmony_ci ISetCompressCodecsInfo, 410370b324cSopenharmony_ci setCompressCodecsInfo, coder) 411370b324cSopenharmony_ci if (setCompressCodecsInfo) 412370b324cSopenharmony_ci { 413370b324cSopenharmony_ci // we must use g_ExternalCodecs also 414370b324cSopenharmony_ci RINOK(setCompressCodecsInfo->SetCompressCodecsInfo(_externalCodecs->GetCodecs)) 415370b324cSopenharmony_ci } 416370b324cSopenharmony_ci } 417370b324cSopenharmony_ci #endif 418370b324cSopenharmony_ci */ 419370b324cSopenharmony_ci { 420370b324cSopenharmony_ci Z7_DECL_CMyComPtr_QI_FROM( 421370b324cSopenharmony_ci ICryptoResetInitVector, 422370b324cSopenharmony_ci resetInitVector, coder) 423370b324cSopenharmony_ci if (resetInitVector) 424370b324cSopenharmony_ci { 425370b324cSopenharmony_ci RINOK(resetInitVector->ResetInitVector()) 426370b324cSopenharmony_ci } 427370b324cSopenharmony_ci } 428370b324cSopenharmony_ci { 429370b324cSopenharmony_ci Z7_DECL_CMyComPtr_QI_FROM( 430370b324cSopenharmony_ci ICompressSetCoderPropertiesOpt, 431370b324cSopenharmony_ci optProps, coder) 432370b324cSopenharmony_ci if (optProps) 433370b324cSopenharmony_ci { 434370b324cSopenharmony_ci const PROPID propID = NCoderPropID::kExpectedDataSize; 435370b324cSopenharmony_ci NWindows::NCOM::CPropVariant prop = (UInt64)expectedDataSize; 436370b324cSopenharmony_ci RINOK(optProps->SetCoderPropertiesOpt(&propID, &prop, 1)) 437370b324cSopenharmony_ci } 438370b324cSopenharmony_ci } 439370b324cSopenharmony_ci // we must write properties from coder after ResetInitVector() 440370b324cSopenharmony_ci RINOK(FillProps_from_Coder(coder, folderItem.Coders[numMethods - 1 - i].Props)) 441370b324cSopenharmony_ci } 442370b324cSopenharmony_ci 443370b324cSopenharmony_ci _mixer->SelectMainCoder(false); 444370b324cSopenharmony_ci const UInt32 mainCoder = _mixer->MainCoderIndex; 445370b324cSopenharmony_ci 446370b324cSopenharmony_ci bool useMtProgress = false; 447370b324cSopenharmony_ci if (!_mixer->Is_PackSize_Correct_for_Coder(mainCoder)) 448370b324cSopenharmony_ci { 449370b324cSopenharmony_ci #ifdef Z7_ST 450370b324cSopenharmony_ci if (!_mixer->IsThere_ExternalCoder_in_PackTree(mainCoder)) 451370b324cSopenharmony_ci #endif 452370b324cSopenharmony_ci useMtProgress = true; 453370b324cSopenharmony_ci } 454370b324cSopenharmony_ci 455370b324cSopenharmony_ci if (useMtProgress) 456370b324cSopenharmony_ci { 457370b324cSopenharmony_ci mtProgressSpec = new CMtEncMultiProgress; 458370b324cSopenharmony_ci mtProgress = mtProgressSpec; 459370b324cSopenharmony_ci mtProgressSpec->Init(compressProgress); 460370b324cSopenharmony_ci 461370b324cSopenharmony_ci mtOutStreamNotifySpec = new CSequentialOutMtNotify; 462370b324cSopenharmony_ci mtOutStreamNotify = mtOutStreamNotifySpec; 463370b324cSopenharmony_ci mtOutStreamNotifySpec->_stream = outStream; 464370b324cSopenharmony_ci mtOutStreamNotifySpec->_mtProgressSpec = mtProgressSpec; 465370b324cSopenharmony_ci 466370b324cSopenharmony_ci FOR_VECTOR (t, tempBufferSpecs) 467370b324cSopenharmony_ci { 468370b324cSopenharmony_ci tempBufferSpecs[t]->_mtProgressSpec = mtProgressSpec; 469370b324cSopenharmony_ci } 470370b324cSopenharmony_ci } 471370b324cSopenharmony_ci 472370b324cSopenharmony_ci 473370b324cSopenharmony_ci if (_bindInfo.PackStreams.Size() != 0) 474370b324cSopenharmony_ci { 475370b324cSopenharmony_ci outStreamSizeCountSpec = new CSequentialOutStreamSizeCount; 476370b324cSopenharmony_ci outStreamSizeCount = outStreamSizeCountSpec; 477370b324cSopenharmony_ci outStreamSizeCountSpec->SetStream(mtOutStreamNotify ? (ISequentialOutStream *)mtOutStreamNotify : outStream); 478370b324cSopenharmony_ci outStreamSizeCountSpec->Init(); 479370b324cSopenharmony_ci outStreamPointers.Add(outStreamSizeCount); 480370b324cSopenharmony_ci } 481370b324cSopenharmony_ci 482370b324cSopenharmony_ci for (i = 1; i < _bindInfo.PackStreams.Size(); i++) 483370b324cSopenharmony_ci outStreamPointers.Add(tempBuffers[i - 1]); 484370b324cSopenharmony_ci 485370b324cSopenharmony_ci bool dataAfterEnd_Error; 486370b324cSopenharmony_ci 487370b324cSopenharmony_ci RINOK(_mixer->Code( 488370b324cSopenharmony_ci &inStreamPointer, 489370b324cSopenharmony_ci &outStreamPointers.Front(), 490370b324cSopenharmony_ci mtProgress ? (ICompressProgressInfo *)mtProgress : compressProgress, dataAfterEnd_Error)) 491370b324cSopenharmony_ci 492370b324cSopenharmony_ci if (_bindInfo.PackStreams.Size() != 0) 493370b324cSopenharmony_ci packSizes.Add(outStreamSizeCountSpec->GetSize()); 494370b324cSopenharmony_ci 495370b324cSopenharmony_ci for (i = 1; i < _bindInfo.PackStreams.Size(); i++) 496370b324cSopenharmony_ci { 497370b324cSopenharmony_ci CInOutTempBuffer &iotb = tempBufferSpecs[i - 1]->TempBuffer; 498370b324cSopenharmony_ci RINOK(iotb.WriteToStream(outStream)) 499370b324cSopenharmony_ci packSizes.Add(iotb.GetDataSize()); 500370b324cSopenharmony_ci } 501370b324cSopenharmony_ci 502370b324cSopenharmony_ci /* Code() in some future codec can change properties. 503370b324cSopenharmony_ci v23: so we fill properties again after Code() */ 504370b324cSopenharmony_ci for (i = 0; i < numMethods; i++) 505370b324cSopenharmony_ci { 506370b324cSopenharmony_ci IUnknown *coder = _mixer->GetCoder(i).GetUnknown(); 507370b324cSopenharmony_ci RINOK(FillProps_from_Coder(coder, folderItem.Coders[numMethods - 1 - i].Props)) 508370b324cSopenharmony_ci } 509370b324cSopenharmony_ci 510370b324cSopenharmony_ci return S_OK; 511370b324cSopenharmony_ci} 512370b324cSopenharmony_ci 513370b324cSopenharmony_ci 514370b324cSopenharmony_civoid CEncoder::Encode_Post( 515370b324cSopenharmony_ci UInt64 unpackSize, 516370b324cSopenharmony_ci CRecordVector<UInt64> &coderUnpackSizes) 517370b324cSopenharmony_ci{ 518370b324cSopenharmony_ci // unpackSize = 0; 519370b324cSopenharmony_ci for (unsigned i = 0; i < _bindInfo.Coders.Size(); i++) 520370b324cSopenharmony_ci { 521370b324cSopenharmony_ci const int bond = _bindInfo.FindBond_for_UnpackStream(DestOut_to_SrcIn[i]); 522370b324cSopenharmony_ci UInt64 streamSize; 523370b324cSopenharmony_ci if (bond < 0) 524370b324cSopenharmony_ci { 525370b324cSopenharmony_ci // streamSize = inStreamSizeCountSpec->GetSize(); 526370b324cSopenharmony_ci // unpackSize = streamSize; 527370b324cSopenharmony_ci streamSize = unpackSize; 528370b324cSopenharmony_ci } 529370b324cSopenharmony_ci else 530370b324cSopenharmony_ci streamSize = _mixer->GetBondStreamSize((unsigned)bond); 531370b324cSopenharmony_ci coderUnpackSizes.Add(streamSize); 532370b324cSopenharmony_ci } 533370b324cSopenharmony_ci} 534370b324cSopenharmony_ci 535370b324cSopenharmony_ci 536370b324cSopenharmony_ciCEncoder::CEncoder(const CCompressionMethodMode &options): 537370b324cSopenharmony_ci _constructed(false) 538370b324cSopenharmony_ci{ 539370b324cSopenharmony_ci if (options.IsEmpty()) 540370b324cSopenharmony_ci throw 1; 541370b324cSopenharmony_ci 542370b324cSopenharmony_ci _options = options; 543370b324cSopenharmony_ci 544370b324cSopenharmony_ci #ifdef USE_MIXER_ST 545370b324cSopenharmony_ci _mixerST = NULL; 546370b324cSopenharmony_ci #endif 547370b324cSopenharmony_ci 548370b324cSopenharmony_ci #ifdef USE_MIXER_MT 549370b324cSopenharmony_ci _mixerMT = NULL; 550370b324cSopenharmony_ci #endif 551370b324cSopenharmony_ci 552370b324cSopenharmony_ci _mixer = NULL; 553370b324cSopenharmony_ci} 554370b324cSopenharmony_ci 555370b324cSopenharmony_ci 556370b324cSopenharmony_ciHRESULT CEncoder::EncoderConstr() 557370b324cSopenharmony_ci{ 558370b324cSopenharmony_ci if (_constructed) 559370b324cSopenharmony_ci return S_OK; 560370b324cSopenharmony_ci if (_options.Methods.IsEmpty()) 561370b324cSopenharmony_ci { 562370b324cSopenharmony_ci // it has only password method; 563370b324cSopenharmony_ci if (!_options.PasswordIsDefined) 564370b324cSopenharmony_ci throw 1; 565370b324cSopenharmony_ci if (!_options.Bonds.IsEmpty()) 566370b324cSopenharmony_ci throw 1; 567370b324cSopenharmony_ci 568370b324cSopenharmony_ci CMethodFull method; 569370b324cSopenharmony_ci method.Id = k_AES; 570370b324cSopenharmony_ci method.NumStreams = 1; 571370b324cSopenharmony_ci _options.Methods.Add(method); 572370b324cSopenharmony_ci 573370b324cSopenharmony_ci NCoderMixer2::CCoderStreamsInfo coderStreamsInfo; 574370b324cSopenharmony_ci coderStreamsInfo.NumStreams = 1; 575370b324cSopenharmony_ci _bindInfo.Coders.Add(coderStreamsInfo); 576370b324cSopenharmony_ci 577370b324cSopenharmony_ci _bindInfo.PackStreams.Add(0); 578370b324cSopenharmony_ci _bindInfo.UnpackCoder = 0; 579370b324cSopenharmony_ci } 580370b324cSopenharmony_ci else 581370b324cSopenharmony_ci { 582370b324cSopenharmony_ci 583370b324cSopenharmony_ci UInt32 numOutStreams = 0; 584370b324cSopenharmony_ci unsigned i; 585370b324cSopenharmony_ci 586370b324cSopenharmony_ci for (i = 0; i < _options.Methods.Size(); i++) 587370b324cSopenharmony_ci { 588370b324cSopenharmony_ci const CMethodFull &methodFull = _options.Methods[i]; 589370b324cSopenharmony_ci NCoderMixer2::CCoderStreamsInfo cod; 590370b324cSopenharmony_ci 591370b324cSopenharmony_ci cod.NumStreams = methodFull.NumStreams; 592370b324cSopenharmony_ci 593370b324cSopenharmony_ci if (_options.Bonds.IsEmpty()) 594370b324cSopenharmony_ci { 595370b324cSopenharmony_ci // if there are no bonds in options, we create bonds via first streams of coders 596370b324cSopenharmony_ci if (i != _options.Methods.Size() - 1) 597370b324cSopenharmony_ci { 598370b324cSopenharmony_ci NCoderMixer2::CBond bond; 599370b324cSopenharmony_ci bond.PackIndex = numOutStreams; 600370b324cSopenharmony_ci bond.UnpackIndex = i + 1; // it's next coder 601370b324cSopenharmony_ci _bindInfo.Bonds.Add(bond); 602370b324cSopenharmony_ci } 603370b324cSopenharmony_ci else if (cod.NumStreams != 0) 604370b324cSopenharmony_ci _bindInfo.PackStreams.Insert(0, numOutStreams); 605370b324cSopenharmony_ci 606370b324cSopenharmony_ci for (UInt32 j = 1; j < cod.NumStreams; j++) 607370b324cSopenharmony_ci _bindInfo.PackStreams.Add(numOutStreams + j); 608370b324cSopenharmony_ci } 609370b324cSopenharmony_ci 610370b324cSopenharmony_ci numOutStreams += cod.NumStreams; 611370b324cSopenharmony_ci 612370b324cSopenharmony_ci _bindInfo.Coders.Add(cod); 613370b324cSopenharmony_ci } 614370b324cSopenharmony_ci 615370b324cSopenharmony_ci if (!_options.Bonds.IsEmpty()) 616370b324cSopenharmony_ci { 617370b324cSopenharmony_ci for (i = 0; i < _options.Bonds.Size(); i++) 618370b324cSopenharmony_ci { 619370b324cSopenharmony_ci NCoderMixer2::CBond mixerBond; 620370b324cSopenharmony_ci const CBond2 &bond = _options.Bonds[i]; 621370b324cSopenharmony_ci if (bond.InCoder >= _bindInfo.Coders.Size() 622370b324cSopenharmony_ci || bond.OutCoder >= _bindInfo.Coders.Size() 623370b324cSopenharmony_ci || bond.OutStream >= _bindInfo.Coders[bond.OutCoder].NumStreams) 624370b324cSopenharmony_ci return E_INVALIDARG; 625370b324cSopenharmony_ci mixerBond.PackIndex = _bindInfo.GetStream_for_Coder(bond.OutCoder) + bond.OutStream; 626370b324cSopenharmony_ci mixerBond.UnpackIndex = bond.InCoder; 627370b324cSopenharmony_ci _bindInfo.Bonds.Add(mixerBond); 628370b324cSopenharmony_ci } 629370b324cSopenharmony_ci 630370b324cSopenharmony_ci for (i = 0; i < numOutStreams; i++) 631370b324cSopenharmony_ci if (_bindInfo.FindBond_for_PackStream(i) == -1) 632370b324cSopenharmony_ci _bindInfo.PackStreams.Add(i); 633370b324cSopenharmony_ci } 634370b324cSopenharmony_ci 635370b324cSopenharmony_ci if (!_bindInfo.SetUnpackCoder()) 636370b324cSopenharmony_ci return E_INVALIDARG; 637370b324cSopenharmony_ci 638370b324cSopenharmony_ci if (!_bindInfo.CalcMapsAndCheck()) 639370b324cSopenharmony_ci return E_INVALIDARG; 640370b324cSopenharmony_ci 641370b324cSopenharmony_ci if (_bindInfo.PackStreams.Size() != 1) 642370b324cSopenharmony_ci { 643370b324cSopenharmony_ci /* main_PackStream is pack stream of main path of coders tree. 644370b324cSopenharmony_ci We find main_PackStream, and place to start of list of out streams. 645370b324cSopenharmony_ci It allows to use more optimal memory usage for temp buffers, 646370b324cSopenharmony_ci if main_PackStream is largest stream. */ 647370b324cSopenharmony_ci 648370b324cSopenharmony_ci UInt32 ci = _bindInfo.UnpackCoder; 649370b324cSopenharmony_ci 650370b324cSopenharmony_ci for (;;) 651370b324cSopenharmony_ci { 652370b324cSopenharmony_ci if (_bindInfo.Coders[ci].NumStreams == 0) 653370b324cSopenharmony_ci break; 654370b324cSopenharmony_ci 655370b324cSopenharmony_ci const UInt32 outIndex = _bindInfo.Coder_to_Stream[ci]; 656370b324cSopenharmony_ci const int bond = _bindInfo.FindBond_for_PackStream(outIndex); 657370b324cSopenharmony_ci if (bond >= 0) 658370b324cSopenharmony_ci { 659370b324cSopenharmony_ci ci = _bindInfo.Bonds[(unsigned)bond].UnpackIndex; 660370b324cSopenharmony_ci continue; 661370b324cSopenharmony_ci } 662370b324cSopenharmony_ci 663370b324cSopenharmony_ci const int si = _bindInfo.FindStream_in_PackStreams(outIndex); 664370b324cSopenharmony_ci if (si >= 0) 665370b324cSopenharmony_ci _bindInfo.PackStreams.MoveToFront((unsigned)si); 666370b324cSopenharmony_ci break; 667370b324cSopenharmony_ci } 668370b324cSopenharmony_ci } 669370b324cSopenharmony_ci 670370b324cSopenharmony_ci if (_options.PasswordIsDefined) 671370b324cSopenharmony_ci { 672370b324cSopenharmony_ci unsigned numCryptoStreams = _bindInfo.PackStreams.Size(); 673370b324cSopenharmony_ci 674370b324cSopenharmony_ci unsigned numInStreams = _bindInfo.Coders.Size(); 675370b324cSopenharmony_ci 676370b324cSopenharmony_ci for (i = 0; i < numCryptoStreams; i++) 677370b324cSopenharmony_ci { 678370b324cSopenharmony_ci NCoderMixer2::CBond bond; 679370b324cSopenharmony_ci bond.UnpackIndex = numInStreams + i; 680370b324cSopenharmony_ci bond.PackIndex = _bindInfo.PackStreams[i]; 681370b324cSopenharmony_ci _bindInfo.Bonds.Add(bond); 682370b324cSopenharmony_ci } 683370b324cSopenharmony_ci _bindInfo.PackStreams.Clear(); 684370b324cSopenharmony_ci 685370b324cSopenharmony_ci /* 686370b324cSopenharmony_ci if (numCryptoStreams == 0) 687370b324cSopenharmony_ci numCryptoStreams = 1; 688370b324cSopenharmony_ci */ 689370b324cSopenharmony_ci 690370b324cSopenharmony_ci for (i = 0; i < numCryptoStreams; i++) 691370b324cSopenharmony_ci { 692370b324cSopenharmony_ci CMethodFull method; 693370b324cSopenharmony_ci method.NumStreams = 1; 694370b324cSopenharmony_ci method.Id = k_AES; 695370b324cSopenharmony_ci _options.Methods.Add(method); 696370b324cSopenharmony_ci 697370b324cSopenharmony_ci NCoderMixer2::CCoderStreamsInfo cod; 698370b324cSopenharmony_ci cod.NumStreams = 1; 699370b324cSopenharmony_ci _bindInfo.Coders.Add(cod); 700370b324cSopenharmony_ci 701370b324cSopenharmony_ci _bindInfo.PackStreams.Add(numOutStreams++); 702370b324cSopenharmony_ci } 703370b324cSopenharmony_ci } 704370b324cSopenharmony_ci 705370b324cSopenharmony_ci } 706370b324cSopenharmony_ci 707370b324cSopenharmony_ci for (unsigned i = _options.Methods.Size(); i != 0;) 708370b324cSopenharmony_ci _decompressionMethods.Add(_options.Methods[--i].Id); 709370b324cSopenharmony_ci 710370b324cSopenharmony_ci if (_bindInfo.Coders.Size() > 16) 711370b324cSopenharmony_ci return E_INVALIDARG; 712370b324cSopenharmony_ci if (_bindInfo.GetNum_Bonds_and_PackStreams() > 16) 713370b324cSopenharmony_ci return E_INVALIDARG; 714370b324cSopenharmony_ci 715370b324cSopenharmony_ci if (!_bindInfo.CalcMapsAndCheck()) 716370b324cSopenharmony_ci return E_INVALIDARG; 717370b324cSopenharmony_ci 718370b324cSopenharmony_ci InitBindConv(); 719370b324cSopenharmony_ci _constructed = true; 720370b324cSopenharmony_ci return S_OK; 721370b324cSopenharmony_ci} 722370b324cSopenharmony_ci 723370b324cSopenharmony_ciCEncoder::~CEncoder() {} 724370b324cSopenharmony_ci 725370b324cSopenharmony_ci}} 726