1 /* LzmaDec.c -- LZMA Decoder
2 2016-05-16 : Igor Pavlov : Public domain */
12 #define kNumTopBits 24
13 #define kTopValue ((UInt32)1 << kNumTopBits)
15 #define kNumBitModelTotalBits 11
16 #define kBitModelTotal (1 << kNumBitModelTotalBits)
17 #define kNumMoveBits 5
19 #define RC_INIT_SIZE 5
21 #define NORMALIZE if (range < kTopValue) { range <<= 8; code = (code << 8) | (*buf++); }
23 #define IF_BIT_0(p) ttt = *(p); NORMALIZE; bound = (range >> kNumBitModelTotalBits) * ttt; if (code < bound)
24 #define UPDATE_0(p) range = bound; *(p) = (CLzmaProb)(ttt + ((kBitModelTotal - ttt) >> kNumMoveBits));
25 #define UPDATE_1(p) range -= bound; code -= bound; *(p) = (CLzmaProb)(ttt - (ttt >> kNumMoveBits));
26 #define GET_BIT2(p, i, A0, A1) IF_BIT_0(p) \
27 { UPDATE_0(p); i = (i + i); A0; } else \
28 { UPDATE_1(p); i = (i + i) + 1; A1; }
29 #define GET_BIT(p, i) GET_BIT2(p, i, ; , ;)
31 #define TREE_GET_BIT(probs, i) { GET_BIT((probs + i), i); }
32 #define TREE_DECODE(probs, limit, i) \
33 { i = 1; do { TREE_GET_BIT(probs, i); } while (i < limit); i -= limit; }
35 /* #define _LZMA_SIZE_OPT */
38 #define TREE_6_DECODE(probs, i) TREE_DECODE(probs, (1 << 6), i)
40 #define TREE_6_DECODE(probs, i) \
42 TREE_GET_BIT(probs, i); \
43 TREE_GET_BIT(probs, i); \
44 TREE_GET_BIT(probs, i); \
45 TREE_GET_BIT(probs, i); \
46 TREE_GET_BIT(probs, i); \
47 TREE_GET_BIT(probs, i); \
51 #define NORMAL_LITER_DEC GET_BIT(prob + symbol, symbol)
52 #define MATCHED_LITER_DEC \
54 bit = (matchByte & offs); \
55 probLit = prob + offs + bit + symbol; \
56 GET_BIT2(probLit, symbol, offs &= ~bit, offs &= bit)
58 #define NORMALIZE_CHECK if (range < kTopValue) { if (buf >= bufLimit) return DUMMY_ERROR; range <<= 8; code = (code << 8) | (*buf++); }
60 #define IF_BIT_0_CHECK(p) ttt = *(p); NORMALIZE_CHECK; bound = (range >> kNumBitModelTotalBits) * ttt; if (code < bound)
61 #define UPDATE_0_CHECK range = bound;
62 #define UPDATE_1_CHECK range -= bound; code -= bound;
63 #define GET_BIT2_CHECK(p, i, A0, A1) IF_BIT_0_CHECK(p) \
64 { UPDATE_0_CHECK; i = (i + i); A0; } else \
65 { UPDATE_1_CHECK; i = (i + i) + 1; A1; }
66 #define GET_BIT_CHECK(p, i) GET_BIT2_CHECK(p, i, ; , ;)
67 #define TREE_DECODE_CHECK(probs, limit, i) \
68 { i = 1; do { GET_BIT_CHECK(probs + i, i) } while (i < limit); i -= limit; }
71 #define kNumPosBitsMax 4
72 #define kNumPosStatesMax (1 << kNumPosBitsMax)
74 #define kLenNumLowBits 3
75 #define kLenNumLowSymbols (1 << kLenNumLowBits)
76 #define kLenNumMidBits 3
77 #define kLenNumMidSymbols (1 << kLenNumMidBits)
78 #define kLenNumHighBits 8
79 #define kLenNumHighSymbols (1 << kLenNumHighBits)
82 #define LenChoice2 (LenChoice + 1)
83 #define LenLow (LenChoice2 + 1)
84 #define LenMid (LenLow + (kNumPosStatesMax << kLenNumLowBits))
85 #define LenHigh (LenMid + (kNumPosStatesMax << kLenNumMidBits))
86 #define kNumLenProbs (LenHigh + kLenNumHighSymbols)
90 #define kNumLitStates 7
92 #define kStartPosModelIndex 4
93 #define kEndPosModelIndex 14
94 #define kNumFullDistances (1 << (kEndPosModelIndex >> 1))
96 #define kNumPosSlotBits 6
97 #define kNumLenToPosStates 4
99 #define kNumAlignBits 4
100 #define kAlignTableSize (1 << kNumAlignBits)
102 #define kMatchMinLen 2
103 #define kMatchSpecLenStart (kMatchMinLen + kLenNumLowSymbols + kLenNumMidSymbols + kLenNumHighSymbols)
106 #define IsRep (IsMatch + (kNumStates << kNumPosBitsMax))
107 #define IsRepG0 (IsRep + kNumStates)
108 #define IsRepG1 (IsRepG0 + kNumStates)
109 #define IsRepG2 (IsRepG1 + kNumStates)
110 #define IsRep0Long (IsRepG2 + kNumStates)
111 #define PosSlot (IsRep0Long + (kNumStates << kNumPosBitsMax))
112 #define SpecPos (PosSlot + (kNumLenToPosStates << kNumPosSlotBits))
113 #define Align (SpecPos + kNumFullDistances - kEndPosModelIndex)
114 #define LenCoder (Align + kAlignTableSize)
115 #define RepLenCoder (LenCoder + kNumLenProbs)
116 #define Literal (RepLenCoder + kNumLenProbs)
118 #define LZMA_BASE_SIZE 1846
119 #define LZMA_LIT_SIZE 0x300
121 #if Literal != LZMA_BASE_SIZE
125 #define LzmaProps_GetNumProbs(p) (Literal + ((UInt32)LZMA_LIT_SIZE << ((p)->lc + (p)->lp)))
127 #define LZMA_DIC_MIN (1 << 12)
129 /* First LZMA-symbol is always decoded.
130 And it decodes new LZMA-symbols while (buf < bufLimit), but "buf" is without last normalization
134 SZ_ERROR_DATA - Error
136 < kMatchSpecLenStart : normal remain
137 = kMatchSpecLenStart : finished
138 = kMatchSpecLenStart + 1 : Flush marker (unused now)
139 = kMatchSpecLenStart + 2 : State Init Marker (unused now)
142 static int MY_FAST_CALL
LzmaDec_DecodeReal(CLzmaDec
*p
, SizeT limit
, const Byte
*bufLimit
)
144 CLzmaProb
*probs
= p
->probs
;
146 unsigned state
= p
->state
;
147 UInt32 rep0
= p
->reps
[0], rep1
= p
->reps
[1], rep2
= p
->reps
[2], rep3
= p
->reps
[3];
148 unsigned pbMask
= ((unsigned)1 << (p
->prop
.pb
)) - 1;
149 unsigned lpMask
= ((unsigned)1 << (p
->prop
.lp
)) - 1;
150 unsigned lc
= p
->prop
.lc
;
153 SizeT dicBufSize
= p
->dicBufSize
;
154 SizeT dicPos
= p
->dicPos
;
156 UInt32 processedPos
= p
->processedPos
;
157 UInt32 checkDicSize
= p
->checkDicSize
;
160 const Byte
*buf
= p
->buf
;
161 UInt32 range
= p
->range
;
162 UInt32 code
= p
->code
;
169 unsigned posState
= processedPos
& pbMask
;
171 prob
= probs
+ IsMatch
+ (state
<< kNumPosBitsMax
) + posState
;
176 prob
= probs
+ Literal
;
177 if (processedPos
!= 0 || checkDicSize
!= 0)
178 prob
+= ((UInt32
)LZMA_LIT_SIZE
* (((processedPos
& lpMask
) << lc
) +
179 (dic
[(dicPos
== 0 ? dicBufSize
: dicPos
) - 1] >> (8 - lc
))));
182 if (state
< kNumLitStates
)
184 state
-= (state
< 4) ? state
: 3;
186 #ifdef _LZMA_SIZE_OPT
187 do { NORMAL_LITER_DEC
} while (symbol
< 0x100);
201 unsigned matchByte
= dic
[dicPos
- rep0
+ (dicPos
< rep0
? dicBufSize
: 0)];
202 unsigned offs
= 0x100;
203 state
-= (state
< 10) ? 3 : 6;
205 #ifdef _LZMA_SIZE_OPT
212 while (symbol
< 0x100);
229 dic
[dicPos
++] = (Byte
)symbol
;
235 prob
= probs
+ IsRep
+ state
;
240 prob
= probs
+ LenCoder
;
245 if (checkDicSize
== 0 && processedPos
== 0)
246 return SZ_ERROR_DATA
;
247 prob
= probs
+ IsRepG0
+ state
;
251 prob
= probs
+ IsRep0Long
+ (state
<< kNumPosBitsMax
) + posState
;
255 dic
[dicPos
] = dic
[dicPos
- rep0
+ (dicPos
< rep0
? dicBufSize
: 0)];
258 state
= state
< kNumLitStates
? 9 : 11;
267 prob
= probs
+ IsRepG1
+ state
;
276 prob
= probs
+ IsRepG2
+ state
;
293 state
= state
< kNumLitStates
? 8 : 11;
294 prob
= probs
+ RepLenCoder
;
297 #ifdef _LZMA_SIZE_OPT
299 unsigned lim
, offset
;
300 CLzmaProb
*probLen
= prob
+ LenChoice
;
304 probLen
= prob
+ LenLow
+ (posState
<< kLenNumLowBits
);
306 lim
= (1 << kLenNumLowBits
);
311 probLen
= prob
+ LenChoice2
;
315 probLen
= prob
+ LenMid
+ (posState
<< kLenNumMidBits
);
316 offset
= kLenNumLowSymbols
;
317 lim
= (1 << kLenNumMidBits
);
322 probLen
= prob
+ LenHigh
;
323 offset
= kLenNumLowSymbols
+ kLenNumMidSymbols
;
324 lim
= (1 << kLenNumHighBits
);
327 TREE_DECODE(probLen
, lim
, len
);
332 CLzmaProb
*probLen
= prob
+ LenChoice
;
336 probLen
= prob
+ LenLow
+ (posState
<< kLenNumLowBits
);
338 TREE_GET_BIT(probLen
, len
);
339 TREE_GET_BIT(probLen
, len
);
340 TREE_GET_BIT(probLen
, len
);
346 probLen
= prob
+ LenChoice2
;
350 probLen
= prob
+ LenMid
+ (posState
<< kLenNumMidBits
);
352 TREE_GET_BIT(probLen
, len
);
353 TREE_GET_BIT(probLen
, len
);
354 TREE_GET_BIT(probLen
, len
);
359 probLen
= prob
+ LenHigh
;
360 TREE_DECODE(probLen
, (1 << kLenNumHighBits
), len
);
361 len
+= kLenNumLowSymbols
+ kLenNumMidSymbols
;
367 if (state
>= kNumStates
)
370 prob
= probs
+ PosSlot
+
371 ((len
< kNumLenToPosStates
? len
: kNumLenToPosStates
- 1) << kNumPosSlotBits
);
372 TREE_6_DECODE(prob
, distance
);
373 if (distance
>= kStartPosModelIndex
)
375 unsigned posSlot
= (unsigned)distance
;
376 unsigned numDirectBits
= (unsigned)(((distance
>> 1) - 1));
377 distance
= (2 | (distance
& 1));
378 if (posSlot
< kEndPosModelIndex
)
380 distance
<<= numDirectBits
;
381 prob
= probs
+ SpecPos
+ distance
- posSlot
- 1;
387 GET_BIT2(prob
+ i
, i
, ; , distance
|= mask
);
390 while (--numDirectBits
!= 0);
395 numDirectBits
-= kNumAlignBits
;
404 t
= (0 - ((UInt32
)code
>> 31)); /* (UInt32)((Int32)code >> 31) */
405 distance
= (distance
<< 1) + (t
+ 1);
417 while (--numDirectBits
!= 0);
418 prob
= probs
+ Align
;
419 distance
<<= kNumAlignBits
;
422 GET_BIT2(prob
+ i
, i
, ; , distance
|= 1);
423 GET_BIT2(prob
+ i
, i
, ; , distance
|= 2);
424 GET_BIT2(prob
+ i
, i
, ; , distance
|= 4);
425 GET_BIT2(prob
+ i
, i
, ; , distance
|= 8);
427 if (distance
== (UInt32
)0xFFFFFFFF)
429 len
+= kMatchSpecLenStart
;
440 if (checkDicSize
== 0)
442 if (distance
>= processedPos
)
445 return SZ_ERROR_DATA
;
448 else if (distance
>= checkDicSize
)
451 return SZ_ERROR_DATA
;
453 state
= (state
< kNumStates
+ kNumLitStates
) ? kNumLitStates
: kNumLitStates
+ 3;
463 if ((rem
= limit
- dicPos
) == 0)
466 return SZ_ERROR_DATA
;
469 curLen
= ((rem
< len
) ? (unsigned)rem
: len
);
470 pos
= dicPos
- rep0
+ (dicPos
< rep0
? dicBufSize
: 0);
472 processedPos
+= curLen
;
475 if (curLen
<= dicBufSize
- pos
)
477 Byte
*dest
= dic
+ dicPos
;
478 ptrdiff_t src
= (ptrdiff_t)pos
- (ptrdiff_t)dicPos
;
479 const Byte
*lim
= dest
+ curLen
;
482 *(dest
) = (Byte
)*(dest
+ src
);
483 while (++dest
!= lim
);
489 dic
[dicPos
++] = dic
[pos
];
490 if (++pos
== dicBufSize
)
493 while (--curLen
!= 0);
498 while (dicPos
< limit
&& buf
< bufLimit
);
507 p
->processedPos
= processedPos
;
517 static void MY_FAST_CALL
LzmaDec_WriteRem(CLzmaDec
*p
, SizeT limit
)
519 if (p
->remainLen
!= 0 && p
->remainLen
< kMatchSpecLenStart
)
522 SizeT dicPos
= p
->dicPos
;
523 SizeT dicBufSize
= p
->dicBufSize
;
524 unsigned len
= p
->remainLen
;
525 SizeT rep0
= p
->reps
[0]; /* we use SizeT to avoid the BUG of VC14 for AMD64 */
526 SizeT rem
= limit
- dicPos
;
528 len
= (unsigned)(rem
);
530 if (p
->checkDicSize
== 0 && p
->prop
.dicSize
- p
->processedPos
<= len
)
531 p
->checkDicSize
= p
->prop
.dicSize
;
533 p
->processedPos
+= len
;
538 dic
[dicPos
] = dic
[dicPos
- rep0
+ (dicPos
< rep0
? dicBufSize
: 0)];
545 static int MY_FAST_CALL
LzmaDec_DecodeReal2(CLzmaDec
*p
, SizeT limit
, const Byte
*bufLimit
)
549 SizeT limit2
= limit
;
550 if (p
->checkDicSize
== 0)
552 UInt32 rem
= p
->prop
.dicSize
- p
->processedPos
;
553 if (limit
- p
->dicPos
> rem
)
554 limit2
= p
->dicPos
+ rem
;
557 RINOK(LzmaDec_DecodeReal(p
, limit2
, bufLimit
));
559 if (p
->checkDicSize
== 0 && p
->processedPos
>= p
->prop
.dicSize
)
560 p
->checkDicSize
= p
->prop
.dicSize
;
562 LzmaDec_WriteRem(p
, limit
);
564 while (p
->dicPos
< limit
&& p
->buf
< bufLimit
&& p
->remainLen
< kMatchSpecLenStart
);
566 if (p
->remainLen
> kMatchSpecLenStart
)
567 p
->remainLen
= kMatchSpecLenStart
;
574 DUMMY_ERROR
, /* unexpected end of input stream */
580 static ELzmaDummy
LzmaDec_TryDummy(const CLzmaDec
*p
, const Byte
*buf
, SizeT inSize
)
582 UInt32 range
= p
->range
;
583 UInt32 code
= p
->code
;
584 const Byte
*bufLimit
= buf
+ inSize
;
585 const CLzmaProb
*probs
= p
->probs
;
586 unsigned state
= p
->state
;
590 const CLzmaProb
*prob
;
593 unsigned posState
= (p
->processedPos
) & ((1 << p
->prop
.pb
) - 1);
595 prob
= probs
+ IsMatch
+ (state
<< kNumPosBitsMax
) + posState
;
600 /* if (bufLimit - buf >= 7) return DUMMY_LIT; */
602 prob
= probs
+ Literal
;
603 if (p
->checkDicSize
!= 0 || p
->processedPos
!= 0)
604 prob
+= ((UInt32
)LZMA_LIT_SIZE
*
605 ((((p
->processedPos
) & ((1 << (p
->prop
.lp
)) - 1)) << p
->prop
.lc
) +
606 (p
->dic
[(p
->dicPos
== 0 ? p
->dicBufSize
: p
->dicPos
) - 1] >> (8 - p
->prop
.lc
))));
608 if (state
< kNumLitStates
)
611 do { GET_BIT_CHECK(prob
+ symbol
, symbol
) } while (symbol
< 0x100);
615 unsigned matchByte
= p
->dic
[p
->dicPos
- p
->reps
[0] +
616 (p
->dicPos
< p
->reps
[0] ? p
->dicBufSize
: 0)];
617 unsigned offs
= 0x100;
622 const CLzmaProb
*probLit
;
624 bit
= (matchByte
& offs
);
625 probLit
= prob
+ offs
+ bit
+ symbol
;
626 GET_BIT2_CHECK(probLit
, symbol
, offs
&= ~bit
, offs
&= bit
)
628 while (symbol
< 0x100);
637 prob
= probs
+ IsRep
+ state
;
642 prob
= probs
+ LenCoder
;
649 prob
= probs
+ IsRepG0
+ state
;
653 prob
= probs
+ IsRep0Long
+ (state
<< kNumPosBitsMax
) + posState
;
668 prob
= probs
+ IsRepG1
+ state
;
676 prob
= probs
+ IsRepG2
+ state
;
688 prob
= probs
+ RepLenCoder
;
691 unsigned limit
, offset
;
692 const CLzmaProb
*probLen
= prob
+ LenChoice
;
693 IF_BIT_0_CHECK(probLen
)
696 probLen
= prob
+ LenLow
+ (posState
<< kLenNumLowBits
);
698 limit
= 1 << kLenNumLowBits
;
703 probLen
= prob
+ LenChoice2
;
704 IF_BIT_0_CHECK(probLen
)
707 probLen
= prob
+ LenMid
+ (posState
<< kLenNumMidBits
);
708 offset
= kLenNumLowSymbols
;
709 limit
= 1 << kLenNumMidBits
;
714 probLen
= prob
+ LenHigh
;
715 offset
= kLenNumLowSymbols
+ kLenNumMidSymbols
;
716 limit
= 1 << kLenNumHighBits
;
719 TREE_DECODE_CHECK(probLen
, limit
, len
);
726 prob
= probs
+ PosSlot
+
727 ((len
< kNumLenToPosStates
? len
: kNumLenToPosStates
- 1) <<
729 TREE_DECODE_CHECK(prob
, 1 << kNumPosSlotBits
, posSlot
);
730 if (posSlot
>= kStartPosModelIndex
)
732 unsigned numDirectBits
= ((posSlot
>> 1) - 1);
734 /* if (bufLimit - buf >= 8) return DUMMY_MATCH; */
736 if (posSlot
< kEndPosModelIndex
)
738 prob
= probs
+ SpecPos
+ ((2 | (posSlot
& 1)) << numDirectBits
) - posSlot
- 1;
742 numDirectBits
-= kNumAlignBits
;
747 code
-= range
& (((code
- range
) >> 31) - 1);
748 /* if (code >= range) code -= range; */
750 while (--numDirectBits
!= 0);
751 prob
= probs
+ Align
;
752 numDirectBits
= kNumAlignBits
;
758 GET_BIT_CHECK(prob
+ i
, i
);
760 while (--numDirectBits
!= 0);
771 void LzmaDec_InitDicAndState(CLzmaDec
*p
, Bool initDic
, Bool initState
)
781 p
->needInitState
= 1;
784 p
->needInitState
= 1;
787 void LzmaDec_Init(CLzmaDec
*p
)
790 LzmaDec_InitDicAndState(p
, True
, True
);
793 static void LzmaDec_InitStateReal(CLzmaDec
*p
)
795 SizeT numProbs
= LzmaProps_GetNumProbs(&p
->prop
);
797 CLzmaProb
*probs
= p
->probs
;
798 for (i
= 0; i
< numProbs
; i
++)
799 probs
[i
] = kBitModelTotal
>> 1;
800 p
->reps
[0] = p
->reps
[1] = p
->reps
[2] = p
->reps
[3] = 1;
802 p
->needInitState
= 0;
805 SRes
LzmaDec_DecodeToDic(CLzmaDec
*p
, SizeT dicLimit
, const Byte
*src
, SizeT
*srcLen
,
806 ELzmaFinishMode finishMode
, ELzmaStatus
*status
)
808 SizeT inSize
= *srcLen
;
810 LzmaDec_WriteRem(p
, dicLimit
);
812 *status
= LZMA_STATUS_NOT_SPECIFIED
;
814 while (p
->remainLen
!= kMatchSpecLenStart
)
820 for (; inSize
> 0 && p
->tempBufSize
< RC_INIT_SIZE
; (*srcLen
)++, inSize
--)
821 p
->tempBuf
[p
->tempBufSize
++] = *src
++;
822 if (p
->tempBufSize
< RC_INIT_SIZE
)
824 *status
= LZMA_STATUS_NEEDS_MORE_INPUT
;
827 if (p
->tempBuf
[0] != 0)
828 return SZ_ERROR_DATA
;
830 ((UInt32
)p
->tempBuf
[1] << 24)
831 | ((UInt32
)p
->tempBuf
[2] << 16)
832 | ((UInt32
)p
->tempBuf
[3] << 8)
833 | ((UInt32
)p
->tempBuf
[4]);
834 p
->range
= 0xFFFFFFFF;
840 if (p
->dicPos
>= dicLimit
)
842 if (p
->remainLen
== 0 && p
->code
== 0)
844 *status
= LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK
;
847 if (finishMode
== LZMA_FINISH_ANY
)
849 *status
= LZMA_STATUS_NOT_FINISHED
;
852 if (p
->remainLen
!= 0)
854 *status
= LZMA_STATUS_NOT_FINISHED
;
855 return SZ_ERROR_DATA
;
860 if (p
->needInitState
)
861 LzmaDec_InitStateReal(p
);
863 if (p
->tempBufSize
== 0)
866 const Byte
*bufLimit
;
867 if (inSize
< LZMA_REQUIRED_INPUT_MAX
|| checkEndMarkNow
)
869 int dummyRes
= LzmaDec_TryDummy(p
, src
, inSize
);
870 if (dummyRes
== DUMMY_ERROR
)
872 memcpy(p
->tempBuf
, src
, inSize
);
873 p
->tempBufSize
= (unsigned)inSize
;
875 *status
= LZMA_STATUS_NEEDS_MORE_INPUT
;
878 if (checkEndMarkNow
&& dummyRes
!= DUMMY_MATCH
)
880 *status
= LZMA_STATUS_NOT_FINISHED
;
881 return SZ_ERROR_DATA
;
886 bufLimit
= src
+ inSize
- LZMA_REQUIRED_INPUT_MAX
;
888 if (LzmaDec_DecodeReal2(p
, dicLimit
, bufLimit
) != 0)
889 return SZ_ERROR_DATA
;
890 processed
= (SizeT
)(p
->buf
- src
);
891 (*srcLen
) += processed
;
897 unsigned rem
= p
->tempBufSize
, lookAhead
= 0;
898 while (rem
< LZMA_REQUIRED_INPUT_MAX
&& lookAhead
< inSize
)
899 p
->tempBuf
[rem
++] = src
[lookAhead
++];
900 p
->tempBufSize
= rem
;
901 if (rem
< LZMA_REQUIRED_INPUT_MAX
|| checkEndMarkNow
)
903 int dummyRes
= LzmaDec_TryDummy(p
, p
->tempBuf
, rem
);
904 if (dummyRes
== DUMMY_ERROR
)
906 (*srcLen
) += lookAhead
;
907 *status
= LZMA_STATUS_NEEDS_MORE_INPUT
;
910 if (checkEndMarkNow
&& dummyRes
!= DUMMY_MATCH
)
912 *status
= LZMA_STATUS_NOT_FINISHED
;
913 return SZ_ERROR_DATA
;
917 if (LzmaDec_DecodeReal2(p
, dicLimit
, p
->buf
) != 0)
918 return SZ_ERROR_DATA
;
921 unsigned kkk
= (unsigned)(p
->buf
- p
->tempBuf
);
923 return SZ_ERROR_FAIL
; /* some internal error */
926 return SZ_ERROR_FAIL
; /* some internal error */
929 (*srcLen
) += lookAhead
;
936 *status
= LZMA_STATUS_FINISHED_WITH_MARK
;
937 return (p
->code
== 0) ? SZ_OK
: SZ_ERROR_DATA
;
940 SRes
LzmaDec_DecodeToBuf(CLzmaDec
*p
, Byte
*dest
, SizeT
*destLen
, const Byte
*src
, SizeT
*srcLen
, ELzmaFinishMode finishMode
, ELzmaStatus
*status
)
942 SizeT outSize
= *destLen
;
943 SizeT inSize
= *srcLen
;
944 *srcLen
= *destLen
= 0;
947 SizeT inSizeCur
= inSize
, outSizeCur
, dicPos
;
948 ELzmaFinishMode curFinishMode
;
950 if (p
->dicPos
== p
->dicBufSize
)
953 if (outSize
> p
->dicBufSize
- dicPos
)
955 outSizeCur
= p
->dicBufSize
;
956 curFinishMode
= LZMA_FINISH_ANY
;
960 outSizeCur
= dicPos
+ outSize
;
961 curFinishMode
= finishMode
;
964 res
= LzmaDec_DecodeToDic(p
, outSizeCur
, src
, &inSizeCur
, curFinishMode
, status
);
967 *srcLen
+= inSizeCur
;
968 outSizeCur
= p
->dicPos
- dicPos
;
969 memcpy(dest
, p
->dic
+ dicPos
, outSizeCur
);
971 outSize
-= outSizeCur
;
972 *destLen
+= outSizeCur
;
975 if (outSizeCur
== 0 || outSize
== 0)
980 void LzmaDec_FreeProbs(CLzmaDec
*p
, ISzAlloc
*alloc
)
982 alloc
->Free(alloc
, p
->probs
);
986 static void LzmaDec_FreeDict(CLzmaDec
*p
, ISzAlloc
*alloc
)
988 alloc
->Free(alloc
, p
->dic
);
992 void LzmaDec_Free(CLzmaDec
*p
, ISzAlloc
*alloc
)
994 LzmaDec_FreeProbs(p
, alloc
);
995 LzmaDec_FreeDict(p
, alloc
);
998 SRes
LzmaProps_Decode(CLzmaProps
*p
, const Byte
*data
, unsigned size
)
1003 if (size
< LZMA_PROPS_SIZE
)
1004 return SZ_ERROR_UNSUPPORTED
;
1006 dicSize
= data
[1] | ((UInt32
)data
[2] << 8) | ((UInt32
)data
[3] << 16) | ((UInt32
)data
[4] << 24);
1008 if (dicSize
< LZMA_DIC_MIN
)
1009 dicSize
= LZMA_DIC_MIN
;
1010 p
->dicSize
= dicSize
;
1013 if (d
>= (9 * 5 * 5))
1014 return SZ_ERROR_UNSUPPORTED
;
1024 static SRes
LzmaDec_AllocateProbs2(CLzmaDec
*p
, const CLzmaProps
*propNew
, ISzAlloc
*alloc
)
1026 UInt32 numProbs
= LzmaProps_GetNumProbs(propNew
);
1027 if (!p
->probs
|| numProbs
!= p
->numProbs
)
1029 LzmaDec_FreeProbs(p
, alloc
);
1030 p
->probs
= (CLzmaProb
*)alloc
->Alloc(alloc
, numProbs
* sizeof(CLzmaProb
));
1031 p
->numProbs
= numProbs
;
1033 return SZ_ERROR_MEM
;
1038 SRes
LzmaDec_AllocateProbs(CLzmaDec
*p
, const Byte
*props
, unsigned propsSize
, ISzAlloc
*alloc
)
1041 RINOK(LzmaProps_Decode(&propNew
, props
, propsSize
));
1042 RINOK(LzmaDec_AllocateProbs2(p
, &propNew
, alloc
));
1047 SRes
LzmaDec_Allocate(CLzmaDec
*p
, const Byte
*props
, unsigned propsSize
, ISzAlloc
*alloc
)
1051 RINOK(LzmaProps_Decode(&propNew
, props
, propsSize
));
1052 RINOK(LzmaDec_AllocateProbs2(p
, &propNew
, alloc
));
1055 UInt32 dictSize
= propNew
.dicSize
;
1056 SizeT mask
= ((UInt32
)1 << 12) - 1;
1057 if (dictSize
>= ((UInt32
)1 << 30)) mask
= ((UInt32
)1 << 22) - 1;
1058 else if (dictSize
>= ((UInt32
)1 << 22)) mask
= ((UInt32
)1 << 20) - 1;;
1059 dicBufSize
= ((SizeT
)dictSize
+ mask
) & ~mask
;
1060 if (dicBufSize
< dictSize
)
1061 dicBufSize
= dictSize
;
1064 if (!p
->dic
|| dicBufSize
!= p
->dicBufSize
)
1066 LzmaDec_FreeDict(p
, alloc
);
1067 p
->dic
= (Byte
*)alloc
->Alloc(alloc
, dicBufSize
);
1070 LzmaDec_FreeProbs(p
, alloc
);
1071 return SZ_ERROR_MEM
;
1074 p
->dicBufSize
= dicBufSize
;
1079 SRes
LzmaDecode(Byte
*dest
, SizeT
*destLen
, const Byte
*src
, SizeT
*srcLen
,
1080 const Byte
*propData
, unsigned propSize
, ELzmaFinishMode finishMode
,
1081 ELzmaStatus
*status
, ISzAlloc
*alloc
)
1085 SizeT outSize
= *destLen
, inSize
= *srcLen
;
1086 *destLen
= *srcLen
= 0;
1087 *status
= LZMA_STATUS_NOT_SPECIFIED
;
1088 if (inSize
< RC_INIT_SIZE
)
1089 return SZ_ERROR_INPUT_EOF
;
1090 LzmaDec_Construct(&p
);
1091 RINOK(LzmaDec_AllocateProbs(&p
, propData
, propSize
, alloc
));
1093 p
.dicBufSize
= outSize
;
1096 res
= LzmaDec_DecodeToDic(&p
, outSize
, src
, srcLen
, finishMode
, status
);
1097 *destLen
= p
.dicPos
;
1098 if (res
== SZ_OK
&& *status
== LZMA_STATUS_NEEDS_MORE_INPUT
)
1099 res
= SZ_ERROR_INPUT_EOF
;
1100 LzmaDec_FreeProbs(&p
, alloc
);