1*8996SAlok.Aggarwal@Sun.COM /*
2*8996SAlok.Aggarwal@Sun.COM * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
3*8996SAlok.Aggarwal@Sun.COM * Use is subject to license terms.
4*8996SAlok.Aggarwal@Sun.COM */
5*8996SAlok.Aggarwal@Sun.COM
6*8996SAlok.Aggarwal@Sun.COM /* LzmaDec.c -- LZMA Decoder
7*8996SAlok.Aggarwal@Sun.COM 2008-11-06 : Igor Pavlov : Public domain */
8*8996SAlok.Aggarwal@Sun.COM
9*8996SAlok.Aggarwal@Sun.COM #include "LzmaDec.h"
10*8996SAlok.Aggarwal@Sun.COM
11*8996SAlok.Aggarwal@Sun.COM #ifndef _KERNEL
12*8996SAlok.Aggarwal@Sun.COM #include <string.h>
13*8996SAlok.Aggarwal@Sun.COM #endif /* _KERNEL */
14*8996SAlok.Aggarwal@Sun.COM
15*8996SAlok.Aggarwal@Sun.COM #define kNumTopBits 24
16*8996SAlok.Aggarwal@Sun.COM #define kTopValue ((UInt32)1 << kNumTopBits)
17*8996SAlok.Aggarwal@Sun.COM
18*8996SAlok.Aggarwal@Sun.COM #define kNumBitModelTotalBits 11
19*8996SAlok.Aggarwal@Sun.COM #define kBitModelTotal (1 << kNumBitModelTotalBits)
20*8996SAlok.Aggarwal@Sun.COM #define kNumMoveBits 5
21*8996SAlok.Aggarwal@Sun.COM
22*8996SAlok.Aggarwal@Sun.COM #define RC_INIT_SIZE 5
23*8996SAlok.Aggarwal@Sun.COM
24*8996SAlok.Aggarwal@Sun.COM #define NORMALIZE if (range < kTopValue) { range <<= 8; code = (code << 8) | (*buf++); }
25*8996SAlok.Aggarwal@Sun.COM
26*8996SAlok.Aggarwal@Sun.COM #define IF_BIT_0(p) ttt = *(p); NORMALIZE; bound = (range >> kNumBitModelTotalBits) * ttt; if (code < bound)
27*8996SAlok.Aggarwal@Sun.COM #define UPDATE_0(p) range = bound; *(p) = (CLzmaProb)(ttt + ((kBitModelTotal - ttt) >> kNumMoveBits));
28*8996SAlok.Aggarwal@Sun.COM #define UPDATE_1(p) range -= bound; code -= bound; *(p) = (CLzmaProb)(ttt - (ttt >> kNumMoveBits));
29*8996SAlok.Aggarwal@Sun.COM #define GET_BIT2(p, i, A0, A1) IF_BIT_0(p) \
30*8996SAlok.Aggarwal@Sun.COM { UPDATE_0(p); i = (i + i); A0; } else \
31*8996SAlok.Aggarwal@Sun.COM { UPDATE_1(p); i = (i + i) + 1; A1; }
32*8996SAlok.Aggarwal@Sun.COM #define GET_BIT(p, i) GET_BIT2(p, i, ; , ;)
33*8996SAlok.Aggarwal@Sun.COM
34*8996SAlok.Aggarwal@Sun.COM #define TREE_GET_BIT(probs, i) { GET_BIT((probs + i), i); }
35*8996SAlok.Aggarwal@Sun.COM #define TREE_DECODE(probs, limit, i) \
36*8996SAlok.Aggarwal@Sun.COM { i = 1; do { TREE_GET_BIT(probs, i); } while (i < limit); i -= limit; }
37*8996SAlok.Aggarwal@Sun.COM
38*8996SAlok.Aggarwal@Sun.COM /* #define _LZMA_SIZE_OPT */
39*8996SAlok.Aggarwal@Sun.COM
40*8996SAlok.Aggarwal@Sun.COM #ifdef _LZMA_SIZE_OPT
41*8996SAlok.Aggarwal@Sun.COM #define TREE_6_DECODE(probs, i) TREE_DECODE(probs, (1 << 6), i)
42*8996SAlok.Aggarwal@Sun.COM #else
43*8996SAlok.Aggarwal@Sun.COM #define TREE_6_DECODE(probs, i) \
44*8996SAlok.Aggarwal@Sun.COM { i = 1; \
45*8996SAlok.Aggarwal@Sun.COM TREE_GET_BIT(probs, i); \
46*8996SAlok.Aggarwal@Sun.COM TREE_GET_BIT(probs, i); \
47*8996SAlok.Aggarwal@Sun.COM TREE_GET_BIT(probs, i); \
48*8996SAlok.Aggarwal@Sun.COM TREE_GET_BIT(probs, i); \
49*8996SAlok.Aggarwal@Sun.COM TREE_GET_BIT(probs, i); \
50*8996SAlok.Aggarwal@Sun.COM TREE_GET_BIT(probs, i); \
51*8996SAlok.Aggarwal@Sun.COM i -= 0x40; }
52*8996SAlok.Aggarwal@Sun.COM #endif
53*8996SAlok.Aggarwal@Sun.COM
54*8996SAlok.Aggarwal@Sun.COM #define NORMALIZE_CHECK if (range < kTopValue) { if (buf >= bufLimit) return DUMMY_ERROR; range <<= 8; code = (code << 8) | (*buf++); }
55*8996SAlok.Aggarwal@Sun.COM
56*8996SAlok.Aggarwal@Sun.COM #define IF_BIT_0_CHECK(p) ttt = *(p); NORMALIZE_CHECK; bound = (range >> kNumBitModelTotalBits) * ttt; if (code < bound)
57*8996SAlok.Aggarwal@Sun.COM #define UPDATE_0_CHECK range = bound;
58*8996SAlok.Aggarwal@Sun.COM #define UPDATE_1_CHECK range -= bound; code -= bound;
59*8996SAlok.Aggarwal@Sun.COM #define GET_BIT2_CHECK(p, i, A0, A1) IF_BIT_0_CHECK(p) \
60*8996SAlok.Aggarwal@Sun.COM { UPDATE_0_CHECK; i = (i + i); A0; } else \
61*8996SAlok.Aggarwal@Sun.COM { UPDATE_1_CHECK; i = (i + i) + 1; A1; }
62*8996SAlok.Aggarwal@Sun.COM #define GET_BIT_CHECK(p, i) GET_BIT2_CHECK(p, i, ; , ;)
63*8996SAlok.Aggarwal@Sun.COM #define TREE_DECODE_CHECK(probs, limit, i) \
64*8996SAlok.Aggarwal@Sun.COM { i = 1; do { GET_BIT_CHECK(probs + i, i) } while (i < limit); i -= limit; }
65*8996SAlok.Aggarwal@Sun.COM
66*8996SAlok.Aggarwal@Sun.COM
67*8996SAlok.Aggarwal@Sun.COM #define kNumPosBitsMax 4
68*8996SAlok.Aggarwal@Sun.COM #define kNumPosStatesMax (1 << kNumPosBitsMax)
69*8996SAlok.Aggarwal@Sun.COM
70*8996SAlok.Aggarwal@Sun.COM #define kLenNumLowBits 3
71*8996SAlok.Aggarwal@Sun.COM #define kLenNumLowSymbols (1 << kLenNumLowBits)
72*8996SAlok.Aggarwal@Sun.COM #define kLenNumMidBits 3
73*8996SAlok.Aggarwal@Sun.COM #define kLenNumMidSymbols (1 << kLenNumMidBits)
74*8996SAlok.Aggarwal@Sun.COM #define kLenNumHighBits 8
75*8996SAlok.Aggarwal@Sun.COM #define kLenNumHighSymbols (1 << kLenNumHighBits)
76*8996SAlok.Aggarwal@Sun.COM
77*8996SAlok.Aggarwal@Sun.COM #define LenChoice 0
78*8996SAlok.Aggarwal@Sun.COM #define LenChoice2 (LenChoice + 1)
79*8996SAlok.Aggarwal@Sun.COM #define LenLow (LenChoice2 + 1)
80*8996SAlok.Aggarwal@Sun.COM #define LenMid (LenLow + (kNumPosStatesMax << kLenNumLowBits))
81*8996SAlok.Aggarwal@Sun.COM #define LenHigh (LenMid + (kNumPosStatesMax << kLenNumMidBits))
82*8996SAlok.Aggarwal@Sun.COM #define kNumLenProbs (LenHigh + kLenNumHighSymbols)
83*8996SAlok.Aggarwal@Sun.COM
84*8996SAlok.Aggarwal@Sun.COM
85*8996SAlok.Aggarwal@Sun.COM #define kNumStates 12
86*8996SAlok.Aggarwal@Sun.COM #define kNumLitStates 7
87*8996SAlok.Aggarwal@Sun.COM
88*8996SAlok.Aggarwal@Sun.COM #define kStartPosModelIndex 4
89*8996SAlok.Aggarwal@Sun.COM #define kEndPosModelIndex 14
90*8996SAlok.Aggarwal@Sun.COM #define kNumFullDistances (1 << (kEndPosModelIndex >> 1))
91*8996SAlok.Aggarwal@Sun.COM
92*8996SAlok.Aggarwal@Sun.COM #define kNumPosSlotBits 6
93*8996SAlok.Aggarwal@Sun.COM #define kNumLenToPosStates 4
94*8996SAlok.Aggarwal@Sun.COM
95*8996SAlok.Aggarwal@Sun.COM #define kNumAlignBits 4
96*8996SAlok.Aggarwal@Sun.COM #define kAlignTableSize (1 << kNumAlignBits)
97*8996SAlok.Aggarwal@Sun.COM
98*8996SAlok.Aggarwal@Sun.COM #define kMatchMinLen 2
99*8996SAlok.Aggarwal@Sun.COM #define kMatchSpecLenStart (kMatchMinLen + kLenNumLowSymbols + kLenNumMidSymbols + kLenNumHighSymbols)
100*8996SAlok.Aggarwal@Sun.COM
101*8996SAlok.Aggarwal@Sun.COM #define IsMatch 0
102*8996SAlok.Aggarwal@Sun.COM #define IsRep (IsMatch + (kNumStates << kNumPosBitsMax))
103*8996SAlok.Aggarwal@Sun.COM #define IsRepG0 (IsRep + kNumStates)
104*8996SAlok.Aggarwal@Sun.COM #define IsRepG1 (IsRepG0 + kNumStates)
105*8996SAlok.Aggarwal@Sun.COM #define IsRepG2 (IsRepG1 + kNumStates)
106*8996SAlok.Aggarwal@Sun.COM #define IsRep0Long (IsRepG2 + kNumStates)
107*8996SAlok.Aggarwal@Sun.COM #define PosSlot (IsRep0Long + (kNumStates << kNumPosBitsMax))
108*8996SAlok.Aggarwal@Sun.COM #define SpecPos (PosSlot + (kNumLenToPosStates << kNumPosSlotBits))
109*8996SAlok.Aggarwal@Sun.COM #define Align (SpecPos + kNumFullDistances - kEndPosModelIndex)
110*8996SAlok.Aggarwal@Sun.COM #define LenCoder (Align + kAlignTableSize)
111*8996SAlok.Aggarwal@Sun.COM #define RepLenCoder (LenCoder + kNumLenProbs)
112*8996SAlok.Aggarwal@Sun.COM #define Literal (RepLenCoder + kNumLenProbs)
113*8996SAlok.Aggarwal@Sun.COM
114*8996SAlok.Aggarwal@Sun.COM #define LZMA_BASE_SIZE 1846
115*8996SAlok.Aggarwal@Sun.COM #define LZMA_LIT_SIZE 768
116*8996SAlok.Aggarwal@Sun.COM
117*8996SAlok.Aggarwal@Sun.COM #define LzmaProps_GetNumProbs(p) ((UInt32)LZMA_BASE_SIZE + (LZMA_LIT_SIZE << ((p)->lc + (p)->lp)))
118*8996SAlok.Aggarwal@Sun.COM
119*8996SAlok.Aggarwal@Sun.COM #if Literal != LZMA_BASE_SIZE
120*8996SAlok.Aggarwal@Sun.COM StopCompilingDueBUG
121*8996SAlok.Aggarwal@Sun.COM #endif
122*8996SAlok.Aggarwal@Sun.COM
123*8996SAlok.Aggarwal@Sun.COM static const Byte kLiteralNextStates[kNumStates * 2] =
124*8996SAlok.Aggarwal@Sun.COM {
125*8996SAlok.Aggarwal@Sun.COM 0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 4, 5,
126*8996SAlok.Aggarwal@Sun.COM 7, 7, 7, 7, 7, 7, 7, 10, 10, 10, 10, 10
127*8996SAlok.Aggarwal@Sun.COM };
128*8996SAlok.Aggarwal@Sun.COM
129*8996SAlok.Aggarwal@Sun.COM #ifdef _KERNEL
130*8996SAlok.Aggarwal@Sun.COM extern void *memcpy(void *, const void *, size_t);
131*8996SAlok.Aggarwal@Sun.COM #endif /* _KERNEL */
132*8996SAlok.Aggarwal@Sun.COM
133*8996SAlok.Aggarwal@Sun.COM #define LZMA_DIC_MIN (1 << 12)
134*8996SAlok.Aggarwal@Sun.COM
135*8996SAlok.Aggarwal@Sun.COM /* First LZMA-symbol is always decoded.
136*8996SAlok.Aggarwal@Sun.COM And it decodes new LZMA-symbols while (buf < bufLimit), but "buf" is without last normalization
137*8996SAlok.Aggarwal@Sun.COM Out:
138*8996SAlok.Aggarwal@Sun.COM Result:
139*8996SAlok.Aggarwal@Sun.COM SZ_OK - OK
140*8996SAlok.Aggarwal@Sun.COM SZ_ERROR_DATA - Error
141*8996SAlok.Aggarwal@Sun.COM p->remainLen:
142*8996SAlok.Aggarwal@Sun.COM < kMatchSpecLenStart : normal remain
143*8996SAlok.Aggarwal@Sun.COM = kMatchSpecLenStart : finished
144*8996SAlok.Aggarwal@Sun.COM = kMatchSpecLenStart + 1 : Flush marker
145*8996SAlok.Aggarwal@Sun.COM = kMatchSpecLenStart + 2 : State Init Marker
146*8996SAlok.Aggarwal@Sun.COM */
147*8996SAlok.Aggarwal@Sun.COM
LzmaDec_DecodeReal(CLzmaDec * p,SizeT limit,const Byte * bufLimit)148*8996SAlok.Aggarwal@Sun.COM static int MY_FAST_CALL LzmaDec_DecodeReal(CLzmaDec *p, SizeT limit, const Byte *bufLimit)
149*8996SAlok.Aggarwal@Sun.COM {
150*8996SAlok.Aggarwal@Sun.COM CLzmaProb *probs = p->probs;
151*8996SAlok.Aggarwal@Sun.COM
152*8996SAlok.Aggarwal@Sun.COM unsigned state = p->state;
153*8996SAlok.Aggarwal@Sun.COM UInt32 rep0 = p->reps[0], rep1 = p->reps[1], rep2 = p->reps[2], rep3 = p->reps[3];
154*8996SAlok.Aggarwal@Sun.COM unsigned pbMask = ((unsigned)1 << (p->prop.pb)) - 1;
155*8996SAlok.Aggarwal@Sun.COM unsigned lpMask = ((unsigned)1 << (p->prop.lp)) - 1;
156*8996SAlok.Aggarwal@Sun.COM unsigned lc = p->prop.lc;
157*8996SAlok.Aggarwal@Sun.COM
158*8996SAlok.Aggarwal@Sun.COM Byte *dic = p->dic;
159*8996SAlok.Aggarwal@Sun.COM SizeT dicBufSize = p->dicBufSize;
160*8996SAlok.Aggarwal@Sun.COM SizeT dicPos = p->dicPos;
161*8996SAlok.Aggarwal@Sun.COM
162*8996SAlok.Aggarwal@Sun.COM UInt32 processedPos = p->processedPos;
163*8996SAlok.Aggarwal@Sun.COM UInt32 checkDicSize = p->checkDicSize;
164*8996SAlok.Aggarwal@Sun.COM unsigned len = 0;
165*8996SAlok.Aggarwal@Sun.COM
166*8996SAlok.Aggarwal@Sun.COM const Byte *buf = p->buf;
167*8996SAlok.Aggarwal@Sun.COM UInt32 range = p->range;
168*8996SAlok.Aggarwal@Sun.COM UInt32 code = p->code;
169*8996SAlok.Aggarwal@Sun.COM
170*8996SAlok.Aggarwal@Sun.COM do
171*8996SAlok.Aggarwal@Sun.COM {
172*8996SAlok.Aggarwal@Sun.COM CLzmaProb *prob;
173*8996SAlok.Aggarwal@Sun.COM UInt32 bound;
174*8996SAlok.Aggarwal@Sun.COM unsigned ttt;
175*8996SAlok.Aggarwal@Sun.COM unsigned posState = processedPos & pbMask;
176*8996SAlok.Aggarwal@Sun.COM
177*8996SAlok.Aggarwal@Sun.COM prob = probs + IsMatch + (state << kNumPosBitsMax) + posState;
178*8996SAlok.Aggarwal@Sun.COM IF_BIT_0(prob)
179*8996SAlok.Aggarwal@Sun.COM {
180*8996SAlok.Aggarwal@Sun.COM unsigned symbol;
181*8996SAlok.Aggarwal@Sun.COM UPDATE_0(prob);
182*8996SAlok.Aggarwal@Sun.COM prob = probs + Literal;
183*8996SAlok.Aggarwal@Sun.COM if (checkDicSize != 0 || processedPos != 0)
184*8996SAlok.Aggarwal@Sun.COM prob += (LZMA_LIT_SIZE * (((processedPos & lpMask) << lc) +
185*8996SAlok.Aggarwal@Sun.COM (dic[(dicPos == 0 ? dicBufSize : dicPos) - 1] >> (8 - lc))));
186*8996SAlok.Aggarwal@Sun.COM
187*8996SAlok.Aggarwal@Sun.COM if (state < kNumLitStates)
188*8996SAlok.Aggarwal@Sun.COM {
189*8996SAlok.Aggarwal@Sun.COM symbol = 1;
190*8996SAlok.Aggarwal@Sun.COM do { GET_BIT(prob + symbol, symbol) } while (symbol < 0x100);
191*8996SAlok.Aggarwal@Sun.COM }
192*8996SAlok.Aggarwal@Sun.COM else
193*8996SAlok.Aggarwal@Sun.COM {
194*8996SAlok.Aggarwal@Sun.COM unsigned matchByte = p->dic[(dicPos - rep0) + ((dicPos < rep0) ? dicBufSize : 0)];
195*8996SAlok.Aggarwal@Sun.COM unsigned offs = 0x100;
196*8996SAlok.Aggarwal@Sun.COM symbol = 1;
197*8996SAlok.Aggarwal@Sun.COM do
198*8996SAlok.Aggarwal@Sun.COM {
199*8996SAlok.Aggarwal@Sun.COM unsigned bit;
200*8996SAlok.Aggarwal@Sun.COM CLzmaProb *probLit;
201*8996SAlok.Aggarwal@Sun.COM matchByte <<= 1;
202*8996SAlok.Aggarwal@Sun.COM bit = (matchByte & offs);
203*8996SAlok.Aggarwal@Sun.COM probLit = prob + offs + bit + symbol;
204*8996SAlok.Aggarwal@Sun.COM GET_BIT2(probLit, symbol, offs &= ~bit, offs &= bit)
205*8996SAlok.Aggarwal@Sun.COM }
206*8996SAlok.Aggarwal@Sun.COM while (symbol < 0x100);
207*8996SAlok.Aggarwal@Sun.COM }
208*8996SAlok.Aggarwal@Sun.COM dic[dicPos++] = (Byte)symbol;
209*8996SAlok.Aggarwal@Sun.COM processedPos++;
210*8996SAlok.Aggarwal@Sun.COM
211*8996SAlok.Aggarwal@Sun.COM state = kLiteralNextStates[state];
212*8996SAlok.Aggarwal@Sun.COM /* if (state < 4) state = 0; else if (state < 10) state -= 3; else state -= 6; */
213*8996SAlok.Aggarwal@Sun.COM continue;
214*8996SAlok.Aggarwal@Sun.COM }
215*8996SAlok.Aggarwal@Sun.COM else
216*8996SAlok.Aggarwal@Sun.COM {
217*8996SAlok.Aggarwal@Sun.COM UPDATE_1(prob);
218*8996SAlok.Aggarwal@Sun.COM prob = probs + IsRep + state;
219*8996SAlok.Aggarwal@Sun.COM IF_BIT_0(prob)
220*8996SAlok.Aggarwal@Sun.COM {
221*8996SAlok.Aggarwal@Sun.COM UPDATE_0(prob);
222*8996SAlok.Aggarwal@Sun.COM state += kNumStates;
223*8996SAlok.Aggarwal@Sun.COM prob = probs + LenCoder;
224*8996SAlok.Aggarwal@Sun.COM }
225*8996SAlok.Aggarwal@Sun.COM else
226*8996SAlok.Aggarwal@Sun.COM {
227*8996SAlok.Aggarwal@Sun.COM UPDATE_1(prob);
228*8996SAlok.Aggarwal@Sun.COM if (checkDicSize == 0 && processedPos == 0)
229*8996SAlok.Aggarwal@Sun.COM return SZ_ERROR_DATA;
230*8996SAlok.Aggarwal@Sun.COM prob = probs + IsRepG0 + state;
231*8996SAlok.Aggarwal@Sun.COM IF_BIT_0(prob)
232*8996SAlok.Aggarwal@Sun.COM {
233*8996SAlok.Aggarwal@Sun.COM UPDATE_0(prob);
234*8996SAlok.Aggarwal@Sun.COM prob = probs + IsRep0Long + (state << kNumPosBitsMax) + posState;
235*8996SAlok.Aggarwal@Sun.COM IF_BIT_0(prob)
236*8996SAlok.Aggarwal@Sun.COM {
237*8996SAlok.Aggarwal@Sun.COM UPDATE_0(prob);
238*8996SAlok.Aggarwal@Sun.COM dic[dicPos] = dic[(dicPos - rep0) + ((dicPos < rep0) ? dicBufSize : 0)];
239*8996SAlok.Aggarwal@Sun.COM dicPos++;
240*8996SAlok.Aggarwal@Sun.COM processedPos++;
241*8996SAlok.Aggarwal@Sun.COM state = state < kNumLitStates ? 9 : 11;
242*8996SAlok.Aggarwal@Sun.COM continue;
243*8996SAlok.Aggarwal@Sun.COM }
244*8996SAlok.Aggarwal@Sun.COM UPDATE_1(prob);
245*8996SAlok.Aggarwal@Sun.COM }
246*8996SAlok.Aggarwal@Sun.COM else
247*8996SAlok.Aggarwal@Sun.COM {
248*8996SAlok.Aggarwal@Sun.COM UInt32 distance;
249*8996SAlok.Aggarwal@Sun.COM UPDATE_1(prob);
250*8996SAlok.Aggarwal@Sun.COM prob = probs + IsRepG1 + state;
251*8996SAlok.Aggarwal@Sun.COM IF_BIT_0(prob)
252*8996SAlok.Aggarwal@Sun.COM {
253*8996SAlok.Aggarwal@Sun.COM UPDATE_0(prob);
254*8996SAlok.Aggarwal@Sun.COM distance = rep1;
255*8996SAlok.Aggarwal@Sun.COM }
256*8996SAlok.Aggarwal@Sun.COM else
257*8996SAlok.Aggarwal@Sun.COM {
258*8996SAlok.Aggarwal@Sun.COM UPDATE_1(prob);
259*8996SAlok.Aggarwal@Sun.COM prob = probs + IsRepG2 + state;
260*8996SAlok.Aggarwal@Sun.COM IF_BIT_0(prob)
261*8996SAlok.Aggarwal@Sun.COM {
262*8996SAlok.Aggarwal@Sun.COM UPDATE_0(prob);
263*8996SAlok.Aggarwal@Sun.COM distance = rep2;
264*8996SAlok.Aggarwal@Sun.COM }
265*8996SAlok.Aggarwal@Sun.COM else
266*8996SAlok.Aggarwal@Sun.COM {
267*8996SAlok.Aggarwal@Sun.COM UPDATE_1(prob);
268*8996SAlok.Aggarwal@Sun.COM distance = rep3;
269*8996SAlok.Aggarwal@Sun.COM rep3 = rep2;
270*8996SAlok.Aggarwal@Sun.COM }
271*8996SAlok.Aggarwal@Sun.COM rep2 = rep1;
272*8996SAlok.Aggarwal@Sun.COM }
273*8996SAlok.Aggarwal@Sun.COM rep1 = rep0;
274*8996SAlok.Aggarwal@Sun.COM rep0 = distance;
275*8996SAlok.Aggarwal@Sun.COM }
276*8996SAlok.Aggarwal@Sun.COM state = state < kNumLitStates ? 8 : 11;
277*8996SAlok.Aggarwal@Sun.COM prob = probs + RepLenCoder;
278*8996SAlok.Aggarwal@Sun.COM }
279*8996SAlok.Aggarwal@Sun.COM {
280*8996SAlok.Aggarwal@Sun.COM unsigned limit, offset;
281*8996SAlok.Aggarwal@Sun.COM CLzmaProb *probLen = prob + LenChoice;
282*8996SAlok.Aggarwal@Sun.COM IF_BIT_0(probLen)
283*8996SAlok.Aggarwal@Sun.COM {
284*8996SAlok.Aggarwal@Sun.COM UPDATE_0(probLen);
285*8996SAlok.Aggarwal@Sun.COM probLen = prob + LenLow + (posState << kLenNumLowBits);
286*8996SAlok.Aggarwal@Sun.COM offset = 0;
287*8996SAlok.Aggarwal@Sun.COM limit = (1 << kLenNumLowBits);
288*8996SAlok.Aggarwal@Sun.COM }
289*8996SAlok.Aggarwal@Sun.COM else
290*8996SAlok.Aggarwal@Sun.COM {
291*8996SAlok.Aggarwal@Sun.COM UPDATE_1(probLen);
292*8996SAlok.Aggarwal@Sun.COM probLen = prob + LenChoice2;
293*8996SAlok.Aggarwal@Sun.COM IF_BIT_0(probLen)
294*8996SAlok.Aggarwal@Sun.COM {
295*8996SAlok.Aggarwal@Sun.COM UPDATE_0(probLen);
296*8996SAlok.Aggarwal@Sun.COM probLen = prob + LenMid + (posState << kLenNumMidBits);
297*8996SAlok.Aggarwal@Sun.COM offset = kLenNumLowSymbols;
298*8996SAlok.Aggarwal@Sun.COM limit = (1 << kLenNumMidBits);
299*8996SAlok.Aggarwal@Sun.COM }
300*8996SAlok.Aggarwal@Sun.COM else
301*8996SAlok.Aggarwal@Sun.COM {
302*8996SAlok.Aggarwal@Sun.COM UPDATE_1(probLen);
303*8996SAlok.Aggarwal@Sun.COM probLen = prob + LenHigh;
304*8996SAlok.Aggarwal@Sun.COM offset = kLenNumLowSymbols + kLenNumMidSymbols;
305*8996SAlok.Aggarwal@Sun.COM limit = (1 << kLenNumHighBits);
306*8996SAlok.Aggarwal@Sun.COM }
307*8996SAlok.Aggarwal@Sun.COM }
308*8996SAlok.Aggarwal@Sun.COM TREE_DECODE(probLen, limit, len);
309*8996SAlok.Aggarwal@Sun.COM len += offset;
310*8996SAlok.Aggarwal@Sun.COM }
311*8996SAlok.Aggarwal@Sun.COM
312*8996SAlok.Aggarwal@Sun.COM if (state >= kNumStates)
313*8996SAlok.Aggarwal@Sun.COM {
314*8996SAlok.Aggarwal@Sun.COM UInt32 distance;
315*8996SAlok.Aggarwal@Sun.COM prob = probs + PosSlot +
316*8996SAlok.Aggarwal@Sun.COM ((len < kNumLenToPosStates ? len : kNumLenToPosStates - 1) << kNumPosSlotBits);
317*8996SAlok.Aggarwal@Sun.COM TREE_6_DECODE(prob, distance);
318*8996SAlok.Aggarwal@Sun.COM if (distance >= kStartPosModelIndex)
319*8996SAlok.Aggarwal@Sun.COM {
320*8996SAlok.Aggarwal@Sun.COM unsigned posSlot = (unsigned)distance;
321*8996SAlok.Aggarwal@Sun.COM int numDirectBits = (int)(((distance >> 1) - 1));
322*8996SAlok.Aggarwal@Sun.COM distance = (2 | (distance & 1));
323*8996SAlok.Aggarwal@Sun.COM if (posSlot < kEndPosModelIndex)
324*8996SAlok.Aggarwal@Sun.COM {
325*8996SAlok.Aggarwal@Sun.COM distance <<= numDirectBits;
326*8996SAlok.Aggarwal@Sun.COM prob = probs + SpecPos + distance - posSlot - 1;
327*8996SAlok.Aggarwal@Sun.COM {
328*8996SAlok.Aggarwal@Sun.COM UInt32 mask = 1;
329*8996SAlok.Aggarwal@Sun.COM unsigned i = 1;
330*8996SAlok.Aggarwal@Sun.COM do
331*8996SAlok.Aggarwal@Sun.COM {
332*8996SAlok.Aggarwal@Sun.COM GET_BIT2(prob + i, i, ; , distance |= mask);
333*8996SAlok.Aggarwal@Sun.COM mask <<= 1;
334*8996SAlok.Aggarwal@Sun.COM }
335*8996SAlok.Aggarwal@Sun.COM while (--numDirectBits != 0);
336*8996SAlok.Aggarwal@Sun.COM }
337*8996SAlok.Aggarwal@Sun.COM }
338*8996SAlok.Aggarwal@Sun.COM else
339*8996SAlok.Aggarwal@Sun.COM {
340*8996SAlok.Aggarwal@Sun.COM numDirectBits -= kNumAlignBits;
341*8996SAlok.Aggarwal@Sun.COM do
342*8996SAlok.Aggarwal@Sun.COM {
343*8996SAlok.Aggarwal@Sun.COM NORMALIZE
344*8996SAlok.Aggarwal@Sun.COM range >>= 1;
345*8996SAlok.Aggarwal@Sun.COM
346*8996SAlok.Aggarwal@Sun.COM {
347*8996SAlok.Aggarwal@Sun.COM UInt32 t;
348*8996SAlok.Aggarwal@Sun.COM code -= range;
349*8996SAlok.Aggarwal@Sun.COM t = (0 - ((UInt32)code >> 31)); /* (UInt32)((Int32)code >> 31) */
350*8996SAlok.Aggarwal@Sun.COM distance = (distance << 1) + (t + 1);
351*8996SAlok.Aggarwal@Sun.COM code += range & t;
352*8996SAlok.Aggarwal@Sun.COM }
353*8996SAlok.Aggarwal@Sun.COM /*
354*8996SAlok.Aggarwal@Sun.COM distance <<= 1;
355*8996SAlok.Aggarwal@Sun.COM if (code >= range)
356*8996SAlok.Aggarwal@Sun.COM {
357*8996SAlok.Aggarwal@Sun.COM code -= range;
358*8996SAlok.Aggarwal@Sun.COM distance |= 1;
359*8996SAlok.Aggarwal@Sun.COM }
360*8996SAlok.Aggarwal@Sun.COM */
361*8996SAlok.Aggarwal@Sun.COM }
362*8996SAlok.Aggarwal@Sun.COM while (--numDirectBits != 0);
363*8996SAlok.Aggarwal@Sun.COM prob = probs + Align;
364*8996SAlok.Aggarwal@Sun.COM distance <<= kNumAlignBits;
365*8996SAlok.Aggarwal@Sun.COM {
366*8996SAlok.Aggarwal@Sun.COM unsigned i = 1;
367*8996SAlok.Aggarwal@Sun.COM GET_BIT2(prob + i, i, ; , distance |= 1);
368*8996SAlok.Aggarwal@Sun.COM GET_BIT2(prob + i, i, ; , distance |= 2);
369*8996SAlok.Aggarwal@Sun.COM GET_BIT2(prob + i, i, ; , distance |= 4);
370*8996SAlok.Aggarwal@Sun.COM GET_BIT2(prob + i, i, ; , distance |= 8);
371*8996SAlok.Aggarwal@Sun.COM }
372*8996SAlok.Aggarwal@Sun.COM if (distance == (UInt32)0xFFFFFFFF)
373*8996SAlok.Aggarwal@Sun.COM {
374*8996SAlok.Aggarwal@Sun.COM len += kMatchSpecLenStart;
375*8996SAlok.Aggarwal@Sun.COM state -= kNumStates;
376*8996SAlok.Aggarwal@Sun.COM break;
377*8996SAlok.Aggarwal@Sun.COM }
378*8996SAlok.Aggarwal@Sun.COM }
379*8996SAlok.Aggarwal@Sun.COM }
380*8996SAlok.Aggarwal@Sun.COM rep3 = rep2;
381*8996SAlok.Aggarwal@Sun.COM rep2 = rep1;
382*8996SAlok.Aggarwal@Sun.COM rep1 = rep0;
383*8996SAlok.Aggarwal@Sun.COM rep0 = distance + 1;
384*8996SAlok.Aggarwal@Sun.COM if (checkDicSize == 0)
385*8996SAlok.Aggarwal@Sun.COM {
386*8996SAlok.Aggarwal@Sun.COM if (distance >= processedPos)
387*8996SAlok.Aggarwal@Sun.COM return SZ_ERROR_DATA;
388*8996SAlok.Aggarwal@Sun.COM }
389*8996SAlok.Aggarwal@Sun.COM else if (distance >= checkDicSize)
390*8996SAlok.Aggarwal@Sun.COM return SZ_ERROR_DATA;
391*8996SAlok.Aggarwal@Sun.COM state = (state < kNumStates + kNumLitStates) ? kNumLitStates : kNumLitStates + 3;
392*8996SAlok.Aggarwal@Sun.COM /* state = kLiteralNextStates[state]; */
393*8996SAlok.Aggarwal@Sun.COM }
394*8996SAlok.Aggarwal@Sun.COM
395*8996SAlok.Aggarwal@Sun.COM len += kMatchMinLen;
396*8996SAlok.Aggarwal@Sun.COM
397*8996SAlok.Aggarwal@Sun.COM if (limit == dicPos)
398*8996SAlok.Aggarwal@Sun.COM return SZ_ERROR_DATA;
399*8996SAlok.Aggarwal@Sun.COM {
400*8996SAlok.Aggarwal@Sun.COM SizeT rem = limit - dicPos;
401*8996SAlok.Aggarwal@Sun.COM unsigned curLen = ((rem < len) ? (unsigned)rem : len);
402*8996SAlok.Aggarwal@Sun.COM SizeT pos = (dicPos - rep0) + ((dicPos < rep0) ? dicBufSize : 0);
403*8996SAlok.Aggarwal@Sun.COM
404*8996SAlok.Aggarwal@Sun.COM processedPos += curLen;
405*8996SAlok.Aggarwal@Sun.COM
406*8996SAlok.Aggarwal@Sun.COM len -= curLen;
407*8996SAlok.Aggarwal@Sun.COM if (pos + curLen <= dicBufSize)
408*8996SAlok.Aggarwal@Sun.COM {
409*8996SAlok.Aggarwal@Sun.COM Byte *dest = dic + dicPos;
410*8996SAlok.Aggarwal@Sun.COM ptrdiff_t src = (ptrdiff_t)pos - (ptrdiff_t)dicPos;
411*8996SAlok.Aggarwal@Sun.COM const Byte *lim = dest + curLen;
412*8996SAlok.Aggarwal@Sun.COM dicPos += curLen;
413*8996SAlok.Aggarwal@Sun.COM do
414*8996SAlok.Aggarwal@Sun.COM *(dest) = (Byte)*(dest + src);
415*8996SAlok.Aggarwal@Sun.COM while (++dest != lim);
416*8996SAlok.Aggarwal@Sun.COM }
417*8996SAlok.Aggarwal@Sun.COM else
418*8996SAlok.Aggarwal@Sun.COM {
419*8996SAlok.Aggarwal@Sun.COM do
420*8996SAlok.Aggarwal@Sun.COM {
421*8996SAlok.Aggarwal@Sun.COM dic[dicPos++] = dic[pos];
422*8996SAlok.Aggarwal@Sun.COM if (++pos == dicBufSize)
423*8996SAlok.Aggarwal@Sun.COM pos = 0;
424*8996SAlok.Aggarwal@Sun.COM }
425*8996SAlok.Aggarwal@Sun.COM while (--curLen != 0);
426*8996SAlok.Aggarwal@Sun.COM }
427*8996SAlok.Aggarwal@Sun.COM }
428*8996SAlok.Aggarwal@Sun.COM }
429*8996SAlok.Aggarwal@Sun.COM }
430*8996SAlok.Aggarwal@Sun.COM while (dicPos < limit && buf < bufLimit);
431*8996SAlok.Aggarwal@Sun.COM NORMALIZE;
432*8996SAlok.Aggarwal@Sun.COM p->buf = buf;
433*8996SAlok.Aggarwal@Sun.COM p->range = range;
434*8996SAlok.Aggarwal@Sun.COM p->code = code;
435*8996SAlok.Aggarwal@Sun.COM p->remainLen = len;
436*8996SAlok.Aggarwal@Sun.COM p->dicPos = dicPos;
437*8996SAlok.Aggarwal@Sun.COM p->processedPos = processedPos;
438*8996SAlok.Aggarwal@Sun.COM p->reps[0] = rep0;
439*8996SAlok.Aggarwal@Sun.COM p->reps[1] = rep1;
440*8996SAlok.Aggarwal@Sun.COM p->reps[2] = rep2;
441*8996SAlok.Aggarwal@Sun.COM p->reps[3] = rep3;
442*8996SAlok.Aggarwal@Sun.COM p->state = state;
443*8996SAlok.Aggarwal@Sun.COM
444*8996SAlok.Aggarwal@Sun.COM return SZ_OK;
445*8996SAlok.Aggarwal@Sun.COM }
446*8996SAlok.Aggarwal@Sun.COM
LzmaDec_WriteRem(CLzmaDec * p,SizeT limit)447*8996SAlok.Aggarwal@Sun.COM static void MY_FAST_CALL LzmaDec_WriteRem(CLzmaDec *p, SizeT limit)
448*8996SAlok.Aggarwal@Sun.COM {
449*8996SAlok.Aggarwal@Sun.COM if (p->remainLen != 0 && p->remainLen < kMatchSpecLenStart)
450*8996SAlok.Aggarwal@Sun.COM {
451*8996SAlok.Aggarwal@Sun.COM Byte *dic = p->dic;
452*8996SAlok.Aggarwal@Sun.COM SizeT dicPos = p->dicPos;
453*8996SAlok.Aggarwal@Sun.COM SizeT dicBufSize = p->dicBufSize;
454*8996SAlok.Aggarwal@Sun.COM unsigned len = p->remainLen;
455*8996SAlok.Aggarwal@Sun.COM UInt32 rep0 = p->reps[0];
456*8996SAlok.Aggarwal@Sun.COM if (limit - dicPos < len)
457*8996SAlok.Aggarwal@Sun.COM len = (unsigned)(limit - dicPos);
458*8996SAlok.Aggarwal@Sun.COM
459*8996SAlok.Aggarwal@Sun.COM if (p->checkDicSize == 0 && p->prop.dicSize - p->processedPos <= len)
460*8996SAlok.Aggarwal@Sun.COM p->checkDicSize = p->prop.dicSize;
461*8996SAlok.Aggarwal@Sun.COM
462*8996SAlok.Aggarwal@Sun.COM p->processedPos += len;
463*8996SAlok.Aggarwal@Sun.COM p->remainLen -= len;
464*8996SAlok.Aggarwal@Sun.COM while (len-- != 0)
465*8996SAlok.Aggarwal@Sun.COM {
466*8996SAlok.Aggarwal@Sun.COM dic[dicPos] = dic[(dicPos - rep0) + ((dicPos < rep0) ? dicBufSize : 0)];
467*8996SAlok.Aggarwal@Sun.COM dicPos++;
468*8996SAlok.Aggarwal@Sun.COM }
469*8996SAlok.Aggarwal@Sun.COM p->dicPos = dicPos;
470*8996SAlok.Aggarwal@Sun.COM }
471*8996SAlok.Aggarwal@Sun.COM }
472*8996SAlok.Aggarwal@Sun.COM
LzmaDec_DecodeReal2(CLzmaDec * p,SizeT limit,const Byte * bufLimit)473*8996SAlok.Aggarwal@Sun.COM static int MY_FAST_CALL LzmaDec_DecodeReal2(CLzmaDec *p, SizeT limit, const Byte *bufLimit)
474*8996SAlok.Aggarwal@Sun.COM {
475*8996SAlok.Aggarwal@Sun.COM do
476*8996SAlok.Aggarwal@Sun.COM {
477*8996SAlok.Aggarwal@Sun.COM SizeT limit2 = limit;
478*8996SAlok.Aggarwal@Sun.COM if (p->checkDicSize == 0)
479*8996SAlok.Aggarwal@Sun.COM {
480*8996SAlok.Aggarwal@Sun.COM UInt32 rem = p->prop.dicSize - p->processedPos;
481*8996SAlok.Aggarwal@Sun.COM if (limit - p->dicPos > rem)
482*8996SAlok.Aggarwal@Sun.COM limit2 = p->dicPos + rem;
483*8996SAlok.Aggarwal@Sun.COM }
484*8996SAlok.Aggarwal@Sun.COM RINOK(LzmaDec_DecodeReal(p, limit2, bufLimit));
485*8996SAlok.Aggarwal@Sun.COM if (p->processedPos >= p->prop.dicSize)
486*8996SAlok.Aggarwal@Sun.COM p->checkDicSize = p->prop.dicSize;
487*8996SAlok.Aggarwal@Sun.COM LzmaDec_WriteRem(p, limit);
488*8996SAlok.Aggarwal@Sun.COM }
489*8996SAlok.Aggarwal@Sun.COM while (p->dicPos < limit && p->buf < bufLimit && p->remainLen < kMatchSpecLenStart);
490*8996SAlok.Aggarwal@Sun.COM
491*8996SAlok.Aggarwal@Sun.COM if (p->remainLen > kMatchSpecLenStart)
492*8996SAlok.Aggarwal@Sun.COM {
493*8996SAlok.Aggarwal@Sun.COM p->remainLen = kMatchSpecLenStart;
494*8996SAlok.Aggarwal@Sun.COM }
495*8996SAlok.Aggarwal@Sun.COM return 0;
496*8996SAlok.Aggarwal@Sun.COM }
497*8996SAlok.Aggarwal@Sun.COM
498*8996SAlok.Aggarwal@Sun.COM typedef enum
499*8996SAlok.Aggarwal@Sun.COM {
500*8996SAlok.Aggarwal@Sun.COM DUMMY_ERROR, /* unexpected end of input stream */
501*8996SAlok.Aggarwal@Sun.COM DUMMY_LIT,
502*8996SAlok.Aggarwal@Sun.COM DUMMY_MATCH,
503*8996SAlok.Aggarwal@Sun.COM DUMMY_REP
504*8996SAlok.Aggarwal@Sun.COM } ELzmaDummy;
505*8996SAlok.Aggarwal@Sun.COM
LzmaDec_TryDummy(const CLzmaDec * p,const Byte * buf,SizeT inSize)506*8996SAlok.Aggarwal@Sun.COM static ELzmaDummy LzmaDec_TryDummy(const CLzmaDec *p, const Byte *buf, SizeT inSize)
507*8996SAlok.Aggarwal@Sun.COM {
508*8996SAlok.Aggarwal@Sun.COM UInt32 range = p->range;
509*8996SAlok.Aggarwal@Sun.COM UInt32 code = p->code;
510*8996SAlok.Aggarwal@Sun.COM const Byte *bufLimit = buf + inSize;
511*8996SAlok.Aggarwal@Sun.COM CLzmaProb *probs = p->probs;
512*8996SAlok.Aggarwal@Sun.COM unsigned state = p->state;
513*8996SAlok.Aggarwal@Sun.COM ELzmaDummy res;
514*8996SAlok.Aggarwal@Sun.COM
515*8996SAlok.Aggarwal@Sun.COM {
516*8996SAlok.Aggarwal@Sun.COM CLzmaProb *prob;
517*8996SAlok.Aggarwal@Sun.COM UInt32 bound;
518*8996SAlok.Aggarwal@Sun.COM unsigned ttt;
519*8996SAlok.Aggarwal@Sun.COM unsigned posState = (p->processedPos) & ((1 << p->prop.pb) - 1);
520*8996SAlok.Aggarwal@Sun.COM
521*8996SAlok.Aggarwal@Sun.COM prob = probs + IsMatch + (state << kNumPosBitsMax) + posState;
522*8996SAlok.Aggarwal@Sun.COM IF_BIT_0_CHECK(prob)
523*8996SAlok.Aggarwal@Sun.COM {
524*8996SAlok.Aggarwal@Sun.COM UPDATE_0_CHECK
525*8996SAlok.Aggarwal@Sun.COM
526*8996SAlok.Aggarwal@Sun.COM /* if (bufLimit - buf >= 7) return DUMMY_LIT; */
527*8996SAlok.Aggarwal@Sun.COM
528*8996SAlok.Aggarwal@Sun.COM prob = probs + Literal;
529*8996SAlok.Aggarwal@Sun.COM if (p->checkDicSize != 0 || p->processedPos != 0)
530*8996SAlok.Aggarwal@Sun.COM prob += (LZMA_LIT_SIZE *
531*8996SAlok.Aggarwal@Sun.COM ((((p->processedPos) & ((1 << (p->prop.lp)) - 1)) << p->prop.lc) +
532*8996SAlok.Aggarwal@Sun.COM (p->dic[(p->dicPos == 0 ? p->dicBufSize : p->dicPos) - 1] >> (8 - p->prop.lc))));
533*8996SAlok.Aggarwal@Sun.COM
534*8996SAlok.Aggarwal@Sun.COM if (state < kNumLitStates)
535*8996SAlok.Aggarwal@Sun.COM {
536*8996SAlok.Aggarwal@Sun.COM unsigned symbol = 1;
537*8996SAlok.Aggarwal@Sun.COM do { GET_BIT_CHECK(prob + symbol, symbol) } while (symbol < 0x100);
538*8996SAlok.Aggarwal@Sun.COM }
539*8996SAlok.Aggarwal@Sun.COM else
540*8996SAlok.Aggarwal@Sun.COM {
541*8996SAlok.Aggarwal@Sun.COM unsigned matchByte = p->dic[p->dicPos - p->reps[0] +
542*8996SAlok.Aggarwal@Sun.COM ((p->dicPos < p->reps[0]) ? p->dicBufSize : 0)];
543*8996SAlok.Aggarwal@Sun.COM unsigned offs = 0x100;
544*8996SAlok.Aggarwal@Sun.COM unsigned symbol = 1;
545*8996SAlok.Aggarwal@Sun.COM do
546*8996SAlok.Aggarwal@Sun.COM {
547*8996SAlok.Aggarwal@Sun.COM unsigned bit;
548*8996SAlok.Aggarwal@Sun.COM CLzmaProb *probLit;
549*8996SAlok.Aggarwal@Sun.COM matchByte <<= 1;
550*8996SAlok.Aggarwal@Sun.COM bit = (matchByte & offs);
551*8996SAlok.Aggarwal@Sun.COM probLit = prob + offs + bit + symbol;
552*8996SAlok.Aggarwal@Sun.COM GET_BIT2_CHECK(probLit, symbol, offs &= ~bit, offs &= bit)
553*8996SAlok.Aggarwal@Sun.COM }
554*8996SAlok.Aggarwal@Sun.COM while (symbol < 0x100);
555*8996SAlok.Aggarwal@Sun.COM }
556*8996SAlok.Aggarwal@Sun.COM res = DUMMY_LIT;
557*8996SAlok.Aggarwal@Sun.COM }
558*8996SAlok.Aggarwal@Sun.COM else
559*8996SAlok.Aggarwal@Sun.COM {
560*8996SAlok.Aggarwal@Sun.COM unsigned len;
561*8996SAlok.Aggarwal@Sun.COM UPDATE_1_CHECK;
562*8996SAlok.Aggarwal@Sun.COM
563*8996SAlok.Aggarwal@Sun.COM prob = probs + IsRep + state;
564*8996SAlok.Aggarwal@Sun.COM IF_BIT_0_CHECK(prob)
565*8996SAlok.Aggarwal@Sun.COM {
566*8996SAlok.Aggarwal@Sun.COM UPDATE_0_CHECK;
567*8996SAlok.Aggarwal@Sun.COM state = 0;
568*8996SAlok.Aggarwal@Sun.COM prob = probs + LenCoder;
569*8996SAlok.Aggarwal@Sun.COM res = DUMMY_MATCH;
570*8996SAlok.Aggarwal@Sun.COM }
571*8996SAlok.Aggarwal@Sun.COM else
572*8996SAlok.Aggarwal@Sun.COM {
573*8996SAlok.Aggarwal@Sun.COM UPDATE_1_CHECK;
574*8996SAlok.Aggarwal@Sun.COM res = DUMMY_REP;
575*8996SAlok.Aggarwal@Sun.COM prob = probs + IsRepG0 + state;
576*8996SAlok.Aggarwal@Sun.COM IF_BIT_0_CHECK(prob)
577*8996SAlok.Aggarwal@Sun.COM {
578*8996SAlok.Aggarwal@Sun.COM UPDATE_0_CHECK;
579*8996SAlok.Aggarwal@Sun.COM prob = probs + IsRep0Long + (state << kNumPosBitsMax) + posState;
580*8996SAlok.Aggarwal@Sun.COM IF_BIT_0_CHECK(prob)
581*8996SAlok.Aggarwal@Sun.COM {
582*8996SAlok.Aggarwal@Sun.COM UPDATE_0_CHECK;
583*8996SAlok.Aggarwal@Sun.COM NORMALIZE_CHECK;
584*8996SAlok.Aggarwal@Sun.COM return DUMMY_REP;
585*8996SAlok.Aggarwal@Sun.COM }
586*8996SAlok.Aggarwal@Sun.COM else
587*8996SAlok.Aggarwal@Sun.COM {
588*8996SAlok.Aggarwal@Sun.COM UPDATE_1_CHECK;
589*8996SAlok.Aggarwal@Sun.COM }
590*8996SAlok.Aggarwal@Sun.COM }
591*8996SAlok.Aggarwal@Sun.COM else
592*8996SAlok.Aggarwal@Sun.COM {
593*8996SAlok.Aggarwal@Sun.COM UPDATE_1_CHECK;
594*8996SAlok.Aggarwal@Sun.COM prob = probs + IsRepG1 + state;
595*8996SAlok.Aggarwal@Sun.COM IF_BIT_0_CHECK(prob)
596*8996SAlok.Aggarwal@Sun.COM {
597*8996SAlok.Aggarwal@Sun.COM UPDATE_0_CHECK;
598*8996SAlok.Aggarwal@Sun.COM }
599*8996SAlok.Aggarwal@Sun.COM else
600*8996SAlok.Aggarwal@Sun.COM {
601*8996SAlok.Aggarwal@Sun.COM UPDATE_1_CHECK;
602*8996SAlok.Aggarwal@Sun.COM prob = probs + IsRepG2 + state;
603*8996SAlok.Aggarwal@Sun.COM IF_BIT_0_CHECK(prob)
604*8996SAlok.Aggarwal@Sun.COM {
605*8996SAlok.Aggarwal@Sun.COM UPDATE_0_CHECK;
606*8996SAlok.Aggarwal@Sun.COM }
607*8996SAlok.Aggarwal@Sun.COM else
608*8996SAlok.Aggarwal@Sun.COM {
609*8996SAlok.Aggarwal@Sun.COM UPDATE_1_CHECK;
610*8996SAlok.Aggarwal@Sun.COM }
611*8996SAlok.Aggarwal@Sun.COM }
612*8996SAlok.Aggarwal@Sun.COM }
613*8996SAlok.Aggarwal@Sun.COM state = kNumStates;
614*8996SAlok.Aggarwal@Sun.COM prob = probs + RepLenCoder;
615*8996SAlok.Aggarwal@Sun.COM }
616*8996SAlok.Aggarwal@Sun.COM {
617*8996SAlok.Aggarwal@Sun.COM unsigned limit, offset;
618*8996SAlok.Aggarwal@Sun.COM CLzmaProb *probLen = prob + LenChoice;
619*8996SAlok.Aggarwal@Sun.COM IF_BIT_0_CHECK(probLen)
620*8996SAlok.Aggarwal@Sun.COM {
621*8996SAlok.Aggarwal@Sun.COM UPDATE_0_CHECK;
622*8996SAlok.Aggarwal@Sun.COM probLen = prob + LenLow + (posState << kLenNumLowBits);
623*8996SAlok.Aggarwal@Sun.COM offset = 0;
624*8996SAlok.Aggarwal@Sun.COM limit = 1 << kLenNumLowBits;
625*8996SAlok.Aggarwal@Sun.COM }
626*8996SAlok.Aggarwal@Sun.COM else
627*8996SAlok.Aggarwal@Sun.COM {
628*8996SAlok.Aggarwal@Sun.COM UPDATE_1_CHECK;
629*8996SAlok.Aggarwal@Sun.COM probLen = prob + LenChoice2;
630*8996SAlok.Aggarwal@Sun.COM IF_BIT_0_CHECK(probLen)
631*8996SAlok.Aggarwal@Sun.COM {
632*8996SAlok.Aggarwal@Sun.COM UPDATE_0_CHECK;
633*8996SAlok.Aggarwal@Sun.COM probLen = prob + LenMid + (posState << kLenNumMidBits);
634*8996SAlok.Aggarwal@Sun.COM offset = kLenNumLowSymbols;
635*8996SAlok.Aggarwal@Sun.COM limit = 1 << kLenNumMidBits;
636*8996SAlok.Aggarwal@Sun.COM }
637*8996SAlok.Aggarwal@Sun.COM else
638*8996SAlok.Aggarwal@Sun.COM {
639*8996SAlok.Aggarwal@Sun.COM UPDATE_1_CHECK;
640*8996SAlok.Aggarwal@Sun.COM probLen = prob + LenHigh;
641*8996SAlok.Aggarwal@Sun.COM offset = kLenNumLowSymbols + kLenNumMidSymbols;
642*8996SAlok.Aggarwal@Sun.COM limit = 1 << kLenNumHighBits;
643*8996SAlok.Aggarwal@Sun.COM }
644*8996SAlok.Aggarwal@Sun.COM }
645*8996SAlok.Aggarwal@Sun.COM TREE_DECODE_CHECK(probLen, limit, len);
646*8996SAlok.Aggarwal@Sun.COM len += offset;
647*8996SAlok.Aggarwal@Sun.COM }
648*8996SAlok.Aggarwal@Sun.COM
649*8996SAlok.Aggarwal@Sun.COM if (state < 4)
650*8996SAlok.Aggarwal@Sun.COM {
651*8996SAlok.Aggarwal@Sun.COM unsigned posSlot;
652*8996SAlok.Aggarwal@Sun.COM prob = probs + PosSlot +
653*8996SAlok.Aggarwal@Sun.COM ((len < kNumLenToPosStates ? len : kNumLenToPosStates - 1) <<
654*8996SAlok.Aggarwal@Sun.COM kNumPosSlotBits);
655*8996SAlok.Aggarwal@Sun.COM TREE_DECODE_CHECK(prob, 1 << kNumPosSlotBits, posSlot);
656*8996SAlok.Aggarwal@Sun.COM if (posSlot >= kStartPosModelIndex)
657*8996SAlok.Aggarwal@Sun.COM {
658*8996SAlok.Aggarwal@Sun.COM int numDirectBits = ((posSlot >> 1) - 1);
659*8996SAlok.Aggarwal@Sun.COM
660*8996SAlok.Aggarwal@Sun.COM /* if (bufLimit - buf >= 8) return DUMMY_MATCH; */
661*8996SAlok.Aggarwal@Sun.COM
662*8996SAlok.Aggarwal@Sun.COM if (posSlot < kEndPosModelIndex)
663*8996SAlok.Aggarwal@Sun.COM {
664*8996SAlok.Aggarwal@Sun.COM prob = probs + SpecPos + ((2 | (posSlot & 1)) << numDirectBits) - posSlot - 1;
665*8996SAlok.Aggarwal@Sun.COM }
666*8996SAlok.Aggarwal@Sun.COM else
667*8996SAlok.Aggarwal@Sun.COM {
668*8996SAlok.Aggarwal@Sun.COM numDirectBits -= kNumAlignBits;
669*8996SAlok.Aggarwal@Sun.COM do
670*8996SAlok.Aggarwal@Sun.COM {
671*8996SAlok.Aggarwal@Sun.COM NORMALIZE_CHECK
672*8996SAlok.Aggarwal@Sun.COM range >>= 1;
673*8996SAlok.Aggarwal@Sun.COM code -= range & (((code - range) >> 31) - 1);
674*8996SAlok.Aggarwal@Sun.COM /* if (code >= range) code -= range; */
675*8996SAlok.Aggarwal@Sun.COM }
676*8996SAlok.Aggarwal@Sun.COM while (--numDirectBits != 0);
677*8996SAlok.Aggarwal@Sun.COM prob = probs + Align;
678*8996SAlok.Aggarwal@Sun.COM numDirectBits = kNumAlignBits;
679*8996SAlok.Aggarwal@Sun.COM }
680*8996SAlok.Aggarwal@Sun.COM {
681*8996SAlok.Aggarwal@Sun.COM unsigned i = 1;
682*8996SAlok.Aggarwal@Sun.COM do
683*8996SAlok.Aggarwal@Sun.COM {
684*8996SAlok.Aggarwal@Sun.COM GET_BIT_CHECK(prob + i, i);
685*8996SAlok.Aggarwal@Sun.COM }
686*8996SAlok.Aggarwal@Sun.COM while (--numDirectBits != 0);
687*8996SAlok.Aggarwal@Sun.COM }
688*8996SAlok.Aggarwal@Sun.COM }
689*8996SAlok.Aggarwal@Sun.COM }
690*8996SAlok.Aggarwal@Sun.COM }
691*8996SAlok.Aggarwal@Sun.COM }
692*8996SAlok.Aggarwal@Sun.COM NORMALIZE_CHECK;
693*8996SAlok.Aggarwal@Sun.COM return res;
694*8996SAlok.Aggarwal@Sun.COM }
695*8996SAlok.Aggarwal@Sun.COM
696*8996SAlok.Aggarwal@Sun.COM
LzmaDec_InitRc(CLzmaDec * p,const Byte * data)697*8996SAlok.Aggarwal@Sun.COM static void LzmaDec_InitRc(CLzmaDec *p, const Byte *data)
698*8996SAlok.Aggarwal@Sun.COM {
699*8996SAlok.Aggarwal@Sun.COM p->code = ((UInt32)data[1] << 24) | ((UInt32)data[2] << 16) | ((UInt32)data[3] << 8) | ((UInt32)data[4]);
700*8996SAlok.Aggarwal@Sun.COM p->range = 0xFFFFFFFF;
701*8996SAlok.Aggarwal@Sun.COM p->needFlush = 0;
702*8996SAlok.Aggarwal@Sun.COM }
703*8996SAlok.Aggarwal@Sun.COM
LzmaDec_InitDicAndState(CLzmaDec * p,Bool initDic,Bool initState)704*8996SAlok.Aggarwal@Sun.COM void LzmaDec_InitDicAndState(CLzmaDec *p, Bool initDic, Bool initState)
705*8996SAlok.Aggarwal@Sun.COM {
706*8996SAlok.Aggarwal@Sun.COM p->needFlush = 1;
707*8996SAlok.Aggarwal@Sun.COM p->remainLen = 0;
708*8996SAlok.Aggarwal@Sun.COM p->tempBufSize = 0;
709*8996SAlok.Aggarwal@Sun.COM
710*8996SAlok.Aggarwal@Sun.COM if (initDic)
711*8996SAlok.Aggarwal@Sun.COM {
712*8996SAlok.Aggarwal@Sun.COM p->processedPos = 0;
713*8996SAlok.Aggarwal@Sun.COM p->checkDicSize = 0;
714*8996SAlok.Aggarwal@Sun.COM p->needInitState = 1;
715*8996SAlok.Aggarwal@Sun.COM }
716*8996SAlok.Aggarwal@Sun.COM if (initState)
717*8996SAlok.Aggarwal@Sun.COM p->needInitState = 1;
718*8996SAlok.Aggarwal@Sun.COM }
719*8996SAlok.Aggarwal@Sun.COM
LzmaDec_Init(CLzmaDec * p)720*8996SAlok.Aggarwal@Sun.COM void LzmaDec_Init(CLzmaDec *p)
721*8996SAlok.Aggarwal@Sun.COM {
722*8996SAlok.Aggarwal@Sun.COM p->dicPos = 0;
723*8996SAlok.Aggarwal@Sun.COM LzmaDec_InitDicAndState(p, True, True);
724*8996SAlok.Aggarwal@Sun.COM }
725*8996SAlok.Aggarwal@Sun.COM
LzmaDec_InitStateReal(CLzmaDec * p)726*8996SAlok.Aggarwal@Sun.COM static void LzmaDec_InitStateReal(CLzmaDec *p)
727*8996SAlok.Aggarwal@Sun.COM {
728*8996SAlok.Aggarwal@Sun.COM UInt32 numProbs = Literal + ((UInt32)LZMA_LIT_SIZE << (p->prop.lc + p->prop.lp));
729*8996SAlok.Aggarwal@Sun.COM UInt32 i;
730*8996SAlok.Aggarwal@Sun.COM CLzmaProb *probs = p->probs;
731*8996SAlok.Aggarwal@Sun.COM for (i = 0; i < numProbs; i++)
732*8996SAlok.Aggarwal@Sun.COM probs[i] = kBitModelTotal >> 1;
733*8996SAlok.Aggarwal@Sun.COM p->reps[0] = p->reps[1] = p->reps[2] = p->reps[3] = 1;
734*8996SAlok.Aggarwal@Sun.COM p->state = 0;
735*8996SAlok.Aggarwal@Sun.COM p->needInitState = 0;
736*8996SAlok.Aggarwal@Sun.COM }
737*8996SAlok.Aggarwal@Sun.COM
LzmaDec_DecodeToDic(CLzmaDec * p,SizeT dicLimit,const Byte * src,SizeT * srcLen,ELzmaFinishMode finishMode,ELzmaStatus * status)738*8996SAlok.Aggarwal@Sun.COM SRes LzmaDec_DecodeToDic(CLzmaDec *p, SizeT dicLimit, const Byte *src, SizeT *srcLen,
739*8996SAlok.Aggarwal@Sun.COM ELzmaFinishMode finishMode, ELzmaStatus *status)
740*8996SAlok.Aggarwal@Sun.COM {
741*8996SAlok.Aggarwal@Sun.COM SizeT inSize = *srcLen;
742*8996SAlok.Aggarwal@Sun.COM (*srcLen) = 0;
743*8996SAlok.Aggarwal@Sun.COM LzmaDec_WriteRem(p, dicLimit);
744*8996SAlok.Aggarwal@Sun.COM
745*8996SAlok.Aggarwal@Sun.COM *status = LZMA_STATUS_NOT_SPECIFIED;
746*8996SAlok.Aggarwal@Sun.COM
747*8996SAlok.Aggarwal@Sun.COM while (p->remainLen != kMatchSpecLenStart)
748*8996SAlok.Aggarwal@Sun.COM {
749*8996SAlok.Aggarwal@Sun.COM int checkEndMarkNow;
750*8996SAlok.Aggarwal@Sun.COM
751*8996SAlok.Aggarwal@Sun.COM if (p->needFlush != 0)
752*8996SAlok.Aggarwal@Sun.COM {
753*8996SAlok.Aggarwal@Sun.COM for (; inSize > 0 && p->tempBufSize < RC_INIT_SIZE; (*srcLen)++, inSize--)
754*8996SAlok.Aggarwal@Sun.COM p->tempBuf[p->tempBufSize++] = *src++;
755*8996SAlok.Aggarwal@Sun.COM if (p->tempBufSize < RC_INIT_SIZE)
756*8996SAlok.Aggarwal@Sun.COM {
757*8996SAlok.Aggarwal@Sun.COM *status = LZMA_STATUS_NEEDS_MORE_INPUT;
758*8996SAlok.Aggarwal@Sun.COM return SZ_OK;
759*8996SAlok.Aggarwal@Sun.COM }
760*8996SAlok.Aggarwal@Sun.COM if (p->tempBuf[0] != 0)
761*8996SAlok.Aggarwal@Sun.COM return SZ_ERROR_DATA;
762*8996SAlok.Aggarwal@Sun.COM
763*8996SAlok.Aggarwal@Sun.COM LzmaDec_InitRc(p, p->tempBuf);
764*8996SAlok.Aggarwal@Sun.COM p->tempBufSize = 0;
765*8996SAlok.Aggarwal@Sun.COM }
766*8996SAlok.Aggarwal@Sun.COM
767*8996SAlok.Aggarwal@Sun.COM checkEndMarkNow = 0;
768*8996SAlok.Aggarwal@Sun.COM if (p->dicPos >= dicLimit)
769*8996SAlok.Aggarwal@Sun.COM {
770*8996SAlok.Aggarwal@Sun.COM if (p->remainLen == 0 && p->code == 0)
771*8996SAlok.Aggarwal@Sun.COM {
772*8996SAlok.Aggarwal@Sun.COM *status = LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK;
773*8996SAlok.Aggarwal@Sun.COM return SZ_OK;
774*8996SAlok.Aggarwal@Sun.COM }
775*8996SAlok.Aggarwal@Sun.COM if (finishMode == LZMA_FINISH_ANY)
776*8996SAlok.Aggarwal@Sun.COM {
777*8996SAlok.Aggarwal@Sun.COM *status = LZMA_STATUS_NOT_FINISHED;
778*8996SAlok.Aggarwal@Sun.COM return SZ_OK;
779*8996SAlok.Aggarwal@Sun.COM }
780*8996SAlok.Aggarwal@Sun.COM if (p->remainLen != 0)
781*8996SAlok.Aggarwal@Sun.COM {
782*8996SAlok.Aggarwal@Sun.COM *status = LZMA_STATUS_NOT_FINISHED;
783*8996SAlok.Aggarwal@Sun.COM return SZ_ERROR_DATA;
784*8996SAlok.Aggarwal@Sun.COM }
785*8996SAlok.Aggarwal@Sun.COM checkEndMarkNow = 1;
786*8996SAlok.Aggarwal@Sun.COM }
787*8996SAlok.Aggarwal@Sun.COM
788*8996SAlok.Aggarwal@Sun.COM if (p->needInitState)
789*8996SAlok.Aggarwal@Sun.COM LzmaDec_InitStateReal(p);
790*8996SAlok.Aggarwal@Sun.COM
791*8996SAlok.Aggarwal@Sun.COM if (p->tempBufSize == 0)
792*8996SAlok.Aggarwal@Sun.COM {
793*8996SAlok.Aggarwal@Sun.COM SizeT processed;
794*8996SAlok.Aggarwal@Sun.COM const Byte *bufLimit;
795*8996SAlok.Aggarwal@Sun.COM if (inSize < LZMA_REQUIRED_INPUT_MAX || checkEndMarkNow)
796*8996SAlok.Aggarwal@Sun.COM {
797*8996SAlok.Aggarwal@Sun.COM int dummyRes = LzmaDec_TryDummy(p, src, inSize);
798*8996SAlok.Aggarwal@Sun.COM if (dummyRes == DUMMY_ERROR)
799*8996SAlok.Aggarwal@Sun.COM {
800*8996SAlok.Aggarwal@Sun.COM (void) memcpy(p->tempBuf, src, inSize);
801*8996SAlok.Aggarwal@Sun.COM p->tempBufSize = (unsigned)inSize;
802*8996SAlok.Aggarwal@Sun.COM (*srcLen) += inSize;
803*8996SAlok.Aggarwal@Sun.COM *status = LZMA_STATUS_NEEDS_MORE_INPUT;
804*8996SAlok.Aggarwal@Sun.COM return SZ_OK;
805*8996SAlok.Aggarwal@Sun.COM }
806*8996SAlok.Aggarwal@Sun.COM if (checkEndMarkNow && dummyRes != DUMMY_MATCH)
807*8996SAlok.Aggarwal@Sun.COM {
808*8996SAlok.Aggarwal@Sun.COM *status = LZMA_STATUS_NOT_FINISHED;
809*8996SAlok.Aggarwal@Sun.COM return SZ_ERROR_DATA;
810*8996SAlok.Aggarwal@Sun.COM }
811*8996SAlok.Aggarwal@Sun.COM bufLimit = src;
812*8996SAlok.Aggarwal@Sun.COM }
813*8996SAlok.Aggarwal@Sun.COM else
814*8996SAlok.Aggarwal@Sun.COM bufLimit = src + inSize - LZMA_REQUIRED_INPUT_MAX;
815*8996SAlok.Aggarwal@Sun.COM p->buf = src;
816*8996SAlok.Aggarwal@Sun.COM if (LzmaDec_DecodeReal2(p, dicLimit, bufLimit) != 0)
817*8996SAlok.Aggarwal@Sun.COM return SZ_ERROR_DATA;
818*8996SAlok.Aggarwal@Sun.COM /*LINTED*/
819*8996SAlok.Aggarwal@Sun.COM processed = (SizeT)(p->buf - src);
820*8996SAlok.Aggarwal@Sun.COM (*srcLen) += processed;
821*8996SAlok.Aggarwal@Sun.COM src += processed;
822*8996SAlok.Aggarwal@Sun.COM inSize -= processed;
823*8996SAlok.Aggarwal@Sun.COM }
824*8996SAlok.Aggarwal@Sun.COM else
825*8996SAlok.Aggarwal@Sun.COM {
826*8996SAlok.Aggarwal@Sun.COM unsigned rem = p->tempBufSize, lookAhead = 0;
827*8996SAlok.Aggarwal@Sun.COM while (rem < LZMA_REQUIRED_INPUT_MAX && lookAhead < inSize)
828*8996SAlok.Aggarwal@Sun.COM p->tempBuf[rem++] = src[lookAhead++];
829*8996SAlok.Aggarwal@Sun.COM p->tempBufSize = rem;
830*8996SAlok.Aggarwal@Sun.COM if (rem < LZMA_REQUIRED_INPUT_MAX || checkEndMarkNow)
831*8996SAlok.Aggarwal@Sun.COM {
832*8996SAlok.Aggarwal@Sun.COM int dummyRes = LzmaDec_TryDummy(p, p->tempBuf, rem);
833*8996SAlok.Aggarwal@Sun.COM if (dummyRes == DUMMY_ERROR)
834*8996SAlok.Aggarwal@Sun.COM {
835*8996SAlok.Aggarwal@Sun.COM (*srcLen) += lookAhead;
836*8996SAlok.Aggarwal@Sun.COM *status = LZMA_STATUS_NEEDS_MORE_INPUT;
837*8996SAlok.Aggarwal@Sun.COM return SZ_OK;
838*8996SAlok.Aggarwal@Sun.COM }
839*8996SAlok.Aggarwal@Sun.COM if (checkEndMarkNow && dummyRes != DUMMY_MATCH)
840*8996SAlok.Aggarwal@Sun.COM {
841*8996SAlok.Aggarwal@Sun.COM *status = LZMA_STATUS_NOT_FINISHED;
842*8996SAlok.Aggarwal@Sun.COM return SZ_ERROR_DATA;
843*8996SAlok.Aggarwal@Sun.COM }
844*8996SAlok.Aggarwal@Sun.COM }
845*8996SAlok.Aggarwal@Sun.COM p->buf = p->tempBuf;
846*8996SAlok.Aggarwal@Sun.COM if (LzmaDec_DecodeReal2(p, dicLimit, p->buf) != 0)
847*8996SAlok.Aggarwal@Sun.COM return SZ_ERROR_DATA;
848*8996SAlok.Aggarwal@Sun.COM /*LINTED*/
849*8996SAlok.Aggarwal@Sun.COM lookAhead -= (rem - (unsigned)(p->buf - p->tempBuf));
850*8996SAlok.Aggarwal@Sun.COM (*srcLen) += lookAhead;
851*8996SAlok.Aggarwal@Sun.COM src += lookAhead;
852*8996SAlok.Aggarwal@Sun.COM inSize -= lookAhead;
853*8996SAlok.Aggarwal@Sun.COM p->tempBufSize = 0;
854*8996SAlok.Aggarwal@Sun.COM }
855*8996SAlok.Aggarwal@Sun.COM }
856*8996SAlok.Aggarwal@Sun.COM if (p->code == 0)
857*8996SAlok.Aggarwal@Sun.COM *status = LZMA_STATUS_FINISHED_WITH_MARK;
858*8996SAlok.Aggarwal@Sun.COM return (p->code == 0) ? SZ_OK : SZ_ERROR_DATA;
859*8996SAlok.Aggarwal@Sun.COM }
860*8996SAlok.Aggarwal@Sun.COM
LzmaDec_DecodeToBuf(CLzmaDec * p,Byte * dest,SizeT * destLen,const Byte * src,SizeT * srcLen,ELzmaFinishMode finishMode,ELzmaStatus * status)861*8996SAlok.Aggarwal@Sun.COM SRes LzmaDec_DecodeToBuf(CLzmaDec *p, Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen, ELzmaFinishMode finishMode, ELzmaStatus *status)
862*8996SAlok.Aggarwal@Sun.COM {
863*8996SAlok.Aggarwal@Sun.COM SizeT outSize = *destLen;
864*8996SAlok.Aggarwal@Sun.COM SizeT inSize = *srcLen;
865*8996SAlok.Aggarwal@Sun.COM *srcLen = *destLen = 0;
866*8996SAlok.Aggarwal@Sun.COM for (;;)
867*8996SAlok.Aggarwal@Sun.COM {
868*8996SAlok.Aggarwal@Sun.COM SizeT inSizeCur = inSize, outSizeCur, dicPos;
869*8996SAlok.Aggarwal@Sun.COM ELzmaFinishMode curFinishMode;
870*8996SAlok.Aggarwal@Sun.COM SRes res;
871*8996SAlok.Aggarwal@Sun.COM if (p->dicPos == p->dicBufSize)
872*8996SAlok.Aggarwal@Sun.COM p->dicPos = 0;
873*8996SAlok.Aggarwal@Sun.COM dicPos = p->dicPos;
874*8996SAlok.Aggarwal@Sun.COM if (outSize > p->dicBufSize - dicPos)
875*8996SAlok.Aggarwal@Sun.COM {
876*8996SAlok.Aggarwal@Sun.COM outSizeCur = p->dicBufSize;
877*8996SAlok.Aggarwal@Sun.COM curFinishMode = LZMA_FINISH_ANY;
878*8996SAlok.Aggarwal@Sun.COM }
879*8996SAlok.Aggarwal@Sun.COM else
880*8996SAlok.Aggarwal@Sun.COM {
881*8996SAlok.Aggarwal@Sun.COM outSizeCur = dicPos + outSize;
882*8996SAlok.Aggarwal@Sun.COM curFinishMode = finishMode;
883*8996SAlok.Aggarwal@Sun.COM }
884*8996SAlok.Aggarwal@Sun.COM
885*8996SAlok.Aggarwal@Sun.COM res = LzmaDec_DecodeToDic(p, outSizeCur, src, &inSizeCur, curFinishMode, status);
886*8996SAlok.Aggarwal@Sun.COM src += inSizeCur;
887*8996SAlok.Aggarwal@Sun.COM inSize -= inSizeCur;
888*8996SAlok.Aggarwal@Sun.COM *srcLen += inSizeCur;
889*8996SAlok.Aggarwal@Sun.COM outSizeCur = p->dicPos - dicPos;
890*8996SAlok.Aggarwal@Sun.COM (void) memcpy(dest, p->dic + dicPos, outSizeCur);
891*8996SAlok.Aggarwal@Sun.COM dest += outSizeCur;
892*8996SAlok.Aggarwal@Sun.COM outSize -= outSizeCur;
893*8996SAlok.Aggarwal@Sun.COM *destLen += outSizeCur;
894*8996SAlok.Aggarwal@Sun.COM if (res != 0)
895*8996SAlok.Aggarwal@Sun.COM return res;
896*8996SAlok.Aggarwal@Sun.COM if (outSizeCur == 0 || outSize == 0)
897*8996SAlok.Aggarwal@Sun.COM return SZ_OK;
898*8996SAlok.Aggarwal@Sun.COM }
899*8996SAlok.Aggarwal@Sun.COM }
900*8996SAlok.Aggarwal@Sun.COM
LzmaDec_FreeProbs(CLzmaDec * p,ISzAlloc * alloc)901*8996SAlok.Aggarwal@Sun.COM void LzmaDec_FreeProbs(CLzmaDec *p, ISzAlloc *alloc)
902*8996SAlok.Aggarwal@Sun.COM {
903*8996SAlok.Aggarwal@Sun.COM if (p->probs != 0)
904*8996SAlok.Aggarwal@Sun.COM alloc->Free(alloc, p->probs, (p->numProbs * sizeof (*p->probs)));
905*8996SAlok.Aggarwal@Sun.COM p->probs = 0;
906*8996SAlok.Aggarwal@Sun.COM }
907*8996SAlok.Aggarwal@Sun.COM
LzmaDec_FreeDict(CLzmaDec * p,ISzAlloc * alloc)908*8996SAlok.Aggarwal@Sun.COM static void LzmaDec_FreeDict(CLzmaDec *p, ISzAlloc *alloc)
909*8996SAlok.Aggarwal@Sun.COM {
910*8996SAlok.Aggarwal@Sun.COM if (p->dic != 0)
911*8996SAlok.Aggarwal@Sun.COM alloc->Free(alloc, p->dic, ((p->prop).dicSize * sizeof (*p->dic)));
912*8996SAlok.Aggarwal@Sun.COM p->dic = 0;
913*8996SAlok.Aggarwal@Sun.COM }
914*8996SAlok.Aggarwal@Sun.COM
LzmaDec_Free(CLzmaDec * p,ISzAlloc * alloc)915*8996SAlok.Aggarwal@Sun.COM void LzmaDec_Free(CLzmaDec *p, ISzAlloc *alloc)
916*8996SAlok.Aggarwal@Sun.COM {
917*8996SAlok.Aggarwal@Sun.COM LzmaDec_FreeProbs(p, alloc);
918*8996SAlok.Aggarwal@Sun.COM LzmaDec_FreeDict(p, alloc);
919*8996SAlok.Aggarwal@Sun.COM }
920*8996SAlok.Aggarwal@Sun.COM
LzmaProps_Decode(CLzmaProps * p,const Byte * data,unsigned size)921*8996SAlok.Aggarwal@Sun.COM SRes LzmaProps_Decode(CLzmaProps *p, const Byte *data, unsigned size)
922*8996SAlok.Aggarwal@Sun.COM {
923*8996SAlok.Aggarwal@Sun.COM UInt32 dicSize;
924*8996SAlok.Aggarwal@Sun.COM Byte d;
925*8996SAlok.Aggarwal@Sun.COM
926*8996SAlok.Aggarwal@Sun.COM if (size < LZMA_PROPS_SIZE)
927*8996SAlok.Aggarwal@Sun.COM return SZ_ERROR_UNSUPPORTED;
928*8996SAlok.Aggarwal@Sun.COM else
929*8996SAlok.Aggarwal@Sun.COM dicSize = data[1] | ((UInt32)data[2] << 8) | ((UInt32)data[3] << 16) | ((UInt32)data[4] << 24);
930*8996SAlok.Aggarwal@Sun.COM
931*8996SAlok.Aggarwal@Sun.COM if (dicSize < LZMA_DIC_MIN)
932*8996SAlok.Aggarwal@Sun.COM dicSize = LZMA_DIC_MIN;
933*8996SAlok.Aggarwal@Sun.COM p->dicSize = dicSize;
934*8996SAlok.Aggarwal@Sun.COM
935*8996SAlok.Aggarwal@Sun.COM d = data[0];
936*8996SAlok.Aggarwal@Sun.COM if (d >= (9 * 5 * 5))
937*8996SAlok.Aggarwal@Sun.COM return SZ_ERROR_UNSUPPORTED;
938*8996SAlok.Aggarwal@Sun.COM
939*8996SAlok.Aggarwal@Sun.COM p->lc = d % 9;
940*8996SAlok.Aggarwal@Sun.COM d /= 9;
941*8996SAlok.Aggarwal@Sun.COM p->pb = d / 5;
942*8996SAlok.Aggarwal@Sun.COM p->lp = d % 5;
943*8996SAlok.Aggarwal@Sun.COM
944*8996SAlok.Aggarwal@Sun.COM return SZ_OK;
945*8996SAlok.Aggarwal@Sun.COM }
946*8996SAlok.Aggarwal@Sun.COM
LzmaDec_AllocateProbs2(CLzmaDec * p,const CLzmaProps * propNew,ISzAlloc * alloc)947*8996SAlok.Aggarwal@Sun.COM static SRes LzmaDec_AllocateProbs2(CLzmaDec *p, const CLzmaProps *propNew, ISzAlloc *alloc)
948*8996SAlok.Aggarwal@Sun.COM {
949*8996SAlok.Aggarwal@Sun.COM UInt32 numProbs = LzmaProps_GetNumProbs(propNew);
950*8996SAlok.Aggarwal@Sun.COM if (p->probs == 0 || numProbs != p->numProbs)
951*8996SAlok.Aggarwal@Sun.COM {
952*8996SAlok.Aggarwal@Sun.COM LzmaDec_FreeProbs(p, alloc);
953*8996SAlok.Aggarwal@Sun.COM p->probs = (CLzmaProb *)alloc->Alloc(alloc, numProbs * sizeof(CLzmaProb));
954*8996SAlok.Aggarwal@Sun.COM p->numProbs = numProbs;
955*8996SAlok.Aggarwal@Sun.COM if (p->probs == 0)
956*8996SAlok.Aggarwal@Sun.COM return SZ_ERROR_MEM;
957*8996SAlok.Aggarwal@Sun.COM }
958*8996SAlok.Aggarwal@Sun.COM return SZ_OK;
959*8996SAlok.Aggarwal@Sun.COM }
960*8996SAlok.Aggarwal@Sun.COM
LzmaDec_AllocateProbs(CLzmaDec * p,const Byte * props,unsigned propsSize,ISzAlloc * alloc)961*8996SAlok.Aggarwal@Sun.COM SRes LzmaDec_AllocateProbs(CLzmaDec *p, const Byte *props, unsigned propsSize, ISzAlloc *alloc)
962*8996SAlok.Aggarwal@Sun.COM {
963*8996SAlok.Aggarwal@Sun.COM CLzmaProps propNew;
964*8996SAlok.Aggarwal@Sun.COM RINOK(LzmaProps_Decode(&propNew, props, propsSize));
965*8996SAlok.Aggarwal@Sun.COM RINOK(LzmaDec_AllocateProbs2(p, &propNew, alloc));
966*8996SAlok.Aggarwal@Sun.COM p->prop = propNew;
967*8996SAlok.Aggarwal@Sun.COM return SZ_OK;
968*8996SAlok.Aggarwal@Sun.COM }
969*8996SAlok.Aggarwal@Sun.COM
LzmaDec_Allocate(CLzmaDec * p,const Byte * props,unsigned propsSize,ISzAlloc * alloc)970*8996SAlok.Aggarwal@Sun.COM SRes LzmaDec_Allocate(CLzmaDec *p, const Byte *props, unsigned propsSize, ISzAlloc *alloc)
971*8996SAlok.Aggarwal@Sun.COM {
972*8996SAlok.Aggarwal@Sun.COM CLzmaProps propNew;
973*8996SAlok.Aggarwal@Sun.COM SizeT dicBufSize;
974*8996SAlok.Aggarwal@Sun.COM RINOK(LzmaProps_Decode(&propNew, props, propsSize));
975*8996SAlok.Aggarwal@Sun.COM RINOK(LzmaDec_AllocateProbs2(p, &propNew, alloc));
976*8996SAlok.Aggarwal@Sun.COM dicBufSize = propNew.dicSize;
977*8996SAlok.Aggarwal@Sun.COM if (p->dic == 0 || dicBufSize != p->dicBufSize)
978*8996SAlok.Aggarwal@Sun.COM {
979*8996SAlok.Aggarwal@Sun.COM LzmaDec_FreeDict(p, alloc);
980*8996SAlok.Aggarwal@Sun.COM p->dic = (Byte *)alloc->Alloc(alloc, dicBufSize);
981*8996SAlok.Aggarwal@Sun.COM if (p->dic == 0)
982*8996SAlok.Aggarwal@Sun.COM {
983*8996SAlok.Aggarwal@Sun.COM LzmaDec_FreeProbs(p, alloc);
984*8996SAlok.Aggarwal@Sun.COM return SZ_ERROR_MEM;
985*8996SAlok.Aggarwal@Sun.COM }
986*8996SAlok.Aggarwal@Sun.COM }
987*8996SAlok.Aggarwal@Sun.COM p->dicBufSize = dicBufSize;
988*8996SAlok.Aggarwal@Sun.COM p->prop = propNew;
989*8996SAlok.Aggarwal@Sun.COM return SZ_OK;
990*8996SAlok.Aggarwal@Sun.COM }
991*8996SAlok.Aggarwal@Sun.COM
LzmaDecode(Byte * dest,SizeT * destLen,const Byte * src,SizeT * srcLen,const Byte * propData,unsigned propSize,ELzmaFinishMode finishMode,ELzmaStatus * status,ISzAlloc * alloc)992*8996SAlok.Aggarwal@Sun.COM SRes LzmaDecode(Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen,
993*8996SAlok.Aggarwal@Sun.COM const Byte *propData, unsigned propSize, ELzmaFinishMode finishMode,
994*8996SAlok.Aggarwal@Sun.COM ELzmaStatus *status, ISzAlloc *alloc)
995*8996SAlok.Aggarwal@Sun.COM {
996*8996SAlok.Aggarwal@Sun.COM CLzmaDec p;
997*8996SAlok.Aggarwal@Sun.COM SRes res;
998*8996SAlok.Aggarwal@Sun.COM SizeT inSize = *srcLen;
999*8996SAlok.Aggarwal@Sun.COM SizeT outSize = *destLen;
1000*8996SAlok.Aggarwal@Sun.COM *srcLen = *destLen = 0;
1001*8996SAlok.Aggarwal@Sun.COM if (inSize < RC_INIT_SIZE)
1002*8996SAlok.Aggarwal@Sun.COM return SZ_ERROR_INPUT_EOF;
1003*8996SAlok.Aggarwal@Sun.COM
1004*8996SAlok.Aggarwal@Sun.COM LzmaDec_Construct(&p);
1005*8996SAlok.Aggarwal@Sun.COM res = LzmaDec_AllocateProbs(&p, propData, propSize, alloc);
1006*8996SAlok.Aggarwal@Sun.COM if (res != 0)
1007*8996SAlok.Aggarwal@Sun.COM return res;
1008*8996SAlok.Aggarwal@Sun.COM p.dic = dest;
1009*8996SAlok.Aggarwal@Sun.COM p.dicBufSize = outSize;
1010*8996SAlok.Aggarwal@Sun.COM
1011*8996SAlok.Aggarwal@Sun.COM LzmaDec_Init(&p);
1012*8996SAlok.Aggarwal@Sun.COM
1013*8996SAlok.Aggarwal@Sun.COM *srcLen = inSize;
1014*8996SAlok.Aggarwal@Sun.COM res = LzmaDec_DecodeToDic(&p, outSize, src, srcLen, finishMode, status);
1015*8996SAlok.Aggarwal@Sun.COM
1016*8996SAlok.Aggarwal@Sun.COM if (res == SZ_OK && *status == LZMA_STATUS_NEEDS_MORE_INPUT)
1017*8996SAlok.Aggarwal@Sun.COM res = SZ_ERROR_INPUT_EOF;
1018*8996SAlok.Aggarwal@Sun.COM
1019*8996SAlok.Aggarwal@Sun.COM (*destLen) = p.dicPos;
1020*8996SAlok.Aggarwal@Sun.COM LzmaDec_FreeProbs(&p, alloc);
1021*8996SAlok.Aggarwal@Sun.COM return res;
1022*8996SAlok.Aggarwal@Sun.COM }
1023