mirror of
https://github.com/Xevion/easy7zip.git
synced 2025-12-08 22:07:07 -06:00
21.02
This commit is contained in:
@@ -55,10 +55,15 @@ The number of selectors stored in bzip2 block:
|
||||
(numSelectors <= 18001) - must work with any decoder.
|
||||
(numSelectors == 18002) - works with bzip2 1.0.6 decoder and all derived decoders.
|
||||
(numSelectors > 18002)
|
||||
7-Zip decoder doesn't support it.
|
||||
bzip2 1.0.6 decoder can overflow selector[18002] arrays. But there are another
|
||||
lbzip2 2.5: encoder can write up to (18001 + 7) selectors.
|
||||
|
||||
7-Zip before 19.03: decoder doesn't support it.
|
||||
7-Zip 19.03: decoder allows 8 additional selector records for lbzip2 compatibility.
|
||||
|
||||
bzip2 1.0.6: decoder can overflow selector[18002] arrays. But there are another
|
||||
arrays after selector arrays. So the compiled code works.
|
||||
lbzip2 2.5 encoder can write up to (18001 + 7) selectors.
|
||||
bzip2 1.0.7: decoder doesn't support it.
|
||||
bzip2 1.0.8: decoder allows additional selector records for lbzip2 compatibility.
|
||||
*/
|
||||
|
||||
}}
|
||||
|
||||
@@ -19,6 +19,7 @@ void CBZip2Crc::InitTable()
|
||||
}
|
||||
}
|
||||
|
||||
static
|
||||
class CBZip2CrcTableInit
|
||||
{
|
||||
public:
|
||||
|
||||
@@ -20,7 +20,6 @@
|
||||
#define PRIN(s)
|
||||
#define PRIN_VAL(s, val)
|
||||
|
||||
#define PRIN_MT(s) PRIN(" " s)
|
||||
|
||||
#include "../../../C/Alloc.h"
|
||||
|
||||
@@ -183,10 +182,10 @@ SRes CBase::ReadStreamSignature2()
|
||||
unsigned b;
|
||||
READ_BITS_8(b, 8);
|
||||
|
||||
if ( state2 == 0 && b != kArSig0
|
||||
|| state2 == 1 && b != kArSig1
|
||||
|| state2 == 2 && b != kArSig2
|
||||
|| state2 == 3 && (b <= kArSig3 || b > kArSig3 + kBlockSizeMultMax))
|
||||
if ( (state2 == 0 && b != kArSig0)
|
||||
|| (state2 == 1 && b != kArSig1)
|
||||
|| (state2 == 2 && b != kArSig2)
|
||||
|| (state2 == 3 && (b <= kArSig3 || b > kArSig3 + kBlockSizeMultMax)))
|
||||
return SZ_ERROR_DATA;
|
||||
state2++;
|
||||
|
||||
@@ -342,7 +341,11 @@ SRes CBase::ReadBlock2()
|
||||
state2 = 0x543210;
|
||||
state3 = 0;
|
||||
state4 = 0;
|
||||
if (numSelectors == 0 || numSelectors > kNumSelectorsMax)
|
||||
// lbzip2 can write small number of additional selectors,
|
||||
// 20.01: we allow big number of selectors here like bzip2-1.0.8
|
||||
if (numSelectors == 0
|
||||
// || numSelectors > kNumSelectorsMax_Decoder
|
||||
)
|
||||
return SZ_ERROR_DATA;
|
||||
}
|
||||
|
||||
@@ -365,10 +368,19 @@ SRes CBase::ReadBlock2()
|
||||
UInt32 mask = ((UInt32)1 << ((state4 + 1) * kMtfBits)) - 1;
|
||||
state4 = 0;
|
||||
state2 = ((state2 << kMtfBits) & mask) | (state2 & ~mask) | tmp;
|
||||
selectors[state3] = (Byte)tmp;
|
||||
// 20.01: here we keep compatibility with bzip2-1.0.8 decoder:
|
||||
if (state3 < kNumSelectorsMax)
|
||||
selectors[state3] = (Byte)tmp;
|
||||
}
|
||||
while (++state3 < numSelectors);
|
||||
|
||||
// we allowed additional dummy selector records filled above to support lbzip2's archives.
|
||||
// but we still don't allow to use these additional dummy selectors in the code bellow
|
||||
// bzip2 1.0.8 decoder also has similar restriction.
|
||||
|
||||
if (numSelectors > kNumSelectorsMax)
|
||||
numSelectors = kNumSelectorsMax;
|
||||
|
||||
state = STATE_LEVELS;
|
||||
state2 = 0;
|
||||
state3 = 0;
|
||||
@@ -412,14 +424,15 @@ SRes CBase::ReadBlock2()
|
||||
state5 = 0;
|
||||
}
|
||||
|
||||
// 19.03: we use Build() instead of BuildFull() to support lbzip2 archives
|
||||
// lbzip2 2.5 can produce dummy tree, where lens[i] = kMaxHuffmanLen
|
||||
// BuildFull() returns error for such tree
|
||||
/*
|
||||
for (unsigned i = state4; i < kMaxAlphaSize; i++)
|
||||
lens[i] = 0;
|
||||
if (!huffs[state2].Build(lens))
|
||||
*/
|
||||
/*
|
||||
if (!huffs[state2].BuildFull(lens, state4))
|
||||
*/
|
||||
return SZ_ERROR_DATA;
|
||||
state3 = 0;
|
||||
}
|
||||
@@ -476,10 +489,11 @@ SRes CBase::ReadBlock2()
|
||||
val = VAL >> (32 - kMaxHuffmanLen);
|
||||
unsigned len;
|
||||
for (len = kNumTableBits + 1; val >= huff->_limits[len]; len++);
|
||||
/*
|
||||
|
||||
// 19.03: we use that check to support partial trees created Build() for lbzip2 archives
|
||||
if (len > kNumBitsMax)
|
||||
return SZ_ERROR_DATA; // that check is required, if NHuffman::Build() was used instead of BuildFull()
|
||||
*/
|
||||
|
||||
if (_numBits < len)
|
||||
{
|
||||
SAVE_LOCAL
|
||||
@@ -769,7 +783,7 @@ Byte * CSpecState::Decode(Byte *data, size_t size) throw()
|
||||
continue;
|
||||
}
|
||||
|
||||
reps = b;
|
||||
reps = (int)b;
|
||||
while (reps)
|
||||
{
|
||||
reps--;
|
||||
@@ -802,7 +816,7 @@ Byte * CSpecState::Decode(Byte *data, size_t size) throw()
|
||||
_randToGo--;
|
||||
}
|
||||
|
||||
reps = b;
|
||||
reps = (int)b;
|
||||
}
|
||||
|
||||
_tPos = tPos;
|
||||
@@ -857,7 +871,7 @@ HRESULT CDecoder::DecodeBlock(const CBlockProps &props)
|
||||
}
|
||||
|
||||
TICKS_START
|
||||
const size_t processed = block.Decode(data, size) - data;
|
||||
const size_t processed = (size_t)(block.Decode(data, size) - data);
|
||||
TICKS_UPDATE(2)
|
||||
|
||||
_outPosTotal += processed;
|
||||
@@ -879,11 +893,12 @@ HRESULT CDecoder::DecodeBlock(const CBlockProps &props)
|
||||
|
||||
|
||||
CDecoder::CDecoder():
|
||||
_inBuf(NULL),
|
||||
_outBuf(NULL),
|
||||
_counters(NULL),
|
||||
FinishMode(false),
|
||||
_outSizeDefined(false)
|
||||
_outSizeDefined(false),
|
||||
_counters(NULL),
|
||||
_inBuf(NULL),
|
||||
_inProcessed(0)
|
||||
{
|
||||
#ifndef _7ZIP_ST
|
||||
MtMode = false;
|
||||
@@ -909,9 +924,8 @@ CDecoder::~CDecoder()
|
||||
ScoutEvent.Set();
|
||||
|
||||
PRIN("\nThread.Wait()()");
|
||||
Thread.Wait();
|
||||
Thread.Wait_Close();
|
||||
PRIN("\n after Thread.Wait()()");
|
||||
Thread.Close();
|
||||
|
||||
// if (ScoutRes != S_OK) throw ScoutRes;
|
||||
}
|
||||
@@ -929,7 +943,7 @@ HRESULT CDecoder::ReadInput()
|
||||
if (Base._buf != Base._lim || _inputFinished || _inputRes != S_OK)
|
||||
return _inputRes;
|
||||
|
||||
_inProcessed += (Base._buf - _inBuf);
|
||||
_inProcessed += (size_t)(Base._buf - _inBuf);
|
||||
Base._buf = _inBuf;
|
||||
Base._lim = _inBuf;
|
||||
UInt32 size = 0;
|
||||
@@ -1138,7 +1152,11 @@ HRESULT CDecoder::DecodeStreams(ICompressProgressInfo *progress)
|
||||
if (useMt)
|
||||
{
|
||||
PRIN("DecoderEvent.Lock()");
|
||||
RINOK(DecoderEvent.Lock());
|
||||
{
|
||||
WRes wres = DecoderEvent.Lock();
|
||||
if (wres != 0)
|
||||
return HRESULT_FROM_WIN32(wres);
|
||||
}
|
||||
NeedWaitScout = false;
|
||||
PRIN("-- DecoderEvent.Lock()");
|
||||
props = _block.Props;
|
||||
@@ -1186,7 +1204,11 @@ HRESULT CDecoder::DecodeStreams(ICompressProgressInfo *progress)
|
||||
*/
|
||||
|
||||
PRIN("ScoutEvent.Set()");
|
||||
RINOK(ScoutEvent.Set());
|
||||
{
|
||||
WRes wres = ScoutEvent.Set();
|
||||
if (wres != 0)
|
||||
return HRESULT_FROM_WIN32(wres);
|
||||
}
|
||||
NeedWaitScout = true;
|
||||
}
|
||||
#endif
|
||||
@@ -1219,14 +1241,17 @@ bool CDecoder::CreateInputBufer()
|
||||
_inBuf = (Byte *)MidAlloc(kInBufSize);
|
||||
if (!_inBuf)
|
||||
return false;
|
||||
Base._buf = _inBuf;
|
||||
Base._lim = _inBuf;
|
||||
}
|
||||
if (!_counters)
|
||||
{
|
||||
_counters = (UInt32 *)::BigAlloc((256 + kBlockSizeMax) * sizeof(UInt32)
|
||||
const size_t size = (256 + kBlockSizeMax) * sizeof(UInt32)
|
||||
#ifdef BZIP2_BYTE_MODE
|
||||
+ kBlockSizeMax
|
||||
#endif
|
||||
+ 256);
|
||||
+ 256;
|
||||
_counters = (UInt32 *)::BigAlloc(size);
|
||||
if (!_counters)
|
||||
return false;
|
||||
Base.Counters = _counters;
|
||||
@@ -1266,14 +1291,19 @@ STDMETHODIMP CDecoder::Code(ISequentialInStream *inStream, ISequentialOutStream
|
||||
}
|
||||
*/
|
||||
|
||||
InitOutSize(outSize);
|
||||
|
||||
_inputFinished = false;
|
||||
_inputRes = S_OK;
|
||||
_writeRes = S_OK;
|
||||
|
||||
try {
|
||||
|
||||
InitOutSize(outSize);
|
||||
|
||||
// we can request data from InputBuffer after Code().
|
||||
// so we init InputBuffer before any function return.
|
||||
|
||||
InitInputBuffer();
|
||||
|
||||
if (!CreateInputBufer())
|
||||
return E_OUTOFMEMORY;
|
||||
|
||||
@@ -1286,7 +1316,7 @@ STDMETHODIMP CDecoder::Code(ISequentialInStream *inStream, ISequentialOutStream
|
||||
|
||||
Base.InStream = inStream;
|
||||
|
||||
InitInputBuffer();
|
||||
// InitInputBuffer();
|
||||
|
||||
_outStream = outStream;
|
||||
_outWritten = 0;
|
||||
@@ -1323,23 +1353,43 @@ STDMETHODIMP CDecoder::SetFinishMode(UInt32 finishMode)
|
||||
|
||||
STDMETHODIMP CDecoder::GetInStreamProcessedSize(UInt64 *value)
|
||||
{
|
||||
*value = GetInputProcessedSize();
|
||||
*value = GetInStreamSize();
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
|
||||
STDMETHODIMP CDecoder::ReadUnusedFromInBuf(void *data, UInt32 size, UInt32 *processedSize)
|
||||
{
|
||||
Base.AlignToByte();
|
||||
UInt32 i;
|
||||
for (i = 0; i < size; i++)
|
||||
{
|
||||
int b;
|
||||
Base.ReadByte(b);
|
||||
if (b < 0)
|
||||
break;
|
||||
((Byte *)data)[i] = (Byte)b;
|
||||
}
|
||||
if (processedSize)
|
||||
*processedSize = i;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
|
||||
#ifndef _7ZIP_ST
|
||||
|
||||
#define RINOK_THREAD(x) { WRes __result_ = (x); if (__result_ != 0) return __result_; }
|
||||
#define PRIN_MT(s) PRIN(" " s)
|
||||
|
||||
// #define RINOK_THREAD(x) { WRes __result_ = (x); if (__result_ != 0) return __result_; }
|
||||
|
||||
static THREAD_FUNC_DECL RunScout2(void *p) { ((CDecoder *)p)->RunScout(); return 0; }
|
||||
|
||||
HRESULT CDecoder::CreateThread()
|
||||
{
|
||||
RINOK_THREAD(DecoderEvent.CreateIfNotCreated());
|
||||
RINOK_THREAD(ScoutEvent.CreateIfNotCreated());
|
||||
RINOK_THREAD(Thread.Create(RunScout2, this));
|
||||
return S_OK;
|
||||
WRes wres = DecoderEvent.CreateIfNotCreated_Reset();
|
||||
if (wres == 0) { wres = ScoutEvent.CreateIfNotCreated_Reset();
|
||||
if (wres == 0) { wres = Thread.Create(RunScout2, this); }}
|
||||
return HRESULT_FROM_WIN32(wres);
|
||||
}
|
||||
|
||||
void CDecoder::RunScout()
|
||||
@@ -1512,10 +1562,12 @@ STDMETHODIMP CDecoder::SetOutStreamSize(const UInt64 *outSize)
|
||||
{
|
||||
InitOutSize(outSize);
|
||||
|
||||
InitInputBuffer();
|
||||
|
||||
if (!CreateInputBufer())
|
||||
return E_OUTOFMEMORY;
|
||||
|
||||
InitInputBuffer();
|
||||
// InitInputBuffer();
|
||||
|
||||
StartNewStream();
|
||||
|
||||
|
||||
@@ -73,9 +73,19 @@ struct CBitDecoder
|
||||
*/
|
||||
|
||||
SRes ReadByte(int &b);
|
||||
|
||||
CBitDecoder():
|
||||
_buf(NULL),
|
||||
_lim(NULL)
|
||||
{
|
||||
InitBitDecoder();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
// 19.03: we allow additional 8 selectors to support files created by lbzip2.
|
||||
const UInt32 kNumSelectorsMax_Decoder = kNumSelectorsMax + 8;
|
||||
|
||||
struct CBase: public CBitDecoder
|
||||
{
|
||||
unsigned numInUse;
|
||||
@@ -100,7 +110,7 @@ struct CBase: public CBitDecoder
|
||||
|
||||
private:
|
||||
CMtf8Decoder mtf;
|
||||
Byte selectors[kNumSelectorsMax];
|
||||
Byte selectors[kNumSelectorsMax_Decoder];
|
||||
CHuffmanDecoder huffs[kNumTablesMax];
|
||||
|
||||
Byte lens[kMaxAlphaSize];
|
||||
@@ -188,6 +198,7 @@ class CDecoder :
|
||||
public ICompressCoder,
|
||||
public ICompressSetFinishMode,
|
||||
public ICompressGetInStreamProcessedSize,
|
||||
public ICompressReadUnusedFromInBuf,
|
||||
|
||||
#ifndef NO_READ_FROM_CODER
|
||||
public ICompressSetInStream,
|
||||
@@ -293,6 +304,8 @@ public:
|
||||
|
||||
void InitInputBuffer()
|
||||
{
|
||||
// We use InitInputBuffer() before stream init.
|
||||
// So don't read from stream here
|
||||
_inProcessed = 0;
|
||||
Base._buf = _inBuf;
|
||||
Base._lim = _inBuf;
|
||||
@@ -302,7 +315,12 @@ public:
|
||||
UInt64 GetInputProcessedSize() const
|
||||
{
|
||||
// for NSIS case : we need also look the number of bits in bitDecoder
|
||||
return _inProcessed + (Base._buf - _inBuf);
|
||||
return _inProcessed + (size_t)(Base._buf - _inBuf);
|
||||
}
|
||||
|
||||
UInt64 GetInStreamSize() const
|
||||
{
|
||||
return _inProcessed + (size_t)(Base._buf - _inBuf) - (Base._numBits >> 3);
|
||||
}
|
||||
|
||||
UInt64 GetOutProcessedSize() const { return _outWritten + _outPos; }
|
||||
@@ -324,6 +342,7 @@ public:
|
||||
MY_QUERYINTERFACE_BEGIN2(ICompressCoder)
|
||||
MY_QUERYINTERFACE_ENTRY(ICompressSetFinishMode)
|
||||
MY_QUERYINTERFACE_ENTRY(ICompressGetInStreamProcessedSize)
|
||||
MY_QUERYINTERFACE_ENTRY(ICompressReadUnusedFromInBuf)
|
||||
|
||||
#ifndef NO_READ_FROM_CODER
|
||||
MY_QUERYINTERFACE_ENTRY(ICompressSetInStream)
|
||||
@@ -344,6 +363,7 @@ public:
|
||||
|
||||
STDMETHOD(SetFinishMode)(UInt32 finishMode);
|
||||
STDMETHOD(GetInStreamProcessedSize)(UInt64 *value);
|
||||
STDMETHOD(ReadUnusedFromInBuf)(void *data, UInt32 size, UInt32 *processedSize);
|
||||
|
||||
UInt64 GetNumStreams() const { return Base.NumStreams; }
|
||||
UInt64 GetNumBlocks() const { return Base.NumBlocks; }
|
||||
|
||||
@@ -20,17 +20,17 @@ static const unsigned kNumHuffPasses = 4;
|
||||
|
||||
bool CThreadInfo::Alloc()
|
||||
{
|
||||
if (m_BlockSorterIndex == 0)
|
||||
if (!m_BlockSorterIndex)
|
||||
{
|
||||
m_BlockSorterIndex = (UInt32 *)::BigAlloc(BLOCK_SORT_BUF_SIZE(kBlockSizeMax) * sizeof(UInt32));
|
||||
if (m_BlockSorterIndex == 0)
|
||||
if (!m_BlockSorterIndex)
|
||||
return false;
|
||||
}
|
||||
|
||||
if (m_Block == 0)
|
||||
if (!m_Block)
|
||||
{
|
||||
m_Block = (Byte *)::MidAlloc(kBlockSizeMax * 5 + kBlockSizeMax / 10 + (20 << 10));
|
||||
if (m_Block == 0)
|
||||
if (!m_Block)
|
||||
return false;
|
||||
m_MtfArray = m_Block + kBlockSizeMax;
|
||||
m_TempArray = m_MtfArray + kBlockSizeMax * 2 + 2;
|
||||
@@ -41,9 +41,9 @@ bool CThreadInfo::Alloc()
|
||||
void CThreadInfo::Free()
|
||||
{
|
||||
::BigFree(m_BlockSorterIndex);
|
||||
m_BlockSorterIndex = 0;
|
||||
m_BlockSorterIndex = NULL;
|
||||
::MidFree(m_Block);
|
||||
m_Block = 0;
|
||||
m_Block = NULL;
|
||||
}
|
||||
|
||||
#ifndef _7ZIP_ST
|
||||
@@ -53,15 +53,19 @@ static THREAD_FUNC_DECL MFThread(void *threadCoderInfo)
|
||||
return ((CThreadInfo *)threadCoderInfo)->ThreadFunc();
|
||||
}
|
||||
|
||||
#define RINOK_THREAD(x) { WRes __result_ = (x); if (__result_ != 0) return __result_; }
|
||||
|
||||
HRESULT CThreadInfo::Create()
|
||||
{
|
||||
RINOK_THREAD(StreamWasFinishedEvent.Create());
|
||||
RINOK_THREAD(WaitingWasStartedEvent.Create());
|
||||
RINOK_THREAD(CanWriteEvent.Create());
|
||||
RINOK_THREAD(Thread.Create(MFThread, this));
|
||||
return S_OK;
|
||||
WRes wres = StreamWasFinishedEvent.Create();
|
||||
if (wres == 0) { wres = WaitingWasStartedEvent.Create();
|
||||
if (wres == 0) { wres = CanWriteEvent.Create();
|
||||
if (wres == 0)
|
||||
{
|
||||
if (Encoder->_props.Affinity != 0)
|
||||
wres = Thread.Create_With_Affinity(MFThread, this, (CAffinityMask)Encoder->_props.Affinity);
|
||||
else
|
||||
wres = Thread.Create(MFThread, this);
|
||||
}}}
|
||||
return HRESULT_FROM_WIN32(wres);
|
||||
}
|
||||
|
||||
void CThreadInfo::FinishStream(bool needLeave)
|
||||
@@ -74,7 +78,7 @@ void CThreadInfo::FinishStream(bool needLeave)
|
||||
WaitingWasStartedEvent.Set();
|
||||
}
|
||||
|
||||
DWORD CThreadInfo::ThreadFunc()
|
||||
THREAD_FUNC_RET_TYPE CThreadInfo::ThreadFunc()
|
||||
{
|
||||
for (;;)
|
||||
{
|
||||
@@ -133,7 +137,7 @@ void CEncProps::Normalize(int level)
|
||||
if (NumPasses > kNumPassesMax) NumPasses = kNumPassesMax;
|
||||
|
||||
if (BlockSizeMult == (UInt32)(Int32)-1)
|
||||
BlockSizeMult = (level >= 5 ? 9 : (level >= 1 ? level * 2 - 1: 1));
|
||||
BlockSizeMult = (level >= 5 ? 9 : (level >= 1 ? (unsigned)level * 2 - 1: 1));
|
||||
if (BlockSizeMult < kBlockSizeMultMin) BlockSizeMult = kBlockSizeMultMin;
|
||||
if (BlockSizeMult > kBlockSizeMultMax) BlockSizeMult = kBlockSizeMultMax;
|
||||
}
|
||||
@@ -143,7 +147,7 @@ CEncoder::CEncoder()
|
||||
_props.Normalize(-1);
|
||||
|
||||
#ifndef _7ZIP_ST
|
||||
ThreadsInfo = 0;
|
||||
ThreadsInfo = NULL;
|
||||
m_NumThreadsPrev = 0;
|
||||
NumThreads = 1;
|
||||
#endif
|
||||
@@ -157,9 +161,14 @@ CEncoder::~CEncoder()
|
||||
|
||||
HRESULT CEncoder::Create()
|
||||
{
|
||||
RINOK_THREAD(CanProcessEvent.CreateIfNotCreated());
|
||||
RINOK_THREAD(CanStartWaitingEvent.CreateIfNotCreated());
|
||||
if (ThreadsInfo != 0 && m_NumThreadsPrev == NumThreads)
|
||||
{
|
||||
WRes wres = CanProcessEvent.CreateIfNotCreated_Reset();
|
||||
if (wres == 0) { wres = CanStartWaitingEvent.CreateIfNotCreated_Reset(); }
|
||||
if (wres != 0)
|
||||
return HRESULT_FROM_WIN32(wres);
|
||||
}
|
||||
|
||||
if (ThreadsInfo && m_NumThreadsPrev == NumThreads)
|
||||
return S_OK;
|
||||
try
|
||||
{
|
||||
@@ -167,7 +176,7 @@ HRESULT CEncoder::Create()
|
||||
MtMode = (NumThreads > 1);
|
||||
m_NumThreadsPrev = NumThreads;
|
||||
ThreadsInfo = new CThreadInfo[NumThreads];
|
||||
if (ThreadsInfo == 0)
|
||||
if (!ThreadsInfo)
|
||||
return E_OUTOFMEMORY;
|
||||
}
|
||||
catch(...) { return E_OUTOFMEMORY; }
|
||||
@@ -199,11 +208,11 @@ void CEncoder::Free()
|
||||
{
|
||||
CThreadInfo &ti = ThreadsInfo[t];
|
||||
if (MtMode)
|
||||
ti.Thread.Wait();
|
||||
ti.Thread.Wait_Close();
|
||||
ti.Free();
|
||||
}
|
||||
delete []ThreadsInfo;
|
||||
ThreadsInfo = 0;
|
||||
ThreadsInfo = NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -745,9 +754,11 @@ HRESULT CEncoder::CodeReal(ISequentialInStream *inStream, ISequentialOutStream *
|
||||
CThreadInfo &ti = ThreadsInfo[t];
|
||||
if (MtMode)
|
||||
{
|
||||
RINOK(ti.StreamWasFinishedEvent.Reset());
|
||||
RINOK(ti.WaitingWasStartedEvent.Reset());
|
||||
RINOK(ti.CanWriteEvent.Reset());
|
||||
WRes wres = ti.StreamWasFinishedEvent.Reset();
|
||||
if (wres == 0) { wres = ti.WaitingWasStartedEvent.Reset();
|
||||
if (wres == 0) { wres = ti.CanWriteEvent.Reset(); }}
|
||||
if (wres != 0)
|
||||
return HRESULT_FROM_WIN32(wres);
|
||||
}
|
||||
#else
|
||||
CThreadInfo &ti = ThreadsInfo;
|
||||
@@ -854,6 +865,16 @@ HRESULT CEncoder::SetCoderProperties(const PROPID *propIDs, const PROPVARIANT *c
|
||||
{
|
||||
const PROPVARIANT &prop = coderProps[i];
|
||||
PROPID propID = propIDs[i];
|
||||
|
||||
if (propID == NCoderPropID::kAffinity)
|
||||
{
|
||||
if (prop.vt == VT_UI8)
|
||||
props.Affinity = prop.uhVal.QuadPart;
|
||||
else
|
||||
return E_INVALIDARG;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (propID >= NCoderPropID::kReduceSize)
|
||||
continue;
|
||||
if (prop.vt != VT_UI4)
|
||||
@@ -863,7 +884,7 @@ HRESULT CEncoder::SetCoderProperties(const PROPID *propIDs, const PROPVARIANT *c
|
||||
{
|
||||
case NCoderPropID::kNumPasses: props.NumPasses = v; break;
|
||||
case NCoderPropID::kDictionarySize: props.BlockSizeMult = v / kBlockSizeStep; break;
|
||||
case NCoderPropID::kLevel: level = v; break;
|
||||
case NCoderPropID::kLevel: level = (int)v; break;
|
||||
case NCoderPropID::kNumThreads:
|
||||
{
|
||||
#ifndef _7ZIP_ST
|
||||
|
||||
@@ -53,7 +53,7 @@ public:
|
||||
unsigned numNewBits = MyMin(numBits, _bitPos);
|
||||
numBits -= numNewBits;
|
||||
|
||||
_curByte <<= numNewBits;
|
||||
_curByte = (Byte)(_curByte << numNewBits);
|
||||
UInt32 newBits = value >> numBits;
|
||||
_curByte |= Byte(newBits);
|
||||
value -= (newBits << numBits);
|
||||
@@ -134,10 +134,10 @@ public:
|
||||
Byte MtPad[1 << 8]; // It's pad for Multi-Threading. Must be >= Cache_Line_Size.
|
||||
HRESULT Create();
|
||||
void FinishStream(bool needLeave);
|
||||
DWORD ThreadFunc();
|
||||
THREAD_FUNC_RET_TYPE ThreadFunc();
|
||||
#endif
|
||||
|
||||
CThreadInfo(): m_BlockSorterIndex(0), m_Block(0) {}
|
||||
CThreadInfo(): m_Block(NULL), m_BlockSorterIndex(NULL) {}
|
||||
~CThreadInfo() { Free(); }
|
||||
bool Alloc();
|
||||
void Free();
|
||||
@@ -149,11 +149,13 @@ struct CEncProps
|
||||
{
|
||||
UInt32 BlockSizeMult;
|
||||
UInt32 NumPasses;
|
||||
UInt64 Affinity;
|
||||
|
||||
CEncProps()
|
||||
{
|
||||
BlockSizeMult = (UInt32)(Int32)-1;
|
||||
NumPasses = (UInt32)(Int32)-1;
|
||||
Affinity = 0;
|
||||
}
|
||||
void Normalize(int level);
|
||||
bool DoOptimizeNumTables() const { return NumPasses > 1; }
|
||||
|
||||
@@ -234,14 +234,14 @@ HRESULT CEncoder::CodeReal(ISequentialInStream * const *inStreams, const UInt64
|
||||
|
||||
Bcj2Enc_Encode(&enc);
|
||||
|
||||
currentInPos = totalStreamRead - numBytes_in_ReadBuf + (enc.src - _bufs[BCJ2_NUM_STREAMS]) - enc.tempPos;
|
||||
currentInPos = totalStreamRead - numBytes_in_ReadBuf + (size_t)(enc.src - _bufs[BCJ2_NUM_STREAMS]) - enc.tempPos;
|
||||
|
||||
if (Bcj2Enc_IsFinished(&enc))
|
||||
break;
|
||||
|
||||
if (enc.state < BCJ2_NUM_STREAMS)
|
||||
{
|
||||
size_t curSize = enc.bufs[enc.state] - _bufs[enc.state];
|
||||
const size_t curSize = (size_t)(enc.bufs[enc.state] - _bufs[enc.state]);
|
||||
// printf("Write stream = %2d %6d\n", enc.state, curSize);
|
||||
RINOK(WriteStream(outStreams[enc.state], _bufs[enc.state], curSize));
|
||||
if (enc.state == BCJ2_STREAM_RC)
|
||||
@@ -286,7 +286,7 @@ HRESULT CEncoder::CodeReal(ISequentialInStream * const *inStreams, const UInt64
|
||||
|
||||
if (progress && currentInPos - prevProgress >= (1 << 20))
|
||||
{
|
||||
UInt64 outSize2 = currentInPos + outSizeRc + enc.bufs[BCJ2_STREAM_RC] - enc.bufs[BCJ2_STREAM_RC];
|
||||
const UInt64 outSize2 = currentInPos + outSizeRc + (size_t)(enc.bufs[BCJ2_STREAM_RC] - enc.bufs[BCJ2_STREAM_RC]);
|
||||
prevProgress = currentInPos;
|
||||
// printf("progress %8d, %8d\n", (int)inSize2, (int)outSize2);
|
||||
RINOK(progress->SetRatioInfo(¤tInPos, &outSize2));
|
||||
@@ -295,7 +295,7 @@ HRESULT CEncoder::CodeReal(ISequentialInStream * const *inStreams, const UInt64
|
||||
|
||||
for (int i = 0; i < BCJ2_NUM_STREAMS; i++)
|
||||
{
|
||||
RINOK(WriteStream(outStreams[i], _bufs[i], enc.bufs[i] - _bufs[i]));
|
||||
RINOK(WriteStream(outStreams[i], _bufs[i], (size_t)(enc.bufs[i] - _bufs[i])));
|
||||
}
|
||||
|
||||
// if (currentInPos != subStreamStartPos + subStreamSize) return E_FAIL;
|
||||
@@ -440,7 +440,7 @@ HRESULT CDecoder::Code(ISequentialInStream * const *inStreams, const UInt64 * co
|
||||
}
|
||||
else // if (dec.state <= BCJ2_STATE_ORIG)
|
||||
{
|
||||
size_t curSize = dec.dest - _bufs[BCJ2_NUM_STREAMS];
|
||||
const size_t curSize = (size_t)(dec.dest - _bufs[BCJ2_NUM_STREAMS]);
|
||||
if (curSize != 0)
|
||||
{
|
||||
outSizeProcessed += curSize;
|
||||
@@ -463,17 +463,17 @@ HRESULT CDecoder::Code(ISequentialInStream * const *inStreams, const UInt64 * co
|
||||
|
||||
if (progress)
|
||||
{
|
||||
const UInt64 outSize2 = outSizeProcessed + (dec.dest - _bufs[BCJ2_NUM_STREAMS]);
|
||||
const UInt64 outSize2 = outSizeProcessed + (size_t)(dec.dest - _bufs[BCJ2_NUM_STREAMS]);
|
||||
if (outSize2 - prevProgress >= (1 << 22))
|
||||
{
|
||||
const UInt64 inSize2 = outSize2 + _inStreamsProcessed[BCJ2_STREAM_RC] - (dec.lims[BCJ2_STREAM_RC] - dec.bufs[BCJ2_STREAM_RC]);
|
||||
const UInt64 inSize2 = outSize2 + _inStreamsProcessed[BCJ2_STREAM_RC] - (size_t)(dec.lims[BCJ2_STREAM_RC] - dec.bufs[BCJ2_STREAM_RC]);
|
||||
RINOK(progress->SetRatioInfo(&inSize2, &outSize2));
|
||||
prevProgress = outSize2;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
size_t curSize = dec.dest - _bufs[BCJ2_NUM_STREAMS];
|
||||
const size_t curSize = (size_t)(dec.dest - _bufs[BCJ2_NUM_STREAMS]);
|
||||
if (curSize != 0)
|
||||
{
|
||||
outSizeProcessed += curSize;
|
||||
@@ -498,7 +498,7 @@ HRESULT CDecoder::Code(ISequentialInStream * const *inStreams, const UInt64 * co
|
||||
{
|
||||
for (int i = 0; i < BCJ2_NUM_STREAMS; i++)
|
||||
{
|
||||
size_t rem = dec.lims[i] - dec.bufs[i] + _extraReadSizes[i];
|
||||
const size_t rem = (size_t)(dec.lims[i] - dec.bufs[i]) + _extraReadSizes[i];
|
||||
/*
|
||||
if (rem != 0)
|
||||
return S_FALSE;
|
||||
@@ -658,7 +658,7 @@ STDMETHODIMP CDecoder::Read(void *data, UInt32 size, UInt32 *processedSize)
|
||||
|
||||
STDMETHODIMP CDecoder::GetInStreamProcessedSize2(UInt32 streamIndex, UInt64 *value)
|
||||
{
|
||||
const size_t rem = dec.lims[streamIndex] - dec.bufs[streamIndex] + _extraReadSizes[streamIndex];
|
||||
const size_t rem = (size_t)(dec.lims[streamIndex] - dec.bufs[streamIndex]) + _extraReadSizes[streamIndex];
|
||||
*value = _inStreamsProcessed[streamIndex] - rem;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
@@ -16,7 +16,7 @@ REGISTER_CODEC_CREATE_2(CreateCodecOut, CEncoder(), ICompressCoder2)
|
||||
#define CreateCodecOut NULL
|
||||
#endif
|
||||
|
||||
REGISTER_CODEC_VAR
|
||||
REGISTER_CODEC_VAR(BCJ2)
|
||||
{ CreateCodec, CreateCodecOut, 0x303011B, "BCJ2", 4, false };
|
||||
|
||||
REGISTER_CODEC(BCJ2)
|
||||
|
||||
@@ -8,6 +8,7 @@ namespace NBitl {
|
||||
|
||||
Byte kInvertTable[256];
|
||||
|
||||
static
|
||||
struct CInverterTableInitializer
|
||||
{
|
||||
CInverterTableInitializer()
|
||||
|
||||
@@ -38,7 +38,18 @@ public:
|
||||
_value = 0;
|
||||
}
|
||||
|
||||
UInt64 GetStreamSize() const { return _stream.GetStreamSize(); }
|
||||
// the size of portion data in real stream that was already read from this object.
|
||||
// it doesn't include unused data in BitStream object buffer (up to 4 bytes)
|
||||
// it doesn't include unused data in TInByte buffers
|
||||
// it doesn't include virtual Extra bytes after the end of real stream data
|
||||
UInt64 GetStreamSize() const
|
||||
{
|
||||
return ExtraBitsWereRead() ?
|
||||
_stream.GetStreamSize():
|
||||
GetProcessedSize();
|
||||
}
|
||||
|
||||
// the size of virtual data that was read from this object.
|
||||
UInt64 GetProcessedSize() const { return _stream.GetProcessedSize() - ((kNumBigValueBits - _bitPos) >> 3); }
|
||||
|
||||
bool ThereAreDataInBitsBuffer() const { return this->_bitPos != kNumBigValueBits; }
|
||||
@@ -139,6 +150,17 @@ public:
|
||||
MovePos(8);
|
||||
return b;
|
||||
}
|
||||
|
||||
// call it only if the object is aligned for byte.
|
||||
MY_FORCE_INLINE
|
||||
bool ReadAlignedByte_FromBuf(Byte &b)
|
||||
{
|
||||
if (this->_bitPos == kNumBigValueBits)
|
||||
return this->_stream.ReadByte_FromBuf(b);
|
||||
b = (Byte)(_normalValue & 0xFF);
|
||||
MovePos(8);
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -39,7 +39,7 @@ public:
|
||||
{
|
||||
if (numBits < _bitPos)
|
||||
{
|
||||
_curByte |= (value & ((1 << numBits) - 1)) << (8 - _bitPos);
|
||||
_curByte |= (Byte)((value & ((1 << numBits) - 1)) << (8 - _bitPos));
|
||||
_bitPos -= numBits;
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -33,7 +33,7 @@ public:
|
||||
{
|
||||
if (numBits < _bitPos)
|
||||
{
|
||||
_curByte |= ((Byte)value << (_bitPos -= numBits));
|
||||
_curByte = (Byte)(_curByte | (value << (_bitPos -= numBits)));
|
||||
return;
|
||||
}
|
||||
numBits -= _bitPos;
|
||||
|
||||
@@ -82,6 +82,14 @@ static HRESULT FindCodecClassId(const GUID *clsid, bool isCoder2, bool isFilter,
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
#ifdef __GNUC__
|
||||
#ifndef __clang__
|
||||
#pragma GCC diagnostic ignored "-Wduplicated-branches"
|
||||
#endif
|
||||
#endif
|
||||
*/
|
||||
|
||||
static HRESULT CreateCoderMain(unsigned index, bool encode, void **coder)
|
||||
{
|
||||
COM_TRY_BEGIN
|
||||
@@ -97,12 +105,15 @@ static HRESULT CreateCoderMain(unsigned index, bool encode, void **coder)
|
||||
if (c)
|
||||
{
|
||||
IUnknown *unk;
|
||||
unk = (IUnknown *)c;
|
||||
/*
|
||||
if (codec.IsFilter)
|
||||
unk = (IUnknown *)(ICompressFilter *)c;
|
||||
else if (codec.NumStreams != 1)
|
||||
unk = (IUnknown *)(ICompressCoder2 *)c;
|
||||
else
|
||||
unk = (IUnknown *)(ICompressCoder *)c;
|
||||
*/
|
||||
unk->AddRef();
|
||||
*coder = c;
|
||||
}
|
||||
@@ -136,16 +147,22 @@ static HRESULT CreateCoder2(bool encode, UInt32 index, const GUID *iid, void **o
|
||||
return CreateCoderMain(index, encode, outObject);
|
||||
}
|
||||
|
||||
|
||||
STDAPI CreateDecoder(UInt32 index, const GUID *iid, void **outObject);
|
||||
STDAPI CreateDecoder(UInt32 index, const GUID *iid, void **outObject)
|
||||
{
|
||||
return CreateCoder2(false, index, iid, outObject);
|
||||
}
|
||||
|
||||
|
||||
STDAPI CreateEncoder(UInt32 index, const GUID *iid, void **outObject);
|
||||
STDAPI CreateEncoder(UInt32 index, const GUID *iid, void **outObject)
|
||||
{
|
||||
return CreateCoder2(true, index, iid, outObject);
|
||||
}
|
||||
|
||||
|
||||
STDAPI CreateCoder(const GUID *clsid, const GUID *iid, void **outObject);
|
||||
STDAPI CreateCoder(const GUID *clsid, const GUID *iid, void **outObject)
|
||||
{
|
||||
*outObject = NULL;
|
||||
@@ -175,6 +192,8 @@ STDAPI CreateCoder(const GUID *clsid, const GUID *iid, void **outObject)
|
||||
return CreateCoderMain(codecIndex, encode, outObject);
|
||||
}
|
||||
|
||||
|
||||
STDAPI GetMethodProperty(UInt32 codecIndex, PROPID propID, PROPVARIANT *value);
|
||||
STDAPI GetMethodProperty(UInt32 codecIndex, PROPID propID, PROPVARIANT *value)
|
||||
{
|
||||
::VariantClear((VARIANTARG *)value);
|
||||
@@ -238,6 +257,8 @@ STDAPI GetMethodProperty(UInt32 codecIndex, PROPID propID, PROPVARIANT *value)
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
|
||||
STDAPI GetNumberOfMethods(UINT32 *numCodecs);
|
||||
STDAPI GetNumberOfMethods(UINT32 *numCodecs)
|
||||
{
|
||||
*numCodecs = g_NumCodecs;
|
||||
@@ -270,6 +291,7 @@ static HRESULT CreateHasher2(UInt32 index, IHasher **hasher)
|
||||
COM_TRY_END
|
||||
}
|
||||
|
||||
STDAPI CreateHasher(const GUID *clsid, IHasher **outObject);
|
||||
STDAPI CreateHasher(const GUID *clsid, IHasher **outObject)
|
||||
{
|
||||
COM_TRY_BEGIN
|
||||
@@ -281,6 +303,7 @@ STDAPI CreateHasher(const GUID *clsid, IHasher **outObject)
|
||||
COM_TRY_END
|
||||
}
|
||||
|
||||
STDAPI GetHasherProp(UInt32 codecIndex, PROPID propID, PROPVARIANT *value);
|
||||
STDAPI GetHasherProp(UInt32 codecIndex, PROPID propID, PROPVARIANT *value)
|
||||
{
|
||||
::VariantClear((VARIANTARG *)value);
|
||||
@@ -318,6 +341,7 @@ public:
|
||||
STDMETHOD(CreateHasher)(UInt32 index, IHasher **hasher);
|
||||
};
|
||||
|
||||
STDAPI GetHashers(IHashers **hashers);
|
||||
STDAPI GetHashers(IHashers **hashers)
|
||||
{
|
||||
COM_TRY_BEGIN
|
||||
|
||||
@@ -9,8 +9,8 @@ namespace NDeflate {
|
||||
namespace NDecoder {
|
||||
|
||||
CCoder::CCoder(bool deflate64Mode):
|
||||
_deflate64Mode(deflate64Mode),
|
||||
_deflateNSIS(false),
|
||||
_deflate64Mode(deflate64Mode),
|
||||
_keepHistory(false),
|
||||
_needFinishInput(false),
|
||||
_needInitInStream(true),
|
||||
@@ -408,9 +408,25 @@ STDMETHODIMP CCoder::SetFinishMode(UInt32 finishMode)
|
||||
|
||||
STDMETHODIMP CCoder::GetInStreamProcessedSize(UInt64 *value)
|
||||
{
|
||||
if (!value)
|
||||
return E_INVALIDARG;
|
||||
*value = m_InBitStream.GetProcessedSize();
|
||||
*value = m_InBitStream.GetStreamSize();
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
|
||||
STDMETHODIMP CCoder::ReadUnusedFromInBuf(void *data, UInt32 size, UInt32 *processedSize)
|
||||
{
|
||||
AlignToByte();
|
||||
UInt32 i = 0;
|
||||
if (!m_InBitStream.ExtraBitsWereRead())
|
||||
{
|
||||
for (i = 0; i < size; i++)
|
||||
{
|
||||
if (!m_InBitStream.ReadAlignedByte_FromBuf(((Byte *)data)[i]))
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (processedSize)
|
||||
*processedSize = i;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
|
||||
@@ -25,6 +25,7 @@ class CCoder:
|
||||
public ICompressCoder,
|
||||
public ICompressSetFinishMode,
|
||||
public ICompressGetInStreamProcessedSize,
|
||||
public ICompressReadUnusedFromInBuf,
|
||||
#ifndef NO_READ_FROM_CODER
|
||||
public ICompressSetInStream,
|
||||
public ICompressSetOutStreamSize,
|
||||
@@ -103,6 +104,7 @@ public:
|
||||
MY_QUERYINTERFACE_BEGIN2(ICompressCoder)
|
||||
MY_QUERYINTERFACE_ENTRY(ICompressSetFinishMode)
|
||||
MY_QUERYINTERFACE_ENTRY(ICompressGetInStreamProcessedSize)
|
||||
MY_QUERYINTERFACE_ENTRY(ICompressReadUnusedFromInBuf)
|
||||
|
||||
#ifndef NO_READ_FROM_CODER
|
||||
MY_QUERYINTERFACE_ENTRY(ICompressSetInStream)
|
||||
@@ -119,6 +121,7 @@ public:
|
||||
|
||||
STDMETHOD(SetFinishMode)(UInt32 finishMode);
|
||||
STDMETHOD(GetInStreamProcessedSize)(UInt64 *value);
|
||||
STDMETHOD(ReadUnusedFromInBuf)(void *data, UInt32 size, UInt32 *processedSize);
|
||||
|
||||
STDMETHOD(SetInStream)(ISequentialInStream *inStream);
|
||||
STDMETHOD(ReleaseInStream)();
|
||||
@@ -141,7 +144,10 @@ public:
|
||||
}
|
||||
bool InputEofError() const { return m_InBitStream.ExtraBitsWereRead(); }
|
||||
|
||||
// size of used real data from input stream
|
||||
UInt64 GetStreamSize() const { return m_InBitStream.GetStreamSize(); }
|
||||
|
||||
// size of virtual input stream processed
|
||||
UInt64 GetInputProcessedSize() const { return m_InBitStream.GetProcessedSize(); }
|
||||
};
|
||||
|
||||
|
||||
@@ -36,7 +36,7 @@ static const UInt32 kMatchArrayLimit = kMatchArraySize - kMatchMaxLen * 4 * size
|
||||
static const UInt32 kBlockUncompressedSizeThreshold = kMaxUncompressedBlockSize -
|
||||
kMatchMaxLen - kNumOpts;
|
||||
|
||||
static const unsigned kMaxCodeBitLength = 11;
|
||||
// static const unsigned kMaxCodeBitLength = 11;
|
||||
static const unsigned kMaxLevelBitLength = 7;
|
||||
|
||||
static const Byte kNoLiteralStatPrice = 11;
|
||||
@@ -89,7 +89,7 @@ void CEncProps::Normalize()
|
||||
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 (mc == 0) mc = (16 + ((unsigned)fb >> 1));
|
||||
if (numPasses == (UInt32)(Int32)-1) numPasses = (level < 7 ? 1 : (level < 9 ? 3 : 10));
|
||||
}
|
||||
|
||||
@@ -100,7 +100,7 @@ void CCoder::SetProps(const CEncProps *props2)
|
||||
|
||||
m_MatchFinderCycles = props.mc;
|
||||
{
|
||||
unsigned fb = props.fb;
|
||||
unsigned fb = (unsigned)props.fb;
|
||||
if (fb < kMatchMinLen)
|
||||
fb = kMatchMinLen;
|
||||
if (fb > m_MatchMaxLen)
|
||||
@@ -125,12 +125,12 @@ void CCoder::SetProps(const CEncProps *props2)
|
||||
}
|
||||
|
||||
CCoder::CCoder(bool deflate64Mode):
|
||||
m_Deflate64Mode(deflate64Mode),
|
||||
m_OnePosMatchesMemory(0),
|
||||
m_DistanceMemory(0),
|
||||
m_Values(NULL),
|
||||
m_OnePosMatchesMemory(NULL),
|
||||
m_DistanceMemory(NULL),
|
||||
m_Created(false),
|
||||
m_Values(0),
|
||||
m_Tables(0)
|
||||
m_Deflate64Mode(deflate64Mode),
|
||||
m_Tables(NULL)
|
||||
{
|
||||
m_MatchMaxLen = deflate64Mode ? kMatchMaxLen64 : kMatchMaxLen32;
|
||||
m_NumLenCombinations = deflate64Mode ? kNumLenSymbols64 : kNumLenSymbols32;
|
||||
@@ -213,10 +213,10 @@ HRESULT CCoder::BaseSetEncoderProperties2(const PROPID *propIDs, const PROPVARIA
|
||||
switch (propID)
|
||||
{
|
||||
case NCoderPropID::kNumPasses: props.numPasses = v; break;
|
||||
case NCoderPropID::kNumFastBytes: props.fb = v; break;
|
||||
case NCoderPropID::kNumFastBytes: props.fb = (int)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::kAlgorithm: props.algo = (int)v; break;
|
||||
case NCoderPropID::kLevel: props.Level = (int)v; break;
|
||||
case NCoderPropID::kNumThreads: break;
|
||||
default: return E_INVALIDARG;
|
||||
}
|
||||
@@ -595,7 +595,7 @@ NO_INLINE void CCoder::MakeTables(unsigned maxHuffLen)
|
||||
Huffman_Generate(distFreqs, distCodes, m_NewLevels.distLevels, kDistTableSize64, maxHuffLen);
|
||||
}
|
||||
|
||||
NO_INLINE UInt32 Huffman_GetPrice(const UInt32 *freqs, const Byte *lens, UInt32 num)
|
||||
static NO_INLINE UInt32 Huffman_GetPrice(const UInt32 *freqs, const Byte *lens, UInt32 num)
|
||||
{
|
||||
UInt32 price = 0;
|
||||
UInt32 i;
|
||||
@@ -604,7 +604,7 @@ NO_INLINE UInt32 Huffman_GetPrice(const UInt32 *freqs, const Byte *lens, UInt32
|
||||
return price;
|
||||
}
|
||||
|
||||
NO_INLINE UInt32 Huffman_GetPrice_Spec(const UInt32 *freqs, const Byte *lens, UInt32 num, const Byte *extraBits, UInt32 extraBase)
|
||||
static NO_INLINE UInt32 Huffman_GetPrice_Spec(const UInt32 *freqs, const Byte *lens, UInt32 num, const Byte *extraBits, UInt32 extraBase)
|
||||
{
|
||||
return Huffman_GetPrice(freqs, lens, num) +
|
||||
Huffman_GetPrice(freqs + extraBase, extraBits, num - extraBase);
|
||||
@@ -629,8 +629,9 @@ NO_INLINE void CCoder::TryBlock()
|
||||
{
|
||||
if (m_OptimumCurrentIndex == m_OptimumEndIndex)
|
||||
{
|
||||
if (m_Pos >= kMatchArrayLimit || BlockSizeRes >= blockSize || !m_SecondPass &&
|
||||
((Inline_MatchFinder_GetNumAvailableBytes(&_lzInWindow) == 0) || m_ValueIndex >= m_ValueBlockSize))
|
||||
if (m_Pos >= kMatchArrayLimit
|
||||
|| BlockSizeRes >= blockSize
|
||||
|| (!m_SecondPass && ((Inline_MatchFinder_GetNumAvailableBytes(&_lzInWindow) == 0) || m_ValueIndex >= m_ValueBlockSize)))
|
||||
break;
|
||||
}
|
||||
UInt32 pos;
|
||||
@@ -688,7 +689,7 @@ NO_INLINE void CCoder::SetPrices(const CLevels &levels)
|
||||
}
|
||||
}
|
||||
|
||||
NO_INLINE void Huffman_ReverseBits(UInt32 *codes, const Byte *lens, UInt32 num)
|
||||
static NO_INLINE void Huffman_ReverseBits(UInt32 *codes, const Byte *lens, UInt32 num)
|
||||
{
|
||||
for (UInt32 i = 0; i < num; i++)
|
||||
{
|
||||
|
||||
@@ -27,6 +27,16 @@ void RegisterHasher(const CHasherInfo *hashInfo) throw()
|
||||
}
|
||||
|
||||
#ifdef _WIN32
|
||||
|
||||
extern "C"
|
||||
BOOL WINAPI DllMain(
|
||||
#ifdef UNDER_CE
|
||||
HANDLE
|
||||
#else
|
||||
HINSTANCE
|
||||
#endif
|
||||
, DWORD /* dwReason */, LPVOID /*lpReserved*/);
|
||||
|
||||
extern "C"
|
||||
BOOL WINAPI DllMain(
|
||||
#ifdef UNDER_CE
|
||||
@@ -42,6 +52,7 @@ BOOL WINAPI DllMain(
|
||||
|
||||
STDAPI CreateCoder(const GUID *clsid, const GUID *iid, void **outObject);
|
||||
|
||||
STDAPI CreateObject(const GUID *clsid, const GUID *iid, void **outObject);
|
||||
STDAPI CreateObject(const GUID *clsid, const GUID *iid, void **outObject)
|
||||
{
|
||||
return CreateCoder(clsid, iid, outObject);
|
||||
|
||||
@@ -83,8 +83,8 @@ static const UInt32 kHistorySize = (1 << kNumDistDirectBitsBig) * kDistTableSize
|
||||
|
||||
|
||||
CCoder::CCoder():
|
||||
_fullStreamMode(false),
|
||||
_flags(0)
|
||||
_flags(0),
|
||||
_fullStreamMode(false)
|
||||
{}
|
||||
|
||||
|
||||
|
||||
@@ -34,6 +34,7 @@ CEncoder::~CEncoder()
|
||||
}
|
||||
|
||||
|
||||
HRESULT SetLzma2Prop(PROPID propID, const PROPVARIANT &prop, CLzma2EncProps &lzma2Props);
|
||||
HRESULT SetLzma2Prop(PROPID propID, const PROPVARIANT &prop, CLzma2EncProps &lzma2Props)
|
||||
{
|
||||
switch (propID)
|
||||
@@ -49,7 +50,10 @@ HRESULT SetLzma2Prop(PROPID propID, const PROPVARIANT &prop, CLzma2EncProps &lzm
|
||||
break;
|
||||
}
|
||||
case NCoderPropID::kNumThreads:
|
||||
if (prop.vt != VT_UI4) return E_INVALIDARG; lzma2Props.numTotalThreads = (int)(prop.ulVal); break;
|
||||
if (prop.vt != VT_UI4)
|
||||
return E_INVALIDARG;
|
||||
lzma2Props.numTotalThreads = (int)(prop.ulVal);
|
||||
break;
|
||||
default:
|
||||
RINOK(NLzma::SetLzmaProp(propID, prop, lzma2Props.lzmaProps));
|
||||
}
|
||||
|
||||
@@ -153,7 +153,7 @@ HRESULT CDecoder::CodeSpec(ISequentialInStream *inStream, ISequentialOutStream *
|
||||
|
||||
SizeT inProcessed = _inLim - _inPos;
|
||||
ELzmaStatus status;
|
||||
|
||||
|
||||
SRes res = LzmaDec_DecodeToDic(&_state, dicPos + size, _inBuf + _inPos, &inProcessed, finishMode, &status);
|
||||
|
||||
_lzmaStatus = status;
|
||||
@@ -183,7 +183,10 @@ HRESULT CDecoder::CodeSpec(ISequentialInStream *inStream, ISequentialOutStream *
|
||||
if (needStop)
|
||||
{
|
||||
if (res != 0)
|
||||
{
|
||||
// return SResToHRESULT(res);
|
||||
return S_FALSE;
|
||||
}
|
||||
|
||||
if (status == LZMA_STATUS_FINISHED_WITH_MARK)
|
||||
{
|
||||
|
||||
@@ -9,6 +9,20 @@
|
||||
|
||||
#include "LzmaEncoder.h"
|
||||
|
||||
#include "../../Common/IntToString.h"
|
||||
#include "../../Windows/TimeUtils.h"
|
||||
|
||||
// #define LOG_LZMA_THREADS
|
||||
|
||||
#ifdef LOG_LZMA_THREADS
|
||||
#include <stdio.h>
|
||||
|
||||
EXTERN_C_BEGIN
|
||||
void LzmaEnc_GetLzThreads(CLzmaEncHandle pp, HANDLE lz_threads[2]);
|
||||
EXTERN_C_END
|
||||
|
||||
#endif
|
||||
|
||||
namespace NCompress {
|
||||
namespace NLzma {
|
||||
|
||||
@@ -26,46 +40,48 @@ CEncoder::~CEncoder()
|
||||
LzmaEnc_Destroy(_encoder, &g_AlignedAlloc, &g_BigAlloc);
|
||||
}
|
||||
|
||||
static inline wchar_t GetUpperChar(wchar_t c)
|
||||
static inline wchar_t GetLowCharFast(wchar_t c)
|
||||
{
|
||||
if (c >= 'a' && c <= 'z')
|
||||
c -= 0x20;
|
||||
return c;
|
||||
return c |= 0x20;
|
||||
}
|
||||
|
||||
static int ParseMatchFinder(const wchar_t *s, int *btMode, int *numHashBytes)
|
||||
{
|
||||
wchar_t c = GetUpperChar(*s++);
|
||||
if (c == L'H')
|
||||
wchar_t c = GetLowCharFast(*s++);
|
||||
if (c == 'h')
|
||||
{
|
||||
if (GetUpperChar(*s++) != L'C')
|
||||
if (GetLowCharFast(*s++) != 'c')
|
||||
return 0;
|
||||
int numHashBytesLoc = (int)(*s++ - L'0');
|
||||
if (numHashBytesLoc < 4 || numHashBytesLoc > 4)
|
||||
int num = (int)(*s++ - L'0');
|
||||
if (num < 4 || num > 5)
|
||||
return 0;
|
||||
if (*s != 0)
|
||||
return 0;
|
||||
*btMode = 0;
|
||||
*numHashBytes = numHashBytesLoc;
|
||||
*numHashBytes = num;
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (c != L'B')
|
||||
if (c != 'b')
|
||||
return 0;
|
||||
if (GetUpperChar(*s++) != L'T')
|
||||
return 0;
|
||||
int numHashBytesLoc = (int)(*s++ - L'0');
|
||||
if (numHashBytesLoc < 2 || numHashBytesLoc > 4)
|
||||
return 0;
|
||||
if (*s != 0)
|
||||
return 0;
|
||||
*btMode = 1;
|
||||
*numHashBytes = numHashBytesLoc;
|
||||
return 1;
|
||||
{
|
||||
if (GetLowCharFast(*s++) != 't')
|
||||
return 0;
|
||||
int num = (int)(*s++ - L'0');
|
||||
if (num < 2 || num > 5)
|
||||
return 0;
|
||||
if (*s != 0)
|
||||
return 0;
|
||||
*btMode = 1;
|
||||
*numHashBytes = num;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
#define SET_PROP_32(_id_, _dest_) case NCoderPropID::_id_: ep._dest_ = v; break;
|
||||
#define SET_PROP_32(_id_, _dest_) case NCoderPropID::_id_: ep._dest_ = (int)v; break;
|
||||
#define SET_PROP_32U(_id_, _dest_) case NCoderPropID::_id_: ep._dest_ = v; break;
|
||||
|
||||
HRESULT SetLzmaProp(PROPID propID, const PROPVARIANT &prop, CLzmaEncProps &ep);
|
||||
HRESULT SetLzmaProp(PROPID propID, const PROPVARIANT &prop, CLzmaEncProps &ep)
|
||||
{
|
||||
if (propID == NCoderPropID::kMatchFinder)
|
||||
@@ -74,7 +90,16 @@ 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::kAffinity)
|
||||
{
|
||||
if (prop.vt == VT_UI8)
|
||||
ep.affinity = prop.uhVal.QuadPart;
|
||||
else
|
||||
return E_INVALIDARG;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
if (propID > NCoderPropID::kReduceSize)
|
||||
return S_OK;
|
||||
|
||||
@@ -95,9 +120,9 @@ HRESULT SetLzmaProp(PROPID propID, const PROPVARIANT &prop, CLzmaEncProps &ep)
|
||||
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_32U(kMatchFinderCycles, mc)
|
||||
SET_PROP_32(kAlgorithm, algo)
|
||||
SET_PROP_32(kDictionarySize, dictSize)
|
||||
SET_PROP_32U(kDictionarySize, dictSize)
|
||||
SET_PROP_32(kPosStateBits, pb)
|
||||
SET_PROP_32(kLitPosBits, lp)
|
||||
SET_PROP_32(kLitContextBits, lc)
|
||||
@@ -120,7 +145,10 @@ STDMETHODIMP CEncoder::SetCoderProperties(const PROPID *propIDs,
|
||||
switch (propID)
|
||||
{
|
||||
case NCoderPropID::kEndMarker:
|
||||
if (prop.vt != VT_BOOL) return E_INVALIDARG; props.writeEndMark = (prop.boolVal != VARIANT_FALSE); break;
|
||||
if (prop.vt != VT_BOOL)
|
||||
return E_INVALIDARG;
|
||||
props.writeEndMark = (prop.boolVal != VARIANT_FALSE);
|
||||
break;
|
||||
default:
|
||||
RINOK(SetLzmaProp(propID, prop, props));
|
||||
}
|
||||
@@ -156,6 +184,92 @@ STDMETHODIMP CEncoder::WriteCoderProperties(ISequentialOutStream *outStream)
|
||||
#define RET_IF_WRAP_ERROR(wrapRes, sRes, sResErrorCode) \
|
||||
if (wrapRes != S_OK /* && (sRes == SZ_OK || sRes == sResErrorCode) */) return wrapRes;
|
||||
|
||||
|
||||
|
||||
#ifdef LOG_LZMA_THREADS
|
||||
|
||||
static inline UInt64 GetTime64(const FILETIME &t) { return ((UInt64)t.dwHighDateTime << 32) | t.dwLowDateTime; }
|
||||
|
||||
static void PrintNum(UInt64 val, unsigned numDigits, char c = ' ')
|
||||
{
|
||||
char temp[64];
|
||||
char *p = temp + 32;
|
||||
ConvertUInt64ToString(val, p);
|
||||
unsigned len = (unsigned)strlen(p);
|
||||
for (; len < numDigits; len++)
|
||||
*--p = c;
|
||||
printf("%s", p);
|
||||
}
|
||||
|
||||
static void PrintTime(const char *s, UInt64 val, UInt64 total)
|
||||
{
|
||||
printf(" %s :", s);
|
||||
const UInt32 kFreq = 10000000;
|
||||
UInt64 sec = val / kFreq;
|
||||
PrintNum(sec, 6);
|
||||
printf(" .");
|
||||
UInt32 ms = (UInt32)(val - (sec * kFreq)) / (kFreq / 1000);
|
||||
PrintNum(ms, 3, '0');
|
||||
|
||||
while (val > ((UInt64)1 << 56))
|
||||
{
|
||||
val >>= 1;
|
||||
total >>= 1;
|
||||
}
|
||||
|
||||
UInt64 percent = 0;
|
||||
if (total != 0)
|
||||
percent = val * 100 / total;
|
||||
printf(" =");
|
||||
PrintNum(percent, 4);
|
||||
printf("%%");
|
||||
}
|
||||
|
||||
|
||||
struct CBaseStat
|
||||
{
|
||||
UInt64 kernelTime, userTime;
|
||||
|
||||
BOOL Get(HANDLE thread, const CBaseStat *prevStat)
|
||||
{
|
||||
FILETIME creationTimeFT, exitTimeFT, kernelTimeFT, userTimeFT;
|
||||
BOOL res = GetThreadTimes(thread
|
||||
, &creationTimeFT, &exitTimeFT, &kernelTimeFT, &userTimeFT);
|
||||
if (res)
|
||||
{
|
||||
kernelTime = GetTime64(kernelTimeFT);
|
||||
userTime = GetTime64(userTimeFT);
|
||||
if (prevStat)
|
||||
{
|
||||
kernelTime -= prevStat->kernelTime;
|
||||
userTime -= prevStat->userTime;
|
||||
}
|
||||
}
|
||||
return res;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
static void PrintStat(HANDLE thread, UInt64 totalTime, const CBaseStat *prevStat)
|
||||
{
|
||||
CBaseStat newStat;
|
||||
if (!newStat.Get(thread, prevStat))
|
||||
return;
|
||||
|
||||
PrintTime("K", newStat.kernelTime, totalTime);
|
||||
|
||||
const UInt64 processTime = newStat.kernelTime + newStat.userTime;
|
||||
|
||||
PrintTime("U", newStat.userTime, totalTime);
|
||||
PrintTime("S", processTime, totalTime);
|
||||
printf("\n");
|
||||
// PrintTime("G ", totalTime, totalTime);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
STDMETHODIMP CEncoder::Code(ISequentialInStream *inStream, ISequentialOutStream *outStream,
|
||||
const UInt64 * /* inSize */, const UInt64 * /* outSize */, ICompressProgressInfo *progress)
|
||||
{
|
||||
@@ -167,6 +281,18 @@ STDMETHODIMP CEncoder::Code(ISequentialInStream *inStream, ISequentialOutStream
|
||||
outWrap.Init(outStream);
|
||||
progressWrap.Init(progress);
|
||||
|
||||
#ifdef LOG_LZMA_THREADS
|
||||
|
||||
FILETIME startTimeFT;
|
||||
NWindows::NTime::GetCurUtcFileTime(startTimeFT);
|
||||
UInt64 totalTime = GetTime64(startTimeFT);
|
||||
CBaseStat oldStat;
|
||||
if (!oldStat.Get(GetCurrentThread(), NULL))
|
||||
return E_FAIL;
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
SRes res = LzmaEnc_Encode(_encoder, &outWrap.vt, &inWrap.vt,
|
||||
progress ? &progressWrap.vt : NULL, &g_AlignedAlloc, &g_BigAlloc);
|
||||
|
||||
@@ -175,7 +301,23 @@ STDMETHODIMP CEncoder::Code(ISequentialInStream *inStream, ISequentialOutStream
|
||||
RET_IF_WRAP_ERROR(inWrap.Res, res, SZ_ERROR_READ)
|
||||
RET_IF_WRAP_ERROR(outWrap.Res, res, SZ_ERROR_WRITE)
|
||||
RET_IF_WRAP_ERROR(progressWrap.Res, res, SZ_ERROR_PROGRESS)
|
||||
|
||||
|
||||
#ifdef LOG_LZMA_THREADS
|
||||
|
||||
NWindows::NTime::GetCurUtcFileTime(startTimeFT);
|
||||
totalTime = GetTime64(startTimeFT) - totalTime;
|
||||
HANDLE lz_threads[2];
|
||||
LzmaEnc_GetLzThreads(_encoder, lz_threads);
|
||||
printf("\n");
|
||||
printf("Main: "); PrintStat(GetCurrentThread(), totalTime, &oldStat);
|
||||
printf("Hash: "); PrintStat(lz_threads[0], totalTime, NULL);
|
||||
printf("BinT: "); PrintStat(lz_threads[1], totalTime, NULL);
|
||||
// PrintTime("Total: ", totalTime, totalTime);
|
||||
printf("\n");
|
||||
|
||||
#endif
|
||||
|
||||
return SResToHRESULT(res);
|
||||
}
|
||||
|
||||
|
||||
@@ -123,7 +123,7 @@ static void x86_Filter(Byte *data, UInt32 size, Int32 *history)
|
||||
|
||||
for (;;)
|
||||
{
|
||||
const Byte *p = data + (UInt32)i;
|
||||
Byte *p = data + (UInt32)i;
|
||||
|
||||
for (;;)
|
||||
{
|
||||
@@ -198,7 +198,7 @@ static void x86_Filter(Byte *data, UInt32 size, Int32 *history)
|
||||
|
||||
Int32 *target;
|
||||
{
|
||||
const Byte *p2 = p + codeLen;
|
||||
Byte *p2 = p + codeLen;
|
||||
UInt32 n = GetUi32(p2);
|
||||
if (i - last_x86_pos <= maxTransOffset)
|
||||
{
|
||||
@@ -208,7 +208,7 @@ static void x86_Filter(Byte *data, UInt32 size, Int32 *history)
|
||||
target = history + (((UInt32)i + n) & 0xFFFF);
|
||||
}
|
||||
|
||||
i += codeLen + sizeof(UInt32) - 1;
|
||||
i += (Int32)(codeLen + sizeof(UInt32) - 1);
|
||||
|
||||
if (i - *target <= k_x86_WindowSize)
|
||||
last_x86_pos = i;
|
||||
@@ -220,7 +220,7 @@ static void x86_Filter(Byte *data, UInt32 size, Int32 *history)
|
||||
|
||||
|
||||
|
||||
static const int kLenIdNeedInit = -2;
|
||||
// static const int kLenIdNeedInit = -2;
|
||||
|
||||
CDecoder::CDecoder():
|
||||
_x86_history(NULL)
|
||||
@@ -232,7 +232,7 @@ CDecoder::~CDecoder()
|
||||
::MidFree(_x86_history);
|
||||
}
|
||||
|
||||
#define RIF(x) { if (!(x)) return false; }
|
||||
// #define RIF(x) { if (!(x)) return false; }
|
||||
|
||||
#define LIMIT_CHECK if (_bs._buf < _rc.cur) return S_FALSE;
|
||||
// #define LIMIT_CHECK
|
||||
@@ -539,8 +539,8 @@ HRESULT CDecoder::CodeReal(const Byte *in, size_t inSize, Byte *_win, size_t out
|
||||
_rc.Normalize();
|
||||
if (_rc.code != 0)
|
||||
return S_FALSE;
|
||||
if (_rc.cur > _bs._buf ||
|
||||
_rc.cur == _bs._buf && _bs._bitPos != 0)
|
||||
if (_rc.cur > _bs._buf
|
||||
|| (_rc.cur == _bs._buf && _bs._bitPos != 0))
|
||||
return S_FALSE;
|
||||
|
||||
/*
|
||||
|
||||
@@ -263,7 +263,7 @@ public:
|
||||
~CDecoder();
|
||||
|
||||
HRESULT Code(const Byte *in, size_t inSize, Byte *out, size_t outSize);
|
||||
const size_t GetUnpackSize() const { return _pos; }
|
||||
size_t GetUnpackSize() const { return _pos; }
|
||||
};
|
||||
|
||||
}}
|
||||
|
||||
@@ -32,7 +32,7 @@ static void x86_Filter(Byte *data, UInt32 size, UInt32 processedSize, UInt32 tra
|
||||
|
||||
for (UInt32 i = 0;;)
|
||||
{
|
||||
const Byte *p = data + i;
|
||||
Byte *p = data + i;
|
||||
for (;;)
|
||||
{
|
||||
if (*p++ == 0xE8) break;
|
||||
@@ -46,13 +46,13 @@ static void x86_Filter(Byte *data, UInt32 size, UInt32 processedSize, UInt32 tra
|
||||
if (i > size)
|
||||
break;
|
||||
{
|
||||
Int32 v = GetUi32(p);
|
||||
Int32 v = (Int32)GetUi32(p);
|
||||
Int32 pos = (Int32)((Int32)1 - (Int32)(processedSize + i));
|
||||
i += 4;
|
||||
if (v >= pos && v < (Int32)translationSize)
|
||||
{
|
||||
v += (v >= 0 ? pos : translationSize);
|
||||
SetUi32(p, v);
|
||||
v += (v >= 0 ? pos : (Int32)translationSize);
|
||||
SetUi32(p, (UInt32)v);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -63,15 +63,15 @@ static void x86_Filter(Byte *data, UInt32 size, UInt32 processedSize, UInt32 tra
|
||||
|
||||
CDecoder::CDecoder(bool wimMode):
|
||||
_win(NULL),
|
||||
_keepHistory(false),
|
||||
_skipByte(false),
|
||||
_wimMode(wimMode),
|
||||
_numDictBits(15),
|
||||
_unpackBlockSize(0),
|
||||
_x86_buf(NULL),
|
||||
_x86_translationSize(0),
|
||||
KeepHistoryForNext(true),
|
||||
NeedAlloc(true),
|
||||
_keepHistory(false),
|
||||
_wimMode(wimMode),
|
||||
_numDictBits(15),
|
||||
_x86_buf(NULL),
|
||||
_x86_translationSize(0),
|
||||
_unpackedData(NULL)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -30,7 +30,7 @@ public:
|
||||
_extraSize = 0;
|
||||
}
|
||||
|
||||
size_t GetRem() const { return _bufLim + 1 - _buf; }
|
||||
size_t GetRem() const { return (size_t)(_bufLim + 1 - _buf); }
|
||||
bool WasExtraReadError_Fast() const { return _extraSize > 4; }
|
||||
|
||||
bool WasFinishedOK() const
|
||||
@@ -238,7 +238,7 @@ public:
|
||||
|
||||
bool WasBlockFinished() const { return _unpackBlockSize == 0; }
|
||||
const Byte *GetUnpackData() const { return _unpackedData; }
|
||||
const UInt32 GetUnpackSize() const { return _pos - _writePos; }
|
||||
UInt32 GetUnpackSize() const { return _pos - _writePos; }
|
||||
};
|
||||
|
||||
}}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
// PpmdDecoder.cpp
|
||||
// 2009-03-11 : Igor Pavlov : Public domain
|
||||
// 2020-07-03 : Igor Pavlov : Public domain
|
||||
|
||||
#include "StdAfx.h"
|
||||
|
||||
@@ -13,13 +13,13 @@
|
||||
namespace NCompress {
|
||||
namespace NPpmd {
|
||||
|
||||
static const UInt32 kBufSize = (1 << 20);
|
||||
static const UInt32 kBufSize = (1 << 16);
|
||||
|
||||
enum
|
||||
{
|
||||
kStatus_NeedInit,
|
||||
kStatus_Normal,
|
||||
kStatus_Finished,
|
||||
kStatus_Finished_With_Mark,
|
||||
kStatus_Error
|
||||
};
|
||||
|
||||
@@ -35,7 +35,8 @@ STDMETHODIMP CDecoder::SetDecoderProperties2(const Byte *props, UInt32 size)
|
||||
return E_INVALIDARG;
|
||||
_order = props[0];
|
||||
UInt32 memSize = GetUi32(props + 1);
|
||||
if (_order < PPMD7_MIN_ORDER ||
|
||||
if (
|
||||
// _order < PPMD7_MIN_ORDER ||
|
||||
_order > PPMD7_MAX_ORDER ||
|
||||
memSize < PPMD7_MIN_MEM_SIZE ||
|
||||
memSize > PPMD7_MAX_MEM_SIZE)
|
||||
@@ -47,23 +48,36 @@ STDMETHODIMP CDecoder::SetDecoderProperties2(const Byte *props, UInt32 size)
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
#define _rangeDec _ppmd.rc.dec
|
||||
|
||||
#define CHECK_EXTRA_ERROR \
|
||||
if (_inStream.Extra) { \
|
||||
_status = kStatus_Error; \
|
||||
return (_res = (_inStream.Res != SZ_OK ? _inStream.Res: S_FALSE)); }
|
||||
|
||||
|
||||
HRESULT CDecoder::CodeSpec(Byte *memStream, UInt32 size)
|
||||
{
|
||||
if (_res != S_OK)
|
||||
return _res;
|
||||
|
||||
switch (_status)
|
||||
{
|
||||
case kStatus_Finished: return S_OK;
|
||||
case kStatus_Finished_With_Mark: return S_OK;
|
||||
case kStatus_Error: return S_FALSE;
|
||||
case kStatus_NeedInit:
|
||||
_inStream.Init();
|
||||
if (!Ppmd7z_RangeDec_Init(&_rangeDec))
|
||||
{
|
||||
_status = kStatus_Error;
|
||||
return S_FALSE;
|
||||
return (_res = S_FALSE);
|
||||
}
|
||||
CHECK_EXTRA_ERROR
|
||||
_status = kStatus_Normal;
|
||||
Ppmd7_Init(&_ppmd, _order);
|
||||
break;
|
||||
}
|
||||
|
||||
if (_outSizeDefined)
|
||||
{
|
||||
const UInt64 rem = _outSize - _processedSize;
|
||||
@@ -71,29 +85,54 @@ HRESULT CDecoder::CodeSpec(Byte *memStream, UInt32 size)
|
||||
size = (UInt32)rem;
|
||||
}
|
||||
|
||||
UInt32 i;
|
||||
int sym = 0;
|
||||
for (i = 0; i != size; i++)
|
||||
{
|
||||
sym = Ppmd7_DecodeSymbol(&_ppmd, &_rangeDec.vt);
|
||||
if (_inStream.Extra || sym < 0)
|
||||
break;
|
||||
memStream[i] = (Byte)sym;
|
||||
Byte *buf = memStream;
|
||||
const Byte *lim = buf + size;
|
||||
for (; buf != lim; buf++)
|
||||
{
|
||||
sym = Ppmd7z_DecodeSymbol(&_ppmd);
|
||||
if (_inStream.Extra || sym < 0)
|
||||
break;
|
||||
*buf = (Byte)sym;
|
||||
}
|
||||
/*
|
||||
buf = Ppmd7z_DecodeSymbols(&_ppmd, buf, lim);
|
||||
sym = _ppmd.LastSymbol;
|
||||
*/
|
||||
_processedSize += (size_t)(buf - memStream);
|
||||
}
|
||||
|
||||
_processedSize += i;
|
||||
if (_inStream.Extra)
|
||||
CHECK_EXTRA_ERROR
|
||||
|
||||
if (sym >= 0)
|
||||
{
|
||||
if (!FinishStream
|
||||
|| !_outSizeDefined
|
||||
|| _outSize != _processedSize
|
||||
|| _rangeDec.Code == 0)
|
||||
return S_OK;
|
||||
/*
|
||||
// We can decode additional End Marker here:
|
||||
sym = Ppmd7z_DecodeSymbol(&_ppmd);
|
||||
CHECK_EXTRA_ERROR
|
||||
*/
|
||||
}
|
||||
|
||||
if (sym != PPMD7_SYM_END || _rangeDec.Code != 0)
|
||||
{
|
||||
_status = kStatus_Error;
|
||||
return _inStream.Res;
|
||||
return (_res = S_FALSE);
|
||||
}
|
||||
if (sym < 0)
|
||||
_status = (sym < -1) ? kStatus_Error : kStatus_Finished;
|
||||
|
||||
_status = kStatus_Finished_With_Mark;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
|
||||
|
||||
STDMETHODIMP CDecoder::Code(ISequentialInStream *inStream, ISequentialOutStream *outStream,
|
||||
const UInt64 * /* inSize */, const UInt64 *outSize, ICompressProgressInfo *progress)
|
||||
const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress)
|
||||
{
|
||||
if (!_outBuf)
|
||||
{
|
||||
@@ -112,18 +151,23 @@ STDMETHODIMP CDecoder::Code(ISequentialInStream *inStream, ISequentialOutStream
|
||||
size_t processed = (size_t)(_processedSize - startPos);
|
||||
RINOK(WriteStream(outStream, _outBuf, processed));
|
||||
RINOK(res);
|
||||
if (_status == kStatus_Finished)
|
||||
if (_status == kStatus_Finished_With_Mark)
|
||||
break;
|
||||
if (progress)
|
||||
{
|
||||
UInt64 inSize = _inStream.GetProcessed();
|
||||
RINOK(progress->SetRatioInfo(&inSize, &_processedSize));
|
||||
const UInt64 inProcessed = _inStream.GetProcessed();
|
||||
RINOK(progress->SetRatioInfo(&inProcessed, &_processedSize));
|
||||
}
|
||||
}
|
||||
while (!_outSizeDefined || _processedSize < _outSize);
|
||||
|
||||
if (FinishStream && inSize && *inSize != _inStream.GetProcessed())
|
||||
return S_FALSE;
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
|
||||
STDMETHODIMP CDecoder::SetOutStreamSize(const UInt64 *outSize)
|
||||
{
|
||||
_outSizeDefined = (outSize != NULL);
|
||||
@@ -131,9 +175,15 @@ STDMETHODIMP CDecoder::SetOutStreamSize(const UInt64 *outSize)
|
||||
_outSize = *outSize;
|
||||
_processedSize = 0;
|
||||
_status = kStatus_NeedInit;
|
||||
_res = SZ_OK;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP CDecoder::SetFinishMode(UInt32 finishMode)
|
||||
{
|
||||
FinishStream = (finishMode != 0);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP CDecoder::GetInStreamProcessedSize(UInt64 *value)
|
||||
{
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
// PpmdDecoder.h
|
||||
// 2009-03-11 : Igor Pavlov : Public domain
|
||||
// 2020-07-03 : Igor Pavlov : Public domain
|
||||
|
||||
#ifndef __COMPRESS_PPMD_DECODER_H
|
||||
#define __COMPRESS_PPMD_DECODER_H
|
||||
@@ -8,16 +8,17 @@
|
||||
|
||||
#include "../../Common/MyCom.h"
|
||||
|
||||
#include "../Common/CWrappers.h"
|
||||
|
||||
#include "../ICoder.h"
|
||||
|
||||
#include "../Common/CWrappers.h"
|
||||
|
||||
namespace NCompress {
|
||||
namespace NPpmd {
|
||||
|
||||
class CDecoder :
|
||||
public ICompressCoder,
|
||||
public ICompressSetDecoderProperties2,
|
||||
public ICompressSetFinishMode,
|
||||
public ICompressGetInStreamProcessedSize,
|
||||
#ifndef NO_READ_FROM_CODER
|
||||
public ICompressSetInStream,
|
||||
@@ -27,12 +28,13 @@ class CDecoder :
|
||||
public CMyUnknownImp
|
||||
{
|
||||
Byte *_outBuf;
|
||||
CPpmd7z_RangeDec _rangeDec;
|
||||
CByteInBufWrap _inStream;
|
||||
CPpmd7 _ppmd;
|
||||
|
||||
Byte _order;
|
||||
bool FinishStream;
|
||||
bool _outSizeDefined;
|
||||
HRESULT _res;
|
||||
int _status;
|
||||
UInt64 _outSize;
|
||||
UInt64 _processedSize;
|
||||
@@ -47,7 +49,7 @@ public:
|
||||
|
||||
MY_QUERYINTERFACE_BEGIN2(ICompressCoder)
|
||||
MY_QUERYINTERFACE_ENTRY(ICompressSetDecoderProperties2)
|
||||
// MY_QUERYINTERFACE_ENTRY(ICompressSetFinishMode)
|
||||
MY_QUERYINTERFACE_ENTRY(ICompressSetFinishMode)
|
||||
MY_QUERYINTERFACE_ENTRY(ICompressGetInStreamProcessedSize)
|
||||
#ifndef NO_READ_FROM_CODER
|
||||
MY_QUERYINTERFACE_ENTRY(ICompressSetInStream)
|
||||
@@ -61,6 +63,7 @@ public:
|
||||
STDMETHOD(Code)(ISequentialInStream *inStream, ISequentialOutStream *outStream,
|
||||
const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress);
|
||||
STDMETHOD(SetDecoderProperties2)(const Byte *data, UInt32 size);
|
||||
STDMETHOD(SetFinishMode)(UInt32 finishMode);
|
||||
STDMETHOD(GetInStreamProcessedSize)(UInt64 *value);
|
||||
|
||||
STDMETHOD(SetOutStreamSize)(const UInt64 *outSize);
|
||||
@@ -71,11 +74,13 @@ public:
|
||||
STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize);
|
||||
#endif
|
||||
|
||||
CDecoder(): _outBuf(NULL), _outSizeDefined(false)
|
||||
CDecoder():
|
||||
_outBuf(NULL),
|
||||
FinishStream(false),
|
||||
_outSizeDefined(false)
|
||||
{
|
||||
Ppmd7z_RangeDec_CreateVTable(&_rangeDec);
|
||||
_rangeDec.Stream = &_inStream.vt;
|
||||
Ppmd7_Construct(&_ppmd);
|
||||
_ppmd.rc.dec.Stream = &_inStream.vt;
|
||||
}
|
||||
|
||||
~CDecoder();
|
||||
|
||||
@@ -3,7 +3,6 @@
|
||||
#include "StdAfx.h"
|
||||
|
||||
#include "../../../C/Alloc.h"
|
||||
#include "../../../C/CpuArch.h"
|
||||
|
||||
#include "../Common/StreamUtils.h"
|
||||
|
||||
@@ -21,7 +20,7 @@ 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)
|
||||
{
|
||||
@@ -43,8 +42,8 @@ CEncoder::CEncoder():
|
||||
_inBuf(NULL)
|
||||
{
|
||||
_props.Normalize(-1);
|
||||
_rangeEnc.Stream = &_outStream.vt;
|
||||
Ppmd7_Construct(&_ppmd);
|
||||
_ppmd.rc.enc.Stream = &_outStream.vt;
|
||||
}
|
||||
|
||||
CEncoder::~CEncoder()
|
||||
@@ -120,8 +119,8 @@ 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 (;;)
|
||||
@@ -131,19 +130,27 @@ HRESULT CEncoder::Code(ISequentialInStream *inStream, ISequentialOutStream *outS
|
||||
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();
|
||||
const UInt64 outSize = _outStream.GetProcessed();
|
||||
RINOK(progress->SetRatioInfo(&processed, &outSize));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -37,7 +37,6 @@ class CEncoder :
|
||||
{
|
||||
Byte *_inBuf;
|
||||
CByteOutBufWrap _outStream;
|
||||
CPpmd7z_RangeEnc _rangeEnc;
|
||||
CPpmd7 _ppmd;
|
||||
CEncProps _props;
|
||||
public:
|
||||
|
||||
@@ -15,8 +15,8 @@ namespace NPpmdZip {
|
||||
CDecoder::CDecoder(bool fullFileMode):
|
||||
_fullFileMode(fullFileMode)
|
||||
{
|
||||
_ppmd.Stream.In = &_inStream.vt;
|
||||
Ppmd8_Construct(&_ppmd);
|
||||
_ppmd.Stream.In = &_inStream.vt;
|
||||
}
|
||||
|
||||
CDecoder::~CDecoder()
|
||||
@@ -27,6 +27,8 @@ CDecoder::~CDecoder()
|
||||
STDMETHODIMP CDecoder::Code(ISequentialInStream *inStream, ISequentialOutStream *outStream,
|
||||
const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress)
|
||||
{
|
||||
// try {
|
||||
|
||||
if (!_outStream.Alloc())
|
||||
return E_OUTOFMEMORY;
|
||||
if (!_inStream.Alloc(1 << 20))
|
||||
@@ -43,9 +45,9 @@ STDMETHODIMP CDecoder::Code(ISequentialInStream *inStream, ISequentialOutStream
|
||||
return S_FALSE;
|
||||
|
||||
UInt32 val = GetUi16(buf);
|
||||
UInt32 order = (val & 0xF) + 1;
|
||||
unsigned order = (val & 0xF) + 1;
|
||||
UInt32 mem = ((val >> 4) & 0xFF) + 1;
|
||||
UInt32 restor = (val >> 12);
|
||||
unsigned restor = (val >> 12);
|
||||
if (order < 2 || restor > 2)
|
||||
return S_FALSE;
|
||||
|
||||
@@ -57,7 +59,7 @@ STDMETHODIMP CDecoder::Code(ISequentialInStream *inStream, ISequentialOutStream
|
||||
if (!Ppmd8_Alloc(&_ppmd, mem << 20, &g_BigAlloc))
|
||||
return E_OUTOFMEMORY;
|
||||
|
||||
if (!Ppmd8_RangeDec_Init(&_ppmd))
|
||||
if (!Ppmd8_Init_RangeDec(&_ppmd))
|
||||
return S_FALSE;
|
||||
Ppmd8_Init(&_ppmd, order, restor);
|
||||
}
|
||||
@@ -79,21 +81,23 @@ STDMETHODIMP CDecoder::Code(ISequentialInStream *inStream, ISequentialOutStream
|
||||
}
|
||||
}
|
||||
|
||||
Byte *data = _outStream.Buf;
|
||||
size_t i = 0;
|
||||
int sym = 0;
|
||||
int sym;
|
||||
Byte *buf = _outStream.Buf;
|
||||
const Byte *lim = buf + size;
|
||||
|
||||
do
|
||||
{
|
||||
sym = Ppmd8_DecodeSymbol(&_ppmd);
|
||||
if (_inStream.Extra || sym < 0)
|
||||
break;
|
||||
data[i] = (Byte)sym;
|
||||
*buf++ = (Byte)sym;
|
||||
}
|
||||
while (++i != size);
|
||||
while (buf != lim);
|
||||
|
||||
processedSize += i;
|
||||
size_t cur = (size_t)(buf - _outStream.Buf);
|
||||
processedSize += cur;
|
||||
|
||||
RINOK(WriteStream(outStream, _outStream.Buf, i));
|
||||
RINOK(WriteStream(outStream, _outStream.Buf, cur));
|
||||
|
||||
RINOK(_inStream.Res);
|
||||
if (_inStream.Extra)
|
||||
@@ -133,6 +137,8 @@ STDMETHODIMP CDecoder::Code(ISequentialInStream *inStream, ISequentialOutStream
|
||||
}
|
||||
|
||||
return S_OK;
|
||||
|
||||
// } catch (...) { return E_FAIL; }
|
||||
}
|
||||
|
||||
|
||||
@@ -158,21 +164,14 @@ void CEncProps::Normalize(int level)
|
||||
if (level == 0) level = 1;
|
||||
if (level > 9) level = 9;
|
||||
if (MemSizeMB == (UInt32)(Int32)-1)
|
||||
MemSizeMB = (1 << ((level > 8 ? 8 : level) - 1));
|
||||
MemSizeMB = 1 << (level - 1);
|
||||
const unsigned kMult = 16;
|
||||
if ((MemSizeMB << 20) / kMult > ReduceSize)
|
||||
{
|
||||
for (UInt32 m = (1 << 20); m <= (1 << 28); m <<= 1)
|
||||
for (UInt32 m = 1; m < MemSizeMB; m <<= 1)
|
||||
if (ReduceSize <= (m << 20) / kMult)
|
||||
{
|
||||
if (ReduceSize <= m / kMult)
|
||||
{
|
||||
m >>= 20;
|
||||
if (MemSizeMB > m)
|
||||
MemSizeMB = m;
|
||||
break;
|
||||
}
|
||||
MemSizeMB = m;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (Order == -1) Order = 3 + level;
|
||||
if (Restor == -1)
|
||||
Restor = level < 7 ?
|
||||
@@ -197,6 +196,7 @@ STDMETHODIMP CEncoder::SetCoderProperties(const PROPID *propIDs, const PROPVARIA
|
||||
continue;
|
||||
if (propID == NCoderPropID::kReduceSize)
|
||||
{
|
||||
props.ReduceSize = (UInt32)(Int32)-1;
|
||||
if (prop.vt == VT_UI8 && prop.uhVal.QuadPart < (UInt32)(Int32)-1)
|
||||
props.ReduceSize = (UInt32)prop.uhVal.QuadPart;
|
||||
continue;
|
||||
@@ -219,9 +219,9 @@ STDMETHODIMP CEncoder::SetCoderProperties(const PROPID *propIDs, const PROPVARIA
|
||||
case NCoderPropID::kNumThreads: break;
|
||||
case NCoderPropID::kLevel: level = (int)v; break;
|
||||
case NCoderPropID::kAlgorithm:
|
||||
if (v > 1)
|
||||
if (v >= PPMD8_RESTORE_METHOD_UNSUPPPORTED)
|
||||
return E_INVALIDARG;
|
||||
props.Restor = v;
|
||||
props.Restor = (int)v;
|
||||
break;
|
||||
default: return E_INVALIDARG;
|
||||
}
|
||||
@@ -251,12 +251,14 @@ STDMETHODIMP CEncoder::Code(ISequentialInStream *inStream, ISequentialOutStream
|
||||
_outStream.Stream = outStream;
|
||||
_outStream.Init();
|
||||
|
||||
Ppmd8_RangeEnc_Init(&_ppmd);
|
||||
Ppmd8_Init(&_ppmd, _props.Order, _props.Restor);
|
||||
Ppmd8_Init_RangeEnc(&_ppmd);
|
||||
Ppmd8_Init(&_ppmd, (unsigned)_props.Order, (unsigned)_props.Restor);
|
||||
|
||||
UInt32 val = (UInt32)((_props.Order - 1) + ((_props.MemSizeMB - 1) << 4) + (_props.Restor << 12));
|
||||
_outStream.WriteByte((Byte)(val & 0xFF));
|
||||
_outStream.WriteByte((Byte)(val >> 8));
|
||||
{
|
||||
UInt32 val = (UInt32)(((unsigned)_props.Order - 1) + ((_props.MemSizeMB - 1) << 4) + ((unsigned)_props.Restor << 12));
|
||||
_outStream.WriteByte((Byte)(val & 0xFF));
|
||||
_outStream.WriteByte((Byte)(val >> 8));
|
||||
}
|
||||
RINOK(_outStream.Res);
|
||||
|
||||
UInt64 processed = 0;
|
||||
@@ -267,15 +269,23 @@ STDMETHODIMP CEncoder::Code(ISequentialInStream *inStream, ISequentialOutStream
|
||||
if (size == 0)
|
||||
{
|
||||
Ppmd8_EncodeSymbol(&_ppmd, -1);
|
||||
Ppmd8_RangeEnc_FlushData(&_ppmd);
|
||||
Ppmd8_Flush_RangeEnc(&_ppmd);
|
||||
return _outStream.Flush();
|
||||
}
|
||||
for (UInt32 i = 0; i < size; i++)
|
||||
{
|
||||
Ppmd8_EncodeSymbol(&_ppmd, _inStream.Buf[i]);
|
||||
RINOK(_outStream.Res);
|
||||
}
|
||||
|
||||
processed += size;
|
||||
const Byte *buf = _inStream.Buf;
|
||||
const Byte *lim = buf + size;
|
||||
do
|
||||
{
|
||||
Ppmd8_EncodeSymbol(&_ppmd, *buf);
|
||||
if (_outStream.Res != S_OK)
|
||||
break;
|
||||
}
|
||||
while (++buf != lim);
|
||||
|
||||
RINOK(_outStream.Res);
|
||||
|
||||
if (progress)
|
||||
{
|
||||
const UInt64 outProccessed = _outStream.GetProcessed();
|
||||
@@ -284,4 +294,7 @@ STDMETHODIMP CEncoder::Code(ISequentialInStream *inStream, ISequentialOutStream
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}}
|
||||
|
||||
@@ -8,10 +8,10 @@
|
||||
|
||||
#include "../../Common/MyCom.h"
|
||||
|
||||
#include "../Common/CWrappers.h"
|
||||
|
||||
#include "../ICoder.h"
|
||||
|
||||
#include "../Common/CWrappers.h"
|
||||
|
||||
namespace NCompress {
|
||||
namespace NPpmdZip {
|
||||
|
||||
@@ -21,7 +21,7 @@ struct CBuf
|
||||
{
|
||||
Byte *Buf;
|
||||
|
||||
CBuf(): Buf(0) {}
|
||||
CBuf(): Buf(NULL) {}
|
||||
~CBuf() { ::MidFree(Buf); }
|
||||
bool Alloc()
|
||||
{
|
||||
@@ -52,7 +52,7 @@ public:
|
||||
STDMETHOD(SetFinishMode)(UInt32 finishMode);
|
||||
STDMETHOD(GetInStreamProcessedSize)(UInt64 *value);
|
||||
|
||||
CDecoder(bool fullFileMode);
|
||||
CDecoder(bool fullFileMode = true);
|
||||
~CDecoder();
|
||||
};
|
||||
|
||||
|
||||
@@ -41,7 +41,7 @@ unsigned CModelDecoder::Decode(CRangeDecoder *rc)
|
||||
unsigned res = Vals[--i];
|
||||
|
||||
do
|
||||
Freqs[i] += kUpdateStep;
|
||||
Freqs[i] = (UInt16)(Freqs[i] + kUpdateStep);
|
||||
while (i--);
|
||||
|
||||
if (Freqs[0] > kFreqSumMax)
|
||||
@@ -72,7 +72,7 @@ unsigned CModelDecoder::Decode(CRangeDecoder *rc)
|
||||
i = NumItems - 1;
|
||||
do
|
||||
{
|
||||
Freqs[i] >>= 1;
|
||||
Freqs[i] = (UInt16)(Freqs[i] >> 1);
|
||||
if (Freqs[i] <= Freqs[(size_t)i + 1])
|
||||
Freqs[i] = (UInt16)(Freqs[(size_t)i + 1] + 1);
|
||||
}
|
||||
|
||||
@@ -239,6 +239,7 @@ HRESULT CDecoder::LongLZ()
|
||||
oldAvr3 = AvrLn3;
|
||||
|
||||
if (len != 1 && len != 4)
|
||||
{
|
||||
if (len == 0 && dist <= MaxDist3)
|
||||
{
|
||||
AvrLn3++;
|
||||
@@ -246,6 +247,7 @@ HRESULT CDecoder::LongLZ()
|
||||
}
|
||||
else if (AvrLn3 > 0)
|
||||
AvrLn3--;
|
||||
}
|
||||
|
||||
len += 3;
|
||||
|
||||
@@ -254,7 +256,7 @@ HRESULT CDecoder::LongLZ()
|
||||
if (dist <= 256)
|
||||
len += 8;
|
||||
|
||||
if (oldAvr3 > 0xb0 || AvrPlc >= 0x2a00 && oldAvr2 < 0x40)
|
||||
if (oldAvr3 > 0xb0 || (AvrPlc >= 0x2a00 && oldAvr2 < 0x40))
|
||||
MaxDist3 = 0x7f00;
|
||||
else
|
||||
MaxDist3 = 0x2001;
|
||||
@@ -412,7 +414,7 @@ HRESULT CDecoder::CodeReal(ISequentialInStream *inStream, ISequentialOutStream *
|
||||
|
||||
{
|
||||
// InitStructures
|
||||
for (int i = 0; i < kNumRepDists; i++)
|
||||
for (unsigned i = 0; i < kNumRepDists; i++)
|
||||
m_RepDists[i] = 0;
|
||||
m_RepDistPtr = 0;
|
||||
LastLength = 0;
|
||||
|
||||
@@ -4,6 +4,8 @@
|
||||
|
||||
#include "StdAfx.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "Rar2Decoder.h"
|
||||
|
||||
namespace NCompress {
|
||||
@@ -77,7 +79,7 @@ Byte CFilter::Decode(int &channelDelta, Byte deltaByte)
|
||||
|
||||
static const UInt32 kHistorySize = 1 << 20;
|
||||
|
||||
static const UInt32 kWindowReservSize = (1 << 22) + 256;
|
||||
// static const UInt32 kWindowReservSize = (1 << 22) + 256;
|
||||
|
||||
CDecoder::CDecoder():
|
||||
_isSolid(false),
|
||||
@@ -209,6 +211,7 @@ bool CDecoder::ReadLastTables()
|
||||
// + 2 works for: return 0xFF; in CInBuffer::ReadByte.
|
||||
if (m_InBitStream.GetProcessedSize() + 7 <= m_PackSize) // test it: probably incorrect;
|
||||
// if (m_InBitStream.GetProcessedSize() + 2 <= m_PackSize) // test it: probably incorrect;
|
||||
{
|
||||
if (m_AudioMode)
|
||||
{
|
||||
UInt32 symbol = m_MMDecoders[m_MmFilter.CurrentChannel].Decode(&m_InBitStream);
|
||||
@@ -225,6 +228,7 @@ bool CDecoder::ReadLastTables()
|
||||
if (sym >= kMainTableSize)
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -19,20 +19,14 @@ static const UInt32 kNumAlignReps = 15;
|
||||
|
||||
static const UInt32 kSymbolReadTable = 256;
|
||||
static const UInt32 kSymbolRep = 259;
|
||||
static const UInt32 kSymbolLen2 = kSymbolRep + kNumReps;
|
||||
|
||||
static const Byte kLenStart [kLenTableSize] = {0,1,2,3,4,5,6,7,8,10,12,14,16,20,24,28,32,40,48,56,64,80,96,112,128,160,192,224};
|
||||
static const Byte kLenDirectBits[kLenTableSize] = {0,0,0,0,0,0,0,0,1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5};
|
||||
|
||||
static const Byte kDistDirectBits[kDistTableSize] =
|
||||
{0,0,0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,11,11,12,12,13,13,14,14,15,15,
|
||||
16,16,16,16,16,16,16,16,16,16,16,16,16,16,
|
||||
18,18,18,18,18,18,18,18,18,18,18,18};
|
||||
|
||||
static const Byte kLevelDirectBits[kLevelTableSize] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,3,7};
|
||||
|
||||
static const Byte kLen2DistStarts[kNumLen2Symbols]={0,4,8,16,32,64,128,192};
|
||||
static const Byte kLen2DistDirectBits[kNumLen2Symbols]={2,2,3, 4, 5, 6, 6, 6};
|
||||
static const Byte kLen2DistStarts[kNumLen2Symbols] = {0,4,8,16,32,64,128,192};
|
||||
static const Byte kLen2DistDirectBits[kNumLen2Symbols] = {2,2,3, 4, 5, 6, 6, 6};
|
||||
|
||||
static const UInt32 kDistLimit3 = 0x2000 - 2;
|
||||
static const UInt32 kDistLimit4 = 0x40000 - 2;
|
||||
@@ -44,47 +38,20 @@ static const UInt32 kVmCodeSizeMax = 1 << 16;
|
||||
|
||||
extern "C" {
|
||||
|
||||
#define GET_RangeDecoder CRangeDecoder *p = CONTAINER_FROM_VTBL_CLS(pp, CRangeDecoder, vt);
|
||||
|
||||
static UInt32 Range_GetThreshold(const IPpmd7_RangeDec *pp, UInt32 total)
|
||||
static Byte Wrap_ReadByte(const IByteIn *pp) throw()
|
||||
{
|
||||
GET_RangeDecoder;
|
||||
return p->Code / (p->Range /= total);
|
||||
CByteIn *p = CONTAINER_FROM_VTBL_CLS(pp, CByteIn, IByteIn_obj);
|
||||
return p->BitDecoder.Stream.ReadByte();
|
||||
}
|
||||
|
||||
static void Range_Decode(const IPpmd7_RangeDec *pp, UInt32 start, UInt32 size)
|
||||
static Byte Wrap_ReadBits8(const IByteIn *pp) throw()
|
||||
{
|
||||
GET_RangeDecoder;
|
||||
start *= p->Range;
|
||||
p->Low += start;
|
||||
p->Code -= start;
|
||||
p->Range *= size;
|
||||
p->Normalize();
|
||||
}
|
||||
|
||||
static UInt32 Range_DecodeBit(const IPpmd7_RangeDec *pp, UInt32 size0)
|
||||
{
|
||||
GET_RangeDecoder;
|
||||
if (p->Code / (p->Range >>= 14) < size0)
|
||||
{
|
||||
Range_Decode(&p->vt, 0, size0);
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
Range_Decode(&p->vt, size0, (1 << 14) - size0);
|
||||
return 1;
|
||||
}
|
||||
CByteIn *p = CONTAINER_FROM_VTBL_CLS(pp, CByteIn, IByteIn_obj);
|
||||
return (Byte)p->BitDecoder.ReadByteFromAligned();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
CRangeDecoder::CRangeDecoder() throw()
|
||||
{
|
||||
vt.GetThreshold = Range_GetThreshold;
|
||||
vt.Decode = Range_Decode;
|
||||
vt.DecodeBit = Range_DecodeBit;
|
||||
}
|
||||
|
||||
CDecoder::CDecoder():
|
||||
_window(0),
|
||||
@@ -98,6 +65,13 @@ CDecoder::CDecoder():
|
||||
_solidAllowed(false)
|
||||
{
|
||||
Ppmd7_Construct(&_ppmd);
|
||||
|
||||
UInt32 start = 0;
|
||||
for (UInt32 i = 0; i < kDistTableSize; i++)
|
||||
{
|
||||
kDistStart[i] = start;
|
||||
start += ((UInt32)1 << kDistDirectBits[i]);
|
||||
}
|
||||
}
|
||||
|
||||
CDecoder::~CDecoder()
|
||||
@@ -360,32 +334,37 @@ bool CDecoder::AddVmCode(UInt32 firstByte, UInt32 codeSize)
|
||||
bool CDecoder::ReadVmCodeLZ()
|
||||
{
|
||||
UInt32 firstByte = ReadBits(8);
|
||||
UInt32 length = (firstByte & 7) + 1;
|
||||
if (length == 7)
|
||||
length = ReadBits(8) + 7;
|
||||
else if (length == 8)
|
||||
length = ReadBits(16);
|
||||
if (length > kVmDataSizeMax)
|
||||
UInt32 len = (firstByte & 7) + 1;
|
||||
if (len == 7)
|
||||
len = ReadBits(8) + 7;
|
||||
else if (len == 8)
|
||||
len = ReadBits(16);
|
||||
if (len > kVmDataSizeMax)
|
||||
return false;
|
||||
for (UInt32 i = 0; i < length; i++)
|
||||
for (UInt32 i = 0; i < len; i++)
|
||||
_vmData[i] = (Byte)ReadBits(8);
|
||||
return AddVmCode(firstByte, length);
|
||||
return AddVmCode(firstByte, len);
|
||||
}
|
||||
|
||||
|
||||
// int CDecoder::DecodePpmSymbol() { return Ppmd7a_DecodeSymbol(&_ppmd); }
|
||||
#define DecodePpmSymbol() Ppmd7a_DecodeSymbol(&_ppmd)
|
||||
|
||||
|
||||
bool CDecoder::ReadVmCodePPM()
|
||||
{
|
||||
int firstByte = DecodePpmSymbol();
|
||||
if (firstByte < 0)
|
||||
return false;
|
||||
UInt32 length = (firstByte & 7) + 1;
|
||||
if (length == 7)
|
||||
UInt32 len = (firstByte & 7) + 1;
|
||||
if (len == 7)
|
||||
{
|
||||
int b1 = DecodePpmSymbol();
|
||||
if (b1 < 0)
|
||||
return false;
|
||||
length = b1 + 7;
|
||||
len = b1 + 7;
|
||||
}
|
||||
else if (length == 8)
|
||||
else if (len == 8)
|
||||
{
|
||||
int b1 = DecodePpmSymbol();
|
||||
if (b1 < 0)
|
||||
@@ -393,20 +372,20 @@ bool CDecoder::ReadVmCodePPM()
|
||||
int b2 = DecodePpmSymbol();
|
||||
if (b2 < 0)
|
||||
return false;
|
||||
length = b1 * 256 + b2;
|
||||
len = b1 * 256 + b2;
|
||||
}
|
||||
if (length > kVmDataSizeMax)
|
||||
if (len > kVmDataSizeMax)
|
||||
return false;
|
||||
if (InputEofError_Fast())
|
||||
return false;
|
||||
for (UInt32 i = 0; i < length; i++)
|
||||
for (UInt32 i = 0; i < len; i++)
|
||||
{
|
||||
int b = DecodePpmSymbol();
|
||||
if (b < 0)
|
||||
return false;
|
||||
_vmData[i] = (Byte)b;
|
||||
}
|
||||
return AddVmCode(firstByte, length);
|
||||
return AddVmCode(firstByte, len);
|
||||
}
|
||||
|
||||
#define RIF(x) { if (!(x)) return S_FALSE; }
|
||||
@@ -422,19 +401,22 @@ HRESULT CDecoder::InitPPM()
|
||||
bool reset = ((maxOrder & 0x20) != 0);
|
||||
UInt32 maxMB = 0;
|
||||
if (reset)
|
||||
maxMB = (Byte)ReadBits(8);
|
||||
maxMB = (Byte)Wrap_ReadBits8(&m_InBitStream.IByteIn_obj);
|
||||
else
|
||||
{
|
||||
if (PpmError || !Ppmd7_WasAllocated(&_ppmd))
|
||||
return S_FALSE;
|
||||
}
|
||||
if (maxOrder & 0x40)
|
||||
PpmEscChar = (Byte)ReadBits(8);
|
||||
m_InBitStream.InitRangeCoder();
|
||||
/*
|
||||
if (m_InBitStream.m_BitPos != 0)
|
||||
return S_FALSE;
|
||||
*/
|
||||
PpmEscChar = (Byte)Wrap_ReadBits8(&m_InBitStream.IByteIn_obj);
|
||||
|
||||
_ppmd.rc.dec.Stream = &m_InBitStream.IByteIn_obj;
|
||||
m_InBitStream.IByteIn_obj.Read = Wrap_ReadBits8;
|
||||
|
||||
Ppmd7a_RangeDec_Init(&_ppmd.rc.dec);
|
||||
|
||||
m_InBitStream.IByteIn_obj.Read = Wrap_ReadByte;
|
||||
|
||||
if (reset)
|
||||
{
|
||||
PpmError = true;
|
||||
@@ -454,7 +436,6 @@ HRESULT CDecoder::InitPPM()
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
int CDecoder::DecodePpmSymbol() { return Ppmd7_DecodeSymbol(&_ppmd, &m_InBitStream.vt); }
|
||||
|
||||
HRESULT CDecoder::DecodePPM(Int32 num, bool &keepDecompressing)
|
||||
{
|
||||
@@ -503,8 +484,8 @@ HRESULT CDecoder::DecodePPM(Int32 num, bool &keepDecompressing)
|
||||
}
|
||||
if (nextCh == 4 || nextCh == 5)
|
||||
{
|
||||
UInt32 distance = 0;
|
||||
UInt32 length = 4;
|
||||
UInt32 dist = 0;
|
||||
UInt32 len = 4;
|
||||
if (nextCh == 4)
|
||||
{
|
||||
for (int i = 0; i < 3; i++)
|
||||
@@ -515,10 +496,10 @@ HRESULT CDecoder::DecodePPM(Int32 num, bool &keepDecompressing)
|
||||
PpmError = true;
|
||||
return S_FALSE;
|
||||
}
|
||||
distance = (distance << 8) + (Byte)c2;
|
||||
dist = (dist << 8) + (Byte)c2;
|
||||
}
|
||||
distance++;
|
||||
length += 28;
|
||||
dist++;
|
||||
len += 28;
|
||||
}
|
||||
int c2 = DecodePpmSymbol();
|
||||
if (c2 < 0)
|
||||
@@ -526,11 +507,11 @@ HRESULT CDecoder::DecodePPM(Int32 num, bool &keepDecompressing)
|
||||
PpmError = true;
|
||||
return S_FALSE;
|
||||
}
|
||||
length += c2;
|
||||
if (distance >= _lzSize)
|
||||
len += c2;
|
||||
if (dist >= _lzSize)
|
||||
return S_FALSE;
|
||||
CopyBlock(distance, length);
|
||||
num -= (Int32)length;
|
||||
CopyBlock(dist, len);
|
||||
num -= (Int32)len;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
@@ -571,8 +552,8 @@ HRESULT CDecoder::ReadTables(bool &keepDecompressing)
|
||||
|
||||
for (i = 0; i < kLevelTableSize; i++)
|
||||
{
|
||||
UInt32 length = ReadBits(4);
|
||||
if (length == 15)
|
||||
UInt32 len = ReadBits(4);
|
||||
if (len == 15)
|
||||
{
|
||||
UInt32 zeroCount = ReadBits(4);
|
||||
if (zeroCount != 0)
|
||||
@@ -584,7 +565,7 @@ HRESULT CDecoder::ReadTables(bool &keepDecompressing)
|
||||
continue;
|
||||
}
|
||||
}
|
||||
levelLevels[i] = (Byte)length;
|
||||
levelLevels[i] = (Byte)len;
|
||||
}
|
||||
|
||||
RIF(m_LevelDecoder.Build(levelLevels));
|
||||
@@ -674,22 +655,6 @@ HRESULT CDecoder::ReadEndOfBlock(bool &keepDecompressing)
|
||||
return ReadTables(keepDecompressing);
|
||||
}
|
||||
|
||||
UInt32 kDistStart[kDistTableSize];
|
||||
|
||||
class CDistInit
|
||||
{
|
||||
public:
|
||||
CDistInit() { Init(); }
|
||||
void Init()
|
||||
{
|
||||
UInt32 start = 0;
|
||||
for (UInt32 i = 0; i < kDistTableSize; i++)
|
||||
{
|
||||
kDistStart[i] = start;
|
||||
start += (1 << kDistDirectBits[i]);
|
||||
}
|
||||
}
|
||||
} g_DistInit;
|
||||
|
||||
HRESULT CDecoder::DecodeLZ(bool &keepDecompressing)
|
||||
{
|
||||
@@ -697,7 +662,7 @@ HRESULT CDecoder::DecodeLZ(bool &keepDecompressing)
|
||||
UInt32 rep1 = _reps[1];
|
||||
UInt32 rep2 = _reps[2];
|
||||
UInt32 rep3 = _reps[3];
|
||||
UInt32 length = _lastLength;
|
||||
UInt32 len = _lastLength;
|
||||
for (;;)
|
||||
{
|
||||
if (((_wrPtr - _winPos) & kWindowMask) < 260 && _wrPtr != _winPos)
|
||||
@@ -732,35 +697,40 @@ HRESULT CDecoder::DecodeLZ(bool &keepDecompressing)
|
||||
}
|
||||
else if (sym == 258)
|
||||
{
|
||||
if (length == 0)
|
||||
if (len == 0)
|
||||
return S_FALSE;
|
||||
}
|
||||
else if (sym < kSymbolRep + 4)
|
||||
{
|
||||
if (sym != kSymbolRep)
|
||||
{
|
||||
UInt32 distance;
|
||||
UInt32 dist;
|
||||
if (sym == kSymbolRep + 1)
|
||||
distance = rep1;
|
||||
dist = rep1;
|
||||
else
|
||||
{
|
||||
if (sym == kSymbolRep + 2)
|
||||
distance = rep2;
|
||||
dist = rep2;
|
||||
else
|
||||
{
|
||||
distance = rep3;
|
||||
dist = rep3;
|
||||
rep3 = rep2;
|
||||
}
|
||||
rep2 = rep1;
|
||||
}
|
||||
rep1 = rep0;
|
||||
rep0 = distance;
|
||||
rep0 = dist;
|
||||
}
|
||||
|
||||
const UInt32 sym2 = m_LenDecoder.Decode(&m_InBitStream.BitDecoder);
|
||||
if (sym2 >= kLenTableSize)
|
||||
return S_FALSE;
|
||||
length = 2 + kLenStart[sym2] + m_InBitStream.BitDecoder.ReadBits(kLenDirectBits[sym2]);
|
||||
len = 2 + sym2;
|
||||
if (sym2 >= 8)
|
||||
{
|
||||
unsigned num = (sym2 >> 2) - 1;
|
||||
len = 2 + ((4 + (sym2 & 3)) << num) + m_InBitStream.BitDecoder.ReadBits_upto8(num);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -770,13 +740,18 @@ HRESULT CDecoder::DecodeLZ(bool &keepDecompressing)
|
||||
if (sym < 271)
|
||||
{
|
||||
sym -= 263;
|
||||
rep0 = kLen2DistStarts[sym] + m_InBitStream.BitDecoder.ReadBits(kLen2DistDirectBits[sym]);
|
||||
length = 2;
|
||||
rep0 = kLen2DistStarts[sym] + m_InBitStream.BitDecoder.ReadBits_upto8(kLen2DistDirectBits[sym]);
|
||||
len = 2;
|
||||
}
|
||||
else if (sym < 299)
|
||||
{
|
||||
sym -= 271;
|
||||
length = kNormalMatchMinLen + (UInt32)kLenStart[sym] + m_InBitStream.BitDecoder.ReadBits(kLenDirectBits[sym]);
|
||||
len = kNormalMatchMinLen + sym;
|
||||
if (sym >= 8)
|
||||
{
|
||||
unsigned num = (sym >> 2) - 1;
|
||||
len = kNormalMatchMinLen + ((4 + (sym & 3)) << num) + m_InBitStream.BitDecoder.ReadBits_upto8(num);
|
||||
}
|
||||
const UInt32 sym2 = m_DistDecoder.Decode(&m_InBitStream.BitDecoder);
|
||||
if (sym2 >= kDistTableSize)
|
||||
return S_FALSE;
|
||||
@@ -809,21 +784,21 @@ HRESULT CDecoder::DecodeLZ(bool &keepDecompressing)
|
||||
}
|
||||
}
|
||||
else
|
||||
rep0 += m_InBitStream.BitDecoder.ReadBits(numBits);
|
||||
length += ((kDistLimit4 - rep0) >> 31) + ((kDistLimit3 - rep0) >> 31);
|
||||
rep0 += m_InBitStream.BitDecoder.ReadBits_upto8(numBits);
|
||||
len += ((UInt32)(kDistLimit4 - rep0) >> 31) + ((UInt32)(kDistLimit3 - rep0) >> 31);
|
||||
}
|
||||
else
|
||||
return S_FALSE;
|
||||
}
|
||||
if (rep0 >= _lzSize)
|
||||
return S_FALSE;
|
||||
CopyBlock(rep0, length);
|
||||
CopyBlock(rep0, len);
|
||||
}
|
||||
_reps[0] = rep0;
|
||||
_reps[1] = rep1;
|
||||
_reps[2] = rep2;
|
||||
_reps[3] = rep3;
|
||||
_lastLength = length;
|
||||
_lastLength = len;
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
@@ -839,7 +814,7 @@ HRESULT CDecoder::CodeReal(ICompressProgressInfo *progress)
|
||||
_lzSize = 0;
|
||||
_winPos = 0;
|
||||
_wrPtr = 0;
|
||||
for (int i = 0; i < kNumReps; i++)
|
||||
for (unsigned i = 0; i < kNumReps; i++)
|
||||
_reps[i] = 0;
|
||||
_lastLength = 0;
|
||||
memset(m_LastLevels, 0, kTablesSizesSum);
|
||||
|
||||
@@ -95,44 +95,40 @@ public:
|
||||
MovePos(numBits);
|
||||
return res;
|
||||
}
|
||||
};
|
||||
|
||||
const UInt32 kTopValue = (1 << 24);
|
||||
const UInt32 kBot = (1 << 15);
|
||||
|
||||
struct CRangeDecoder
|
||||
{
|
||||
IPpmd7_RangeDec vt;
|
||||
UInt32 Range;
|
||||
UInt32 Code;
|
||||
UInt32 Low;
|
||||
CBitDecoder BitDecoder;
|
||||
SRes Res;
|
||||
|
||||
public:
|
||||
void InitRangeCoder()
|
||||
UInt32 ReadBits_upto8(unsigned numBits)
|
||||
{
|
||||
Code = 0;
|
||||
Low = 0;
|
||||
Range = 0xFFFFFFFF;
|
||||
for (int i = 0; i < 4; i++)
|
||||
Code = (Code << 8) | BitDecoder.ReadBits(8);
|
||||
}
|
||||
|
||||
void Normalize()
|
||||
{
|
||||
while ((Low ^ (Low + Range)) < kTopValue ||
|
||||
Range < kBot && ((Range = (0 - Low) & (kBot - 1)), 1))
|
||||
if (_bitPos < numBits)
|
||||
{
|
||||
Code = (Code << 8) | BitDecoder.Stream.ReadByte();
|
||||
Range <<= 8;
|
||||
Low <<= 8;
|
||||
_bitPos += 8;
|
||||
_value = (_value << 8) | Stream.ReadByte();
|
||||
}
|
||||
_bitPos -= numBits;
|
||||
UInt32 res = _value >> _bitPos;
|
||||
_value = _value & ((1 << _bitPos) - 1);
|
||||
return res;
|
||||
}
|
||||
|
||||
CRangeDecoder() throw();
|
||||
Byte ReadByteFromAligned()
|
||||
{
|
||||
if (_bitPos == 0)
|
||||
return Stream.ReadByte();
|
||||
unsigned bitsPos = _bitPos - 8;
|
||||
Byte b = (Byte)(_value >> bitsPos);
|
||||
_value = _value & ((1 << bitsPos) - 1);
|
||||
_bitPos = bitsPos;
|
||||
return b;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
struct CByteIn
|
||||
{
|
||||
IByteIn IByteIn_obj;
|
||||
CBitDecoder BitDecoder;
|
||||
};
|
||||
|
||||
|
||||
struct CFilter: public NVm::CProgram
|
||||
{
|
||||
CRecordVector<Byte> GlobalData;
|
||||
@@ -165,7 +161,7 @@ class CDecoder:
|
||||
public ICompressSetDecoderProperties2,
|
||||
public CMyUnknownImp
|
||||
{
|
||||
CRangeDecoder m_InBitStream;
|
||||
CByteIn m_InBitStream;
|
||||
Byte *_window;
|
||||
UInt32 _winPos;
|
||||
UInt32 _wrPtr;
|
||||
@@ -174,6 +170,7 @@ class CDecoder:
|
||||
UInt64 _writtenFileSize; // if it's > _unpackSize, then _unpackSize only written
|
||||
ISequentialOutStream *_outStream;
|
||||
NHuffman::CDecoder<kNumHuffmanBits, kMainTableSize> m_MainDecoder;
|
||||
UInt32 kDistStart[kDistTableSize];
|
||||
NHuffman::CDecoder<kNumHuffmanBits, kDistTableSize> m_DistDecoder;
|
||||
NHuffman::CDecoder<kNumHuffmanBits, kAlignTableSize> m_AlignDecoder;
|
||||
NHuffman::CDecoder<kNumHuffmanBits, kLenTableSize> m_LenDecoder;
|
||||
@@ -223,7 +220,7 @@ class CDecoder:
|
||||
UInt32 ReadBits(unsigned numBits);
|
||||
|
||||
HRESULT InitPPM();
|
||||
int DecodePpmSymbol();
|
||||
// int DecodePpmSymbol();
|
||||
HRESULT DecodePPM(Int32 num, bool &keepDecompressing);
|
||||
|
||||
HRESULT ReadTables(bool &keepDecompressing);
|
||||
@@ -245,10 +242,10 @@ public:
|
||||
|
||||
STDMETHOD(SetDecoderProperties2)(const Byte *data, UInt32 size);
|
||||
|
||||
void CopyBlock(UInt32 distance, UInt32 len)
|
||||
void CopyBlock(UInt32 dist, UInt32 len)
|
||||
{
|
||||
_lzSize += len;
|
||||
UInt32 pos = (_winPos - distance - 1) & kWindowMask;
|
||||
UInt32 pos = (_winPos - dist - 1) & kWindowMask;
|
||||
Byte *window = _window;
|
||||
UInt32 winPos = _winPos;
|
||||
if (kWindowSize - winPos > len && kWindowSize - pos > len)
|
||||
@@ -273,12 +270,11 @@ public:
|
||||
|
||||
void PutByte(Byte b)
|
||||
{
|
||||
_window[_winPos] = b;
|
||||
_winPos = (_winPos + 1) & kWindowMask;
|
||||
UInt32 wp = _winPos;
|
||||
_window[wp] = b;
|
||||
_winPos = (wp + 1) & kWindowMask;
|
||||
_lzSize++;
|
||||
}
|
||||
|
||||
|
||||
};
|
||||
|
||||
}}
|
||||
|
||||
@@ -34,7 +34,7 @@ UInt32 CMemBitDecoder::ReadBits(unsigned numBits)
|
||||
if (numBits <= avail)
|
||||
{
|
||||
_bitPos += numBits;
|
||||
return res | (b >> (avail - numBits)) & ((1 << numBits) - 1);
|
||||
return res | ((b >> (avail - numBits)) & ((1 << numBits) - 1));
|
||||
}
|
||||
numBits -= avail;
|
||||
res |= (UInt32)(b & ((1 << avail) - 1)) << numBits;
|
||||
|
||||
@@ -64,16 +64,16 @@ enum FilterType
|
||||
static const size_t kWriteStep = (size_t)1 << 22;
|
||||
|
||||
CDecoder::CDecoder():
|
||||
_window(NULL),
|
||||
_winPos(0),
|
||||
_winSizeAllocated(0),
|
||||
_lzSize(0),
|
||||
_lzEnd(0),
|
||||
_writtenFileSize(0),
|
||||
_dictSizeLog(0),
|
||||
_isSolid(false),
|
||||
_solidAllowed(false),
|
||||
_wasInit(false),
|
||||
_dictSizeLog(0),
|
||||
_window(NULL),
|
||||
_winPos(0),
|
||||
_lzSize(0),
|
||||
_lzEnd(0),
|
||||
_writtenFileSize(0),
|
||||
_winSizeAllocated(0),
|
||||
_inputBuf(NULL)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -160,7 +160,7 @@ HRESULT CDecoder::CodeReal(ISequentialInStream *inStream, ISequentialOutStream *
|
||||
}
|
||||
}
|
||||
|
||||
lastSym = sym;
|
||||
lastSym = (int)sym;
|
||||
unsigned cur = sym;
|
||||
unsigned i = 0;
|
||||
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
#include "../../../C/CpuArch.h"
|
||||
|
||||
#include "HuffmanDecoder.h"
|
||||
#include "XpressDecoder.h"
|
||||
|
||||
namespace NCompress {
|
||||
namespace NXpress {
|
||||
|
||||
@@ -34,7 +34,7 @@ static HRESULT SResToHRESULT_Code(SRes res) throw()
|
||||
HRESULT CDecoder::Decode(ISequentialInStream *seqInStream, ISequentialOutStream *outStream,
|
||||
const UInt64 *outSizeLimit, bool finishStream, ICompressProgressInfo *progress)
|
||||
{
|
||||
MainDecodeSRes = S_OK;
|
||||
MainDecodeSRes = SZ_OK;
|
||||
MainDecodeSRes_wasUsed = false;
|
||||
XzStatInfo_Clear(&Stat);
|
||||
|
||||
@@ -95,7 +95,7 @@ HRESULT CDecoder::Decode(ISequentialInStream *seqInStream, ISequentialOutStream
|
||||
RET_IF_WRAP_ERROR(progressWrap.Res, res, SZ_ERROR_PROGRESS)
|
||||
RET_IF_WRAP_ERROR_CONFIRMED(inWrap.Res, res, SZ_ERROR_READ)
|
||||
|
||||
// return E_OUTOFMEMORY;
|
||||
// return E_OUTOFMEMORY; // for debug check
|
||||
|
||||
MainDecodeSRes_wasUsed = true;
|
||||
|
||||
|
||||
@@ -38,8 +38,9 @@ struct CDecoder
|
||||
XzDecMt_Destroy(xz);
|
||||
}
|
||||
|
||||
/* Decode() can return ERROR code only if there is progress or stream error.
|
||||
Decode() returns S_OK in case of xz decoding error, but DecodeRes and CStatInfo contain error information */
|
||||
/* Decode() can return S_OK, if there is data after good xz streams, and that data is not new xz stream.
|
||||
check also (Stat.DataAfterEnd) flag */
|
||||
|
||||
HRESULT Decode(ISequentialInStream *seqInStream, ISequentialOutStream *outStream,
|
||||
const UInt64 *outSizeLimit, bool finishStream, ICompressProgressInfo *compressProgress);
|
||||
};
|
||||
|
||||
@@ -159,7 +159,7 @@ HRESULT CEncoder::SetCoderProp(PROPID propID, const PROPVARIANT &prop)
|
||||
int filterId = FilterIdFromName(prop.bstrVal);
|
||||
if (filterId < 0 /* || filterId == XZ_ID_LZMA2 */)
|
||||
return E_INVALIDARG;
|
||||
id32 = filterId;
|
||||
id32 = (unsigned)filterId;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -15,6 +15,7 @@ namespace NZlib {
|
||||
#define ADLER_MOD 65521
|
||||
#define ADLER_LOOP_MAX 5550
|
||||
|
||||
UInt32 Adler32_Update(UInt32 adler, const Byte *buf, size_t size);
|
||||
UInt32 Adler32_Update(UInt32 adler, const Byte *buf, size_t size)
|
||||
{
|
||||
UInt32 a = adler & 0xFFFF;
|
||||
|
||||
Reference in New Issue
Block a user