/* 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
#include <string.h>\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
/* LzmaEnc.c -- LZMA Encoder\r
-2016-05-16 : Igor Pavlov : Public domain */\r
+2018-04-29 : Igor Pavlov : Public domain */\r
\r
#include "Precomp.h"\r
\r
static unsigned g_STAT_OFFSET = 0;\r
#endif\r
\r
-#define kMaxHistorySize ((UInt32)3 << 29)\r
-/* #define kMaxHistorySize ((UInt32)7 << 29) */\r
-\r
-#define kBlockSizeMax ((1 << LZMA_NUM_BLOCK_SIZE_BITS) - 1)\r
-\r
-#define kBlockSize (9 << 10)\r
-#define kUnpackBlockSize (1 << 18)\r
-#define kMatchArraySize (1 << 21)\r
-#define kMatchRecordMaxSize ((LZMA_MATCH_LEN_MAX * 2 + 3) * LZMA_MATCH_LEN_MAX)\r
-\r
-#define kNumMaxDirectBits (31)\r
+#define kLzmaMaxHistorySize ((UInt32)3 << 29)\r
+/* #define kLzmaMaxHistorySize ((UInt32)7 << 29) */\r
\r
#define kNumTopBits 24\r
#define kTopValue ((UInt32)1 << kNumTopBits)\r
if (level < 0) level = 5;\r
p->level = level;\r
\r
- if (p->dictSize == 0) p->dictSize = (level <= 5 ? (1 << (level * 2 + 14)) : (level == 6 ? (1 << 25) : (1 << 26)));\r
+ if (p->dictSize == 0) p->dictSize = (level <= 5 ? (1 << (level * 2 + 14)) : (level <= 7 ? (1 << 25) : (1 << 26)));\r
if (p->dictSize > p->reduceSize)\r
{\r
unsigned i;\r
+ UInt32 reduceSize = (UInt32)p->reduceSize;\r
for (i = 11; i <= 30; i++)\r
{\r
- if ((UInt32)p->reduceSize <= ((UInt32)2 << i)) { p->dictSize = ((UInt32)2 << i); break; }\r
- if ((UInt32)p->reduceSize <= ((UInt32)3 << i)) { p->dictSize = ((UInt32)3 << i); break; }\r
+ if (reduceSize <= ((UInt32)2 << i)) { p->dictSize = ((UInt32)2 << i); break; }\r
+ if (reduceSize <= ((UInt32)3 << i)) { p->dictSize = ((UInt32)3 << i); break; }\r
}\r
}\r
\r
\r
#define BSR2_RET(pos, res) { unsigned long zz; _BitScanReverse(&zz, (pos)); res = (zz + zz) + ((pos >> (zz - 1)) & 1); }\r
\r
-static UInt32 GetPosSlot1(UInt32 pos)\r
+static unsigned GetPosSlot1(UInt32 pos)\r
{\r
- UInt32 res;\r
+ unsigned res;\r
BSR2_RET(pos, res);\r
return res;\r
}\r
\r
/* we can use ((limit - pos) >> 31) only if (pos < ((UInt32)1 << 31)) */\r
/*\r
-#define BSR2_RET(pos, res) { UInt32 zz = 6 + ((kNumLogBits - 1) & \\r
+#define BSR2_RET(pos, res) { unsigned zz = 6 + ((kNumLogBits - 1) & \\r
(0 - (((((UInt32)1 << (kNumLogBits + 6)) - 1) - pos) >> 31))); \\r
res = p->g_FastPos[pos >> zz] + (zz * 2); }\r
*/\r
\r
/*\r
-#define BSR2_RET(pos, res) { UInt32 zz = 6 + ((kNumLogBits - 1) & \\r
+#define BSR2_RET(pos, res) { unsigned zz = 6 + ((kNumLogBits - 1) & \\r
(0 - (((((UInt32)1 << (kNumLogBits)) - 1) - (pos >> 6)) >> 31))); \\r
res = p->g_FastPos[pos >> zz] + (zz * 2); }\r
*/\r
\r
-#define BSR2_RET(pos, res) { UInt32 zz = (pos < (1 << (kNumLogBits + 6))) ? 6 : 6 + kNumLogBits - 1; \\r
+#define BSR2_RET(pos, res) { unsigned zz = (pos < (1 << (kNumLogBits + 6))) ? 6 : 6 + kNumLogBits - 1; \\r
res = p->g_FastPos[pos >> zz] + (zz * 2); }\r
\r
/*\r
\r
#define GetPosSlot1(pos) p->g_FastPos[pos]\r
#define GetPosSlot2(pos, res) { BSR2_RET(pos, res); }\r
-#define GetPosSlot(pos, res) { if (pos < kNumFullDistances) res = p->g_FastPos[pos]; else BSR2_RET(pos, res); }\r
+#define GetPosSlot(pos, res) { if (pos < kNumFullDistances) res = p->g_FastPos[pos & (kNumFullDistances - 1)]; else BSR2_RET(pos, res); }\r
\r
#endif\r
\r
\r
#define LZMA_NUM_REPS 4\r
\r
-typedef unsigned CState;\r
+typedef UInt16 CState;\r
+typedef UInt16 CExtra;\r
\r
typedef struct\r
{\r
UInt32 price;\r
-\r
CState state;\r
- int prev1IsChar;\r
- int prev2;\r
-\r
- UInt32 posPrev2;\r
- UInt32 backPrev2;\r
-\r
- UInt32 posPrev;\r
- UInt32 backPrev;\r
- UInt32 backs[LZMA_NUM_REPS];\r
+ CExtra extra;\r
+ // 0 : normal\r
+ // 1 : LIT : MATCH\r
+ // > 1 : MATCH (extra-1) : LIT : REP0 (len)\r
+ UInt32 len;\r
+ UInt32 dist;\r
+ UInt32 reps[LZMA_NUM_REPS];\r
} COptimal;\r
\r
+\r
#define kNumOpts (1 << 12)\r
+#define kPackReserve (1 + kNumOpts * 2)\r
\r
#define kNumLenToPosStates 4\r
#define kNumPosSlotBits 6\r
#define kDicLogSizeMax 32\r
#define kDistTableSizeMax (kDicLogSizeMax * 2)\r
\r
-\r
#define kNumAlignBits 4\r
#define kAlignTableSize (1 << kNumAlignBits)\r
#define kAlignMask (kAlignTableSize - 1)\r
\r
#define kStartPosModelIndex 4\r
#define kEndPosModelIndex 14\r
-#define kNumPosModels (kEndPosModelIndex - kStartPosModelIndex)\r
-\r
#define kNumFullDistances (1 << (kEndPosModelIndex >> 1))\r
\r
+typedef\r
#ifdef _LZMA_PROB32\r
-#define CLzmaProb UInt32\r
+ UInt32\r
#else\r
-#define CLzmaProb UInt16\r
+ UInt16\r
#endif\r
+ CLzmaProb;\r
\r
#define LZMA_PB_MAX 4\r
#define LZMA_LC_MAX 8\r
\r
#define LZMA_NUM_PB_STATES_MAX (1 << LZMA_PB_MAX)\r
\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 kLenNumSymbolsTotal (kLenNumLowSymbols + kLenNumMidSymbols + kLenNumHighSymbols)\r
+#define kLenNumSymbolsTotal (kLenNumLowSymbols * 2 + kLenNumHighSymbols)\r
\r
#define LZMA_MATCH_LEN_MIN 2\r
#define LZMA_MATCH_LEN_MAX (LZMA_MATCH_LEN_MIN + kLenNumSymbolsTotal - 1)\r
\r
typedef struct\r
{\r
- CLzmaProb choice;\r
- CLzmaProb choice2;\r
- CLzmaProb low[LZMA_NUM_PB_STATES_MAX << kLenNumLowBits];\r
- CLzmaProb mid[LZMA_NUM_PB_STATES_MAX << kLenNumMidBits];\r
+ CLzmaProb low[LZMA_NUM_PB_STATES_MAX << (kLenNumLowBits + 1)];\r
CLzmaProb high[kLenNumHighSymbols];\r
} CLenEnc;\r
\r
\r
typedef struct\r
{\r
- CLenEnc p;\r
- UInt32 tableSize;\r
+ unsigned tableSize;\r
+ unsigned counters[LZMA_NUM_PB_STATES_MAX];\r
UInt32 prices[LZMA_NUM_PB_STATES_MAX][kLenNumSymbolsTotal];\r
- UInt32 counters[LZMA_NUM_PB_STATES_MAX];\r
} CLenPriceEnc;\r
\r
\r
typedef struct\r
{\r
UInt32 range;\r
- Byte cache;\r
+ unsigned cache;\r
UInt64 low;\r
UInt64 cacheSize;\r
Byte *buf;\r
{\r
CLzmaProb *litProbs;\r
\r
- UInt32 state;\r
+ unsigned state;\r
UInt32 reps[LZMA_NUM_REPS];\r
\r
- CLzmaProb isMatch[kNumStates][LZMA_NUM_PB_STATES_MAX];\r
+ CLzmaProb posAlignEncoder[1 << kNumAlignBits];\r
CLzmaProb isRep[kNumStates];\r
CLzmaProb isRepG0[kNumStates];\r
CLzmaProb isRepG1[kNumStates];\r
CLzmaProb isRepG2[kNumStates];\r
+ CLzmaProb isMatch[kNumStates][LZMA_NUM_PB_STATES_MAX];\r
CLzmaProb isRep0Long[kNumStates][LZMA_NUM_PB_STATES_MAX];\r
\r
CLzmaProb posSlotEncoder[kNumLenToPosStates][1 << kNumPosSlotBits];\r
- CLzmaProb posEncoders[kNumFullDistances - kEndPosModelIndex];\r
- CLzmaProb posAlignEncoder[1 << kNumAlignBits];\r
+ CLzmaProb posEncoders[kNumFullDistances];\r
\r
- CLenPriceEnc lenEnc;\r
- CLenPriceEnc repLenEnc;\r
+ CLenEnc lenProbs;\r
+ CLenEnc repLenProbs;\r
+\r
} CSaveState;\r
\r
\r
+typedef UInt32 CProbPrice;\r
+\r
+\r
typedef struct\r
{\r
void *matchFinderObj;\r
IMatchFinder matchFinder;\r
\r
- UInt32 optimumEndIndex;\r
- UInt32 optimumCurrentIndex;\r
+ unsigned optCur;\r
+ unsigned optEnd;\r
\r
- UInt32 longestMatchLength;\r
- UInt32 numPairs;\r
+ unsigned longestMatchLen;\r
+ unsigned numPairs;\r
UInt32 numAvail;\r
\r
- UInt32 numFastBytes;\r
- UInt32 additionalOffset;\r
+ unsigned state;\r
+ unsigned numFastBytes;\r
+ unsigned additionalOffset;\r
UInt32 reps[LZMA_NUM_REPS];\r
- UInt32 state;\r
+ unsigned lpMask, pbMask;\r
+ CLzmaProb *litProbs;\r
+ CRangeEnc rc;\r
+\r
+ UInt32 backRes;\r
\r
unsigned lc, lp, pb;\r
- unsigned lpMask, pbMask;\r
unsigned lclp;\r
\r
- CLzmaProb *litProbs;\r
-\r
Bool fastMode;\r
Bool writeEndMark;\r
Bool finished;\r
\r
UInt64 nowPos64;\r
\r
- UInt32 matchPriceCount;\r
- UInt32 alignPriceCount;\r
+ unsigned matchPriceCount;\r
+ unsigned alignPriceCount;\r
\r
- UInt32 distTableSize;\r
+ unsigned distTableSize;\r
\r
UInt32 dictSize;\r
SRes result;\r
\r
- CRangeEnc rc;\r
-\r
#ifndef _7ZIP_ST\r
Bool mtMode;\r
+ // begin of CMatchFinderMt is used in LZ thread\r
CMatchFinderMt matchFinderMt;\r
+ // end of CMatchFinderMt is used in BT and HASH threads\r
#endif\r
\r
CMatchFinder matchFinderBase;\r
Byte pad[128];\r
#endif\r
\r
- COptimal opt[kNumOpts];\r
- \r
- #ifndef LZMA_LOG_BSR\r
- Byte g_FastPos[1 << kNumLogBits];\r
- #endif\r
+ // LZ thread\r
+ CProbPrice ProbPrices[kBitModelTotal >> kNumMoveReducingBits];\r
\r
- UInt32 ProbPrices[kBitModelTotal >> kNumMoveReducingBits];\r
UInt32 matches[LZMA_MATCH_LEN_MAX * 2 + 2 + 1];\r
\r
+ UInt32 alignPrices[kAlignTableSize];\r
UInt32 posSlotPrices[kNumLenToPosStates][kDistTableSizeMax];\r
UInt32 distancesPrices[kNumLenToPosStates][kNumFullDistances];\r
- UInt32 alignPrices[kAlignTableSize];\r
\r
- CLzmaProb isMatch[kNumStates][LZMA_NUM_PB_STATES_MAX];\r
+ CLzmaProb posAlignEncoder[1 << kNumAlignBits];\r
CLzmaProb isRep[kNumStates];\r
CLzmaProb isRepG0[kNumStates];\r
CLzmaProb isRepG1[kNumStates];\r
CLzmaProb isRepG2[kNumStates];\r
+ CLzmaProb isMatch[kNumStates][LZMA_NUM_PB_STATES_MAX];\r
CLzmaProb isRep0Long[kNumStates][LZMA_NUM_PB_STATES_MAX];\r
-\r
CLzmaProb posSlotEncoder[kNumLenToPosStates][1 << kNumPosSlotBits];\r
- CLzmaProb posEncoders[kNumFullDistances - kEndPosModelIndex];\r
- CLzmaProb posAlignEncoder[1 << kNumAlignBits];\r
+ CLzmaProb posEncoders[kNumFullDistances];\r
\r
+ CLenEnc lenProbs;\r
+ CLenEnc repLenProbs;\r
+\r
+ #ifndef LZMA_LOG_BSR\r
+ Byte g_FastPos[1 << kNumLogBits];\r
+ #endif\r
+\r
CLenPriceEnc lenEnc;\r
CLenPriceEnc repLenEnc;\r
\r
+ COptimal opt[kNumOpts];\r
+\r
CSaveState saveState;\r
\r
#ifndef _7ZIP_ST\r
} CLzmaEnc;\r
\r
\r
+\r
+#define COPY_ARR(dest, src, arr) memcpy(dest->arr, src->arr, sizeof(src->arr));\r
+\r
void LzmaEnc_SaveState(CLzmaEncHandle pp)\r
{\r
CLzmaEnc *p = (CLzmaEnc *)pp;\r
CSaveState *dest = &p->saveState;\r
- int i;\r
- dest->lenEnc = p->lenEnc;\r
- dest->repLenEnc = p->repLenEnc;\r
+ \r
dest->state = p->state;\r
+ \r
+ dest->lenProbs = p->lenProbs;\r
+ dest->repLenProbs = p->repLenProbs;\r
+\r
+ COPY_ARR(dest, p, reps);\r
+\r
+ COPY_ARR(dest, p, posAlignEncoder);\r
+ COPY_ARR(dest, p, isRep);\r
+ COPY_ARR(dest, p, isRepG0);\r
+ COPY_ARR(dest, p, isRepG1);\r
+ COPY_ARR(dest, p, isRepG2);\r
+ COPY_ARR(dest, p, isMatch);\r
+ COPY_ARR(dest, p, isRep0Long);\r
+ COPY_ARR(dest, p, posSlotEncoder);\r
+ COPY_ARR(dest, p, posEncoders);\r
\r
- for (i = 0; i < kNumStates; i++)\r
- {\r
- memcpy(dest->isMatch[i], p->isMatch[i], sizeof(p->isMatch[i]));\r
- memcpy(dest->isRep0Long[i], p->isRep0Long[i], sizeof(p->isRep0Long[i]));\r
- }\r
- for (i = 0; i < kNumLenToPosStates; i++)\r
- memcpy(dest->posSlotEncoder[i], p->posSlotEncoder[i], sizeof(p->posSlotEncoder[i]));\r
- memcpy(dest->isRep, p->isRep, sizeof(p->isRep));\r
- memcpy(dest->isRepG0, p->isRepG0, sizeof(p->isRepG0));\r
- memcpy(dest->isRepG1, p->isRepG1, sizeof(p->isRepG1));\r
- memcpy(dest->isRepG2, p->isRepG2, sizeof(p->isRepG2));\r
- memcpy(dest->posEncoders, p->posEncoders, sizeof(p->posEncoders));\r
- memcpy(dest->posAlignEncoder, p->posAlignEncoder, sizeof(p->posAlignEncoder));\r
- memcpy(dest->reps, p->reps, sizeof(p->reps));\r
memcpy(dest->litProbs, p->litProbs, ((UInt32)0x300 << p->lclp) * sizeof(CLzmaProb));\r
}\r
\r
+\r
void LzmaEnc_RestoreState(CLzmaEncHandle pp)\r
{\r
CLzmaEnc *dest = (CLzmaEnc *)pp;\r
const CSaveState *p = &dest->saveState;\r
- int i;\r
- dest->lenEnc = p->lenEnc;\r
- dest->repLenEnc = p->repLenEnc;\r
+\r
dest->state = p->state;\r
\r
- for (i = 0; i < kNumStates; i++)\r
- {\r
- memcpy(dest->isMatch[i], p->isMatch[i], sizeof(p->isMatch[i]));\r
- memcpy(dest->isRep0Long[i], p->isRep0Long[i], sizeof(p->isRep0Long[i]));\r
- }\r
- for (i = 0; i < kNumLenToPosStates; i++)\r
- memcpy(dest->posSlotEncoder[i], p->posSlotEncoder[i], sizeof(p->posSlotEncoder[i]));\r
- memcpy(dest->isRep, p->isRep, sizeof(p->isRep));\r
- memcpy(dest->isRepG0, p->isRepG0, sizeof(p->isRepG0));\r
- memcpy(dest->isRepG1, p->isRepG1, sizeof(p->isRepG1));\r
- memcpy(dest->isRepG2, p->isRepG2, sizeof(p->isRepG2));\r
- memcpy(dest->posEncoders, p->posEncoders, sizeof(p->posEncoders));\r
- memcpy(dest->posAlignEncoder, p->posAlignEncoder, sizeof(p->posAlignEncoder));\r
- memcpy(dest->reps, p->reps, sizeof(p->reps));\r
+ dest->lenProbs = p->lenProbs;\r
+ dest->repLenProbs = p->repLenProbs;\r
+ \r
+ COPY_ARR(dest, p, reps);\r
+ \r
+ COPY_ARR(dest, p, posAlignEncoder);\r
+ COPY_ARR(dest, p, isRep);\r
+ COPY_ARR(dest, p, isRepG0);\r
+ COPY_ARR(dest, p, isRepG1);\r
+ COPY_ARR(dest, p, isRepG2);\r
+ COPY_ARR(dest, p, isMatch);\r
+ COPY_ARR(dest, p, isRep0Long);\r
+ COPY_ARR(dest, p, posSlotEncoder);\r
+ COPY_ARR(dest, p, posEncoders);\r
+\r
memcpy(dest->litProbs, p->litProbs, ((UInt32)0x300 << dest->lclp) * sizeof(CLzmaProb));\r
}\r
\r
+\r
+\r
SRes LzmaEnc_SetProps(CLzmaEncHandle pp, const CLzmaEncProps *props2)\r
{\r
CLzmaEnc *p = (CLzmaEnc *)pp;\r
|| props.lp > LZMA_LP_MAX\r
|| props.pb > LZMA_PB_MAX\r
|| props.dictSize > ((UInt64)1 << kDicLogSizeMaxCompress)\r
- || props.dictSize > kMaxHistorySize)\r
+ || props.dictSize > kLzmaMaxHistorySize)\r
return SZ_ERROR_PARAM;\r
\r
p->dictSize = props.dictSize;\r
p->fastMode = (props.algo == 0);\r
p->matchFinderBase.btMode = (Byte)(props.btMode ? 1 : 0);\r
{\r
- UInt32 numHashBytes = 4;\r
+ unsigned numHashBytes = 4;\r
if (props.btMode)\r
{\r
if (props.numHashBytes < 2)\r
return SZ_OK;\r
}\r
\r
-static const int kLiteralNextStates[kNumStates] = {0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 4, 5};\r
-static const int kMatchNextStates[kNumStates] = {7, 7, 7, 7, 7, 7, 7, 10, 10, 10, 10, 10};\r
-static const int kRepNextStates[kNumStates] = {8, 8, 8, 8, 8, 8, 8, 11, 11, 11, 11, 11};\r
-static const int kShortRepNextStates[kNumStates]= {9, 9, 9, 9, 9, 9, 9, 11, 11, 11, 11, 11};\r
\r
-#define IsCharState(s) ((s) < 7)\r
+void LzmaEnc_SetDataSize(CLzmaEncHandle pp, UInt64 expectedDataSiize)\r
+{\r
+ CLzmaEnc *p = (CLzmaEnc *)pp;\r
+ p->matchFinderBase.expectedDataSize = expectedDataSiize;\r
+}\r
+\r
\r
+#define kState_Start 0\r
+#define kState_LitAfterMatch 4\r
+#define kState_LitAfterRep 5\r
+#define kState_MatchAfterLit 7\r
+#define kState_RepAfterLit 8\r
+\r
+static const Byte kLiteralNextStates[kNumStates] = {0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 4, 5};\r
+static const Byte kMatchNextStates[kNumStates] = {7, 7, 7, 7, 7, 7, 7, 10, 10, 10, 10, 10};\r
+static const Byte kRepNextStates[kNumStates] = {8, 8, 8, 8, 8, 8, 8, 11, 11, 11, 11, 11};\r
+static const Byte kShortRepNextStates[kNumStates]= {9, 9, 9, 9, 9, 9, 9, 11, 11, 11, 11, 11};\r
+\r
+#define IsLitState(s) ((s) < 7)\r
+#define GetLenToPosState2(len) (((len) < kNumLenToPosStates - 1) ? (len) : kNumLenToPosStates - 1)\r
#define GetLenToPosState(len) (((len) < kNumLenToPosStates + 1) ? (len) - 2 : kNumLenToPosStates - 1)\r
\r
#define kInfinityPrice (1 << 30)\r
p->bufBase = NULL;\r
}\r
\r
-#define RangeEnc_GetProcessed(p) ((p)->processed + ((p)->buf - (p)->bufBase) + (p)->cacheSize)\r
+#define RangeEnc_GetProcessed(p) ((p)->processed + ((p)->buf - (p)->bufBase) + (p)->cacheSize)\r
+#define RangeEnc_GetProcessed_sizet(p) ((size_t)(p)->processed + ((p)->buf - (p)->bufBase) + (size_t)(p)->cacheSize)\r
\r
#define RC_BUF_SIZE (1 << 16)\r
-static int RangeEnc_Alloc(CRangeEnc *p, ISzAlloc *alloc)\r
+\r
+static int RangeEnc_Alloc(CRangeEnc *p, ISzAllocPtr alloc)\r
{\r
if (!p->bufBase)\r
{\r
- p->bufBase = (Byte *)alloc->Alloc(alloc, RC_BUF_SIZE);\r
+ p->bufBase = (Byte *)ISzAlloc_Alloc(alloc, RC_BUF_SIZE);\r
if (!p->bufBase)\r
return 0;\r
p->bufLim = p->bufBase + RC_BUF_SIZE;\r
return 1;\r
}\r
\r
-static void RangeEnc_Free(CRangeEnc *p, ISzAlloc *alloc)\r
+static void RangeEnc_Free(CRangeEnc *p, ISzAllocPtr alloc)\r
{\r
- alloc->Free(alloc, p->bufBase);\r
+ ISzAlloc_Free(alloc, p->bufBase);\r
p->bufBase = 0;\r
}\r
\r
static void RangeEnc_Init(CRangeEnc *p)\r
{\r
/* Stream.Init(); */\r
- p->low = 0;\r
p->range = 0xFFFFFFFF;\r
- p->cacheSize = 1;\r
p->cache = 0;\r
+ p->low = 0;\r
+ p->cacheSize = 0;\r
\r
p->buf = p->bufBase;\r
\r
p->res = SZ_OK;\r
}\r
\r
-static void RangeEnc_FlushStream(CRangeEnc *p)\r
+MY_NO_INLINE static void RangeEnc_FlushStream(CRangeEnc *p)\r
{\r
size_t num;\r
if (p->res != SZ_OK)\r
return;\r
num = p->buf - p->bufBase;\r
- if (num != p->outStream->Write(p->outStream, p->bufBase, num))\r
+ if (num != ISeqOutStream_Write(p->outStream, p->bufBase, num))\r
p->res = SZ_ERROR_WRITE;\r
p->processed += num;\r
p->buf = p->bufBase;\r
}\r
\r
-static void MY_FAST_CALL RangeEnc_ShiftLow(CRangeEnc *p)\r
+MY_NO_INLINE static void MY_FAST_CALL RangeEnc_ShiftLow(CRangeEnc *p)\r
{\r
- if ((UInt32)p->low < (UInt32)0xFF000000 || (unsigned)(p->low >> 32) != 0)\r
+ UInt32 low = (UInt32)p->low;\r
+ unsigned high = (unsigned)(p->low >> 32);\r
+ p->low = (UInt32)(low << 8);\r
+ if (low < (UInt32)0xFF000000 || high != 0)\r
{\r
- Byte temp = p->cache;\r
- do\r
{\r
Byte *buf = p->buf;\r
- *buf++ = (Byte)(temp + (Byte)(p->low >> 32));\r
+ *buf++ = (Byte)(p->cache + high);\r
+ p->cache = (unsigned)(low >> 24);\r
p->buf = buf;\r
if (buf == p->bufLim)\r
RangeEnc_FlushStream(p);\r
- temp = 0xFF;\r
+ if (p->cacheSize == 0)\r
+ return;\r
+ }\r
+ high += 0xFF;\r
+ for (;;)\r
+ {\r
+ Byte *buf = p->buf;\r
+ *buf++ = (Byte)(high);\r
+ p->buf = buf;\r
+ if (buf == p->bufLim)\r
+ RangeEnc_FlushStream(p);\r
+ if (--p->cacheSize == 0)\r
+ return;\r
}\r
- while (--p->cacheSize != 0);\r
- p->cache = (Byte)((UInt32)p->low >> 24);\r
}\r
p->cacheSize++;\r
- p->low = (UInt32)p->low << 8;\r
}\r
\r
static void RangeEnc_FlushData(CRangeEnc *p)\r
RangeEnc_ShiftLow(p);\r
}\r
\r
-static void RangeEnc_EncodeDirectBits(CRangeEnc *p, UInt32 value, unsigned numBits)\r
-{\r
- do\r
- {\r
- p->range >>= 1;\r
- p->low += p->range & (0 - ((value >> --numBits) & 1));\r
- if (p->range < kTopValue)\r
- {\r
- p->range <<= 8;\r
- RangeEnc_ShiftLow(p);\r
- }\r
- }\r
- while (numBits != 0);\r
-}\r
+#define RC_NORM(p) if (range < kTopValue) { range <<= 8; RangeEnc_ShiftLow(p); }\r
\r
-static void RangeEnc_EncodeBit(CRangeEnc *p, CLzmaProb *prob, UInt32 symbol)\r
-{\r
- UInt32 ttt = *prob;\r
- UInt32 newBound = (p->range >> kNumBitModelTotalBits) * ttt;\r
- if (symbol == 0)\r
- {\r
- p->range = newBound;\r
- ttt += (kBitModelTotal - ttt) >> kNumMoveBits;\r
- }\r
- else\r
- {\r
- p->low += newBound;\r
- p->range -= newBound;\r
- ttt -= ttt >> kNumMoveBits;\r
+#define RC_BIT_PRE(p, prob) \\r
+ ttt = *(prob); \\r
+ newBound = (range >> kNumBitModelTotalBits) * ttt;\r
+\r
+// #define _LZMA_ENC_USE_BRANCH\r
+\r
+#ifdef _LZMA_ENC_USE_BRANCH\r
+\r
+#define RC_BIT(p, prob, symbol) { \\r
+ RC_BIT_PRE(p, prob) \\r
+ if (symbol == 0) { range = newBound; ttt += (kBitModelTotal - ttt) >> kNumMoveBits; } \\r
+ else { (p)->low += newBound; range -= newBound; ttt -= ttt >> kNumMoveBits; } \\r
+ *(prob) = (CLzmaProb)ttt; \\r
+ RC_NORM(p) \\r
}\r
- *prob = (CLzmaProb)ttt;\r
- if (p->range < kTopValue)\r
- {\r
- p->range <<= 8;\r
- RangeEnc_ShiftLow(p);\r
+\r
+#else\r
+\r
+#define RC_BIT(p, prob, symbol) { \\r
+ UInt32 mask; \\r
+ RC_BIT_PRE(p, prob) \\r
+ mask = 0 - (UInt32)symbol; \\r
+ range &= mask; \\r
+ mask &= newBound; \\r
+ range -= mask; \\r
+ (p)->low += mask; \\r
+ mask = (UInt32)symbol - 1; \\r
+ range += newBound & mask; \\r
+ mask &= (kBitModelTotal - ((1 << kNumMoveBits) - 1)); \\r
+ mask += ((1 << kNumMoveBits) - 1); \\r
+ ttt += (Int32)(mask - ttt) >> kNumMoveBits; \\r
+ *(prob) = (CLzmaProb)ttt; \\r
+ RC_NORM(p) \\r
}\r
+\r
+#endif\r
+\r
+\r
+\r
+\r
+#define RC_BIT_0_BASE(p, prob) \\r
+ range = newBound; *(prob) = (CLzmaProb)(ttt + ((kBitModelTotal - ttt) >> kNumMoveBits));\r
+\r
+#define RC_BIT_1_BASE(p, prob) \\r
+ range -= newBound; (p)->low += newBound; *(prob) = (CLzmaProb)(ttt - (ttt >> kNumMoveBits)); \\r
+\r
+#define RC_BIT_0(p, prob) \\r
+ RC_BIT_0_BASE(p, prob) \\r
+ RC_NORM(p)\r
+\r
+#define RC_BIT_1(p, prob) \\r
+ RC_BIT_1_BASE(p, prob) \\r
+ RC_NORM(p)\r
+\r
+static void RangeEnc_EncodeBit_0(CRangeEnc *p, CLzmaProb *prob)\r
+{\r
+ UInt32 range, ttt, newBound;\r
+ range = p->range;\r
+ RC_BIT_PRE(p, prob)\r
+ RC_BIT_0(p, prob)\r
+ p->range = range;\r
}\r
\r
static void LitEnc_Encode(CRangeEnc *p, CLzmaProb *probs, UInt32 symbol)\r
{\r
+ UInt32 range = p->range;\r
symbol |= 0x100;\r
do\r
{\r
- RangeEnc_EncodeBit(p, probs + (symbol >> 8), (symbol >> 7) & 1);\r
+ UInt32 ttt, newBound;\r
+ // RangeEnc_EncodeBit(p, probs + (symbol >> 8), (symbol >> 7) & 1);\r
+ CLzmaProb *prob = probs + (symbol >> 8);\r
+ UInt32 bit = (symbol >> 7) & 1;\r
symbol <<= 1;\r
+ RC_BIT(p, prob, bit);\r
}\r
while (symbol < 0x10000);\r
+ p->range = range;\r
}\r
\r
static void LitEnc_EncodeMatched(CRangeEnc *p, CLzmaProb *probs, UInt32 symbol, UInt32 matchByte)\r
{\r
+ UInt32 range = p->range;\r
UInt32 offs = 0x100;\r
symbol |= 0x100;\r
do\r
{\r
+ UInt32 ttt, newBound;\r
+ CLzmaProb *prob;\r
+ UInt32 bit;\r
matchByte <<= 1;\r
- RangeEnc_EncodeBit(p, probs + (offs + (matchByte & offs) + (symbol >> 8)), (symbol >> 7) & 1);\r
+ // RangeEnc_EncodeBit(p, probs + (offs + (matchByte & offs) + (symbol >> 8)), (symbol >> 7) & 1);\r
+ prob = probs + (offs + (matchByte & offs) + (symbol >> 8));\r
+ bit = (symbol >> 7) & 1;\r
symbol <<= 1;\r
offs &= ~(matchByte ^ symbol);\r
+ RC_BIT(p, prob, bit);\r
}\r
while (symbol < 0x10000);\r
+ p->range = range;\r
}\r
\r
-static void LzmaEnc_InitPriceTables(UInt32 *ProbPrices)\r
+\r
+\r
+static void LzmaEnc_InitPriceTables(CProbPrice *ProbPrices)\r
{\r
UInt32 i;\r
- for (i = (1 << kNumMoveReducingBits) / 2; i < kBitModelTotal; i += (1 << kNumMoveReducingBits))\r
+ for (i = 0; i < (kBitModelTotal >> kNumMoveReducingBits); i++)\r
{\r
- const int kCyclesBits = kNumBitPriceShiftBits;\r
- UInt32 w = i;\r
- UInt32 bitCount = 0;\r
- int j;\r
+ const unsigned kCyclesBits = kNumBitPriceShiftBits;\r
+ UInt32 w = (i << kNumMoveReducingBits) + (1 << (kNumMoveReducingBits - 1));\r
+ unsigned bitCount = 0;\r
+ unsigned j;\r
for (j = 0; j < kCyclesBits; j++)\r
{\r
w = w * w;\r
bitCount++;\r
}\r
}\r
- ProbPrices[i >> kNumMoveReducingBits] = ((kNumBitModelTotalBits << kCyclesBits) - 15 - bitCount);\r
+ ProbPrices[i] = (CProbPrice)((kNumBitModelTotalBits << kCyclesBits) - 15 - bitCount);\r
+ // printf("\n%3d: %5d", i, ProbPrices[i]);\r
}\r
}\r
\r
\r
#define GET_PRICE(prob, symbol) \\r
- p->ProbPrices[((prob) ^ (((-(int)(symbol))) & (kBitModelTotal - 1))) >> kNumMoveReducingBits];\r
+ p->ProbPrices[((prob) ^ (unsigned)(((-(int)(symbol))) & (kBitModelTotal - 1))) >> kNumMoveReducingBits];\r
\r
#define GET_PRICEa(prob, symbol) \\r
- ProbPrices[((prob) ^ ((-((int)(symbol))) & (kBitModelTotal - 1))) >> kNumMoveReducingBits];\r
+ ProbPrices[((prob) ^ (unsigned)((-((int)(symbol))) & (kBitModelTotal - 1))) >> kNumMoveReducingBits];\r
\r
#define GET_PRICE_0(prob) p->ProbPrices[(prob) >> kNumMoveReducingBits]\r
#define GET_PRICE_1(prob) p->ProbPrices[((prob) ^ (kBitModelTotal - 1)) >> kNumMoveReducingBits]\r
\r
-#define GET_PRICE_0a(prob) ProbPrices[(prob) >> kNumMoveReducingBits]\r
-#define GET_PRICE_1a(prob) ProbPrices[((prob) ^ (kBitModelTotal - 1)) >> kNumMoveReducingBits]\r
+#define GET_PRICEa_0(prob) ProbPrices[(prob) >> kNumMoveReducingBits]\r
+#define GET_PRICEa_1(prob) ProbPrices[((prob) ^ (kBitModelTotal - 1)) >> kNumMoveReducingBits]\r
+\r
\r
-static UInt32 LitEnc_GetPrice(const CLzmaProb *probs, UInt32 symbol, const UInt32 *ProbPrices)\r
+static UInt32 LitEnc_GetPrice(const CLzmaProb *probs, UInt32 symbol, const CProbPrice *ProbPrices)\r
{\r
UInt32 price = 0;\r
symbol |= 0x100;\r
do\r
{\r
- price += GET_PRICEa(probs[symbol >> 8], (symbol >> 7) & 1);\r
- symbol <<= 1;\r
+ unsigned bit = symbol & 1;\r
+ symbol >>= 1;\r
+ price += GET_PRICEa(probs[symbol], bit);\r
}\r
- while (symbol < 0x10000);\r
+ while (symbol >= 2);\r
return price;\r
}\r
\r
-static UInt32 LitEnc_GetPriceMatched(const CLzmaProb *probs, UInt32 symbol, UInt32 matchByte, const UInt32 *ProbPrices)\r
+\r
+static UInt32 LitEnc_Matched_GetPrice(const CLzmaProb *probs, UInt32 symbol, UInt32 matchByte, const CProbPrice *ProbPrices)\r
{\r
UInt32 price = 0;\r
UInt32 offs = 0x100;\r
}\r
\r
\r
-static void RcTree_Encode(CRangeEnc *rc, CLzmaProb *probs, int numBitLevels, UInt32 symbol)\r
+static void RcTree_ReverseEncode(CRangeEnc *rc, CLzmaProb *probs, unsigned numBits, UInt32 symbol)\r
{\r
- UInt32 m = 1;\r
- int i;\r
- for (i = numBitLevels; i != 0;)\r
- {\r
- UInt32 bit;\r
- i--;\r
- bit = (symbol >> i) & 1;\r
- RangeEnc_EncodeBit(rc, probs + m, bit);\r
- m = (m << 1) | bit;\r
- }\r
-}\r
-\r
-static void RcTree_ReverseEncode(CRangeEnc *rc, CLzmaProb *probs, int numBitLevels, UInt32 symbol)\r
-{\r
- UInt32 m = 1;\r
- int i;\r
- for (i = 0; i < numBitLevels; i++)\r
- {\r
- UInt32 bit = symbol & 1;\r
- RangeEnc_EncodeBit(rc, probs + m, bit);\r
- m = (m << 1) | bit;\r
- symbol >>= 1;\r
- }\r
-}\r
-\r
-static UInt32 RcTree_GetPrice(const CLzmaProb *probs, int numBitLevels, UInt32 symbol, const UInt32 *ProbPrices)\r
-{\r
- UInt32 price = 0;\r
- symbol |= (1 << numBitLevels);\r
- while (symbol != 1)\r
- {\r
- price += GET_PRICEa(probs[symbol >> 1], symbol & 1);\r
- symbol >>= 1;\r
- }\r
- return price;\r
-}\r
-\r
-static UInt32 RcTree_ReverseGetPrice(const CLzmaProb *probs, int numBitLevels, UInt32 symbol, const UInt32 *ProbPrices)\r
-{\r
- UInt32 price = 0;\r
- UInt32 m = 1;\r
- int i;\r
- for (i = numBitLevels; i != 0; i--)\r
+ UInt32 range = rc->range;\r
+ unsigned m = 1;\r
+ do\r
{\r
- UInt32 bit = symbol & 1;\r
+ UInt32 ttt, newBound;\r
+ unsigned bit = symbol & 1;\r
+ // RangeEnc_EncodeBit(rc, probs + m, bit);\r
symbol >>= 1;\r
- price += GET_PRICEa(probs[m], bit);\r
+ RC_BIT(rc, probs + m, bit);\r
m = (m << 1) | bit;\r
}\r
- return price;\r
+ while (--numBits);\r
+ rc->range = range;\r
}\r
\r
\r
+\r
static void LenEnc_Init(CLenEnc *p)\r
{\r
unsigned i;\r
- p->choice = p->choice2 = kProbInitValue;\r
- for (i = 0; i < (LZMA_NUM_PB_STATES_MAX << kLenNumLowBits); i++)\r
+ for (i = 0; i < (LZMA_NUM_PB_STATES_MAX << (kLenNumLowBits + 1)); i++)\r
p->low[i] = kProbInitValue;\r
- for (i = 0; i < (LZMA_NUM_PB_STATES_MAX << kLenNumMidBits); i++)\r
- p->mid[i] = kProbInitValue;\r
for (i = 0; i < kLenNumHighSymbols; i++)\r
p->high[i] = kProbInitValue;\r
}\r
\r
-static void LenEnc_Encode(CLenEnc *p, CRangeEnc *rc, UInt32 symbol, UInt32 posState)\r
+static void LenEnc_Encode(CLenEnc *p, CRangeEnc *rc, unsigned symbol, unsigned posState)\r
{\r
- if (symbol < kLenNumLowSymbols)\r
+ UInt32 range, ttt, newBound;\r
+ CLzmaProb *probs = p->low;\r
+ range = rc->range;\r
+ RC_BIT_PRE(rc, probs);\r
+ if (symbol >= kLenNumLowSymbols)\r
{\r
- RangeEnc_EncodeBit(rc, &p->choice, 0);\r
- RcTree_Encode(rc, p->low + (posState << kLenNumLowBits), kLenNumLowBits, symbol);\r
- }\r
- else\r
- {\r
- RangeEnc_EncodeBit(rc, &p->choice, 1);\r
- if (symbol < kLenNumLowSymbols + kLenNumMidSymbols)\r
+ RC_BIT_1(rc, probs);\r
+ probs += kLenNumLowSymbols;\r
+ RC_BIT_PRE(rc, probs);\r
+ if (symbol >= kLenNumLowSymbols * 2)\r
{\r
- RangeEnc_EncodeBit(rc, &p->choice2, 0);\r
- RcTree_Encode(rc, p->mid + (posState << kLenNumMidBits), kLenNumMidBits, symbol - kLenNumLowSymbols);\r
- }\r
- else\r
- {\r
- RangeEnc_EncodeBit(rc, &p->choice2, 1);\r
- RcTree_Encode(rc, p->high, kLenNumHighBits, symbol - kLenNumLowSymbols - kLenNumMidSymbols);\r
+ RC_BIT_1(rc, probs);\r
+ rc->range = range;\r
+ // RcTree_Encode(rc, p->high, kLenNumHighBits, symbol - kLenNumLowSymbols * 2);\r
+ LitEnc_Encode(rc, p->high, symbol - kLenNumLowSymbols * 2);\r
+ return;\r
}\r
+ symbol -= kLenNumLowSymbols;\r
}\r
-}\r
\r
-static void LenEnc_SetPrices(CLenEnc *p, UInt32 posState, UInt32 numSymbols, UInt32 *prices, const UInt32 *ProbPrices)\r
-{\r
- UInt32 a0 = GET_PRICE_0a(p->choice);\r
- UInt32 a1 = GET_PRICE_1a(p->choice);\r
- UInt32 b0 = a1 + GET_PRICE_0a(p->choice2);\r
- UInt32 b1 = a1 + GET_PRICE_1a(p->choice2);\r
- UInt32 i = 0;\r
- for (i = 0; i < kLenNumLowSymbols; i++)\r
+ // RcTree_Encode(rc, probs + (posState << kLenNumLowBits), kLenNumLowBits, symbol);\r
{\r
- if (i >= numSymbols)\r
- return;\r
- prices[i] = a0 + RcTree_GetPrice(p->low + (posState << kLenNumLowBits), kLenNumLowBits, i, ProbPrices);\r
+ unsigned m;\r
+ unsigned bit;\r
+ RC_BIT_0(rc, probs);\r
+ probs += (posState << (1 + kLenNumLowBits));\r
+ bit = (symbol >> 2) ; RC_BIT(rc, probs + 1, bit); m = (1 << 1) + bit;\r
+ bit = (symbol >> 1) & 1; RC_BIT(rc, probs + m, bit); m = (m << 1) + bit;\r
+ bit = symbol & 1; RC_BIT(rc, probs + m, bit);\r
+ rc->range = range;\r
}\r
- for (; i < kLenNumLowSymbols + kLenNumMidSymbols; i++)\r
- {\r
- if (i >= numSymbols)\r
- return;\r
- prices[i] = b0 + RcTree_GetPrice(p->mid + (posState << kLenNumMidBits), kLenNumMidBits, i - kLenNumLowSymbols, ProbPrices);\r
- }\r
- for (; i < numSymbols; i++)\r
- prices[i] = b1 + RcTree_GetPrice(p->high, kLenNumHighBits, i - kLenNumLowSymbols - kLenNumMidSymbols, ProbPrices);\r
}\r
\r
-static void MY_FAST_CALL LenPriceEnc_UpdateTable(CLenPriceEnc *p, UInt32 posState, const UInt32 *ProbPrices)\r
+static void SetPrices_3(const CLzmaProb *probs, UInt32 startPrice, UInt32 *prices, const CProbPrice *ProbPrices)\r
{\r
- LenEnc_SetPrices(&p->p, posState, p->tableSize, p->prices[posState], ProbPrices);\r
- p->counters[posState] = p->tableSize;\r
+ unsigned i;\r
+ for (i = 0; i < 8; i += 2)\r
+ {\r
+ UInt32 price = startPrice;\r
+ UInt32 prob;\r
+ price += GET_PRICEa(probs[1 ], (i >> 2));\r
+ price += GET_PRICEa(probs[2 + (i >> 2)], (i >> 1) & 1);\r
+ prob = probs[4 + (i >> 1)];\r
+ prices[i ] = price + GET_PRICEa_0(prob);\r
+ prices[i + 1] = price + GET_PRICEa_1(prob);\r
+ }\r
}\r
\r
-static void LenPriceEnc_UpdateTables(CLenPriceEnc *p, UInt32 numPosStates, const UInt32 *ProbPrices)\r
+\r
+MY_NO_INLINE static void MY_FAST_CALL LenPriceEnc_UpdateTable(\r
+ CLenPriceEnc *p, unsigned posState,\r
+ const CLenEnc *enc,\r
+ const CProbPrice *ProbPrices)\r
{\r
- UInt32 posState;\r
- for (posState = 0; posState < numPosStates; posState++)\r
- LenPriceEnc_UpdateTable(p, posState, ProbPrices);\r
+ // int y; for (y = 0; y < 100; y++) {\r
+ UInt32 a;\r
+ unsigned i, numSymbols;\r
+\r
+ UInt32 *prices = p->prices[posState];\r
+ {\r
+ const CLzmaProb *probs = enc->low + (posState << (1 + kLenNumLowBits));\r
+ SetPrices_3(probs, GET_PRICEa_0(enc->low[0]), prices, ProbPrices);\r
+ a = GET_PRICEa_1(enc->low[0]);\r
+ SetPrices_3(probs + kLenNumLowSymbols, a + GET_PRICEa_0(enc->low[kLenNumLowSymbols]), prices + kLenNumLowSymbols, ProbPrices);\r
+ a += GET_PRICEa_1(enc->low[kLenNumLowSymbols]);\r
+ }\r
+ numSymbols = p->tableSize;\r
+ p->counters[posState] = numSymbols;\r
+ for (i = kLenNumLowSymbols * 2; i < numSymbols; i += 1)\r
+ {\r
+ prices[i] = a +\r
+ // RcTree_GetPrice(enc->high, kLenNumHighBits, i - kLenNumLowSymbols * 2, ProbPrices);\r
+ LitEnc_GetPrice(enc->high, i - kLenNumLowSymbols * 2, ProbPrices);\r
+ /*\r
+ unsigned sym = (i - kLenNumLowSymbols * 2) >> 1;\r
+ UInt32 price = a + RcTree_GetPrice(enc->high, kLenNumHighBits - 1, sym, ProbPrices);\r
+ UInt32 prob = enc->high[(1 << 7) + sym];\r
+ prices[i ] = price + GET_PRICEa_0(prob);\r
+ prices[i + 1] = price + GET_PRICEa_1(prob);\r
+ */\r
+ }\r
+ // }\r
}\r
\r
-static void LenEnc_Encode2(CLenPriceEnc *p, CRangeEnc *rc, UInt32 symbol, UInt32 posState, Bool updatePrice, const UInt32 *ProbPrices)\r
+static void LenPriceEnc_UpdateTables(CLenPriceEnc *p, unsigned numPosStates,\r
+ const CLenEnc *enc,\r
+ const CProbPrice *ProbPrices)\r
{\r
- LenEnc_Encode(&p->p, rc, symbol, posState);\r
- if (updatePrice)\r
- if (--p->counters[posState] == 0)\r
- LenPriceEnc_UpdateTable(p, posState, ProbPrices);\r
+ unsigned posState;\r
+ for (posState = 0; posState < numPosStates; posState++)\r
+ LenPriceEnc_UpdateTable(p, posState, enc, ProbPrices);\r
}\r
\r
\r
-\r
-\r
-static void MovePos(CLzmaEnc *p, UInt32 num)\r
-{\r
+/*\r
#ifdef SHOW_STAT\r
g_STAT_OFFSET += num;\r
printf("\n MovePos %u", num);\r
#endif\r
+*/\r
\r
- if (num != 0)\r
- {\r
- p->additionalOffset += num;\r
- p->matchFinder.Skip(p->matchFinderObj, num);\r
- }\r
-}\r
+#define MOVE_POS(p, num) { \\r
+ p->additionalOffset += (num); \\r
+ p->matchFinder.Skip(p->matchFinderObj, (num)); }\r
+\r
\r
-static UInt32 ReadMatchDistances(CLzmaEnc *p, UInt32 *numDistancePairsRes)\r
+static unsigned ReadMatchDistances(CLzmaEnc *p, unsigned *numPairsRes)\r
{\r
- UInt32 lenRes = 0, numPairs;\r
+ unsigned numPairs;\r
+ \r
+ p->additionalOffset++;\r
p->numAvail = p->matchFinder.GetNumAvailableBytes(p->matchFinderObj);\r
numPairs = p->matchFinder.GetMatches(p->matchFinderObj, p->matches);\r
+ *numPairsRes = numPairs;\r
\r
#ifdef SHOW_STAT\r
printf("\n i = %u numPairs = %u ", g_STAT_OFFSET, numPairs / 2);\r
g_STAT_OFFSET++;\r
{\r
- UInt32 i;\r
+ unsigned i;\r
for (i = 0; i < numPairs; i += 2)\r
printf("%2u %6u | ", p->matches[i], p->matches[i + 1]);\r
}\r
#endif\r
\r
- if (numPairs > 0)\r
+ if (numPairs == 0)\r
+ return 0;\r
{\r
- lenRes = p->matches[numPairs - 2];\r
- if (lenRes == p->numFastBytes)\r
+ unsigned len = p->matches[(size_t)numPairs - 2];\r
+ if (len != p->numFastBytes)\r
+ return len;\r
{\r
UInt32 numAvail = p->numAvail;\r
if (numAvail > LZMA_MATCH_LEN_MAX)\r
numAvail = LZMA_MATCH_LEN_MAX;\r
{\r
- const Byte *pbyCur = p->matchFinder.GetPointerToCurrentPos(p->matchFinderObj) - 1;\r
- const Byte *pby = pbyCur + lenRes;\r
- ptrdiff_t dif = (ptrdiff_t)-1 - p->matches[numPairs - 1];\r
- const Byte *pbyLim = pbyCur + numAvail;\r
- for (; pby != pbyLim && *pby == pby[dif]; pby++);\r
- lenRes = (UInt32)(pby - pbyCur);\r
+ const Byte *p1 = p->matchFinder.GetPointerToCurrentPos(p->matchFinderObj) - 1;\r
+ const Byte *p2 = p1 + len;\r
+ ptrdiff_t dif = (ptrdiff_t)-1 - p->matches[(size_t)numPairs - 1];\r
+ const Byte *lim = p1 + numAvail;\r
+ for (; p2 != lim && *p2 == p2[dif]; p2++);\r
+ return (unsigned)(p2 - p1);\r
}\r
}\r
}\r
- p->additionalOffset++;\r
- *numDistancePairsRes = numPairs;\r
- return lenRes;\r
}\r
\r
+#define MARK_LIT ((UInt32)(Int32)-1)\r
\r
-#define MakeAsChar(p) (p)->backPrev = (UInt32)(-1); (p)->prev1IsChar = False;\r
-#define MakeAsShortRep(p) (p)->backPrev = 0; (p)->prev1IsChar = False;\r
-#define IsShortRep(p) ((p)->backPrev == 0)\r
+#define MakeAs_Lit(p) { (p)->dist = MARK_LIT; (p)->extra = 0; }\r
+#define MakeAs_ShortRep(p) { (p)->dist = 0; (p)->extra = 0; }\r
+#define IsShortRep(p) ((p)->dist == 0)\r
\r
-static UInt32 GetRepLen1Price(CLzmaEnc *p, UInt32 state, UInt32 posState)\r
-{\r
- return\r
- GET_PRICE_0(p->isRepG0[state]) +\r
- GET_PRICE_0(p->isRep0Long[state][posState]);\r
-}\r
\r
-static UInt32 GetPureRepPrice(CLzmaEnc *p, UInt32 repIndex, UInt32 state, UInt32 posState)\r
+#define GetPrice_ShortRep(p, state, posState) \\r
+ ( GET_PRICE_0(p->isRepG0[state]) + GET_PRICE_0(p->isRep0Long[state][posState]))\r
+\r
+#define GetPrice_Rep_0(p, state, posState) ( \\r
+ GET_PRICE_1(p->isMatch[state][posState]) \\r
+ + GET_PRICE_1(p->isRep0Long[state][posState])) \\r
+ + GET_PRICE_1(p->isRep[state]) \\r
+ + GET_PRICE_0(p->isRepG0[state])\r
+ \r
+\r
+static UInt32 GetPrice_PureRep(const CLzmaEnc *p, unsigned repIndex, size_t state, size_t posState)\r
{\r
UInt32 price;\r
+ UInt32 prob = p->isRepG0[state];\r
if (repIndex == 0)\r
{\r
- price = GET_PRICE_0(p->isRepG0[state]);\r
+ price = GET_PRICE_0(prob);\r
price += GET_PRICE_1(p->isRep0Long[state][posState]);\r
}\r
else\r
{\r
- price = GET_PRICE_1(p->isRepG0[state]);\r
+ price = GET_PRICE_1(prob);\r
+ prob = p->isRepG1[state];\r
if (repIndex == 1)\r
- price += GET_PRICE_0(p->isRepG1[state]);\r
+ price += GET_PRICE_0(prob);\r
else\r
{\r
- price += GET_PRICE_1(p->isRepG1[state]);\r
+ price += GET_PRICE_1(prob);\r
price += GET_PRICE(p->isRepG2[state], repIndex - 2);\r
}\r
}\r
return price;\r
}\r
\r
-static UInt32 GetRepPrice(CLzmaEnc *p, UInt32 repIndex, UInt32 len, UInt32 state, UInt32 posState)\r
-{\r
- return p->repLenEnc.prices[posState][len - LZMA_MATCH_LEN_MIN] +\r
- GetPureRepPrice(p, repIndex, state, posState);\r
-}\r
\r
-static UInt32 Backward(CLzmaEnc *p, UInt32 *backRes, UInt32 cur)\r
+static unsigned Backward(CLzmaEnc *p, unsigned cur)\r
{\r
- UInt32 posMem = p->opt[cur].posPrev;\r
- UInt32 backMem = p->opt[cur].backPrev;\r
- p->optimumEndIndex = cur;\r
- do\r
+ unsigned wr = cur + 1;\r
+ p->optEnd = wr;\r
+\r
+ for (;;)\r
{\r
- if (p->opt[cur].prev1IsChar)\r
+ UInt32 dist = p->opt[cur].dist;\r
+ UInt32 len = p->opt[cur].len;\r
+ UInt32 extra = p->opt[cur].extra;\r
+ cur -= len;\r
+\r
+ if (extra)\r
{\r
- MakeAsChar(&p->opt[posMem])\r
- p->opt[posMem].posPrev = posMem - 1;\r
- if (p->opt[cur].prev2)\r
+ wr--;\r
+ p->opt[wr].len = len;\r
+ cur -= extra;\r
+ len = extra;\r
+ if (extra == 1)\r
+ {\r
+ p->opt[wr].dist = dist;\r
+ dist = MARK_LIT;\r
+ }\r
+ else\r
{\r
- p->opt[posMem - 1].prev1IsChar = False;\r
- p->opt[posMem - 1].posPrev = p->opt[cur].posPrev2;\r
- p->opt[posMem - 1].backPrev = p->opt[cur].backPrev2;\r
+ p->opt[wr].dist = 0;\r
+ len--;\r
+ wr--;\r
+ p->opt[wr].dist = MARK_LIT;\r
+ p->opt[wr].len = 1;\r
}\r
}\r
+\r
+ if (cur == 0)\r
{\r
- UInt32 posPrev = posMem;\r
- UInt32 backCur = backMem;\r
- \r
- backMem = p->opt[posPrev].backPrev;\r
- posMem = p->opt[posPrev].posPrev;\r
- \r
- p->opt[posPrev].backPrev = backCur;\r
- p->opt[posPrev].posPrev = cur;\r
- cur = posPrev;\r
+ p->backRes = dist;\r
+ p->optCur = wr;\r
+ return len;\r
}\r
+ \r
+ wr--;\r
+ p->opt[wr].dist = dist;\r
+ p->opt[wr].len = len;\r
}\r
- while (cur != 0);\r
- *backRes = p->opt[0].backPrev;\r
- p->optimumCurrentIndex = p->opt[0].posPrev;\r
- return p->optimumCurrentIndex;\r
}\r
\r
-#define LIT_PROBS(pos, prevByte) (p->litProbs + ((((pos) & p->lpMask) << p->lc) + ((prevByte) >> (8 - p->lc))) * (UInt32)0x300)\r
\r
-static UInt32 GetOptimum(CLzmaEnc *p, UInt32 position, UInt32 *backRes)\r
-{\r
- UInt32 lenEnd, cur;\r
- UInt32 reps[LZMA_NUM_REPS], repLens[LZMA_NUM_REPS];\r
- UInt32 *matches;\r
\r
- {\r
+#define LIT_PROBS(pos, prevByte) \\r
+ (p->litProbs + (UInt32)3 * (((((pos) << 8) + (prevByte)) & p->lpMask) << p->lc))\r
\r
- UInt32 numAvail, mainLen, numPairs, repMaxIndex, i, posState, len;\r
- UInt32 matchPrice, repMatchPrice, normalMatchPrice;\r
- const Byte *data;\r
- Byte curByte, matchByte;\r
\r
- if (p->optimumEndIndex != p->optimumCurrentIndex)\r
- {\r
- const COptimal *opt = &p->opt[p->optimumCurrentIndex];\r
- UInt32 lenRes = opt->posPrev - p->optimumCurrentIndex;\r
- *backRes = opt->backPrev;\r
- p->optimumCurrentIndex = opt->posPrev;\r
- return lenRes;\r
- }\r
- p->optimumCurrentIndex = p->optimumEndIndex = 0;\r
- \r
- if (p->additionalOffset == 0)\r
- mainLen = ReadMatchDistances(p, &numPairs);\r
- else\r
- {\r
- mainLen = p->longestMatchLength;\r
- numPairs = p->numPairs;\r
- }\r
-\r
- numAvail = p->numAvail;\r
- if (numAvail < 2)\r
- {\r
- *backRes = (UInt32)(-1);\r
- return 1;\r
- }\r
- if (numAvail > LZMA_MATCH_LEN_MAX)\r
- numAvail = LZMA_MATCH_LEN_MAX;\r
+static unsigned GetOptimum(CLzmaEnc *p, UInt32 position)\r
+{\r
+ unsigned last, cur;\r
+ UInt32 reps[LZMA_NUM_REPS];\r
+ unsigned repLens[LZMA_NUM_REPS];\r
+ UInt32 *matches;\r
\r
- data = p->matchFinder.GetPointerToCurrentPos(p->matchFinderObj) - 1;\r
- repMaxIndex = 0;\r
- for (i = 0; i < LZMA_NUM_REPS; i++)\r
{\r
- UInt32 lenTest;\r
- const Byte *data2;\r
- reps[i] = p->reps[i];\r
- data2 = data - reps[i] - 1;\r
- if (data[0] != data2[0] || data[1] != data2[1])\r
+ UInt32 numAvail;\r
+ unsigned numPairs, mainLen, repMaxIndex, i, posState;\r
+ UInt32 matchPrice, repMatchPrice;\r
+ const Byte *data;\r
+ Byte curByte, matchByte;\r
+ \r
+ p->optCur = p->optEnd = 0;\r
+ \r
+ if (p->additionalOffset == 0)\r
+ mainLen = ReadMatchDistances(p, &numPairs);\r
+ else\r
{\r
- repLens[i] = 0;\r
- continue;\r
+ mainLen = p->longestMatchLen;\r
+ numPairs = p->numPairs;\r
}\r
- for (lenTest = 2; lenTest < numAvail && data[lenTest] == data2[lenTest]; lenTest++);\r
- repLens[i] = lenTest;\r
- if (lenTest > repLens[repMaxIndex])\r
- repMaxIndex = i;\r
- }\r
- if (repLens[repMaxIndex] >= p->numFastBytes)\r
- {\r
- UInt32 lenRes;\r
- *backRes = repMaxIndex;\r
- lenRes = repLens[repMaxIndex];\r
- MovePos(p, lenRes - 1);\r
- return lenRes;\r
- }\r
-\r
- matches = p->matches;\r
- if (mainLen >= p->numFastBytes)\r
- {\r
- *backRes = matches[numPairs - 1] + LZMA_NUM_REPS;\r
- MovePos(p, mainLen - 1);\r
- return mainLen;\r
- }\r
- curByte = *data;\r
- matchByte = *(data - (reps[0] + 1));\r
-\r
- if (mainLen < 2 && curByte != matchByte && repLens[repMaxIndex] < 2)\r
- {\r
- *backRes = (UInt32)-1;\r
- return 1;\r
- }\r
-\r
- p->opt[0].state = (CState)p->state;\r
-\r
- posState = (position & p->pbMask);\r
-\r
- {\r
- const CLzmaProb *probs = LIT_PROBS(position, *(data - 1));\r
- p->opt[1].price = GET_PRICE_0(p->isMatch[p->state][posState]) +\r
- (!IsCharState(p->state) ?\r
- LitEnc_GetPriceMatched(probs, curByte, matchByte, p->ProbPrices) :\r
- LitEnc_GetPrice(probs, curByte, p->ProbPrices));\r
- }\r
-\r
- MakeAsChar(&p->opt[1]);\r
-\r
- matchPrice = GET_PRICE_1(p->isMatch[p->state][posState]);\r
- repMatchPrice = matchPrice + GET_PRICE_1(p->isRep[p->state]);\r
-\r
- if (matchByte == curByte)\r
- {\r
- UInt32 shortRepPrice = repMatchPrice + GetRepLen1Price(p, p->state, posState);\r
- if (shortRepPrice < p->opt[1].price)\r
+ \r
+ numAvail = p->numAvail;\r
+ if (numAvail < 2)\r
{\r
- p->opt[1].price = shortRepPrice;\r
- MakeAsShortRep(&p->opt[1]);\r
+ p->backRes = MARK_LIT;\r
+ return 1;\r
}\r
- }\r
- lenEnd = ((mainLen >= repLens[repMaxIndex]) ? mainLen : repLens[repMaxIndex]);\r
-\r
- if (lenEnd < 2)\r
- {\r
- *backRes = p->opt[1].backPrev;\r
- return 1;\r
- }\r
-\r
- p->opt[1].posPrev = 0;\r
- for (i = 0; i < LZMA_NUM_REPS; i++)\r
- p->opt[0].backs[i] = reps[i];\r
-\r
- len = lenEnd;\r
- do\r
- p->opt[len--].price = kInfinityPrice;\r
- while (len >= 2);\r
-\r
- for (i = 0; i < LZMA_NUM_REPS; i++)\r
- {\r
- UInt32 repLen = repLens[i];\r
- UInt32 price;\r
- if (repLen < 2)\r
- continue;\r
- price = repMatchPrice + GetPureRepPrice(p, i, p->state, posState);\r
- do\r
+ if (numAvail > LZMA_MATCH_LEN_MAX)\r
+ numAvail = LZMA_MATCH_LEN_MAX;\r
+ \r
+ data = p->matchFinder.GetPointerToCurrentPos(p->matchFinderObj) - 1;\r
+ repMaxIndex = 0;\r
+ \r
+ for (i = 0; i < LZMA_NUM_REPS; i++)\r
{\r
- UInt32 curAndLenPrice = price + p->repLenEnc.prices[posState][repLen - 2];\r
- COptimal *opt = &p->opt[repLen];\r
- if (curAndLenPrice < opt->price)\r
+ unsigned len;\r
+ const Byte *data2;\r
+ reps[i] = p->reps[i];\r
+ data2 = data - reps[i];\r
+ if (data[0] != data2[0] || data[1] != data2[1])\r
{\r
- opt->price = curAndLenPrice;\r
- opt->posPrev = 0;\r
- opt->backPrev = i;\r
- opt->prev1IsChar = False;\r
+ repLens[i] = 0;\r
+ continue;\r
}\r
+ for (len = 2; len < numAvail && data[len] == data2[len]; len++);\r
+ repLens[i] = len;\r
+ if (len > repLens[repMaxIndex])\r
+ repMaxIndex = i;\r
}\r
- while (--repLen >= 2);\r
- }\r
-\r
- normalMatchPrice = matchPrice + GET_PRICE_0(p->isRep[p->state]);\r
-\r
- len = ((repLens[0] >= 2) ? repLens[0] + 1 : 2);\r
- if (len <= mainLen)\r
- {\r
- UInt32 offs = 0;\r
- while (len > matches[offs])\r
- offs += 2;\r
- for (; ; len++)\r
+ \r
+ if (repLens[repMaxIndex] >= p->numFastBytes)\r
{\r
- COptimal *opt;\r
- UInt32 distance = matches[offs + 1];\r
-\r
- UInt32 curAndLenPrice = normalMatchPrice + p->lenEnc.prices[posState][len - LZMA_MATCH_LEN_MIN];\r
- UInt32 lenToPosState = GetLenToPosState(len);\r
- if (distance < kNumFullDistances)\r
- curAndLenPrice += p->distancesPrices[lenToPosState][distance];\r
- else\r
+ unsigned len;\r
+ p->backRes = repMaxIndex;\r
+ len = repLens[repMaxIndex];\r
+ MOVE_POS(p, len - 1)\r
+ return len;\r
+ }\r
+ \r
+ matches = p->matches;\r
+ \r
+ if (mainLen >= p->numFastBytes)\r
+ {\r
+ p->backRes = matches[(size_t)numPairs - 1] + LZMA_NUM_REPS;\r
+ MOVE_POS(p, mainLen - 1)\r
+ return mainLen;\r
+ }\r
+ \r
+ curByte = *data;\r
+ matchByte = *(data - reps[0]);\r
+ \r
+ if (mainLen < 2 && curByte != matchByte && repLens[repMaxIndex] < 2)\r
+ {\r
+ p->backRes = MARK_LIT;\r
+ return 1;\r
+ }\r
+ \r
+ p->opt[0].state = (CState)p->state;\r
+ \r
+ posState = (position & p->pbMask);\r
+ \r
+ {\r
+ const CLzmaProb *probs = LIT_PROBS(position, *(data - 1));\r
+ p->opt[1].price = GET_PRICE_0(p->isMatch[p->state][posState]) +\r
+ (!IsLitState(p->state) ?\r
+ LitEnc_Matched_GetPrice(probs, curByte, matchByte, p->ProbPrices) :\r
+ LitEnc_GetPrice(probs, curByte, p->ProbPrices));\r
+ }\r
+ \r
+ MakeAs_Lit(&p->opt[1]);\r
+ \r
+ matchPrice = GET_PRICE_1(p->isMatch[p->state][posState]);\r
+ repMatchPrice = matchPrice + GET_PRICE_1(p->isRep[p->state]);\r
+ \r
+ if (matchByte == curByte)\r
+ {\r
+ UInt32 shortRepPrice = repMatchPrice + GetPrice_ShortRep(p, p->state, posState);\r
+ if (shortRepPrice < p->opt[1].price)\r
{\r
- UInt32 slot;\r
- GetPosSlot2(distance, slot);\r
- curAndLenPrice += p->alignPrices[distance & kAlignMask] + p->posSlotPrices[lenToPosState][slot];\r
+ p->opt[1].price = shortRepPrice;\r
+ MakeAs_ShortRep(&p->opt[1]);\r
}\r
- opt = &p->opt[len];\r
- if (curAndLenPrice < opt->price)\r
+ }\r
+ \r
+ last = (mainLen >= repLens[repMaxIndex] ? mainLen : repLens[repMaxIndex]);\r
+ \r
+ if (last < 2)\r
+ {\r
+ p->backRes = p->opt[1].dist;\r
+ return 1;\r
+ }\r
+ \r
+ p->opt[1].len = 1;\r
+ \r
+ p->opt[0].reps[0] = reps[0];\r
+ p->opt[0].reps[1] = reps[1];\r
+ p->opt[0].reps[2] = reps[2];\r
+ p->opt[0].reps[3] = reps[3];\r
+ \r
+ {\r
+ unsigned len = last;\r
+ do\r
+ p->opt[len--].price = kInfinityPrice;\r
+ while (len >= 2);\r
+ }\r
+\r
+ // ---------- REP ----------\r
+ \r
+ for (i = 0; i < LZMA_NUM_REPS; i++)\r
+ {\r
+ unsigned repLen = repLens[i];\r
+ UInt32 price;\r
+ if (repLen < 2)\r
+ continue;\r
+ price = repMatchPrice + GetPrice_PureRep(p, i, p->state, posState);\r
+ do\r
{\r
- opt->price = curAndLenPrice;\r
- opt->posPrev = 0;\r
- opt->backPrev = distance + LZMA_NUM_REPS;\r
- opt->prev1IsChar = False;\r
+ UInt32 price2 = price + p->repLenEnc.prices[posState][(size_t)repLen - 2];\r
+ COptimal *opt = &p->opt[repLen];\r
+ if (price2 < opt->price)\r
+ {\r
+ opt->price = price2;\r
+ opt->len = repLen;\r
+ opt->dist = i;\r
+ opt->extra = 0;\r
+ }\r
}\r
- if (len == matches[offs])\r
+ while (--repLen >= 2);\r
+ }\r
+ \r
+ \r
+ // ---------- MATCH ----------\r
+ {\r
+ unsigned len = ((repLens[0] >= 2) ? repLens[0] + 1 : 2);\r
+ if (len <= mainLen)\r
{\r
- offs += 2;\r
- if (offs == numPairs)\r
- break;\r
+ unsigned offs = 0;\r
+ UInt32 normalMatchPrice = matchPrice + GET_PRICE_0(p->isRep[p->state]);\r
+\r
+ while (len > matches[offs])\r
+ offs += 2;\r
+ \r
+ for (; ; len++)\r
+ {\r
+ COptimal *opt;\r
+ UInt32 dist = matches[(size_t)offs + 1];\r
+ UInt32 price2 = normalMatchPrice + p->lenEnc.prices[posState][(size_t)len - LZMA_MATCH_LEN_MIN];\r
+ unsigned lenToPosState = GetLenToPosState(len);\r
+ \r
+ if (dist < kNumFullDistances)\r
+ price2 += p->distancesPrices[lenToPosState][dist & (kNumFullDistances - 1)];\r
+ else\r
+ {\r
+ unsigned slot;\r
+ GetPosSlot2(dist, slot);\r
+ price2 += p->alignPrices[dist & kAlignMask];\r
+ price2 += p->posSlotPrices[lenToPosState][slot];\r
+ }\r
+ \r
+ opt = &p->opt[len];\r
+ \r
+ if (price2 < opt->price)\r
+ {\r
+ opt->price = price2;\r
+ opt->len = len;\r
+ opt->dist = dist + LZMA_NUM_REPS;\r
+ opt->extra = 0;\r
+ }\r
+ \r
+ if (len == matches[offs])\r
+ {\r
+ offs += 2;\r
+ if (offs == numPairs)\r
+ break;\r
+ }\r
+ }\r
}\r
}\r
- }\r
+ \r
\r
- cur = 0;\r
+ cur = 0;\r
\r
#ifdef SHOW_STAT2\r
/* if (position >= 0) */\r
{\r
unsigned i;\r
printf("\n pos = %4X", position);\r
- for (i = cur; i <= lenEnd; i++)\r
+ for (i = cur; i <= last; i++)\r
printf("\nprice[%4X] = %u", position - cur + i, p->opt[i].price);\r
}\r
#endif\r
+ }\r
+\r
\r
- }\r
+ \r
+ // ---------- Optimal Parsing ----------\r
\r
for (;;)\r
{\r
- UInt32 numAvail;\r
- UInt32 numAvailFull, newLen, numPairs, posPrev, state, posState, startLen;\r
- UInt32 curPrice, curAnd1Price, matchPrice, repMatchPrice;\r
- Bool nextIsChar;\r
+ UInt32 numAvail, numAvailFull;\r
+ unsigned newLen, numPairs, prev, state, posState, startLen;\r
+ UInt32 curPrice, litPrice, matchPrice, repMatchPrice;\r
+ Bool nextIsLit;\r
Byte curByte, matchByte;\r
const Byte *data;\r
- COptimal *curOpt;\r
- COptimal *nextOpt;\r
+ COptimal *curOpt, *nextOpt;\r
\r
- cur++;\r
- if (cur == lenEnd)\r
- return Backward(p, backRes, cur);\r
+ if (++cur == last)\r
+ return Backward(p, cur);\r
\r
newLen = ReadMatchDistances(p, &numPairs);\r
+ \r
if (newLen >= p->numFastBytes)\r
{\r
p->numPairs = numPairs;\r
- p->longestMatchLength = newLen;\r
- return Backward(p, backRes, cur);\r
+ p->longestMatchLen = newLen;\r
+ return Backward(p, cur);\r
}\r
- position++;\r
+ \r
curOpt = &p->opt[cur];\r
- posPrev = curOpt->posPrev;\r
- if (curOpt->prev1IsChar)\r
- {\r
- posPrev--;\r
- if (curOpt->prev2)\r
- {\r
- state = p->opt[curOpt->posPrev2].state;\r
- if (curOpt->backPrev2 < LZMA_NUM_REPS)\r
- state = kRepNextStates[state];\r
- else\r
- state = kMatchNextStates[state];\r
- }\r
- else\r
- state = p->opt[posPrev].state;\r
- state = kLiteralNextStates[state];\r
- }\r
- else\r
- state = p->opt[posPrev].state;\r
- if (posPrev == cur - 1)\r
+ prev = cur - curOpt->len;\r
+ \r
+ if (curOpt->len == 1)\r
{\r
+ state = p->opt[prev].state;\r
if (IsShortRep(curOpt))\r
state = kShortRepNextStates[state];\r
else\r
}\r
else\r
{\r
- UInt32 pos;\r
const COptimal *prevOpt;\r
- if (curOpt->prev1IsChar && curOpt->prev2)\r
+ UInt32 b0;\r
+ UInt32 dist = curOpt->dist;\r
+\r
+ if (curOpt->extra)\r
{\r
- posPrev = curOpt->posPrev2;\r
- pos = curOpt->backPrev2;\r
- state = kRepNextStates[state];\r
+ prev -= curOpt->extra;\r
+ state = kState_RepAfterLit;\r
+ if (curOpt->extra == 1)\r
+ state = (dist < LZMA_NUM_REPS) ? kState_RepAfterLit : kState_MatchAfterLit;\r
}\r
else\r
{\r
- pos = curOpt->backPrev;\r
- if (pos < LZMA_NUM_REPS)\r
+ state = p->opt[prev].state;\r
+ if (dist < LZMA_NUM_REPS)\r
state = kRepNextStates[state];\r
else\r
state = kMatchNextStates[state];\r
}\r
- prevOpt = &p->opt[posPrev];\r
- if (pos < LZMA_NUM_REPS)\r
+\r
+ prevOpt = &p->opt[prev];\r
+ b0 = prevOpt->reps[0];\r
+\r
+ if (dist < LZMA_NUM_REPS)\r
{\r
- UInt32 i;\r
- reps[0] = prevOpt->backs[pos];\r
- for (i = 1; i <= pos; i++)\r
- reps[i] = prevOpt->backs[i - 1];\r
- for (; i < LZMA_NUM_REPS; i++)\r
- reps[i] = prevOpt->backs[i];\r
+ if (dist == 0)\r
+ {\r
+ reps[0] = b0;\r
+ reps[1] = prevOpt->reps[1];\r
+ reps[2] = prevOpt->reps[2];\r
+ reps[3] = prevOpt->reps[3];\r
+ }\r
+ else\r
+ {\r
+ reps[1] = b0;\r
+ b0 = prevOpt->reps[1];\r
+ if (dist == 1)\r
+ {\r
+ reps[0] = b0;\r
+ reps[2] = prevOpt->reps[2];\r
+ reps[3] = prevOpt->reps[3];\r
+ }\r
+ else\r
+ {\r
+ reps[2] = b0;\r
+ reps[0] = prevOpt->reps[dist];\r
+ reps[3] = prevOpt->reps[dist ^ 1];\r
+ }\r
+ }\r
}\r
else\r
{\r
- UInt32 i;\r
- reps[0] = (pos - LZMA_NUM_REPS);\r
- for (i = 1; i < LZMA_NUM_REPS; i++)\r
- reps[i] = prevOpt->backs[i - 1];\r
+ reps[0] = (dist - LZMA_NUM_REPS + 1);\r
+ reps[1] = b0;\r
+ reps[2] = prevOpt->reps[1];\r
+ reps[3] = prevOpt->reps[2];\r
}\r
}\r
+ \r
curOpt->state = (CState)state;\r
+ curOpt->reps[0] = reps[0];\r
+ curOpt->reps[1] = reps[1];\r
+ curOpt->reps[2] = reps[2];\r
+ curOpt->reps[3] = reps[3];\r
\r
- curOpt->backs[0] = reps[0];\r
- curOpt->backs[1] = reps[1];\r
- curOpt->backs[2] = reps[2];\r
- curOpt->backs[3] = reps[3];\r
-\r
- curPrice = curOpt->price;\r
- nextIsChar = False;\r
data = p->matchFinder.GetPointerToCurrentPos(p->matchFinderObj) - 1;\r
curByte = *data;\r
- matchByte = *(data - (reps[0] + 1));\r
+ matchByte = *(data - reps[0]);\r
\r
+ position++;\r
posState = (position & p->pbMask);\r
\r
- curAnd1Price = curPrice + GET_PRICE_0(p->isMatch[state][posState]);\r
- {\r
- const CLzmaProb *probs = LIT_PROBS(position, *(data - 1));\r
- curAnd1Price +=\r
- (!IsCharState(state) ?\r
- LitEnc_GetPriceMatched(probs, curByte, matchByte, p->ProbPrices) :\r
- LitEnc_GetPrice(probs, curByte, p->ProbPrices));\r
- }\r
+ /*\r
+ The order of Price checks:\r
+ < LIT\r
+ <= SHORT_REP\r
+ < LIT : REP_0\r
+ < REP [ : LIT : REP_0 ]\r
+ < MATCH [ : LIT : REP_0 ]\r
+ */\r
+\r
+ curPrice = curOpt->price;\r
+ litPrice = curPrice + GET_PRICE_0(p->isMatch[state][posState]);\r
\r
- nextOpt = &p->opt[cur + 1];\r
+ nextOpt = &p->opt[(size_t)cur + 1];\r
+ nextIsLit = False;\r
\r
- if (curAnd1Price < nextOpt->price)\r
+ // if (litPrice >= nextOpt->price) litPrice = 0; else // 18.new\r
{\r
- nextOpt->price = curAnd1Price;\r
- nextOpt->posPrev = cur;\r
- MakeAsChar(nextOpt);\r
- nextIsChar = True;\r
+ const CLzmaProb *probs = LIT_PROBS(position, *(data - 1));\r
+ litPrice += (!IsLitState(state) ?\r
+ LitEnc_Matched_GetPrice(probs, curByte, matchByte, p->ProbPrices) :\r
+ LitEnc_GetPrice(probs, curByte, p->ProbPrices));\r
+ \r
+ if (litPrice < nextOpt->price)\r
+ {\r
+ nextOpt->price = litPrice;\r
+ nextOpt->len = 1;\r
+ MakeAs_Lit(nextOpt);\r
+ nextIsLit = True;\r
+ }\r
}\r
\r
matchPrice = curPrice + GET_PRICE_1(p->isMatch[state][posState]);\r
repMatchPrice = matchPrice + GET_PRICE_1(p->isRep[state]);\r
\r
- if (matchByte == curByte && !(nextOpt->posPrev < cur && nextOpt->backPrev == 0))\r
+ // ---------- SHORT_REP ----------\r
+ // if (IsLitState(state)) // 18.new\r
+ if (matchByte == curByte)\r
+ // if (repMatchPrice < nextOpt->price) // 18.new\r
+ if (nextOpt->len < 2\r
+ || (nextOpt->dist != 0\r
+ && nextOpt->extra <= 1 // 17.old\r
+ ))\r
{\r
- UInt32 shortRepPrice = repMatchPrice + GetRepLen1Price(p, state, posState);\r
- if (shortRepPrice <= nextOpt->price)\r
+ UInt32 shortRepPrice = repMatchPrice + GetPrice_ShortRep(p, state, posState);\r
+ if (shortRepPrice <= nextOpt->price) // 17.old\r
+ // if (shortRepPrice < nextOpt->price) // 18.new\r
{\r
nextOpt->price = shortRepPrice;\r
- nextOpt->posPrev = cur;\r
- MakeAsShortRep(nextOpt);\r
- nextIsChar = True;\r
+ nextOpt->len = 1;\r
+ MakeAs_ShortRep(nextOpt);\r
+ nextIsLit = False;\r
}\r
}\r
+ \r
numAvailFull = p->numAvail;\r
{\r
UInt32 temp = kNumOpts - 1 - cur;\r
- if (temp < numAvailFull)\r
+ if (numAvailFull > temp)\r
numAvailFull = temp;\r
}\r
\r
continue;\r
numAvail = (numAvailFull <= p->numFastBytes ? numAvailFull : p->numFastBytes);\r
\r
- if (!nextIsChar && matchByte != curByte) /* speed optimization */\r
+ // numAvail <= p->numFastBytes\r
+\r
+ // ---------- LIT : REP_0 ----------\r
+\r
+ if (\r
+ // litPrice != 0 && // 18.new\r
+ !nextIsLit\r
+ && matchByte != curByte\r
+ && numAvailFull > 2)\r
{\r
- /* try Literal + rep0 */\r
- UInt32 temp;\r
- UInt32 lenTest2;\r
- const Byte *data2 = data - reps[0] - 1;\r
- UInt32 limit = p->numFastBytes + 1;\r
- if (limit > numAvailFull)\r
- limit = numAvailFull;\r
-\r
- for (temp = 1; temp < limit && data[temp] == data2[temp]; temp++);\r
- lenTest2 = temp - 1;\r
- if (lenTest2 >= 2)\r
+ const Byte *data2 = data - reps[0];\r
+ if (data[1] == data2[1] && data[2] == data2[2])\r
{\r
- UInt32 state2 = kLiteralNextStates[state];\r
- UInt32 posStateNext = (position + 1) & p->pbMask;\r
- UInt32 nextRepMatchPrice = curAnd1Price +\r
- GET_PRICE_1(p->isMatch[state2][posStateNext]) +\r
- GET_PRICE_1(p->isRep[state2]);\r
- /* for (; lenTest2 >= 2; lenTest2--) */\r
+ unsigned len;\r
+ unsigned limit = p->numFastBytes + 1;\r
+ if (limit > numAvailFull)\r
+ limit = numAvailFull;\r
+ for (len = 3; len < limit && data[len] == data2[len]; len++);\r
+ \r
{\r
- UInt32 curAndLenPrice;\r
- COptimal *opt;\r
- UInt32 offset = cur + 1 + lenTest2;\r
- while (lenEnd < offset)\r
- p->opt[++lenEnd].price = kInfinityPrice;\r
- curAndLenPrice = nextRepMatchPrice + GetRepPrice(p, 0, lenTest2, state2, posStateNext);\r
- opt = &p->opt[offset];\r
- if (curAndLenPrice < opt->price)\r
+ unsigned state2 = kLiteralNextStates[state];\r
+ unsigned posState2 = (position + 1) & p->pbMask;\r
+ UInt32 price = litPrice + GetPrice_Rep_0(p, state2, posState2);\r
{\r
- opt->price = curAndLenPrice;\r
- opt->posPrev = cur + 1;\r
- opt->backPrev = 0;\r
- opt->prev1IsChar = True;\r
- opt->prev2 = False;\r
+ unsigned offset = cur + len;\r
+ while (last < offset)\r
+ p->opt[++last].price = kInfinityPrice;\r
+ \r
+ // do\r
+ {\r
+ UInt32 price2;\r
+ COptimal *opt;\r
+ len--;\r
+ // price2 = price + GetPrice_Len_Rep_0(p, len, state2, posState2);\r
+ price2 = price + p->repLenEnc.prices[posState2][len - LZMA_MATCH_LEN_MIN];\r
+\r
+ opt = &p->opt[offset];\r
+ // offset--;\r
+ if (price2 < opt->price)\r
+ {\r
+ opt->price = price2;\r
+ opt->len = len;\r
+ opt->dist = 0;\r
+ opt->extra = 1;\r
+ }\r
+ }\r
+ // while (len >= 3);\r
}\r
}\r
}\r
\r
startLen = 2; /* speed optimization */\r
{\r
- UInt32 repIndex;\r
- for (repIndex = 0; repIndex < LZMA_NUM_REPS; repIndex++)\r
- {\r
- UInt32 lenTest;\r
- UInt32 lenTestTemp;\r
- UInt32 price;\r
- const Byte *data2 = data - reps[repIndex] - 1;\r
- if (data[0] != data2[0] || data[1] != data2[1])\r
- continue;\r
- for (lenTest = 2; lenTest < numAvail && data[lenTest] == data2[lenTest]; lenTest++);\r
- while (lenEnd < cur + lenTest)\r
- p->opt[++lenEnd].price = kInfinityPrice;\r
- lenTestTemp = lenTest;\r
- price = repMatchPrice + GetPureRepPrice(p, repIndex, state, posState);\r
- do\r
+ // ---------- REP ----------\r
+ unsigned repIndex = 0; // 17.old\r
+ // unsigned repIndex = IsLitState(state) ? 0 : 1; // 18.notused\r
+ for (; repIndex < LZMA_NUM_REPS; repIndex++)\r
{\r
- UInt32 curAndLenPrice = price + p->repLenEnc.prices[posState][lenTest - 2];\r
- COptimal *opt = &p->opt[cur + lenTest];\r
- if (curAndLenPrice < opt->price)\r
+ unsigned len;\r
+ UInt32 price;\r
+ const Byte *data2 = data - reps[repIndex];\r
+ if (data[0] != data2[0] || data[1] != data2[1])\r
+ continue;\r
+ \r
+ for (len = 2; len < numAvail && data[len] == data2[len]; len++);\r
+ \r
+ // if (len < startLen) continue; // 18.new: speed optimization\r
+\r
+ while (last < cur + len)\r
+ p->opt[++last].price = kInfinityPrice;\r
{\r
- opt->price = curAndLenPrice;\r
- opt->posPrev = cur;\r
- opt->backPrev = repIndex;\r
- opt->prev1IsChar = False;\r
+ unsigned len2 = len;\r
+ price = repMatchPrice + GetPrice_PureRep(p, repIndex, state, posState);\r
+ do\r
+ {\r
+ UInt32 price2 = price + p->repLenEnc.prices[posState][(size_t)len2 - 2];\r
+ COptimal *opt = &p->opt[cur + len2];\r
+ if (price2 < opt->price)\r
+ {\r
+ opt->price = price2;\r
+ opt->len = len2;\r
+ opt->dist = repIndex;\r
+ opt->extra = 0;\r
+ }\r
+ }\r
+ while (--len2 >= 2);\r
}\r
- }\r
- while (--lenTest >= 2);\r
- lenTest = lenTestTemp;\r
- \r
- if (repIndex == 0)\r
- startLen = lenTest + 1;\r
\r
- /* if (_maxMode) */\r
+ if (repIndex == 0) startLen = len + 1; // 17.old\r
+ // startLen = len + 1; // 18.new\r
+\r
+ /* if (_maxMode) */\r
{\r
- UInt32 lenTest2 = lenTest + 1;\r
- UInt32 limit = lenTest2 + p->numFastBytes;\r
+ // ---------- REP : LIT : REP_0 ----------\r
+ // numFastBytes + 1 + numFastBytes\r
+\r
+ unsigned len2 = len + 1;\r
+ unsigned limit = len2 + p->numFastBytes;\r
if (limit > numAvailFull)\r
limit = numAvailFull;\r
- for (; lenTest2 < limit && data[lenTest2] == data2[lenTest2]; lenTest2++);\r
- lenTest2 -= lenTest + 1;\r
- if (lenTest2 >= 2)\r
+ \r
+ for (; len2 < limit && data[len2] == data2[len2]; len2++);\r
+ \r
+ len2 -= len;\r
+ if (len2 >= 3)\r
{\r
- UInt32 nextRepMatchPrice;\r
- UInt32 state2 = kRepNextStates[state];\r
- UInt32 posStateNext = (position + lenTest) & p->pbMask;\r
- UInt32 curAndLenCharPrice =\r
- price + p->repLenEnc.prices[posState][lenTest - 2] +\r
- GET_PRICE_0(p->isMatch[state2][posStateNext]) +\r
- LitEnc_GetPriceMatched(LIT_PROBS(position + lenTest, data[lenTest - 1]),\r
- data[lenTest], data2[lenTest], p->ProbPrices);\r
- state2 = kLiteralNextStates[state2];\r
- posStateNext = (position + lenTest + 1) & p->pbMask;\r
- nextRepMatchPrice = curAndLenCharPrice +\r
- GET_PRICE_1(p->isMatch[state2][posStateNext]) +\r
- GET_PRICE_1(p->isRep[state2]);\r
+ unsigned state2 = kRepNextStates[state];\r
+ unsigned posState2 = (position + len) & p->pbMask;\r
+ price +=\r
+ p->repLenEnc.prices[posState][(size_t)len - 2]\r
+ + GET_PRICE_0(p->isMatch[state2][posState2])\r
+ + LitEnc_Matched_GetPrice(LIT_PROBS(position + len, data[(size_t)len - 1]),\r
+ data[len], data2[len], p->ProbPrices);\r
\r
- /* for (; lenTest2 >= 2; lenTest2--) */\r
+ // state2 = kLiteralNextStates[state2];\r
+ state2 = kState_LitAfterRep;\r
+ posState2 = (posState2 + 1) & p->pbMask;\r
+\r
+\r
+ price += GetPrice_Rep_0(p, state2, posState2);\r
{\r
- UInt32 curAndLenPrice;\r
- COptimal *opt;\r
- UInt32 offset = cur + lenTest + 1 + lenTest2;\r
- while (lenEnd < offset)\r
- p->opt[++lenEnd].price = kInfinityPrice;\r
- curAndLenPrice = nextRepMatchPrice + GetRepPrice(p, 0, lenTest2, state2, posStateNext);\r
- opt = &p->opt[offset];\r
- if (curAndLenPrice < opt->price)\r
+ unsigned offset = cur + len + len2;\r
+ while (last < offset)\r
+ p->opt[++last].price = kInfinityPrice;\r
+ // do\r
{\r
- opt->price = curAndLenPrice;\r
- opt->posPrev = cur + lenTest + 1;\r
- opt->backPrev = 0;\r
- opt->prev1IsChar = True;\r
- opt->prev2 = True;\r
- opt->posPrev2 = cur;\r
- opt->backPrev2 = repIndex;\r
+ unsigned price2;\r
+ COptimal *opt;\r
+ len2--;\r
+ // price2 = price + GetPrice_Len_Rep_0(p, len2, state2, posState2);\r
+ price2 = price + p->repLenEnc.prices[posState2][len2 - LZMA_MATCH_LEN_MIN];\r
+\r
+ opt = &p->opt[offset];\r
+ // offset--;\r
+ if (price2 < opt->price)\r
+ {\r
+ opt->price = price2;\r
+ opt->len = len2;\r
+ opt->extra = (CExtra)(len + 1);\r
+ opt->dist = repIndex;\r
+ }\r
}\r
+ // while (len2 >= 3);\r
}\r
}\r
}\r
+ }\r
}\r
- }\r
- /* for (UInt32 lenTest = 2; lenTest <= newLen; lenTest++) */\r
+\r
+\r
+ // ---------- MATCH ----------\r
+ /* for (unsigned len = 2; len <= newLen; len++) */\r
if (newLen > numAvail)\r
{\r
newLen = numAvail;\r
matches[numPairs] = newLen;\r
numPairs += 2;\r
}\r
+ \r
if (newLen >= startLen)\r
{\r
UInt32 normalMatchPrice = matchPrice + GET_PRICE_0(p->isRep[state]);\r
- UInt32 offs, curBack, posSlot;\r
- UInt32 lenTest;\r
- while (lenEnd < cur + newLen)\r
- p->opt[++lenEnd].price = kInfinityPrice;\r
+ UInt32 dist;\r
+ unsigned offs, posSlot, len;\r
+ while (last < cur + newLen)\r
+ p->opt[++last].price = kInfinityPrice;\r
\r
offs = 0;\r
while (startLen > matches[offs])\r
offs += 2;\r
- curBack = matches[offs + 1];\r
- GetPosSlot2(curBack, posSlot);\r
- for (lenTest = /*2*/ startLen; ; lenTest++)\r
+ dist = matches[(size_t)offs + 1];\r
+ \r
+ // if (dist >= kNumFullDistances)\r
+ GetPosSlot2(dist, posSlot);\r
+ \r
+ for (len = /*2*/ startLen; ; len++)\r
{\r
- UInt32 curAndLenPrice = normalMatchPrice + p->lenEnc.prices[posState][lenTest - LZMA_MATCH_LEN_MIN];\r
- {\r
- UInt32 lenToPosState = GetLenToPosState(lenTest);\r
- COptimal *opt;\r
- if (curBack < kNumFullDistances)\r
- curAndLenPrice += p->distancesPrices[lenToPosState][curBack];\r
- else\r
- curAndLenPrice += p->posSlotPrices[lenToPosState][posSlot] + p->alignPrices[curBack & kAlignMask];\r
- \r
- opt = &p->opt[cur + lenTest];\r
- if (curAndLenPrice < opt->price)\r
+ UInt32 price = normalMatchPrice + p->lenEnc.prices[posState][(size_t)len - LZMA_MATCH_LEN_MIN];\r
{\r
- opt->price = curAndLenPrice;\r
- opt->posPrev = cur;\r
- opt->backPrev = curBack + LZMA_NUM_REPS;\r
- opt->prev1IsChar = False;\r
- }\r
+ COptimal *opt;\r
+ unsigned lenToPosState = len - 2; lenToPosState = GetLenToPosState2(lenToPosState);\r
+ if (dist < kNumFullDistances)\r
+ price += p->distancesPrices[lenToPosState][dist & (kNumFullDistances - 1)];\r
+ else\r
+ price += p->posSlotPrices[lenToPosState][posSlot] + p->alignPrices[dist & kAlignMask];\r
+ \r
+ opt = &p->opt[cur + len];\r
+ if (price < opt->price)\r
+ {\r
+ opt->price = price;\r
+ opt->len = len;\r
+ opt->dist = dist + LZMA_NUM_REPS;\r
+ opt->extra = 0;\r
+ }\r
}\r
\r
- if (/*_maxMode && */lenTest == matches[offs])\r
+ if (/*_maxMode && */ len == matches[offs])\r
{\r
- /* Try Match + Literal + Rep0 */\r
- const Byte *data2 = data - curBack - 1;\r
- UInt32 lenTest2 = lenTest + 1;\r
- UInt32 limit = lenTest2 + p->numFastBytes;\r
+ // MATCH : LIT : REP_0\r
+\r
+ const Byte *data2 = data - dist - 1;\r
+ unsigned len2 = len + 1;\r
+ unsigned limit = len2 + p->numFastBytes;\r
if (limit > numAvailFull)\r
limit = numAvailFull;\r
- for (; lenTest2 < limit && data[lenTest2] == data2[lenTest2]; lenTest2++);\r
- lenTest2 -= lenTest + 1;\r
- if (lenTest2 >= 2)\r
+ \r
+ for (; len2 < limit && data[len2] == data2[len2]; len2++);\r
+ \r
+ len2 -= len;\r
+ \r
+ if (len2 >= 3)\r
{\r
- UInt32 nextRepMatchPrice;\r
- UInt32 state2 = kMatchNextStates[state];\r
- UInt32 posStateNext = (position + lenTest) & p->pbMask;\r
- UInt32 curAndLenCharPrice = curAndLenPrice +\r
- GET_PRICE_0(p->isMatch[state2][posStateNext]) +\r
- LitEnc_GetPriceMatched(LIT_PROBS(position + lenTest, data[lenTest - 1]),\r
- data[lenTest], data2[lenTest], p->ProbPrices);\r
- state2 = kLiteralNextStates[state2];\r
- posStateNext = (posStateNext + 1) & p->pbMask;\r
- nextRepMatchPrice = curAndLenCharPrice +\r
- GET_PRICE_1(p->isMatch[state2][posStateNext]) +\r
- GET_PRICE_1(p->isRep[state2]);\r
- \r
- /* for (; lenTest2 >= 2; lenTest2--) */\r
+ unsigned state2 = kMatchNextStates[state];\r
+ unsigned posState2 = (position + len) & p->pbMask;\r
+ unsigned offset;\r
+ price += GET_PRICE_0(p->isMatch[state2][posState2]);\r
+ price += LitEnc_Matched_GetPrice(LIT_PROBS(position + len, data[(size_t)len - 1]),\r
+ data[len], data2[len], p->ProbPrices);\r
+\r
+ // state2 = kLiteralNextStates[state2];\r
+ state2 = kState_LitAfterMatch;\r
+\r
+ posState2 = (posState2 + 1) & p->pbMask;\r
+ price += GetPrice_Rep_0(p, state2, posState2);\r
+\r
+ offset = cur + len + len2;\r
+ while (last < offset)\r
+ p->opt[++last].price = kInfinityPrice;\r
+ // do\r
{\r
- UInt32 offset = cur + lenTest + 1 + lenTest2;\r
- UInt32 curAndLenPrice2;\r
+ UInt32 price2;\r
COptimal *opt;\r
- while (lenEnd < offset)\r
- p->opt[++lenEnd].price = kInfinityPrice;\r
- curAndLenPrice2 = nextRepMatchPrice + GetRepPrice(p, 0, lenTest2, state2, posStateNext);\r
+ len2--;\r
+ // price2 = price + GetPrice_Len_Rep_0(p, len2, state2, posState2);\r
+ price2 = price + p->repLenEnc.prices[posState2][len2 - LZMA_MATCH_LEN_MIN];\r
opt = &p->opt[offset];\r
- if (curAndLenPrice2 < opt->price)\r
+ // offset--;\r
+ if (price2 < opt->price)\r
{\r
- opt->price = curAndLenPrice2;\r
- opt->posPrev = cur + lenTest + 1;\r
- opt->backPrev = 0;\r
- opt->prev1IsChar = True;\r
- opt->prev2 = True;\r
- opt->posPrev2 = cur;\r
- opt->backPrev2 = curBack + LZMA_NUM_REPS;\r
+ opt->price = price2;\r
+ opt->len = len2;\r
+ opt->extra = (CExtra)(len + 1);\r
+ opt->dist = dist + LZMA_NUM_REPS;\r
}\r
}\r
+ // while (len2 >= 3);\r
}\r
+ \r
offs += 2;\r
if (offs == numPairs)\r
break;\r
- curBack = matches[offs + 1];\r
- if (curBack >= kNumFullDistances)\r
- GetPosSlot2(curBack, posSlot);\r
+ dist = matches[(size_t)offs + 1];\r
+ // if (dist >= kNumFullDistances)\r
+ GetPosSlot2(dist, posSlot);\r
}\r
}\r
}\r
}\r
}\r
\r
+\r
+\r
#define ChangePair(smallDist, bigDist) (((bigDist) >> 7) > (smallDist))\r
\r
-static UInt32 GetOptimumFast(CLzmaEnc *p, UInt32 *backRes)\r
+\r
+\r
+static unsigned GetOptimumFast(CLzmaEnc *p)\r
{\r
- UInt32 numAvail, mainLen, mainDist, numPairs, repIndex, repLen, i;\r
+ UInt32 numAvail, mainDist;\r
+ unsigned mainLen, numPairs, repIndex, repLen, i;\r
const Byte *data;\r
- const UInt32 *matches;\r
\r
if (p->additionalOffset == 0)\r
mainLen = ReadMatchDistances(p, &numPairs);\r
else\r
{\r
- mainLen = p->longestMatchLength;\r
+ mainLen = p->longestMatchLen;\r
numPairs = p->numPairs;\r
}\r
\r
numAvail = p->numAvail;\r
- *backRes = (UInt32)-1;\r
+ p->backRes = MARK_LIT;\r
if (numAvail < 2)\r
return 1;\r
if (numAvail > LZMA_MATCH_LEN_MAX)\r
numAvail = LZMA_MATCH_LEN_MAX;\r
data = p->matchFinder.GetPointerToCurrentPos(p->matchFinderObj) - 1;\r
-\r
repLen = repIndex = 0;\r
+ \r
for (i = 0; i < LZMA_NUM_REPS; i++)\r
{\r
- UInt32 len;\r
- const Byte *data2 = data - p->reps[i] - 1;\r
+ unsigned len;\r
+ const Byte *data2 = data - p->reps[i];\r
if (data[0] != data2[0] || data[1] != data2[1])\r
continue;\r
for (len = 2; len < numAvail && data[len] == data2[len]; len++);\r
if (len >= p->numFastBytes)\r
{\r
- *backRes = i;\r
- MovePos(p, len - 1);\r
+ p->backRes = i;\r
+ MOVE_POS(p, len - 1)\r
return len;\r
}\r
if (len > repLen)\r
}\r
}\r
\r
- matches = p->matches;\r
if (mainLen >= p->numFastBytes)\r
{\r
- *backRes = matches[numPairs - 1] + LZMA_NUM_REPS;\r
- MovePos(p, mainLen - 1);\r
+ p->backRes = p->matches[(size_t)numPairs - 1] + LZMA_NUM_REPS;\r
+ MOVE_POS(p, mainLen - 1)\r
return mainLen;\r
}\r
\r
mainDist = 0; /* for GCC */\r
+ \r
if (mainLen >= 2)\r
{\r
- mainDist = matches[numPairs - 1];\r
- while (numPairs > 2 && mainLen == matches[numPairs - 4] + 1)\r
+ mainDist = p->matches[(size_t)numPairs - 1];\r
+ while (numPairs > 2)\r
{\r
- if (!ChangePair(matches[numPairs - 3], mainDist))\r
+ UInt32 dist2;\r
+ if (mainLen != p->matches[(size_t)numPairs - 4] + 1)\r
+ break;\r
+ dist2 = p->matches[(size_t)numPairs - 3];\r
+ if (!ChangePair(dist2, mainDist))\r
break;\r
numPairs -= 2;\r
- mainLen = matches[numPairs - 2];\r
- mainDist = matches[numPairs - 1];\r
+ mainLen--;\r
+ mainDist = dist2;\r
}\r
if (mainLen == 2 && mainDist >= 0x80)\r
mainLen = 1;\r
}\r
\r
- if (repLen >= 2 && (\r
- (repLen + 1 >= mainLen) ||\r
- (repLen + 2 >= mainLen && mainDist >= (1 << 9)) ||\r
- (repLen + 3 >= mainLen && mainDist >= (1 << 15))))\r
+ if (repLen >= 2)\r
+ if ( repLen + 1 >= mainLen\r
+ || (repLen + 2 >= mainLen && mainDist >= (1 << 9))\r
+ || (repLen + 3 >= mainLen && mainDist >= (1 << 15)))\r
{\r
- *backRes = repIndex;\r
- MovePos(p, repLen - 1);\r
+ p->backRes = repIndex;\r
+ MOVE_POS(p, repLen - 1)\r
return repLen;\r
}\r
\r
if (mainLen < 2 || numAvail <= 2)\r
return 1;\r
\r
- p->longestMatchLength = ReadMatchDistances(p, &p->numPairs);\r
- if (p->longestMatchLength >= 2)\r
{\r
- UInt32 newDistance = matches[p->numPairs - 1];\r
- if ((p->longestMatchLength >= mainLen && newDistance < mainDist) ||\r
- (p->longestMatchLength == mainLen + 1 && !ChangePair(mainDist, newDistance)) ||\r
- (p->longestMatchLength > mainLen + 1) ||\r
- (p->longestMatchLength + 1 >= mainLen && mainLen >= 3 && ChangePair(newDistance, mainDist)))\r
- return 1;\r
+ unsigned len1 = ReadMatchDistances(p, &p->numPairs);\r
+ p->longestMatchLen = len1;\r
+ \r
+ if (len1 >= 2)\r
+ {\r
+ UInt32 newDist = p->matches[(size_t)p->numPairs - 1];\r
+ if ( (len1 >= mainLen && newDist < mainDist)\r
+ || (len1 == mainLen + 1 && !ChangePair(mainDist, newDist))\r
+ || (len1 > mainLen + 1)\r
+ || (len1 + 1 >= mainLen && mainLen >= 3 && ChangePair(newDist, mainDist)))\r
+ return 1;\r
+ }\r
}\r
\r
data = p->matchFinder.GetPointerToCurrentPos(p->matchFinderObj) - 1;\r
+ \r
for (i = 0; i < LZMA_NUM_REPS; i++)\r
{\r
- UInt32 len, limit;\r
- const Byte *data2 = data - p->reps[i] - 1;\r
+ unsigned len, limit;\r
+ const Byte *data2 = data - p->reps[i];\r
if (data[0] != data2[0] || data[1] != data2[1])\r
continue;\r
limit = mainLen - 1;\r
- for (len = 2; len < limit && data[len] == data2[len]; len++);\r
- if (len >= limit)\r
- return 1;\r
+ for (len = 2;; len++)\r
+ {\r
+ if (len >= limit)\r
+ return 1;\r
+ if (data[len] != data2[len])\r
+ break;\r
+ }\r
+ }\r
+ \r
+ p->backRes = mainDist + LZMA_NUM_REPS;\r
+ if (mainLen != 2)\r
+ {\r
+ MOVE_POS(p, mainLen - 2)\r
}\r
- *backRes = mainDist + LZMA_NUM_REPS;\r
- MovePos(p, mainLen - 2);\r
return mainLen;\r
}\r
\r
-static void WriteEndMarker(CLzmaEnc *p, UInt32 posState)\r
+\r
+\r
+\r
+static void WriteEndMarker(CLzmaEnc *p, unsigned posState)\r
{\r
- UInt32 len;\r
- RangeEnc_EncodeBit(&p->rc, &p->isMatch[p->state][posState], 1);\r
- RangeEnc_EncodeBit(&p->rc, &p->isRep[p->state], 0);\r
+ UInt32 range;\r
+ range = p->rc.range;\r
+ {\r
+ UInt32 ttt, newBound;\r
+ CLzmaProb *prob = &p->isMatch[p->state][posState];\r
+ RC_BIT_PRE(&p->rc, prob)\r
+ RC_BIT_1(&p->rc, prob)\r
+ prob = &p->isRep[p->state];\r
+ RC_BIT_PRE(&p->rc, prob)\r
+ RC_BIT_0(&p->rc, prob)\r
+ }\r
p->state = kMatchNextStates[p->state];\r
- len = LZMA_MATCH_LEN_MIN;\r
- LenEnc_Encode2(&p->lenEnc, &p->rc, len - LZMA_MATCH_LEN_MIN, posState, !p->fastMode, p->ProbPrices);\r
- RcTree_Encode(&p->rc, p->posSlotEncoder[GetLenToPosState(len)], kNumPosSlotBits, (1 << kNumPosSlotBits) - 1);\r
- RangeEnc_EncodeDirectBits(&p->rc, (((UInt32)1 << 30) - 1) >> kNumAlignBits, 30 - kNumAlignBits);\r
- RcTree_ReverseEncode(&p->rc, p->posAlignEncoder, kNumAlignBits, kAlignMask);\r
+ \r
+ p->rc.range = range;\r
+ LenEnc_Encode(&p->lenProbs, &p->rc, 0, posState);\r
+ range = p->rc.range;\r
+\r
+ {\r
+ // RcTree_Encode_PosSlot(&p->rc, p->posSlotEncoder[0], (1 << kNumPosSlotBits) - 1);\r
+ CLzmaProb *probs = p->posSlotEncoder[0];\r
+ unsigned m = 1;\r
+ do\r
+ {\r
+ UInt32 ttt, newBound;\r
+ RC_BIT_PRE(p, probs + m)\r
+ RC_BIT_1(&p->rc, probs + m);\r
+ m = (m << 1) + 1;\r
+ }\r
+ while (m < (1 << kNumPosSlotBits));\r
+ }\r
+ {\r
+ // RangeEnc_EncodeDirectBits(&p->rc, ((UInt32)1 << (30 - kNumAlignBits)) - 1, 30 - kNumAlignBits); UInt32 range = p->range;\r
+ unsigned numBits = 30 - kNumAlignBits;\r
+ do\r
+ {\r
+ range >>= 1;\r
+ p->rc.low += range;\r
+ RC_NORM(&p->rc)\r
+ }\r
+ while (--numBits);\r
+ }\r
+ \r
+ {\r
+ // RcTree_ReverseEncode(&p->rc, p->posAlignEncoder, kNumAlignBits, kAlignMask);\r
+ CLzmaProb *probs = p->posAlignEncoder;\r
+ unsigned m = 1;\r
+ do\r
+ {\r
+ UInt32 ttt, newBound;\r
+ RC_BIT_PRE(p, probs + m)\r
+ RC_BIT_1(&p->rc, probs + m);\r
+ m = (m << 1) + 1;\r
+ }\r
+ while (m < kAlignTableSize);\r
+ }\r
+ p->rc.range = range;\r
}\r
\r
+\r
static SRes CheckErrors(CLzmaEnc *p)\r
{\r
if (p->result != SZ_OK)\r
return p->result;\r
}\r
\r
-static SRes Flush(CLzmaEnc *p, UInt32 nowPos)\r
+\r
+MY_NO_INLINE static SRes Flush(CLzmaEnc *p, UInt32 nowPos)\r
{\r
/* ReleaseMFStream(); */\r
p->finished = True;\r
return CheckErrors(p);\r
}\r
\r
+\r
+\r
static void FillAlignPrices(CLzmaEnc *p)\r
{\r
- UInt32 i;\r
- for (i = 0; i < kAlignTableSize; i++)\r
- p->alignPrices[i] = RcTree_ReverseGetPrice(p->posAlignEncoder, kNumAlignBits, i, p->ProbPrices);\r
+ unsigned i;\r
+ const CProbPrice *ProbPrices = p->ProbPrices;\r
+ const CLzmaProb *probs = p->posAlignEncoder;\r
p->alignPriceCount = 0;\r
+ for (i = 0; i < kAlignTableSize / 2; i++)\r
+ {\r
+ UInt32 price = 0;\r
+ unsigned symbol = i;\r
+ unsigned m = 1;\r
+ unsigned bit;\r
+ UInt32 prob;\r
+ bit = symbol & 1; symbol >>= 1; price += GET_PRICEa(probs[m], bit); m = (m << 1) + bit;\r
+ bit = symbol & 1; symbol >>= 1; price += GET_PRICEa(probs[m], bit); m = (m << 1) + bit;\r
+ bit = symbol & 1; symbol >>= 1; price += GET_PRICEa(probs[m], bit); m = (m << 1) + bit;\r
+ prob = probs[m];\r
+ p->alignPrices[i ] = price + GET_PRICEa_0(prob);\r
+ p->alignPrices[i + 8] = price + GET_PRICEa_1(prob);\r
+ // p->alignPrices[i] = RcTree_ReverseGetPrice(p->posAlignEncoder, kNumAlignBits, i, p->ProbPrices);\r
+ }\r
}\r
\r
+\r
static void FillDistancesPrices(CLzmaEnc *p)\r
{\r
UInt32 tempPrices[kNumFullDistances];\r
- UInt32 i, lenToPosState;\r
+ unsigned i, lenToPosState;\r
+\r
+ const CProbPrice *ProbPrices = p->ProbPrices;\r
+ p->matchPriceCount = 0;\r
+\r
for (i = kStartPosModelIndex; i < kNumFullDistances; i++)\r
{\r
- UInt32 posSlot = GetPosSlot1(i);\r
- UInt32 footerBits = ((posSlot >> 1) - 1);\r
- UInt32 base = ((2 | (posSlot & 1)) << footerBits);\r
- tempPrices[i] = RcTree_ReverseGetPrice(p->posEncoders + base - posSlot - 1, footerBits, i - base, p->ProbPrices);\r
+ unsigned posSlot = GetPosSlot1(i);\r
+ unsigned footerBits = ((posSlot >> 1) - 1);\r
+ unsigned base = ((2 | (posSlot & 1)) << footerBits);\r
+ // tempPrices[i] = RcTree_ReverseGetPrice(p->posEncoders + base, footerBits, i - base, p->ProbPrices);\r
+\r
+ const CLzmaProb *probs = p->posEncoders + base;\r
+ UInt32 price = 0;\r
+ unsigned m = 1;\r
+ unsigned symbol = i - base;\r
+ do\r
+ {\r
+ unsigned bit = symbol & 1;\r
+ symbol >>= 1;\r
+ price += GET_PRICEa(probs[m], bit);\r
+ m = (m << 1) + bit;\r
+ }\r
+ while (--footerBits);\r
+ tempPrices[i] = price;\r
}\r
\r
for (lenToPosState = 0; lenToPosState < kNumLenToPosStates; lenToPosState++)\r
{\r
- UInt32 posSlot;\r
+ unsigned posSlot;\r
const CLzmaProb *encoder = p->posSlotEncoder[lenToPosState];\r
UInt32 *posSlotPrices = p->posSlotPrices[lenToPosState];\r
- for (posSlot = 0; posSlot < p->distTableSize; posSlot++)\r
- posSlotPrices[posSlot] = RcTree_GetPrice(encoder, kNumPosSlotBits, posSlot, p->ProbPrices);\r
- for (posSlot = kEndPosModelIndex; posSlot < p->distTableSize; posSlot++)\r
- posSlotPrices[posSlot] += ((((posSlot >> 1) - 1) - kNumAlignBits) << kNumBitPriceShiftBits);\r
+ unsigned distTableSize = p->distTableSize;\r
+ const CLzmaProb *probs = encoder;\r
+ for (posSlot = 0; posSlot < distTableSize; posSlot += 2)\r
+ {\r
+ // posSlotPrices[posSlot] = RcTree_GetPrice(encoder, kNumPosSlotBits, posSlot, p->ProbPrices);\r
+ UInt32 price = 0;\r
+ unsigned bit;\r
+ unsigned symbol = (posSlot >> 1) + (1 << (kNumPosSlotBits - 1));\r
+ UInt32 prob;\r
+ bit = symbol & 1; symbol >>= 1; price += GET_PRICEa(probs[symbol], bit);\r
+ bit = symbol & 1; symbol >>= 1; price += GET_PRICEa(probs[symbol], bit);\r
+ bit = symbol & 1; symbol >>= 1; price += GET_PRICEa(probs[symbol], bit);\r
+ bit = symbol & 1; symbol >>= 1; price += GET_PRICEa(probs[symbol], bit);\r
+ bit = symbol & 1; symbol >>= 1; price += GET_PRICEa(probs[symbol], bit);\r
+ prob = probs[(posSlot >> 1) + (1 << (kNumPosSlotBits - 1))];\r
+ posSlotPrices[posSlot ] = price + GET_PRICEa_0(prob);\r
+ posSlotPrices[posSlot + 1] = price + GET_PRICEa_1(prob);\r
+ }\r
+ for (posSlot = kEndPosModelIndex; posSlot < distTableSize; posSlot++)\r
+ posSlotPrices[posSlot] += ((UInt32)(((posSlot >> 1) - 1) - kNumAlignBits) << kNumBitPriceShiftBits);\r
\r
{\r
UInt32 *distancesPrices = p->distancesPrices[lenToPosState];\r
- for (i = 0; i < kStartPosModelIndex; i++)\r
- distancesPrices[i] = posSlotPrices[i];\r
- for (; i < kNumFullDistances; i++)\r
- distancesPrices[i] = posSlotPrices[GetPosSlot1(i)] + tempPrices[i];\r
+ {\r
+ distancesPrices[0] = posSlotPrices[0];\r
+ distancesPrices[1] = posSlotPrices[1];\r
+ distancesPrices[2] = posSlotPrices[2];\r
+ distancesPrices[3] = posSlotPrices[3];\r
+ }\r
+ for (i = 4; i < kNumFullDistances; i += 2)\r
+ {\r
+ UInt32 slotPrice = posSlotPrices[GetPosSlot1(i)];\r
+ distancesPrices[i ] = slotPrice + tempPrices[i];\r
+ distancesPrices[i + 1] = slotPrice + tempPrices[i + 1];\r
+ }\r
}\r
}\r
- p->matchPriceCount = 0;\r
}\r
\r
+\r
+\r
void LzmaEnc_Construct(CLzmaEnc *p)\r
{\r
RangeEnc_Construct(&p->rc);\r
LzmaEnc_InitPriceTables(p->ProbPrices);\r
p->litProbs = NULL;\r
p->saveState.litProbs = NULL;\r
+\r
}\r
\r
-CLzmaEncHandle LzmaEnc_Create(ISzAlloc *alloc)\r
+CLzmaEncHandle LzmaEnc_Create(ISzAllocPtr alloc)\r
{\r
void *p;\r
- p = alloc->Alloc(alloc, sizeof(CLzmaEnc));\r
+ p = ISzAlloc_Alloc(alloc, sizeof(CLzmaEnc));\r
if (p)\r
LzmaEnc_Construct((CLzmaEnc *)p);\r
return p;\r
}\r
\r
-void LzmaEnc_FreeLits(CLzmaEnc *p, ISzAlloc *alloc)\r
+void LzmaEnc_FreeLits(CLzmaEnc *p, ISzAllocPtr alloc)\r
{\r
- alloc->Free(alloc, p->litProbs);\r
- alloc->Free(alloc, p->saveState.litProbs);\r
+ ISzAlloc_Free(alloc, p->litProbs);\r
+ ISzAlloc_Free(alloc, p->saveState.litProbs);\r
p->litProbs = NULL;\r
p->saveState.litProbs = NULL;\r
}\r
\r
-void LzmaEnc_Destruct(CLzmaEnc *p, ISzAlloc *alloc, ISzAlloc *allocBig)\r
+void LzmaEnc_Destruct(CLzmaEnc *p, ISzAllocPtr alloc, ISzAllocPtr allocBig)\r
{\r
#ifndef _7ZIP_ST\r
MatchFinderMt_Destruct(&p->matchFinderMt, allocBig);\r
RangeEnc_Free(&p->rc, alloc);\r
}\r
\r
-void LzmaEnc_Destroy(CLzmaEncHandle p, ISzAlloc *alloc, ISzAlloc *allocBig)\r
+void LzmaEnc_Destroy(CLzmaEncHandle p, ISzAllocPtr alloc, ISzAllocPtr allocBig)\r
{\r
LzmaEnc_Destruct((CLzmaEnc *)p, alloc, allocBig);\r
- alloc->Free(alloc, p);\r
+ ISzAlloc_Free(alloc, p);\r
}\r
\r
-static SRes LzmaEnc_CodeOneBlock(CLzmaEnc *p, Bool useLimits, UInt32 maxPackSize, UInt32 maxUnpackSize)\r
+\r
+static SRes LzmaEnc_CodeOneBlock(CLzmaEnc *p, UInt32 maxPackSize, UInt32 maxUnpackSize)\r
{\r
UInt32 nowPos32, startPos32;\r
if (p->needInit)\r
\r
if (p->nowPos64 == 0)\r
{\r
- UInt32 numPairs;\r
+ unsigned numPairs;\r
Byte curByte;\r
if (p->matchFinder.GetNumAvailableBytes(p->matchFinderObj) == 0)\r
return Flush(p, nowPos32);\r
ReadMatchDistances(p, &numPairs);\r
- RangeEnc_EncodeBit(&p->rc, &p->isMatch[p->state][0], 0);\r
- p->state = kLiteralNextStates[p->state];\r
+ RangeEnc_EncodeBit_0(&p->rc, &p->isMatch[kState_Start][0]);\r
+ // p->state = kLiteralNextStates[p->state];\r
curByte = *(p->matchFinder.GetPointerToCurrentPos(p->matchFinderObj) - p->additionalOffset);\r
LitEnc_Encode(&p->rc, p->litProbs, curByte);\r
p->additionalOffset--;\r
}\r
\r
if (p->matchFinder.GetNumAvailableBytes(p->matchFinderObj) != 0)\r
+ \r
for (;;)\r
{\r
- UInt32 pos, len, posState;\r
-\r
+ UInt32 dist;\r
+ unsigned len, posState;\r
+ UInt32 range, ttt, newBound;\r
+ CLzmaProb *probs;\r
+ \r
if (p->fastMode)\r
- len = GetOptimumFast(p, &pos);\r
+ len = GetOptimumFast(p);\r
else\r
- len = GetOptimum(p, nowPos32, &pos);\r
+ {\r
+ unsigned oci = p->optCur;\r
+ if (p->optEnd == oci)\r
+ len = GetOptimum(p, nowPos32);\r
+ else\r
+ {\r
+ const COptimal *opt = &p->opt[oci];\r
+ len = opt->len;\r
+ p->backRes = opt->dist;\r
+ p->optCur = oci + 1;\r
+ }\r
+ }\r
+\r
+ posState = (unsigned)nowPos32 & p->pbMask;\r
+ range = p->rc.range;\r
+ probs = &p->isMatch[p->state][posState];\r
+ \r
+ RC_BIT_PRE(&p->rc, probs)\r
+ \r
+ dist = p->backRes;\r
\r
#ifdef SHOW_STAT2\r
- printf("\n pos = %4X, len = %u pos = %u", nowPos32, len, pos);\r
+ printf("\n pos = %6X, len = %3u pos = %6u", nowPos32, len, dist);\r
#endif\r
\r
- posState = nowPos32 & p->pbMask;\r
- if (len == 1 && pos == (UInt32)-1)\r
+ if (dist == MARK_LIT)\r
{\r
Byte curByte;\r
- CLzmaProb *probs;\r
const Byte *data;\r
+ unsigned state;\r
\r
- RangeEnc_EncodeBit(&p->rc, &p->isMatch[p->state][posState], 0);\r
+ RC_BIT_0(&p->rc, probs);\r
+ p->rc.range = range;\r
data = p->matchFinder.GetPointerToCurrentPos(p->matchFinderObj) - p->additionalOffset;\r
- curByte = *data;\r
probs = LIT_PROBS(nowPos32, *(data - 1));\r
- if (IsCharState(p->state))\r
+ curByte = *data;\r
+ state = p->state;\r
+ p->state = kLiteralNextStates[state];\r
+ if (IsLitState(state))\r
LitEnc_Encode(&p->rc, probs, curByte);\r
else\r
- LitEnc_EncodeMatched(&p->rc, probs, curByte, *(data - p->reps[0] - 1));\r
- p->state = kLiteralNextStates[p->state];\r
+ LitEnc_EncodeMatched(&p->rc, probs, curByte, *(data - p->reps[0]));\r
}\r
else\r
{\r
- RangeEnc_EncodeBit(&p->rc, &p->isMatch[p->state][posState], 1);\r
- if (pos < LZMA_NUM_REPS)\r
+ RC_BIT_1(&p->rc, probs);\r
+ probs = &p->isRep[p->state];\r
+ RC_BIT_PRE(&p->rc, probs)\r
+ \r
+ if (dist < LZMA_NUM_REPS)\r
{\r
- RangeEnc_EncodeBit(&p->rc, &p->isRep[p->state], 1);\r
- if (pos == 0)\r
+ RC_BIT_1(&p->rc, probs);\r
+ probs = &p->isRepG0[p->state];\r
+ RC_BIT_PRE(&p->rc, probs)\r
+ if (dist == 0)\r
{\r
- RangeEnc_EncodeBit(&p->rc, &p->isRepG0[p->state], 0);\r
- RangeEnc_EncodeBit(&p->rc, &p->isRep0Long[p->state][posState], ((len == 1) ? 0 : 1));\r
+ RC_BIT_0(&p->rc, probs);\r
+ probs = &p->isRep0Long[p->state][posState];\r
+ RC_BIT_PRE(&p->rc, probs)\r
+ if (len != 1)\r
+ {\r
+ RC_BIT_1_BASE(&p->rc, probs);\r
+ }\r
+ else\r
+ {\r
+ RC_BIT_0_BASE(&p->rc, probs);\r
+ p->state = kShortRepNextStates[p->state];\r
+ }\r
}\r
else\r
{\r
- UInt32 distance = p->reps[pos];\r
- RangeEnc_EncodeBit(&p->rc, &p->isRepG0[p->state], 1);\r
- if (pos == 1)\r
- RangeEnc_EncodeBit(&p->rc, &p->isRepG1[p->state], 0);\r
+ RC_BIT_1(&p->rc, probs);\r
+ probs = &p->isRepG1[p->state];\r
+ RC_BIT_PRE(&p->rc, probs)\r
+ if (dist == 1)\r
+ {\r
+ RC_BIT_0_BASE(&p->rc, probs);\r
+ dist = p->reps[1];\r
+ }\r
else\r
{\r
- RangeEnc_EncodeBit(&p->rc, &p->isRepG1[p->state], 1);\r
- RangeEnc_EncodeBit(&p->rc, &p->isRepG2[p->state], pos - 2);\r
- if (pos == 3)\r
+ RC_BIT_1(&p->rc, probs);\r
+ probs = &p->isRepG2[p->state];\r
+ RC_BIT_PRE(&p->rc, probs)\r
+ if (dist == 2)\r
+ {\r
+ RC_BIT_0_BASE(&p->rc, probs);\r
+ dist = p->reps[2];\r
+ }\r
+ else\r
+ {\r
+ RC_BIT_1_BASE(&p->rc, probs);\r
+ dist = p->reps[3];\r
p->reps[3] = p->reps[2];\r
+ }\r
p->reps[2] = p->reps[1];\r
}\r
p->reps[1] = p->reps[0];\r
- p->reps[0] = distance;\r
+ p->reps[0] = dist;\r
}\r
- if (len == 1)\r
- p->state = kShortRepNextStates[p->state];\r
- else\r
+\r
+ RC_NORM(&p->rc)\r
+\r
+ p->rc.range = range;\r
+\r
+ if (len != 1)\r
{\r
- LenEnc_Encode2(&p->repLenEnc, &p->rc, len - LZMA_MATCH_LEN_MIN, posState, !p->fastMode, p->ProbPrices);\r
+ LenEnc_Encode(&p->repLenProbs, &p->rc, len - LZMA_MATCH_LEN_MIN, posState);\r
+ if (!p->fastMode)\r
+ if (--p->repLenEnc.counters[posState] == 0)\r
+ LenPriceEnc_UpdateTable(&p->repLenEnc, posState, &p->repLenProbs, p->ProbPrices);\r
+\r
p->state = kRepNextStates[p->state];\r
}\r
}\r
else\r
{\r
- UInt32 posSlot;\r
- RangeEnc_EncodeBit(&p->rc, &p->isRep[p->state], 0);\r
+ unsigned posSlot;\r
+ RC_BIT_0(&p->rc, probs);\r
+ p->rc.range = range;\r
p->state = kMatchNextStates[p->state];\r
- LenEnc_Encode2(&p->lenEnc, &p->rc, len - LZMA_MATCH_LEN_MIN, posState, !p->fastMode, p->ProbPrices);\r
- pos -= LZMA_NUM_REPS;\r
- GetPosSlot(pos, posSlot);\r
- RcTree_Encode(&p->rc, p->posSlotEncoder[GetLenToPosState(len)], kNumPosSlotBits, posSlot);\r
+\r
+ LenEnc_Encode(&p->lenProbs, &p->rc, len - LZMA_MATCH_LEN_MIN, posState);\r
+ if (!p->fastMode)\r
+ if (--p->lenEnc.counters[posState] == 0)\r
+ LenPriceEnc_UpdateTable(&p->lenEnc, posState, &p->lenProbs, p->ProbPrices);\r
+\r
+ dist -= LZMA_NUM_REPS;\r
+ p->reps[3] = p->reps[2];\r
+ p->reps[2] = p->reps[1];\r
+ p->reps[1] = p->reps[0];\r
+ p->reps[0] = dist + 1;\r
\r
- if (posSlot >= kStartPosModelIndex)\r
+ p->matchPriceCount++;\r
+ GetPosSlot(dist, posSlot);\r
+ // RcTree_Encode_PosSlot(&p->rc, p->posSlotEncoder[GetLenToPosState(len)], posSlot);\r
+ {\r
+ UInt32 symbol = posSlot + (1 << kNumPosSlotBits);\r
+ range = p->rc.range;\r
+ probs = p->posSlotEncoder[GetLenToPosState(len)];\r
+ do\r
+ {\r
+ CLzmaProb *prob = probs + (symbol >> kNumPosSlotBits);\r
+ UInt32 bit = (symbol >> (kNumPosSlotBits - 1)) & 1;\r
+ symbol <<= 1;\r
+ RC_BIT(&p->rc, prob, bit);\r
+ }\r
+ while (symbol < (1 << kNumPosSlotBits * 2));\r
+ p->rc.range = range;\r
+ }\r
+ \r
+ if (dist >= kStartPosModelIndex)\r
{\r
- UInt32 footerBits = ((posSlot >> 1) - 1);\r
- UInt32 base = ((2 | (posSlot & 1)) << footerBits);\r
- UInt32 posReduced = pos - base;\r
+ unsigned footerBits = ((posSlot >> 1) - 1);\r
\r
- if (posSlot < kEndPosModelIndex)\r
- RcTree_ReverseEncode(&p->rc, p->posEncoders + base - posSlot - 1, footerBits, posReduced);\r
+ if (dist < kNumFullDistances)\r
+ {\r
+ unsigned base = ((2 | (posSlot & 1)) << footerBits);\r
+ RcTree_ReverseEncode(&p->rc, p->posEncoders + base, footerBits, dist - base);\r
+ }\r
else\r
{\r
- RangeEnc_EncodeDirectBits(&p->rc, posReduced >> kNumAlignBits, footerBits - kNumAlignBits);\r
- RcTree_ReverseEncode(&p->rc, p->posAlignEncoder, kNumAlignBits, posReduced & kAlignMask);\r
- p->alignPriceCount++;\r
+ UInt32 pos2 = (dist | 0xF) << (32 - footerBits);\r
+ range = p->rc.range;\r
+ // RangeEnc_EncodeDirectBits(&p->rc, posReduced >> kNumAlignBits, footerBits - kNumAlignBits);\r
+ /*\r
+ do\r
+ {\r
+ range >>= 1;\r
+ p->rc.low += range & (0 - ((dist >> --footerBits) & 1));\r
+ RC_NORM(&p->rc)\r
+ }\r
+ while (footerBits > kNumAlignBits);\r
+ */\r
+ do\r
+ {\r
+ range >>= 1;\r
+ p->rc.low += range & (0 - (pos2 >> 31));\r
+ pos2 += pos2;\r
+ RC_NORM(&p->rc)\r
+ }\r
+ while (pos2 != 0xF0000000);\r
+\r
+\r
+ // RcTree_ReverseEncode(&p->rc, p->posAlignEncoder, kNumAlignBits, posReduced & kAlignMask);\r
+\r
+ {\r
+ unsigned m = 1;\r
+ unsigned bit;\r
+ bit = dist & 1; dist >>= 1; RC_BIT(&p->rc, p->posAlignEncoder + m, bit); m = (m << 1) + bit;\r
+ bit = dist & 1; dist >>= 1; RC_BIT(&p->rc, p->posAlignEncoder + m, bit); m = (m << 1) + bit;\r
+ bit = dist & 1; dist >>= 1; RC_BIT(&p->rc, p->posAlignEncoder + m, bit); m = (m << 1) + bit;\r
+ bit = dist & 1; RC_BIT(&p->rc, p->posAlignEncoder + m, bit);\r
+ p->rc.range = range;\r
+ p->alignPriceCount++;\r
+ }\r
}\r
}\r
- p->reps[3] = p->reps[2];\r
- p->reps[2] = p->reps[1];\r
- p->reps[1] = p->reps[0];\r
- p->reps[0] = pos;\r
- p->matchPriceCount++;\r
}\r
}\r
- p->additionalOffset -= len;\r
+\r
nowPos32 += len;\r
+ p->additionalOffset -= len;\r
+ \r
if (p->additionalOffset == 0)\r
{\r
UInt32 processed;\r
+\r
if (!p->fastMode)\r
{\r
if (p->matchPriceCount >= (1 << 7))\r
if (p->alignPriceCount >= kAlignTableSize)\r
FillAlignPrices(p);\r
}\r
+ \r
if (p->matchFinder.GetNumAvailableBytes(p->matchFinderObj) == 0)\r
break;\r
processed = nowPos32 - startPos32;\r
- if (useLimits)\r
+ \r
+ if (maxPackSize)\r
{\r
- if (processed + kNumOpts + 300 >= maxUnpackSize ||\r
- RangeEnc_GetProcessed(&p->rc) + kNumOpts * 2 >= maxPackSize)\r
+ if (processed + kNumOpts + 300 >= maxUnpackSize\r
+ || RangeEnc_GetProcessed_sizet(&p->rc) + kPackReserve >= maxPackSize)\r
break;\r
}\r
else if (processed >= (1 << 17))\r
}\r
}\r
}\r
+\r
p->nowPos64 += nowPos32 - startPos32;\r
return Flush(p, nowPos32);\r
}\r
\r
+\r
+\r
#define kBigHashDicLimit ((UInt32)1 << 24)\r
\r
-static SRes LzmaEnc_Alloc(CLzmaEnc *p, UInt32 keepWindowSize, ISzAlloc *alloc, ISzAlloc *allocBig)\r
+static SRes LzmaEnc_Alloc(CLzmaEnc *p, UInt32 keepWindowSize, ISzAllocPtr alloc, ISzAllocPtr allocBig)\r
{\r
UInt32 beforeSize = kNumOpts;\r
if (!RangeEnc_Alloc(&p->rc, alloc))\r
if (!p->litProbs || !p->saveState.litProbs || p->lclp != lclp)\r
{\r
LzmaEnc_FreeLits(p, alloc);\r
- p->litProbs = (CLzmaProb *)alloc->Alloc(alloc, ((UInt32)0x300 << lclp) * sizeof(CLzmaProb));\r
- p->saveState.litProbs = (CLzmaProb *)alloc->Alloc(alloc, ((UInt32)0x300 << lclp) * sizeof(CLzmaProb));\r
+ p->litProbs = (CLzmaProb *)ISzAlloc_Alloc(alloc, ((UInt32)0x300 << lclp) * sizeof(CLzmaProb));\r
+ p->saveState.litProbs = (CLzmaProb *)ISzAlloc_Alloc(alloc, ((UInt32)0x300 << lclp) * sizeof(CLzmaProb));\r
if (!p->litProbs || !p->saveState.litProbs)\r
{\r
LzmaEnc_FreeLits(p, alloc);\r
#ifndef _7ZIP_ST\r
if (p->mtMode)\r
{\r
- RINOK(MatchFinderMt_Create(&p->matchFinderMt, p->dictSize, beforeSize, p->numFastBytes, LZMA_MATCH_LEN_MAX, allocBig));\r
+ RINOK(MatchFinderMt_Create(&p->matchFinderMt, p->dictSize, beforeSize, p->numFastBytes,\r
+ LZMA_MATCH_LEN_MAX\r
+ + 1 /* 18.04 */\r
+ , allocBig));\r
p->matchFinderObj = &p->matchFinderMt;\r
+ p->matchFinderBase.bigHash = (Byte)(\r
+ (p->dictSize > kBigHashDicLimit && p->matchFinderBase.hashMask >= 0xFFFFFF) ? 1 : 0);\r
MatchFinderMt_CreateVTable(&p->matchFinderMt, &p->matchFinder);\r
}\r
else\r
\r
void LzmaEnc_Init(CLzmaEnc *p)\r
{\r
- UInt32 i;\r
+ unsigned i;\r
p->state = 0;\r
- for (i = 0 ; i < LZMA_NUM_REPS; i++)\r
- p->reps[i] = 0;\r
+ p->reps[0] =\r
+ p->reps[1] =\r
+ p->reps[2] =\r
+ p->reps[3] = 1;\r
\r
RangeEnc_Init(&p->rc);\r
\r
+ for (i = 0; i < (1 << kNumAlignBits); i++)\r
+ p->posAlignEncoder[i] = kProbInitValue;\r
\r
for (i = 0; i < kNumStates; i++)\r
{\r
- UInt32 j;\r
+ unsigned j;\r
for (j = 0; j < LZMA_NUM_PB_STATES_MAX; j++)\r
{\r
p->isMatch[i][j] = kProbInitValue;\r
p->isRepG2[i] = kProbInitValue;\r
}\r
\r
- {\r
- UInt32 num = (UInt32)0x300 << (p->lp + p->lc);\r
- CLzmaProb *probs = p->litProbs;\r
- for (i = 0; i < num; i++)\r
- probs[i] = kProbInitValue;\r
- }\r
-\r
{\r
for (i = 0; i < kNumLenToPosStates; i++)\r
{\r
CLzmaProb *probs = p->posSlotEncoder[i];\r
- UInt32 j;\r
+ unsigned j;\r
for (j = 0; j < (1 << kNumPosSlotBits); j++)\r
probs[j] = kProbInitValue;\r
}\r
}\r
{\r
- for (i = 0; i < kNumFullDistances - kEndPosModelIndex; i++)\r
+ for (i = 0; i < kNumFullDistances; i++)\r
p->posEncoders[i] = kProbInitValue;\r
}\r
\r
- LenEnc_Init(&p->lenEnc.p);\r
- LenEnc_Init(&p->repLenEnc.p);\r
+ {\r
+ UInt32 num = (UInt32)0x300 << (p->lp + p->lc);\r
+ UInt32 k;\r
+ CLzmaProb *probs = p->litProbs;\r
+ for (k = 0; k < num; k++)\r
+ probs[k] = kProbInitValue;\r
+ }\r
\r
- for (i = 0; i < (1 << kNumAlignBits); i++)\r
- p->posAlignEncoder[i] = kProbInitValue;\r
\r
- p->optimumEndIndex = 0;\r
- p->optimumCurrentIndex = 0;\r
+ LenEnc_Init(&p->lenProbs);\r
+ LenEnc_Init(&p->repLenProbs);\r
+\r
+ p->optEnd = 0;\r
+ p->optCur = 0;\r
p->additionalOffset = 0;\r
\r
p->pbMask = (1 << p->pb) - 1;\r
- p->lpMask = (1 << p->lp) - 1;\r
+ p->lpMask = ((UInt32)0x100 << p->lp) - ((unsigned)0x100 >> p->lc);\r
}\r
\r
void LzmaEnc_InitPrices(CLzmaEnc *p)\r
p->lenEnc.tableSize =\r
p->repLenEnc.tableSize =\r
p->numFastBytes + 1 - LZMA_MATCH_LEN_MIN;\r
- LenPriceEnc_UpdateTables(&p->lenEnc, 1 << p->pb, p->ProbPrices);\r
- LenPriceEnc_UpdateTables(&p->repLenEnc, 1 << p->pb, p->ProbPrices);\r
+ LenPriceEnc_UpdateTables(&p->lenEnc, 1 << p->pb, &p->lenProbs, p->ProbPrices);\r
+ LenPriceEnc_UpdateTables(&p->repLenEnc, 1 << p->pb, &p->repLenProbs, p->ProbPrices);\r
}\r
\r
-static SRes LzmaEnc_AllocAndInit(CLzmaEnc *p, UInt32 keepWindowSize, ISzAlloc *alloc, ISzAlloc *allocBig)\r
+static SRes LzmaEnc_AllocAndInit(CLzmaEnc *p, UInt32 keepWindowSize, ISzAllocPtr alloc, ISzAllocPtr allocBig)\r
{\r
- UInt32 i;\r
- for (i = 0; i < (UInt32)kDicLogSizeMaxCompress; i++)\r
+ unsigned i;\r
+ for (i = kEndPosModelIndex / 2; i < kDicLogSizeMax; i++)\r
if (p->dictSize <= ((UInt32)1 << i))\r
break;\r
p->distTableSize = i * 2;\r
}\r
\r
static SRes LzmaEnc_Prepare(CLzmaEncHandle pp, ISeqOutStream *outStream, ISeqInStream *inStream,\r
- ISzAlloc *alloc, ISzAlloc *allocBig)\r
+ ISzAllocPtr alloc, ISzAllocPtr allocBig)\r
{\r
CLzmaEnc *p = (CLzmaEnc *)pp;\r
p->matchFinderBase.stream = inStream;\r
\r
SRes LzmaEnc_PrepareForLzma2(CLzmaEncHandle pp,\r
ISeqInStream *inStream, UInt32 keepWindowSize,\r
- ISzAlloc *alloc, ISzAlloc *allocBig)\r
+ ISzAllocPtr alloc, ISzAllocPtr allocBig)\r
{\r
CLzmaEnc *p = (CLzmaEnc *)pp;\r
p->matchFinderBase.stream = inStream;\r
}\r
\r
SRes LzmaEnc_MemPrepare(CLzmaEncHandle pp, const Byte *src, SizeT srcLen,\r
- UInt32 keepWindowSize, ISzAlloc *alloc, ISzAlloc *allocBig)\r
+ UInt32 keepWindowSize, ISzAllocPtr alloc, ISzAllocPtr allocBig)\r
{\r
CLzmaEnc *p = (CLzmaEnc *)pp;\r
LzmaEnc_SetInputBuf(p, src, srcLen);\r
p->needInit = 1;\r
\r
+ LzmaEnc_SetDataSize(pp, srcLen);\r
return LzmaEnc_AllocAndInit(p, keepWindowSize, alloc, allocBig);\r
}\r
\r
\r
typedef struct\r
{\r
- ISeqOutStream funcTable;\r
+ ISeqOutStream vt;\r
Byte *data;\r
SizeT rem;\r
Bool overflow;\r
-} CSeqOutStreamBuf;\r
+} CLzmaEnc_SeqOutStreamBuf;\r
\r
-static size_t MyWrite(void *pp, const void *data, size_t size)\r
+static size_t SeqOutStreamBuf_Write(const ISeqOutStream *pp, const void *data, size_t size)\r
{\r
- CSeqOutStreamBuf *p = (CSeqOutStreamBuf *)pp;\r
+ CLzmaEnc_SeqOutStreamBuf *p = CONTAINER_FROM_VTBL(pp, CLzmaEnc_SeqOutStreamBuf, vt);\r
if (p->rem < size)\r
{\r
size = p->rem;\r
CLzmaEnc *p = (CLzmaEnc *)pp;\r
UInt64 nowPos64;\r
SRes res;\r
- CSeqOutStreamBuf outStream;\r
+ CLzmaEnc_SeqOutStreamBuf outStream;\r
\r
- outStream.funcTable.Write = MyWrite;\r
+ outStream.vt.Write = SeqOutStreamBuf_Write;\r
outStream.data = dest;\r
outStream.rem = *destLen;\r
outStream.overflow = False;\r
if (reInit)\r
LzmaEnc_Init(p);\r
LzmaEnc_InitPrices(p);\r
+\r
nowPos64 = p->nowPos64;\r
RangeEnc_Init(&p->rc);\r
- p->rc.outStream = &outStream.funcTable;\r
+ p->rc.outStream = &outStream.vt;\r
+\r
+ if (desiredPackSize == 0)\r
+ return SZ_ERROR_OUTPUT_EOF;\r
\r
- res = LzmaEnc_CodeOneBlock(p, True, desiredPackSize, *unpackSize);\r
+ res = LzmaEnc_CodeOneBlock(p, desiredPackSize, *unpackSize);\r
\r
*unpackSize = (UInt32)(p->nowPos64 - nowPos64);\r
*destLen -= outStream.rem;\r
\r
for (;;)\r
{\r
- res = LzmaEnc_CodeOneBlock(p, False, 0, 0);\r
+ res = LzmaEnc_CodeOneBlock(p, 0, 0);\r
if (res != SZ_OK || p->finished)\r
break;\r
if (progress)\r
{\r
- res = progress->Progress(progress, p->nowPos64, RangeEnc_GetProcessed(&p->rc));\r
+ res = ICompressProgress_Progress(progress, p->nowPos64, RangeEnc_GetProcessed(&p->rc));\r
if (res != SZ_OK)\r
{\r
res = SZ_ERROR_PROGRESS;\r
LzmaEnc_Finish(p);\r
\r
/*\r
- if (res == S_OK && !Inline_MatchFinder_IsFinishedOK(&p->matchFinderBase))\r
+ if (res == SZ_OK && !Inline_MatchFinder_IsFinishedOK(&p->matchFinderBase))\r
res = SZ_ERROR_FAIL;\r
}\r
*/\r
\r
\r
SRes LzmaEnc_Encode(CLzmaEncHandle pp, ISeqOutStream *outStream, ISeqInStream *inStream, ICompressProgress *progress,\r
- ISzAlloc *alloc, ISzAlloc *allocBig)\r
+ ISzAllocPtr alloc, ISzAllocPtr allocBig)\r
{\r
RINOK(LzmaEnc_Prepare(pp, outStream, inStream, alloc, allocBig));\r
return LzmaEnc_Encode2((CLzmaEnc *)pp, progress);\r
}\r
\r
\r
+unsigned LzmaEnc_IsWriteEndMark(CLzmaEncHandle pp)\r
+{\r
+ return ((CLzmaEnc *)pp)->writeEndMark;\r
+}\r
+\r
+\r
SRes LzmaEnc_MemEncode(CLzmaEncHandle pp, Byte *dest, SizeT *destLen, const Byte *src, SizeT srcLen,\r
- int writeEndMark, ICompressProgress *progress, ISzAlloc *alloc, ISzAlloc *allocBig)\r
+ int writeEndMark, ICompressProgress *progress, ISzAllocPtr alloc, ISzAllocPtr allocBig)\r
{\r
SRes res;\r
CLzmaEnc *p = (CLzmaEnc *)pp;\r
\r
- CSeqOutStreamBuf outStream;\r
+ CLzmaEnc_SeqOutStreamBuf outStream;\r
\r
- outStream.funcTable.Write = MyWrite;\r
+ outStream.vt.Write = SeqOutStreamBuf_Write;\r
outStream.data = dest;\r
outStream.rem = *destLen;\r
outStream.overflow = False;\r
\r
p->writeEndMark = writeEndMark;\r
- p->rc.outStream = &outStream.funcTable;\r
+ p->rc.outStream = &outStream.vt;\r
\r
res = LzmaEnc_MemPrepare(pp, src, srcLen, 0, alloc, allocBig);\r
\r
\r
SRes LzmaEncode(Byte *dest, SizeT *destLen, const Byte *src, SizeT srcLen,\r
const CLzmaEncProps *props, Byte *propsEncoded, SizeT *propsSize, int writeEndMark,\r
- ICompressProgress *progress, ISzAlloc *alloc, ISzAlloc *allocBig)\r
+ ICompressProgress *progress, ISzAllocPtr alloc, ISzAllocPtr allocBig)\r
{\r
CLzmaEnc *p = (CLzmaEnc *)LzmaEnc_Create(alloc);\r
SRes res;\r