📄 7zencode.cpp
字号:
// 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
#ifdef COMPRESS_LZMA
#include "../../Compress/LZMA/LZMAEncoder.h"
static NArchive::N7z::CMethodID k_LZMA = { { 0x3, 0x1, 0x1 }, 3 };
#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()
{
_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
}
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);
values[i] = property.Value;
}
CMyComPtr<ICompressSetCoderProperties> setCoderProperties;
if (methodFull.IsSimpleCoder())
{
RINOK(encoder.QueryInterface(IID_ICompressSetCoderProperties,
&setCoderProperties));
}
else
{
RINOK(encoder2.QueryInterface(IID_ICompressSetCoderProperties,
&setCoderProperties));
}
RINOK(setCoderProperties->SetCoderProperties(&propIDs.Front(), values, numProperties));
}
catch(...)
{
delete []values;
throw;
}
delete []values;
}
CMyComPtr<ICompressWriteCoderProperties> writeCoderProperties;
if (methodFull.IsSimpleCoder())
{
encoder.QueryInterface(IID_ICompressWriteCoderProperties,
&writeCoderProperties);
}
else
{
encoder2.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;
if (methodFull.IsSimpleCoder())
{
encoder.QueryInterface(IID_ICryptoSetPassword, &cryptoSetPassword);
}
else
{
encoder2.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));
}
// public ICompressWriteCoderProperties,
if (methodFull.IsSimpleCoder())
{
_mixerCoderSpec->AddCoder(encoder);
}
else
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -