3 LZMA Decoder (optimized for Size version)
5 LZMA SDK 4.40 Copyright (c) 1999-2006 Igor Pavlov (2006-05-01)
8 LZMA SDK is licensed under two licenses:
9 1) GNU Lesser General Public License (GNU LGPL)
10 2) Common Public License (CPL)
11 It means that you can select one of these two licenses and
12 follow rules of that license.
15 Igor Pavlov, as the author of this code, expressly permits you to
16 statically or dynamically link your code (or bind by name) to the
17 interfaces of this file without subjecting your linked code to the
18 terms of the CPL or GNU LGPL. Any modifications or additions
19 to this file, however, are subject to the LGPL or CPL terms.
22 #include "LzmaDecode.h"
24 #define kNumTopBits 24
25 #define kTopValue ((UInt32)1 << kNumTopBits)
27 #define kNumBitModelTotalBits 11
28 #define kBitModelTotal (1 << kNumBitModelTotalBits)
29 #define kNumMoveBits 5
31 typedef struct _CRangeDecoder
34 const Byte *BufferLim;
38 ILzmaInCallback *InCallback;
44 Byte RangeDecoderReadByte(CRangeDecoder *rd)
46 if (rd->Buffer == rd->BufferLim)
50 rd->Result = rd->InCallback->Read(rd->InCallback, &rd->Buffer, &size);
51 rd->BufferLim = rd->Buffer + size;
59 return (*rd->Buffer++);
62 /* #define ReadByte (*rd->Buffer++) */
63 #define ReadByte (RangeDecoderReadByte(rd))
65 void RangeDecoderInit(CRangeDecoder *rd
67 , const Byte *stream, SizeT bufferSize
73 rd->Buffer = rd->BufferLim = 0;
76 rd->BufferLim = stream + bufferSize;
80 rd->Range = (0xFFFFFFFF);
81 for(i = 0; i < 5; i++)
82 rd->Code = (rd->Code << 8) | ReadByte;
85 #define RC_INIT_VAR UInt32 range = rd->Range; UInt32 code = rd->Code;
86 #define RC_FLUSH_VAR rd->Range = range; rd->Code = code;
87 #define RC_NORMALIZE if (range < kTopValue) { range <<= 8; code = (code << 8) | ReadByte; }
89 UInt32 RangeDecoderDecodeDirectBits(CRangeDecoder *rd, int numTotalBits)
94 for (i = numTotalBits; i != 0; i--)
106 t = (code - range) >> 31;
108 code -= range & (t - 1);
109 result = (result + result) | (1 - t);
117 int RangeDecoderBitDecode(CProb *prob, CRangeDecoder *rd)
119 UInt32 bound = (rd->Range >> kNumBitModelTotalBits) * *prob;
120 if (rd->Code < bound)
123 *prob += (kBitModelTotal - *prob) >> kNumMoveBits;
124 if (rd->Range < kTopValue)
126 rd->Code = (rd->Code << 8) | ReadByte;
135 *prob -= (*prob) >> kNumMoveBits;
136 if (rd->Range < kTopValue)
138 rd->Code = (rd->Code << 8) | ReadByte;
145 #define RC_GET_BIT2(prob, mi, A0, A1) \
146 UInt32 bound = (range >> kNumBitModelTotalBits) * *prob; \
148 { A0; range = bound; *prob += (kBitModelTotal - *prob) >> kNumMoveBits; mi <<= 1; } \
150 { A1; range -= bound; code -= bound; *prob -= (*prob) >> kNumMoveBits; mi = (mi + mi) + 1; } \
153 #define RC_GET_BIT(prob, mi) RC_GET_BIT2(prob, mi, ; , ;)
155 int RangeDecoderBitTreeDecode(CProb *probs, int numLevels, CRangeDecoder *rd)
162 for(i = numLevels; i != 0; i--)
165 CProb *prob = probs + mi;
168 mi = (mi + mi) + RangeDecoderBitDecode(probs + mi, rd);
174 return mi - (1 << numLevels);
177 int RangeDecoderReverseBitTreeDecode(CProb *probs, int numLevels, CRangeDecoder *rd)
185 for(i = 0; i < numLevels; i++)
188 CProb *prob = probs + mi;
189 RC_GET_BIT2(prob, mi, ; , symbol |= (1 << i))
191 int bit = RangeDecoderBitDecode(probs + mi, rd);
193 symbol |= (bit << i);
202 Byte LzmaLiteralDecode(CProb *probs, CRangeDecoder *rd)
211 CProb *prob = probs + symbol;
212 RC_GET_BIT(prob, symbol)
214 symbol = (symbol + symbol) | RangeDecoderBitDecode(probs + symbol, rd);
217 while (symbol < 0x100);
224 Byte LzmaLiteralDecodeMatch(CProb *probs, CRangeDecoder *rd, Byte matchByte)
233 int matchBit = (matchByte >> 7) & 1;
237 CProb *prob = probs + 0x100 + (matchBit << 8) + symbol;
238 RC_GET_BIT2(prob, symbol, bit = 0, bit = 1)
241 bit = RangeDecoderBitDecode(probs + 0x100 + (matchBit << 8) + symbol, rd);
242 symbol = (symbol << 1) | bit;
246 while (symbol < 0x100)
249 CProb *prob = probs + symbol;
250 RC_GET_BIT(prob, symbol)
252 symbol = (symbol + symbol) | RangeDecoderBitDecode(probs + symbol, rd);
258 while (symbol < 0x100);
265 #define kNumPosBitsMax 4
266 #define kNumPosStatesMax (1 << kNumPosBitsMax)
268 #define kLenNumLowBits 3
269 #define kLenNumLowSymbols (1 << kLenNumLowBits)
270 #define kLenNumMidBits 3
271 #define kLenNumMidSymbols (1 << kLenNumMidBits)
272 #define kLenNumHighBits 8
273 #define kLenNumHighSymbols (1 << kLenNumHighBits)
276 #define LenChoice2 (LenChoice + 1)
277 #define LenLow (LenChoice2 + 1)
278 #define LenMid (LenLow + (kNumPosStatesMax << kLenNumLowBits))
279 #define LenHigh (LenMid + (kNumPosStatesMax << kLenNumMidBits))
280 #define kNumLenProbs (LenHigh + kLenNumHighSymbols)
282 int LzmaLenDecode(CProb *p, CRangeDecoder *rd, int posState)
284 if(RangeDecoderBitDecode(p + LenChoice, rd) == 0)
285 return RangeDecoderBitTreeDecode(p + LenLow +
286 (posState << kLenNumLowBits), kLenNumLowBits, rd);
287 if(RangeDecoderBitDecode(p + LenChoice2, rd) == 0)
288 return kLenNumLowSymbols + RangeDecoderBitTreeDecode(p + LenMid +
289 (posState << kLenNumMidBits), kLenNumMidBits, rd);
290 return kLenNumLowSymbols + kLenNumMidSymbols +
291 RangeDecoderBitTreeDecode(p + LenHigh, kLenNumHighBits, rd);
294 #define kNumStates 12
295 #define kNumLitStates 7
297 #define kStartPosModelIndex 4
298 #define kEndPosModelIndex 14
299 #define kNumFullDistances (1 << (kEndPosModelIndex >> 1))
301 #define kNumPosSlotBits 6
302 #define kNumLenToPosStates 4
304 #define kNumAlignBits 4
305 #define kAlignTableSize (1 << kNumAlignBits)
307 #define kMatchMinLen 2
310 #define IsRep (IsMatch + (kNumStates << kNumPosBitsMax))
311 #define IsRepG0 (IsRep + kNumStates)
312 #define IsRepG1 (IsRepG0 + kNumStates)
313 #define IsRepG2 (IsRepG1 + kNumStates)
314 #define IsRep0Long (IsRepG2 + kNumStates)
315 #define PosSlot (IsRep0Long + (kNumStates << kNumPosBitsMax))
316 #define SpecPos (PosSlot + (kNumLenToPosStates << kNumPosSlotBits))
317 #define Align (SpecPos + kNumFullDistances - kEndPosModelIndex)
318 #define LenCoder (Align + kAlignTableSize)
319 #define RepLenCoder (LenCoder + kNumLenProbs)
320 #define Literal (RepLenCoder + kNumLenProbs)
322 #if Literal != LZMA_BASE_SIZE
326 int LzmaDecodeProperties(CLzmaProperties *propsRes, const unsigned char *propsData, int size)
329 if (size < LZMA_PROPERTIES_SIZE)
330 return LZMA_RESULT_DATA_ERROR;
331 prop0 = propsData[0];
332 if (prop0 >= (9 * 5 * 5))
333 return LZMA_RESULT_DATA_ERROR;
335 for (propsRes->pb = 0; prop0 >= (9 * 5); propsRes->pb++, prop0 -= (9 * 5));
336 for (propsRes->lp = 0; prop0 >= 9; propsRes->lp++, prop0 -= 9);
337 propsRes->lc = prop0;
339 unsigned char remainder = (unsigned char)(prop0 / 9);
340 propsRes->lc = prop0 % 9;
341 propsRes->pb = remainder / 5;
342 propsRes->lp = remainder % 5;
346 #ifdef _LZMA_OUT_READ
349 propsRes->DictionarySize = 0;
350 for (i = 0; i < 4; i++)
351 propsRes->DictionarySize += (UInt32)(propsData[1 + i]) << (i * 8);
352 if (propsRes->DictionarySize == 0)
353 propsRes->DictionarySize = 1;
356 return LZMA_RESULT_OK;
359 #define kLzmaStreamWasFinishedId (-1)
361 int LzmaDecode(CLzmaDecoderState *vs,
363 ILzmaInCallback *InCallback,
365 const unsigned char *inStream, SizeT inSize, SizeT *inSizeProcessed,
367 unsigned char *outStream, SizeT outSize, SizeT *outSizeProcessed)
369 CProb *p = vs->Probs;
371 Byte previousByte = 0;
372 UInt32 posStateMask = (1 << (vs->Properties.pb)) - 1;
373 UInt32 literalPosMask = (1 << (vs->Properties.lp)) - 1;
374 int lc = vs->Properties.lc;
377 #ifdef _LZMA_OUT_READ
379 int state = vs->State;
380 UInt32 rep0 = vs->Reps[0], rep1 = vs->Reps[1], rep2 = vs->Reps[2], rep3 = vs->Reps[3];
381 int len = vs->RemainLen;
382 UInt32 globalPos = vs->GlobalPos;
383 UInt32 distanceLimit = vs->DistanceLimit;
385 Byte *dictionary = vs->Dictionary;
386 UInt32 dictionarySize = vs->Properties.DictionarySize;
387 UInt32 dictionaryPos = vs->DictionaryPos;
389 Byte tempDictionary[4];
391 rd.Range = vs->Range;
394 rd.InCallback = InCallback;
395 rd.Buffer = vs->Buffer;
396 rd.BufferLim = vs->BufferLim;
398 rd.Buffer = inStream;
399 rd.BufferLim = inStream + inSize;
403 *inSizeProcessed = 0;
405 *outSizeProcessed = 0;
406 if (len == kLzmaStreamWasFinishedId)
407 return LZMA_RESULT_OK;
409 if (dictionarySize == 0)
411 dictionary = tempDictionary;
413 tempDictionary[0] = vs->TempDictionary[0];
416 if (len == kLzmaNeedInitId)
419 UInt32 numProbs = Literal + ((UInt32)LZMA_LIT_SIZE << (lc + vs->Properties.lp));
421 for (i = 0; i < numProbs; i++)
422 p[i] = kBitModelTotal >> 1;
423 rep0 = rep1 = rep2 = rep3 = 1;
428 dictionary[dictionarySize - 1] = 0;
435 if (rd.Result != LZMA_RESULT_OK)
438 if (rd.ExtraBytes != 0)
439 return LZMA_RESULT_DATA_ERROR;
443 while(len != 0 && nowPos < outSize)
445 UInt32 pos = dictionaryPos - rep0;
446 if (pos >= dictionarySize)
447 pos += dictionarySize;
448 outStream[nowPos++] = dictionary[dictionaryPos] = dictionary[pos];
449 if (++dictionaryPos == dictionarySize)
453 if (dictionaryPos == 0)
454 previousByte = dictionary[dictionarySize - 1];
456 previousByte = dictionary[dictionaryPos - 1];
459 rd.Result = LZMA_RESULT_OK;
463 #else /* if !_LZMA_OUT_READ */
466 UInt32 rep0 = 1, rep1 = 1, rep2 = 1, rep3 = 1;
470 *inSizeProcessed = 0;
472 *outSizeProcessed = 0;
476 UInt32 numProbs = Literal + ((UInt32)LZMA_LIT_SIZE << (lc + vs->Properties.lp));
477 for (i = 0; i < numProbs; i++)
478 p[i] = kBitModelTotal >> 1;
482 rd.InCallback = InCallback;
491 if (rd.Result != LZMA_RESULT_OK)
494 if (rd.ExtraBytes != 0)
495 return LZMA_RESULT_DATA_ERROR;
497 #endif /* _LZMA_OUT_READ */
500 while(nowPos < outSize)
502 int posState = (int)(
504 #ifdef _LZMA_OUT_READ
510 if (rd.Result != LZMA_RESULT_OK)
513 if (rd.ExtraBytes != 0)
514 return LZMA_RESULT_DATA_ERROR;
515 if (RangeDecoderBitDecode(p + IsMatch + (state << kNumPosBitsMax) + posState, &rd) == 0)
517 CProb *probs = p + Literal + (LZMA_LIT_SIZE *
520 #ifdef _LZMA_OUT_READ
524 & literalPosMask) << lc) + (previousByte >> (8 - lc))));
526 if (state >= kNumLitStates)
529 #ifdef _LZMA_OUT_READ
530 UInt32 pos = dictionaryPos - rep0;
531 if (pos >= dictionarySize)
532 pos += dictionarySize;
533 matchByte = dictionary[pos];
535 matchByte = outStream[nowPos - rep0];
537 previousByte = LzmaLiteralDecodeMatch(probs, &rd, matchByte);
540 previousByte = LzmaLiteralDecode(probs, &rd);
541 outStream[nowPos++] = previousByte;
542 #ifdef _LZMA_OUT_READ
543 if (distanceLimit < dictionarySize)
546 dictionary[dictionaryPos] = previousByte;
547 if (++dictionaryPos == dictionarySize)
550 if (state < 4) state = 0;
551 else if (state < 10) state -= 3;
556 if (RangeDecoderBitDecode(p + IsRep + state, &rd) == 1)
558 if (RangeDecoderBitDecode(p + IsRepG0 + state, &rd) == 0)
560 if (RangeDecoderBitDecode(p + IsRep0Long + (state << kNumPosBitsMax) + posState, &rd) == 0)
562 #ifdef _LZMA_OUT_READ
566 #ifdef _LZMA_OUT_READ
567 if (distanceLimit == 0)
571 return LZMA_RESULT_DATA_ERROR;
573 state = state < 7 ? 9 : 11;
574 #ifdef _LZMA_OUT_READ
575 pos = dictionaryPos - rep0;
576 if (pos >= dictionarySize)
577 pos += dictionarySize;
578 previousByte = dictionary[pos];
579 dictionary[dictionaryPos] = previousByte;
580 if (++dictionaryPos == dictionarySize)
583 previousByte = outStream[nowPos - rep0];
585 outStream[nowPos++] = previousByte;
587 #ifdef _LZMA_OUT_READ
588 if (distanceLimit < dictionarySize)
597 if(RangeDecoderBitDecode(p + IsRepG1 + state, &rd) == 0)
601 if(RangeDecoderBitDecode(p + IsRepG2 + state, &rd) == 0)
613 len = LzmaLenDecode(p + RepLenCoder, &rd, posState);
614 state = state < 7 ? 8 : 11;
622 state = state < 7 ? 7 : 10;
623 len = LzmaLenDecode(p + LenCoder, &rd, posState);
624 posSlot = RangeDecoderBitTreeDecode(p + PosSlot +
625 ((len < kNumLenToPosStates ? len : kNumLenToPosStates - 1) <<
626 kNumPosSlotBits), kNumPosSlotBits, &rd);
627 if (posSlot >= kStartPosModelIndex)
629 int numDirectBits = ((posSlot >> 1) - 1);
630 rep0 = ((2 | ((UInt32)posSlot & 1)) << numDirectBits);
631 if (posSlot < kEndPosModelIndex)
633 rep0 += RangeDecoderReverseBitTreeDecode(
634 p + SpecPos + rep0 - posSlot - 1, numDirectBits, &rd);
638 rep0 += RangeDecoderDecodeDirectBits(&rd,
639 numDirectBits - kNumAlignBits) << kNumAlignBits;
640 rep0 += RangeDecoderReverseBitTreeDecode(p + Align, kNumAlignBits, &rd);
645 if (++rep0 == (UInt32)(0))
647 /* it's for stream version */
648 len = kLzmaStreamWasFinishedId;
654 #ifdef _LZMA_OUT_READ
655 if (rep0 > distanceLimit)
659 return LZMA_RESULT_DATA_ERROR;
661 #ifdef _LZMA_OUT_READ
662 if (dictionarySize - distanceLimit > (UInt32)len)
663 distanceLimit += len;
665 distanceLimit = dictionarySize;
670 #ifdef _LZMA_OUT_READ
671 UInt32 pos = dictionaryPos - rep0;
672 if (pos >= dictionarySize)
673 pos += dictionarySize;
674 previousByte = dictionary[pos];
675 dictionary[dictionaryPos] = previousByte;
676 if (++dictionaryPos == dictionarySize)
679 previousByte = outStream[nowPos - rep0];
682 outStream[nowPos++] = previousByte;
684 while(len != 0 && nowPos < outSize);
689 #ifdef _LZMA_OUT_READ
690 vs->Range = rd.Range;
692 vs->DictionaryPos = dictionaryPos;
693 vs->GlobalPos = globalPos + (UInt32)nowPos;
694 vs->DistanceLimit = distanceLimit;
701 vs->TempDictionary[0] = tempDictionary[0];
705 vs->Buffer = rd.Buffer;
706 vs->BufferLim = rd.BufferLim;
708 *inSizeProcessed = (SizeT)(rd.Buffer - inStream);
710 *outSizeProcessed = nowPos;
711 return LZMA_RESULT_OK;