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

github.com/kornelski/7z.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/CPP/7zip
diff options
context:
space:
mode:
authorIgor Pavlov <ipavlov@users.sourceforge.net>2008-11-23 03:00:00 +0300
committerKornel LesiƄski <kornel@geekhood.net>2016-05-28 02:15:57 +0300
commitb717a4dbfe15fd7540e68e6c5ccbe91901bbadba (patch)
treec89b25a1f9a690e69cd20e313be9eb4180ee7a6f /CPP/7zip
parentc10e6b16f6d5484ed896b2c614cb7fb77f336d24 (diff)
4.61 beta
Diffstat (limited to 'CPP/7zip')
-rwxr-xr-xCPP/7zip/Archive/Cab/CabIn.cpp92
-rwxr-xr-xCPP/7zip/Archive/Cab/CabIn.h14
-rwxr-xr-xCPP/7zip/Archive/Iso/IsoIn.cpp41
-rwxr-xr-xCPP/7zip/Archive/PeHandler.cpp31
-rwxr-xr-xCPP/7zip/Archive/Zip/ZipAddCommon.cpp104
-rwxr-xr-xCPP/7zip/Archive/Zip/ZipCompressionMode.h2
-rwxr-xr-xCPP/7zip/Archive/Zip/ZipHandler.cpp73
-rwxr-xr-xCPP/7zip/Archive/Zip/ZipHandlerOut.cpp116
-rwxr-xr-xCPP/7zip/Archive/Zip/ZipHeader.h5
-rwxr-xr-xCPP/7zip/Archive/Zip/ZipItem.cpp14
-rwxr-xr-xCPP/7zip/Archive/Zip/ZipItem.h3
-rwxr-xr-xCPP/7zip/Archive/Zip/ZipUpdate.cpp10
-rwxr-xr-xCPP/7zip/Bundles/SFXCon/Main.cpp55
-rwxr-xr-xCPP/7zip/Bundles/SFXCon/SFXCon.dsp8
-rwxr-xr-xCPP/7zip/Bundles/SFXCon/makefile1
-rwxr-xr-xCPP/7zip/Bundles/SFXSetup/ExtractCallback.cpp23
-rwxr-xr-xCPP/7zip/Compress/LZMA/LZMADecoder.cpp9
-rwxr-xr-xCPP/7zip/Compress/LZMA/LZMADecoder.h2
-rwxr-xr-xCPP/7zip/Compress/LZMA_Alone/AloneLZMA.dsp36
-rwxr-xr-xCPP/7zip/Compress/LZMA_Alone/LzmaAlone.cpp134
-rwxr-xr-xCPP/7zip/MyVersion.h8
-rwxr-xr-xCPP/7zip/UI/Common/DefaultName.cpp8
-rwxr-xr-xCPP/7zip/UI/Common/UpdatePair.cpp26
-rwxr-xr-xCPP/7zip/UI/FileManager/PanelItemOpen.cpp2
-rwxr-xr-xCPP/7zip/UI/FileManager/RootFolder.cpp11
-rwxr-xr-xCPP/7zip/UI/GUI/CompressDialog.cpp38
26 files changed, 501 insertions, 365 deletions
diff --git a/CPP/7zip/Archive/Cab/CabIn.cpp b/CPP/7zip/Archive/Cab/CabIn.cpp
index 072e4076..2b0a426b 100755
--- a/CPP/7zip/Archive/Cab/CabIn.cpp
+++ b/CPP/7zip/Archive/Cab/CabIn.cpp
@@ -9,34 +9,6 @@
namespace NArchive {
namespace NCab {
-/*
-static HRESULT ReadBytes(IInStream *inStream, void *data, UInt32 size)
-{
- UInt32 realProcessedSize;
- RINOK(ReadStream(inStream, data, size, &realProcessedSize));
- if(realProcessedSize != size)
- return S_FALSE;
- return S_OK;
-}
-
-static HRESULT SafeRead(IInStream *inStream, void *data, UInt32 size)
-{
- UInt32 realProcessedSize;
- RINOK(ReadStream(inStream, data, size, &realProcessedSize));
- if(realProcessedSize != size)
- throw CInArchiveException(CInArchiveException::kUnexpectedEndOfArchive);
- return S_OK;
-}
-
-static void SafeInByteRead(::CInBuffer &inBuffer, void *data, UInt32 size)
-{
- UInt32 realProcessedSize;
- inBuffer.ReadBytes(data, size, realProcessedSize);
- if(realProcessedSize != size)
- throw CInArchiveException(CInArchiveException::kUnexpectedEndOfArchive);
-}
-*/
-
Byte CInArchive::ReadByte()
{
Byte b;
@@ -107,43 +79,43 @@ HRESULT CInArchive::Open2(IInStream *stream,
inBuffer.SetStream(stream);
inBuffer.Init();
- CInArchiveInfo &archiveInfo = database.ArchiveInfo;
+ CInArchiveInfo &ai = database.ArchiveInfo;
- archiveInfo.Size = ReadUInt32(); // size of this cabinet file in bytes
+ ai.Size = ReadUInt32();
if (ReadUInt32() != 0)
return S_FALSE;
- archiveInfo.FileHeadersOffset = ReadUInt32(); // offset of the first CFFILE entry
+ ai.FileHeadersOffset = ReadUInt32();
if (ReadUInt32() != 0)
return S_FALSE;
- archiveInfo.VersionMinor = ReadByte(); // cabinet file format version, minor
- archiveInfo.VersionMajor = ReadByte(); // cabinet file format version, major
- archiveInfo.NumFolders = ReadUInt16(); // number of CFFOLDER entries in this cabinet
- archiveInfo.NumFiles = ReadUInt16(); // number of CFFILE entries in this cabinet
- archiveInfo.Flags = ReadUInt16();
- if (archiveInfo.Flags > 7)
+ ai.VersionMinor = ReadByte();
+ ai.VersionMajor = ReadByte();
+ ai.NumFolders = ReadUInt16();
+ ai.NumFiles = ReadUInt16();
+ ai.Flags = ReadUInt16();
+ if (ai.Flags > 7)
return S_FALSE;
- archiveInfo.SetID = ReadUInt16(); // must be the same for all cabinets in a set
- archiveInfo.CabinetNumber = ReadUInt16(); // number of this cabinet file in a set
+ ai.SetID = ReadUInt16();
+ ai.CabinetNumber = ReadUInt16();
- if (archiveInfo.ReserveBlockPresent())
+ if (ai.ReserveBlockPresent())
{
- archiveInfo.PerCabinetAreaSize = ReadUInt16(); // (optional) size of per-cabinet reserved area
- archiveInfo.PerFolderAreaSize = ReadByte(); // (optional) size of per-folder reserved area
- archiveInfo.PerDataBlockAreaSize = ReadByte(); // (optional) size of per-datablock reserved area
+ ai.PerCabinetAreaSize = ReadUInt16();
+ ai.PerFolderAreaSize = ReadByte();
+ ai.PerDataBlockAreaSize = ReadByte();
- Skeep(archiveInfo.PerCabinetAreaSize);
+ Skeep(ai.PerCabinetAreaSize);
}
{
- if (archiveInfo.IsTherePrev())
- ReadOtherArchive(archiveInfo.PreviousArchive);
- if (archiveInfo.IsThereNext())
- ReadOtherArchive(archiveInfo.NextArchive);
+ if (ai.IsTherePrev())
+ ReadOtherArchive(ai.PreviousArchive);
+ if (ai.IsThereNext())
+ ReadOtherArchive(ai.NextArchive);
}
int i;
- for(i = 0; i < archiveInfo.NumFolders; i++)
+ for (i = 0; i < ai.NumFolders; i++)
{
CFolder folder;
@@ -152,15 +124,15 @@ HRESULT CInArchive::Open2(IInStream *stream,
folder.CompressionTypeMajor = ReadByte();
folder.CompressionTypeMinor = ReadByte();
- Skeep(archiveInfo.PerFolderAreaSize);
+ Skeep(ai.PerFolderAreaSize);
database.Folders.Add(folder);
}
- RINOK(stream->Seek(database.StartPosition + archiveInfo.FileHeadersOffset, STREAM_SEEK_SET, NULL));
+ RINOK(stream->Seek(database.StartPosition + ai.FileHeadersOffset, STREAM_SEEK_SET, NULL));
inBuffer.SetStream(stream);
inBuffer.Init();
- for(i = 0; i < archiveInfo.NumFiles; i++)
+ for (i = 0; i < ai.NumFiles; i++)
{
CItem item;
item.Size = ReadUInt32();
@@ -224,16 +196,10 @@ bool CMvDatabaseEx::AreItemsEqual(int i1, int i2)
const CDatabaseEx &db2 = Volumes[p2->VolumeIndex];
const CItem &item1 = db1.Items[p1->ItemIndex];
const CItem &item2 = db2.Items[p2->ItemIndex];;
- int f1 = GetFolderIndex(p1);
- int f2 = GetFolderIndex(p2);
- if (f1 != f2)
- return false;
- if (item1.Offset != item2.Offset)
- return false;
- if (item1.Size != item2.Size)
- return false;
-
- return true;
+ return GetFolderIndex(p1) == GetFolderIndex(p2) &&
+ item1.Offset == item2.Offset &&
+ item1.Size == item2.Size &&
+ item1.Name == item2.Name;
}
void CMvDatabaseEx::FillSortAndShrink()
@@ -296,7 +262,7 @@ bool CMvDatabaseEx::Check()
}
UInt64 maxPos = 0;
int prevFolder = -2;
- for(int i = 0; i < Items.Size(); i++)
+ for (int i = 0; i < Items.Size(); i++)
{
const CMvItem &mvItem = Items[i];
int fIndex = GetFolderIndex(&mvItem);
diff --git a/CPP/7zip/Archive/Cab/CabIn.h b/CPP/7zip/Archive/Cab/CabIn.h
index 4975095f..197017b9 100755
--- a/CPP/7zip/Archive/Cab/CabIn.h
+++ b/CPP/7zip/Archive/Cab/CabIn.h
@@ -31,13 +31,13 @@ struct COtherArchive
struct CArchiveInfo
{
- Byte VersionMinor; /* cabinet file format version, minor */
- Byte VersionMajor; /* cabinet file format version, major */
- UInt16 NumFolders; /* number of CFFOLDER entries in this cabinet */
- UInt16 NumFiles; /* number of CFFILE entries in this cabinet */
- UInt16 Flags; /* cabinet file option indicators */
- UInt16 SetID; /* must be the same for all cabinets in a set */
- UInt16 CabinetNumber; /* number of this cabinet file in a set */
+ Byte VersionMinor; /* cabinet file format version, minor */
+ Byte VersionMajor; /* cabinet file format version, major */
+ UInt16 NumFolders; /* number of CFFOLDER entries in this cabinet */
+ UInt16 NumFiles; /* number of CFFILE entries in this cabinet */
+ UInt16 Flags; /* cabinet file option indicators */
+ UInt16 SetID; /* must be the same for all cabinets in a set */
+ UInt16 CabinetNumber; /* number of this cabinet file in a set */
bool ReserveBlockPresent() const { return (Flags & NHeader::NArchive::NFlags::kReservePresent) != 0; }
diff --git a/CPP/7zip/Archive/Iso/IsoIn.cpp b/CPP/7zip/Archive/Iso/IsoIn.cpp
index 37d2798a..dee23395 100755
--- a/CPP/7zip/Archive/Iso/IsoIn.cpp
+++ b/CPP/7zip/Archive/Iso/IsoIn.cpp
@@ -346,10 +346,8 @@ HRESULT CInArchive::Open2()
Clear();
RINOK(_stream->Seek(kStartPos, STREAM_SEEK_CUR, &_position));
- bool primVolDescDefined = false;
m_BufferPos = 0;
BlockSize = kBlockSize;
- VolDescs.Add(CVolumeDescriptor());
for (;;)
{
Byte sig[7];
@@ -396,42 +394,33 @@ HRESULT CInArchive::Open2()
break;
}
case NVolDescType::kPrimaryVol:
- {
- if (primVolDescDefined)
- return S_FALSE;
- primVolDescDefined = true;
- CVolumeDescriptor &volDesc = VolDescs[0];
- ReadVolumeDescriptor(volDesc);
- // some burners write "Joliet" Escape Sequence to primary volume
- memset(volDesc.EscapeSequence, 0, sizeof(volDesc.EscapeSequence));
- break;
- }
case NVolDescType::kSupplementaryVol:
{
- CVolumeDescriptor sd;
- ReadVolumeDescriptor(sd);
- VolDescs.Add(sd);
+ // some ISOs have two PrimaryVols.
+ CVolumeDescriptor vd;
+ ReadVolumeDescriptor(vd);
+ if (sig[0] == NVolDescType::kPrimaryVol)
+ {
+ // some burners write "Joliet" Escape Sequence to primary volume
+ memset(vd.EscapeSequence, 0, sizeof(vd.EscapeSequence));
+ }
+ VolDescs.Add(vd);
break;
}
default:
break;
}
}
- MainVolDescIndex = 0;
- if (!primVolDescDefined)
+ if (VolDescs.IsEmpty())
return S_FALSE;
- for (int i = VolDescs.Size() - 1; i >= 0; i--)
- {
- if (VolDescs[i].IsJoliet())
- {
- MainVolDescIndex = i;
+ for (MainVolDescIndex = VolDescs.Size() - 1; MainVolDescIndex > 0; MainVolDescIndex--)
+ if (VolDescs[MainVolDescIndex].IsJoliet())
break;
- }
- }
// MainVolDescIndex = 0; // to read primary volume
- if (VolDescs[MainVolDescIndex].LogicalBlockSize != kBlockSize)
+ const CVolumeDescriptor &vd = VolDescs[MainVolDescIndex];
+ if (vd.LogicalBlockSize != kBlockSize)
return S_FALSE;
- (CDirRecord &)_rootDir = VolDescs[MainVolDescIndex].RootDirRecord;
+ (CDirRecord &)_rootDir = vd.RootDirRecord;
ReadDir(_rootDir, 0);
CreateRefs(_rootDir);
ReadBootInfo();
diff --git a/CPP/7zip/Archive/PeHandler.cpp b/CPP/7zip/Archive/PeHandler.cpp
index 245c30c1..7031db97 100755
--- a/CPP/7zip/Archive/PeHandler.cpp
+++ b/CPP/7zip/Archive/PeHandler.cpp
@@ -264,6 +264,9 @@ struct CSection
void Parse(const Byte *p);
};
+static bool operator <(const CSection &a1, const CSection &a2) { return (a1.Pa < a2.Pa); }
+static bool operator ==(const CSection &a1, const CSection &a2) { return (a1.Pa == a2.Pa); }
+
static AString GetName(const Byte *name)
{
const int kNameSize = 8;
@@ -726,6 +729,34 @@ HRESULT CHandler::Open2(IInStream *stream)
if (fileSize > _totalSize)
return S_FALSE;
_totalSizeLimited = (_totalSize < fileSize) ? _totalSize : (UInt32)fileSize;
+
+ {
+ CObjectVector<CSection> sections = _sections;
+ sections.Sort();
+ UInt32 limit = (1 << 12);
+ int num = 0;
+ for (int i = 0; i < sections.Size(); i++)
+ {
+ const CSection &s = sections[i];
+ if (s.Pa > limit)
+ {
+ CSection s2;
+ s2.Pa = s2.Va = limit;
+ s2.PSize = s2.VSize = s.Pa - limit;
+ char sz[32];
+ ConvertUInt64ToString(++num, sz);
+ s2.Name = "[data-";
+ s2.Name += sz;
+ s2.Name += "]";
+ _sections.Add(s2);
+ }
+ UInt32 next = s.Pa + s.PSize;
+ if (next < limit)
+ break;
+ limit = next;
+ }
+ }
+
return S_OK;
}
diff --git a/CPP/7zip/Archive/Zip/ZipAddCommon.cpp b/CPP/7zip/Archive/Zip/ZipAddCommon.cpp
index ca16ef97..d0b13af4 100755
--- a/CPP/7zip/Archive/Zip/ZipAddCommon.cpp
+++ b/CPP/7zip/Archive/Zip/ZipAddCommon.cpp
@@ -9,9 +9,13 @@ extern "C"
#include "Windows/PropVariant.h"
#include "Windows/Defs.h"
+#include "../../MyVersion.h"
#include "../../ICoder.h"
#include "../../IPassword.h"
#include "../../Common/CreateCoder.h"
+#include "../../Common/StreamObjects.h"
+#include "../../Common/StreamUtils.h"
+#include "../../Compress/LZMA/LZMAEncoder.h"
#include "../Common/InStreamWithCRC.h"
#include "ZipAddCommon.h"
@@ -23,11 +27,59 @@ namespace NZip {
static const CMethodId kMethodId_ZipBase = 0x040100;
static const CMethodId kMethodId_BZip2 = 0x040202;
+static const UInt32 kLzmaPropsSize = 5;
+static const UInt32 kLzmaHeaderSize = 4 + kLzmaPropsSize;
+
+class CLzmaEncoder:
+ public ICompressCoder,
+ public CMyUnknownImp
+{
+ NCompress::NLZMA::CEncoder *EncoderSpec;
+ CMyComPtr<ICompressCoder> Encoder;
+ Byte Header[kLzmaHeaderSize];
+public:
+ STDMETHOD(Code)(ISequentialInStream *inStream, ISequentialOutStream *outStream,
+ const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress);
+ HRESULT CLzmaEncoder::SetCoderProperties(const PROPID *propIDs, const PROPVARIANT *props, UInt32 numProps);
+
+ MY_UNKNOWN_IMP
+};
+
+HRESULT CLzmaEncoder::SetCoderProperties(const PROPID *propIDs, const PROPVARIANT *props, UInt32 numProps)
+{
+ if (!Encoder)
+ {
+ EncoderSpec = new NCompress::NLZMA::CEncoder;
+ Encoder = EncoderSpec;
+ }
+ CSequentialOutStreamImp *outStreamSpec = new CSequentialOutStreamImp;
+ CMyComPtr<ISequentialOutStream> outStream(outStreamSpec);
+ outStreamSpec->Init();
+ RINOK(EncoderSpec->SetCoderProperties(propIDs, props, numProps));
+ RINOK(EncoderSpec->WriteCoderProperties(outStream));
+ if (outStreamSpec->GetSize() != kLzmaPropsSize)
+ return E_FAIL;
+ Header[0] = MY_VER_MAJOR;
+ Header[1] = MY_VER_MINOR;
+ Header[2] = kLzmaPropsSize;
+ Header[3] = 0;
+ memcpy(Header + 4, outStreamSpec->GetBuffer(), kLzmaPropsSize);
+ return S_OK;
+}
+
+HRESULT CLzmaEncoder::Code(ISequentialInStream *inStream, ISequentialOutStream *outStream,
+ const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress)
+{
+ RINOK(WriteStream(outStream, Header, kLzmaHeaderSize));
+ return Encoder->Code(inStream, outStream, inSize, outSize, progress);
+}
+
+
CAddCommon::CAddCommon(const CCompressionMethodMode &options):
_options(options),
_copyCoderSpec(NULL),
_cryptoStreamSpec(0)
- {}
+ {}
static HRESULT GetStreamCRC(ISequentialInStream *inStream, UInt32 &resultCRC)
{
@@ -38,7 +90,7 @@ static HRESULT GetStreamCRC(ISequentialInStream *inStream, UInt32 &resultCRC)
{
UInt32 realProcessedSize;
RINOK(inStream->Read(buffer, kBufferSize, &realProcessedSize));
- if(realProcessedSize == 0)
+ if (realProcessedSize == 0)
{
resultCRC = CRC_GET_DIGEST(crc);
return S_OK;
@@ -87,7 +139,7 @@ HRESULT CAddCommon::Compress(
}
Byte method = 0;
COutStreamReleaser outStreamReleaser;
- for(int i = 0; i < numTestMethods; i++)
+ for (int i = 0; i < numTestMethods; i++)
{
if (inCrcStreamSpec != 0)
RINOK(inCrcStreamSpec->Seek(0, STREAM_SEEK_SET, NULL));
@@ -127,7 +179,7 @@ HRESULT CAddCommon::Compress(
{
case NFileHeader::NCompressionMethod::kStored:
{
- if(_copyCoderSpec == NULL)
+ if (_copyCoderSpec == NULL)
{
_copyCoderSpec = new NCompress::CCopyCoder;
_copyCoder = _copyCoderSpec;
@@ -143,8 +195,41 @@ HRESULT CAddCommon::Compress(
}
default:
{
- if(!_compressEncoder)
+ if (!_compressEncoder)
{
+ if (method == NFileHeader::NCompressionMethod::kLZMA)
+ {
+ CLzmaEncoder *_lzmaEncoder = new CLzmaEncoder();
+ _compressEncoder = _lzmaEncoder;
+ NWindows::NCOM::CPropVariant props[] =
+ {
+ #ifdef COMPRESS_MT
+ _options.NumThreads,
+ #endif
+ _options.Algo,
+ _options.DicSize,
+ _options.NumFastBytes,
+ (BSTR)(const wchar_t *)_options.MatchFinder,
+ _options.NumMatchFinderCycles
+ };
+ PROPID propIDs[] =
+ {
+ #ifdef COMPRESS_MT
+ NCoderPropID::kNumThreads,
+ #endif
+ NCoderPropID::kAlgorithm,
+ NCoderPropID::kDictionarySize,
+ NCoderPropID::kNumFastBytes,
+ NCoderPropID::kMatchFinder,
+ NCoderPropID::kMatchFinderCycles
+ };
+ int numProps = sizeof(propIDs) / sizeof(propIDs[0]);
+ if (!_options.NumMatchFinderCyclesDefined)
+ numProps--;
+ RINOK(_lzmaEncoder->SetCoderProperties(propIDs, props, numProps));
+ }
+ else
+ {
CMethodId methodId;
switch(method)
{
@@ -164,7 +249,7 @@ HRESULT CAddCommon::Compress(
if (method == NFileHeader::NCompressionMethod::kDeflated ||
method == NFileHeader::NCompressionMethod::kDeflated64)
{
- NWindows::NCOM::CPropVariant properties[] =
+ NWindows::NCOM::CPropVariant props[] =
{
_options.Algo,
_options.NumPasses,
@@ -185,12 +270,12 @@ HRESULT CAddCommon::Compress(
_compressEncoder.QueryInterface(IID_ICompressSetCoderProperties, &setCoderProperties);
if (setCoderProperties)
{
- RINOK(setCoderProperties->SetCoderProperties(propIDs, properties, numProps));
+ RINOK(setCoderProperties->SetCoderProperties(propIDs, props, numProps));
}
}
else if (method == NFileHeader::NCompressionMethod::kBZip2)
{
- NWindows::NCOM::CPropVariant properties[] =
+ NWindows::NCOM::CPropVariant props[] =
{
_options.DicSize,
_options.NumPasses
@@ -210,9 +295,10 @@ HRESULT CAddCommon::Compress(
_compressEncoder.QueryInterface(IID_ICompressSetCoderProperties, &setCoderProperties);
if (setCoderProperties)
{
- RINOK(setCoderProperties->SetCoderProperties(propIDs, properties, sizeof(propIDs) / sizeof(propIDs[0])));
+ RINOK(setCoderProperties->SetCoderProperties(propIDs, props, sizeof(propIDs) / sizeof(propIDs[0])));
}
}
+ }
}
CMyComPtr<ISequentialOutStream> outStreamNew;
if (_options.PasswordIsDefined)
diff --git a/CPP/7zip/Archive/Zip/ZipCompressionMode.h b/CPP/7zip/Archive/Zip/ZipCompressionMode.h
index ae29a5a4..de5f5ccd 100755
--- a/CPP/7zip/Archive/Zip/ZipCompressionMode.h
+++ b/CPP/7zip/Archive/Zip/ZipCompressionMode.h
@@ -11,7 +11,7 @@ namespace NZip {
struct CCompressionMethodMode
{
CRecordVector<Byte> MethodSequence;
- // bool MaximizeRatio;
+ UString MatchFinder;
UInt32 Algo;
UInt32 NumPasses;
UInt32 NumFastBytes;
diff --git a/CPP/7zip/Archive/Zip/ZipHandler.cpp b/CPP/7zip/Archive/Zip/ZipHandler.cpp
index aba36b3b..40d131f0 100755
--- a/CPP/7zip/Archive/Zip/ZipHandler.cpp
+++ b/CPP/7zip/Archive/Zip/ZipHandler.cpp
@@ -16,10 +16,12 @@
#include "../../Common/ProgressUtils.h"
#include "../../Common/StreamObjects.h"
+#include "../../Common/StreamUtils.h"
#include "../../Common/CreateCoder.h"
#include "../../Common/FilterCoder.h"
#include "../../Compress/Copy/CopyCoder.h"
+#include "../../Compress/LZMA/LZMADecoder.h"
#include "../Common/ItemNameUtils.h"
#include "../Common/OutStreamWithCRC.h"
@@ -108,13 +110,13 @@ const wchar_t *kMethods[] =
L"Tokenizing",
L"Deflate",
L"Deflate64",
- L"PKImploding",
- L"Unknown",
- L"BZip2"
+ L"PKImploding"
};
const int kNumMethods = sizeof(kMethods) / sizeof(kMethods[0]);
-// const wchar_t *kUnknownMethod = L"Unknown";
+const wchar_t *kBZip2Method = L"BZip2";
+const wchar_t *kLZMAMethod = L"LZMA";
+const wchar_t *kJpegMethod = L"Jpeg";
const wchar_t *kWavPackMethod = L"WavPack";
const wchar_t *kPPMdMethod = L"PPMd";
const wchar_t *kAESMethod = L"AES";
@@ -294,15 +296,23 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val
}
if (methodId < kNumMethods)
method += kMethods[methodId];
- else if (methodId == NFileHeader::NCompressionMethod::kPPMd)
- method += kPPMdMethod;
- else if (methodId == NFileHeader::NCompressionMethod::kWavPack)
- method += kWavPackMethod;
- else
+ else switch (methodId)
{
- wchar_t s[32];
- ConvertUInt64ToString(methodId, s);
- method += s;
+ case NFileHeader::NCompressionMethod::kLZMA:
+ method += kLZMAMethod;
+ if (item.IsLzmaEOS())
+ method += L":EOS";
+ break;
+ case NFileHeader::NCompressionMethod::kBZip2: method += kBZip2Method; break;
+ case NFileHeader::NCompressionMethod::kJpeg: method += kJpegMethod; break;
+ case NFileHeader::NCompressionMethod::kWavPack: method += kWavPackMethod; break;
+ case NFileHeader::NCompressionMethod::kPPMd: method += kPPMdMethod; break;
+ default:
+ {
+ wchar_t s[32];
+ ConvertUInt64ToString(methodId, s);
+ method += s;
+ }
}
prop = method;
break;
@@ -367,6 +377,37 @@ STDMETHODIMP CHandler::Close()
//////////////////////////////////////
// CHandler::DecompressItems
+class CLzmaDecoder:
+ public ICompressCoder,
+ public CMyUnknownImp
+{
+ NCompress::NLZMA::CDecoder *DecoderSpec;
+ CMyComPtr<ICompressCoder> Decoder;
+public:
+ CLzmaDecoder();
+ STDMETHOD(Code)(ISequentialInStream *inStream, ISequentialOutStream *outStream,
+ const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress);
+
+ MY_UNKNOWN_IMP
+};
+
+CLzmaDecoder::CLzmaDecoder()
+{
+ DecoderSpec = new NCompress::NLZMA::CDecoder;
+ Decoder = DecoderSpec;
+}
+
+HRESULT CLzmaDecoder::Code(ISequentialInStream *inStream, ISequentialOutStream *outStream,
+ const UInt64 * /* inSize */, const UInt64 *outSize, ICompressProgressInfo *progress)
+{
+ Byte buf[9];
+ RINOK(ReadStream_FALSE(inStream, buf, 9));
+ if (buf[2] != 5 || buf[3] != 0)
+ return E_NOTIMPL;
+ RINOK(DecoderSpec->SetDecoderProperties2(buf + 4, 5));
+ return Decoder->Code(inStream, outStream, NULL, outSize, progress);
+}
+
struct CMethodItem
{
UInt16 ZipMethod;
@@ -568,6 +609,8 @@ HRESULT CZipDecoder::Decode(
mi.Coder = new NCompress::NShrink::CDecoder;
else if (methodId == NFileHeader::NCompressionMethod::kImploded)
mi.Coder = new NCompress::NImplode::NDecoder::CCoder;
+ else if (methodId == NFileHeader::NCompressionMethod::kLZMA)
+ mi.Coder = new CLzmaDecoder;
else
{
CMethodId szMethodID;
@@ -656,6 +699,12 @@ HRESULT CZipDecoder::Decode(
result = coder->Code(inStreamNew, outStream, NULL, &item.UnPackSize, compressProgress);
if (result == S_FALSE)
return S_OK;
+ if (result == E_NOTIMPL)
+ {
+ res = NArchive::NExtract::NOperationResult::kUnSupportedMethod;
+ return S_OK;
+ }
+
RINOK(result);
}
bool crcOK = true;
diff --git a/CPP/7zip/Archive/Zip/ZipHandlerOut.cpp b/CPP/7zip/Archive/Zip/ZipHandlerOut.cpp
index c493b0c9..ea46e131 100755
--- a/CPP/7zip/Archive/Zip/ZipHandlerOut.cpp
+++ b/CPP/7zip/Archive/Zip/ZipHandlerOut.cpp
@@ -25,16 +25,28 @@ using namespace NTime;
namespace NArchive {
namespace NZip {
-static const UInt32 kDeflateAlgoX1 = 0;
-static const UInt32 kDeflateAlgoX5 = 1;
+static const UInt32 kLzAlgoX1 = 0;
+static const UInt32 kLzAlgoX5 = 1;
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 kDeflateNumFastBytesX1 = 32;
+static const UInt32 kDeflateNumFastBytesX7 = 64;
+static const UInt32 kDeflateNumFastBytesX9 = 128;
+
+static const wchar_t *kLzmaMatchFinderX1 = L"HC4";
+static const wchar_t *kLzmaMatchFinderX5 = L"BT4";
+
+static const UInt32 kLzmaNumFastBytesX1 = 32;
+static const UInt32 kLzmaNumFastBytesX7 = 64;
+
+static const UInt32 kLzmaDicSizeX1 = 1 << 16;
+static const UInt32 kLzmaDicSizeX3 = 1 << 20;
+static const UInt32 kLzmaDicSizeX5 = 1 << 24;
+static const UInt32 kLzmaDicSizeX7 = 1 << 25;
+static const UInt32 kLzmaDicSizeX9 = 1 << 26;
static const UInt32 kBZip2NumPassesX1 = 1;
static const UInt32 kBZip2NumPassesX7 = 2;
@@ -173,24 +185,20 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numIt
{
bool defaultCharWasUsed;
ui.Name = UnicodeStringToMultiByte(name, CP_OEMCP, '_', defaultCharWasUsed);
- tryUtf8 = (!m_ForseLocal && defaultCharWasUsed);
+ tryUtf8 = (!m_ForseLocal && (defaultCharWasUsed ||
+ MultiByteToUnicodeString(ui.Name, CP_OEMCP) != name));
}
if (tryUtf8)
{
- bool needUtf = false;
- for (int i = 0; i < name.Length(); i++)
- if ((unsigned)name[i] >= 0x80)
- {
- needUtf = true;
- break;
- }
- ui.IsUtf8 = needUtf;
+ int i;
+ for (i = 0; i < name.Length() && (unsigned)name[i] < 0x80; i++);
+ ui.IsUtf8 = (i != name.Length());
if (!ConvertUnicodeToUTF8(name, ui.Name))
return E_INVALIDARG;
}
- if (ui.Name.Length() > 0xFFFF)
+ if (ui.Name.Length() >= (1 << 16))
return E_INVALIDARG;
ui.IndexInClient = i;
@@ -272,6 +280,8 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numIt
options.MethodSequence.Add(NFileHeader::NCompressionMethod::kStored);
bool isDeflate = (mainMethod == NFileHeader::NCompressionMethod::kDeflated) ||
(mainMethod == NFileHeader::NCompressionMethod::kDeflated64);
+ bool isLZMA = (mainMethod == NFileHeader::NCompressionMethod::kLZMA);
+ bool isLz = (isLZMA || isDeflate);
bool isBZip2 = (mainMethod == NFileHeader::NCompressionMethod::kBZip2);
options.NumPasses = m_NumPasses;
options.DicSize = m_DicSize;
@@ -282,20 +292,41 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numIt
#ifdef COMPRESS_MT
options.NumThreads = _numThreads;
#endif
- if (isDeflate)
+ if (isLz)
{
- if (options.NumPasses == 0xFFFFFFFF)
- options.NumPasses = (level >= 9 ? kDeflateNumPassesX9 :
- (level >= 7 ? kDeflateNumPassesX7 :
- kDeflateNumPassesX1));
- if (options.NumFastBytes == 0xFFFFFFFF)
- options.NumFastBytes = (level >= 9 ? kNumFastBytesX9 :
- (level >= 7 ? kNumFastBytesX7 :
- kNumFastBytesX1));
+ if (isDeflate)
+ {
+ if (options.NumPasses == 0xFFFFFFFF)
+ options.NumPasses = (level >= 9 ? kDeflateNumPassesX9 :
+ (level >= 7 ? kDeflateNumPassesX7 :
+ kDeflateNumPassesX1));
+ if (options.NumFastBytes == 0xFFFFFFFF)
+ options.NumFastBytes = (level >= 9 ? kDeflateNumFastBytesX9 :
+ (level >= 7 ? kDeflateNumFastBytesX7 :
+ kDeflateNumFastBytesX1));
+ }
+ else if (isLZMA)
+ {
+ if (options.DicSize == 0xFFFFFFFF)
+ options.DicSize =
+ (level >= 9 ? kLzmaDicSizeX9 :
+ (level >= 7 ? kLzmaDicSizeX7 :
+ (level >= 5 ? kLzmaDicSizeX5 :
+ (level >= 3 ? kLzmaDicSizeX3 :
+ kLzmaDicSizeX1))));
+
+ if (options.NumFastBytes == 0xFFFFFFFF)
+ options.NumFastBytes = (level >= 7 ? kLzmaNumFastBytesX7 :
+ kLzmaNumFastBytesX1);
+
+ options.MatchFinder =
+ (level >= 5 ? kLzmaMatchFinderX5 :
+ kLzmaMatchFinderX1);
+ }
+
if (options.Algo == 0xFFFFFFFF)
- options.Algo =
- (level >= 5 ? kDeflateAlgoX5 :
- kDeflateAlgoX1);
+ options.Algo = (level >= 5 ? kLzAlgoX5 :
+ kLzAlgoX1);
}
if (isBZip2)
{
@@ -343,18 +374,14 @@ STDMETHODIMP CHandler::SetProperties(const wchar_t **names, const PROPVARIANT *v
{
if (prop.vt == VT_BSTR)
{
- UString valueString = prop.bstrVal;
- valueString.MakeUpper();
- if (valueString == L"COPY")
- m_MainMethod = NFileHeader::NCompressionMethod::kStored;
- else if (valueString == L"DEFLATE")
- m_MainMethod = NFileHeader::NCompressionMethod::kDeflated;
- else if (valueString == L"DEFLATE64")
- m_MainMethod = NFileHeader::NCompressionMethod::kDeflated64;
- else if (valueString == L"BZIP2")
- m_MainMethod = NFileHeader::NCompressionMethod::kBZip2;
- else
- return E_INVALIDARG;
+ UString m = prop.bstrVal;
+ m.MakeUpper();
+ if (m == L"COPY") m_MainMethod = NFileHeader::NCompressionMethod::kStored;
+ else if (m == L"DEFLATE") m_MainMethod = NFileHeader::NCompressionMethod::kDeflated;
+ else if (m == L"DEFLATE64") m_MainMethod = NFileHeader::NCompressionMethod::kDeflated64;
+ else if (m == L"BZIP2") m_MainMethod = NFileHeader::NCompressionMethod::kBZip2;
+ else if (m == L"LZMA") m_MainMethod = NFileHeader::NCompressionMethod::kLZMA;
+ else return E_INVALIDARG;
}
else if (prop.vt == VT_UI4)
{
@@ -364,6 +391,7 @@ STDMETHODIMP CHandler::SetProperties(const wchar_t **names, const PROPVARIANT *v
case NFileHeader::NCompressionMethod::kDeflated:
case NFileHeader::NCompressionMethod::kDeflated64:
case NFileHeader::NCompressionMethod::kBZip2:
+ case NFileHeader::NCompressionMethod::kLZMA:
m_MainMethod = (Byte)prop.ulVal;
break;
default:
@@ -414,7 +442,7 @@ STDMETHODIMP CHandler::SetProperties(const wchar_t **names, const PROPVARIANT *v
}
else if (name.Left(2) == L"FB")
{
- UInt32 num = kNumFastBytesX9;
+ UInt32 num = kDeflateNumFastBytesX9;
RINOK(ParsePropValue(name.Mid(2), prop, num));
m_NumFastBytes = num;
}
@@ -433,25 +461,25 @@ STDMETHODIMP CHandler::SetProperties(const wchar_t **names, const PROPVARIANT *v
}
else if (name.Left(1) == L"A")
{
- UInt32 num = kDeflateAlgoX5;
+ UInt32 num = kLzAlgoX5;
RINOK(ParsePropValue(name.Mid(1), prop, num));
m_Algo = num;
}
else if (name.CompareNoCase(L"TC") == 0)
- return SetBoolProperty(m_WriteNtfsTimeExtra, prop);
+ {
+ RINOK(SetBoolProperty(m_WriteNtfsTimeExtra, prop));
+ }
else if (name.CompareNoCase(L"CL") == 0)
{
RINOK(SetBoolProperty(m_ForseLocal, prop));
if (m_ForseLocal)
m_ForseUtf8 = false;
- return S_OK;
}
else if (name.CompareNoCase(L"CU") == 0)
{
RINOK(SetBoolProperty(m_ForseUtf8, prop));
if (m_ForseUtf8)
m_ForseLocal = false;
- return S_OK;
}
else
return E_INVALIDARG;
diff --git a/CPP/7zip/Archive/Zip/ZipHeader.h b/CPP/7zip/Archive/Zip/ZipHeader.h
index 3af72369..e974079d 100755
--- a/CPP/7zip/Archive/Zip/ZipHeader.h
+++ b/CPP/7zip/Archive/Zip/ZipHeader.h
@@ -69,6 +69,10 @@ namespace NFileHeader
kPKImploding = 10,
kBZip2 = 12,
+ kLZMA = 14,
+ kTerse = 18,
+ kLz77 = 19,
+ kJpeg = 0x60,
kWavPack = 0x61,
kPPMd = 0x62,
kWzAES = 0x63
@@ -170,6 +174,7 @@ namespace NFileHeader
namespace NFlags
{
const int kEncrypted = 1 << 0;
+ const int kLzmaEOS = 1 << 1;
const int kDescriptorUsedMask = 1 << 3;
const int kStrongEncrypted = 1 << 6;
const int kUtf8 = 1 << 11;
diff --git a/CPP/7zip/Archive/Zip/ZipItem.cpp b/CPP/7zip/Archive/Zip/ZipItem.cpp
index 9bbf3882..03472d85 100755
--- a/CPP/7zip/Archive/Zip/ZipItem.cpp
+++ b/CPP/7zip/Archive/Zip/ZipItem.cpp
@@ -51,20 +51,6 @@ bool CExtraSubBlock::ExtractNtfsTime(int index, FILETIME &ft) const
return false;
}
-bool CLocalItem::IsImplodeBigDictionary() const
-{
- if (CompressionMethod != NFileHeader::NCompressionMethod::kImploded)
- throw 12312212;
- return (Flags & NFileHeader::NFlags::kImplodeDictionarySizeMask) != 0;
-}
-
-bool CLocalItem::IsImplodeLiteralsOn() const
-{
- if (CompressionMethod != NFileHeader::NCompressionMethod::kImploded)
- throw 12312213;
- return (Flags & NFileHeader::NFlags::kImplodeLiteralsOnMask) != 0;
-}
-
bool CLocalItem::IsDir() const
{
return NItemName::HasTailSlash(Name, GetCodePage());
diff --git a/CPP/7zip/Archive/Zip/ZipItem.h b/CPP/7zip/Archive/Zip/ZipItem.h
index bc1b27c0..c41ba8c8 100755
--- a/CPP/7zip/Archive/Zip/ZipItem.h
+++ b/CPP/7zip/Archive/Zip/ZipItem.h
@@ -188,8 +188,7 @@ public:
bool IsEncrypted() const { return (Flags & NFileHeader::NFlags::kEncrypted) != 0; }
bool IsStrongEncrypted() const { return IsEncrypted() && (Flags & NFileHeader::NFlags::kStrongEncrypted) != 0; };
- bool IsImplodeBigDictionary() const;
- bool IsImplodeLiteralsOn() const;
+ bool IsLzmaEOS() const { return (Flags & NFileHeader::NFlags::kLzmaEOS) != 0; }
bool IsDir() const;
bool IgnoreItem() const { return false; }
diff --git a/CPP/7zip/Archive/Zip/ZipUpdate.cpp b/CPP/7zip/Archive/Zip/ZipUpdate.cpp
index 3294ad78..403b5efe 100755
--- a/CPP/7zip/Archive/Zip/ZipUpdate.cpp
+++ b/CPP/7zip/Archive/Zip/ZipUpdate.cpp
@@ -1,4 +1,4 @@
-// ZipUpdate.cpp
+lzma// ZipUpdate.cpp
#include "StdAfx.h"
@@ -568,6 +568,14 @@ static HRESULT Update2(
if (numThreads <= 1)
mtMode = false;
}
+ if (method == NFileHeader::NCompressionMethod::kLZMA)
+ {
+ UInt32 numLZMAThreads = (options->Algo > 0 ? 2 : 1);
+ numThreads /= numLZMAThreads;
+ options2.NumThreads = numLZMAThreads;
+ if (numThreads <= 1)
+ mtMode = false;
+ }
}
if (!mtMode)
diff --git a/CPP/7zip/Bundles/SFXCon/Main.cpp b/CPP/7zip/Bundles/SFXCon/Main.cpp
index 5ae6878d..ac8c1cdf 100755
--- a/CPP/7zip/Bundles/SFXCon/Main.cpp
+++ b/CPP/7zip/Bundles/SFXCon/Main.cpp
@@ -5,27 +5,30 @@
#include "Common/MyInitGuid.h"
#include "Common/CommandLineParser.h"
-#include "Common/StdOutStream.h"
-#include "Common/Wildcard.h"
-#include "Common/StringConvert.h"
#include "Common/MyCom.h"
#include "Common/MyException.h"
+#include "Common/StdOutStream.h"
+#include "Common/StringConvert.h"
+#include "Common/Wildcard.h"
-#include "Windows/FileDir.h"
-#include "Windows/FileName.h"
#include "Windows/Defs.h"
+#include "Windows/FileName.h"
+#ifdef _WIN32
+#include "Windows/DLL.h"
+#include "Windows/FileDir.h"
+#endif
#include "../../IPassword.h"
#include "../../ICoder.h"
-#include "../../UI/Common/OpenArchive.h"
#include "../../UI/Common/DefaultName.h"
#include "../../UI/Common/ExitCode.h"
#include "../../UI/Common/Extract.h"
+#include "../../UI/Common/OpenArchive.h"
+#include "../../UI/Console/ExtractCallbackConsole.h"
#include "../../UI/Console/List.h"
#include "../../UI/Console/OpenCallbackConsole.h"
-#include "../../UI/Console/ExtractCallbackConsole.h"
#include "../../MyVersion.h"
@@ -40,11 +43,6 @@ static const char *kCopyrightString =
static const int kNumSwitches = 6;
-#ifdef _WIN32
-static const wchar_t *kDefaultExt = L".exe";
-static const int kDefaultExtLength = 4;
-#endif
-
namespace NKey {
enum Enum
{
@@ -271,7 +269,25 @@ int Main2(
GetArguments(numArguments, arguments, commandStrings);
#endif
- UString archiveName = commandStrings.Front();
+ #ifdef _WIN32
+
+ UString arcPath;
+ {
+ UString path;
+ NDLL::MyGetModuleFileName(NULL, path);
+ int fileNamePartStartIndex;
+ if (!NDirectory::MyGetFullPathName(path, arcPath, fileNamePartStartIndex))
+ {
+ g_StdOut << "GetFullPathName Error";
+ return NExitCode::kFatalError;
+ }
+ }
+
+ #else
+
+ UString arcPath = commandStrings.Front();
+
+ #endif
commandStrings.Delete(0);
@@ -318,11 +334,6 @@ int Main2(
bool yesToAll = parser[NKey::kYes].ThereIs;
- #ifdef _WIN32
- if (archiveName.Right(kDefaultExtLength).CompareNoCase(kDefaultExt) != 0)
- archiveName += kDefaultExt;
- #endif
-
// NExtractMode::EEnum extractMode;
// bool isExtractGroupCommand = command.IsFromExtractGroup(extractMode);
@@ -333,13 +344,13 @@ int Main2(
password = parser[NKey::kPassword].PostStrings[0];
NFind::CFileInfoW archiveFileInfo;
- if (!NFind::FindFile(archiveName, archiveFileInfo))
+ if (!NFind::FindFile(arcPath, archiveFileInfo))
throw kCantFindSFX;
if (archiveFileInfo.IsDir())
throw kCantFindSFX;
UString outputDir;
- if(parser[NKey::kOutputDir].ThereIs)
+ if (parser[NKey::kOutputDir].ThereIs)
{
outputDir = parser[NKey::kOutputDir].PostStrings[0];
NName::NormalizeDirPathPrefix(outputDir);
@@ -347,8 +358,8 @@ int Main2(
{
UStringVector v1, v2;
- v1.Add(archiveName);
- v2.Add(archiveName);
+ v1.Add(arcPath);
+ v2.Add(arcPath);
const NWildcard::CCensorNode &wildcardCensorHead =
wildcardCensor.Pairs.Front().Head;
diff --git a/CPP/7zip/Bundles/SFXCon/SFXCon.dsp b/CPP/7zip/Bundles/SFXCon/SFXCon.dsp
index e272d88d..7d1f73a2 100755
--- a/CPP/7zip/Bundles/SFXCon/SFXCon.dsp
+++ b/CPP/7zip/Bundles/SFXCon/SFXCon.dsp
@@ -381,6 +381,14 @@ SOURCE=..\..\Crypto\Hash\RotateDefs.h
# PROP Default_Filter ""
# Begin Source File
+SOURCE=..\..\..\Windows\DLL.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\DLL.h
+# End Source File
+# Begin Source File
+
SOURCE=..\..\..\Windows\Error.cpp
# End Source File
# Begin Source File
diff --git a/CPP/7zip/Bundles/SFXCon/makefile b/CPP/7zip/Bundles/SFXCon/makefile
index c32b11cd..4bfe7f3d 100755
--- a/CPP/7zip/Bundles/SFXCon/makefile
+++ b/CPP/7zip/Bundles/SFXCon/makefile
@@ -29,6 +29,7 @@ COMMON_OBJS = \
$O\Wildcard.obj \
WIN_OBJS = \
+ $O\DLL.obj \
$O\Error.obj \
$O\FileDir.obj \
$O\FileFind.obj \
diff --git a/CPP/7zip/Bundles/SFXSetup/ExtractCallback.cpp b/CPP/7zip/Bundles/SFXSetup/ExtractCallback.cpp
index f2af88e6..5ec72dc4 100755
--- a/CPP/7zip/Bundles/SFXSetup/ExtractCallback.cpp
+++ b/CPP/7zip/Bundles/SFXSetup/ExtractCallback.cpp
@@ -106,8 +106,6 @@ STDMETHODIMP CExtractCallbackImp::GetStream(UInt32 index,
}
_filePath = fullPath;
- // m_CurrentFilePath = GetSystemString(fullPath, _codePage);
-
if (askExtractMode == NArchive::NExtract::NAskMode::kExtract)
{
NCOM::CPropVariant prop;
@@ -135,14 +133,9 @@ STDMETHODIMP CExtractCallbackImp::GetStream(UInt32 index,
RINOK(_archiveHandler->GetProperty(index, kpidMTime, &prop));
switch(prop.vt)
{
- case VT_EMPTY:
- _processedFileInfo.MTime = _defaultMTime;
- break;
- case VT_FILETIME:
- _processedFileInfo.MTime = prop.filetime;
- break;
- default:
- return E_FAIL;
+ case VT_EMPTY: _processedFileInfo.MTime = _defaultMTime; break;
+ case VT_FILETIME: _processedFileInfo.MTime = prop.filetime; break;
+ default: return E_FAIL;
}
UStringVector pathParts;
@@ -168,6 +161,8 @@ STDMETHODIMP CExtractCallbackImp::GetStream(UInt32 index,
if (isAnti)
NDirectory::MyRemoveDirectory(_diskFilePath);
+ else
+ NDirectory::SetDirTime(_diskFilePath, NULL, NULL, &_processedFileInfo.MTime);
return S_OK;
}
@@ -204,13 +199,7 @@ STDMETHODIMP CExtractCallbackImp::GetStream(UInt32 index,
STDMETHODIMP CExtractCallbackImp::PrepareOperation(Int32 askExtractMode)
{
- _extractMode = false;
- switch (askExtractMode)
- {
- case NArchive::NExtract::NAskMode::kExtract:
- _extractMode = true;
- break;
- };
+ _extractMode = (askExtractMode == NArchive::NExtract::NAskMode::kExtract);
return S_OK;
}
diff --git a/CPP/7zip/Compress/LZMA/LZMADecoder.cpp b/CPP/7zip/Compress/LZMA/LZMADecoder.cpp
index 545b8f1d..ae5da5de 100755
--- a/CPP/7zip/Compress/LZMA/LZMADecoder.cpp
+++ b/CPP/7zip/Compress/LZMA/LZMADecoder.cpp
@@ -18,6 +18,7 @@ static HRESULT SResToHRESULT(SRes res)
case SZ_OK: return S_OK;
case SZ_ERROR_MEM: return E_OUTOFMEMORY;
case SZ_ERROR_PARAM: return E_INVALIDARG;
+ case SZ_ERROR_UNSUPPORTED: return E_NOTIMPL;
// case SZ_ERROR_PROGRESS: return E_ABORT;
case SZ_ERROR_DATA: return S_FALSE;
}
@@ -29,7 +30,7 @@ namespace NLZMA {
static const UInt32 kInBufSize = 1 << 20;
-CDecoder::CDecoder(): _inBuf(0), _outSizeDefined(false)
+CDecoder::CDecoder(): _inBuf(0), _outSizeDefined(false), FinishStream(false)
{
LzmaDec_Construct(&_state);
}
@@ -104,10 +105,8 @@ STDMETHODIMP CDecoder::Code(ISequentialInStream *inStream,
if (rem < curSize)
{
curSize = (SizeT)rem;
- /*
- // finishMode = LZMA_FINISH_END;
- we can't use LZMA_FINISH_END here to allow partial decoding
- */
+ if (FinishStream)
+ finishMode = LZMA_FINISH_END;
}
}
diff --git a/CPP/7zip/Compress/LZMA/LZMADecoder.h b/CPP/7zip/Compress/LZMA/LZMADecoder.h
index fa140e47..40dc3f36 100755
--- a/CPP/7zip/Compress/LZMA/LZMADecoder.h
+++ b/CPP/7zip/Compress/LZMA/LZMADecoder.h
@@ -65,6 +65,8 @@ public:
STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize);
#endif
+ bool FinishStream;
+
CDecoder();
virtual ~CDecoder();
diff --git a/CPP/7zip/Compress/LZMA_Alone/AloneLZMA.dsp b/CPP/7zip/Compress/LZMA_Alone/AloneLZMA.dsp
index a09c3069..abfbb237 100755
--- a/CPP/7zip/Compress/LZMA_Alone/AloneLZMA.dsp
+++ b/CPP/7zip/Compress/LZMA_Alone/AloneLZMA.dsp
@@ -179,42 +179,6 @@ SOURCE=..\LZMA\LZMAEncoder.cpp
SOURCE=..\LZMA\LZMAEncoder.h
# End Source File
# End Group
-# Begin Group "RangeCoder"
-
-# PROP Default_Filter ""
-# Begin Source File
-
-SOURCE=..\RangeCoder\RangeCoder.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\RangeCoder\RangeCoderBit.cpp
-# End Source File
-# Begin Source File
-
-SOURCE=..\RangeCoder\RangeCoderBit.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\RangeCoder\RangeCoderBitTree.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\RangeCoder\RangeCoderOpt.h
-# End Source File
-# End Group
-# Begin Group "LZ"
-
-# PROP Default_Filter ""
-# Begin Source File
-
-SOURCE=..\LZ\LZOutWindow.cpp
-# End Source File
-# Begin Source File
-
-SOURCE=..\LZ\LZOutWindow.h
-# End Source File
-# End Group
# End Group
# Begin Group "Windows"
diff --git a/CPP/7zip/Compress/LZMA_Alone/LzmaAlone.cpp b/CPP/7zip/Compress/LZMA_Alone/LzmaAlone.cpp
index 1afbec97..d6ead3f4 100755
--- a/CPP/7zip/Compress/LZMA_Alone/LzmaAlone.cpp
+++ b/CPP/7zip/Compress/LZMA_Alone/LzmaAlone.cpp
@@ -31,11 +31,9 @@
#include "../../../Windows/System.h"
#endif
-#include "../../MyVersion.h"
-
-
extern "C"
{
+ #include "../../../../C/7zVersion.h"
#include "../../../../C/Alloc.h"
#include "../../../../C/LzmaUtil/Lzma86Dec.h"
#include "../../../../C/LzmaUtil/Lzma86Enc.h"
@@ -64,13 +62,13 @@ enum Enum
{
kHelp1 = 0,
kHelp2,
- kMode,
- kDictionary,
- kFastBytes,
- kMatchFinderCycles,
- kLitContext,
- kLitPos,
- kPosBits,
+ kAlgo,
+ kDict,
+ kFb,
+ kMc,
+ kLc,
+ kLp,
+ kPb,
kMatchFinder,
kMultiThread,
kEOS,
@@ -109,7 +107,7 @@ static void PrintHelp()
" b: Benchmark\n"
"<Switches>\n"
" -a{N}: set compression mode - [0, 1], default: 1 (max)\n"
- " -d{N}: set dictionary - [12, 30], default: 23 (8MB)\n"
+ " -d{N}: set dictionary size - [12, 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"
@@ -157,6 +155,13 @@ static bool GetNumber(const wchar_t *s, UInt32 &value)
return true;
}
+static void ParseUInt32(const CParser &parser, int index, UInt32 &res)
+{
+ if (parser[index].ThereIs)
+ if (!GetNumber(parser[index].PostStrings[0], res))
+ IncorrectCommand();
+}
+
int main2(int n, const char *args[])
{
#ifdef _WIN32
@@ -202,15 +207,15 @@ int main2(int n, const char *args[])
IncorrectCommand();
const UString &command = nonSwitchStrings[paramIndex++];
- bool dictionaryIsDefined = false;
- UInt32 dictionary = (UInt32)-1;
- if(parser[NKey::kDictionary].ThereIs)
+ bool dictDefined = false;
+ UInt32 dict = (UInt32)-1;
+ if(parser[NKey::kDict].ThereIs)
{
UInt32 dicLog;
- if (!GetNumber(parser[NKey::kDictionary].PostStrings[0], dicLog))
+ if (!GetNumber(parser[NKey::kDict].PostStrings[0], dicLog))
IncorrectCommand();
- dictionary = 1 << dicLog;
- dictionaryIsDefined = true;
+ dict = 1 << dicLog;
+ dictDefined = true;
}
UString mf = L"BT4";
if (parser[NKey::kMatchFinder].ThereIs)
@@ -240,7 +245,7 @@ int main2(int n, const char *args[])
if (!GetNumber(nonSwitchStrings[paramIndex++], numIterations))
numIterations = kNumDefaultItereations;
}
- return LzmaBenchCon(stderr, numIterations, numThreads, dictionary);
+ return LzmaBenchCon(stderr, numIterations, numThreads, dict);
}
if (numThreads == (UInt32)-1)
@@ -334,10 +339,10 @@ int main2(int n, const char *args[])
if (outBuffer == 0)
throw kCantAllocate;
}
- if (!dictionaryIsDefined)
- dictionary = 1 << 23;
+ if (!dictDefined)
+ dict = 1 << 23;
int res = Lzma86_Encode(outBuffer, &outSize, inBuffer, inSize,
- 5, dictionary, parser[NKey::kFilter86].PostCharIndex == 0 ? SZ_FILTER_YES : SZ_FILTER_AUTO);
+ 5, dict, parser[NKey::kFilter86].PostCharIndex == 0 ? SZ_FILTER_YES : SZ_FILTER_AUTO);
if (res != 0)
{
fprintf(stderr, "\nEncoder error = %d\n", (int)res);
@@ -378,42 +383,30 @@ int main2(int n, const char *args[])
NCompress::NLZMA::CEncoder *encoderSpec = new NCompress::NLZMA::CEncoder;
CMyComPtr<ICompressCoder> encoder = encoderSpec;
- if (!dictionaryIsDefined)
- dictionary = 1 << 23;
+ if (!dictDefined)
+ dict = 1 << 23;
- UInt32 posStateBits = 2;
- UInt32 litContextBits = 3; // for normal files
- // UInt32 litContextBits = 0; // for 32-bit data
- UInt32 litPosBits = 0;
- // UInt32 litPosBits = 2; // for 32-bit data
- UInt32 algorithm = 1;
- UInt32 numFastBytes = 128;
- UInt32 matchFinderCycles = 16 + numFastBytes / 2;
- bool matchFinderCyclesDefined = false;
+ UInt32 pb = 2;
+ UInt32 lc = 3; // = 0; for 32-bit data
+ UInt32 lp = 0; // = 2; for 32-bit data
+ UInt32 algo = 1;
+ UInt32 fb = 128;
+ UInt32 mc = 16 + fb / 2;
+ bool mcDefined = false;
bool eos = parser[NKey::kEOS].ThereIs || stdInMode;
- if(parser[NKey::kMode].ThereIs)
- if (!GetNumber(parser[NKey::kMode].PostStrings[0], algorithm))
- IncorrectCommand();
-
- if(parser[NKey::kFastBytes].ThereIs)
- if (!GetNumber(parser[NKey::kFastBytes].PostStrings[0], numFastBytes))
- IncorrectCommand();
- matchFinderCyclesDefined = parser[NKey::kMatchFinderCycles].ThereIs;
- if (matchFinderCyclesDefined)
- if (!GetNumber(parser[NKey::kMatchFinderCycles].PostStrings[0], matchFinderCycles))
- IncorrectCommand();
- if(parser[NKey::kLitContext].ThereIs)
- if (!GetNumber(parser[NKey::kLitContext].PostStrings[0], litContextBits))
- IncorrectCommand();
- if(parser[NKey::kLitPos].ThereIs)
- if (!GetNumber(parser[NKey::kLitPos].PostStrings[0], litPosBits))
+ ParseUInt32(parser, NKey::kAlgo, algo);
+ ParseUInt32(parser, NKey::kFb, fb);
+ ParseUInt32(parser, NKey::kLc, lc);
+ ParseUInt32(parser, NKey::kLp, lp);
+ ParseUInt32(parser, NKey::kPb, pb);
+
+ mcDefined = parser[NKey::kMc].ThereIs;
+ if (mcDefined)
+ if (!GetNumber(parser[NKey::kMc].PostStrings[0], mc))
IncorrectCommand();
- if(parser[NKey::kPosBits].ThereIs)
- if (!GetNumber(parser[NKey::kPosBits].PostStrings[0], posStateBits))
- IncorrectCommand();
-
+
PROPID propIDs[] =
{
NCoderPropID::kDictionarySize,
@@ -429,35 +422,35 @@ int main2(int n, const char *args[])
};
const int kNumPropsMax = sizeof(propIDs) / sizeof(propIDs[0]);
- PROPVARIANT properties[kNumPropsMax];
+ PROPVARIANT props[kNumPropsMax];
for (int p = 0; p < 6; p++)
- properties[p].vt = VT_UI4;
+ props[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;
+ props[0].ulVal = (UInt32)dict;
+ props[1].ulVal = (UInt32)pb;
+ props[2].ulVal = (UInt32)lc;
+ props[3].ulVal = (UInt32)lp;
+ props[4].ulVal = (UInt32)algo;
+ props[5].ulVal = (UInt32)fb;
- properties[6].vt = VT_BSTR;
- properties[6].bstrVal = (BSTR)(const wchar_t *)mf;
+ props[6].vt = VT_BSTR;
+ props[6].bstrVal = (BSTR)(const wchar_t *)mf;
- properties[7].vt = VT_BOOL;
- properties[7].boolVal = eos ? VARIANT_TRUE : VARIANT_FALSE;
+ props[7].vt = VT_BOOL;
+ props[7].boolVal = eos ? VARIANT_TRUE : VARIANT_FALSE;
- properties[8].vt = VT_UI4;
- properties[8].ulVal = (UInt32)numThreads;
+ props[8].vt = VT_UI4;
+ props[8].ulVal = (UInt32)numThreads;
// it must be last in property list
- properties[9].vt = VT_UI4;
- properties[9].ulVal = (UInt32)matchFinderCycles;
+ props[9].vt = VT_UI4;
+ props[9].ulVal = (UInt32)mc;
int numProps = kNumPropsMax;
- if (!matchFinderCyclesDefined)
+ if (!mcDefined)
numProps--;
- if (encoderSpec->SetCoderProperties(propIDs, properties, numProps) != S_OK)
+ if (encoderSpec->SetCoderProperties(propIDs, props, numProps) != S_OK)
IncorrectCommand();
encoderSpec->WriteCoderProperties(outStream);
@@ -491,6 +484,7 @@ int main2(int n, const char *args[])
{
NCompress::NLZMA::CDecoder *decoderSpec = new NCompress::NLZMA::CDecoder;
CMyComPtr<ICompressCoder> decoder = decoderSpec;
+ decoderSpec->FinishStream = true;
const UInt32 kPropertiesSize = 5;
Byte header[kPropertiesSize + 8];
if (ReadStream_FALSE(inStream, header, kPropertiesSize + 8) != S_OK)
diff --git a/CPP/7zip/MyVersion.h b/CPP/7zip/MyVersion.h
index 31b8ea3b..70657739 100755
--- a/CPP/7zip/MyVersion.h
+++ b/CPP/7zip/MyVersion.h
@@ -1,8 +1,8 @@
#define MY_VER_MAJOR 4
-#define MY_VER_MINOR 60
+#define MY_VER_MINOR 61
#define MY_VER_BUILD 0
-#define MY_VERSION " 4.60 beta"
-#define MY_7ZIP_VERSION "7-Zip 4.60 beta"
-#define MY_DATE "2008-08-19"
+#define MY_VERSION "4.61 beta"
+#define MY_7ZIP_VERSION "7-Zip 4.61 beta"
+#define MY_DATE "2008-11-23"
#define MY_COPYRIGHT "Copyright (c) 1999-2008 Igor Pavlov"
#define MY_VERSION_COPYRIGHT_DATE MY_VERSION " " MY_COPYRIGHT " " MY_DATE
diff --git a/CPP/7zip/UI/Common/DefaultName.cpp b/CPP/7zip/UI/Common/DefaultName.cpp
index 020cb50a..4335e273 100755
--- a/CPP/7zip/UI/Common/DefaultName.cpp
+++ b/CPP/7zip/UI/Common/DefaultName.cpp
@@ -4,8 +4,6 @@
#include "DefaultName.h"
-static const wchar_t *kEmptyFileAlias = L"[Content]";
-
static UString GetDefaultName3(const UString &fileName,
const UString &extension, const UString &addSubExtension)
{
@@ -21,7 +19,11 @@ static UString GetDefaultName3(const UString &fileName,
int dotPos = fileName.ReverseFind(L'.');
if (dotPos > 0)
return fileName.Left(dotPos) + addSubExtension;
- return kEmptyFileAlias;
+
+ if (addSubExtension.IsEmpty())
+ return fileName + L"~";
+ else
+ return fileName + addSubExtension;
}
UString GetDefaultName2(const UString &fileName,
diff --git a/CPP/7zip/UI/Common/UpdatePair.cpp b/CPP/7zip/UI/Common/UpdatePair.cpp
index 26a1a8de..f6727cbf 100755
--- a/CPP/7zip/UI/Common/UpdatePair.cpp
+++ b/CPP/7zip/UI/Common/UpdatePair.cpp
@@ -39,25 +39,23 @@ static int MyCompareTime(NFileTimeType::EEnum fileTimeType, const FILETIME &time
}
static const wchar_t *kDuplicateFileNameMessage = L"Duplicate filename:";
+static const wchar_t *kNotCensoredCollisionMessaged = L"Internal file name collision (file on disk, file in archive):";
-/*
-static const char *kNotCensoredCollisionMessaged = "Internal file name collision:\n";
-static const char *kSameTimeChangedSizeCollisionMessaged =
- "Collision between files with same date/time and different sizes:\n";
-*/
+static void ThrowError(const UString &message, const UString &s1, const UString &s2)
+{
+ UString m = message;
+ m += L'\n';
+ m += s1;
+ m += L'\n';
+ m += s2;
+ throw m;
+}
static void TestDuplicateString(const UStringVector &strings, const CIntVector &indices)
{
for(int i = 0; i + 1 < indices.Size(); i++)
if (CompareFileNames(strings[indices[i]], strings[indices[i + 1]]) == 0)
- {
- UString message = kDuplicateFileNameMessage;
- message += L"\n";
- message += strings[indices[i]];
- message += L"\n";
- message += strings[indices[i + 1]];
- throw message;
- }
+ ThrowError(kDuplicateFileNameMessage, strings[indices[i]], strings[indices[i + 1]]);
}
void GetUpdatePairInfoList(
@@ -116,7 +114,7 @@ void GetUpdatePairInfoList(
else
{
if (!ai.Censored)
- throw 1082022;
+ ThrowError(kNotCensoredCollisionMessaged, dirNames[dirIndex2], ai.Name);
pair.DirIndex = dirIndex2;
pair.ArcIndex = arcIndex2;
switch (MyCompareTime(
diff --git a/CPP/7zip/UI/FileManager/PanelItemOpen.cpp b/CPP/7zip/UI/FileManager/PanelItemOpen.cpp
index afb376d0..ed8813c7 100755
--- a/CPP/7zip/UI/FileManager/PanelItemOpen.cpp
+++ b/CPP/7zip/UI/FileManager/PanelItemOpen.cpp
@@ -164,6 +164,8 @@ static const wchar_t *kStartExtensions[] =
L"docx", L"docm", L"dotx", L"dotm", L"xlsx", L"xlsm", L"xltx", L"xltm", L"xlsb",
L"xlam", L"pptx", L"pptm", L"potx", L"potm", L"ppam", L"ppsx", L"ppsm", L"xsn",
+ L"dwf",
+
L"odt", L"ods",
L"wb3",
L"pdf"
diff --git a/CPP/7zip/UI/FileManager/RootFolder.cpp b/CPP/7zip/UI/FileManager/RootFolder.cpp
index 0dec5412..1cb71e5f 100755
--- a/CPP/7zip/UI/FileManager/RootFolder.cpp
+++ b/CPP/7zip/UI/FileManager/RootFolder.cpp
@@ -81,17 +81,24 @@ STDMETHODIMP CRootFolder::GetProperty(UInt32 itemIndex, PROPID propID, PROPVARIA
return S_OK;
}
+typedef BOOL (WINAPI *SHGetSpecialFolderPathWp)(HWND hwnd, LPWSTR pszPath, int csidl, BOOL fCreate);
+typedef BOOL (WINAPI *SHGetSpecialFolderPathAp)(HWND hwnd, LPSTR pszPath, int csidl, BOOL fCreate);
+
UString GetMyDocsPath()
{
UString us;
WCHAR s[MAX_PATH + 1];
- if (SHGetSpecialFolderPathW(0, s, CSIDL_PERSONAL, FALSE))
+ SHGetSpecialFolderPathWp getW = (SHGetSpecialFolderPathWp)
+ ::GetProcAddress(::GetModuleHandleA("shell32.dll"), "SHGetSpecialFolderPathW");
+ if (getW && getW(0, s, CSIDL_PERSONAL, FALSE))
us = s;
#ifndef _UNICODE
else
{
+ SHGetSpecialFolderPathAp getA = (SHGetSpecialFolderPathAp)
+ ::GetProcAddress(::GetModuleHandleA("shell32.dll"), "SHGetSpecialFolderPathA");
CHAR s2[MAX_PATH + 1];
- if (SHGetSpecialFolderPathA(0, s2, CSIDL_PERSONAL, FALSE))
+ if (getA && getA(0, s2, CSIDL_PERSONAL, FALSE))
us = GetUnicodeString(s2);
}
#endif
diff --git a/CPP/7zip/UI/GUI/CompressDialog.cpp b/CPP/7zip/UI/GUI/CompressDialog.cpp
index 468c87c8..69587f3a 100755
--- a/CPP/7zip/UI/GUI/CompressDialog.cpp
+++ b/CPP/7zip/UI/GUI/CompressDialog.cpp
@@ -146,7 +146,8 @@ static EMethodID g_ZipMethods[] =
{
kDeflate,
kDeflate64,
- kBZip2
+ kBZip2,
+ kLZMA
};
static EMethodID g_GZipMethods[] =
@@ -173,6 +174,8 @@ struct CFormatInfo
bool EncryptFileNames;
};
+#define METHODS_PAIR(x) x, MY_SIZE_OF_ARRAY(x)
+
static const CFormatInfo g_Formats[] =
{
{
@@ -184,26 +187,25 @@ static const CFormatInfo g_Formats[] =
{
k7zFormat,
(1 << 0) | (1 << 1) | (1 << 3) | (1 << 5) | (1 << 7) | (1 << 9),
- g_7zMethods, MY_SIZE_OF_ARRAY(g_7zMethods),
+ METHODS_PAIR(g_7zMethods),
true, true, true, true, true, true
},
{
L"Zip",
(1 << 0) | (1 << 1) | (1 << 3) | (1 << 5) | (1 << 7) | (1 << 9),
- g_ZipMethods, MY_SIZE_OF_ARRAY(g_ZipMethods) ,
+ METHODS_PAIR(g_ZipMethods),
false, false, true, false, true, false
},
{
L"GZip",
(1 << 1) | (1 << 5) | (1 << 7) | (1 << 9),
- g_GZipMethods, MY_SIZE_OF_ARRAY(g_GZipMethods),
+ METHODS_PAIR(g_GZipMethods),
false, false, false, false, false, false
},
{
L"BZip2",
(1 << 1) | (1 << 3) | (1 << 5) | (1 << 7) | (1 << 9),
- g_BZip2Methods,
- MY_SIZE_OF_ARRAY(g_BZip2Methods),
+ METHODS_PAIR(g_BZip2Methods),
false, false, true, false, false
},
{
@@ -1289,8 +1291,12 @@ UInt64 CCompressDialog::GetMemoryUsage(UInt32 dictionary, UInt64 &decompressMemo
UInt32 numThreads = GetNumThreads2();
if (IsZipFormat())
{
- if (numThreads > 1)
- size += (UInt64)numThreads << 25;
+ UInt32 numSubThreads = 1;
+ if (GetMethodID() == kLZMA && numThreads > 1 && level >= 5)
+ numSubThreads = 2;
+ UInt32 numMainThreads = numThreads / numSubThreads;
+ if (numMainThreads > 1)
+ size += (UInt64)numMainThreads << 25;
}
switch (GetMethodID())
{
@@ -1306,13 +1312,19 @@ UInt64 CCompressDialog::GetMemoryUsage(UInt32 dictionary, UInt64 &decompressMemo
if (hs > (1 << 24))
hs >>= 1;
hs++;
- size += hs * 4;
- size += (UInt64)dictionary * 11 / 2;
+ UInt64 size1 = (UInt64)hs * 4;
+ size1 += (UInt64)dictionary * 11 / 2;
if (level >= 5)
- size += dictionary * 4;
- size += (2 << 20);
+ size1 += dictionary * 4;
+ size1 += (2 << 20);
+
+ UInt32 numThreads1 = 1;
if (numThreads > 1 && level >= 5)
- size += (2 << 20) + (4 << 20);
+ {
+ size1 += (2 << 20) + (4 << 20);
+ numThreads1 = 2;
+ }
+ size += size1 * numThreads / numThreads1;
decompressMemory = dictionary + (2 << 20);
return size;