1 /* LzmaDec.c -- LZMA Decoder
2 2009-09-20 : Igor Pavlov : Public domain */
9 #define kTopValue ((uint32_t)1 << kNumTopBits)
11 #define kNumBitModelTotalBits 11
12 #define kBitModelTotal (1 << kNumBitModelTotalBits)
13 #define kNumMoveBits 5
15 #define RC_INIT_SIZE 5
17 #define NORMALIZE if (range < kTopValue) { range <<= 8; code = (code << 8) | (*buf++); }
19 #define IF_BIT_0(p) ttt = *(p); NORMALIZE; bound = (range >> kNumBitModelTotalBits) * ttt; if (code < bound)
20 #define UPDATE_0(p) range = bound; *(p) = (CLzmaProb)(ttt + ((kBitModelTotal - ttt) >> kNumMoveBits));
21 #define UPDATE_1(p) range -= bound; code -= bound; *(p) = (CLzmaProb)(ttt - (ttt >> kNumMoveBits));
22 #define GET_BIT2(p, i, A0, A1) IF_BIT_0(p) \
23 { UPDATE_0(p); i = (i + i); A0; } else \
24 { UPDATE_1(p); i = (i + i) + 1; A1; }
25 #define GET_BIT(p, i) GET_BIT2(p, i, ; , ;)
27 #define TREE_GET_BIT(probs, i) { GET_BIT((probs + i), i); }
28 #define TREE_DECODE(probs, limit, i) \
29 { i = 1; do { TREE_GET_BIT(probs, i); } while (i < limit); i -= limit; }
31 #define TREE_6_DECODE(probs, i) \
33 TREE_GET_BIT(probs, i); \
34 TREE_GET_BIT(probs, i); \
35 TREE_GET_BIT(probs, i); \
36 TREE_GET_BIT(probs, i); \
37 TREE_GET_BIT(probs, i); \
38 TREE_GET_BIT(probs, i); \
41 #define NORMALIZE_CHECK if (range < kTopValue) { if (buf >= bufLimit) return DUMMY_ERROR; range <<= 8; code = (code << 8) | (*buf++); }
43 #define IF_BIT_0_CHECK(p) ttt = *(p); NORMALIZE_CHECK; bound = (range >> kNumBitModelTotalBits) * ttt; if (code < bound)
44 #define UPDATE_0_CHECK range = bound;
45 #define UPDATE_1_CHECK range -= bound; code -= bound;
46 #define GET_BIT2_CHECK(p, i, A0, A1) IF_BIT_0_CHECK(p) \
47 { UPDATE_0_CHECK; i = (i + i); A0; } else \
48 { UPDATE_1_CHECK; i = (i + i) + 1; A1; }
49 #define GET_BIT_CHECK(p, i) GET_BIT2_CHECK(p, i, ; , ;)
50 #define TREE_DECODE_CHECK(probs, limit, i) \
51 { i = 1; do { GET_BIT_CHECK(probs + i, i) } while (i < limit); i -= limit; }
54 #define kNumPosBitsMax 4
55 #define kNumPosStatesMax (1 << kNumPosBitsMax)
57 #define kLenNumLowBits 3
58 #define kLenNumLowSymbols (1 << kLenNumLowBits)
59 #define kLenNumMidBits 3
60 #define kLenNumMidSymbols (1 << kLenNumMidBits)
61 #define kLenNumHighBits 8
62 #define kLenNumHighSymbols (1 << kLenNumHighBits)
65 #define LenChoice2 (LenChoice + 1)
66 #define LenLow (LenChoice2 + 1)
67 #define LenMid (LenLow + (kNumPosStatesMax << kLenNumLowBits))
68 #define LenHigh (LenMid + (kNumPosStatesMax << kLenNumMidBits))
69 #define kNumLenProbs (LenHigh + kLenNumHighSymbols)
73 #define kNumLitStates 7
75 #define kStartPosModelIndex 4
76 #define kEndPosModelIndex 14
77 #define kNumFullDistances (1 << (kEndPosModelIndex >> 1))
79 #define kNumPosSlotBits 6
80 #define kNumLenToPosStates 4
82 #define kNumAlignBits 4
83 #define kAlignTableSize (1 << kNumAlignBits)
85 #define kMatchMinLen 2
86 #define kMatchSpecLenStart (kMatchMinLen + kLenNumLowSymbols + kLenNumMidSymbols + kLenNumHighSymbols)
89 #define IsRep (IsMatch + (kNumStates << kNumPosBitsMax))
90 #define IsRepG0 (IsRep + kNumStates)
91 #define IsRepG1 (IsRepG0 + kNumStates)
92 #define IsRepG2 (IsRepG1 + kNumStates)
93 #define IsRep0Long (IsRepG2 + kNumStates)
94 #define PosSlot (IsRep0Long + (kNumStates << kNumPosBitsMax))
95 #define SpecPos (PosSlot + (kNumLenToPosStates << kNumPosSlotBits))
96 #define Align (SpecPos + kNumFullDistances - kEndPosModelIndex)
97 #define LenCoder (Align + kAlignTableSize)
98 #define RepLenCoder (LenCoder + kNumLenProbs)
99 #define Literal (RepLenCoder + kNumLenProbs)
101 #define LZMA_BASE_SIZE 1846
102 #define LZMA_LIT_SIZE 768
104 #define LzmaProps_GetNumProbs(p) ((uint32_t)LZMA_BASE_SIZE + (LZMA_LIT_SIZE << ((p)->lc + (p)->lp)))
106 #if Literal != LZMA_BASE_SIZE
110 #define LZMA_DIC_MIN (1 << 12)
112 /* First LZMA-symbol is always decoded.
113 And it decodes new LZMA-symbols while (buf < bufLimit), but "buf" is without last normalization
117 SZ_ERROR_DATA - Error
119 < kMatchSpecLenStart : normal remain
120 = kMatchSpecLenStart : finished
121 = kMatchSpecLenStart + 1 : Flush marker
122 = kMatchSpecLenStart + 2 : State Init Marker
125 static int LzmaDec_DecodeReal(struct CLzmaDec
*p
, size_t limit_parm
, const uint8_t *bufLimit
)
127 CLzmaProb
*probs
= p
->probs
;
129 unsigned state
= p
->state
;
130 uint32_t rep0
= p
->reps
[0], rep1
= p
->reps
[1], rep2
= p
->reps
[2], rep3
= p
->reps
[3];
131 unsigned pbMask
= ((unsigned)1 << (p
->prop
.pb
)) - 1;
132 unsigned lpMask
= ((unsigned)1 << (p
->prop
.lp
)) - 1;
133 unsigned lc
= p
->prop
.lc
;
135 uint8_t *dic
= p
->dic
;
136 size_t dicBufSize
= p
->dicBufSize
;
137 size_t dicPos
= p
->dicPos
;
139 uint32_t processedPos
= p
->processedPos
;
140 uint32_t checkDicSize
= p
->checkDicSize
;
143 const uint8_t *buf
= p
->buf
;
144 uint32_t range
= p
->range
;
145 uint32_t code
= p
->code
;
152 unsigned posState
= processedPos
& pbMask
;
154 prob
= probs
+ IsMatch
+ (state
<< kNumPosBitsMax
) + posState
;
159 prob
= probs
+ Literal
;
160 if (checkDicSize
!= 0 || processedPos
!= 0)
161 prob
+= (LZMA_LIT_SIZE
* (((processedPos
& lpMask
) << lc
) +
162 (dic
[(dicPos
== 0 ? dicBufSize
: dicPos
) - 1] >> (8 - lc
))));
164 if (state
< kNumLitStates
)
166 state
-= (state
< 4) ? state
: 3;
168 do { GET_BIT(prob
+ symbol
, symbol
) } while (symbol
< 0x100);
172 unsigned matchuint8_t
= p
->dic
[(dicPos
- rep0
) + ((dicPos
< rep0
) ? dicBufSize
: 0)];
173 unsigned offs
= 0x100;
174 state
-= (state
< 10) ? 3 : 6;
181 bit
= (matchuint8_t
& offs
);
182 probLit
= prob
+ offs
+ bit
+ symbol
;
183 GET_BIT2(probLit
, symbol
, offs
&= ~bit
, offs
&= bit
)
185 while (symbol
< 0x100);
187 dic
[dicPos
++] = (uint8_t)symbol
;
194 prob
= probs
+ IsRep
+ state
;
199 prob
= probs
+ LenCoder
;
204 if (checkDicSize
== 0 && processedPos
== 0)
205 return SZ_ERROR_DATA
;
206 prob
= probs
+ IsRepG0
+ state
;
210 prob
= probs
+ IsRep0Long
+ (state
<< kNumPosBitsMax
) + posState
;
214 dic
[dicPos
] = dic
[(dicPos
- rep0
) + ((dicPos
< rep0
) ? dicBufSize
: 0)];
217 state
= state
< kNumLitStates
? 9 : 11;
226 prob
= probs
+ IsRepG1
+ state
;
235 prob
= probs
+ IsRepG2
+ state
;
252 state
= state
< kNumLitStates
? 8 : 11;
253 prob
= probs
+ RepLenCoder
;
256 unsigned limit
, offset
;
257 CLzmaProb
*probLen
= prob
+ LenChoice
;
261 probLen
= prob
+ LenLow
+ (posState
<< kLenNumLowBits
);
263 limit
= (1 << kLenNumLowBits
);
268 probLen
= prob
+ LenChoice2
;
272 probLen
= prob
+ LenMid
+ (posState
<< kLenNumMidBits
);
273 offset
= kLenNumLowSymbols
;
274 limit
= (1 << kLenNumMidBits
);
279 probLen
= prob
+ LenHigh
;
280 offset
= kLenNumLowSymbols
+ kLenNumMidSymbols
;
281 limit
= (1 << kLenNumHighBits
);
284 TREE_DECODE(probLen
, limit
, len
);
288 if (state
>= kNumStates
)
291 prob
= probs
+ PosSlot
+
292 ((len
< kNumLenToPosStates
? len
: kNumLenToPosStates
- 1) << kNumPosSlotBits
);
293 TREE_6_DECODE(prob
, distance
);
294 if (distance
>= kStartPosModelIndex
)
296 unsigned posSlot
= (unsigned)distance
;
297 int numDirectBits
= (int)(((distance
>> 1) - 1));
298 distance
= (2 | (distance
& 1));
299 if (posSlot
< kEndPosModelIndex
)
301 distance
<<= numDirectBits
;
302 prob
= probs
+ SpecPos
+ distance
- posSlot
- 1;
308 GET_BIT2(prob
+ i
, i
, ; , distance
|= mask
);
311 while (--numDirectBits
!= 0);
316 numDirectBits
-= kNumAlignBits
;
325 t
= (0 - ((uint32_t)code
>> 31)); /* (uint32_t)((int32_t)code >> 31) */
326 distance
= (distance
<< 1) + (t
+ 1);
338 while (--numDirectBits
!= 0);
339 prob
= probs
+ Align
;
340 distance
<<= kNumAlignBits
;
343 GET_BIT2(prob
+ i
, i
, ; , distance
|= 1);
344 GET_BIT2(prob
+ i
, i
, ; , distance
|= 2);
345 GET_BIT2(prob
+ i
, i
, ; , distance
|= 4);
346 GET_BIT2(prob
+ i
, i
, ; , distance
|= 8);
348 if (distance
== (uint32_t)0xFFFFFFFF)
350 len
+= kMatchSpecLenStart
;
360 if (checkDicSize
== 0)
362 if (distance
>= processedPos
)
363 return SZ_ERROR_DATA
;
365 else if (distance
>= checkDicSize
)
366 return SZ_ERROR_DATA
;
367 state
= (state
< kNumStates
+ kNumLitStates
) ? kNumLitStates
: kNumLitStates
+ 3;
372 if (limit_parm
== dicPos
)
373 return SZ_ERROR_DATA
;
375 size_t rem
= limit_parm
- dicPos
;
376 unsigned curLen
= ((rem
< len
) ? (unsigned)rem
: len
);
377 size_t pos
= (dicPos
- rep0
) + ((dicPos
< rep0
) ? dicBufSize
: 0);
379 processedPos
+= curLen
;
382 if (pos
+ curLen
<= dicBufSize
)
384 uint8_t *dest
= dic
+ dicPos
;
385 ptrdiff_t src
= (ptrdiff_t)pos
- (ptrdiff_t)dicPos
;
386 const uint8_t *lim
= dest
+ curLen
;
389 *(dest
) = (uint8_t)*(dest
+ src
);
390 while (++dest
!= lim
);
396 dic
[dicPos
++] = dic
[pos
];
397 if (++pos
== dicBufSize
)
400 while (--curLen
!= 0);
405 while (dicPos
< limit_parm
&& buf
< bufLimit
);
412 p
->processedPos
= processedPos
;
422 static void LzmaDec_WriteRem(struct CLzmaDec
*p
, size_t limit
)
424 if (p
->remainLen
!= 0 && p
->remainLen
< kMatchSpecLenStart
)
426 uint8_t *dic
= p
->dic
;
427 size_t dicPos
= p
->dicPos
;
428 size_t dicBufSize
= p
->dicBufSize
;
429 unsigned len
= p
->remainLen
;
430 uint32_t rep0
= p
->reps
[0];
431 if (limit
- dicPos
< len
)
432 len
= (unsigned)(limit
- dicPos
);
434 if (p
->checkDicSize
== 0 && p
->prop
.dicSize
- p
->processedPos
<= len
)
435 p
->checkDicSize
= p
->prop
.dicSize
;
437 p
->processedPos
+= len
;
441 dic
[dicPos
] = dic
[(dicPos
- rep0
) + ((dicPos
< rep0
) ? dicBufSize
: 0)];
448 static int LzmaDec_DecodeReal2(struct CLzmaDec
*p
, size_t limit
, const uint8_t *bufLimit
)
452 size_t limit2
= limit
;
453 if (p
->checkDicSize
== 0)
455 uint32_t rem
= p
->prop
.dicSize
- p
->processedPos
;
456 if (limit
- p
->dicPos
> rem
)
457 limit2
= p
->dicPos
+ rem
;
459 RINOK(LzmaDec_DecodeReal(p
, limit2
, bufLimit
));
460 if (p
->processedPos
>= p
->prop
.dicSize
)
461 p
->checkDicSize
= p
->prop
.dicSize
;
462 LzmaDec_WriteRem(p
, limit
);
464 while (p
->dicPos
< limit
&& p
->buf
< bufLimit
&& p
->remainLen
< kMatchSpecLenStart
);
466 if (p
->remainLen
> kMatchSpecLenStart
)
468 p
->remainLen
= kMatchSpecLenStart
;
475 DUMMY_ERROR
, /* unexpected end of input stream */
481 static enum ELzmaDummy
LzmaDec_TryDummy(const struct CLzmaDec
*p
, const uint8_t *buf
, size_t inSize
)
483 uint32_t range
= p
->range
;
484 uint32_t code
= p
->code
;
485 const uint8_t *bufLimit
= buf
+ inSize
;
486 CLzmaProb
*probs
= p
->probs
;
487 unsigned state
= p
->state
;
494 unsigned posState
= (p
->processedPos
) & ((1 << p
->prop
.pb
) - 1);
496 prob
= probs
+ IsMatch
+ (state
<< kNumPosBitsMax
) + posState
;
501 /* if (bufLimit - buf >= 7) return DUMMY_LIT; */
503 prob
= probs
+ Literal
;
504 if (p
->checkDicSize
!= 0 || p
->processedPos
!= 0)
505 prob
+= (LZMA_LIT_SIZE
*
506 ((((p
->processedPos
) & ((1 << (p
->prop
.lp
)) - 1)) << p
->prop
.lc
) +
507 (p
->dic
[(p
->dicPos
== 0 ? p
->dicBufSize
: p
->dicPos
) - 1] >> (8 - p
->prop
.lc
))));
509 if (state
< kNumLitStates
)
512 do { GET_BIT_CHECK(prob
+ symbol
, symbol
) } while (symbol
< 0x100);
516 unsigned matchuint8_t
= p
->dic
[p
->dicPos
- p
->reps
[0] +
517 ((p
->dicPos
< p
->reps
[0]) ? p
->dicBufSize
: 0)];
518 unsigned offs
= 0x100;
525 bit
= (matchuint8_t
& offs
);
526 probLit
= prob
+ offs
+ bit
+ symbol
;
527 GET_BIT2_CHECK(probLit
, symbol
, offs
&= ~bit
, offs
&= bit
)
529 while (symbol
< 0x100);
538 prob
= probs
+ IsRep
+ state
;
543 prob
= probs
+ LenCoder
;
550 prob
= probs
+ IsRepG0
+ state
;
554 prob
= probs
+ IsRep0Long
+ (state
<< kNumPosBitsMax
) + posState
;
569 prob
= probs
+ IsRepG1
+ state
;
577 prob
= probs
+ IsRepG2
+ state
;
589 prob
= probs
+ RepLenCoder
;
592 unsigned limit
, offset
;
593 CLzmaProb
*probLen
= prob
+ LenChoice
;
594 IF_BIT_0_CHECK(probLen
)
597 probLen
= prob
+ LenLow
+ (posState
<< kLenNumLowBits
);
599 limit
= 1 << kLenNumLowBits
;
604 probLen
= prob
+ LenChoice2
;
605 IF_BIT_0_CHECK(probLen
)
608 probLen
= prob
+ LenMid
+ (posState
<< kLenNumMidBits
);
609 offset
= kLenNumLowSymbols
;
610 limit
= 1 << kLenNumMidBits
;
615 probLen
= prob
+ LenHigh
;
616 offset
= kLenNumLowSymbols
+ kLenNumMidSymbols
;
617 limit
= 1 << kLenNumHighBits
;
620 TREE_DECODE_CHECK(probLen
, limit
, len
);
627 prob
= probs
+ PosSlot
+
628 ((len
< kNumLenToPosStates
? len
: kNumLenToPosStates
- 1) <<
630 TREE_DECODE_CHECK(prob
, 1 << kNumPosSlotBits
, posSlot
);
631 if (posSlot
>= kStartPosModelIndex
)
633 int numDirectBits
= ((posSlot
>> 1) - 1);
635 /* if (bufLimit - buf >= 8) return DUMMY_MATCH; */
637 if (posSlot
< kEndPosModelIndex
)
639 prob
= probs
+ SpecPos
+ ((2 | (posSlot
& 1)) << numDirectBits
) - posSlot
- 1;
643 numDirectBits
-= kNumAlignBits
;
648 code
-= range
& (((code
- range
) >> 31) - 1);
649 /* if (code >= range) code -= range; */
651 while (--numDirectBits
!= 0);
652 prob
= probs
+ Align
;
653 numDirectBits
= kNumAlignBits
;
659 GET_BIT_CHECK(prob
+ i
, i
);
661 while (--numDirectBits
!= 0);
672 static void LzmaDec_InitRc(struct CLzmaDec
*p
, const uint8_t *data
)
674 p
->code
= ((uint32_t)data
[1] << 24) | ((uint32_t)data
[2] << 16) | ((uint32_t)data
[3] << 8) | ((uint32_t)data
[4]);
675 p
->range
= 0xFFFFFFFF;
679 static void LzmaDec_InitDicAndState(struct CLzmaDec
*p
, bool initDic
, bool initState
)
689 p
->needInitState
= 1;
692 p
->needInitState
= 1;
695 void LzmaDec_Init(struct CLzmaDec
*p
)
698 LzmaDec_InitDicAndState(p
, true, true);
701 static void LzmaDec_InitStateReal(struct CLzmaDec
*p
)
703 uint32_t numProbs
= Literal
+ ((uint32_t)LZMA_LIT_SIZE
<< (p
->prop
.lc
+ p
->prop
.lp
));
705 CLzmaProb
*probs
= p
->probs
;
706 for (i
= 0; i
< numProbs
; i
++)
707 probs
[i
] = kBitModelTotal
>> 1;
708 p
->reps
[0] = p
->reps
[1] = p
->reps
[2] = p
->reps
[3] = 1;
710 p
->needInitState
= 0;
713 SRes
LzmaDec_DecodeToDic(struct CLzmaDec
*p
, size_t dicLimit
, const uint8_t *src
, size_t *srcLen
,
714 enum ELzmaFinishMode finishMode
, enum ELzmaStatus
*status
)
716 size_t inSize
= *srcLen
;
718 LzmaDec_WriteRem(p
, dicLimit
);
720 *status
= LZMA_STATUS_NOT_SPECIFIED
;
722 while (p
->remainLen
!= kMatchSpecLenStart
)
726 if (p
->needFlush
!= 0)
728 for (; inSize
> 0 && p
->tempBufSize
< RC_INIT_SIZE
; (*srcLen
)++, inSize
--)
729 p
->tempBuf
[p
->tempBufSize
++] = *src
++;
730 if (p
->tempBufSize
< RC_INIT_SIZE
)
732 *status
= LZMA_STATUS_NEEDS_MORE_INPUT
;
735 if (p
->tempBuf
[0] != 0)
736 return SZ_ERROR_DATA
;
738 LzmaDec_InitRc(p
, p
->tempBuf
);
743 if (p
->dicPos
>= dicLimit
)
745 if (p
->remainLen
== 0 && p
->code
== 0)
747 *status
= LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK
;
750 if (finishMode
== LZMA_FINISH_ANY
)
752 *status
= LZMA_STATUS_NOT_FINISHED
;
755 if (p
->remainLen
!= 0)
757 *status
= LZMA_STATUS_NOT_FINISHED
;
758 return SZ_ERROR_DATA
;
763 if (p
->needInitState
)
764 LzmaDec_InitStateReal(p
);
766 if (p
->tempBufSize
== 0)
769 const uint8_t *bufLimit
;
770 if (inSize
< LZMA_REQUIRED_INPUT_MAX
|| checkEndMarkNow
)
772 int dummyRes
= LzmaDec_TryDummy(p
, src
, inSize
);
773 if (dummyRes
== DUMMY_ERROR
)
775 memcpy(p
->tempBuf
, src
, inSize
);
776 p
->tempBufSize
= (unsigned)inSize
;
778 *status
= LZMA_STATUS_NEEDS_MORE_INPUT
;
781 if (checkEndMarkNow
&& dummyRes
!= DUMMY_MATCH
)
783 *status
= LZMA_STATUS_NOT_FINISHED
;
784 return SZ_ERROR_DATA
;
789 bufLimit
= src
+ inSize
- LZMA_REQUIRED_INPUT_MAX
;
791 if (LzmaDec_DecodeReal2(p
, dicLimit
, bufLimit
) != 0)
792 return SZ_ERROR_DATA
;
793 processed
= (size_t)(p
->buf
- src
);
794 (*srcLen
) += processed
;
800 unsigned rem
= p
->tempBufSize
, lookAhead
= 0;
801 while (rem
< LZMA_REQUIRED_INPUT_MAX
&& lookAhead
< inSize
)
802 p
->tempBuf
[rem
++] = src
[lookAhead
++];
803 p
->tempBufSize
= rem
;
804 if (rem
< LZMA_REQUIRED_INPUT_MAX
|| checkEndMarkNow
)
806 int dummyRes
= LzmaDec_TryDummy(p
, p
->tempBuf
, rem
);
807 if (dummyRes
== DUMMY_ERROR
)
809 (*srcLen
) += lookAhead
;
810 *status
= LZMA_STATUS_NEEDS_MORE_INPUT
;
813 if (checkEndMarkNow
&& dummyRes
!= DUMMY_MATCH
)
815 *status
= LZMA_STATUS_NOT_FINISHED
;
816 return SZ_ERROR_DATA
;
820 if (LzmaDec_DecodeReal2(p
, dicLimit
, p
->buf
) != 0)
821 return SZ_ERROR_DATA
;
822 lookAhead
-= (rem
- (unsigned)(p
->buf
- p
->tempBuf
));
823 (*srcLen
) += lookAhead
;
830 *status
= LZMA_STATUS_FINISHED_WITH_MARK
;
831 return (p
->code
== 0) ? SZ_OK
: SZ_ERROR_DATA
;
834 SRes
LzmaDec_DecodeToBuf(struct CLzmaDec
*p
, uint8_t *dest
, size_t *destLen
, const uint8_t *src
, size_t *srcLen
, enum ELzmaFinishMode finishMode
, enum ELzmaStatus
*status
)
836 size_t outSize
= *destLen
;
837 size_t inSize
= *srcLen
;
838 *srcLen
= *destLen
= 0;
841 size_t inSizeCur
= inSize
, outSizeCur
, dicPos
;
842 enum ELzmaFinishMode curFinishMode
;
844 if (p
->dicPos
== p
->dicBufSize
)
847 if (outSize
> p
->dicBufSize
- dicPos
)
849 outSizeCur
= p
->dicBufSize
;
850 curFinishMode
= LZMA_FINISH_ANY
;
854 outSizeCur
= dicPos
+ outSize
;
855 curFinishMode
= finishMode
;
858 res
= LzmaDec_DecodeToDic(p
, outSizeCur
, src
, &inSizeCur
, curFinishMode
, status
);
861 *srcLen
+= inSizeCur
;
862 outSizeCur
= p
->dicPos
- dicPos
;
863 memcpy(dest
, p
->dic
+ dicPos
, outSizeCur
);
865 outSize
-= outSizeCur
;
866 *destLen
+= outSizeCur
;
869 if (outSizeCur
== 0 || outSize
== 0)
874 void LzmaDec_FreeProbs(struct CLzmaDec
*p
, struct ISzAlloc
*alloc
)
876 alloc
->Free(alloc
, p
->probs
);
880 static void LzmaDec_FreeDict(struct CLzmaDec
*p
, struct ISzAlloc
*alloc
)
882 alloc
->Free(alloc
, p
->dic
);
886 void LzmaDec_Free(struct CLzmaDec
*p
, struct ISzAlloc
*alloc
)
888 LzmaDec_FreeProbs(p
, alloc
);
889 LzmaDec_FreeDict(p
, alloc
);
892 SRes
LzmaProps_Decode(struct CLzmaProps
*p
, const uint8_t *data
, unsigned size
)
897 if (size
< LZMA_PROPS_SIZE
)
898 return SZ_ERROR_UNSUPPORTED
;
900 dicSize
= data
[1] | ((uint32_t)data
[2] << 8) | ((uint32_t)data
[3] << 16) | ((uint32_t)data
[4] << 24);
902 if (dicSize
< LZMA_DIC_MIN
)
903 dicSize
= LZMA_DIC_MIN
;
904 p
->dicSize
= dicSize
;
907 if (d
>= (9 * 5 * 5))
908 return SZ_ERROR_UNSUPPORTED
;
918 static SRes
LzmaDec_AllocateProbs2(struct CLzmaDec
*p
, const struct CLzmaProps
*propNew
, struct ISzAlloc
*alloc
)
920 uint32_t numProbs
= LzmaProps_GetNumProbs(propNew
);
921 if (p
->probs
== 0 || numProbs
!= p
->numProbs
)
923 LzmaDec_FreeProbs(p
, alloc
);
924 p
->probs
= (CLzmaProb
*)alloc
->Alloc(alloc
, numProbs
* sizeof(CLzmaProb
));
925 p
->numProbs
= numProbs
;
932 SRes
LzmaDec_AllocateProbs(struct CLzmaDec
*p
, const uint8_t *props
, unsigned propsSize
, struct ISzAlloc
*alloc
)
934 struct CLzmaProps propNew
;
935 RINOK(LzmaProps_Decode(&propNew
, props
, propsSize
));
936 RINOK(LzmaDec_AllocateProbs2(p
, &propNew
, alloc
));
941 SRes
LzmaDec_Allocate(struct CLzmaDec
*p
, const uint8_t *props
, unsigned propsSize
, struct ISzAlloc
*alloc
)
943 struct CLzmaProps propNew
;
945 RINOK(LzmaProps_Decode(&propNew
, props
, propsSize
));
946 RINOK(LzmaDec_AllocateProbs2(p
, &propNew
, alloc
));
947 dicBufSize
= propNew
.dicSize
;
948 if (p
->dic
== 0 || dicBufSize
!= p
->dicBufSize
)
950 LzmaDec_FreeDict(p
, alloc
);
951 p
->dic
= (uint8_t *)alloc
->Alloc(alloc
, dicBufSize
);
954 LzmaDec_FreeProbs(p
, alloc
);
958 p
->dicBufSize
= dicBufSize
;
963 SRes
LzmaDecode(uint8_t *dest
, size_t *destLen
, const uint8_t *src
, size_t *srcLen
,
964 const uint8_t *propData
, unsigned propSize
, enum ELzmaFinishMode finishMode
,
965 enum ELzmaStatus
*status
, struct ISzAlloc
*alloc
)
969 size_t inSize
= *srcLen
;
970 size_t outSize
= *destLen
;
971 *srcLen
= *destLen
= 0;
972 if (inSize
< RC_INIT_SIZE
)
973 return SZ_ERROR_INPUT_EOF
;
975 LzmaDec_Construct(&p
);
976 res
= LzmaDec_AllocateProbs(&p
, propData
, propSize
, alloc
);
980 p
.dicBufSize
= outSize
;
985 res
= LzmaDec_DecodeToDic(&p
, outSize
, src
, srcLen
, finishMode
, status
);
987 if (res
== SZ_OK
&& *status
== LZMA_STATUS_NEEDS_MORE_INPUT
)
988 res
= SZ_ERROR_INPUT_EOF
;
990 (*destLen
) = p
.dicPos
;
991 LzmaDec_FreeProbs(&p
, alloc
);