This commit is contained in:
Igor Pavlov
2021-07-22 23:00:14 +01:00
committed by Kornel
parent 4a960640a3
commit 585698650f
619 changed files with 34904 additions and 10859 deletions

View File

@@ -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.
*/
}}

View File

@@ -19,6 +19,7 @@ void CBZip2Crc::InitTable()
}
}
static
class CBZip2CrcTableInit
{
public:

View File

@@ -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();

View File

@@ -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; }

View File

@@ -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

View File

@@ -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; }

View File

@@ -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(&currentInPos, &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;
}

View File

@@ -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)

View File

@@ -8,6 +8,7 @@ namespace NBitl {
Byte kInvertTable[256];
static
struct CInverterTableInitializer
{
CInverterTableInitializer()

View File

@@ -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;
}
};
}

View File

@@ -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;
}

View File

@@ -33,7 +33,7 @@ public:
{
if (numBits < _bitPos)
{
_curByte |= ((Byte)value << (_bitPos -= numBits));
_curByte = (Byte)(_curByte | (value << (_bitPos -= numBits)));
return;
}
numBits -= _bitPos;

View File

@@ -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

View File

@@ -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;
}

View File

@@ -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(); }
};

View File

@@ -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++)
{

View File

@@ -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);

View File

@@ -83,8 +83,8 @@ static const UInt32 kHistorySize = (1 << kNumDistDirectBitsBig) * kDistTableSize
CCoder::CCoder():
_fullStreamMode(false),
_flags(0)
_flags(0),
_fullStreamMode(false)
{}

View File

@@ -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));
}

View File

@@ -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)
{

View File

@@ -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);
}

View File

@@ -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;
/*

View File

@@ -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; }
};
}}

View File

@@ -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)
{
}

View File

@@ -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; }
};
}}

View File

@@ -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)
{

View File

@@ -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();

View File

@@ -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));
}
}

View File

@@ -37,7 +37,6 @@ class CEncoder :
{
Byte *_inBuf;
CByteOutBufWrap _outStream;
CPpmd7z_RangeEnc _rangeEnc;
CPpmd7 _ppmd;
CEncProps _props;
public:

View File

@@ -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
}
}
}}

View File

@@ -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();
};

View File

@@ -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);
}

View File

@@ -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;

View File

@@ -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;
}

View File

@@ -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);

View File

@@ -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++;
}
};
}}

View File

@@ -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;

View File

@@ -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)
{
}

View File

@@ -160,7 +160,7 @@ HRESULT CDecoder::CodeReal(ISequentialInStream *inStream, ISequentialOutStream *
}
}
lastSym = sym;
lastSym = (int)sym;
unsigned cur = sym;
unsigned i = 0;

View File

@@ -7,6 +7,7 @@
#include "../../../C/CpuArch.h"
#include "HuffmanDecoder.h"
#include "XpressDecoder.h"
namespace NCompress {
namespace NXpress {

View File

@@ -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;

View File

@@ -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);
};

View File

@@ -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;
}
}

View File

@@ -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;