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