-/** @file\r
- LzmaDec.c\r
+/* LzmaDec.c -- LZMA Decoder\r
+2016-05-16 : Igor Pavlov : Public domain */\r
\r
- Based on LZMA SDK 4.65:\r
- LzmaDec.c -- LZMA Decoder\r
- 2008-11-06 : Igor Pavlov : Public domain\r
-\r
- Copyright (c) 2009, Intel Corporation. All rights reserved.<BR>\r
- This program and the accompanying materials\r
- are licensed and made available under the terms and conditions of the BSD License\r
- which accompanies this distribution. The full text of the license may be found at\r
- http://opensource.org/licenses/bsd-license.php\r
-\r
- THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
- WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
-\r
-**/\r
+#include "Precomp.h"\r
\r
#include "LzmaDec.h"\r
\r
#ifndef EFIAPI\r
-\r
#include <string.h>\r
-\r
-#endif // !EFIAPI\r
+#endif\r
\r
#define kNumTopBits 24\r
#define kTopValue ((UInt32)1 << kNumTopBits)\r
i -= 0x40; }\r
#endif\r
\r
+#define NORMAL_LITER_DEC GET_BIT(prob + symbol, 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
+\r
#define NORMALIZE_CHECK if (range < kTopValue) { if (buf >= bufLimit) return DUMMY_ERROR; range <<= 8; code = (code << 8) | (*buf++); }\r
\r
#define IF_BIT_0_CHECK(p) ttt = *(p); NORMALIZE_CHECK; bound = (range >> kNumBitModelTotalBits) * ttt; if (code < bound)\r
#define Literal (RepLenCoder + kNumLenProbs)\r
\r
#define LZMA_BASE_SIZE 1846\r
-#define LZMA_LIT_SIZE 768\r
-\r
-#define LzmaProps_GetNumProbs(p) ((UInt32)LZMA_BASE_SIZE + (LZMA_LIT_SIZE << ((p)->lc + (p)->lp)))\r
+#define LZMA_LIT_SIZE 0x300\r
\r
#if Literal != LZMA_BASE_SIZE\r
StopCompilingDueBUG\r
#endif\r
\r
-static const Byte kLiteralNextStates[kNumStates * 2] =\r
-{\r
- 0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 4, 5,\r
- 7, 7, 7, 7, 7, 7, 7, 10, 10, 10, 10, 10\r
-};\r
+#define LzmaProps_GetNumProbs(p) (Literal + ((UInt32)LZMA_LIT_SIZE << ((p)->lc + (p)->lp)))\r
\r
#define LZMA_DIC_MIN (1 << 12)\r
\r
p->remainLen:\r
< kMatchSpecLenStart : normal remain\r
= kMatchSpecLenStart : finished\r
- = kMatchSpecLenStart + 1 : Flush marker\r
- = kMatchSpecLenStart + 2 : State Init Marker\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
unsigned symbol;\r
UPDATE_0(prob);\r
prob = probs + Literal;\r
- if (checkDicSize != 0 || processedPos != 0)\r
- prob += (LZMA_LIT_SIZE * (((processedPos & lpMask) << lc) +\r
- (dic[(dicPos == 0 ? dicBufSize : dicPos) - 1] >> (8 - lc))));\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
+ processedPos++;\r
\r
if (state < kNumLitStates)\r
{\r
+ state -= (state < 4) ? state : 3;\r
symbol = 1;\r
- do { GET_BIT(prob + symbol, symbol) } while (symbol < 0x100);\r
+ #ifdef _LZMA_SIZE_OPT\r
+ do { NORMAL_LITER_DEC } while (symbol < 0x100);\r
+ #else\r
+ NORMAL_LITER_DEC\r
+ NORMAL_LITER_DEC\r
+ NORMAL_LITER_DEC\r
+ NORMAL_LITER_DEC\r
+ NORMAL_LITER_DEC\r
+ NORMAL_LITER_DEC\r
+ NORMAL_LITER_DEC\r
+ NORMAL_LITER_DEC\r
+ #endif\r
}\r
else\r
{\r
- unsigned matchByte = p->dic[(dicPos - rep0) + ((dicPos < rep0) ? dicBufSize : 0)];\r
+ unsigned matchByte = dic[dicPos - rep0 + (dicPos < rep0 ? dicBufSize : 0)];\r
unsigned offs = 0x100;\r
+ state -= (state < 10) ? 3 : 6;\r
symbol = 1;\r
+ #ifdef _LZMA_SIZE_OPT\r
do\r
{\r
unsigned bit;\r
CLzmaProb *probLit;\r
- matchByte <<= 1;\r
- bit = (matchByte & offs);\r
- probLit = prob + offs + bit + symbol;\r
- GET_BIT2(probLit, symbol, offs &= ~bit, offs &= bit)\r
+ MATCHED_LITER_DEC\r
}\r
while (symbol < 0x100);\r
+ #else\r
+ {\r
+ unsigned bit;\r
+ CLzmaProb *probLit;\r
+ MATCHED_LITER_DEC\r
+ MATCHED_LITER_DEC\r
+ MATCHED_LITER_DEC\r
+ MATCHED_LITER_DEC\r
+ MATCHED_LITER_DEC\r
+ MATCHED_LITER_DEC\r
+ MATCHED_LITER_DEC\r
+ MATCHED_LITER_DEC\r
+ }\r
+ #endif\r
}\r
- dic[dicPos++] = (Byte)symbol;\r
- processedPos++;\r
\r
- state = kLiteralNextStates[state];\r
- /* if (state < 4) state = 0; else if (state < 10) state -= 3; else state -= 6; */\r
+ dic[dicPos++] = (Byte)symbol;\r
continue;\r
}\r
- else\r
+ \r
{\r
UPDATE_1(prob);\r
prob = probs + IsRep + state;\r
IF_BIT_0(prob)\r
{\r
UPDATE_0(prob);\r
- dic[dicPos] = dic[(dicPos - rep0) + ((dicPos < rep0) ? dicBufSize : 0)];\r
+ dic[dicPos] = dic[dicPos - rep0 + (dicPos < rep0 ? dicBufSize : 0)];\r
dicPos++;\r
processedPos++;\r
state = state < kNumLitStates ? 9 : 11;\r
state = state < kNumLitStates ? 8 : 11;\r
prob = probs + RepLenCoder;\r
}\r
+ \r
+ #ifdef _LZMA_SIZE_OPT\r
{\r
- unsigned limit2, offset;\r
+ unsigned lim, offset;\r
CLzmaProb *probLen = prob + LenChoice;\r
IF_BIT_0(probLen)\r
{\r
UPDATE_0(probLen);\r
probLen = prob + LenLow + (posState << kLenNumLowBits);\r
offset = 0;\r
- limit2 = (1 << kLenNumLowBits);\r
+ lim = (1 << kLenNumLowBits);\r
}\r
else\r
{\r
UPDATE_0(probLen);\r
probLen = prob + LenMid + (posState << kLenNumMidBits);\r
offset = kLenNumLowSymbols;\r
- limit2 = (1 << kLenNumMidBits);\r
+ lim = (1 << kLenNumMidBits);\r
}\r
else\r
{\r
UPDATE_1(probLen);\r
probLen = prob + LenHigh;\r
offset = kLenNumLowSymbols + kLenNumMidSymbols;\r
- limit2 = (1 << kLenNumHighBits);\r
+ lim = (1 << kLenNumHighBits);\r
}\r
}\r
- TREE_DECODE(probLen, limit2, len);\r
+ TREE_DECODE(probLen, lim, len);\r
len += offset;\r
}\r
+ #else\r
+ {\r
+ CLzmaProb *probLen = prob + LenChoice;\r
+ IF_BIT_0(probLen)\r
+ {\r
+ UPDATE_0(probLen);\r
+ probLen = prob + LenLow + (posState << kLenNumLowBits);\r
+ len = 1;\r
+ TREE_GET_BIT(probLen, len);\r
+ TREE_GET_BIT(probLen, len);\r
+ TREE_GET_BIT(probLen, len);\r
+ len -= 8;\r
+ }\r
+ else\r
+ {\r
+ UPDATE_1(probLen);\r
+ probLen = prob + LenChoice2;\r
+ IF_BIT_0(probLen)\r
+ {\r
+ UPDATE_0(probLen);\r
+ probLen = prob + LenMid + (posState << kLenNumMidBits);\r
+ len = 1;\r
+ TREE_GET_BIT(probLen, len);\r
+ TREE_GET_BIT(probLen, len);\r
+ TREE_GET_BIT(probLen, len);\r
+ }\r
+ else\r
+ {\r
+ UPDATE_1(probLen);\r
+ probLen = prob + LenHigh;\r
+ TREE_DECODE(probLen, (1 << kLenNumHighBits), len);\r
+ len += kLenNumLowSymbols + kLenNumMidSymbols;\r
+ }\r
+ }\r
+ }\r
+ #endif\r
\r
if (state >= kNumStates)\r
{\r
if (distance >= kStartPosModelIndex)\r
{\r
unsigned posSlot = (unsigned)distance;\r
- int numDirectBits = (int)(((distance >> 1) - 1));\r
+ unsigned numDirectBits = (unsigned)(((distance >> 1) - 1));\r
distance = (2 | (distance & 1));\r
if (posSlot < kEndPosModelIndex)\r
{\r
}\r
}\r
}\r
+ \r
rep3 = rep2;\r
rep2 = rep1;\r
rep1 = rep0;\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
+ {\r
+ p->dicPos = dicPos;\r
return SZ_ERROR_DATA;\r
+ }\r
state = (state < kNumStates + kNumLitStates) ? kNumLitStates : kNumLitStates + 3;\r
- /* state = kLiteralNextStates[state]; */\r
}\r
\r
len += kMatchMinLen;\r
\r
- if (limit == dicPos)\r
- return SZ_ERROR_DATA;\r
{\r
- SizeT rem = limit - dicPos;\r
- unsigned curLen = ((rem < len) ? (unsigned)rem : len);\r
- SizeT pos = (dicPos - rep0) + ((dicPos < rep0) ? dicBufSize : 0);\r
+ SizeT rem;\r
+ unsigned curLen;\r
+ SizeT pos;\r
+ \r
+ if ((rem = limit - dicPos) == 0)\r
+ {\r
+ p->dicPos = dicPos;\r
+ return SZ_ERROR_DATA;\r
+ }\r
+ \r
+ curLen = ((rem < len) ? (unsigned)rem : len);\r
+ pos = dicPos - rep0 + (dicPos < rep0 ? dicBufSize : 0);\r
\r
processedPos += curLen;\r
\r
len -= curLen;\r
- if (pos + curLen <= dicBufSize)\r
+ if (curLen <= dicBufSize - pos)\r
{\r
Byte *dest = dic + dicPos;\r
ptrdiff_t src = (ptrdiff_t)pos - (ptrdiff_t)dicPos;\r
const Byte *lim = dest + curLen;\r
dicPos += curLen;\r
do\r
- *((volatile Byte *)dest) = (Byte)*(dest + src);\r
+ *(dest) = (Byte)*(dest + src);\r
while (++dest != lim);\r
}\r
else\r
}\r
}\r
while (dicPos < limit && buf < bufLimit);\r
+\r
NORMALIZE;\r
+ \r
p->buf = buf;\r
p->range = range;\r
p->code = code;\r
SizeT dicPos = p->dicPos;\r
SizeT dicBufSize = p->dicBufSize;\r
unsigned len = p->remainLen;\r
- UInt32 rep0 = p->reps[0];\r
- if (limit - dicPos < len)\r
- len = (unsigned)(limit - dicPos);\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
+ len = (unsigned)(rem);\r
\r
if (p->checkDicSize == 0 && p->prop.dicSize - p->processedPos <= len)\r
p->checkDicSize = p->prop.dicSize;\r
\r
p->processedPos += len;\r
p->remainLen -= len;\r
- while (len-- != 0)\r
+ while (len != 0)\r
{\r
- dic[dicPos] = dic[(dicPos - rep0) + ((dicPos < rep0) ? dicBufSize : 0)];\r
+ len--;\r
+ dic[dicPos] = dic[dicPos - rep0 + (dicPos < rep0 ? dicBufSize : 0)];\r
dicPos++;\r
}\r
p->dicPos = dicPos;\r
if (limit - p->dicPos > rem)\r
limit2 = p->dicPos + rem;\r
}\r
+ \r
RINOK(LzmaDec_DecodeReal(p, limit2, bufLimit));\r
- if (p->processedPos >= p->prop.dicSize)\r
+ \r
+ if (p->checkDicSize == 0 && p->processedPos >= p->prop.dicSize)\r
p->checkDicSize = p->prop.dicSize;\r
+ \r
LzmaDec_WriteRem(p, limit);\r
}\r
while (p->dicPos < limit && p->buf < bufLimit && p->remainLen < kMatchSpecLenStart);\r
\r
if (p->remainLen > kMatchSpecLenStart)\r
- {\r
p->remainLen = kMatchSpecLenStart;\r
- }\r
+\r
return 0;\r
}\r
\r
UInt32 range = p->range;\r
UInt32 code = p->code;\r
const Byte *bufLimit = buf + inSize;\r
- CLzmaProb *probs = p->probs;\r
+ const CLzmaProb *probs = p->probs;\r
unsigned state = p->state;\r
ELzmaDummy res;\r
\r
{\r
- CLzmaProb *prob;\r
+ const CLzmaProb *prob;\r
UInt32 bound;\r
unsigned ttt;\r
unsigned posState = (p->processedPos) & ((1 << p->prop.pb) - 1);\r
\r
prob = probs + Literal;\r
if (p->checkDicSize != 0 || p->processedPos != 0)\r
- prob += (LZMA_LIT_SIZE *\r
- ((((p->processedPos) & ((1 << (p->prop.lp)) - 1)) << p->prop.lc) +\r
- (p->dic[(p->dicPos == 0 ? p->dicBufSize : p->dicPos) - 1] >> (8 - p->prop.lc))));\r
+ prob += ((UInt32)LZMA_LIT_SIZE *\r
+ ((((p->processedPos) & ((1 << (p->prop.lp)) - 1)) << p->prop.lc) +\r
+ (p->dic[(p->dicPos == 0 ? p->dicBufSize : p->dicPos) - 1] >> (8 - p->prop.lc))));\r
\r
if (state < kNumLitStates)\r
{\r
else\r
{\r
unsigned matchByte = p->dic[p->dicPos - p->reps[0] +\r
- ((p->dicPos < p->reps[0]) ? p->dicBufSize : 0)];\r
+ (p->dicPos < p->reps[0] ? p->dicBufSize : 0)];\r
unsigned offs = 0x100;\r
unsigned symbol = 1;\r
do\r
{\r
unsigned bit;\r
- CLzmaProb *probLit;\r
+ const CLzmaProb *probLit;\r
matchByte <<= 1;\r
bit = (matchByte & offs);\r
probLit = prob + offs + bit + symbol;\r
}\r
{\r
unsigned limit, offset;\r
- CLzmaProb *probLen = prob + LenChoice;\r
+ const CLzmaProb *probLen = prob + LenChoice;\r
IF_BIT_0_CHECK(probLen)\r
{\r
UPDATE_0_CHECK;\r
TREE_DECODE_CHECK(prob, 1 << kNumPosSlotBits, posSlot);\r
if (posSlot >= kStartPosModelIndex)\r
{\r
- int numDirectBits = ((posSlot >> 1) - 1);\r
+ unsigned numDirectBits = ((posSlot >> 1) - 1);\r
\r
/* if (bufLimit - buf >= 8) return DUMMY_MATCH; */\r
\r
return res;\r
}\r
\r
-static void LzmaDec_InitRc(CLzmaDec *p, const Byte *data)\r
-{\r
- p->code = ((UInt32)data[1] << 24) | ((UInt32)data[2] << 16) | ((UInt32)data[3] << 8) | ((UInt32)data[4]);\r
- p->range = 0xFFFFFFFF;\r
- p->needFlush = 0;\r
-}\r
\r
void LzmaDec_InitDicAndState(CLzmaDec *p, Bool initDic, Bool initState)\r
{\r
\r
static void LzmaDec_InitStateReal(CLzmaDec *p)\r
{\r
- UInt32 numProbs = Literal + ((UInt32)LZMA_LIT_SIZE << (p->prop.lc + p->prop.lp));\r
- UInt32 i;\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
{\r
int checkEndMarkNow;\r
\r
- if (p->needFlush != 0)\r
+ if (p->needFlush)\r
{\r
for (; inSize > 0 && p->tempBufSize < RC_INIT_SIZE; (*srcLen)++, inSize--)\r
p->tempBuf[p->tempBufSize++] = *src++;\r
}\r
if (p->tempBuf[0] != 0)\r
return SZ_ERROR_DATA;\r
-\r
- LzmaDec_InitRc(p, p->tempBuf);\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
\r
p->buf = p->tempBuf;\r
if (LzmaDec_DecodeReal2(p, dicLimit, p->buf) != 0)\r
return SZ_ERROR_DATA;\r
- lookAhead -= (rem - (unsigned)(p->buf - p->tempBuf));\r
+ \r
+ {\r
+ unsigned kkk = (unsigned)(p->buf - p->tempBuf);\r
+ if (rem < kkk)\r
+ return SZ_ERROR_FAIL; /* some internal error */\r
+ rem -= kkk;\r
+ if (lookAhead < rem)\r
+ return SZ_ERROR_FAIL; /* some internal error */\r
+ lookAhead -= rem;\r
+ }\r
(*srcLen) += lookAhead;\r
src += lookAhead;\r
inSize -= lookAhead;\r
void LzmaDec_FreeProbs(CLzmaDec *p, ISzAlloc *alloc)\r
{\r
alloc->Free(alloc, p->probs);\r
- p->probs = 0;\r
+ p->probs = NULL;\r
}\r
\r
static void LzmaDec_FreeDict(CLzmaDec *p, ISzAlloc *alloc)\r
{\r
alloc->Free(alloc, p->dic);\r
- p->dic = 0;\r
+ p->dic = NULL;\r
}\r
\r
void LzmaDec_Free(CLzmaDec *p, ISzAlloc *alloc)\r
static SRes LzmaDec_AllocateProbs2(CLzmaDec *p, const CLzmaProps *propNew, ISzAlloc *alloc)\r
{\r
UInt32 numProbs = LzmaProps_GetNumProbs(propNew);\r
- if (p->probs == 0 || numProbs != p->numProbs)\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
- if (p->probs == 0)\r
+ if (!p->probs)\r
return SZ_ERROR_MEM;\r
}\r
return SZ_OK;\r
SizeT dicBufSize;\r
RINOK(LzmaProps_Decode(&propNew, props, propsSize));\r
RINOK(LzmaDec_AllocateProbs2(p, &propNew, alloc));\r
- dicBufSize = propNew.dicSize;\r
- if (p->dic == 0 || dicBufSize != p->dicBufSize)\r
+\r
+ {\r
+ UInt32 dictSize = propNew.dicSize;\r
+ SizeT mask = ((UInt32)1 << 12) - 1;\r
+ if (dictSize >= ((UInt32)1 << 30)) mask = ((UInt32)1 << 22) - 1;\r
+ else if (dictSize >= ((UInt32)1 << 22)) mask = ((UInt32)1 << 20) - 1;;\r
+ dicBufSize = ((SizeT)dictSize + mask) & ~mask;\r
+ if (dicBufSize < dictSize)\r
+ dicBufSize = dictSize;\r
+ }\r
+\r
+ if (!p->dic || dicBufSize != p->dicBufSize)\r
{\r
LzmaDec_FreeDict(p, alloc);\r
p->dic = (Byte *)alloc->Alloc(alloc, dicBufSize);\r
- if (p->dic == 0)\r
+ if (!p->dic)\r
{\r
LzmaDec_FreeProbs(p, alloc);\r
return SZ_ERROR_MEM;\r
{\r
CLzmaDec p;\r
SRes res;\r
- SizeT inSize = *srcLen;\r
- SizeT outSize = *destLen;\r
- *srcLen = *destLen = 0;\r
+ SizeT outSize = *destLen, inSize = *srcLen;\r
+ *destLen = *srcLen = 0;\r
+ *status = LZMA_STATUS_NOT_SPECIFIED;\r
if (inSize < RC_INIT_SIZE)\r
return SZ_ERROR_INPUT_EOF;\r
-\r
LzmaDec_Construct(&p);\r
- res = LzmaDec_AllocateProbs(&p, propData, propSize, alloc);\r
- if (res != 0)\r
- return res;\r
+ RINOK(LzmaDec_AllocateProbs(&p, propData, propSize, alloc));\r
p.dic = dest;\r
p.dicBufSize = outSize;\r
-\r
LzmaDec_Init(&p);\r
- \r
*srcLen = inSize;\r
res = LzmaDec_DecodeToDic(&p, outSize, src, srcLen, finishMode, status);\r
-\r
+ *destLen = p.dicPos;\r
if (res == SZ_OK && *status == LZMA_STATUS_NEEDS_MORE_INPUT)\r
res = SZ_ERROR_INPUT_EOF;\r
-\r
- (*destLen) = p.dicPos;\r
LzmaDec_FreeProbs(&p, alloc);\r
return res;\r
}\r
-\r