mirror of
https://github.com/Xevion/easy7zip.git
synced 2026-01-31 20:24:05 -06:00
23.01
This commit is contained in:
@@ -89,11 +89,8 @@ HRESULT CDecoder::DecodeUncompressed(UInt32 unpackSize)
|
||||
|
||||
|
||||
|
||||
HRESULT CDecoder::DecodeLzvn(UInt32 unpackSize)
|
||||
HRESULT CDecoder::DecodeLzvn(UInt32 unpackSize, UInt32 packSize)
|
||||
{
|
||||
UInt32 packSize;
|
||||
RINOK(GetUInt32(packSize));
|
||||
|
||||
PRF(printf("\nLZVN %7u %7u", unpackSize, packSize));
|
||||
|
||||
UInt32 D = 0;
|
||||
@@ -296,7 +293,7 @@ static UInt32 SumFreqs(const UInt16 *freqs, unsigned num)
|
||||
}
|
||||
|
||||
|
||||
static MY_FORCE_INLINE unsigned CountZeroBits(UInt32 val, UInt32 mask)
|
||||
static Z7_FORCE_INLINE unsigned CountZeroBits(UInt32 val, UInt32 mask)
|
||||
{
|
||||
for (unsigned i = 0;;)
|
||||
{
|
||||
@@ -308,7 +305,7 @@ static MY_FORCE_INLINE unsigned CountZeroBits(UInt32 val, UInt32 mask)
|
||||
}
|
||||
|
||||
|
||||
static MY_FORCE_INLINE void InitLitTable(const UInt16 *freqs, UInt32 *table)
|
||||
static Z7_FORCE_INLINE void InitLitTable(const UInt16 *freqs, UInt32 *table)
|
||||
{
|
||||
for (unsigned i = 0; i < NUM_LIT_SYMBOLS; i++)
|
||||
{
|
||||
@@ -443,7 +440,7 @@ typedef struct
|
||||
} CBitStream;
|
||||
|
||||
|
||||
static MY_FORCE_INLINE int FseInStream_Init(CBitStream *s,
|
||||
static Z7_FORCE_INLINE int FseInStream_Init(CBitStream *s,
|
||||
int n, // [-7, 0], (-n == number_of_unused_bits) in last byte
|
||||
const Byte **pbuf)
|
||||
{
|
||||
@@ -451,7 +448,7 @@ static MY_FORCE_INLINE int FseInStream_Init(CBitStream *s,
|
||||
s->accum = GetUi32(*pbuf);
|
||||
if (n)
|
||||
{
|
||||
s->numBits = n + 32;
|
||||
s->numBits = (unsigned)(n + 32);
|
||||
if ((s->accum >> s->numBits) != 0)
|
||||
return -1; // ERROR, encoder should have zeroed the upper bits
|
||||
}
|
||||
@@ -469,7 +466,7 @@ static MY_FORCE_INLINE int FseInStream_Init(CBitStream *s,
|
||||
#define mask31(x, numBits) ((x) & (((UInt32)1 << (numBits)) - 1))
|
||||
|
||||
#define FseInStream_FLUSH \
|
||||
{ unsigned nbits = (31 - in.numBits) & -8; \
|
||||
{ const unsigned nbits = (31 - in.numBits) & (unsigned)-8; \
|
||||
if (nbits) { \
|
||||
buf -= (nbits >> 3); \
|
||||
if (buf < buf_check) return S_FALSE; \
|
||||
@@ -479,7 +476,7 @@ static MY_FORCE_INLINE int FseInStream_Init(CBitStream *s,
|
||||
|
||||
|
||||
|
||||
static MY_FORCE_INLINE UInt32 BitStream_Pull(CBitStream *s, unsigned numBits)
|
||||
static Z7_FORCE_INLINE UInt32 BitStream_Pull(CBitStream *s, unsigned numBits)
|
||||
{
|
||||
s->numBits -= numBits;
|
||||
UInt32 v = s->accum >> s->numBits;
|
||||
@@ -494,7 +491,7 @@ static MY_FORCE_INLINE UInt32 BitStream_Pull(CBitStream *s, unsigned numBits)
|
||||
dest = (Byte)(e >> 8); }
|
||||
|
||||
|
||||
static MY_FORCE_INLINE UInt32 FseDecodeExtra(CFseState *pstate,
|
||||
static Z7_FORCE_INLINE UInt32 FseDecodeExtra(CFseState *pstate,
|
||||
const CExtraEntry *table,
|
||||
CBitStream *s)
|
||||
{
|
||||
@@ -512,6 +509,7 @@ static MY_FORCE_INLINE UInt32 FseDecodeExtra(CFseState *pstate,
|
||||
#define freqs_LIT (freqs_D + NUM_D_SYMBOLS)
|
||||
|
||||
#define GET_BITS_64(v, offset, num, dest) dest = (UInt32) ((v >> (offset)) & ((1 << (num)) - 1));
|
||||
#define GET_BITS_64_Int32(v, offset, num, dest) dest = (Int32)((v >> (offset)) & ((1 << (num)) - 1));
|
||||
#define GET_BITS_32(v, offset, num, dest) dest = (CFseState)((v >> (offset)) & ((1 << (num)) - 1));
|
||||
|
||||
|
||||
@@ -595,22 +593,22 @@ HRESULT CDecoder::DecodeLzfse(UInt32 unpackSize, Byte version)
|
||||
UInt64 v;
|
||||
|
||||
v = GetUi64(temp);
|
||||
GET_BITS_64(v, 0, 20, numLiterals);
|
||||
GET_BITS_64(v, 20, 20, litPayloadSize);
|
||||
GET_BITS_64(v, 40, 20, numMatches);
|
||||
GET_BITS_64(v, 60, 3 + 1, literal_bits); // (NumberOfUsedBits - 1)
|
||||
GET_BITS_64(v, 0, 20, numLiterals)
|
||||
GET_BITS_64(v, 20, 20, litPayloadSize)
|
||||
GET_BITS_64(v, 40, 20, numMatches)
|
||||
GET_BITS_64_Int32(v, 60, 3 + 1, literal_bits) // (NumberOfUsedBits - 1)
|
||||
literal_bits -= 7; // (-NumberOfUnusedBits)
|
||||
if (literal_bits > 0)
|
||||
return S_FALSE;
|
||||
// GET_BITS_64(v, 63, 1, unused);
|
||||
|
||||
v = GetUi64(temp + 8);
|
||||
GET_BITS_64(v, 0, 10, lit_state_0);
|
||||
GET_BITS_64(v, 10, 10, lit_state_1);
|
||||
GET_BITS_64(v, 20, 10, lit_state_2);
|
||||
GET_BITS_64(v, 30, 10, lit_state_3);
|
||||
GET_BITS_64(v, 40, 20, lmdPayloadSize);
|
||||
GET_BITS_64(v, 60, 3 + 1, lmd_bits);
|
||||
GET_BITS_64(v, 0, 10, lit_state_0)
|
||||
GET_BITS_64(v, 10, 10, lit_state_1)
|
||||
GET_BITS_64(v, 20, 10, lit_state_2)
|
||||
GET_BITS_64(v, 30, 10, lit_state_3)
|
||||
GET_BITS_64(v, 40, 20, lmdPayloadSize)
|
||||
GET_BITS_64_Int32(v, 60, 3 + 1, lmd_bits)
|
||||
lmd_bits -= 7;
|
||||
if (lmd_bits > 0)
|
||||
return S_FALSE;
|
||||
@@ -621,10 +619,10 @@ HRESULT CDecoder::DecodeLzfse(UInt32 unpackSize, Byte version)
|
||||
// correspond to a field in the uncompressed header version,
|
||||
// but is required; we wouldn't know the size of the
|
||||
// compresssed header otherwise.
|
||||
GET_BITS_32(v32, 0, 10, l_state);
|
||||
GET_BITS_32(v32, 10, 10, m_state);
|
||||
GET_BITS_32(v32, 20, 10 + 2, d_state);
|
||||
// GET_BITS_64(v, 62, 2, unused);
|
||||
GET_BITS_32(v32, 0, 10, l_state)
|
||||
GET_BITS_32(v32, 10, 10, m_state)
|
||||
GET_BITS_32(v32, 20, 10 + 2, d_state)
|
||||
// GET_BITS_64(v, 62, 2, unused)
|
||||
|
||||
headerSize = GetUi32(temp + 16);
|
||||
if (headerSize <= kPreHeaderSize + kHeaderSize)
|
||||
@@ -729,11 +727,11 @@ HRESULT CDecoder::DecodeLzfse(UInt32 unpackSize, Byte version)
|
||||
for (; lit < lit_limit; lit += 4)
|
||||
{
|
||||
FseInStream_FLUSH
|
||||
DECODE_LIT (lit[0], lit_state_0);
|
||||
DECODE_LIT (lit[1], lit_state_1);
|
||||
DECODE_LIT (lit[0], lit_state_0)
|
||||
DECODE_LIT (lit[1], lit_state_1)
|
||||
FseInStream_FLUSH
|
||||
DECODE_LIT (lit[2], lit_state_2);
|
||||
DECODE_LIT (lit[3], lit_state_3);
|
||||
DECODE_LIT (lit[2], lit_state_2)
|
||||
DECODE_LIT (lit[3], lit_state_3)
|
||||
}
|
||||
|
||||
if ((buf_start - buf) * 8 != (int)in.numBits)
|
||||
@@ -824,7 +822,7 @@ HRESULT CDecoder::DecodeLzfse(UInt32 unpackSize, Byte version)
|
||||
|
||||
// LZFSE encoder writes 8 additional zero bytes before LMD payload
|
||||
// We test it:
|
||||
if ((buf - buf_start) * 8 + in.numBits != 64)
|
||||
if ((size_t)(buf - buf_start) * 8 + in.numBits != 64)
|
||||
return S_FALSE;
|
||||
if (GetUi64(buf_start) != 0)
|
||||
return S_FALSE;
|
||||
@@ -833,7 +831,7 @@ HRESULT CDecoder::DecodeLzfse(UInt32 unpackSize, Byte version)
|
||||
}
|
||||
|
||||
|
||||
STDMETHODIMP CDecoder::CodeReal(ISequentialInStream *inStream, ISequentialOutStream *outStream,
|
||||
HRESULT CDecoder::CodeReal(ISequentialInStream *inStream, ISequentialOutStream *outStream,
|
||||
const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress)
|
||||
{
|
||||
PRF(printf("\n\nLzfseDecoder %7u %7u\n", (unsigned)*outSize, (unsigned)*inSize));
|
||||
@@ -854,6 +852,18 @@ STDMETHODIMP CDecoder::CodeReal(ISequentialInStream *inStream, ISequentialOutStr
|
||||
UInt64 prevOut = 0;
|
||||
UInt64 prevIn = 0;
|
||||
|
||||
if (LzvnMode)
|
||||
{
|
||||
if (!outSize || !inSize)
|
||||
return E_NOTIMPL;
|
||||
const UInt64 unpackSize = *outSize;
|
||||
const UInt64 packSize = *inSize;
|
||||
if (unpackSize > (UInt32)(Int32)-1
|
||||
|| packSize > (UInt32)(Int32)-1)
|
||||
return S_FALSE;
|
||||
RINOK(DecodeLzvn((UInt32)unpackSize, (UInt32)packSize))
|
||||
}
|
||||
else
|
||||
for (;;)
|
||||
{
|
||||
const UInt64 pos = m_OutWindowStream.GetProcessedSize();
|
||||
@@ -861,12 +871,11 @@ STDMETHODIMP CDecoder::CodeReal(ISequentialInStream *inStream, ISequentialOutStr
|
||||
|
||||
if (progress && ((pos - prevOut) >= (1 << 22) || (packPos - prevIn) >= (1 << 22)))
|
||||
{
|
||||
RINOK(progress->SetRatioInfo(&packPos, &pos));
|
||||
RINOK(progress->SetRatioInfo(&packPos, &pos))
|
||||
prevIn = packPos;
|
||||
prevOut = pos;
|
||||
}
|
||||
|
||||
const UInt64 rem = *outSize - pos;
|
||||
UInt32 v;
|
||||
RINOK(GetUInt32(v))
|
||||
if ((v & 0xFFFFFF) != 0x787662) // bvx
|
||||
@@ -877,19 +886,27 @@ STDMETHODIMP CDecoder::CodeReal(ISequentialInStream *inStream, ISequentialOutStr
|
||||
break;
|
||||
|
||||
UInt32 unpackSize;
|
||||
RINOK(GetUInt32(unpackSize));
|
||||
|
||||
RINOK(GetUInt32(unpackSize))
|
||||
|
||||
UInt32 cur = unpackSize;
|
||||
if (cur > rem)
|
||||
cur = (UInt32)rem;
|
||||
|
||||
if (outSize)
|
||||
{
|
||||
const UInt64 rem = *outSize - pos;
|
||||
if (cur > rem)
|
||||
cur = (UInt32)rem;
|
||||
}
|
||||
unpackSize -= cur;
|
||||
|
||||
HRESULT res;
|
||||
if (v == kSignature_LZFSE_V1 || v == kSignature_LZFSE_V2)
|
||||
res = DecodeLzfse(cur, (Byte)v);
|
||||
else if (v == 0x6E) // 'n'
|
||||
res = DecodeLzvn(cur);
|
||||
{
|
||||
UInt32 packSize;
|
||||
res = GetUInt32(packSize);
|
||||
if (res == S_OK)
|
||||
res = DecodeLzvn(cur, packSize);
|
||||
}
|
||||
else if (v == 0x2D) // '-'
|
||||
res = DecodeUncompressed(cur);
|
||||
else
|
||||
@@ -905,15 +922,15 @@ STDMETHODIMP CDecoder::CodeReal(ISequentialInStream *inStream, ISequentialOutStr
|
||||
coderReleaser.NeedFlush = false;
|
||||
HRESULT res = m_OutWindowStream.Flush();
|
||||
if (res == S_OK)
|
||||
if (*inSize != m_InStream.GetProcessedSize()
|
||||
|| *outSize != m_OutWindowStream.GetProcessedSize())
|
||||
if ((inSize && *inSize != m_InStream.GetProcessedSize())
|
||||
|| (outSize && *outSize != m_OutWindowStream.GetProcessedSize()))
|
||||
res = S_FALSE;
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
STDMETHODIMP CDecoder::Code(ISequentialInStream *inStream, ISequentialOutStream *outStream,
|
||||
const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress)
|
||||
Z7_COM7F_IMF(CDecoder::Code(ISequentialInStream *inStream, ISequentialOutStream *outStream,
|
||||
const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress))
|
||||
{
|
||||
try { return CodeReal(inStream, outStream, inSize, outSize, progress); }
|
||||
catch(const CInBufferException &e) { return e.ErrorCode; }
|
||||
|
||||
Reference in New Issue
Block a user