3 LZMA Decoder (optimized for Size version)
5 LZMA SDK 4.27 Copyright (c) 1999-2005 Igor Pavlov (2005-08-07)
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"
25 #define Byte unsigned char
28 #define kNumTopBits 24
29 #define kTopValue ((UInt32)1 << kNumTopBits)
31 #define kNumBitModelTotalBits 11
32 #define kBitModelTotal (1 << kNumBitModelTotalBits)
33 #define kNumMoveBits 5
35 typedef struct _CRangeDecoder
38 const Byte
*BufferLim
;
42 ILzmaInCallback
*InCallback
;
48 Byte
RangeDecoderReadByte(CRangeDecoder
*rd
)
50 if (rd
->Buffer
== rd
->BufferLim
)
54 rd
->Result
= rd
->InCallback
->Read(rd
->InCallback
, &rd
->Buffer
, &size
);
55 rd
->BufferLim
= rd
->Buffer
+ size
;
63 return (*rd
->Buffer
++);
66 /* #define ReadByte (*rd->Buffer++) */
67 #define ReadByte (RangeDecoderReadByte(rd))
69 void RangeDecoderInit(CRangeDecoder
*rd
71 , const Byte
*stream
, SizeT bufferSize
77 rd
->Buffer
= rd
->BufferLim
= 0;
80 rd
->BufferLim
= stream
+ bufferSize
;
84 rd
->Range
= (0xFFFFFFFF);
85 for(i
= 0; i
< 5; i
++)
86 rd
->Code
= (rd
->Code
<< 8) | ReadByte
;
89 #define RC_INIT_VAR UInt32 range = rd->Range; UInt32 code = rd->Code;
90 #define RC_FLUSH_VAR rd->Range = range; rd->Code = code;
91 #define RC_NORMALIZE if (range < kTopValue) { range <<= 8; code = (code << 8) | ReadByte; }
93 UInt32
RangeDecoderDecodeDirectBits(CRangeDecoder
*rd
, int numTotalBits
)
98 for (i
= numTotalBits
; i
!= 0; i
--)
110 t = (code - range) >> 31;
112 code -= range & (t - 1);
113 result = (result + result) | (1 - t);
121 int RangeDecoderBitDecode(CProb
*prob
, CRangeDecoder
*rd
)
123 UInt32 bound
= (rd
->Range
>> kNumBitModelTotalBits
) * *prob
;
124 if (rd
->Code
< bound
)
127 *prob
+= (kBitModelTotal
- *prob
) >> kNumMoveBits
;
128 if (rd
->Range
< kTopValue
)
130 rd
->Code
= (rd
->Code
<< 8) | ReadByte
;
139 *prob
-= (*prob
) >> kNumMoveBits
;
140 if (rd
->Range
< kTopValue
)
142 rd
->Code
= (rd
->Code
<< 8) | ReadByte
;
149 #define RC_GET_BIT2(prob, mi, A0, A1) \
150 UInt32 bound = (range >> kNumBitModelTotalBits) * *prob; \
152 { A0; range = bound; *prob += (kBitModelTotal - *prob) >> kNumMoveBits; mi <<= 1; } \
154 { A1; range -= bound; code -= bound; *prob -= (*prob) >> kNumMoveBits; mi = (mi + mi) + 1; } \
157 #define RC_GET_BIT(prob, mi) RC_GET_BIT2(prob, mi, ; , ;)
159 int RangeDecoderBitTreeDecode(CProb
*probs
, int numLevels
, CRangeDecoder
*rd
)
166 for(i
= numLevels
; i
!= 0; i
--)
169 CProb
*prob
= probs
+ mi
;
172 mi
= (mi
+ mi
) + RangeDecoderBitDecode(probs
+ mi
, rd
);
178 return mi
- (1 << numLevels
);
181 int RangeDecoderReverseBitTreeDecode(CProb
*probs
, int numLevels
, CRangeDecoder
*rd
)
189 for(i
= 0; i
< numLevels
; i
++)
192 CProb
*prob
= probs
+ mi
;
193 RC_GET_BIT2(prob
, mi
, ; , symbol
|= (1 << i
))
195 int bit
= RangeDecoderBitDecode(probs
+ mi
, rd
);
197 symbol
|= (bit
<< i
);
206 Byte
LzmaLiteralDecode(CProb
*probs
, CRangeDecoder
*rd
)
215 CProb
*prob
= probs
+ symbol
;
216 RC_GET_BIT(prob
, symbol
)
218 symbol
= (symbol
+ symbol
) | RangeDecoderBitDecode(probs
+ symbol
, rd
);
221 while (symbol
< 0x100);
228 Byte
LzmaLiteralDecodeMatch(CProb
*probs
, CRangeDecoder
*rd
, Byte matchByte
)
237 int matchBit
= (matchByte
>> 7) & 1;
241 CProb
*prob
= probs
+ 0x100 + (matchBit
<< 8) + symbol
;
242 RC_GET_BIT2(prob
, symbol
, bit
= 0, bit
= 1)
245 bit
= RangeDecoderBitDecode(probs
+ 0x100 + (matchBit
<< 8) + symbol
, rd
);
246 symbol
= (symbol
<< 1) | bit
;
250 while (symbol
< 0x100)
253 CProb
*prob
= probs
+ symbol
;
254 RC_GET_BIT(prob
, symbol
)
256 symbol
= (symbol
+ symbol
) | RangeDecoderBitDecode(probs
+ symbol
, rd
);
262 while (symbol
< 0x100);
269 #define kNumPosBitsMax 4
270 #define kNumPosStatesMax (1 << kNumPosBitsMax)
272 #define kLenNumLowBits 3
273 #define kLenNumLowSymbols (1 << kLenNumLowBits)
274 #define kLenNumMidBits 3
275 #define kLenNumMidSymbols (1 << kLenNumMidBits)
276 #define kLenNumHighBits 8
277 #define kLenNumHighSymbols (1 << kLenNumHighBits)
280 #define LenChoice2 (LenChoice + 1)
281 #define LenLow (LenChoice2 + 1)
282 #define LenMid (LenLow + (kNumPosStatesMax << kLenNumLowBits))
283 #define LenHigh (LenMid + (kNumPosStatesMax << kLenNumMidBits))
284 #define kNumLenProbs (LenHigh + kLenNumHighSymbols)
286 int LzmaLenDecode(CProb
*p
, CRangeDecoder
*rd
, int posState
)
288 if(RangeDecoderBitDecode(p
+ LenChoice
, rd
) == 0)
289 return RangeDecoderBitTreeDecode(p
+ LenLow
+
290 (posState
<< kLenNumLowBits
), kLenNumLowBits
, rd
);
291 if(RangeDecoderBitDecode(p
+ LenChoice2
, rd
) == 0)
292 return kLenNumLowSymbols
+ RangeDecoderBitTreeDecode(p
+ LenMid
+
293 (posState
<< kLenNumMidBits
), kLenNumMidBits
, rd
);
294 return kLenNumLowSymbols
+ kLenNumMidSymbols
+
295 RangeDecoderBitTreeDecode(p
+ LenHigh
, kLenNumHighBits
, rd
);
298 #define kNumStates 12
299 #define kNumLitStates 7
301 #define kStartPosModelIndex 4
302 #define kEndPosModelIndex 14
303 #define kNumFullDistances (1 << (kEndPosModelIndex >> 1))
305 #define kNumPosSlotBits 6
306 #define kNumLenToPosStates 4
308 #define kNumAlignBits 4
309 #define kAlignTableSize (1 << kNumAlignBits)
311 #define kMatchMinLen 2
314 #define IsRep (IsMatch + (kNumStates << kNumPosBitsMax))
315 #define IsRepG0 (IsRep + kNumStates)
316 #define IsRepG1 (IsRepG0 + kNumStates)
317 #define IsRepG2 (IsRepG1 + kNumStates)
318 #define IsRep0Long (IsRepG2 + kNumStates)
319 #define PosSlot (IsRep0Long + (kNumStates << kNumPosBitsMax))
320 #define SpecPos (PosSlot + (kNumLenToPosStates << kNumPosSlotBits))
321 #define Align (SpecPos + kNumFullDistances - kEndPosModelIndex)
322 #define LenCoder (Align + kAlignTableSize)
323 #define RepLenCoder (LenCoder + kNumLenProbs)
324 #define Literal (RepLenCoder + kNumLenProbs)
326 #if Literal != LZMA_BASE_SIZE
330 int LzmaDecodeProperties(CLzmaProperties
*propsRes
, const unsigned char *propsData
, int size
)
333 if (size
< LZMA_PROPERTIES_SIZE
)
334 return LZMA_RESULT_DATA_ERROR
;
335 prop0
= propsData
[0];
336 if (prop0
>= (9 * 5 * 5))
337 return LZMA_RESULT_DATA_ERROR
;
339 for (propsRes
->pb
= 0; prop0
>= (9 * 5); propsRes
->pb
++, prop0
-= (9 * 5));
340 for (propsRes
->lp
= 0; prop0
>= 9; propsRes
->lp
++, prop0
-= 9);
341 propsRes
->lc
= prop0
;
343 unsigned char remainder = (unsigned char)(prop0 / 9);
344 propsRes->lc = prop0 % 9;
345 propsRes->pb = remainder / 5;
346 propsRes->lp = remainder % 5;
350 #ifdef _LZMA_OUT_READ
353 propsRes
->DictionarySize
= 0;
354 for (i
= 0; i
< 4; i
++)
355 propsRes
->DictionarySize
+= (UInt32
)(propsData
[1 + i
]) << (i
* 8);
356 if (propsRes
->DictionarySize
== 0)
357 propsRes
->DictionarySize
= 1;
360 return LZMA_RESULT_OK
;
363 #define kLzmaStreamWasFinishedId (-1)
365 int LzmaDecode(CLzmaDecoderState
*vs
,
367 ILzmaInCallback
*InCallback
,
369 const unsigned char *inStream
, SizeT inSize
, SizeT
*inSizeProcessed
,
371 unsigned char *outStream
, SizeT outSize
, SizeT
*outSizeProcessed
)
373 CProb
*p
= vs
->Probs
;
375 Byte previousByte
= 0;
376 UInt32 posStateMask
= (1 << (vs
->Properties
.pb
)) - 1;
377 UInt32 literalPosMask
= (1 << (vs
->Properties
.lp
)) - 1;
378 int lc
= vs
->Properties
.lc
;
381 #ifdef _LZMA_OUT_READ
383 int state
= vs
->State
;
384 UInt32 rep0
= vs
->Reps
[0], rep1
= vs
->Reps
[1], rep2
= vs
->Reps
[2], rep3
= vs
->Reps
[3];
385 int len
= vs
->RemainLen
;
386 UInt32 globalPos
= vs
->GlobalPos
;
387 UInt32 distanceLimit
= vs
->DistanceLimit
;
389 Byte
*dictionary
= vs
->Dictionary
;
390 UInt32 dictionarySize
= vs
->Properties
.DictionarySize
;
391 UInt32 dictionaryPos
= vs
->DictionaryPos
;
393 Byte tempDictionary
[4];
395 rd
.Range
= vs
->Range
;
398 rd
.InCallback
= InCallback
;
399 rd
.Buffer
= vs
->Buffer
;
400 rd
.BufferLim
= vs
->BufferLim
;
402 rd
.Buffer
= inStream
;
403 rd
.BufferLim
= inStream
+ inSize
;
407 *inSizeProcessed
= 0;
409 *outSizeProcessed
= 0;
410 if (len
== kLzmaStreamWasFinishedId
)
411 return LZMA_RESULT_OK
;
413 if (dictionarySize
== 0)
415 dictionary
= tempDictionary
;
417 tempDictionary
[0] = vs
->TempDictionary
[0];
420 if (len
== kLzmaNeedInitId
)
423 UInt32 numProbs
= Literal
+ ((UInt32
)LZMA_LIT_SIZE
<< (lc
+ vs
->Properties
.lp
));
425 for (i
= 0; i
< numProbs
; i
++)
426 p
[i
] = kBitModelTotal
>> 1;
427 rep0
= rep1
= rep2
= rep3
= 1;
432 dictionary
[dictionarySize
- 1] = 0;
439 if (rd
.Result
!= LZMA_RESULT_OK
)
442 if (rd
.ExtraBytes
!= 0)
443 return LZMA_RESULT_DATA_ERROR
;
447 while(len
!= 0 && nowPos
< outSize
)
449 UInt32 pos
= dictionaryPos
- rep0
;
450 if (pos
>= dictionarySize
)
451 pos
+= dictionarySize
;
452 outStream
[nowPos
++] = dictionary
[dictionaryPos
] = dictionary
[pos
];
453 if (++dictionaryPos
== dictionarySize
)
457 if (dictionaryPos
== 0)
458 previousByte
= dictionary
[dictionarySize
- 1];
460 previousByte
= dictionary
[dictionaryPos
- 1];
463 rd
.Result
= LZMA_RESULT_OK
;
467 #else /* if !_LZMA_OUT_READ */
470 UInt32 rep0
= 1, rep1
= 1, rep2
= 1, rep3
= 1;
474 *inSizeProcessed
= 0;
476 *outSizeProcessed
= 0;
480 UInt32 numProbs
= Literal
+ ((UInt32
)LZMA_LIT_SIZE
<< (lc
+ vs
->Properties
.lp
));
481 for (i
= 0; i
< numProbs
; i
++)
482 p
[i
] = kBitModelTotal
>> 1;
486 rd
.InCallback
= InCallback
;
495 if (rd
.Result
!= LZMA_RESULT_OK
)
498 if (rd
.ExtraBytes
!= 0)
499 return LZMA_RESULT_DATA_ERROR
;
501 #endif /* _LZMA_OUT_READ */
504 while(nowPos
< outSize
)
506 int posState
= (int)(
508 #ifdef _LZMA_OUT_READ
514 if (rd
.Result
!= LZMA_RESULT_OK
)
517 if (rd
.ExtraBytes
!= 0)
518 return LZMA_RESULT_DATA_ERROR
;
519 if (RangeDecoderBitDecode(p
+ IsMatch
+ (state
<< kNumPosBitsMax
) + posState
, &rd
) == 0)
521 CProb
*probs
= p
+ Literal
+ (LZMA_LIT_SIZE
*
524 #ifdef _LZMA_OUT_READ
528 & literalPosMask
) << lc
) + (previousByte
>> (8 - lc
))));
530 if (state
>= kNumLitStates
)
533 #ifdef _LZMA_OUT_READ
534 UInt32 pos
= dictionaryPos
- rep0
;
535 if (pos
>= dictionarySize
)
536 pos
+= dictionarySize
;
537 matchByte
= dictionary
[pos
];
539 matchByte
= outStream
[nowPos
- rep0
];
541 previousByte
= LzmaLiteralDecodeMatch(probs
, &rd
, matchByte
);
544 previousByte
= LzmaLiteralDecode(probs
, &rd
);
545 outStream
[nowPos
++] = previousByte
;
546 #ifdef _LZMA_OUT_READ
547 if (distanceLimit
< dictionarySize
)
550 dictionary
[dictionaryPos
] = previousByte
;
551 if (++dictionaryPos
== dictionarySize
)
554 if (state
< 4) state
= 0;
555 else if (state
< 10) state
-= 3;
560 if (RangeDecoderBitDecode(p
+ IsRep
+ state
, &rd
) == 1)
562 if (RangeDecoderBitDecode(p
+ IsRepG0
+ state
, &rd
) == 0)
564 if (RangeDecoderBitDecode(p
+ IsRep0Long
+ (state
<< kNumPosBitsMax
) + posState
, &rd
) == 0)
566 #ifdef _LZMA_OUT_READ
570 #ifdef _LZMA_OUT_READ
571 if (distanceLimit
== 0)
575 return LZMA_RESULT_DATA_ERROR
;
577 state
= state
< 7 ? 9 : 11;
578 #ifdef _LZMA_OUT_READ
579 pos
= dictionaryPos
- rep0
;
580 if (pos
>= dictionarySize
)
581 pos
+= dictionarySize
;
582 previousByte
= dictionary
[pos
];
583 dictionary
[dictionaryPos
] = previousByte
;
584 if (++dictionaryPos
== dictionarySize
)
587 previousByte
= outStream
[nowPos
- rep0
];
589 outStream
[nowPos
++] = previousByte
;
591 #ifdef _LZMA_OUT_READ
592 if (distanceLimit
< dictionarySize
)
601 if(RangeDecoderBitDecode(p
+ IsRepG1
+ state
, &rd
) == 0)
605 if(RangeDecoderBitDecode(p
+ IsRepG2
+ state
, &rd
) == 0)
617 len
= LzmaLenDecode(p
+ RepLenCoder
, &rd
, posState
);
618 state
= state
< 7 ? 8 : 11;
626 state
= state
< 7 ? 7 : 10;
627 len
= LzmaLenDecode(p
+ LenCoder
, &rd
, posState
);
628 posSlot
= RangeDecoderBitTreeDecode(p
+ PosSlot
+
629 ((len
< kNumLenToPosStates
? len
: kNumLenToPosStates
- 1) <<
630 kNumPosSlotBits
), kNumPosSlotBits
, &rd
);
631 if (posSlot
>= kStartPosModelIndex
)
633 int numDirectBits
= ((posSlot
>> 1) - 1);
634 rep0
= ((2 | ((UInt32
)posSlot
& 1)) << numDirectBits
);
635 if (posSlot
< kEndPosModelIndex
)
637 rep0
+= RangeDecoderReverseBitTreeDecode(
638 p
+ SpecPos
+ rep0
- posSlot
- 1, numDirectBits
, &rd
);
642 rep0
+= RangeDecoderDecodeDirectBits(&rd
,
643 numDirectBits
- kNumAlignBits
) << kNumAlignBits
;
644 rep0
+= RangeDecoderReverseBitTreeDecode(p
+ Align
, kNumAlignBits
, &rd
);
649 if (++rep0
== (UInt32
)(0))
651 /* it's for stream version */
652 len
= kLzmaStreamWasFinishedId
;
658 #ifdef _LZMA_OUT_READ
659 if (rep0
> distanceLimit
)
663 return LZMA_RESULT_DATA_ERROR
;
665 #ifdef _LZMA_OUT_READ
666 if (dictionarySize
- distanceLimit
> (UInt32
)len
)
667 distanceLimit
+= len
;
669 distanceLimit
= dictionarySize
;
674 #ifdef _LZMA_OUT_READ
675 UInt32 pos
= dictionaryPos
- rep0
;
676 if (pos
>= dictionarySize
)
677 pos
+= dictionarySize
;
678 previousByte
= dictionary
[pos
];
679 dictionary
[dictionaryPos
] = previousByte
;
680 if (++dictionaryPos
== dictionarySize
)
683 previousByte
= outStream
[nowPos
- rep0
];
686 outStream
[nowPos
++] = previousByte
;
688 while(len
!= 0 && nowPos
< outSize
);
693 #ifdef _LZMA_OUT_READ
694 vs
->Range
= rd
.Range
;
696 vs
->DictionaryPos
= dictionaryPos
;
697 vs
->GlobalPos
= globalPos
+ (UInt32
)nowPos
;
698 vs
->DistanceLimit
= distanceLimit
;
705 vs
->TempDictionary
[0] = tempDictionary
[0];
709 vs
->Buffer
= rd
.Buffer
;
710 vs
->BufferLim
= rd
.BufferLim
;
712 *inSizeProcessed
= (SizeT
)(rd
.Buffer
- inStream
);
714 *outSizeProcessed
= nowPos
;
715 return LZMA_RESULT_OK
;