From 0f60a4933b33cf5061a73ce39d0dd49e274b8a26 Mon Sep 17 00:00:00 2001 From: Igor Pavlov Date: Wed, 1 Mar 2006 00:00:00 +0000 Subject: 4.34 beta --- 7zip/Archive/7z/7z.dsp | 16 +- 7zip/Archive/7z/7zCompressionMode.h | 10 +- 7zip/Archive/7z/7zDecode.cpp | 79 +++--- 7zip/Archive/7z/7zDecode.h | 3 + 7zip/Archive/7z/7zEncode.cpp | 54 ++-- 7zip/Archive/7z/7zExtract.cpp | 3 + 7zip/Archive/7z/7zHandler.cpp | 46 ++++ 7zip/Archive/7z/7zHandler.h | 70 ++++-- 7zip/Archive/7z/7zHandlerOut.cpp | 397 ++++++++++++------------------ 7zip/Archive/7z/7zIn.cpp | 3 + 7zip/Archive/7z/makefile | 3 +- 7zip/Archive/BZip2/BZip2.dsp | 12 +- 7zip/Archive/BZip2/BZip2Handler.cpp | 10 + 7zip/Archive/BZip2/BZip2Handler.h | 19 +- 7zip/Archive/BZip2/BZip2HandlerOut.cpp | 114 +++++---- 7zip/Archive/BZip2/BZip2Update.cpp | 26 +- 7zip/Archive/BZip2/BZip2Update.h | 4 + 7zip/Archive/BZip2/makefile | 3 +- 7zip/Archive/Common/ParseProperties.cpp | 171 +++++++++++++ 7zip/Archive/Common/ParseProperties.h | 17 ++ 7zip/Archive/GZip/GZip.dsp | 8 + 7zip/Archive/GZip/GZipHandler.h | 4 +- 7zip/Archive/GZip/GZipHandlerOut.cpp | 67 ++--- 7zip/Archive/GZip/GZipUpdate.cpp | 24 +- 7zip/Archive/GZip/GZipUpdate.h | 2 + 7zip/Archive/GZip/makefile | 1 + 7zip/Archive/Zip/Zip.dsp | 12 +- 7zip/Archive/Zip/ZipAddCommon.cpp | 45 +++- 7zip/Archive/Zip/ZipCompressionMode.h | 7 + 7zip/Archive/Zip/ZipHandler.cpp | 22 +- 7zip/Archive/Zip/ZipHandler.h | 22 +- 7zip/Archive/Zip/ZipHandlerOut.cpp | 142 ++++++----- 7zip/Archive/Zip/makefile | 3 +- 7zip/Bundles/Alone/Alone.dsp | 24 +- 7zip/Bundles/Alone/makefile | 4 + 7zip/Bundles/Format7z/Format7z.dsp | 12 +- 7zip/Bundles/Format7z/makefile | 3 + 7zip/Bundles/Format7zExtract/Format7z.dsp | 12 +- 7zip/Bundles/Format7zExtract/makefile | 3 + 7zip/Compress/BZip2/BZip2.dsp | 24 +- 7zip/Compress/BZip2/BZip2Decoder.cpp | 320 ++++++++++++++++++++---- 7zip/Compress/BZip2/BZip2Decoder.h | 88 ++++++- 7zip/Compress/BZip2/BZip2Encoder.cpp | 356 ++++++++++++++++++++++----- 7zip/Compress/BZip2/BZip2Encoder.h | 131 ++++++++-- 7zip/Compress/BZip2/makefile | 8 +- 7zip/Compress/Deflate/DeflateEncoder.cpp | 27 +- 7zip/Compress/Deflate/DeflateEncoder.h | 3 + 7zip/Compress/LZ/BinTree/BinTree.h | 5 +- 7zip/Compress/LZ/IMatchFinder.h | 5 + 7zip/Compress/LZMA/LZMAEncoder.cpp | 64 +++-- 7zip/Compress/LZMA/LZMAEncoder.h | 12 +- 7zip/Compress/LZMA_Alone/LzmaAlone.cpp | 27 +- 7zip/Guid.txt | 1 + 7zip/ICoder.h | 7 + 7zip/MyVersion.h | 8 +- 7zip/UI/Common/ArchiveCommandLine.cpp | 79 ++++-- 7zip/UI/Common/ArchiveCommandLine.h | 1 + 7zip/UI/Common/Extract.cpp | 6 +- 7zip/UI/Common/Extract.h | 4 + 7zip/UI/Common/Property.h | 14 ++ 7zip/UI/Common/SetProperties.cpp | 65 +++++ 7zip/UI/Common/SetProperties.h | 10 + 7zip/UI/Common/Update.cpp | 45 +--- 7zip/UI/Common/Update.h | 9 +- 7zip/UI/Console/Console.dsp | 20 +- 7zip/UI/Console/Main.cpp | 3 + 7zip/UI/Console/UpdateCallbackConsole.cpp | 2 +- 7zip/UI/Console/makefile | 3 +- 7zip/UI/GUI/CompressDialog.cpp | 102 ++++++-- 7zip/UI/GUI/CompressDialog.h | 1 + 7zip/UI/GUI/GUI.cpp | 3 + 7zip/UI/GUI/GUI.dsp | 20 +- 7zip/UI/GUI/makefile | 3 +- Common/ListFileUtils.cpp | 9 +- DOC/7zip.nsi | 6 +- DOC/lzma.txt | 4 +- Windows/System.h | 21 ++ 77 files changed, 2167 insertions(+), 826 deletions(-) create mode 100755 7zip/Archive/Common/ParseProperties.cpp create mode 100755 7zip/Archive/Common/ParseProperties.h create mode 100755 7zip/UI/Common/Property.h create mode 100755 7zip/UI/Common/SetProperties.cpp create mode 100755 7zip/UI/Common/SetProperties.h create mode 100755 Windows/System.h 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 Methods; CRecordVector 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 > inStreams; @@ -329,50 +332,60 @@ HRESULT CDecoder::Decode(IInStream *inStream, { const CCoderInfo &coderInfo = folderInfo.Coders[i]; const CAltCoderInfo &altCoderInfo = coderInfo.AltCoders.Front(); - CMyComPtr compressSetDecoderProperties; - HRESULT result = _decoders[coderIndex].QueryInterface( - IID_ICompressSetDecoderProperties2, &compressSetDecoderProperties); + CMyComPtr &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 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 cryptoSetPassword; - result = _decoders[coderIndex].QueryInterface( - IID_ICryptoSetPassword, &cryptoSetPassword); + #ifdef COMPRESS_MT + if (mtMode) + { + CMyComPtr 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 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 encoderCommon = methodFull.IsSimpleCoder() ? (IUnknown *)encoder : (IUnknown *)encoder2; + + #ifdef COMPRESS_MT + { + CMyComPtr setCoderMt; + encoderCommon.QueryInterface(IID_ICompressSetCoderMt, &setCoderMt); + if (setCoderMt) + { + RINOK(setCoderMt->SetNumberOfThreads(_options.NumThreads)); + } + } + #endif + if (methodFull.CoderProperties.Size() > 0) { CRecordVector propIDs; @@ -246,16 +259,7 @@ HRESULT CEncoder::CreateMixerCoder(const UInt64 *inSizeForReduce) values[i] = value; } CMyComPtr 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 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 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 _methods; CRecordVector _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 &methodsInfo, - bool multiThread); + CObjectVector &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 &methodsInfo, - bool multiThread) + CObjectVector &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 setCoderMt; + decoder.QueryInterface(IID_ICompressSetCoderMt, &setCoderMt); + if (setCoderMt) + { + RINOK(setCoderMt->SetNumberOfThreads(_numThreads)); + } + } + #endif CDummyOutStream *outStreamSpec = new CDummyOutStream; CMyComPtr 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 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 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 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 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 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 compressSetDecoderProperties; - if (coder->QueryInterface(IID_ICompressSetDecoderProperties2, (void **)&compressSetDecoderProperties) == S_OK) { - Byte properties = (Byte)item.Flags; - RINOK(compressSetDecoderProperties->SetDecoderProperties2(&properties, 1)); + CMyComPtr setDecoderProperties; + coder->QueryInterface(IID_ICompressSetDecoderProperties2, (void **)&setDecoderProperties); + if (setDecoderProperties) + { + Byte properties = (Byte)item.Flags; + RINOK(setDecoderProperties->SetDecoderProperties2(&properties, 1)); + } + } + + #ifdef COMPRESS_MT + { + CMyComPtr 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 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 m_InStream; +public: COutBuffer m_OutStream; - + Byte MtPad[1 << 8]; // It's pad for Multi-Threading. Must be >= Cache_Line_Size. + NStream::NMSBF::CDecoder 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 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 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 &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 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 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 &properties) +{ + if (properties.IsEmpty()) + return S_OK; + CMyComPtr 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 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 &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 copyCoder = new NCompress::CCopyCoder; @@ -439,36 +427,7 @@ static HRESULT Compress( */ } - CMyComPtr 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 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 -- cgit v1.2.3