mirror of
https://github.com/Xevion/easy7zip.git
synced 2025-12-07 03:15:00 -06:00
4.34 beta
This commit is contained in:
committed by
Kornel Lesiński
parent
02516d3fce
commit
0f60a4933b
@@ -43,7 +43,7 @@ RSC=rc.exe
|
||||
# PROP Ignore_Export_Lib 1
|
||||
# PROP Target_Dir ""
|
||||
# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "MY7Z_EXPORTS" /YX /FD /c
|
||||
# ADD CPP /nologo /Gz /MD /W3 /GX /O1 /I "..\..\..\\" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "MY7Z_EXPORTS" /Yu"StdAfx.h" /FD /c
|
||||
# ADD CPP /nologo /Gz /MD /W3 /GX /O1 /I "..\..\..\\" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "MY7Z_EXPORTS" /D "COMPRESS_MT" /Yu"StdAfx.h" /FD /c
|
||||
# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
|
||||
# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
|
||||
# ADD BASE RSC /l 0x419 /d "NDEBUG"
|
||||
@@ -70,7 +70,7 @@ LINK32=link.exe
|
||||
# PROP Ignore_Export_Lib 1
|
||||
# PROP Target_Dir ""
|
||||
# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "MY7Z_EXPORTS" /YX /FD /GZ /c
|
||||
# ADD CPP /nologo /Gz /MTd /W3 /Gm /GX /ZI /Od /I "..\..\..\\" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "MY7Z_EXPORTS" /Yu"StdAfx.h" /FD /GZ /c
|
||||
# ADD CPP /nologo /Gz /MTd /W3 /Gm /GX /ZI /Od /I "..\..\..\\" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "MY7Z_EXPORTS" /D "COMPRESS_MT" /Yu"StdAfx.h" /FD /GZ /c
|
||||
# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32
|
||||
# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32
|
||||
# ADD BASE RSC /l 0x419 /d "_DEBUG"
|
||||
@@ -254,10 +254,6 @@ SOURCE=..\..\ICoder.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\ICoderProperties.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\IMyUnknown.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
@@ -436,6 +432,14 @@ SOURCE=..\Common\OutStreamWithCRC.cpp
|
||||
|
||||
SOURCE=..\Common\OutStreamWithCRC.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\Common\ParseProperties.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\Common\ParseProperties.h
|
||||
# End Source File
|
||||
# End Group
|
||||
# Begin Group "7-Zip Common"
|
||||
|
||||
|
||||
@@ -45,12 +45,18 @@ struct CCompressionMethodMode
|
||||
{
|
||||
CObjectVector<CMethodFull> Methods;
|
||||
CRecordVector<CBind> Binds;
|
||||
bool MultiThread;
|
||||
#ifdef COMPRESS_MT
|
||||
UInt32 NumThreads;
|
||||
#endif
|
||||
bool PasswordIsDefined;
|
||||
UString Password;
|
||||
|
||||
bool IsEmpty() const { return (Methods.IsEmpty() && !PasswordIsDefined); }
|
||||
CCompressionMethodMode(): PasswordIsDefined(false), MultiThread(false) {}
|
||||
CCompressionMethodMode(): PasswordIsDefined(false)
|
||||
#ifdef COMPRESS_MT
|
||||
, NumThreads(1)
|
||||
#endif
|
||||
{}
|
||||
};
|
||||
|
||||
}}
|
||||
|
||||
@@ -155,6 +155,9 @@ HRESULT CDecoder::Decode(IInStream *inStream,
|
||||
#ifndef _NO_CRYPTO
|
||||
, ICryptoGetTextPassword *getTextPassword
|
||||
#endif
|
||||
#ifdef COMPRESS_MT
|
||||
, bool mtMode, UInt32 numThreads
|
||||
#endif
|
||||
)
|
||||
{
|
||||
CObjectVector< CMyComPtr<ISequentialInStream> > inStreams;
|
||||
@@ -329,50 +332,60 @@ HRESULT CDecoder::Decode(IInStream *inStream,
|
||||
{
|
||||
const CCoderInfo &coderInfo = folderInfo.Coders[i];
|
||||
const CAltCoderInfo &altCoderInfo = coderInfo.AltCoders.Front();
|
||||
CMyComPtr<ICompressSetDecoderProperties2> compressSetDecoderProperties;
|
||||
HRESULT result = _decoders[coderIndex].QueryInterface(
|
||||
IID_ICompressSetDecoderProperties2, &compressSetDecoderProperties);
|
||||
CMyComPtr<IUnknown> &decoder = _decoders[coderIndex];
|
||||
|
||||
if (result == S_OK)
|
||||
{
|
||||
const CByteBuffer &properties = altCoderInfo.Properties;
|
||||
size_t size = properties.GetCapacity();
|
||||
if (size > 0xFFFFFFFF)
|
||||
return E_NOTIMPL;
|
||||
if (size > 0)
|
||||
CMyComPtr<ICompressSetDecoderProperties2> setDecoderProperties;
|
||||
HRESULT result = decoder.QueryInterface(IID_ICompressSetDecoderProperties2, &setDecoderProperties);
|
||||
if (setDecoderProperties)
|
||||
{
|
||||
RINOK(compressSetDecoderProperties->SetDecoderProperties2((const Byte *)properties, (UInt32)size));
|
||||
const CByteBuffer &properties = altCoderInfo.Properties;
|
||||
size_t size = properties.GetCapacity();
|
||||
if (size > 0xFFFFFFFF)
|
||||
return E_NOTIMPL;
|
||||
if (size > 0)
|
||||
{
|
||||
RINOK(setDecoderProperties->SetDecoderProperties2((const Byte *)properties, (UInt32)size));
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (result != E_NOINTERFACE)
|
||||
return result;
|
||||
|
||||
#ifdef COMPRESS_MT
|
||||
if (mtMode)
|
||||
{
|
||||
CMyComPtr<ICompressSetCoderMt> setCoderMt;
|
||||
decoder.QueryInterface(IID_ICompressSetCoderMt, &setCoderMt);
|
||||
if (setCoderMt)
|
||||
{
|
||||
RINOK(setCoderMt->SetNumberOfThreads(numThreads));
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef _NO_CRYPTO
|
||||
CMyComPtr<ICryptoSetPassword> cryptoSetPassword;
|
||||
result = _decoders[coderIndex].QueryInterface(
|
||||
IID_ICryptoSetPassword, &cryptoSetPassword);
|
||||
|
||||
if (result == S_OK)
|
||||
{
|
||||
if (getTextPassword == 0)
|
||||
return E_FAIL;
|
||||
CMyComBSTR password;
|
||||
RINOK(getTextPassword->CryptoGetTextPassword(&password));
|
||||
CByteBuffer buffer;
|
||||
UString unicodePassword(password);
|
||||
const UInt32 sizeInBytes = unicodePassword.Length() * 2;
|
||||
buffer.SetCapacity(sizeInBytes);
|
||||
for (int i = 0; i < unicodePassword.Length(); i++)
|
||||
CMyComPtr<ICryptoSetPassword> cryptoSetPassword;
|
||||
HRESULT result = decoder.QueryInterface(IID_ICryptoSetPassword, &cryptoSetPassword);
|
||||
if (cryptoSetPassword)
|
||||
{
|
||||
wchar_t c = unicodePassword[i];
|
||||
((Byte *)buffer)[i * 2] = (Byte)c;
|
||||
((Byte *)buffer)[i * 2 + 1] = (Byte)(c >> 8);
|
||||
if (getTextPassword == 0)
|
||||
return E_FAIL;
|
||||
CMyComBSTR password;
|
||||
RINOK(getTextPassword->CryptoGetTextPassword(&password));
|
||||
CByteBuffer buffer;
|
||||
UString unicodePassword(password);
|
||||
const UInt32 sizeInBytes = unicodePassword.Length() * 2;
|
||||
buffer.SetCapacity(sizeInBytes);
|
||||
for (int i = 0; i < unicodePassword.Length(); i++)
|
||||
{
|
||||
wchar_t c = unicodePassword[i];
|
||||
((Byte *)buffer)[i * 2] = (Byte)c;
|
||||
((Byte *)buffer)[i * 2 + 1] = (Byte)(c >> 8);
|
||||
}
|
||||
RINOK(cryptoSetPassword->CryptoSetPassword(
|
||||
(const Byte *)buffer, sizeInBytes));
|
||||
}
|
||||
RINOK(cryptoSetPassword->CryptoSetPassword(
|
||||
(const Byte *)buffer, sizeInBytes));
|
||||
}
|
||||
else if (result != E_NOINTERFACE)
|
||||
return result;
|
||||
#endif
|
||||
|
||||
coderIndex++;
|
||||
|
||||
@@ -60,6 +60,9 @@ public:
|
||||
#ifndef _NO_CRYPTO
|
||||
, ICryptoGetTextPassword *getTextPasswordSpec
|
||||
#endif
|
||||
#ifdef COMPRESS_MT
|
||||
, bool mtMode, UInt32 numThreads
|
||||
#endif
|
||||
);
|
||||
};
|
||||
|
||||
|
||||
@@ -228,7 +228,20 @@ HRESULT CEncoder::CreateMixerCoder(const UInt64 *inSizeForReduce)
|
||||
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;
|
||||
@@ -246,16 +259,7 @@ HRESULT CEncoder::CreateMixerCoder(const UInt64 *inSizeForReduce)
|
||||
values[i] = value;
|
||||
}
|
||||
CMyComPtr<ICompressSetCoderProperties> setCoderProperties;
|
||||
if (methodFull.IsSimpleCoder())
|
||||
{
|
||||
RINOK(encoder.QueryInterface(IID_ICompressSetCoderProperties,
|
||||
&setCoderProperties));
|
||||
}
|
||||
else
|
||||
{
|
||||
RINOK(encoder2.QueryInterface(IID_ICompressSetCoderProperties,
|
||||
&setCoderProperties));
|
||||
}
|
||||
RINOK(encoderCommon.QueryInterface(IID_ICompressSetCoderProperties, &setCoderProperties));
|
||||
RINOK(setCoderProperties->SetCoderProperties(&propIDs.Front(), values, numProperties));
|
||||
}
|
||||
catch(...)
|
||||
@@ -268,16 +272,7 @@ HRESULT CEncoder::CreateMixerCoder(const UInt64 *inSizeForReduce)
|
||||
|
||||
CMyComPtr<ICompressWriteCoderProperties> writeCoderProperties;
|
||||
|
||||
if (methodFull.IsSimpleCoder())
|
||||
{
|
||||
encoder.QueryInterface(IID_ICompressWriteCoderProperties,
|
||||
&writeCoderProperties);
|
||||
}
|
||||
else
|
||||
{
|
||||
encoder2.QueryInterface(IID_ICompressWriteCoderProperties,
|
||||
&writeCoderProperties);
|
||||
}
|
||||
encoderCommon.QueryInterface(IID_ICompressWriteCoderProperties, &writeCoderProperties);
|
||||
|
||||
if (writeCoderProperties != NULL)
|
||||
{
|
||||
@@ -298,14 +293,7 @@ HRESULT CEncoder::CreateMixerCoder(const UInt64 *inSizeForReduce)
|
||||
}
|
||||
|
||||
CMyComPtr<ICryptoSetPassword> cryptoSetPassword;
|
||||
if (methodFull.IsSimpleCoder())
|
||||
{
|
||||
encoder.QueryInterface(IID_ICryptoSetPassword, &cryptoSetPassword);
|
||||
}
|
||||
else
|
||||
{
|
||||
encoder2.QueryInterface(IID_ICryptoSetPassword, &cryptoSetPassword);
|
||||
}
|
||||
encoderCommon.QueryInterface(IID_ICryptoSetPassword, &cryptoSetPassword);
|
||||
|
||||
if (cryptoSetPassword)
|
||||
{
|
||||
@@ -318,19 +306,13 @@ HRESULT CEncoder::CreateMixerCoder(const UInt64 *inSizeForReduce)
|
||||
((Byte *)buffer)[i * 2] = (Byte)c;
|
||||
((Byte *)buffer)[i * 2 + 1] = (Byte)(c >> 8);
|
||||
}
|
||||
RINOK(cryptoSetPassword->CryptoSetPassword(
|
||||
(const Byte *)buffer, sizeInBytes));
|
||||
RINOK(cryptoSetPassword->CryptoSetPassword((const Byte *)buffer, sizeInBytes));
|
||||
}
|
||||
|
||||
// public ICompressWriteCoderProperties,
|
||||
if (methodFull.IsSimpleCoder())
|
||||
{
|
||||
_mixerCoderSpec->AddCoder(encoder);
|
||||
}
|
||||
else
|
||||
{
|
||||
_mixerCoderSpec->AddCoder2(encoder2);
|
||||
}
|
||||
}
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
@@ -230,6 +230,9 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
|
||||
#ifndef _NO_CRYPTO
|
||||
, getTextPassword
|
||||
#endif
|
||||
#ifdef COMPRESS_MT
|
||||
, true, _numThreads
|
||||
#endif
|
||||
);
|
||||
|
||||
if (result == S_FALSE)
|
||||
|
||||
@@ -14,6 +14,12 @@
|
||||
#include "../Common/MultiStream.h"
|
||||
#endif
|
||||
|
||||
#ifdef __7Z_SET_PROPERTIES
|
||||
#ifdef EXTRACT_ONLY
|
||||
#include "../Common/ParseProperties.h"
|
||||
#endif
|
||||
#endif
|
||||
|
||||
using namespace NWindows;
|
||||
|
||||
namespace NArchive {
|
||||
@@ -21,6 +27,9 @@ namespace N7z {
|
||||
|
||||
CHandler::CHandler()
|
||||
{
|
||||
#ifdef COMPRESS_MT
|
||||
_numThreads = NWindows::NSystem::GetNumberOfProcessors();
|
||||
#endif
|
||||
#ifndef EXTRACT_ONLY
|
||||
Init();
|
||||
#endif
|
||||
@@ -708,4 +717,41 @@ STDMETHODIMP CHandler::GetStream(UInt32 index, ISequentialInStream **stream)
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef __7Z_SET_PROPERTIES
|
||||
#ifdef EXTRACT_ONLY
|
||||
|
||||
STDMETHODIMP CHandler::SetProperties(const wchar_t **names, const PROPVARIANT *values, Int32 numProperties)
|
||||
{
|
||||
COM_TRY_BEGIN
|
||||
const UInt32 numProcessors = NSystem::GetNumberOfProcessors();
|
||||
_numThreads = numProcessors;
|
||||
|
||||
for (int i = 0; i < numProperties; i++)
|
||||
{
|
||||
UString name = names[i];
|
||||
name.MakeUpper();
|
||||
if (name.IsEmpty())
|
||||
return E_INVALIDARG;
|
||||
const PROPVARIANT &value = values[i];
|
||||
UInt32 number;
|
||||
int index = ParseStringToUInt32(name, number);
|
||||
if (index == 0)
|
||||
{
|
||||
if(name.Left(2).CompareNoCase(L"MT") == 0)
|
||||
{
|
||||
RINOK(ParseMtProp(name.Mid(2), value, numProcessors, _numThreads));
|
||||
continue;
|
||||
}
|
||||
else
|
||||
return E_INVALIDARG;
|
||||
}
|
||||
}
|
||||
return S_OK;
|
||||
COM_TRY_END
|
||||
}
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
||||
}}
|
||||
|
||||
@@ -12,6 +12,10 @@
|
||||
#include "7zMethods.h"
|
||||
#endif
|
||||
|
||||
#ifdef COMPRESS_MT
|
||||
#include "../../../Windows/System.h"
|
||||
#endif
|
||||
|
||||
namespace NArchive {
|
||||
namespace N7z {
|
||||
|
||||
@@ -54,14 +58,29 @@ struct COneMethodInfo
|
||||
DEFINE_GUID(CLSID_CFormat7z,
|
||||
0x23170F69, 0x40C1, 0x278A, 0x10, 0x00, 0x00, 0x01, 0x10, 0x07, 0x00, 0x00);
|
||||
|
||||
#ifndef __7Z_SET_PROPERTIES
|
||||
|
||||
#ifdef EXTRACT_ONLY
|
||||
#ifdef COMPRESS_MT
|
||||
#define __7Z_SET_PROPERTIES
|
||||
#endif
|
||||
#else
|
||||
#define __7Z_SET_PROPERTIES
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
class CHandler:
|
||||
public IInArchive,
|
||||
#ifdef _7Z_VOL
|
||||
public IInArchiveGetStream,
|
||||
#endif
|
||||
#ifdef __7Z_SET_PROPERTIES
|
||||
public ISetProperties,
|
||||
#endif
|
||||
#ifndef EXTRACT_ONLY
|
||||
public IOutArchive,
|
||||
public ISetProperties,
|
||||
#endif
|
||||
public CMyUnknownImp
|
||||
{
|
||||
@@ -70,9 +89,11 @@ public:
|
||||
#ifdef _7Z_VOL
|
||||
MY_QUERYINTERFACE_ENTRY(IInArchiveGetStream)
|
||||
#endif
|
||||
#ifdef __7Z_SET_PROPERTIES
|
||||
MY_QUERYINTERFACE_ENTRY(ISetProperties)
|
||||
#endif
|
||||
#ifndef EXTRACT_ONLY
|
||||
MY_QUERYINTERFACE_ENTRY(IOutArchive)
|
||||
MY_QUERYINTERFACE_ENTRY(ISetProperties)
|
||||
#endif
|
||||
MY_QUERYINTERFACE_END
|
||||
MY_ADDREF_RELEASE
|
||||
@@ -101,6 +122,10 @@ public:
|
||||
STDMETHOD(GetStream)(UInt32 index, ISequentialInStream **stream);
|
||||
#endif
|
||||
|
||||
#ifdef __7Z_SET_PROPERTIES
|
||||
STDMETHOD(SetProperties)(const wchar_t **names, const PROPVARIANT *values, Int32 numProperties);
|
||||
#endif
|
||||
|
||||
#ifndef EXTRACT_ONLY
|
||||
// IOutArchiveHandler
|
||||
STDMETHOD(UpdateItems)(ISequentialOutStream *outStream, UInt32 numItems,
|
||||
@@ -109,7 +134,6 @@ public:
|
||||
STDMETHOD(GetFileTimeType)(UInt32 *type);
|
||||
|
||||
// ISetProperties
|
||||
STDMETHOD(SetProperties)(const wchar_t **names, const PROPVARIANT *values, Int32 numProperties);
|
||||
|
||||
HRESULT SetSolidSettings(const UString &s);
|
||||
HRESULT SetSolidSettings(const PROPVARIANT &value);
|
||||
@@ -126,6 +150,10 @@ private:
|
||||
NArchive::N7z::CArchiveDatabaseEx _database;
|
||||
#endif
|
||||
|
||||
#ifdef COMPRESS_MT
|
||||
UInt32 _numThreads;
|
||||
#endif
|
||||
|
||||
#ifndef EXTRACT_ONLY
|
||||
CObjectVector<COneMethodInfo> _methods;
|
||||
CRecordVector<CBind> _binds;
|
||||
@@ -144,18 +172,13 @@ private:
|
||||
UInt32 _defaultDicSize;
|
||||
UInt32 _defaultAlgorithm;
|
||||
UInt32 _defaultFastBytes;
|
||||
UInt32 _defaultPasses;
|
||||
UString _defaultMatchFinder;
|
||||
|
||||
UInt32 _defaultBZip2Passes;
|
||||
|
||||
UInt32 _defaultPpmdMemSize;
|
||||
UInt32 _defaultPpmdOrder;
|
||||
|
||||
UInt32 _defaultDeflateFastBytes;
|
||||
UInt32 _defaultDeflatePasses;
|
||||
|
||||
bool _autoFilter;
|
||||
bool _multiThread;
|
||||
UInt32 _level;
|
||||
|
||||
bool _volumeMode;
|
||||
@@ -168,8 +191,11 @@ private:
|
||||
IArchiveUpdateCallback *updateCallback);
|
||||
|
||||
HRESULT SetCompressionMethod(CCompressionMethodMode &method,
|
||||
CObjectVector<COneMethodInfo> &methodsInfo,
|
||||
bool multiThread);
|
||||
CObjectVector<COneMethodInfo> &methodsInfo
|
||||
#ifdef COMPRESS_MT
|
||||
, UInt32 numThreads
|
||||
#endif
|
||||
);
|
||||
|
||||
HRESULT SetCompressionMethod(
|
||||
CCompressionMethodMode &method,
|
||||
@@ -226,21 +252,19 @@ private:
|
||||
_compressHeaders = true;
|
||||
_compressHeadersFull = true;
|
||||
_encryptHeaders = false;
|
||||
_multiThread = false;
|
||||
#ifdef COMPRESS_MT
|
||||
_numThreads = NWindows::NSystem::GetNumberOfProcessors();
|
||||
#endif
|
||||
_copyMode = false;
|
||||
|
||||
_defaultDicSize = (1 << 22);
|
||||
_defaultAlgorithm = 1;
|
||||
_defaultFastBytes = 32;
|
||||
_defaultMatchFinder = L"BT4";
|
||||
_defaultDicSize =
|
||||
_defaultAlgorithm =
|
||||
_defaultFastBytes =
|
||||
_defaultPasses =
|
||||
_defaultPpmdMemSize =
|
||||
_defaultPpmdOrder = 0xFFFFFFFF;
|
||||
_defaultMatchFinder.Empty();
|
||||
|
||||
_defaultBZip2Passes = 1;
|
||||
|
||||
_defaultPpmdMemSize = (1 << 24);
|
||||
_defaultPpmdOrder = 6;
|
||||
|
||||
_defaultDeflateFastBytes = 32;
|
||||
_defaultDeflatePasses = 1;
|
||||
|
||||
_level = 5;
|
||||
_autoFilter = true;
|
||||
|
||||
@@ -8,12 +8,14 @@
|
||||
#include "7zMethods.h"
|
||||
|
||||
#include "../../../Windows/PropVariant.h"
|
||||
|
||||
#include "../../../Common/ComTry.h"
|
||||
#include "../../../Common/StringToInt.h"
|
||||
#include "../../IPassword.h"
|
||||
#include "../../ICoder.h"
|
||||
|
||||
#include "../Common/ItemNameUtils.h"
|
||||
#include "../Common/ParseProperties.h"
|
||||
|
||||
using namespace NWindows;
|
||||
|
||||
@@ -67,45 +69,53 @@ const wchar_t *kPpmdMethodName = L"PPMd";
|
||||
const wchar_t *kDeflateMethodName = L"Deflate";
|
||||
const wchar_t *kDeflate64MethodName = L"Deflate64";
|
||||
|
||||
static const wchar_t *kMatchFinderX1 = L"HC4";
|
||||
static const wchar_t *kMatchFinderX3 = L"HC4";
|
||||
static const wchar_t *kLzmaMatchFinderX1 = L"HC4";
|
||||
static const wchar_t *kLzmaMatchFinderX5 = L"BT4";
|
||||
|
||||
static const UInt32 kAlgorithmX1 = 0;
|
||||
static const UInt32 kAlgorithmX3 = 0;
|
||||
static const UInt32 kAlgorithmX7 = 1;
|
||||
static const UInt32 kAlgorithmX9 = 1;
|
||||
static const UInt32 kLzmaAlgorithmX1 = 0;
|
||||
static const UInt32 kLzmaAlgorithmX5 = 1;
|
||||
|
||||
static const UInt32 kDicSizeX1 = 1 << 16;
|
||||
static const UInt32 kDicSizeX3 = 1 << 20;
|
||||
static const UInt32 kDicSizeX7 = 1 << 24;
|
||||
static const UInt32 kDicSizeX9 = 1 << 26;
|
||||
static const UInt32 kLzmaDicSizeX1 = 1 << 16;
|
||||
static const UInt32 kLzmaDicSizeX3 = 1 << 20;
|
||||
static const UInt32 kLzmaDicSizeX5 = 1 << 22;
|
||||
static const UInt32 kLzmaDicSizeX7 = 1 << 24;
|
||||
static const UInt32 kLzmaDicSizeX9 = 1 << 26;
|
||||
|
||||
static const UInt32 kFastBytesX7 = 64;
|
||||
static const UInt32 kFastBytesX9 = 64;
|
||||
static const UInt32 kLzmaFastBytesX1 = 32;
|
||||
static const UInt32 kLzmaFastBytesX7 = 64;
|
||||
|
||||
static const UInt32 kPpmdMemSizeX1 = (1 << 22);
|
||||
static const UInt32 kPpmdMemSizeX5 = (1 << 24);
|
||||
static const UInt32 kPpmdMemSizeX7 = (1 << 26);
|
||||
static const UInt32 kPpmdMemSizeX9 = (192 << 20);
|
||||
|
||||
static const UInt32 kPpmdOrderX1 = 4;
|
||||
static const UInt32 kPpmdOrderX5 = 6;
|
||||
static const UInt32 kPpmdOrderX7 = 16;
|
||||
static const UInt32 kPpmdOrderX9 = 32;
|
||||
|
||||
static const UInt32 kDeflateFastBytesX1 = 32;
|
||||
static const UInt32 kDeflateFastBytesX7 = 64;
|
||||
static const UInt32 kDeflatePassesX7 = 3;
|
||||
static const UInt32 kDeflateFastBytesX9 = 128;
|
||||
|
||||
static const UInt32 kDeflateFastBytesX9 = 64;
|
||||
static const UInt32 kDeflatePassesX1 = 1;
|
||||
static const UInt32 kDeflatePassesX7 = 3;
|
||||
static const UInt32 kDeflatePassesX9 = 10;
|
||||
|
||||
static const UInt32 kNumBZip2PassesX1 = 1;
|
||||
static const UInt32 kNumBZip2PassesX7 = 2;
|
||||
static const UInt32 kNumBZip2PassesX9 = 7;
|
||||
static const UInt32 kBZip2NumPassesX1 = 1;
|
||||
static const UInt32 kBZip2NumPassesX7 = 2;
|
||||
static const UInt32 kBZip2NumPassesX9 = 7;
|
||||
|
||||
static const UInt32 kBZip2DicSizeX1 = 100000;
|
||||
static const UInt32 kBZip2DicSizeX3 = 500000;
|
||||
static const UInt32 kBZip2DicSizeX5 = 900000;
|
||||
|
||||
const wchar_t *kDefaultMethodName = kLZMAMethodName;
|
||||
|
||||
static const wchar_t *kMatchFinderForHeaders = L"BT2";
|
||||
static const wchar_t *kLzmaMatchFinderForHeaders = L"BT2";
|
||||
static const UInt32 kDictionaryForHeaders = 1 << 20;
|
||||
static const UInt32 kNumFastBytesForHeaders = 273;
|
||||
static const UInt32 kAlgorithmForHeaders = kLzmaAlgorithmX5;
|
||||
|
||||
static bool IsLZMAMethod(const UString &methodName)
|
||||
{ return (methodName.CompareNoCase(kLZMAMethodName) == 0); }
|
||||
@@ -168,9 +178,10 @@ CNameToPropID g_NameToPropID[] =
|
||||
|
||||
{ NCoderPropID::kNumPasses, VT_UI4, L"Pass" },
|
||||
{ NCoderPropID::kNumFastBytes, VT_UI4, L"fb" },
|
||||
{ NCoderPropID::kMatchFinderCycles, VT_UI4, L"mc" },
|
||||
{ NCoderPropID::kAlgorithm, VT_UI4, L"a" },
|
||||
{ NCoderPropID::kMatchFinder, VT_BSTR, L"mf" },
|
||||
{ NCoderPropID::kMultiThread, VT_BOOL, L"mt" }
|
||||
{ NCoderPropID::kNumThreads, VT_UI4, L"mt" }
|
||||
};
|
||||
|
||||
bool ConvertProperty(PROPVARIANT srcProp, VARTYPE varType,
|
||||
@@ -209,7 +220,12 @@ HRESULT CHandler::SetCompressionMethod(
|
||||
CCompressionMethodMode &methodMode,
|
||||
CCompressionMethodMode &headerMethod)
|
||||
{
|
||||
RINOK(SetCompressionMethod(methodMode, _methods, _multiThread));
|
||||
HRESULT res = SetCompressionMethod(methodMode, _methods
|
||||
#ifdef COMPRESS_MT
|
||||
, _numThreads
|
||||
#endif
|
||||
);
|
||||
RINOK(res);
|
||||
methodMode.Binds = _binds;
|
||||
if (_compressHeadersFull)
|
||||
_compressHeaders = true;
|
||||
@@ -224,13 +240,13 @@ HRESULT CHandler::SetCompressionMethod(
|
||||
{
|
||||
CProperty property;
|
||||
property.PropID = NCoderPropID::kMatchFinder;
|
||||
property.Value = kMatchFinderForHeaders;
|
||||
property.Value = kLzmaMatchFinderForHeaders;
|
||||
oneMethodInfo.CoderProperties.Add(property);
|
||||
}
|
||||
{
|
||||
CProperty property;
|
||||
property.PropID = NCoderPropID::kAlgorithm;
|
||||
property.Value = kAlgorithmX9;
|
||||
property.Value = kAlgorithmForHeaders;
|
||||
oneMethodInfo.CoderProperties.Add(property);
|
||||
}
|
||||
{
|
||||
@@ -246,7 +262,12 @@ HRESULT CHandler::SetCompressionMethod(
|
||||
oneMethodInfo.CoderProperties.Add(property);
|
||||
}
|
||||
headerMethodInfoVector.Add(oneMethodInfo);
|
||||
RINOK(SetCompressionMethod(headerMethod, headerMethodInfoVector, false));
|
||||
HRESULT res = SetCompressionMethod(headerMethod, headerMethodInfoVector
|
||||
#ifdef COMPRESS_MT
|
||||
,1
|
||||
#endif
|
||||
);
|
||||
RINOK(res);
|
||||
}
|
||||
return S_OK;
|
||||
}
|
||||
@@ -268,8 +289,11 @@ static void SetOneMethodProp(COneMethodInfo &oneMethodInfo, PROPID propID,
|
||||
|
||||
HRESULT CHandler::SetCompressionMethod(
|
||||
CCompressionMethodMode &methodMode,
|
||||
CObjectVector<COneMethodInfo> &methodsInfo,
|
||||
bool multiThread)
|
||||
CObjectVector<COneMethodInfo> &methodsInfo
|
||||
#ifdef COMPRESS_MT
|
||||
, UInt32 numThreads
|
||||
#endif
|
||||
)
|
||||
{
|
||||
#ifndef EXCLUDE_COM
|
||||
/*
|
||||
@@ -287,6 +311,8 @@ HRESULT CHandler::SetCompressionMethod(
|
||||
methodsInfo.Add(oneMethodInfo);
|
||||
}
|
||||
|
||||
UInt32 level = _level;
|
||||
|
||||
for(int i = 0; i < methodsInfo.Size(); i++)
|
||||
{
|
||||
COneMethodInfo &oneMethodInfo = methodsInfo[i];
|
||||
@@ -295,26 +321,94 @@ HRESULT CHandler::SetCompressionMethod(
|
||||
|
||||
if (IsLZMAMethod(oneMethodInfo.MethodName))
|
||||
{
|
||||
SetOneMethodProp(oneMethodInfo, NCoderPropID::kDictionarySize, _defaultDicSize);
|
||||
SetOneMethodProp(oneMethodInfo, NCoderPropID::kAlgorithm, _defaultAlgorithm);
|
||||
SetOneMethodProp(oneMethodInfo, NCoderPropID::kNumFastBytes, _defaultFastBytes);
|
||||
SetOneMethodProp(oneMethodInfo, NCoderPropID::kMatchFinder, (const wchar_t *)_defaultMatchFinder);
|
||||
if (multiThread)
|
||||
SetOneMethodProp(oneMethodInfo, NCoderPropID::kMultiThread, true);
|
||||
UInt32 dicSize = _defaultDicSize;
|
||||
if (dicSize == 0xFFFFFFFF)
|
||||
dicSize = (level >= 9 ? kLzmaDicSizeX9 :
|
||||
(level >= 7 ? kLzmaDicSizeX7 :
|
||||
(level >= 5 ? kLzmaDicSizeX5 :
|
||||
(level >= 3 ? kLzmaDicSizeX3 :
|
||||
kLzmaDicSizeX1))));
|
||||
|
||||
UInt32 algorithm = _defaultAlgorithm;
|
||||
if (algorithm == 0xFFFFFFFF)
|
||||
algorithm = (level >= 5 ? kLzmaAlgorithmX5 :
|
||||
kLzmaAlgorithmX1);
|
||||
|
||||
UInt32 fastBytes = _defaultFastBytes;
|
||||
if (fastBytes == 0xFFFFFFFF)
|
||||
fastBytes = (level >= 7 ? kLzmaFastBytesX7 :
|
||||
kLzmaFastBytesX1);
|
||||
|
||||
const wchar_t *matchFinder = 0;
|
||||
if (_defaultMatchFinder.IsEmpty())
|
||||
matchFinder = (level >= 5 ? kLzmaMatchFinderX5 :
|
||||
kLzmaMatchFinderX1);
|
||||
else
|
||||
matchFinder = (const wchar_t *)_defaultMatchFinder;
|
||||
|
||||
SetOneMethodProp(oneMethodInfo, NCoderPropID::kDictionarySize, dicSize);
|
||||
SetOneMethodProp(oneMethodInfo, NCoderPropID::kAlgorithm, algorithm);
|
||||
SetOneMethodProp(oneMethodInfo, NCoderPropID::kNumFastBytes, fastBytes);
|
||||
SetOneMethodProp(oneMethodInfo, NCoderPropID::kMatchFinder, matchFinder);
|
||||
#ifdef COMPRESS_MT
|
||||
SetOneMethodProp(oneMethodInfo, NCoderPropID::kNumThreads, numThreads);
|
||||
#endif
|
||||
}
|
||||
else if (IsDeflateMethod(oneMethodInfo.MethodName))
|
||||
{
|
||||
SetOneMethodProp(oneMethodInfo, NCoderPropID::kNumFastBytes, _defaultDeflateFastBytes);
|
||||
SetOneMethodProp(oneMethodInfo, NCoderPropID::kNumPasses, _defaultDeflatePasses);
|
||||
UInt32 fastBytes = _defaultFastBytes;
|
||||
if (fastBytes == 0xFFFFFFFF)
|
||||
fastBytes = (level >= 9 ? kDeflateFastBytesX9 :
|
||||
(level >= 7 ? kDeflateFastBytesX7 :
|
||||
kDeflateFastBytesX1));
|
||||
|
||||
UInt32 numPasses = _defaultPasses;
|
||||
if (numPasses == 0xFFFFFFFF)
|
||||
numPasses = (level >= 9 ? kDeflatePassesX9 :
|
||||
(level >= 7 ? kDeflatePassesX7 :
|
||||
kDeflatePassesX1));
|
||||
|
||||
SetOneMethodProp(oneMethodInfo, NCoderPropID::kNumFastBytes, fastBytes);
|
||||
SetOneMethodProp(oneMethodInfo, NCoderPropID::kNumPasses, numPasses);
|
||||
}
|
||||
else if (IsBZip2Method(oneMethodInfo.MethodName))
|
||||
{
|
||||
SetOneMethodProp(oneMethodInfo, NCoderPropID::kNumPasses, _defaultBZip2Passes);
|
||||
UInt32 numPasses = _defaultPasses;
|
||||
if (numPasses == 0xFFFFFFFF)
|
||||
numPasses = (level >= 9 ? kBZip2NumPassesX9 :
|
||||
(level >= 7 ? kBZip2NumPassesX7 :
|
||||
kBZip2NumPassesX1));
|
||||
|
||||
UInt32 dicSize = _defaultDicSize;
|
||||
if (dicSize == 0xFFFFFFFF)
|
||||
dicSize = (level >= 5 ? kBZip2DicSizeX5 :
|
||||
(level >= 3 ? kBZip2DicSizeX3 :
|
||||
kBZip2DicSizeX1));
|
||||
|
||||
SetOneMethodProp(oneMethodInfo, NCoderPropID::kNumPasses, numPasses);
|
||||
SetOneMethodProp(oneMethodInfo, NCoderPropID::kDictionarySize, dicSize);
|
||||
#ifdef COMPRESS_MT
|
||||
SetOneMethodProp(oneMethodInfo, NCoderPropID::kNumThreads, numThreads);
|
||||
#endif
|
||||
}
|
||||
else if (IsPpmdMethod(oneMethodInfo.MethodName))
|
||||
{
|
||||
SetOneMethodProp(oneMethodInfo, NCoderPropID::kUsedMemorySize, _defaultPpmdMemSize);
|
||||
SetOneMethodProp(oneMethodInfo, NCoderPropID::kOrder, _defaultPpmdOrder);
|
||||
UInt32 useMemSize = _defaultPpmdMemSize;
|
||||
if (useMemSize == 0xFFFFFFFF)
|
||||
useMemSize = (level >= 9 ? kPpmdMemSizeX9 :
|
||||
(level >= 7 ? kPpmdMemSizeX7 :
|
||||
(level >= 5 ? kPpmdMemSizeX5 :
|
||||
kPpmdMemSizeX1)));
|
||||
|
||||
UInt32 order = _defaultPpmdOrder;
|
||||
if (order == 0xFFFFFFFF)
|
||||
order = (level >= 9 ? kPpmdOrderX9 :
|
||||
(level >= 7 ? kPpmdOrderX7 :
|
||||
(level >= 5 ? kPpmdOrderX5 :
|
||||
kPpmdOrderX1)));
|
||||
|
||||
SetOneMethodProp(oneMethodInfo, NCoderPropID::kUsedMemorySize, useMemSize);
|
||||
SetOneMethodProp(oneMethodInfo, NCoderPropID::kOrder, order);
|
||||
}
|
||||
|
||||
|
||||
@@ -602,11 +696,10 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numIt
|
||||
|
||||
CCompressionMethodMode methodMode, headerMethod;
|
||||
RINOK(SetCompressionMethod(methodMode, headerMethod));
|
||||
methodMode.MultiThread = _multiThread;
|
||||
// methodMode.MultiThreadMult = _multiThreadMult;
|
||||
|
||||
headerMethod.MultiThread = false;
|
||||
// headerMethod.MultiThreadMult = _multiThreadMult;
|
||||
#ifdef COMPRESS_MT
|
||||
methodMode.NumThreads = _numThreads;
|
||||
headerMethod.NumThreads = 1;
|
||||
#endif
|
||||
|
||||
RINOK(SetPassword(methodMode, updateCallback));
|
||||
|
||||
@@ -655,101 +748,6 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numIt
|
||||
COM_TRY_END
|
||||
}
|
||||
|
||||
static int ParseStringToUInt32(const UString &srcString, UInt32 &number)
|
||||
{
|
||||
const wchar_t *start = srcString;
|
||||
const wchar_t *end;
|
||||
UInt64 number64 = ConvertStringToUInt64(start, &end);
|
||||
if (number64 > 0xFFFFFFFF)
|
||||
{
|
||||
number = 0;
|
||||
return 0;
|
||||
}
|
||||
number = (UInt32)number64;
|
||||
return (int)(end - start);
|
||||
}
|
||||
|
||||
static const int kLogarithmicSizeLimit = 32;
|
||||
static const char kByteSymbol = 'B';
|
||||
static const char kKiloByteSymbol = 'K';
|
||||
static const char kMegaByteSymbol = 'M';
|
||||
|
||||
HRESULT ParseDictionaryValues(const UString &srcStringSpec, UInt32 &dicSize)
|
||||
{
|
||||
UString srcString = srcStringSpec;
|
||||
srcString.MakeUpper();
|
||||
|
||||
const wchar_t *start = srcString;
|
||||
const wchar_t *end;
|
||||
UInt64 number = ConvertStringToUInt64(start, &end);
|
||||
int numDigits = (int)(end - start);
|
||||
if (numDigits == 0 || srcString.Length() > numDigits + 1)
|
||||
return E_INVALIDARG;
|
||||
if (srcString.Length() == numDigits)
|
||||
{
|
||||
if (number >= kLogarithmicSizeLimit)
|
||||
return E_INVALIDARG;
|
||||
dicSize = (UInt32)1 << (int)number;
|
||||
return S_OK;
|
||||
}
|
||||
switch (srcString[numDigits])
|
||||
{
|
||||
case kByteSymbol:
|
||||
if (number >= ((UInt64)1 << kLogarithmicSizeLimit))
|
||||
return E_INVALIDARG;
|
||||
dicSize = (UInt32)number;
|
||||
break;
|
||||
case kKiloByteSymbol:
|
||||
if (number >= ((UInt64)1 << (kLogarithmicSizeLimit - 10)))
|
||||
return E_INVALIDARG;
|
||||
dicSize = UInt32(number << 10);
|
||||
break;
|
||||
case kMegaByteSymbol:
|
||||
if (number >= ((UInt64)1 << (kLogarithmicSizeLimit - 20)))
|
||||
return E_INVALIDARG;
|
||||
dicSize = UInt32(number << 20);
|
||||
break;
|
||||
default:
|
||||
return E_INVALIDARG;
|
||||
}
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static inline UINT GetCurrentFileCodePage()
|
||||
{
|
||||
return AreFileApisANSI() ? CP_ACP : CP_OEMCP;
|
||||
}
|
||||
|
||||
static HRESULT SetBoolProperty(bool &dest, const PROPVARIANT &value)
|
||||
{
|
||||
switch(value.vt)
|
||||
{
|
||||
case VT_EMPTY:
|
||||
dest = true;
|
||||
break;
|
||||
/*
|
||||
case VT_UI4:
|
||||
dest = (value.ulVal != 0);
|
||||
break;
|
||||
*/
|
||||
case VT_BSTR:
|
||||
{
|
||||
UString valueString = value.bstrVal;
|
||||
valueString.MakeUpper();
|
||||
if (valueString.Compare(L"ON") == 0)
|
||||
dest = true;
|
||||
else if (valueString.Compare(L"OFF") == 0)
|
||||
dest = false;
|
||||
else
|
||||
return E_INVALIDARG;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
return E_INVALIDARG;
|
||||
}
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
static HRESULT SetComplexProperty(bool &boolStatus, UInt32 &number,
|
||||
const PROPVARIANT &value)
|
||||
@@ -852,7 +850,7 @@ HRESULT CHandler::SetParam(COneMethodInfo &oneMethodInfo, const UString &name, c
|
||||
if (name.CompareNoCase(L"D") == 0 || name.CompareNoCase(L"MEM") == 0)
|
||||
{
|
||||
UInt32 dicSize;
|
||||
RINOK(ParseDictionaryValues(value, dicSize));
|
||||
RINOK(ParsePropDictionaryValue(value, dicSize));
|
||||
if (name.CompareNoCase(L"D") == 0)
|
||||
property.PropID = NCoderPropID::kDictionarySize;
|
||||
else
|
||||
@@ -983,11 +981,14 @@ HRESULT CHandler::SetSolidSettings(const PROPVARIANT &value)
|
||||
|
||||
STDMETHODIMP CHandler::SetProperties(const wchar_t **names, const PROPVARIANT *values, Int32 numProperties)
|
||||
{
|
||||
UINT codePage = GetCurrentFileCodePage();
|
||||
COM_TRY_BEGIN
|
||||
_methods.Clear();
|
||||
_binds.Clear();
|
||||
Init();
|
||||
#ifdef COMPRESS_MT
|
||||
const UInt32 numProcessors = NSystem::GetNumberOfProcessors();
|
||||
#endif
|
||||
|
||||
UInt32 minNumber = 0;
|
||||
|
||||
for (int i = 0; i < numProperties; i++)
|
||||
@@ -1002,82 +1003,11 @@ STDMETHODIMP CHandler::SetProperties(const wchar_t **names, const PROPVARIANT *v
|
||||
if (name[0] == 'X')
|
||||
{
|
||||
name.Delete(0);
|
||||
|
||||
_level = 9;
|
||||
if (value.vt == VT_UI4)
|
||||
{
|
||||
if (!name.IsEmpty())
|
||||
return E_INVALIDARG;
|
||||
_level = value.ulVal;
|
||||
}
|
||||
else if (value.vt == VT_EMPTY)
|
||||
{
|
||||
if(!name.IsEmpty())
|
||||
{
|
||||
int index = ParseStringToUInt32(name, _level);
|
||||
if (index != name.Length())
|
||||
return E_INVALIDARG;
|
||||
}
|
||||
}
|
||||
else
|
||||
return E_INVALIDARG;
|
||||
RINOK(ParsePropValue(name, value, _level));
|
||||
if (_level == 0)
|
||||
{
|
||||
_copyMode = true;
|
||||
_defaultBZip2Passes = 1;
|
||||
}
|
||||
else if (_level < 3)
|
||||
{
|
||||
_defaultAlgorithm = kAlgorithmX1;
|
||||
_defaultDicSize = kDicSizeX1;
|
||||
_defaultMatchFinder = kMatchFinderX1;
|
||||
|
||||
_defaultBZip2Passes = 1;
|
||||
|
||||
_defaultPpmdMemSize = kPpmdMemSizeX1;
|
||||
_defaultPpmdOrder = kPpmdOrderX1;
|
||||
}
|
||||
else if (_level < 5)
|
||||
{
|
||||
_defaultAlgorithm = kAlgorithmX3;
|
||||
_defaultDicSize = kDicSizeX3;
|
||||
_defaultMatchFinder = kMatchFinderX3;
|
||||
|
||||
_defaultBZip2Passes = 1;
|
||||
|
||||
_defaultPpmdMemSize = kPpmdMemSizeX1;
|
||||
_defaultPpmdOrder = kPpmdOrderX1;
|
||||
}
|
||||
else if (_level < 7)
|
||||
{
|
||||
_defaultBZip2Passes = 1;
|
||||
// normal;
|
||||
}
|
||||
else if(_level < 9)
|
||||
{
|
||||
_defaultAlgorithm = kAlgorithmX7;
|
||||
_defaultDicSize = kDicSizeX7;
|
||||
_defaultFastBytes = kFastBytesX7;
|
||||
_defaultBZip2Passes = kNumBZip2PassesX7;
|
||||
|
||||
_defaultPpmdMemSize = kPpmdMemSizeX7;
|
||||
_defaultPpmdOrder = kPpmdOrderX7;
|
||||
|
||||
_defaultDeflateFastBytes = kDeflateFastBytesX7;
|
||||
_defaultDeflatePasses = kDeflatePassesX7;
|
||||
}
|
||||
else
|
||||
{
|
||||
_defaultAlgorithm = kAlgorithmX9;
|
||||
_defaultDicSize = kDicSizeX9;
|
||||
_defaultFastBytes = kFastBytesX9;
|
||||
_defaultBZip2Passes = kNumBZip2PassesX9;
|
||||
|
||||
_defaultPpmdMemSize = kPpmdMemSizeX9;
|
||||
_defaultPpmdOrder = kPpmdOrderX9;
|
||||
|
||||
_defaultDeflateFastBytes = kDeflateFastBytesX9;
|
||||
_defaultDeflatePasses = kDeflatePassesX9;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -1110,7 +1040,14 @@ STDMETHODIMP CHandler::SetProperties(const wchar_t **names, const PROPVARIANT *v
|
||||
UString realName = name.Mid(index);
|
||||
if (index == 0)
|
||||
{
|
||||
if (name.CompareNoCase(L"RSFX") == 0)
|
||||
if(name.Left(2).CompareNoCase(L"MT") == 0)
|
||||
{
|
||||
#ifdef COMPRESS_MT
|
||||
RINOK(ParseMtProp(name.Mid(2), value, numProcessors, _numThreads));
|
||||
#endif
|
||||
continue;
|
||||
}
|
||||
else if (name.CompareNoCase(L"RSFX") == 0)
|
||||
{
|
||||
RINOK(SetBoolProperty(_removeSfxBlock, value));
|
||||
continue;
|
||||
@@ -1135,13 +1072,6 @@ STDMETHODIMP CHandler::SetProperties(const wchar_t **names, const PROPVARIANT *v
|
||||
RINOK(SetBoolProperty(_encryptHeaders, value));
|
||||
continue;
|
||||
}
|
||||
else if (name.CompareNoCase(L"MT") == 0)
|
||||
{
|
||||
// _multiThreadMult = 200;
|
||||
RINOK(SetBoolProperty(_multiThread, value));
|
||||
// RINOK(SetComplexProperty(MultiThread, _multiThreadMult, value));
|
||||
continue;
|
||||
}
|
||||
else if (name.CompareNoCase(L"V") == 0)
|
||||
{
|
||||
RINOK(SetBoolProperty(_volumeMode, value));
|
||||
@@ -1173,26 +1103,19 @@ STDMETHODIMP CHandler::SetProperties(const wchar_t **names, const PROPVARIANT *v
|
||||
else
|
||||
{
|
||||
CProperty property;
|
||||
if (realName.CompareNoCase(L"D") == 0 || realName.CompareNoCase(L"MEM") == 0)
|
||||
if (realName.Left(1).CompareNoCase(L"D") == 0)
|
||||
{
|
||||
UInt32 dicSize;
|
||||
if (value.vt == VT_UI4)
|
||||
{
|
||||
UInt32 logDicSize = value.ulVal;
|
||||
if (logDicSize >= 32)
|
||||
return E_INVALIDARG;
|
||||
dicSize = (UInt32)1 << logDicSize;
|
||||
}
|
||||
else if (value.vt == VT_BSTR)
|
||||
{
|
||||
RINOK(ParseDictionaryValues(value.bstrVal, dicSize));
|
||||
}
|
||||
else
|
||||
return E_FAIL;
|
||||
if (realName.CompareNoCase(L"D") == 0)
|
||||
property.PropID = NCoderPropID::kDictionarySize;
|
||||
else
|
||||
property.PropID = NCoderPropID::kUsedMemorySize;
|
||||
RINOK(ParsePropDictionaryValue(realName.Mid(1), value, dicSize));
|
||||
property.PropID = NCoderPropID::kDictionarySize;
|
||||
property.Value = dicSize;
|
||||
oneMethodInfo.CoderProperties.Add(property);
|
||||
}
|
||||
else if (realName.Left(3).CompareNoCase(L"MEM") == 0)
|
||||
{
|
||||
UInt32 dicSize;
|
||||
RINOK(ParsePropDictionaryValue(realName.Mid(3), value, dicSize));
|
||||
property.PropID = NCoderPropID::kUsedMemorySize;
|
||||
property.Value = dicSize;
|
||||
oneMethodInfo.CoderProperties.Add(property);
|
||||
}
|
||||
|
||||
@@ -880,6 +880,9 @@ HRESULT CInArchive::ReadAndDecodePackedStreams(UInt64 baseOffset,
|
||||
#ifndef _NO_CRYPTO
|
||||
, getTextPassword
|
||||
#endif
|
||||
#ifdef COMPRESS_MT
|
||||
, false, 1
|
||||
#endif
|
||||
);
|
||||
RINOK(result);
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
PROG = 7z.dll
|
||||
DEF_FILE = ../Archive.def
|
||||
CFLAGS = $(CFLAGS) -I ../../../
|
||||
CFLAGS = $(CFLAGS) -I ../../../ -DCOMPRESS_MT
|
||||
LIBS = $(LIBS) oleaut32.lib user32.lib
|
||||
|
||||
7Z_OBJS = \
|
||||
@@ -61,6 +61,7 @@ AR_COMMON_OBJS = \
|
||||
$O\ItemNameUtils.obj \
|
||||
$O\MultiStream.obj \
|
||||
$O\OutStreamWithCRC.obj \
|
||||
$O\ParseProperties.obj \
|
||||
|
||||
OBJS = \
|
||||
$O\StdAfx.obj \
|
||||
|
||||
@@ -43,7 +43,7 @@ RSC=rc.exe
|
||||
# PROP Ignore_Export_Lib 1
|
||||
# PROP Target_Dir ""
|
||||
# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "BZIP2_EXPORTS" /YX /FD /c
|
||||
# ADD CPP /nologo /Gz /MD /W3 /GX /O1 /I "..\..\..\\" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "BZIP2_EXPORTS" /Yu"StdAfx.h" /FD /c
|
||||
# ADD CPP /nologo /Gz /MD /W3 /GX /O1 /I "..\..\..\\" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "BZIP2_EXPORTS" /D "COMPRESS_MT" /Yu"StdAfx.h" /FD /c
|
||||
# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
|
||||
# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
|
||||
# ADD BASE RSC /l 0x419 /d "NDEBUG"
|
||||
@@ -70,7 +70,7 @@ LINK32=link.exe
|
||||
# PROP Ignore_Export_Lib 1
|
||||
# PROP Target_Dir ""
|
||||
# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "BZIP2_EXPORTS" /YX /FD /GZ /c
|
||||
# ADD CPP /nologo /Gz /MTd /W3 /Gm /GX /ZI /Od /I "..\..\..\\" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "BZIP2_EXPORTS" /Yu"StdAfx.h" /FD /GZ /c
|
||||
# ADD CPP /nologo /Gz /MTd /W3 /Gm /GX /ZI /Od /I "..\..\..\\" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "BZIP2_EXPORTS" /D "COMPRESS_MT" /Yu"StdAfx.h" /FD /GZ /c
|
||||
# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32
|
||||
# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32
|
||||
# ADD BASE RSC /l 0x419 /d "_DEBUG"
|
||||
@@ -216,6 +216,14 @@ SOURCE=..\Common\DummyOutStream.cpp
|
||||
|
||||
SOURCE=..\Common\DummyOutStream.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\Common\ParseProperties.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\Common\ParseProperties.h
|
||||
# End Source File
|
||||
# End Group
|
||||
# Begin Group "Engine"
|
||||
|
||||
|
||||
@@ -191,6 +191,16 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef COMPRESS_MT
|
||||
{
|
||||
CMyComPtr<ICompressSetCoderMt> setCoderMt;
|
||||
decoder.QueryInterface(IID_ICompressSetCoderMt, &setCoderMt);
|
||||
if (setCoderMt)
|
||||
{
|
||||
RINOK(setCoderMt->SetNumberOfThreads(_numThreads));
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
CDummyOutStream *outStreamSpec = new CDummyOutStream;
|
||||
CMyComPtr<ISequentialOutStream> outStream(outStreamSpec);
|
||||
|
||||
@@ -7,6 +7,10 @@
|
||||
#include "../IArchive.h"
|
||||
#include "BZip2Item.h"
|
||||
|
||||
#ifdef COMPRESS_MT
|
||||
#include "../../../Windows/System.h"
|
||||
#endif
|
||||
|
||||
namespace NArchive {
|
||||
namespace NBZip2 {
|
||||
|
||||
@@ -20,8 +24,21 @@ class CHandler:
|
||||
NArchive::NBZip2::CItem _item;
|
||||
UInt64 _streamStartPosition;
|
||||
|
||||
UInt32 _level;
|
||||
UInt32 _dicSize;
|
||||
UInt32 _numPasses;
|
||||
void InitMethodProperties() { _numPasses = 1; }
|
||||
#ifdef COMPRESS_MT
|
||||
UInt32 _numThreads;
|
||||
#endif
|
||||
void InitMethodProperties()
|
||||
{
|
||||
_level = 5;
|
||||
_dicSize =
|
||||
_numPasses = 0xFFFFFFFF;
|
||||
#ifdef COMPRESS_MT
|
||||
_numThreads = NWindows::NSystem::GetNumberOfProcessors();;
|
||||
#endif
|
||||
}
|
||||
|
||||
public:
|
||||
MY_UNKNOWN_IMP3(
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// BZip2/OutHandler.cpp
|
||||
// BZip2HandlerOut.cpp
|
||||
|
||||
#include "StdAfx.h"
|
||||
|
||||
@@ -7,13 +7,23 @@
|
||||
|
||||
#include "Common/Defs.h"
|
||||
#include "Common/String.h"
|
||||
#include "Common/StringToInt.h"
|
||||
|
||||
#include "Windows/PropVariant.h"
|
||||
|
||||
#include "../../Compress/Copy/CopyCoder.h"
|
||||
|
||||
#include "../Common/ParseProperties.h"
|
||||
|
||||
using namespace NWindows;
|
||||
|
||||
static const UInt32 kNumPassesX1 = 1;
|
||||
static const UInt32 kNumPassesX7 = 2;
|
||||
static const UInt32 kNumPassesX9 = 7;
|
||||
|
||||
static const UInt32 kDicSizeX1 = 100000;
|
||||
static const UInt32 kDicSizeX3 = 500000;
|
||||
static const UInt32 kDicSizeX5 = 900000;
|
||||
|
||||
namespace NArchive {
|
||||
namespace NBZip2 {
|
||||
|
||||
@@ -69,7 +79,24 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numIt
|
||||
return E_INVALIDARG;
|
||||
size = propVariant.uhVal.QuadPart;
|
||||
}
|
||||
return UpdateArchive(size, outStream, 0, _numPasses, updateCallback);
|
||||
|
||||
UInt32 dicSize = _dicSize;
|
||||
if (dicSize == 0xFFFFFFFF)
|
||||
dicSize = (_level >= 5 ? kDicSizeX5 :
|
||||
(_level >= 3 ? kDicSizeX3 :
|
||||
kDicSizeX1));
|
||||
|
||||
UInt32 numPasses = _numPasses;
|
||||
if (numPasses == 0xFFFFFFFF)
|
||||
numPasses = (_level >= 9 ? kNumPassesX9 :
|
||||
(_level >= 7 ? kNumPassesX7 :
|
||||
kNumPassesX1));
|
||||
|
||||
return UpdateArchive(size, outStream, 0, dicSize, numPasses,
|
||||
#ifdef COMPRESS_MT
|
||||
_numThreads,
|
||||
#endif
|
||||
updateCallback);
|
||||
}
|
||||
if (indexInArchive != 0)
|
||||
return E_INVALIDARG;
|
||||
@@ -80,6 +107,11 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numIt
|
||||
STDMETHODIMP CHandler::SetProperties(const wchar_t **names, const PROPVARIANT *values, Int32 numProperties)
|
||||
{
|
||||
InitMethodProperties();
|
||||
#ifdef COMPRESS_MT
|
||||
const UInt32 numProcessors = NSystem::GetNumberOfProcessors();
|
||||
_numThreads = numProcessors;
|
||||
#endif
|
||||
|
||||
for (int i = 0; i < numProperties; i++)
|
||||
{
|
||||
UString name = UString(names[i]);
|
||||
@@ -87,68 +119,34 @@ STDMETHODIMP CHandler::SetProperties(const wchar_t **names, const PROPVARIANT *v
|
||||
if (name.IsEmpty())
|
||||
return E_INVALIDARG;
|
||||
|
||||
const PROPVARIANT &value = values[i];
|
||||
const PROPVARIANT &prop = values[i];
|
||||
|
||||
if (name[0] == 'X')
|
||||
{
|
||||
name.Delete(0);
|
||||
UInt32 level = 9;
|
||||
if (value.vt == VT_UI4)
|
||||
{
|
||||
if (!name.IsEmpty())
|
||||
return E_INVALIDARG;
|
||||
level = value.ulVal;
|
||||
}
|
||||
else if (value.vt == VT_EMPTY)
|
||||
{
|
||||
if(!name.IsEmpty())
|
||||
{
|
||||
const wchar_t *start = name;
|
||||
const wchar_t *end;
|
||||
UInt64 v = ConvertStringToUInt64(start, &end);
|
||||
if (end - start != name.Length())
|
||||
return E_INVALIDARG;
|
||||
level = (UInt32)v;
|
||||
}
|
||||
}
|
||||
else
|
||||
return E_INVALIDARG;
|
||||
if (level < 7)
|
||||
_numPasses = 1;
|
||||
else if (level < 9)
|
||||
_numPasses = 2;
|
||||
else
|
||||
_numPasses = 7;
|
||||
RINOK(ParsePropValue(name.Mid(1), prop, level));
|
||||
_level = level;
|
||||
continue;
|
||||
}
|
||||
else if (name.Left(4) == L"PASS")
|
||||
if (name[0] == 'D')
|
||||
{
|
||||
name.Delete(0, 4);
|
||||
UInt32 numPasses = 1;
|
||||
if (value.vt == VT_UI4)
|
||||
{
|
||||
if (!name.IsEmpty())
|
||||
return E_INVALIDARG;
|
||||
numPasses = value.ulVal;
|
||||
}
|
||||
else if (value.vt == VT_EMPTY)
|
||||
{
|
||||
if(!name.IsEmpty())
|
||||
{
|
||||
const wchar_t *start = name;
|
||||
const wchar_t *end;
|
||||
UInt64 v = ConvertStringToUInt64(start, &end);
|
||||
if (end - start != name.Length())
|
||||
return E_INVALIDARG;
|
||||
numPasses = (UInt32)v;
|
||||
}
|
||||
}
|
||||
else
|
||||
return E_INVALIDARG;
|
||||
|
||||
if (numPasses < 1 || numPasses > 10)
|
||||
return E_INVALIDARG;
|
||||
_numPasses = numPasses;
|
||||
UInt32 dicSize = kDicSizeX5;
|
||||
RINOK(ParsePropDictionaryValue(name.Mid(1), prop, dicSize));
|
||||
_dicSize = dicSize;
|
||||
continue;
|
||||
}
|
||||
if (name.Left(4) == L"PASS")
|
||||
{
|
||||
UInt32 num = kNumPassesX9;
|
||||
RINOK(ParsePropValue(name.Mid(4), prop, num));
|
||||
_numPasses = num;
|
||||
continue;
|
||||
}
|
||||
if (name.Left(2) == L"MT")
|
||||
{
|
||||
#ifdef COMPRESS_MT
|
||||
RINOK(ParseMtProp(name.Mid(2), prop, numProcessors, _numThreads));
|
||||
#endif
|
||||
continue;
|
||||
}
|
||||
return E_INVALIDARG;
|
||||
|
||||
@@ -23,7 +23,11 @@ namespace NBZip2 {
|
||||
HRESULT UpdateArchive(UInt64 unpackSize,
|
||||
ISequentialOutStream *outStream,
|
||||
int indexInClient,
|
||||
UInt32 dictionary,
|
||||
UInt32 numPasses,
|
||||
#ifdef COMPRESS_MT
|
||||
UInt32 numThreads,
|
||||
#endif
|
||||
IArchiveUpdateCallback *updateCallback)
|
||||
{
|
||||
RINOK(updateCallback->SetTotal(unpackSize));
|
||||
@@ -53,21 +57,23 @@ HRESULT UpdateArchive(UInt64 unpackSize,
|
||||
encoder.QueryInterface(IID_ICompressSetCoderProperties, &setCoderProperties);
|
||||
if (setCoderProperties)
|
||||
{
|
||||
/*
|
||||
NWindows::NCOM::CPropVariant properties[2] =
|
||||
NWindows::NCOM::CPropVariant properties[] =
|
||||
{
|
||||
dictionary, numPasses
|
||||
dictionary,
|
||||
numPasses
|
||||
#ifdef COMPRESS_MT
|
||||
, numThreads
|
||||
#endif
|
||||
};
|
||||
PROPID propIDs[2] =
|
||||
PROPID propIDs[] =
|
||||
{
|
||||
NCoderPropID::kDictionarySize,
|
||||
NCoderPropID::kNumPasses,
|
||||
NCoderPropID::kNumPasses
|
||||
#ifdef COMPRESS_MT
|
||||
, NCoderPropID::kNumThreads
|
||||
#endif
|
||||
};
|
||||
RINOK(setCoderProperties->SetCoderProperties(propIDs, properties, 2));
|
||||
*/
|
||||
NWindows::NCOM::CPropVariant property = numPasses;
|
||||
PROPID propID = NCoderPropID::kNumPasses;
|
||||
RINOK(setCoderProperties->SetCoderProperties(&propID, &property, 1));
|
||||
RINOK(setCoderProperties->SetCoderProperties(propIDs, properties, sizeof(propIDs) / sizeof(propIDs[0])));
|
||||
}
|
||||
|
||||
RINOK(encoder->Code(fileInStream, outStream, NULL, NULL, localProgress));
|
||||
|
||||
@@ -12,7 +12,11 @@ HRESULT UpdateArchive(
|
||||
UInt64 unpackSize,
|
||||
ISequentialOutStream *outStream,
|
||||
int indexInClient,
|
||||
UInt32 dictionary,
|
||||
UInt32 numPasses,
|
||||
#ifdef COMPRESS_MT
|
||||
UInt32 numThreads,
|
||||
#endif
|
||||
IArchiveUpdateCallback *updateCallback);
|
||||
|
||||
}}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
PROG = bz2.dll
|
||||
DEF_FILE = ../Archive.def
|
||||
CFLAGS = $(CFLAGS) -I ../../../
|
||||
CFLAGS = $(CFLAGS) -I ../../../ -DCOMPRESS_MT
|
||||
LIBS = $(LIBS) oleaut32.lib user32.lib
|
||||
|
||||
BZ2_OBJS = \
|
||||
@@ -27,6 +27,7 @@ WIN_OBJS = \
|
||||
AR_COMMON_OBJS = \
|
||||
$O\CodecsPath.obj \
|
||||
$O\DummyOutStream.obj \
|
||||
$O\ParseProperties.obj \
|
||||
|
||||
OBJS = \
|
||||
$O\StdAfx.obj \
|
||||
|
||||
171
7zip/Archive/Common/ParseProperties.cpp
Executable file
171
7zip/Archive/Common/ParseProperties.cpp
Executable file
@@ -0,0 +1,171 @@
|
||||
// ParseProperties.cpp
|
||||
|
||||
#include "StdAfx.h"
|
||||
|
||||
#include "ParseProperties.h"
|
||||
|
||||
#include "Common/StringToInt.h"
|
||||
#include "Common/MyCom.h"
|
||||
|
||||
HRESULT ParsePropValue(const UString &name, const PROPVARIANT &prop, UInt32 &resValue)
|
||||
{
|
||||
if (prop.vt == VT_UI4)
|
||||
{
|
||||
if (!name.IsEmpty())
|
||||
return E_INVALIDARG;
|
||||
resValue = prop.ulVal;
|
||||
}
|
||||
else if (prop.vt == VT_EMPTY)
|
||||
{
|
||||
if(!name.IsEmpty())
|
||||
{
|
||||
const wchar_t *start = name;
|
||||
const wchar_t *end;
|
||||
UInt64 v = ConvertStringToUInt64(start, &end);
|
||||
if (end - start != name.Length())
|
||||
return E_INVALIDARG;
|
||||
resValue = (UInt32)v;
|
||||
}
|
||||
}
|
||||
else
|
||||
return E_INVALIDARG;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static const int kLogarithmicSizeLimit = 32;
|
||||
static const wchar_t kByteSymbol = L'B';
|
||||
static const wchar_t kKiloByteSymbol = L'K';
|
||||
static const wchar_t kMegaByteSymbol = L'M';
|
||||
|
||||
HRESULT ParsePropDictionaryValue(const UString &srcStringSpec, UInt32 &dicSize)
|
||||
{
|
||||
UString srcString = srcStringSpec;
|
||||
srcString.MakeUpper();
|
||||
|
||||
const wchar_t *start = srcString;
|
||||
const wchar_t *end;
|
||||
UInt64 number = ConvertStringToUInt64(start, &end);
|
||||
int numDigits = (int)(end - start);
|
||||
if (numDigits == 0 || srcString.Length() > numDigits + 1)
|
||||
return E_INVALIDARG;
|
||||
if (srcString.Length() == numDigits)
|
||||
{
|
||||
if (number >= kLogarithmicSizeLimit)
|
||||
return E_INVALIDARG;
|
||||
dicSize = (UInt32)1 << (int)number;
|
||||
return S_OK;
|
||||
}
|
||||
switch (srcString[numDigits])
|
||||
{
|
||||
case kByteSymbol:
|
||||
if (number >= ((UInt64)1 << kLogarithmicSizeLimit))
|
||||
return E_INVALIDARG;
|
||||
dicSize = (UInt32)number;
|
||||
break;
|
||||
case kKiloByteSymbol:
|
||||
if (number >= ((UInt64)1 << (kLogarithmicSizeLimit - 10)))
|
||||
return E_INVALIDARG;
|
||||
dicSize = (UInt32)(number << 10);
|
||||
break;
|
||||
case kMegaByteSymbol:
|
||||
if (number >= ((UInt64)1 << (kLogarithmicSizeLimit - 20)))
|
||||
return E_INVALIDARG;
|
||||
dicSize = (UInt32)(number << 20);
|
||||
break;
|
||||
default:
|
||||
return E_INVALIDARG;
|
||||
}
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT ParsePropDictionaryValue(const UString &name, const PROPVARIANT &prop, UInt32 &resValue)
|
||||
{
|
||||
if (name.IsEmpty())
|
||||
{
|
||||
if (prop.vt == VT_UI4)
|
||||
{
|
||||
UInt32 logDicSize = prop.ulVal;
|
||||
if (logDicSize >= 32)
|
||||
return E_INVALIDARG;
|
||||
resValue = (UInt32)1 << logDicSize;
|
||||
return S_OK;
|
||||
}
|
||||
if (prop.vt == VT_BSTR)
|
||||
return ParsePropDictionaryValue(prop.bstrVal, resValue);
|
||||
return E_INVALIDARG;
|
||||
}
|
||||
return ParsePropDictionaryValue(name, resValue);
|
||||
}
|
||||
|
||||
HRESULT SetBoolProperty(bool &dest, const PROPVARIANT &value)
|
||||
{
|
||||
switch(value.vt)
|
||||
{
|
||||
case VT_EMPTY:
|
||||
dest = true;
|
||||
break;
|
||||
/*
|
||||
case VT_UI4:
|
||||
dest = (value.ulVal != 0);
|
||||
break;
|
||||
*/
|
||||
case VT_BSTR:
|
||||
{
|
||||
UString valueString = value.bstrVal;
|
||||
valueString.MakeUpper();
|
||||
if (valueString.Compare(L"ON") == 0)
|
||||
dest = true;
|
||||
else if (valueString.Compare(L"OFF") == 0)
|
||||
dest = false;
|
||||
else
|
||||
return E_INVALIDARG;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
return E_INVALIDARG;
|
||||
}
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
int ParseStringToUInt32(const UString &srcString, UInt32 &number)
|
||||
{
|
||||
const wchar_t *start = srcString;
|
||||
const wchar_t *end;
|
||||
UInt64 number64 = ConvertStringToUInt64(start, &end);
|
||||
if (number64 > 0xFFFFFFFF)
|
||||
{
|
||||
number = 0;
|
||||
return 0;
|
||||
}
|
||||
number = (UInt32)number64;
|
||||
return (int)(end - start);
|
||||
}
|
||||
|
||||
HRESULT ParseMtProp(const UString &name, const PROPVARIANT &prop, UInt32 defaultNumThreads, UInt32 &numThreads)
|
||||
{
|
||||
if (name.IsEmpty())
|
||||
{
|
||||
switch(prop.vt)
|
||||
{
|
||||
case VT_UI4:
|
||||
numThreads = prop.ulVal;
|
||||
break;
|
||||
default:
|
||||
{
|
||||
bool val;
|
||||
RINOK(SetBoolProperty(val, prop));
|
||||
numThreads = (val ? defaultNumThreads : 1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
UInt32 number;
|
||||
int index = ParseStringToUInt32(name, number);
|
||||
if (index != name.Length())
|
||||
return E_INVALIDARG;
|
||||
numThreads = number;
|
||||
}
|
||||
return S_OK;
|
||||
}
|
||||
17
7zip/Archive/Common/ParseProperties.h
Executable file
17
7zip/Archive/Common/ParseProperties.h
Executable file
@@ -0,0 +1,17 @@
|
||||
// ParseProperties.h
|
||||
|
||||
#ifndef __PARSEPROPERTIES_H
|
||||
#define __PARSEPROPERTIES_H
|
||||
|
||||
#include "Common/String.h"
|
||||
#include "Common/Types.h"
|
||||
|
||||
HRESULT ParsePropValue(const UString &name, const PROPVARIANT &prop, UInt32 &resValue);
|
||||
HRESULT ParsePropDictionaryValue(const UString &srcStringSpec, UInt32 &dicSize);
|
||||
HRESULT ParsePropDictionaryValue(const UString &name, const PROPVARIANT &prop, UInt32 &resValue);
|
||||
|
||||
HRESULT SetBoolProperty(bool &dest, const PROPVARIANT &value);
|
||||
int ParseStringToUInt32(const UString &srcString, UInt32 &number);
|
||||
HRESULT ParseMtProp(const UString &name, const PROPVARIANT &prop, UInt32 defaultNumThreads, UInt32 &numThreads);
|
||||
|
||||
#endif
|
||||
@@ -304,6 +304,14 @@ SOURCE=..\Common\OutStreamWithCRC.cpp
|
||||
|
||||
SOURCE=..\Common\OutStreamWithCRC.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\Common\ParseProperties.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\Common\ParseProperties.h
|
||||
# End Source File
|
||||
# End Group
|
||||
# Begin Source File
|
||||
|
||||
|
||||
@@ -66,9 +66,11 @@ private:
|
||||
CMyComPtr<IInStream> m_Stream;
|
||||
CCompressionMethodMode m_Method;
|
||||
UInt32 m_Level;
|
||||
|
||||
void InitMethodProperties()
|
||||
{
|
||||
m_Level = m_Method.NumPasses = m_Method.NumFastBytes = 0xFFFFFFFF;
|
||||
m_Method.NumMatchFinderCyclesDefined = false;
|
||||
m_Level = m_Method.NumPasses = m_Method.NumFastBytes = m_Method.NumMatchFinderCycles = 0xFFFFFFFF;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
#include "Windows/PropVariant.h"
|
||||
|
||||
#include "../../Compress/Copy/CopyCoder.h"
|
||||
#include "../Common/ParseProperties.h"
|
||||
|
||||
using namespace NWindows;
|
||||
using namespace NTime;
|
||||
@@ -130,14 +131,16 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numIt
|
||||
UInt32 level = m_Level;
|
||||
if (level == 0xFFFFFFFF)
|
||||
level = 5;
|
||||
|
||||
if (m_Method.NumPasses == 0xFFFFFFFF)
|
||||
m_Method.NumPasses = (level >= 9 ? kNumPassesX9 : (level >= 7 ? kNumPassesX7 : kNumPassesX1));
|
||||
m_Method.NumPasses = (level >= 9 ? kNumPassesX9 :
|
||||
(level >= 7 ? kNumPassesX7 :
|
||||
kNumPassesX1));
|
||||
if (m_Method.NumFastBytes == 0xFFFFFFFF)
|
||||
m_Method.NumFastBytes = (level >= 9 ? kNumFastBytesX9 : (level >= 7 ? kNumFastBytesX7 : kNumFastBytesX1));
|
||||
m_Method.NumFastBytes = (level >= 9 ? kNumFastBytesX9 :
|
||||
(level >= 7 ? kNumFastBytesX7 :
|
||||
kNumFastBytesX1));
|
||||
|
||||
return UpdateArchive(m_Stream, size, outStream, newItem,
|
||||
m_Method, itemIndex, updateCallback);
|
||||
return UpdateArchive(m_Stream, size, outStream, newItem, m_Method, itemIndex, updateCallback);
|
||||
}
|
||||
|
||||
if (indexInArchive != 0)
|
||||
@@ -162,49 +165,33 @@ STDMETHODIMP CHandler::SetProperties(const wchar_t **names, const PROPVARIANT *v
|
||||
InitMethodProperties();
|
||||
for (int i = 0; i < numProperties; i++)
|
||||
{
|
||||
UString name = UString(names[i]);
|
||||
UString name = names[i];
|
||||
name.MakeUpper();
|
||||
const PROPVARIANT &value = values[i];
|
||||
if (name[0] == 'X')
|
||||
const PROPVARIANT &prop = values[i];
|
||||
if (name[0] == L'X')
|
||||
{
|
||||
name.Delete(0);
|
||||
UInt32 level = 9;
|
||||
if (value.vt == VT_UI4)
|
||||
{
|
||||
if (!name.IsEmpty())
|
||||
return E_INVALIDARG;
|
||||
level = value.ulVal;
|
||||
}
|
||||
else if (value.vt == VT_EMPTY)
|
||||
{
|
||||
if(!name.IsEmpty())
|
||||
{
|
||||
const wchar_t *start = name;
|
||||
const wchar_t *end;
|
||||
UInt64 v = ConvertStringToUInt64(start, &end);
|
||||
if (end - start != name.Length())
|
||||
return E_INVALIDARG;
|
||||
level = (UInt32)v;
|
||||
}
|
||||
}
|
||||
else
|
||||
return E_INVALIDARG;
|
||||
RINOK(ParsePropValue(name.Mid(1), prop, level));
|
||||
m_Level = level;
|
||||
continue;
|
||||
}
|
||||
else if (name == L"PASS")
|
||||
else if (name.Left(4) == L"PASS")
|
||||
{
|
||||
if (value.vt != VT_UI4)
|
||||
return E_INVALIDARG;
|
||||
m_Method.NumPasses = value.ulVal;
|
||||
if (m_Method.NumPasses < 1)
|
||||
return E_INVALIDARG;
|
||||
UInt32 num = kNumPassesX9;
|
||||
RINOK(ParsePropValue(name.Mid(4), prop, num));
|
||||
m_Method.NumPasses = num;
|
||||
}
|
||||
else if (name == L"FB")
|
||||
else if (name.Left(2) == L"FB")
|
||||
{
|
||||
if (value.vt != VT_UI4)
|
||||
return E_INVALIDARG;
|
||||
m_Method.NumFastBytes = value.ulVal;
|
||||
UInt32 num = kNumFastBytesX9;
|
||||
RINOK(ParsePropValue(name.Mid(2), prop, num));
|
||||
m_Method.NumFastBytes = num;
|
||||
}
|
||||
else if (name.Left(2) == L"MC")
|
||||
{
|
||||
UInt32 num = 0xFFFFFFFF;
|
||||
RINOK(ParsePropValue(name.Mid(2), prop, num));
|
||||
m_Method.NumMatchFinderCycles = num;
|
||||
m_Method.NumMatchFinderCyclesDefined = true;
|
||||
}
|
||||
else
|
||||
return E_INVALIDARG;
|
||||
|
||||
@@ -89,14 +89,24 @@ HRESULT UpdateArchive(IInStream *inStream,
|
||||
CLSID_CCompressDeflateEncoder, &deflateEncoder));
|
||||
#endif
|
||||
|
||||
NWindows::NCOM::CPropVariant properties[2] =
|
||||
{ compressionMethod.NumPasses, compressionMethod.NumFastBytes };
|
||||
PROPID propIDs[2] =
|
||||
{ NCoderPropID::kNumPasses, NCoderPropID::kNumFastBytes };
|
||||
NWindows::NCOM::CPropVariant properties[] =
|
||||
{
|
||||
compressionMethod.NumPasses,
|
||||
compressionMethod.NumFastBytes,
|
||||
compressionMethod.NumMatchFinderCycles
|
||||
};
|
||||
PROPID propIDs[] =
|
||||
{
|
||||
NCoderPropID::kNumPasses,
|
||||
NCoderPropID::kNumFastBytes,
|
||||
NCoderPropID::kMatchFinderCycles
|
||||
};
|
||||
int numProps = sizeof(propIDs) / sizeof(propIDs[0]);
|
||||
if (!compressionMethod.NumMatchFinderCyclesDefined)
|
||||
numProps--;
|
||||
CMyComPtr<ICompressSetCoderProperties> setCoderProperties;
|
||||
RINOK(deflateEncoder.QueryInterface(
|
||||
IID_ICompressSetCoderProperties, &setCoderProperties));
|
||||
RINOK(setCoderProperties->SetCoderProperties(propIDs, properties, 2));
|
||||
RINOK(deflateEncoder.QueryInterface(IID_ICompressSetCoderProperties, &setCoderProperties));
|
||||
RINOK(setCoderProperties->SetCoderProperties(propIDs, properties, numProps));
|
||||
}
|
||||
RINOK(deflateEncoder->Code(crcStream, outStream, NULL, NULL, compressProgress));
|
||||
|
||||
|
||||
@@ -15,6 +15,8 @@ struct CCompressionMethodMode
|
||||
{
|
||||
UInt32 NumPasses;
|
||||
UInt32 NumFastBytes;
|
||||
bool NumMatchFinderCyclesDefined;
|
||||
UInt32 NumMatchFinderCycles;
|
||||
};
|
||||
|
||||
HRESULT UpdateArchive(IInStream *inStream,
|
||||
|
||||
@@ -32,6 +32,7 @@ AR_COMMON_OBJS = \
|
||||
$O\CodecsPath.obj \
|
||||
$O\InStreamWithCRC.obj \
|
||||
$O\OutStreamWithCRC.obj \
|
||||
$O\ParseProperties.obj \
|
||||
|
||||
OBJS = \
|
||||
$O\StdAfx.obj \
|
||||
|
||||
@@ -43,7 +43,7 @@ RSC=rc.exe
|
||||
# PROP Ignore_Export_Lib 1
|
||||
# PROP Target_Dir ""
|
||||
# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "ZIP_EXPORTS" /YX /FD /c
|
||||
# ADD CPP /nologo /Gz /MD /W3 /GX /O1 /I "..\..\..\\" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "ZIP_EXPORTS" /Yu"StdAfx.h" /FD /c
|
||||
# ADD CPP /nologo /Gz /MD /W3 /GX /O1 /I "..\..\..\\" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "ZIP_EXPORTS" /D "COMPRESS_MT" /Yu"StdAfx.h" /FD /c
|
||||
# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
|
||||
# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
|
||||
# ADD BASE RSC /l 0x419 /d "NDEBUG"
|
||||
@@ -70,7 +70,7 @@ LINK32=link.exe
|
||||
# PROP Ignore_Export_Lib 1
|
||||
# PROP Target_Dir ""
|
||||
# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "ZIP_EXPORTS" /YX /FD /GZ /c
|
||||
# ADD CPP /nologo /Gz /MTd /W3 /Gm /GX /ZI /Od /I "..\..\..\\" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "ZIP_EXPORTS" /Yu"StdAfx.h" /FD /GZ /c
|
||||
# ADD CPP /nologo /Gz /MTd /W3 /Gm /GX /ZI /Od /I "..\..\..\\" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "ZIP_EXPORTS" /D "COMPRESS_MT" /Yu"StdAfx.h" /FD /GZ /c
|
||||
# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32
|
||||
# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32
|
||||
# ADD BASE RSC /l 0x419 /d "_DEBUG"
|
||||
@@ -268,6 +268,14 @@ SOURCE=..\Common\OutStreamWithCRC.cpp
|
||||
|
||||
SOURCE=..\Common\OutStreamWithCRC.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\Common\ParseProperties.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\Common\ParseProperties.h
|
||||
# End Source File
|
||||
# End Group
|
||||
# Begin Group "7zip common"
|
||||
|
||||
|
||||
@@ -198,34 +198,53 @@ HRESULT CAddCommon::Compress(ISequentialInStream *inStream, IOutStream *outStrea
|
||||
if (method == NFileHeader::NCompressionMethod::kDeflated ||
|
||||
method == NFileHeader::NCompressionMethod::kDeflated64)
|
||||
{
|
||||
NWindows::NCOM::CPropVariant properties[2] =
|
||||
NWindows::NCOM::CPropVariant properties[] =
|
||||
{
|
||||
_options.NumPasses,
|
||||
_options.NumFastBytes
|
||||
_options.NumFastBytes,
|
||||
_options.NumMatchFinderCycles
|
||||
};
|
||||
PROPID propIDs[2] =
|
||||
PROPID propIDs[] =
|
||||
{
|
||||
NCoderPropID::kNumPasses,
|
||||
NCoderPropID::kNumFastBytes
|
||||
NCoderPropID::kNumFastBytes,
|
||||
NCoderPropID::kMatchFinderCycles
|
||||
};
|
||||
int numProps = sizeof(propIDs) / sizeof(propIDs[0]);
|
||||
if (!_options.NumMatchFinderCyclesDefined)
|
||||
numProps--;
|
||||
CMyComPtr<ICompressSetCoderProperties> setCoderProperties;
|
||||
RINOK(_compressEncoder.QueryInterface(IID_ICompressSetCoderProperties, &setCoderProperties));
|
||||
RINOK(setCoderProperties->SetCoderProperties(propIDs, properties, 2));
|
||||
} else if (method == NFileHeader::NCompressionMethod::kBZip2)
|
||||
_compressEncoder.QueryInterface(IID_ICompressSetCoderProperties, &setCoderProperties);
|
||||
if (setCoderProperties)
|
||||
{
|
||||
RINOK(setCoderProperties->SetCoderProperties(propIDs, properties, numProps));
|
||||
}
|
||||
}
|
||||
else if (method == NFileHeader::NCompressionMethod::kBZip2)
|
||||
{
|
||||
NWindows::NCOM::CPropVariant properties[1] =
|
||||
NWindows::NCOM::CPropVariant properties[] =
|
||||
{
|
||||
_options.DicSize,
|
||||
_options.NumPasses
|
||||
#ifdef COMPRESS_MT
|
||||
, _options.NumThreads
|
||||
#endif
|
||||
};
|
||||
PROPID propIDs[1] =
|
||||
PROPID propIDs[] =
|
||||
{
|
||||
NCoderPropID::kNumPasses,
|
||||
NCoderPropID::kDictionarySize,
|
||||
NCoderPropID::kNumPasses
|
||||
#ifdef COMPRESS_MT
|
||||
, NCoderPropID::kNumThreads
|
||||
#endif
|
||||
};
|
||||
CMyComPtr<ICompressSetCoderProperties> setCoderProperties;
|
||||
RINOK(_compressEncoder.QueryInterface(IID_ICompressSetCoderProperties, &setCoderProperties));
|
||||
RINOK(setCoderProperties->SetCoderProperties(propIDs, properties, 1));
|
||||
_compressEncoder.QueryInterface(IID_ICompressSetCoderProperties, &setCoderProperties);
|
||||
if (setCoderProperties)
|
||||
{
|
||||
RINOK(setCoderProperties->SetCoderProperties(propIDs, properties, sizeof(propIDs) / sizeof(propIDs[0])));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
CMyComPtr<ISequentialOutStream> outStreamNew;
|
||||
if (_options.PasswordIsDefined)
|
||||
|
||||
@@ -15,8 +15,15 @@ struct CCompressionMethodMode
|
||||
// bool MaximizeRatio;
|
||||
UInt32 NumPasses;
|
||||
UInt32 NumFastBytes;
|
||||
bool NumMatchFinderCyclesDefined;
|
||||
UInt32 NumMatchFinderCycles;
|
||||
UInt32 DicSize;
|
||||
#ifdef COMPRESS_MT
|
||||
UInt32 NumThreads;
|
||||
#endif
|
||||
bool PasswordIsDefined;
|
||||
AString Password;
|
||||
CCompressionMethodMode(): NumMatchFinderCyclesDefined(false) {}
|
||||
};
|
||||
|
||||
}}
|
||||
|
||||
@@ -539,13 +539,27 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
|
||||
}
|
||||
ICompressCoder *coder = methodItems[m].Coder;
|
||||
|
||||
CMyComPtr<ICompressSetDecoderProperties2> compressSetDecoderProperties;
|
||||
if (coder->QueryInterface(IID_ICompressSetDecoderProperties2, (void **)&compressSetDecoderProperties) == S_OK)
|
||||
{
|
||||
Byte properties = (Byte)item.Flags;
|
||||
RINOK(compressSetDecoderProperties->SetDecoderProperties2(&properties, 1));
|
||||
CMyComPtr<ICompressSetDecoderProperties2> setDecoderProperties;
|
||||
coder->QueryInterface(IID_ICompressSetDecoderProperties2, (void **)&setDecoderProperties);
|
||||
if (setDecoderProperties)
|
||||
{
|
||||
Byte properties = (Byte)item.Flags;
|
||||
RINOK(setDecoderProperties->SetDecoderProperties2(&properties, 1));
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef COMPRESS_MT
|
||||
{
|
||||
CMyComPtr<ICompressSetCoderMt> setCoderMt;
|
||||
coder->QueryInterface(IID_ICompressSetCoderMt, (void **)&setCoderMt);
|
||||
if (setCoderMt)
|
||||
{
|
||||
RINOK(setCoderMt->SetNumberOfThreads(_numThreads));
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
// case NFileHeader::NCompressionMethod::kImploded:
|
||||
// switch(item.CompressionMethod)
|
||||
try
|
||||
|
||||
@@ -10,6 +10,10 @@
|
||||
#include "ZipIn.h"
|
||||
#include "ZipCompressionMode.h"
|
||||
|
||||
#ifdef COMPRESS_MT
|
||||
#include "../../../Windows/System.h"
|
||||
#endif
|
||||
|
||||
namespace NArchive {
|
||||
namespace NZip {
|
||||
|
||||
@@ -61,14 +65,28 @@ private:
|
||||
|
||||
int m_Level;
|
||||
int m_MainMethod;
|
||||
UInt32 m_DicSize;
|
||||
UInt32 m_NumPasses;
|
||||
UInt32 m_NumFastBytes;
|
||||
UInt32 m_NumMatchFinderCycles;
|
||||
bool m_NumMatchFinderCyclesDefined;
|
||||
|
||||
#ifdef COMPRESS_MT
|
||||
UInt32 _numThreads;
|
||||
#endif
|
||||
|
||||
void InitMethodProperties()
|
||||
{
|
||||
m_Level = -1;
|
||||
m_MainMethod = -1;
|
||||
m_NumPasses = 0xFFFFFFFF;
|
||||
m_NumFastBytes = 0xFFFFFFFF;
|
||||
m_DicSize =
|
||||
m_NumPasses =
|
||||
m_NumFastBytes =
|
||||
m_NumMatchFinderCycles = 0xFFFFFFFF;
|
||||
m_NumMatchFinderCyclesDefined = false;
|
||||
#ifdef COMPRESS_MT
|
||||
_numThreads = NWindows::NSystem::GetNumberOfProcessors();;
|
||||
#endif
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
|
||||
#include "../../IPassword.h"
|
||||
#include "../Common/ItemNameUtils.h"
|
||||
#include "../Common/ParseProperties.h"
|
||||
|
||||
using namespace NWindows;
|
||||
using namespace NCOM;
|
||||
@@ -22,17 +23,21 @@ using namespace NTime;
|
||||
namespace NArchive {
|
||||
namespace NZip {
|
||||
|
||||
static const UInt32 kNumDeflatePassesX1 = 1;
|
||||
static const UInt32 kNumDeflatePassesX7 = 3;
|
||||
static const UInt32 kNumDeflatePassesX9 = 10;
|
||||
static const UInt32 kDeflateNumPassesX1 = 1;
|
||||
static const UInt32 kDeflateNumPassesX7 = 3;
|
||||
static const UInt32 kDeflateNumPassesX9 = 10;
|
||||
|
||||
static const UInt32 kNumFastBytesX1 = 32;
|
||||
static const UInt32 kNumFastBytesX7 = 64;
|
||||
static const UInt32 kNumFastBytesX9 = 128;
|
||||
|
||||
static const UInt32 kNumBZip2PassesX1 = 1;
|
||||
static const UInt32 kNumBZip2PassesX7 = 2;
|
||||
static const UInt32 kNumBZip2PassesX9 = 7;
|
||||
static const UInt32 kBZip2NumPassesX1 = 1;
|
||||
static const UInt32 kBZip2NumPassesX7 = 2;
|
||||
static const UInt32 kBZip2NumPassesX9 = 7;
|
||||
|
||||
static const UInt32 kBZip2DicSizeX1 = 100000;
|
||||
static const UInt32 kBZip2DicSizeX3 = 500000;
|
||||
static const UInt32 kBZip2DicSizeX5 = 900000;
|
||||
|
||||
STDMETHODIMP CHandler::GetFileTimeType(UInt32 *timeType)
|
||||
{
|
||||
@@ -202,21 +207,34 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numIt
|
||||
(mainMethod == NFileHeader::NCompressionMethod::kDeflated64);
|
||||
bool isBZip2 = (mainMethod == NFileHeader::NCompressionMethod::kBZip2);
|
||||
options.NumPasses = m_NumPasses;
|
||||
if (options.NumPasses == 0xFFFFFFFF)
|
||||
{
|
||||
if (isDeflate)
|
||||
options.NumPasses = (level >= 9 ? kNumDeflatePassesX9 :
|
||||
(level >= 7 ? kNumDeflatePassesX7 : kNumDeflatePassesX1));
|
||||
else if (isBZip2)
|
||||
options.NumPasses = (level >= 9 ? kNumBZip2PassesX9 :
|
||||
(level >= 7 ? kNumBZip2PassesX7 : kNumBZip2PassesX1));
|
||||
}
|
||||
|
||||
options.DicSize = m_DicSize;
|
||||
options.NumFastBytes = m_NumFastBytes;
|
||||
if (options.NumFastBytes == 0xFFFFFFFF)
|
||||
options.NumMatchFinderCycles = m_NumMatchFinderCycles;
|
||||
options.NumMatchFinderCyclesDefined = m_NumMatchFinderCyclesDefined;
|
||||
#ifdef COMPRESS_MT
|
||||
options.NumThreads = _numThreads;
|
||||
#endif
|
||||
if (isDeflate)
|
||||
{
|
||||
if (isDeflate)
|
||||
options.NumFastBytes = (level >= 9 ? kNumFastBytesX9 : (level >= 7 ? kNumFastBytesX7 : kNumFastBytesX1));
|
||||
if (options.NumPasses == 0xFFFFFFFF)
|
||||
options.NumPasses = (level >= 9 ? kDeflateNumPassesX9 :
|
||||
(level >= 7 ? kDeflateNumPassesX7 :
|
||||
kDeflateNumPassesX1));
|
||||
if (options.NumFastBytes == 0xFFFFFFFF)
|
||||
options.NumFastBytes = (level >= 9 ? kNumFastBytesX9 :
|
||||
(level >= 7 ? kNumFastBytesX7 :
|
||||
kNumFastBytesX1));
|
||||
}
|
||||
if (isBZip2)
|
||||
{
|
||||
if (options.NumPasses == 0xFFFFFFFF)
|
||||
options.NumPasses = (level >= 9 ? kBZip2NumPassesX9 :
|
||||
(level >= 7 ? kBZip2NumPassesX7 :
|
||||
kBZip2NumPassesX1));
|
||||
if (options.DicSize == 0xFFFFFFFF)
|
||||
options.DicSize = (level >= 5 ? kBZip2DicSizeX5 :
|
||||
(level >= 3 ? kBZip2DicSizeX3 :
|
||||
kBZip2DicSizeX1));
|
||||
}
|
||||
|
||||
return Update(m_Items, updateItems, outStream,
|
||||
@@ -226,45 +244,32 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numIt
|
||||
|
||||
STDMETHODIMP CHandler::SetProperties(const wchar_t **names, const PROPVARIANT *values, Int32 numProperties)
|
||||
{
|
||||
#ifdef COMPRESS_MT
|
||||
const UInt32 numProcessors = NSystem::GetNumberOfProcessors();
|
||||
_numThreads = numProcessors;
|
||||
#endif
|
||||
InitMethodProperties();
|
||||
for (int i = 0; i < numProperties; i++)
|
||||
{
|
||||
UString name = UString(names[i]);
|
||||
name.MakeUpper();
|
||||
const PROPVARIANT &value = values[i];
|
||||
if (name.IsEmpty())
|
||||
return E_INVALIDARG;
|
||||
|
||||
if (name[0] == 'X')
|
||||
const PROPVARIANT &prop = values[i];
|
||||
|
||||
if (name[0] == L'X')
|
||||
{
|
||||
name.Delete(0);
|
||||
UInt32 level = 9;
|
||||
if (value.vt == VT_UI4)
|
||||
{
|
||||
if (!name.IsEmpty())
|
||||
return E_INVALIDARG;
|
||||
level = value.ulVal;
|
||||
}
|
||||
else if (value.vt == VT_EMPTY)
|
||||
{
|
||||
if(!name.IsEmpty())
|
||||
{
|
||||
const wchar_t *start = name;
|
||||
const wchar_t *end;
|
||||
UInt64 v = ConvertStringToUInt64(start, &end);
|
||||
if (end - start != name.Length())
|
||||
return E_INVALIDARG;
|
||||
level = (UInt32)v;
|
||||
}
|
||||
}
|
||||
else
|
||||
return E_INVALIDARG;
|
||||
m_Level = (level <= 9) ? (int)level: 9;
|
||||
RINOK(ParsePropValue(name.Mid(1), prop, level));
|
||||
m_Level = level;
|
||||
continue;
|
||||
}
|
||||
else if (name == L"M")
|
||||
{
|
||||
if (value.vt == VT_BSTR)
|
||||
if (prop.vt == VT_BSTR)
|
||||
{
|
||||
UString valueString = value.bstrVal;
|
||||
UString valueString = prop.bstrVal;
|
||||
valueString.MakeUpper();
|
||||
if (valueString == L"COPY")
|
||||
m_MainMethod = NFileHeader::NCompressionMethod::kStored;
|
||||
@@ -277,15 +282,15 @@ STDMETHODIMP CHandler::SetProperties(const wchar_t **names, const PROPVARIANT *v
|
||||
else
|
||||
return E_INVALIDARG;
|
||||
}
|
||||
else if (value.vt == VT_UI4)
|
||||
else if (prop.vt == VT_UI4)
|
||||
{
|
||||
switch(value.ulVal)
|
||||
switch(prop.ulVal)
|
||||
{
|
||||
case NFileHeader::NCompressionMethod::kStored:
|
||||
case NFileHeader::NCompressionMethod::kDeflated:
|
||||
case NFileHeader::NCompressionMethod::kDeflated64:
|
||||
case NFileHeader::NCompressionMethod::kBZip2:
|
||||
m_MainMethod = (Byte)value.ulVal;
|
||||
m_MainMethod = (Byte)prop.ulVal;
|
||||
break;
|
||||
default:
|
||||
return E_INVALIDARG;
|
||||
@@ -294,25 +299,38 @@ STDMETHODIMP CHandler::SetProperties(const wchar_t **names, const PROPVARIANT *v
|
||||
else
|
||||
return E_INVALIDARG;
|
||||
}
|
||||
else if (name == L"PASS")
|
||||
else if (name[0] == L'D')
|
||||
{
|
||||
if (value.vt != VT_UI4)
|
||||
return E_INVALIDARG;
|
||||
if (value.ulVal < 1)
|
||||
return E_INVALIDARG;
|
||||
m_NumPasses = value.ulVal;
|
||||
UInt32 dicSize = kBZip2DicSizeX5;
|
||||
RINOK(ParsePropDictionaryValue(name.Mid(1), prop, dicSize));
|
||||
m_DicSize = dicSize;
|
||||
}
|
||||
else if (name == L"FB")
|
||||
else if (name.Left(4) == L"PASS")
|
||||
{
|
||||
if (value.vt != VT_UI4)
|
||||
return E_INVALIDARG;
|
||||
/*
|
||||
if (value.ulVal < 3 || value.ulVal > 255)
|
||||
return E_INVALIDARG;
|
||||
*/
|
||||
m_NumFastBytes = value.ulVal;
|
||||
UInt32 num = kDeflateNumPassesX9;
|
||||
RINOK(ParsePropValue(name.Mid(4), prop, num));
|
||||
m_NumPasses = num;
|
||||
}
|
||||
else
|
||||
else if (name.Left(2) == L"FB")
|
||||
{
|
||||
UInt32 num = kNumFastBytesX9;
|
||||
RINOK(ParsePropValue(name.Mid(2), prop, num));
|
||||
m_NumFastBytes = num;
|
||||
}
|
||||
else if (name.Left(2) == L"MC")
|
||||
{
|
||||
UInt32 num = 0xFFFFFFFF;
|
||||
RINOK(ParsePropValue(name.Mid(2), prop, num));
|
||||
m_NumMatchFinderCycles = num;
|
||||
m_NumMatchFinderCyclesDefined = true;
|
||||
}
|
||||
else if (name.Left(2) == L"MT")
|
||||
{
|
||||
#ifdef COMPRESS_MT
|
||||
RINOK(ParseMtProp(name.Mid(2), prop, numProcessors, _numThreads));
|
||||
#endif
|
||||
}
|
||||
else
|
||||
return E_INVALIDARG;
|
||||
}
|
||||
return S_OK;
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
PROG = zip.dll
|
||||
DEF_FILE = ../Archive.def
|
||||
CFLAGS = $(CFLAGS) -I ../../../
|
||||
CFLAGS = $(CFLAGS) -I ../../../ -DCOMPRESS_MT
|
||||
LIBS = $(LIBS) oleaut32.lib user32.lib
|
||||
|
||||
ZIP_OBJS = \
|
||||
@@ -47,6 +47,7 @@ AR_COMMON_OBJS = \
|
||||
$O\InStreamWithCRC.obj \
|
||||
$O\ItemNameUtils.obj \
|
||||
$O\OutStreamWithCRC.obj \
|
||||
$O\ParseProperties.obj \
|
||||
|
||||
7Z_OBJS = \
|
||||
$O\7zMethodID.obj \
|
||||
|
||||
@@ -44,7 +44,7 @@ RSC=rc.exe
|
||||
# PROP Ignore_Export_Lib 0
|
||||
# PROP Target_Dir ""
|
||||
# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
|
||||
# ADD CPP /nologo /Gz /MT /W3 /GX /O1 /I "..\..\..\\" /D "NDEBUG" /D "_MBCS" /D "WIN32" /D "_CONSOLE" /D "EXCLUDE_COM" /D "NO_REGISTRY" /D "FORMAT_7Z" /D "FORMAT_BZIP2" /D "FORMAT_ZIP" /D "FORMAT_TAR" /D "FORMAT_GZIP" /D "FORMAT_Z" /D "FORMAT_SPLIT" /D "COMPRESS_LZMA" /D "COMPRESS_BCJ_X86" /D "COMPRESS_BCJ2" /D "COMPRESS_COPY" /D "COMPRESS_MF_MT" /D "COMPRESS_PPMD" /D "COMPRESS_DEFLATE" /D "COMPRESS_DEFLATE64" /D "COMPRESS_IMPLODE" /D "COMPRESS_BZIP2" /D "CRYPTO_ZIP" /D "CRYPTO_7ZAES" /D "CRYPTO_AES" /Yu"StdAfx.h" /FD /c
|
||||
# ADD CPP /nologo /Gz /MT /W3 /GX /O1 /I "..\..\..\\" /D "NDEBUG" /D "_MBCS" /D "WIN32" /D "_CONSOLE" /D "EXCLUDE_COM" /D "NO_REGISTRY" /D "FORMAT_7Z" /D "FORMAT_BZIP2" /D "FORMAT_ZIP" /D "FORMAT_TAR" /D "FORMAT_GZIP" /D "FORMAT_Z" /D "FORMAT_SPLIT" /D "COMPRESS_LZMA" /D "COMPRESS_BCJ_X86" /D "COMPRESS_BCJ2" /D "COMPRESS_COPY" /D "COMPRESS_MF_MT" /D "COMPRESS_PPMD" /D "COMPRESS_DEFLATE" /D "COMPRESS_DEFLATE64" /D "COMPRESS_IMPLODE" /D "COMPRESS_BZIP2" /D "CRYPTO_ZIP" /D "CRYPTO_7ZAES" /D "CRYPTO_AES" /D "COMPRESS_MT" /D "COMPRESS_BZIP2_MT" /Yu"StdAfx.h" /FD /c
|
||||
# ADD BASE RSC /l 0x419 /d "NDEBUG"
|
||||
# ADD RSC /l 0x419 /d "NDEBUG"
|
||||
BSC32=bscmake.exe
|
||||
@@ -69,7 +69,7 @@ LINK32=link.exe
|
||||
# PROP Ignore_Export_Lib 0
|
||||
# PROP Target_Dir ""
|
||||
# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c
|
||||
# ADD CPP /nologo /Gz /W3 /Gm /GX /ZI /Od /I "..\..\..\\" /D "_DEBUG" /D "_MBCS" /D "WIN32" /D "_CONSOLE" /D "EXCLUDE_COM" /D "NO_REGISTRY" /D "FORMAT_7Z" /D "FORMAT_BZIP2" /D "FORMAT_ZIP" /D "FORMAT_TAR" /D "FORMAT_GZIP" /D "FORMAT_Z" /D "FORMAT_SPLIT" /D "COMPRESS_LZMA" /D "COMPRESS_BCJ_X86" /D "COMPRESS_BCJ2" /D "COMPRESS_COPY" /D "COMPRESS_MF_MT" /D "COMPRESS_PPMD" /D "COMPRESS_DEFLATE" /D "COMPRESS_DEFLATE64" /D "COMPRESS_IMPLODE" /D "COMPRESS_BZIP2" /D "CRYPTO_ZIP" /D "CRYPTO_7ZAES" /D "CRYPTO_AES" /Yu"StdAfx.h" /FD /GZ /c
|
||||
# ADD CPP /nologo /Gz /W3 /Gm /GX /ZI /Od /I "..\..\..\\" /D "_DEBUG" /D "_MBCS" /D "WIN32" /D "_CONSOLE" /D "EXCLUDE_COM" /D "NO_REGISTRY" /D "FORMAT_7Z" /D "FORMAT_BZIP2" /D "FORMAT_ZIP" /D "FORMAT_TAR" /D "FORMAT_GZIP" /D "FORMAT_Z" /D "FORMAT_SPLIT" /D "COMPRESS_LZMA" /D "COMPRESS_BCJ_X86" /D "COMPRESS_BCJ2" /D "COMPRESS_COPY" /D "COMPRESS_MF_MT" /D "COMPRESS_PPMD" /D "COMPRESS_DEFLATE" /D "COMPRESS_DEFLATE64" /D "COMPRESS_IMPLODE" /D "COMPRESS_BZIP2" /D "CRYPTO_ZIP" /D "CRYPTO_7ZAES" /D "CRYPTO_AES" /D "COMPRESS_MT" /D "COMPRESS_BZIP2_MT" /Yu"StdAfx.h" /FD /GZ /c
|
||||
# ADD BASE RSC /l 0x419 /d "_DEBUG"
|
||||
# ADD RSC /l 0x419 /d "_DEBUG"
|
||||
BSC32=bscmake.exe
|
||||
@@ -94,7 +94,7 @@ LINK32=link.exe
|
||||
# PROP Ignore_Export_Lib 0
|
||||
# PROP Target_Dir ""
|
||||
# ADD BASE CPP /nologo /MD /W3 /GX /O2 /D "NDEBUG" /D "WIN32" /D "_CONSOLE" /D "EXCLUDE_COM" /D "NO_REGISTRY" /D "FORMAT_7Z" /D "FORMAT_BZIP2" /D "FORMAT_ZIP" /D "FORMAT_TAR" /D "FORMAT_GZIP" /D "COMPRESS_LZMA" /D "COMPRESS_BCJ_X86" /D "COMPRESS_BCJ2" /D "COMPRESS_COPY" /D "COMPRESS_MF_PAT" /D "COMPRESS_MF_BT" /D "COMPRESS_PPMD" /D "COMPRESS_DEFLATE" /D "COMPRESS_IMPLODE" /D "COMPRESS_BZIP2" /D "CRYPTO_ZIP" /Yu"StdAfx.h" /FD /c
|
||||
# ADD CPP /nologo /Gz /MD /W3 /GX /O1 /I "..\..\..\\" /D "NDEBUG" /D "UNICODE" /D "_UNICODE" /D "WIN32" /D "_CONSOLE" /D "EXCLUDE_COM" /D "NO_REGISTRY" /D "FORMAT_7Z" /D "FORMAT_BZIP2" /D "FORMAT_ZIP" /D "FORMAT_TAR" /D "FORMAT_GZIP" /D "FORMAT_Z" /D "FORMAT_SPLIT" /D "COMPRESS_LZMA" /D "COMPRESS_BCJ_X86" /D "COMPRESS_BCJ2" /D "COMPRESS_COPY" /D "COMPRESS_MF_MT" /D "COMPRESS_PPMD" /D "COMPRESS_DEFLATE" /D "COMPRESS_DEFLATE64" /D "COMPRESS_IMPLODE" /D "COMPRESS_BZIP2" /D "CRYPTO_ZIP" /D "CRYPTO_7ZAES" /D "CRYPTO_AES" /Yu"StdAfx.h" /FD /c
|
||||
# ADD CPP /nologo /Gz /MD /W3 /GX /O1 /I "..\..\..\\" /D "NDEBUG" /D "UNICODE" /D "_UNICODE" /D "WIN32" /D "_CONSOLE" /D "EXCLUDE_COM" /D "NO_REGISTRY" /D "FORMAT_7Z" /D "FORMAT_BZIP2" /D "FORMAT_ZIP" /D "FORMAT_TAR" /D "FORMAT_GZIP" /D "FORMAT_Z" /D "FORMAT_SPLIT" /D "COMPRESS_LZMA" /D "COMPRESS_BCJ_X86" /D "COMPRESS_BCJ2" /D "COMPRESS_COPY" /D "COMPRESS_MF_MT" /D "COMPRESS_PPMD" /D "COMPRESS_DEFLATE" /D "COMPRESS_DEFLATE64" /D "COMPRESS_IMPLODE" /D "COMPRESS_BZIP2" /D "CRYPTO_ZIP" /D "CRYPTO_7ZAES" /D "CRYPTO_AES" /D "COMPRESS_MT" /D "COMPRESS_BZIP2_MT" /Yu"StdAfx.h" /FD /c
|
||||
# ADD BASE RSC /l 0x419 /d "NDEBUG"
|
||||
# ADD RSC /l 0x419 /d "NDEBUG"
|
||||
BSC32=bscmake.exe
|
||||
@@ -121,7 +121,7 @@ LINK32=link.exe
|
||||
# PROP Ignore_Export_Lib 0
|
||||
# PROP Target_Dir ""
|
||||
# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "_DEBUG" /D "WIN32" /D "_CONSOLE" /D "EXCLUDE_COM" /D "NO_REGISTRY" /D "FORMAT_7Z" /D "FORMAT_BZIP2" /D "FORMAT_ZIP" /D "FORMAT_TAR" /D "FORMAT_GZIP" /D "COMPRESS_LZMA" /D "COMPRESS_BCJ_X86" /D "COMPRESS_BCJ2" /D "COMPRESS_COPY" /D "COMPRESS_MF_PAT" /D "COMPRESS_MF_BT" /D "COMPRESS_PPMD" /D "COMPRESS_DEFLATE" /D "COMPRESS_IMPLODE" /D "COMPRESS_BZIP2" /D "CRYPTO_ZIP" /D "_MBCS" /Yu"StdAfx.h" /FD /GZ /c
|
||||
# ADD CPP /nologo /Gz /W3 /Gm /GX /ZI /Od /I "..\..\..\\" /D "_DEBUG" /D "_UNICODE" /D "UNICODE" /D "WIN32" /D "_CONSOLE" /D "EXCLUDE_COM" /D "NO_REGISTRY" /D "FORMAT_7Z" /D "FORMAT_BZIP2" /D "FORMAT_ZIP" /D "FORMAT_TAR" /D "FORMAT_GZIP" /D "FORMAT_Z" /D "FORMAT_SPLIT" /D "COMPRESS_LZMA" /D "COMPRESS_BCJ_X86" /D "COMPRESS_BCJ2" /D "COMPRESS_COPY" /D "COMPRESS_MF_MT" /D "COMPRESS_PPMD" /D "COMPRESS_DEFLATE" /D "COMPRESS_DEFLATE64" /D "COMPRESS_IMPLODE" /D "COMPRESS_BZIP2" /D "CRYPTO_ZIP" /D "CRYPTO_7ZAES" /D "CRYPTO_AES" /Yu"StdAfx.h" /FD /GZ /c
|
||||
# ADD CPP /nologo /Gz /W3 /Gm /GX /ZI /Od /I "..\..\..\\" /D "_DEBUG" /D "_UNICODE" /D "UNICODE" /D "WIN32" /D "_CONSOLE" /D "EXCLUDE_COM" /D "NO_REGISTRY" /D "FORMAT_7Z" /D "FORMAT_BZIP2" /D "FORMAT_ZIP" /D "FORMAT_TAR" /D "FORMAT_GZIP" /D "FORMAT_Z" /D "FORMAT_SPLIT" /D "COMPRESS_LZMA" /D "COMPRESS_BCJ_X86" /D "COMPRESS_BCJ2" /D "COMPRESS_COPY" /D "COMPRESS_MF_MT" /D "COMPRESS_PPMD" /D "COMPRESS_DEFLATE" /D "COMPRESS_DEFLATE64" /D "COMPRESS_IMPLODE" /D "COMPRESS_BZIP2" /D "CRYPTO_ZIP" /D "CRYPTO_7ZAES" /D "CRYPTO_AES" /D "COMPRESS_MT" /D "COMPRESS_BZIP2_MT" /Yu"StdAfx.h" /FD /GZ /c
|
||||
# ADD BASE RSC /l 0x419 /d "_DEBUG"
|
||||
# ADD RSC /l 0x419 /d "_DEBUG"
|
||||
BSC32=bscmake.exe
|
||||
@@ -1652,6 +1652,14 @@ SOURCE=..\..\Archive\Common\OutStreamWithCRC.cpp
|
||||
|
||||
SOURCE=..\..\Archive\Common\OutStreamWithCRC.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\Archive\Common\ParseProperties.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\Archive\Common\ParseProperties.h
|
||||
# End Source File
|
||||
# End Group
|
||||
# Begin Group "split"
|
||||
|
||||
@@ -1763,6 +1771,14 @@ SOURCE=..\..\UI\Common\PropIDUtils.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\UI\Common\SetProperties.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\UI\Common\SetProperties.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\UI\Common\SortUtils.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
@@ -11,9 +11,11 @@ CFLAGS = $(CFLAGS) -I ../../../ \
|
||||
-DFORMAT_TAR \
|
||||
-DFORMAT_Z \
|
||||
-DFORMAT_ZIP \
|
||||
-DCOMPRESS_MT \
|
||||
-DCOMPRESS_BCJ_X86 \
|
||||
-DCOMPRESS_BCJ2 \
|
||||
-DCOMPRESS_BZIP2 \
|
||||
-DCOMPRESS_BZIP2_MT \
|
||||
-DCOMPRESS_COPY \
|
||||
-DCOMPRESS_DEFLATE \
|
||||
-DCOMPRESS_DEFLATE64 \
|
||||
@@ -93,6 +95,7 @@ UI_COMMON_OBJS = \
|
||||
$O\ExtractingFilePath.obj \
|
||||
$O\OpenArchive.obj \
|
||||
$O\PropIDUtils.obj \
|
||||
$O\SetProperties.obj \
|
||||
$O\SortUtils.obj \
|
||||
$O\TempFiles.obj \
|
||||
$O\Update.obj \
|
||||
@@ -112,6 +115,7 @@ AR_COMMON_OBJS = \
|
||||
$O\ItemNameUtils.obj \
|
||||
$O\MultiStream.obj \
|
||||
$O\OutStreamWithCRC.obj \
|
||||
$O\ParseProperties.obj \
|
||||
|
||||
|
||||
7Z_OBJS = \
|
||||
|
||||
@@ -43,7 +43,7 @@ RSC=rc.exe
|
||||
# PROP Ignore_Export_Lib 1
|
||||
# PROP Target_Dir ""
|
||||
# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "MY7Z_EXPORTS" /YX /FD /c
|
||||
# ADD CPP /nologo /Gz /MT /W3 /GX /O1 /I "..\..\..\\" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "MY7Z_EXPORTS" /D "EXCLUDE_COM" /D "NO_REGISTRY" /D "FORMAT_7Z" /D "COMPRESS_LZMA" /D "COMPRESS_BCJ_X86" /D "COMPRESS_BCJ2" /D "COMPRESS_COPY" /D "COMPRESS_MF_MT" /D "COMPRESS_PPMD" /D "COMPRESS_DEFLATE_DECODER" /D "COMPRESS_BZIP2_DECODER" /D "CRYPTO_7ZAES" /D "CRYPTO_AES" /Yu"StdAfx.h" /FD /c
|
||||
# ADD CPP /nologo /Gz /MT /W3 /GX /O1 /I "..\..\..\\" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "MY7Z_EXPORTS" /D "EXCLUDE_COM" /D "NO_REGISTRY" /D "FORMAT_7Z" /D "COMPRESS_LZMA" /D "COMPRESS_BCJ_X86" /D "COMPRESS_BCJ2" /D "COMPRESS_COPY" /D "COMPRESS_MF_MT" /D "COMPRESS_PPMD" /D "COMPRESS_DEFLATE_DECODER" /D "COMPRESS_BZIP2_DECODER" /D "CRYPTO_7ZAES" /D "CRYPTO_AES" /D "COMPRESS_MT" /D "COMPRESS_BZIP2_MT" /Yu"StdAfx.h" /FD /c
|
||||
# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
|
||||
# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
|
||||
# ADD BASE RSC /l 0x419 /d "NDEBUG"
|
||||
@@ -70,7 +70,7 @@ LINK32=link.exe
|
||||
# PROP Ignore_Export_Lib 1
|
||||
# PROP Target_Dir ""
|
||||
# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "MY7Z_EXPORTS" /YX /FD /GZ /c
|
||||
# ADD CPP /nologo /Gz /MTd /W3 /Gm /GX /ZI /Od /I "..\..\..\..\SDK" /I "..\..\..\\" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "MY7Z_EXPORTS" /D "EXCLUDE_COM" /D "NO_REGISTRY" /D "FORMAT_7Z" /D "COMPRESS_LZMA" /D "COMPRESS_BCJ_X86" /D "COMPRESS_BCJ2" /D "COMPRESS_COPY" /D "COMPRESS_MF_MT" /D "COMPRESS_PPMD" /D "COMPRESS_DEFLATE_DECODER" /D "COMPRESS_BZIP2_DECODER" /D "CRYPTO_7ZAES" /D "CRYPTO_AES" /Yu"StdAfx.h" /FD /GZ /c
|
||||
# ADD CPP /nologo /Gz /MTd /W3 /Gm /GX /ZI /Od /I "..\..\..\..\SDK" /I "..\..\..\\" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "MY7Z_EXPORTS" /D "EXCLUDE_COM" /D "NO_REGISTRY" /D "FORMAT_7Z" /D "COMPRESS_LZMA" /D "COMPRESS_BCJ_X86" /D "COMPRESS_BCJ2" /D "COMPRESS_COPY" /D "COMPRESS_MF_MT" /D "COMPRESS_PPMD" /D "COMPRESS_DEFLATE_DECODER" /D "COMPRESS_BZIP2_DECODER" /D "CRYPTO_7ZAES" /D "CRYPTO_AES" /D "COMPRESS_MT" /D "COMPRESS_BZIP2_MT" /Yu"StdAfx.h" /FD /GZ /c
|
||||
# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32
|
||||
# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32
|
||||
# ADD BASE RSC /l 0x419 /d "_DEBUG"
|
||||
@@ -292,6 +292,14 @@ SOURCE=..\..\Archive\Common\OutStreamWithCRC.cpp
|
||||
|
||||
SOURCE=..\..\Archive\Common\OutStreamWithCRC.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\Archive\Common\ParseProperties.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\Archive\Common\ParseProperties.h
|
||||
# End Source File
|
||||
# End Group
|
||||
# Begin Group "Compress"
|
||||
|
||||
|
||||
@@ -5,9 +5,11 @@ CFLAGS = $(CFLAGS) -I ../../../ \
|
||||
-DEXCLUDE_COM \
|
||||
-DNO_REGISTRY \
|
||||
-DFORMAT_7Z \
|
||||
-DCOMPRESS_MT \
|
||||
-DCOMPRESS_BCJ_X86 \
|
||||
-DCOMPRESS_BCJ2 \
|
||||
-DCOMPRESS_BZIP2_DECODER \
|
||||
-DCOMPRESS_BZIP2_MT \
|
||||
-DCOMPRESS_COPY \
|
||||
-DCOMPRESS_DEFLATE_DECODER \
|
||||
-DCOMPRESS_LZMA \
|
||||
@@ -54,6 +56,7 @@ AR_COMMON_OBJS = \
|
||||
$O\InStreamWithCRC.obj \
|
||||
$O\ItemNameUtils.obj \
|
||||
$O\OutStreamWithCRC.obj \
|
||||
$O\ParseProperties.obj \
|
||||
|
||||
|
||||
7Z_OBJS = \
|
||||
|
||||
@@ -43,7 +43,7 @@ RSC=rc.exe
|
||||
# PROP Ignore_Export_Lib 1
|
||||
# PROP Target_Dir ""
|
||||
# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "MY7Z_EXPORTS" /YX /FD /c
|
||||
# ADD CPP /nologo /Gz /MT /W3 /GX /O1 /I "..\..\..\\" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "MY7Z_EXPORTS" /D "EXCLUDE_COM" /D "NO_REGISTRY" /D "EXTRACT_ONLY" /D "FORMAT_7Z" /D "COMPRESS_LZMA" /D "COMPRESS_BCJ_X86" /D "COMPRESS_BCJ2" /D "COMPRESS_COPY" /D "COMPRESS_MF_MT" /D "COMPRESS_PPMD" /D "COMPRESS_DEFLATE_DECODER" /D "COMPRESS_BZIP2_DECODER" /D "CRYPTO_7ZAES" /D "CRYPTO_AES" /Yu"StdAfx.h" /FD /c
|
||||
# ADD CPP /nologo /Gz /MT /W3 /GX /O1 /I "..\..\..\\" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "MY7Z_EXPORTS" /D "EXCLUDE_COM" /D "NO_REGISTRY" /D "EXTRACT_ONLY" /D "FORMAT_7Z" /D "COMPRESS_LZMA" /D "COMPRESS_BCJ_X86" /D "COMPRESS_BCJ2" /D "COMPRESS_COPY" /D "COMPRESS_MF_MT" /D "COMPRESS_PPMD" /D "COMPRESS_DEFLATE_DECODER" /D "COMPRESS_BZIP2_DECODER" /D "CRYPTO_7ZAES" /D "CRYPTO_AES" /D "COMPRESS_MT" /D "COMPRESS_BZIP2_MT" /Yu"StdAfx.h" /FD /c
|
||||
# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
|
||||
# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
|
||||
# ADD BASE RSC /l 0x419 /d "NDEBUG"
|
||||
@@ -70,7 +70,7 @@ LINK32=link.exe
|
||||
# PROP Ignore_Export_Lib 1
|
||||
# PROP Target_Dir ""
|
||||
# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "MY7Z_EXPORTS" /YX /FD /GZ /c
|
||||
# ADD CPP /nologo /Gz /MTd /W3 /Gm /GX /ZI /Od /I "..\..\..\..\SDK" /I "..\..\..\\" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "MY7Z_EXPORTS" /D "EXCLUDE_COM" /D "NO_REGISTRY" /D "EXTRACT_ONLY" /D "FORMAT_7Z" /D "COMPRESS_LZMA" /D "COMPRESS_BCJ_X86" /D "COMPRESS_BCJ2" /D "COMPRESS_COPY" /D "COMPRESS_MF_MT" /D "COMPRESS_PPMD" /D "COMPRESS_DEFLATE_DECODER" /D "COMPRESS_BZIP2_DECODER" /D "CRYPTO_7ZAES" /D "CRYPTO_AES" /Yu"StdAfx.h" /FD /GZ /c
|
||||
# ADD CPP /nologo /Gz /MTd /W3 /Gm /GX /ZI /Od /I "..\..\..\..\SDK" /I "..\..\..\\" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "MY7Z_EXPORTS" /D "EXCLUDE_COM" /D "NO_REGISTRY" /D "EXTRACT_ONLY" /D "FORMAT_7Z" /D "COMPRESS_LZMA" /D "COMPRESS_BCJ_X86" /D "COMPRESS_BCJ2" /D "COMPRESS_COPY" /D "COMPRESS_MF_MT" /D "COMPRESS_PPMD" /D "COMPRESS_DEFLATE_DECODER" /D "COMPRESS_BZIP2_DECODER" /D "CRYPTO_7ZAES" /D "CRYPTO_AES" /D "COMPRESS_MT" /D "COMPRESS_BZIP2_MT" /Yu"StdAfx.h" /FD /GZ /c
|
||||
# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32
|
||||
# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32
|
||||
# ADD BASE RSC /l 0x419 /d "_DEBUG"
|
||||
@@ -288,6 +288,14 @@ SOURCE=..\..\Archive\Common\OutStreamWithCRC.cpp
|
||||
|
||||
SOURCE=..\..\Archive\Common\OutStreamWithCRC.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\Archive\Common\ParseProperties.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\Archive\Common\ParseProperties.h
|
||||
# End Source File
|
||||
# End Group
|
||||
# Begin Group "Compress"
|
||||
|
||||
|
||||
@@ -6,9 +6,11 @@ CFLAGS = $(CFLAGS) -I ../../../ \
|
||||
-DNO_REGISTRY \
|
||||
-DEXTRACT_ONLY \
|
||||
-DFORMAT_7Z \
|
||||
-DCOMPRESS_MT \
|
||||
-DCOMPRESS_BCJ_X86 \
|
||||
-DCOMPRESS_BCJ2 \
|
||||
-DCOMPRESS_BZIP2_DECODER \
|
||||
-DCOMPRESS_BZIP2_MT \
|
||||
-DCOMPRESS_COPY \
|
||||
-DCOMPRESS_DEFLATE_DECODER \
|
||||
-DCOMPRESS_LZMA \
|
||||
@@ -54,6 +56,7 @@ AR_COMMON_OBJS = \
|
||||
$O\FilterCoder.obj \
|
||||
$O\ItemNameUtils.obj \
|
||||
$O\OutStreamWithCRC.obj \
|
||||
$O\ParseProperties.obj \
|
||||
|
||||
|
||||
7Z_OBJS = \
|
||||
|
||||
@@ -43,7 +43,7 @@ RSC=rc.exe
|
||||
# PROP Ignore_Export_Lib 1
|
||||
# PROP Target_Dir ""
|
||||
# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "BZIP2_EXPORTS" /YX /FD /c
|
||||
# ADD CPP /nologo /Gz /MD /W3 /GX /O1 /I "..\..\..\\" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "BZIP2_EXPORTS" /D "BZ_NO_STDIO" /Yu"StdAfx.h" /FD /c
|
||||
# ADD CPP /nologo /Gz /MD /W3 /GX /O1 /I "..\..\..\\" /D "NDEBUG" /D "BZ_NO_STDIO" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "BZIP2_EXPORTS" /D "COMPRESS_BZIP2_MT" /Yu"StdAfx.h" /FD /c
|
||||
# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
|
||||
# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
|
||||
# ADD BASE RSC /l 0x419 /d "NDEBUG"
|
||||
@@ -70,7 +70,7 @@ LINK32=link.exe
|
||||
# PROP Ignore_Export_Lib 1
|
||||
# PROP Target_Dir ""
|
||||
# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "BZIP2_EXPORTS" /YX /FD /GZ /c
|
||||
# ADD CPP /nologo /Gz /MDd /W3 /Gm /GX /ZI /Od /I "..\..\..\\" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "BZIP2_EXPORTS" /Yu"StdAfx.h" /FD /GZ /c
|
||||
# ADD CPP /nologo /Gz /MDd /W3 /Gm /GX /ZI /Od /I "..\..\..\\" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "BZIP2_EXPORTS" /D "COMPRESS_BZIP2_MT" /Yu"StdAfx.h" /FD /GZ /c
|
||||
# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32
|
||||
# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32
|
||||
# ADD BASE RSC /l 0x419 /d "_DEBUG"
|
||||
@@ -213,6 +213,26 @@ SOURCE=..\BWT\BlockSort.h
|
||||
SOURCE=..\BWT\Mtf8.h
|
||||
# End Source File
|
||||
# End Group
|
||||
# Begin Group "Windows"
|
||||
|
||||
# PROP Default_Filter ""
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\Windows\Synchronization.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\Windows\Synchronization.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\Windows\Thread.h
|
||||
# End Source File
|
||||
# End Group
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\BZip2Const.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\BZip2CRC.cpp
|
||||
|
||||
@@ -12,6 +12,8 @@
|
||||
namespace NCompress {
|
||||
namespace NBZip2 {
|
||||
|
||||
const UInt32 kNumThreadsMax = 4;
|
||||
|
||||
static const UInt32 kBufferSize = (1 << 17);
|
||||
|
||||
static Int16 kRandNums[512] = {
|
||||
@@ -69,11 +71,6 @@ static Int16 kRandNums[512] = {
|
||||
936, 638
|
||||
};
|
||||
|
||||
CState::~CState()
|
||||
{
|
||||
::BigFree(tt);
|
||||
}
|
||||
|
||||
bool CState::Alloc()
|
||||
{
|
||||
if (tt == 0)
|
||||
@@ -81,6 +78,109 @@ bool CState::Alloc()
|
||||
return (tt != 0);
|
||||
}
|
||||
|
||||
void CState::Free()
|
||||
{
|
||||
::BigFree(tt);
|
||||
tt = 0;
|
||||
}
|
||||
|
||||
#ifdef COMPRESS_BZIP2_MT
|
||||
void CState::FinishStream()
|
||||
{
|
||||
Decoder->StreamWasFinished = true;
|
||||
StreamWasFinishedEvent.Set();
|
||||
Decoder->CS.Leave();
|
||||
Decoder->CanStartWaitingEvent.Lock();
|
||||
WaitingWasStartedEvent.Set();
|
||||
}
|
||||
|
||||
DWORD CState::ThreadFunc()
|
||||
{
|
||||
while (true)
|
||||
{
|
||||
Decoder->CS.Enter();
|
||||
if (Decoder->CloseThreads)
|
||||
{
|
||||
Decoder->CS.Leave();
|
||||
return 0;
|
||||
}
|
||||
if (Decoder->StreamWasFinished)
|
||||
{
|
||||
FinishStream();
|
||||
continue;
|
||||
}
|
||||
HRESULT res = S_OK;
|
||||
try
|
||||
{
|
||||
UInt32 blockIndex = Decoder->NextBlockIndex;
|
||||
UInt32 nextBlockIndex = blockIndex + 1;
|
||||
if (nextBlockIndex == Decoder->NumThreads)
|
||||
nextBlockIndex = 0;
|
||||
Decoder->NextBlockIndex = nextBlockIndex;
|
||||
|
||||
bool wasFinished;
|
||||
UInt32 crc;
|
||||
res = Decoder->ReadSignatures(wasFinished, crc);
|
||||
if (res != S_OK)
|
||||
{
|
||||
Decoder->Result = res;
|
||||
FinishStream();
|
||||
continue;
|
||||
}
|
||||
if (wasFinished)
|
||||
{
|
||||
Decoder->Result = res;
|
||||
FinishStream();
|
||||
continue;
|
||||
}
|
||||
|
||||
res = Decoder->ReadBlock(Decoder->BlockSizeMax, *this);
|
||||
UInt64 packSize = Decoder->m_InStream.GetProcessedSize();
|
||||
if (res != S_OK)
|
||||
{
|
||||
Decoder->Result = res;
|
||||
FinishStream();
|
||||
continue;
|
||||
}
|
||||
Decoder->CS.Leave();
|
||||
|
||||
DecodeBlock1();
|
||||
|
||||
Decoder->m_States[blockIndex].CanWriteEvent.Lock();
|
||||
|
||||
if (DecodeBlock2(Decoder->m_OutStream) != crc)
|
||||
{
|
||||
Decoder->Result = S_FALSE;
|
||||
FinishStream();
|
||||
continue;
|
||||
}
|
||||
|
||||
if (Decoder->Progress)
|
||||
{
|
||||
UInt64 unpackSize = Decoder->m_OutStream.GetProcessedSize();
|
||||
res = Decoder->Progress->SetRatioInfo(&packSize, &unpackSize);
|
||||
}
|
||||
|
||||
Decoder->m_States[nextBlockIndex].CanWriteEvent.Set();
|
||||
}
|
||||
catch(const CInBufferException &e) { res = e.ErrorCode; }
|
||||
catch(const COutBufferException &e) { res = e.ErrorCode; }
|
||||
catch(...) { res = E_FAIL; }
|
||||
if (res != S_OK)
|
||||
{
|
||||
Decoder->Result = res;
|
||||
FinishStream();
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static DWORD WINAPI MFThread(void *threadCoderInfo)
|
||||
{
|
||||
return ((CState *)threadCoderInfo)->ThreadFunc();
|
||||
}
|
||||
#endif
|
||||
|
||||
UInt32 CDecoder::ReadBits(int numBits) { return m_InStream.ReadBits(numBits); }
|
||||
Byte CDecoder::ReadByte() {return (Byte)ReadBits(8); }
|
||||
bool CDecoder::ReadBit() { return ReadBits(1) != 0; }
|
||||
@@ -201,7 +301,7 @@ HRESULT CDecoder::ReadBlock(UInt32 blockSizeMax, CState &state)
|
||||
groupSize = kGroupSize;
|
||||
huffmanDecoder = &m_HuffmanDecoders[state.m_Selectors[groupIndex++]];
|
||||
}
|
||||
groupSize--; \
|
||||
groupSize--;
|
||||
|
||||
UInt32 nextSym = huffmanDecoder->DecodeSymbol(&m_InStream);
|
||||
|
||||
@@ -241,7 +341,7 @@ HRESULT CDecoder::ReadBlock(UInt32 blockSizeMax, CState &state)
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT CState::DecodeBlock(COutBuffer &m_OutStream)
|
||||
void CState::DecodeBlock1()
|
||||
{
|
||||
UInt32 *charCounters = this->CharCounters;
|
||||
{
|
||||
@@ -259,8 +359,11 @@ HRESULT CState::DecodeBlock(COutBuffer &m_OutStream)
|
||||
do
|
||||
tt[charCounters[tt[i] & 0xFF]++] |= (i << 8);
|
||||
while(++i < blockSize);
|
||||
}
|
||||
|
||||
// Decode
|
||||
UInt32 CState::DecodeBlock2(COutBuffer &m_OutStream)
|
||||
{
|
||||
UInt32 blockSize = this->BlockSize;
|
||||
|
||||
CBZip2CRC crc;
|
||||
|
||||
@@ -310,11 +413,122 @@ HRESULT CState::DecodeBlock(COutBuffer &m_OutStream)
|
||||
m_OutStream.WriteByte(b);
|
||||
}
|
||||
while(--blockSize != 0);
|
||||
return (StoredCRC == crc.GetDigest()) ? S_OK : S_FALSE;
|
||||
return crc.GetDigest();
|
||||
}
|
||||
|
||||
#ifdef COMPRESS_BZIP2_MT
|
||||
CDecoder::CDecoder():
|
||||
m_States(0)
|
||||
{
|
||||
m_NumThreadsPrev = 0;
|
||||
NumThreads = 1;
|
||||
CS.Enter();
|
||||
}
|
||||
|
||||
CDecoder::~CDecoder()
|
||||
{
|
||||
Free();
|
||||
}
|
||||
|
||||
bool CDecoder::Create()
|
||||
{
|
||||
try
|
||||
{
|
||||
if (m_States != 0 && m_NumThreadsPrev == NumThreads)
|
||||
return true;
|
||||
Free();
|
||||
MtMode = (NumThreads > 1);
|
||||
m_NumThreadsPrev = NumThreads;
|
||||
m_States = new CState[NumThreads];
|
||||
if (m_States == 0)
|
||||
return false;
|
||||
#ifdef COMPRESS_BZIP2_MT
|
||||
for (UInt32 t = 0; t < NumThreads; t++)
|
||||
{
|
||||
CState &ti = m_States[t];
|
||||
ti.Decoder = this;
|
||||
if (MtMode)
|
||||
if (!ti.Thread.Create(MFThread, &ti))
|
||||
{
|
||||
NumThreads = t;
|
||||
Free();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
catch(...) { return false; }
|
||||
return true;
|
||||
}
|
||||
|
||||
void CDecoder::Free()
|
||||
{
|
||||
if (!m_States)
|
||||
return;
|
||||
CloseThreads = true;
|
||||
CS.Leave();
|
||||
for (UInt32 t = 0; t < NumThreads; t++)
|
||||
{
|
||||
CState &s = m_States[t];
|
||||
if (MtMode)
|
||||
s.Thread.Wait();
|
||||
s.Free();
|
||||
}
|
||||
delete []m_States;
|
||||
m_States = 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
HRESULT CDecoder::ReadSignatures(bool &wasFinished, UInt32 &crc)
|
||||
{
|
||||
wasFinished = false;
|
||||
Byte s[6];
|
||||
for (int i = 0; i < 6; i++)
|
||||
s[i] = ReadByte();
|
||||
crc = ReadCRC();
|
||||
if (s[0] == kFinSig0)
|
||||
{
|
||||
if (s[1] != kFinSig1 ||
|
||||
s[2] != kFinSig2 ||
|
||||
s[3] != kFinSig3 ||
|
||||
s[4] != kFinSig4 ||
|
||||
s[5] != kFinSig5)
|
||||
return S_FALSE;
|
||||
|
||||
wasFinished = true;
|
||||
return (crc == CombinedCRC.GetDigest()) ? S_OK : S_FALSE;
|
||||
}
|
||||
if (s[0] != kBlockSig0 ||
|
||||
s[1] != kBlockSig1 ||
|
||||
s[2] != kBlockSig2 ||
|
||||
s[3] != kBlockSig3 ||
|
||||
s[4] != kBlockSig4 ||
|
||||
s[5] != kBlockSig5)
|
||||
return S_FALSE;
|
||||
CombinedCRC.Update(crc);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT CDecoder::DecodeFile(bool &isBZ, ICompressProgressInfo *progress)
|
||||
{
|
||||
#ifdef COMPRESS_BZIP2_MT
|
||||
Progress = progress;
|
||||
if (!Create())
|
||||
return E_FAIL;
|
||||
for (UInt32 t = 0; t < NumThreads; t++)
|
||||
{
|
||||
CState &s = m_States[t];
|
||||
if (!s.Alloc())
|
||||
return E_OUTOFMEMORY;
|
||||
s.StreamWasFinishedEvent.Reset();
|
||||
s.WaitingWasStartedEvent.Reset();
|
||||
s.CanWriteEvent.Reset();
|
||||
}
|
||||
#else
|
||||
if (!m_States[0].Alloc())
|
||||
return E_OUTOFMEMORY;
|
||||
#endif
|
||||
|
||||
isBZ = false;
|
||||
Byte s[6];
|
||||
int i;
|
||||
@@ -329,45 +543,53 @@ HRESULT CDecoder::DecodeFile(bool &isBZ, ICompressProgressInfo *progress)
|
||||
isBZ = true;
|
||||
UInt32 dicSize = (UInt32)(s[3] - kArSig3) * kBlockSizeStep;
|
||||
|
||||
if (!m_State.Alloc())
|
||||
return E_OUTOFMEMORY;
|
||||
|
||||
CBZip2CombinedCRC computedCombinedCRC;
|
||||
while (true)
|
||||
CombinedCRC.Init();
|
||||
#ifdef COMPRESS_BZIP2_MT
|
||||
if (MtMode)
|
||||
{
|
||||
if (progress)
|
||||
{
|
||||
UInt64 packSize = m_InStream.GetProcessedSize();
|
||||
UInt64 unpackSize = m_OutStream.GetProcessedSize();
|
||||
RINOK(progress->SetRatioInfo(&packSize, &unpackSize));
|
||||
}
|
||||
|
||||
for (i = 0; i < 6; i++)
|
||||
s[i] = ReadByte();
|
||||
UInt32 crc = ReadCRC();
|
||||
if (s[0] == kFinSig0)
|
||||
{
|
||||
if (s[1] != kFinSig1 ||
|
||||
s[2] != kFinSig2 ||
|
||||
s[3] != kFinSig3 ||
|
||||
s[4] != kFinSig4 ||
|
||||
s[5] != kFinSig5)
|
||||
return S_FALSE;
|
||||
|
||||
return (crc == computedCombinedCRC.GetDigest()) ? S_OK : S_FALSE;
|
||||
}
|
||||
if (s[0] != kBlockSig0 ||
|
||||
s[1] != kBlockSig1 ||
|
||||
s[2] != kBlockSig2 ||
|
||||
s[3] != kBlockSig3 ||
|
||||
s[4] != kBlockSig4 ||
|
||||
s[5] != kBlockSig5)
|
||||
return S_FALSE;
|
||||
m_State.StoredCRC = crc;
|
||||
computedCombinedCRC.Update(crc);
|
||||
RINOK(ReadBlock(dicSize, m_State));
|
||||
RINOK(m_State.DecodeBlock(m_OutStream));
|
||||
NextBlockIndex = 0;
|
||||
StreamWasFinished = false;
|
||||
CloseThreads = false;
|
||||
CanStartWaitingEvent.Reset();
|
||||
m_States[0].CanWriteEvent.Set();
|
||||
BlockSizeMax = dicSize;
|
||||
Result = S_OK;
|
||||
CS.Leave();
|
||||
UInt32 t;
|
||||
for (t = 0; t < NumThreads; t++)
|
||||
m_States[t].StreamWasFinishedEvent.Lock();
|
||||
CS.Enter();
|
||||
CanStartWaitingEvent.Set();
|
||||
for (t = 0; t < NumThreads; t++)
|
||||
m_States[t].WaitingWasStartedEvent.Lock();
|
||||
CanStartWaitingEvent.Reset();
|
||||
RINOK(Result);
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
CState &state = m_States[0];
|
||||
while (true)
|
||||
{
|
||||
if (progress)
|
||||
{
|
||||
UInt64 packSize = m_InStream.GetProcessedSize();
|
||||
UInt64 unpackSize = m_OutStream.GetProcessedSize();
|
||||
RINOK(progress->SetRatioInfo(&packSize, &unpackSize));
|
||||
}
|
||||
bool wasFinished;
|
||||
UInt32 crc;
|
||||
RINOK(ReadSignatures(wasFinished, crc));
|
||||
if (wasFinished)
|
||||
return S_OK;
|
||||
|
||||
RINOK(ReadBlock(dicSize, state));
|
||||
state.DecodeBlock1();
|
||||
if (state.DecodeBlock2(m_OutStream) != crc)
|
||||
return S_FALSE;
|
||||
}
|
||||
}
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT CDecoder::CodeReal(ISequentialInStream *inStream,
|
||||
@@ -408,4 +630,16 @@ STDMETHODIMP CDecoder::GetInStreamProcessedSize(UInt64 *value)
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
#ifdef COMPRESS_BZIP2_MT
|
||||
STDMETHODIMP CDecoder::SetNumberOfThreads(UInt32 numThreads)
|
||||
{
|
||||
NumThreads = numThreads;
|
||||
if (NumThreads < 1)
|
||||
NumThreads = 1;
|
||||
if (NumThreads > kNumThreadsMax)
|
||||
NumThreads = kNumThreadsMax;
|
||||
return S_OK;
|
||||
}
|
||||
#endif
|
||||
|
||||
}}
|
||||
|
||||
@@ -10,12 +10,20 @@
|
||||
#include "../../Common/OutBuffer.h"
|
||||
#include "../Huffman/HuffmanDecoder.h"
|
||||
#include "BZip2Const.h"
|
||||
#include "BZip2CRC.h"
|
||||
|
||||
#ifdef COMPRESS_BZIP2_MT
|
||||
#include "../../../Windows/Thread.h"
|
||||
#include "../../../Windows/Synchronization.h"
|
||||
#endif
|
||||
|
||||
namespace NCompress {
|
||||
namespace NBZip2 {
|
||||
|
||||
typedef NCompress::NHuffman::CDecoder<kMaxHuffmanLen, kMaxAlphaSize> CHuffmanDecoder;
|
||||
|
||||
class CDecoder;
|
||||
|
||||
struct CState
|
||||
{
|
||||
UInt32 *tt;
|
||||
@@ -24,31 +32,55 @@ struct CState
|
||||
UInt32 BlockSize;
|
||||
UInt32 CharCounters[256];
|
||||
Byte m_Selectors[kNumSelectorsMax];
|
||||
UInt32 StoredCRC;
|
||||
|
||||
#ifdef COMPRESS_BZIP2_MT
|
||||
|
||||
CDecoder *Decoder;
|
||||
NWindows::CThread Thread;
|
||||
bool m_OptimizeNumTables;
|
||||
|
||||
NWindows::NSynchronization::CAutoResetEvent StreamWasFinishedEvent;
|
||||
NWindows::NSynchronization::CAutoResetEvent WaitingWasStartedEvent;
|
||||
|
||||
// it's not member of this thread. We just need one event per thread
|
||||
NWindows::NSynchronization::CAutoResetEvent CanWriteEvent;
|
||||
|
||||
Byte MtPad[1 << 8]; // It's pad for Multi-Threading. Must be >= Cache_Line_Size.
|
||||
|
||||
void FinishStream();
|
||||
DWORD ThreadFunc();
|
||||
|
||||
#endif
|
||||
|
||||
CState(): tt(0) {}
|
||||
~CState();
|
||||
~CState() { Free(); }
|
||||
bool Alloc();
|
||||
HRESULT DecodeBlock(COutBuffer &m_OutStream);
|
||||
void Free();
|
||||
void DecodeBlock1();
|
||||
UInt32 DecodeBlock2(COutBuffer &m_OutStream);
|
||||
};
|
||||
|
||||
class CDecoder :
|
||||
public ICompressCoder,
|
||||
#ifdef COMPRESS_BZIP2_MT
|
||||
public ICompressSetCoderMt,
|
||||
#endif
|
||||
public ICompressGetInStreamProcessedSize,
|
||||
public CMyUnknownImp
|
||||
{
|
||||
NStream::NMSBF::CDecoder<CInBuffer> m_InStream;
|
||||
public:
|
||||
COutBuffer m_OutStream;
|
||||
|
||||
Byte MtPad[1 << 8]; // It's pad for Multi-Threading. Must be >= Cache_Line_Size.
|
||||
NStream::NMSBF::CDecoder<CInBuffer> m_InStream;
|
||||
private:
|
||||
CHuffmanDecoder m_HuffmanDecoders[kNumTablesMax];
|
||||
|
||||
CState m_State;
|
||||
|
||||
UInt32 m_NumThreadsPrev;
|
||||
|
||||
UInt32 ReadBits(int numBits);
|
||||
Byte ReadByte();
|
||||
bool ReadBit();
|
||||
UInt32 ReadCRC();
|
||||
HRESULT ReadBlock(UInt32 blockSizeMax, CState &state);
|
||||
HRESULT PrepareBlock(CState &state);
|
||||
HRESULT DecodeFile(bool &isBZ, ICompressProgressInfo *progress);
|
||||
HRESULT CodeReal(ISequentialInStream *inStream,
|
||||
@@ -69,6 +101,37 @@ class CDecoder :
|
||||
};
|
||||
|
||||
public:
|
||||
CBZip2CombinedCRC CombinedCRC;
|
||||
|
||||
#ifdef COMPRESS_BZIP2_MT
|
||||
ICompressProgressInfo *Progress;
|
||||
CState *m_States;
|
||||
|
||||
NWindows::NSynchronization::CCriticalSection CS;
|
||||
UInt32 NumThreads;
|
||||
bool MtMode;
|
||||
UInt32 NextBlockIndex;
|
||||
bool CloseThreads;
|
||||
bool StreamWasFinished;
|
||||
NWindows::NSynchronization::CManualResetEvent CanStartWaitingEvent;
|
||||
|
||||
HRESULT Result;
|
||||
|
||||
UInt32 BlockSizeMax;
|
||||
CDecoder();
|
||||
~CDecoder();
|
||||
bool Create();
|
||||
void Free();
|
||||
|
||||
#else
|
||||
CState m_States[1];
|
||||
#endif
|
||||
|
||||
HRESULT ReadBlock(UInt32 blockSizeMax, CState &state);
|
||||
|
||||
HRESULT ReadSignatures(bool &wasFinished, UInt32 &crc);
|
||||
|
||||
|
||||
HRESULT Flush() { return m_OutStream.Flush(); }
|
||||
void ReleaseStreams()
|
||||
{
|
||||
@@ -76,13 +139,22 @@ public:
|
||||
m_OutStream.ReleaseStream();
|
||||
}
|
||||
|
||||
#ifdef COMPRESS_BZIP2_MT
|
||||
MY_UNKNOWN_IMP2(ICompressSetCoderMt, ICompressGetInStreamProcessedSize)
|
||||
#else
|
||||
MY_UNKNOWN_IMP1(ICompressGetInStreamProcessedSize)
|
||||
#endif
|
||||
|
||||
|
||||
STDMETHOD(Code)(ISequentialInStream *inStream,
|
||||
ISequentialOutStream *outStream, const UInt64 *inSize, const UInt64 *outSize,
|
||||
ICompressProgressInfo *progress);
|
||||
|
||||
STDMETHOD(GetInStreamProcessedSize)(UInt64 *value);
|
||||
|
||||
#ifdef COMPRESS_BZIP2_MT
|
||||
STDMETHOD(SetNumberOfThreads)(UInt32 numThreads);
|
||||
#endif
|
||||
};
|
||||
|
||||
}}
|
||||
|
||||
@@ -2,9 +2,10 @@
|
||||
|
||||
#include "StdAfx.h"
|
||||
|
||||
#include "../../../Common/Alloc.h"
|
||||
|
||||
#include "BZip2Encoder.h"
|
||||
|
||||
#include "../../../Common/Alloc.h"
|
||||
#include "../BWT/Mtf8.h"
|
||||
#include "BZip2CRC.h"
|
||||
|
||||
@@ -14,19 +15,161 @@ namespace NBZip2 {
|
||||
static const UInt32 kBufferSize = (1 << 17);
|
||||
static const int kNumHuffPasses = 4;
|
||||
|
||||
CEncoder::CEncoder():
|
||||
m_Block(0),
|
||||
m_NeedHuffmanCreate(true),
|
||||
m_NumPasses(1),
|
||||
bool CThreadInfo::Create()
|
||||
{
|
||||
if (!m_BlockSorter.Create(kBlockSizeMax))
|
||||
return false;
|
||||
|
||||
if (m_Block == 0)
|
||||
{
|
||||
m_Block = (Byte *)::BigAlloc(kBlockSizeMax * 5 + kBlockSizeMax / 10 + (20 << 10));
|
||||
if (m_Block == 0)
|
||||
return false;
|
||||
m_MtfArray = m_Block + kBlockSizeMax;
|
||||
m_TempArray = m_MtfArray + kBlockSizeMax * 2 + 2;
|
||||
}
|
||||
if (m_NeedHuffmanCreate)
|
||||
{
|
||||
for (int i = 0; i < kNumTablesMax; i++)
|
||||
if (!m_HuffEncoders[i].Create(kMaxAlphaSize, 0, 0, kMaxHuffmanLen))
|
||||
return false;
|
||||
m_NeedHuffmanCreate = false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void CThreadInfo::Free()
|
||||
{
|
||||
m_BlockSorter.Free();
|
||||
::BigFree(m_Block);
|
||||
m_Block = 0;
|
||||
}
|
||||
|
||||
#ifdef COMPRESS_BZIP2_MT
|
||||
void CThreadInfo::FinishStream()
|
||||
{
|
||||
Encoder->StreamWasFinished = true;
|
||||
StreamWasFinishedEvent.Set();
|
||||
Encoder->CS.Leave();
|
||||
Encoder->CanStartWaitingEvent.Lock();
|
||||
WaitingWasStartedEvent.Set();
|
||||
}
|
||||
|
||||
DWORD CThreadInfo::ThreadFunc()
|
||||
{
|
||||
while (true)
|
||||
{
|
||||
Encoder->CS.Enter();
|
||||
if (Encoder->CloseThreads)
|
||||
{
|
||||
Encoder->CS.Leave();
|
||||
return 0;
|
||||
}
|
||||
if (Encoder->StreamWasFinished)
|
||||
{
|
||||
FinishStream();
|
||||
continue;
|
||||
}
|
||||
HRESULT res = S_OK;
|
||||
try
|
||||
{
|
||||
UInt32 blockSize = Encoder->ReadRleBlock(m_Block);
|
||||
m_PackSize = Encoder->m_InStream.GetProcessedSize();
|
||||
m_BlockIndex = Encoder->NextBlockIndex;
|
||||
if (++Encoder->NextBlockIndex == Encoder->NumThreads)
|
||||
Encoder->NextBlockIndex = 0;
|
||||
if (blockSize == 0)
|
||||
{
|
||||
FinishStream();
|
||||
continue;
|
||||
}
|
||||
Encoder->CS.Leave();
|
||||
res = EncodeBlock3(blockSize);
|
||||
}
|
||||
catch(const CInBufferException &e) { res = e.ErrorCode; }
|
||||
catch(const COutBufferException &e) { res = e.ErrorCode; }
|
||||
catch(...) { res = E_FAIL; }
|
||||
if (res != S_OK)
|
||||
{
|
||||
Encoder->Result = res;
|
||||
FinishStream();
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static DWORD WINAPI MFThread(void *threadCoderInfo)
|
||||
{
|
||||
return ((CThreadInfo *)threadCoderInfo)->ThreadFunc();
|
||||
}
|
||||
#endif
|
||||
|
||||
CEncoder::CEncoder():
|
||||
NumPasses(1),
|
||||
m_OptimizeNumTables(false),
|
||||
m_BlockSizeMult(kBlockSizeMultMax)
|
||||
{}
|
||||
{
|
||||
#ifdef COMPRESS_BZIP2_MT
|
||||
ThreadsInfo = 0;
|
||||
m_NumThreadsPrev = 0;
|
||||
NumThreads = 1;
|
||||
CS.Enter();
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef COMPRESS_BZIP2_MT
|
||||
CEncoder::~CEncoder()
|
||||
{
|
||||
::BigFree(m_Block);
|
||||
Free();
|
||||
}
|
||||
|
||||
bool CEncoder::Create()
|
||||
{
|
||||
try
|
||||
{
|
||||
if (ThreadsInfo != 0 && m_NumThreadsPrev == NumThreads)
|
||||
return true;
|
||||
Free();
|
||||
MtMode = (NumThreads > 1);
|
||||
m_NumThreadsPrev = NumThreads;
|
||||
ThreadsInfo = new CThreadInfo[NumThreads];
|
||||
if (ThreadsInfo == 0)
|
||||
return false;
|
||||
for (UInt32 t = 0; t < NumThreads; t++)
|
||||
{
|
||||
CThreadInfo &ti = ThreadsInfo[t];
|
||||
ti.Encoder = this;
|
||||
if (MtMode)
|
||||
if (!ti.Thread.Create(MFThread, &ti))
|
||||
{
|
||||
NumThreads = t;
|
||||
Free();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
catch(...) { return false; }
|
||||
return true;
|
||||
}
|
||||
|
||||
void CEncoder::Free()
|
||||
{
|
||||
if (!ThreadsInfo)
|
||||
return;
|
||||
CloseThreads = true;
|
||||
CS.Leave();
|
||||
for (UInt32 t = 0; t < NumThreads; t++)
|
||||
{
|
||||
CThreadInfo &ti = ThreadsInfo[t];
|
||||
if (MtMode)
|
||||
ti.Thread.Wait();
|
||||
ti.Free();
|
||||
}
|
||||
delete []ThreadsInfo;
|
||||
ThreadsInfo = 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
UInt32 CEncoder::ReadRleBlock(Byte *buffer)
|
||||
{
|
||||
UInt32 i = 0;
|
||||
@@ -66,11 +209,11 @@ UInt32 CEncoder::ReadRleBlock(Byte *buffer)
|
||||
return i;
|
||||
}
|
||||
|
||||
void CEncoder::WriteBits2(UInt32 value, UInt32 numBits)
|
||||
void CThreadInfo::WriteBits2(UInt32 value, UInt32 numBits)
|
||||
{ m_OutStreamCurrent->WriteBits(value, numBits); }
|
||||
void CEncoder::WriteByte2(Byte b) { WriteBits2(b , 8); }
|
||||
void CEncoder::WriteBit2(bool v) { WriteBits2((v ? 1 : 0), 1); }
|
||||
void CEncoder::WriteCRC2(UInt32 v)
|
||||
void CThreadInfo::WriteByte2(Byte b) { WriteBits2(b , 8); }
|
||||
void CThreadInfo::WriteBit2(bool v) { WriteBits2((v ? 1 : 0), 1); }
|
||||
void CThreadInfo::WriteCRC2(UInt32 v)
|
||||
{
|
||||
for (int i = 0; i < 4; i++)
|
||||
WriteByte2(((Byte)(v >> (24 - i * 8))));
|
||||
@@ -88,7 +231,7 @@ void CEncoder::WriteCRC(UInt32 v)
|
||||
|
||||
|
||||
// blockSize > 0
|
||||
void CEncoder::EncodeBlock(Byte *block, UInt32 blockSize)
|
||||
void CThreadInfo::EncodeBlock(Byte *block, UInt32 blockSize)
|
||||
{
|
||||
WriteBit2(false); // Randomised = false
|
||||
|
||||
@@ -404,7 +547,7 @@ void CEncoder::EncodeBlock(Byte *block, UInt32 blockSize)
|
||||
}
|
||||
|
||||
// blockSize > 0
|
||||
UInt32 CEncoder::EncodeBlockWithHeaders(Byte *block, UInt32 blockSize)
|
||||
UInt32 CThreadInfo::EncodeBlockWithHeaders(Byte *block, UInt32 blockSize)
|
||||
{
|
||||
WriteByte2(kBlockSig0);
|
||||
WriteByte2(kBlockSig1);
|
||||
@@ -443,11 +586,10 @@ UInt32 CEncoder::EncodeBlockWithHeaders(Byte *block, UInt32 blockSize)
|
||||
return crcRes;
|
||||
}
|
||||
|
||||
void CEncoder::EncodeBlock2(CBZip2CombinedCRC &combinedCRC,
|
||||
Byte *block, UInt32 blockSize, UInt32 numPasses)
|
||||
void CThreadInfo::EncodeBlock2(Byte *block, UInt32 blockSize, UInt32 numPasses)
|
||||
{
|
||||
UInt32 numCrcs = m_NumCrcs;
|
||||
bool needCompare = false;
|
||||
CBZip2CombinedCRC specCombinedCRC = combinedCRC;
|
||||
|
||||
UInt32 startBytePos = m_OutStreamCurrent->GetBytePos();
|
||||
UInt32 startPos = m_OutStreamCurrent->GetPos();
|
||||
@@ -462,9 +604,8 @@ void CEncoder::EncodeBlock2(CBZip2CombinedCRC &combinedCRC,
|
||||
blockSize0 < blockSize; blockSize0++);
|
||||
if (blockSize0 < blockSize)
|
||||
{
|
||||
EncodeBlock2(specCombinedCRC, block, blockSize0, numPasses - 1);
|
||||
EncodeBlock2(specCombinedCRC, block + blockSize0, blockSize - blockSize0,
|
||||
numPasses - 1);
|
||||
EncodeBlock2(block, blockSize0, numPasses - 1);
|
||||
EncodeBlock2(block + blockSize0, blockSize - blockSize0, numPasses - 1);
|
||||
endPos = m_OutStreamCurrent->GetPos();
|
||||
endCurByte = m_OutStreamCurrent->GetCurByte();
|
||||
if ((endPos & 7) > 0)
|
||||
@@ -479,8 +620,6 @@ void CEncoder::EncodeBlock2(CBZip2CombinedCRC &combinedCRC,
|
||||
UInt32 crcVal = EncodeBlockWithHeaders(block, blockSize);
|
||||
UInt32 endPos2 = m_OutStreamCurrent->GetPos();
|
||||
|
||||
combinedCRC.Update(crcVal);
|
||||
|
||||
if (needCompare)
|
||||
{
|
||||
UInt32 size2 = endPos2 - startPos2;
|
||||
@@ -491,59 +630,102 @@ void CEncoder::EncodeBlock2(CBZip2CombinedCRC &combinedCRC,
|
||||
for (UInt32 i = 0; i < numBytes; i++)
|
||||
buffer[startBytePos + i] = buffer[startBytePos2 + i];
|
||||
m_OutStreamCurrent->SetPos(startPos + endPos2 - startPos2);
|
||||
m_NumCrcs = numCrcs;
|
||||
m_CRCs[m_NumCrcs++] = crcVal;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_OutStreamCurrent->SetPos(endPos);
|
||||
m_OutStreamCurrent->SetCurState((endPos & 7), endCurByte);
|
||||
combinedCRC = specCombinedCRC;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
m_NumCrcs = numCrcs;
|
||||
m_CRCs[m_NumCrcs++] = crcVal;
|
||||
}
|
||||
}
|
||||
|
||||
void CEncoder::EncodeBlock3(CBZip2CombinedCRC &combinedCRC, UInt32 blockSize)
|
||||
HRESULT CThreadInfo::EncodeBlock3(UInt32 blockSize)
|
||||
{
|
||||
CMsbfEncoderTemp outStreamTemp;
|
||||
outStreamTemp.SetStream(m_TempArray);
|
||||
outStreamTemp.Init();
|
||||
m_OutStreamCurrent = &outStreamTemp;
|
||||
|
||||
EncodeBlock2(combinedCRC, m_Block, blockSize, m_NumPasses);
|
||||
m_NumCrcs = 0;
|
||||
|
||||
UInt32 size = outStreamTemp.GetPos();
|
||||
UInt32 bytesSize = (size / 8);
|
||||
for (UInt32 i = 0; i < bytesSize; i++)
|
||||
m_OutStream.WriteBits(m_TempArray[i], 8);
|
||||
WriteBits(outStreamTemp.GetCurByte(), (size & 7));
|
||||
EncodeBlock2(m_Block, blockSize, Encoder->NumPasses);
|
||||
|
||||
#ifdef COMPRESS_BZIP2_MT
|
||||
if (Encoder->MtMode)
|
||||
Encoder->ThreadsInfo[m_BlockIndex].CanWriteEvent.Lock();
|
||||
#endif
|
||||
for (UInt32 i = 0; i < m_NumCrcs; i++)
|
||||
Encoder->CombinedCRC.Update(m_CRCs[i]);
|
||||
Encoder->WriteBytes(m_TempArray, outStreamTemp.GetPos(), outStreamTemp.GetCurByte());
|
||||
HRESULT res = S_OK;
|
||||
#ifdef COMPRESS_BZIP2_MT
|
||||
if (Encoder->MtMode)
|
||||
{
|
||||
UInt32 blockIndex = m_BlockIndex + 1;
|
||||
if (blockIndex == Encoder->NumThreads)
|
||||
blockIndex = 0;
|
||||
|
||||
if (Encoder->Progress)
|
||||
{
|
||||
UInt64 unpackSize = Encoder->m_OutStream.GetProcessedSize();
|
||||
res = Encoder->Progress->SetRatioInfo(&m_PackSize, &unpackSize);
|
||||
}
|
||||
|
||||
Encoder->ThreadsInfo[blockIndex].CanWriteEvent.Set();
|
||||
}
|
||||
#endif
|
||||
return res;
|
||||
}
|
||||
|
||||
void CEncoder::WriteBytes(const Byte *data, UInt32 sizeInBits, Byte lastByte)
|
||||
{
|
||||
UInt32 bytesSize = (sizeInBits / 8);
|
||||
for (UInt32 i = 0; i < bytesSize; i++)
|
||||
m_OutStream.WriteBits(data[i], 8);
|
||||
WriteBits(lastByte, (sizeInBits & 7));
|
||||
}
|
||||
|
||||
|
||||
HRESULT CEncoder::CodeReal(ISequentialInStream *inStream,
|
||||
ISequentialOutStream *outStream, const UInt64 *inSize, const UInt64 *outSize,
|
||||
ICompressProgressInfo *progress)
|
||||
{
|
||||
if (!m_BlockSorter.Create(kBlockSizeMax))
|
||||
return E_OUTOFMEMORY;
|
||||
|
||||
if (m_Block == 0)
|
||||
#ifdef COMPRESS_BZIP2_MT
|
||||
Progress = progress;
|
||||
if (!Create())
|
||||
return E_FAIL;
|
||||
for (UInt32 t = 0; t < NumThreads; t++)
|
||||
#endif
|
||||
{
|
||||
m_Block = (Byte *)BigAlloc(kBlockSizeMax * 5 + kBlockSizeMax / 10 + (20 << 10));
|
||||
if (m_Block == 0)
|
||||
#ifdef COMPRESS_BZIP2_MT
|
||||
CThreadInfo &ti = ThreadsInfo[t];
|
||||
ti.StreamWasFinishedEvent.Reset();
|
||||
ti.WaitingWasStartedEvent.Reset();
|
||||
ti.CanWriteEvent.Reset();
|
||||
#else
|
||||
CThreadInfo &ti = ThreadsInfo;
|
||||
ti.Encoder = this;
|
||||
#endif
|
||||
|
||||
ti.m_OptimizeNumTables = m_OptimizeNumTables;
|
||||
|
||||
if (!ti.Create())
|
||||
return E_OUTOFMEMORY;
|
||||
m_MtfArray = m_Block + kBlockSizeMax;
|
||||
m_TempArray = m_MtfArray + kBlockSizeMax * 2 + 2;
|
||||
}
|
||||
|
||||
|
||||
if (!m_InStream.Create(kBufferSize))
|
||||
return E_OUTOFMEMORY;
|
||||
if (!m_OutStream.Create(kBufferSize))
|
||||
return E_OUTOFMEMORY;
|
||||
|
||||
if (m_NeedHuffmanCreate)
|
||||
{
|
||||
for (int i = 0; i < kNumTablesMax; i++)
|
||||
if (!m_HuffEncoders[i].Create(kMaxAlphaSize, 0, 0, kMaxHuffmanLen))
|
||||
return E_OUTOFMEMORY;
|
||||
m_NeedHuffmanCreate = false;
|
||||
}
|
||||
|
||||
m_InStream.SetStream(inStream);
|
||||
m_InStream.Init();
|
||||
@@ -553,24 +735,57 @@ HRESULT CEncoder::CodeReal(ISequentialInStream *inStream,
|
||||
|
||||
CFlusher flusher(this);
|
||||
|
||||
CBZip2CombinedCRC combinedCRC;
|
||||
CombinedCRC.Init();
|
||||
#ifdef COMPRESS_BZIP2_MT
|
||||
NextBlockIndex = 0;
|
||||
StreamWasFinished = false;
|
||||
CloseThreads = false;
|
||||
CanStartWaitingEvent.Reset();
|
||||
#endif
|
||||
|
||||
WriteByte(kArSig0);
|
||||
WriteByte(kArSig1);
|
||||
WriteByte(kArSig2);
|
||||
WriteByte((Byte)(kArSig3 + m_BlockSizeMult));
|
||||
|
||||
while (true)
|
||||
#ifdef COMPRESS_BZIP2_MT
|
||||
|
||||
if (MtMode)
|
||||
{
|
||||
UInt32 blockSize = ReadRleBlock(m_Block);
|
||||
if (blockSize == 0)
|
||||
break;
|
||||
EncodeBlock3(combinedCRC, blockSize);
|
||||
if (progress)
|
||||
ThreadsInfo[0].CanWriteEvent.Set();
|
||||
Result = S_OK;
|
||||
CS.Leave();
|
||||
UInt32 t;
|
||||
for (t = 0; t < NumThreads; t++)
|
||||
ThreadsInfo[t].StreamWasFinishedEvent.Lock();
|
||||
CS.Enter();
|
||||
CanStartWaitingEvent.Set();
|
||||
for (t = 0; t < NumThreads; t++)
|
||||
ThreadsInfo[t].WaitingWasStartedEvent.Lock();
|
||||
CanStartWaitingEvent.Reset();
|
||||
RINOK(Result);
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
while (true)
|
||||
{
|
||||
UInt64 packSize = m_InStream.GetProcessedSize();
|
||||
UInt64 unpackSize = m_OutStream.GetProcessedSize();
|
||||
RINOK(progress->SetRatioInfo(&packSize, &unpackSize));
|
||||
CThreadInfo &ti =
|
||||
#ifdef COMPRESS_BZIP2_MT
|
||||
ThreadsInfo[0];
|
||||
#else
|
||||
ThreadsInfo;
|
||||
#endif
|
||||
UInt32 blockSize = ReadRleBlock(ti.m_Block);
|
||||
if (blockSize == 0)
|
||||
break;
|
||||
RINOK(ti.EncodeBlock3(blockSize));
|
||||
if (progress)
|
||||
{
|
||||
UInt64 packSize = m_InStream.GetProcessedSize();
|
||||
UInt64 unpackSize = m_OutStream.GetProcessedSize();
|
||||
RINOK(progress->SetRatioInfo(&packSize, &unpackSize));
|
||||
}
|
||||
}
|
||||
}
|
||||
WriteByte(kFinSig0);
|
||||
@@ -580,7 +795,7 @@ HRESULT CEncoder::CodeReal(ISequentialInStream *inStream,
|
||||
WriteByte(kFinSig4);
|
||||
WriteByte(kFinSig5);
|
||||
|
||||
WriteCRC(combinedCRC.GetDigest());
|
||||
WriteCRC(CombinedCRC.GetDigest());
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
@@ -589,6 +804,8 @@ STDMETHODIMP CEncoder::Code(ISequentialInStream *inStream,
|
||||
ICompressProgressInfo *progress)
|
||||
{
|
||||
try { return CodeReal(inStream, outStream, inSize, outSize, progress); }
|
||||
catch(const CInBufferException &e) { return e.ErrorCode; }
|
||||
catch(const COutBufferException &e) { return e.ErrorCode; }
|
||||
catch(...) { return S_FALSE; }
|
||||
}
|
||||
|
||||
@@ -605,10 +822,12 @@ HRESULT CEncoder::SetCoderProperties(const PROPID *propIDs,
|
||||
if (property.vt != VT_UI4)
|
||||
return E_INVALIDARG;
|
||||
UInt32 numPasses = property.ulVal;
|
||||
if(numPasses == 0 || numPasses > 10)
|
||||
return E_INVALIDARG;
|
||||
m_NumPasses = numPasses;
|
||||
m_OptimizeNumTables = (m_NumPasses > 1);
|
||||
if (numPasses == 0)
|
||||
numPasses = 1;
|
||||
if (numPasses > kNumPassesMax)
|
||||
numPasses = kNumPassesMax;
|
||||
NumPasses = numPasses;
|
||||
m_OptimizeNumTables = (NumPasses > 1);
|
||||
break;
|
||||
}
|
||||
case NCoderPropID::kDictionarySize:
|
||||
@@ -623,6 +842,17 @@ HRESULT CEncoder::SetCoderProperties(const PROPID *propIDs,
|
||||
m_BlockSizeMult = dictionary;
|
||||
break;
|
||||
}
|
||||
case NCoderPropID::kNumThreads:
|
||||
{
|
||||
#ifdef COMPRESS_BZIP2_MT
|
||||
if (property.vt != VT_UI4)
|
||||
return E_INVALIDARG;
|
||||
NumThreads = property.ulVal;
|
||||
if (NumThreads < 1)
|
||||
NumThreads = 1;
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
default:
|
||||
return E_INVALIDARG;
|
||||
}
|
||||
@@ -630,4 +860,14 @@ HRESULT CEncoder::SetCoderProperties(const PROPID *propIDs,
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
#ifdef COMPRESS_BZIP2_MT
|
||||
STDMETHODIMP CEncoder::SetNumberOfThreads(UInt32 numThreads)
|
||||
{
|
||||
NumThreads = numThreads;
|
||||
if (NumThreads < 1)
|
||||
NumThreads = 1;
|
||||
return S_OK;
|
||||
}
|
||||
#endif
|
||||
|
||||
}}
|
||||
|
||||
@@ -12,7 +12,12 @@
|
||||
#include "../BWT/BlockSort.h"
|
||||
#include "BZip2Const.h"
|
||||
#include "BZip2CRC.h"
|
||||
|
||||
|
||||
#ifdef COMPRESS_BZIP2_MT
|
||||
#include "../../../Windows/Thread.h"
|
||||
#include "../../../Windows/Synchronization.h"
|
||||
#endif
|
||||
|
||||
namespace NCompress {
|
||||
namespace NBZip2 {
|
||||
|
||||
@@ -76,49 +81,123 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
class CEncoder :
|
||||
public ICompressCoder,
|
||||
public ICompressSetCoderProperties,
|
||||
public CMyUnknownImp
|
||||
class CEncoder;
|
||||
|
||||
const int kNumPassesMax = 10;
|
||||
|
||||
class CThreadInfo
|
||||
{
|
||||
public:
|
||||
Byte *m_Block;
|
||||
CInBuffer m_InStream;
|
||||
NStream::NMSBF::CEncoder<COutBuffer> m_OutStream;
|
||||
CMsbfEncoderTemp *m_OutStreamCurrent;
|
||||
CBlockSorter m_BlockSorter;
|
||||
|
||||
bool m_NeedHuffmanCreate;
|
||||
NCompression::NHuffman::CEncoder m_HuffEncoders[kNumTablesMax];
|
||||
|
||||
private:
|
||||
Byte *m_MtfArray;
|
||||
Byte *m_TempArray;
|
||||
CBlockSorter m_BlockSorter;
|
||||
|
||||
CMsbfEncoderTemp *m_OutStreamCurrent;
|
||||
|
||||
NCompression::NHuffman::CEncoder m_HuffEncoders[kNumTablesMax];
|
||||
Byte m_Selectors[kNumSelectorsMax];
|
||||
|
||||
UInt32 m_BlockSizeMult;
|
||||
UInt32 m_NumPasses;
|
||||
bool m_OptimizeNumTables;
|
||||
bool m_NeedHuffmanCreate;
|
||||
|
||||
UInt32 ReadRleBlock(Byte *buffer);
|
||||
UInt32 m_CRCs[1 << kNumPassesMax];
|
||||
UInt32 m_NumCrcs;
|
||||
|
||||
int m_BlockIndex;
|
||||
|
||||
void FinishStream();
|
||||
|
||||
void WriteBits2(UInt32 value, UInt32 numBits);
|
||||
void WriteByte2(Byte b);
|
||||
void WriteBit2(bool v);
|
||||
void WriteCRC2(UInt32 v);
|
||||
|
||||
|
||||
void EncodeBlock(Byte *block, UInt32 blockSize);
|
||||
UInt32 EncodeBlockWithHeaders(Byte *block, UInt32 blockSize);
|
||||
void EncodeBlock2(Byte *block, UInt32 blockSize, UInt32 numPasses);
|
||||
public:
|
||||
bool m_OptimizeNumTables;
|
||||
CEncoder *Encoder;
|
||||
#ifdef COMPRESS_BZIP2_MT
|
||||
NWindows::CThread Thread;
|
||||
|
||||
NWindows::NSynchronization::CAutoResetEvent StreamWasFinishedEvent;
|
||||
NWindows::NSynchronization::CAutoResetEvent WaitingWasStartedEvent;
|
||||
|
||||
// it's not member of this thread. We just need one event per thread
|
||||
NWindows::NSynchronization::CAutoResetEvent CanWriteEvent;
|
||||
|
||||
UInt64 m_PackSize;
|
||||
|
||||
Byte MtPad[1 << 8]; // It's pad for Multi-Threading. Must be >= Cache_Line_Size.
|
||||
#endif
|
||||
|
||||
CThreadInfo(): m_Block(0), m_NeedHuffmanCreate(true) {}
|
||||
~CThreadInfo() { Free(); }
|
||||
bool Create();
|
||||
void Free();
|
||||
|
||||
HRESULT EncodeBlock3(UInt32 blockSize);
|
||||
DWORD ThreadFunc();
|
||||
};
|
||||
|
||||
class CEncoder :
|
||||
public ICompressCoder,
|
||||
public ICompressSetCoderProperties,
|
||||
#ifdef COMPRESS_BZIP2_MT
|
||||
public ICompressSetCoderMt,
|
||||
#endif
|
||||
public CMyUnknownImp
|
||||
{
|
||||
UInt32 m_BlockSizeMult;
|
||||
bool m_OptimizeNumTables;
|
||||
|
||||
UInt32 m_NumPassesPrev;
|
||||
|
||||
UInt32 m_NumThreadsPrev;
|
||||
public:
|
||||
CInBuffer m_InStream;
|
||||
Byte MtPad[1 << 8]; // It's pad for Multi-Threading. Must be >= Cache_Line_Size.
|
||||
NStream::NMSBF::CEncoder<COutBuffer> m_OutStream;
|
||||
UInt32 NumPasses;
|
||||
CBZip2CombinedCRC CombinedCRC;
|
||||
|
||||
#ifdef COMPRESS_BZIP2_MT
|
||||
CThreadInfo *ThreadsInfo;
|
||||
NWindows::NSynchronization::CCriticalSection CS;
|
||||
UInt32 NumThreads;
|
||||
bool MtMode;
|
||||
UInt32 NextBlockIndex;
|
||||
|
||||
bool CloseThreads;
|
||||
bool StreamWasFinished;
|
||||
NWindows::NSynchronization::CManualResetEvent CanStartWaitingEvent;
|
||||
|
||||
HRESULT Result;
|
||||
ICompressProgressInfo *Progress;
|
||||
#else
|
||||
CThreadInfo ThreadsInfo;
|
||||
#endif
|
||||
|
||||
UInt32 ReadRleBlock(Byte *buffer);
|
||||
void WriteBytes(const Byte *data, UInt32 sizeInBits, Byte lastByte);
|
||||
|
||||
void WriteBits(UInt32 value, UInt32 numBits);
|
||||
void WriteByte(Byte b);
|
||||
void WriteBit(bool v);
|
||||
void WriteCRC(UInt32 v);
|
||||
|
||||
void EncodeBlock(Byte *block, UInt32 blockSize);
|
||||
UInt32 EncodeBlockWithHeaders(Byte *block, UInt32 blockSize);
|
||||
void EncodeBlock2(CBZip2CombinedCRC &combinedCRC, Byte *block, UInt32 blockSize, UInt32 numPasses);
|
||||
void EncodeBlock3(CBZip2CombinedCRC &combinedCRC, UInt32 blockSize);
|
||||
#ifdef COMPRESS_BZIP2_MT
|
||||
bool Create();
|
||||
void Free();
|
||||
#endif
|
||||
|
||||
public:
|
||||
CEncoder();
|
||||
#ifdef COMPRESS_BZIP2_MT
|
||||
~CEncoder();
|
||||
#endif
|
||||
|
||||
HRESULT Flush() { return m_OutStream.Flush(); }
|
||||
|
||||
@@ -142,7 +221,11 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
MY_UNKNOWN_IMP1(ICompressSetCoderProperties)
|
||||
#ifdef COMPRESS_BZIP2_MT
|
||||
MY_UNKNOWN_IMP2(ICompressSetCoderMt, ICompressSetCoderProperties)
|
||||
#else
|
||||
MY_UNKNOWN_IMP1(ICompressGetInStreamProcessedSize)
|
||||
#endif
|
||||
|
||||
HRESULT CodeReal(ISequentialInStream *inStream,
|
||||
ISequentialOutStream *outStream, const UInt64 *inSize, const UInt64 *outSize,
|
||||
@@ -153,6 +236,10 @@ public:
|
||||
ICompressProgressInfo *progress);
|
||||
STDMETHOD(SetCoderProperties)(const PROPID *propIDs,
|
||||
const PROPVARIANT *properties, UInt32 numProperties);
|
||||
|
||||
#ifdef COMPRESS_BZIP2_MT
|
||||
STDMETHOD(SetNumberOfThreads)(UInt32 numThreads);
|
||||
#endif
|
||||
};
|
||||
|
||||
}}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
PROG = BZip2.dll
|
||||
DEF_FILE = ../Codec.def
|
||||
CFLAGS = $(CFLAGS) -I ../../../
|
||||
CFLAGS = $(CFLAGS) -I ../../../ -DCOMPRESS_BZIP2_MT
|
||||
LIBS = $(LIBS) oleaut32.lib
|
||||
|
||||
BZIP2_OBJS = \
|
||||
@@ -14,6 +14,9 @@ BZIP2_OPT_OBJS = \
|
||||
COMMON_OBJS = \
|
||||
$O\Alloc.obj \
|
||||
|
||||
WIN_OBJS = \
|
||||
$O\Synchronization.obj
|
||||
|
||||
7ZIP_COMMON_OBJS = \
|
||||
$O\InBuffer.obj \
|
||||
$O\OutBuffer.obj \
|
||||
@@ -23,6 +26,7 @@ OBJS = \
|
||||
$(BZIP2_OBJS) \
|
||||
$(BZIP2_OPT_OBJS) \
|
||||
$(COMMON_OBJS) \
|
||||
$(WIN_OBJS) \
|
||||
$(7ZIP_COMMON_OBJS) \
|
||||
$O\BlockSort.obj \
|
||||
$O\HuffmanEncoder.obj \
|
||||
@@ -36,6 +40,8 @@ $(BZIP2_OPT_OBJS): $(*B).cpp
|
||||
$(COMPL_O2)
|
||||
$(COMMON_OBJS): ../../../Common/$(*B).cpp
|
||||
$(COMPL)
|
||||
$(WIN_OBJS): ../../../Windows/$(*B).cpp
|
||||
$(COMPL)
|
||||
$(7ZIP_COMMON_OBJS): ../../Common/$(*B).cpp
|
||||
$(COMPL)
|
||||
$O\BlockSort.obj: ../BWT/$(*B).cpp
|
||||
|
||||
@@ -86,7 +86,9 @@ CCoder::CCoder(bool deflate64Mode):
|
||||
m_DistanceMemory(0),
|
||||
m_Created(false),
|
||||
m_Values(0),
|
||||
m_Tables(0)
|
||||
m_Tables(0),
|
||||
m_MatchFinderCycles(0),
|
||||
m_SetMfPasses(0)
|
||||
{
|
||||
m_MatchMaxLen = deflate64Mode ? kMatchMaxLen64 : kMatchMaxLen32;
|
||||
m_NumLenCombinations = deflate64Mode ? kNumLenSymbols64 : kNumLenSymbols32;
|
||||
@@ -99,7 +101,9 @@ HRESULT CCoder::Create()
|
||||
COM_TRY_BEGIN
|
||||
if (!m_MatchFinder)
|
||||
{
|
||||
m_MatchFinder = new NBT3Z::CMatchFinder;
|
||||
NBT3Z::CMatchFinder *matchFinderSpec = new NBT3Z::CMatchFinder;
|
||||
m_SetMfPasses = matchFinderSpec;
|
||||
m_MatchFinder = matchFinderSpec;
|
||||
if (m_MatchFinder == 0)
|
||||
return E_OUTOFMEMORY;
|
||||
}
|
||||
@@ -149,6 +153,8 @@ HRESULT CCoder::Create()
|
||||
if (!LevelCoder.Create(kLevelTableSize, kLevelDirectBits, kTableDirectLevels, kMaxLevelBitLength))
|
||||
return E_OUTOFMEMORY;
|
||||
}
|
||||
if (m_MatchFinderCycles != 0 && m_SetMfPasses != 0)
|
||||
m_SetMfPasses->SetNumPasses(m_MatchFinderCycles);
|
||||
m_Created = true;
|
||||
return S_OK;
|
||||
COM_TRY_END
|
||||
@@ -160,13 +166,13 @@ HRESULT CCoder::BaseSetEncoderProperties2(const PROPID *propIDs,
|
||||
{
|
||||
for(UInt32 i = 0; i < numProperties; i++)
|
||||
{
|
||||
const PROPVARIANT &property = properties[i];
|
||||
const PROPVARIANT &prop = properties[i];
|
||||
switch(propIDs[i])
|
||||
{
|
||||
case NCoderPropID::kNumPasses:
|
||||
if (property.vt != VT_UI4)
|
||||
if (prop.vt != VT_UI4)
|
||||
return E_INVALIDARG;
|
||||
m_NumDivPasses = property.ulVal;
|
||||
m_NumDivPasses = prop.ulVal;
|
||||
if (m_NumDivPasses == 0)
|
||||
m_NumDivPasses = 1;
|
||||
if (m_NumDivPasses == 1)
|
||||
@@ -180,12 +186,19 @@ HRESULT CCoder::BaseSetEncoderProperties2(const PROPID *propIDs,
|
||||
}
|
||||
break;
|
||||
case NCoderPropID::kNumFastBytes:
|
||||
if (property.vt != VT_UI4)
|
||||
if (prop.vt != VT_UI4)
|
||||
return E_INVALIDARG;
|
||||
m_NumFastBytes = property.ulVal;
|
||||
m_NumFastBytes = prop.ulVal;
|
||||
if(m_NumFastBytes < kMatchMinLen || m_NumFastBytes > m_MatchMaxLen)
|
||||
return E_INVALIDARG;
|
||||
break;
|
||||
case NCoderPropID::kMatchFinderCycles:
|
||||
{
|
||||
if (prop.vt != VT_UI4)
|
||||
return E_INVALIDARG;
|
||||
m_MatchFinderCycles = prop.ulVal;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
return E_INVALIDARG;
|
||||
}
|
||||
|
||||
@@ -102,6 +102,9 @@ public:
|
||||
CTables *m_Tables;
|
||||
COptimal m_Optimum[kNumOpts];
|
||||
|
||||
UInt32 m_MatchFinderCycles;
|
||||
IMatchFinderSetNumPasses *m_SetMfPasses;
|
||||
|
||||
void GetMatches();
|
||||
void MovePos(UInt32 num);
|
||||
UInt32 Backward(UInt32 &backRes, UInt32 cur);
|
||||
|
||||
@@ -11,7 +11,8 @@ const UInt32 kMaxValForNormalize = (UInt32(1) << 31) - 1;
|
||||
class CMatchFinder:
|
||||
public IMatchFinder,
|
||||
public CLZInWindow,
|
||||
public CMyUnknownImp
|
||||
public CMyUnknownImp,
|
||||
public IMatchFinderSetNumPasses
|
||||
{
|
||||
UInt32 _cyclicBufferPos;
|
||||
UInt32 _cyclicBufferSize; // it must be historySize + 1
|
||||
@@ -47,7 +48,7 @@ class CMatchFinder:
|
||||
public:
|
||||
CMatchFinder();
|
||||
virtual ~CMatchFinder();
|
||||
void SetCutValue(UInt32 cutValue) { _cutValue = cutValue; }
|
||||
virtual void SetNumPasses(UInt32 numPasses) { _cutValue = numPasses; }
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -24,4 +24,9 @@ struct IMatchFinder: public IInWindowStream
|
||||
STDMETHOD(Skip)(UInt32 num) PURE;
|
||||
};
|
||||
|
||||
struct IMatchFinderSetNumPasses
|
||||
{
|
||||
virtual void SetNumPasses(UInt32 numPasses) PURE;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -220,6 +220,7 @@ void CEncoder::SetPrices(UInt32 posState, UInt32 numSymbols, UInt32 *prices) con
|
||||
}
|
||||
CEncoder::CEncoder():
|
||||
_numFastBytes(kNumFastBytesDefault),
|
||||
_matchFinderCycles(0),
|
||||
_distTableSize(kDefaultDictionaryLogSize * 2),
|
||||
_posStateBits(2),
|
||||
_posStateMask(4 - 1),
|
||||
@@ -229,6 +230,7 @@ CEncoder::CEncoder():
|
||||
_dictionarySizePrev(UInt32(-1)),
|
||||
_numFastBytesPrev(UInt32(-1)),
|
||||
_matchFinderIndex(kBT4),
|
||||
setMfPasses(0),
|
||||
#ifdef COMPRESS_MF_MT
|
||||
_multiThread(false),
|
||||
#endif
|
||||
@@ -249,25 +251,41 @@ HRESULT CEncoder::Create()
|
||||
#ifdef COMPRESS_MF_BT
|
||||
#ifdef COMPRESS_MF_BT2
|
||||
case kBT2:
|
||||
_matchFinder = new NBT2::CMatchFinder;
|
||||
{
|
||||
NBT2::CMatchFinder *mfSpec = new NBT2::CMatchFinder;
|
||||
setMfPasses = mfSpec;
|
||||
_matchFinder = mfSpec;
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
#ifdef COMPRESS_MF_BT3
|
||||
case kBT3:
|
||||
_matchFinder = new NBT3::CMatchFinder;
|
||||
{
|
||||
NBT3::CMatchFinder *mfSpec = new NBT3::CMatchFinder;
|
||||
setMfPasses = mfSpec;
|
||||
_matchFinder = mfSpec;
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
#ifdef COMPRESS_MF_BT4
|
||||
case kBT4:
|
||||
_matchFinder = new NBT4::CMatchFinder;
|
||||
{
|
||||
NBT4::CMatchFinder *mfSpec = new NBT4::CMatchFinder;
|
||||
setMfPasses = mfSpec;
|
||||
_matchFinder = mfSpec;
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef COMPRESS_MF_HC
|
||||
case kHC4:
|
||||
_matchFinder = new NHC4::CMatchFinder;
|
||||
{
|
||||
NHC4::CMatchFinder *mfSpec = new NHC4::CMatchFinder;
|
||||
setMfPasses = mfSpec;
|
||||
_matchFinder = mfSpec;
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
if (_matchFinder == 0)
|
||||
@@ -293,6 +311,8 @@ HRESULT CEncoder::Create()
|
||||
if (_dictionarySize == _dictionarySizePrev && _numFastBytesPrev == _numFastBytes)
|
||||
return S_OK;
|
||||
RINOK(_matchFinder->Create(_dictionarySize, kNumOpts, _numFastBytes, kMatchMaxLen + 1)); // actually it's + _numFastBytes - _numFastBytes
|
||||
if (_matchFinderCycles != 0 && setMfPasses != 0)
|
||||
setMfPasses->SetNumPasses(_matchFinderCycles);
|
||||
_dictionarySizePrev = _dictionarySize;
|
||||
_numFastBytesPrev = _numFastBytes;
|
||||
return S_OK;
|
||||
@@ -340,6 +360,13 @@ STDMETHODIMP CEncoder::SetCoderProperties(const PROPID *propIDs,
|
||||
_numFastBytes = numFastBytes;
|
||||
break;
|
||||
}
|
||||
case NCoderPropID::kMatchFinderCycles:
|
||||
{
|
||||
if (prop.vt != VT_UI4)
|
||||
return E_INVALIDARG;
|
||||
_matchFinderCycles = prop.ulVal;
|
||||
break;
|
||||
}
|
||||
case NCoderPropID::kAlgorithm:
|
||||
{
|
||||
if (prop.vt != VT_UI4)
|
||||
@@ -360,8 +387,8 @@ STDMETHODIMP CEncoder::SetCoderProperties(const PROPID *propIDs,
|
||||
_matchFinderIndex = m;
|
||||
if (_matchFinder && matchFinderIndexPrev != _matchFinderIndex)
|
||||
{
|
||||
_dictionarySizePrev = UInt32(-1);
|
||||
_matchFinder.Release();
|
||||
_dictionarySizePrev = (UInt32)-1;
|
||||
ReleaseMatchFinder();
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -373,10 +400,23 @@ STDMETHODIMP CEncoder::SetCoderProperties(const PROPID *propIDs,
|
||||
bool newMultiThread = (prop.boolVal == VARIANT_TRUE);
|
||||
if (newMultiThread != _multiThread)
|
||||
{
|
||||
_dictionarySizePrev = UInt32(-1);
|
||||
_matchFinder.Release();
|
||||
_dictionarySizePrev = (UInt32)-1;
|
||||
ReleaseMatchFinder();
|
||||
_multiThread = newMultiThread;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case NCoderPropID::kNumThreads:
|
||||
{
|
||||
if (prop.vt != VT_UI4)
|
||||
return E_INVALIDARG;
|
||||
bool newMultiThread = (prop.ulVal > 1);
|
||||
if (newMultiThread != _multiThread)
|
||||
{
|
||||
_dictionarySizePrev = (UInt32)-1;
|
||||
ReleaseMatchFinder();
|
||||
_multiThread = newMultiThread;
|
||||
}
|
||||
_multiThread = newMultiThread;
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
@@ -1219,12 +1259,6 @@ HRESULT CEncoder::GetOptimumFast(UInt32 position, UInt32 &backRes, UInt32 &lenRe
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP CEncoder::InitMatchFinder(IMatchFinder *matchFinder)
|
||||
{
|
||||
_matchFinder = matchFinder;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT CEncoder::Flush(UInt32 nowPos)
|
||||
{
|
||||
ReleaseMFStream();
|
||||
|
||||
@@ -240,6 +240,7 @@ class CEncoder :
|
||||
bool _finished;
|
||||
ISequentialInStream *_inStream;
|
||||
|
||||
UInt32 _matchFinderCycles;
|
||||
int _matchFinderIndex;
|
||||
#ifdef COMPRESS_MF_MT
|
||||
bool _multiThread;
|
||||
@@ -248,6 +249,14 @@ class CEncoder :
|
||||
bool _writeEndMark;
|
||||
|
||||
bool _needReleaseMFStream;
|
||||
|
||||
IMatchFinderSetNumPasses *setMfPasses;
|
||||
|
||||
void ReleaseMatchFinder()
|
||||
{
|
||||
setMfPasses = 0;
|
||||
_matchFinder.Release();
|
||||
}
|
||||
|
||||
HRESULT ReadMatchDistances(UInt32 &len, UInt32 &numDistancePairs);
|
||||
|
||||
@@ -384,9 +393,6 @@ public:
|
||||
const UInt64 *inSize, const UInt64 *outSize,
|
||||
ICompressProgressInfo *progress);
|
||||
|
||||
// IInitMatchFinder interface
|
||||
STDMETHOD(InitMatchFinder)(IMatchFinder *matchFinder);
|
||||
|
||||
// ICompressSetCoderProperties2
|
||||
STDMETHOD(SetCoderProperties)(const PROPID *propIDs,
|
||||
const PROPVARIANT *properties, UInt32 numProperties);
|
||||
|
||||
@@ -59,6 +59,7 @@ enum Enum
|
||||
kMode,
|
||||
kDictionary,
|
||||
kFastBytes,
|
||||
kMatchFinderCycles,
|
||||
kLitContext,
|
||||
kLitPos,
|
||||
kPosBits,
|
||||
@@ -77,6 +78,7 @@ static const CSwitchForm kSwitchForms[] =
|
||||
{ L"A", NSwitchType::kUnLimitedPostString, false, 1 },
|
||||
{ L"D", NSwitchType::kUnLimitedPostString, false, 1 },
|
||||
{ L"FB", NSwitchType::kUnLimitedPostString, false, 1 },
|
||||
{ L"MC", NSwitchType::kUnLimitedPostString, false, 1 },
|
||||
{ L"LC", NSwitchType::kUnLimitedPostString, false, 1 },
|
||||
{ L"LP", NSwitchType::kUnLimitedPostString, false, 1 },
|
||||
{ L"PB", NSwitchType::kUnLimitedPostString, false, 1 },
|
||||
@@ -99,6 +101,7 @@ static void PrintHelp()
|
||||
" -a{N}: set compression mode - [0, 1], default: 1 (max)\n"
|
||||
" -d{N}: set dictionary - [0,30], default: 23 (8MB)\n"
|
||||
" -fb{N}: set number of fast bytes - [5, 273], default: 128\n"
|
||||
" -mc{N}: set number of cycles for match finder\n"
|
||||
" -lc{N}: set number of literal context bits - [0, 8], default: 3\n"
|
||||
" -lp{N}: set number of literal pos bits - [0, 4], default: 0\n"
|
||||
" -pb{N}: set number of pos bits - [0, 4], default: 2\n"
|
||||
@@ -149,7 +152,7 @@ int main2(int n, const char *args[])
|
||||
g_IsNT = IsItWindowsNT();
|
||||
#endif
|
||||
|
||||
fprintf(stderr, "\nLZMA 4.33 Copyright (c) 1999-2006 Igor Pavlov 2006-02-05\n");
|
||||
fprintf(stderr, "\nLZMA 4.34 Copyright (c) 1999-2006 Igor Pavlov 2006-02-23\n");
|
||||
|
||||
if (n == 1)
|
||||
{
|
||||
@@ -353,6 +356,8 @@ int main2(int n, const char *args[])
|
||||
// UInt32 litPosBits = 2; // for 32-bit data
|
||||
UInt32 algorithm = 2;
|
||||
UInt32 numFastBytes = 128;
|
||||
UInt32 matchFinderCycles = 16 + numFastBytes / 2;
|
||||
bool matchFinderCyclesDefined = false;
|
||||
|
||||
bool eos = parser[NKey::kEOS].ThereIs || stdInMode;
|
||||
|
||||
@@ -363,6 +368,9 @@ int main2(int n, const char *args[])
|
||||
if(parser[NKey::kFastBytes].ThereIs)
|
||||
if (!GetNumber(parser[NKey::kFastBytes].PostStrings[0], numFastBytes))
|
||||
IncorrectCommand();
|
||||
if (matchFinderCyclesDefined = parser[NKey::kMatchFinderCycles].ThereIs)
|
||||
if (!GetNumber(parser[NKey::kMatchFinderCycles].PostStrings[0], matchFinderCycles))
|
||||
IncorrectCommand();
|
||||
if(parser[NKey::kLitContext].ThereIs)
|
||||
if (!GetNumber(parser[NKey::kLitContext].PostStrings[0], litContextBits))
|
||||
IncorrectCommand();
|
||||
@@ -382,9 +390,10 @@ int main2(int n, const char *args[])
|
||||
NCoderPropID::kAlgorithm,
|
||||
NCoderPropID::kNumFastBytes,
|
||||
NCoderPropID::kMatchFinder,
|
||||
NCoderPropID::kEndMarker
|
||||
NCoderPropID::kEndMarker,
|
||||
NCoderPropID::kMatchFinderCycles
|
||||
};
|
||||
const int kNumProps = sizeof(propIDs) / sizeof(propIDs[0]);
|
||||
const int kNumPropsMax = sizeof(propIDs) / sizeof(propIDs[0]);
|
||||
/*
|
||||
NWindows::NCOM::CPropVariant properties[kNumProps];
|
||||
properties[0] = UInt32(dictionary);
|
||||
@@ -397,15 +406,19 @@ int main2(int n, const char *args[])
|
||||
properties[6] = mf;
|
||||
properties[7] = eos;
|
||||
*/
|
||||
PROPVARIANT properties[kNumProps];
|
||||
PROPVARIANT properties[kNumPropsMax];
|
||||
for (int p = 0; p < 6; p++)
|
||||
properties[p].vt = VT_UI4;
|
||||
|
||||
properties[0].ulVal = UInt32(dictionary);
|
||||
properties[1].ulVal = UInt32(posStateBits);
|
||||
properties[2].ulVal = UInt32(litContextBits);
|
||||
properties[3].ulVal = UInt32(litPosBits);
|
||||
properties[4].ulVal = UInt32(algorithm);
|
||||
properties[5].ulVal = UInt32(numFastBytes);
|
||||
|
||||
properties[8].vt = VT_UI4;
|
||||
properties[8].ulVal = UInt32(matchFinderCycles);
|
||||
|
||||
properties[6].vt = VT_BSTR;
|
||||
properties[6].bstrVal = (BSTR)(const wchar_t *)mf;
|
||||
@@ -413,7 +426,11 @@ int main2(int n, const char *args[])
|
||||
properties[7].vt = VT_BOOL;
|
||||
properties[7].boolVal = eos ? VARIANT_TRUE : VARIANT_FALSE;
|
||||
|
||||
if (encoderSpec->SetCoderProperties(propIDs, properties, kNumProps) != S_OK)
|
||||
int numProps = kNumPropsMax;
|
||||
if (!matchFinderCyclesDefined)
|
||||
numProps--;
|
||||
|
||||
if (encoderSpec->SetCoderProperties(propIDs, properties, numProps) != S_OK)
|
||||
IncorrectCommand();
|
||||
encoderSpec->WriteCoderProperties(outStream);
|
||||
|
||||
|
||||
@@ -25,6 +25,7 @@
|
||||
22 ICompressSetDecoderProperties2
|
||||
23 ICompressWriteCoderProperties
|
||||
24 ICompressGetInStreamProcessedSize
|
||||
25 ICompressSetCoderMt
|
||||
30 ICompressGetSubStreamSize
|
||||
31 ICompressSetInStream
|
||||
32 ICompressSetOutStream
|
||||
|
||||
@@ -48,9 +48,11 @@ namespace NCoderPropID
|
||||
kLitPosBits,
|
||||
kNumFastBytes = 0x450,
|
||||
kMatchFinder,
|
||||
kMatchFinderCycles,
|
||||
kNumPasses = 0x460,
|
||||
kAlgorithm = 0x470,
|
||||
kMultiThread = 0x480,
|
||||
kNumThreads,
|
||||
kEndMarker = 0x490
|
||||
};
|
||||
}
|
||||
@@ -83,6 +85,11 @@ CODER_INTERFACE(ICompressGetInStreamProcessedSize, 0x24)
|
||||
STDMETHOD(GetInStreamProcessedSize)(UInt64 *value) PURE;
|
||||
};
|
||||
|
||||
CODER_INTERFACE(ICompressSetCoderMt, 0x25)
|
||||
{
|
||||
STDMETHOD(SetNumberOfThreads)(UInt32 numThreads) PURE;
|
||||
};
|
||||
|
||||
CODER_INTERFACE(ICompressGetSubStreamSize, 0x30)
|
||||
{
|
||||
STDMETHOD(GetSubStreamSize)(UInt64 subStream, UInt64 *value) PURE;
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#define MY_VER_MAJOR 4
|
||||
#define MY_VER_MINOR 33
|
||||
#define MY_VERSION "4.33 beta"
|
||||
#define MY_7ZIP_VERSION "7-Zip 4.33 beta"
|
||||
#define MY_DATE "2006-02-05"
|
||||
#define MY_VER_MINOR 34
|
||||
#define MY_VERSION "4.34 beta"
|
||||
#define MY_7ZIP_VERSION "7-Zip 4.34 beta"
|
||||
#define MY_DATE "2006-02-27"
|
||||
#define MY_COPYRIGHT "Copyright (c) 1999-2006 Igor Pavlov"
|
||||
#define MY_VERSION_COPYRIGHT_DATE MY_VERSION " " MY_COPYRIGHT " " MY_DATE
|
||||
|
||||
@@ -27,7 +27,7 @@ using namespace NCommandLineParser;
|
||||
using namespace NWindows;
|
||||
using namespace NFile;
|
||||
|
||||
static const int kNumSwitches = 25;
|
||||
static const int kNumSwitches = 26;
|
||||
|
||||
namespace NKey {
|
||||
enum Enum
|
||||
@@ -56,7 +56,8 @@ enum Enum
|
||||
kOverwrite,
|
||||
kEmail,
|
||||
kShowDialog,
|
||||
kLargePages
|
||||
kLargePages,
|
||||
kCharSet
|
||||
};
|
||||
|
||||
}
|
||||
@@ -119,7 +120,8 @@ static const CSwitchForm kSwitchForms[kNumSwitches] =
|
||||
{ L"AO", NSwitchType::kPostChar, false, 1, 1, kOverwritePostCharSet},
|
||||
{ L"SEML", NSwitchType::kUnLimitedPostString, false, 0},
|
||||
{ L"AD", NSwitchType::kSimple, false },
|
||||
{ L"SLP", NSwitchType::kUnLimitedPostString, false, 0}
|
||||
{ L"SLP", NSwitchType::kUnLimitedPostString, false, 0},
|
||||
{ L"SCS", NSwitchType::kUnLimitedPostString, false, 0}
|
||||
};
|
||||
|
||||
static const int kNumCommandForms = 7;
|
||||
@@ -234,15 +236,13 @@ static bool AddNameToCensor(NWildcard::CCensor &wildcardCensor,
|
||||
return true;
|
||||
}
|
||||
|
||||
static inline UINT GetCurrentCodePage()
|
||||
{ return ::AreFileApisANSI() ? CP_ACP : CP_OEMCP; }
|
||||
static inline GetCurrentCodePage() { return ::AreFileApisANSI() ? CP_ACP : CP_OEMCP; }
|
||||
|
||||
static void AddToCensorFromListFile(NWildcard::CCensor &wildcardCensor,
|
||||
LPCWSTR fileName, bool include, NRecursedType::EEnum type)
|
||||
LPCWSTR fileName, bool include, NRecursedType::EEnum type, UINT codePage)
|
||||
{
|
||||
UStringVector names;
|
||||
if (!ReadNamesFromListFile(GetSystemString(fileName,
|
||||
GetCurrentCodePage()), names))
|
||||
if (!ReadNamesFromListFile(GetSystemString(fileName, GetCurrentCodePage()), names, codePage))
|
||||
throw kIncorrectListFile;
|
||||
for (int i = 0; i < names.Size(); i++)
|
||||
if (!AddNameToCensor(wildcardCensor, names[i], include, type))
|
||||
@@ -260,7 +260,7 @@ static void AddToCensorFromNonSwitchesStrings(
|
||||
int startIndex,
|
||||
NWildcard::CCensor &wildcardCensor,
|
||||
const UStringVector &nonSwitchStrings, NRecursedType::EEnum type,
|
||||
bool thereAreSwitchIncludes)
|
||||
bool thereAreSwitchIncludes, UINT codePage)
|
||||
{
|
||||
if(nonSwitchStrings.Size() == startIndex && (!thereAreSwitchIncludes))
|
||||
AddCommandLineWildCardToCensr(wildcardCensor, kUniversalWildcard, true, type);
|
||||
@@ -268,7 +268,7 @@ static void AddToCensorFromNonSwitchesStrings(
|
||||
{
|
||||
const UString &s = nonSwitchStrings[i];
|
||||
if (s[0] == kFileListID)
|
||||
AddToCensorFromListFile(wildcardCensor, s.Mid(1), true, type);
|
||||
AddToCensorFromListFile(wildcardCensor, s.Mid(1), true, type, codePage);
|
||||
else
|
||||
AddCommandLineWildCardToCensr(wildcardCensor, s, true, type);
|
||||
}
|
||||
@@ -341,7 +341,7 @@ static void ParseMapWithPaths(NWildcard::CCensor &wildcardCensor,
|
||||
|
||||
static void AddSwitchWildCardsToCensor(NWildcard::CCensor &wildcardCensor,
|
||||
const UStringVector &strings, bool include,
|
||||
NRecursedType::EEnum commonRecursedType)
|
||||
NRecursedType::EEnum commonRecursedType, UINT codePage)
|
||||
{
|
||||
for(int i = 0; i < strings.Size(); i++)
|
||||
{
|
||||
@@ -366,7 +366,7 @@ static void AddSwitchWildCardsToCensor(NWildcard::CCensor &wildcardCensor,
|
||||
if (name[pos] == kImmediateNameID)
|
||||
AddCommandLineWildCardToCensr(wildcardCensor, tail, include, recursedType);
|
||||
else if (name[pos] == kFileListID)
|
||||
AddToCensorFromListFile(wildcardCensor, tail, include, recursedType);
|
||||
AddToCensorFromListFile(wildcardCensor, tail, include, recursedType, codePage);
|
||||
#ifdef _WIN32
|
||||
else if (name[pos] == kMapNameID)
|
||||
ParseMapWithPaths(wildcardCensor, tail, include, recursedType);
|
||||
@@ -632,8 +632,7 @@ static void SetAddCommandOptions(
|
||||
}
|
||||
}
|
||||
|
||||
static void SetMethodOptions(const CParser &parser,
|
||||
CUpdateOptions &options)
|
||||
static void SetMethodOptions(const CParser &parser, CObjectVector<CProperty> &properties)
|
||||
{
|
||||
if (parser[NKey::kProperty].ThereIs)
|
||||
{
|
||||
@@ -650,7 +649,7 @@ static void SetMethodOptions(const CParser &parser,
|
||||
property.Name = postString.Left(index);
|
||||
property.Value = postString.Mid(index + 1);
|
||||
}
|
||||
options.MethodMode.Properties.Add(property);
|
||||
properties.Add(property);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -723,6 +722,21 @@ void CArchiveCommandLineParser::Parse1(const UStringVector &commandStrings,
|
||||
#endif
|
||||
}
|
||||
|
||||
struct CCodePagePair
|
||||
{
|
||||
const wchar_t *Name;
|
||||
UINT CodePage;
|
||||
};
|
||||
|
||||
static CCodePagePair g_CodePagePairs[] =
|
||||
{
|
||||
{ L"UTF-8", CP_UTF8 },
|
||||
{ L"WIN", CP_ACP },
|
||||
{ L"DOS", CP_OEMCP }
|
||||
};
|
||||
|
||||
static const int kNumCodePages = sizeof(g_CodePagePairs) / sizeof(g_CodePagePairs[0]);
|
||||
|
||||
void CArchiveCommandLineParser::Parse2(CArchiveCommandLineOptions &options)
|
||||
{
|
||||
const UStringVector &nonSwitchStrings = parser.NonSwitchStrings;
|
||||
@@ -739,16 +753,35 @@ void CArchiveCommandLineParser::Parse2(CArchiveCommandLineOptions &options)
|
||||
else
|
||||
recursedType = NRecursedType::kNonRecursed;
|
||||
|
||||
UINT codePage = CP_UTF8;
|
||||
if (parser[NKey::kCharSet].ThereIs)
|
||||
{
|
||||
UString name = parser[NKey::kCharSet].PostStrings.Front();
|
||||
name.MakeUpper();
|
||||
int i;
|
||||
for (i = 0; i < kNumCodePages; i++)
|
||||
{
|
||||
const CCodePagePair &pair = g_CodePagePairs[i];
|
||||
if (name.Compare(pair.Name) == 0)
|
||||
{
|
||||
codePage = pair.CodePage;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (i >= kNumCodePages)
|
||||
throw kUserErrorMessage;
|
||||
}
|
||||
|
||||
bool thereAreSwitchIncludes = false;
|
||||
if (parser[NKey::kInclude].ThereIs)
|
||||
{
|
||||
thereAreSwitchIncludes = true;
|
||||
AddSwitchWildCardsToCensor(options.WildcardCensor,
|
||||
parser[NKey::kInclude].PostStrings, true, recursedType);
|
||||
parser[NKey::kInclude].PostStrings, true, recursedType, codePage);
|
||||
}
|
||||
if (parser[NKey::kExclude].ThereIs)
|
||||
AddSwitchWildCardsToCensor(options.WildcardCensor,
|
||||
parser[NKey::kExclude].PostStrings, false, recursedType);
|
||||
parser[NKey::kExclude].PostStrings, false, recursedType, codePage);
|
||||
|
||||
int curCommandIndex = kCommandIndex + 1;
|
||||
bool thereIsArchiveName = !parser[NKey::kNoArName].ThereIs;
|
||||
@@ -761,7 +794,7 @@ void CArchiveCommandLineParser::Parse2(CArchiveCommandLineOptions &options)
|
||||
|
||||
AddToCensorFromNonSwitchesStrings(
|
||||
curCommandIndex, options.WildcardCensor,
|
||||
nonSwitchStrings, recursedType, thereAreSwitchIncludes);
|
||||
nonSwitchStrings, recursedType, thereAreSwitchIncludes, codePage);
|
||||
|
||||
options.YesToAll = parser[NKey::kYes].ThereIs;
|
||||
|
||||
@@ -787,11 +820,11 @@ void CArchiveCommandLineParser::Parse2(CArchiveCommandLineOptions &options)
|
||||
if (parser[NKey::kArInclude].ThereIs)
|
||||
{
|
||||
AddSwitchWildCardsToCensor(archiveWildcardCensor,
|
||||
parser[NKey::kArInclude].PostStrings, true, NRecursedType::kNonRecursed);
|
||||
parser[NKey::kArInclude].PostStrings, true, NRecursedType::kNonRecursed, codePage);
|
||||
}
|
||||
if (parser[NKey::kArExclude].ThereIs)
|
||||
AddSwitchWildCardsToCensor(archiveWildcardCensor,
|
||||
parser[NKey::kArExclude].PostStrings, false, NRecursedType::kNonRecursed);
|
||||
parser[NKey::kArExclude].PostStrings, false, NRecursedType::kNonRecursed, codePage);
|
||||
|
||||
if (thereIsArchiveName)
|
||||
AddCommandLineWildCardToCensr(archiveWildcardCensor, options.ArchiveName, true, NRecursedType::kNonRecursed);
|
||||
@@ -840,6 +873,7 @@ void CArchiveCommandLineParser::Parse2(CArchiveCommandLineOptions &options)
|
||||
|
||||
if(isExtractGroupCommand)
|
||||
{
|
||||
SetMethodOptions(parser, options.ExtractProperties);
|
||||
if (options.StdOutMode && options.IsStdOutTerminal)
|
||||
throw kTerminalOutError;
|
||||
if(parser[NKey::kOutputDir].ThereIs)
|
||||
@@ -882,10 +916,9 @@ void CArchiveCommandLineParser::Parse2(CArchiveCommandLineOptions &options)
|
||||
updateOptions.ArchivePath.BaseExtension = extension;
|
||||
updateOptions.ArchivePath.VolExtension = typeExtension;
|
||||
updateOptions.ArchivePath.ParseFromPath(options.ArchiveName);
|
||||
SetAddCommandOptions(options.Command.CommandType, parser,
|
||||
updateOptions);
|
||||
SetAddCommandOptions(options.Command.CommandType, parser, updateOptions);
|
||||
|
||||
SetMethodOptions(parser, updateOptions);
|
||||
SetMethodOptions(parser, updateOptions.MethodMode.Properties);
|
||||
|
||||
options.EnablePercents = !parser[NKey::kDisablePercents].ThereIs;
|
||||
|
||||
|
||||
@@ -68,6 +68,7 @@ struct CArchiveCommandLineOptions
|
||||
NExtract::NOverwriteMode::EEnum OverwriteMode;
|
||||
UStringVector ArchivePathsSorted;
|
||||
UStringVector ArchivePathsFullSorted;
|
||||
CObjectVector<CProperty> ExtractProperties;
|
||||
|
||||
CUpdateOptions UpdateOptions;
|
||||
bool EnablePercents;
|
||||
|
||||
@@ -5,10 +5,10 @@
|
||||
#include "Extract.h"
|
||||
|
||||
#include "Windows/Defs.h"
|
||||
#include "Windows/PropVariant.h"
|
||||
#include "Windows/FileDir.h"
|
||||
|
||||
#include "OpenArchive.h"
|
||||
#include "SetProperties.h"
|
||||
|
||||
#ifndef EXCLUDE_COM
|
||||
#include "Windows/DLL.h"
|
||||
@@ -68,6 +68,10 @@ HRESULT DecompressArchive(
|
||||
options.ArchiveFileInfo.LastWriteTime,
|
||||
options.ArchiveFileInfo.Attributes);
|
||||
|
||||
#ifdef COMPRESS_MT
|
||||
RINOK(SetProperties(archive, options.Properties));
|
||||
#endif
|
||||
|
||||
HRESULT result = archive->Extract(&realIndices.Front(),
|
||||
realIndices.Size(), options.TestMode? 1: 0,
|
||||
extractCallback);
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
#include "ArchiveExtractCallback.h"
|
||||
#include "ArchiveOpenCallback.h"
|
||||
#include "ExtractMode.h"
|
||||
#include "Property.h"
|
||||
|
||||
class CExtractOptions
|
||||
{
|
||||
@@ -27,6 +28,9 @@ public:
|
||||
// bool ShowDialog;
|
||||
// bool PasswordEnabled;
|
||||
// UString Password;
|
||||
#ifdef COMPRESS_MT
|
||||
CObjectVector<CProperty> Properties;
|
||||
#endif
|
||||
|
||||
NExtract::NOverwriteMode::EEnum OverwriteMode;
|
||||
|
||||
|
||||
14
7zip/UI/Common/Property.h
Executable file
14
7zip/UI/Common/Property.h
Executable file
@@ -0,0 +1,14 @@
|
||||
// Property.h
|
||||
|
||||
#ifndef __PROPERTY_H
|
||||
#define __PROPERTY_H
|
||||
|
||||
#include "Common/String.h"
|
||||
|
||||
struct CProperty
|
||||
{
|
||||
UString Name;
|
||||
UString Value;
|
||||
};
|
||||
|
||||
#endif
|
||||
65
7zip/UI/Common/SetProperties.cpp
Executable file
65
7zip/UI/Common/SetProperties.cpp
Executable file
@@ -0,0 +1,65 @@
|
||||
// SetProperties.cpp
|
||||
|
||||
#include "StdAfx.h"
|
||||
|
||||
#include "SetProperties.h"
|
||||
|
||||
#include "Windows/PropVariant.h"
|
||||
#include "Common/String.h"
|
||||
#include "Common/StringToInt.h"
|
||||
#include "Common/MyCom.h"
|
||||
|
||||
#include "../../Archive/IArchive.h"
|
||||
|
||||
using namespace NWindows;
|
||||
using namespace NCOM;
|
||||
|
||||
static void ParseNumberString(const UString &s, NCOM::CPropVariant &prop)
|
||||
{
|
||||
const wchar_t *endPtr;
|
||||
UInt64 result = ConvertStringToUInt64(s, &endPtr);
|
||||
if (endPtr - (const wchar_t *)s != s.Length())
|
||||
prop = s;
|
||||
else if (result <= 0xFFFFFFFF)
|
||||
prop = (UInt32)result;
|
||||
else
|
||||
prop = result;
|
||||
}
|
||||
|
||||
HRESULT SetProperties(IUnknown *unknown, const CObjectVector<CProperty> &properties)
|
||||
{
|
||||
if (properties.IsEmpty())
|
||||
return S_OK;
|
||||
CMyComPtr<ISetProperties> setProperties;
|
||||
unknown->QueryInterface(IID_ISetProperties, (void **)&setProperties);
|
||||
if (!setProperties)
|
||||
return S_OK;
|
||||
|
||||
UStringVector realNames;
|
||||
CPropVariant *values = new CPropVariant[properties.Size()];
|
||||
try
|
||||
{
|
||||
int i;
|
||||
for(i = 0; i < properties.Size(); i++)
|
||||
{
|
||||
const CProperty &property = properties[i];
|
||||
NCOM::CPropVariant propVariant;
|
||||
if (!property.Value.IsEmpty())
|
||||
ParseNumberString(property.Value, propVariant);
|
||||
realNames.Add(property.Name);
|
||||
values[i] = propVariant;
|
||||
}
|
||||
CRecordVector<const wchar_t *> names;
|
||||
for(i = 0; i < realNames.Size(); i++)
|
||||
names.Add((const wchar_t *)realNames[i]);
|
||||
|
||||
RINOK(setProperties->SetProperties(&names.Front(), values, names.Size()));
|
||||
}
|
||||
catch(...)
|
||||
{
|
||||
delete []values;
|
||||
throw;
|
||||
}
|
||||
delete []values;
|
||||
return S_OK;
|
||||
}
|
||||
10
7zip/UI/Common/SetProperties.h
Executable file
10
7zip/UI/Common/SetProperties.h
Executable file
@@ -0,0 +1,10 @@
|
||||
// SetProperties.h
|
||||
|
||||
#ifndef __SETPROPERTIES_H
|
||||
#define __SETPROPERTIES_H
|
||||
|
||||
#include "Property.h"
|
||||
|
||||
HRESULT SetProperties(IUnknown *unknown, const CObjectVector<CProperty> &properties);
|
||||
|
||||
#endif
|
||||
@@ -9,7 +9,6 @@
|
||||
#include "Update.h"
|
||||
|
||||
#include "Common/IntToString.h"
|
||||
#include "Common/StringToInt.h"
|
||||
#include "Common/StringConvert.h"
|
||||
#include "Common/CommandLineParser.h"
|
||||
|
||||
@@ -36,6 +35,7 @@
|
||||
#include "TempFiles.h"
|
||||
#include "UpdateCallback.h"
|
||||
#include "EnumDirItems.h"
|
||||
#include "SetProperties.h"
|
||||
|
||||
#ifdef FORMAT_7Z
|
||||
#include "../../Archive/7z/7zHandler.h"
|
||||
@@ -77,18 +77,6 @@ static const char *kIllegalFileNameMessage = "Illegal file name for temp archive
|
||||
|
||||
using namespace NUpdateArchive;
|
||||
|
||||
static void ParseNumberString(const UString &s, NCOM::CPropVariant &prop)
|
||||
{
|
||||
const wchar_t *endPtr;
|
||||
UInt64 result = ConvertStringToUInt64(s, &endPtr);
|
||||
if (endPtr - (const wchar_t *)s != s.Length())
|
||||
prop = s;
|
||||
else if (result <= 0xFFFFFFFF)
|
||||
prop = (UInt32)result;
|
||||
else
|
||||
prop = result;
|
||||
}
|
||||
|
||||
static HRESULT CopyBlock(ISequentialInStream *inStream, ISequentialOutStream *outStream)
|
||||
{
|
||||
CMyComPtr<ICompressCoder> copyCoder = new NCompress::CCopyCoder;
|
||||
@@ -439,36 +427,7 @@ static HRESULT Compress(
|
||||
*/
|
||||
}
|
||||
|
||||
CMyComPtr<ISetProperties> setProperties;
|
||||
if (outArchive.QueryInterface(IID_ISetProperties, &setProperties) == S_OK)
|
||||
{
|
||||
UStringVector realNames;
|
||||
CPropVariant *values = new CPropVariant[compressionMethod.Properties.Size()];
|
||||
try
|
||||
{
|
||||
int i;
|
||||
for(i = 0; i < compressionMethod.Properties.Size(); i++)
|
||||
{
|
||||
const CProperty &property = compressionMethod.Properties[i];
|
||||
NCOM::CPropVariant propVariant;
|
||||
if (!property.Value.IsEmpty())
|
||||
ParseNumberString(property.Value, propVariant);
|
||||
realNames.Add(property.Name);
|
||||
values[i] = propVariant;
|
||||
}
|
||||
CRecordVector<const wchar_t *> names;
|
||||
for(i = 0; i < realNames.Size(); i++)
|
||||
names.Add((const wchar_t *)realNames[i]);
|
||||
|
||||
RINOK(setProperties->SetProperties(&names.Front(), values, names.Size()));
|
||||
}
|
||||
catch(...)
|
||||
{
|
||||
delete []values;
|
||||
throw;
|
||||
}
|
||||
delete []values;
|
||||
}
|
||||
RINOK(SetProperties(outArchive, compressionMethod.Properties));
|
||||
|
||||
if (sfxMode)
|
||||
{
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
#include "UpdateAction.h"
|
||||
#include "ArchiveOpenCallback.h"
|
||||
#include "UpdateCallback.h"
|
||||
#include "Property.h"
|
||||
|
||||
struct CArchivePath
|
||||
{
|
||||
@@ -75,12 +76,6 @@ struct CUpdateArchiveCommand
|
||||
NUpdateArchive::CActionSet ActionSet;
|
||||
};
|
||||
|
||||
struct CProperty
|
||||
{
|
||||
UString Name;
|
||||
UString Value;
|
||||
};
|
||||
|
||||
struct CCompressionMethodMode
|
||||
{
|
||||
#ifndef EXCLUDE_COM
|
||||
@@ -111,7 +106,7 @@ struct CUpdateOptions
|
||||
bool EMailRemoveAfter;
|
||||
UString EMailAddress;
|
||||
|
||||
UString WorkingDir;
|
||||
UString WorkingDir;
|
||||
|
||||
CUpdateOptions():
|
||||
UpdateArchiveItself(true),
|
||||
|
||||
@@ -44,7 +44,7 @@ RSC=rc.exe
|
||||
# PROP Ignore_Export_Lib 0
|
||||
# PROP Target_Dir ""
|
||||
# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
|
||||
# ADD CPP /nologo /Gz /MD /W3 /GX /O1 /I "../../../" /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /Yu"StdAfx.h" /FD /c
|
||||
# ADD CPP /nologo /Gz /MD /W3 /GX /O1 /I "../../../" /D "NDEBUG" /D "_MBCS" /D "WIN32" /D "_CONSOLE" /D "COMPRESS_MT" /Yu"StdAfx.h" /FD /c
|
||||
# ADD BASE RSC /l 0x419 /d "NDEBUG"
|
||||
# ADD RSC /l 0x419 /d "NDEBUG"
|
||||
BSC32=bscmake.exe
|
||||
@@ -69,7 +69,7 @@ LINK32=link.exe
|
||||
# PROP Ignore_Export_Lib 0
|
||||
# PROP Target_Dir ""
|
||||
# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c
|
||||
# ADD CPP /nologo /Gz /W3 /Gm /GX /ZI /Od /I "../../../" /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /Yu"StdAfx.h" /FD /GZ /c
|
||||
# ADD CPP /nologo /Gz /W3 /Gm /GX /ZI /Od /I "../../../" /D "_DEBUG" /D "_MBCS" /D "WIN32" /D "_CONSOLE" /D "COMPRESS_MT" /Yu"StdAfx.h" /FD /GZ /c
|
||||
# ADD BASE RSC /l 0x419 /d "_DEBUG"
|
||||
# ADD RSC /l 0x419 /d "_DEBUG"
|
||||
BSC32=bscmake.exe
|
||||
@@ -94,7 +94,7 @@ LINK32=link.exe
|
||||
# PROP Ignore_Export_Lib 0
|
||||
# PROP Target_Dir ""
|
||||
# ADD BASE CPP /nologo /Gz /MD /W3 /GX /O1 /I "../../../" /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /Yu"StdAfx.h" /FD /c
|
||||
# ADD CPP /nologo /Gz /MD /W3 /GX /O1 /I "../../../" /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_UNICODE" /D "UNICODE" /Yu"StdAfx.h" /FD /c
|
||||
# ADD CPP /nologo /Gz /MD /W3 /GX /O1 /I "../../../" /D "NDEBUG" /D "_UNICODE" /D "UNICODE" /D "WIN32" /D "_CONSOLE" /D "COMPRESS_MT" /Yu"StdAfx.h" /FD /c
|
||||
# ADD BASE RSC /l 0x419 /d "NDEBUG"
|
||||
# ADD RSC /l 0x419 /d "NDEBUG"
|
||||
BSC32=bscmake.exe
|
||||
@@ -120,7 +120,7 @@ LINK32=link.exe
|
||||
# PROP Ignore_Export_Lib 0
|
||||
# PROP Target_Dir ""
|
||||
# ADD BASE CPP /nologo /Gz /W3 /Gm /GX /ZI /Od /I "../../../" /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /Yu"StdAfx.h" /FD /GZ /c
|
||||
# ADD CPP /nologo /Gz /W3 /Gm /GX /ZI /Od /I "../../../" /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_UNICODE" /D "UNICODE" /Yu"StdAfx.h" /FD /GZ /c
|
||||
# ADD CPP /nologo /Gz /W3 /Gm /GX /ZI /Od /I "../../../" /D "_DEBUG" /D "_UNICODE" /D "UNICODE" /D "WIN32" /D "_CONSOLE" /D "COMPRESS_MT" /Yu"StdAfx.h" /FD /GZ /c
|
||||
# ADD BASE RSC /l 0x419 /d "_DEBUG"
|
||||
# ADD RSC /l 0x419 /d "_DEBUG"
|
||||
BSC32=bscmake.exe
|
||||
@@ -532,6 +532,10 @@ SOURCE=..\Common\OpenArchive.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\Common\Property.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\Common\PropIDUtils.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
@@ -540,6 +544,14 @@ SOURCE=..\Common\PropIDUtils.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\Common\SetProperties.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\Common\SetProperties.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\Common\SortUtils.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
@@ -220,6 +220,9 @@ int Main2(
|
||||
eo.OverwriteMode = options.OverwriteMode;
|
||||
eo.OutputDir = options.OutputDir;
|
||||
eo.YesToAll = options.YesToAll;
|
||||
#ifdef COMPRESS_MT
|
||||
eo.Properties = options.ExtractProperties;
|
||||
#endif
|
||||
HRESULT result = DecompressArchives(
|
||||
options.ArchivePathsSorted,
|
||||
options.ArchivePathsFullSorted,
|
||||
|
||||
@@ -131,7 +131,7 @@ HRESULT CUpdateCallbackConsole::GetStream(const wchar_t *name, bool isAnti)
|
||||
m_PercentPrinter.PrintString("Anti item ");
|
||||
else
|
||||
m_PercentPrinter.PrintString("Compressing ");
|
||||
if (wcslen(name) == 0)
|
||||
if (name[0] == 0)
|
||||
name = kEmptyFileAlias;
|
||||
m_PercentPrinter.PrintString(name);
|
||||
if (EnablePercents)
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
PROG = 7z.exe
|
||||
LIBS = $(LIBS) user32.lib oleaut32.lib advapi32.lib
|
||||
CFLAGS = $(CFLAGS) -I ../../../
|
||||
CFLAGS = $(CFLAGS) -I ../../../ -DCOMPRESS_MT
|
||||
|
||||
CONSOLE_OBJS = \
|
||||
$O\ConsoleClose.obj \
|
||||
@@ -56,6 +56,7 @@ UI_COMMON_OBJS = \
|
||||
$O\ExtractingFilePath.obj \
|
||||
$O\OpenArchive.obj \
|
||||
$O\PropIDUtils.obj \
|
||||
$O\SetProperties.obj \
|
||||
$O\SortUtils.obj \
|
||||
$O\TempFiles.obj \
|
||||
$O\Update.obj \
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
#include "Windows/FileDir.h"
|
||||
#include "Windows/FileName.h"
|
||||
#include "Windows/ResourceString.h"
|
||||
#include "Windows/System.h"
|
||||
|
||||
#include "../../FileManager/HelpUtils.h"
|
||||
#include "../../FileManager/SplitUtils.h"
|
||||
@@ -178,9 +179,9 @@ static const CFormatInfo g_Formats[] =
|
||||
},
|
||||
{
|
||||
L"Zip",
|
||||
(1 << 0) | (1 << 5) | (1 << 7) | (1 << 9),
|
||||
(1 << 0) | (1 << 1) | (1 << 3) | (1 << 5) | (1 << 7) | (1 << 9),
|
||||
g_ZipMethods, MY_SIZE_OF_ARRAY(g_ZipMethods) ,
|
||||
false, false, false, false, true, false
|
||||
false, false, true, false, true, false
|
||||
},
|
||||
{
|
||||
L"GZip",
|
||||
@@ -190,10 +191,10 @@ static const CFormatInfo g_Formats[] =
|
||||
},
|
||||
{
|
||||
L"BZip2",
|
||||
(1 << 5) | (1 << 7) | (1 << 9),
|
||||
(1 << 1) | (1 << 3) | (1 << 5) | (1 << 7) | (1 << 9),
|
||||
g_BZip2Methods,
|
||||
MY_SIZE_OF_ARRAY(g_BZip2Methods),
|
||||
false, false, false, false, false
|
||||
false, false, true, false, false
|
||||
},
|
||||
{
|
||||
L"Tar",
|
||||
@@ -211,6 +212,49 @@ static bool IsMethodSupportedBySfx(int methodID)
|
||||
return false;
|
||||
};
|
||||
|
||||
#ifndef _WIN64
|
||||
typedef BOOL (WINAPI *GlobalMemoryStatusExP)(LPMEMORYSTATUSEX lpBuffer);
|
||||
#endif
|
||||
|
||||
static UInt64 GetPhysicalRamSize()
|
||||
{
|
||||
MEMORYSTATUSEX stat;
|
||||
stat.dwLength = sizeof(stat);
|
||||
// return (128 << 20);
|
||||
#ifdef _WIN64
|
||||
if (!::GlobalMemoryStatusEx(&stat))
|
||||
return 0;
|
||||
return stat.ullTotalPhys;
|
||||
#else
|
||||
GlobalMemoryStatusExP globalMemoryStatusEx = (GlobalMemoryStatusExP)
|
||||
::GetProcAddress(::GetModuleHandle(TEXT("kernel32.dll")),
|
||||
"GlobalMemoryStatusEx");
|
||||
if (globalMemoryStatusEx != 0)
|
||||
if (globalMemoryStatusEx(&stat))
|
||||
return stat.ullTotalPhys;
|
||||
{
|
||||
MEMORYSTATUS stat;
|
||||
stat.dwLength = sizeof(stat);
|
||||
GlobalMemoryStatus(&stat);
|
||||
return stat.dwTotalPhys;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
static UInt64 GetMaxRamSizeForProgram()
|
||||
{
|
||||
UInt64 physSize = GetPhysicalRamSize();
|
||||
const UInt64 kMinSysSize = (1 << 24);
|
||||
if (physSize <= kMinSysSize)
|
||||
physSize = 0;
|
||||
else
|
||||
physSize -= kMinSysSize;
|
||||
const UInt64 kMinUseSize = (1 << 25);
|
||||
if (physSize < kMinUseSize)
|
||||
physSize = kMinUseSize;
|
||||
return physSize;
|
||||
}
|
||||
|
||||
bool CCompressDialog::OnInit()
|
||||
{
|
||||
#ifdef LANG
|
||||
@@ -326,9 +370,7 @@ bool CCompressDialog::OnButtonClicked(int buttonID, HWND buttonHWND)
|
||||
|
||||
static bool IsMultiProcessor()
|
||||
{
|
||||
SYSTEM_INFO systemInfo;
|
||||
GetSystemInfo(&systemInfo);
|
||||
return systemInfo.dwNumberOfProcessors > 1;
|
||||
return NSystem::GetNumberOfProcessors() > 1;
|
||||
}
|
||||
|
||||
void CCompressDialog::CheckSFXControlsEnable()
|
||||
@@ -837,6 +879,7 @@ void CCompressDialog::SetDictionary()
|
||||
SetMemoryUsage();
|
||||
return;
|
||||
}
|
||||
const UInt64 maxRamSize = GetMaxRamSizeForProgram();
|
||||
switch (methodID)
|
||||
{
|
||||
case kLZMA:
|
||||
@@ -857,22 +900,29 @@ void CCompressDialog::SetDictionary()
|
||||
}
|
||||
int i;
|
||||
AddDictionarySize(kMinDicSize);
|
||||
m_Dictionary.SetCurSel(0);
|
||||
for (i = 20; i <= 30; i++)
|
||||
for (int j = 0; j < 2; j++)
|
||||
{
|
||||
if (i == 20 && j > 0)
|
||||
continue;
|
||||
UInt32 dictionary = (1 << i) + (j << (i - 1));
|
||||
if (dictionary <=
|
||||
if (dictionary >
|
||||
#ifdef _WIN64
|
||||
(1 << 30)
|
||||
#else
|
||||
(1 << 27)
|
||||
#endif
|
||||
)
|
||||
AddDictionarySize(dictionary);
|
||||
continue;
|
||||
AddDictionarySize(dictionary);
|
||||
UInt64 decomprSize;
|
||||
UInt64 requiredComprSize = GetMemoryUsage(dictionary, false, decomprSize);
|
||||
if (dictionary <= defaultDictionary && requiredComprSize <= maxRamSize)
|
||||
m_Dictionary.SetCurSel(m_Dictionary.GetCount() - 1);
|
||||
}
|
||||
SetNearestSelectComboBox(m_Dictionary, defaultDictionary);
|
||||
|
||||
// SetNearestSelectComboBox(m_Dictionary, defaultDictionary);
|
||||
break;
|
||||
}
|
||||
case kPPMd:
|
||||
@@ -898,6 +948,10 @@ void CCompressDialog::SetDictionary()
|
||||
if (dictionary >= (1 << 31))
|
||||
continue;
|
||||
AddDictionarySize(dictionary);
|
||||
UInt64 decomprSize;
|
||||
UInt64 requiredComprSize = GetMemoryUsage(dictionary, false, decomprSize);
|
||||
if (dictionary <= defaultDictionary && requiredComprSize <= maxRamSize || m_Dictionary.GetCount() == 0)
|
||||
m_Dictionary.SetCurSel(m_Dictionary.GetCount() - 1);
|
||||
}
|
||||
SetNearestSelectComboBox(m_Dictionary, defaultDictionary);
|
||||
break;
|
||||
@@ -916,8 +970,20 @@ void CCompressDialog::SetDictionary()
|
||||
}
|
||||
case kBZip2:
|
||||
{
|
||||
AddDictionarySize(900 << 10);
|
||||
m_Dictionary.SetCurSel(0);
|
||||
UInt32 defaultDictionary;
|
||||
if (level >= 5)
|
||||
defaultDictionary = (900 << 10);
|
||||
else if (level >= 3)
|
||||
defaultDictionary = (500 << 10);
|
||||
else
|
||||
defaultDictionary = (100 << 10);
|
||||
for (int i = 1; i <= 9; i++)
|
||||
{
|
||||
UInt32 dictionary = (i * 100) << 10;
|
||||
AddDictionarySize(dictionary);
|
||||
if (dictionary <= defaultDictionary || m_Dictionary.GetCount() == 0)
|
||||
m_Dictionary.SetCurSel(m_Dictionary.GetCount() - 1);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -1067,10 +1133,9 @@ UInt32 CCompressDialog::GetOrderSpec()
|
||||
return GetOrder();
|
||||
}
|
||||
|
||||
UInt64 CCompressDialog::GetMemoryUsage(UInt64 &decompressMemory)
|
||||
UInt64 CCompressDialog::GetMemoryUsage(UInt32 dictionary, bool isMultiThread, UInt64 &decompressMemory)
|
||||
{
|
||||
decompressMemory = UInt64(Int64(-1));
|
||||
UInt32 dictionary = GetDictionary();
|
||||
int level = GetLevel2();
|
||||
if (level == 0)
|
||||
{
|
||||
@@ -1082,7 +1147,6 @@ UInt64 CCompressDialog::GetMemoryUsage(UInt64 &decompressMemory)
|
||||
const CFormatInfo &fi = g_Formats[GetStaticFormatIndex()];
|
||||
if (fi.Filter && level >= 9)
|
||||
size += (12 << 20) * 2 + (5 << 20);
|
||||
bool isMultiThread = IsMultiThread();
|
||||
switch (GetMethodID())
|
||||
{
|
||||
case kLZMA:
|
||||
@@ -1128,12 +1192,20 @@ UInt64 CCompressDialog::GetMemoryUsage(UInt64 &decompressMemory)
|
||||
case kBZip2:
|
||||
{
|
||||
decompressMemory = (7 << 20);
|
||||
UInt64 memForOneThread = (10 << 20);
|
||||
if (isMultiThread)
|
||||
memForOneThread *= NSystem::GetNumberOfProcessors();
|
||||
return size + (10 << 20);
|
||||
}
|
||||
}
|
||||
return UInt64(Int64(-1));
|
||||
}
|
||||
|
||||
UInt64 CCompressDialog::GetMemoryUsage(UInt64 &decompressMemory)
|
||||
{
|
||||
return GetMemoryUsage(GetDictionary(), IsMultiThread(), decompressMemory);
|
||||
}
|
||||
|
||||
void CCompressDialog::PrintMemUsage(UINT res, UInt64 value)
|
||||
{
|
||||
if (value == (UInt64)Int64(-1))
|
||||
|
||||
@@ -123,6 +123,7 @@ class CCompressDialog: public NWindows::NControl::CModalDialog
|
||||
UInt32 GetOrder();
|
||||
UInt32 GetOrderSpec();
|
||||
|
||||
UInt64 GetMemoryUsage(UInt32 dictionary, bool isMultiThread, UInt64 &decompressMemory);
|
||||
UInt64 GetMemoryUsage(UInt64 &decompressMemory);
|
||||
void PrintMemUsage(UINT res, UInt64 value);
|
||||
void SetMemoryUsage();
|
||||
|
||||
@@ -104,6 +104,9 @@ int Main2()
|
||||
eo.OverwriteMode = options.OverwriteMode;
|
||||
eo.PathMode = options.Command.GetPathMode();
|
||||
eo.TestMode = options.Command.IsTestMode();
|
||||
#ifdef COMPRESS_MT
|
||||
eo.Properties = options.ExtractProperties;
|
||||
#endif
|
||||
|
||||
HRESULT result = ExtractGUI(
|
||||
options.ArchivePathsSorted,
|
||||
|
||||
@@ -45,7 +45,7 @@ RSC=rc.exe
|
||||
# PROP Ignore_Export_Lib 0
|
||||
# PROP Target_Dir ""
|
||||
# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /Yu"stdafx.h" /FD /c
|
||||
# ADD CPP /nologo /Gz /MD /W3 /GX /O1 /I "..\..\..\\" /D "NDEBUG" /D "_MBCS" /D "WIN32" /D "_WINDOWS" /D "LANG" /Yu"stdafx.h" /FD /c
|
||||
# ADD CPP /nologo /Gz /MD /W3 /GX /O1 /I "..\..\..\\" /D "NDEBUG" /D "_MBCS" /D "WIN32" /D "_WINDOWS" /D "LANG" /D "COMPRESS_MT" /Yu"stdafx.h" /FD /c
|
||||
# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
|
||||
# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
|
||||
# ADD BASE RSC /l 0x419 /d "NDEBUG"
|
||||
@@ -72,7 +72,7 @@ LINK32=link.exe
|
||||
# PROP Ignore_Export_Lib 0
|
||||
# PROP Target_Dir ""
|
||||
# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /Yu"stdafx.h" /FD /GZ /c
|
||||
# ADD CPP /nologo /Gz /MDd /W3 /Gm /GX /ZI /Od /I "..\..\..\\" /D "_DEBUG" /D "_MBCS" /D "WIN32" /D "_WINDOWS" /D "LANG" /Yu"stdafx.h" /FD /GZ /c
|
||||
# ADD CPP /nologo /Gz /MDd /W3 /Gm /GX /ZI /Od /I "..\..\..\\" /D "_DEBUG" /D "_MBCS" /D "WIN32" /D "_WINDOWS" /D "LANG" /D "COMPRESS_MT" /Yu"stdafx.h" /FD /GZ /c
|
||||
# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32
|
||||
# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32
|
||||
# ADD BASE RSC /l 0x419 /d "_DEBUG"
|
||||
@@ -99,7 +99,7 @@ LINK32=link.exe
|
||||
# PROP Ignore_Export_Lib 0
|
||||
# PROP Target_Dir ""
|
||||
# ADD BASE CPP /nologo /MD /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /Yu"stdafx.h" /FD /c
|
||||
# ADD CPP /nologo /Gz /MD /W3 /GX /O1 /I "..\..\..\\" /D "NDEBUG" /D "_UNICODE" /D "UNICODE" /D "WIN32" /D "_WINDOWS" /D "LANG" /Yu"stdafx.h" /FD /c
|
||||
# ADD CPP /nologo /Gz /MD /W3 /GX /O1 /I "..\..\..\\" /D "NDEBUG" /D "_UNICODE" /D "UNICODE" /D "WIN32" /D "_WINDOWS" /D "LANG" /D "COMPRESS_MT" /Yu"stdafx.h" /FD /c
|
||||
# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
|
||||
# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
|
||||
# ADD BASE RSC /l 0x419 /d "NDEBUG"
|
||||
@@ -127,7 +127,7 @@ LINK32=link.exe
|
||||
# PROP Ignore_Export_Lib 0
|
||||
# PROP Target_Dir ""
|
||||
# ADD BASE CPP /nologo /MDd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /Yu"stdafx.h" /FD /GZ /c
|
||||
# ADD CPP /nologo /Gz /MDd /W3 /Gm /GX /ZI /Od /I "..\..\..\\" /D "_DEBUG" /D "_UNICODE" /D "UNICODE" /D "WIN32" /D "_WINDOWS" /D "LANG" /Yu"stdafx.h" /FD /GZ /c
|
||||
# ADD CPP /nologo /Gz /MDd /W3 /Gm /GX /ZI /Od /I "..\..\..\\" /D "_DEBUG" /D "_UNICODE" /D "UNICODE" /D "WIN32" /D "_WINDOWS" /D "LANG" /D "COMPRESS_MT" /Yu"stdafx.h" /FD /GZ /c
|
||||
# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32
|
||||
# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32
|
||||
# ADD BASE RSC /l 0x419 /d "_DEBUG"
|
||||
@@ -549,6 +549,10 @@ SOURCE=..\Common\OpenArchive.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\Common\Property.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\Common\PropIDUtils.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
@@ -557,6 +561,14 @@ SOURCE=..\Common\PropIDUtils.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\Common\SetProperties.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\Common\SetProperties.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\Common\SortUtils.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
PROG = 7zG.exe
|
||||
LIBS = $(LIBS) user32.lib advapi32.lib oleaut32.lib shell32.lib comctl32.lib htmlhelp.lib ole32.lib comdlg32.lib
|
||||
CFLAGS = $(CFLAGS) -I ../../../ -DLANG
|
||||
CFLAGS = $(CFLAGS) -I ../../../ -DLANG -DCOMPRESS_MT
|
||||
|
||||
GUI_OBJS = \
|
||||
$O\CompressDialog.obj \
|
||||
@@ -65,6 +65,7 @@ UI_COMMON_OBJS = \
|
||||
$O\ExtractingFilePath.obj \
|
||||
$O\OpenArchive.obj \
|
||||
$O\PropIDUtils.obj \
|
||||
$O\SetProperties.obj \
|
||||
$O\SortUtils.obj \
|
||||
$O\TempFiles.obj \
|
||||
$O\Update.obj \
|
||||
|
||||
@@ -15,8 +15,7 @@ static void RemoveQuote(UString &s)
|
||||
s = s.Mid(1, s.Length() - 2);
|
||||
}
|
||||
|
||||
bool ReadNamesFromListFile(LPCTSTR fileName, UStringVector &resultStrings,
|
||||
UINT codePage)
|
||||
bool ReadNamesFromListFile(LPCTSTR fileName, UStringVector &resultStrings, UINT codePage)
|
||||
{
|
||||
CStdInStream file;
|
||||
if (!file.Open(fileName))
|
||||
@@ -32,6 +31,12 @@ bool ReadNamesFromListFile(LPCTSTR fileName, UStringVector &resultStrings,
|
||||
}
|
||||
else
|
||||
u = MultiByteToUnicodeString(s, codePage);
|
||||
if (!u.IsEmpty())
|
||||
{
|
||||
if (u[0] == 0xFEFF)
|
||||
u.Delete(0);
|
||||
}
|
||||
|
||||
UString t;
|
||||
for(int i = 0; i < u.Length(); i++)
|
||||
{
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
;Defines
|
||||
|
||||
!define VERSION_MAJOR 4
|
||||
!define VERSION_MINOR 33
|
||||
!define VERSION_MINOR 34
|
||||
!define VERSION_POSTFIX_FULL " beta"
|
||||
!ifdef WIN64
|
||||
!ifdef IA64
|
||||
@@ -14,7 +14,7 @@
|
||||
!define VERSION_SYS_POSTFIX_FULL ""
|
||||
!endif
|
||||
!define NAME_FULL "7-Zip ${VERSION_MAJOR}.${VERSION_MINOR}${VERSION_POSTFIX_FULL}${VERSION_SYS_POSTFIX_FULL}"
|
||||
!define VERSION_POSTFIX ""
|
||||
!define VERSION_POSTFIX "b"
|
||||
!ifdef WIN64
|
||||
!ifdef IA64
|
||||
!define VERSION_SYS_POSTFIX "-ia64"
|
||||
@@ -225,6 +225,7 @@ Section
|
||||
File ru.txt
|
||||
File sk.txt
|
||||
File sl.txt
|
||||
File sq.txt
|
||||
File sr.txt
|
||||
File sv.txt
|
||||
File ta.txt
|
||||
@@ -428,6 +429,7 @@ Section "Uninstall"
|
||||
Delete $INSTDIR\Lang\ru.txt
|
||||
Delete $INSTDIR\Lang\sk.txt
|
||||
Delete $INSTDIR\Lang\sl.txt
|
||||
Delete $INSTDIR\Lang\sq.txt
|
||||
Delete $INSTDIR\Lang\sr.txt
|
||||
Delete $INSTDIR\Lang\sv.txt
|
||||
Delete $INSTDIR\Lang\ta.txt
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
LZMA SDK 4.33
|
||||
LZMA SDK 4.34
|
||||
-------------
|
||||
|
||||
LZMA SDK 4.33 Copyright (C) 1999-2006 Igor Pavlov
|
||||
LZMA SDK 4.34 Copyright (C) 1999-2006 Igor Pavlov
|
||||
|
||||
LZMA SDK provides the documentation, samples, header files, libraries,
|
||||
and tools you need to develop applications that use LZMA compression.
|
||||
|
||||
21
Windows/System.h
Executable file
21
Windows/System.h
Executable file
@@ -0,0 +1,21 @@
|
||||
// Windows/System.h
|
||||
|
||||
#ifndef __WINDOWS_SYSTEM_H
|
||||
#define __WINDOWS_SYSTEM_H
|
||||
|
||||
#include "..\Common\Types.h"
|
||||
|
||||
namespace NWindows {
|
||||
namespace NSystem {
|
||||
|
||||
static UInt32 GetNumberOfProcessors()
|
||||
{
|
||||
SYSTEM_INFO systemInfo;
|
||||
GetSystemInfo(&systemInfo);
|
||||
return (UInt32)systemInfo.dwNumberOfProcessors;
|
||||
}
|
||||
|
||||
|
||||
}}
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user