1 /* LzmaDec.c -- LZMA Decoder
2 2018-07-04 : Igor Pavlov : Public domain */
10 /* #include "CpuArch.h" */
13 #define kNumTopBits 24
14 #define kTopValue ((UInt32)1 << kNumTopBits)
16 #define kNumBitModelTotalBits 11
17 #define kBitModelTotal (1 << kNumBitModelTotalBits)
18 #define kNumMoveBits 5
20 #define RC_INIT_SIZE 5
22 #define NORMALIZE if (range < kTopValue) { range <<= 8; code = (code << 8) | (*buf++); }
24 #define IF_BIT_0(p) ttt = *(p); NORMALIZE; bound = (range >> kNumBitModelTotalBits) * (UInt32)ttt; if (code < bound)
25 #define UPDATE_0(p) range = bound; *(p) = (CLzmaProb)(ttt + ((kBitModelTotal - ttt) >> kNumMoveBits));
26 #define UPDATE_1(p) range -= bound; code -= bound; *(p) = (CLzmaProb)(ttt - (ttt >> kNumMoveBits));
27 #define GET_BIT2(p, i, A0, A1) IF_BIT_0(p)\
28 { UPDATE_0(p); i = (i + i); A0; } else \
29 { UPDATE_1(p); i = (i + i) + 1; A1; }
31 #define TREE_GET_BIT(probs, i) { GET_BIT2(probs + i, i, ;, ;); }
33 #define REV_BIT(p, i, A0, A1) IF_BIT_0(p + i)\
34 { UPDATE_0(p + i); A0; } else \
35 { UPDATE_1(p + i); A1; }
36 #define REV_BIT_VAR(p, i, m) REV_BIT(p, i, i += m; m += m, m += m; i += m; )
37 #define REV_BIT_CONST(p, i, m) REV_BIT(p, i, i += m; , i += m * 2; )
38 #define REV_BIT_LAST(p, i, m) REV_BIT(p, i, i -= m , ; )
40 #define TREE_DECODE(probs, limit, i) \
41 { i = 1; do { TREE_GET_BIT(probs, i); } while (i < limit); i -= limit; }
43 /* #define _LZMA_SIZE_OPT */
46 #define TREE_6_DECODE(probs, i) TREE_DECODE(probs, (1 << 6), i)
48 #define TREE_6_DECODE(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); \
54 TREE_GET_BIT(probs, i); \
55 TREE_GET_BIT(probs, i); \
59 #define NORMAL_LITER_DEC TREE_GET_BIT(prob, symbol)
60 #define MATCHED_LITER_DEC \
61 matchByte += matchByte; \
64 probLit = prob + (offs + bit + symbol); \
65 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; }
79 #define REV_BIT_CHECK(p, i, m) IF_BIT_0_CHECK(p + i)\
80 { UPDATE_0_CHECK; i += m; m += m; } else \
81 { UPDATE_1_CHECK; m += m; i += m; }
83 #define kNumPosBitsMax 4
84 #define kNumPosStatesMax (1 << kNumPosBitsMax)
86 #define kLenNumLowBits 3
87 #define kLenNumLowSymbols (1 << kLenNumLowBits)
88 #define kLenNumHighBits 8
89 #define kLenNumHighSymbols (1 << kLenNumHighBits)
92 #define LenHigh (LenLow + 2 * (kNumPosStatesMax << kLenNumLowBits))
93 #define kNumLenProbs (LenHigh + kLenNumHighSymbols)
95 #define LenChoice LenLow
96 #define LenChoice2 (LenLow + (1 << kLenNumLowBits))
99 #define kNumStates2 16
100 #define kNumLitStates 7
102 #define kStartPosModelIndex 4
103 #define kEndPosModelIndex 14
104 #define kNumFullDistances (1 << (kEndPosModelIndex >> 1))
106 #define kNumPosSlotBits 6
107 #define kNumLenToPosStates 4
109 #define kNumAlignBits 4
110 #define kAlignTableSize (1 << kNumAlignBits)
112 #define kMatchMinLen 2
113 #define kMatchSpecLenStart (kMatchMinLen + kLenNumLowSymbols * 2 + kLenNumHighSymbols)
115 /* External ASM code needs same CLzmaProb array layout. So don't change it. */
117 /* (probs_1664) is faster and better for code size at some platforms */
120 #ifdef MY_CPU_X86_OR_AMD64
122 #define kStartOffset 1664
123 #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
155 #define LZMA_LIT_SIZE 0x300
157 #define LzmaProps_GetNumProbs(p) (NUM_BASE_PROBS + ((UInt32)LZMA_LIT_SIZE << ((p)->lc + (p)->lp)))
159 #define CALC_POS_STATE(processedPos, pbMask) (((processedPos) & (pbMask)) << 4)
160 #define COMBINED_PS_STATE (posState + state)
161 #define GET_LEN_STATE (posState)
163 #define LZMA_DIC_MIN (1 << 12)
166 p->remainLen : shows status of LZMA decoder:
167 < kMatchSpecLenStart : normal remain
168 = kMatchSpecLenStart : finished
169 = kMatchSpecLenStart + 1 : need init range coder
170 = kMatchSpecLenStart + 2 : need init range coder and state
173 /* ---------- LZMA_DECODE_REAL ---------- */
176 LzmaDec_DecodeReal_3() can be implemented in external ASM file.
177 3 - is the code compatibility version of that function for check at link time.
180 #define LZMA_DECODE_REAL LzmaDec_DecodeReal_3
185 RangeCoder is normalized
186 if (p->dicPos == limit)
188 LzmaDec_TryDummy() was called before to exclude LITERAL and MATCH-REP cases.
189 So first symbol can be only MATCH-NON-REP. And if that MATCH-NON-REP symbol
190 is not END_OF_PAYALOAD_MARKER, then function returns error code.
194 first LZMA symbol will be decoded in any case
195 All checks for limits are at the end of main loop,
196 It will decode new LZMA-symbols while (p->buf < bufLimit && dicPos < limit),
197 RangeCoder is still without last normalization when (p->buf < bufLimit) is being checked.
200 RangeCoder is normalized
203 SZ_ERROR_DATA - Error
205 < kMatchSpecLenStart : normal remain
206 = kMatchSpecLenStart : finished
228 CLzmaProb
*probs
= GET_PROBS
;
229 unsigned state
= (unsigned)p
->state
;
230 UInt32 rep0
= p
->reps
[0], rep1
= p
->reps
[1], rep2
= p
->reps
[2], rep3
= p
->reps
[3];
231 unsigned pbMask
= ((unsigned)1 << (p
->prop
.pb
)) - 1;
232 unsigned lc
= p
->prop
.lc
;
233 unsigned lpMask
= ((unsigned)0x100 << p
->prop
.lp
) - ((unsigned)0x100 >> lc
);
236 SizeT dicBufSize
= p
->dicBufSize
;
237 SizeT dicPos
= p
->dicPos
;
239 UInt32 processedPos
= p
->processedPos
;
240 UInt32 checkDicSize
= p
->checkDicSize
;
243 const Byte
*buf
= p
->buf
;
244 UInt32 range
= p
->range
;
245 UInt32 code
= p
->code
;
251 unsigned posState
= CALC_POS_STATE (processedPos
, pbMask
);
253 prob
= probs
+ IsMatch
+ COMBINED_PS_STATE
;
258 prob
= probs
+ Literal
;
259 if ((processedPos
!= 0) || (checkDicSize
!= 0)) {
260 prob
+= (UInt32
)3 * ((((processedPos
<< 8) + dic
[(dicPos
== 0 ? dicBufSize
: dicPos
) - 1]) & lpMask
) << lc
);
265 if (state
< kNumLitStates
) {
266 state
-= (state
< 4) ? state
: 3;
268 #ifdef _LZMA_SIZE_OPT
271 } while (symbol
< 0x100);
284 unsigned matchByte
= dic
[dicPos
- rep0
+ (dicPos
< rep0
? dicBufSize
: 0)];
285 unsigned offs
= 0x100;
286 state
-= (state
< 10) ? 3 : 6;
288 #ifdef _LZMA_SIZE_OPT
293 } while (symbol
< 0x100);
311 dic
[dicPos
++] = (Byte
)symbol
;
317 prob
= probs
+ IsRep
+ state
;
321 prob
= probs
+ LenCoder
;
326 // that case was checked before with kBadRepCode
327 if (checkDicSize == 0 && processedPos == 0)
328 return SZ_ERROR_DATA;
330 prob
= probs
+ IsRepG0
+ state
;
333 prob
= probs
+ IsRep0Long
+ COMBINED_PS_STATE
;
336 dic
[dicPos
] = dic
[dicPos
- rep0
+ (dicPos
< rep0
? dicBufSize
: 0)];
339 state
= state
< kNumLitStates
? 9 : 11;
346 prob
= probs
+ IsRepG1
+ state
;
352 prob
= probs
+ IsRepG2
+ state
;
366 state
= state
< kNumLitStates
? 8 : 11;
367 prob
= probs
+ RepLenCoder
;
370 #ifdef _LZMA_SIZE_OPT
372 unsigned lim
, offset
;
373 CLzmaProb
*probLen
= prob
+ LenChoice
;
376 probLen
= prob
+ LenLow
+ GET_LEN_STATE
;
378 lim
= (1 << kLenNumLowBits
);
381 probLen
= prob
+ LenChoice2
;
384 probLen
= prob
+ LenLow
+ GET_LEN_STATE
+ (1 << kLenNumLowBits
);
385 offset
= kLenNumLowSymbols
;
386 lim
= (1 << kLenNumLowBits
);
389 probLen
= prob
+ LenHigh
;
390 offset
= kLenNumLowSymbols
* 2;
391 lim
= (1 << kLenNumHighBits
);
394 TREE_DECODE (probLen
, lim
, len
);
399 CLzmaProb
*probLen
= prob
+ LenChoice
;
402 probLen
= prob
+ LenLow
+ GET_LEN_STATE
;
404 TREE_GET_BIT (probLen
, len
);
405 TREE_GET_BIT (probLen
, len
);
406 TREE_GET_BIT (probLen
, len
);
410 probLen
= prob
+ LenChoice2
;
413 probLen
= prob
+ LenLow
+ GET_LEN_STATE
+ (1 << kLenNumLowBits
);
415 TREE_GET_BIT (probLen
, len
);
416 TREE_GET_BIT (probLen
, len
);
417 TREE_GET_BIT (probLen
, len
);
420 probLen
= prob
+ LenHigh
;
421 TREE_DECODE (probLen
, (1 << kLenNumHighBits
), len
);
422 len
+= kLenNumLowSymbols
* 2;
428 if (state
>= kNumStates
) {
430 prob
= probs
+ PosSlot
+
431 ((len
< kNumLenToPosStates
? len
: kNumLenToPosStates
- 1) << kNumPosSlotBits
);
432 TREE_6_DECODE (prob
, distance
);
433 if (distance
>= kStartPosModelIndex
) {
434 unsigned posSlot
= (unsigned)distance
;
435 unsigned numDirectBits
= (unsigned)(((distance
>> 1) - 1));
436 distance
= (2 | (distance
& 1));
437 if (posSlot
< kEndPosModelIndex
) {
438 distance
<<= numDirectBits
;
439 prob
= probs
+ SpecPos
;
444 REV_BIT_VAR (prob
, distance
, m
);
445 } while (--numDirectBits
);
450 numDirectBits
-= kNumAlignBits
;
458 t
= (0 - ((UInt32
)code
>> 31)); /* (UInt32)((Int32)code >> 31) */
459 distance
= (distance
<< 1) + (t
+ 1);
471 } while (--numDirectBits
);
473 prob
= probs
+ Align
;
474 distance
<<= kNumAlignBits
;
477 REV_BIT_CONST (prob
, i
, 1);
478 REV_BIT_CONST (prob
, i
, 2);
479 REV_BIT_CONST (prob
, i
, 4);
480 REV_BIT_LAST (prob
, i
, 8);
483 if (distance
== (UInt32
)0xFFFFFFFF) {
484 len
= kMatchSpecLenStart
;
495 state
= (state
< kNumStates
+ kNumLitStates
) ? kNumLitStates
: kNumLitStates
+ 3;
496 if (distance
>= ((checkDicSize
== 0) ? processedPos
: checkDicSize
)) {
498 return SZ_ERROR_DATA
;
509 if ((rem
= limit
- dicPos
) == 0) {
511 return SZ_ERROR_DATA
;
514 curLen
= ((rem
< len
) ? (unsigned)rem
: len
);
515 pos
= dicPos
- rep0
+ (dicPos
< rep0
? dicBufSize
: 0);
517 processedPos
+= (UInt32
)curLen
;
520 if (curLen
<= dicBufSize
- pos
) {
521 Byte
*dest
= dic
+ dicPos
;
522 ptrdiff_t src
= (ptrdiff_t)pos
- (ptrdiff_t)dicPos
;
523 const Byte
*lim
= dest
+ curLen
;
524 dicPos
+= (SizeT
)curLen
;
526 *(dest
) = (Byte
)*(dest
+ src
);
527 } while (++dest
!= lim
);
530 dic
[dicPos
++] = dic
[pos
];
531 if (++pos
== dicBufSize
) {
534 } while (--curLen
!= 0);
538 } while (dicPos
< limit
&& buf
< bufLimit
);
545 p
->remainLen
= (UInt32
)len
;
547 p
->processedPos
= processedPos
;
552 p
->state
= (UInt32
)state
;
559 static void MY_FAST_CALL
565 if ((p
->remainLen
!= 0) && (p
->remainLen
< kMatchSpecLenStart
)) {
567 SizeT dicPos
= p
->dicPos
;
568 SizeT dicBufSize
= p
->dicBufSize
;
569 unsigned len
= (unsigned)p
->remainLen
;
570 SizeT rep0
= p
->reps
[0]; /* we use SizeT to avoid the BUG of VC14 for AMD64 */
571 SizeT rem
= limit
- dicPos
;
573 len
= (unsigned)(rem
);
576 if ((p
->checkDicSize
== 0) && (p
->prop
.dicSize
- p
->processedPos
<= len
)) {
577 p
->checkDicSize
= p
->prop
.dicSize
;
580 p
->processedPos
+= (UInt32
)len
;
581 p
->remainLen
-= (UInt32
)len
;
584 dic
[dicPos
] = dic
[dicPos
- rep0
+ (dicPos
< rep0
? dicBufSize
: 0)];
592 #define kRange0 0xFFFFFFFF
593 #define kBound0 ((kRange0 >> kNumBitModelTotalBits) << (kNumBitModelTotalBits - 1))
594 #define kBadRepCode (kBound0 + (((kRange0 - kBound0) >> kNumBitModelTotalBits) << (kNumBitModelTotalBits - 1)))
595 #if kBadRepCode != (0xC0000000 - 0x400)
596 #error Stop_Compiling_Bad_LZMA_Check
599 static int MY_FAST_CALL
600 LzmaDec_DecodeReal2 (
607 SizeT limit2
= limit
;
608 if (p
->checkDicSize
== 0) {
609 UInt32 rem
= p
->prop
.dicSize
- p
->processedPos
;
610 if (limit
- p
->dicPos
> rem
) {
611 limit2
= p
->dicPos
+ rem
;
614 if (p
->processedPos
== 0) {
615 if (p
->code
>= kBadRepCode
) {
616 return SZ_ERROR_DATA
;
621 RINOK (LZMA_DECODE_REAL (p
, limit2
, bufLimit
));
623 if ((p
->checkDicSize
== 0) && (p
->processedPos
>= p
->prop
.dicSize
)) {
624 p
->checkDicSize
= p
->prop
.dicSize
;
627 LzmaDec_WriteRem (p
, limit
);
628 } while (p
->dicPos
< limit
&& p
->buf
< bufLimit
&& p
->remainLen
< kMatchSpecLenStart
);
634 DUMMY_ERROR
, /* unexpected end of input stream */
647 UInt32 range
= p
->range
;
648 UInt32 code
= p
->code
;
649 const Byte
*bufLimit
= buf
+ inSize
;
650 const CLzmaProb
*probs
= GET_PROBS
;
651 unsigned state
= (unsigned)p
->state
;
655 const CLzmaProb
*prob
;
658 unsigned posState
= CALC_POS_STATE (p
->processedPos
, (1 << p
->prop
.pb
) - 1);
660 prob
= probs
+ IsMatch
+ COMBINED_PS_STATE
;
661 IF_BIT_0_CHECK (prob
) {
664 /* if (bufLimit - buf >= 7) return DUMMY_LIT; */
666 prob
= probs
+ Literal
;
668 if ((p
->checkDicSize
!= 0) || (p
->processedPos
!= 0)) {
669 prob
+= ((UInt32
)LZMA_LIT_SIZE
*
670 ((((p
->processedPos
) & ((1 << (p
->prop
.lp
)) - 1)) << p
->prop
.lc
) +
671 (p
->dic
[(p
->dicPos
== 0 ? p
->dicBufSize
: p
->dicPos
) - 1] >> (8 - p
->prop
.lc
))));
674 if (state
< kNumLitStates
) {
677 GET_BIT_CHECK (prob
+ symbol
, symbol
)
678 } while (symbol
< 0x100);
680 unsigned matchByte
= p
->dic
[p
->dicPos
- p
->reps
[0] +
681 (p
->dicPos
< p
->reps
[0] ? p
->dicBufSize
: 0)];
682 unsigned offs
= 0x100;
686 const CLzmaProb
*probLit
;
687 matchByte
+= matchByte
;
690 probLit
= prob
+ (offs
+ bit
+ symbol
);
698 } while (symbol
< 0x100);
706 prob
= probs
+ IsRep
+ state
;
707 IF_BIT_0_CHECK (prob
) {
710 prob
= probs
+ LenCoder
;
715 prob
= probs
+ IsRepG0
+ state
;
716 IF_BIT_0_CHECK (prob
) {
718 prob
= probs
+ IsRep0Long
+ COMBINED_PS_STATE
;
719 IF_BIT_0_CHECK (prob
) {
728 prob
= probs
+ IsRepG1
+ state
;
729 IF_BIT_0_CHECK (prob
) {
733 prob
= probs
+ IsRepG2
+ state
;
734 IF_BIT_0_CHECK (prob
) {
742 prob
= probs
+ RepLenCoder
;
745 unsigned limit
, offset
;
746 const CLzmaProb
*probLen
= prob
+ LenChoice
;
747 IF_BIT_0_CHECK (probLen
) {
749 probLen
= prob
+ LenLow
+ GET_LEN_STATE
;
751 limit
= 1 << kLenNumLowBits
;
754 probLen
= prob
+ LenChoice2
;
755 IF_BIT_0_CHECK (probLen
) {
757 probLen
= prob
+ LenLow
+ GET_LEN_STATE
+ (1 << kLenNumLowBits
);
758 offset
= kLenNumLowSymbols
;
759 limit
= 1 << kLenNumLowBits
;
762 probLen
= prob
+ LenHigh
;
763 offset
= kLenNumLowSymbols
* 2;
764 limit
= 1 << kLenNumHighBits
;
767 TREE_DECODE_CHECK (probLen
, limit
, len
);
773 prob
= probs
+ PosSlot
+
774 ((len
< kNumLenToPosStates
- 1 ? len
: kNumLenToPosStates
- 1) <<
776 TREE_DECODE_CHECK (prob
, 1 << kNumPosSlotBits
, posSlot
);
777 if (posSlot
>= kStartPosModelIndex
) {
778 unsigned numDirectBits
= ((posSlot
>> 1) - 1);
780 /* if (bufLimit - buf >= 8) return DUMMY_MATCH; */
782 if (posSlot
< kEndPosModelIndex
) {
783 prob
= probs
+ SpecPos
+ ((2 | (posSlot
& 1)) << numDirectBits
);
785 numDirectBits
-= kNumAlignBits
;
789 code
-= range
& (((code
- range
) >> 31) - 1);
790 /* if (code >= range) code -= range; */
791 } while (--numDirectBits
);
793 prob
= probs
+ Align
;
794 numDirectBits
= kNumAlignBits
;
801 REV_BIT_CHECK (prob
, i
, m
);
802 } while (--numDirectBits
);
814 LzmaDec_InitDicAndState (
820 p
->remainLen
= kMatchSpecLenStart
+ 1;
826 p
->remainLen
= kMatchSpecLenStart
+ 2;
830 p
->remainLen
= kMatchSpecLenStart
+ 2;
840 LzmaDec_InitDicAndState (p
, True
, True
);
844 LzmaDec_DecodeToDic (
849 ELzmaFinishMode finishMode
,
853 SizeT inSize
= *srcLen
;
857 *status
= LZMA_STATUS_NOT_SPECIFIED
;
859 if (p
->remainLen
> kMatchSpecLenStart
) {
860 for ( ; inSize
> 0 && p
->tempBufSize
< RC_INIT_SIZE
; (*srcLen
)++, inSize
--) {
861 p
->tempBuf
[p
->tempBufSize
++] = *src
++;
864 if ((p
->tempBufSize
!= 0) && (p
->tempBuf
[0] != 0)) {
865 return SZ_ERROR_DATA
;
868 if (p
->tempBufSize
< RC_INIT_SIZE
) {
869 *status
= LZMA_STATUS_NEEDS_MORE_INPUT
;
874 ((UInt32
)p
->tempBuf
[1] << 24)
875 | ((UInt32
)p
->tempBuf
[2] << 16)
876 | ((UInt32
)p
->tempBuf
[3] << 8)
877 | ((UInt32
)p
->tempBuf
[4]);
878 p
->range
= 0xFFFFFFFF;
881 if (p
->remainLen
> kMatchSpecLenStart
+ 1) {
882 SizeT numProbs
= LzmaProps_GetNumProbs (&p
->prop
);
884 CLzmaProb
*probs
= p
->probs
;
885 for (i
= 0; i
< numProbs
; i
++) {
886 probs
[i
] = kBitModelTotal
>> 1;
889 p
->reps
[0] = p
->reps
[1] = p
->reps
[2] = p
->reps
[3] = 1;
896 LzmaDec_WriteRem (p
, dicLimit
);
898 while (p
->remainLen
!= kMatchSpecLenStart
) {
899 int checkEndMarkNow
= 0;
901 if (p
->dicPos
>= dicLimit
) {
902 if ((p
->remainLen
== 0) && (p
->code
== 0)) {
903 *status
= LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK
;
907 if (finishMode
== LZMA_FINISH_ANY
) {
908 *status
= LZMA_STATUS_NOT_FINISHED
;
912 if (p
->remainLen
!= 0) {
913 *status
= LZMA_STATUS_NOT_FINISHED
;
914 return SZ_ERROR_DATA
;
920 if (p
->tempBufSize
== 0) {
922 const Byte
*bufLimit
;
923 if ((inSize
< LZMA_REQUIRED_INPUT_MAX
) || checkEndMarkNow
) {
924 int dummyRes
= LzmaDec_TryDummy (p
, src
, inSize
);
925 if (dummyRes
== DUMMY_ERROR
) {
926 memcpy (p
->tempBuf
, src
, inSize
);
927 p
->tempBufSize
= (unsigned)inSize
;
929 *status
= LZMA_STATUS_NEEDS_MORE_INPUT
;
933 if (checkEndMarkNow
&& (dummyRes
!= DUMMY_MATCH
)) {
934 *status
= LZMA_STATUS_NOT_FINISHED
;
935 return SZ_ERROR_DATA
;
940 bufLimit
= src
+ inSize
- LZMA_REQUIRED_INPUT_MAX
;
944 if (LzmaDec_DecodeReal2 (p
, dicLimit
, bufLimit
) != 0) {
945 return SZ_ERROR_DATA
;
948 processed
= (SizeT
)(p
->buf
- src
);
949 (*srcLen
) += processed
;
953 unsigned rem
= p
->tempBufSize
, lookAhead
= 0;
954 while (rem
< LZMA_REQUIRED_INPUT_MAX
&& lookAhead
< inSize
) {
955 p
->tempBuf
[rem
++] = src
[lookAhead
++];
958 p
->tempBufSize
= rem
;
959 if ((rem
< LZMA_REQUIRED_INPUT_MAX
) || checkEndMarkNow
) {
960 int dummyRes
= LzmaDec_TryDummy (p
, p
->tempBuf
, (SizeT
)rem
);
961 if (dummyRes
== DUMMY_ERROR
) {
962 (*srcLen
) += (SizeT
)lookAhead
;
963 *status
= LZMA_STATUS_NEEDS_MORE_INPUT
;
967 if (checkEndMarkNow
&& (dummyRes
!= DUMMY_MATCH
)) {
968 *status
= LZMA_STATUS_NOT_FINISHED
;
969 return SZ_ERROR_DATA
;
974 if (LzmaDec_DecodeReal2 (p
, dicLimit
, p
->buf
) != 0) {
975 return SZ_ERROR_DATA
;
979 unsigned kkk
= (unsigned)(p
->buf
- p
->tempBuf
);
981 return SZ_ERROR_FAIL
; /* some internal error */
985 if (lookAhead
< rem
) {
986 return SZ_ERROR_FAIL
; /* some internal error */
991 (*srcLen
) += (SizeT
)lookAhead
;
993 inSize
-= (SizeT
)lookAhead
;
999 return SZ_ERROR_DATA
;
1002 *status
= LZMA_STATUS_FINISHED_WITH_MARK
;
1007 LzmaDec_DecodeToBuf (
1013 ELzmaFinishMode finishMode
,
1017 SizeT outSize
= *destLen
;
1018 SizeT inSize
= *srcLen
;
1020 *srcLen
= *destLen
= 0;
1022 SizeT inSizeCur
= inSize
, outSizeCur
, dicPos
;
1023 ELzmaFinishMode curFinishMode
;
1025 if (p
->dicPos
== p
->dicBufSize
) {
1030 if (outSize
> p
->dicBufSize
- dicPos
) {
1031 outSizeCur
= p
->dicBufSize
;
1032 curFinishMode
= LZMA_FINISH_ANY
;
1034 outSizeCur
= dicPos
+ outSize
;
1035 curFinishMode
= finishMode
;
1038 res
= LzmaDec_DecodeToDic (p
, outSizeCur
, src
, &inSizeCur
, curFinishMode
, status
);
1040 inSize
-= inSizeCur
;
1041 *srcLen
+= inSizeCur
;
1042 outSizeCur
= p
->dicPos
- dicPos
;
1043 memcpy (dest
, p
->dic
+ dicPos
, outSizeCur
);
1045 outSize
-= outSizeCur
;
1046 *destLen
+= outSizeCur
;
1051 if ((outSizeCur
== 0) || (outSize
== 0)) {
1063 ISzAlloc_Free (alloc
, p
->probs
);
1073 ISzAlloc_Free (alloc
, p
->dic
);
1083 LzmaDec_FreeProbs (p
, alloc
);
1084 LzmaDec_FreeDict (p
, alloc
);
1097 if (size
< LZMA_PROPS_SIZE
) {
1098 return SZ_ERROR_UNSUPPORTED
;
1100 dicSize
= data
[1] | ((UInt32
)data
[2] << 8) | ((UInt32
)data
[3] << 16) | ((UInt32
)data
[4] << 24);
1103 if (dicSize
< LZMA_DIC_MIN
) {
1104 dicSize
= LZMA_DIC_MIN
;
1107 p
->dicSize
= dicSize
;
1110 if (d
>= (9 * 5 * 5)) {
1111 return SZ_ERROR_UNSUPPORTED
;
1114 p
->lc
= (Byte
)(d
% 9);
1116 p
->pb
= (Byte
)(d
/ 5);
1117 p
->lp
= (Byte
)(d
% 5);
1123 LzmaDec_AllocateProbs2 (
1125 const CLzmaProps
*propNew
,
1129 UInt32 numProbs
= LzmaProps_GetNumProbs (propNew
);
1131 if (!p
->probs
|| (numProbs
!= p
->numProbs
)) {
1132 LzmaDec_FreeProbs (p
, alloc
);
1133 p
->probs
= (CLzmaProb
*)ISzAlloc_Alloc (alloc
, numProbs
* sizeof (CLzmaProb
));
1135 return SZ_ERROR_MEM
;
1138 p
->probs_1664
= p
->probs
+ 1664;
1139 p
->numProbs
= numProbs
;
1146 LzmaDec_AllocateProbs (
1155 RINOK (LzmaProps_Decode (&propNew
, props
, propsSize
));
1156 RINOK (LzmaDec_AllocateProbs2 (p
, &propNew
, alloc
));
1172 RINOK (LzmaProps_Decode (&propNew
, props
, propsSize
));
1173 RINOK (LzmaDec_AllocateProbs2 (p
, &propNew
, alloc
));
1176 UInt32 dictSize
= propNew
.dicSize
;
1177 SizeT mask
= ((UInt32
)1 << 12) - 1;
1178 if (dictSize
>= ((UInt32
)1 << 30)) {
1179 mask
= ((UInt32
)1 << 22) - 1;
1180 } else if (dictSize
>= ((UInt32
)1 << 22)) {
1181 mask
= ((UInt32
)1 << 20) - 1;
1184 dicBufSize
= ((SizeT
)dictSize
+ mask
) & ~mask
;
1185 if (dicBufSize
< dictSize
) {
1186 dicBufSize
= dictSize
;
1190 if (!p
->dic
|| (dicBufSize
!= p
->dicBufSize
)) {
1191 LzmaDec_FreeDict (p
, alloc
);
1192 p
->dic
= (Byte
*)ISzAlloc_Alloc (alloc
, dicBufSize
);
1194 LzmaDec_FreeProbs (p
, alloc
);
1195 return SZ_ERROR_MEM
;
1199 p
->dicBufSize
= dicBufSize
;
1210 const Byte
*propData
,
1212 ELzmaFinishMode finishMode
,
1213 ELzmaStatus
*status
,
1219 SizeT outSize
= *destLen
, inSize
= *srcLen
;
1221 *destLen
= *srcLen
= 0;
1222 *status
= LZMA_STATUS_NOT_SPECIFIED
;
1223 if (inSize
< RC_INIT_SIZE
) {
1224 return SZ_ERROR_INPUT_EOF
;
1227 LzmaDec_Construct (&p
);
1228 RINOK (LzmaDec_AllocateProbs (&p
, propData
, propSize
, alloc
));
1230 p
.dicBufSize
= outSize
;
1233 res
= LzmaDec_DecodeToDic (&p
, outSize
, src
, srcLen
, finishMode
, status
);
1234 *destLen
= p
.dicPos
;
1235 if ((res
== SZ_OK
) && (*status
== LZMA_STATUS_NEEDS_MORE_INPUT
)) {
1236 res
= SZ_ERROR_INPUT_EOF
;
1239 LzmaDec_FreeProbs (&p
, alloc
);