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