Page Menu
Home
Phabricator (Chris)
Search
Configure Global Search
Log In
Files
F621909
LzmaDec.c
No One
Temporary
Actions
Download File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Authored By
Unknown
Size
27 KB
Referenced Files
None
Subscribers
None
LzmaDec.c
View Options
/* LzmaDec.c -- LZMA Decoder
2009-09-20 : Igor Pavlov : Public domain */
#include
"LzmaDec.h"
#include
<string.h>
#define kNumTopBits 24
#define kTopValue ((UInt32)1 << kNumTopBits)
#define kNumBitModelTotalBits 11
#define kBitModelTotal (1 << kNumBitModelTotalBits)
#define kNumMoveBits 5
#define RC_INIT_SIZE 5
#define NORMALIZE if (range < kTopValue) { range <<= 8; code = (code << 8) | (*buf++); }
#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 UPDATE_1(p) range -= bound; code -= bound; *(p) = (CLzmaProb)(ttt - (ttt >> kNumMoveBits));
#define GET_BIT2(p, i, A0, A1) IF_BIT_0(p) \
{ UPDATE_0(p); i = (i + i); A0; } else \
{ UPDATE_1(p); i = (i + i) + 1; A1; }
#define GET_BIT(p, i) GET_BIT2(p, i, ; , ;)
#define TREE_GET_BIT(probs, i) { GET_BIT((probs + i), i); }
#define TREE_DECODE(probs, limit, i) \
{ i = 1; do { TREE_GET_BIT(probs, i); } while (i < limit); i -= limit; }
/* #define _LZMA_SIZE_OPT */
#ifdef _LZMA_SIZE_OPT
#define TREE_6_DECODE(probs, i) TREE_DECODE(probs, (1 << 6), i)
#else
#define TREE_6_DECODE(probs, i) \
{ 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)
#define UPDATE_0_CHECK range = bound;
#define UPDATE_1_CHECK range -= bound; code -= bound;
#define GET_BIT2_CHECK(p, i, A0, A1) IF_BIT_0_CHECK(p) \
{ UPDATE_0_CHECK; i = (i + i); A0; } else \
{ UPDATE_1_CHECK; i = (i + i) + 1; A1; }
#define GET_BIT_CHECK(p, i) GET_BIT2_CHECK(p, i, ; , ;)
#define TREE_DECODE_CHECK(probs, limit, i) \
{ i = 1; do { GET_BIT_CHECK(probs + i, i) } while (i < limit); i -= limit; }
#define kNumPosBitsMax 4
#define kNumPosStatesMax (1 << kNumPosBitsMax)
#define kLenNumLowBits 3
#define kLenNumLowSymbols (1 << kLenNumLowBits)
#define kLenNumMidBits 3
#define kLenNumMidSymbols (1 << kLenNumMidBits)
#define kLenNumHighBits 8
#define kLenNumHighSymbols (1 << kLenNumHighBits)
#define LenChoice 0
#define LenChoice2 (LenChoice + 1)
#define LenLow (LenChoice2 + 1)
#define LenMid (LenLow + (kNumPosStatesMax << kLenNumLowBits))
#define LenHigh (LenMid + (kNumPosStatesMax << kLenNumMidBits))
#define kNumLenProbs (LenHigh + kLenNumHighSymbols)
#define kNumStates 12
#define kNumLitStates 7
#define kStartPosModelIndex 4
#define kEndPosModelIndex 14
#define kNumFullDistances (1 << (kEndPosModelIndex >> 1))
#define kNumPosSlotBits 6
#define kNumLenToPosStates 4
#define kNumAlignBits 4
#define kAlignTableSize (1 << kNumAlignBits)
#define kMatchMinLen 2
#define kMatchSpecLenStart (kMatchMinLen + kLenNumLowSymbols + kLenNumMidSymbols + kLenNumHighSymbols)
#define IsMatch 0
#define IsRep (IsMatch + (kNumStates << kNumPosBitsMax))
#define IsRepG0 (IsRep + kNumStates)
#define IsRepG1 (IsRepG0 + kNumStates)
#define IsRepG2 (IsRepG1 + kNumStates)
#define IsRep0Long (IsRepG2 + kNumStates)
#define PosSlot (IsRep0Long + (kNumStates << kNumPosBitsMax))
#define SpecPos (PosSlot + (kNumLenToPosStates << kNumPosSlotBits))
#define Align (SpecPos + kNumFullDistances - kEndPosModelIndex)
#define LenCoder (Align + kAlignTableSize)
#define RepLenCoder (LenCoder + kNumLenProbs)
#define Literal (RepLenCoder + kNumLenProbs)
#define LZMA_BASE_SIZE 1846
#define LZMA_LIT_SIZE 768
#define LzmaProps_GetNumProbs(p) ((UInt32)LZMA_BASE_SIZE + (LZMA_LIT_SIZE << ((p)->lc + (p)->lp)))
#if Literal != LZMA_BASE_SIZE
StopCompilingDueBUG
#endif
#define LZMA_DIC_MIN (1 << 12)
/* First LZMA-symbol is always decoded.
And it decodes new LZMA-symbols while (buf < bufLimit), but "buf" is without last normalization
Out:
Result:
SZ_OK - OK
SZ_ERROR_DATA - Error
p->remainLen:
< kMatchSpecLenStart : normal remain
= kMatchSpecLenStart : finished
= kMatchSpecLenStart + 1 : Flush marker
= kMatchSpecLenStart + 2 : State Init Marker
*/
static
int
MY_FAST_CALL
LzmaDec_DecodeReal
(
CLzmaDec
*
p
,
SizeT
limit
,
const
Byte
*
bufLimit
)
{
CLzmaProb
*
probs
=
p
->
probs
;
unsigned
state
=
p
->
state
;
UInt32
rep0
=
p
->
reps
[
0
],
rep1
=
p
->
reps
[
1
],
rep2
=
p
->
reps
[
2
],
rep3
=
p
->
reps
[
3
];
unsigned
pbMask
=
((
unsigned
)
1
<<
(
p
->
prop
.
pb
))
-
1
;
unsigned
lpMask
=
((
unsigned
)
1
<<
(
p
->
prop
.
lp
))
-
1
;
unsigned
lc
=
p
->
prop
.
lc
;
Byte
*
dic
=
p
->
dic
;
SizeT
dicBufSize
=
p
->
dicBufSize
;
SizeT
dicPos
=
p
->
dicPos
;
UInt32
processedPos
=
p
->
processedPos
;
UInt32
checkDicSize
=
p
->
checkDicSize
;
unsigned
len
=
0
;
const
Byte
*
buf
=
p
->
buf
;
UInt32
range
=
p
->
range
;
UInt32
code
=
p
->
code
;
do
{
CLzmaProb
*
prob
;
UInt32
bound
;
unsigned
ttt
;
unsigned
posState
=
processedPos
&
pbMask
;
prob
=
probs
+
IsMatch
+
(
state
<<
kNumPosBitsMax
)
+
posState
;
IF_BIT_0
(
prob
)
{
unsigned
symbol
;
UPDATE_0
(
prob
);
prob
=
probs
+
Literal
;
if
(
checkDicSize
!=
0
||
processedPos
!=
0
)
prob
+=
(
LZMA_LIT_SIZE
*
(((
processedPos
&
lpMask
)
<<
lc
)
+
(
dic
[(
dicPos
==
0
?
dicBufSize
:
dicPos
)
-
1
]
>>
(
8
-
lc
))));
if
(
state
<
kNumLitStates
)
{
state
-=
(
state
<
4
)
?
state
:
3
;
symbol
=
1
;
do
{
GET_BIT
(
prob
+
symbol
,
symbol
)
}
while
(
symbol
<
0x100
);
}
else
{
unsigned
matchByte
=
p
->
dic
[(
dicPos
-
rep0
)
+
((
dicPos
<
rep0
)
?
dicBufSize
:
0
)];
unsigned
offs
=
0x100
;
state
-=
(
state
<
10
)
?
3
:
6
;
symbol
=
1
;
do
{
unsigned
bit
;
CLzmaProb
*
probLit
;
matchByte
<<=
1
;
bit
=
(
matchByte
&
offs
);
probLit
=
prob
+
offs
+
bit
+
symbol
;
GET_BIT2
(
probLit
,
symbol
,
offs
&=
~
bit
,
offs
&=
bit
)
}
while
(
symbol
<
0x100
);
}
dic
[
dicPos
++
]
=
(
Byte
)
symbol
;
processedPos
++
;
continue
;
}
else
{
UPDATE_1
(
prob
);
prob
=
probs
+
IsRep
+
state
;
IF_BIT_0
(
prob
)
{
UPDATE_0
(
prob
);
state
+=
kNumStates
;
prob
=
probs
+
LenCoder
;
}
else
{
UPDATE_1
(
prob
);
if
(
checkDicSize
==
0
&&
processedPos
==
0
)
return
SZ_ERROR_DATA
;
prob
=
probs
+
IsRepG0
+
state
;
IF_BIT_0
(
prob
)
{
UPDATE_0
(
prob
);
prob
=
probs
+
IsRep0Long
+
(
state
<<
kNumPosBitsMax
)
+
posState
;
IF_BIT_0
(
prob
)
{
UPDATE_0
(
prob
);
dic
[
dicPos
]
=
dic
[(
dicPos
-
rep0
)
+
((
dicPos
<
rep0
)
?
dicBufSize
:
0
)];
dicPos
++
;
processedPos
++
;
state
=
state
<
kNumLitStates
?
9
:
11
;
continue
;
}
UPDATE_1
(
prob
);
}
else
{
UInt32
distance
;
UPDATE_1
(
prob
);
prob
=
probs
+
IsRepG1
+
state
;
IF_BIT_0
(
prob
)
{
UPDATE_0
(
prob
);
distance
=
rep1
;
}
else
{
UPDATE_1
(
prob
);
prob
=
probs
+
IsRepG2
+
state
;
IF_BIT_0
(
prob
)
{
UPDATE_0
(
prob
);
distance
=
rep2
;
}
else
{
UPDATE_1
(
prob
);
distance
=
rep3
;
rep3
=
rep2
;
}
rep2
=
rep1
;
}
rep1
=
rep0
;
rep0
=
distance
;
}
state
=
state
<
kNumLitStates
?
8
:
11
;
prob
=
probs
+
RepLenCoder
;
}
{
unsigned
limit
,
offset
;
CLzmaProb
*
probLen
=
prob
+
LenChoice
;
IF_BIT_0
(
probLen
)
{
UPDATE_0
(
probLen
);
probLen
=
prob
+
LenLow
+
(
posState
<<
kLenNumLowBits
);
offset
=
0
;
limit
=
(
1
<<
kLenNumLowBits
);
}
else
{
UPDATE_1
(
probLen
);
probLen
=
prob
+
LenChoice2
;
IF_BIT_0
(
probLen
)
{
UPDATE_0
(
probLen
);
probLen
=
prob
+
LenMid
+
(
posState
<<
kLenNumMidBits
);
offset
=
kLenNumLowSymbols
;
limit
=
(
1
<<
kLenNumMidBits
);
}
else
{
UPDATE_1
(
probLen
);
probLen
=
prob
+
LenHigh
;
offset
=
kLenNumLowSymbols
+
kLenNumMidSymbols
;
limit
=
(
1
<<
kLenNumHighBits
);
}
}
TREE_DECODE
(
probLen
,
limit
,
len
);
len
+=
offset
;
}
if
(
state
>=
kNumStates
)
{
UInt32
distance
;
prob
=
probs
+
PosSlot
+
((
len
<
kNumLenToPosStates
?
len
:
kNumLenToPosStates
-
1
)
<<
kNumPosSlotBits
);
TREE_6_DECODE
(
prob
,
distance
);
if
(
distance
>=
kStartPosModelIndex
)
{
unsigned
posSlot
=
(
unsigned
)
distance
;
int
numDirectBits
=
(
int
)(((
distance
>>
1
)
-
1
));
distance
=
(
2
|
(
distance
&
1
));
if
(
posSlot
<
kEndPosModelIndex
)
{
distance
<<=
numDirectBits
;
prob
=
probs
+
SpecPos
+
distance
-
posSlot
-
1
;
{
UInt32
mask
=
1
;
unsigned
i
=
1
;
do
{
GET_BIT2
(
prob
+
i
,
i
,
;
,
distance
|=
mask
);
mask
<<=
1
;
}
while
(
--
numDirectBits
!=
0
);
}
}
else
{
numDirectBits
-=
kNumAlignBits
;
do
{
NORMALIZE
range
>>=
1
;
{
UInt32
t
;
code
-=
range
;
t
=
(
0
-
((
UInt32
)
code
>>
31
));
/* (UInt32)((Int32)code >> 31) */
distance
=
(
distance
<<
1
)
+
(
t
+
1
);
code
+=
range
&
t
;
}
/*
distance <<= 1;
if (code >= range)
{
code -= range;
distance |= 1;
}
*/
}
while
(
--
numDirectBits
!=
0
);
prob
=
probs
+
Align
;
distance
<<=
kNumAlignBits
;
{
unsigned
i
=
1
;
GET_BIT2
(
prob
+
i
,
i
,
;
,
distance
|=
1
);
GET_BIT2
(
prob
+
i
,
i
,
;
,
distance
|=
2
);
GET_BIT2
(
prob
+
i
,
i
,
;
,
distance
|=
4
);
GET_BIT2
(
prob
+
i
,
i
,
;
,
distance
|=
8
);
}
if
(
distance
==
(
UInt32
)
0xFFFFFFFF
)
{
len
+=
kMatchSpecLenStart
;
state
-=
kNumStates
;
break
;
}
}
}
rep3
=
rep2
;
rep2
=
rep1
;
rep1
=
rep0
;
rep0
=
distance
+
1
;
if
(
checkDicSize
==
0
)
{
if
(
distance
>=
processedPos
)
return
SZ_ERROR_DATA
;
}
else
if
(
distance
>=
checkDicSize
)
return
SZ_ERROR_DATA
;
state
=
(
state
<
kNumStates
+
kNumLitStates
)
?
kNumLitStates
:
kNumLitStates
+
3
;
}
len
+=
kMatchMinLen
;
if
(
limit
==
dicPos
)
return
SZ_ERROR_DATA
;
{
SizeT
rem
=
limit
-
dicPos
;
unsigned
curLen
=
((
rem
<
len
)
?
(
unsigned
)
rem
:
len
);
SizeT
pos
=
(
dicPos
-
rep0
)
+
((
dicPos
<
rep0
)
?
dicBufSize
:
0
);
processedPos
+=
curLen
;
len
-=
curLen
;
if
(
pos
+
curLen
<=
dicBufSize
)
{
Byte
*
dest
=
dic
+
dicPos
;
ptrdiff_t
src
=
(
ptrdiff_t
)
pos
-
(
ptrdiff_t
)
dicPos
;
const
Byte
*
lim
=
dest
+
curLen
;
dicPos
+=
curLen
;
do
*
(
dest
)
=
(
Byte
)
*
(
dest
+
src
);
while
(
++
dest
!=
lim
);
}
else
{
do
{
dic
[
dicPos
++
]
=
dic
[
pos
];
if
(
++
pos
==
dicBufSize
)
pos
=
0
;
}
while
(
--
curLen
!=
0
);
}
}
}
}
while
(
dicPos
<
limit
&&
buf
<
bufLimit
);
NORMALIZE
;
p
->
buf
=
buf
;
p
->
range
=
range
;
p
->
code
=
code
;
p
->
remainLen
=
len
;
p
->
dicPos
=
dicPos
;
p
->
processedPos
=
processedPos
;
p
->
reps
[
0
]
=
rep0
;
p
->
reps
[
1
]
=
rep1
;
p
->
reps
[
2
]
=
rep2
;
p
->
reps
[
3
]
=
rep3
;
p
->
state
=
state
;
return
SZ_OK
;
}
static
void
MY_FAST_CALL
LzmaDec_WriteRem
(
CLzmaDec
*
p
,
SizeT
limit
)
{
if
(
p
->
remainLen
!=
0
&&
p
->
remainLen
<
kMatchSpecLenStart
)
{
Byte
*
dic
=
p
->
dic
;
SizeT
dicPos
=
p
->
dicPos
;
SizeT
dicBufSize
=
p
->
dicBufSize
;
unsigned
len
=
p
->
remainLen
;
UInt32
rep0
=
p
->
reps
[
0
];
if
(
limit
-
dicPos
<
len
)
len
=
(
unsigned
)(
limit
-
dicPos
);
if
(
p
->
checkDicSize
==
0
&&
p
->
prop
.
dicSize
-
p
->
processedPos
<=
len
)
p
->
checkDicSize
=
p
->
prop
.
dicSize
;
p
->
processedPos
+=
len
;
p
->
remainLen
-=
len
;
while
(
len
--
!=
0
)
{
dic
[
dicPos
]
=
dic
[(
dicPos
-
rep0
)
+
((
dicPos
<
rep0
)
?
dicBufSize
:
0
)];
dicPos
++
;
}
p
->
dicPos
=
dicPos
;
}
}
static
int
MY_FAST_CALL
LzmaDec_DecodeReal2
(
CLzmaDec
*
p
,
SizeT
limit
,
const
Byte
*
bufLimit
)
{
do
{
SizeT
limit2
=
limit
;
if
(
p
->
checkDicSize
==
0
)
{
UInt32
rem
=
p
->
prop
.
dicSize
-
p
->
processedPos
;
if
(
limit
-
p
->
dicPos
>
rem
)
limit2
=
p
->
dicPos
+
rem
;
}
RINOK
(
LzmaDec_DecodeReal
(
p
,
limit2
,
bufLimit
));
if
(
p
->
processedPos
>=
p
->
prop
.
dicSize
)
p
->
checkDicSize
=
p
->
prop
.
dicSize
;
LzmaDec_WriteRem
(
p
,
limit
);
}
while
(
p
->
dicPos
<
limit
&&
p
->
buf
<
bufLimit
&&
p
->
remainLen
<
kMatchSpecLenStart
);
if
(
p
->
remainLen
>
kMatchSpecLenStart
)
{
p
->
remainLen
=
kMatchSpecLenStart
;
}
return
0
;
}
typedef
enum
{
DUMMY_ERROR
,
/* unexpected end of input stream */
DUMMY_LIT
,
DUMMY_MATCH
,
DUMMY_REP
}
ELzmaDummy
;
static
ELzmaDummy
LzmaDec_TryDummy
(
const
CLzmaDec
*
p
,
const
Byte
*
buf
,
SizeT
inSize
)
{
UInt32
range
=
p
->
range
;
UInt32
code
=
p
->
code
;
const
Byte
*
bufLimit
=
buf
+
inSize
;
CLzmaProb
*
probs
=
p
->
probs
;
unsigned
state
=
p
->
state
;
ELzmaDummy
res
;
{
CLzmaProb
*
prob
;
UInt32
bound
;
unsigned
ttt
;
unsigned
posState
=
(
p
->
processedPos
)
&
((
1
<<
p
->
prop
.
pb
)
-
1
);
prob
=
probs
+
IsMatch
+
(
state
<<
kNumPosBitsMax
)
+
posState
;
IF_BIT_0_CHECK
(
prob
)
{
UPDATE_0_CHECK
/* if (bufLimit - buf >= 7) return DUMMY_LIT; */
prob
=
probs
+
Literal
;
if
(
p
->
checkDicSize
!=
0
||
p
->
processedPos
!=
0
)
prob
+=
(
LZMA_LIT_SIZE
*
((((
p
->
processedPos
)
&
((
1
<<
(
p
->
prop
.
lp
))
-
1
))
<<
p
->
prop
.
lc
)
+
(
p
->
dic
[(
p
->
dicPos
==
0
?
p
->
dicBufSize
:
p
->
dicPos
)
-
1
]
>>
(
8
-
p
->
prop
.
lc
))));
if
(
state
<
kNumLitStates
)
{
unsigned
symbol
=
1
;
do
{
GET_BIT_CHECK
(
prob
+
symbol
,
symbol
)
}
while
(
symbol
<
0x100
);
}
else
{
unsigned
matchByte
=
p
->
dic
[
p
->
dicPos
-
p
->
reps
[
0
]
+
((
p
->
dicPos
<
p
->
reps
[
0
])
?
p
->
dicBufSize
:
0
)];
unsigned
offs
=
0x100
;
unsigned
symbol
=
1
;
do
{
unsigned
bit
;
CLzmaProb
*
probLit
;
matchByte
<<=
1
;
bit
=
(
matchByte
&
offs
);
probLit
=
prob
+
offs
+
bit
+
symbol
;
GET_BIT2_CHECK
(
probLit
,
symbol
,
offs
&=
~
bit
,
offs
&=
bit
)
}
while
(
symbol
<
0x100
);
}
res
=
DUMMY_LIT
;
}
else
{
unsigned
len
;
UPDATE_1_CHECK
;
prob
=
probs
+
IsRep
+
state
;
IF_BIT_0_CHECK
(
prob
)
{
UPDATE_0_CHECK
;
state
=
0
;
prob
=
probs
+
LenCoder
;
res
=
DUMMY_MATCH
;
}
else
{
UPDATE_1_CHECK
;
res
=
DUMMY_REP
;
prob
=
probs
+
IsRepG0
+
state
;
IF_BIT_0_CHECK
(
prob
)
{
UPDATE_0_CHECK
;
prob
=
probs
+
IsRep0Long
+
(
state
<<
kNumPosBitsMax
)
+
posState
;
IF_BIT_0_CHECK
(
prob
)
{
UPDATE_0_CHECK
;
NORMALIZE_CHECK
;
return
DUMMY_REP
;
}
else
{
UPDATE_1_CHECK
;
}
}
else
{
UPDATE_1_CHECK
;
prob
=
probs
+
IsRepG1
+
state
;
IF_BIT_0_CHECK
(
prob
)
{
UPDATE_0_CHECK
;
}
else
{
UPDATE_1_CHECK
;
prob
=
probs
+
IsRepG2
+
state
;
IF_BIT_0_CHECK
(
prob
)
{
UPDATE_0_CHECK
;
}
else
{
UPDATE_1_CHECK
;
}
}
}
state
=
kNumStates
;
prob
=
probs
+
RepLenCoder
;
}
{
unsigned
limit
,
offset
;
CLzmaProb
*
probLen
=
prob
+
LenChoice
;
IF_BIT_0_CHECK
(
probLen
)
{
UPDATE_0_CHECK
;
probLen
=
prob
+
LenLow
+
(
posState
<<
kLenNumLowBits
);
offset
=
0
;
limit
=
1
<<
kLenNumLowBits
;
}
else
{
UPDATE_1_CHECK
;
probLen
=
prob
+
LenChoice2
;
IF_BIT_0_CHECK
(
probLen
)
{
UPDATE_0_CHECK
;
probLen
=
prob
+
LenMid
+
(
posState
<<
kLenNumMidBits
);
offset
=
kLenNumLowSymbols
;
limit
=
1
<<
kLenNumMidBits
;
}
else
{
UPDATE_1_CHECK
;
probLen
=
prob
+
LenHigh
;
offset
=
kLenNumLowSymbols
+
kLenNumMidSymbols
;
limit
=
1
<<
kLenNumHighBits
;
}
}
TREE_DECODE_CHECK
(
probLen
,
limit
,
len
);
len
+=
offset
;
}
if
(
state
<
4
)
{
unsigned
posSlot
;
prob
=
probs
+
PosSlot
+
((
len
<
kNumLenToPosStates
?
len
:
kNumLenToPosStates
-
1
)
<<
kNumPosSlotBits
);
TREE_DECODE_CHECK
(
prob
,
1
<<
kNumPosSlotBits
,
posSlot
);
if
(
posSlot
>=
kStartPosModelIndex
)
{
int
numDirectBits
=
((
posSlot
>>
1
)
-
1
);
/* if (bufLimit - buf >= 8) return DUMMY_MATCH; */
if
(
posSlot
<
kEndPosModelIndex
)
{
prob
=
probs
+
SpecPos
+
((
2
|
(
posSlot
&
1
))
<<
numDirectBits
)
-
posSlot
-
1
;
}
else
{
numDirectBits
-=
kNumAlignBits
;
do
{
NORMALIZE_CHECK
range
>>=
1
;
code
-=
range
&
(((
code
-
range
)
>>
31
)
-
1
);
/* if (code >= range) code -= range; */
}
while
(
--
numDirectBits
!=
0
);
prob
=
probs
+
Align
;
numDirectBits
=
kNumAlignBits
;
}
{
unsigned
i
=
1
;
do
{
GET_BIT_CHECK
(
prob
+
i
,
i
);
}
while
(
--
numDirectBits
!=
0
);
}
}
}
}
}
NORMALIZE_CHECK
;
return
res
;
}
static
void
LzmaDec_InitRc
(
CLzmaDec
*
p
,
const
Byte
*
data
)
{
p
->
code
=
((
UInt32
)
data
[
1
]
<<
24
)
|
((
UInt32
)
data
[
2
]
<<
16
)
|
((
UInt32
)
data
[
3
]
<<
8
)
|
((
UInt32
)
data
[
4
]);
p
->
range
=
0xFFFFFFFF
;
p
->
needFlush
=
0
;
}
void
LzmaDec_InitDicAndState
(
CLzmaDec
*
p
,
LzmaBool
initDic
,
LzmaBool
initState
)
{
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
;
}
void
LzmaDec_Init
(
CLzmaDec
*
p
)
{
p
->
dicPos
=
0
;
LzmaDec_InitDicAndState
(
p
,
True
,
True
);
}
static
void
LzmaDec_InitStateReal
(
CLzmaDec
*
p
)
{
UInt32
numProbs
=
Literal
+
((
UInt32
)
LZMA_LIT_SIZE
<<
(
p
->
prop
.
lc
+
p
->
prop
.
lp
));
UInt32
i
;
CLzmaProb
*
probs
=
p
->
probs
;
for
(
i
=
0
;
i
<
numProbs
;
i
++
)
probs
[
i
]
=
kBitModelTotal
>>
1
;
p
->
reps
[
0
]
=
p
->
reps
[
1
]
=
p
->
reps
[
2
]
=
p
->
reps
[
3
]
=
1
;
p
->
state
=
0
;
p
->
needInitState
=
0
;
}
SRes
LzmaDec_DecodeToDic
(
CLzmaDec
*
p
,
SizeT
dicLimit
,
const
Byte
*
src
,
SizeT
*
srcLen
,
ELzmaFinishMode
finishMode
,
ELzmaStatus
*
status
)
{
SizeT
inSize
=
*
srcLen
;
(
*
srcLen
)
=
0
;
LzmaDec_WriteRem
(
p
,
dicLimit
);
*
status
=
LZMA_STATUS_NOT_SPECIFIED
;
while
(
p
->
remainLen
!=
kMatchSpecLenStart
)
{
int
checkEndMarkNow
;
if
(
p
->
needFlush
!=
0
)
{
for
(;
inSize
>
0
&&
p
->
tempBufSize
<
RC_INIT_SIZE
;
(
*
srcLen
)
++
,
inSize
--
)
p
->
tempBuf
[
p
->
tempBufSize
++
]
=
*
src
++
;
if
(
p
->
tempBufSize
<
RC_INIT_SIZE
)
{
*
status
=
LZMA_STATUS_NEEDS_MORE_INPUT
;
return
SZ_OK
;
}
if
(
p
->
tempBuf
[
0
]
!=
0
)
return
SZ_ERROR_DATA
;
LzmaDec_InitRc
(
p
,
p
->
tempBuf
);
p
->
tempBufSize
=
0
;
}
checkEndMarkNow
=
0
;
if
(
p
->
dicPos
>=
dicLimit
)
{
if
(
p
->
remainLen
==
0
&&
p
->
code
==
0
)
{
*
status
=
LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK
;
return
SZ_OK
;
}
if
(
finishMode
==
LZMA_FINISH_ANY
)
{
*
status
=
LZMA_STATUS_NOT_FINISHED
;
return
SZ_OK
;
}
if
(
p
->
remainLen
!=
0
)
{
*
status
=
LZMA_STATUS_NOT_FINISHED
;
return
SZ_ERROR_DATA
;
}
checkEndMarkNow
=
1
;
}
if
(
p
->
needInitState
)
LzmaDec_InitStateReal
(
p
);
if
(
p
->
tempBufSize
==
0
)
{
SizeT
processed
;
const
Byte
*
bufLimit
;
if
(
inSize
<
LZMA_REQUIRED_INPUT_MAX
||
checkEndMarkNow
)
{
int
dummyRes
=
LzmaDec_TryDummy
(
p
,
src
,
inSize
);
if
(
dummyRes
==
DUMMY_ERROR
)
{
memcpy
(
p
->
tempBuf
,
src
,
inSize
);
p
->
tempBufSize
=
(
unsigned
)
inSize
;
(
*
srcLen
)
+=
inSize
;
*
status
=
LZMA_STATUS_NEEDS_MORE_INPUT
;
return
SZ_OK
;
}
if
(
checkEndMarkNow
&&
dummyRes
!=
DUMMY_MATCH
)
{
*
status
=
LZMA_STATUS_NOT_FINISHED
;
return
SZ_ERROR_DATA
;
}
bufLimit
=
src
;
}
else
bufLimit
=
src
+
inSize
-
LZMA_REQUIRED_INPUT_MAX
;
p
->
buf
=
src
;
if
(
LzmaDec_DecodeReal2
(
p
,
dicLimit
,
bufLimit
)
!=
0
)
return
SZ_ERROR_DATA
;
processed
=
(
SizeT
)(
p
->
buf
-
src
);
(
*
srcLen
)
+=
processed
;
src
+=
processed
;
inSize
-=
processed
;
}
else
{
unsigned
rem
=
p
->
tempBufSize
,
lookAhead
=
0
;
while
(
rem
<
LZMA_REQUIRED_INPUT_MAX
&&
lookAhead
<
inSize
)
p
->
tempBuf
[
rem
++
]
=
src
[
lookAhead
++
];
p
->
tempBufSize
=
rem
;
if
(
rem
<
LZMA_REQUIRED_INPUT_MAX
||
checkEndMarkNow
)
{
int
dummyRes
=
LzmaDec_TryDummy
(
p
,
p
->
tempBuf
,
rem
);
if
(
dummyRes
==
DUMMY_ERROR
)
{
(
*
srcLen
)
+=
lookAhead
;
*
status
=
LZMA_STATUS_NEEDS_MORE_INPUT
;
return
SZ_OK
;
}
if
(
checkEndMarkNow
&&
dummyRes
!=
DUMMY_MATCH
)
{
*
status
=
LZMA_STATUS_NOT_FINISHED
;
return
SZ_ERROR_DATA
;
}
}
p
->
buf
=
p
->
tempBuf
;
if
(
LzmaDec_DecodeReal2
(
p
,
dicLimit
,
p
->
buf
)
!=
0
)
return
SZ_ERROR_DATA
;
lookAhead
-=
(
rem
-
(
unsigned
)(
p
->
buf
-
p
->
tempBuf
));
(
*
srcLen
)
+=
lookAhead
;
src
+=
lookAhead
;
inSize
-=
lookAhead
;
p
->
tempBufSize
=
0
;
}
}
if
(
p
->
code
==
0
)
*
status
=
LZMA_STATUS_FINISHED_WITH_MARK
;
return
(
p
->
code
==
0
)
?
SZ_OK
:
SZ_ERROR_DATA
;
}
SRes
LzmaDec_DecodeToBuf
(
CLzmaDec
*
p
,
Byte
*
dest
,
SizeT
*
destLen
,
const
Byte
*
src
,
SizeT
*
srcLen
,
ELzmaFinishMode
finishMode
,
ELzmaStatus
*
status
)
{
SizeT
outSize
=
*
destLen
;
SizeT
inSize
=
*
srcLen
;
*
srcLen
=
*
destLen
=
0
;
for
(;;)
{
SizeT
inSizeCur
=
inSize
,
outSizeCur
,
dicPos
;
ELzmaFinishMode
curFinishMode
;
SRes
res
;
if
(
p
->
dicPos
==
p
->
dicBufSize
)
p
->
dicPos
=
0
;
dicPos
=
p
->
dicPos
;
if
(
outSize
>
p
->
dicBufSize
-
dicPos
)
{
outSizeCur
=
p
->
dicBufSize
;
curFinishMode
=
LZMA_FINISH_ANY
;
}
else
{
outSizeCur
=
dicPos
+
outSize
;
curFinishMode
=
finishMode
;
}
res
=
LzmaDec_DecodeToDic
(
p
,
outSizeCur
,
src
,
&
inSizeCur
,
curFinishMode
,
status
);
src
+=
inSizeCur
;
inSize
-=
inSizeCur
;
*
srcLen
+=
inSizeCur
;
outSizeCur
=
p
->
dicPos
-
dicPos
;
memcpy
(
dest
,
p
->
dic
+
dicPos
,
outSizeCur
);
dest
+=
outSizeCur
;
outSize
-=
outSizeCur
;
*
destLen
+=
outSizeCur
;
if
(
res
!=
0
)
return
res
;
if
(
outSizeCur
==
0
||
outSize
==
0
)
return
SZ_OK
;
}
}
void
LzmaDec_FreeProbs
(
CLzmaDec
*
p
,
ISzAlloc
*
alloc
)
{
alloc
->
Free
(
alloc
,
p
->
probs
);
p
->
probs
=
0
;
}
static
void
LzmaDec_FreeDict
(
CLzmaDec
*
p
,
ISzAlloc
*
alloc
)
{
alloc
->
Free
(
alloc
,
p
->
dic
);
p
->
dic
=
0
;
}
void
LzmaDec_Free
(
CLzmaDec
*
p
,
ISzAlloc
*
alloc
)
{
LzmaDec_FreeProbs
(
p
,
alloc
);
LzmaDec_FreeDict
(
p
,
alloc
);
}
SRes
LzmaProps_Decode
(
CLzmaProps
*
p
,
const
Byte
*
data
,
unsigned
size
)
{
UInt32
dicSize
;
Byte
d
;
if
(
size
<
LZMA_PROPS_SIZE
)
return
SZ_ERROR_UNSUPPORTED
;
else
dicSize
=
data
[
1
]
|
((
UInt32
)
data
[
2
]
<<
8
)
|
((
UInt32
)
data
[
3
]
<<
16
)
|
((
UInt32
)
data
[
4
]
<<
24
);
if
(
dicSize
<
LZMA_DIC_MIN
)
dicSize
=
LZMA_DIC_MIN
;
p
->
dicSize
=
dicSize
;
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
;
}
static
SRes
LzmaDec_AllocateProbs2
(
CLzmaDec
*
p
,
const
CLzmaProps
*
propNew
,
ISzAlloc
*
alloc
)
{
UInt32
numProbs
=
LzmaProps_GetNumProbs
(
propNew
);
if
(
p
->
probs
==
0
||
numProbs
!=
p
->
numProbs
)
{
LzmaDec_FreeProbs
(
p
,
alloc
);
p
->
probs
=
(
CLzmaProb
*
)
alloc
->
Alloc
(
alloc
,
numProbs
*
sizeof
(
CLzmaProb
));
p
->
numProbs
=
numProbs
;
if
(
p
->
probs
==
0
)
return
SZ_ERROR_MEM
;
}
return
SZ_OK
;
}
SRes
LzmaDec_AllocateProbs
(
CLzmaDec
*
p
,
const
Byte
*
props
,
unsigned
propsSize
,
ISzAlloc
*
alloc
)
{
CLzmaProps
propNew
;
RINOK
(
LzmaProps_Decode
(
&
propNew
,
props
,
propsSize
));
RINOK
(
LzmaDec_AllocateProbs2
(
p
,
&
propNew
,
alloc
));
p
->
prop
=
propNew
;
return
SZ_OK
;
}
SRes
LzmaDec_Allocate
(
CLzmaDec
*
p
,
const
Byte
*
props
,
unsigned
propsSize
,
ISzAlloc
*
alloc
)
{
CLzmaProps
propNew
;
SizeT
dicBufSize
;
RINOK
(
LzmaProps_Decode
(
&
propNew
,
props
,
propsSize
));
RINOK
(
LzmaDec_AllocateProbs2
(
p
,
&
propNew
,
alloc
));
dicBufSize
=
propNew
.
dicSize
;
if
(
p
->
dic
==
0
||
dicBufSize
!=
p
->
dicBufSize
)
{
LzmaDec_FreeDict
(
p
,
alloc
);
p
->
dic
=
(
Byte
*
)
alloc
->
Alloc
(
alloc
,
dicBufSize
);
if
(
p
->
dic
==
0
)
{
LzmaDec_FreeProbs
(
p
,
alloc
);
return
SZ_ERROR_MEM
;
}
}
p
->
dicBufSize
=
dicBufSize
;
p
->
prop
=
propNew
;
return
SZ_OK
;
}
SRes
LzmaDecode
(
Byte
*
dest
,
SizeT
*
destLen
,
const
Byte
*
src
,
SizeT
*
srcLen
,
const
Byte
*
propData
,
unsigned
propSize
,
ELzmaFinishMode
finishMode
,
ELzmaStatus
*
status
,
ISzAlloc
*
alloc
)
{
CLzmaDec
p
;
SRes
res
;
SizeT
inSize
=
*
srcLen
;
SizeT
outSize
=
*
destLen
;
*
srcLen
=
*
destLen
=
0
;
if
(
inSize
<
RC_INIT_SIZE
)
return
SZ_ERROR_INPUT_EOF
;
LzmaDec_Construct
(
&
p
);
res
=
LzmaDec_AllocateProbs
(
&
p
,
propData
,
propSize
,
alloc
);
if
(
res
!=
0
)
return
res
;
p
.
dic
=
dest
;
p
.
dicBufSize
=
outSize
;
LzmaDec_Init
(
&
p
);
*
srcLen
=
inSize
;
res
=
LzmaDec_DecodeToDic
(
&
p
,
outSize
,
src
,
srcLen
,
finishMode
,
status
);
if
(
res
==
SZ_OK
&&
*
status
==
LZMA_STATUS_NEEDS_MORE_INPUT
)
res
=
SZ_ERROR_INPUT_EOF
;
(
*
destLen
)
=
p
.
dicPos
;
LzmaDec_FreeProbs
(
&
p
,
alloc
);
return
res
;
}
File Metadata
Details
Attached
Mime Type
text/x-c
Expires
Sat, Nov 14, 7:37 PM (20 h, 50 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
126389
Default Alt Text
LzmaDec.c (27 KB)
Attached To
Mode
R75 R-Tech1
Attached
Detach File
Event Timeline