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
diff options
context:
space:
mode:
Diffstat (limited to 'CPP/7zip/Compress')
-rwxr-xr-xCPP/7zip/Compress/BZip2Encoder.cpp89
-rwxr-xr-xCPP/7zip/Compress/BZip2Encoder.h21
-rwxr-xr-xCPP/7zip/Compress/DeflateEncoder.cpp134
-rwxr-xr-xCPP/7zip/Compress/DeflateEncoder.h21
-rwxr-xr-xCPP/7zip/Compress/DeltaFilter.cpp17
-rwxr-xr-xCPP/7zip/Compress/DllExports2.cpp9
-rwxr-xr-xCPP/7zip/Compress/LzmaEncoder.cpp29
-rwxr-xr-xCPP/7zip/Compress/LzxDecoder.cpp3
-rwxr-xr-xCPP/7zip/Compress/PpmdEncoder.cpp67
-rwxr-xr-xCPP/7zip/Compress/PpmdEncoder.h23
-rwxr-xr-xCPP/7zip/Compress/PpmdZip.cpp92
-rwxr-xr-xCPP/7zip/Compress/PpmdZip.h27
-rwxr-xr-xCPP/7zip/Compress/QuantumDecoder.cpp22
-rwxr-xr-xCPP/7zip/Compress/QuantumDecoder.h2
14 files changed, 372 insertions, 184 deletions
diff --git a/CPP/7zip/Compress/BZip2Encoder.cpp b/CPP/7zip/Compress/BZip2Encoder.cpp
index eaa10855..6dafc45f 100755
--- a/CPP/7zip/Compress/BZip2Encoder.cpp
+++ b/CPP/7zip/Compress/BZip2Encoder.cpp
@@ -122,11 +122,24 @@ DWORD CThreadInfo::ThreadFunc()
#endif
-CEncoder::CEncoder():
- NumPasses(1),
- m_OptimizeNumTables(false),
- m_BlockSizeMult(kBlockSizeMultMax)
+void CEncProps::Normalize(int level)
{
+ if (level < 0) level = 5;
+ if (level > 9) level = 9;
+ if (NumPasses == (UInt32)(Int32)-1)
+ NumPasses = (level >= 9 ? 7 : (level >= 7 ? 2 : 1));
+ if (NumPasses < kBlockSizeMultMin) NumPasses = kBlockSizeMultMin;
+ if (NumPasses > kBlockSizeMultMax) NumPasses = kBlockSizeMultMax;
+ if (BlockSizeMult == (UInt32)(Int32)-1)
+ BlockSizeMult = (level >= 5 ? 9 : (level >= 1 ? level * 2 - 1: 1));
+ if (BlockSizeMult == 0) BlockSizeMult = 1;
+ if (BlockSizeMult > kNumPassesMax) BlockSizeMult = kNumPassesMax;
+}
+
+CEncoder::CEncoder()
+{
+ _props.Normalize(-1);
+
#ifndef _7ZIP_ST
ThreadsInfo = 0;
m_NumThreadsPrev = 0;
@@ -198,7 +211,7 @@ UInt32 CEncoder::ReadRleBlock(Byte *buffer)
Byte prevByte;
if (m_InStream.ReadByte(prevByte))
{
- UInt32 blockSize = m_BlockSizeMult * kBlockSizeStep - 1;
+ UInt32 blockSize = _props.BlockSizeMult * kBlockSizeStep - 1;
int numReps = 1;
buffer[i++] = prevByte;
while (i < blockSize) // "- 1" to support RLE
@@ -678,7 +691,7 @@ HRESULT CThreadInfo::EncodeBlock3(UInt32 blockSize)
m_NumCrcs = 0;
- EncodeBlock2(m_Block, blockSize, Encoder->NumPasses);
+ EncodeBlock2(m_Block, blockSize, Encoder->_props.NumPasses);
#ifndef _7ZIP_ST
if (Encoder->MtMode)
@@ -738,7 +751,7 @@ HRESULT CEncoder::CodeReal(ISequentialInStream *inStream, ISequentialOutStream *
ti.Encoder = this;
#endif
- ti.m_OptimizeNumTables = m_OptimizeNumTables;
+ ti.m_OptimizeNumTables = _props.DoOptimizeNumTables();
if (!ti.Alloc())
return E_OUTOFMEMORY;
@@ -770,7 +783,7 @@ HRESULT CEncoder::CodeReal(ISequentialInStream *inStream, ISequentialOutStream *
WriteByte(kArSig0);
WriteByte(kArSig1);
WriteByte(kArSig2);
- WriteByte((Byte)(kArSig3 + m_BlockSizeMult));
+ WriteByte((Byte)(kArSig3 + _props.BlockSizeMult));
#ifndef _7ZIP_ST
@@ -832,62 +845,46 @@ STDMETHODIMP CEncoder::Code(ISequentialInStream *inStream, ISequentialOutStream
catch(...) { return S_FALSE; }
}
-HRESULT CEncoder::SetCoderProperties(const PROPID *propIDs, const PROPVARIANT *props, UInt32 numProps)
+HRESULT CEncoder::SetCoderProperties(const PROPID *propIDs, const PROPVARIANT *coderProps, UInt32 numProps)
{
- for(UInt32 i = 0; i < numProps; i++)
+ int level = -1;
+ CEncProps props;
+ for (UInt32 i = 0; i < numProps; i++)
{
- const PROPVARIANT &prop = props[i];
- switch(propIDs[i])
+ const PROPVARIANT &prop = coderProps[i];
+ PROPID propID = propIDs[i];
+ if (propID >= NCoderPropID::kReduceSize)
+ continue;
+ if (prop.vt != VT_UI4)
+ return E_INVALIDARG;
+ UInt32 v = (UInt32)prop.ulVal;
+ switch (propID)
{
- case NCoderPropID::kNumPasses:
- {
- if (prop.vt != VT_UI4)
- return E_INVALIDARG;
- UInt32 numPasses = prop.ulVal;
- if (numPasses == 0)
- numPasses = 1;
- if (numPasses > kNumPassesMax)
- numPasses = kNumPassesMax;
- NumPasses = numPasses;
- m_OptimizeNumTables = (NumPasses > 1);
- break;
- }
- case NCoderPropID::kDictionarySize:
- {
- if (prop.vt != VT_UI4)
- return E_INVALIDARG;
- UInt32 dictionary = prop.ulVal / kBlockSizeStep;
- if (dictionary < kBlockSizeMultMin)
- dictionary = kBlockSizeMultMin;
- else if (dictionary > kBlockSizeMultMax)
- dictionary = kBlockSizeMultMax;
- m_BlockSizeMult = dictionary;
- break;
- }
+ case NCoderPropID::kNumPasses: props.NumPasses = v; break;
+ case NCoderPropID::kDictionarySize: props.BlockSizeMult = v / kBlockSizeStep; break;
+ case NCoderPropID::kLevel: level = v; break;
case NCoderPropID::kNumThreads:
{
#ifndef _7ZIP_ST
- if (prop.vt != VT_UI4)
- return E_INVALIDARG;
- NumThreads = prop.ulVal;
- if (NumThreads < 1)
- NumThreads = 1;
+ SetNumberOfThreads(v);
#endif
break;
}
- default:
- return E_INVALIDARG;
+ default: return E_INVALIDARG;
}
}
+ props.Normalize(level);
+ _props = props;
return S_OK;
}
#ifndef _7ZIP_ST
STDMETHODIMP CEncoder::SetNumberOfThreads(UInt32 numThreads)
{
+ const UInt32 kNumThreadsMax = 64;
+ if (numThreads < 1) numThreads = 1;
+ if (numThreads > kNumThreadsMax) numThreads = kNumThreadsMax;
NumThreads = numThreads;
- if (NumThreads < 1)
- NumThreads = 1;
return S_OK;
}
#endif
diff --git a/CPP/7zip/Compress/BZip2Encoder.h b/CPP/7zip/Compress/BZip2Encoder.h
index a863172f..5aa8a786 100755
--- a/CPP/7zip/Compress/BZip2Encoder.h
+++ b/CPP/7zip/Compress/BZip2Encoder.h
@@ -145,6 +145,20 @@ public:
HRESULT EncodeBlock3(UInt32 blockSize);
};
+struct CEncProps
+{
+ UInt32 BlockSizeMult;
+ UInt32 NumPasses;
+
+ CEncProps()
+ {
+ BlockSizeMult = (UInt32)(Int32)-1;
+ NumPasses = (UInt32)(Int32)-1;
+ }
+ void Normalize(int level);
+ bool DoOptimizeNumTables() const { return NumPasses > 1; }
+};
+
class CEncoder :
public ICompressCoder,
public ICompressSetCoderProperties,
@@ -153,17 +167,12 @@ class CEncoder :
#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.
CBitmEncoder<COutBuffer> m_OutStream;
- UInt32 NumPasses;
+ CEncProps _props;
CBZip2CombinedCrc CombinedCrc;
#ifndef _7ZIP_ST
diff --git a/CPP/7zip/Compress/DeflateEncoder.cpp b/CPP/7zip/Compress/DeflateEncoder.cpp
index 35a81cae..813b6de4 100755
--- a/CPP/7zip/Compress/DeflateEncoder.cpp
+++ b/CPP/7zip/Compress/DeflateEncoder.cpp
@@ -21,12 +21,12 @@ namespace NCompress {
namespace NDeflate {
namespace NEncoder {
-const int kNumDivPassesMax = 10; // [0, 16); ratio/speed/ram tradeoff; use big value for better compression ratio.
-const UInt32 kNumTables = (1 << kNumDivPassesMax);
+static const int kNumDivPassesMax = 10; // [0, 16); ratio/speed/ram tradeoff; use big value for better compression ratio.
+static const UInt32 kNumTables = (1 << kNumDivPassesMax);
-static UInt32 kFixedHuffmanCodeBlockSizeMax = (1 << 8); // [0, (1 << 32)); ratio/speed tradeoff; use big value for better compression ratio.
-static UInt32 kDivideCodeBlockSizeMin = (1 << 7); // [1, (1 << 32)); ratio/speed tradeoff; use small value for better compression ratio.
-static UInt32 kDivideBlockSizeMin = (1 << 6); // [1, (1 << 32)); ratio/speed tradeoff; use small value for better compression ratio.
+static const UInt32 kFixedHuffmanCodeBlockSizeMax = (1 << 8); // [0, (1 << 32)); ratio/speed tradeoff; use big value for better compression ratio.
+static const UInt32 kDivideCodeBlockSizeMin = (1 << 7); // [1, (1 << 32)); ratio/speed tradeoff; use small value for better compression ratio.
+static const UInt32 kDivideBlockSizeMin = (1 << 6); // [1, (1 << 32)); ratio/speed tradeoff; use small value for better compression ratio.
static const UInt32 kMaxUncompressedBlockSize = ((1 << 16) - 1) * 1; // [1, (1 << 32))
static const UInt32 kMatchArraySize = kMaxUncompressedBlockSize * 10; // [kMatchMaxLen * 2, (1 << 32))
@@ -37,9 +37,9 @@ static const UInt32 kBlockUncompressedSizeThreshold = kMaxUncompressedBlockSize
static const int kMaxCodeBitLength = 11;
static const int kMaxLevelBitLength = 7;
-static Byte kNoLiteralStatPrice = 11;
-static Byte kNoLenStatPrice = 11;
-static Byte kNoPosStatPrice = 6;
+static const Byte kNoLiteralStatPrice = 11;
+static const Byte kNoLenStatPrice = 11;
+static const Byte kNoPosStatPrice = 6;
static Byte g_LenSlots[kNumLenSymbolsMax];
static Byte g_FastPos[1 << 9];
@@ -83,21 +83,61 @@ static void *SzAlloc(void *p, size_t size) { p = p; return MyAlloc(size); }
static void SzFree(void *p, void *address) { p = p; MyFree(address); }
static ISzAlloc g_Alloc = { SzAlloc, SzFree };
+void CEncProps::Normalize()
+{
+ int level = Level;
+ if (level < 0) level = 5;
+ Level = level;
+ if (algo < 0) algo = (level < 5 ? 0 : 1);
+ if (fb < 0) fb = (level < 7 ? 32 : (level < 9 ? 64 : 128));
+ if (btMode < 0) btMode = (algo == 0 ? 0 : 1);
+ if (mc == 0) mc = (16 + (fb >> 1));
+ if (numPasses == (UInt32)(Int32)-1) numPasses = (level < 7 ? 1 : (level < 9 ? 3 : 10));
+}
+
+void CCoder::SetProps(const CEncProps *props2)
+{
+ CEncProps props = *props2;
+ props.Normalize();
+
+ m_MatchFinderCycles = props.mc;
+ {
+ unsigned fb = props.fb;
+ if (fb < kMatchMinLen)
+ fb = kMatchMinLen;
+ if (fb > m_MatchMaxLen)
+ fb = m_MatchMaxLen;
+ m_NumFastBytes = fb;
+ }
+ _fastMode = (props.algo == 0);
+ _btMode = (props.btMode != 0);
+
+ m_NumDivPasses = props.numPasses;
+ if (m_NumDivPasses == 0)
+ m_NumDivPasses = 1;
+ if (m_NumDivPasses == 1)
+ m_NumPasses = 1;
+ else if (m_NumDivPasses <= kNumDivPassesMax)
+ m_NumPasses = 2;
+ else
+ {
+ m_NumPasses = 2 + (m_NumDivPasses - kNumDivPassesMax);
+ m_NumDivPasses = kNumDivPassesMax;
+ }
+}
+
CCoder::CCoder(bool deflate64Mode):
m_Deflate64Mode(deflate64Mode),
- m_NumPasses(1),
- m_NumDivPasses(1),
- m_NumFastBytes(32),
- _fastMode(false),
- _btMode(true),
m_OnePosMatchesMemory(0),
m_DistanceMemory(0),
m_Created(false),
m_Values(0),
- m_Tables(0),
- m_MatchFinderCycles(0)
- // m_SetMfPasses(0)
+ m_Tables(0)
{
+ {
+ CEncProps props;
+ SetProps(&props);
+ }
m_MatchMaxLen = deflate64Mode ? kMatchMaxLen64 : kMatchMaxLen32;
m_NumLenCombinations = deflate64Mode ? kNumLenSymbols64 : kNumLenSymbols32;
m_LenStart = deflate64Mode ? kLenStart64 : kLenStart32;
@@ -160,56 +200,30 @@ HRESULT CCoder::Create()
COM_TRY_END
}
-HRESULT CCoder::BaseSetEncoderProperties2(const PROPID *propIDs, const PROPVARIANT *props, UInt32 numProps)
+HRESULT CCoder::BaseSetEncoderProperties2(const PROPID *propIDs, const PROPVARIANT *coderProps, UInt32 numProps)
{
+ CEncProps props;
for (UInt32 i = 0; i < numProps; i++)
{
- const PROPVARIANT &prop = props[i];
- switch(propIDs[i])
+ const PROPVARIANT &prop = coderProps[i];
+ PROPID propID = propIDs[i];
+ if (propID >= NCoderPropID::kReduceSize)
+ continue;
+ if (prop.vt != VT_UI4)
+ return E_INVALIDARG;
+ UInt32 v = (UInt32)prop.ulVal;
+ switch (propID)
{
- case NCoderPropID::kNumPasses:
- if (prop.vt != VT_UI4)
- return E_INVALIDARG;
- m_NumDivPasses = prop.ulVal;
- if (m_NumDivPasses == 0)
- m_NumDivPasses = 1;
- if (m_NumDivPasses == 1)
- m_NumPasses = 1;
- else if (m_NumDivPasses <= kNumDivPassesMax)
- m_NumPasses = 2;
- else
- {
- m_NumPasses = 2 + (m_NumDivPasses - kNumDivPassesMax);
- m_NumDivPasses = kNumDivPassesMax;
- }
- break;
- case NCoderPropID::kNumFastBytes:
- if (prop.vt != VT_UI4)
- return E_INVALIDARG;
- 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;
- }
- case NCoderPropID::kAlgorithm:
- {
- if (prop.vt != VT_UI4)
- return E_INVALIDARG;
- UInt32 maximize = prop.ulVal;
- _fastMode = (maximize == 0);
- _btMode = !_fastMode;
- break;
- }
- default:
- return E_INVALIDARG;
+ case NCoderPropID::kNumPasses: props.numPasses = v; break;
+ case NCoderPropID::kNumFastBytes: props.fb = v; break;
+ case NCoderPropID::kMatchFinderCycles: props.mc = v; break;
+ case NCoderPropID::kAlgorithm: props.algo = v; break;
+ case NCoderPropID::kLevel: props.Level = v; break;
+ case NCoderPropID::kNumThreads: break;
+ default: return E_INVALIDARG;
}
}
+ SetProps(&props);
return S_OK;
}
diff --git a/CPP/7zip/Compress/DeflateEncoder.h b/CPP/7zip/Compress/DeflateEncoder.h
index 71c39e4e..f25d802e 100755
--- a/CPP/7zip/Compress/DeflateEncoder.h
+++ b/CPP/7zip/Compress/DeflateEncoder.h
@@ -52,6 +52,25 @@ typedef struct _CSeqInStream
CMyComPtr<ISequentialInStream> RealStream;
} CSeqInStream;
+struct CEncProps
+{
+ int Level;
+ int algo;
+ int fb;
+ int btMode;
+ UInt32 mc;
+ UInt32 numPasses;
+
+ CEncProps()
+ {
+ Level = -1;
+ mc = 0;
+ algo = fb = btMode = -1;
+ numPasses = (UInt32)(Int32)-1;
+ }
+ void Normalize();
+};
+
class CCoder
{
CMatchFinder _lzInWindow;
@@ -116,7 +135,6 @@ public:
COptimal m_Optimum[kNumOpts];
UInt32 m_MatchFinderCycles;
- // IMatchFinderSetNumPasses *m_SetMfPasses;
void GetMatches();
void MovePos(UInt32 num);
@@ -164,6 +182,7 @@ public:
UInt32 GetBlockPrice(int tableIndex, int numDivPasses);
void CodeBlock(int tableIndex, bool finalBlock);
+ void SetProps(const CEncProps *props2);
public:
CCoder(bool deflate64Mode = false);
~CCoder();
diff --git a/CPP/7zip/Compress/DeltaFilter.cpp b/CPP/7zip/Compress/DeltaFilter.cpp
index 2e421acf..d8378a60 100755
--- a/CPP/7zip/Compress/DeltaFilter.cpp
+++ b/CPP/7zip/Compress/DeltaFilter.cpp
@@ -62,9 +62,22 @@ STDMETHODIMP CDeltaEncoder::SetCoderProperties(const PROPID *propIDs, const PROP
for (UInt32 i = 0; i < numProps; i++)
{
const PROPVARIANT &prop = props[i];
- if (propIDs[i] != NCoderPropID::kDefaultProp || prop.vt != VT_UI4 || prop.ulVal < 1 || prop.ulVal > 256)
+ PROPID propID = propIDs[i];
+ if (propID >= NCoderPropID::kReduceSize)
+ continue;
+ if (prop.vt != VT_UI4)
return E_INVALIDARG;
- delta = prop.ulVal;
+ switch (propID)
+ {
+ case NCoderPropID::kDefaultProp:
+ delta = (UInt32)prop.ulVal;
+ if (delta < 1 || delta > 256)
+ return E_INVALIDARG;
+ break;
+ case NCoderPropID::kNumThreads: break;
+ case NCoderPropID::kLevel: break;
+ default: return E_INVALIDARG;
+ }
}
_delta = delta;
return S_OK;
diff --git a/CPP/7zip/Compress/DllExports2.cpp b/CPP/7zip/Compress/DllExports2.cpp
index 836f3fa4..286ef08b 100755
--- a/CPP/7zip/Compress/DllExports2.cpp
+++ b/CPP/7zip/Compress/DllExports2.cpp
@@ -9,7 +9,13 @@
#include "../Common/RegisterCodec.h"
extern "C"
-BOOL WINAPI DllMain(HINSTANCE /* hInstance */, DWORD /* dwReason */, LPVOID /*lpReserved*/)
+BOOL WINAPI DllMain(
+ #ifdef UNDER_CE
+ HANDLE
+ #else
+ HINSTANCE
+ #endif
+ /* hInstance */, DWORD /* dwReason */, LPVOID /*lpReserved*/)
{
return TRUE;
}
@@ -25,4 +31,3 @@ STDAPI CreateObject(const GUID *clsid, const GUID *iid, void **outObject)
{
return CreateCoder(clsid, iid, outObject);
}
-
diff --git a/CPP/7zip/Compress/LzmaEncoder.cpp b/CPP/7zip/Compress/LzmaEncoder.cpp
index 9bdedaeb..80e12f18 100755
--- a/CPP/7zip/Compress/LzmaEncoder.cpp
+++ b/CPP/7zip/Compress/LzmaEncoder.cpp
@@ -73,6 +73,8 @@ static int ParseMatchFinder(const wchar_t *s, int *btMode, int *numHashBytes)
return 1;
}
+#define SET_PROP_32(_id_, _dest_) case NCoderPropID::_id_: ep._dest_ = v; break;
+
HRESULT SetLzmaProp(PROPID propID, const PROPVARIANT &prop, CLzmaEncProps &ep)
{
if (propID == NCoderPropID::kMatchFinder)
@@ -81,18 +83,29 @@ HRESULT SetLzmaProp(PROPID propID, const PROPVARIANT &prop, CLzmaEncProps &ep)
return E_INVALIDARG;
return ParseMatchFinder(prop.bstrVal, &ep.btMode, &ep.numHashBytes) ? S_OK : E_INVALIDARG;
}
+ if (propID > NCoderPropID::kReduceSize)
+ return S_OK;
+ if (propID == NCoderPropID::kReduceSize)
+ {
+ if (prop.vt == VT_UI8 && prop.uhVal.QuadPart < (UInt32)(Int32)-1)
+ ep.reduceSize = (UInt32)prop.uhVal.QuadPart;
+ return S_OK;
+ }
if (prop.vt != VT_UI4)
return E_INVALIDARG;
UInt32 v = prop.ulVal;
switch (propID)
{
- case NCoderPropID::kNumFastBytes: ep.fb = v; break;
- case NCoderPropID::kMatchFinderCycles: ep.mc = v; break;
- case NCoderPropID::kAlgorithm: ep.algo = v; break;
- case NCoderPropID::kDictionarySize: ep.dictSize = v; break;
- case NCoderPropID::kPosStateBits: ep.pb = v; break;
- case NCoderPropID::kLitPosBits: ep.lp = v; break;
- case NCoderPropID::kLitContextBits: ep.lc = v; break;
+ case NCoderPropID::kDefaultProp: if (v > 31) return E_INVALIDARG; ep.dictSize = (UInt32)1 << (unsigned)v; break;
+ SET_PROP_32(kLevel, level)
+ SET_PROP_32(kNumFastBytes, fb)
+ SET_PROP_32(kMatchFinderCycles, mc)
+ SET_PROP_32(kAlgorithm, algo)
+ SET_PROP_32(kDictionarySize, dictSize)
+ SET_PROP_32(kPosStateBits, pb)
+ SET_PROP_32(kLitPosBits, lp)
+ SET_PROP_32(kLitContextBits, lc)
+ SET_PROP_32(kNumThreads, numThreads)
default: return E_INVALIDARG;
}
return S_OK;
@@ -112,8 +125,6 @@ STDMETHODIMP CEncoder::SetCoderProperties(const PROPID *propIDs,
{
case NCoderPropID::kEndMarker:
if (prop.vt != VT_BOOL) return E_INVALIDARG; props.writeEndMark = (prop.boolVal == VARIANT_TRUE); break;
- case NCoderPropID::kNumThreads:
- if (prop.vt != VT_UI4) return E_INVALIDARG; props.numThreads = prop.ulVal; break;
default:
RINOK(SetLzmaProp(propID, prop, props));
}
diff --git a/CPP/7zip/Compress/LzxDecoder.cpp b/CPP/7zip/Compress/LzxDecoder.cpp
index d1027f1f..924229e9 100755
--- a/CPP/7zip/Compress/LzxDecoder.cpp
+++ b/CPP/7zip/Compress/LzxDecoder.cpp
@@ -360,6 +360,9 @@ STDMETHODIMP CDecoder::SetOutStreamSize(const UInt64 *outSize)
{
if (outSize == NULL)
return E_FAIL;
+ // flush calls m_x86ConvertOutStreamSpec->flush, so we must init x86Convert.
+ if (!_keepHistory)
+ m_x86ConvertOutStreamSpec->Init(false, 0);
_remainLen = kLenIdNeedInit;
m_OutWindowStream.Init(_keepHistory);
return S_OK;
diff --git a/CPP/7zip/Compress/PpmdEncoder.cpp b/CPP/7zip/Compress/PpmdEncoder.cpp
index d823ffe8..5bf83529 100755
--- a/CPP/7zip/Compress/PpmdEncoder.cpp
+++ b/CPP/7zip/Compress/PpmdEncoder.cpp
@@ -1,5 +1,4 @@
// PpmdEncoder.cpp
-// 2009-03-11 : Igor Pavlov : Public domain
#include "StdAfx.h"
@@ -19,11 +18,35 @@ static void *SzBigAlloc(void *, size_t size) { return BigAlloc(size); }
static void SzBigFree(void *, void *address) { BigFree(address); }
static ISzAlloc g_BigAlloc = { SzBigAlloc, SzBigFree };
+static const Byte kOrders[10] = { 3, 4, 4, 5, 5, 6, 8, 16, 24, 32 };
+
+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));
+ const unsigned kMult = 16;
+ if (MemSize / kMult > ReduceSize)
+ {
+ for (unsigned i = 16; i <= 31; i++)
+ {
+ UInt32 m = (UInt32)1 << i;
+ if (ReduceSize <= m / kMult)
+ {
+ if (MemSize > m)
+ MemSize = m;
+ break;
+ }
+ }
+ }
+ if (Order == -1) Order = kOrders[level];
+}
+
CEncoder::CEncoder():
- _inBuf(NULL),
- _usedMemSize(1 << 24),
- _order(6)
+ _inBuf(NULL)
{
+ _props.Normalize(-1);
_rangeEnc.Stream = &_outStream.p;
Ppmd7_Construct(&_ppmd);
}
@@ -34,30 +57,44 @@ CEncoder::~CEncoder()
Ppmd7_Free(&_ppmd, &g_BigAlloc);
}
-STDMETHODIMP CEncoder::SetCoderProperties(const PROPID *propIDs, const PROPVARIANT *props, UInt32 numProps)
+STDMETHODIMP 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 = props[i];
+ const PROPVARIANT &prop = coderProps[i];
+ PROPID propID = propIDs[i];
+ if (propID > NCoderPropID::kReduceSize)
+ continue;
+ if (propID == NCoderPropID::kReduceSize)
+ {
+ if (prop.vt == VT_UI8 && prop.uhVal.QuadPart < (UInt32)(Int32)-1)
+ props.ReduceSize = (UInt32)prop.uhVal.QuadPart;
+ continue;
+ }
if (prop.vt != VT_UI4)
return E_INVALIDARG;
UInt32 v = (UInt32)prop.ulVal;
- switch(propIDs[i])
+ switch (propID)
{
case NCoderPropID::kUsedMemorySize:
if (v < (1 << 16) || v > PPMD7_MAX_MEM_SIZE || (v & 3) != 0)
return E_INVALIDARG;
- _usedMemSize = v;
+ props.MemSize = v;
break;
case NCoderPropID::kOrder:
if (v < 2 || v > 32)
return E_INVALIDARG;
- _order = (Byte)v;
+ props.Order = (Byte)v;
break;
- default:
- return E_INVALIDARG;
+ case NCoderPropID::kNumThreads: break;
+ case NCoderPropID::kLevel: level = (int)v; break;
+ default: return E_INVALIDARG;
}
}
+ props.Normalize(level);
+ _props = props;
return S_OK;
}
@@ -65,8 +102,8 @@ STDMETHODIMP CEncoder::WriteCoderProperties(ISequentialOutStream *outStream)
{
const UInt32 kPropSize = 5;
Byte props[kPropSize];
- props[0] = _order;
- SetUi32(props + 1, _usedMemSize);
+ props[0] = (Byte)_props.Order;
+ SetUi32(props + 1, _props.MemSize);
return WriteStream(outStream, props, kPropSize);
}
@@ -81,14 +118,14 @@ HRESULT CEncoder::Code(ISequentialInStream *inStream, ISequentialOutStream *outS
}
if (!_outStream.Alloc(1 << 20))
return E_OUTOFMEMORY;
- if (!Ppmd7_Alloc(&_ppmd, _usedMemSize, &g_BigAlloc))
+ if (!Ppmd7_Alloc(&_ppmd, _props.MemSize, &g_BigAlloc))
return E_OUTOFMEMORY;
_outStream.Stream = outStream;
_outStream.Init();
Ppmd7z_RangeEnc_Init(&_rangeEnc);
- Ppmd7_Init(&_ppmd, _order);
+ Ppmd7_Init(&_ppmd, _props.Order);
UInt64 processed = 0;
for (;;)
diff --git a/CPP/7zip/Compress/PpmdEncoder.h b/CPP/7zip/Compress/PpmdEncoder.h
index ed8b3713..fb74cf57 100755
--- a/CPP/7zip/Compress/PpmdEncoder.h
+++ b/CPP/7zip/Compress/PpmdEncoder.h
@@ -1,5 +1,4 @@
// PpmdEncoder.h
-// 2009-03-11 : Igor Pavlov : Public domain
#ifndef __COMPRESS_PPMD_ENCODER_H
#define __COMPRESS_PPMD_ENCODER_H
@@ -15,6 +14,21 @@
namespace NCompress {
namespace NPpmd {
+struct CEncProps
+{
+ UInt32 MemSize;
+ UInt32 ReduceSize;
+ int Order;
+
+ CEncProps()
+ {
+ MemSize = (UInt32)(Int32)-1;
+ ReduceSize = (UInt32)(Int32)-1;
+ Order = -1;
+ }
+ void Normalize(int level);
+};
+
class CEncoder :
public ICompressCoder,
public ICompressSetCoderProperties,
@@ -25,20 +39,15 @@ class CEncoder :
CByteOutBufWrap _outStream;
CPpmd7z_RangeEnc _rangeEnc;
CPpmd7 _ppmd;
-
- UInt32 _usedMemSize;
- Byte _order;
-
+ CEncProps _props;
public:
MY_UNKNOWN_IMP2(
ICompressSetCoderProperties,
ICompressWriteCoderProperties)
-
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(WriteCoderProperties)(ISequentialOutStream *outStream);
-
CEncoder();
~CEncoder();
};
diff --git a/CPP/7zip/Compress/PpmdZip.cpp b/CPP/7zip/Compress/PpmdZip.cpp
index e83d979c..036f3c72 100755
--- a/CPP/7zip/Compress/PpmdZip.cpp
+++ b/CPP/7zip/Compress/PpmdZip.cpp
@@ -1,10 +1,10 @@
// PpmdZip.cpp
-// 2010-03-24 : Igor Pavlov : Public domain
#include "StdAfx.h"
#include "../../../C/CpuArch.h"
+#include "../Common/RegisterCodec.h"
#include "../Common/StreamUtils.h"
#include "PpmdZip.h"
@@ -128,69 +128,109 @@ STDMETHODIMP CDecoder::Code(ISequentialInStream *inStream, ISequentialOutStream
// ---------- Encoder ----------
+void CEncProps::Normalize(int level)
+{
+ if (level < 0) level = 5;
+ if (level == 0) level = 1;
+ if (level > 9) level = 9;
+ if (MemSizeMB == (UInt32)(Int32)-1)
+ MemSizeMB = (1 << ((level > 8 ? 8 : level) - 1));
+ const unsigned kMult = 16;
+ if ((MemSizeMB << 20) / kMult > ReduceSize)
+ {
+ for (UInt32 m = (1 << 20); m <= (1 << 28); m <<= 1)
+ {
+ if (ReduceSize <= m / kMult)
+ {
+ m >>= 20;
+ if (MemSizeMB > m)
+ MemSizeMB = m;
+ break;
+ }
+ }
+ }
+ if (Order == -1) Order = 3 + level;
+ if (Restor == -1)
+ Restor = level < 7 ?
+ PPMD8_RESTORE_METHOD_RESTART :
+ PPMD8_RESTORE_METHOD_CUT_OFF;
+}
+
CEncoder::~CEncoder()
{
Ppmd8_Free(&_ppmd, &g_BigAlloc);
}
-HRESULT CEncoder::SetCoderProperties(const PROPID *propIDs, const PROPVARIANT *props, UInt32 numProps)
+STDMETHODIMP 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 = props[i];
+ const PROPVARIANT &prop = coderProps[i];
+ PROPID propID = propIDs[i];
+ if (propID > NCoderPropID::kReduceSize)
+ continue;
+ if (propID == NCoderPropID::kReduceSize)
+ {
+ if (prop.vt == VT_UI8 && prop.uhVal.QuadPart < (UInt32)(Int32)-1)
+ props.ReduceSize = (UInt32)prop.uhVal.QuadPart;
+ continue;
+ }
if (prop.vt != VT_UI4)
return E_INVALIDARG;
UInt32 v = (UInt32)prop.ulVal;
- switch(propIDs[i])
+ switch (propID)
{
- case NCoderPropID::kAlgorithm:
- if (v > 1)
- return E_INVALIDARG;
- _restor = v;
- break;
case NCoderPropID::kUsedMemorySize:
if (v < (1 << 20) || v > (1 << 28))
return E_INVALIDARG;
- _usedMemInMB = v >> 20;
+ props.MemSizeMB = v >> 20;
break;
case NCoderPropID::kOrder:
if (v < PPMD8_MIN_ORDER || v > PPMD8_MAX_ORDER)
return E_INVALIDARG;
- _order = (Byte)v;
+ props.Order = (Byte)v;
+ break;
+ case NCoderPropID::kNumThreads: break;
+ case NCoderPropID::kLevel: level = (int)v; break;
+ case NCoderPropID::kAlgorithm:
+ if (v > 1)
+ return E_INVALIDARG;
+ props.Restor = v;
break;
- default:
- return E_INVALIDARG;
+ default: return E_INVALIDARG;
}
}
+ props.Normalize(level);
+ _props = props;
return S_OK;
}
-CEncoder::CEncoder():
- _usedMemInMB(16),
- _order(6),
- _restor(PPMD8_RESTORE_METHOD_RESTART)
+CEncoder::CEncoder()
{
+ _props.Normalize(-1);
_ppmd.Stream.Out = &_outStream.p;
Ppmd8_Construct(&_ppmd);
}
-HRESULT CEncoder::Code(ISequentialInStream *inStream, ISequentialOutStream *outStream,
+STDMETHODIMP CEncoder::Code(ISequentialInStream *inStream, ISequentialOutStream *outStream,
const UInt64 * /* inSize */, const UInt64 * /* outSize */, ICompressProgressInfo *progress)
{
if (!_inStream.Alloc())
return E_OUTOFMEMORY;
if (!_outStream.Alloc(1 << 20))
return E_OUTOFMEMORY;
- if (!Ppmd8_Alloc(&_ppmd, _usedMemInMB << 20, &g_BigAlloc))
+ if (!Ppmd8_Alloc(&_ppmd, _props.MemSizeMB << 20, &g_BigAlloc))
return E_OUTOFMEMORY;
_outStream.Stream = outStream;
_outStream.Init();
Ppmd8_RangeEnc_Init(&_ppmd);
- Ppmd8_Init(&_ppmd, _order, _restor);
+ Ppmd8_Init(&_ppmd, _props.Order, _props.Restor);
- UInt32 val = (UInt32)((_order - 1) + ((_usedMemInMB - 1) << 4) + (_restor << 12));
+ UInt32 val = (UInt32)((_props.Order - 1) + ((_props.MemSizeMB - 1) << 4) + (_props.Restor << 12));
_outStream.WriteByte((Byte)(val & 0xFF));
_outStream.WriteByte((Byte)(val >> 8));
RINOK(_outStream.Res);
@@ -220,4 +260,14 @@ HRESULT CEncoder::Code(ISequentialInStream *inStream, ISequentialOutStream *outS
}
}
+/*
+static void *CreateCodec() { return (void *)(ICompressCoder *)(new CDecoder(false)); }
+static void *CreateCodecOut() { return (void *)(ICompressCoder *)(new CEncoder); }
+
+static CCodecInfo g_CodecInfo =
+ { CreateCodec, CreateCodecOut, 0x040162, L"PPMdZIP", 1, false };
+
+REGISTER_CODEC(PPMdZIP)
+*/
+
}}
diff --git a/CPP/7zip/Compress/PpmdZip.h b/CPP/7zip/Compress/PpmdZip.h
index c2288b5a..e15a060d 100755
--- a/CPP/7zip/Compress/PpmdZip.h
+++ b/CPP/7zip/Compress/PpmdZip.h
@@ -1,5 +1,4 @@
// PpmdZip.h
-// 2010-03-11 : Igor Pavlov : Public domain
#ifndef __COMPRESS_PPMD_ZIP_H
#define __COMPRESS_PPMD_ZIP_H
@@ -48,21 +47,37 @@ public:
~CDecoder();
};
+struct CEncProps
+{
+ UInt32 MemSizeMB;
+ UInt32 ReduceSize;
+ int Order;
+ int Restor;
+
+ CEncProps()
+ {
+ MemSizeMB = (UInt32)(Int32)-1;
+ ReduceSize = (UInt32)(Int32)-1;
+ Order = -1;
+ Restor = -1;
+ }
+ void Normalize(int level);
+};
+
class CEncoder :
public ICompressCoder,
+ public ICompressSetCoderProperties,
public CMyUnknownImp
{
CByteOutBufWrap _outStream;
CBuf _inStream;
CPpmd8 _ppmd;
- UInt32 _usedMemInMB;
- unsigned _order;
- unsigned _restor;
+ CEncProps _props;
public:
- MY_UNKNOWN_IMP
+ MY_UNKNOWN_IMP1(ICompressSetCoderProperties)
STDMETHOD(Code)(ISequentialInStream *inStream, ISequentialOutStream *outStream,
const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress);
- HRESULT SetCoderProperties(const PROPID *propIDs, const PROPVARIANT *props, UInt32 numProps);
+ STDMETHOD(SetCoderProperties)(const PROPID *propIDs, const PROPVARIANT *props, UInt32 numProps);
CEncoder();
~CEncoder();
};
diff --git a/CPP/7zip/Compress/QuantumDecoder.cpp b/CPP/7zip/Compress/QuantumDecoder.cpp
index 501bd0e1..63da32cc 100755
--- a/CPP/7zip/Compress/QuantumDecoder.cpp
+++ b/CPP/7zip/Compress/QuantumDecoder.cpp
@@ -33,14 +33,6 @@ HRESULT CDecoder::CodeSpec(UInt32 curSize)
{
if (_remainLen == kLenIdNeedInit)
{
- if (!_keepHistory)
- {
- if (!_outWindowStream.Create((UInt32)1 << _numDictBits))
- return E_OUTOFMEMORY;
- Init();
- }
- if (!_rangeDecoder.Create(1 << 20))
- return E_OUTOFMEMORY;
_rangeDecoder.Init();
_remainLen = 0;
}
@@ -169,6 +161,20 @@ STDMETHODIMP CDecoder::SetOutStreamSize(const UInt64 *outSize)
return E_FAIL;
_remainLen = kLenIdNeedInit;
_outWindowStream.Init(_keepHistory);
+ if (!_keepHistory)
+ Init();
+ return S_OK;
+}
+
+HRESULT CDecoder::SetParams(int numDictBits)
+{
+ if (numDictBits > 21)
+ return E_INVALIDARG;
+ _numDictBits = numDictBits;
+ if (!_outWindowStream.Create((UInt32)1 << _numDictBits))
+ return E_OUTOFMEMORY;
+ if (!_rangeDecoder.Create(1 << 20))
+ return E_OUTOFMEMORY;
return S_OK;
}
diff --git a/CPP/7zip/Compress/QuantumDecoder.h b/CPP/7zip/Compress/QuantumDecoder.h
index e9ab023b..a5f78358 100755
--- a/CPP/7zip/Compress/QuantumDecoder.h
+++ b/CPP/7zip/Compress/QuantumDecoder.h
@@ -253,7 +253,7 @@ public:
STDMETHOD(ReleaseInStream)();
STDMETHOD(SetOutStreamSize)(const UInt64 *outSize);
- void SetParams(int numDictBits) { _numDictBits = numDictBits; }
+ HRESULT SetParams(int numDictBits);
void SetKeepHistory(bool keepHistory) { _keepHistory = keepHistory; }
CDecoder(): _keepHistory(false) {}
virtual ~CDecoder() {}