4 Based on LZMA SDK 4.65:
5 LzmaDec.c -- LZMA Decoder
6 2008-11-06 : Igor Pavlov : Public domain
8 Copyright (c) 2009, Intel Corporation<BR>
9 All rights reserved. This program and the accompanying materials
10 are licensed and made available under the terms and conditions of the BSD License
11 which accompanies this distribution. The full text of the license may be found at
12 http://opensource.org/licenses/bsd-license.php
14 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
15 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
27 #define kNumTopBits 24
28 #define kTopValue ((UInt32)1 << kNumTopBits)
30 #define kNumBitModelTotalBits 11
31 #define kBitModelTotal (1 << kNumBitModelTotalBits)
32 #define kNumMoveBits 5
34 #define RC_INIT_SIZE 5
36 #define NORMALIZE if (range < kTopValue) { range <<= 8; code = (code << 8) | (*buf++); }
38 #define IF_BIT_0(p) ttt = *(p); NORMALIZE; bound = (range >> kNumBitModelTotalBits) * ttt; if (code < bound)
39 #define UPDATE_0(p) range = bound; *(p) = (CLzmaProb)(ttt + ((kBitModelTotal - ttt) >> kNumMoveBits));
40 #define UPDATE_1(p) range -= bound; code -= bound; *(p) = (CLzmaProb)(ttt - (ttt >> kNumMoveBits));
41 #define GET_BIT2(p, i, A0, A1) IF_BIT_0(p) \
42 { UPDATE_0(p); i = (i + i); A0; } else \
43 { UPDATE_1(p); i = (i + i) + 1; A1; }
44 #define GET_BIT(p, i) GET_BIT2(p, i, ; , ;)
46 #define TREE_GET_BIT(probs, i) { GET_BIT((probs + i), i); }
47 #define TREE_DECODE(probs, limit, i) \
48 { i = 1; do { TREE_GET_BIT(probs, i); } while (i < limit); i -= limit; }
50 /* #define _LZMA_SIZE_OPT */
53 #define TREE_6_DECODE(probs, i) TREE_DECODE(probs, (1 << 6), i)
55 #define TREE_6_DECODE(probs, i) \
57 TREE_GET_BIT(probs, i); \
58 TREE_GET_BIT(probs, i); \
59 TREE_GET_BIT(probs, i); \
60 TREE_GET_BIT(probs, i); \
61 TREE_GET_BIT(probs, i); \
62 TREE_GET_BIT(probs, i); \
66 #define NORMALIZE_CHECK if (range < kTopValue) { if (buf >= bufLimit) return DUMMY_ERROR; range <<= 8; code = (code << 8) | (*buf++); }
68 #define IF_BIT_0_CHECK(p) ttt = *(p); NORMALIZE_CHECK; bound = (range >> kNumBitModelTotalBits) * ttt; if (code < bound)
69 #define UPDATE_0_CHECK range = bound;
70 #define UPDATE_1_CHECK range -= bound; code -= bound;
71 #define GET_BIT2_CHECK(p, i, A0, A1) IF_BIT_0_CHECK(p) \
72 { UPDATE_0_CHECK; i = (i + i); A0; } else \
73 { UPDATE_1_CHECK; i = (i + i) + 1; A1; }
74 #define GET_BIT_CHECK(p, i) GET_BIT2_CHECK(p, i, ; , ;)
75 #define TREE_DECODE_CHECK(probs, limit, i) \
76 { i = 1; do { GET_BIT_CHECK(probs + i, i) } while (i < limit); i -= limit; }
79 #define kNumPosBitsMax 4
80 #define kNumPosStatesMax (1 << kNumPosBitsMax)
82 #define kLenNumLowBits 3
83 #define kLenNumLowSymbols (1 << kLenNumLowBits)
84 #define kLenNumMidBits 3
85 #define kLenNumMidSymbols (1 << kLenNumMidBits)
86 #define kLenNumHighBits 8
87 #define kLenNumHighSymbols (1 << kLenNumHighBits)
90 #define LenChoice2 (LenChoice + 1)
91 #define LenLow (LenChoice2 + 1)
92 #define LenMid (LenLow + (kNumPosStatesMax << kLenNumLowBits))
93 #define LenHigh (LenMid + (kNumPosStatesMax << kLenNumMidBits))
94 #define kNumLenProbs (LenHigh + kLenNumHighSymbols)
98 #define kNumLitStates 7
100 #define kStartPosModelIndex 4
101 #define kEndPosModelIndex 14
102 #define kNumFullDistances (1 << (kEndPosModelIndex >> 1))
104 #define kNumPosSlotBits 6
105 #define kNumLenToPosStates 4
107 #define kNumAlignBits 4
108 #define kAlignTableSize (1 << kNumAlignBits)
110 #define kMatchMinLen 2
111 #define kMatchSpecLenStart (kMatchMinLen + kLenNumLowSymbols + kLenNumMidSymbols + kLenNumHighSymbols)
114 #define IsRep (IsMatch + (kNumStates << kNumPosBitsMax))
115 #define IsRepG0 (IsRep + kNumStates)
116 #define IsRepG1 (IsRepG0 + kNumStates)
117 #define IsRepG2 (IsRepG1 + kNumStates)
118 #define IsRep0Long (IsRepG2 + kNumStates)
119 #define PosSlot (IsRep0Long + (kNumStates << kNumPosBitsMax))
120 #define SpecPos (PosSlot + (kNumLenToPosStates << kNumPosSlotBits))
121 #define Align (SpecPos + kNumFullDistances - kEndPosModelIndex)
122 #define LenCoder (Align + kAlignTableSize)
123 #define RepLenCoder (LenCoder + kNumLenProbs)
124 #define Literal (RepLenCoder + kNumLenProbs)
126 #define LZMA_BASE_SIZE 1846
127 #define LZMA_LIT_SIZE 768
129 #define LzmaProps_GetNumProbs(p) ((UInt32)LZMA_BASE_SIZE + (LZMA_LIT_SIZE << ((p)->lc + (p)->lp)))
131 #if Literal != LZMA_BASE_SIZE
135 static const Byte kLiteralNextStates
[kNumStates
* 2] =
137 0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 4, 5,
138 7, 7, 7, 7, 7, 7, 7, 10, 10, 10, 10, 10
141 #define LZMA_DIC_MIN (1 << 12)
143 /* First LZMA-symbol is always decoded.
144 And it decodes new LZMA-symbols while (buf < bufLimit), but "buf" is without last normalization
148 SZ_ERROR_DATA - Error
150 < kMatchSpecLenStart : normal remain
151 = kMatchSpecLenStart : finished
152 = kMatchSpecLenStart + 1 : Flush marker
153 = kMatchSpecLenStart + 2 : State Init Marker
156 static int MY_FAST_CALL
LzmaDec_DecodeReal(CLzmaDec
*p
, SizeT limit
, const Byte
*bufLimit
)
158 CLzmaProb
*probs
= p
->probs
;
160 unsigned state
= p
->state
;
161 UInt32 rep0
= p
->reps
[0], rep1
= p
->reps
[1], rep2
= p
->reps
[2], rep3
= p
->reps
[3];
162 unsigned pbMask
= ((unsigned)1 << (p
->prop
.pb
)) - 1;
163 unsigned lpMask
= ((unsigned)1 << (p
->prop
.lp
)) - 1;
164 unsigned lc
= p
->prop
.lc
;
167 SizeT dicBufSize
= p
->dicBufSize
;
168 SizeT dicPos
= p
->dicPos
;
170 UInt32 processedPos
= p
->processedPos
;
171 UInt32 checkDicSize
= p
->checkDicSize
;
174 const Byte
*buf
= p
->buf
;
175 UInt32 range
= p
->range
;
176 UInt32 code
= p
->code
;
183 unsigned posState
= processedPos
& pbMask
;
185 prob
= probs
+ IsMatch
+ (state
<< kNumPosBitsMax
) + posState
;
190 prob
= probs
+ Literal
;
191 if (checkDicSize
!= 0 || processedPos
!= 0)
192 prob
+= (LZMA_LIT_SIZE
* (((processedPos
& lpMask
) << lc
) +
193 (dic
[(dicPos
== 0 ? dicBufSize
: dicPos
) - 1] >> (8 - lc
))));
195 if (state
< kNumLitStates
)
198 do { GET_BIT(prob
+ symbol
, symbol
) } while (symbol
< 0x100);
202 unsigned matchByte
= p
->dic
[(dicPos
- rep0
) + ((dicPos
< rep0
) ? dicBufSize
: 0)];
203 unsigned offs
= 0x100;
210 bit
= (matchByte
& offs
);
211 probLit
= prob
+ offs
+ bit
+ symbol
;
212 GET_BIT2(probLit
, symbol
, offs
&= ~bit
, offs
&= bit
)
214 while (symbol
< 0x100);
216 dic
[dicPos
++] = (Byte
)symbol
;
219 state
= kLiteralNextStates
[state
];
220 /* if (state < 4) state = 0; else if (state < 10) state -= 3; else state -= 6; */
226 prob
= probs
+ IsRep
+ state
;
231 prob
= probs
+ LenCoder
;
236 if (checkDicSize
== 0 && processedPos
== 0)
237 return SZ_ERROR_DATA
;
238 prob
= probs
+ IsRepG0
+ state
;
242 prob
= probs
+ IsRep0Long
+ (state
<< kNumPosBitsMax
) + posState
;
246 dic
[dicPos
] = dic
[(dicPos
- rep0
) + ((dicPos
< rep0
) ? dicBufSize
: 0)];
249 state
= state
< kNumLitStates
? 9 : 11;
258 prob
= probs
+ IsRepG1
+ state
;
267 prob
= probs
+ IsRepG2
+ state
;
284 state
= state
< kNumLitStates
? 8 : 11;
285 prob
= probs
+ RepLenCoder
;
288 unsigned limit2
, offset
;
289 CLzmaProb
*probLen
= prob
+ LenChoice
;
293 probLen
= prob
+ LenLow
+ (posState
<< kLenNumLowBits
);
295 limit2
= (1 << kLenNumLowBits
);
300 probLen
= prob
+ LenChoice2
;
304 probLen
= prob
+ LenMid
+ (posState
<< kLenNumMidBits
);
305 offset
= kLenNumLowSymbols
;
306 limit2
= (1 << kLenNumMidBits
);
311 probLen
= prob
+ LenHigh
;
312 offset
= kLenNumLowSymbols
+ kLenNumMidSymbols
;
313 limit2
= (1 << kLenNumHighBits
);
316 TREE_DECODE(probLen
, limit2
, len
);
320 if (state
>= kNumStates
)
323 prob
= probs
+ PosSlot
+
324 ((len
< kNumLenToPosStates
? len
: kNumLenToPosStates
- 1) << kNumPosSlotBits
);
325 TREE_6_DECODE(prob
, distance
);
326 if (distance
>= kStartPosModelIndex
)
328 unsigned posSlot
= (unsigned)distance
;
329 int numDirectBits
= (int)(((distance
>> 1) - 1));
330 distance
= (2 | (distance
& 1));
331 if (posSlot
< kEndPosModelIndex
)
333 distance
<<= numDirectBits
;
334 prob
= probs
+ SpecPos
+ distance
- posSlot
- 1;
340 GET_BIT2(prob
+ i
, i
, ; , distance
|= mask
);
343 while (--numDirectBits
!= 0);
348 numDirectBits
-= kNumAlignBits
;
357 t
= (0 - ((UInt32
)code
>> 31)); /* (UInt32)((Int32)code >> 31) */
358 distance
= (distance
<< 1) + (t
+ 1);
370 while (--numDirectBits
!= 0);
371 prob
= probs
+ Align
;
372 distance
<<= kNumAlignBits
;
375 GET_BIT2(prob
+ i
, i
, ; , distance
|= 1);
376 GET_BIT2(prob
+ i
, i
, ; , distance
|= 2);
377 GET_BIT2(prob
+ i
, i
, ; , distance
|= 4);
378 GET_BIT2(prob
+ i
, i
, ; , distance
|= 8);
380 if (distance
== (UInt32
)0xFFFFFFFF)
382 len
+= kMatchSpecLenStart
;
392 if (checkDicSize
== 0)
394 if (distance
>= processedPos
)
395 return SZ_ERROR_DATA
;
397 else if (distance
>= checkDicSize
)
398 return SZ_ERROR_DATA
;
399 state
= (state
< kNumStates
+ kNumLitStates
) ? kNumLitStates
: kNumLitStates
+ 3;
400 /* state = kLiteralNextStates[state]; */
406 return SZ_ERROR_DATA
;
408 SizeT rem
= limit
- dicPos
;
409 unsigned curLen
= ((rem
< len
) ? (unsigned)rem
: len
);
410 SizeT pos
= (dicPos
- rep0
) + ((dicPos
< rep0
) ? dicBufSize
: 0);
412 processedPos
+= curLen
;
415 if (pos
+ curLen
<= dicBufSize
)
417 Byte
*dest
= dic
+ dicPos
;
418 ptrdiff_t src
= (ptrdiff_t)pos
- (ptrdiff_t)dicPos
;
419 const Byte
*lim
= dest
+ curLen
;
422 *(dest
) = (Byte
)*(dest
+ src
);
423 while (++dest
!= lim
);
429 dic
[dicPos
++] = dic
[pos
];
430 if (++pos
== dicBufSize
)
433 while (--curLen
!= 0);
438 while (dicPos
< limit
&& buf
< bufLimit
);
445 p
->processedPos
= processedPos
;
455 static void MY_FAST_CALL
LzmaDec_WriteRem(CLzmaDec
*p
, SizeT limit
)
457 if (p
->remainLen
!= 0 && p
->remainLen
< kMatchSpecLenStart
)
460 SizeT dicPos
= p
->dicPos
;
461 SizeT dicBufSize
= p
->dicBufSize
;
462 unsigned len
= p
->remainLen
;
463 UInt32 rep0
= p
->reps
[0];
464 if (limit
- dicPos
< len
)
465 len
= (unsigned)(limit
- dicPos
);
467 if (p
->checkDicSize
== 0 && p
->prop
.dicSize
- p
->processedPos
<= len
)
468 p
->checkDicSize
= p
->prop
.dicSize
;
470 p
->processedPos
+= len
;
474 dic
[dicPos
] = dic
[(dicPos
- rep0
) + ((dicPos
< rep0
) ? dicBufSize
: 0)];
481 static int MY_FAST_CALL
LzmaDec_DecodeReal2(CLzmaDec
*p
, SizeT limit
, const Byte
*bufLimit
)
485 SizeT limit2
= limit
;
486 if (p
->checkDicSize
== 0)
488 UInt32 rem
= p
->prop
.dicSize
- p
->processedPos
;
489 if (limit
- p
->dicPos
> rem
)
490 limit2
= p
->dicPos
+ rem
;
492 RINOK(LzmaDec_DecodeReal(p
, limit2
, bufLimit
));
493 if (p
->processedPos
>= p
->prop
.dicSize
)
494 p
->checkDicSize
= p
->prop
.dicSize
;
495 LzmaDec_WriteRem(p
, limit
);
497 while (p
->dicPos
< limit
&& p
->buf
< bufLimit
&& p
->remainLen
< kMatchSpecLenStart
);
499 if (p
->remainLen
> kMatchSpecLenStart
)
501 p
->remainLen
= kMatchSpecLenStart
;
508 DUMMY_ERROR
, /* unexpected end of input stream */
514 static ELzmaDummy
LzmaDec_TryDummy(const CLzmaDec
*p
, const Byte
*buf
, SizeT inSize
)
516 UInt32 range
= p
->range
;
517 UInt32 code
= p
->code
;
518 const Byte
*bufLimit
= buf
+ inSize
;
519 CLzmaProb
*probs
= p
->probs
;
520 unsigned state
= p
->state
;
527 unsigned posState
= (p
->processedPos
) & ((1 << p
->prop
.pb
) - 1);
529 prob
= probs
+ IsMatch
+ (state
<< kNumPosBitsMax
) + posState
;
534 /* if (bufLimit - buf >= 7) return DUMMY_LIT; */
536 prob
= probs
+ Literal
;
537 if (p
->checkDicSize
!= 0 || p
->processedPos
!= 0)
538 prob
+= (LZMA_LIT_SIZE
*
539 ((((p
->processedPos
) & ((1 << (p
->prop
.lp
)) - 1)) << p
->prop
.lc
) +
540 (p
->dic
[(p
->dicPos
== 0 ? p
->dicBufSize
: p
->dicPos
) - 1] >> (8 - p
->prop
.lc
))));
542 if (state
< kNumLitStates
)
545 do { GET_BIT_CHECK(prob
+ symbol
, symbol
) } while (symbol
< 0x100);
549 unsigned matchByte
= p
->dic
[p
->dicPos
- p
->reps
[0] +
550 ((p
->dicPos
< p
->reps
[0]) ? p
->dicBufSize
: 0)];
551 unsigned offs
= 0x100;
558 bit
= (matchByte
& offs
);
559 probLit
= prob
+ offs
+ bit
+ symbol
;
560 GET_BIT2_CHECK(probLit
, symbol
, offs
&= ~bit
, offs
&= bit
)
562 while (symbol
< 0x100);
571 prob
= probs
+ IsRep
+ state
;
576 prob
= probs
+ LenCoder
;
583 prob
= probs
+ IsRepG0
+ state
;
587 prob
= probs
+ IsRep0Long
+ (state
<< kNumPosBitsMax
) + posState
;
602 prob
= probs
+ IsRepG1
+ state
;
610 prob
= probs
+ IsRepG2
+ state
;
622 prob
= probs
+ RepLenCoder
;
625 unsigned limit
, offset
;
626 CLzmaProb
*probLen
= prob
+ LenChoice
;
627 IF_BIT_0_CHECK(probLen
)
630 probLen
= prob
+ LenLow
+ (posState
<< kLenNumLowBits
);
632 limit
= 1 << kLenNumLowBits
;
637 probLen
= prob
+ LenChoice2
;
638 IF_BIT_0_CHECK(probLen
)
641 probLen
= prob
+ LenMid
+ (posState
<< kLenNumMidBits
);
642 offset
= kLenNumLowSymbols
;
643 limit
= 1 << kLenNumMidBits
;
648 probLen
= prob
+ LenHigh
;
649 offset
= kLenNumLowSymbols
+ kLenNumMidSymbols
;
650 limit
= 1 << kLenNumHighBits
;
653 TREE_DECODE_CHECK(probLen
, limit
, len
);
660 prob
= probs
+ PosSlot
+
661 ((len
< kNumLenToPosStates
? len
: kNumLenToPosStates
- 1) <<
663 TREE_DECODE_CHECK(prob
, 1 << kNumPosSlotBits
, posSlot
);
664 if (posSlot
>= kStartPosModelIndex
)
666 int numDirectBits
= ((posSlot
>> 1) - 1);
668 /* if (bufLimit - buf >= 8) return DUMMY_MATCH; */
670 if (posSlot
< kEndPosModelIndex
)
672 prob
= probs
+ SpecPos
+ ((2 | (posSlot
& 1)) << numDirectBits
) - posSlot
- 1;
676 numDirectBits
-= kNumAlignBits
;
681 code
-= range
& (((code
- range
) >> 31) - 1);
682 /* if (code >= range) code -= range; */
684 while (--numDirectBits
!= 0);
685 prob
= probs
+ Align
;
686 numDirectBits
= kNumAlignBits
;
692 GET_BIT_CHECK(prob
+ i
, i
);
694 while (--numDirectBits
!= 0);
704 static void LzmaDec_InitRc(CLzmaDec
*p
, const Byte
*data
)
706 p
->code
= ((UInt32
)data
[1] << 24) | ((UInt32
)data
[2] << 16) | ((UInt32
)data
[3] << 8) | ((UInt32
)data
[4]);
707 p
->range
= 0xFFFFFFFF;
711 void LzmaDec_InitDicAndState(CLzmaDec
*p
, Bool initDic
, Bool initState
)
721 p
->needInitState
= 1;
724 p
->needInitState
= 1;
727 void LzmaDec_Init(CLzmaDec
*p
)
730 LzmaDec_InitDicAndState(p
, True
, True
);
733 static void LzmaDec_InitStateReal(CLzmaDec
*p
)
735 UInt32 numProbs
= Literal
+ ((UInt32
)LZMA_LIT_SIZE
<< (p
->prop
.lc
+ p
->prop
.lp
));
737 CLzmaProb
*probs
= p
->probs
;
738 for (i
= 0; i
< numProbs
; i
++)
739 probs
[i
] = kBitModelTotal
>> 1;
740 p
->reps
[0] = p
->reps
[1] = p
->reps
[2] = p
->reps
[3] = 1;
742 p
->needInitState
= 0;
745 SRes
LzmaDec_DecodeToDic(CLzmaDec
*p
, SizeT dicLimit
, const Byte
*src
, SizeT
*srcLen
,
746 ELzmaFinishMode finishMode
, ELzmaStatus
*status
)
748 SizeT inSize
= *srcLen
;
750 LzmaDec_WriteRem(p
, dicLimit
);
752 *status
= LZMA_STATUS_NOT_SPECIFIED
;
754 while (p
->remainLen
!= kMatchSpecLenStart
)
758 if (p
->needFlush
!= 0)
760 for (; inSize
> 0 && p
->tempBufSize
< RC_INIT_SIZE
; (*srcLen
)++, inSize
--)
761 p
->tempBuf
[p
->tempBufSize
++] = *src
++;
762 if (p
->tempBufSize
< RC_INIT_SIZE
)
764 *status
= LZMA_STATUS_NEEDS_MORE_INPUT
;
767 if (p
->tempBuf
[0] != 0)
768 return SZ_ERROR_DATA
;
770 LzmaDec_InitRc(p
, p
->tempBuf
);
775 if (p
->dicPos
>= dicLimit
)
777 if (p
->remainLen
== 0 && p
->code
== 0)
779 *status
= LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK
;
782 if (finishMode
== LZMA_FINISH_ANY
)
784 *status
= LZMA_STATUS_NOT_FINISHED
;
787 if (p
->remainLen
!= 0)
789 *status
= LZMA_STATUS_NOT_FINISHED
;
790 return SZ_ERROR_DATA
;
795 if (p
->needInitState
)
796 LzmaDec_InitStateReal(p
);
798 if (p
->tempBufSize
== 0)
801 const Byte
*bufLimit
;
802 if (inSize
< LZMA_REQUIRED_INPUT_MAX
|| checkEndMarkNow
)
804 int dummyRes
= LzmaDec_TryDummy(p
, src
, inSize
);
805 if (dummyRes
== DUMMY_ERROR
)
807 memcpy(p
->tempBuf
, src
, inSize
);
808 p
->tempBufSize
= (unsigned)inSize
;
810 *status
= LZMA_STATUS_NEEDS_MORE_INPUT
;
813 if (checkEndMarkNow
&& dummyRes
!= DUMMY_MATCH
)
815 *status
= LZMA_STATUS_NOT_FINISHED
;
816 return SZ_ERROR_DATA
;
821 bufLimit
= src
+ inSize
- LZMA_REQUIRED_INPUT_MAX
;
823 if (LzmaDec_DecodeReal2(p
, dicLimit
, bufLimit
) != 0)
824 return SZ_ERROR_DATA
;
825 processed
= (SizeT
)(p
->buf
- src
);
826 (*srcLen
) += processed
;
832 unsigned rem
= p
->tempBufSize
, lookAhead
= 0;
833 while (rem
< LZMA_REQUIRED_INPUT_MAX
&& lookAhead
< inSize
)
834 p
->tempBuf
[rem
++] = src
[lookAhead
++];
835 p
->tempBufSize
= rem
;
836 if (rem
< LZMA_REQUIRED_INPUT_MAX
|| checkEndMarkNow
)
838 int dummyRes
= LzmaDec_TryDummy(p
, p
->tempBuf
, rem
);
839 if (dummyRes
== DUMMY_ERROR
)
841 (*srcLen
) += lookAhead
;
842 *status
= LZMA_STATUS_NEEDS_MORE_INPUT
;
845 if (checkEndMarkNow
&& dummyRes
!= DUMMY_MATCH
)
847 *status
= LZMA_STATUS_NOT_FINISHED
;
848 return SZ_ERROR_DATA
;
852 if (LzmaDec_DecodeReal2(p
, dicLimit
, p
->buf
) != 0)
853 return SZ_ERROR_DATA
;
854 lookAhead
-= (rem
- (unsigned)(p
->buf
- p
->tempBuf
));
855 (*srcLen
) += lookAhead
;
862 *status
= LZMA_STATUS_FINISHED_WITH_MARK
;
863 return (p
->code
== 0) ? SZ_OK
: SZ_ERROR_DATA
;
866 SRes
LzmaDec_DecodeToBuf(CLzmaDec
*p
, Byte
*dest
, SizeT
*destLen
, const Byte
*src
, SizeT
*srcLen
, ELzmaFinishMode finishMode
, ELzmaStatus
*status
)
868 SizeT outSize
= *destLen
;
869 SizeT inSize
= *srcLen
;
870 *srcLen
= *destLen
= 0;
873 SizeT inSizeCur
= inSize
, outSizeCur
, dicPos
;
874 ELzmaFinishMode curFinishMode
;
876 if (p
->dicPos
== p
->dicBufSize
)
879 if (outSize
> p
->dicBufSize
- dicPos
)
881 outSizeCur
= p
->dicBufSize
;
882 curFinishMode
= LZMA_FINISH_ANY
;
886 outSizeCur
= dicPos
+ outSize
;
887 curFinishMode
= finishMode
;
890 res
= LzmaDec_DecodeToDic(p
, outSizeCur
, src
, &inSizeCur
, curFinishMode
, status
);
893 *srcLen
+= inSizeCur
;
894 outSizeCur
= p
->dicPos
- dicPos
;
895 memcpy(dest
, p
->dic
+ dicPos
, outSizeCur
);
897 outSize
-= outSizeCur
;
898 *destLen
+= outSizeCur
;
901 if (outSizeCur
== 0 || outSize
== 0)
906 void LzmaDec_FreeProbs(CLzmaDec
*p
, ISzAlloc
*alloc
)
908 alloc
->Free(alloc
, p
->probs
);
912 static void LzmaDec_FreeDict(CLzmaDec
*p
, ISzAlloc
*alloc
)
914 alloc
->Free(alloc
, p
->dic
);
918 void LzmaDec_Free(CLzmaDec
*p
, ISzAlloc
*alloc
)
920 LzmaDec_FreeProbs(p
, alloc
);
921 LzmaDec_FreeDict(p
, alloc
);
924 SRes
LzmaProps_Decode(CLzmaProps
*p
, const Byte
*data
, unsigned size
)
929 if (size
< LZMA_PROPS_SIZE
)
930 return SZ_ERROR_UNSUPPORTED
;
932 dicSize
= data
[1] | ((UInt32
)data
[2] << 8) | ((UInt32
)data
[3] << 16) | ((UInt32
)data
[4] << 24);
934 if (dicSize
< LZMA_DIC_MIN
)
935 dicSize
= LZMA_DIC_MIN
;
936 p
->dicSize
= dicSize
;
939 if (d
>= (9 * 5 * 5))
940 return SZ_ERROR_UNSUPPORTED
;
950 static SRes
LzmaDec_AllocateProbs2(CLzmaDec
*p
, const CLzmaProps
*propNew
, ISzAlloc
*alloc
)
952 UInt32 numProbs
= LzmaProps_GetNumProbs(propNew
);
953 if (p
->probs
== 0 || numProbs
!= p
->numProbs
)
955 LzmaDec_FreeProbs(p
, alloc
);
956 p
->probs
= (CLzmaProb
*)alloc
->Alloc(alloc
, numProbs
* sizeof(CLzmaProb
));
957 p
->numProbs
= numProbs
;
964 SRes
LzmaDec_AllocateProbs(CLzmaDec
*p
, const Byte
*props
, unsigned propsSize
, ISzAlloc
*alloc
)
967 RINOK(LzmaProps_Decode(&propNew
, props
, propsSize
));
968 RINOK(LzmaDec_AllocateProbs2(p
, &propNew
, alloc
));
973 SRes
LzmaDec_Allocate(CLzmaDec
*p
, const Byte
*props
, unsigned propsSize
, ISzAlloc
*alloc
)
977 RINOK(LzmaProps_Decode(&propNew
, props
, propsSize
));
978 RINOK(LzmaDec_AllocateProbs2(p
, &propNew
, alloc
));
979 dicBufSize
= propNew
.dicSize
;
980 if (p
->dic
== 0 || dicBufSize
!= p
->dicBufSize
)
982 LzmaDec_FreeDict(p
, alloc
);
983 p
->dic
= (Byte
*)alloc
->Alloc(alloc
, dicBufSize
);
986 LzmaDec_FreeProbs(p
, alloc
);
990 p
->dicBufSize
= dicBufSize
;
995 SRes
LzmaDecode(Byte
*dest
, SizeT
*destLen
, const Byte
*src
, SizeT
*srcLen
,
996 const Byte
*propData
, unsigned propSize
, ELzmaFinishMode finishMode
,
997 ELzmaStatus
*status
, ISzAlloc
*alloc
)
1001 SizeT inSize
= *srcLen
;
1002 SizeT outSize
= *destLen
;
1003 *srcLen
= *destLen
= 0;
1004 if (inSize
< RC_INIT_SIZE
)
1005 return SZ_ERROR_INPUT_EOF
;
1007 LzmaDec_Construct(&p
);
1008 res
= LzmaDec_AllocateProbs(&p
, propData
, propSize
, alloc
);
1012 p
.dicBufSize
= outSize
;
1017 res
= LzmaDec_DecodeToDic(&p
, outSize
, src
, srcLen
, finishMode
, status
);
1019 if (res
== SZ_OK
&& *status
== LZMA_STATUS_NEEDS_MORE_INPUT
)
1020 res
= SZ_ERROR_INPUT_EOF
;
1022 (*destLen
) = p
.dicPos
;
1023 LzmaDec_FreeProbs(&p
, alloc
);