7zencode.cpp
来自「由7-zip提供的压缩、解压缩程序」· C++ 代码 · 共 613 行 · 第 1/2 页
CPP
613 行
// 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_COPYstatic NArchive::N7z::CMethodID k_Copy = { { 0x0 }, 1 };#include "../../Compress/Copy/CopyCoder.h"#endifstatic NArchive::N7z::CMethodID k_LZMA = { { 0x3, 0x1, 0x1 }, 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_X86static NArchive::N7z::CMethodID k_BCJ_X86 = { { 0x3, 0x3, 0x1, 0x3 }, 4 };#include "../../Compress/Branch/x86.h"#endif#ifdef COMPRESS_BCJ2static 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 };#endifstatic NArchive::N7z::CMethodID k_AES = { { 0x6, 0xF1, 0x7, 0x1}, 4 };#ifndef EXCLUDE_COMstatic 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"#endifnamespace 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) { while (true) { 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);
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?