/* LzmaDec.c -- LZMA Decoder\r
-2016-05-16 : Igor Pavlov : Public domain */\r
+2018-02-28 : Igor Pavlov : Public domain */\r
\r
#include "Precomp.h"\r
\r
+/* #include "CpuArch.h" */\r
#include "LzmaDec.h"\r
\r
#ifndef EFIAPI\r
#define GET_BIT2(p, i, A0, A1) IF_BIT_0(p) \\r
{ UPDATE_0(p); i = (i + i); A0; } else \\r
{ UPDATE_1(p); i = (i + i) + 1; A1; }\r
-#define GET_BIT(p, i) GET_BIT2(p, i, ; , ;)\r
\r
-#define TREE_GET_BIT(probs, i) { GET_BIT((probs + i), i); }\r
+#define TREE_GET_BIT(probs, i) { GET_BIT2(probs + i, i, ;, ;); }\r
+\r
+#define REV_BIT(p, i, A0, A1) IF_BIT_0(p + i) \\r
+ { UPDATE_0(p + i); A0; } else \\r
+ { UPDATE_1(p + i); A1; }\r
+#define REV_BIT_VAR( p, i, m) REV_BIT(p, i, i += m; m += m, m += m; i += m; )\r
+#define REV_BIT_CONST(p, i, m) REV_BIT(p, i, i += m; , i += m * 2; )\r
+#define REV_BIT_LAST( p, i, m) REV_BIT(p, i, i -= m , ; )\r
+\r
#define TREE_DECODE(probs, limit, i) \\r
{ i = 1; do { TREE_GET_BIT(probs, i); } while (i < limit); i -= limit; }\r
\r
i -= 0x40; }\r
#endif\r
\r
-#define NORMAL_LITER_DEC GET_BIT(prob + symbol, symbol)\r
+#define NORMAL_LITER_DEC TREE_GET_BIT(prob, symbol)\r
#define MATCHED_LITER_DEC \\r
- matchByte <<= 1; \\r
- bit = (matchByte & offs); \\r
- probLit = prob + offs + bit + symbol; \\r
- GET_BIT2(probLit, symbol, offs &= ~bit, offs &= bit)\r
+ matchByte += matchByte; \\r
+ bit = offs; \\r
+ offs &= matchByte; \\r
+ probLit = prob + (offs + bit + symbol); \\r
+ GET_BIT2(probLit, symbol, offs ^= bit; , ;)\r
+\r
+\r
\r
#define NORMALIZE_CHECK if (range < kTopValue) { if (buf >= bufLimit) return DUMMY_ERROR; range <<= 8; code = (code << 8) | (*buf++); }\r
\r
{ i = 1; do { GET_BIT_CHECK(probs + i, i) } while (i < limit); i -= limit; }\r
\r
\r
+#define REV_BIT_CHECK(p, i, m) IF_BIT_0_CHECK(p + i) \\r
+ { UPDATE_0_CHECK; i += m; m += m; } else \\r
+ { UPDATE_1_CHECK; m += m; i += m; }\r
+\r
+\r
#define kNumPosBitsMax 4\r
#define kNumPosStatesMax (1 << kNumPosBitsMax)\r
\r
#define kLenNumLowBits 3\r
#define kLenNumLowSymbols (1 << kLenNumLowBits)\r
-#define kLenNumMidBits 3\r
-#define kLenNumMidSymbols (1 << kLenNumMidBits)\r
#define kLenNumHighBits 8\r
#define kLenNumHighSymbols (1 << kLenNumHighBits)\r
\r
-#define LenChoice 0\r
-#define LenChoice2 (LenChoice + 1)\r
-#define LenLow (LenChoice2 + 1)\r
-#define LenMid (LenLow + (kNumPosStatesMax << kLenNumLowBits))\r
-#define LenHigh (LenMid + (kNumPosStatesMax << kLenNumMidBits))\r
+#define LenLow 0\r
+#define LenHigh (LenLow + 2 * (kNumPosStatesMax << kLenNumLowBits))\r
#define kNumLenProbs (LenHigh + kLenNumHighSymbols)\r
\r
+#define LenChoice LenLow\r
+#define LenChoice2 (LenLow + (1 << kLenNumLowBits))\r
\r
#define kNumStates 12\r
+#define kNumStates2 16\r
#define kNumLitStates 7\r
\r
#define kStartPosModelIndex 4\r
#define kAlignTableSize (1 << kNumAlignBits)\r
\r
#define kMatchMinLen 2\r
-#define kMatchSpecLenStart (kMatchMinLen + kLenNumLowSymbols + kLenNumMidSymbols + kLenNumHighSymbols)\r
+#define kMatchSpecLenStart (kMatchMinLen + kLenNumLowSymbols * 2 + kLenNumHighSymbols)\r
\r
-#define IsMatch 0\r
-#define IsRep (IsMatch + (kNumStates << kNumPosBitsMax))\r
+/* External ASM code needs same CLzmaProb array layout. So don't change it. */\r
+\r
+/* (probs_1664) is faster and better for code size at some platforms */\r
+/*\r
+#ifdef MY_CPU_X86_OR_AMD64\r
+*/\r
+#define kStartOffset 1664\r
+#define GET_PROBS p->probs_1664\r
+/*\r
+#define GET_PROBS p->probs + kStartOffset\r
+#else\r
+#define kStartOffset 0\r
+#define GET_PROBS p->probs\r
+#endif\r
+*/\r
+\r
+#define SpecPos (-kStartOffset)\r
+#define IsRep0Long (SpecPos + kNumFullDistances)\r
+#define RepLenCoder (IsRep0Long + (kNumStates2 << kNumPosBitsMax))\r
+#define LenCoder (RepLenCoder + kNumLenProbs)\r
+#define IsMatch (LenCoder + kNumLenProbs)\r
+#define Align (IsMatch + (kNumStates2 << kNumPosBitsMax))\r
+#define IsRep (Align + kAlignTableSize)\r
#define IsRepG0 (IsRep + kNumStates)\r
#define IsRepG1 (IsRepG0 + kNumStates)\r
#define IsRepG2 (IsRepG1 + kNumStates)\r
-#define IsRep0Long (IsRepG2 + kNumStates)\r
-#define PosSlot (IsRep0Long + (kNumStates << kNumPosBitsMax))\r
-#define SpecPos (PosSlot + (kNumLenToPosStates << kNumPosSlotBits))\r
-#define Align (SpecPos + kNumFullDistances - kEndPosModelIndex)\r
-#define LenCoder (Align + kAlignTableSize)\r
-#define RepLenCoder (LenCoder + kNumLenProbs)\r
-#define Literal (RepLenCoder + kNumLenProbs)\r
-\r
-#define LZMA_BASE_SIZE 1846\r
-#define LZMA_LIT_SIZE 0x300\r
+#define PosSlot (IsRepG2 + kNumStates)\r
+#define Literal (PosSlot + (kNumLenToPosStates << kNumPosSlotBits))\r
+#define NUM_BASE_PROBS (Literal + kStartOffset)\r
\r
-#if Literal != LZMA_BASE_SIZE\r
-StopCompilingDueBUG\r
+#if Align != 0 && kStartOffset != 0\r
+ #error Stop_Compiling_Bad_LZMA_kAlign\r
#endif\r
\r
-#define LzmaProps_GetNumProbs(p) (Literal + ((UInt32)LZMA_LIT_SIZE << ((p)->lc + (p)->lp)))\r
+#if NUM_BASE_PROBS != 1984\r
+ #error Stop_Compiling_Bad_LZMA_PROBS\r
+#endif\r
+\r
+\r
+#define LZMA_LIT_SIZE 0x300\r
+\r
+#define LzmaProps_GetNumProbs(p) (NUM_BASE_PROBS + ((UInt32)LZMA_LIT_SIZE << ((p)->lc + (p)->lp)))\r
+\r
+\r
+#define CALC_POS_STATE(processedPos, pbMask) (((processedPos) & (pbMask)) << 4)\r
+#define COMBINED_PS_STATE (posState + state)\r
+#define GET_LEN_STATE (posState)\r
\r
#define LZMA_DIC_MIN (1 << 12)\r
\r
-/* First LZMA-symbol is always decoded.\r
-And it decodes new LZMA-symbols while (buf < bufLimit), but "buf" is without last normalization\r
+/*\r
+p->remainLen : shows status of LZMA decoder:\r
+ < kMatchSpecLenStart : normal remain\r
+ = kMatchSpecLenStart : finished\r
+ = kMatchSpecLenStart + 1 : need init range coder\r
+ = kMatchSpecLenStart + 2 : need init range coder and state\r
+*/\r
+\r
+/* ---------- LZMA_DECODE_REAL ---------- */\r
+/*\r
+LzmaDec_DecodeReal_3() can be implemented in external ASM file.\r
+3 - is the code compatibility version of that function for check at link time.\r
+*/\r
+\r
+#define LZMA_DECODE_REAL LzmaDec_DecodeReal_3\r
+\r
+/*\r
+LZMA_DECODE_REAL()\r
+In:\r
+ RangeCoder is normalized\r
+ if (p->dicPos == limit)\r
+ {\r
+ LzmaDec_TryDummy() was called before to exclude LITERAL and MATCH-REP cases.\r
+ So first symbol can be only MATCH-NON-REP. And if that MATCH-NON-REP symbol\r
+ is not END_OF_PAYALOAD_MARKER, then function returns error code.\r
+ }\r
+\r
+Processing:\r
+ first LZMA symbol will be decoded in any case\r
+ All checks for limits are at the end of main loop,\r
+ It will decode new LZMA-symbols while (p->buf < bufLimit && dicPos < limit),\r
+ RangeCoder is still without last normalization when (p->buf < bufLimit) is being checked.\r
+\r
Out:\r
+ RangeCoder is normalized\r
Result:\r
SZ_OK - OK\r
SZ_ERROR_DATA - Error\r
p->remainLen:\r
< kMatchSpecLenStart : normal remain\r
= kMatchSpecLenStart : finished\r
- = kMatchSpecLenStart + 1 : Flush marker (unused now)\r
- = kMatchSpecLenStart + 2 : State Init Marker (unused now)\r
*/\r
\r
-static int MY_FAST_CALL LzmaDec_DecodeReal(CLzmaDec *p, SizeT limit, const Byte *bufLimit)\r
-{\r
- CLzmaProb *probs = p->probs;\r
\r
- unsigned state = p->state;\r
+#ifdef _LZMA_DEC_OPT\r
+\r
+int MY_FAST_CALL LZMA_DECODE_REAL(CLzmaDec *p, SizeT limit, const Byte *bufLimit);\r
+\r
+#else\r
+\r
+static\r
+int MY_FAST_CALL LZMA_DECODE_REAL(CLzmaDec *p, SizeT limit, const Byte *bufLimit)\r
+{\r
+ CLzmaProb *probs = GET_PROBS;\r
+ unsigned state = (unsigned)p->state;\r
UInt32 rep0 = p->reps[0], rep1 = p->reps[1], rep2 = p->reps[2], rep3 = p->reps[3];\r
unsigned pbMask = ((unsigned)1 << (p->prop.pb)) - 1;\r
- unsigned lpMask = ((unsigned)1 << (p->prop.lp)) - 1;\r
unsigned lc = p->prop.lc;\r
+ unsigned lpMask = ((unsigned)0x100 << p->prop.lp) - ((unsigned)0x100 >> lc);\r
\r
Byte *dic = p->dic;\r
SizeT dicBufSize = p->dicBufSize;\r
CLzmaProb *prob;\r
UInt32 bound;\r
unsigned ttt;\r
- unsigned posState = processedPos & pbMask;\r
+ unsigned posState = CALC_POS_STATE(processedPos, pbMask);\r
\r
- prob = probs + IsMatch + (state << kNumPosBitsMax) + posState;\r
+ prob = probs + IsMatch + COMBINED_PS_STATE;\r
IF_BIT_0(prob)\r
{\r
unsigned symbol;\r
UPDATE_0(prob);\r
prob = probs + Literal;\r
if (processedPos != 0 || checkDicSize != 0)\r
- prob += ((UInt32)LZMA_LIT_SIZE * (((processedPos & lpMask) << lc) +\r
- (dic[(dicPos == 0 ? dicBufSize : dicPos) - 1] >> (8 - lc))));\r
+ prob += (UInt32)3 * ((((processedPos << 8) + dic[(dicPos == 0 ? dicBufSize : dicPos) - 1]) & lpMask) << lc);\r
processedPos++;\r
\r
if (state < kNumLitStates)\r
else\r
{\r
UPDATE_1(prob);\r
+ /*\r
+ // that case was checked before with kBadRepCode\r
if (checkDicSize == 0 && processedPos == 0)\r
return SZ_ERROR_DATA;\r
+ */\r
prob = probs + IsRepG0 + state;\r
IF_BIT_0(prob)\r
{\r
UPDATE_0(prob);\r
- prob = probs + IsRep0Long + (state << kNumPosBitsMax) + posState;\r
+ prob = probs + IsRep0Long + COMBINED_PS_STATE;\r
IF_BIT_0(prob)\r
{\r
UPDATE_0(prob);\r
IF_BIT_0(probLen)\r
{\r
UPDATE_0(probLen);\r
- probLen = prob + LenLow + (posState << kLenNumLowBits);\r
+ probLen = prob + LenLow + GET_LEN_STATE;\r
offset = 0;\r
lim = (1 << kLenNumLowBits);\r
}\r
IF_BIT_0(probLen)\r
{\r
UPDATE_0(probLen);\r
- probLen = prob + LenMid + (posState << kLenNumMidBits);\r
+ probLen = prob + LenLow + GET_LEN_STATE + (1 << kLenNumLowBits);\r
offset = kLenNumLowSymbols;\r
- lim = (1 << kLenNumMidBits);\r
+ lim = (1 << kLenNumLowBits);\r
}\r
else\r
{\r
UPDATE_1(probLen);\r
probLen = prob + LenHigh;\r
- offset = kLenNumLowSymbols + kLenNumMidSymbols;\r
+ offset = kLenNumLowSymbols * 2;\r
lim = (1 << kLenNumHighBits);\r
}\r
}\r
IF_BIT_0(probLen)\r
{\r
UPDATE_0(probLen);\r
- probLen = prob + LenLow + (posState << kLenNumLowBits);\r
+ probLen = prob + LenLow + GET_LEN_STATE;\r
len = 1;\r
TREE_GET_BIT(probLen, len);\r
TREE_GET_BIT(probLen, len);\r
IF_BIT_0(probLen)\r
{\r
UPDATE_0(probLen);\r
- probLen = prob + LenMid + (posState << kLenNumMidBits);\r
+ probLen = prob + LenLow + GET_LEN_STATE + (1 << kLenNumLowBits);\r
len = 1;\r
TREE_GET_BIT(probLen, len);\r
TREE_GET_BIT(probLen, len);\r
UPDATE_1(probLen);\r
probLen = prob + LenHigh;\r
TREE_DECODE(probLen, (1 << kLenNumHighBits), len);\r
- len += kLenNumLowSymbols + kLenNumMidSymbols;\r
+ len += kLenNumLowSymbols * 2;\r
}\r
}\r
}\r
if (posSlot < kEndPosModelIndex)\r
{\r
distance <<= numDirectBits;\r
- prob = probs + SpecPos + distance - posSlot - 1;\r
+ prob = probs + SpecPos;\r
{\r
- UInt32 mask = 1;\r
- unsigned i = 1;\r
+ UInt32 m = 1;\r
+ distance++;\r
do\r
{\r
- GET_BIT2(prob + i, i, ; , distance |= mask);\r
- mask <<= 1;\r
+ REV_BIT_VAR(prob, distance, m);\r
}\r
- while (--numDirectBits != 0);\r
+ while (--numDirectBits);\r
+ distance -= m;\r
}\r
}\r
else\r
}\r
*/\r
}\r
- while (--numDirectBits != 0);\r
+ while (--numDirectBits);\r
prob = probs + Align;\r
distance <<= kNumAlignBits;\r
{\r
unsigned i = 1;\r
- GET_BIT2(prob + i, i, ; , distance |= 1);\r
- GET_BIT2(prob + i, i, ; , distance |= 2);\r
- GET_BIT2(prob + i, i, ; , distance |= 4);\r
- GET_BIT2(prob + i, i, ; , distance |= 8);\r
+ REV_BIT_CONST(prob, i, 1);\r
+ REV_BIT_CONST(prob, i, 2);\r
+ REV_BIT_CONST(prob, i, 4);\r
+ REV_BIT_LAST (prob, i, 8);\r
+ distance |= i;\r
}\r
if (distance == (UInt32)0xFFFFFFFF)\r
{\r
- len += kMatchSpecLenStart;\r
+ len = kMatchSpecLenStart;\r
state -= kNumStates;\r
break;\r
}\r
rep2 = rep1;\r
rep1 = rep0;\r
rep0 = distance + 1;\r
- if (checkDicSize == 0)\r
- {\r
- if (distance >= processedPos)\r
- {\r
- p->dicPos = dicPos;\r
- return SZ_ERROR_DATA;\r
- }\r
- }\r
- else if (distance >= checkDicSize)\r
+ state = (state < kNumStates + kNumLitStates) ? kNumLitStates : kNumLitStates + 3;\r
+ if (distance >= (checkDicSize == 0 ? processedPos: checkDicSize))\r
{\r
p->dicPos = dicPos;\r
return SZ_ERROR_DATA;\r
}\r
- state = (state < kNumStates + kNumLitStates) ? kNumLitStates : kNumLitStates + 3;\r
}\r
\r
len += kMatchMinLen;\r
\r
return SZ_OK;\r
}\r
+#endif\r
\r
static void MY_FAST_CALL LzmaDec_WriteRem(CLzmaDec *p, SizeT limit)\r
{\r
Byte *dic = p->dic;\r
SizeT dicPos = p->dicPos;\r
SizeT dicBufSize = p->dicBufSize;\r
- unsigned len = p->remainLen;\r
+ unsigned len = (unsigned)p->remainLen;\r
SizeT rep0 = p->reps[0]; /* we use SizeT to avoid the BUG of VC14 for AMD64 */\r
SizeT rem = limit - dicPos;\r
if (rem < len)\r
}\r
}\r
\r
+\r
+#define kRange0 0xFFFFFFFF\r
+#define kBound0 ((kRange0 >> kNumBitModelTotalBits) << (kNumBitModelTotalBits - 1))\r
+#define kBadRepCode (kBound0 + (((kRange0 - kBound0) >> kNumBitModelTotalBits) << (kNumBitModelTotalBits - 1)))\r
+#if kBadRepCode != (0xC0000000 - 0x400)\r
+ #error Stop_Compiling_Bad_LZMA_Check\r
+#endif\r
+\r
static int MY_FAST_CALL LzmaDec_DecodeReal2(CLzmaDec *p, SizeT limit, const Byte *bufLimit)\r
{\r
do\r
UInt32 rem = p->prop.dicSize - p->processedPos;\r
if (limit - p->dicPos > rem)\r
limit2 = p->dicPos + rem;\r
+\r
+ if (p->processedPos == 0)\r
+ if (p->code >= kBadRepCode)\r
+ return SZ_ERROR_DATA;\r
}\r
- \r
- RINOK(LzmaDec_DecodeReal(p, limit2, bufLimit));\r
+\r
+ RINOK(LZMA_DECODE_REAL(p, limit2, bufLimit));\r
\r
if (p->checkDicSize == 0 && p->processedPos >= p->prop.dicSize)\r
p->checkDicSize = p->prop.dicSize;\r
}\r
while (p->dicPos < limit && p->buf < bufLimit && p->remainLen < kMatchSpecLenStart);\r
\r
- if (p->remainLen > kMatchSpecLenStart)\r
- p->remainLen = kMatchSpecLenStart;\r
-\r
return 0;\r
}\r
\r
UInt32 range = p->range;\r
UInt32 code = p->code;\r
const Byte *bufLimit = buf + inSize;\r
- const CLzmaProb *probs = p->probs;\r
- unsigned state = p->state;\r
+ const CLzmaProb *probs = GET_PROBS;\r
+ unsigned state = (unsigned)p->state;\r
ELzmaDummy res;\r
\r
{\r
const CLzmaProb *prob;\r
UInt32 bound;\r
unsigned ttt;\r
- unsigned posState = (p->processedPos) & ((1 << p->prop.pb) - 1);\r
+ unsigned posState = CALC_POS_STATE(p->processedPos, (1 << p->prop.pb) - 1);\r
\r
- prob = probs + IsMatch + (state << kNumPosBitsMax) + posState;\r
+ prob = probs + IsMatch + COMBINED_PS_STATE;\r
IF_BIT_0_CHECK(prob)\r
{\r
UPDATE_0_CHECK\r
{\r
unsigned bit;\r
const CLzmaProb *probLit;\r
- matchByte <<= 1;\r
- bit = (matchByte & offs);\r
- probLit = prob + offs + bit + symbol;\r
- GET_BIT2_CHECK(probLit, symbol, offs &= ~bit, offs &= bit)\r
+ matchByte += matchByte;\r
+ bit = offs;\r
+ offs &= matchByte;\r
+ probLit = prob + (offs + bit + symbol);\r
+ GET_BIT2_CHECK(probLit, symbol, offs ^= bit; , ; )\r
}\r
while (symbol < 0x100);\r
}\r
IF_BIT_0_CHECK(prob)\r
{\r
UPDATE_0_CHECK;\r
- prob = probs + IsRep0Long + (state << kNumPosBitsMax) + posState;\r
+ prob = probs + IsRep0Long + COMBINED_PS_STATE;\r
IF_BIT_0_CHECK(prob)\r
{\r
UPDATE_0_CHECK;\r
IF_BIT_0_CHECK(probLen)\r
{\r
UPDATE_0_CHECK;\r
- probLen = prob + LenLow + (posState << kLenNumLowBits);\r
+ probLen = prob + LenLow + GET_LEN_STATE;\r
offset = 0;\r
limit = 1 << kLenNumLowBits;\r
}\r
IF_BIT_0_CHECK(probLen)\r
{\r
UPDATE_0_CHECK;\r
- probLen = prob + LenMid + (posState << kLenNumMidBits);\r
+ probLen = prob + LenLow + GET_LEN_STATE + (1 << kLenNumLowBits);\r
offset = kLenNumLowSymbols;\r
- limit = 1 << kLenNumMidBits;\r
+ limit = 1 << kLenNumLowBits;\r
}\r
else\r
{\r
UPDATE_1_CHECK;\r
probLen = prob + LenHigh;\r
- offset = kLenNumLowSymbols + kLenNumMidSymbols;\r
+ offset = kLenNumLowSymbols * 2;\r
limit = 1 << kLenNumHighBits;\r
}\r
}\r
{\r
unsigned posSlot;\r
prob = probs + PosSlot +\r
- ((len < kNumLenToPosStates ? len : kNumLenToPosStates - 1) <<\r
+ ((len < kNumLenToPosStates - 1 ? len : kNumLenToPosStates - 1) <<\r
kNumPosSlotBits);\r
TREE_DECODE_CHECK(prob, 1 << kNumPosSlotBits, posSlot);\r
if (posSlot >= kStartPosModelIndex)\r
\r
if (posSlot < kEndPosModelIndex)\r
{\r
- prob = probs + SpecPos + ((2 | (posSlot & 1)) << numDirectBits) - posSlot - 1;\r
+ prob = probs + SpecPos + ((2 | (posSlot & 1)) << numDirectBits);\r
}\r
else\r
{\r
code -= range & (((code - range) >> 31) - 1);\r
/* if (code >= range) code -= range; */\r
}\r
- while (--numDirectBits != 0);\r
+ while (--numDirectBits);\r
prob = probs + Align;\r
numDirectBits = kNumAlignBits;\r
}\r
{\r
unsigned i = 1;\r
+ unsigned m = 1;\r
do\r
{\r
- GET_BIT_CHECK(prob + i, i);\r
+ REV_BIT_CHECK(prob, i, m);\r
}\r
- while (--numDirectBits != 0);\r
+ while (--numDirectBits);\r
}\r
}\r
}\r
\r
void LzmaDec_InitDicAndState(CLzmaDec *p, Bool initDic, Bool initState)\r
{\r
- p->needFlush = 1;\r
- p->remainLen = 0;\r
+ p->remainLen = kMatchSpecLenStart + 1;\r
p->tempBufSize = 0;\r
\r
if (initDic)\r
{\r
p->processedPos = 0;\r
p->checkDicSize = 0;\r
- p->needInitState = 1;\r
+ p->remainLen = kMatchSpecLenStart + 2;\r
}\r
if (initState)\r
- p->needInitState = 1;\r
+ p->remainLen = kMatchSpecLenStart + 2;\r
}\r
\r
void LzmaDec_Init(CLzmaDec *p)\r
LzmaDec_InitDicAndState(p, True, True);\r
}\r
\r
-static void LzmaDec_InitStateReal(CLzmaDec *p)\r
-{\r
- SizeT numProbs = LzmaProps_GetNumProbs(&p->prop);\r
- SizeT i;\r
- CLzmaProb *probs = p->probs;\r
- for (i = 0; i < numProbs; i++)\r
- probs[i] = kBitModelTotal >> 1;\r
- p->reps[0] = p->reps[1] = p->reps[2] = p->reps[3] = 1;\r
- p->state = 0;\r
- p->needInitState = 0;\r
-}\r
\r
SRes LzmaDec_DecodeToDic(CLzmaDec *p, SizeT dicLimit, const Byte *src, SizeT *srcLen,\r
ELzmaFinishMode finishMode, ELzmaStatus *status)\r
{\r
SizeT inSize = *srcLen;\r
(*srcLen) = 0;\r
- LzmaDec_WriteRem(p, dicLimit);\r
\r
*status = LZMA_STATUS_NOT_SPECIFIED;\r
\r
- while (p->remainLen != kMatchSpecLenStart)\r
+ if (p->remainLen > kMatchSpecLenStart)\r
{\r
- int checkEndMarkNow;\r
+ for (; inSize > 0 && p->tempBufSize < RC_INIT_SIZE; (*srcLen)++, inSize--)\r
+ p->tempBuf[p->tempBufSize++] = *src++;\r
+ if (p->tempBufSize != 0 && p->tempBuf[0] != 0)\r
+ return SZ_ERROR_DATA;\r
+ if (p->tempBufSize < RC_INIT_SIZE)\r
+ {\r
+ *status = LZMA_STATUS_NEEDS_MORE_INPUT;\r
+ return SZ_OK;\r
+ }\r
+ p->code =\r
+ ((UInt32)p->tempBuf[1] << 24)\r
+ | ((UInt32)p->tempBuf[2] << 16)\r
+ | ((UInt32)p->tempBuf[3] << 8)\r
+ | ((UInt32)p->tempBuf[4]);\r
+ p->range = 0xFFFFFFFF;\r
+ p->tempBufSize = 0;\r
+\r
+ if (p->remainLen > kMatchSpecLenStart + 1)\r
+ {\r
+ SizeT numProbs = LzmaProps_GetNumProbs(&p->prop);\r
+ SizeT i;\r
+ CLzmaProb *probs = p->probs;\r
+ for (i = 0; i < numProbs; i++)\r
+ probs[i] = kBitModelTotal >> 1;\r
+ p->reps[0] = p->reps[1] = p->reps[2] = p->reps[3] = 1;\r
+ p->state = 0;\r
+ }\r
\r
- if (p->needFlush)\r
- {\r
- for (; inSize > 0 && p->tempBufSize < RC_INIT_SIZE; (*srcLen)++, inSize--)\r
- p->tempBuf[p->tempBufSize++] = *src++;\r
- if (p->tempBufSize < RC_INIT_SIZE)\r
- {\r
- *status = LZMA_STATUS_NEEDS_MORE_INPUT;\r
- return SZ_OK;\r
- }\r
- if (p->tempBuf[0] != 0)\r
- return SZ_ERROR_DATA;\r
- p->code =\r
- ((UInt32)p->tempBuf[1] << 24)\r
- | ((UInt32)p->tempBuf[2] << 16)\r
- | ((UInt32)p->tempBuf[3] << 8)\r
- | ((UInt32)p->tempBuf[4]);\r
- p->range = 0xFFFFFFFF;\r
- p->needFlush = 0;\r
- p->tempBufSize = 0;\r
- }\r
+ p->remainLen = 0;\r
+ }\r
+\r
+ LzmaDec_WriteRem(p, dicLimit);\r
+\r
+ while (p->remainLen != kMatchSpecLenStart)\r
+ {\r
+ int checkEndMarkNow = 0;\r
\r
- checkEndMarkNow = 0;\r
if (p->dicPos >= dicLimit)\r
{\r
if (p->remainLen == 0 && p->code == 0)\r
checkEndMarkNow = 1;\r
}\r
\r
- if (p->needInitState)\r
- LzmaDec_InitStateReal(p);\r
- \r
if (p->tempBufSize == 0)\r
{\r
SizeT processed;\r
p->tempBufSize = 0;\r
}\r
}\r
- if (p->code == 0)\r
- *status = LZMA_STATUS_FINISHED_WITH_MARK;\r
- return (p->code == 0) ? SZ_OK : SZ_ERROR_DATA;\r
+ \r
+ if (p->code != 0)\r
+ return SZ_ERROR_DATA;\r
+ *status = LZMA_STATUS_FINISHED_WITH_MARK;\r
+ return SZ_OK;\r
}\r
\r
+\r
SRes LzmaDec_DecodeToBuf(CLzmaDec *p, Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen, ELzmaFinishMode finishMode, ELzmaStatus *status)\r
{\r
SizeT outSize = *destLen;\r
}\r
}\r
\r
-void LzmaDec_FreeProbs(CLzmaDec *p, ISzAlloc *alloc)\r
+void LzmaDec_FreeProbs(CLzmaDec *p, ISzAllocPtr alloc)\r
{\r
- alloc->Free(alloc, p->probs);\r
+ ISzAlloc_Free(alloc, p->probs);\r
p->probs = NULL;\r
}\r
\r
-static void LzmaDec_FreeDict(CLzmaDec *p, ISzAlloc *alloc)\r
+static void LzmaDec_FreeDict(CLzmaDec *p, ISzAllocPtr alloc)\r
{\r
- alloc->Free(alloc, p->dic);\r
+ ISzAlloc_Free(alloc, p->dic);\r
p->dic = NULL;\r
}\r
\r
-void LzmaDec_Free(CLzmaDec *p, ISzAlloc *alloc)\r
+void LzmaDec_Free(CLzmaDec *p, ISzAllocPtr alloc)\r
{\r
LzmaDec_FreeProbs(p, alloc);\r
LzmaDec_FreeDict(p, alloc);\r
if (d >= (9 * 5 * 5))\r
return SZ_ERROR_UNSUPPORTED;\r
\r
- p->lc = d % 9;\r
+ p->lc = (Byte)(d % 9);\r
d /= 9;\r
- p->pb = d / 5;\r
- p->lp = d % 5;\r
+ p->pb = (Byte)(d / 5);\r
+ p->lp = (Byte)(d % 5);\r
\r
return SZ_OK;\r
}\r
\r
-static SRes LzmaDec_AllocateProbs2(CLzmaDec *p, const CLzmaProps *propNew, ISzAlloc *alloc)\r
+static SRes LzmaDec_AllocateProbs2(CLzmaDec *p, const CLzmaProps *propNew, ISzAllocPtr alloc)\r
{\r
UInt32 numProbs = LzmaProps_GetNumProbs(propNew);\r
if (!p->probs || numProbs != p->numProbs)\r
{\r
LzmaDec_FreeProbs(p, alloc);\r
- p->probs = (CLzmaProb *)alloc->Alloc(alloc, numProbs * sizeof(CLzmaProb));\r
- p->numProbs = numProbs;\r
+ p->probs = (CLzmaProb *)ISzAlloc_Alloc(alloc, numProbs * sizeof(CLzmaProb));\r
if (!p->probs)\r
return SZ_ERROR_MEM;\r
+ p->probs_1664 = p->probs + 1664;\r
+ p->numProbs = numProbs;\r
}\r
return SZ_OK;\r
}\r
\r
-SRes LzmaDec_AllocateProbs(CLzmaDec *p, const Byte *props, unsigned propsSize, ISzAlloc *alloc)\r
+SRes LzmaDec_AllocateProbs(CLzmaDec *p, const Byte *props, unsigned propsSize, ISzAllocPtr alloc)\r
{\r
CLzmaProps propNew;\r
RINOK(LzmaProps_Decode(&propNew, props, propsSize));\r
return SZ_OK;\r
}\r
\r
-SRes LzmaDec_Allocate(CLzmaDec *p, const Byte *props, unsigned propsSize, ISzAlloc *alloc)\r
+SRes LzmaDec_Allocate(CLzmaDec *p, const Byte *props, unsigned propsSize, ISzAllocPtr alloc)\r
{\r
CLzmaProps propNew;\r
SizeT dicBufSize;\r
if (!p->dic || dicBufSize != p->dicBufSize)\r
{\r
LzmaDec_FreeDict(p, alloc);\r
- p->dic = (Byte *)alloc->Alloc(alloc, dicBufSize);\r
+ p->dic = (Byte *)ISzAlloc_Alloc(alloc, dicBufSize);\r
if (!p->dic)\r
{\r
LzmaDec_FreeProbs(p, alloc);\r
\r
SRes LzmaDecode(Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen,\r
const Byte *propData, unsigned propSize, ELzmaFinishMode finishMode,\r
- ELzmaStatus *status, ISzAlloc *alloc)\r
+ ELzmaStatus *status, ISzAllocPtr alloc)\r
{\r
CLzmaDec p;\r
SRes res;\r