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