/*
* GRUB -- GRand Unified Bootloader
* Copyright (c) 1999-2008 Igor Pavlov
* Copyright (C) 2008 Free Software Foundation, Inc.
*
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* GRUB is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with GRUB. If not, see <http://www.gnu.org/licenses/>.
*/
/*
* This code was taken from LZMA SDK 4.58 beta, and was slightly modified
* to adapt it to GRUB's requirement.
*
* See <http://www.7-zip.org>, for more information about LZMA.
*/
#include <string.h>
#define IF_BIT_0(p) ttt = *(p); NORMALIZE; bound = (range >> kNumBitModelTotalBits) * ttt; if (code < bound)
#define UPDATE_0(p) range = bound; *(p) = (CLzmaProb)(ttt + ((kBitModelTotal - ttt) >> kNumMoveBits));
/* #define _LZMA_SIZE_OPT */
#ifdef _LZMA_SIZE_OPT
#else
{ i = 1; \
TREE_GET_BIT(probs, i); \
TREE_GET_BIT(probs, i); \
TREE_GET_BIT(probs, i); \
TREE_GET_BIT(probs, i); \
TREE_GET_BIT(probs, i); \
TREE_GET_BIT(probs, i); \
i -= 0x40; }
#endif
#define NORMALIZE_CHECK if (range < kTopValue) { if (buf >= bufLimit) return DUMMY_ERROR; range <<= 8; code = (code << 8) | (*buf++); }
#define IF_BIT_0_CHECK(p) ttt = *(p); NORMALIZE_CHECK; bound = (range >> kNumBitModelTotalBits) * ttt; if (code < bound)
{ UPDATE_0_CHECK; i = (i + i); A0; } else \
#define LenChoice 0
#define kMatchSpecLenStart (kMatchMinLen + kLenNumLowSymbols + kLenNumMidSymbols + kLenNumHighSymbols)
#define IsMatch 0
#if Literal != LZMA_BASE_SIZE
#endif
/*
#define LZMA_STREAM_WAS_FINISHED_ID (-1)
#define LZMA_SPEC_LEN_OFFSET (-3)
*/
{
0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 4, 5,
7, 7, 7, 7, 7, 7, 7, 10, 10, 10, 10, 10
};
/* First LZMA-symbol is always decoded.
And it decodes new LZMA-symbols while (buf < bufLimit), but "buf" is without last normalization
Out:
Result:
0 - OK
1 - Error
p->remainLen:
< kMatchSpecLenStart : normal remain
= kMatchSpecLenStart : finished
= kMatchSpecLenStart + 1 : Flush marker
= kMatchSpecLenStart + 2 : State Init Marker
*/
{
unsigned len = 0;
do
{
unsigned ttt;
{
unsigned symbol;
if (checkDicSize != 0 || processedPos != 0)
if (state < kNumLitStates)
{
symbol = 1;
}
else
{
symbol = 1;
do
{
unsigned bit;
matchByte <<= 1;
}
while (symbol < 0x100);
}
processedPos++;
/* if (state < 4) state = 0; else if (state < 10) state -= 3; else state -= 6; */
continue;
}
else
{
{
state += kNumStates;
}
else
{
if (checkDicSize == 0 && processedPos == 0)
return SZ_ERROR_DATA;
{
{
dicPos++;
processedPos++;
continue;
}
}
else
{
{
}
else
{
{
}
else
{
}
}
}
}
{
{
offset = 0;
}
else
{
{
}
else
{
}
}
}
if (state >= kNumStates)
{
if (distance >= kStartPosModelIndex)
{
if (posSlot < kEndPosModelIndex)
{
{
unsigned i = 1;
do
{
mask <<= 1;
}
while(--numDirectBits != 0);
}
}
else
{
do
{
{
UInt32 t;
}
/*
distance <<= 1;
if (code >= range)
{
code -= range;
distance |= 1;
}
*/
}
while (--numDirectBits != 0);
{
unsigned i = 1;
}
{
state -= kNumStates;
break;
}
}
}
if (checkDicSize == 0)
{
if (distance >= processedPos)
return SZ_ERROR_DATA;
}
else if (distance >= checkDicSize)
return SZ_ERROR_DATA;
/* state = kLiteralNextStates[state]; */
}
len += kMatchMinLen;
{
processedPos += curLen;
{
do
}
else
{
do
{
if (++pos == dicBufSize)
pos = 0;
}
while (--curLen != 0);
}
}
}
}
p->processedPos = processedPos;
return SZ_OK;
}
{
{
p->processedPos += len;
while (len-- != 0)
{
dicPos++;
}
}
}
/* LzmaDec_DecodeReal2 decodes LZMA-symbols and sets p->needFlush and p->needInit, if required. */
{
do
{
if (p->checkDicSize == 0)
{
}
LzmaDec_WriteRem(p, limit);
}
if (p->remainLen > kMatchSpecLenStart)
{
p->remainLen = kMatchSpecLenStart;
}
return 0;
}
typedef enum
{
} ELzmaDummy;
{
{
unsigned ttt;
{
/* if (bufLimit - buf >= 7) return DUMMY_LIT; */
if (p->checkDicSize != 0 || p->processedPos != 0)
prob += (LZMA_LIT_SIZE *
if (state < kNumLitStates)
{
}
else
{
do
{
unsigned bit;
matchByte <<= 1;
}
while (symbol < 0x100);
}
}
else
{
unsigned len;
{
state = 0;
res = DUMMY_MATCH;
}
else
{
{
{
return DUMMY_REP;
}
else
{
}
}
else
{
{
}
else
{
{
}
else
{
}
}
}
state = kNumStates;
}
{
{
offset = 0;
}
else
{
{
}
else
{
}
}
}
if (state < 4)
{
unsigned posSlot;
if (posSlot >= kStartPosModelIndex)
{
/* if (bufLimit - buf >= 8) return DUMMY_MATCH; */
if (posSlot < kEndPosModelIndex)
{
}
else
{
do
{
/* if (code >= range) code -= range; */
}
while (--numDirectBits != 0);
}
{
unsigned i = 1;
do
{
GET_BIT_CHECK(prob + i, i);
}
while(--numDirectBits != 0);
}
}
}
}
}
return res;
}
{
p->code = ((UInt32)data[1] << 24) | ((UInt32)data[2] << 16) | ((UInt32)data[3] << 8) | ((UInt32)data[4]);
p->range = 0xFFFFFFFF;
p->needFlush = 0;
}
{
p->needFlush = 1;
p->remainLen = 0;
p->tempBufSize = 0;
if (initDic)
{
p->processedPos = 0;
p->checkDicSize = 0;
p->needInitState = 1;
}
if (initState)
p->needInitState = 1;
}
{
p->dicPos = 0;
}
{
UInt32 i;
for (i = 0; i < numProbs; i++)
p->state = 0;
p->needInitState = 0;
}
{
(*srcLen) = 0;
LzmaDec_WriteRem(p, dicLimit);
while (p->remainLen != kMatchSpecLenStart)
{
int checkEndMarkNow;
if (p->needFlush != 0)
{
if (p->tempBufSize < RC_INIT_SIZE)
{
return SZ_OK;
}
if (p->tempBuf[0] != 0)
return SZ_ERROR_DATA;
LzmaDec_InitRc(p, p->tempBuf);
p->tempBufSize = 0;
}
checkEndMarkNow = 0;
{
{
return SZ_OK;
}
if (finishMode == LZMA_FINISH_ANY)
{
return SZ_OK;
}
if (p->remainLen != 0)
{
return SZ_ERROR_DATA;
}
checkEndMarkNow = 1;
}
if (p->needInitState)
if (p->tempBufSize == 0)
{
{
if (dummyRes == DUMMY_ERROR)
{
p->tempBufSize = (unsigned)inSize;
return SZ_OK;
}
{
return SZ_ERROR_DATA;
}
}
else
return SZ_ERROR_DATA;
}
else
{
p->tempBufSize = rem;
{
if (dummyRes == DUMMY_ERROR)
{
return SZ_OK;
}
{
return SZ_ERROR_DATA;
}
}
return SZ_ERROR_DATA;
p->tempBufSize = 0;
}
}
if (p->code == 0)
}
SRes LzmaDec_DecodeToBuf(CLzmaDec *p, Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen, ELzmaFinishMode finishMode, ELzmaStatus *status)
{
for (;;)
{
if (p->dicPos == p->dicBufSize)
p->dicPos = 0;
{
outSizeCur = p->dicBufSize;
}
else
{
}
dest += outSizeCur;
outSize -= outSizeCur;
*destLen += outSizeCur;
if (res != 0)
return res;
if (outSizeCur == 0 || outSize == 0)
return SZ_OK;
}
}
{
p->probs = 0;
}
{
p->dic = 0;
}
{
LzmaDec_FreeProbs(p, alloc);
LzmaDec_FreeDict(p, alloc);
}
{
Byte d;
if (size < LZMA_PROPS_SIZE)
return SZ_ERROR_UNSUPPORTED;
else
if (dicSize < LZMA_DIC_MIN)
d = data[0];
if (d >= (9 * 5 * 5))
return SZ_ERROR_UNSUPPORTED;
p->lc = d % 9;
d /= 9;
p->pb = d / 5;
p->lp = d % 5;
return SZ_OK;
}
{
{
LzmaDec_FreeProbs(p, alloc);
if (p->probs == 0)
return SZ_ERROR_MEM;
}
return SZ_OK;
}
{
return SZ_OK;
}
{
{
LzmaDec_FreeDict(p, alloc);
if (p->dic == 0)
{
LzmaDec_FreeProbs(p, alloc);
return SZ_ERROR_MEM;
}
}
p->dicBufSize = dicBufSize;
return SZ_OK;
}
{
CLzmaDec p;
if (inSize < RC_INIT_SIZE)
return SZ_ERROR_INPUT_EOF;
LzmaDec_Construct(&p);
if (res != 0)
return res;
p.dicBufSize = outSize;
LzmaDec_Init(&p);
LzmaDec_FreeProbs(&p, alloc);
return res;
}