Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/kornelski/7z.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIgor Pavlov <ipavlov@users.sourceforge.net>2006-03-01 03:00:00 +0300
committerKornel LesiƄski <kornel@geekhood.net>2016-05-28 02:15:46 +0300
commit0f60a4933b33cf5061a73ce39d0dd49e274b8a26 (patch)
tree172f103c5f55f0f56f4164d0ad391c74038f34af
parent02516d3fce853bdb249826d12f08b7b4e50beddc (diff)
4.34 beta
-rwxr-xr-x7zip/Archive/7z/7z.dsp16
-rwxr-xr-x7zip/Archive/7z/7zCompressionMode.h10
-rwxr-xr-x7zip/Archive/7z/7zDecode.cpp79
-rwxr-xr-x7zip/Archive/7z/7zDecode.h3
-rwxr-xr-x7zip/Archive/7z/7zEncode.cpp54
-rwxr-xr-x7zip/Archive/7z/7zExtract.cpp3
-rwxr-xr-x7zip/Archive/7z/7zHandler.cpp46
-rwxr-xr-x7zip/Archive/7z/7zHandler.h70
-rwxr-xr-x7zip/Archive/7z/7zHandlerOut.cpp397
-rwxr-xr-x7zip/Archive/7z/7zIn.cpp3
-rwxr-xr-x7zip/Archive/7z/makefile3
-rwxr-xr-x7zip/Archive/BZip2/BZip2.dsp12
-rwxr-xr-x7zip/Archive/BZip2/BZip2Handler.cpp10
-rwxr-xr-x7zip/Archive/BZip2/BZip2Handler.h19
-rwxr-xr-x7zip/Archive/BZip2/BZip2HandlerOut.cpp114
-rwxr-xr-x7zip/Archive/BZip2/BZip2Update.cpp26
-rwxr-xr-x7zip/Archive/BZip2/BZip2Update.h4
-rwxr-xr-x7zip/Archive/BZip2/makefile3
-rwxr-xr-x7zip/Archive/Common/ParseProperties.cpp171
-rwxr-xr-x7zip/Archive/Common/ParseProperties.h17
-rwxr-xr-x7zip/Archive/GZip/GZip.dsp8
-rwxr-xr-x7zip/Archive/GZip/GZipHandler.h4
-rwxr-xr-x7zip/Archive/GZip/GZipHandlerOut.cpp67
-rwxr-xr-x7zip/Archive/GZip/GZipUpdate.cpp24
-rwxr-xr-x7zip/Archive/GZip/GZipUpdate.h2
-rwxr-xr-x7zip/Archive/GZip/makefile1
-rwxr-xr-x7zip/Archive/Zip/Zip.dsp12
-rwxr-xr-x7zip/Archive/Zip/ZipAddCommon.cpp45
-rwxr-xr-x7zip/Archive/Zip/ZipCompressionMode.h7
-rwxr-xr-x7zip/Archive/Zip/ZipHandler.cpp22
-rwxr-xr-x7zip/Archive/Zip/ZipHandler.h22
-rwxr-xr-x7zip/Archive/Zip/ZipHandlerOut.cpp142
-rwxr-xr-x7zip/Archive/Zip/makefile3
-rwxr-xr-x7zip/Bundles/Alone/Alone.dsp24
-rwxr-xr-x7zip/Bundles/Alone/makefile4
-rwxr-xr-x7zip/Bundles/Format7z/Format7z.dsp12
-rwxr-xr-x7zip/Bundles/Format7z/makefile3
-rwxr-xr-x7zip/Bundles/Format7zExtract/Format7z.dsp12
-rwxr-xr-x7zip/Bundles/Format7zExtract/makefile3
-rwxr-xr-x7zip/Compress/BZip2/BZip2.dsp24
-rwxr-xr-x7zip/Compress/BZip2/BZip2Decoder.cpp320
-rwxr-xr-x7zip/Compress/BZip2/BZip2Decoder.h88
-rwxr-xr-x7zip/Compress/BZip2/BZip2Encoder.cpp356
-rwxr-xr-x7zip/Compress/BZip2/BZip2Encoder.h131
-rwxr-xr-x7zip/Compress/BZip2/makefile8
-rwxr-xr-x7zip/Compress/Deflate/DeflateEncoder.cpp27
-rwxr-xr-x7zip/Compress/Deflate/DeflateEncoder.h3
-rwxr-xr-x7zip/Compress/LZ/BinTree/BinTree.h5
-rwxr-xr-x7zip/Compress/LZ/IMatchFinder.h5
-rwxr-xr-x7zip/Compress/LZMA/LZMAEncoder.cpp64
-rwxr-xr-x7zip/Compress/LZMA/LZMAEncoder.h12
-rwxr-xr-x7zip/Compress/LZMA_Alone/LzmaAlone.cpp27
-rwxr-xr-x7zip/Guid.txt1
-rwxr-xr-x7zip/ICoder.h7
-rwxr-xr-x7zip/MyVersion.h8
-rwxr-xr-x7zip/UI/Common/ArchiveCommandLine.cpp79
-rwxr-xr-x7zip/UI/Common/ArchiveCommandLine.h1
-rwxr-xr-x7zip/UI/Common/Extract.cpp6
-rwxr-xr-x7zip/UI/Common/Extract.h4
-rwxr-xr-x7zip/UI/Common/Property.h14
-rwxr-xr-x7zip/UI/Common/SetProperties.cpp65
-rwxr-xr-x7zip/UI/Common/SetProperties.h10
-rwxr-xr-x7zip/UI/Common/Update.cpp45
-rwxr-xr-x7zip/UI/Common/Update.h9
-rwxr-xr-x7zip/UI/Console/Console.dsp20
-rwxr-xr-x7zip/UI/Console/Main.cpp3
-rwxr-xr-x7zip/UI/Console/UpdateCallbackConsole.cpp2
-rwxr-xr-x7zip/UI/Console/makefile3
-rwxr-xr-x7zip/UI/GUI/CompressDialog.cpp102
-rwxr-xr-x7zip/UI/GUI/CompressDialog.h1
-rwxr-xr-x7zip/UI/GUI/GUI.cpp3
-rwxr-xr-x7zip/UI/GUI/GUI.dsp20
-rwxr-xr-x7zip/UI/GUI/makefile3
-rwxr-xr-xCommon/ListFileUtils.cpp9
-rwxr-xr-xDOC/7zip.nsi6
-rwxr-xr-xDOC/lzma.txt4
-rwxr-xr-xWindows/System.h21
77 files changed, 2167 insertions, 826 deletions
diff --git a/7zip/Archive/7z/7z.dsp b/7zip/Archive/7z/7z.dsp
index 83e48cef..e57115ef 100755
--- a/7zip/Archive/7z/7z.dsp
+++ b/7zip/Archive/7z/7z.dsp
@@ -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"
diff --git a/7zip/Archive/7z/7zCompressionMode.h b/7zip/Archive/7z/7zCompressionMode.h
index 1df324b6..fe54e8a6 100755
--- a/7zip/Archive/7z/7zCompressionMode.h
+++ b/7zip/Archive/7z/7zCompressionMode.h
@@ -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
+ {}
};
}}
diff --git a/7zip/Archive/7z/7zDecode.cpp b/7zip/Archive/7z/7zDecode.cpp
index 2deffc12..7621282a 100755
--- a/7zip/Archive/7z/7zDecode.cpp
+++ b/7zip/Archive/7z/7zDecode.cpp
@@ -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;
- #ifndef _NO_CRYPTO
- CMyComPtr<ICryptoSetPassword> cryptoSetPassword;
- result = _decoders[coderIndex].QueryInterface(
- IID_ICryptoSetPassword, &cryptoSetPassword);
+ #ifdef COMPRESS_MT
+ if (mtMode)
+ {
+ CMyComPtr<ICompressSetCoderMt> setCoderMt;
+ decoder.QueryInterface(IID_ICompressSetCoderMt, &setCoderMt);
+ if (setCoderMt)
+ {
+ RINOK(setCoderMt->SetNumberOfThreads(numThreads));
+ }
+ }
+ #endif
- if (result == S_OK)
+ #ifndef _NO_CRYPTO
{
- 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++;
diff --git a/7zip/Archive/7z/7zDecode.h b/7zip/Archive/7z/7zDecode.h
index 352f89f9..0e510b5b 100755
--- a/7zip/Archive/7z/7zDecode.h
+++ b/7zip/Archive/7z/7zDecode.h
@@ -60,6 +60,9 @@ public:
#ifndef _NO_CRYPTO
, ICryptoGetTextPassword *getTextPasswordSpec
#endif
+ #ifdef COMPRESS_MT
+ , bool mtMode, UInt32 numThreads
+ #endif
);
};
diff --git a/7zip/Archive/7z/7zEncode.cpp b/7zip/Archive/7z/7zEncode.cpp
index a4fb7159..b246d2ac 100755
--- a/7zip/Archive/7z/7zEncode.cpp
+++ b/7zip/Archive/7z/7zEncode.cpp
@@ -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;
}
diff --git a/7zip/Archive/7z/7zExtract.cpp b/7zip/Archive/7z/7zExtract.cpp
index bf827dc0..0fb77623 100755
--- a/7zip/Archive/7z/7zExtract.cpp
+++ b/7zip/Archive/7z/7zExtract.cpp
@@ -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)
diff --git a/7zip/Archive/7z/7zHandler.cpp b/7zip/Archive/7z/7zHandler.cpp
index 45ca1abe..ac1e2405 100755
--- a/7zip/Archive/7z/7zHandler.cpp
+++ b/7zip/Archive/7z/7zHandler.cpp
@@ -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
+
}}
diff --git a/7zip/Archive/7z/7zHandler.h b/7zip/Archive/7z/7zHandler.h
index 0e3b5434..99b63782 100755
--- a/7zip/Archive/7z/7zHandler.h
+++ b/7zip/Archive/7z/7zHandler.h
@@ -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";
-
- _defaultBZip2Passes = 1;
-
- _defaultPpmdMemSize = (1 << 24);
- _defaultPpmdOrder = 6;
+ _defaultDicSize =
+ _defaultAlgorithm =
+ _defaultFastBytes =
+ _defaultPasses =
+ _defaultPpmdMemSize =
+ _defaultPpmdOrder = 0xFFFFFFFF;
+ _defaultMatchFinder.Empty();
- _defaultDeflateFastBytes = 32;
- _defaultDeflatePasses = 1;
_level = 5;
_autoFilter = true;
diff --git a/7zip/Archive/7z/7zHandlerOut.cpp b/7zip/Archive/7z/7zHandlerOut.cpp
index a108464d..6a959513 100755
--- a/7zip/Archive/7z/7zHandlerOut.cpp
+++ b/7zip/Archive/7z/7zHandlerOut.cpp
@@ -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);
}
diff --git a/7zip/Archive/7z/7zIn.cpp b/7zip/Archive/7z/7zIn.cpp
index c35a77ce..cd7fea3a 100755
--- a/7zip/Archive/7z/7zIn.cpp
+++ b/7zip/Archive/7z/7zIn.cpp
@@ -880,6 +880,9 @@ HRESULT CInArchive::ReadAndDecodePackedStreams(UInt64 baseOffset,
#ifndef _NO_CRYPTO
, getTextPassword
#endif
+ #ifdef COMPRESS_MT
+ , false, 1
+ #endif
);
RINOK(result);
diff --git a/7zip/Archive/7z/makefile b/7zip/Archive/7z/makefile
index 97bbbaaf..06bf2f37 100755
--- a/7zip/Archive/7z/makefile
+++ b/7zip/Archive/7z/makefile
@@ -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 \
diff --git a/7zip/Archive/BZip2/BZip2.dsp b/7zip/Archive/BZip2/BZip2.dsp
index ccae8d3b..1d14aedb 100755
--- a/7zip/Archive/BZip2/BZip2.dsp
+++ b/7zip/Archive/BZip2/BZip2.dsp
@@ -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"
diff --git a/7zip/Archive/BZip2/BZip2Handler.cpp b/7zip/Archive/BZip2/BZip2Handler.cpp
index 88e5da1f..a2b5a797 100755
--- a/7zip/Archive/BZip2/BZip2Handler.cpp
+++ b/7zip/Archive/BZip2/BZip2Handler.cpp
@@ -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);
diff --git a/7zip/Archive/BZip2/BZip2Handler.h b/7zip/Archive/BZip2/BZip2Handler.h
index 8577d039..7977334e 100755
--- a/7zip/Archive/BZip2/BZip2Handler.h
+++ b/7zip/Archive/BZip2/BZip2Handler.h
@@ -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(
diff --git a/7zip/Archive/BZip2/BZip2HandlerOut.cpp b/7zip/Archive/BZip2/BZip2HandlerOut.cpp
index 509b82a6..f1eb43e0 100755
--- a/7zip/Archive/BZip2/BZip2HandlerOut.cpp
+++ b/7zip/Archive/BZip2/BZip2HandlerOut.cpp
@@ -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;
diff --git a/7zip/Archive/BZip2/BZip2Update.cpp b/7zip/Archive/BZip2/BZip2Update.cpp
index 114c79d1..d9bdf963 100755
--- a/7zip/Archive/BZip2/BZip2Update.cpp
+++ b/7zip/Archive/BZip2/BZip2Update.cpp
@@ -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));
diff --git a/7zip/Archive/BZip2/BZip2Update.h b/7zip/Archive/BZip2/BZip2Update.h
index 5f40d752..ce20e323 100755
--- a/7zip/Archive/BZip2/BZip2Update.h
+++ b/7zip/Archive/BZip2/BZip2Update.h
@@ -12,7 +12,11 @@ HRESULT UpdateArchive(
UInt64 unpackSize,
ISequentialOutStream *outStream,
int indexInClient,
+ UInt32 dictionary,
UInt32 numPasses,
+ #ifdef COMPRESS_MT
+ UInt32 numThreads,
+ #endif
IArchiveUpdateCallback *updateCallback);
}}
diff --git a/7zip/Archive/BZip2/makefile b/7zip/Archive/BZip2/makefile
index 85095122..20f20bdb 100755
--- a/7zip/Archive/BZip2/makefile
+++ b/7zip/Archive/BZip2/makefile
@@ -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 \
diff --git a/7zip/Archive/Common/ParseProperties.cpp b/7zip/Archive/Common/ParseProperties.cpp
new file mode 100755
index 00000000..9866d900
--- /dev/null
+++ b/7zip/Archive/Common/ParseProperties.cpp
@@ -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;
+}
diff --git a/7zip/Archive/Common/ParseProperties.h b/7zip/Archive/Common/ParseProperties.h
new file mode 100755
index 00000000..e6db316b
--- /dev/null
+++ b/7zip/Archive/Common/ParseProperties.h
@@ -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
diff --git a/7zip/Archive/GZip/GZip.dsp b/7zip/Archive/GZip/GZip.dsp
index 4507e833..3af06b46 100755
--- a/7zip/Archive/GZip/GZip.dsp
+++ b/7zip/Archive/GZip/GZip.dsp
@@ -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
diff --git a/7zip/Archive/GZip/GZipHandler.h b/7zip/Archive/GZip/GZipHandler.h
index 4c8f17ef..9af7e4a4 100755
--- a/7zip/Archive/GZip/GZipHandler.h
+++ b/7zip/Archive/GZip/GZipHandler.h
@@ -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;
}
};
diff --git a/7zip/Archive/GZip/GZipHandlerOut.cpp b/7zip/Archive/GZip/GZipHandlerOut.cpp
index f3534fba..c58fcb52 100755
--- a/7zip/Archive/GZip/GZipHandlerOut.cpp
+++ b/7zip/Archive/GZip/GZipHandlerOut.cpp
@@ -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;
diff --git a/7zip/Archive/GZip/GZipUpdate.cpp b/7zip/Archive/GZip/GZipUpdate.cpp
index 4ce178fd..9bc54522 100755
--- a/7zip/Archive/GZip/GZipUpdate.cpp
+++ b/7zip/Archive/GZip/GZipUpdate.cpp
@@ -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));
diff --git a/7zip/Archive/GZip/GZipUpdate.h b/7zip/Archive/GZip/GZipUpdate.h
index 7c660087..c06e8a4c 100755
--- a/7zip/Archive/GZip/GZipUpdate.h
+++ b/7zip/Archive/GZip/GZipUpdate.h
@@ -15,6 +15,8 @@ struct CCompressionMethodMode
{
UInt32 NumPasses;
UInt32 NumFastBytes;
+ bool NumMatchFinderCyclesDefined;
+ UInt32 NumMatchFinderCycles;
};
HRESULT UpdateArchive(IInStream *inStream,
diff --git a/7zip/Archive/GZip/makefile b/7zip/Archive/GZip/makefile
index 06d8908d..abc3f1e4 100755
--- a/7zip/Archive/GZip/makefile
+++ b/7zip/Archive/GZip/makefile
@@ -32,6 +32,7 @@ AR_COMMON_OBJS = \
$O\CodecsPath.obj \
$O\InStreamWithCRC.obj \
$O\OutStreamWithCRC.obj \
+ $O\ParseProperties.obj \
OBJS = \
$O\StdAfx.obj \
diff --git a/7zip/Archive/Zip/Zip.dsp b/7zip/Archive/Zip/Zip.dsp
index 0bfb5fd1..00ef44e6 100755
--- a/7zip/Archive/Zip/Zip.dsp
+++ b/7zip/Archive/Zip/Zip.dsp
@@ -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"
diff --git a/7zip/Archive/Zip/ZipAddCommon.cpp b/7zip/Archive/Zip/ZipAddCommon.cpp
index 84cada5b..c2b79212 100755
--- a/7zip/Archive/Zip/ZipAddCommon.cpp
+++ b/7zip/Archive/Zip/ZipAddCommon.cpp
@@ -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)
diff --git a/7zip/Archive/Zip/ZipCompressionMode.h b/7zip/Archive/Zip/ZipCompressionMode.h
index 2ef91460..83b8fe44 100755
--- a/7zip/Archive/Zip/ZipCompressionMode.h
+++ b/7zip/Archive/Zip/ZipCompressionMode.h
@@ -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) {}
};
}}
diff --git a/7zip/Archive/Zip/ZipHandler.cpp b/7zip/Archive/Zip/ZipHandler.cpp
index 6b6c03c9..149ed666 100755
--- a/7zip/Archive/Zip/ZipHandler.cpp
+++ b/7zip/Archive/Zip/ZipHandler.cpp
@@ -539,12 +539,26 @@ 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)
diff --git a/7zip/Archive/Zip/ZipHandler.h b/7zip/Archive/Zip/ZipHandler.h
index bb879436..94aae211 100755
--- a/7zip/Archive/Zip/ZipHandler.h
+++ b/7zip/Archive/Zip/ZipHandler.h
@@ -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
}
};
diff --git a/7zip/Archive/Zip/ZipHandlerOut.cpp b/7zip/Archive/Zip/ZipHandlerOut.cpp
index a61417b2..310233a9 100755
--- a/7zip/Archive/Zip/ZipHandlerOut.cpp
+++ b/7zip/Archive/Zip/ZipHandlerOut.cpp
@@ -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)
+ options.DicSize = m_DicSize;
+ options.NumFastBytes = m_NumFastBytes;
+ options.NumMatchFinderCycles = m_NumMatchFinderCycles;
+ options.NumMatchFinderCyclesDefined = m_NumMatchFinderCyclesDefined;
+ #ifdef COMPRESS_MT
+ options.NumThreads = _numThreads;
+ #endif
+ if (isDeflate)
{
- if (isDeflate)
- options.NumPasses = (level >= 9 ? kNumDeflatePassesX9 :
- (level >= 7 ? kNumDeflatePassesX7 : kNumDeflatePassesX1));
- else if (isBZip2)
- options.NumPasses = (level >= 9 ? kNumBZip2PassesX9 :
- (level >= 7 ? kNumBZip2PassesX7 : kNumBZip2PassesX1));
+ 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));
}
-
- options.NumFastBytes = m_NumFastBytes;
- if (options.NumFastBytes == 0xFFFFFFFF)
+ if (isBZip2)
{
- if (isDeflate)
- options.NumFastBytes = (level >= 9 ? kNumFastBytesX9 : (level >= 7 ? kNumFastBytesX7 : kNumFastBytesX1));
+ 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;
+
+ const PROPVARIANT &prop = values[i];
- if (name[0] == 'X')
+ 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 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
+ else
return E_INVALIDARG;
}
return S_OK;
diff --git a/7zip/Archive/Zip/makefile b/7zip/Archive/Zip/makefile
index 4d59fb0c..cb50a884 100755
--- a/7zip/Archive/Zip/makefile
+++ b/7zip/Archive/Zip/makefile
@@ -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 \
diff --git a/7zip/Bundles/Alone/Alone.dsp b/7zip/Bundles/Alone/Alone.dsp
index edef69bc..4ad83675 100755
--- a/7zip/Bundles/Alone/Alone.dsp
+++ b/7zip/Bundles/Alone/Alone.dsp
@@ -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
diff --git a/7zip/Bundles/Alone/makefile b/7zip/Bundles/Alone/makefile
index 0a4137d5..72832de1 100755
--- a/7zip/Bundles/Alone/makefile
+++ b/7zip/Bundles/Alone/makefile
@@ -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 = \
diff --git a/7zip/Bundles/Format7z/Format7z.dsp b/7zip/Bundles/Format7z/Format7z.dsp
index 597f2bd7..74b8b25b 100755
--- a/7zip/Bundles/Format7z/Format7z.dsp
+++ b/7zip/Bundles/Format7z/Format7z.dsp
@@ -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"
diff --git a/7zip/Bundles/Format7z/makefile b/7zip/Bundles/Format7z/makefile
index 02ce7144..f03a4dbd 100755
--- a/7zip/Bundles/Format7z/makefile
+++ b/7zip/Bundles/Format7z/makefile
@@ -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 = \
diff --git a/7zip/Bundles/Format7zExtract/Format7z.dsp b/7zip/Bundles/Format7zExtract/Format7z.dsp
index d3a7d434..eba80af3 100755
--- a/7zip/Bundles/Format7zExtract/Format7z.dsp
+++ b/7zip/Bundles/Format7zExtract/Format7z.dsp
@@ -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"
diff --git a/7zip/Bundles/Format7zExtract/makefile b/7zip/Bundles/Format7zExtract/makefile
index fbe77392..86d4d4d4 100755
--- a/7zip/Bundles/Format7zExtract/makefile
+++ b/7zip/Bundles/Format7zExtract/makefile
@@ -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 = \
diff --git a/7zip/Compress/BZip2/BZip2.dsp b/7zip/Compress/BZip2/BZip2.dsp
index 7cea72cf..c8d1bd1e 100755
--- a/7zip/Compress/BZip2/BZip2.dsp
+++ b/7zip/Compress/BZip2/BZip2.dsp
@@ -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
diff --git a/7zip/Compress/BZip2/BZip2Decoder.cpp b/7zip/Compress/BZip2/BZip2Decoder.cpp
index 0f0fbbfa..b9582779 100755
--- a/7zip/Compress/BZip2/BZip2Decoder.cpp
+++ b/7zip/Compress/BZip2/BZip2Decoder.cpp
@@ -12,6 +12,8 @@
namespace NCompress {
namespace NBZip2 {
+const UInt32 kNumThreadsMax = 4;
+
static const UInt32 kBufferSize = (1 << 17);
static Int16 kRandNums[512] = {
@@ -69,11 +71,6 @@ static Int16 kRandNums[512] = {
936, 638
};
-CState::~CState()
-{
- ::BigFree(tt);
-}
-
bool CState::Alloc()
{
if (tt == 0)
@@ -81,6 +78,109 @@ bool CState::Alloc()
return (tt != 0);
}
+void CState::Free()
+{
+ ::BigFree(tt);
+ tt = 0;
+}
+
+#ifdef COMPRESS_BZIP2_MT
+void CState::FinishStream()
+{
+ Decoder->StreamWasFinished = true;
+ StreamWasFinishedEvent.Set();
+ Decoder->CS.Leave();
+ Decoder->CanStartWaitingEvent.Lock();
+ WaitingWasStartedEvent.Set();
+}
+
+DWORD CState::ThreadFunc()
+{
+ while (true)
+ {
+ Decoder->CS.Enter();
+ if (Decoder->CloseThreads)
+ {
+ Decoder->CS.Leave();
+ return 0;
+ }
+ if (Decoder->StreamWasFinished)
+ {
+ FinishStream();
+ continue;
+ }
+ HRESULT res = S_OK;
+ try
+ {
+ UInt32 blockIndex = Decoder->NextBlockIndex;
+ UInt32 nextBlockIndex = blockIndex + 1;
+ if (nextBlockIndex == Decoder->NumThreads)
+ nextBlockIndex = 0;
+ Decoder->NextBlockIndex = nextBlockIndex;
+
+ bool wasFinished;
+ UInt32 crc;
+ res = Decoder->ReadSignatures(wasFinished, crc);
+ if (res != S_OK)
+ {
+ Decoder->Result = res;
+ FinishStream();
+ continue;
+ }
+ if (wasFinished)
+ {
+ Decoder->Result = res;
+ FinishStream();
+ continue;
+ }
+
+ res = Decoder->ReadBlock(Decoder->BlockSizeMax, *this);
+ UInt64 packSize = Decoder->m_InStream.GetProcessedSize();
+ if (res != S_OK)
+ {
+ Decoder->Result = res;
+ FinishStream();
+ continue;
+ }
+ Decoder->CS.Leave();
+
+ DecodeBlock1();
+
+ Decoder->m_States[blockIndex].CanWriteEvent.Lock();
+
+ if (DecodeBlock2(Decoder->m_OutStream) != crc)
+ {
+ Decoder->Result = S_FALSE;
+ FinishStream();
+ continue;
+ }
+
+ if (Decoder->Progress)
+ {
+ UInt64 unpackSize = Decoder->m_OutStream.GetProcessedSize();
+ res = Decoder->Progress->SetRatioInfo(&packSize, &unpackSize);
+ }
+
+ Decoder->m_States[nextBlockIndex].CanWriteEvent.Set();
+ }
+ catch(const CInBufferException &e) { res = e.ErrorCode; }
+ catch(const COutBufferException &e) { res = e.ErrorCode; }
+ catch(...) { res = E_FAIL; }
+ if (res != S_OK)
+ {
+ Decoder->Result = res;
+ FinishStream();
+ continue;
+ }
+ }
+}
+
+static DWORD WINAPI MFThread(void *threadCoderInfo)
+{
+ return ((CState *)threadCoderInfo)->ThreadFunc();
+}
+#endif
+
UInt32 CDecoder::ReadBits(int numBits) { return m_InStream.ReadBits(numBits); }
Byte CDecoder::ReadByte() {return (Byte)ReadBits(8); }
bool CDecoder::ReadBit() { return ReadBits(1) != 0; }
@@ -201,7 +301,7 @@ HRESULT CDecoder::ReadBlock(UInt32 blockSizeMax, CState &state)
groupSize = kGroupSize;
huffmanDecoder = &m_HuffmanDecoders[state.m_Selectors[groupIndex++]];
}
- groupSize--; \
+ groupSize--;
UInt32 nextSym = huffmanDecoder->DecodeSymbol(&m_InStream);
@@ -241,7 +341,7 @@ HRESULT CDecoder::ReadBlock(UInt32 blockSizeMax, CState &state)
return S_OK;
}
-HRESULT CState::DecodeBlock(COutBuffer &m_OutStream)
+void CState::DecodeBlock1()
{
UInt32 *charCounters = this->CharCounters;
{
@@ -259,8 +359,11 @@ HRESULT CState::DecodeBlock(COutBuffer &m_OutStream)
do
tt[charCounters[tt[i] & 0xFF]++] |= (i << 8);
while(++i < blockSize);
+}
- // Decode
+UInt32 CState::DecodeBlock2(COutBuffer &m_OutStream)
+{
+ UInt32 blockSize = this->BlockSize;
CBZip2CRC crc;
@@ -310,11 +413,122 @@ HRESULT CState::DecodeBlock(COutBuffer &m_OutStream)
m_OutStream.WriteByte(b);
}
while(--blockSize != 0);
- return (StoredCRC == crc.GetDigest()) ? S_OK : S_FALSE;
+ return crc.GetDigest();
+}
+
+#ifdef COMPRESS_BZIP2_MT
+CDecoder::CDecoder():
+ m_States(0)
+{
+ m_NumThreadsPrev = 0;
+ NumThreads = 1;
+ CS.Enter();
+}
+
+CDecoder::~CDecoder()
+{
+ Free();
+}
+
+bool CDecoder::Create()
+{
+ try
+ {
+ if (m_States != 0 && m_NumThreadsPrev == NumThreads)
+ return true;
+ Free();
+ MtMode = (NumThreads > 1);
+ m_NumThreadsPrev = NumThreads;
+ m_States = new CState[NumThreads];
+ if (m_States == 0)
+ return false;
+ #ifdef COMPRESS_BZIP2_MT
+ for (UInt32 t = 0; t < NumThreads; t++)
+ {
+ CState &ti = m_States[t];
+ ti.Decoder = this;
+ if (MtMode)
+ if (!ti.Thread.Create(MFThread, &ti))
+ {
+ NumThreads = t;
+ Free();
+ return false;
+ }
+ }
+ #endif
+ }
+ catch(...) { return false; }
+ return true;
+}
+
+void CDecoder::Free()
+{
+ if (!m_States)
+ return;
+ CloseThreads = true;
+ CS.Leave();
+ for (UInt32 t = 0; t < NumThreads; t++)
+ {
+ CState &s = m_States[t];
+ if (MtMode)
+ s.Thread.Wait();
+ s.Free();
+ }
+ delete []m_States;
+ m_States = 0;
+}
+#endif
+
+HRESULT CDecoder::ReadSignatures(bool &wasFinished, UInt32 &crc)
+{
+ wasFinished = false;
+ Byte s[6];
+ for (int i = 0; i < 6; i++)
+ s[i] = ReadByte();
+ crc = ReadCRC();
+ if (s[0] == kFinSig0)
+ {
+ if (s[1] != kFinSig1 ||
+ s[2] != kFinSig2 ||
+ s[3] != kFinSig3 ||
+ s[4] != kFinSig4 ||
+ s[5] != kFinSig5)
+ return S_FALSE;
+
+ wasFinished = true;
+ return (crc == CombinedCRC.GetDigest()) ? S_OK : S_FALSE;
+ }
+ if (s[0] != kBlockSig0 ||
+ s[1] != kBlockSig1 ||
+ s[2] != kBlockSig2 ||
+ s[3] != kBlockSig3 ||
+ s[4] != kBlockSig4 ||
+ s[5] != kBlockSig5)
+ return S_FALSE;
+ CombinedCRC.Update(crc);
+ return S_OK;
}
HRESULT CDecoder::DecodeFile(bool &isBZ, ICompressProgressInfo *progress)
{
+ #ifdef COMPRESS_BZIP2_MT
+ Progress = progress;
+ if (!Create())
+ return E_FAIL;
+ for (UInt32 t = 0; t < NumThreads; t++)
+ {
+ CState &s = m_States[t];
+ if (!s.Alloc())
+ return E_OUTOFMEMORY;
+ s.StreamWasFinishedEvent.Reset();
+ s.WaitingWasStartedEvent.Reset();
+ s.CanWriteEvent.Reset();
+ }
+ #else
+ if (!m_States[0].Alloc())
+ return E_OUTOFMEMORY;
+ #endif
+
isBZ = false;
Byte s[6];
int i;
@@ -329,45 +543,53 @@ HRESULT CDecoder::DecodeFile(bool &isBZ, ICompressProgressInfo *progress)
isBZ = true;
UInt32 dicSize = (UInt32)(s[3] - kArSig3) * kBlockSizeStep;
- if (!m_State.Alloc())
- return E_OUTOFMEMORY;
-
- CBZip2CombinedCRC computedCombinedCRC;
- while (true)
+ CombinedCRC.Init();
+ #ifdef COMPRESS_BZIP2_MT
+ if (MtMode)
{
- if (progress)
- {
- UInt64 packSize = m_InStream.GetProcessedSize();
- UInt64 unpackSize = m_OutStream.GetProcessedSize();
- RINOK(progress->SetRatioInfo(&packSize, &unpackSize));
- }
-
- for (i = 0; i < 6; i++)
- s[i] = ReadByte();
- UInt32 crc = ReadCRC();
- if (s[0] == kFinSig0)
+ 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 (s[1] != kFinSig1 ||
- s[2] != kFinSig2 ||
- s[3] != kFinSig3 ||
- s[4] != kFinSig4 ||
- s[5] != kFinSig5)
+ 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 (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));
}
+ 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
+
}}
diff --git a/7zip/Compress/BZip2/BZip2Decoder.h b/7zip/Compress/BZip2/BZip2Decoder.h
index 0eb73130..87a7dc67 100755
--- a/7zip/Compress/BZip2/BZip2Decoder.h
+++ b/7zip/Compress/BZip2/BZip2Decoder.h
@@ -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
};
}}
diff --git a/7zip/Compress/BZip2/BZip2Encoder.cpp b/7zip/Compress/BZip2/BZip2Encoder.cpp
index 657fcfb2..dc08e7a8 100755
--- a/7zip/Compress/BZip2/BZip2Encoder.cpp
+++ b/7zip/Compress/BZip2/BZip2Encoder.cpp
@@ -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,18 +15,160 @@ 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)
{
@@ -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;
+
+ 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;
+}
- UInt32 size = outStreamTemp.GetPos();
- UInt32 bytesSize = (size / 8);
+void CEncoder::WriteBytes(const Byte *data, UInt32 sizeInBits, Byte lastByte)
+{
+ UInt32 bytesSize = (sizeInBits / 8);
for (UInt32 i = 0; i < bytesSize; i++)
- m_OutStream.WriteBits(m_TempArray[i], 8);
- WriteBits(outStreamTemp.GetCurByte(), (size & 7));
+ 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
+
}}
diff --git a/7zip/Compress/BZip2/BZip2Encoder.h b/7zip/Compress/BZip2/BZip2Encoder.h
index 7eca18a0..e08eb614 100755
--- a/7zip/Compress/BZip2/BZip2Encoder.h
+++ b/7zip/Compress/BZip2/BZip2Encoder.h
@@ -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;
+private:
+ Byte *m_MtfArray;
+ Byte *m_TempArray;
CBlockSorter m_BlockSorter;
- bool m_NeedHuffmanCreate;
+ CMsbfEncoderTemp *m_OutStreamCurrent;
+
NCompression::NHuffman::CEncoder m_HuffEncoders[kNumTablesMax];
+ Byte m_Selectors[kNumSelectorsMax];
- Byte *m_MtfArray;
- Byte *m_TempArray;
+ bool m_NeedHuffmanCreate;
- Byte m_Selectors[kNumSelectorsMax];
+ UInt32 m_CRCs[1 << kNumPassesMax];
+ UInt32 m_NumCrcs;
- UInt32 m_BlockSizeMult;
- UInt32 m_NumPasses;
- bool m_OptimizeNumTables;
+ int m_BlockIndex;
- UInt32 ReadRleBlock(Byte *buffer);
+ 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
};
}}
diff --git a/7zip/Compress/BZip2/makefile b/7zip/Compress/BZip2/makefile
index fdd5a164..f355e7d9 100755
--- a/7zip/Compress/BZip2/makefile
+++ b/7zip/Compress/BZip2/makefile
@@ -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
diff --git a/7zip/Compress/Deflate/DeflateEncoder.cpp b/7zip/Compress/Deflate/DeflateEncoder.cpp
index 4ded78f0..a3e9f4aa 100755
--- a/7zip/Compress/Deflate/DeflateEncoder.cpp
+++ b/7zip/Compress/Deflate/DeflateEncoder.cpp
@@ -86,7 +86,9 @@ CCoder::CCoder(bool deflate64Mode):
m_DistanceMemory(0),
m_Created(false),
m_Values(0),
- m_Tables(0)
+ m_Tables(0),
+ m_MatchFinderCycles(0),
+ m_SetMfPasses(0)
{
m_MatchMaxLen = deflate64Mode ? kMatchMaxLen64 : kMatchMaxLen32;
m_NumLenCombinations = deflate64Mode ? kNumLenSymbols64 : kNumLenSymbols32;
@@ -99,7 +101,9 @@ HRESULT CCoder::Create()
COM_TRY_BEGIN
if (!m_MatchFinder)
{
- m_MatchFinder = new NBT3Z::CMatchFinder;
+ NBT3Z::CMatchFinder *matchFinderSpec = new NBT3Z::CMatchFinder;
+ m_SetMfPasses = matchFinderSpec;
+ m_MatchFinder = matchFinderSpec;
if (m_MatchFinder == 0)
return E_OUTOFMEMORY;
}
@@ -149,6 +153,8 @@ HRESULT CCoder::Create()
if (!LevelCoder.Create(kLevelTableSize, kLevelDirectBits, kTableDirectLevels, kMaxLevelBitLength))
return E_OUTOFMEMORY;
}
+ if (m_MatchFinderCycles != 0 && m_SetMfPasses != 0)
+ m_SetMfPasses->SetNumPasses(m_MatchFinderCycles);
m_Created = true;
return S_OK;
COM_TRY_END
@@ -160,13 +166,13 @@ HRESULT CCoder::BaseSetEncoderProperties2(const PROPID *propIDs,
{
for(UInt32 i = 0; i < numProperties; i++)
{
- const PROPVARIANT &property = properties[i];
+ const PROPVARIANT &prop = properties[i];
switch(propIDs[i])
{
case NCoderPropID::kNumPasses:
- if (property.vt != VT_UI4)
+ if (prop.vt != VT_UI4)
return E_INVALIDARG;
- m_NumDivPasses = property.ulVal;
+ m_NumDivPasses = prop.ulVal;
if (m_NumDivPasses == 0)
m_NumDivPasses = 1;
if (m_NumDivPasses == 1)
@@ -180,12 +186,19 @@ HRESULT CCoder::BaseSetEncoderProperties2(const PROPID *propIDs,
}
break;
case NCoderPropID::kNumFastBytes:
- if (property.vt != VT_UI4)
+ if (prop.vt != VT_UI4)
return E_INVALIDARG;
- m_NumFastBytes = property.ulVal;
+ m_NumFastBytes = prop.ulVal;
if(m_NumFastBytes < kMatchMinLen || m_NumFastBytes > m_MatchMaxLen)
return E_INVALIDARG;
break;
+ case NCoderPropID::kMatchFinderCycles:
+ {
+ if (prop.vt != VT_UI4)
+ return E_INVALIDARG;
+ m_MatchFinderCycles = prop.ulVal;
+ break;
+ }
default:
return E_INVALIDARG;
}
diff --git a/7zip/Compress/Deflate/DeflateEncoder.h b/7zip/Compress/Deflate/DeflateEncoder.h
index f010e047..eb2ffbf1 100755
--- a/7zip/Compress/Deflate/DeflateEncoder.h
+++ b/7zip/Compress/Deflate/DeflateEncoder.h
@@ -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);
diff --git a/7zip/Compress/LZ/BinTree/BinTree.h b/7zip/Compress/LZ/BinTree/BinTree.h
index 2776259f..b3b3f13a 100755
--- a/7zip/Compress/LZ/BinTree/BinTree.h
+++ b/7zip/Compress/LZ/BinTree/BinTree.h
@@ -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; }
};
}
diff --git a/7zip/Compress/LZ/IMatchFinder.h b/7zip/Compress/LZ/IMatchFinder.h
index 55dd5956..528b7b1c 100755
--- a/7zip/Compress/LZ/IMatchFinder.h
+++ b/7zip/Compress/LZ/IMatchFinder.h
@@ -24,4 +24,9 @@ struct IMatchFinder: public IInWindowStream
STDMETHOD(Skip)(UInt32 num) PURE;
};
+struct IMatchFinderSetNumPasses
+{
+ virtual void SetNumPasses(UInt32 numPasses) PURE;
+};
+
#endif
diff --git a/7zip/Compress/LZMA/LZMAEncoder.cpp b/7zip/Compress/LZMA/LZMAEncoder.cpp
index 4a5ba0e8..bafdb875 100755
--- a/7zip/Compress/LZMA/LZMAEncoder.cpp
+++ b/7zip/Compress/LZMA/LZMAEncoder.cpp
@@ -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();
diff --git a/7zip/Compress/LZMA/LZMAEncoder.h b/7zip/Compress/LZMA/LZMAEncoder.h
index 365e9ddf..f4c2c151 100755
--- a/7zip/Compress/LZMA/LZMAEncoder.h
+++ b/7zip/Compress/LZMA/LZMAEncoder.h
@@ -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);
diff --git a/7zip/Compress/LZMA_Alone/LzmaAlone.cpp b/7zip/Compress/LZMA_Alone/LzmaAlone.cpp
index 207f4580..dc99b47c 100755
--- a/7zip/Compress/LZMA_Alone/LzmaAlone.cpp
+++ b/7zip/Compress/LZMA_Alone/LzmaAlone.cpp
@@ -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);
diff --git a/7zip/Guid.txt b/7zip/Guid.txt
index 869b2b9e..d6423714 100755
--- a/7zip/Guid.txt
+++ b/7zip/Guid.txt
@@ -25,6 +25,7 @@
22 ICompressSetDecoderProperties2
23 ICompressWriteCoderProperties
24 ICompressGetInStreamProcessedSize
+25 ICompressSetCoderMt
30 ICompressGetSubStreamSize
31 ICompressSetInStream
32 ICompressSetOutStream
diff --git a/7zip/ICoder.h b/7zip/ICoder.h
index 8d556fdc..d84575dc 100755
--- a/7zip/ICoder.h
+++ b/7zip/ICoder.h
@@ -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;
diff --git a/7zip/MyVersion.h b/7zip/MyVersion.h
index 38e9e737..d1b8070e 100755
--- a/7zip/MyVersion.h
+++ b/7zip/MyVersion.h
@@ -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
diff --git a/7zip/UI/Common/ArchiveCommandLine.cpp b/7zip/UI/Common/ArchiveCommandLine.cpp
index f41c8811..30531276 100755
--- a/7zip/UI/Common/ArchiveCommandLine.cpp
+++ b/7zip/UI/Common/ArchiveCommandLine.cpp
@@ -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;
diff --git a/7zip/UI/Common/ArchiveCommandLine.h b/7zip/UI/Common/ArchiveCommandLine.h
index ddca3237..e2031499 100755
--- a/7zip/UI/Common/ArchiveCommandLine.h
+++ b/7zip/UI/Common/ArchiveCommandLine.h
@@ -68,6 +68,7 @@ struct CArchiveCommandLineOptions
NExtract::NOverwriteMode::EEnum OverwriteMode;
UStringVector ArchivePathsSorted;
UStringVector ArchivePathsFullSorted;
+ CObjectVector<CProperty> ExtractProperties;
CUpdateOptions UpdateOptions;
bool EnablePercents;
diff --git a/7zip/UI/Common/Extract.cpp b/7zip/UI/Common/Extract.cpp
index 4dff13e8..2879feaa 100755
--- a/7zip/UI/Common/Extract.cpp
+++ b/7zip/UI/Common/Extract.cpp
@@ -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);
diff --git a/7zip/UI/Common/Extract.h b/7zip/UI/Common/Extract.h
index 8823b08b..58636f70 100755
--- a/7zip/UI/Common/Extract.h
+++ b/7zip/UI/Common/Extract.h
@@ -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;
diff --git a/7zip/UI/Common/Property.h b/7zip/UI/Common/Property.h
new file mode 100755
index 00000000..57e7b452
--- /dev/null
+++ b/7zip/UI/Common/Property.h
@@ -0,0 +1,14 @@
+// Property.h
+
+#ifndef __PROPERTY_H
+#define __PROPERTY_H
+
+#include "Common/String.h"
+
+struct CProperty
+{
+ UString Name;
+ UString Value;
+};
+
+#endif
diff --git a/7zip/UI/Common/SetProperties.cpp b/7zip/UI/Common/SetProperties.cpp
new file mode 100755
index 00000000..6c92a847
--- /dev/null
+++ b/7zip/UI/Common/SetProperties.cpp
@@ -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;
+}
diff --git a/7zip/UI/Common/SetProperties.h b/7zip/UI/Common/SetProperties.h
new file mode 100755
index 00000000..892f1a21
--- /dev/null
+++ b/7zip/UI/Common/SetProperties.h
@@ -0,0 +1,10 @@
+// SetProperties.h
+
+#ifndef __SETPROPERTIES_H
+#define __SETPROPERTIES_H
+
+#include "Property.h"
+
+HRESULT SetProperties(IUnknown *unknown, const CObjectVector<CProperty> &properties);
+
+#endif
diff --git a/7zip/UI/Common/Update.cpp b/7zip/UI/Common/Update.cpp
index f8185bfe..9bebb34a 100755
--- a/7zip/UI/Common/Update.cpp
+++ b/7zip/UI/Common/Update.cpp
@@ -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)
{
diff --git a/7zip/UI/Common/Update.h b/7zip/UI/Common/Update.h
index 237ff0d2..ed7e8885 100755
--- a/7zip/UI/Common/Update.h
+++ b/7zip/UI/Common/Update.h
@@ -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),
diff --git a/7zip/UI/Console/Console.dsp b/7zip/UI/Console/Console.dsp
index 2f4db36e..4ce596ec 100755
--- a/7zip/UI/Console/Console.dsp
+++ b/7zip/UI/Console/Console.dsp
@@ -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
diff --git a/7zip/UI/Console/Main.cpp b/7zip/UI/Console/Main.cpp
index 8be5483a..3d46e832 100755
--- a/7zip/UI/Console/Main.cpp
+++ b/7zip/UI/Console/Main.cpp
@@ -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,
diff --git a/7zip/UI/Console/UpdateCallbackConsole.cpp b/7zip/UI/Console/UpdateCallbackConsole.cpp
index 74b685d7..4abeecbe 100755
--- a/7zip/UI/Console/UpdateCallbackConsole.cpp
+++ b/7zip/UI/Console/UpdateCallbackConsole.cpp
@@ -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)
diff --git a/7zip/UI/Console/makefile b/7zip/UI/Console/makefile
index a79106d5..3e5dd8f6 100755
--- a/7zip/UI/Console/makefile
+++ b/7zip/UI/Console/makefile
@@ -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 \
diff --git a/7zip/UI/GUI/CompressDialog.cpp b/7zip/UI/GUI/CompressDialog.cpp
index c0c9d19b..f25fc51b 100755
--- a/7zip/UI/GUI/CompressDialog.cpp
+++ b/7zip/UI/GUI/CompressDialog.cpp
@@ -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))
diff --git a/7zip/UI/GUI/CompressDialog.h b/7zip/UI/GUI/CompressDialog.h
index 33970fa3..3425ca48 100755
--- a/7zip/UI/GUI/CompressDialog.h
+++ b/7zip/UI/GUI/CompressDialog.h
@@ -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();
diff --git a/7zip/UI/GUI/GUI.cpp b/7zip/UI/GUI/GUI.cpp
index f263601a..cd26f35f 100755
--- a/7zip/UI/GUI/GUI.cpp
+++ b/7zip/UI/GUI/GUI.cpp
@@ -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,
diff --git a/7zip/UI/GUI/GUI.dsp b/7zip/UI/GUI/GUI.dsp
index bf6eb541..0483b53a 100755
--- a/7zip/UI/GUI/GUI.dsp
+++ b/7zip/UI/GUI/GUI.dsp
@@ -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
diff --git a/7zip/UI/GUI/makefile b/7zip/UI/GUI/makefile
index 85b98f81..a0c3e988 100755
--- a/7zip/UI/GUI/makefile
+++ b/7zip/UI/GUI/makefile
@@ -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 \
diff --git a/Common/ListFileUtils.cpp b/Common/ListFileUtils.cpp
index e4370f48..ea4cde38 100755
--- a/Common/ListFileUtils.cpp
+++ b/Common/ListFileUtils.cpp
@@ -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++)
{
diff --git a/DOC/7zip.nsi b/DOC/7zip.nsi
index 7be88968..dca89615 100755
--- a/DOC/7zip.nsi
+++ b/DOC/7zip.nsi
@@ -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
diff --git a/DOC/lzma.txt b/DOC/lzma.txt
index cddc0723..f225c417 100755
--- a/DOC/lzma.txt
+++ b/DOC/lzma.txt
@@ -1,7 +1,7 @@
-LZMA SDK 4.33
+LZMA SDK 4.34
-------------
-LZMA SDK 4.33 Copyright (C) 1999-2006 Igor Pavlov
+LZMA SDK 4.34 Copyright (C) 1999-2006 Igor Pavlov
LZMA SDK provides the documentation, samples, header files, libraries,
and tools you need to develop applications that use LZMA compression.
diff --git a/Windows/System.h b/Windows/System.h
new file mode 100755
index 00000000..2bd1f858
--- /dev/null
+++ b/Windows/System.h
@@ -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