1baa3858d3f5d128a5c8466b700098109edcad5f2repo sync// 7zEncode.cpp
2baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
3baa3858d3f5d128a5c8466b700098109edcad5f2repo sync#include "StdAfx.h"
4baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
5baa3858d3f5d128a5c8466b700098109edcad5f2repo sync#include "../../Common/CreateCoder.h"
6baa3858d3f5d128a5c8466b700098109edcad5f2repo sync#include "../../Common/FilterCoder.h"
7baa3858d3f5d128a5c8466b700098109edcad5f2repo sync#include "../../Common/LimitedStreams.h"
8baa3858d3f5d128a5c8466b700098109edcad5f2repo sync#include "../../Common/InOutTempBuffer.h"
9baa3858d3f5d128a5c8466b700098109edcad5f2repo sync#include "../../Common/ProgressUtils.h"
10baa3858d3f5d128a5c8466b700098109edcad5f2repo sync#include "../../Common/StreamObjects.h"
11baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
12baa3858d3f5d128a5c8466b700098109edcad5f2repo sync#include "7zEncode.h"
13baa3858d3f5d128a5c8466b700098109edcad5f2repo sync#include "7zSpecStream.h"
14baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
15baa3858d3f5d128a5c8466b700098109edcad5f2repo syncstatic const UInt64 k_Delta = 0x03;
16baa3858d3f5d128a5c8466b700098109edcad5f2repo syncstatic const UInt64 k_BCJ = 0x03030103;
17baa3858d3f5d128a5c8466b700098109edcad5f2repo syncstatic const UInt64 k_BCJ2 = 0x0303011B;
18baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
19baa3858d3f5d128a5c8466b700098109edcad5f2repo syncnamespace NArchive {
20baa3858d3f5d128a5c8466b700098109edcad5f2repo syncnamespace N7z {
21baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
22baa3858d3f5d128a5c8466b700098109edcad5f2repo syncstatic void ConvertBindInfoToFolderItemInfo(const NCoderMixer::CBindInfo &bindInfo,
23baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    const CRecordVector<CMethodId> decompressionMethods,
24baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    CFolder &folder)
25baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{
26baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  // bindInfo.CoderMethodIDs.Clear();
27baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  // folder.OutStreams.Clear();
28cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  folder.BindPairs.SetSize(bindInfo.BindPairs.Size());
29cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  unsigned i;
30baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  for (i = 0; i < bindInfo.BindPairs.Size(); i++)
31baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  {
32cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    CBindPair &bp = folder.BindPairs[i];
33cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    const NCoderMixer::CBindPair &mixerBp = bindInfo.BindPairs[i];
34cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    bp.InIndex = mixerBp.InIndex;
35cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    bp.OutIndex = mixerBp.OutIndex;
36baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  }
37cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  folder.Coders.SetSize(bindInfo.Coders.Size());
38baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  for (i = 0; i < bindInfo.Coders.Size(); i++)
39baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  {
40cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    CCoderInfo &coderInfo = folder.Coders[i];
41baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    const NCoderMixer::CCoderStreamsInfo &coderStreamsInfo = bindInfo.Coders[i];
42baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    coderInfo.NumInStreams = coderStreamsInfo.NumInStreams;
43baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    coderInfo.NumOutStreams = coderStreamsInfo.NumOutStreams;
44baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    coderInfo.MethodID = decompressionMethods[i];
45cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    // coderInfo.Props can be nonFree;
46baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  }
47cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  folder.PackStreams.SetSize(bindInfo.InStreams.Size());
48baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  for (i = 0; i < bindInfo.InStreams.Size(); i++)
49cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    folder.PackStreams[i] = bindInfo.InStreams[i];
50cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky}
51cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
52cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbeckystatic HRESULT SetCoderProps2(const CProps &props, const UInt64 *dataSizeReduce, IUnknown *coder)
53cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky{
54cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  CMyComPtr<ICompressSetCoderProperties> setCoderProperties;
55cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  coder->QueryInterface(IID_ICompressSetCoderProperties, (void **)&setCoderProperties);
56cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  if (setCoderProperties)
57cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    return props.SetCoderProps(setCoderProperties, dataSizeReduce);
58cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  return props.AreThereNonOptionalProps() ? E_INVALIDARG : S_OK;
59baa3858d3f5d128a5c8466b700098109edcad5f2repo sync}
60baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
61baa3858d3f5d128a5c8466b700098109edcad5f2repo syncHRESULT CEncoder::CreateMixerCoder(
62baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    DECL_EXTERNAL_CODECS_LOC_VARS
63baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    const UInt64 *inSizeForReduce)
64baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{
65baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  _mixerCoderSpec = new NCoderMixer::CCoderMixer2MT;
66baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  _mixerCoder = _mixerCoderSpec;
67baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  RINOK(_mixerCoderSpec->SetBindInfo(_bindInfo));
68cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  FOR_VECTOR (i, _options.Methods)
69baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  {
70baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    const CMethodFull &methodFull = _options.Methods[i];
71cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    CCoderInfo &encodingInfo = _codersInfo.AddNew();
72baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    encodingInfo.MethodID = methodFull.Id;
73baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    CMyComPtr<ICompressCoder> encoder;
74baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    CMyComPtr<ICompressCoder2> encoder2;
75baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
76baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
77baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    RINOK(CreateCoder(
78baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        EXTERNAL_CODECS_LOC_VARS
79baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        methodFull.Id, encoder, encoder2, true));
80baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
81baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    if (!encoder && !encoder2)
82baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      return E_FAIL;
83baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
84baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    CMyComPtr<IUnknown> encoderCommon = encoder ? (IUnknown *)encoder : (IUnknown *)encoder2;
85baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
86baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    #ifndef _7ZIP_ST
87baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    {
88baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      CMyComPtr<ICompressSetCoderMt> setCoderMt;
89baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      encoderCommon.QueryInterface(IID_ICompressSetCoderMt, &setCoderMt);
90baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      if (setCoderMt)
91baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      {
92baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        RINOK(setCoderMt->SetNumberOfThreads(_options.NumThreads));
93baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      }
94baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    }
95baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    #endif
96baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
97cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    RINOK(SetCoderProps2(methodFull, inSizeForReduce, encoderCommon));
98baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
99baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    /*
100baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    CMyComPtr<ICryptoResetSalt> resetSalt;
101baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    encoderCommon.QueryInterface(IID_ICryptoResetSalt, (void **)&resetSalt);
102cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    if (resetSalt)
103baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    {
104baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      resetSalt->ResetSalt();
105baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    }
106baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    */
107baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
108baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    #ifdef EXTERNAL_CODECS
109baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    CMyComPtr<ISetCompressCodecsInfo> setCompressCodecsInfo;
110baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    encoderCommon.QueryInterface(IID_ISetCompressCodecsInfo, (void **)&setCompressCodecsInfo);
111baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    if (setCompressCodecsInfo)
112baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    {
113cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      RINOK(setCompressCodecsInfo->SetCompressCodecsInfo(__externalCodecs->GetCodecs));
114baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    }
115baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    #endif
116baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
117baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    CMyComPtr<ICryptoSetPassword> cryptoSetPassword;
118baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    encoderCommon.QueryInterface(IID_ICryptoSetPassword, &cryptoSetPassword);
119baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
120baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    if (cryptoSetPassword)
121baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    {
122cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      const UInt32 sizeInBytes = _options.Password.Len() * 2;
123cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      CByteBuffer buffer(sizeInBytes);
124cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      for (unsigned i = 0; i < _options.Password.Len(); i++)
125baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      {
126baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        wchar_t c = _options.Password[i];
127baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        ((Byte *)buffer)[i * 2] = (Byte)c;
128baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        ((Byte *)buffer)[i * 2 + 1] = (Byte)(c >> 8);
129baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      }
130baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      RINOK(cryptoSetPassword->CryptoSetPassword((const Byte *)buffer, sizeInBytes));
131baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    }
132baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
133baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    if (encoder)
134baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      _mixerCoderSpec->AddCoder(encoder);
135baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    else
136baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      _mixerCoderSpec->AddCoder2(encoder2);
137baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  }
138baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  return S_OK;
139baa3858d3f5d128a5c8466b700098109edcad5f2repo sync}
140baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
141baa3858d3f5d128a5c8466b700098109edcad5f2repo syncHRESULT CEncoder::Encode(
142baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    DECL_EXTERNAL_CODECS_LOC_VARS
143baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    ISequentialInStream *inStream,
144baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    const UInt64 *inStreamSize, const UInt64 *inSizeForReduce,
145baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    CFolder &folderItem,
146cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    CRecordVector<UInt64> &coderUnpackSizes,
147cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    UInt64 &unpackSize,
148baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    ISequentialOutStream *outStream,
149baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    CRecordVector<UInt64> &packSizes,
150baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    ICompressProgressInfo *compressProgress)
151baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{
152baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  RINOK(EncoderConstr());
153baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
154cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  if (!_mixerCoderSpec)
155baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  {
156baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    RINOK(CreateMixerCoder(EXTERNAL_CODECS_LOC_VARS inSizeForReduce));
157baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  }
158baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  _mixerCoderSpec->ReInit();
159baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  // _mixerCoderSpec->SetCoderInfo(0, NULL, NULL, progress);
160baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
161baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  CObjectVector<CInOutTempBuffer> inOutTempBuffers;
162baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  CObjectVector<CSequentialOutTempBufferImp *> tempBufferSpecs;
163baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  CObjectVector<CMyComPtr<ISequentialOutStream> > tempBuffers;
164cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  unsigned numMethods = _bindInfo.Coders.Size();
165cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  unsigned i;
166baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  for (i = 1; i < _bindInfo.OutStreams.Size(); i++)
167baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  {
168cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    CInOutTempBuffer &iotb = inOutTempBuffers.AddNew();
169cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    iotb.Create();
170cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    iotb.InitWriting();
171baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  }
172baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  for (i = 1; i < _bindInfo.OutStreams.Size(); i++)
173baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  {
174baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    CSequentialOutTempBufferImp *tempBufferSpec = new CSequentialOutTempBufferImp;
175baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    CMyComPtr<ISequentialOutStream> tempBuffer = tempBufferSpec;
176baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    tempBufferSpec->Init(&inOutTempBuffers[i - 1]);
177baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    tempBuffers.Add(tempBuffer);
178baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    tempBufferSpecs.Add(tempBufferSpec);
179baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  }
180baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
181baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  for (i = 0; i < numMethods; i++)
182baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    _mixerCoderSpec->SetCoderInfo(i, NULL, NULL);
183baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
184baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  if (_bindInfo.InStreams.IsEmpty())
185baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    return E_FAIL;
186baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  UInt32 mainCoderIndex, mainStreamIndex;
187baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  _bindInfo.FindInStream(_bindInfo.InStreams[0], mainCoderIndex, mainStreamIndex);
188baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
189cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  if (inStreamSize)
190baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  {
191baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    CRecordVector<const UInt64 *> sizePointers;
192baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    for (UInt32 i = 0; i < _bindInfo.Coders[mainCoderIndex].NumInStreams; i++)
193baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      if (i == mainStreamIndex)
194baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        sizePointers.Add(inStreamSize);
195baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      else
196baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        sizePointers.Add(NULL);
197baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    _mixerCoderSpec->SetCoderInfo(mainCoderIndex, &sizePointers.Front(), NULL);
198baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  }
199baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
200baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
201baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  // UInt64 outStreamStartPos;
202baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  // RINOK(stream->Seek(0, STREAM_SEEK_CUR, &outStreamStartPos));
203baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
204baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  CSequentialInStreamSizeCount2 *inStreamSizeCountSpec = new CSequentialInStreamSizeCount2;
205baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  CMyComPtr<ISequentialInStream> inStreamSizeCount = inStreamSizeCountSpec;
206cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  CSequentialOutStreamSizeCount *outStreamSizeCountSpec = NULL;
207cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  CMyComPtr<ISequentialOutStream> outStreamSizeCount;
208baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
209baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  inStreamSizeCountSpec->Init(inStream);
210baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
211baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  CRecordVector<ISequentialInStream *> inStreamPointers;
212baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  CRecordVector<ISequentialOutStream *> outStreamPointers;
213baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  inStreamPointers.Add(inStreamSizeCount);
214cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
215cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  if (_bindInfo.OutStreams.Size() != 0)
216cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  {
217cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    outStreamSizeCountSpec = new CSequentialOutStreamSizeCount;
218cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    outStreamSizeCount = outStreamSizeCountSpec;
219cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    outStreamSizeCountSpec->SetStream(outStream);
220cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    outStreamSizeCountSpec->Init();
221cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    outStreamPointers.Add(outStreamSizeCount);
222cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  }
223cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
224baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  for (i = 1; i < _bindInfo.OutStreams.Size(); i++)
225baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    outStreamPointers.Add(tempBuffers[i - 1]);
226baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
227baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  for (i = 0; i < _codersInfo.Size(); i++)
228baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  {
229baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    CCoderInfo &encodingInfo = _codersInfo[i];
230baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
231baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    CMyComPtr<ICryptoResetInitVector> resetInitVector;
232baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    _mixerCoderSpec->_coders[i].QueryInterface(IID_ICryptoResetInitVector, (void **)&resetInitVector);
233cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    if (resetInitVector)
234baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    {
235baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      resetInitVector->ResetInitVector();
236baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    }
237baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
238baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    CMyComPtr<ICompressWriteCoderProperties> writeCoderProperties;
239baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    _mixerCoderSpec->_coders[i].QueryInterface(IID_ICompressWriteCoderProperties, (void **)&writeCoderProperties);
240cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    if (writeCoderProperties)
241baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    {
242baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      CDynBufSeqOutStream *outStreamSpec = new CDynBufSeqOutStream;
243baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      CMyComPtr<ISequentialOutStream> outStream(outStreamSpec);
244baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      outStreamSpec->Init();
245baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      writeCoderProperties->WriteCoderProperties(outStream);
246baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      outStreamSpec->CopyToBuffer(encodingInfo.Props);
247baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    }
248baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  }
249baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
250baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  UInt32 progressIndex = mainCoderIndex;
251baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
252baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  for (i = 0; i + 1 < _codersInfo.Size(); i++)
253baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  {
254baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    UInt64 m = _codersInfo[i].MethodID;
255baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    if (m == k_Delta || m == k_BCJ || m == k_BCJ2)
256baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      progressIndex = i + 1;
257baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  }
258baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
259baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  _mixerCoderSpec->SetProgressCoderIndex(progressIndex);
260baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
261baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  RINOK(_mixerCoder->Code(&inStreamPointers.Front(), NULL, 1,
262baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    &outStreamPointers.Front(), NULL, outStreamPointers.Size(), compressProgress));
263baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
264baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  ConvertBindInfoToFolderItemInfo(_decompressBindInfo, _decompressionMethods, folderItem);
265baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
266cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  if (_bindInfo.OutStreams.Size() != 0)
267cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    packSizes.Add(outStreamSizeCountSpec->GetSize());
268baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
269baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  for (i = 1; i < _bindInfo.OutStreams.Size(); i++)
270baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  {
271baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    CInOutTempBuffer &inOutTempBuffer = inOutTempBuffers[i - 1];
272baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    RINOK(inOutTempBuffer.WriteToStream(outStream));
273baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    packSizes.Add(inOutTempBuffer.GetDataSize());
274baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  }
275cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
276cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  unpackSize = 0;
277baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  for (i = 0; i < (int)_bindReverseConverter->NumSrcInStreams; i++)
278baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  {
279baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    int binder = _bindInfo.FindBinderForInStream(
280baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        _bindReverseConverter->DestOutToSrcInMap[i]);
281baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    UInt64 streamSize;
282baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    if (binder < 0)
283cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    {
284baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      streamSize = inStreamSizeCountSpec->GetSize();
285cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      unpackSize = streamSize;
286cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    }
287baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    else
288baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      streamSize = _mixerCoderSpec->GetWriteProcessedSize(binder);
289cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    coderUnpackSizes.Add(streamSize);
290baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  }
291cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  for (i = 0; i < numMethods; i++)
292baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    folderItem.Coders[numMethods - 1 - i].Props = _codersInfo[i].Props;
293baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  return S_OK;
294baa3858d3f5d128a5c8466b700098109edcad5f2repo sync}
295baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
296baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
297baa3858d3f5d128a5c8466b700098109edcad5f2repo syncCEncoder::CEncoder(const CCompressionMethodMode &options):
298baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  _bindReverseConverter(0),
299baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  _constructed(false)
300baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{
301baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  if (options.IsEmpty())
302baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    throw 1;
303baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
304baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  _options = options;
305baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  _mixerCoderSpec = NULL;
306baa3858d3f5d128a5c8466b700098109edcad5f2repo sync}
307baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
308baa3858d3f5d128a5c8466b700098109edcad5f2repo syncHRESULT CEncoder::EncoderConstr()
309baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{
310baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  if (_constructed)
311baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    return S_OK;
312baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  if (_options.Methods.IsEmpty())
313baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  {
314baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    // it has only password method;
315baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    if (!_options.PasswordIsDefined)
316baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      throw 1;
317baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    if (!_options.Binds.IsEmpty())
318baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      throw 1;
319baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    NCoderMixer::CCoderStreamsInfo coderStreamsInfo;
320baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    CMethodFull method;
321baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
322baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    method.NumInStreams = 1;
323baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    method.NumOutStreams = 1;
324baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    coderStreamsInfo.NumInStreams = 1;
325baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    coderStreamsInfo.NumOutStreams = 1;
326baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    method.Id = k_AES;
327baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
328baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    _options.Methods.Add(method);
329baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    _bindInfo.Coders.Add(coderStreamsInfo);
330baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
331baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    _bindInfo.InStreams.Add(0);
332baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    _bindInfo.OutStreams.Add(0);
333baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  }
334baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  else
335baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  {
336baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
337baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  UInt32 numInStreams = 0, numOutStreams = 0;
338cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  unsigned i;
339baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  for (i = 0; i < _options.Methods.Size(); i++)
340baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  {
341baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    const CMethodFull &methodFull = _options.Methods[i];
342baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    NCoderMixer::CCoderStreamsInfo coderStreamsInfo;
343baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    coderStreamsInfo.NumInStreams = methodFull.NumOutStreams;
344baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    coderStreamsInfo.NumOutStreams = methodFull.NumInStreams;
345baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    if (_options.Binds.IsEmpty())
346baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    {
347baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      if (i < _options.Methods.Size() - 1)
348baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      {
349baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        NCoderMixer::CBindPair bindPair;
350baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        bindPair.InIndex = numInStreams + coderStreamsInfo.NumInStreams;
351baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        bindPair.OutIndex = numOutStreams;
352baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        _bindInfo.BindPairs.Add(bindPair);
353baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      }
354cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      else if (coderStreamsInfo.NumOutStreams != 0)
355baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        _bindInfo.OutStreams.Insert(0, numOutStreams);
356baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      for (UInt32 j = 1; j < coderStreamsInfo.NumOutStreams; j++)
357baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        _bindInfo.OutStreams.Add(numOutStreams + j);
358baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    }
359baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
360baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    numInStreams += coderStreamsInfo.NumInStreams;
361baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    numOutStreams += coderStreamsInfo.NumOutStreams;
362baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
363baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    _bindInfo.Coders.Add(coderStreamsInfo);
364baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  }
365baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
366baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  if (!_options.Binds.IsEmpty())
367baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  {
368baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    for (i = 0; i < _options.Binds.Size(); i++)
369baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    {
370baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      NCoderMixer::CBindPair bindPair;
371baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      const CBind &bind = _options.Binds[i];
372baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      bindPair.InIndex = _bindInfo.GetCoderInStreamIndex(bind.InCoder) + bind.InStream;
373baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      bindPair.OutIndex = _bindInfo.GetCoderOutStreamIndex(bind.OutCoder) + bind.OutStream;
374baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      _bindInfo.BindPairs.Add(bindPair);
375baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    }
376baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    for (i = 0; i < (int)numOutStreams; i++)
377baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      if (_bindInfo.FindBinderForOutStream(i) == -1)
378baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        _bindInfo.OutStreams.Add(i);
379baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  }
380baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
381baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  for (i = 0; i < (int)numInStreams; i++)
382baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    if (_bindInfo.FindBinderForInStream(i) == -1)
383baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      _bindInfo.InStreams.Add(i);
384baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
385baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  if (_bindInfo.InStreams.IsEmpty())
386baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    throw 1; // this is error
387baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
388baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  // Make main stream first in list
389baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  int inIndex = _bindInfo.InStreams[0];
390baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  for (;;)
391baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  {
392baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    UInt32 coderIndex, coderStreamIndex;
393baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    _bindInfo.FindInStream(inIndex, coderIndex, coderStreamIndex);
394baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    UInt32 outIndex = _bindInfo.GetCoderOutStreamIndex(coderIndex);
395baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    int binder = _bindInfo.FindBinderForOutStream(outIndex);
396baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    if (binder >= 0)
397baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    {
398baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      inIndex = _bindInfo.BindPairs[binder].InIndex;
399baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      continue;
400baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    }
401baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    for (i = 0; i < _bindInfo.OutStreams.Size(); i++)
402baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      if (_bindInfo.OutStreams[i] == outIndex)
403baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      {
404baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        _bindInfo.OutStreams.Delete(i);
405baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        _bindInfo.OutStreams.Insert(0, outIndex);
406baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        break;
407baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      }
408baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    break;
409baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  }
410baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
411baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  if (_options.PasswordIsDefined)
412baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  {
413cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    unsigned numCryptoStreams = _bindInfo.OutStreams.Size();
414baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
415baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    for (i = 0; i < numCryptoStreams; i++)
416baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    {
417baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      NCoderMixer::CBindPair bindPair;
418baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      bindPair.InIndex = numInStreams + i;
419baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      bindPair.OutIndex = _bindInfo.OutStreams[i];
420baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      _bindInfo.BindPairs.Add(bindPair);
421baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    }
422baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    _bindInfo.OutStreams.Clear();
423baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
424baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    /*
425baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    if (numCryptoStreams == 0)
426baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      numCryptoStreams = 1;
427baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    */
428baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
429baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    for (i = 0; i < numCryptoStreams; i++)
430baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    {
431baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      NCoderMixer::CCoderStreamsInfo coderStreamsInfo;
432baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      CMethodFull method;
433baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      method.NumInStreams = 1;
434baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      method.NumOutStreams = 1;
435baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      coderStreamsInfo.NumInStreams = method.NumOutStreams;
436baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      coderStreamsInfo.NumOutStreams = method.NumInStreams;
437baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      method.Id = k_AES;
438baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
439baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      _options.Methods.Add(method);
440baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      _bindInfo.Coders.Add(coderStreamsInfo);
441baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      _bindInfo.OutStreams.Add(numOutStreams + i);
442baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    }
443baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  }
444baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
445baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  }
446baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
447baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  for (int i = _options.Methods.Size() - 1; i >= 0; i--)
448baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  {
449baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    const CMethodFull &methodFull = _options.Methods[i];
450baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    _decompressionMethods.Add(methodFull.Id);
451baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  }
452baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
453baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  _bindReverseConverter = new NCoderMixer::CBindReverseConverter(_bindInfo);
454baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  _bindReverseConverter->CreateReverseBindInfo(_decompressBindInfo);
455baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  _constructed = true;
456baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  return S_OK;
457baa3858d3f5d128a5c8466b700098109edcad5f2repo sync}
458baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
459baa3858d3f5d128a5c8466b700098109edcad5f2repo syncCEncoder::~CEncoder()
460baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{
461baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  delete _bindReverseConverter;
462baa3858d3f5d128a5c8466b700098109edcad5f2repo sync}
463baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
464baa3858d3f5d128a5c8466b700098109edcad5f2repo sync}}
465