3 #ifndef __LZMA_DECODER_H
4 #define __LZMA_DECODER_H
6 #include "../../../Common/MyCom.h"
7 #include "../../ICoder.h"
8 #include "../LZ/LZOutWindow.h"
9 #include "../RangeCoder/RangeCoderBitTree.h"
13 #include "../../../../C/Alloc.h"
21 typedef NRangeCoder::CBitDecoder<kNumMoveBits> CMyBitDecoder;
23 class CLiteralDecoder2
25 CMyBitDecoder _decoders[0x300];
29 for (int i = 0; i < 0x300; i++)
32 Byte DecodeNormal(NRangeCoder::CDecoder *rangeDecoder)
38 // symbol = (symbol << 1) | _decoders[0][symbol].Decode(rangeDecoder);
39 RC_GETBIT(kNumMoveBits, _decoders[symbol].Prob, symbol)
41 while (symbol < 0x100);
45 Byte DecodeWithMatchByte(NRangeCoder::CDecoder *rangeDecoder, Byte matchByte)
51 UInt32 matchBit = (matchByte >> 7) & 1;
53 // UInt32 bit = _decoders[1 + matchBit][symbol].Decode(rangeDecoder);
54 // symbol = (symbol << 1) | bit;
56 RC_GETBIT2(kNumMoveBits, _decoders[0x100 + (matchBit << 8) + symbol].Prob, symbol,
60 while (symbol < 0x100)
62 // symbol = (symbol << 1) | _decoders[0][symbol].Decode(rangeDecoder);
63 RC_GETBIT(kNumMoveBits, _decoders[symbol].Prob, symbol)
68 while (symbol < 0x100);
76 CLiteralDecoder2 *_coders;
81 CLiteralDecoder(): _coders(0) {}
82 ~CLiteralDecoder() { Free(); }
88 bool Create(int numPosBits, int numPrevBits)
90 if (_coders == 0 || (numPosBits + numPrevBits) !=
91 (_numPrevBits + _numPosBits) )
94 UInt32 numStates = 1 << (numPosBits + numPrevBits);
95 _coders = (CLiteralDecoder2 *)MyAlloc(numStates * sizeof(CLiteralDecoder2));
97 _numPosBits = numPosBits;
98 _posMask = (1 << numPosBits) - 1;
99 _numPrevBits = numPrevBits;
100 return (_coders != 0);
104 UInt32 numStates = 1 << (_numPrevBits + _numPosBits);
105 for (UInt32 i = 0; i < numStates; i++)
108 UInt32 GetState(UInt32 pos, Byte prevByte) const
109 { return ((pos & _posMask) << _numPrevBits) + (prevByte >> (8 - _numPrevBits)); }
110 Byte DecodeNormal(NRangeCoder::CDecoder *rangeDecoder, UInt32 pos, Byte prevByte)
111 { return _coders[GetState(pos, prevByte)].DecodeNormal(rangeDecoder); }
112 Byte DecodeWithMatchByte(NRangeCoder::CDecoder *rangeDecoder, UInt32 pos, Byte prevByte, Byte matchByte)
113 { return _coders[GetState(pos, prevByte)].DecodeWithMatchByte(rangeDecoder, matchByte); }
120 CMyBitDecoder _choice;
121 CMyBitDecoder _choice2;
122 NRangeCoder::CBitTreeDecoder<kNumMoveBits, kNumLowBits> _lowCoder[kNumPosStatesMax];
123 NRangeCoder::CBitTreeDecoder<kNumMoveBits, kNumMidBits> _midCoder[kNumPosStatesMax];
124 NRangeCoder::CBitTreeDecoder<kNumMoveBits, kNumHighBits> _highCoder;
126 void Init(UInt32 numPosStates)
130 for (UInt32 posState = 0; posState < numPosStates; posState++)
132 _lowCoder[posState].Init();
133 _midCoder[posState].Init();
137 UInt32 Decode(NRangeCoder::CDecoder *rangeDecoder, UInt32 posState)
139 if(_choice.Decode(rangeDecoder) == 0)
140 return _lowCoder[posState].Decode(rangeDecoder);
141 if(_choice2.Decode(rangeDecoder) == 0)
142 return kNumLowSymbols + _midCoder[posState].Decode(rangeDecoder);
143 return kNumLowSymbols + kNumMidSymbols + _highCoder.Decode(rangeDecoder);
150 public ICompressCoder,
151 public ICompressSetDecoderProperties2,
152 public ICompressGetInStreamProcessedSize,
153 #ifndef NO_READ_FROM_CODER
154 public ICompressSetInStream,
155 public ICompressSetOutStreamSize,
156 public ISequentialInStream,
160 CLZOutWindow _outWindowStream;
161 NRangeCoder::CDecoder _rangeDecoder;
163 CMyBitDecoder _isMatch[kNumStates][NLength::kNumPosStatesMax];
164 CMyBitDecoder _isRep[kNumStates];
165 CMyBitDecoder _isRepG0[kNumStates];
166 CMyBitDecoder _isRepG1[kNumStates];
167 CMyBitDecoder _isRepG2[kNumStates];
168 CMyBitDecoder _isRep0Long[kNumStates][NLength::kNumPosStatesMax];
170 NRangeCoder::CBitTreeDecoder<kNumMoveBits, kNumPosSlotBits> _posSlotDecoder[kNumLenToPosStates];
172 CMyBitDecoder _posDecoders[kNumFullDistances - kEndPosModelIndex];
173 NRangeCoder::CBitTreeDecoder<kNumMoveBits, kNumAlignBits> _posAlignDecoder;
175 NLength::CDecoder _lenDecoder;
176 NLength::CDecoder _repMatchLenDecoder;
178 CLiteralDecoder _literalDecoder;
180 UInt32 _posStateMask;
186 Int32 _remainLen; // -1 means end of stream. // -2 means need Init
188 bool _outSizeDefined;
191 HRESULT CodeSpec(UInt32 size);
194 #ifndef NO_READ_FROM_CODER
196 ICompressSetDecoderProperties2,
197 ICompressGetInStreamProcessedSize,
198 ICompressSetInStream,
199 ICompressSetOutStreamSize,
203 ICompressSetDecoderProperties2,
204 ICompressGetInStreamProcessedSize)
207 void ReleaseStreams()
209 _outWindowStream.ReleaseStream();
213 class CDecoderFlusher
218 CDecoderFlusher(CDecoder *decoder): _decoder(decoder), NeedFlush(true) {}
223 _decoder->ReleaseStreams();
227 HRESULT Flush() { return _outWindowStream.Flush(); }
229 STDMETHOD(CodeReal)(ISequentialInStream *inStream,
230 ISequentialOutStream *outStream, const UInt64 *inSize, const UInt64 *outSize,
231 ICompressProgressInfo *progress);
233 STDMETHOD(Code)(ISequentialInStream *inStream,
234 ISequentialOutStream *outStream, const UInt64 *inSize, const UInt64 *outSize,
235 ICompressProgressInfo *progress);
237 STDMETHOD(SetDecoderProperties2)(const Byte *data, UInt32 size);
239 STDMETHOD(GetInStreamProcessedSize)(UInt64 *value);
241 STDMETHOD(SetInStream)(ISequentialInStream *inStream);
242 STDMETHOD(ReleaseInStream)();
243 STDMETHOD(SetOutStreamSize)(const UInt64 *outSize);
245 #ifndef NO_READ_FROM_CODER
246 STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize);
249 CDecoder(): _outSizeDefined(false) {}
250 virtual ~CDecoder() {}