mirror of
https://github.com/Xevion/easy7zip.git
synced 2025-12-08 12:07:03 -06:00
21.04
This commit is contained in:
@@ -1665,7 +1665,7 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
|
||||
m_Archive, item, realOutStream, extractCallback,
|
||||
progress,
|
||||
#ifndef _7ZIP_ST
|
||||
_props._numThreads, _props._memUsage,
|
||||
_props._numThreads, _props._memUsage_Decompress,
|
||||
#endif
|
||||
res);
|
||||
|
||||
|
||||
@@ -989,7 +989,8 @@ bool CInArchive::ReadFileName(unsigned size, AString &s)
|
||||
|
||||
|
||||
bool CInArchive::ReadExtra(const CLocalItem &item, unsigned extraSize, CExtraBlock &extra,
|
||||
UInt64 &unpackSize, UInt64 &packSize, UInt64 &localOffset, UInt32 &disk)
|
||||
UInt64 &unpackSize, UInt64 &packSize,
|
||||
CItem *cdItem)
|
||||
{
|
||||
extra.Clear();
|
||||
|
||||
@@ -1017,18 +1018,40 @@ bool CInArchive::ReadExtra(const CLocalItem &item, unsigned extraSize, CExtraBlo
|
||||
{
|
||||
extra.IsZip64 = true;
|
||||
bool isOK = true;
|
||||
|
||||
if (!cdItem
|
||||
&& size == 16
|
||||
&& !ZIP64_IS_32_MAX(unpackSize)
|
||||
&& !ZIP64_IS_32_MAX(packSize))
|
||||
{
|
||||
/* Win10 Explorer's "Send to Zip" for big (3500 MiB) files
|
||||
creates Zip64 Extra in local file header.
|
||||
But if both uncompressed and compressed sizes are smaller than 4 GiB,
|
||||
Win10 doesn't store 0xFFFFFFFF in 32-bit fields as expected by zip specification.
|
||||
21.04: we ignore these minor errors in Win10 zip archives. */
|
||||
if (ReadUInt64() != unpackSize)
|
||||
isOK = false;
|
||||
if (ReadUInt64() != packSize)
|
||||
isOK = false;
|
||||
size = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (ZIP64_IS_32_MAX(unpackSize))
|
||||
{ if (size < 8) isOK = false; else { size -= 8; unpackSize = ReadUInt64(); }}
|
||||
|
||||
if (ZIP64_IS_32_MAX(unpackSize))
|
||||
{ if (size < 8) isOK = false; else { size -= 8; unpackSize = ReadUInt64(); }}
|
||||
if (isOK && ZIP64_IS_32_MAX(packSize))
|
||||
{ if (size < 8) isOK = false; else { size -= 8; packSize = ReadUInt64(); }}
|
||||
|
||||
if (isOK && ZIP64_IS_32_MAX(packSize))
|
||||
{ if (size < 8) isOK = false; else { size -= 8; packSize = ReadUInt64(); }}
|
||||
|
||||
if (isOK && ZIP64_IS_32_MAX(localOffset))
|
||||
{ if (size < 8) isOK = false; else { size -= 8; localOffset = ReadUInt64(); }}
|
||||
|
||||
if (isOK && ZIP64_IS_16_MAX(disk))
|
||||
{ if (size < 4) isOK = false; else { size -= 4; disk = ReadUInt32(); }}
|
||||
if (cdItem)
|
||||
{
|
||||
if (isOK && ZIP64_IS_32_MAX(cdItem->LocalHeaderPos))
|
||||
{ if (size < 8) isOK = false; else { size -= 8; cdItem->LocalHeaderPos = ReadUInt64(); }}
|
||||
|
||||
if (isOK && ZIP64_IS_16_MAX(cdItem->Disk))
|
||||
{ if (size < 4) isOK = false; else { size -= 4; cdItem->Disk = ReadUInt32(); }}
|
||||
}
|
||||
}
|
||||
|
||||
if (!isOK || size != 0)
|
||||
{
|
||||
@@ -1100,9 +1123,7 @@ bool CInArchive::ReadLocalItem(CItemEx &item)
|
||||
|
||||
if (extraSize > 0)
|
||||
{
|
||||
UInt64 localOffset = 0;
|
||||
UInt32 disk = 0;
|
||||
if (!ReadExtra(item, extraSize, item.LocalExtra, item.Size, item.PackSize, localOffset, disk))
|
||||
if (!ReadExtra(item, extraSize, item.LocalExtra, item.Size, item.PackSize, NULL))
|
||||
{
|
||||
/* Most of archives are OK for Extra. But there are some rare cases
|
||||
that have error. And if error in first item, it can't open archive.
|
||||
@@ -1557,7 +1578,7 @@ HRESULT CInArchive::ReadCdItem(CItemEx &item)
|
||||
ReadFileName(nameSize, item.Name);
|
||||
|
||||
if (extraSize > 0)
|
||||
ReadExtra(item, extraSize, item.CentralExtra, item.Size, item.PackSize, item.LocalHeaderPos, item.Disk);
|
||||
ReadExtra(item, extraSize, item.CentralExtra, item.Size, item.PackSize, &item);
|
||||
|
||||
// May be these strings must be deleted
|
||||
/*
|
||||
|
||||
@@ -312,7 +312,7 @@ class CInArchive
|
||||
bool ReadFileName(unsigned nameSize, AString &dest);
|
||||
|
||||
bool ReadExtra(const CLocalItem &item, unsigned extraSize, CExtraBlock &extra,
|
||||
UInt64 &unpackSize, UInt64 &packSize, UInt64 &localOffset, UInt32 &disk);
|
||||
UInt64 &unpackSize, UInt64 &packSize, CItem *cdItem);
|
||||
bool ReadLocalItem(CItemEx &item);
|
||||
HRESULT FindDescriptor(CItemEx &item, unsigned numFiles);
|
||||
HRESULT ReadCdItem(CItemEx &item);
|
||||
|
||||
@@ -773,7 +773,7 @@ static HRESULT Update2(
|
||||
if (numThreads < 1)
|
||||
numThreads = 1;
|
||||
|
||||
const size_t kMemPerThread = (size_t)1 << 25;
|
||||
const size_t kMemPerThread = (size_t)sizeof(size_t) << 23;
|
||||
const size_t kBlockSize = 1 << 16;
|
||||
|
||||
bool mtMode = (numThreads > 1);
|
||||
@@ -791,6 +791,7 @@ static HRESULT Update2(
|
||||
|
||||
if (onem.FindProp(NCoderPropID::kNumThreads) < 0)
|
||||
{
|
||||
// fixme: we should check the number of threads for xz mehod also
|
||||
// fixed for 9.31. bzip2 default is just one thread.
|
||||
onem.AddProp_NumThreads(numThreads);
|
||||
}
|
||||
@@ -801,8 +802,8 @@ static HRESULT Update2(
|
||||
if (method == NFileHeader::NCompressionMethod::kStore && !options.PasswordIsDefined)
|
||||
numThreads = 1;
|
||||
|
||||
if (oneMethodMain)
|
||||
{
|
||||
if (oneMethodMain)
|
||||
{
|
||||
|
||||
if (method == NFileHeader::NCompressionMethod::kBZip2)
|
||||
{
|
||||
@@ -828,6 +829,7 @@ static HRESULT Update2(
|
||||
int numXzThreads = oneMethodMain->Get_Xz_NumThreads(numLzmaThreads);
|
||||
if (numXzThreads < 0)
|
||||
{
|
||||
// numXzThreads is unknown
|
||||
const UInt64 averageSize = numBytesToCompress / numFilesToCompress;
|
||||
const UInt64 blockSize = oneMethodMain->Get_Xz_BlockSize();
|
||||
UInt64 averageNumberOfBlocks = 1;
|
||||
@@ -844,18 +846,52 @@ static HRESULT Update2(
|
||||
}
|
||||
numThreads /= (unsigned)numXzThreads;
|
||||
}
|
||||
else if (
|
||||
method == NFileHeader::NCompressionMethod::kDeflate
|
||||
|| method == NFileHeader::NCompressionMethod::kDeflate64
|
||||
|| method == NFileHeader::NCompressionMethod::kPPMd)
|
||||
{
|
||||
if (numThreads > 1
|
||||
&& options._memUsage_WasSet
|
||||
&& !options._numThreads_WasForced)
|
||||
{
|
||||
UInt64 methodMemUsage;
|
||||
if (method == NFileHeader::NCompressionMethod::kPPMd)
|
||||
methodMemUsage = oneMethodMain->Get_Ppmd_MemSize();
|
||||
else
|
||||
methodMemUsage = (4 << 20); // for deflate
|
||||
const UInt64 threadMemUsage = kMemPerThread + methodMemUsage;
|
||||
const UInt64 numThreads64 = options._memUsage_Compress / threadMemUsage;
|
||||
if (numThreads64 < numThreads)
|
||||
numThreads = (UInt32)numThreads64;
|
||||
}
|
||||
}
|
||||
else if (method == NFileHeader::NCompressionMethod::kLZMA)
|
||||
{
|
||||
// we suppose that default LZMA is 2 thread. So we don't change it
|
||||
UInt32 numLZMAThreads = oneMethodMain->Get_Lzma_NumThreads();
|
||||
const UInt32 numLZMAThreads = oneMethodMain->Get_Lzma_NumThreads();
|
||||
numThreads /= numLZMAThreads;
|
||||
|
||||
if (numThreads > 1
|
||||
&& options._memUsage_WasSet
|
||||
&& !options._numThreads_WasForced)
|
||||
{
|
||||
const UInt64 methodMemUsage = oneMethodMain->Get_Lzma_MemUsage(true);
|
||||
const UInt64 threadMemUsage = kMemPerThread + methodMemUsage;
|
||||
const UInt64 numThreads64 = options._memUsage_Compress / threadMemUsage;
|
||||
if (numThreads64 < numThreads)
|
||||
numThreads = (UInt32)numThreads64;
|
||||
}
|
||||
}
|
||||
}
|
||||
} // (oneMethodMain)
|
||||
|
||||
if (numThreads > numFilesToCompress)
|
||||
numThreads = (UInt32)numFilesToCompress;
|
||||
if (numThreads <= 1)
|
||||
{
|
||||
mtMode = false;
|
||||
numThreads = 1;
|
||||
}
|
||||
}
|
||||
|
||||
// mtMode = true; // to test mtMode for seqMode
|
||||
|
||||
Reference in New Issue
Block a user