2 * GRUB -- GRand Unified Bootloader
3 * Copyright (c) 1999-2008 Igor Pavlov
4 * Copyright (C) 2008 Free Software Foundation, Inc.
6 * GRUB is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation, either version 3 of the License, or
9 * (at your option) any later version.
11 * GRUB is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with GRUB. If not, see <http://www.gnu.org/licenses/>.
21 * This code was taken from LZMA SDK 4.58 beta, and was slightly modified
22 * to adapt it to GRUB's requirement.
24 * See <http://www.7-zip.org>, for more information about LZMA.
27 #include <grub/lib/LzmaDec.h>
31 #define kNumTopBits 24
32 #define kTopValue ((UInt32)1 << kNumTopBits)
34 #define kNumBitModelTotalBits 11
35 #define kBitModelTotal (1 << kNumBitModelTotalBits)
36 #define kNumMoveBits 5
38 #define RC_INIT_SIZE 5
40 #define NORMALIZE if (range < kTopValue) { range <<= 8; code = (code << 8) | (*buf++); }
42 #define IF_BIT_0(p) ttt = *(p); NORMALIZE; bound = (range >> kNumBitModelTotalBits) * ttt; if (code < bound)
43 #define UPDATE_0(p) range = bound; *(p) = (CLzmaProb)(ttt + ((kBitModelTotal - ttt) >> kNumMoveBits));
44 #define UPDATE_1(p) range -= bound; code -= bound; *(p) = (CLzmaProb)(ttt - (ttt >> kNumMoveBits));
45 #define GET_BIT2(p, i, A0, A1) IF_BIT_0(p) \
46 { UPDATE_0(p); i = (i + i); A0; } else \
47 { UPDATE_1(p); i = (i + i) + 1; A1; }
48 #define GET_BIT(p, i) GET_BIT2(p, i, ; , ;)
50 #define TREE_GET_BIT(probs, i) { GET_BIT((probs + i), i); }
51 #define TREE_DECODE(probs, limit, i) \
52 { i = 1; do { TREE_GET_BIT(probs, i); } while (i < limit); i -= limit; }
54 /* #define _LZMA_SIZE_OPT */
57 #define TREE_6_DECODE(probs, i) TREE_DECODE(probs, (1 << 6), i)
59 #define TREE_6_DECODE(probs, i) \
61 TREE_GET_BIT(probs, i); \
62 TREE_GET_BIT(probs, i); \
63 TREE_GET_BIT(probs, i); \
64 TREE_GET_BIT(probs, i); \
65 TREE_GET_BIT(probs, i); \
66 TREE_GET_BIT(probs, i); \
70 #define NORMALIZE_CHECK if (range < kTopValue) { if (buf >= bufLimit) return DUMMY_ERROR; range <<= 8; code = (code << 8) | (*buf++); }
72 #define IF_BIT_0_CHECK(p) ttt = *(p); NORMALIZE_CHECK; bound = (range >> kNumBitModelTotalBits) * ttt; if (code < bound)
73 #define UPDATE_0_CHECK range = bound;
74 #define UPDATE_1_CHECK range -= bound; code -= bound;
75 #define GET_BIT2_CHECK(p, i, A0, A1) IF_BIT_0_CHECK(p) \
76 { UPDATE_0_CHECK; i = (i + i); A0; } else \
77 { UPDATE_1_CHECK; i = (i + i) + 1; A1; }
78 #define GET_BIT_CHECK(p, i) GET_BIT2_CHECK(p, i, ; , ;)
79 #define TREE_DECODE_CHECK(probs, limit, i) \
80 { i = 1; do { GET_BIT_CHECK(probs + i, i) } while(i < limit); i -= limit; }
83 #define kNumPosBitsMax 4
84 #define kNumPosStatesMax (1 << kNumPosBitsMax)
86 #define kLenNumLowBits 3
87 #define kLenNumLowSymbols (1 << kLenNumLowBits)
88 #define kLenNumMidBits 3
89 #define kLenNumMidSymbols (1 << kLenNumMidBits)
90 #define kLenNumHighBits 8
91 #define kLenNumHighSymbols (1 << kLenNumHighBits)
94 #define LenChoice2 (LenChoice + 1)
95 #define LenLow (LenChoice2 + 1)
96 #define LenMid (LenLow + (kNumPosStatesMax << kLenNumLowBits))
97 #define LenHigh (LenMid + (kNumPosStatesMax << kLenNumMidBits))
98 #define kNumLenProbs (LenHigh + kLenNumHighSymbols)
101 #define kNumStates 12
102 #define kNumLitStates 7
104 #define kStartPosModelIndex 4
105 #define kEndPosModelIndex 14
106 #define kNumFullDistances (1 << (kEndPosModelIndex >> 1))
108 #define kNumPosSlotBits 6
109 #define kNumLenToPosStates 4
111 #define kNumAlignBits 4
112 #define kAlignTableSize (1 << kNumAlignBits)
114 #define kMatchMinLen 2
115 #define kMatchSpecLenStart (kMatchMinLen + kLenNumLowSymbols + kLenNumMidSymbols + kLenNumHighSymbols)
118 #define IsRep (IsMatch + (kNumStates << kNumPosBitsMax))
119 #define IsRepG0 (IsRep + kNumStates)
120 #define IsRepG1 (IsRepG0 + kNumStates)
121 #define IsRepG2 (IsRepG1 + kNumStates)
122 #define IsRep0Long (IsRepG2 + kNumStates)
123 #define PosSlot (IsRep0Long + (kNumStates << kNumPosBitsMax))
124 #define SpecPos (PosSlot + (kNumLenToPosStates << kNumPosSlotBits))
125 #define Align (SpecPos + kNumFullDistances - kEndPosModelIndex)
126 #define LenCoder (Align + kAlignTableSize)
127 #define RepLenCoder (LenCoder + kNumLenProbs)
128 #define Literal (RepLenCoder + kNumLenProbs)
130 #define LZMA_BASE_SIZE 1846
131 #define LZMA_LIT_SIZE 768
133 #define LzmaProps_GetNumProbs(p) ((UInt32)LZMA_BASE_SIZE + (LZMA_LIT_SIZE << ((p)->lc + (p)->lp)))
135 #if Literal != LZMA_BASE_SIZE
140 #define LZMA_STREAM_WAS_FINISHED_ID (-1)
141 #define LZMA_SPEC_LEN_OFFSET (-3)
144 Byte kLiteralNextStates
[kNumStates
* 2] =
146 0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 4, 5,
147 7, 7, 7, 7, 7, 7, 7, 10, 10, 10, 10, 10
150 #define LZMA_DIC_MIN (1 << 12)
152 /* First LZMA-symbol is always decoded.
153 And it decodes new LZMA-symbols while (buf < bufLimit), but "buf" is without last normalization
159 < kMatchSpecLenStart : normal remain
160 = kMatchSpecLenStart : finished
161 = kMatchSpecLenStart + 1 : Flush marker
162 = kMatchSpecLenStart + 2 : State Init Marker
165 static int MY_FAST_CALL
LzmaDec_DecodeReal(CLzmaDec
*p
, SizeT limit
, const Byte
*bufLimit
)
167 CLzmaProb
*probs
= p
->probs
;
169 unsigned state
= p
->state
;
170 UInt32 rep0
= p
->reps
[0], rep1
= p
->reps
[1], rep2
= p
->reps
[2], rep3
= p
->reps
[3];
171 unsigned pbMask
= ((unsigned)1 << (p
->prop
.pb
)) - 1;
172 unsigned lpMask
= ((unsigned)1 << (p
->prop
.lp
)) - 1;
173 unsigned lc
= p
->prop
.lc
;
176 SizeT dicBufSize
= p
->dicBufSize
;
177 SizeT dicPos
= p
->dicPos
;
179 UInt32 processedPos
= p
->processedPos
;
180 UInt32 checkDicSize
= p
->checkDicSize
;
183 const Byte
*buf
= p
->buf
;
184 UInt32 range
= p
->range
;
185 UInt32 code
= p
->code
;
192 unsigned posState
= processedPos
& pbMask
;
194 prob
= probs
+ IsMatch
+ (state
<< kNumPosBitsMax
) + posState
;
199 prob
= probs
+ Literal
;
200 if (checkDicSize
!= 0 || processedPos
!= 0)
201 prob
+= (LZMA_LIT_SIZE
* (((processedPos
& lpMask
) << lc
) +
202 (dic
[(dicPos
== 0 ? dicBufSize
: dicPos
) - 1] >> (8 - lc
))));
204 if (state
< kNumLitStates
)
207 do { GET_BIT(prob
+ symbol
, symbol
) } while (symbol
< 0x100);
211 unsigned matchByte
= p
->dic
[(dicPos
- rep0
) + ((dicPos
< rep0
) ? dicBufSize
: 0)];
212 unsigned offs
= 0x100;
219 bit
= (matchByte
& offs
);
220 probLit
= prob
+ offs
+ bit
+ symbol
;
221 GET_BIT2(probLit
, symbol
, offs
&= ~bit
, offs
&= bit
)
223 while (symbol
< 0x100);
225 dic
[dicPos
++] = (Byte
)symbol
;
228 state
= kLiteralNextStates
[state
];
229 /* if (state < 4) state = 0; else if (state < 10) state -= 3; else state -= 6; */
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 unsigned limit
, offset
;
298 CLzmaProb
*probLen
= prob
+ LenChoice
;
302 probLen
= prob
+ LenLow
+ (posState
<< kLenNumLowBits
);
304 limit
= (1 << kLenNumLowBits
);
309 probLen
= prob
+ LenChoice2
;
313 probLen
= prob
+ LenMid
+ (posState
<< kLenNumMidBits
);
314 offset
= kLenNumLowSymbols
;
315 limit
= (1 << kLenNumMidBits
);
320 probLen
= prob
+ LenHigh
;
321 offset
= kLenNumLowSymbols
+ kLenNumMidSymbols
;
322 limit
= (1 << kLenNumHighBits
);
325 TREE_DECODE(probLen
, limit
, len
);
329 if (state
>= kNumStates
)
332 prob
= probs
+ PosSlot
+
333 ((len
< kNumLenToPosStates
? len
: kNumLenToPosStates
- 1) << kNumPosSlotBits
);
334 TREE_6_DECODE(prob
, distance
);
335 if (distance
>= kStartPosModelIndex
)
337 unsigned posSlot
= (unsigned)distance
;
338 int numDirectBits
= (int)(((distance
>> 1) - 1));
339 distance
= (2 | (distance
& 1));
340 if (posSlot
< kEndPosModelIndex
)
342 distance
<<= numDirectBits
;
343 prob
= probs
+ SpecPos
+ distance
- posSlot
- 1;
349 GET_BIT2(prob
+ i
, i
, ; , distance
|= mask
);
352 while(--numDirectBits
!= 0);
357 numDirectBits
-= kNumAlignBits
;
366 t
= (0 - ((UInt32
)code
>> 31)); /* (UInt32)((Int32)code >> 31) */
367 distance
= (distance
<< 1) + (t
+ 1);
379 while (--numDirectBits
!= 0);
380 prob
= probs
+ Align
;
381 distance
<<= kNumAlignBits
;
384 GET_BIT2(prob
+ i
, i
, ; , distance
|= 1);
385 GET_BIT2(prob
+ i
, i
, ; , distance
|= 2);
386 GET_BIT2(prob
+ i
, i
, ; , distance
|= 4);
387 GET_BIT2(prob
+ i
, i
, ; , distance
|= 8);
389 if (distance
== (UInt32
)0xFFFFFFFF)
391 len
+= kMatchSpecLenStart
;
401 if (checkDicSize
== 0)
403 if (distance
>= processedPos
)
404 return SZ_ERROR_DATA
;
406 else if (distance
>= checkDicSize
)
407 return SZ_ERROR_DATA
;
408 state
= (state
< kNumStates
+ kNumLitStates
) ? kNumLitStates
: kNumLitStates
+ 3;
409 /* state = kLiteralNextStates[state]; */
415 SizeT rem
= limit
- dicPos
;
416 unsigned curLen
= ((rem
< len
) ? (unsigned)rem
: len
);
417 SizeT pos
= (dicPos
- rep0
) + ((dicPos
< rep0
) ? dicBufSize
: 0);
419 processedPos
+= curLen
;
422 if (pos
+ curLen
<= dicBufSize
)
424 Byte
*dest
= dic
+ dicPos
;
425 ptrdiff_t src
= (ptrdiff_t)pos
- (ptrdiff_t)dicPos
;
426 const Byte
*lim
= dest
+ curLen
;
429 *(dest
) = (Byte
)*(dest
+ src
);
430 while (++dest
!= lim
);
436 dic
[dicPos
++] = dic
[pos
];
437 if (++pos
== dicBufSize
)
440 while (--curLen
!= 0);
445 while (dicPos
< limit
&& buf
< bufLimit
);
452 p
->processedPos
= processedPos
;
462 static void MY_FAST_CALL
LzmaDec_WriteRem(CLzmaDec
*p
, SizeT limit
)
464 if (p
->remainLen
!= 0 && p
->remainLen
< kMatchSpecLenStart
)
467 SizeT dicPos
= p
->dicPos
;
468 SizeT dicBufSize
= p
->dicBufSize
;
469 unsigned len
= p
->remainLen
;
470 UInt32 rep0
= p
->reps
[0];
471 if (limit
- dicPos
< len
)
472 len
= (unsigned)(limit
- dicPos
);
474 if (p
->checkDicSize
== 0 && p
->prop
.dicSize
- p
->processedPos
<= len
)
475 p
->checkDicSize
= p
->prop
.dicSize
;
477 p
->processedPos
+= len
;
481 dic
[dicPos
] = dic
[(dicPos
- rep0
) + ((dicPos
< rep0
) ? dicBufSize
: 0)];
488 /* LzmaDec_DecodeReal2 decodes LZMA-symbols and sets p->needFlush and p->needInit, if required. */
490 static int MY_FAST_CALL
LzmaDec_DecodeReal2(CLzmaDec
*p
, SizeT limit
, const Byte
*bufLimit
)
494 SizeT limit2
= limit
;
495 if (p
->checkDicSize
== 0)
497 UInt32 rem
= p
->prop
.dicSize
- p
->processedPos
;
498 if (limit
- p
->dicPos
> rem
)
499 limit2
= p
->dicPos
+ rem
;
501 RINOK(LzmaDec_DecodeReal(p
, limit2
, bufLimit
));
502 if (p
->processedPos
>= p
->prop
.dicSize
)
503 p
->checkDicSize
= p
->prop
.dicSize
;
504 LzmaDec_WriteRem(p
, limit
);
506 while (p
->dicPos
< limit
&& p
->buf
< bufLimit
&& p
->remainLen
< kMatchSpecLenStart
);
508 if (p
->remainLen
> kMatchSpecLenStart
)
510 p
->remainLen
= kMatchSpecLenStart
;
517 DUMMY_ERROR
, /* unexpected end of input stream */
523 static ELzmaDummy
LzmaDec_TryDummy(const CLzmaDec
*p
, const Byte
*buf
, SizeT inSize
)
525 UInt32 range
= p
->range
;
526 UInt32 code
= p
->code
;
527 const Byte
*bufLimit
= buf
+ inSize
;
528 CLzmaProb
*probs
= p
->probs
;
529 unsigned state
= p
->state
;
536 unsigned posState
= (p
->processedPos
) & ((1 << p
->prop
.pb
) - 1);
538 prob
= probs
+ IsMatch
+ (state
<< kNumPosBitsMax
) + posState
;
543 /* if (bufLimit - buf >= 7) return DUMMY_LIT; */
545 prob
= probs
+ Literal
;
546 if (p
->checkDicSize
!= 0 || p
->processedPos
!= 0)
547 prob
+= (LZMA_LIT_SIZE
*
548 ((((p
->processedPos
) & ((1 << (p
->prop
.lp
)) - 1)) << p
->prop
.lc
) +
549 (p
->dic
[(p
->dicPos
== 0 ? p
->dicBufSize
: p
->dicPos
) - 1] >> (8 - p
->prop
.lc
))));
551 if (state
< kNumLitStates
)
554 do { GET_BIT_CHECK(prob
+ symbol
, symbol
) } while (symbol
< 0x100);
558 unsigned matchByte
= p
->dic
[p
->dicPos
- p
->reps
[0] +
559 ((p
->dicPos
< p
->reps
[0]) ? p
->dicBufSize
: 0)];
560 unsigned offs
= 0x100;
567 bit
= (matchByte
& offs
);
568 probLit
= prob
+ offs
+ bit
+ symbol
;
569 GET_BIT2_CHECK(probLit
, symbol
, offs
&= ~bit
, offs
&= bit
)
571 while (symbol
< 0x100);
580 prob
= probs
+ IsRep
+ state
;
585 prob
= probs
+ LenCoder
;
592 prob
= probs
+ IsRepG0
+ state
;
596 prob
= probs
+ IsRep0Long
+ (state
<< kNumPosBitsMax
) + posState
;
611 prob
= probs
+ IsRepG1
+ state
;
619 prob
= probs
+ IsRepG2
+ state
;
631 prob
= probs
+ RepLenCoder
;
634 unsigned limit
, offset
;
635 CLzmaProb
*probLen
= prob
+ LenChoice
;
636 IF_BIT_0_CHECK(probLen
)
639 probLen
= prob
+ LenLow
+ (posState
<< kLenNumLowBits
);
641 limit
= 1 << kLenNumLowBits
;
646 probLen
= prob
+ LenChoice2
;
647 IF_BIT_0_CHECK(probLen
)
650 probLen
= prob
+ LenMid
+ (posState
<< kLenNumMidBits
);
651 offset
= kLenNumLowSymbols
;
652 limit
= 1 << kLenNumMidBits
;
657 probLen
= prob
+ LenHigh
;
658 offset
= kLenNumLowSymbols
+ kLenNumMidSymbols
;
659 limit
= 1 << kLenNumHighBits
;
662 TREE_DECODE_CHECK(probLen
, limit
, len
);
669 prob
= probs
+ PosSlot
+
670 ((len
< kNumLenToPosStates
? len
: kNumLenToPosStates
- 1) <<
672 TREE_DECODE_CHECK(prob
, 1 << kNumPosSlotBits
, posSlot
);
673 if (posSlot
>= kStartPosModelIndex
)
675 int numDirectBits
= ((posSlot
>> 1) - 1);
677 /* if (bufLimit - buf >= 8) return DUMMY_MATCH; */
679 if (posSlot
< kEndPosModelIndex
)
681 prob
= probs
+ SpecPos
+ ((2 | (posSlot
& 1)) << numDirectBits
) - posSlot
- 1;
685 numDirectBits
-= kNumAlignBits
;
690 code
-= range
& (((code
- range
) >> 31) - 1);
691 /* if (code >= range) code -= range; */
693 while (--numDirectBits
!= 0);
694 prob
= probs
+ Align
;
695 numDirectBits
= kNumAlignBits
;
701 GET_BIT_CHECK(prob
+ i
, i
);
703 while(--numDirectBits
!= 0);
714 static void LzmaDec_InitRc(CLzmaDec
*p
, const Byte
*data
)
716 p
->code
= ((UInt32
)data
[1] << 24) | ((UInt32
)data
[2] << 16) | ((UInt32
)data
[3] << 8) | ((UInt32
)data
[4]);
717 p
->range
= 0xFFFFFFFF;
721 void LzmaDec_InitDicAndState(CLzmaDec
*p
, Bool initDic
, Bool initState
)
731 p
->needInitState
= 1;
734 p
->needInitState
= 1;
737 void LzmaDec_Init(CLzmaDec
*p
)
740 LzmaDec_InitDicAndState(p
, True
, True
);
743 static void LzmaDec_InitStateReal(CLzmaDec
*p
)
745 UInt32 numProbs
= Literal
+ ((UInt32
)LZMA_LIT_SIZE
<< (p
->prop
.lc
+ p
->prop
.lp
));
747 CLzmaProb
*probs
= p
->probs
;
748 for (i
= 0; i
< numProbs
; i
++)
749 probs
[i
] = kBitModelTotal
>> 1;
750 p
->reps
[0] = p
->reps
[1] = p
->reps
[2] = p
->reps
[3] = 1;
752 p
->needInitState
= 0;
755 SRes
LzmaDec_DecodeToDic(CLzmaDec
*p
, SizeT dicLimit
, const Byte
*src
, SizeT
*srcLen
,
756 ELzmaFinishMode finishMode
, ELzmaStatus
*status
)
758 SizeT inSize
= *srcLen
;
760 LzmaDec_WriteRem(p
, dicLimit
);
762 *status
= LZMA_STATUS_NOT_SPECIFIED
;
764 while (p
->remainLen
!= kMatchSpecLenStart
)
768 if (p
->needFlush
!= 0)
770 for (; inSize
> 0 && p
->tempBufSize
< RC_INIT_SIZE
; (*srcLen
)++, inSize
--)
771 p
->tempBuf
[p
->tempBufSize
++] = *src
++;
772 if (p
->tempBufSize
< RC_INIT_SIZE
)
774 *status
= LZMA_STATUS_NEEDS_MORE_INPUT
;
777 if (p
->tempBuf
[0] != 0)
778 return SZ_ERROR_DATA
;
780 LzmaDec_InitRc(p
, p
->tempBuf
);
785 if (p
->dicPos
>= dicLimit
)
787 if (p
->remainLen
== 0 && p
->code
== 0)
789 *status
= LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK
;
792 if (finishMode
== LZMA_FINISH_ANY
)
794 *status
= LZMA_STATUS_NOT_FINISHED
;
797 if (p
->remainLen
!= 0)
799 *status
= LZMA_STATUS_NOT_FINISHED
;
800 return SZ_ERROR_DATA
;
805 if (p
->needInitState
)
806 LzmaDec_InitStateReal(p
);
808 if (p
->tempBufSize
== 0)
811 const Byte
*bufLimit
;
812 if (inSize
< LZMA_REQUIRED_INPUT_MAX
|| checkEndMarkNow
)
814 int dummyRes
= LzmaDec_TryDummy(p
, src
, inSize
);
815 if (dummyRes
== DUMMY_ERROR
)
817 memcpy(p
->tempBuf
, src
, inSize
);
818 p
->tempBufSize
= (unsigned)inSize
;
820 *status
= LZMA_STATUS_NEEDS_MORE_INPUT
;
823 if (checkEndMarkNow
&& dummyRes
!= DUMMY_MATCH
)
825 *status
= LZMA_STATUS_NOT_FINISHED
;
826 return SZ_ERROR_DATA
;
831 bufLimit
= src
+ inSize
- LZMA_REQUIRED_INPUT_MAX
;
833 if (LzmaDec_DecodeReal2(p
, dicLimit
, bufLimit
) != 0)
834 return SZ_ERROR_DATA
;
835 processed
= p
->buf
- src
;
836 (*srcLen
) += processed
;
842 unsigned rem
= p
->tempBufSize
, lookAhead
= 0;
843 while (rem
< LZMA_REQUIRED_INPUT_MAX
&& lookAhead
< inSize
)
844 p
->tempBuf
[rem
++] = src
[lookAhead
++];
845 p
->tempBufSize
= rem
;
846 if (rem
< LZMA_REQUIRED_INPUT_MAX
|| checkEndMarkNow
)
848 int dummyRes
= LzmaDec_TryDummy(p
, p
->tempBuf
, rem
);
849 if (dummyRes
== DUMMY_ERROR
)
851 (*srcLen
) += lookAhead
;
852 *status
= LZMA_STATUS_NEEDS_MORE_INPUT
;
855 if (checkEndMarkNow
&& dummyRes
!= DUMMY_MATCH
)
857 *status
= LZMA_STATUS_NOT_FINISHED
;
858 return SZ_ERROR_DATA
;
862 if (LzmaDec_DecodeReal2(p
, dicLimit
, p
->buf
) != 0)
863 return SZ_ERROR_DATA
;
864 lookAhead
-= (rem
- (unsigned)(p
->buf
- p
->tempBuf
));
865 (*srcLen
) += lookAhead
;
872 *status
= LZMA_STATUS_FINISHED_WITH_MARK
;
873 return (p
->code
== 0) ? SZ_OK
: SZ_ERROR_DATA
;
876 SRes
LzmaDec_DecodeToBuf(CLzmaDec
*p
, Byte
*dest
, SizeT
*destLen
, const Byte
*src
, SizeT
*srcLen
, ELzmaFinishMode finishMode
, ELzmaStatus
*status
)
878 SizeT outSize
= *destLen
;
879 SizeT inSize
= *srcLen
;
880 *srcLen
= *destLen
= 0;
883 SizeT inSizeCur
= inSize
, outSizeCur
, dicPos
;
884 ELzmaFinishMode curFinishMode
;
886 if (p
->dicPos
== p
->dicBufSize
)
889 if (outSize
> p
->dicBufSize
- dicPos
)
891 outSizeCur
= p
->dicBufSize
;
892 curFinishMode
= LZMA_FINISH_ANY
;
896 outSizeCur
= dicPos
+ outSize
;
897 curFinishMode
= finishMode
;
900 res
= LzmaDec_DecodeToDic(p
, outSizeCur
, src
, &inSizeCur
, curFinishMode
, status
);
903 *srcLen
+= inSizeCur
;
904 outSizeCur
= p
->dicPos
- dicPos
;
905 memcpy(dest
, p
->dic
+ dicPos
, outSizeCur
);
907 outSize
-= outSizeCur
;
908 *destLen
+= outSizeCur
;
911 if (outSizeCur
== 0 || outSize
== 0)
916 void LzmaDec_FreeProbs(CLzmaDec
*p
, ISzAlloc
*alloc
)
918 alloc
->Free(alloc
, p
->probs
);
922 static void LzmaDec_FreeDict(CLzmaDec
*p
, ISzAlloc
*alloc
)
924 alloc
->Free(alloc
, p
->dic
);
928 void LzmaDec_Free(CLzmaDec
*p
, ISzAlloc
*alloc
)
930 LzmaDec_FreeProbs(p
, alloc
);
931 LzmaDec_FreeDict(p
, alloc
);
934 SRes
LzmaProps_Decode(CLzmaProps
*p
, const Byte
*data
, unsigned size
)
939 if (size
< LZMA_PROPS_SIZE
)
940 return SZ_ERROR_UNSUPPORTED
;
942 dicSize
= data
[1] | ((UInt32
)data
[2] << 8) | ((UInt32
)data
[3] << 16) | ((UInt32
)data
[4] << 24);
944 if (dicSize
< LZMA_DIC_MIN
)
945 dicSize
= LZMA_DIC_MIN
;
946 p
->dicSize
= dicSize
;
949 if (d
>= (9 * 5 * 5))
950 return SZ_ERROR_UNSUPPORTED
;
960 static SRes
LzmaDec_AllocateProbs2(CLzmaDec
*p
, const CLzmaProps
*propNew
, ISzAlloc
*alloc
)
962 UInt32 numProbs
= LzmaProps_GetNumProbs(propNew
);
963 if (p
->probs
== 0 || numProbs
!= p
->numProbs
)
965 LzmaDec_FreeProbs(p
, alloc
);
966 p
->probs
= (CLzmaProb
*)alloc
->Alloc(alloc
, numProbs
* sizeof(CLzmaProb
));
967 p
->numProbs
= numProbs
;
974 SRes
LzmaDec_AllocateProbs(CLzmaDec
*p
, const Byte
*props
, unsigned propsSize
, ISzAlloc
*alloc
)
977 RINOK(LzmaProps_Decode(&propNew
, props
, propsSize
));
978 RINOK(LzmaDec_AllocateProbs2(p
, &propNew
, alloc
));
983 SRes
LzmaDec_Allocate(CLzmaDec
*p
, const Byte
*props
, unsigned propsSize
, ISzAlloc
*alloc
)
987 RINOK(LzmaProps_Decode(&propNew
, props
, propsSize
));
988 RINOK(LzmaDec_AllocateProbs2(p
, &propNew
, alloc
));
989 dicBufSize
= propNew
.dicSize
;
990 if (p
->dic
== 0 || dicBufSize
!= p
->dicBufSize
)
992 LzmaDec_FreeDict(p
, alloc
);
993 p
->dic
= (Byte
*)alloc
->Alloc(alloc
, dicBufSize
);
996 LzmaDec_FreeProbs(p
, alloc
);
1000 p
->dicBufSize
= dicBufSize
;
1005 SRes
LzmaDecode(Byte
*dest
, SizeT
*destLen
, const Byte
*src
, SizeT
*srcLen
,
1006 const Byte
*propData
, unsigned propSize
, ELzmaFinishMode finishMode
,
1007 ELzmaStatus
*status
, ISzAlloc
*alloc
)
1011 SizeT inSize
= *srcLen
;
1012 SizeT outSize
= *destLen
;
1013 *srcLen
= *destLen
= 0;
1014 if (inSize
< RC_INIT_SIZE
)
1015 return SZ_ERROR_INPUT_EOF
;
1017 LzmaDec_Construct(&p
);
1018 res
= LzmaDec_AllocateProbs(&p
, propData
, propSize
, alloc
);
1022 p
.dicBufSize
= outSize
;
1027 res
= LzmaDec_DecodeToDic(&p
, outSize
, src
, srcLen
, finishMode
, status
);
1029 if (res
== SZ_OK
&& *status
== LZMA_STATUS_NEEDS_MORE_INPUT
)
1030 res
= SZ_ERROR_INPUT_EOF
;
1032 (*destLen
) = p
.dicPos
;
1033 LzmaDec_FreeProbs(&p
, alloc
);