4.34 beta

This commit is contained in:
Igor Pavlov
2006-03-01 00:00:00 +00:00
committed by Kornel Lesiński
parent 02516d3fce
commit 0f60a4933b
77 changed files with 2173 additions and 832 deletions

View File

@@ -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"

View File

@@ -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
{}
};
}}

View File

@@ -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++;

View File

@@ -60,6 +60,9 @@ public:
#ifndef _NO_CRYPTO
, ICryptoGetTextPassword *getTextPasswordSpec
#endif
#ifdef COMPRESS_MT
, bool mtMode, UInt32 numThreads
#endif
);
};

View File

@@ -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;
}

View File

@@ -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)

View File

@@ -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
}}

View File

@@ -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;

View File

@@ -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);
}

View File

@@ -880,6 +880,9 @@ HRESULT CInArchive::ReadAndDecodePackedStreams(UInt64 baseOffset,
#ifndef _NO_CRYPTO
, getTextPassword
#endif
#ifdef COMPRESS_MT
, false, 1
#endif
);
RINOK(result);

View File

@@ -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 \

View File

@@ -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"

View File

@@ -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);

View File

@@ -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(

View File

@@ -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;

View File

@@ -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));

View File

@@ -12,7 +12,11 @@ HRESULT UpdateArchive(
UInt64 unpackSize,
ISequentialOutStream *outStream,
int indexInClient,
UInt32 dictionary,
UInt32 numPasses,
#ifdef COMPRESS_MT
UInt32 numThreads,
#endif
IArchiveUpdateCallback *updateCallback);
}}

View File

@@ -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 \

View 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;
}

View 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

View File

@@ -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

View 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;
}
};

View File

@@ -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;

View File

@@ -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));

View File

@@ -15,6 +15,8 @@ struct CCompressionMethodMode
{
UInt32 NumPasses;
UInt32 NumFastBytes;
bool NumMatchFinderCyclesDefined;
UInt32 NumMatchFinderCycles;
};
HRESULT UpdateArchive(IInStream *inStream,

View File

@@ -32,6 +32,7 @@ AR_COMMON_OBJS = \
$O\CodecsPath.obj \
$O\InStreamWithCRC.obj \
$O\OutStreamWithCRC.obj \
$O\ParseProperties.obj \
OBJS = \
$O\StdAfx.obj \

View File

@@ -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"

View File

@@ -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)

View File

@@ -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) {}
};
}}

View File

@@ -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

View File

@@ -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
}
};

View File

@@ -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;

View File

@@ -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 \

View File

@@ -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

View 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 = \

View File

@@ -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"

View File

@@ -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 = \

View File

@@ -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"

View File

@@ -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 = \

View File

@@ -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

View File

@@ -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
}}

View File

@@ -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
};
}}

View File

@@ -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
}}

View File

@@ -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
};
}}

View File

@@ -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

View File

@@ -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;
}

View File

@@ -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);

View File

@@ -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; }
};
}

View File

@@ -24,4 +24,9 @@ struct IMatchFinder: public IInWindowStream
STDMETHOD(Skip)(UInt32 num) PURE;
};
struct IMatchFinderSetNumPasses
{
virtual void SetNumPasses(UInt32 numPasses) PURE;
};
#endif

View File

@@ -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();

View File

@@ -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);

View File

@@ -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);

View File

@@ -25,6 +25,7 @@
22 ICompressSetDecoderProperties2
23 ICompressWriteCoderProperties
24 ICompressGetInStreamProcessedSize
25 ICompressSetCoderMt
30 ICompressGetSubStreamSize
31 ICompressSetInStream
32 ICompressSetOutStream

View File

@@ -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;

View File

@@ -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

View File

@@ -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;

View File

@@ -68,6 +68,7 @@ struct CArchiveCommandLineOptions
NExtract::NOverwriteMode::EEnum OverwriteMode;
UStringVector ArchivePathsSorted;
UStringVector ArchivePathsFullSorted;
CObjectVector<CProperty> ExtractProperties;
CUpdateOptions UpdateOptions;
bool EnablePercents;

View File

@@ -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);

View File

@@ -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
View File

@@ -0,0 +1,14 @@
// Property.h
#ifndef __PROPERTY_H
#define __PROPERTY_H
#include "Common/String.h"
struct CProperty
{
UString Name;
UString Value;
};
#endif

View 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
View 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

View File

@@ -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)
{

View File

@@ -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),

View File

@@ -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

View 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,

View File

@@ -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)

View File

@@ -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 \

View File

@@ -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))

View File

@@ -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();

View File

@@ -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,

View File

@@ -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

View 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 \

View File

@@ -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++)
{

View File

@@ -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

View File

@@ -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
View 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