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