3 #ifndef __LZMA_DECODER_H
4 #define __LZMA_DECODER_H
6 #include "../../../Common/MyCom.h"
7 #include "../../../Common/Alloc.h"
8 #include "../../ICoder.h"
9 #include "../LZ/LZOutWindow.h"
10 #include "../RangeCoder/RangeCoderBitTree.h"
17 typedef NRangeCoder::CBitDecoder
<kNumMoveBits
> CMyBitDecoder
;
19 class CLiteralDecoder2
21 CMyBitDecoder _decoders
[0x300];
25 for (int i
= 0; i
< 0x300; i
++)
28 Byte
DecodeNormal(NRangeCoder::CDecoder
*rangeDecoder
)
34 // symbol = (symbol << 1) | _decoders[0][symbol].Decode(rangeDecoder);
35 RC_GETBIT(kNumMoveBits
, _decoders
[symbol
].Prob
, symbol
)
37 while (symbol
< 0x100);
41 Byte
DecodeWithMatchByte(NRangeCoder::CDecoder
*rangeDecoder
, Byte matchByte
)
47 UInt32 matchBit
= (matchByte
>> 7) & 1;
49 // UInt32 bit = _decoders[1 + matchBit][symbol].Decode(rangeDecoder);
50 // symbol = (symbol << 1) | bit;
52 RC_GETBIT2(kNumMoveBits
, _decoders
[0x100 + (matchBit
<< 8) + symbol
].Prob
, symbol
,
56 while (symbol
< 0x100)
58 // symbol = (symbol << 1) | _decoders[0][symbol].Decode(rangeDecoder);
59 RC_GETBIT(kNumMoveBits
, _decoders
[symbol
].Prob
, symbol
)
64 while (symbol
< 0x100);
72 CLiteralDecoder2
*_coders
;
77 CLiteralDecoder(): _coders(0) {}
78 ~CLiteralDecoder() { Free(); }
84 bool Create(int numPosBits
, int numPrevBits
)
86 if (_coders
== 0 || (numPosBits
+ numPrevBits
) !=
87 (_numPrevBits
+ _numPosBits
) )
90 UInt32 numStates
= 1 << (numPosBits
+ numPrevBits
);
91 _coders
= (CLiteralDecoder2
*)MyAlloc(numStates
* sizeof(CLiteralDecoder2
));
93 _numPosBits
= numPosBits
;
94 _posMask
= (1 << numPosBits
) - 1;
95 _numPrevBits
= numPrevBits
;
96 return (_coders
!= 0);
100 UInt32 numStates
= 1 << (_numPrevBits
+ _numPosBits
);
101 for (UInt32 i
= 0; i
< numStates
; i
++)
104 UInt32
GetState(UInt32 pos
, Byte prevByte
) const
105 { return ((pos
& _posMask
) << _numPrevBits
) + (prevByte
>> (8 - _numPrevBits
)); }
106 Byte
DecodeNormal(NRangeCoder::CDecoder
*rangeDecoder
, UInt32 pos
, Byte prevByte
)
107 { return _coders
[GetState(pos
, prevByte
)].DecodeNormal(rangeDecoder
); }
108 Byte
DecodeWithMatchByte(NRangeCoder::CDecoder
*rangeDecoder
, UInt32 pos
, Byte prevByte
, Byte matchByte
)
109 { return _coders
[GetState(pos
, prevByte
)].DecodeWithMatchByte(rangeDecoder
, matchByte
); }
116 CMyBitDecoder _choice
;
117 CMyBitDecoder _choice2
;
118 NRangeCoder::CBitTreeDecoder
<kNumMoveBits
, kNumLowBits
> _lowCoder
[kNumPosStatesMax
];
119 NRangeCoder::CBitTreeDecoder
<kNumMoveBits
, kNumMidBits
> _midCoder
[kNumPosStatesMax
];
120 NRangeCoder::CBitTreeDecoder
<kNumMoveBits
, kNumHighBits
> _highCoder
;
122 void Init(UInt32 numPosStates
)
126 for (UInt32 posState
= 0; posState
< numPosStates
; posState
++)
128 _lowCoder
[posState
].Init();
129 _midCoder
[posState
].Init();
133 UInt32
Decode(NRangeCoder::CDecoder
*rangeDecoder
, UInt32 posState
)
135 if(_choice
.Decode(rangeDecoder
) == 0)
136 return _lowCoder
[posState
].Decode(rangeDecoder
);
137 if(_choice2
.Decode(rangeDecoder
) == 0)
138 return kNumLowSymbols
+ _midCoder
[posState
].Decode(rangeDecoder
);
139 return kNumLowSymbols
+ kNumMidSymbols
+ _highCoder
.Decode(rangeDecoder
);
146 public ICompressCoder
,
147 public ICompressSetDecoderProperties2
,
149 public ICompressSetInStream
,
150 public ICompressSetOutStreamSize
,
151 public ISequentialInStream
,
155 CLZOutWindow _outWindowStream
;
156 NRangeCoder::CDecoder _rangeDecoder
;
158 CMyBitDecoder _isMatch
[kNumStates
][NLength::kNumPosStatesMax
];
159 CMyBitDecoder _isRep
[kNumStates
];
160 CMyBitDecoder _isRepG0
[kNumStates
];
161 CMyBitDecoder _isRepG1
[kNumStates
];
162 CMyBitDecoder _isRepG2
[kNumStates
];
163 CMyBitDecoder _isRep0Long
[kNumStates
][NLength::kNumPosStatesMax
];
165 NRangeCoder::CBitTreeDecoder
<kNumMoveBits
, kNumPosSlotBits
> _posSlotDecoder
[kNumLenToPosStates
];
167 CMyBitDecoder _posDecoders
[kNumFullDistances
- kEndPosModelIndex
];
168 NRangeCoder::CBitTreeDecoder
<kNumMoveBits
, kNumAlignBits
> _posAlignDecoder
;
170 NLength::CDecoder _lenDecoder
;
171 NLength::CDecoder _repMatchLenDecoder
;
173 CLiteralDecoder _literalDecoder
;
175 UInt32 _posStateMask
;
181 Int32 _remainLen
; // -1 means end of stream. // -2 means need Init
183 bool _outSizeDefined
;
186 HRESULT
CodeSpec(UInt32 size
);
191 ICompressSetDecoderProperties2
,
192 ICompressSetInStream
,
193 ICompressSetOutStreamSize
,
197 ICompressSetDecoderProperties2
)
200 void ReleaseStreams()
202 _outWindowStream
.ReleaseStream();
206 class CDecoderFlusher
211 CDecoderFlusher(CDecoder
*decoder
): _decoder(decoder
), NeedFlush(true) {}
216 _decoder
->ReleaseStreams();
220 HRESULT
Flush() { return _outWindowStream
.Flush(); }
222 STDMETHOD(CodeReal
)(ISequentialInStream
*inStream
,
223 ISequentialOutStream
*outStream
, const UInt64
*inSize
, const UInt64
*outSize
,
224 ICompressProgressInfo
*progress
);
226 STDMETHOD(Code
)(ISequentialInStream
*inStream
,
227 ISequentialOutStream
*outStream
, const UInt64
*inSize
, const UInt64
*outSize
,
228 ICompressProgressInfo
*progress
);
230 STDMETHOD(SetDecoderProperties2
)(const Byte
*data
, UInt32 size
);
231 STDMETHOD(SetDecoderPropertiesRaw
)(int lc
, int lp
, int pb
, UInt32 dictionarySize
);
233 STDMETHOD(GetInStreamProcessedSize
)(UInt64
*value
);
235 STDMETHOD(SetInStream
)(ISequentialInStream
*inStream
);
236 STDMETHOD(ReleaseInStream
)();
237 STDMETHOD(SetOutStreamSize
)(const UInt64
*outSize
);
240 STDMETHOD(Read
)(void *data
, UInt32 size
, UInt32
*processedSize
);
243 CDecoder(): _outSizeDefined(false) {}
244 virtual ~CDecoder() {}