Update to 7-Zip 17.01 Beta from Igor Pavlov

- Minor speed optimization for LZMA2 (xz and 7z) multi-threading compression.
  7-Zip now uses additional memory buffers for multi-block LZMA2 compression.
  CPU utilization was slightly improved.
- 7-zip now creates multi-block xz archives by default. Block size can be
  specified with -ms[Size]{m|g} switch.
- xz decoder now can unpack random block from multi-block xz archives.  7-Zip
  File Manager now can open nested multi-block xz archives (for example,
  image.iso.xz) without full unpacking of xz archive.
- 7-Zip now can create zip archives from stdin to stdout.
- 7-Zip command line: @listfile now doesn't work after -- switch.  Use
  -i@listfile before -- switch instead.

fixed bugs:
- 7-Zip could add unrequired alternate file streams to WIM archives, for
  commands that contain filename wildcards and -sns switch.
- 7-Zip 17.00 beta crashed for commands that write anti-item to 7z archive.
- 7-Zip 17.00 beta ignored "Use large memory pages" option.
This commit is contained in:
Tino Reichardt
2017-08-28 16:34:04 +02:00
parent 7c1f566312
commit ef790b5209
112 changed files with 4712 additions and 1705 deletions

View File

@@ -36,6 +36,7 @@ static const UInt32 kLzmaHeaderSize = 4 + kLzmaPropsSize;
class CLzmaEncoder:
public ICompressCoder,
public ICompressSetCoderProperties,
public ICompressSetCoderPropertiesOpt,
public CMyUnknownImp
{
public:
@@ -46,8 +47,11 @@ public:
STDMETHOD(Code)(ISequentialInStream *inStream, ISequentialOutStream *outStream,
const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress);
STDMETHOD(SetCoderProperties)(const PROPID *propIDs, const PROPVARIANT *props, UInt32 numProps);
STDMETHOD(SetCoderPropertiesOpt)(const PROPID *propIDs, const PROPVARIANT *props, UInt32 numProps);
MY_UNKNOWN_IMP1(ICompressSetCoderProperties)
MY_UNKNOWN_IMP2(
ICompressSetCoderProperties,
ICompressSetCoderPropertiesOpt)
};
STDMETHODIMP CLzmaEncoder::SetCoderProperties(const PROPID *propIDs, const PROPVARIANT *props, UInt32 numProps)
@@ -71,6 +75,11 @@ STDMETHODIMP CLzmaEncoder::SetCoderProperties(const PROPID *propIDs, const PROPV
return S_OK;
}
STDMETHODIMP CLzmaEncoder::SetCoderPropertiesOpt(const PROPID *propIDs, const PROPVARIANT *props, UInt32 numProps)
{
return EncoderSpec->SetCoderPropertiesOpt(propIDs, props, numProps);
}
STDMETHODIMP CLzmaEncoder::Code(ISequentialInStream *inStream, ISequentialOutStream *outStream,
const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress)
{
@@ -118,7 +127,8 @@ HRESULT CAddCommon::CalcStreamCRC(ISequentialInStream *inStream, UInt32 &resultC
}
HRESULT CAddCommon::Set_Pre_CompressionResult(bool seqMode, UInt64 unpackSize, CCompressingResult &opRes) const
HRESULT CAddCommon::Set_Pre_CompressionResult(bool inSeqMode, bool outSeqMode, UInt64 unpackSize,
CCompressingResult &opRes) const
{
// We use Zip64, if unPackSize size is larger than 0xF8000000 to support
// cases when compressed size can be about 3% larger than uncompressed size
@@ -144,7 +154,7 @@ HRESULT CAddCommon::Set_Pre_CompressionResult(bool seqMode, UInt64 unpackSize, C
opRes.LzmaEos = false;
opRes.ExtractVersion = NCompressionMethod::kExtractVersion_Default;
opRes.FileTimeWasUsed = false;
opRes.DescriptorMode = outSeqMode;
if (_options.PasswordIsDefined)
{
@@ -153,8 +163,8 @@ HRESULT CAddCommon::Set_Pre_CompressionResult(bool seqMode, UInt64 unpackSize, C
opRes.ExtractVersion = NCompressionMethod::kExtractVersion_Aes;
else
{
if (seqMode)
opRes.FileTimeWasUsed = true;
if (inSeqMode)
opRes.DescriptorMode = true;
}
}
@@ -187,7 +197,8 @@ HRESULT CAddCommon::Set_Pre_CompressionResult(bool seqMode, UInt64 unpackSize, C
HRESULT CAddCommon::Compress(
DECL_EXTERNAL_CODECS_LOC_VARS
ISequentialInStream *inStream, IOutStream *outStream,
bool seqMode, UInt32 fileTime,
bool inSeqMode, bool outSeqMode,
UInt32 fileTime, UInt64 expectedDataSize,
ICompressProgressInfo *progress, CCompressingResult &opRes)
{
opRes.LzmaEos = false;
@@ -202,16 +213,31 @@ HRESULT CAddCommon::Compress(
CMyComPtr<ISequentialInStream> inCrcStream = inSecCrcStreamSpec;
CMyComPtr<IInStream> inStream2;
if (!seqMode)
if (!inSeqMode)
{
inStream->QueryInterface(IID_IInStream, (void **)&inStream2);
if (!inStream2)
{
// inSeqMode = true;
// inSeqMode must be correct before
return E_FAIL;
}
}
inSecCrcStreamSpec->SetStream(inStream);
inSecCrcStreamSpec->Init();
unsigned numTestMethods = _options.MethodSequence.Size();
if (seqMode || (numTestMethods > 1 && !inStream2))
numTestMethods = 1;
bool descriptorMode = outSeqMode;
if (!outSeqMode)
if (inSeqMode && _options.PasswordIsDefined && !_options.IsAesMode)
descriptorMode = true;
opRes.DescriptorMode = descriptorMode;
if (numTestMethods > 1)
if (inSeqMode || outSeqMode || !inStream2)
numTestMethods = 1;
UInt32 crc = 0;
bool crc_IsCalculated = false;
@@ -219,19 +245,23 @@ HRESULT CAddCommon::Compress(
Byte method = 0;
CFilterCoder::C_OutStream_Releaser outStreamReleaser;
opRes.ExtractVersion = NCompressionMethod::kExtractVersion_Default;
opRes.FileTimeWasUsed = false;
for (unsigned i = 0; i < numTestMethods; i++)
{
opRes.LzmaEos = false;
opRes.ExtractVersion = NCompressionMethod::kExtractVersion_Default;
if (inStream2 && i != 0)
if (i != 0)
{
inSecCrcStreamSpec->Init();
RINOK(inStream2->Seek(0, STREAM_SEEK_SET, NULL));
if (inStream2)
{
inSecCrcStreamSpec->Init();
RINOK(inStream2->Seek(0, STREAM_SEEK_SET, NULL));
}
RINOK(outStream->SetSize(0));
RINOK(outStream->Seek(0, STREAM_SEEK_SET, NULL));
}
RINOK(outStream->SetSize(0));
RINOK(outStream->Seek(0, STREAM_SEEK_SET, NULL));
if (_options.PasswordIsDefined)
{
@@ -264,7 +294,12 @@ HRESULT CAddCommon::Compress(
UInt32 check;
if (inStream2)
if (descriptorMode)
{
// it's Info-ZIP modification for stream_mode descriptor_mode (bit 3 of the general purpose bit flag is set)
check = (fileTime & 0xFFFF);
}
else
{
if (!crc_IsCalculated)
{
@@ -275,11 +310,6 @@ HRESULT CAddCommon::Compress(
}
check = (crc >> 16);
}
else
{
opRes.FileTimeWasUsed = true;
check = (fileTime & 0xFFFF);
}
RINOK(_filterSpec->WriteHeader_Check16(outStream, (UInt16)check));
}
@@ -295,7 +325,13 @@ HRESULT CAddCommon::Compress(
{
case NCompressionMethod::kStore:
{
if (_copyCoderSpec == NULL)
if (descriptorMode)
{
// we still can create descriptor_mode archives with "Store" method, but they are not good for 100%
return E_NOTIMPL;
}
if (!_copyCoderSpec)
{
_copyCoderSpec = new NCompress::CCopyCoder;
_copyCoder = _copyCoderSpec;
@@ -390,6 +426,18 @@ HRESULT CAddCommon::Compress(
outStreamNew = outStream;
if (_compressExtractVersion > opRes.ExtractVersion)
opRes.ExtractVersion = _compressExtractVersion;
{
CMyComPtr<ICompressSetCoderPropertiesOpt> optProps;
_compressEncoder->QueryInterface(IID_ICompressSetCoderPropertiesOpt, (void **)&optProps);
if (optProps)
{
PROPID propID = NCoderPropID::kExpectedDataSize;
NWindows::NCOM::CPropVariant prop = (UInt64)expectedDataSize;
RINOK(optProps->SetCoderPropertiesOpt(&propID, &prop, 1));
}
}
RINOK(_compressEncoder->Code(inCrcStream, outStreamNew, NULL, NULL, progress));
break;
}