mirror of
https://github.com/RPCS3/rpcs3.git
synced 2025-07-06 06:51:26 +12:00
7z: Update from 19.00 to 21.07
This commit is contained in:
parent
f6de42a2ae
commit
7ef112cf30
59 changed files with 8366 additions and 2483 deletions
422
3rdparty/7z/src/LzmaDec.c
vendored
422
3rdparty/7z/src/LzmaDec.c
vendored
|
@ -1,5 +1,5 @@
|
|||
/* LzmaDec.c -- LZMA Decoder
|
||||
2018-07-04 : Igor Pavlov : Public domain */
|
||||
2021-04-01 : Igor Pavlov : Public domain */
|
||||
|
||||
#include "Precomp.h"
|
||||
|
||||
|
@ -13,10 +13,12 @@
|
|||
|
||||
#define kNumBitModelTotalBits 11
|
||||
#define kBitModelTotal (1 << kNumBitModelTotalBits)
|
||||
#define kNumMoveBits 5
|
||||
|
||||
#define RC_INIT_SIZE 5
|
||||
|
||||
#ifndef _LZMA_DEC_OPT
|
||||
|
||||
#define kNumMoveBits 5
|
||||
#define NORMALIZE if (range < kTopValue) { range <<= 8; code = (code << 8) | (*buf++); }
|
||||
|
||||
#define IF_BIT_0(p) ttt = *(p); NORMALIZE; bound = (range >> kNumBitModelTotalBits) * (UInt32)ttt; if (code < bound)
|
||||
|
@ -62,9 +64,10 @@
|
|||
probLit = prob + (offs + bit + symbol); \
|
||||
GET_BIT2(probLit, symbol, offs ^= bit; , ;)
|
||||
|
||||
#endif // _LZMA_DEC_OPT
|
||||
|
||||
|
||||
#define NORMALIZE_CHECK if (range < kTopValue) { if (buf >= bufLimit) return DUMMY_ERROR; range <<= 8; code = (code << 8) | (*buf++); }
|
||||
#define NORMALIZE_CHECK if (range < kTopValue) { if (buf >= bufLimit) return DUMMY_INPUT_EOF; range <<= 8; code = (code << 8) | (*buf++); }
|
||||
|
||||
#define IF_BIT_0_CHECK(p) ttt = *(p); NORMALIZE_CHECK; bound = (range >> kNumBitModelTotalBits) * (UInt32)ttt; if (code < bound)
|
||||
#define UPDATE_0_CHECK range = bound;
|
||||
|
@ -114,6 +117,9 @@
|
|||
#define kMatchMinLen 2
|
||||
#define kMatchSpecLenStart (kMatchMinLen + kLenNumLowSymbols * 2 + kLenNumHighSymbols)
|
||||
|
||||
#define kMatchSpecLen_Error_Data (1 << 9)
|
||||
#define kMatchSpecLen_Error_Fail (kMatchSpecLen_Error_Data - 1)
|
||||
|
||||
/* External ASM code needs same CLzmaProb array layout. So don't change it. */
|
||||
|
||||
/* (probs_1664) is faster and better for code size at some platforms */
|
||||
|
@ -166,10 +172,12 @@
|
|||
|
||||
/*
|
||||
p->remainLen : shows status of LZMA decoder:
|
||||
< kMatchSpecLenStart : normal remain
|
||||
= kMatchSpecLenStart : finished
|
||||
= kMatchSpecLenStart + 1 : need init range coder
|
||||
= kMatchSpecLenStart + 2 : need init range coder and state
|
||||
< kMatchSpecLenStart : the number of bytes to be copied with (p->rep0) offset
|
||||
= kMatchSpecLenStart : the LZMA stream was finished with end mark
|
||||
= kMatchSpecLenStart + 1 : need init range coder
|
||||
= kMatchSpecLenStart + 2 : need init range coder and state
|
||||
= kMatchSpecLen_Error_Fail : Internal Code Failure
|
||||
= kMatchSpecLen_Error_Data + [0 ... 273] : LZMA Data Error
|
||||
*/
|
||||
|
||||
/* ---------- LZMA_DECODE_REAL ---------- */
|
||||
|
@ -188,23 +196,31 @@ In:
|
|||
{
|
||||
LzmaDec_TryDummy() was called before to exclude LITERAL and MATCH-REP cases.
|
||||
So first symbol can be only MATCH-NON-REP. And if that MATCH-NON-REP symbol
|
||||
is not END_OF_PAYALOAD_MARKER, then function returns error code.
|
||||
is not END_OF_PAYALOAD_MARKER, then the function doesn't write any byte to dictionary,
|
||||
the function returns SZ_OK, and the caller can use (p->remainLen) and (p->reps[0]) later.
|
||||
}
|
||||
|
||||
Processing:
|
||||
first LZMA symbol will be decoded in any case
|
||||
All checks for limits are at the end of main loop,
|
||||
It will decode new LZMA-symbols while (p->buf < bufLimit && dicPos < limit),
|
||||
The first LZMA symbol will be decoded in any case.
|
||||
All main checks for limits are at the end of main loop,
|
||||
It decodes additional LZMA-symbols while (p->buf < bufLimit && dicPos < limit),
|
||||
RangeCoder is still without last normalization when (p->buf < bufLimit) is being checked.
|
||||
But if (p->buf < bufLimit), the caller provided at least (LZMA_REQUIRED_INPUT_MAX + 1) bytes for
|
||||
next iteration before limit (bufLimit + LZMA_REQUIRED_INPUT_MAX),
|
||||
that is enough for worst case LZMA symbol with one additional RangeCoder normalization for one bit.
|
||||
So that function never reads bufLimit [LZMA_REQUIRED_INPUT_MAX] byte.
|
||||
|
||||
Out:
|
||||
RangeCoder is normalized
|
||||
Result:
|
||||
SZ_OK - OK
|
||||
SZ_ERROR_DATA - Error
|
||||
p->remainLen:
|
||||
< kMatchSpecLenStart : normal remain
|
||||
= kMatchSpecLenStart : finished
|
||||
p->remainLen:
|
||||
< kMatchSpecLenStart : the number of bytes to be copied with (p->reps[0]) offset
|
||||
= kMatchSpecLenStart : the LZMA stream was finished with end mark
|
||||
|
||||
SZ_ERROR_DATA - error, when the MATCH-Symbol refers out of dictionary
|
||||
p->remainLen : undefined
|
||||
p->reps[*] : undefined
|
||||
*/
|
||||
|
||||
|
||||
|
@ -316,11 +332,6 @@ int MY_FAST_CALL LZMA_DECODE_REAL(CLzmaDec *p, SizeT limit, const Byte *bufLimit
|
|||
else
|
||||
{
|
||||
UPDATE_1(prob);
|
||||
/*
|
||||
// that case was checked before with kBadRepCode
|
||||
if (checkDicSize == 0 && processedPos == 0)
|
||||
return SZ_ERROR_DATA;
|
||||
*/
|
||||
prob = probs + IsRepG0 + state;
|
||||
IF_BIT_0(prob)
|
||||
{
|
||||
|
@ -329,6 +340,13 @@ int MY_FAST_CALL LZMA_DECODE_REAL(CLzmaDec *p, SizeT limit, const Byte *bufLimit
|
|||
IF_BIT_0(prob)
|
||||
{
|
||||
UPDATE_0(prob);
|
||||
|
||||
// that case was checked before with kBadRepCode
|
||||
// if (checkDicSize == 0 && processedPos == 0) { len = kMatchSpecLen_Error_Data + 1; break; }
|
||||
// The caller doesn't allow (dicPos == limit) case here
|
||||
// so we don't need the following check:
|
||||
// if (dicPos == limit) { state = state < kNumLitStates ? 9 : 11; len = 1; break; }
|
||||
|
||||
dic[dicPos] = dic[dicPos - rep0 + (dicPos < rep0 ? dicBufSize : 0)];
|
||||
dicPos++;
|
||||
processedPos++;
|
||||
|
@ -518,8 +536,10 @@ int MY_FAST_CALL LZMA_DECODE_REAL(CLzmaDec *p, SizeT limit, const Byte *bufLimit
|
|||
state = (state < kNumStates + kNumLitStates) ? kNumLitStates : kNumLitStates + 3;
|
||||
if (distance >= (checkDicSize == 0 ? processedPos: checkDicSize))
|
||||
{
|
||||
p->dicPos = dicPos;
|
||||
return SZ_ERROR_DATA;
|
||||
len += kMatchSpecLen_Error_Data + kMatchMinLen;
|
||||
// len = kMatchSpecLen_Error_Data;
|
||||
// len += kMatchMinLen;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -532,8 +552,13 @@ int MY_FAST_CALL LZMA_DECODE_REAL(CLzmaDec *p, SizeT limit, const Byte *bufLimit
|
|||
|
||||
if ((rem = limit - dicPos) == 0)
|
||||
{
|
||||
p->dicPos = dicPos;
|
||||
return SZ_ERROR_DATA;
|
||||
/*
|
||||
We stop decoding and return SZ_OK, and we can resume decoding later.
|
||||
Any error conditions can be tested later in caller code.
|
||||
For more strict mode we can stop decoding with error
|
||||
// len += kMatchSpecLen_Error_Data;
|
||||
*/
|
||||
break;
|
||||
}
|
||||
|
||||
curLen = ((rem < len) ? (unsigned)rem : len);
|
||||
|
@ -572,7 +597,7 @@ int MY_FAST_CALL LZMA_DECODE_REAL(CLzmaDec *p, SizeT limit, const Byte *bufLimit
|
|||
p->buf = buf;
|
||||
p->range = range;
|
||||
p->code = code;
|
||||
p->remainLen = (UInt32)len;
|
||||
p->remainLen = (UInt32)len; // & (kMatchSpecLen_Error_Data - 1); // we can write real length for error matches too.
|
||||
p->dicPos = dicPos;
|
||||
p->processedPos = processedPos;
|
||||
p->reps[0] = rep0;
|
||||
|
@ -580,40 +605,61 @@ int MY_FAST_CALL LZMA_DECODE_REAL(CLzmaDec *p, SizeT limit, const Byte *bufLimit
|
|||
p->reps[2] = rep2;
|
||||
p->reps[3] = rep3;
|
||||
p->state = (UInt32)state;
|
||||
|
||||
if (len >= kMatchSpecLen_Error_Data)
|
||||
return SZ_ERROR_DATA;
|
||||
return SZ_OK;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
static void MY_FAST_CALL LzmaDec_WriteRem(CLzmaDec *p, SizeT limit)
|
||||
{
|
||||
if (p->remainLen != 0 && p->remainLen < kMatchSpecLenStart)
|
||||
unsigned len = (unsigned)p->remainLen;
|
||||
if (len == 0 /* || len >= kMatchSpecLenStart */)
|
||||
return;
|
||||
{
|
||||
Byte *dic = p->dic;
|
||||
SizeT dicPos = p->dicPos;
|
||||
SizeT dicBufSize = p->dicBufSize;
|
||||
unsigned len = (unsigned)p->remainLen;
|
||||
SizeT rep0 = p->reps[0]; /* we use SizeT to avoid the BUG of VC14 for AMD64 */
|
||||
SizeT rem = limit - dicPos;
|
||||
if (rem < len)
|
||||
len = (unsigned)(rem);
|
||||
Byte *dic;
|
||||
SizeT dicBufSize;
|
||||
SizeT rep0; /* we use SizeT to avoid the BUG of VC14 for AMD64 */
|
||||
{
|
||||
SizeT rem = limit - dicPos;
|
||||
if (rem < len)
|
||||
{
|
||||
len = (unsigned)(rem);
|
||||
if (len == 0)
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (p->checkDicSize == 0 && p->prop.dicSize - p->processedPos <= len)
|
||||
p->checkDicSize = p->prop.dicSize;
|
||||
|
||||
p->processedPos += (UInt32)len;
|
||||
p->remainLen -= (UInt32)len;
|
||||
while (len != 0)
|
||||
dic = p->dic;
|
||||
rep0 = p->reps[0];
|
||||
dicBufSize = p->dicBufSize;
|
||||
do
|
||||
{
|
||||
len--;
|
||||
dic[dicPos] = dic[dicPos - rep0 + (dicPos < rep0 ? dicBufSize : 0)];
|
||||
dicPos++;
|
||||
}
|
||||
while (--len);
|
||||
p->dicPos = dicPos;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
At staring of new stream we have one of the following symbols:
|
||||
- Literal - is allowed
|
||||
- Non-Rep-Match - is allowed only if it's end marker symbol
|
||||
- Rep-Match - is not allowed
|
||||
We use early check of (RangeCoder:Code) over kBadRepCode to simplify main decoding code
|
||||
*/
|
||||
|
||||
#define kRange0 0xFFFFFFFF
|
||||
#define kBound0 ((kRange0 >> kNumBitModelTotalBits) << (kNumBitModelTotalBits - 1))
|
||||
#define kBadRepCode (kBound0 + (((kRange0 - kBound0) >> kNumBitModelTotalBits) << (kNumBitModelTotalBits - 1)))
|
||||
|
@ -621,69 +667,77 @@ static void MY_FAST_CALL LzmaDec_WriteRem(CLzmaDec *p, SizeT limit)
|
|||
#error Stop_Compiling_Bad_LZMA_Check
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
LzmaDec_DecodeReal2():
|
||||
It calls LZMA_DECODE_REAL() and it adjusts limit according (p->checkDicSize).
|
||||
|
||||
We correct (p->checkDicSize) after LZMA_DECODE_REAL() and in LzmaDec_WriteRem(),
|
||||
and we support the following state of (p->checkDicSize):
|
||||
if (total_processed < p->prop.dicSize) then
|
||||
{
|
||||
(total_processed == p->processedPos)
|
||||
(p->checkDicSize == 0)
|
||||
}
|
||||
else
|
||||
(p->checkDicSize == p->prop.dicSize)
|
||||
*/
|
||||
|
||||
static int MY_FAST_CALL LzmaDec_DecodeReal2(CLzmaDec *p, SizeT limit, const Byte *bufLimit)
|
||||
{
|
||||
do
|
||||
if (p->checkDicSize == 0)
|
||||
{
|
||||
SizeT limit2 = limit;
|
||||
if (p->checkDicSize == 0)
|
||||
{
|
||||
UInt32 rem = p->prop.dicSize - p->processedPos;
|
||||
if (limit - p->dicPos > rem)
|
||||
limit2 = p->dicPos + rem;
|
||||
|
||||
if (p->processedPos == 0)
|
||||
if (p->code >= kBadRepCode)
|
||||
return SZ_ERROR_DATA;
|
||||
}
|
||||
|
||||
RINOK(LZMA_DECODE_REAL(p, limit2, bufLimit));
|
||||
|
||||
UInt32 rem = p->prop.dicSize - p->processedPos;
|
||||
if (limit - p->dicPos > rem)
|
||||
limit = p->dicPos + rem;
|
||||
}
|
||||
{
|
||||
int res = LZMA_DECODE_REAL(p, limit, bufLimit);
|
||||
if (p->checkDicSize == 0 && p->processedPos >= p->prop.dicSize)
|
||||
p->checkDicSize = p->prop.dicSize;
|
||||
|
||||
LzmaDec_WriteRem(p, limit);
|
||||
return res;
|
||||
}
|
||||
while (p->dicPos < limit && p->buf < bufLimit && p->remainLen < kMatchSpecLenStart);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
typedef enum
|
||||
{
|
||||
DUMMY_ERROR, /* unexpected end of input stream */
|
||||
DUMMY_INPUT_EOF, /* need more input data */
|
||||
DUMMY_LIT,
|
||||
DUMMY_MATCH,
|
||||
DUMMY_REP
|
||||
} ELzmaDummy;
|
||||
|
||||
static ELzmaDummy LzmaDec_TryDummy(const CLzmaDec *p, const Byte *buf, SizeT inSize)
|
||||
|
||||
#define IS_DUMMY_END_MARKER_POSSIBLE(dummyRes) ((dummyRes) == DUMMY_MATCH)
|
||||
|
||||
static ELzmaDummy LzmaDec_TryDummy(const CLzmaDec *p, const Byte *buf, const Byte **bufOut)
|
||||
{
|
||||
UInt32 range = p->range;
|
||||
UInt32 code = p->code;
|
||||
const Byte *bufLimit = buf + inSize;
|
||||
const Byte *bufLimit = *bufOut;
|
||||
const CLzmaProb *probs = GET_PROBS;
|
||||
unsigned state = (unsigned)p->state;
|
||||
ELzmaDummy res;
|
||||
|
||||
for (;;)
|
||||
{
|
||||
const CLzmaProb *prob;
|
||||
UInt32 bound;
|
||||
unsigned ttt;
|
||||
unsigned posState = CALC_POS_STATE(p->processedPos, (1 << p->prop.pb) - 1);
|
||||
unsigned posState = CALC_POS_STATE(p->processedPos, ((unsigned)1 << p->prop.pb) - 1);
|
||||
|
||||
prob = probs + IsMatch + COMBINED_PS_STATE;
|
||||
IF_BIT_0_CHECK(prob)
|
||||
{
|
||||
UPDATE_0_CHECK
|
||||
|
||||
/* if (bufLimit - buf >= 7) return DUMMY_LIT; */
|
||||
|
||||
prob = probs + Literal;
|
||||
if (p->checkDicSize != 0 || p->processedPos != 0)
|
||||
prob += ((UInt32)LZMA_LIT_SIZE *
|
||||
((((p->processedPos) & ((1 << (p->prop.lp)) - 1)) << p->prop.lc) +
|
||||
(p->dic[(p->dicPos == 0 ? p->dicBufSize : p->dicPos) - 1] >> (8 - p->prop.lc))));
|
||||
((((p->processedPos) & (((unsigned)1 << (p->prop.lp)) - 1)) << p->prop.lc) +
|
||||
((unsigned)p->dic[(p->dicPos == 0 ? p->dicBufSize : p->dicPos) - 1] >> (8 - p->prop.lc))));
|
||||
|
||||
if (state < kNumLitStates)
|
||||
{
|
||||
|
@ -735,8 +789,7 @@ static ELzmaDummy LzmaDec_TryDummy(const CLzmaDec *p, const Byte *buf, SizeT inS
|
|||
IF_BIT_0_CHECK(prob)
|
||||
{
|
||||
UPDATE_0_CHECK;
|
||||
NORMALIZE_CHECK;
|
||||
return DUMMY_REP;
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -812,8 +865,6 @@ static ELzmaDummy LzmaDec_TryDummy(const CLzmaDec *p, const Byte *buf, SizeT inS
|
|||
{
|
||||
unsigned numDirectBits = ((posSlot >> 1) - 1);
|
||||
|
||||
/* if (bufLimit - buf >= 8) return DUMMY_MATCH; */
|
||||
|
||||
if (posSlot < kEndPosModelIndex)
|
||||
{
|
||||
prob = probs + SpecPos + ((2 | (posSlot & 1)) << numDirectBits);
|
||||
|
@ -844,12 +895,15 @@ static ELzmaDummy LzmaDec_TryDummy(const CLzmaDec *p, const Byte *buf, SizeT inS
|
|||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
NORMALIZE_CHECK;
|
||||
|
||||
*bufOut = buf;
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
void LzmaDec_InitDicAndState(CLzmaDec *p, BoolInt initDic, BoolInt initState);
|
||||
void LzmaDec_InitDicAndState(CLzmaDec *p, BoolInt initDic, BoolInt initState)
|
||||
{
|
||||
p->remainLen = kMatchSpecLenStart + 1;
|
||||
|
@ -872,16 +926,41 @@ void LzmaDec_Init(CLzmaDec *p)
|
|||
}
|
||||
|
||||
|
||||
/*
|
||||
LZMA supports optional end_marker.
|
||||
So the decoder can lookahead for one additional LZMA-Symbol to check end_marker.
|
||||
That additional LZMA-Symbol can require up to LZMA_REQUIRED_INPUT_MAX bytes in input stream.
|
||||
When the decoder reaches dicLimit, it looks (finishMode) parameter:
|
||||
if (finishMode == LZMA_FINISH_ANY), the decoder doesn't lookahead
|
||||
if (finishMode != LZMA_FINISH_ANY), the decoder lookahead, if end_marker is possible for current position
|
||||
|
||||
When the decoder lookahead, and the lookahead symbol is not end_marker, we have two ways:
|
||||
1) Strict mode (default) : the decoder returns SZ_ERROR_DATA.
|
||||
2) The relaxed mode (alternative mode) : we could return SZ_OK, and the caller
|
||||
must check (status) value. The caller can show the error,
|
||||
if the end of stream is expected, and the (status) is noit
|
||||
LZMA_STATUS_FINISHED_WITH_MARK or LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK.
|
||||
*/
|
||||
|
||||
|
||||
#define RETURN__NOT_FINISHED__FOR_FINISH \
|
||||
*status = LZMA_STATUS_NOT_FINISHED; \
|
||||
return SZ_ERROR_DATA; // for strict mode
|
||||
// return SZ_OK; // for relaxed mode
|
||||
|
||||
|
||||
SRes LzmaDec_DecodeToDic(CLzmaDec *p, SizeT dicLimit, const Byte *src, SizeT *srcLen,
|
||||
ELzmaFinishMode finishMode, ELzmaStatus *status)
|
||||
{
|
||||
SizeT inSize = *srcLen;
|
||||
(*srcLen) = 0;
|
||||
|
||||
*status = LZMA_STATUS_NOT_SPECIFIED;
|
||||
|
||||
if (p->remainLen > kMatchSpecLenStart)
|
||||
{
|
||||
if (p->remainLen > kMatchSpecLenStart + 2)
|
||||
return p->remainLen == kMatchSpecLen_Error_Fail ? SZ_ERROR_FAIL : SZ_ERROR_DATA;
|
||||
|
||||
for (; inSize > 0 && p->tempBufSize < RC_INIT_SIZE; (*srcLen)++, inSize--)
|
||||
p->tempBuf[p->tempBufSize++] = *src++;
|
||||
if (p->tempBufSize != 0 && p->tempBuf[0] != 0)
|
||||
|
@ -896,6 +975,12 @@ SRes LzmaDec_DecodeToDic(CLzmaDec *p, SizeT dicLimit, const Byte *src, SizeT *sr
|
|||
| ((UInt32)p->tempBuf[2] << 16)
|
||||
| ((UInt32)p->tempBuf[3] << 8)
|
||||
| ((UInt32)p->tempBuf[4]);
|
||||
|
||||
if (p->checkDicSize == 0
|
||||
&& p->processedPos == 0
|
||||
&& p->code >= kBadRepCode)
|
||||
return SZ_ERROR_DATA;
|
||||
|
||||
p->range = 0xFFFFFFFF;
|
||||
p->tempBufSize = 0;
|
||||
|
||||
|
@ -913,10 +998,21 @@ SRes LzmaDec_DecodeToDic(CLzmaDec *p, SizeT dicLimit, const Byte *src, SizeT *sr
|
|||
p->remainLen = 0;
|
||||
}
|
||||
|
||||
LzmaDec_WriteRem(p, dicLimit);
|
||||
|
||||
while (p->remainLen != kMatchSpecLenStart)
|
||||
for (;;)
|
||||
{
|
||||
if (p->remainLen == kMatchSpecLenStart)
|
||||
{
|
||||
if (p->code != 0)
|
||||
return SZ_ERROR_DATA;
|
||||
*status = LZMA_STATUS_FINISHED_WITH_MARK;
|
||||
return SZ_OK;
|
||||
}
|
||||
|
||||
LzmaDec_WriteRem(p, dicLimit);
|
||||
|
||||
{
|
||||
// (p->remainLen == 0 || p->dicPos == dicLimit)
|
||||
|
||||
int checkEndMarkNow = 0;
|
||||
|
||||
if (p->dicPos >= dicLimit)
|
||||
|
@ -933,92 +1029,174 @@ SRes LzmaDec_DecodeToDic(CLzmaDec *p, SizeT dicLimit, const Byte *src, SizeT *sr
|
|||
}
|
||||
if (p->remainLen != 0)
|
||||
{
|
||||
*status = LZMA_STATUS_NOT_FINISHED;
|
||||
return SZ_ERROR_DATA;
|
||||
RETURN__NOT_FINISHED__FOR_FINISH;
|
||||
}
|
||||
checkEndMarkNow = 1;
|
||||
}
|
||||
|
||||
// (p->remainLen == 0)
|
||||
|
||||
if (p->tempBufSize == 0)
|
||||
{
|
||||
SizeT processed;
|
||||
const Byte *bufLimit;
|
||||
int dummyProcessed = -1;
|
||||
|
||||
if (inSize < LZMA_REQUIRED_INPUT_MAX || checkEndMarkNow)
|
||||
{
|
||||
int dummyRes = LzmaDec_TryDummy(p, src, inSize);
|
||||
if (dummyRes == DUMMY_ERROR)
|
||||
const Byte *bufOut = src + inSize;
|
||||
|
||||
ELzmaDummy dummyRes = LzmaDec_TryDummy(p, src, &bufOut);
|
||||
|
||||
if (dummyRes == DUMMY_INPUT_EOF)
|
||||
{
|
||||
memcpy(p->tempBuf, src, inSize);
|
||||
p->tempBufSize = (unsigned)inSize;
|
||||
size_t i;
|
||||
if (inSize >= LZMA_REQUIRED_INPUT_MAX)
|
||||
break;
|
||||
(*srcLen) += inSize;
|
||||
p->tempBufSize = (unsigned)inSize;
|
||||
for (i = 0; i < inSize; i++)
|
||||
p->tempBuf[i] = src[i];
|
||||
*status = LZMA_STATUS_NEEDS_MORE_INPUT;
|
||||
return SZ_OK;
|
||||
}
|
||||
if (checkEndMarkNow && dummyRes != DUMMY_MATCH)
|
||||
|
||||
dummyProcessed = (int)(bufOut - src);
|
||||
if ((unsigned)dummyProcessed > LZMA_REQUIRED_INPUT_MAX)
|
||||
break;
|
||||
|
||||
if (checkEndMarkNow && !IS_DUMMY_END_MARKER_POSSIBLE(dummyRes))
|
||||
{
|
||||
*status = LZMA_STATUS_NOT_FINISHED;
|
||||
return SZ_ERROR_DATA;
|
||||
unsigned i;
|
||||
(*srcLen) += (unsigned)dummyProcessed;
|
||||
p->tempBufSize = (unsigned)dummyProcessed;
|
||||
for (i = 0; i < (unsigned)dummyProcessed; i++)
|
||||
p->tempBuf[i] = src[i];
|
||||
// p->remainLen = kMatchSpecLen_Error_Data;
|
||||
RETURN__NOT_FINISHED__FOR_FINISH;
|
||||
}
|
||||
|
||||
bufLimit = src;
|
||||
// we will decode only one iteration
|
||||
}
|
||||
else
|
||||
bufLimit = src + inSize - LZMA_REQUIRED_INPUT_MAX;
|
||||
|
||||
p->buf = src;
|
||||
if (LzmaDec_DecodeReal2(p, dicLimit, bufLimit) != 0)
|
||||
return SZ_ERROR_DATA;
|
||||
processed = (SizeT)(p->buf - src);
|
||||
(*srcLen) += processed;
|
||||
src += processed;
|
||||
inSize -= processed;
|
||||
}
|
||||
else
|
||||
{
|
||||
unsigned rem = p->tempBufSize, lookAhead = 0;
|
||||
while (rem < LZMA_REQUIRED_INPUT_MAX && lookAhead < inSize)
|
||||
p->tempBuf[rem++] = src[lookAhead++];
|
||||
p->tempBufSize = rem;
|
||||
if (rem < LZMA_REQUIRED_INPUT_MAX || checkEndMarkNow)
|
||||
|
||||
{
|
||||
int dummyRes = LzmaDec_TryDummy(p, p->tempBuf, (SizeT)rem);
|
||||
if (dummyRes == DUMMY_ERROR)
|
||||
int res = LzmaDec_DecodeReal2(p, dicLimit, bufLimit);
|
||||
|
||||
SizeT processed = (SizeT)(p->buf - src);
|
||||
|
||||
if (dummyProcessed < 0)
|
||||
{
|
||||
(*srcLen) += (SizeT)lookAhead;
|
||||
*status = LZMA_STATUS_NEEDS_MORE_INPUT;
|
||||
return SZ_OK;
|
||||
if (processed > inSize)
|
||||
break;
|
||||
}
|
||||
if (checkEndMarkNow && dummyRes != DUMMY_MATCH)
|
||||
else if ((unsigned)dummyProcessed != processed)
|
||||
break;
|
||||
|
||||
src += processed;
|
||||
inSize -= processed;
|
||||
(*srcLen) += processed;
|
||||
|
||||
if (res != SZ_OK)
|
||||
{
|
||||
*status = LZMA_STATUS_NOT_FINISHED;
|
||||
p->remainLen = kMatchSpecLen_Error_Data;
|
||||
return SZ_ERROR_DATA;
|
||||
}
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
{
|
||||
// we have some data in (p->tempBuf)
|
||||
// in strict mode: tempBufSize is not enough for one Symbol decoding.
|
||||
// in relaxed mode: tempBufSize not larger than required for one Symbol decoding.
|
||||
|
||||
unsigned rem = p->tempBufSize;
|
||||
unsigned ahead = 0;
|
||||
int dummyProcessed = -1;
|
||||
|
||||
while (rem < LZMA_REQUIRED_INPUT_MAX && ahead < inSize)
|
||||
p->tempBuf[rem++] = src[ahead++];
|
||||
|
||||
// ahead - the size of new data copied from (src) to (p->tempBuf)
|
||||
// rem - the size of temp buffer including new data from (src)
|
||||
|
||||
if (rem < LZMA_REQUIRED_INPUT_MAX || checkEndMarkNow)
|
||||
{
|
||||
const Byte *bufOut = p->tempBuf + rem;
|
||||
|
||||
ELzmaDummy dummyRes = LzmaDec_TryDummy(p, p->tempBuf, &bufOut);
|
||||
|
||||
if (dummyRes == DUMMY_INPUT_EOF)
|
||||
{
|
||||
if (rem >= LZMA_REQUIRED_INPUT_MAX)
|
||||
break;
|
||||
p->tempBufSize = rem;
|
||||
(*srcLen) += (SizeT)ahead;
|
||||
*status = LZMA_STATUS_NEEDS_MORE_INPUT;
|
||||
return SZ_OK;
|
||||
}
|
||||
|
||||
dummyProcessed = (int)(bufOut - p->tempBuf);
|
||||
|
||||
if ((unsigned)dummyProcessed < p->tempBufSize)
|
||||
break;
|
||||
|
||||
if (checkEndMarkNow && !IS_DUMMY_END_MARKER_POSSIBLE(dummyRes))
|
||||
{
|
||||
(*srcLen) += (unsigned)dummyProcessed - p->tempBufSize;
|
||||
p->tempBufSize = (unsigned)dummyProcessed;
|
||||
// p->remainLen = kMatchSpecLen_Error_Data;
|
||||
RETURN__NOT_FINISHED__FOR_FINISH;
|
||||
}
|
||||
}
|
||||
|
||||
p->buf = p->tempBuf;
|
||||
if (LzmaDec_DecodeReal2(p, dicLimit, p->buf) != 0)
|
||||
return SZ_ERROR_DATA;
|
||||
|
||||
{
|
||||
unsigned kkk = (unsigned)(p->buf - p->tempBuf);
|
||||
if (rem < kkk)
|
||||
return SZ_ERROR_FAIL; /* some internal error */
|
||||
rem -= kkk;
|
||||
if (lookAhead < rem)
|
||||
return SZ_ERROR_FAIL; /* some internal error */
|
||||
lookAhead -= rem;
|
||||
// we decode one symbol from (p->tempBuf) here, so the (bufLimit) is equal to (p->buf)
|
||||
int res = LzmaDec_DecodeReal2(p, dicLimit, p->buf);
|
||||
|
||||
SizeT processed = (SizeT)(p->buf - p->tempBuf);
|
||||
rem = p->tempBufSize;
|
||||
|
||||
if (dummyProcessed < 0)
|
||||
{
|
||||
if (processed > LZMA_REQUIRED_INPUT_MAX)
|
||||
break;
|
||||
if (processed < rem)
|
||||
break;
|
||||
}
|
||||
else if ((unsigned)dummyProcessed != processed)
|
||||
break;
|
||||
|
||||
processed -= rem;
|
||||
|
||||
src += processed;
|
||||
inSize -= processed;
|
||||
(*srcLen) += processed;
|
||||
p->tempBufSize = 0;
|
||||
|
||||
if (res != SZ_OK)
|
||||
{
|
||||
p->remainLen = kMatchSpecLen_Error_Data;
|
||||
return SZ_ERROR_DATA;
|
||||
}
|
||||
}
|
||||
(*srcLen) += (SizeT)lookAhead;
|
||||
src += lookAhead;
|
||||
inSize -= (SizeT)lookAhead;
|
||||
p->tempBufSize = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (p->code != 0)
|
||||
return SZ_ERROR_DATA;
|
||||
*status = LZMA_STATUS_FINISHED_WITH_MARK;
|
||||
return SZ_OK;
|
||||
|
||||
/* Some unexpected error: internal error of code, memory corruption or hardware failure */
|
||||
p->remainLen = kMatchSpecLen_Error_Fail;
|
||||
return SZ_ERROR_FAIL;
|
||||
}
|
||||
|
||||
|
||||
|
||||
SRes LzmaDec_DecodeToBuf(CLzmaDec *p, Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen, ELzmaFinishMode finishMode, ELzmaStatus *status)
|
||||
{
|
||||
SizeT outSize = *destLen;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue