1*f6dc9357SAndroid Build Coastguard Worker // 7zEncode.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/ComTry.h"
6*f6dc9357SAndroid Build Coastguard Worker
7*f6dc9357SAndroid Build Coastguard Worker #include "../../Common/CreateCoder.h"
8*f6dc9357SAndroid Build Coastguard Worker #include "../../Common/FilterCoder.h"
9*f6dc9357SAndroid Build Coastguard Worker #include "../../Common/LimitedStreams.h"
10*f6dc9357SAndroid Build Coastguard Worker #include "../../Common/InOutTempBuffer.h"
11*f6dc9357SAndroid Build Coastguard Worker #include "../../Common/ProgressUtils.h"
12*f6dc9357SAndroid Build Coastguard Worker #include "../../Common/StreamObjects.h"
13*f6dc9357SAndroid Build Coastguard Worker
14*f6dc9357SAndroid Build Coastguard Worker #include "7zEncode.h"
15*f6dc9357SAndroid Build Coastguard Worker #include "7zSpecStream.h"
16*f6dc9357SAndroid Build Coastguard Worker
17*f6dc9357SAndroid Build Coastguard Worker namespace NArchive {
18*f6dc9357SAndroid Build Coastguard Worker namespace N7z {
19*f6dc9357SAndroid Build Coastguard Worker
InitBindConv()20*f6dc9357SAndroid Build Coastguard Worker void CEncoder::InitBindConv()
21*f6dc9357SAndroid Build Coastguard Worker {
22*f6dc9357SAndroid Build Coastguard Worker unsigned numIn = _bindInfo.Coders.Size();
23*f6dc9357SAndroid Build Coastguard Worker
24*f6dc9357SAndroid Build Coastguard Worker SrcIn_to_DestOut.ClearAndSetSize(numIn);
25*f6dc9357SAndroid Build Coastguard Worker DestOut_to_SrcIn.ClearAndSetSize(numIn);
26*f6dc9357SAndroid Build Coastguard Worker
27*f6dc9357SAndroid Build Coastguard Worker unsigned numOut = _bindInfo.GetNum_Bonds_and_PackStreams();
28*f6dc9357SAndroid Build Coastguard Worker SrcOut_to_DestIn.ClearAndSetSize(numOut);
29*f6dc9357SAndroid Build Coastguard Worker // _DestIn_to_SrcOut.ClearAndSetSize(numOut);
30*f6dc9357SAndroid Build Coastguard Worker
31*f6dc9357SAndroid Build Coastguard Worker UInt32 destIn = 0;
32*f6dc9357SAndroid Build Coastguard Worker UInt32 destOut = 0;
33*f6dc9357SAndroid Build Coastguard Worker
34*f6dc9357SAndroid Build Coastguard Worker for (unsigned i = _bindInfo.Coders.Size(); i != 0;)
35*f6dc9357SAndroid Build Coastguard Worker {
36*f6dc9357SAndroid Build Coastguard Worker i--;
37*f6dc9357SAndroid Build Coastguard Worker
38*f6dc9357SAndroid Build Coastguard Worker const NCoderMixer2::CCoderStreamsInfo &coder = _bindInfo.Coders[i];
39*f6dc9357SAndroid Build Coastguard Worker
40*f6dc9357SAndroid Build Coastguard Worker numIn--;
41*f6dc9357SAndroid Build Coastguard Worker numOut -= coder.NumStreams;
42*f6dc9357SAndroid Build Coastguard Worker
43*f6dc9357SAndroid Build Coastguard Worker SrcIn_to_DestOut[numIn] = destOut;
44*f6dc9357SAndroid Build Coastguard Worker DestOut_to_SrcIn[destOut] = numIn;
45*f6dc9357SAndroid Build Coastguard Worker
46*f6dc9357SAndroid Build Coastguard Worker destOut++;
47*f6dc9357SAndroid Build Coastguard Worker
48*f6dc9357SAndroid Build Coastguard Worker for (UInt32 j = 0; j < coder.NumStreams; j++, destIn++)
49*f6dc9357SAndroid Build Coastguard Worker {
50*f6dc9357SAndroid Build Coastguard Worker UInt32 index = numOut + j;
51*f6dc9357SAndroid Build Coastguard Worker SrcOut_to_DestIn[index] = destIn;
52*f6dc9357SAndroid Build Coastguard Worker // _DestIn_to_SrcOut[destIn] = index;
53*f6dc9357SAndroid Build Coastguard Worker }
54*f6dc9357SAndroid Build Coastguard Worker }
55*f6dc9357SAndroid Build Coastguard Worker }
56*f6dc9357SAndroid Build Coastguard Worker
SetFolder(CFolder & folder)57*f6dc9357SAndroid Build Coastguard Worker void CEncoder::SetFolder(CFolder &folder)
58*f6dc9357SAndroid Build Coastguard Worker {
59*f6dc9357SAndroid Build Coastguard Worker folder.Bonds.SetSize(_bindInfo.Bonds.Size());
60*f6dc9357SAndroid Build Coastguard Worker
61*f6dc9357SAndroid Build Coastguard Worker unsigned i;
62*f6dc9357SAndroid Build Coastguard Worker
63*f6dc9357SAndroid Build Coastguard Worker for (i = 0; i < _bindInfo.Bonds.Size(); i++)
64*f6dc9357SAndroid Build Coastguard Worker {
65*f6dc9357SAndroid Build Coastguard Worker CBond &fb = folder.Bonds[i];
66*f6dc9357SAndroid Build Coastguard Worker const NCoderMixer2::CBond &mixerBond = _bindInfo.Bonds[_bindInfo.Bonds.Size() - 1 - i];
67*f6dc9357SAndroid Build Coastguard Worker fb.PackIndex = SrcOut_to_DestIn[mixerBond.PackIndex];
68*f6dc9357SAndroid Build Coastguard Worker fb.UnpackIndex = SrcIn_to_DestOut[mixerBond.UnpackIndex];
69*f6dc9357SAndroid Build Coastguard Worker }
70*f6dc9357SAndroid Build Coastguard Worker
71*f6dc9357SAndroid Build Coastguard Worker folder.Coders.SetSize(_bindInfo.Coders.Size());
72*f6dc9357SAndroid Build Coastguard Worker
73*f6dc9357SAndroid Build Coastguard Worker for (i = 0; i < _bindInfo.Coders.Size(); i++)
74*f6dc9357SAndroid Build Coastguard Worker {
75*f6dc9357SAndroid Build Coastguard Worker CCoderInfo &coderInfo = folder.Coders[i];
76*f6dc9357SAndroid Build Coastguard Worker const NCoderMixer2::CCoderStreamsInfo &coderStreamsInfo = _bindInfo.Coders[_bindInfo.Coders.Size() - 1 - i];
77*f6dc9357SAndroid Build Coastguard Worker
78*f6dc9357SAndroid Build Coastguard Worker coderInfo.NumStreams = coderStreamsInfo.NumStreams;
79*f6dc9357SAndroid Build Coastguard Worker coderInfo.MethodID = _decompressionMethods[i];
80*f6dc9357SAndroid Build Coastguard Worker // we don't free coderInfo.Props here. So coderInfo.Props can be non-empty.
81*f6dc9357SAndroid Build Coastguard Worker }
82*f6dc9357SAndroid Build Coastguard Worker
83*f6dc9357SAndroid Build Coastguard Worker folder.PackStreams.SetSize(_bindInfo.PackStreams.Size());
84*f6dc9357SAndroid Build Coastguard Worker
85*f6dc9357SAndroid Build Coastguard Worker for (i = 0; i < _bindInfo.PackStreams.Size(); i++)
86*f6dc9357SAndroid Build Coastguard Worker folder.PackStreams[i] = SrcOut_to_DestIn[_bindInfo.PackStreams[i]];
87*f6dc9357SAndroid Build Coastguard Worker }
88*f6dc9357SAndroid Build Coastguard Worker
89*f6dc9357SAndroid Build Coastguard Worker
90*f6dc9357SAndroid Build Coastguard Worker
SetCoderProps2(const CProps & props,const UInt64 * dataSizeReduce,IUnknown * coder)91*f6dc9357SAndroid Build Coastguard Worker static HRESULT SetCoderProps2(const CProps &props, const UInt64 *dataSizeReduce, IUnknown *coder)
92*f6dc9357SAndroid Build Coastguard Worker {
93*f6dc9357SAndroid Build Coastguard Worker Z7_DECL_CMyComPtr_QI_FROM(
94*f6dc9357SAndroid Build Coastguard Worker ICompressSetCoderProperties,
95*f6dc9357SAndroid Build Coastguard Worker setCoderProperties, coder)
96*f6dc9357SAndroid Build Coastguard Worker if (setCoderProperties)
97*f6dc9357SAndroid Build Coastguard Worker return props.SetCoderProps(setCoderProperties, dataSizeReduce);
98*f6dc9357SAndroid Build Coastguard Worker return props.AreThereNonOptionalProps() ? E_INVALIDARG : S_OK;
99*f6dc9357SAndroid Build Coastguard Worker }
100*f6dc9357SAndroid Build Coastguard Worker
101*f6dc9357SAndroid Build Coastguard Worker
102*f6dc9357SAndroid Build Coastguard Worker
Init(ICompressProgressInfo * progress)103*f6dc9357SAndroid Build Coastguard Worker void CMtEncMultiProgress::Init(ICompressProgressInfo *progress)
104*f6dc9357SAndroid Build Coastguard Worker {
105*f6dc9357SAndroid Build Coastguard Worker _progress = progress;
106*f6dc9357SAndroid Build Coastguard Worker OutSize = 0;
107*f6dc9357SAndroid Build Coastguard Worker }
108*f6dc9357SAndroid Build Coastguard Worker
Z7_COM7F_IMF(CMtEncMultiProgress::SetRatioInfo (const UInt64 * inSize,const UInt64 *))109*f6dc9357SAndroid Build Coastguard Worker Z7_COM7F_IMF(CMtEncMultiProgress::SetRatioInfo(const UInt64 *inSize, const UInt64 * /* outSize */))
110*f6dc9357SAndroid Build Coastguard Worker {
111*f6dc9357SAndroid Build Coastguard Worker UInt64 outSize2;
112*f6dc9357SAndroid Build Coastguard Worker {
113*f6dc9357SAndroid Build Coastguard Worker #ifndef Z7_ST
114*f6dc9357SAndroid Build Coastguard Worker NWindows::NSynchronization::CCriticalSectionLock lock(CriticalSection);
115*f6dc9357SAndroid Build Coastguard Worker #endif
116*f6dc9357SAndroid Build Coastguard Worker outSize2 = OutSize;
117*f6dc9357SAndroid Build Coastguard Worker }
118*f6dc9357SAndroid Build Coastguard Worker
119*f6dc9357SAndroid Build Coastguard Worker if (_progress)
120*f6dc9357SAndroid Build Coastguard Worker return _progress->SetRatioInfo(inSize, &outSize2);
121*f6dc9357SAndroid Build Coastguard Worker
122*f6dc9357SAndroid Build Coastguard Worker return S_OK;
123*f6dc9357SAndroid Build Coastguard Worker }
124*f6dc9357SAndroid Build Coastguard Worker
125*f6dc9357SAndroid Build Coastguard Worker
126*f6dc9357SAndroid Build Coastguard Worker
CreateMixerCoder(DECL_EXTERNAL_CODECS_LOC_VARS const UInt64 * inSizeForReduce)127*f6dc9357SAndroid Build Coastguard Worker HRESULT CEncoder::CreateMixerCoder(
128*f6dc9357SAndroid Build Coastguard Worker DECL_EXTERNAL_CODECS_LOC_VARS
129*f6dc9357SAndroid Build Coastguard Worker const UInt64 *inSizeForReduce)
130*f6dc9357SAndroid Build Coastguard Worker {
131*f6dc9357SAndroid Build Coastguard Worker #ifdef USE_MIXER_MT
132*f6dc9357SAndroid Build Coastguard Worker #ifdef USE_MIXER_ST
133*f6dc9357SAndroid Build Coastguard Worker if (_options.MultiThreadMixer)
134*f6dc9357SAndroid Build Coastguard Worker #endif
135*f6dc9357SAndroid Build Coastguard Worker {
136*f6dc9357SAndroid Build Coastguard Worker _mixerMT = new NCoderMixer2::CMixerMT(true);
137*f6dc9357SAndroid Build Coastguard Worker _mixerRef = _mixerMT;
138*f6dc9357SAndroid Build Coastguard Worker _mixer = _mixerMT;
139*f6dc9357SAndroid Build Coastguard Worker }
140*f6dc9357SAndroid Build Coastguard Worker #ifdef USE_MIXER_ST
141*f6dc9357SAndroid Build Coastguard Worker else
142*f6dc9357SAndroid Build Coastguard Worker #endif
143*f6dc9357SAndroid Build Coastguard Worker #endif
144*f6dc9357SAndroid Build Coastguard Worker {
145*f6dc9357SAndroid Build Coastguard Worker #ifdef USE_MIXER_ST
146*f6dc9357SAndroid Build Coastguard Worker _mixerST = new NCoderMixer2::CMixerST(true);
147*f6dc9357SAndroid Build Coastguard Worker _mixerRef = _mixerST;
148*f6dc9357SAndroid Build Coastguard Worker _mixer = _mixerST;
149*f6dc9357SAndroid Build Coastguard Worker #endif
150*f6dc9357SAndroid Build Coastguard Worker }
151*f6dc9357SAndroid Build Coastguard Worker
152*f6dc9357SAndroid Build Coastguard Worker RINOK(_mixer->SetBindInfo(_bindInfo))
153*f6dc9357SAndroid Build Coastguard Worker
154*f6dc9357SAndroid Build Coastguard Worker FOR_VECTOR (m, _options.Methods)
155*f6dc9357SAndroid Build Coastguard Worker {
156*f6dc9357SAndroid Build Coastguard Worker const CMethodFull &methodFull = _options.Methods[m];
157*f6dc9357SAndroid Build Coastguard Worker
158*f6dc9357SAndroid Build Coastguard Worker CCreatedCoder cod;
159*f6dc9357SAndroid Build Coastguard Worker
160*f6dc9357SAndroid Build Coastguard Worker if (methodFull.CodecIndex >= 0)
161*f6dc9357SAndroid Build Coastguard Worker {
162*f6dc9357SAndroid Build Coastguard Worker RINOK(CreateCoder_Index(
163*f6dc9357SAndroid Build Coastguard Worker EXTERNAL_CODECS_LOC_VARS
164*f6dc9357SAndroid Build Coastguard Worker (unsigned)methodFull.CodecIndex, true, cod))
165*f6dc9357SAndroid Build Coastguard Worker }
166*f6dc9357SAndroid Build Coastguard Worker else
167*f6dc9357SAndroid Build Coastguard Worker {
168*f6dc9357SAndroid Build Coastguard Worker RINOK(CreateCoder_Id(
169*f6dc9357SAndroid Build Coastguard Worker EXTERNAL_CODECS_LOC_VARS
170*f6dc9357SAndroid Build Coastguard Worker methodFull.Id, true, cod))
171*f6dc9357SAndroid Build Coastguard Worker }
172*f6dc9357SAndroid Build Coastguard Worker
173*f6dc9357SAndroid Build Coastguard Worker if (!cod.Coder && !cod.Coder2)
174*f6dc9357SAndroid Build Coastguard Worker {
175*f6dc9357SAndroid Build Coastguard Worker return E_NOTIMPL; // unsupported method, if encoder
176*f6dc9357SAndroid Build Coastguard Worker // return E_FAIL;
177*f6dc9357SAndroid Build Coastguard Worker }
178*f6dc9357SAndroid Build Coastguard Worker
179*f6dc9357SAndroid Build Coastguard Worker if (cod.NumStreams != methodFull.NumStreams)
180*f6dc9357SAndroid Build Coastguard Worker return E_FAIL;
181*f6dc9357SAndroid Build Coastguard Worker
182*f6dc9357SAndroid Build Coastguard Worker CMyComPtr<IUnknown> encoderCommon = cod.Coder ? (IUnknown *)cod.Coder : (IUnknown *)cod.Coder2;
183*f6dc9357SAndroid Build Coastguard Worker
184*f6dc9357SAndroid Build Coastguard Worker #ifndef Z7_ST
185*f6dc9357SAndroid Build Coastguard Worker if (methodFull.Set_NumThreads)
186*f6dc9357SAndroid Build Coastguard Worker {
187*f6dc9357SAndroid Build Coastguard Worker CMyComPtr<ICompressSetCoderMt> setCoderMt;
188*f6dc9357SAndroid Build Coastguard Worker encoderCommon.QueryInterface(IID_ICompressSetCoderMt, &setCoderMt);
189*f6dc9357SAndroid Build Coastguard Worker if (setCoderMt)
190*f6dc9357SAndroid Build Coastguard Worker {
191*f6dc9357SAndroid Build Coastguard Worker RINOK(setCoderMt->SetNumberOfThreads(
192*f6dc9357SAndroid Build Coastguard Worker /* _options.NumThreads */
193*f6dc9357SAndroid Build Coastguard Worker methodFull.NumThreads
194*f6dc9357SAndroid Build Coastguard Worker ))
195*f6dc9357SAndroid Build Coastguard Worker }
196*f6dc9357SAndroid Build Coastguard Worker }
197*f6dc9357SAndroid Build Coastguard Worker #endif
198*f6dc9357SAndroid Build Coastguard Worker
199*f6dc9357SAndroid Build Coastguard Worker RINOK(SetCoderProps2(methodFull, inSizeForReduce, encoderCommon))
200*f6dc9357SAndroid Build Coastguard Worker
201*f6dc9357SAndroid Build Coastguard Worker /*
202*f6dc9357SAndroid Build Coastguard Worker CMyComPtr<ICryptoResetSalt> resetSalt;
203*f6dc9357SAndroid Build Coastguard Worker encoderCommon.QueryInterface(IID_ICryptoResetSalt, (void **)&resetSalt);
204*f6dc9357SAndroid Build Coastguard Worker if (resetSalt)
205*f6dc9357SAndroid Build Coastguard Worker {
206*f6dc9357SAndroid Build Coastguard Worker resetSalt->ResetSalt();
207*f6dc9357SAndroid Build Coastguard Worker }
208*f6dc9357SAndroid Build Coastguard Worker */
209*f6dc9357SAndroid Build Coastguard Worker
210*f6dc9357SAndroid Build Coastguard Worker // now there is no codec that uses another external codec
211*f6dc9357SAndroid Build Coastguard Worker /*
212*f6dc9357SAndroid Build Coastguard Worker #ifdef Z7_EXTERNAL_CODECS
213*f6dc9357SAndroid Build Coastguard Worker CMyComPtr<ISetCompressCodecsInfo> setCompressCodecsInfo;
214*f6dc9357SAndroid Build Coastguard Worker encoderCommon.QueryInterface(IID_ISetCompressCodecsInfo, (void **)&setCompressCodecsInfo);
215*f6dc9357SAndroid Build Coastguard Worker if (setCompressCodecsInfo)
216*f6dc9357SAndroid Build Coastguard Worker {
217*f6dc9357SAndroid Build Coastguard Worker // we must use g_ExternalCodecs also
218*f6dc9357SAndroid Build Coastguard Worker RINOK(setCompressCodecsInfo->SetCompressCodecsInfo(_externalCodecs->GetCodecs));
219*f6dc9357SAndroid Build Coastguard Worker }
220*f6dc9357SAndroid Build Coastguard Worker #endif
221*f6dc9357SAndroid Build Coastguard Worker */
222*f6dc9357SAndroid Build Coastguard Worker
223*f6dc9357SAndroid Build Coastguard Worker CMyComPtr<ICryptoSetPassword> cryptoSetPassword;
224*f6dc9357SAndroid Build Coastguard Worker encoderCommon.QueryInterface(IID_ICryptoSetPassword, &cryptoSetPassword);
225*f6dc9357SAndroid Build Coastguard Worker
226*f6dc9357SAndroid Build Coastguard Worker if (cryptoSetPassword)
227*f6dc9357SAndroid Build Coastguard Worker {
228*f6dc9357SAndroid Build Coastguard Worker const unsigned sizeInBytes = _options.Password.Len() * 2;
229*f6dc9357SAndroid Build Coastguard Worker CByteBuffer_Wipe buffer(sizeInBytes);
230*f6dc9357SAndroid Build Coastguard Worker for (unsigned i = 0; i < _options.Password.Len(); i++)
231*f6dc9357SAndroid Build Coastguard Worker {
232*f6dc9357SAndroid Build Coastguard Worker wchar_t c = _options.Password[i];
233*f6dc9357SAndroid Build Coastguard Worker ((Byte *)buffer)[i * 2] = (Byte)c;
234*f6dc9357SAndroid Build Coastguard Worker ((Byte *)buffer)[i * 2 + 1] = (Byte)(c >> 8);
235*f6dc9357SAndroid Build Coastguard Worker }
236*f6dc9357SAndroid Build Coastguard Worker RINOK(cryptoSetPassword->CryptoSetPassword((const Byte *)buffer, (UInt32)sizeInBytes))
237*f6dc9357SAndroid Build Coastguard Worker }
238*f6dc9357SAndroid Build Coastguard Worker
239*f6dc9357SAndroid Build Coastguard Worker _mixer->AddCoder(cod);
240*f6dc9357SAndroid Build Coastguard Worker }
241*f6dc9357SAndroid Build Coastguard Worker return S_OK;
242*f6dc9357SAndroid Build Coastguard Worker }
243*f6dc9357SAndroid Build Coastguard Worker
244*f6dc9357SAndroid Build Coastguard Worker
245*f6dc9357SAndroid Build Coastguard Worker
246*f6dc9357SAndroid Build Coastguard Worker Z7_CLASS_IMP_COM_1(
247*f6dc9357SAndroid Build Coastguard Worker CSequentialOutTempBufferImp2
248*f6dc9357SAndroid Build Coastguard Worker , ISequentialOutStream
249*f6dc9357SAndroid Build Coastguard Worker )
250*f6dc9357SAndroid Build Coastguard Worker public:
251*f6dc9357SAndroid Build Coastguard Worker CInOutTempBuffer TempBuffer;
252*f6dc9357SAndroid Build Coastguard Worker CMtEncMultiProgress *_mtProgressSpec;
253*f6dc9357SAndroid Build Coastguard Worker
254*f6dc9357SAndroid Build Coastguard Worker CSequentialOutTempBufferImp2(): _mtProgressSpec(NULL) {}
255*f6dc9357SAndroid Build Coastguard Worker };
256*f6dc9357SAndroid Build Coastguard Worker
257*f6dc9357SAndroid Build Coastguard Worker Z7_COM7F_IMF(CSequentialOutTempBufferImp2::Write(const void *data, UInt32 size, UInt32 *processed))
258*f6dc9357SAndroid Build Coastguard Worker {
259*f6dc9357SAndroid Build Coastguard Worker COM_TRY_BEGIN
260*f6dc9357SAndroid Build Coastguard Worker if (processed)
261*f6dc9357SAndroid Build Coastguard Worker *processed = 0;
262*f6dc9357SAndroid Build Coastguard Worker RINOK(TempBuffer.Write_HRESULT(data, size))
263*f6dc9357SAndroid Build Coastguard Worker if (processed)
264*f6dc9357SAndroid Build Coastguard Worker *processed = size;
265*f6dc9357SAndroid Build Coastguard Worker if (_mtProgressSpec)
266*f6dc9357SAndroid Build Coastguard Worker _mtProgressSpec->AddOutSize(size);
267*f6dc9357SAndroid Build Coastguard Worker return S_OK;
268*f6dc9357SAndroid Build Coastguard Worker COM_TRY_END
269*f6dc9357SAndroid Build Coastguard Worker }
270*f6dc9357SAndroid Build Coastguard Worker
271*f6dc9357SAndroid Build Coastguard Worker
272*f6dc9357SAndroid Build Coastguard Worker Z7_CLASS_IMP_COM_1(
273*f6dc9357SAndroid Build Coastguard Worker CSequentialOutMtNotify
274*f6dc9357SAndroid Build Coastguard Worker , ISequentialOutStream
275*f6dc9357SAndroid Build Coastguard Worker )
276*f6dc9357SAndroid Build Coastguard Worker public:
277*f6dc9357SAndroid Build Coastguard Worker CMyComPtr<ISequentialOutStream> _stream;
278*f6dc9357SAndroid Build Coastguard Worker CMtEncMultiProgress *_mtProgressSpec;
279*f6dc9357SAndroid Build Coastguard Worker
280*f6dc9357SAndroid Build Coastguard Worker CSequentialOutMtNotify(): _mtProgressSpec(NULL) {}
281*f6dc9357SAndroid Build Coastguard Worker };
282*f6dc9357SAndroid Build Coastguard Worker
283*f6dc9357SAndroid Build Coastguard Worker Z7_COM7F_IMF(CSequentialOutMtNotify::Write(const void *data, UInt32 size, UInt32 *processed))
284*f6dc9357SAndroid Build Coastguard Worker {
285*f6dc9357SAndroid Build Coastguard Worker UInt32 realProcessed = 0;
286*f6dc9357SAndroid Build Coastguard Worker HRESULT res = _stream->Write(data, size, &realProcessed);
287*f6dc9357SAndroid Build Coastguard Worker if (processed)
288*f6dc9357SAndroid Build Coastguard Worker *processed = realProcessed;
289*f6dc9357SAndroid Build Coastguard Worker if (_mtProgressSpec)
290*f6dc9357SAndroid Build Coastguard Worker _mtProgressSpec->AddOutSize(size);
291*f6dc9357SAndroid Build Coastguard Worker return res;
292*f6dc9357SAndroid Build Coastguard Worker }
293*f6dc9357SAndroid Build Coastguard Worker
294*f6dc9357SAndroid Build Coastguard Worker
295*f6dc9357SAndroid Build Coastguard Worker static HRESULT FillProps_from_Coder(IUnknown *coder, CByteBuffer &props)
296*f6dc9357SAndroid Build Coastguard Worker {
297*f6dc9357SAndroid Build Coastguard Worker Z7_DECL_CMyComPtr_QI_FROM(
298*f6dc9357SAndroid Build Coastguard Worker ICompressWriteCoderProperties,
299*f6dc9357SAndroid Build Coastguard Worker writeCoderProperties, coder)
300*f6dc9357SAndroid Build Coastguard Worker if (writeCoderProperties)
301*f6dc9357SAndroid Build Coastguard Worker {
302*f6dc9357SAndroid Build Coastguard Worker CMyComPtr2_Create<ISequentialOutStream, CDynBufSeqOutStream> outStreamSpec;
303*f6dc9357SAndroid Build Coastguard Worker outStreamSpec->Init();
304*f6dc9357SAndroid Build Coastguard Worker RINOK(writeCoderProperties->WriteCoderProperties(outStreamSpec))
305*f6dc9357SAndroid Build Coastguard Worker outStreamSpec->CopyToBuffer(props);
306*f6dc9357SAndroid Build Coastguard Worker }
307*f6dc9357SAndroid Build Coastguard Worker else
308*f6dc9357SAndroid Build Coastguard Worker props.Free();
309*f6dc9357SAndroid Build Coastguard Worker return S_OK;
310*f6dc9357SAndroid Build Coastguard Worker }
311*f6dc9357SAndroid Build Coastguard Worker
312*f6dc9357SAndroid Build Coastguard Worker HRESULT CEncoder::Encode1(
313*f6dc9357SAndroid Build Coastguard Worker DECL_EXTERNAL_CODECS_LOC_VARS
314*f6dc9357SAndroid Build Coastguard Worker ISequentialInStream *inStream,
315*f6dc9357SAndroid Build Coastguard Worker // const UInt64 *inStreamSize,
316*f6dc9357SAndroid Build Coastguard Worker const UInt64 *inSizeForReduce,
317*f6dc9357SAndroid Build Coastguard Worker UInt64 expectedDataSize,
318*f6dc9357SAndroid Build Coastguard Worker CFolder &folderItem,
319*f6dc9357SAndroid Build Coastguard Worker // CRecordVector<UInt64> &coderUnpackSizes,
320*f6dc9357SAndroid Build Coastguard Worker // UInt64 &unpackSize,
321*f6dc9357SAndroid Build Coastguard Worker ISequentialOutStream *outStream,
322*f6dc9357SAndroid Build Coastguard Worker CRecordVector<UInt64> &packSizes,
323*f6dc9357SAndroid Build Coastguard Worker ICompressProgressInfo *compressProgress)
324*f6dc9357SAndroid Build Coastguard Worker {
325*f6dc9357SAndroid Build Coastguard Worker RINOK(EncoderConstr())
326*f6dc9357SAndroid Build Coastguard Worker
327*f6dc9357SAndroid Build Coastguard Worker if (!_mixerRef)
328*f6dc9357SAndroid Build Coastguard Worker {
329*f6dc9357SAndroid Build Coastguard Worker RINOK(CreateMixerCoder(EXTERNAL_CODECS_LOC_VARS inSizeForReduce))
330*f6dc9357SAndroid Build Coastguard Worker }
331*f6dc9357SAndroid Build Coastguard Worker
332*f6dc9357SAndroid Build Coastguard Worker RINOK(_mixer->ReInit2())
333*f6dc9357SAndroid Build Coastguard Worker
334*f6dc9357SAndroid Build Coastguard Worker CMyComPtr2<ICompressProgressInfo, CMtEncMultiProgress> mtProgress;
335*f6dc9357SAndroid Build Coastguard Worker CMyComPtr2<ISequentialOutStream, CSequentialOutMtNotify> mtOutStreamNotify;
336*f6dc9357SAndroid Build Coastguard Worker
337*f6dc9357SAndroid Build Coastguard Worker CRecordVector<CSequentialOutTempBufferImp2 *> tempBufferSpecs;
338*f6dc9357SAndroid Build Coastguard Worker CObjectVector<CMyComPtr<ISequentialOutStream> > tempBuffers;
339*f6dc9357SAndroid Build Coastguard Worker
340*f6dc9357SAndroid Build Coastguard Worker unsigned i;
341*f6dc9357SAndroid Build Coastguard Worker
342*f6dc9357SAndroid Build Coastguard Worker for (i = 1; i < _bindInfo.PackStreams.Size(); i++)
343*f6dc9357SAndroid Build Coastguard Worker {
344*f6dc9357SAndroid Build Coastguard Worker CSequentialOutTempBufferImp2 *tempBufferSpec = new CSequentialOutTempBufferImp2();
345*f6dc9357SAndroid Build Coastguard Worker CMyComPtr<ISequentialOutStream> tempBuffer = tempBufferSpec;
346*f6dc9357SAndroid Build Coastguard Worker tempBufferSpecs.Add(tempBufferSpec);
347*f6dc9357SAndroid Build Coastguard Worker tempBuffers.Add(tempBuffer);
348*f6dc9357SAndroid Build Coastguard Worker }
349*f6dc9357SAndroid Build Coastguard Worker
350*f6dc9357SAndroid Build Coastguard Worker const unsigned numMethods = _bindInfo.Coders.Size();
351*f6dc9357SAndroid Build Coastguard Worker
352*f6dc9357SAndroid Build Coastguard Worker for (i = 0; i < numMethods; i++)
353*f6dc9357SAndroid Build Coastguard Worker _mixer->SetCoderInfo(i, NULL, NULL, false);
354*f6dc9357SAndroid Build Coastguard Worker
355*f6dc9357SAndroid Build Coastguard Worker
356*f6dc9357SAndroid Build Coastguard Worker /* inStreamSize can be used by BCJ2 to set optimal range of conversion.
357*f6dc9357SAndroid Build Coastguard Worker But current BCJ2 encoder uses also another way to check exact size of current file.
358*f6dc9357SAndroid Build Coastguard Worker So inStreamSize is not required. */
359*f6dc9357SAndroid Build Coastguard Worker
360*f6dc9357SAndroid Build Coastguard Worker /*
361*f6dc9357SAndroid Build Coastguard Worker if (inStreamSize)
362*f6dc9357SAndroid Build Coastguard Worker _mixer->SetCoderInfo(_bindInfo.UnpackCoder, inStreamSize, NULL);
363*f6dc9357SAndroid Build Coastguard Worker */
364*f6dc9357SAndroid Build Coastguard Worker
365*f6dc9357SAndroid Build Coastguard Worker
366*f6dc9357SAndroid Build Coastguard Worker /*
367*f6dc9357SAndroid Build Coastguard Worker CSequentialInStreamSizeCount2 *inStreamSizeCountSpec = new CSequentialInStreamSizeCount2;
368*f6dc9357SAndroid Build Coastguard Worker CMyComPtr<ISequentialInStream> inStreamSizeCount = inStreamSizeCountSpec;
369*f6dc9357SAndroid Build Coastguard Worker */
370*f6dc9357SAndroid Build Coastguard Worker
371*f6dc9357SAndroid Build Coastguard Worker CSequentialOutStreamSizeCount *outStreamSizeCountSpec = NULL;
372*f6dc9357SAndroid Build Coastguard Worker CMyComPtr<ISequentialOutStream> outStreamSizeCount;
373*f6dc9357SAndroid Build Coastguard Worker
374*f6dc9357SAndroid Build Coastguard Worker // inStreamSizeCountSpec->Init(inStream);
375*f6dc9357SAndroid Build Coastguard Worker
376*f6dc9357SAndroid Build Coastguard Worker // ISequentialInStream *inStreamPointer = inStreamSizeCount;
377*f6dc9357SAndroid Build Coastguard Worker ISequentialInStream *inStreamPointer = inStream;
378*f6dc9357SAndroid Build Coastguard Worker
379*f6dc9357SAndroid Build Coastguard Worker CRecordVector<ISequentialOutStream *> outStreamPointers;
380*f6dc9357SAndroid Build Coastguard Worker
381*f6dc9357SAndroid Build Coastguard Worker SetFolder(folderItem);
382*f6dc9357SAndroid Build Coastguard Worker
383*f6dc9357SAndroid Build Coastguard Worker for (i = 0; i < numMethods; i++)
384*f6dc9357SAndroid Build Coastguard Worker {
385*f6dc9357SAndroid Build Coastguard Worker IUnknown *coder = _mixer->GetCoder(i).GetUnknown();
386*f6dc9357SAndroid Build Coastguard Worker /*
387*f6dc9357SAndroid Build Coastguard Worker {
388*f6dc9357SAndroid Build Coastguard Worker CEncoder *sfEncoder = NULL;
389*f6dc9357SAndroid Build Coastguard Worker Z7_DECL_CMyComPtr_QI_FROM(
390*f6dc9357SAndroid Build Coastguard Worker IGetSfEncoderInternal,
391*f6dc9357SAndroid Build Coastguard Worker sf, coder)
392*f6dc9357SAndroid Build Coastguard Worker if (sf)
393*f6dc9357SAndroid Build Coastguard Worker {
394*f6dc9357SAndroid Build Coastguard Worker RINOK(sf->GetSfEncoder(&sfEncoder));
395*f6dc9357SAndroid Build Coastguard Worker if (!sfEncoder)
396*f6dc9357SAndroid Build Coastguard Worker return E_FAIL;
397*f6dc9357SAndroid Build Coastguard Worker
398*f6dc9357SAndroid Build Coastguard Worker }
399*f6dc9357SAndroid Build Coastguard Worker }
400*f6dc9357SAndroid Build Coastguard Worker */
401*f6dc9357SAndroid Build Coastguard Worker /*
402*f6dc9357SAndroid Build Coastguard Worker #ifdef Z7_EXTERNAL_CODECS
403*f6dc9357SAndroid Build Coastguard Worker {
404*f6dc9357SAndroid Build Coastguard Worker Z7_DECL_CMyComPtr_QI_FROM(
405*f6dc9357SAndroid Build Coastguard Worker ISetCompressCodecsInfo,
406*f6dc9357SAndroid Build Coastguard Worker setCompressCodecsInfo, coder)
407*f6dc9357SAndroid Build Coastguard Worker if (setCompressCodecsInfo)
408*f6dc9357SAndroid Build Coastguard Worker {
409*f6dc9357SAndroid Build Coastguard Worker // we must use g_ExternalCodecs also
410*f6dc9357SAndroid Build Coastguard Worker RINOK(setCompressCodecsInfo->SetCompressCodecsInfo(_externalCodecs->GetCodecs))
411*f6dc9357SAndroid Build Coastguard Worker }
412*f6dc9357SAndroid Build Coastguard Worker }
413*f6dc9357SAndroid Build Coastguard Worker #endif
414*f6dc9357SAndroid Build Coastguard Worker */
415*f6dc9357SAndroid Build Coastguard Worker {
416*f6dc9357SAndroid Build Coastguard Worker Z7_DECL_CMyComPtr_QI_FROM(
417*f6dc9357SAndroid Build Coastguard Worker ICryptoResetInitVector,
418*f6dc9357SAndroid Build Coastguard Worker resetInitVector, coder)
419*f6dc9357SAndroid Build Coastguard Worker if (resetInitVector)
420*f6dc9357SAndroid Build Coastguard Worker {
421*f6dc9357SAndroid Build Coastguard Worker RINOK(resetInitVector->ResetInitVector())
422*f6dc9357SAndroid Build Coastguard Worker }
423*f6dc9357SAndroid Build Coastguard Worker }
424*f6dc9357SAndroid Build Coastguard Worker {
425*f6dc9357SAndroid Build Coastguard Worker Z7_DECL_CMyComPtr_QI_FROM(
426*f6dc9357SAndroid Build Coastguard Worker ICompressSetCoderPropertiesOpt,
427*f6dc9357SAndroid Build Coastguard Worker optProps, coder)
428*f6dc9357SAndroid Build Coastguard Worker if (optProps)
429*f6dc9357SAndroid Build Coastguard Worker {
430*f6dc9357SAndroid Build Coastguard Worker const PROPID propID = NCoderPropID::kExpectedDataSize;
431*f6dc9357SAndroid Build Coastguard Worker NWindows::NCOM::CPropVariant prop = (UInt64)expectedDataSize;
432*f6dc9357SAndroid Build Coastguard Worker RINOK(optProps->SetCoderPropertiesOpt(&propID, &prop, 1))
433*f6dc9357SAndroid Build Coastguard Worker }
434*f6dc9357SAndroid Build Coastguard Worker }
435*f6dc9357SAndroid Build Coastguard Worker // we must write properties from coder after ResetInitVector()
436*f6dc9357SAndroid Build Coastguard Worker RINOK(FillProps_from_Coder(coder, folderItem.Coders[numMethods - 1 - i].Props))
437*f6dc9357SAndroid Build Coastguard Worker }
438*f6dc9357SAndroid Build Coastguard Worker
439*f6dc9357SAndroid Build Coastguard Worker _mixer->SelectMainCoder(false);
440*f6dc9357SAndroid Build Coastguard Worker const UInt32 mainCoder = _mixer->MainCoderIndex;
441*f6dc9357SAndroid Build Coastguard Worker
442*f6dc9357SAndroid Build Coastguard Worker bool useMtProgress = false;
443*f6dc9357SAndroid Build Coastguard Worker if (!_mixer->Is_PackSize_Correct_for_Coder(mainCoder))
444*f6dc9357SAndroid Build Coastguard Worker {
445*f6dc9357SAndroid Build Coastguard Worker #ifdef Z7_ST
446*f6dc9357SAndroid Build Coastguard Worker if (!_mixer->IsThere_ExternalCoder_in_PackTree(mainCoder))
447*f6dc9357SAndroid Build Coastguard Worker #endif
448*f6dc9357SAndroid Build Coastguard Worker useMtProgress = true;
449*f6dc9357SAndroid Build Coastguard Worker }
450*f6dc9357SAndroid Build Coastguard Worker
451*f6dc9357SAndroid Build Coastguard Worker if (useMtProgress)
452*f6dc9357SAndroid Build Coastguard Worker {
453*f6dc9357SAndroid Build Coastguard Worker mtProgress.SetFromCls(new CMtEncMultiProgress);
454*f6dc9357SAndroid Build Coastguard Worker mtProgress->Init(compressProgress);
455*f6dc9357SAndroid Build Coastguard Worker
456*f6dc9357SAndroid Build Coastguard Worker mtOutStreamNotify.SetFromCls(new CSequentialOutMtNotify);
457*f6dc9357SAndroid Build Coastguard Worker mtOutStreamNotify->_stream = outStream;
458*f6dc9357SAndroid Build Coastguard Worker mtOutStreamNotify->_mtProgressSpec = mtProgress.ClsPtr();
459*f6dc9357SAndroid Build Coastguard Worker
460*f6dc9357SAndroid Build Coastguard Worker FOR_VECTOR (t, tempBufferSpecs)
461*f6dc9357SAndroid Build Coastguard Worker {
462*f6dc9357SAndroid Build Coastguard Worker tempBufferSpecs[t]->_mtProgressSpec = mtProgress.ClsPtr();
463*f6dc9357SAndroid Build Coastguard Worker }
464*f6dc9357SAndroid Build Coastguard Worker }
465*f6dc9357SAndroid Build Coastguard Worker
466*f6dc9357SAndroid Build Coastguard Worker
467*f6dc9357SAndroid Build Coastguard Worker if (_bindInfo.PackStreams.Size() != 0)
468*f6dc9357SAndroid Build Coastguard Worker {
469*f6dc9357SAndroid Build Coastguard Worker outStreamSizeCountSpec = new CSequentialOutStreamSizeCount;
470*f6dc9357SAndroid Build Coastguard Worker outStreamSizeCount = outStreamSizeCountSpec;
471*f6dc9357SAndroid Build Coastguard Worker outStreamSizeCountSpec->SetStream(mtOutStreamNotify.IsDefined() ?
472*f6dc9357SAndroid Build Coastguard Worker mtOutStreamNotify.Interface() : outStream);
473*f6dc9357SAndroid Build Coastguard Worker outStreamSizeCountSpec->Init();
474*f6dc9357SAndroid Build Coastguard Worker outStreamPointers.Add(outStreamSizeCount);
475*f6dc9357SAndroid Build Coastguard Worker }
476*f6dc9357SAndroid Build Coastguard Worker
477*f6dc9357SAndroid Build Coastguard Worker for (i = 1; i < _bindInfo.PackStreams.Size(); i++)
478*f6dc9357SAndroid Build Coastguard Worker outStreamPointers.Add(tempBuffers[i - 1]);
479*f6dc9357SAndroid Build Coastguard Worker
480*f6dc9357SAndroid Build Coastguard Worker bool dataAfterEnd_Error;
481*f6dc9357SAndroid Build Coastguard Worker
482*f6dc9357SAndroid Build Coastguard Worker RINOK(_mixer->Code(
483*f6dc9357SAndroid Build Coastguard Worker &inStreamPointer,
484*f6dc9357SAndroid Build Coastguard Worker outStreamPointers.ConstData(),
485*f6dc9357SAndroid Build Coastguard Worker mtProgress.IsDefined() ? mtProgress.Interface() :
486*f6dc9357SAndroid Build Coastguard Worker compressProgress, dataAfterEnd_Error))
487*f6dc9357SAndroid Build Coastguard Worker
488*f6dc9357SAndroid Build Coastguard Worker if (_bindInfo.PackStreams.Size() != 0)
489*f6dc9357SAndroid Build Coastguard Worker packSizes.Add(outStreamSizeCountSpec->GetSize());
490*f6dc9357SAndroid Build Coastguard Worker
491*f6dc9357SAndroid Build Coastguard Worker for (i = 1; i < _bindInfo.PackStreams.Size(); i++)
492*f6dc9357SAndroid Build Coastguard Worker {
493*f6dc9357SAndroid Build Coastguard Worker CInOutTempBuffer &iotb = tempBufferSpecs[i - 1]->TempBuffer;
494*f6dc9357SAndroid Build Coastguard Worker RINOK(iotb.WriteToStream(outStream))
495*f6dc9357SAndroid Build Coastguard Worker packSizes.Add(iotb.GetDataSize());
496*f6dc9357SAndroid Build Coastguard Worker }
497*f6dc9357SAndroid Build Coastguard Worker
498*f6dc9357SAndroid Build Coastguard Worker /* Code() in some future codec can change properties.
499*f6dc9357SAndroid Build Coastguard Worker v23: so we fill properties again after Code() */
500*f6dc9357SAndroid Build Coastguard Worker for (i = 0; i < numMethods; i++)
501*f6dc9357SAndroid Build Coastguard Worker {
502*f6dc9357SAndroid Build Coastguard Worker IUnknown *coder = _mixer->GetCoder(i).GetUnknown();
503*f6dc9357SAndroid Build Coastguard Worker RINOK(FillProps_from_Coder(coder, folderItem.Coders[numMethods - 1 - i].Props))
504*f6dc9357SAndroid Build Coastguard Worker }
505*f6dc9357SAndroid Build Coastguard Worker
506*f6dc9357SAndroid Build Coastguard Worker return S_OK;
507*f6dc9357SAndroid Build Coastguard Worker }
508*f6dc9357SAndroid Build Coastguard Worker
509*f6dc9357SAndroid Build Coastguard Worker
510*f6dc9357SAndroid Build Coastguard Worker void CEncoder::Encode_Post(
511*f6dc9357SAndroid Build Coastguard Worker UInt64 unpackSize,
512*f6dc9357SAndroid Build Coastguard Worker CRecordVector<UInt64> &coderUnpackSizes)
513*f6dc9357SAndroid Build Coastguard Worker {
514*f6dc9357SAndroid Build Coastguard Worker // unpackSize = 0;
515*f6dc9357SAndroid Build Coastguard Worker for (unsigned i = 0; i < _bindInfo.Coders.Size(); i++)
516*f6dc9357SAndroid Build Coastguard Worker {
517*f6dc9357SAndroid Build Coastguard Worker const int bond = _bindInfo.FindBond_for_UnpackStream(DestOut_to_SrcIn[i]);
518*f6dc9357SAndroid Build Coastguard Worker UInt64 streamSize;
519*f6dc9357SAndroid Build Coastguard Worker if (bond < 0)
520*f6dc9357SAndroid Build Coastguard Worker {
521*f6dc9357SAndroid Build Coastguard Worker // streamSize = inStreamSizeCountSpec->GetSize();
522*f6dc9357SAndroid Build Coastguard Worker // unpackSize = streamSize;
523*f6dc9357SAndroid Build Coastguard Worker streamSize = unpackSize;
524*f6dc9357SAndroid Build Coastguard Worker }
525*f6dc9357SAndroid Build Coastguard Worker else
526*f6dc9357SAndroid Build Coastguard Worker streamSize = _mixer->GetBondStreamSize((unsigned)bond);
527*f6dc9357SAndroid Build Coastguard Worker coderUnpackSizes.Add(streamSize);
528*f6dc9357SAndroid Build Coastguard Worker }
529*f6dc9357SAndroid Build Coastguard Worker }
530*f6dc9357SAndroid Build Coastguard Worker
531*f6dc9357SAndroid Build Coastguard Worker
532*f6dc9357SAndroid Build Coastguard Worker CEncoder::CEncoder(const CCompressionMethodMode &options):
533*f6dc9357SAndroid Build Coastguard Worker _constructed(false)
534*f6dc9357SAndroid Build Coastguard Worker {
535*f6dc9357SAndroid Build Coastguard Worker if (options.IsEmpty())
536*f6dc9357SAndroid Build Coastguard Worker throw 1;
537*f6dc9357SAndroid Build Coastguard Worker
538*f6dc9357SAndroid Build Coastguard Worker _options = options;
539*f6dc9357SAndroid Build Coastguard Worker
540*f6dc9357SAndroid Build Coastguard Worker #ifdef USE_MIXER_ST
541*f6dc9357SAndroid Build Coastguard Worker _mixerST = NULL;
542*f6dc9357SAndroid Build Coastguard Worker #endif
543*f6dc9357SAndroid Build Coastguard Worker
544*f6dc9357SAndroid Build Coastguard Worker #ifdef USE_MIXER_MT
545*f6dc9357SAndroid Build Coastguard Worker _mixerMT = NULL;
546*f6dc9357SAndroid Build Coastguard Worker #endif
547*f6dc9357SAndroid Build Coastguard Worker
548*f6dc9357SAndroid Build Coastguard Worker _mixer = NULL;
549*f6dc9357SAndroid Build Coastguard Worker }
550*f6dc9357SAndroid Build Coastguard Worker
551*f6dc9357SAndroid Build Coastguard Worker
552*f6dc9357SAndroid Build Coastguard Worker HRESULT CEncoder::EncoderConstr()
553*f6dc9357SAndroid Build Coastguard Worker {
554*f6dc9357SAndroid Build Coastguard Worker if (_constructed)
555*f6dc9357SAndroid Build Coastguard Worker return S_OK;
556*f6dc9357SAndroid Build Coastguard Worker if (_options.Methods.IsEmpty())
557*f6dc9357SAndroid Build Coastguard Worker {
558*f6dc9357SAndroid Build Coastguard Worker // it has only password method;
559*f6dc9357SAndroid Build Coastguard Worker if (!_options.PasswordIsDefined)
560*f6dc9357SAndroid Build Coastguard Worker throw 1;
561*f6dc9357SAndroid Build Coastguard Worker if (!_options.Bonds.IsEmpty())
562*f6dc9357SAndroid Build Coastguard Worker throw 1;
563*f6dc9357SAndroid Build Coastguard Worker
564*f6dc9357SAndroid Build Coastguard Worker CMethodFull method;
565*f6dc9357SAndroid Build Coastguard Worker method.Id = k_AES;
566*f6dc9357SAndroid Build Coastguard Worker method.NumStreams = 1;
567*f6dc9357SAndroid Build Coastguard Worker _options.Methods.Add(method);
568*f6dc9357SAndroid Build Coastguard Worker
569*f6dc9357SAndroid Build Coastguard Worker NCoderMixer2::CCoderStreamsInfo coderStreamsInfo;
570*f6dc9357SAndroid Build Coastguard Worker coderStreamsInfo.NumStreams = 1;
571*f6dc9357SAndroid Build Coastguard Worker _bindInfo.Coders.Add(coderStreamsInfo);
572*f6dc9357SAndroid Build Coastguard Worker
573*f6dc9357SAndroid Build Coastguard Worker _bindInfo.PackStreams.Add(0);
574*f6dc9357SAndroid Build Coastguard Worker _bindInfo.UnpackCoder = 0;
575*f6dc9357SAndroid Build Coastguard Worker }
576*f6dc9357SAndroid Build Coastguard Worker else
577*f6dc9357SAndroid Build Coastguard Worker {
578*f6dc9357SAndroid Build Coastguard Worker
579*f6dc9357SAndroid Build Coastguard Worker UInt32 numOutStreams = 0;
580*f6dc9357SAndroid Build Coastguard Worker unsigned i;
581*f6dc9357SAndroid Build Coastguard Worker
582*f6dc9357SAndroid Build Coastguard Worker for (i = 0; i < _options.Methods.Size(); i++)
583*f6dc9357SAndroid Build Coastguard Worker {
584*f6dc9357SAndroid Build Coastguard Worker const CMethodFull &methodFull = _options.Methods[i];
585*f6dc9357SAndroid Build Coastguard Worker NCoderMixer2::CCoderStreamsInfo cod;
586*f6dc9357SAndroid Build Coastguard Worker
587*f6dc9357SAndroid Build Coastguard Worker cod.NumStreams = methodFull.NumStreams;
588*f6dc9357SAndroid Build Coastguard Worker
589*f6dc9357SAndroid Build Coastguard Worker if (_options.Bonds.IsEmpty())
590*f6dc9357SAndroid Build Coastguard Worker {
591*f6dc9357SAndroid Build Coastguard Worker // if there are no bonds in options, we create bonds via first streams of coders
592*f6dc9357SAndroid Build Coastguard Worker if (i != _options.Methods.Size() - 1)
593*f6dc9357SAndroid Build Coastguard Worker {
594*f6dc9357SAndroid Build Coastguard Worker NCoderMixer2::CBond bond;
595*f6dc9357SAndroid Build Coastguard Worker bond.PackIndex = numOutStreams;
596*f6dc9357SAndroid Build Coastguard Worker bond.UnpackIndex = i + 1; // it's next coder
597*f6dc9357SAndroid Build Coastguard Worker _bindInfo.Bonds.Add(bond);
598*f6dc9357SAndroid Build Coastguard Worker }
599*f6dc9357SAndroid Build Coastguard Worker else if (cod.NumStreams != 0)
600*f6dc9357SAndroid Build Coastguard Worker _bindInfo.PackStreams.Insert(0, numOutStreams);
601*f6dc9357SAndroid Build Coastguard Worker
602*f6dc9357SAndroid Build Coastguard Worker for (UInt32 j = 1; j < cod.NumStreams; j++)
603*f6dc9357SAndroid Build Coastguard Worker _bindInfo.PackStreams.Add(numOutStreams + j);
604*f6dc9357SAndroid Build Coastguard Worker }
605*f6dc9357SAndroid Build Coastguard Worker
606*f6dc9357SAndroid Build Coastguard Worker numOutStreams += cod.NumStreams;
607*f6dc9357SAndroid Build Coastguard Worker
608*f6dc9357SAndroid Build Coastguard Worker _bindInfo.Coders.Add(cod);
609*f6dc9357SAndroid Build Coastguard Worker }
610*f6dc9357SAndroid Build Coastguard Worker
611*f6dc9357SAndroid Build Coastguard Worker if (!_options.Bonds.IsEmpty())
612*f6dc9357SAndroid Build Coastguard Worker {
613*f6dc9357SAndroid Build Coastguard Worker for (i = 0; i < _options.Bonds.Size(); i++)
614*f6dc9357SAndroid Build Coastguard Worker {
615*f6dc9357SAndroid Build Coastguard Worker NCoderMixer2::CBond mixerBond;
616*f6dc9357SAndroid Build Coastguard Worker const CBond2 &bond = _options.Bonds[i];
617*f6dc9357SAndroid Build Coastguard Worker if (bond.InCoder >= _bindInfo.Coders.Size()
618*f6dc9357SAndroid Build Coastguard Worker || bond.OutCoder >= _bindInfo.Coders.Size()
619*f6dc9357SAndroid Build Coastguard Worker || bond.OutStream >= _bindInfo.Coders[bond.OutCoder].NumStreams)
620*f6dc9357SAndroid Build Coastguard Worker return E_INVALIDARG;
621*f6dc9357SAndroid Build Coastguard Worker mixerBond.PackIndex = _bindInfo.GetStream_for_Coder(bond.OutCoder) + bond.OutStream;
622*f6dc9357SAndroid Build Coastguard Worker mixerBond.UnpackIndex = bond.InCoder;
623*f6dc9357SAndroid Build Coastguard Worker _bindInfo.Bonds.Add(mixerBond);
624*f6dc9357SAndroid Build Coastguard Worker }
625*f6dc9357SAndroid Build Coastguard Worker
626*f6dc9357SAndroid Build Coastguard Worker for (i = 0; i < numOutStreams; i++)
627*f6dc9357SAndroid Build Coastguard Worker if (_bindInfo.FindBond_for_PackStream(i) == -1)
628*f6dc9357SAndroid Build Coastguard Worker _bindInfo.PackStreams.Add(i);
629*f6dc9357SAndroid Build Coastguard Worker }
630*f6dc9357SAndroid Build Coastguard Worker
631*f6dc9357SAndroid Build Coastguard Worker if (!_bindInfo.SetUnpackCoder())
632*f6dc9357SAndroid Build Coastguard Worker return E_INVALIDARG;
633*f6dc9357SAndroid Build Coastguard Worker
634*f6dc9357SAndroid Build Coastguard Worker if (!_bindInfo.CalcMapsAndCheck())
635*f6dc9357SAndroid Build Coastguard Worker return E_INVALIDARG;
636*f6dc9357SAndroid Build Coastguard Worker
637*f6dc9357SAndroid Build Coastguard Worker if (_bindInfo.PackStreams.Size() != 1)
638*f6dc9357SAndroid Build Coastguard Worker {
639*f6dc9357SAndroid Build Coastguard Worker /* main_PackStream is pack stream of main path of coders tree.
640*f6dc9357SAndroid Build Coastguard Worker We find main_PackStream, and place to start of list of out streams.
641*f6dc9357SAndroid Build Coastguard Worker It allows to use more optimal memory usage for temp buffers,
642*f6dc9357SAndroid Build Coastguard Worker if main_PackStream is largest stream. */
643*f6dc9357SAndroid Build Coastguard Worker
644*f6dc9357SAndroid Build Coastguard Worker UInt32 ci = _bindInfo.UnpackCoder;
645*f6dc9357SAndroid Build Coastguard Worker
646*f6dc9357SAndroid Build Coastguard Worker for (;;)
647*f6dc9357SAndroid Build Coastguard Worker {
648*f6dc9357SAndroid Build Coastguard Worker if (_bindInfo.Coders[ci].NumStreams == 0)
649*f6dc9357SAndroid Build Coastguard Worker break;
650*f6dc9357SAndroid Build Coastguard Worker
651*f6dc9357SAndroid Build Coastguard Worker const UInt32 outIndex = _bindInfo.Coder_to_Stream[ci];
652*f6dc9357SAndroid Build Coastguard Worker const int bond = _bindInfo.FindBond_for_PackStream(outIndex);
653*f6dc9357SAndroid Build Coastguard Worker if (bond >= 0)
654*f6dc9357SAndroid Build Coastguard Worker {
655*f6dc9357SAndroid Build Coastguard Worker ci = _bindInfo.Bonds[(unsigned)bond].UnpackIndex;
656*f6dc9357SAndroid Build Coastguard Worker continue;
657*f6dc9357SAndroid Build Coastguard Worker }
658*f6dc9357SAndroid Build Coastguard Worker
659*f6dc9357SAndroid Build Coastguard Worker const int si = _bindInfo.FindStream_in_PackStreams(outIndex);
660*f6dc9357SAndroid Build Coastguard Worker if (si >= 0)
661*f6dc9357SAndroid Build Coastguard Worker _bindInfo.PackStreams.MoveToFront((unsigned)si);
662*f6dc9357SAndroid Build Coastguard Worker break;
663*f6dc9357SAndroid Build Coastguard Worker }
664*f6dc9357SAndroid Build Coastguard Worker }
665*f6dc9357SAndroid Build Coastguard Worker
666*f6dc9357SAndroid Build Coastguard Worker if (_options.PasswordIsDefined)
667*f6dc9357SAndroid Build Coastguard Worker {
668*f6dc9357SAndroid Build Coastguard Worker unsigned numCryptoStreams = _bindInfo.PackStreams.Size();
669*f6dc9357SAndroid Build Coastguard Worker
670*f6dc9357SAndroid Build Coastguard Worker unsigned numInStreams = _bindInfo.Coders.Size();
671*f6dc9357SAndroid Build Coastguard Worker
672*f6dc9357SAndroid Build Coastguard Worker for (i = 0; i < numCryptoStreams; i++)
673*f6dc9357SAndroid Build Coastguard Worker {
674*f6dc9357SAndroid Build Coastguard Worker NCoderMixer2::CBond bond;
675*f6dc9357SAndroid Build Coastguard Worker bond.UnpackIndex = numInStreams + i;
676*f6dc9357SAndroid Build Coastguard Worker bond.PackIndex = _bindInfo.PackStreams[i];
677*f6dc9357SAndroid Build Coastguard Worker _bindInfo.Bonds.Add(bond);
678*f6dc9357SAndroid Build Coastguard Worker }
679*f6dc9357SAndroid Build Coastguard Worker _bindInfo.PackStreams.Clear();
680*f6dc9357SAndroid Build Coastguard Worker
681*f6dc9357SAndroid Build Coastguard Worker /*
682*f6dc9357SAndroid Build Coastguard Worker if (numCryptoStreams == 0)
683*f6dc9357SAndroid Build Coastguard Worker numCryptoStreams = 1;
684*f6dc9357SAndroid Build Coastguard Worker */
685*f6dc9357SAndroid Build Coastguard Worker
686*f6dc9357SAndroid Build Coastguard Worker for (i = 0; i < numCryptoStreams; i++)
687*f6dc9357SAndroid Build Coastguard Worker {
688*f6dc9357SAndroid Build Coastguard Worker CMethodFull method;
689*f6dc9357SAndroid Build Coastguard Worker method.NumStreams = 1;
690*f6dc9357SAndroid Build Coastguard Worker method.Id = k_AES;
691*f6dc9357SAndroid Build Coastguard Worker _options.Methods.Add(method);
692*f6dc9357SAndroid Build Coastguard Worker
693*f6dc9357SAndroid Build Coastguard Worker NCoderMixer2::CCoderStreamsInfo cod;
694*f6dc9357SAndroid Build Coastguard Worker cod.NumStreams = 1;
695*f6dc9357SAndroid Build Coastguard Worker _bindInfo.Coders.Add(cod);
696*f6dc9357SAndroid Build Coastguard Worker
697*f6dc9357SAndroid Build Coastguard Worker _bindInfo.PackStreams.Add(numOutStreams++);
698*f6dc9357SAndroid Build Coastguard Worker }
699*f6dc9357SAndroid Build Coastguard Worker }
700*f6dc9357SAndroid Build Coastguard Worker
701*f6dc9357SAndroid Build Coastguard Worker }
702*f6dc9357SAndroid Build Coastguard Worker
703*f6dc9357SAndroid Build Coastguard Worker for (unsigned i = _options.Methods.Size(); i != 0;)
704*f6dc9357SAndroid Build Coastguard Worker _decompressionMethods.Add(_options.Methods[--i].Id);
705*f6dc9357SAndroid Build Coastguard Worker
706*f6dc9357SAndroid Build Coastguard Worker if (_bindInfo.Coders.Size() > 16)
707*f6dc9357SAndroid Build Coastguard Worker return E_INVALIDARG;
708*f6dc9357SAndroid Build Coastguard Worker if (_bindInfo.GetNum_Bonds_and_PackStreams() > 16)
709*f6dc9357SAndroid Build Coastguard Worker return E_INVALIDARG;
710*f6dc9357SAndroid Build Coastguard Worker
711*f6dc9357SAndroid Build Coastguard Worker if (!_bindInfo.CalcMapsAndCheck())
712*f6dc9357SAndroid Build Coastguard Worker return E_INVALIDARG;
713*f6dc9357SAndroid Build Coastguard Worker
714*f6dc9357SAndroid Build Coastguard Worker InitBindConv();
715*f6dc9357SAndroid Build Coastguard Worker _constructed = true;
716*f6dc9357SAndroid Build Coastguard Worker return S_OK;
717*f6dc9357SAndroid Build Coastguard Worker }
718*f6dc9357SAndroid Build Coastguard Worker
719*f6dc9357SAndroid Build Coastguard Worker CEncoder::~CEncoder() {}
720*f6dc9357SAndroid Build Coastguard Worker
721*f6dc9357SAndroid Build Coastguard Worker }}
722