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