diff options
Diffstat (limited to '3rdparty/lzma/CPP/7zip/Compress/PpmdEncoder.cpp')
-rw-r--r-- | 3rdparty/lzma/CPP/7zip/Compress/PpmdEncoder.cpp | 91 |
1 files changed, 66 insertions, 25 deletions
diff --git a/3rdparty/lzma/CPP/7zip/Compress/PpmdEncoder.cpp b/3rdparty/lzma/CPP/7zip/Compress/PpmdEncoder.cpp index 00ea9668b00..2dfca6df6f2 100644 --- a/3rdparty/lzma/CPP/7zip/Compress/PpmdEncoder.cpp +++ b/3rdparty/lzma/CPP/7zip/Compress/PpmdEncoder.cpp @@ -3,7 +3,6 @@ #include "StdAfx.h" #include "../../../C/Alloc.h" -#include "../../../C/CpuArch.h" #include "../Common/StreamUtils.h" @@ -21,11 +20,11 @@ void CEncProps::Normalize(int level) if (level < 0) level = 5; if (level > 9) level = 9; if (MemSize == (UInt32)(Int32)-1) - MemSize = level >= 9 ? ((UInt32)192 << 20) : ((UInt32)1 << (level + 19)); + MemSize = (UInt32)1 << (level + 19); const unsigned kMult = 16; if (MemSize / kMult > ReduceSize) { - for (unsigned i = 16; i <= 31; i++) + for (unsigned i = 16; i < 32; i++) { UInt32 m = (UInt32)1 << i; if (ReduceSize <= m / kMult) @@ -43,8 +42,8 @@ CEncoder::CEncoder(): _inBuf(NULL) { _props.Normalize(-1); - _rangeEnc.Stream = &_outStream.p; Ppmd7_Construct(&_ppmd); + _ppmd.rc.enc.Stream = &_outStream.vt; } CEncoder::~CEncoder() @@ -53,14 +52,14 @@ CEncoder::~CEncoder() Ppmd7_Free(&_ppmd, &g_BigAlloc); } -STDMETHODIMP CEncoder::SetCoderProperties(const PROPID *propIDs, const PROPVARIANT *coderProps, UInt32 numProps) +Z7_COM7F_IMF(CEncoder::SetCoderProperties(const PROPID *propIDs, const PROPVARIANT *coderProps, UInt32 numProps)) { int level = -1; CEncProps props; for (UInt32 i = 0; i < numProps; i++) { const PROPVARIANT &prop = coderProps[i]; - PROPID propID = propIDs[i]; + const PROPID propID = propIDs[i]; if (propID > NCoderPropID::kReduceSize) continue; if (propID == NCoderPropID::kReduceSize) @@ -69,16 +68,50 @@ STDMETHODIMP CEncoder::SetCoderProperties(const PROPID *propIDs, const PROPVARIA props.ReduceSize = (UInt32)prop.uhVal.QuadPart; continue; } + + if (propID == NCoderPropID::kUsedMemorySize) + { + // here we have selected (4 GiB - 1 KiB) as replacement for (4 GiB) MEM_SIZE. + const UInt32 kPpmd_Default_4g = (UInt32)0 - ((UInt32)1 << 10); + UInt32 v; + if (prop.vt == VT_UI8) + { + // 21.03 : we support 64-bit values (for 4 GiB value) + const UInt64 v64 = prop.uhVal.QuadPart; + if (v64 > ((UInt64)1 << 32)) + return E_INVALIDARG; + if (v64 == ((UInt64)1 << 32)) + v = kPpmd_Default_4g; + else + v = (UInt32)v64; + } + else if (prop.vt == VT_UI4) + v = (UInt32)prop.ulVal; + else + return E_INVALIDARG; + if (v > PPMD7_MAX_MEM_SIZE) + v = kPpmd_Default_4g; + + /* here we restrict MEM_SIZE for Encoder. + It's for better performance of encoding and decoding. + The Decoder still supports more MEM_SIZE values. */ + if (v < ((UInt32)1 << 16) || (v & 3) != 0) + return E_INVALIDARG; + // if (v < PPMD7_MIN_MEM_SIZE) return E_INVALIDARG; // (1 << 11) + /* + Supported MEM_SIZE range : + [ (1 << 11) , 0xFFFFFFFF - 12 * 3 ] - current 7-Zip's Ppmd7 constants + [ 1824 , 0xFFFFFFFF ] - real limits of Ppmd7 code + */ + props.MemSize = v; + continue; + } + if (prop.vt != VT_UI4) return E_INVALIDARG; - UInt32 v = (UInt32)prop.ulVal; + const UInt32 v = (UInt32)prop.ulVal; switch (propID) { - case NCoderPropID::kUsedMemorySize: - if (v < (1 << 16) || v > PPMD7_MAX_MEM_SIZE || (v & 3) != 0) - return E_INVALIDARG; - props.MemSize = v; - break; case NCoderPropID::kOrder: if (v < 2 || v > 32) return E_INVALIDARG; @@ -94,17 +127,17 @@ STDMETHODIMP CEncoder::SetCoderProperties(const PROPID *propIDs, const PROPVARIA return S_OK; } -STDMETHODIMP CEncoder::WriteCoderProperties(ISequentialOutStream *outStream) +Z7_COM7F_IMF(CEncoder::WriteCoderProperties(ISequentialOutStream *outStream)) { const UInt32 kPropSize = 5; Byte props[kPropSize]; props[0] = (Byte)_props.Order; - SetUi32(props + 1, _props.MemSize); + SetUi32(props + 1, _props.MemSize) return WriteStream(outStream, props, kPropSize); } -HRESULT CEncoder::Code(ISequentialInStream *inStream, ISequentialOutStream *outStream, - const UInt64 * /* inSize */, const UInt64 * /* outSize */, ICompressProgressInfo *progress) +Z7_COM7F_IMF(CEncoder::Code(ISequentialInStream *inStream, ISequentialOutStream *outStream, + const UInt64 * /* inSize */, const UInt64 * /* outSize */, ICompressProgressInfo *progress)) { if (!_inBuf) { @@ -120,31 +153,39 @@ HRESULT CEncoder::Code(ISequentialInStream *inStream, ISequentialOutStream *outS _outStream.Stream = outStream; _outStream.Init(); - Ppmd7z_RangeEnc_Init(&_rangeEnc); - Ppmd7_Init(&_ppmd, _props.Order); + Ppmd7z_Init_RangeEnc(&_ppmd); + Ppmd7_Init(&_ppmd, (unsigned)_props.Order); UInt64 processed = 0; for (;;) { UInt32 size; - RINOK(inStream->Read(_inBuf, kBufSize, &size)); + RINOK(inStream->Read(_inBuf, kBufSize, &size)) if (size == 0) { // We don't write EndMark in PPMD-7z. - // Ppmd7_EncodeSymbol(&_ppmd, &_rangeEnc, -1); - Ppmd7z_RangeEnc_FlushData(&_rangeEnc); + // Ppmd7z_EncodeSymbol(&_ppmd, -1); + Ppmd7z_Flush_RangeEnc(&_ppmd); return _outStream.Flush(); } - for (UInt32 i = 0; i < size; i++) + const Byte *buf = _inBuf; + const Byte *lim = buf + size; + /* + for (; buf < lim; buf++) { - Ppmd7_EncodeSymbol(&_ppmd, &_rangeEnc, _inBuf[i]); + Ppmd7z_EncodeSymbol(&_ppmd, *buf); RINOK(_outStream.Res); } + */ + + Ppmd7z_EncodeSymbols(&_ppmd, buf, lim); + RINOK(_outStream.Res) + processed += size; if (progress) { - UInt64 outSize = _outStream.GetProcessed(); - RINOK(progress->SetRatioInfo(&processed, &outSize)); + const UInt64 outSize = _outStream.GetProcessed(); + RINOK(progress->SetRatioInfo(&processed, &outSize)) } } } |