mirror of
https://github.com/Xevion/easy7zip.git
synced 2025-12-12 01:09:56 -06:00
4.44 beta
This commit is contained in:
committed by
Kornel Lesiński
parent
804edc5756
commit
d9666cf046
614
CPP/7zip/Archive/7z/7zEncode.cpp
Executable file
614
CPP/7zip/Archive/7z/7zEncode.cpp
Executable file
@@ -0,0 +1,614 @@
|
||||
// Encode.cpp
|
||||
|
||||
#include "StdAfx.h"
|
||||
|
||||
#include "7zEncode.h"
|
||||
#include "7zSpecStream.h"
|
||||
#include "7zMethods.h"
|
||||
|
||||
#include "../../IPassword.h"
|
||||
#include "../../Common/ProgressUtils.h"
|
||||
#include "../../Common/LimitedStreams.h"
|
||||
#include "../../Common/InOutTempBuffer.h"
|
||||
#include "../../Common/StreamObjects.h"
|
||||
#include "../Common/FilterCoder.h"
|
||||
|
||||
#ifdef COMPRESS_COPY
|
||||
static NArchive::N7z::CMethodID k_Copy = { { 0x0 }, 1 };
|
||||
#include "../../Compress/Copy/CopyCoder.h"
|
||||
#endif
|
||||
|
||||
static NArchive::N7z::CMethodID k_LZMA = { { 0x3, 0x1, 0x1 }, 3 };
|
||||
static NArchive::N7z::CMethodID k_LZMA2 = { { 0x3, 0x1, 0x2 }, 3 };
|
||||
|
||||
#ifdef COMPRESS_LZMA
|
||||
#include "../../Compress/LZMA/LZMAEncoder.h"
|
||||
#endif
|
||||
|
||||
#ifdef COMPRESS_PPMD
|
||||
#include "../../Compress/PPMD/PPMDEncoder.h"
|
||||
static NArchive::N7z::CMethodID k_PPMD = { { 0x3, 0x4, 0x1 }, 3 };
|
||||
#endif
|
||||
|
||||
#ifdef COMPRESS_BCJ_X86
|
||||
static NArchive::N7z::CMethodID k_BCJ_X86 = { { 0x3, 0x3, 0x1, 0x3 }, 4 };
|
||||
#include "../../Compress/Branch/x86.h"
|
||||
#endif
|
||||
|
||||
#ifdef COMPRESS_BCJ2
|
||||
static NArchive::N7z::CMethodID k_BCJ2 = { { 0x3, 0x3, 0x1, 0x1B }, 4 };
|
||||
#include "../../Compress/Branch/x86_2.h"
|
||||
#endif
|
||||
|
||||
#ifdef COMPRESS_DEFLATE
|
||||
#ifndef COMPRESS_DEFLATE_ENCODER
|
||||
#define COMPRESS_DEFLATE_ENCODER
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef COMPRESS_DEFLATE_ENCODER
|
||||
#include "../../Compress/Deflate/DeflateEncoder.h"
|
||||
static NArchive::N7z::CMethodID k_Deflate = { { 0x4, 0x1, 0x8 }, 3 };
|
||||
#endif
|
||||
|
||||
#ifdef COMPRESS_BZIP2
|
||||
#ifndef COMPRESS_BZIP2_ENCODER
|
||||
#define COMPRESS_BZIP2_ENCODER
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef COMPRESS_BZIP2_ENCODER
|
||||
#include "../../Compress/BZip2/BZip2Encoder.h"
|
||||
static NArchive::N7z::CMethodID k_BZip2 = { { 0x4, 0x2, 0x2 }, 3 };
|
||||
#endif
|
||||
|
||||
static NArchive::N7z::CMethodID k_AES = { { 0x6, 0xF1, 0x7, 0x1}, 4 };
|
||||
|
||||
#ifndef EXCLUDE_COM
|
||||
static const wchar_t *kCryproMethod = L"7zAES";
|
||||
/*
|
||||
// {23170F69-40C1-278B-06F1-070100000100}
|
||||
DEFINE_GUID(CLSID_CCrypto7zAESEncoder,
|
||||
0x23170F69, 0x40C1, 0x278B, 0x06, 0xF1, 0x07, 0x01, 0x00, 0x00, 0x01, 0x00);
|
||||
*/
|
||||
#endif
|
||||
|
||||
#ifdef CRYPTO_7ZAES
|
||||
#include "../../Crypto/7zAES/7zAES.h"
|
||||
#endif
|
||||
|
||||
namespace NArchive {
|
||||
namespace N7z {
|
||||
|
||||
static void ConvertBindInfoToFolderItemInfo(const NCoderMixer2::CBindInfo &bindInfo,
|
||||
const CRecordVector<CMethodID> decompressionMethods,
|
||||
CFolder &folder)
|
||||
{
|
||||
folder.Coders.Clear();
|
||||
// bindInfo.CoderMethodIDs.Clear();
|
||||
// folder.OutStreams.Clear();
|
||||
folder.PackStreams.Clear();
|
||||
folder.BindPairs.Clear();
|
||||
int i;
|
||||
for (i = 0; i < bindInfo.BindPairs.Size(); i++)
|
||||
{
|
||||
CBindPair bindPair;
|
||||
bindPair.InIndex = bindInfo.BindPairs[i].InIndex;
|
||||
bindPair.OutIndex = bindInfo.BindPairs[i].OutIndex;
|
||||
folder.BindPairs.Add(bindPair);
|
||||
}
|
||||
for (i = 0; i < bindInfo.Coders.Size(); i++)
|
||||
{
|
||||
CCoderInfo coderInfo;
|
||||
const NCoderMixer2::CCoderStreamsInfo &coderStreamsInfo = bindInfo.Coders[i];
|
||||
coderInfo.NumInStreams = coderStreamsInfo.NumInStreams;
|
||||
coderInfo.NumOutStreams = coderStreamsInfo.NumOutStreams;
|
||||
|
||||
// coderInfo.MethodID = decompressionMethods[i];
|
||||
// if (coderInfo.AltCoders.Size() == 0)
|
||||
coderInfo.AltCoders.Add(CAltCoderInfo());
|
||||
CAltCoderInfo &altCoderInfo = coderInfo.AltCoders.Front();
|
||||
altCoderInfo.MethodID = decompressionMethods[i];
|
||||
|
||||
folder.Coders.Add(coderInfo);
|
||||
}
|
||||
for (i = 0; i < bindInfo.InStreams.Size(); i++)
|
||||
folder.PackStreams.Add(bindInfo.InStreams[i]);
|
||||
}
|
||||
|
||||
HRESULT CEncoder::CreateMixerCoder(const UInt64 *inSizeForReduce)
|
||||
{
|
||||
_mixerCoderSpec = new NCoderMixer2::CCoderMixer2MT;
|
||||
_mixerCoder = _mixerCoderSpec;
|
||||
_mixerCoderSpec->SetBindInfo(_bindInfo);
|
||||
for (int i = 0; i < _options.Methods.Size(); i++)
|
||||
{
|
||||
const CMethodFull &methodFull = _options.Methods[i];
|
||||
_codersInfo.Add(CCoderInfo());
|
||||
CCoderInfo &encodingInfo = _codersInfo.Back();
|
||||
CMyComPtr<ICompressCoder> encoder;
|
||||
CMyComPtr<ICompressFilter> filter;
|
||||
CMyComPtr<ICompressCoder2> encoder2;
|
||||
|
||||
if (methodFull.IsSimpleCoder())
|
||||
{
|
||||
#ifdef COMPRESS_LZMA
|
||||
if (methodFull.MethodID == k_LZMA)
|
||||
encoder = new NCompress::NLZMA::CEncoder;
|
||||
#endif
|
||||
|
||||
#ifdef COMPRESS_PPMD
|
||||
if (methodFull.MethodID == k_PPMD)
|
||||
encoder = new NCompress::NPPMD::CEncoder;
|
||||
#endif
|
||||
|
||||
#ifdef COMPRESS_BCJ_X86
|
||||
if (methodFull.MethodID == k_BCJ_X86)
|
||||
filter = new CBCJ_x86_Encoder;
|
||||
#endif
|
||||
|
||||
#ifdef COMPRESS_COPY
|
||||
if (methodFull.MethodID == k_Copy)
|
||||
encoder = new NCompress::CCopyCoder;
|
||||
#endif
|
||||
|
||||
#ifdef COMPRESS_BZIP2_ENCODER
|
||||
if (methodFull.MethodID == k_BZip2)
|
||||
encoder = new NCompress::NBZip2::CEncoder;
|
||||
#endif
|
||||
|
||||
#ifdef COMPRESS_DEFLATE_ENCODER
|
||||
if (methodFull.MethodID == k_Deflate)
|
||||
encoder = new NCompress::NDeflate::NEncoder::CCOMCoder;
|
||||
#endif
|
||||
|
||||
#ifdef CRYPTO_7ZAES
|
||||
if (methodFull.MethodID == k_AES)
|
||||
filter = new NCrypto::NSevenZ::CEncoder;
|
||||
#endif
|
||||
|
||||
if (filter)
|
||||
{
|
||||
CFilterCoder *coderSpec = new CFilterCoder;
|
||||
encoder = coderSpec;
|
||||
coderSpec->Filter = filter;
|
||||
}
|
||||
|
||||
#ifndef EXCLUDE_COM
|
||||
if (encoder == 0)
|
||||
{
|
||||
RINOK(_libraries.CreateCoderSpec(methodFull.FilePath,
|
||||
methodFull.EncoderClassID, &encoder));
|
||||
}
|
||||
#endif
|
||||
|
||||
if (encoder == 0)
|
||||
return E_FAIL;
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
#ifdef COMPRESS_BCJ2
|
||||
if (methodFull.MethodID == k_BCJ2)
|
||||
encoder2 = new CBCJ2_x86_Encoder;
|
||||
#endif
|
||||
|
||||
#ifndef EXCLUDE_COM
|
||||
if (encoder2 == 0)
|
||||
{
|
||||
RINOK(_libraries.CreateCoder2(methodFull.FilePath,
|
||||
methodFull.EncoderClassID, &encoder2));
|
||||
}
|
||||
#else
|
||||
|
||||
if (encoder2 == 0)
|
||||
return E_FAIL;
|
||||
#endif
|
||||
}
|
||||
|
||||
bool tryReduce = false;
|
||||
UInt32 reducedDictionarySize = 1 << 10;
|
||||
if (inSizeForReduce != 0 && (methodFull.MethodID == k_LZMA || methodFull.MethodID == k_LZMA2))
|
||||
{
|
||||
for (;;)
|
||||
{
|
||||
const UInt32 step = (reducedDictionarySize >> 1);
|
||||
if (reducedDictionarySize >= *inSizeForReduce)
|
||||
{
|
||||
tryReduce = true;
|
||||
break;
|
||||
}
|
||||
reducedDictionarySize += step;
|
||||
if (reducedDictionarySize >= *inSizeForReduce)
|
||||
{
|
||||
tryReduce = true;
|
||||
break;
|
||||
}
|
||||
if (reducedDictionarySize >= ((UInt32)11 << 30))
|
||||
break;
|
||||
reducedDictionarySize += step;
|
||||
}
|
||||
}
|
||||
|
||||
CMyComPtr<IUnknown> encoderCommon = methodFull.IsSimpleCoder() ? (IUnknown *)encoder : (IUnknown *)encoder2;
|
||||
|
||||
#ifdef COMPRESS_MT
|
||||
{
|
||||
CMyComPtr<ICompressSetCoderMt> setCoderMt;
|
||||
encoderCommon.QueryInterface(IID_ICompressSetCoderMt, &setCoderMt);
|
||||
if (setCoderMt)
|
||||
{
|
||||
RINOK(setCoderMt->SetNumberOfThreads(_options.NumThreads));
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
if (methodFull.CoderProperties.Size() > 0)
|
||||
{
|
||||
CRecordVector<PROPID> propIDs;
|
||||
int numProperties = methodFull.CoderProperties.Size();
|
||||
NWindows::NCOM::CPropVariant *values = new NWindows::NCOM::CPropVariant[numProperties];
|
||||
try
|
||||
{
|
||||
for (int i = 0; i < numProperties; i++)
|
||||
{
|
||||
const CProperty &property = methodFull.CoderProperties[i];
|
||||
propIDs.Add(property.PropID);
|
||||
NWindows::NCOM::CPropVariant value = property.Value;
|
||||
if (tryReduce && property.PropID == NCoderPropID::kDictionarySize && value.vt == VT_UI4 && reducedDictionarySize < value.ulVal)
|
||||
value.ulVal = reducedDictionarySize;
|
||||
values[i] = value;
|
||||
}
|
||||
CMyComPtr<ICompressSetCoderProperties> setCoderProperties;
|
||||
RINOK(encoderCommon.QueryInterface(IID_ICompressSetCoderProperties, &setCoderProperties));
|
||||
RINOK(setCoderProperties->SetCoderProperties(&propIDs.Front(), values, numProperties));
|
||||
}
|
||||
catch(...)
|
||||
{
|
||||
delete []values;
|
||||
throw;
|
||||
}
|
||||
delete []values;
|
||||
}
|
||||
|
||||
CMyComPtr<ICompressWriteCoderProperties> writeCoderProperties;
|
||||
|
||||
encoderCommon.QueryInterface(IID_ICompressWriteCoderProperties, &writeCoderProperties);
|
||||
|
||||
if (writeCoderProperties != NULL)
|
||||
{
|
||||
CSequentialOutStreamImp *outStreamSpec = new CSequentialOutStreamImp;
|
||||
CMyComPtr<ISequentialOutStream> outStream(outStreamSpec);
|
||||
outStreamSpec->Init();
|
||||
writeCoderProperties->WriteCoderProperties(outStream);
|
||||
|
||||
size_t size = outStreamSpec->GetSize();
|
||||
|
||||
// encodingInfo.Properties.SetCapacity(size);
|
||||
if (encodingInfo.AltCoders.Size() == 0)
|
||||
encodingInfo.AltCoders.Add(CAltCoderInfo());
|
||||
CAltCoderInfo &altCoderInfo = encodingInfo.AltCoders.Front();
|
||||
altCoderInfo.Properties.SetCapacity(size);
|
||||
|
||||
memmove(altCoderInfo.Properties, outStreamSpec->GetBuffer(), size);
|
||||
}
|
||||
|
||||
CMyComPtr<ICryptoSetPassword> cryptoSetPassword;
|
||||
encoderCommon.QueryInterface(IID_ICryptoSetPassword, &cryptoSetPassword);
|
||||
|
||||
if (cryptoSetPassword)
|
||||
{
|
||||
CByteBuffer buffer;
|
||||
const UInt32 sizeInBytes = _options.Password.Length() * 2;
|
||||
buffer.SetCapacity(sizeInBytes);
|
||||
for (int i = 0; i < _options.Password.Length(); i++)
|
||||
{
|
||||
wchar_t c = _options.Password[i];
|
||||
((Byte *)buffer)[i * 2] = (Byte)c;
|
||||
((Byte *)buffer)[i * 2 + 1] = (Byte)(c >> 8);
|
||||
}
|
||||
RINOK(cryptoSetPassword->CryptoSetPassword((const Byte *)buffer, sizeInBytes));
|
||||
}
|
||||
|
||||
if (methodFull.IsSimpleCoder())
|
||||
_mixerCoderSpec->AddCoder(encoder);
|
||||
else
|
||||
_mixerCoderSpec->AddCoder2(encoder2);
|
||||
}
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT CEncoder::Encode(ISequentialInStream *inStream,
|
||||
const UInt64 *inStreamSize, const UInt64 *inSizeForReduce,
|
||||
CFolder &folderItem,
|
||||
ISequentialOutStream *outStream,
|
||||
CRecordVector<UInt64> &packSizes,
|
||||
ICompressProgressInfo *compressProgress)
|
||||
{
|
||||
if (_mixerCoderSpec == NULL)
|
||||
{
|
||||
RINOK(CreateMixerCoder(inSizeForReduce));
|
||||
}
|
||||
_mixerCoderSpec->ReInit();
|
||||
// _mixerCoderSpec->SetCoderInfo(0, NULL, NULL, progress);
|
||||
|
||||
CObjectVector<CInOutTempBuffer> inOutTempBuffers;
|
||||
CObjectVector<CSequentialOutTempBufferImp *> tempBufferSpecs;
|
||||
CObjectVector<CMyComPtr<ISequentialOutStream> > tempBuffers;
|
||||
int numMethods = _bindInfo.Coders.Size();
|
||||
int i;
|
||||
for (i = 1; i < _bindInfo.OutStreams.Size(); i++)
|
||||
{
|
||||
inOutTempBuffers.Add(CInOutTempBuffer());
|
||||
inOutTempBuffers.Back().Create();
|
||||
inOutTempBuffers.Back().InitWriting();
|
||||
}
|
||||
for (i = 1; i < _bindInfo.OutStreams.Size(); i++)
|
||||
{
|
||||
CSequentialOutTempBufferImp *tempBufferSpec =
|
||||
new CSequentialOutTempBufferImp;
|
||||
CMyComPtr<ISequentialOutStream> tempBuffer = tempBufferSpec;
|
||||
tempBufferSpec->Init(&inOutTempBuffers[i - 1]);
|
||||
tempBuffers.Add(tempBuffer);
|
||||
tempBufferSpecs.Add(tempBufferSpec);
|
||||
}
|
||||
|
||||
for (i = 0; i < numMethods; i++)
|
||||
_mixerCoderSpec->SetCoderInfo(i, NULL, NULL);
|
||||
|
||||
if (_bindInfo.InStreams.IsEmpty())
|
||||
return E_FAIL;
|
||||
UInt32 mainCoderIndex, mainStreamIndex;
|
||||
_bindInfo.FindInStream(_bindInfo.InStreams[0], mainCoderIndex, mainStreamIndex);
|
||||
_mixerCoderSpec->SetProgressCoderIndex(mainCoderIndex);
|
||||
if (inStreamSize != NULL)
|
||||
{
|
||||
CRecordVector<const UInt64 *> sizePointers;
|
||||
for (UInt32 i = 0; i < _bindInfo.Coders[mainCoderIndex].NumInStreams; i++)
|
||||
if (i == mainStreamIndex)
|
||||
sizePointers.Add(inStreamSize);
|
||||
else
|
||||
sizePointers.Add(NULL);
|
||||
_mixerCoderSpec->SetCoderInfo(mainCoderIndex, &sizePointers.Front(), NULL);
|
||||
}
|
||||
|
||||
|
||||
// UInt64 outStreamStartPos;
|
||||
// RINOK(stream->Seek(0, STREAM_SEEK_CUR, &outStreamStartPos));
|
||||
|
||||
CSequentialInStreamSizeCount2 *inStreamSizeCountSpec =
|
||||
new CSequentialInStreamSizeCount2;
|
||||
CMyComPtr<ISequentialInStream> inStreamSizeCount = inStreamSizeCountSpec;
|
||||
CSequentialOutStreamSizeCount *outStreamSizeCountSpec =
|
||||
new CSequentialOutStreamSizeCount;
|
||||
CMyComPtr<ISequentialOutStream> outStreamSizeCount = outStreamSizeCountSpec;
|
||||
|
||||
inStreamSizeCountSpec->Init(inStream);
|
||||
outStreamSizeCountSpec->SetStream(outStream);
|
||||
outStreamSizeCountSpec->Init();
|
||||
|
||||
CRecordVector<ISequentialInStream *> inStreamPointers;
|
||||
CRecordVector<ISequentialOutStream *> outStreamPointers;
|
||||
inStreamPointers.Add(inStreamSizeCount);
|
||||
outStreamPointers.Add(outStreamSizeCount);
|
||||
for (i = 1; i < _bindInfo.OutStreams.Size(); i++)
|
||||
outStreamPointers.Add(tempBuffers[i - 1]);
|
||||
|
||||
RINOK(_mixerCoder->Code(&inStreamPointers.Front(), NULL, 1,
|
||||
&outStreamPointers.Front(), NULL, outStreamPointers.Size(), compressProgress));
|
||||
|
||||
ConvertBindInfoToFolderItemInfo(_decompressBindInfo, _decompressionMethods,
|
||||
folderItem);
|
||||
|
||||
packSizes.Add(outStreamSizeCountSpec->GetSize());
|
||||
|
||||
for (i = 1; i < _bindInfo.OutStreams.Size(); i++)
|
||||
{
|
||||
CInOutTempBuffer &inOutTempBuffer = inOutTempBuffers[i - 1];
|
||||
inOutTempBuffer.FlushWrite();
|
||||
inOutTempBuffer.InitReading();
|
||||
inOutTempBuffer.WriteToStream(outStream);
|
||||
packSizes.Add(inOutTempBuffer.GetDataSize());
|
||||
}
|
||||
|
||||
for (i = 0; i < (int)_bindReverseConverter->NumSrcInStreams; i++)
|
||||
{
|
||||
int binder = _bindInfo.FindBinderForInStream(
|
||||
_bindReverseConverter->DestOutToSrcInMap[i]);
|
||||
UInt64 streamSize;
|
||||
if (binder < 0)
|
||||
streamSize = inStreamSizeCountSpec->GetSize();
|
||||
else
|
||||
streamSize = _mixerCoderSpec->GetWriteProcessedSize(binder);
|
||||
folderItem.UnPackSizes.Add(streamSize);
|
||||
}
|
||||
for (i = numMethods - 1; i >= 0; i--)
|
||||
{
|
||||
// folderItem.Coders[numMethods - 1 - i].Properties = _codersInfo[i].Properties;
|
||||
for (int j = 0; j < _codersInfo[i].AltCoders.Size(); j++)
|
||||
folderItem.Coders[numMethods - 1 - i].AltCoders[j].Properties
|
||||
= _codersInfo[i].AltCoders[j].Properties;
|
||||
}
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
|
||||
CEncoder::CEncoder(const CCompressionMethodMode &options):
|
||||
_bindReverseConverter(0)
|
||||
{
|
||||
if (options.IsEmpty())
|
||||
throw 1;
|
||||
|
||||
_options = options;
|
||||
_mixerCoderSpec = NULL;
|
||||
|
||||
if (options.Methods.IsEmpty())
|
||||
{
|
||||
// it has only password method;
|
||||
if (!options.PasswordIsDefined)
|
||||
throw 1;
|
||||
if (!options.Binds.IsEmpty())
|
||||
throw 1;
|
||||
NCoderMixer2::CCoderStreamsInfo coderStreamsInfo;
|
||||
CMethodFull method;
|
||||
|
||||
method.NumInStreams = 1;
|
||||
method.NumOutStreams = 1;
|
||||
coderStreamsInfo.NumInStreams = method.NumOutStreams;
|
||||
coderStreamsInfo.NumOutStreams = method.NumInStreams;
|
||||
method.MethodID = k_AES;
|
||||
|
||||
|
||||
#ifndef EXCLUDE_COM
|
||||
CMethodInfo2 methodInfo;
|
||||
if (!GetMethodInfo(kCryproMethod, methodInfo))
|
||||
throw 2;
|
||||
method.FilePath = methodInfo.FilePath;
|
||||
method.EncoderClassID = methodInfo.Encoder;
|
||||
// method.EncoderClassID = CLSID_CCrypto7zAESEncoder;
|
||||
#endif
|
||||
|
||||
_options.Methods.Add(method);
|
||||
_bindInfo.Coders.Add(coderStreamsInfo);
|
||||
|
||||
_bindInfo.InStreams.Add(0);
|
||||
_bindInfo.OutStreams.Add(0);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
UInt32 numInStreams = 0, numOutStreams = 0;
|
||||
int i;
|
||||
for (i = 0; i < options.Methods.Size(); i++)
|
||||
{
|
||||
const CMethodFull &methodFull = options.Methods[i];
|
||||
NCoderMixer2::CCoderStreamsInfo coderStreamsInfo;
|
||||
coderStreamsInfo.NumInStreams = methodFull.NumOutStreams;
|
||||
coderStreamsInfo.NumOutStreams = methodFull.NumInStreams;
|
||||
if (options.Binds.IsEmpty())
|
||||
{
|
||||
if (i < options.Methods.Size() - 1)
|
||||
{
|
||||
NCoderMixer2::CBindPair bindPair;
|
||||
bindPair.InIndex = numInStreams + coderStreamsInfo.NumInStreams;
|
||||
bindPair.OutIndex = numOutStreams;
|
||||
_bindInfo.BindPairs.Add(bindPair);
|
||||
}
|
||||
else
|
||||
_bindInfo.OutStreams.Insert(0, numOutStreams);
|
||||
for (UInt32 j = 1; j < coderStreamsInfo.NumOutStreams; j++)
|
||||
_bindInfo.OutStreams.Add(numOutStreams + j);
|
||||
}
|
||||
|
||||
numInStreams += coderStreamsInfo.NumInStreams;
|
||||
numOutStreams += coderStreamsInfo.NumOutStreams;
|
||||
|
||||
_bindInfo.Coders.Add(coderStreamsInfo);
|
||||
}
|
||||
|
||||
if (!options.Binds.IsEmpty())
|
||||
{
|
||||
for (i = 0; i < options.Binds.Size(); i++)
|
||||
{
|
||||
NCoderMixer2::CBindPair bindPair;
|
||||
const CBind &bind = options.Binds[i];
|
||||
bindPair.InIndex = _bindInfo.GetCoderInStreamIndex(bind.InCoder) + bind.InStream;
|
||||
bindPair.OutIndex = _bindInfo.GetCoderOutStreamIndex(bind.OutCoder) + bind.OutStream;
|
||||
_bindInfo.BindPairs.Add(bindPair);
|
||||
}
|
||||
for (i = 0; i < (int)numOutStreams; i++)
|
||||
if (_bindInfo.FindBinderForOutStream(i) == -1)
|
||||
_bindInfo.OutStreams.Add(i);
|
||||
}
|
||||
|
||||
for (i = 0; i < (int)numInStreams; i++)
|
||||
if (_bindInfo.FindBinderForInStream(i) == -1)
|
||||
_bindInfo.InStreams.Add(i);
|
||||
|
||||
if (_bindInfo.InStreams.IsEmpty())
|
||||
throw 1; // this is error
|
||||
|
||||
// Make main stream first in list
|
||||
int inIndex = _bindInfo.InStreams[0];
|
||||
for (;;)
|
||||
{
|
||||
UInt32 coderIndex, coderStreamIndex;
|
||||
_bindInfo.FindInStream(inIndex, coderIndex, coderStreamIndex);
|
||||
UInt32 outIndex = _bindInfo.GetCoderOutStreamIndex(coderIndex);
|
||||
int binder = _bindInfo.FindBinderForOutStream(outIndex);
|
||||
if (binder >= 0)
|
||||
{
|
||||
inIndex = _bindInfo.BindPairs[binder].InIndex;
|
||||
continue;
|
||||
}
|
||||
for (i = 0; i < _bindInfo.OutStreams.Size(); i++)
|
||||
if (_bindInfo.OutStreams[i] == outIndex)
|
||||
{
|
||||
_bindInfo.OutStreams.Delete(i);
|
||||
_bindInfo.OutStreams.Insert(0, outIndex);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if (_options.PasswordIsDefined)
|
||||
{
|
||||
int numCryptoStreams = _bindInfo.OutStreams.Size();
|
||||
|
||||
for (i = 0; i < numCryptoStreams; i++)
|
||||
{
|
||||
NCoderMixer2::CBindPair bindPair;
|
||||
bindPair.InIndex = numInStreams + i;
|
||||
bindPair.OutIndex = _bindInfo.OutStreams[i];
|
||||
_bindInfo.BindPairs.Add(bindPair);
|
||||
}
|
||||
_bindInfo.OutStreams.Clear();
|
||||
|
||||
/*
|
||||
if (numCryptoStreams == 0)
|
||||
numCryptoStreams = 1;
|
||||
*/
|
||||
|
||||
for (i = 0; i < numCryptoStreams; i++)
|
||||
{
|
||||
NCoderMixer2::CCoderStreamsInfo coderStreamsInfo;
|
||||
CMethodFull method;
|
||||
method.NumInStreams = 1;
|
||||
method.NumOutStreams = 1;
|
||||
coderStreamsInfo.NumInStreams = method.NumOutStreams;
|
||||
coderStreamsInfo.NumOutStreams = method.NumInStreams;
|
||||
method.MethodID = k_AES;
|
||||
|
||||
#ifndef EXCLUDE_COM
|
||||
CMethodInfo2 methodInfo;
|
||||
if (!GetMethodInfo(kCryproMethod, methodInfo))
|
||||
throw 2;
|
||||
method.FilePath = methodInfo.FilePath;
|
||||
method.EncoderClassID = methodInfo.Encoder;
|
||||
// method.EncoderClassID = CLSID_CCrypto7zAESEncoder;
|
||||
#endif
|
||||
|
||||
_options.Methods.Add(method);
|
||||
_bindInfo.Coders.Add(coderStreamsInfo);
|
||||
_bindInfo.OutStreams.Add(numOutStreams + i);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
for (int i = _options.Methods.Size() - 1; i >= 0; i--)
|
||||
{
|
||||
const CMethodFull &methodFull = _options.Methods[i];
|
||||
_decompressionMethods.Add(methodFull.MethodID);
|
||||
}
|
||||
|
||||
_bindReverseConverter = new NCoderMixer2::CBindReverseConverter(_bindInfo);
|
||||
_bindReverseConverter->CreateReverseBindInfo(_decompressBindInfo);
|
||||
}
|
||||
|
||||
CEncoder::~CEncoder()
|
||||
{
|
||||
delete _bindReverseConverter;
|
||||
}
|
||||
|
||||
}}
|
||||
Reference in New Issue
Block a user