update libchdr
[pcsx_rearmed.git] / deps / libchdr / deps / lzma-22.01 / src / LzmaDec.c
1 /* LzmaDec.c -- LZMA Decoder\r
2 2021-04-01 : Igor Pavlov : Public domain */\r
3 \r
4 #include "Precomp.h"\r
5 \r
6 #include <string.h>\r
7 \r
8 /* #include "CpuArch.h" */\r
9 #include "LzmaDec.h"\r
10 \r
11 #define kNumTopBits 24\r
12 #define kTopValue ((UInt32)1 << kNumTopBits)\r
13 \r
14 #define kNumBitModelTotalBits 11\r
15 #define kBitModelTotal (1 << kNumBitModelTotalBits)\r
16 \r
17 #define RC_INIT_SIZE 5\r
18 \r
19 #ifndef _LZMA_DEC_OPT\r
20 \r
21 #define kNumMoveBits 5\r
22 #define NORMALIZE if (range < kTopValue) { range <<= 8; code = (code << 8) | (*buf++); }\r
23 \r
24 #define IF_BIT_0(p) ttt = *(p); NORMALIZE; bound = (range >> kNumBitModelTotalBits) * (UInt32)ttt; if (code < bound)\r
25 #define UPDATE_0(p) range = bound; *(p) = (CLzmaProb)(ttt + ((kBitModelTotal - ttt) >> kNumMoveBits));\r
26 #define UPDATE_1(p) range -= bound; code -= bound; *(p) = (CLzmaProb)(ttt - (ttt >> kNumMoveBits));\r
27 #define GET_BIT2(p, i, A0, A1) IF_BIT_0(p) \\r
28   { UPDATE_0(p); i = (i + i); A0; } else \\r
29   { UPDATE_1(p); i = (i + i) + 1; A1; }\r
30 \r
31 #define TREE_GET_BIT(probs, i) { GET_BIT2(probs + i, i, ;, ;); }\r
32 \r
33 #define REV_BIT(p, i, A0, A1) IF_BIT_0(p + i) \\r
34   { UPDATE_0(p + i); A0; } else \\r
35   { UPDATE_1(p + i); A1; }\r
36 #define REV_BIT_VAR(  p, i, m) REV_BIT(p, i, i += m; m += m, m += m; i += m; )\r
37 #define REV_BIT_CONST(p, i, m) REV_BIT(p, i, i += m;       , i += m * 2; )\r
38 #define REV_BIT_LAST( p, i, m) REV_BIT(p, i, i -= m        , ; )\r
39 \r
40 #define TREE_DECODE(probs, limit, i) \\r
41   { i = 1; do { TREE_GET_BIT(probs, i); } while (i < limit); i -= limit; }\r
42 \r
43 /* #define _LZMA_SIZE_OPT */\r
44 \r
45 #ifdef _LZMA_SIZE_OPT\r
46 #define TREE_6_DECODE(probs, i) TREE_DECODE(probs, (1 << 6), i)\r
47 #else\r
48 #define TREE_6_DECODE(probs, i) \\r
49   { i = 1; \\r
50   TREE_GET_BIT(probs, i); \\r
51   TREE_GET_BIT(probs, i); \\r
52   TREE_GET_BIT(probs, i); \\r
53   TREE_GET_BIT(probs, i); \\r
54   TREE_GET_BIT(probs, i); \\r
55   TREE_GET_BIT(probs, i); \\r
56   i -= 0x40; }\r
57 #endif\r
58 \r
59 #define NORMAL_LITER_DEC TREE_GET_BIT(prob, symbol)\r
60 #define MATCHED_LITER_DEC \\r
61   matchByte += matchByte; \\r
62   bit = offs; \\r
63   offs &= matchByte; \\r
64   probLit = prob + (offs + bit + symbol); \\r
65   GET_BIT2(probLit, symbol, offs ^= bit; , ;)\r
66 \r
67 #endif // _LZMA_DEC_OPT\r
68 \r
69 \r
70 #define NORMALIZE_CHECK if (range < kTopValue) { if (buf >= bufLimit) return DUMMY_INPUT_EOF; range <<= 8; code = (code << 8) | (*buf++); }\r
71 \r
72 #define IF_BIT_0_CHECK(p) ttt = *(p); NORMALIZE_CHECK; bound = (range >> kNumBitModelTotalBits) * (UInt32)ttt; if (code < bound)\r
73 #define UPDATE_0_CHECK range = bound;\r
74 #define UPDATE_1_CHECK range -= bound; code -= bound;\r
75 #define GET_BIT2_CHECK(p, i, A0, A1) IF_BIT_0_CHECK(p) \\r
76   { UPDATE_0_CHECK; i = (i + i); A0; } else \\r
77   { UPDATE_1_CHECK; i = (i + i) + 1; A1; }\r
78 #define GET_BIT_CHECK(p, i) GET_BIT2_CHECK(p, i, ; , ;)\r
79 #define TREE_DECODE_CHECK(probs, limit, i) \\r
80   { i = 1; do { GET_BIT_CHECK(probs + i, i) } while (i < limit); i -= limit; }\r
81 \r
82 \r
83 #define REV_BIT_CHECK(p, i, m) IF_BIT_0_CHECK(p + i) \\r
84   { UPDATE_0_CHECK; i += m; m += m; } else \\r
85   { UPDATE_1_CHECK; m += m; i += m; }\r
86 \r
87 \r
88 #define kNumPosBitsMax 4\r
89 #define kNumPosStatesMax (1 << kNumPosBitsMax)\r
90 \r
91 #define kLenNumLowBits 3\r
92 #define kLenNumLowSymbols (1 << kLenNumLowBits)\r
93 #define kLenNumHighBits 8\r
94 #define kLenNumHighSymbols (1 << kLenNumHighBits)\r
95 \r
96 #define LenLow 0\r
97 #define LenHigh (LenLow + 2 * (kNumPosStatesMax << kLenNumLowBits))\r
98 #define kNumLenProbs (LenHigh + kLenNumHighSymbols)\r
99 \r
100 #define LenChoice LenLow\r
101 #define LenChoice2 (LenLow + (1 << kLenNumLowBits))\r
102 \r
103 #define kNumStates 12\r
104 #define kNumStates2 16\r
105 #define kNumLitStates 7\r
106 \r
107 #define kStartPosModelIndex 4\r
108 #define kEndPosModelIndex 14\r
109 #define kNumFullDistances (1 << (kEndPosModelIndex >> 1))\r
110 \r
111 #define kNumPosSlotBits 6\r
112 #define kNumLenToPosStates 4\r
113 \r
114 #define kNumAlignBits 4\r
115 #define kAlignTableSize (1 << kNumAlignBits)\r
116 \r
117 #define kMatchMinLen 2\r
118 #define kMatchSpecLenStart (kMatchMinLen + kLenNumLowSymbols * 2 + kLenNumHighSymbols)\r
119 \r
120 #define kMatchSpecLen_Error_Data (1 << 9)\r
121 #define kMatchSpecLen_Error_Fail (kMatchSpecLen_Error_Data - 1)\r
122 \r
123 /* External ASM code needs same CLzmaProb array layout. So don't change it. */\r
124 \r
125 /* (probs_1664) is faster and better for code size at some platforms */\r
126 /*\r
127 #ifdef MY_CPU_X86_OR_AMD64\r
128 */\r
129 #define kStartOffset 1664\r
130 #define GET_PROBS p->probs_1664\r
131 /*\r
132 #define GET_PROBS p->probs + kStartOffset\r
133 #else\r
134 #define kStartOffset 0\r
135 #define GET_PROBS p->probs\r
136 #endif\r
137 */\r
138 \r
139 #define SpecPos (-kStartOffset)\r
140 #define IsRep0Long (SpecPos + kNumFullDistances)\r
141 #define RepLenCoder (IsRep0Long + (kNumStates2 << kNumPosBitsMax))\r
142 #define LenCoder (RepLenCoder + kNumLenProbs)\r
143 #define IsMatch (LenCoder + kNumLenProbs)\r
144 #define Align (IsMatch + (kNumStates2 << kNumPosBitsMax))\r
145 #define IsRep (Align + kAlignTableSize)\r
146 #define IsRepG0 (IsRep + kNumStates)\r
147 #define IsRepG1 (IsRepG0 + kNumStates)\r
148 #define IsRepG2 (IsRepG1 + kNumStates)\r
149 #define PosSlot (IsRepG2 + kNumStates)\r
150 #define Literal (PosSlot + (kNumLenToPosStates << kNumPosSlotBits))\r
151 #define NUM_BASE_PROBS (Literal + kStartOffset)\r
152 \r
153 #if Align != 0 && kStartOffset != 0\r
154   #error Stop_Compiling_Bad_LZMA_kAlign\r
155 #endif\r
156 \r
157 #if NUM_BASE_PROBS != 1984\r
158   #error Stop_Compiling_Bad_LZMA_PROBS\r
159 #endif\r
160 \r
161 \r
162 #define LZMA_LIT_SIZE 0x300\r
163 \r
164 #define LzmaProps_GetNumProbs(p) (NUM_BASE_PROBS + ((UInt32)LZMA_LIT_SIZE << ((p)->lc + (p)->lp)))\r
165 \r
166 \r
167 #define CALC_POS_STATE(processedPos, pbMask) (((processedPos) & (pbMask)) << 4)\r
168 #define COMBINED_PS_STATE (posState + state)\r
169 #define GET_LEN_STATE (posState)\r
170 \r
171 #define LZMA_DIC_MIN (1 << 12)\r
172 \r
173 /*\r
174 p->remainLen : shows status of LZMA decoder:\r
175     < kMatchSpecLenStart  : the number of bytes to be copied with (p->rep0) offset\r
176     = kMatchSpecLenStart  : the LZMA stream was finished with end mark\r
177     = kMatchSpecLenStart + 1  : need init range coder\r
178     = kMatchSpecLenStart + 2  : need init range coder and state\r
179     = kMatchSpecLen_Error_Fail                : Internal Code Failure\r
180     = kMatchSpecLen_Error_Data + [0 ... 273]  : LZMA Data Error\r
181 */\r
182 \r
183 /* ---------- LZMA_DECODE_REAL ---------- */\r
184 /*\r
185 LzmaDec_DecodeReal_3() can be implemented in external ASM file.\r
186 3 - is the code compatibility version of that function for check at link time.\r
187 */\r
188 \r
189 #define LZMA_DECODE_REAL LzmaDec_DecodeReal_3\r
190 \r
191 /*\r
192 LZMA_DECODE_REAL()\r
193 In:\r
194   RangeCoder is normalized\r
195   if (p->dicPos == limit)\r
196   {\r
197     LzmaDec_TryDummy() was called before to exclude LITERAL and MATCH-REP cases.\r
198     So first symbol can be only MATCH-NON-REP. And if that MATCH-NON-REP symbol\r
199     is not END_OF_PAYALOAD_MARKER, then the function doesn't write any byte to dictionary,\r
200     the function returns SZ_OK, and the caller can use (p->remainLen) and (p->reps[0]) later.\r
201   }\r
202 \r
203 Processing:\r
204   The first LZMA symbol will be decoded in any case.\r
205   All main checks for limits are at the end of main loop,\r
206   It decodes additional LZMA-symbols while (p->buf < bufLimit && dicPos < limit),\r
207   RangeCoder is still without last normalization when (p->buf < bufLimit) is being checked.\r
208   But if (p->buf < bufLimit), the caller provided at least (LZMA_REQUIRED_INPUT_MAX + 1) bytes for\r
209   next iteration  before limit (bufLimit + LZMA_REQUIRED_INPUT_MAX),\r
210   that is enough for worst case LZMA symbol with one additional RangeCoder normalization for one bit.\r
211   So that function never reads bufLimit [LZMA_REQUIRED_INPUT_MAX] byte.\r
212 \r
213 Out:\r
214   RangeCoder is normalized\r
215   Result:\r
216     SZ_OK - OK\r
217       p->remainLen:\r
218         < kMatchSpecLenStart : the number of bytes to be copied with (p->reps[0]) offset\r
219         = kMatchSpecLenStart : the LZMA stream was finished with end mark\r
220 \r
221     SZ_ERROR_DATA - error, when the MATCH-Symbol refers out of dictionary\r
222       p->remainLen : undefined\r
223       p->reps[*]    : undefined\r
224 */\r
225 \r
226 \r
227 #ifdef _LZMA_DEC_OPT\r
228 \r
229 int MY_FAST_CALL LZMA_DECODE_REAL(CLzmaDec *p, SizeT limit, const Byte *bufLimit);\r
230 \r
231 #else\r
232 \r
233 static\r
234 int MY_FAST_CALL LZMA_DECODE_REAL(CLzmaDec *p, SizeT limit, const Byte *bufLimit)\r
235 {\r
236   CLzmaProb *probs = GET_PROBS;\r
237   unsigned state = (unsigned)p->state;\r
238   UInt32 rep0 = p->reps[0], rep1 = p->reps[1], rep2 = p->reps[2], rep3 = p->reps[3];\r
239   unsigned pbMask = ((unsigned)1 << (p->prop.pb)) - 1;\r
240   unsigned lc = p->prop.lc;\r
241   unsigned lpMask = ((unsigned)0x100 << p->prop.lp) - ((unsigned)0x100 >> lc);\r
242 \r
243   Byte *dic = p->dic;\r
244   SizeT dicBufSize = p->dicBufSize;\r
245   SizeT dicPos = p->dicPos;\r
246   \r
247   UInt32 processedPos = p->processedPos;\r
248   UInt32 checkDicSize = p->checkDicSize;\r
249   unsigned len = 0;\r
250 \r
251   const Byte *buf = p->buf;\r
252   UInt32 range = p->range;\r
253   UInt32 code = p->code;\r
254 \r
255   do\r
256   {\r
257     CLzmaProb *prob;\r
258     UInt32 bound;\r
259     unsigned ttt;\r
260     unsigned posState = CALC_POS_STATE(processedPos, pbMask);\r
261 \r
262     prob = probs + IsMatch + COMBINED_PS_STATE;\r
263     IF_BIT_0(prob)\r
264     {\r
265       unsigned symbol;\r
266       UPDATE_0(prob);\r
267       prob = probs + Literal;\r
268       if (processedPos != 0 || checkDicSize != 0)\r
269         prob += (UInt32)3 * ((((processedPos << 8) + dic[(dicPos == 0 ? dicBufSize : dicPos) - 1]) & lpMask) << lc);\r
270       processedPos++;\r
271 \r
272       if (state < kNumLitStates)\r
273       {\r
274         state -= (state < 4) ? state : 3;\r
275         symbol = 1;\r
276         #ifdef _LZMA_SIZE_OPT\r
277         do { NORMAL_LITER_DEC } while (symbol < 0x100);\r
278         #else\r
279         NORMAL_LITER_DEC\r
280         NORMAL_LITER_DEC\r
281         NORMAL_LITER_DEC\r
282         NORMAL_LITER_DEC\r
283         NORMAL_LITER_DEC\r
284         NORMAL_LITER_DEC\r
285         NORMAL_LITER_DEC\r
286         NORMAL_LITER_DEC\r
287         #endif\r
288       }\r
289       else\r
290       {\r
291         unsigned matchByte = dic[dicPos - rep0 + (dicPos < rep0 ? dicBufSize : 0)];\r
292         unsigned offs = 0x100;\r
293         state -= (state < 10) ? 3 : 6;\r
294         symbol = 1;\r
295         #ifdef _LZMA_SIZE_OPT\r
296         do\r
297         {\r
298           unsigned bit;\r
299           CLzmaProb *probLit;\r
300           MATCHED_LITER_DEC\r
301         }\r
302         while (symbol < 0x100);\r
303         #else\r
304         {\r
305           unsigned bit;\r
306           CLzmaProb *probLit;\r
307           MATCHED_LITER_DEC\r
308           MATCHED_LITER_DEC\r
309           MATCHED_LITER_DEC\r
310           MATCHED_LITER_DEC\r
311           MATCHED_LITER_DEC\r
312           MATCHED_LITER_DEC\r
313           MATCHED_LITER_DEC\r
314           MATCHED_LITER_DEC\r
315         }\r
316         #endif\r
317       }\r
318 \r
319       dic[dicPos++] = (Byte)symbol;\r
320       continue;\r
321     }\r
322     \r
323     {\r
324       UPDATE_1(prob);\r
325       prob = probs + IsRep + state;\r
326       IF_BIT_0(prob)\r
327       {\r
328         UPDATE_0(prob);\r
329         state += kNumStates;\r
330         prob = probs + LenCoder;\r
331       }\r
332       else\r
333       {\r
334         UPDATE_1(prob);\r
335         prob = probs + IsRepG0 + state;\r
336         IF_BIT_0(prob)\r
337         {\r
338           UPDATE_0(prob);\r
339           prob = probs + IsRep0Long + COMBINED_PS_STATE;\r
340           IF_BIT_0(prob)\r
341           {\r
342             UPDATE_0(prob);\r
343   \r
344             // that case was checked before with kBadRepCode\r
345             // if (checkDicSize == 0 && processedPos == 0) { len = kMatchSpecLen_Error_Data + 1; break; }\r
346             // The caller doesn't allow (dicPos == limit) case here\r
347             // so we don't need the following check:\r
348             // if (dicPos == limit) { state = state < kNumLitStates ? 9 : 11; len = 1; break; }\r
349             \r
350             dic[dicPos] = dic[dicPos - rep0 + (dicPos < rep0 ? dicBufSize : 0)];\r
351             dicPos++;\r
352             processedPos++;\r
353             state = state < kNumLitStates ? 9 : 11;\r
354             continue;\r
355           }\r
356           UPDATE_1(prob);\r
357         }\r
358         else\r
359         {\r
360           UInt32 distance;\r
361           UPDATE_1(prob);\r
362           prob = probs + IsRepG1 + state;\r
363           IF_BIT_0(prob)\r
364           {\r
365             UPDATE_0(prob);\r
366             distance = rep1;\r
367           }\r
368           else\r
369           {\r
370             UPDATE_1(prob);\r
371             prob = probs + IsRepG2 + state;\r
372             IF_BIT_0(prob)\r
373             {\r
374               UPDATE_0(prob);\r
375               distance = rep2;\r
376             }\r
377             else\r
378             {\r
379               UPDATE_1(prob);\r
380               distance = rep3;\r
381               rep3 = rep2;\r
382             }\r
383             rep2 = rep1;\r
384           }\r
385           rep1 = rep0;\r
386           rep0 = distance;\r
387         }\r
388         state = state < kNumLitStates ? 8 : 11;\r
389         prob = probs + RepLenCoder;\r
390       }\r
391       \r
392       #ifdef _LZMA_SIZE_OPT\r
393       {\r
394         unsigned lim, offset;\r
395         CLzmaProb *probLen = prob + LenChoice;\r
396         IF_BIT_0(probLen)\r
397         {\r
398           UPDATE_0(probLen);\r
399           probLen = prob + LenLow + GET_LEN_STATE;\r
400           offset = 0;\r
401           lim = (1 << kLenNumLowBits);\r
402         }\r
403         else\r
404         {\r
405           UPDATE_1(probLen);\r
406           probLen = prob + LenChoice2;\r
407           IF_BIT_0(probLen)\r
408           {\r
409             UPDATE_0(probLen);\r
410             probLen = prob + LenLow + GET_LEN_STATE + (1 << kLenNumLowBits);\r
411             offset = kLenNumLowSymbols;\r
412             lim = (1 << kLenNumLowBits);\r
413           }\r
414           else\r
415           {\r
416             UPDATE_1(probLen);\r
417             probLen = prob + LenHigh;\r
418             offset = kLenNumLowSymbols * 2;\r
419             lim = (1 << kLenNumHighBits);\r
420           }\r
421         }\r
422         TREE_DECODE(probLen, lim, len);\r
423         len += offset;\r
424       }\r
425       #else\r
426       {\r
427         CLzmaProb *probLen = prob + LenChoice;\r
428         IF_BIT_0(probLen)\r
429         {\r
430           UPDATE_0(probLen);\r
431           probLen = prob + LenLow + GET_LEN_STATE;\r
432           len = 1;\r
433           TREE_GET_BIT(probLen, len);\r
434           TREE_GET_BIT(probLen, len);\r
435           TREE_GET_BIT(probLen, len);\r
436           len -= 8;\r
437         }\r
438         else\r
439         {\r
440           UPDATE_1(probLen);\r
441           probLen = prob + LenChoice2;\r
442           IF_BIT_0(probLen)\r
443           {\r
444             UPDATE_0(probLen);\r
445             probLen = prob + LenLow + GET_LEN_STATE + (1 << kLenNumLowBits);\r
446             len = 1;\r
447             TREE_GET_BIT(probLen, len);\r
448             TREE_GET_BIT(probLen, len);\r
449             TREE_GET_BIT(probLen, len);\r
450           }\r
451           else\r
452           {\r
453             UPDATE_1(probLen);\r
454             probLen = prob + LenHigh;\r
455             TREE_DECODE(probLen, (1 << kLenNumHighBits), len);\r
456             len += kLenNumLowSymbols * 2;\r
457           }\r
458         }\r
459       }\r
460       #endif\r
461 \r
462       if (state >= kNumStates)\r
463       {\r
464         UInt32 distance;\r
465         prob = probs + PosSlot +\r
466             ((len < kNumLenToPosStates ? len : kNumLenToPosStates - 1) << kNumPosSlotBits);\r
467         TREE_6_DECODE(prob, distance);\r
468         if (distance >= kStartPosModelIndex)\r
469         {\r
470           unsigned posSlot = (unsigned)distance;\r
471           unsigned numDirectBits = (unsigned)(((distance >> 1) - 1));\r
472           distance = (2 | (distance & 1));\r
473           if (posSlot < kEndPosModelIndex)\r
474           {\r
475             distance <<= numDirectBits;\r
476             prob = probs + SpecPos;\r
477             {\r
478               UInt32 m = 1;\r
479               distance++;\r
480               do\r
481               {\r
482                 REV_BIT_VAR(prob, distance, m);\r
483               }\r
484               while (--numDirectBits);\r
485               distance -= m;\r
486             }\r
487           }\r
488           else\r
489           {\r
490             numDirectBits -= kNumAlignBits;\r
491             do\r
492             {\r
493               NORMALIZE\r
494               range >>= 1;\r
495               \r
496               {\r
497                 UInt32 t;\r
498                 code -= range;\r
499                 t = (0 - ((UInt32)code >> 31)); /* (UInt32)((Int32)code >> 31) */\r
500                 distance = (distance << 1) + (t + 1);\r
501                 code += range & t;\r
502               }\r
503               /*\r
504               distance <<= 1;\r
505               if (code >= range)\r
506               {\r
507                 code -= range;\r
508                 distance |= 1;\r
509               }\r
510               */\r
511             }\r
512             while (--numDirectBits);\r
513             prob = probs + Align;\r
514             distance <<= kNumAlignBits;\r
515             {\r
516               unsigned i = 1;\r
517               REV_BIT_CONST(prob, i, 1);\r
518               REV_BIT_CONST(prob, i, 2);\r
519               REV_BIT_CONST(prob, i, 4);\r
520               REV_BIT_LAST (prob, i, 8);\r
521               distance |= i;\r
522             }\r
523             if (distance == (UInt32)0xFFFFFFFF)\r
524             {\r
525               len = kMatchSpecLenStart;\r
526               state -= kNumStates;\r
527               break;\r
528             }\r
529           }\r
530         }\r
531         \r
532         rep3 = rep2;\r
533         rep2 = rep1;\r
534         rep1 = rep0;\r
535         rep0 = distance + 1;\r
536         state = (state < kNumStates + kNumLitStates) ? kNumLitStates : kNumLitStates + 3;\r
537         if (distance >= (checkDicSize == 0 ? processedPos: checkDicSize))\r
538         {\r
539           len += kMatchSpecLen_Error_Data + kMatchMinLen;\r
540           // len = kMatchSpecLen_Error_Data;\r
541           // len += kMatchMinLen;\r
542           break;\r
543         }\r
544       }\r
545 \r
546       len += kMatchMinLen;\r
547 \r
548       {\r
549         SizeT rem;\r
550         unsigned curLen;\r
551         SizeT pos;\r
552         \r
553         if ((rem = limit - dicPos) == 0)\r
554         {\r
555           /*\r
556           We stop decoding and return SZ_OK, and we can resume decoding later.\r
557           Any error conditions can be tested later in caller code.\r
558           For more strict mode we can stop decoding with error\r
559           // len += kMatchSpecLen_Error_Data;\r
560           */\r
561           break;\r
562         }\r
563         \r
564         curLen = ((rem < len) ? (unsigned)rem : len);\r
565         pos = dicPos - rep0 + (dicPos < rep0 ? dicBufSize : 0);\r
566 \r
567         processedPos += (UInt32)curLen;\r
568 \r
569         len -= curLen;\r
570         if (curLen <= dicBufSize - pos)\r
571         {\r
572           Byte *dest = dic + dicPos;\r
573           ptrdiff_t src = (ptrdiff_t)pos - (ptrdiff_t)dicPos;\r
574           const Byte *lim = dest + curLen;\r
575           dicPos += (SizeT)curLen;\r
576           do\r
577             *(dest) = (Byte)*(dest + src);\r
578           while (++dest != lim);\r
579         }\r
580         else\r
581         {\r
582           do\r
583           {\r
584             dic[dicPos++] = dic[pos];\r
585             if (++pos == dicBufSize)\r
586               pos = 0;\r
587           }\r
588           while (--curLen != 0);\r
589         }\r
590       }\r
591     }\r
592   }\r
593   while (dicPos < limit && buf < bufLimit);\r
594 \r
595   NORMALIZE;\r
596   \r
597   p->buf = buf;\r
598   p->range = range;\r
599   p->code = code;\r
600   p->remainLen = (UInt32)len; // & (kMatchSpecLen_Error_Data - 1); // we can write real length for error matches too.\r
601   p->dicPos = dicPos;\r
602   p->processedPos = processedPos;\r
603   p->reps[0] = rep0;\r
604   p->reps[1] = rep1;\r
605   p->reps[2] = rep2;\r
606   p->reps[3] = rep3;\r
607   p->state = (UInt32)state;\r
608   if (len >= kMatchSpecLen_Error_Data)\r
609     return SZ_ERROR_DATA;\r
610   return SZ_OK;\r
611 }\r
612 #endif\r
613 \r
614 \r
615 \r
616 static void MY_FAST_CALL LzmaDec_WriteRem(CLzmaDec *p, SizeT limit)\r
617 {\r
618   unsigned len = (unsigned)p->remainLen;\r
619   if (len == 0 /* || len >= kMatchSpecLenStart */)\r
620     return;\r
621   {\r
622     SizeT dicPos = p->dicPos;\r
623     Byte *dic;\r
624     SizeT dicBufSize;\r
625     SizeT rep0;   /* we use SizeT to avoid the BUG of VC14 for AMD64 */\r
626     {\r
627       SizeT rem = limit - dicPos;\r
628       if (rem < len)\r
629       {\r
630         len = (unsigned)(rem);\r
631         if (len == 0)\r
632           return;\r
633       }\r
634     }\r
635 \r
636     if (p->checkDicSize == 0 && p->prop.dicSize - p->processedPos <= len)\r
637       p->checkDicSize = p->prop.dicSize;\r
638 \r
639     p->processedPos += (UInt32)len;\r
640     p->remainLen -= (UInt32)len;\r
641     dic = p->dic;\r
642     rep0 = p->reps[0];\r
643     dicBufSize = p->dicBufSize;\r
644     do\r
645     {\r
646       dic[dicPos] = dic[dicPos - rep0 + (dicPos < rep0 ? dicBufSize : 0)];\r
647       dicPos++;\r
648     }\r
649     while (--len);\r
650     p->dicPos = dicPos;\r
651   }\r
652 }\r
653 \r
654 \r
655 /*\r
656 At staring of new stream we have one of the following symbols:\r
657   - Literal        - is allowed\r
658   - Non-Rep-Match  - is allowed only if it's end marker symbol\r
659   - Rep-Match      - is not allowed\r
660 We use early check of (RangeCoder:Code) over kBadRepCode to simplify main decoding code\r
661 */\r
662 \r
663 #define kRange0 0xFFFFFFFF\r
664 #define kBound0 ((kRange0 >> kNumBitModelTotalBits) << (kNumBitModelTotalBits - 1))\r
665 #define kBadRepCode (kBound0 + (((kRange0 - kBound0) >> kNumBitModelTotalBits) << (kNumBitModelTotalBits - 1)))\r
666 #if kBadRepCode != (0xC0000000 - 0x400)\r
667   #error Stop_Compiling_Bad_LZMA_Check\r
668 #endif\r
669 \r
670 \r
671 /*\r
672 LzmaDec_DecodeReal2():\r
673   It calls LZMA_DECODE_REAL() and it adjusts limit according (p->checkDicSize).\r
674 \r
675 We correct (p->checkDicSize) after LZMA_DECODE_REAL() and in LzmaDec_WriteRem(),\r
676 and we support the following state of (p->checkDicSize):\r
677   if (total_processed < p->prop.dicSize) then\r
678   {\r
679     (total_processed == p->processedPos)\r
680     (p->checkDicSize == 0)\r
681   }\r
682   else\r
683     (p->checkDicSize == p->prop.dicSize)\r
684 */\r
685 \r
686 static int MY_FAST_CALL LzmaDec_DecodeReal2(CLzmaDec *p, SizeT limit, const Byte *bufLimit)\r
687 {\r
688   if (p->checkDicSize == 0)\r
689   {\r
690     UInt32 rem = p->prop.dicSize - p->processedPos;\r
691     if (limit - p->dicPos > rem)\r
692       limit = p->dicPos + rem;\r
693   }\r
694   {\r
695     int res = LZMA_DECODE_REAL(p, limit, bufLimit);\r
696     if (p->checkDicSize == 0 && p->processedPos >= p->prop.dicSize)\r
697       p->checkDicSize = p->prop.dicSize;\r
698     return res;\r
699   }\r
700 }\r
701 \r
702 \r
703 \r
704 typedef enum\r
705 {\r
706   DUMMY_INPUT_EOF, /* need more input data */\r
707   DUMMY_LIT,\r
708   DUMMY_MATCH,\r
709   DUMMY_REP\r
710 } ELzmaDummy;\r
711 \r
712 \r
713 #define IS_DUMMY_END_MARKER_POSSIBLE(dummyRes) ((dummyRes) == DUMMY_MATCH)\r
714 \r
715 static ELzmaDummy LzmaDec_TryDummy(const CLzmaDec *p, const Byte *buf, const Byte **bufOut)\r
716 {\r
717   UInt32 range = p->range;\r
718   UInt32 code = p->code;\r
719   const Byte *bufLimit = *bufOut;\r
720   const CLzmaProb *probs = GET_PROBS;\r
721   unsigned state = (unsigned)p->state;\r
722   ELzmaDummy res;\r
723 \r
724   for (;;)\r
725   {\r
726     const CLzmaProb *prob;\r
727     UInt32 bound;\r
728     unsigned ttt;\r
729     unsigned posState = CALC_POS_STATE(p->processedPos, ((unsigned)1 << p->prop.pb) - 1);\r
730 \r
731     prob = probs + IsMatch + COMBINED_PS_STATE;\r
732     IF_BIT_0_CHECK(prob)\r
733     {\r
734       UPDATE_0_CHECK\r
735 \r
736       prob = probs + Literal;\r
737       if (p->checkDicSize != 0 || p->processedPos != 0)\r
738         prob += ((UInt32)LZMA_LIT_SIZE *\r
739             ((((p->processedPos) & (((unsigned)1 << (p->prop.lp)) - 1)) << p->prop.lc) +\r
740             ((unsigned)p->dic[(p->dicPos == 0 ? p->dicBufSize : p->dicPos) - 1] >> (8 - p->prop.lc))));\r
741 \r
742       if (state < kNumLitStates)\r
743       {\r
744         unsigned symbol = 1;\r
745         do { GET_BIT_CHECK(prob + symbol, symbol) } while (symbol < 0x100);\r
746       }\r
747       else\r
748       {\r
749         unsigned matchByte = p->dic[p->dicPos - p->reps[0] +\r
750             (p->dicPos < p->reps[0] ? p->dicBufSize : 0)];\r
751         unsigned offs = 0x100;\r
752         unsigned symbol = 1;\r
753         do\r
754         {\r
755           unsigned bit;\r
756           const CLzmaProb *probLit;\r
757           matchByte += matchByte;\r
758           bit = offs;\r
759           offs &= matchByte;\r
760           probLit = prob + (offs + bit + symbol);\r
761           GET_BIT2_CHECK(probLit, symbol, offs ^= bit; , ; )\r
762         }\r
763         while (symbol < 0x100);\r
764       }\r
765       res = DUMMY_LIT;\r
766     }\r
767     else\r
768     {\r
769       unsigned len;\r
770       UPDATE_1_CHECK;\r
771 \r
772       prob = probs + IsRep + state;\r
773       IF_BIT_0_CHECK(prob)\r
774       {\r
775         UPDATE_0_CHECK;\r
776         state = 0;\r
777         prob = probs + LenCoder;\r
778         res = DUMMY_MATCH;\r
779       }\r
780       else\r
781       {\r
782         UPDATE_1_CHECK;\r
783         res = DUMMY_REP;\r
784         prob = probs + IsRepG0 + state;\r
785         IF_BIT_0_CHECK(prob)\r
786         {\r
787           UPDATE_0_CHECK;\r
788           prob = probs + IsRep0Long + COMBINED_PS_STATE;\r
789           IF_BIT_0_CHECK(prob)\r
790           {\r
791             UPDATE_0_CHECK;\r
792             break;\r
793           }\r
794           else\r
795           {\r
796             UPDATE_1_CHECK;\r
797           }\r
798         }\r
799         else\r
800         {\r
801           UPDATE_1_CHECK;\r
802           prob = probs + IsRepG1 + state;\r
803           IF_BIT_0_CHECK(prob)\r
804           {\r
805             UPDATE_0_CHECK;\r
806           }\r
807           else\r
808           {\r
809             UPDATE_1_CHECK;\r
810             prob = probs + IsRepG2 + state;\r
811             IF_BIT_0_CHECK(prob)\r
812             {\r
813               UPDATE_0_CHECK;\r
814             }\r
815             else\r
816             {\r
817               UPDATE_1_CHECK;\r
818             }\r
819           }\r
820         }\r
821         state = kNumStates;\r
822         prob = probs + RepLenCoder;\r
823       }\r
824       {\r
825         unsigned limit, offset;\r
826         const CLzmaProb *probLen = prob + LenChoice;\r
827         IF_BIT_0_CHECK(probLen)\r
828         {\r
829           UPDATE_0_CHECK;\r
830           probLen = prob + LenLow + GET_LEN_STATE;\r
831           offset = 0;\r
832           limit = 1 << kLenNumLowBits;\r
833         }\r
834         else\r
835         {\r
836           UPDATE_1_CHECK;\r
837           probLen = prob + LenChoice2;\r
838           IF_BIT_0_CHECK(probLen)\r
839           {\r
840             UPDATE_0_CHECK;\r
841             probLen = prob + LenLow + GET_LEN_STATE + (1 << kLenNumLowBits);\r
842             offset = kLenNumLowSymbols;\r
843             limit = 1 << kLenNumLowBits;\r
844           }\r
845           else\r
846           {\r
847             UPDATE_1_CHECK;\r
848             probLen = prob + LenHigh;\r
849             offset = kLenNumLowSymbols * 2;\r
850             limit = 1 << kLenNumHighBits;\r
851           }\r
852         }\r
853         TREE_DECODE_CHECK(probLen, limit, len);\r
854         len += offset;\r
855       }\r
856 \r
857       if (state < 4)\r
858       {\r
859         unsigned posSlot;\r
860         prob = probs + PosSlot +\r
861             ((len < kNumLenToPosStates - 1 ? len : kNumLenToPosStates - 1) <<\r
862             kNumPosSlotBits);\r
863         TREE_DECODE_CHECK(prob, 1 << kNumPosSlotBits, posSlot);\r
864         if (posSlot >= kStartPosModelIndex)\r
865         {\r
866           unsigned numDirectBits = ((posSlot >> 1) - 1);\r
867 \r
868           if (posSlot < kEndPosModelIndex)\r
869           {\r
870             prob = probs + SpecPos + ((2 | (posSlot & 1)) << numDirectBits);\r
871           }\r
872           else\r
873           {\r
874             numDirectBits -= kNumAlignBits;\r
875             do\r
876             {\r
877               NORMALIZE_CHECK\r
878               range >>= 1;\r
879               code -= range & (((code - range) >> 31) - 1);\r
880               /* if (code >= range) code -= range; */\r
881             }\r
882             while (--numDirectBits);\r
883             prob = probs + Align;\r
884             numDirectBits = kNumAlignBits;\r
885           }\r
886           {\r
887             unsigned i = 1;\r
888             unsigned m = 1;\r
889             do\r
890             {\r
891               REV_BIT_CHECK(prob, i, m);\r
892             }\r
893             while (--numDirectBits);\r
894           }\r
895         }\r
896       }\r
897     }\r
898     break;\r
899   }\r
900   NORMALIZE_CHECK;\r
901 \r
902   *bufOut = buf;\r
903   return res;\r
904 }\r
905 \r
906 void LzmaDec_InitDicAndState(CLzmaDec *p, BoolInt initDic, BoolInt initState);\r
907 void LzmaDec_InitDicAndState(CLzmaDec *p, BoolInt initDic, BoolInt initState)\r
908 {\r
909   p->remainLen = kMatchSpecLenStart + 1;\r
910   p->tempBufSize = 0;\r
911 \r
912   if (initDic)\r
913   {\r
914     p->processedPos = 0;\r
915     p->checkDicSize = 0;\r
916     p->remainLen = kMatchSpecLenStart + 2;\r
917   }\r
918   if (initState)\r
919     p->remainLen = kMatchSpecLenStart + 2;\r
920 }\r
921 \r
922 void LzmaDec_Init(CLzmaDec *p)\r
923 {\r
924   p->dicPos = 0;\r
925   LzmaDec_InitDicAndState(p, True, True);\r
926 }\r
927 \r
928 \r
929 /*\r
930 LZMA supports optional end_marker.\r
931 So the decoder can lookahead for one additional LZMA-Symbol to check end_marker.\r
932 That additional LZMA-Symbol can require up to LZMA_REQUIRED_INPUT_MAX bytes in input stream.\r
933 When the decoder reaches dicLimit, it looks (finishMode) parameter:\r
934   if (finishMode == LZMA_FINISH_ANY), the decoder doesn't lookahead\r
935   if (finishMode != LZMA_FINISH_ANY), the decoder lookahead, if end_marker is possible for current position\r
936 \r
937 When the decoder lookahead, and the lookahead symbol is not end_marker, we have two ways:\r
938   1) Strict mode (default) : the decoder returns SZ_ERROR_DATA.\r
939   2) The relaxed mode (alternative mode) : we could return SZ_OK, and the caller\r
940      must check (status) value. The caller can show the error,\r
941      if the end of stream is expected, and the (status) is noit\r
942      LZMA_STATUS_FINISHED_WITH_MARK or LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK.\r
943 */\r
944 \r
945 \r
946 #define RETURN__NOT_FINISHED__FOR_FINISH \\r
947   *status = LZMA_STATUS_NOT_FINISHED; \\r
948   return SZ_ERROR_DATA; // for strict mode\r
949   // return SZ_OK; // for relaxed mode\r
950 \r
951 \r
952 SRes LzmaDec_DecodeToDic(CLzmaDec *p, SizeT dicLimit, const Byte *src, SizeT *srcLen,\r
953     ELzmaFinishMode finishMode, ELzmaStatus *status)\r
954 {\r
955   SizeT inSize = *srcLen;\r
956   (*srcLen) = 0;\r
957   *status = LZMA_STATUS_NOT_SPECIFIED;\r
958 \r
959   if (p->remainLen > kMatchSpecLenStart)\r
960   {\r
961     if (p->remainLen > kMatchSpecLenStart + 2)\r
962       return p->remainLen == kMatchSpecLen_Error_Fail ? SZ_ERROR_FAIL : SZ_ERROR_DATA;\r
963 \r
964     for (; inSize > 0 && p->tempBufSize < RC_INIT_SIZE; (*srcLen)++, inSize--)\r
965       p->tempBuf[p->tempBufSize++] = *src++;\r
966     if (p->tempBufSize != 0 && p->tempBuf[0] != 0)\r
967       return SZ_ERROR_DATA;\r
968     if (p->tempBufSize < RC_INIT_SIZE)\r
969     {\r
970       *status = LZMA_STATUS_NEEDS_MORE_INPUT;\r
971       return SZ_OK;\r
972     }\r
973     p->code =\r
974         ((UInt32)p->tempBuf[1] << 24)\r
975       | ((UInt32)p->tempBuf[2] << 16)\r
976       | ((UInt32)p->tempBuf[3] << 8)\r
977       | ((UInt32)p->tempBuf[4]);\r
978 \r
979     if (p->checkDicSize == 0\r
980         && p->processedPos == 0\r
981         && p->code >= kBadRepCode)\r
982       return SZ_ERROR_DATA;\r
983 \r
984     p->range = 0xFFFFFFFF;\r
985     p->tempBufSize = 0;\r
986 \r
987     if (p->remainLen > kMatchSpecLenStart + 1)\r
988     {\r
989       SizeT numProbs = LzmaProps_GetNumProbs(&p->prop);\r
990       SizeT i;\r
991       CLzmaProb *probs = p->probs;\r
992       for (i = 0; i < numProbs; i++)\r
993         probs[i] = kBitModelTotal >> 1;\r
994       p->reps[0] = p->reps[1] = p->reps[2] = p->reps[3] = 1;\r
995       p->state = 0;\r
996     }\r
997 \r
998     p->remainLen = 0;\r
999   }\r
1000 \r
1001   for (;;)\r
1002   {\r
1003     if (p->remainLen == kMatchSpecLenStart)\r
1004     {\r
1005       if (p->code != 0)\r
1006         return SZ_ERROR_DATA;\r
1007       *status = LZMA_STATUS_FINISHED_WITH_MARK;\r
1008       return SZ_OK;\r
1009     }\r
1010 \r
1011     LzmaDec_WriteRem(p, dicLimit);\r
1012 \r
1013     {\r
1014       // (p->remainLen == 0 || p->dicPos == dicLimit)\r
1015 \r
1016       int checkEndMarkNow = 0;\r
1017 \r
1018       if (p->dicPos >= dicLimit)\r
1019       {\r
1020         if (p->remainLen == 0 && p->code == 0)\r
1021         {\r
1022           *status = LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK;\r
1023           return SZ_OK;\r
1024         }\r
1025         if (finishMode == LZMA_FINISH_ANY)\r
1026         {\r
1027           *status = LZMA_STATUS_NOT_FINISHED;\r
1028           return SZ_OK;\r
1029         }\r
1030         if (p->remainLen != 0)\r
1031         {\r
1032           RETURN__NOT_FINISHED__FOR_FINISH;\r
1033         }\r
1034         checkEndMarkNow = 1;\r
1035       }\r
1036 \r
1037       // (p->remainLen == 0)\r
1038 \r
1039       if (p->tempBufSize == 0)\r
1040       {\r
1041         const Byte *bufLimit;\r
1042         int dummyProcessed = -1;\r
1043         \r
1044         if (inSize < LZMA_REQUIRED_INPUT_MAX || checkEndMarkNow)\r
1045         {\r
1046           const Byte *bufOut = src + inSize;\r
1047           \r
1048           ELzmaDummy dummyRes = LzmaDec_TryDummy(p, src, &bufOut);\r
1049           \r
1050           if (dummyRes == DUMMY_INPUT_EOF)\r
1051           {\r
1052             size_t i;\r
1053             if (inSize >= LZMA_REQUIRED_INPUT_MAX)\r
1054               break;\r
1055             (*srcLen) += inSize;\r
1056             p->tempBufSize = (unsigned)inSize;\r
1057             for (i = 0; i < inSize; i++)\r
1058               p->tempBuf[i] = src[i];\r
1059             *status = LZMA_STATUS_NEEDS_MORE_INPUT;\r
1060             return SZ_OK;\r
1061           }\r
1062  \r
1063           dummyProcessed = (int)(bufOut - src);\r
1064           if ((unsigned)dummyProcessed > LZMA_REQUIRED_INPUT_MAX)\r
1065             break;\r
1066           \r
1067           if (checkEndMarkNow && !IS_DUMMY_END_MARKER_POSSIBLE(dummyRes))\r
1068           {\r
1069             unsigned i;\r
1070             (*srcLen) += (unsigned)dummyProcessed;\r
1071             p->tempBufSize = (unsigned)dummyProcessed;\r
1072             for (i = 0; i < (unsigned)dummyProcessed; i++)\r
1073               p->tempBuf[i] = src[i];\r
1074             // p->remainLen = kMatchSpecLen_Error_Data;\r
1075             RETURN__NOT_FINISHED__FOR_FINISH;\r
1076           }\r
1077           \r
1078           bufLimit = src;\r
1079           // we will decode only one iteration\r
1080         }\r
1081         else\r
1082           bufLimit = src + inSize - LZMA_REQUIRED_INPUT_MAX;\r
1083 \r
1084         p->buf = src;\r
1085         \r
1086         {\r
1087           int res = LzmaDec_DecodeReal2(p, dicLimit, bufLimit);\r
1088           \r
1089           SizeT processed = (SizeT)(p->buf - src);\r
1090 \r
1091           if (dummyProcessed < 0)\r
1092           {\r
1093             if (processed > inSize)\r
1094               break;\r
1095           }\r
1096           else if ((unsigned)dummyProcessed != processed)\r
1097             break;\r
1098 \r
1099           src += processed;\r
1100           inSize -= processed;\r
1101           (*srcLen) += processed;\r
1102 \r
1103           if (res != SZ_OK)\r
1104           {\r
1105             p->remainLen = kMatchSpecLen_Error_Data;\r
1106             return SZ_ERROR_DATA;\r
1107           }\r
1108         }\r
1109         continue;\r
1110       }\r
1111 \r
1112       {\r
1113         // we have some data in (p->tempBuf)\r
1114         // in strict mode: tempBufSize is not enough for one Symbol decoding.\r
1115         // in relaxed mode: tempBufSize not larger than required for one Symbol decoding.\r
1116 \r
1117         unsigned rem = p->tempBufSize;\r
1118         unsigned ahead = 0;\r
1119         int dummyProcessed = -1;\r
1120         \r
1121         while (rem < LZMA_REQUIRED_INPUT_MAX && ahead < inSize)\r
1122           p->tempBuf[rem++] = src[ahead++];\r
1123         \r
1124         // ahead - the size of new data copied from (src) to (p->tempBuf)\r
1125         // rem   - the size of temp buffer including new data from (src)\r
1126         \r
1127         if (rem < LZMA_REQUIRED_INPUT_MAX || checkEndMarkNow)\r
1128         {\r
1129           const Byte *bufOut = p->tempBuf + rem;\r
1130         \r
1131           ELzmaDummy dummyRes = LzmaDec_TryDummy(p, p->tempBuf, &bufOut);\r
1132           \r
1133           if (dummyRes == DUMMY_INPUT_EOF)\r
1134           {\r
1135             if (rem >= LZMA_REQUIRED_INPUT_MAX)\r
1136               break;\r
1137             p->tempBufSize = rem;\r
1138             (*srcLen) += (SizeT)ahead;\r
1139             *status = LZMA_STATUS_NEEDS_MORE_INPUT;\r
1140             return SZ_OK;\r
1141           }\r
1142           \r
1143           dummyProcessed = (int)(bufOut - p->tempBuf);\r
1144 \r
1145           if ((unsigned)dummyProcessed < p->tempBufSize)\r
1146             break;\r
1147 \r
1148           if (checkEndMarkNow && !IS_DUMMY_END_MARKER_POSSIBLE(dummyRes))\r
1149           {\r
1150             (*srcLen) += (unsigned)dummyProcessed - p->tempBufSize;\r
1151             p->tempBufSize = (unsigned)dummyProcessed;\r
1152             // p->remainLen = kMatchSpecLen_Error_Data;\r
1153             RETURN__NOT_FINISHED__FOR_FINISH;\r
1154           }\r
1155         }\r
1156 \r
1157         p->buf = p->tempBuf;\r
1158         \r
1159         {\r
1160           // we decode one symbol from (p->tempBuf) here, so the (bufLimit) is equal to (p->buf)\r
1161           int res = LzmaDec_DecodeReal2(p, dicLimit, p->buf);\r
1162 \r
1163           SizeT processed = (SizeT)(p->buf - p->tempBuf);\r
1164           rem = p->tempBufSize;\r
1165           \r
1166           if (dummyProcessed < 0)\r
1167           {\r
1168             if (processed > LZMA_REQUIRED_INPUT_MAX)\r
1169               break;\r
1170             if (processed < rem)\r
1171               break;\r
1172           }\r
1173           else if ((unsigned)dummyProcessed != processed)\r
1174             break;\r
1175           \r
1176           processed -= rem;\r
1177 \r
1178           src += processed;\r
1179           inSize -= processed;\r
1180           (*srcLen) += processed;\r
1181           p->tempBufSize = 0;\r
1182           \r
1183           if (res != SZ_OK)\r
1184           {\r
1185             p->remainLen = kMatchSpecLen_Error_Data;\r
1186             return SZ_ERROR_DATA;\r
1187           }\r
1188         }\r
1189       }\r
1190     }\r
1191   }\r
1192 \r
1193   /*  Some unexpected error: internal error of code, memory corruption or hardware failure */\r
1194   p->remainLen = kMatchSpecLen_Error_Fail;\r
1195   return SZ_ERROR_FAIL;\r
1196 }\r
1197 \r
1198 \r
1199 \r
1200 SRes LzmaDec_DecodeToBuf(CLzmaDec *p, Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen, ELzmaFinishMode finishMode, ELzmaStatus *status)\r
1201 {\r
1202   SizeT outSize = *destLen;\r
1203   SizeT inSize = *srcLen;\r
1204   *srcLen = *destLen = 0;\r
1205   for (;;)\r
1206   {\r
1207     SizeT inSizeCur = inSize, outSizeCur, dicPos;\r
1208     ELzmaFinishMode curFinishMode;\r
1209     SRes res;\r
1210     if (p->dicPos == p->dicBufSize)\r
1211       p->dicPos = 0;\r
1212     dicPos = p->dicPos;\r
1213     if (outSize > p->dicBufSize - dicPos)\r
1214     {\r
1215       outSizeCur = p->dicBufSize;\r
1216       curFinishMode = LZMA_FINISH_ANY;\r
1217     }\r
1218     else\r
1219     {\r
1220       outSizeCur = dicPos + outSize;\r
1221       curFinishMode = finishMode;\r
1222     }\r
1223 \r
1224     res = LzmaDec_DecodeToDic(p, outSizeCur, src, &inSizeCur, curFinishMode, status);\r
1225     src += inSizeCur;\r
1226     inSize -= inSizeCur;\r
1227     *srcLen += inSizeCur;\r
1228     outSizeCur = p->dicPos - dicPos;\r
1229     memcpy(dest, p->dic + dicPos, outSizeCur);\r
1230     dest += outSizeCur;\r
1231     outSize -= outSizeCur;\r
1232     *destLen += outSizeCur;\r
1233     if (res != 0)\r
1234       return res;\r
1235     if (outSizeCur == 0 || outSize == 0)\r
1236       return SZ_OK;\r
1237   }\r
1238 }\r
1239 \r
1240 void LzmaDec_FreeProbs(CLzmaDec *p, ISzAllocPtr alloc)\r
1241 {\r
1242   ISzAlloc_Free(alloc, p->probs);\r
1243   p->probs = NULL;\r
1244 }\r
1245 \r
1246 static void LzmaDec_FreeDict(CLzmaDec *p, ISzAllocPtr alloc)\r
1247 {\r
1248   ISzAlloc_Free(alloc, p->dic);\r
1249   p->dic = NULL;\r
1250 }\r
1251 \r
1252 void LzmaDec_Free(CLzmaDec *p, ISzAllocPtr alloc)\r
1253 {\r
1254   LzmaDec_FreeProbs(p, alloc);\r
1255   LzmaDec_FreeDict(p, alloc);\r
1256 }\r
1257 \r
1258 SRes LzmaProps_Decode(CLzmaProps *p, const Byte *data, unsigned size)\r
1259 {\r
1260   UInt32 dicSize;\r
1261   Byte d;\r
1262   \r
1263   if (size < LZMA_PROPS_SIZE)\r
1264     return SZ_ERROR_UNSUPPORTED;\r
1265   else\r
1266     dicSize = data[1] | ((UInt32)data[2] << 8) | ((UInt32)data[3] << 16) | ((UInt32)data[4] << 24);\r
1267  \r
1268   if (dicSize < LZMA_DIC_MIN)\r
1269     dicSize = LZMA_DIC_MIN;\r
1270   p->dicSize = dicSize;\r
1271 \r
1272   d = data[0];\r
1273   if (d >= (9 * 5 * 5))\r
1274     return SZ_ERROR_UNSUPPORTED;\r
1275 \r
1276   p->lc = (Byte)(d % 9);\r
1277   d /= 9;\r
1278   p->pb = (Byte)(d / 5);\r
1279   p->lp = (Byte)(d % 5);\r
1280 \r
1281   return SZ_OK;\r
1282 }\r
1283 \r
1284 static SRes LzmaDec_AllocateProbs2(CLzmaDec *p, const CLzmaProps *propNew, ISzAllocPtr alloc)\r
1285 {\r
1286   UInt32 numProbs = LzmaProps_GetNumProbs(propNew);\r
1287   if (!p->probs || numProbs != p->numProbs)\r
1288   {\r
1289     LzmaDec_FreeProbs(p, alloc);\r
1290     p->probs = (CLzmaProb *)ISzAlloc_Alloc(alloc, numProbs * sizeof(CLzmaProb));\r
1291     if (!p->probs)\r
1292       return SZ_ERROR_MEM;\r
1293     p->probs_1664 = p->probs + 1664;\r
1294     p->numProbs = numProbs;\r
1295   }\r
1296   return SZ_OK;\r
1297 }\r
1298 \r
1299 SRes LzmaDec_AllocateProbs(CLzmaDec *p, const Byte *props, unsigned propsSize, ISzAllocPtr alloc)\r
1300 {\r
1301   CLzmaProps propNew;\r
1302   RINOK(LzmaProps_Decode(&propNew, props, propsSize));\r
1303   RINOK(LzmaDec_AllocateProbs2(p, &propNew, alloc));\r
1304   p->prop = propNew;\r
1305   return SZ_OK;\r
1306 }\r
1307 \r
1308 SRes LzmaDec_Allocate(CLzmaDec *p, const Byte *props, unsigned propsSize, ISzAllocPtr alloc)\r
1309 {\r
1310   CLzmaProps propNew;\r
1311   SizeT dicBufSize;\r
1312   RINOK(LzmaProps_Decode(&propNew, props, propsSize));\r
1313   RINOK(LzmaDec_AllocateProbs2(p, &propNew, alloc));\r
1314 \r
1315   {\r
1316     UInt32 dictSize = propNew.dicSize;\r
1317     SizeT mask = ((UInt32)1 << 12) - 1;\r
1318          if (dictSize >= ((UInt32)1 << 30)) mask = ((UInt32)1 << 22) - 1;\r
1319     else if (dictSize >= ((UInt32)1 << 22)) mask = ((UInt32)1 << 20) - 1;;\r
1320     dicBufSize = ((SizeT)dictSize + mask) & ~mask;\r
1321     if (dicBufSize < dictSize)\r
1322       dicBufSize = dictSize;\r
1323   }\r
1324 \r
1325   if (!p->dic || dicBufSize != p->dicBufSize)\r
1326   {\r
1327     LzmaDec_FreeDict(p, alloc);\r
1328     p->dic = (Byte *)ISzAlloc_Alloc(alloc, dicBufSize);\r
1329     if (!p->dic)\r
1330     {\r
1331       LzmaDec_FreeProbs(p, alloc);\r
1332       return SZ_ERROR_MEM;\r
1333     }\r
1334   }\r
1335   p->dicBufSize = dicBufSize;\r
1336   p->prop = propNew;\r
1337   return SZ_OK;\r
1338 }\r
1339 \r
1340 SRes LzmaDecode(Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen,\r
1341     const Byte *propData, unsigned propSize, ELzmaFinishMode finishMode,\r
1342     ELzmaStatus *status, ISzAllocPtr alloc)\r
1343 {\r
1344   CLzmaDec p;\r
1345   SRes res;\r
1346   SizeT outSize = *destLen, inSize = *srcLen;\r
1347   *destLen = *srcLen = 0;\r
1348   *status = LZMA_STATUS_NOT_SPECIFIED;\r
1349   if (inSize < RC_INIT_SIZE)\r
1350     return SZ_ERROR_INPUT_EOF;\r
1351   LzmaDec_Construct(&p);\r
1352   RINOK(LzmaDec_AllocateProbs(&p, propData, propSize, alloc));\r
1353   p.dic = dest;\r
1354   p.dicBufSize = outSize;\r
1355   LzmaDec_Init(&p);\r
1356   *srcLen = inSize;\r
1357   res = LzmaDec_DecodeToDic(&p, outSize, src, srcLen, finishMode, status);\r
1358   *destLen = p.dicPos;\r
1359   if (res == SZ_OK && *status == LZMA_STATUS_NEEDS_MORE_INPUT)\r
1360     res = SZ_ERROR_INPUT_EOF;\r
1361   LzmaDec_FreeProbs(&p, alloc);\r
1362   return res;\r
1363 }\r