1 /* LzmaDec.c -- LZMA Decoder
2 2018-07-04 : Igor Pavlov : Public domain */
8 /* #include "CpuArch.h" */
11 #define kNumTopBits 24
12 #define kTopValue ((UInt32)1 << kNumTopBits)
14 #define kNumBitModelTotalBits 11
15 #define kBitModelTotal (1 << kNumBitModelTotalBits)
16 #define kNumMoveBits 5
18 #define RC_INIT_SIZE 5
20 #define NORMALIZE if (range < kTopValue) { range <<= 8; code = (code << 8) | (*buf++); }
22 #define IF_BIT_0(p) ttt = *(p); NORMALIZE; bound = (range >> kNumBitModelTotalBits) * (UInt32)ttt; if (code < bound)
23 #define UPDATE_0(p) range = bound; *(p) = (CLzmaProb)(ttt + ((kBitModelTotal - ttt) >> kNumMoveBits));
24 #define UPDATE_1(p) range -= bound; code -= bound; *(p) = (CLzmaProb)(ttt - (ttt >> kNumMoveBits));
25 #define GET_BIT2(p, i, A0, A1) IF_BIT_0(p) \
26 { UPDATE_0(p); i = (i + i); A0; } else \
27 { UPDATE_1(p); i = (i + i) + 1; A1; }
29 #define TREE_GET_BIT(probs, i) { GET_BIT2(probs + i, i, ;, ;); }
31 #define REV_BIT(p, i, A0, A1) IF_BIT_0(p + i) \
32 { UPDATE_0(p + i); A0; } else \
33 { UPDATE_1(p + i); A1; }
34 #define REV_BIT_VAR( p, i, m) REV_BIT(p, i, i += m; m += m, m += m; i += m; )
35 #define REV_BIT_CONST(p, i, m) REV_BIT(p, i, i += m; , i += m * 2; )
36 #define REV_BIT_LAST( p, i, m) REV_BIT(p, i, i -= m , ; )
38 #define TREE_DECODE(probs, limit, i) \
39 { i = 1; do { TREE_GET_BIT(probs, i); } while (i < limit); i -= limit; }
41 /* #define _LZMA_SIZE_OPT */
44 #define TREE_6_DECODE(probs, i) TREE_DECODE(probs, (1 << 6), i)
46 #define TREE_6_DECODE(probs, i) \
48 TREE_GET_BIT(probs, i); \
49 TREE_GET_BIT(probs, i); \
50 TREE_GET_BIT(probs, i); \
51 TREE_GET_BIT(probs, i); \
52 TREE_GET_BIT(probs, i); \
53 TREE_GET_BIT(probs, i); \
57 #define NORMAL_LITER_DEC TREE_GET_BIT(prob, symbol)
58 #define MATCHED_LITER_DEC \
59 matchByte += matchByte; \
62 probLit = prob + (offs + bit + symbol); \
63 GET_BIT2(probLit, symbol, offs ^= bit; , ;)
67 #define NORMALIZE_CHECK if (range < kTopValue) { if (buf >= bufLimit) return DUMMY_ERROR; range <<= 8; code = (code << 8) | (*buf++); }
69 #define IF_BIT_0_CHECK(p) ttt = *(p); NORMALIZE_CHECK; bound = (range >> kNumBitModelTotalBits) * (UInt32)ttt; if (code < bound)
70 #define UPDATE_0_CHECK range = bound;
71 #define UPDATE_1_CHECK range -= bound; code -= bound;
72 #define GET_BIT2_CHECK(p, i, A0, A1) IF_BIT_0_CHECK(p) \
73 { UPDATE_0_CHECK; i = (i + i); A0; } else \
74 { UPDATE_1_CHECK; i = (i + i) + 1; A1; }
75 #define GET_BIT_CHECK(p, i) GET_BIT2_CHECK(p, i, ; , ;)
76 #define TREE_DECODE_CHECK(probs, limit, i) \
77 { i = 1; do { GET_BIT_CHECK(probs + i, i) } while (i < limit); i -= limit; }
80 #define REV_BIT_CHECK(p, i, m) IF_BIT_0_CHECK(p + i) \
81 { UPDATE_0_CHECK; i += m; m += m; } else \
82 { UPDATE_1_CHECK; m += m; i += m; }
85 #define kNumPosBitsMax 4
86 #define kNumPosStatesMax (1 << kNumPosBitsMax)
88 #define kLenNumLowBits 3
89 #define kLenNumLowSymbols (1 << kLenNumLowBits)
90 #define kLenNumHighBits 8
91 #define kLenNumHighSymbols (1 << kLenNumHighBits)
94 #define LenHigh (LenLow + 2 * (kNumPosStatesMax << kLenNumLowBits))
95 #define kNumLenProbs (LenHigh + kLenNumHighSymbols)
97 #define LenChoice LenLow
98 #define LenChoice2 (LenLow + (1 << kLenNumLowBits))
100 #define kNumStates 12
101 #define kNumStates2 16
102 #define kNumLitStates 7
104 #define kStartPosModelIndex 4
105 #define kEndPosModelIndex 14
106 #define kNumFullDistances (1 << (kEndPosModelIndex >> 1))
108 #define kNumPosSlotBits 6
109 #define kNumLenToPosStates 4
111 #define kNumAlignBits 4
112 #define kAlignTableSize (1 << kNumAlignBits)
114 #define kMatchMinLen 2
115 #define kMatchSpecLenStart (kMatchMinLen + kLenNumLowSymbols * 2 + kLenNumHighSymbols)
117 /* External ASM code needs same CLzmaProb array layout. So don't change it. */
119 /* (probs_1664) is faster and better for code size at some platforms */
121 #ifdef MY_CPU_X86_OR_AMD64
123 #define kStartOffset 1664
124 #define GET_PROBS p->probs_1664
126 #define GET_PROBS p->probs + kStartOffset
128 #define kStartOffset 0
129 #define GET_PROBS p->probs
133 #define SpecPos (-kStartOffset)
134 #define IsRep0Long (SpecPos + kNumFullDistances)
135 #define RepLenCoder (IsRep0Long + (kNumStates2 << kNumPosBitsMax))
136 #define LenCoder (RepLenCoder + kNumLenProbs)
137 #define IsMatch (LenCoder + kNumLenProbs)
138 #define Align (IsMatch + (kNumStates2 << kNumPosBitsMax))
139 #define IsRep (Align + kAlignTableSize)
140 #define IsRepG0 (IsRep + kNumStates)
141 #define IsRepG1 (IsRepG0 + kNumStates)
142 #define IsRepG2 (IsRepG1 + kNumStates)
143 #define PosSlot (IsRepG2 + kNumStates)
144 #define Literal (PosSlot + (kNumLenToPosStates << kNumPosSlotBits))
145 #define NUM_BASE_PROBS (Literal + kStartOffset)
147 #if Align != 0 && kStartOffset != 0
148 #error Stop_Compiling_Bad_LZMA_kAlign
151 #if NUM_BASE_PROBS != 1984
152 #error Stop_Compiling_Bad_LZMA_PROBS
156 #define LZMA_LIT_SIZE 0x300
158 #define LzmaProps_GetNumProbs(p) (NUM_BASE_PROBS + ((UInt32)LZMA_LIT_SIZE << ((p)->lc + (p)->lp)))
161 #define CALC_POS_STATE(processedPos, pbMask) (((processedPos) & (pbMask)) << 4)
162 #define COMBINED_PS_STATE (posState + state)
163 #define GET_LEN_STATE (posState)
165 #define LZMA_DIC_MIN (1 << 12)
168 p->remainLen : shows status of LZMA decoder:
169 < kMatchSpecLenStart : normal remain
170 = kMatchSpecLenStart : finished
171 = kMatchSpecLenStart + 1 : need init range coder
172 = kMatchSpecLenStart + 2 : need init range coder and state
175 /* ---------- LZMA_DECODE_REAL ---------- */
177 LzmaDec_DecodeReal_3() can be implemented in external ASM file.
178 3 - is the code compatibility version of that function for check at link time.
181 #define LZMA_DECODE_REAL LzmaDec_DecodeReal_3
186 RangeCoder is normalized
187 if (p->dicPos == limit)
189 LzmaDec_TryDummy() was called before to exclude LITERAL and MATCH-REP cases.
190 So first symbol can be only MATCH-NON-REP. And if that MATCH-NON-REP symbol
191 is not END_OF_PAYALOAD_MARKER, then function returns error code.
195 first LZMA symbol will be decoded in any case
196 All checks for limits are at the end of main loop,
197 It will decode new LZMA-symbols while (p->buf < bufLimit && dicPos < limit),
198 RangeCoder is still without last normalization when (p->buf < bufLimit) is being checked.
201 RangeCoder is normalized
204 SZ_ERROR_DATA - Error
206 < kMatchSpecLenStart : normal remain
207 = kMatchSpecLenStart : finished
213 int MY_FAST_CALL
LZMA_DECODE_REAL(CLzmaDec
*p
, SizeT limit
, const Byte
*bufLimit
);
218 int MY_FAST_CALL
LZMA_DECODE_REAL(CLzmaDec
*p
, SizeT limit
, const Byte
*bufLimit
)
220 CLzmaProb
*probs
= GET_PROBS
;
221 unsigned state
= (unsigned)p
->state
;
222 UInt32 rep0
= p
->reps
[0], rep1
= p
->reps
[1], rep2
= p
->reps
[2], rep3
= p
->reps
[3];
223 unsigned pbMask
= ((unsigned)1 << (p
->prop
.pb
)) - 1;
224 unsigned lc
= p
->prop
.lc
;
225 unsigned lpMask
= ((unsigned)0x100 << p
->prop
.lp
) - ((unsigned)0x100 >> lc
);
228 SizeT dicBufSize
= p
->dicBufSize
;
229 SizeT dicPos
= p
->dicPos
;
231 UInt32 processedPos
= p
->processedPos
;
232 UInt32 checkDicSize
= p
->checkDicSize
;
235 const Byte
*buf
= p
->buf
;
236 UInt32 range
= p
->range
;
237 UInt32 code
= p
->code
;
244 unsigned posState
= CALC_POS_STATE(processedPos
, pbMask
);
246 prob
= probs
+ IsMatch
+ COMBINED_PS_STATE
;
251 prob
= probs
+ Literal
;
252 if (processedPos
!= 0 || checkDicSize
!= 0)
253 prob
+= (UInt32
)3 * ((((processedPos
<< 8) + dic
[(dicPos
== 0 ? dicBufSize
: dicPos
) - 1]) & lpMask
) << lc
);
256 if (state
< kNumLitStates
)
258 state
-= (state
< 4) ? state
: 3;
260 #ifdef _LZMA_SIZE_OPT
261 do { NORMAL_LITER_DEC
} while (symbol
< 0x100);
275 unsigned matchByte
= dic
[dicPos
- rep0
+ (dicPos
< rep0
? dicBufSize
: 0)];
276 unsigned offs
= 0x100;
277 state
-= (state
< 10) ? 3 : 6;
279 #ifdef _LZMA_SIZE_OPT
286 while (symbol
< 0x100);
303 dic
[dicPos
++] = (Byte
)symbol
;
309 prob
= probs
+ IsRep
+ state
;
314 prob
= probs
+ LenCoder
;
320 // that case was checked before with kBadRepCode
321 if (checkDicSize == 0 && processedPos == 0)
322 return SZ_ERROR_DATA;
324 prob
= probs
+ IsRepG0
+ state
;
328 prob
= probs
+ IsRep0Long
+ COMBINED_PS_STATE
;
332 dic
[dicPos
] = dic
[dicPos
- rep0
+ (dicPos
< rep0
? dicBufSize
: 0)];
335 state
= state
< kNumLitStates
? 9 : 11;
344 prob
= probs
+ IsRepG1
+ state
;
353 prob
= probs
+ IsRepG2
+ state
;
370 state
= state
< kNumLitStates
? 8 : 11;
371 prob
= probs
+ RepLenCoder
;
374 #ifdef _LZMA_SIZE_OPT
376 unsigned lim
, offset
;
377 CLzmaProb
*probLen
= prob
+ LenChoice
;
381 probLen
= prob
+ LenLow
+ GET_LEN_STATE
;
383 lim
= (1 << kLenNumLowBits
);
388 probLen
= prob
+ LenChoice2
;
392 probLen
= prob
+ LenLow
+ GET_LEN_STATE
+ (1 << kLenNumLowBits
);
393 offset
= kLenNumLowSymbols
;
394 lim
= (1 << kLenNumLowBits
);
399 probLen
= prob
+ LenHigh
;
400 offset
= kLenNumLowSymbols
* 2;
401 lim
= (1 << kLenNumHighBits
);
404 TREE_DECODE(probLen
, lim
, len
);
409 CLzmaProb
*probLen
= prob
+ LenChoice
;
413 probLen
= prob
+ LenLow
+ GET_LEN_STATE
;
415 TREE_GET_BIT(probLen
, len
);
416 TREE_GET_BIT(probLen
, len
);
417 TREE_GET_BIT(probLen
, len
);
423 probLen
= prob
+ LenChoice2
;
427 probLen
= prob
+ LenLow
+ GET_LEN_STATE
+ (1 << kLenNumLowBits
);
429 TREE_GET_BIT(probLen
, len
);
430 TREE_GET_BIT(probLen
, len
);
431 TREE_GET_BIT(probLen
, len
);
436 probLen
= prob
+ LenHigh
;
437 TREE_DECODE(probLen
, (1 << kLenNumHighBits
), len
);
438 len
+= kLenNumLowSymbols
* 2;
444 if (state
>= kNumStates
)
447 prob
= probs
+ PosSlot
+
448 ((len
< kNumLenToPosStates
? len
: kNumLenToPosStates
- 1) << kNumPosSlotBits
);
449 TREE_6_DECODE(prob
, distance
);
450 if (distance
>= kStartPosModelIndex
)
452 unsigned posSlot
= (unsigned)distance
;
453 unsigned numDirectBits
= (unsigned)(((distance
>> 1) - 1));
454 distance
= (2 | (distance
& 1));
455 if (posSlot
< kEndPosModelIndex
)
457 distance
<<= numDirectBits
;
458 prob
= probs
+ SpecPos
;
464 REV_BIT_VAR(prob
, distance
, m
);
466 while (--numDirectBits
);
472 numDirectBits
-= kNumAlignBits
;
481 t
= (0 - ((UInt32
)code
>> 31)); /* (UInt32)((Int32)code >> 31) */
482 distance
= (distance
<< 1) + (t
+ 1);
494 while (--numDirectBits
);
495 prob
= probs
+ Align
;
496 distance
<<= kNumAlignBits
;
499 REV_BIT_CONST(prob
, i
, 1);
500 REV_BIT_CONST(prob
, i
, 2);
501 REV_BIT_CONST(prob
, i
, 4);
502 REV_BIT_LAST (prob
, i
, 8);
505 if (distance
== (UInt32
)0xFFFFFFFF)
507 len
= kMatchSpecLenStart
;
518 state
= (state
< kNumStates
+ kNumLitStates
) ? kNumLitStates
: kNumLitStates
+ 3;
519 if (distance
>= (checkDicSize
== 0 ? processedPos
: checkDicSize
))
522 return SZ_ERROR_DATA
;
533 if ((rem
= limit
- dicPos
) == 0)
536 return SZ_ERROR_DATA
;
539 curLen
= ((rem
< len
) ? (unsigned)rem
: len
);
540 pos
= dicPos
- rep0
+ (dicPos
< rep0
? dicBufSize
: 0);
542 processedPos
+= (UInt32
)curLen
;
545 if (curLen
<= dicBufSize
- pos
)
547 Byte
*dest
= dic
+ dicPos
;
548 ptrdiff_t src
= (ptrdiff_t)pos
- (ptrdiff_t)dicPos
;
549 const Byte
*lim
= dest
+ curLen
;
550 dicPos
+= (SizeT
)curLen
;
552 *(dest
) = (Byte
)*(dest
+ src
);
553 while (++dest
!= lim
);
559 dic
[dicPos
++] = dic
[pos
];
560 if (++pos
== dicBufSize
)
563 while (--curLen
!= 0);
568 while (dicPos
< limit
&& buf
< bufLimit
);
575 p
->remainLen
= (UInt32
)len
;
577 p
->processedPos
= processedPos
;
582 p
->state
= (UInt32
)state
;
588 static void MY_FAST_CALL
LzmaDec_WriteRem(CLzmaDec
*p
, SizeT limit
)
590 if (p
->remainLen
!= 0 && p
->remainLen
< kMatchSpecLenStart
)
593 SizeT dicPos
= p
->dicPos
;
594 SizeT dicBufSize
= p
->dicBufSize
;
595 unsigned len
= (unsigned)p
->remainLen
;
596 SizeT rep0
= p
->reps
[0]; /* we use SizeT to avoid the BUG of VC14 for AMD64 */
597 SizeT rem
= limit
- dicPos
;
599 len
= (unsigned)(rem
);
601 if (p
->checkDicSize
== 0 && p
->prop
.dicSize
- p
->processedPos
<= len
)
602 p
->checkDicSize
= p
->prop
.dicSize
;
604 p
->processedPos
+= (UInt32
)len
;
605 p
->remainLen
-= (UInt32
)len
;
609 dic
[dicPos
] = dic
[dicPos
- rep0
+ (dicPos
< rep0
? dicBufSize
: 0)];
617 #define kRange0 0xFFFFFFFF
618 #define kBound0 ((kRange0 >> kNumBitModelTotalBits) << (kNumBitModelTotalBits - 1))
619 #define kBadRepCode (kBound0 + (((kRange0 - kBound0) >> kNumBitModelTotalBits) << (kNumBitModelTotalBits - 1)))
620 #if kBadRepCode != (0xC0000000 - 0x400)
621 #error Stop_Compiling_Bad_LZMA_Check
624 static int MY_FAST_CALL
LzmaDec_DecodeReal2(CLzmaDec
*p
, SizeT limit
, const Byte
*bufLimit
)
628 SizeT limit2
= limit
;
629 if (p
->checkDicSize
== 0)
631 UInt32 rem
= p
->prop
.dicSize
- p
->processedPos
;
632 if (limit
- p
->dicPos
> rem
)
633 limit2
= p
->dicPos
+ rem
;
635 if (p
->processedPos
== 0)
636 if (p
->code
>= kBadRepCode
)
637 return SZ_ERROR_DATA
;
640 RINOK(LZMA_DECODE_REAL(p
, limit2
, bufLimit
));
642 if (p
->checkDicSize
== 0 && p
->processedPos
>= p
->prop
.dicSize
)
643 p
->checkDicSize
= p
->prop
.dicSize
;
645 LzmaDec_WriteRem(p
, limit
);
647 while (p
->dicPos
< limit
&& p
->buf
< bufLimit
&& p
->remainLen
< kMatchSpecLenStart
);
654 DUMMY_ERROR
, /* unexpected end of input stream */
660 static ELzmaDummy
LzmaDec_TryDummy(const CLzmaDec
*p
, const Byte
*buf
, SizeT inSize
)
662 UInt32 range
= p
->range
;
663 UInt32 code
= p
->code
;
664 const Byte
*bufLimit
= buf
+ inSize
;
665 const CLzmaProb
*probs
= GET_PROBS
;
666 unsigned state
= (unsigned)p
->state
;
670 const CLzmaProb
*prob
;
673 unsigned posState
= CALC_POS_STATE(p
->processedPos
, (1 << p
->prop
.pb
) - 1);
675 prob
= probs
+ IsMatch
+ COMBINED_PS_STATE
;
680 /* if (bufLimit - buf >= 7) return DUMMY_LIT; */
682 prob
= probs
+ Literal
;
683 if (p
->checkDicSize
!= 0 || p
->processedPos
!= 0)
684 prob
+= ((UInt32
)LZMA_LIT_SIZE
*
685 ((((p
->processedPos
) & ((1 << (p
->prop
.lp
)) - 1)) << p
->prop
.lc
) +
686 (p
->dic
[(p
->dicPos
== 0 ? p
->dicBufSize
: p
->dicPos
) - 1] >> (8 - p
->prop
.lc
))));
688 if (state
< kNumLitStates
)
691 do { GET_BIT_CHECK(prob
+ symbol
, symbol
) } while (symbol
< 0x100);
695 unsigned matchByte
= p
->dic
[p
->dicPos
- p
->reps
[0] +
696 (p
->dicPos
< p
->reps
[0] ? p
->dicBufSize
: 0)];
697 unsigned offs
= 0x100;
702 const CLzmaProb
*probLit
;
703 matchByte
+= matchByte
;
706 probLit
= prob
+ (offs
+ bit
+ symbol
);
707 GET_BIT2_CHECK(probLit
, symbol
, offs
^= bit
; , ; )
709 while (symbol
< 0x100);
718 prob
= probs
+ IsRep
+ state
;
723 prob
= probs
+ LenCoder
;
730 prob
= probs
+ IsRepG0
+ state
;
734 prob
= probs
+ IsRep0Long
+ COMBINED_PS_STATE
;
749 prob
= probs
+ IsRepG1
+ state
;
757 prob
= probs
+ IsRepG2
+ state
;
769 prob
= probs
+ RepLenCoder
;
772 unsigned limit
, offset
;
773 const CLzmaProb
*probLen
= prob
+ LenChoice
;
774 IF_BIT_0_CHECK(probLen
)
777 probLen
= prob
+ LenLow
+ GET_LEN_STATE
;
779 limit
= 1 << kLenNumLowBits
;
784 probLen
= prob
+ LenChoice2
;
785 IF_BIT_0_CHECK(probLen
)
788 probLen
= prob
+ LenLow
+ GET_LEN_STATE
+ (1 << kLenNumLowBits
);
789 offset
= kLenNumLowSymbols
;
790 limit
= 1 << kLenNumLowBits
;
795 probLen
= prob
+ LenHigh
;
796 offset
= kLenNumLowSymbols
* 2;
797 limit
= 1 << kLenNumHighBits
;
800 TREE_DECODE_CHECK(probLen
, limit
, len
);
807 prob
= probs
+ PosSlot
+
808 ((len
< kNumLenToPosStates
- 1 ? len
: kNumLenToPosStates
- 1) <<
810 TREE_DECODE_CHECK(prob
, 1 << kNumPosSlotBits
, posSlot
);
811 if (posSlot
>= kStartPosModelIndex
)
813 unsigned numDirectBits
= ((posSlot
>> 1) - 1);
815 /* if (bufLimit - buf >= 8) return DUMMY_MATCH; */
817 if (posSlot
< kEndPosModelIndex
)
819 prob
= probs
+ SpecPos
+ ((2 | (posSlot
& 1)) << numDirectBits
);
823 numDirectBits
-= kNumAlignBits
;
828 code
-= range
& (((code
- range
) >> 31) - 1);
829 /* if (code >= range) code -= range; */
831 while (--numDirectBits
);
832 prob
= probs
+ Align
;
833 numDirectBits
= kNumAlignBits
;
840 REV_BIT_CHECK(prob
, i
, m
);
842 while (--numDirectBits
);
853 void LzmaDec_InitDicAndState(CLzmaDec
*p
, BoolInt initDic
, BoolInt initState
)
855 p
->remainLen
= kMatchSpecLenStart
+ 1;
862 p
->remainLen
= kMatchSpecLenStart
+ 2;
865 p
->remainLen
= kMatchSpecLenStart
+ 2;
868 void LzmaDec_Init(CLzmaDec
*p
)
871 LzmaDec_InitDicAndState(p
, True
, True
);
875 SRes
LzmaDec_DecodeToDic(CLzmaDec
*p
, SizeT dicLimit
, const Byte
*src
, SizeT
*srcLen
,
876 ELzmaFinishMode finishMode
, ELzmaStatus
*status
)
878 SizeT inSize
= *srcLen
;
881 *status
= LZMA_STATUS_NOT_SPECIFIED
;
883 if (p
->remainLen
> kMatchSpecLenStart
)
885 for (; inSize
> 0 && p
->tempBufSize
< RC_INIT_SIZE
; (*srcLen
)++, inSize
--)
886 p
->tempBuf
[p
->tempBufSize
++] = *src
++;
887 if (p
->tempBufSize
!= 0 && p
->tempBuf
[0] != 0)
888 return SZ_ERROR_DATA
;
889 if (p
->tempBufSize
< RC_INIT_SIZE
)
891 *status
= LZMA_STATUS_NEEDS_MORE_INPUT
;
895 ((UInt32
)p
->tempBuf
[1] << 24)
896 | ((UInt32
)p
->tempBuf
[2] << 16)
897 | ((UInt32
)p
->tempBuf
[3] << 8)
898 | ((UInt32
)p
->tempBuf
[4]);
899 p
->range
= 0xFFFFFFFF;
902 if (p
->remainLen
> kMatchSpecLenStart
+ 1)
904 SizeT numProbs
= LzmaProps_GetNumProbs(&p
->prop
);
906 CLzmaProb
*probs
= p
->probs
;
907 for (i
= 0; i
< numProbs
; i
++)
908 probs
[i
] = kBitModelTotal
>> 1;
909 p
->reps
[0] = p
->reps
[1] = p
->reps
[2] = p
->reps
[3] = 1;
916 LzmaDec_WriteRem(p
, dicLimit
);
918 while (p
->remainLen
!= kMatchSpecLenStart
)
920 int checkEndMarkNow
= 0;
922 if (p
->dicPos
>= dicLimit
)
924 if (p
->remainLen
== 0 && p
->code
== 0)
926 *status
= LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK
;
929 if (finishMode
== LZMA_FINISH_ANY
)
931 *status
= LZMA_STATUS_NOT_FINISHED
;
934 if (p
->remainLen
!= 0)
936 *status
= LZMA_STATUS_NOT_FINISHED
;
937 return SZ_ERROR_DATA
;
942 if (p
->tempBufSize
== 0)
945 const Byte
*bufLimit
;
946 if (inSize
< LZMA_REQUIRED_INPUT_MAX
|| checkEndMarkNow
)
948 int dummyRes
= LzmaDec_TryDummy(p
, src
, inSize
);
949 if (dummyRes
== DUMMY_ERROR
)
951 memcpy(p
->tempBuf
, src
, inSize
);
952 p
->tempBufSize
= (unsigned)inSize
;
954 *status
= LZMA_STATUS_NEEDS_MORE_INPUT
;
957 if (checkEndMarkNow
&& dummyRes
!= DUMMY_MATCH
)
959 *status
= LZMA_STATUS_NOT_FINISHED
;
960 return SZ_ERROR_DATA
;
965 bufLimit
= src
+ inSize
- LZMA_REQUIRED_INPUT_MAX
;
967 if (LzmaDec_DecodeReal2(p
, dicLimit
, bufLimit
) != 0)
968 return SZ_ERROR_DATA
;
969 processed
= (SizeT
)(p
->buf
- src
);
970 (*srcLen
) += processed
;
976 unsigned rem
= p
->tempBufSize
, lookAhead
= 0;
977 while (rem
< LZMA_REQUIRED_INPUT_MAX
&& lookAhead
< inSize
)
978 p
->tempBuf
[rem
++] = src
[lookAhead
++];
979 p
->tempBufSize
= rem
;
980 if (rem
< LZMA_REQUIRED_INPUT_MAX
|| checkEndMarkNow
)
982 int dummyRes
= LzmaDec_TryDummy(p
, p
->tempBuf
, (SizeT
)rem
);
983 if (dummyRes
== DUMMY_ERROR
)
985 (*srcLen
) += (SizeT
)lookAhead
;
986 *status
= LZMA_STATUS_NEEDS_MORE_INPUT
;
989 if (checkEndMarkNow
&& dummyRes
!= DUMMY_MATCH
)
991 *status
= LZMA_STATUS_NOT_FINISHED
;
992 return SZ_ERROR_DATA
;
996 if (LzmaDec_DecodeReal2(p
, dicLimit
, p
->buf
) != 0)
997 return SZ_ERROR_DATA
;
1000 unsigned kkk
= (unsigned)(p
->buf
- p
->tempBuf
);
1002 return SZ_ERROR_FAIL
; /* some internal error */
1004 if (lookAhead
< rem
)
1005 return SZ_ERROR_FAIL
; /* some internal error */
1008 (*srcLen
) += (SizeT
)lookAhead
;
1010 inSize
-= (SizeT
)lookAhead
;
1016 return SZ_ERROR_DATA
;
1017 *status
= LZMA_STATUS_FINISHED_WITH_MARK
;
1022 SRes
LzmaDec_DecodeToBuf(CLzmaDec
*p
, Byte
*dest
, SizeT
*destLen
, const Byte
*src
, SizeT
*srcLen
, ELzmaFinishMode finishMode
, ELzmaStatus
*status
)
1024 SizeT outSize
= *destLen
;
1025 SizeT inSize
= *srcLen
;
1026 *srcLen
= *destLen
= 0;
1029 SizeT inSizeCur
= inSize
, outSizeCur
, dicPos
;
1030 ELzmaFinishMode curFinishMode
;
1032 if (p
->dicPos
== p
->dicBufSize
)
1035 if (outSize
> p
->dicBufSize
- dicPos
)
1037 outSizeCur
= p
->dicBufSize
;
1038 curFinishMode
= LZMA_FINISH_ANY
;
1042 outSizeCur
= dicPos
+ outSize
;
1043 curFinishMode
= finishMode
;
1046 res
= LzmaDec_DecodeToDic(p
, outSizeCur
, src
, &inSizeCur
, curFinishMode
, status
);
1048 inSize
-= inSizeCur
;
1049 *srcLen
+= inSizeCur
;
1050 outSizeCur
= p
->dicPos
- dicPos
;
1051 memcpy(dest
, p
->dic
+ dicPos
, outSizeCur
);
1053 outSize
-= outSizeCur
;
1054 *destLen
+= outSizeCur
;
1057 if (outSizeCur
== 0 || outSize
== 0)
1062 void LzmaDec_FreeProbs(CLzmaDec
*p
, ISzAllocPtr alloc
)
1064 ISzAlloc_Free(alloc
, p
->probs
);
1068 static void LzmaDec_FreeDict(CLzmaDec
*p
, ISzAllocPtr alloc
)
1070 ISzAlloc_Free(alloc
, p
->dic
);
1074 void LzmaDec_Free(CLzmaDec
*p
, ISzAllocPtr alloc
)
1076 LzmaDec_FreeProbs(p
, alloc
);
1077 LzmaDec_FreeDict(p
, alloc
);
1080 SRes
LzmaProps_Decode(CLzmaProps
*p
, const Byte
*data
, unsigned size
)
1085 if (size
< LZMA_PROPS_SIZE
)
1086 return SZ_ERROR_UNSUPPORTED
;
1088 dicSize
= data
[1] | ((UInt32
)data
[2] << 8) | ((UInt32
)data
[3] << 16) | ((UInt32
)data
[4] << 24);
1090 if (dicSize
< LZMA_DIC_MIN
)
1091 dicSize
= LZMA_DIC_MIN
;
1092 p
->dicSize
= dicSize
;
1095 if (d
>= (9 * 5 * 5))
1096 return SZ_ERROR_UNSUPPORTED
;
1098 p
->lc
= (Byte
)(d
% 9);
1100 p
->pb
= (Byte
)(d
/ 5);
1101 p
->lp
= (Byte
)(d
% 5);
1106 static SRes
LzmaDec_AllocateProbs2(CLzmaDec
*p
, const CLzmaProps
*propNew
, ISzAllocPtr alloc
)
1108 UInt32 numProbs
= LzmaProps_GetNumProbs(propNew
);
1109 if (!p
->probs
|| numProbs
!= p
->numProbs
)
1111 LzmaDec_FreeProbs(p
, alloc
);
1112 p
->probs
= (CLzmaProb
*)ISzAlloc_Alloc(alloc
, numProbs
* sizeof(CLzmaProb
));
1114 return SZ_ERROR_MEM
;
1115 p
->probs_1664
= p
->probs
+ 1664;
1116 p
->numProbs
= numProbs
;
1121 SRes
LzmaDec_AllocateProbs(CLzmaDec
*p
, const Byte
*props
, unsigned propsSize
, ISzAllocPtr alloc
)
1124 RINOK(LzmaProps_Decode(&propNew
, props
, propsSize
));
1125 RINOK(LzmaDec_AllocateProbs2(p
, &propNew
, alloc
));
1130 SRes
LzmaDec_Allocate(CLzmaDec
*p
, const Byte
*props
, unsigned propsSize
, ISzAllocPtr alloc
)
1134 RINOK(LzmaProps_Decode(&propNew
, props
, propsSize
));
1135 RINOK(LzmaDec_AllocateProbs2(p
, &propNew
, alloc
));
1138 UInt32 dictSize
= propNew
.dicSize
;
1139 SizeT mask
= ((UInt32
)1 << 12) - 1;
1140 if (dictSize
>= ((UInt32
)1 << 30)) mask
= ((UInt32
)1 << 22) - 1;
1141 else if (dictSize
>= ((UInt32
)1 << 22)) mask
= ((UInt32
)1 << 20) - 1;;
1142 dicBufSize
= ((SizeT
)dictSize
+ mask
) & ~mask
;
1143 if (dicBufSize
< dictSize
)
1144 dicBufSize
= dictSize
;
1147 if (!p
->dic
|| dicBufSize
!= p
->dicBufSize
)
1149 LzmaDec_FreeDict(p
, alloc
);
1150 p
->dic
= (Byte
*)ISzAlloc_Alloc(alloc
, dicBufSize
);
1153 LzmaDec_FreeProbs(p
, alloc
);
1154 return SZ_ERROR_MEM
;
1157 p
->dicBufSize
= dicBufSize
;
1162 SRes
LzmaDecode(Byte
*dest
, SizeT
*destLen
, const Byte
*src
, SizeT
*srcLen
,
1163 const Byte
*propData
, unsigned propSize
, ELzmaFinishMode finishMode
,
1164 ELzmaStatus
*status
, ISzAllocPtr alloc
)
1168 SizeT outSize
= *destLen
, inSize
= *srcLen
;
1169 *destLen
= *srcLen
= 0;
1170 *status
= LZMA_STATUS_NOT_SPECIFIED
;
1171 if (inSize
< RC_INIT_SIZE
)
1172 return SZ_ERROR_INPUT_EOF
;
1173 LzmaDec_Construct(&p
);
1174 RINOK(LzmaDec_AllocateProbs(&p
, propData
, propSize
, alloc
));
1176 p
.dicBufSize
= outSize
;
1179 res
= LzmaDec_DecodeToDic(&p
, outSize
, src
, srcLen
, finishMode
, status
);
1180 *destLen
= p
.dicPos
;
1181 if (res
== SZ_OK
&& *status
== LZMA_STATUS_NEEDS_MORE_INPUT
)
1182 res
= SZ_ERROR_INPUT_EOF
;
1183 LzmaDec_FreeProbs(&p
, alloc
);