1 /* LzmaDec.c -- LZMA Decoder
2 2018-02-28 : Igor Pavlov : Public domain */
6 /* #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) * 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; , ;)
69 #define NORMALIZE_CHECK if (range < kTopValue) { if (buf >= bufLimit) return DUMMY_ERROR; range <<= 8; code = (code << 8) | (*buf++); }
71 #define IF_BIT_0_CHECK(p) ttt = *(p); NORMALIZE_CHECK; bound = (range >> kNumBitModelTotalBits) * ttt; if (code < bound)
72 #define UPDATE_0_CHECK range = bound;
73 #define UPDATE_1_CHECK range -= bound; code -= bound;
74 #define GET_BIT2_CHECK(p, i, A0, A1) IF_BIT_0_CHECK(p) \
75 { UPDATE_0_CHECK; i = (i + i); A0; } else \
76 { UPDATE_1_CHECK; i = (i + i) + 1; A1; }
77 #define GET_BIT_CHECK(p, i) GET_BIT2_CHECK(p, i, ; , ;)
78 #define TREE_DECODE_CHECK(probs, limit, i) \
79 { i = 1; do { GET_BIT_CHECK(probs + i, i) } while (i < limit); i -= limit; }
82 #define REV_BIT_CHECK(p, i, m) IF_BIT_0_CHECK(p + i) \
83 { UPDATE_0_CHECK; i += m; m += m; } else \
84 { UPDATE_1_CHECK; m += m; i += m; }
87 #define kNumPosBitsMax 4
88 #define kNumPosStatesMax (1 << kNumPosBitsMax)
90 #define kLenNumLowBits 3
91 #define kLenNumLowSymbols (1 << kLenNumLowBits)
92 #define kLenNumHighBits 8
93 #define kLenNumHighSymbols (1 << kLenNumHighBits)
96 #define LenHigh (LenLow + 2 * (kNumPosStatesMax << kLenNumLowBits))
97 #define kNumLenProbs (LenHigh + kLenNumHighSymbols)
99 #define LenChoice LenLow
100 #define LenChoice2 (LenLow + (1 << kLenNumLowBits))
102 #define kNumStates 12
103 #define kNumStates2 16
104 #define kNumLitStates 7
106 #define kStartPosModelIndex 4
107 #define kEndPosModelIndex 14
108 #define kNumFullDistances (1 << (kEndPosModelIndex >> 1))
110 #define kNumPosSlotBits 6
111 #define kNumLenToPosStates 4
113 #define kNumAlignBits 4
114 #define kAlignTableSize (1 << kNumAlignBits)
116 #define kMatchMinLen 2
117 #define kMatchSpecLenStart (kMatchMinLen + kLenNumLowSymbols * 2 + kLenNumHighSymbols)
119 /* External ASM code needs same CLzmaProb array layout. So don't change it. */
121 /* (probs_1664) is faster and better for code size at some platforms */
123 #ifdef MY_CPU_X86_OR_AMD64
125 #define kStartOffset 1664
126 #define GET_PROBS p->probs_1664
128 #define GET_PROBS p->probs + kStartOffset
130 #define kStartOffset 0
131 #define GET_PROBS p->probs
135 #define SpecPos (-kStartOffset)
136 #define IsRep0Long (SpecPos + kNumFullDistances)
137 #define RepLenCoder (IsRep0Long + (kNumStates2 << kNumPosBitsMax))
138 #define LenCoder (RepLenCoder + kNumLenProbs)
139 #define IsMatch (LenCoder + kNumLenProbs)
140 #define Align (IsMatch + (kNumStates2 << kNumPosBitsMax))
141 #define IsRep (Align + kAlignTableSize)
142 #define IsRepG0 (IsRep + kNumStates)
143 #define IsRepG1 (IsRepG0 + kNumStates)
144 #define IsRepG2 (IsRepG1 + kNumStates)
145 #define PosSlot (IsRepG2 + kNumStates)
146 #define Literal (PosSlot + (kNumLenToPosStates << kNumPosSlotBits))
147 #define NUM_BASE_PROBS (Literal + kStartOffset)
149 #if Align != 0 && kStartOffset != 0
150 #error Stop_Compiling_Bad_LZMA_kAlign
153 #if NUM_BASE_PROBS != 1984
154 #error Stop_Compiling_Bad_LZMA_PROBS
158 #define LZMA_LIT_SIZE 0x300
160 #define LzmaProps_GetNumProbs(p) (NUM_BASE_PROBS + ((UInt32)LZMA_LIT_SIZE << ((p)->lc + (p)->lp)))
163 #define CALC_POS_STATE(processedPos, pbMask) (((processedPos) & (pbMask)) << 4)
164 #define COMBINED_PS_STATE (posState + state)
165 #define GET_LEN_STATE (posState)
167 #define LZMA_DIC_MIN (1 << 12)
170 p->remainLen : shows status of LZMA decoder:
171 < kMatchSpecLenStart : normal remain
172 = kMatchSpecLenStart : finished
173 = kMatchSpecLenStart + 1 : need init range coder
174 = kMatchSpecLenStart + 2 : need init range coder and state
177 /* ---------- LZMA_DECODE_REAL ---------- */
179 LzmaDec_DecodeReal_3() can be implemented in external ASM file.
180 3 - is the code compatibility version of that function for check at link time.
183 #define LZMA_DECODE_REAL LzmaDec_DecodeReal_3
188 RangeCoder is normalized
189 if (p->dicPos == limit)
191 LzmaDec_TryDummy() was called before to exclude LITERAL and MATCH-REP cases.
192 So first symbol can be only MATCH-NON-REP. And if that MATCH-NON-REP symbol
193 is not END_OF_PAYALOAD_MARKER, then function returns error code.
197 first LZMA symbol will be decoded in any case
198 All checks for limits are at the end of main loop,
199 It will decode new LZMA-symbols while (p->buf < bufLimit && dicPos < limit),
200 RangeCoder is still without last normalization when (p->buf < bufLimit) is being checked.
203 RangeCoder is normalized
206 SZ_ERROR_DATA - Error
208 < kMatchSpecLenStart : normal remain
209 = kMatchSpecLenStart : finished
215 int MY_FAST_CALL
LZMA_DECODE_REAL(CLzmaDec
*p
, SizeT limit
, const Byte
*bufLimit
);
220 int MY_FAST_CALL
LZMA_DECODE_REAL(CLzmaDec
*p
, SizeT limit
, const Byte
*bufLimit
)
222 CLzmaProb
*probs
= GET_PROBS
;
223 unsigned state
= (unsigned)p
->state
;
224 UInt32 rep0
= p
->reps
[0], rep1
= p
->reps
[1], rep2
= p
->reps
[2], rep3
= p
->reps
[3];
225 unsigned pbMask
= ((unsigned)1 << (p
->prop
.pb
)) - 1;
226 unsigned lc
= p
->prop
.lc
;
227 unsigned lpMask
= ((unsigned)0x100 << p
->prop
.lp
) - ((unsigned)0x100 >> lc
);
230 SizeT dicBufSize
= p
->dicBufSize
;
231 SizeT dicPos
= p
->dicPos
;
233 UInt32 processedPos
= p
->processedPos
;
234 UInt32 checkDicSize
= p
->checkDicSize
;
237 const Byte
*buf
= p
->buf
;
238 UInt32 range
= p
->range
;
239 UInt32 code
= p
->code
;
246 unsigned posState
= CALC_POS_STATE(processedPos
, pbMask
);
248 prob
= probs
+ IsMatch
+ COMBINED_PS_STATE
;
253 prob
= probs
+ Literal
;
254 if (processedPos
!= 0 || checkDicSize
!= 0)
255 prob
+= (UInt32
)3 * ((((processedPos
<< 8) + dic
[(dicPos
== 0 ? dicBufSize
: dicPos
) - 1]) & lpMask
) << lc
);
258 if (state
< kNumLitStates
)
260 state
-= (state
< 4) ? state
: 3;
262 #ifdef _LZMA_SIZE_OPT
263 do { NORMAL_LITER_DEC
} while (symbol
< 0x100);
277 unsigned matchByte
= dic
[dicPos
- rep0
+ (dicPos
< rep0
? dicBufSize
: 0)];
278 unsigned offs
= 0x100;
279 state
-= (state
< 10) ? 3 : 6;
281 #ifdef _LZMA_SIZE_OPT
288 while (symbol
< 0x100);
305 dic
[dicPos
++] = (Byte
)symbol
;
311 prob
= probs
+ IsRep
+ state
;
316 prob
= probs
+ LenCoder
;
322 // that case was checked before with kBadRepCode
323 if (checkDicSize == 0 && processedPos == 0)
324 return SZ_ERROR_DATA;
326 prob
= probs
+ IsRepG0
+ state
;
330 prob
= probs
+ IsRep0Long
+ COMBINED_PS_STATE
;
334 dic
[dicPos
] = dic
[dicPos
- rep0
+ (dicPos
< rep0
? dicBufSize
: 0)];
337 state
= state
< kNumLitStates
? 9 : 11;
346 prob
= probs
+ IsRepG1
+ state
;
355 prob
= probs
+ IsRepG2
+ state
;
372 state
= state
< kNumLitStates
? 8 : 11;
373 prob
= probs
+ RepLenCoder
;
376 #ifdef _LZMA_SIZE_OPT
378 unsigned lim
, offset
;
379 CLzmaProb
*probLen
= prob
+ LenChoice
;
383 probLen
= prob
+ LenLow
+ GET_LEN_STATE
;
385 lim
= (1 << kLenNumLowBits
);
390 probLen
= prob
+ LenChoice2
;
394 probLen
= prob
+ LenLow
+ GET_LEN_STATE
+ (1 << kLenNumLowBits
);
395 offset
= kLenNumLowSymbols
;
396 lim
= (1 << kLenNumLowBits
);
401 probLen
= prob
+ LenHigh
;
402 offset
= kLenNumLowSymbols
* 2;
403 lim
= (1 << kLenNumHighBits
);
406 TREE_DECODE(probLen
, lim
, len
);
411 CLzmaProb
*probLen
= prob
+ LenChoice
;
415 probLen
= prob
+ LenLow
+ GET_LEN_STATE
;
417 TREE_GET_BIT(probLen
, len
);
418 TREE_GET_BIT(probLen
, len
);
419 TREE_GET_BIT(probLen
, len
);
425 probLen
= prob
+ LenChoice2
;
429 probLen
= prob
+ LenLow
+ GET_LEN_STATE
+ (1 << kLenNumLowBits
);
431 TREE_GET_BIT(probLen
, len
);
432 TREE_GET_BIT(probLen
, len
);
433 TREE_GET_BIT(probLen
, len
);
438 probLen
= prob
+ LenHigh
;
439 TREE_DECODE(probLen
, (1 << kLenNumHighBits
), len
);
440 len
+= kLenNumLowSymbols
* 2;
446 if (state
>= kNumStates
)
449 prob
= probs
+ PosSlot
+
450 ((len
< kNumLenToPosStates
? len
: kNumLenToPosStates
- 1) << kNumPosSlotBits
);
451 TREE_6_DECODE(prob
, distance
);
452 if (distance
>= kStartPosModelIndex
)
454 unsigned posSlot
= (unsigned)distance
;
455 unsigned numDirectBits
= (unsigned)(((distance
>> 1) - 1));
456 distance
= (2 | (distance
& 1));
457 if (posSlot
< kEndPosModelIndex
)
459 distance
<<= numDirectBits
;
460 prob
= probs
+ SpecPos
;
466 REV_BIT_VAR(prob
, distance
, m
);
468 while (--numDirectBits
);
474 numDirectBits
-= kNumAlignBits
;
483 t
= (0 - ((UInt32
)code
>> 31)); /* (UInt32)((Int32)code >> 31) */
484 distance
= (distance
<< 1) + (t
+ 1);
496 while (--numDirectBits
);
497 prob
= probs
+ Align
;
498 distance
<<= kNumAlignBits
;
501 REV_BIT_CONST(prob
, i
, 1);
502 REV_BIT_CONST(prob
, i
, 2);
503 REV_BIT_CONST(prob
, i
, 4);
504 REV_BIT_LAST (prob
, i
, 8);
507 if (distance
== (UInt32
)0xFFFFFFFF)
509 len
= kMatchSpecLenStart
;
520 state
= (state
< kNumStates
+ kNumLitStates
) ? kNumLitStates
: kNumLitStates
+ 3;
521 if (distance
>= (checkDicSize
== 0 ? processedPos
: checkDicSize
))
524 return SZ_ERROR_DATA
;
535 if ((rem
= limit
- dicPos
) == 0)
538 return SZ_ERROR_DATA
;
541 curLen
= ((rem
< len
) ? (unsigned)rem
: len
);
542 pos
= dicPos
- rep0
+ (dicPos
< rep0
? dicBufSize
: 0);
544 processedPos
+= curLen
;
547 if (curLen
<= dicBufSize
- pos
)
549 Byte
*dest
= dic
+ dicPos
;
550 ptrdiff_t src
= (ptrdiff_t)pos
- (ptrdiff_t)dicPos
;
551 const Byte
*lim
= dest
+ curLen
;
554 *(dest
) = (Byte
)*(dest
+ src
);
555 while (++dest
!= lim
);
561 dic
[dicPos
++] = dic
[pos
];
562 if (++pos
== dicBufSize
)
565 while (--curLen
!= 0);
570 while (dicPos
< limit
&& buf
< bufLimit
);
579 p
->processedPos
= processedPos
;
590 static void MY_FAST_CALL
LzmaDec_WriteRem(CLzmaDec
*p
, SizeT limit
)
592 if (p
->remainLen
!= 0 && p
->remainLen
< kMatchSpecLenStart
)
595 SizeT dicPos
= p
->dicPos
;
596 SizeT dicBufSize
= p
->dicBufSize
;
597 unsigned len
= (unsigned)p
->remainLen
;
598 SizeT rep0
= p
->reps
[0]; /* we use SizeT to avoid the BUG of VC14 for AMD64 */
599 SizeT rem
= limit
- dicPos
;
601 len
= (unsigned)(rem
);
603 if (p
->checkDicSize
== 0 && p
->prop
.dicSize
- p
->processedPos
<= len
)
604 p
->checkDicSize
= p
->prop
.dicSize
;
606 p
->processedPos
+= len
;
611 dic
[dicPos
] = dic
[dicPos
- rep0
+ (dicPos
< rep0
? dicBufSize
: 0)];
619 #define kRange0 0xFFFFFFFF
620 #define kBound0 ((kRange0 >> kNumBitModelTotalBits) << (kNumBitModelTotalBits - 1))
621 #define kBadRepCode (kBound0 + (((kRange0 - kBound0) >> kNumBitModelTotalBits) << (kNumBitModelTotalBits - 1)))
622 #if kBadRepCode != (0xC0000000 - 0x400)
623 #error Stop_Compiling_Bad_LZMA_Check
626 static int MY_FAST_CALL
LzmaDec_DecodeReal2(CLzmaDec
*p
, SizeT limit
, const Byte
*bufLimit
)
630 SizeT limit2
= limit
;
631 if (p
->checkDicSize
== 0)
633 UInt32 rem
= p
->prop
.dicSize
- p
->processedPos
;
634 if (limit
- p
->dicPos
> rem
)
635 limit2
= p
->dicPos
+ rem
;
637 if (p
->processedPos
== 0)
638 if (p
->code
>= kBadRepCode
)
639 return SZ_ERROR_DATA
;
642 RINOK(LZMA_DECODE_REAL(p
, limit2
, bufLimit
));
644 if (p
->checkDicSize
== 0 && p
->processedPos
>= p
->prop
.dicSize
)
645 p
->checkDicSize
= p
->prop
.dicSize
;
647 LzmaDec_WriteRem(p
, limit
);
649 while (p
->dicPos
< limit
&& p
->buf
< bufLimit
&& p
->remainLen
< kMatchSpecLenStart
);
656 DUMMY_ERROR
, /* unexpected end of input stream */
662 static ELzmaDummy
LzmaDec_TryDummy(const CLzmaDec
*p
, const Byte
*buf
, SizeT inSize
)
664 UInt32 range
= p
->range
;
665 UInt32 code
= p
->code
;
666 const Byte
*bufLimit
= buf
+ inSize
;
667 const CLzmaProb
*probs
= GET_PROBS
;
668 unsigned state
= (unsigned)p
->state
;
672 const CLzmaProb
*prob
;
675 unsigned posState
= CALC_POS_STATE(p
->processedPos
, (1 << p
->prop
.pb
) - 1);
677 prob
= probs
+ IsMatch
+ COMBINED_PS_STATE
;
682 /* if (bufLimit - buf >= 7) return DUMMY_LIT; */
684 prob
= probs
+ Literal
;
685 if (p
->checkDicSize
!= 0 || p
->processedPos
!= 0)
686 prob
+= ((UInt32
)LZMA_LIT_SIZE
*
687 ((((p
->processedPos
) & ((1 << (p
->prop
.lp
)) - 1)) << p
->prop
.lc
) +
688 (p
->dic
[(p
->dicPos
== 0 ? p
->dicBufSize
: p
->dicPos
) - 1] >> (8 - p
->prop
.lc
))));
690 if (state
< kNumLitStates
)
693 do { GET_BIT_CHECK(prob
+ symbol
, symbol
) } while (symbol
< 0x100);
697 unsigned matchByte
= p
->dic
[p
->dicPos
- p
->reps
[0] +
698 (p
->dicPos
< p
->reps
[0] ? p
->dicBufSize
: 0)];
699 unsigned offs
= 0x100;
704 const CLzmaProb
*probLit
;
705 matchByte
+= matchByte
;
708 probLit
= prob
+ (offs
+ bit
+ symbol
);
709 GET_BIT2_CHECK(probLit
, symbol
, offs
^= bit
; , ; )
711 while (symbol
< 0x100);
720 prob
= probs
+ IsRep
+ state
;
725 prob
= probs
+ LenCoder
;
732 prob
= probs
+ IsRepG0
+ state
;
736 prob
= probs
+ IsRep0Long
+ COMBINED_PS_STATE
;
751 prob
= probs
+ IsRepG1
+ state
;
759 prob
= probs
+ IsRepG2
+ state
;
771 prob
= probs
+ RepLenCoder
;
774 unsigned limit
, offset
;
775 const CLzmaProb
*probLen
= prob
+ LenChoice
;
776 IF_BIT_0_CHECK(probLen
)
779 probLen
= prob
+ LenLow
+ GET_LEN_STATE
;
781 limit
= 1 << kLenNumLowBits
;
786 probLen
= prob
+ LenChoice2
;
787 IF_BIT_0_CHECK(probLen
)
790 probLen
= prob
+ LenLow
+ GET_LEN_STATE
+ (1 << kLenNumLowBits
);
791 offset
= kLenNumLowSymbols
;
792 limit
= 1 << kLenNumLowBits
;
797 probLen
= prob
+ LenHigh
;
798 offset
= kLenNumLowSymbols
* 2;
799 limit
= 1 << kLenNumHighBits
;
802 TREE_DECODE_CHECK(probLen
, limit
, len
);
809 prob
= probs
+ PosSlot
+
810 ((len
< kNumLenToPosStates
- 1 ? len
: kNumLenToPosStates
- 1) <<
812 TREE_DECODE_CHECK(prob
, 1 << kNumPosSlotBits
, posSlot
);
813 if (posSlot
>= kStartPosModelIndex
)
815 unsigned numDirectBits
= ((posSlot
>> 1) - 1);
817 /* if (bufLimit - buf >= 8) return DUMMY_MATCH; */
819 if (posSlot
< kEndPosModelIndex
)
821 prob
= probs
+ SpecPos
+ ((2 | (posSlot
& 1)) << numDirectBits
);
825 numDirectBits
-= kNumAlignBits
;
830 code
-= range
& (((code
- range
) >> 31) - 1);
831 /* if (code >= range) code -= range; */
833 while (--numDirectBits
);
834 prob
= probs
+ Align
;
835 numDirectBits
= kNumAlignBits
;
842 REV_BIT_CHECK(prob
, i
, m
);
844 while (--numDirectBits
);
855 void LzmaDec_InitDicAndState(CLzmaDec
*p
, Bool initDic
, Bool initState
)
857 p
->remainLen
= kMatchSpecLenStart
+ 1;
864 p
->remainLen
= kMatchSpecLenStart
+ 2;
867 p
->remainLen
= kMatchSpecLenStart
+ 2;
870 void LzmaDec_Init(CLzmaDec
*p
)
873 LzmaDec_InitDicAndState(p
, True
, True
);
877 SRes
LzmaDec_DecodeToDic(CLzmaDec
*p
, SizeT dicLimit
, const Byte
*src
, SizeT
*srcLen
,
878 ELzmaFinishMode finishMode
, ELzmaStatus
*status
)
880 SizeT inSize
= *srcLen
;
883 *status
= LZMA_STATUS_NOT_SPECIFIED
;
885 if (p
->remainLen
> kMatchSpecLenStart
)
887 for (; inSize
> 0 && p
->tempBufSize
< RC_INIT_SIZE
; (*srcLen
)++, inSize
--)
888 p
->tempBuf
[p
->tempBufSize
++] = *src
++;
889 if (p
->tempBufSize
!= 0 && p
->tempBuf
[0] != 0)
890 return SZ_ERROR_DATA
;
891 if (p
->tempBufSize
< RC_INIT_SIZE
)
893 *status
= LZMA_STATUS_NEEDS_MORE_INPUT
;
897 ((UInt32
)p
->tempBuf
[1] << 24)
898 | ((UInt32
)p
->tempBuf
[2] << 16)
899 | ((UInt32
)p
->tempBuf
[3] << 8)
900 | ((UInt32
)p
->tempBuf
[4]);
901 p
->range
= 0xFFFFFFFF;
904 if (p
->remainLen
> kMatchSpecLenStart
+ 1)
906 SizeT numProbs
= LzmaProps_GetNumProbs(&p
->prop
);
908 CLzmaProb
*probs
= p
->probs
;
909 for (i
= 0; i
< numProbs
; i
++)
910 probs
[i
] = kBitModelTotal
>> 1;
911 p
->reps
[0] = p
->reps
[1] = p
->reps
[2] = p
->reps
[3] = 1;
918 LzmaDec_WriteRem(p
, dicLimit
);
920 while (p
->remainLen
!= kMatchSpecLenStart
)
922 int checkEndMarkNow
= 0;
924 if (p
->dicPos
>= dicLimit
)
926 if (p
->remainLen
== 0 && p
->code
== 0)
928 *status
= LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK
;
931 if (finishMode
== LZMA_FINISH_ANY
)
933 *status
= LZMA_STATUS_NOT_FINISHED
;
936 if (p
->remainLen
!= 0)
938 *status
= LZMA_STATUS_NOT_FINISHED
;
939 return SZ_ERROR_DATA
;
944 if (p
->tempBufSize
== 0)
947 const Byte
*bufLimit
;
948 if (inSize
< LZMA_REQUIRED_INPUT_MAX
|| checkEndMarkNow
)
950 int dummyRes
= LzmaDec_TryDummy(p
, src
, inSize
);
951 if (dummyRes
== DUMMY_ERROR
)
953 memcpy(p
->tempBuf
, src
, inSize
);
954 p
->tempBufSize
= (unsigned)inSize
;
956 *status
= LZMA_STATUS_NEEDS_MORE_INPUT
;
959 if (checkEndMarkNow
&& dummyRes
!= DUMMY_MATCH
)
961 *status
= LZMA_STATUS_NOT_FINISHED
;
962 return SZ_ERROR_DATA
;
967 bufLimit
= src
+ inSize
- LZMA_REQUIRED_INPUT_MAX
;
969 if (LzmaDec_DecodeReal2(p
, dicLimit
, bufLimit
) != 0)
970 return SZ_ERROR_DATA
;
971 processed
= (SizeT
)(p
->buf
- src
);
972 (*srcLen
) += processed
;
978 unsigned rem
= p
->tempBufSize
, lookAhead
= 0;
979 while (rem
< LZMA_REQUIRED_INPUT_MAX
&& lookAhead
< inSize
)
980 p
->tempBuf
[rem
++] = src
[lookAhead
++];
981 p
->tempBufSize
= rem
;
982 if (rem
< LZMA_REQUIRED_INPUT_MAX
|| checkEndMarkNow
)
984 int dummyRes
= LzmaDec_TryDummy(p
, p
->tempBuf
, rem
);
985 if (dummyRes
== DUMMY_ERROR
)
987 (*srcLen
) += lookAhead
;
988 *status
= LZMA_STATUS_NEEDS_MORE_INPUT
;
991 if (checkEndMarkNow
&& dummyRes
!= DUMMY_MATCH
)
993 *status
= LZMA_STATUS_NOT_FINISHED
;
994 return SZ_ERROR_DATA
;
998 if (LzmaDec_DecodeReal2(p
, dicLimit
, p
->buf
) != 0)
999 return SZ_ERROR_DATA
;
1002 unsigned kkk
= (unsigned)(p
->buf
- p
->tempBuf
);
1004 return SZ_ERROR_FAIL
; /* some internal error */
1006 if (lookAhead
< rem
)
1007 return SZ_ERROR_FAIL
; /* some internal error */
1010 (*srcLen
) += lookAhead
;
1012 inSize
-= lookAhead
;
1018 return SZ_ERROR_DATA
;
1019 *status
= LZMA_STATUS_FINISHED_WITH_MARK
;
1024 SRes
LzmaDec_DecodeToBuf(CLzmaDec
*p
, Byte
*dest
, SizeT
*destLen
, const Byte
*src
, SizeT
*srcLen
, ELzmaFinishMode finishMode
, ELzmaStatus
*status
)
1026 SizeT outSize
= *destLen
;
1027 SizeT inSize
= *srcLen
;
1028 *srcLen
= *destLen
= 0;
1031 SizeT inSizeCur
= inSize
, outSizeCur
, dicPos
;
1032 ELzmaFinishMode curFinishMode
;
1034 if (p
->dicPos
== p
->dicBufSize
)
1037 if (outSize
> p
->dicBufSize
- dicPos
)
1039 outSizeCur
= p
->dicBufSize
;
1040 curFinishMode
= LZMA_FINISH_ANY
;
1044 outSizeCur
= dicPos
+ outSize
;
1045 curFinishMode
= finishMode
;
1048 res
= LzmaDec_DecodeToDic(p
, outSizeCur
, src
, &inSizeCur
, curFinishMode
, status
);
1050 inSize
-= inSizeCur
;
1051 *srcLen
+= inSizeCur
;
1052 outSizeCur
= p
->dicPos
- dicPos
;
1053 memcpy(dest
, p
->dic
+ dicPos
, outSizeCur
);
1055 outSize
-= outSizeCur
;
1056 *destLen
+= outSizeCur
;
1059 if (outSizeCur
== 0 || outSize
== 0)
1064 void LzmaDec_FreeProbs(CLzmaDec
*p
, ISzAllocPtr alloc
)
1066 ISzAlloc_Free(alloc
, p
->probs
);
1070 static void LzmaDec_FreeDict(CLzmaDec
*p
, ISzAllocPtr alloc
)
1072 ISzAlloc_Free(alloc
, p
->dic
);
1076 void LzmaDec_Free(CLzmaDec
*p
, ISzAllocPtr alloc
)
1078 LzmaDec_FreeProbs(p
, alloc
);
1079 LzmaDec_FreeDict(p
, alloc
);
1082 SRes
LzmaProps_Decode(CLzmaProps
*p
, const Byte
*data
, unsigned size
)
1087 if (size
< LZMA_PROPS_SIZE
)
1088 return SZ_ERROR_UNSUPPORTED
;
1090 dicSize
= data
[1] | ((UInt32
)data
[2] << 8) | ((UInt32
)data
[3] << 16) | ((UInt32
)data
[4] << 24);
1092 if (dicSize
< LZMA_DIC_MIN
)
1093 dicSize
= LZMA_DIC_MIN
;
1094 p
->dicSize
= dicSize
;
1097 if (d
>= (9 * 5 * 5))
1098 return SZ_ERROR_UNSUPPORTED
;
1100 p
->lc
= (Byte
)(d
% 9);
1102 p
->pb
= (Byte
)(d
/ 5);
1103 p
->lp
= (Byte
)(d
% 5);
1108 static SRes
LzmaDec_AllocateProbs2(CLzmaDec
*p
, const CLzmaProps
*propNew
, ISzAllocPtr alloc
)
1110 UInt32 numProbs
= LzmaProps_GetNumProbs(propNew
);
1111 if (!p
->probs
|| numProbs
!= p
->numProbs
)
1113 LzmaDec_FreeProbs(p
, alloc
);
1114 p
->probs
= (CLzmaProb
*)ISzAlloc_Alloc(alloc
, numProbs
* sizeof(CLzmaProb
));
1116 return SZ_ERROR_MEM
;
1117 p
->probs_1664
= p
->probs
+ 1664;
1118 p
->numProbs
= numProbs
;
1123 SRes
LzmaDec_AllocateProbs(CLzmaDec
*p
, const Byte
*props
, unsigned propsSize
, ISzAllocPtr alloc
)
1126 RINOK(LzmaProps_Decode(&propNew
, props
, propsSize
));
1127 RINOK(LzmaDec_AllocateProbs2(p
, &propNew
, alloc
));
1132 SRes
LzmaDec_Allocate(CLzmaDec
*p
, const Byte
*props
, unsigned propsSize
, ISzAllocPtr alloc
)
1136 RINOK(LzmaProps_Decode(&propNew
, props
, propsSize
));
1137 RINOK(LzmaDec_AllocateProbs2(p
, &propNew
, alloc
));
1140 UInt32 dictSize
= propNew
.dicSize
;
1141 SizeT mask
= ((UInt32
)1 << 12) - 1;
1142 if (dictSize
>= ((UInt32
)1 << 30)) mask
= ((UInt32
)1 << 22) - 1;
1143 else if (dictSize
>= ((UInt32
)1 << 22)) mask
= ((UInt32
)1 << 20) - 1;;
1144 dicBufSize
= ((SizeT
)dictSize
+ mask
) & ~mask
;
1145 if (dicBufSize
< dictSize
)
1146 dicBufSize
= dictSize
;
1149 if (!p
->dic
|| dicBufSize
!= p
->dicBufSize
)
1151 LzmaDec_FreeDict(p
, alloc
);
1152 p
->dic
= (Byte
*)ISzAlloc_Alloc(alloc
, dicBufSize
);
1155 LzmaDec_FreeProbs(p
, alloc
);
1156 return SZ_ERROR_MEM
;
1159 p
->dicBufSize
= dicBufSize
;
1164 SRes
LzmaDecode(Byte
*dest
, SizeT
*destLen
, const Byte
*src
, SizeT
*srcLen
,
1165 const Byte
*propData
, unsigned propSize
, ELzmaFinishMode finishMode
,
1166 ELzmaStatus
*status
, ISzAllocPtr alloc
)
1170 SizeT outSize
= *destLen
, inSize
= *srcLen
;
1171 *destLen
= *srcLen
= 0;
1172 *status
= LZMA_STATUS_NOT_SPECIFIED
;
1173 if (inSize
< RC_INIT_SIZE
)
1174 return SZ_ERROR_INPUT_EOF
;
1175 LzmaDec_Construct(&p
);
1176 RINOK(LzmaDec_AllocateProbs(&p
, propData
, propSize
, alloc
));
1178 p
.dicBufSize
= outSize
;
1181 res
= LzmaDec_DecodeToDic(&p
, outSize
, src
, srcLen
, finishMode
, status
);
1182 *destLen
= p
.dicPos
;
1183 if (res
== SZ_OK
&& *status
== LZMA_STATUS_NEEDS_MORE_INPUT
)
1184 res
= SZ_ERROR_INPUT_EOF
;
1185 LzmaDec_FreeProbs(&p
, alloc
);