| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255 |
- // LZMA/Decoder.h
- #ifndef __LZMA_DECODER_H
- #define __LZMA_DECODER_H
- #include "../../../Common/MyCom.h"
- #include "../../ICoder.h"
- #include "../LZ/LZOutWindow.h"
- #include "../RangeCoder/RangeCoderBitTree.h"
- extern "C"
- {
- #include "../../../../C/Alloc.h"
- }
- #include "LZMA.h"
- namespace NCompress {
- namespace NLZMA {
- typedef NRangeCoder::CBitDecoder<kNumMoveBits> CMyBitDecoder;
- class CLiteralDecoder2
- {
- CMyBitDecoder _decoders[0x300];
- public:
- void Init()
- {
- for (int i = 0; i < 0x300; i++)
- _decoders[i].Init();
- }
- Byte DecodeNormal(NRangeCoder::CDecoder *rangeDecoder)
- {
- UInt32 symbol = 1;
- RC_INIT_VAR
- do
- {
- // symbol = (symbol << 1) | _decoders[0][symbol].Decode(rangeDecoder);
- RC_GETBIT(kNumMoveBits, _decoders[symbol].Prob, symbol)
- }
- while (symbol < 0x100);
- RC_FLUSH_VAR
- return (Byte)symbol;
- }
- Byte DecodeWithMatchByte(NRangeCoder::CDecoder *rangeDecoder, Byte matchByte)
- {
- UInt32 symbol = 1;
- RC_INIT_VAR
- do
- {
- UInt32 matchBit = (matchByte >> 7) & 1;
- matchByte <<= 1;
- // UInt32 bit = _decoders[1 + matchBit][symbol].Decode(rangeDecoder);
- // symbol = (symbol << 1) | bit;
- UInt32 bit;
- RC_GETBIT2(kNumMoveBits, _decoders[0x100 + (matchBit << 8) + symbol].Prob, symbol,
- bit = 0, bit = 1)
- if (matchBit != bit)
- {
- while (symbol < 0x100)
- {
- // symbol = (symbol << 1) | _decoders[0][symbol].Decode(rangeDecoder);
- RC_GETBIT(kNumMoveBits, _decoders[symbol].Prob, symbol)
- }
- break;
- }
- }
- while (symbol < 0x100);
- RC_FLUSH_VAR
- return (Byte)symbol;
- }
- };
- class CLiteralDecoder
- {
- CLiteralDecoder2 *_coders;
- int _numPrevBits;
- int _numPosBits;
- UInt32 _posMask;
- public:
- CLiteralDecoder(): _coders(0) {}
- ~CLiteralDecoder() { Free(); }
- void Free()
- {
- MyFree(_coders);
- _coders = 0;
- }
- bool Create(int numPosBits, int numPrevBits)
- {
- if (_coders == 0 || (numPosBits + numPrevBits) !=
- (_numPrevBits + _numPosBits) )
- {
- Free();
- UInt32 numStates = 1 << (numPosBits + numPrevBits);
- _coders = (CLiteralDecoder2 *)MyAlloc(numStates * sizeof(CLiteralDecoder2));
- }
- _numPosBits = numPosBits;
- _posMask = (1 << numPosBits) - 1;
- _numPrevBits = numPrevBits;
- return (_coders != 0);
- }
- void Init()
- {
- UInt32 numStates = 1 << (_numPrevBits + _numPosBits);
- for (UInt32 i = 0; i < numStates; i++)
- _coders[i].Init();
- }
- UInt32 GetState(UInt32 pos, Byte prevByte) const
- { return ((pos & _posMask) << _numPrevBits) + (prevByte >> (8 - _numPrevBits)); }
- Byte DecodeNormal(NRangeCoder::CDecoder *rangeDecoder, UInt32 pos, Byte prevByte)
- { return _coders[GetState(pos, prevByte)].DecodeNormal(rangeDecoder); }
- Byte DecodeWithMatchByte(NRangeCoder::CDecoder *rangeDecoder, UInt32 pos, Byte prevByte, Byte matchByte)
- { return _coders[GetState(pos, prevByte)].DecodeWithMatchByte(rangeDecoder, matchByte); }
- };
- namespace NLength {
- class CDecoder
- {
- CMyBitDecoder _choice;
- CMyBitDecoder _choice2;
- NRangeCoder::CBitTreeDecoder<kNumMoveBits, kNumLowBits> _lowCoder[kNumPosStatesMax];
- NRangeCoder::CBitTreeDecoder<kNumMoveBits, kNumMidBits> _midCoder[kNumPosStatesMax];
- NRangeCoder::CBitTreeDecoder<kNumMoveBits, kNumHighBits> _highCoder;
- public:
- void Init(UInt32 numPosStates)
- {
- _choice.Init();
- _choice2.Init();
- for (UInt32 posState = 0; posState < numPosStates; posState++)
- {
- _lowCoder[posState].Init();
- _midCoder[posState].Init();
- }
- _highCoder.Init();
- }
- UInt32 Decode(NRangeCoder::CDecoder *rangeDecoder, UInt32 posState)
- {
- if(_choice.Decode(rangeDecoder) == 0)
- return _lowCoder[posState].Decode(rangeDecoder);
- if(_choice2.Decode(rangeDecoder) == 0)
- return kNumLowSymbols + _midCoder[posState].Decode(rangeDecoder);
- return kNumLowSymbols + kNumMidSymbols + _highCoder.Decode(rangeDecoder);
- }
- };
- }
- class CDecoder:
- public ICompressCoder,
- public ICompressSetDecoderProperties2,
- public ICompressGetInStreamProcessedSize,
- #ifndef NO_READ_FROM_CODER
- public ICompressSetInStream,
- public ICompressSetOutStreamSize,
- public ISequentialInStream,
- #endif
- public CMyUnknownImp
- {
- CLZOutWindow _outWindowStream;
- NRangeCoder::CDecoder _rangeDecoder;
- CMyBitDecoder _isMatch[kNumStates][NLength::kNumPosStatesMax];
- CMyBitDecoder _isRep[kNumStates];
- CMyBitDecoder _isRepG0[kNumStates];
- CMyBitDecoder _isRepG1[kNumStates];
- CMyBitDecoder _isRepG2[kNumStates];
- CMyBitDecoder _isRep0Long[kNumStates][NLength::kNumPosStatesMax];
- NRangeCoder::CBitTreeDecoder<kNumMoveBits, kNumPosSlotBits> _posSlotDecoder[kNumLenToPosStates];
- CMyBitDecoder _posDecoders[kNumFullDistances - kEndPosModelIndex];
- NRangeCoder::CBitTreeDecoder<kNumMoveBits, kNumAlignBits> _posAlignDecoder;
-
- NLength::CDecoder _lenDecoder;
- NLength::CDecoder _repMatchLenDecoder;
- CLiteralDecoder _literalDecoder;
- UInt32 _posStateMask;
- ///////////////////
- // State
- UInt32 _reps[4];
- CState _state;
- Int32 _remainLen; // -1 means end of stream. // -2 means need Init
- UInt64 _outSize;
- bool _outSizeDefined;
- void Init();
- HRESULT CodeSpec(UInt32 size);
- public:
- #ifndef NO_READ_FROM_CODER
- MY_UNKNOWN_IMP5(
- ICompressSetDecoderProperties2,
- ICompressGetInStreamProcessedSize,
- ICompressSetInStream,
- ICompressSetOutStreamSize,
- ISequentialInStream)
- #else
- MY_UNKNOWN_IMP2(
- ICompressSetDecoderProperties2,
- ICompressGetInStreamProcessedSize)
- #endif
- void ReleaseStreams()
- {
- _outWindowStream.ReleaseStream();
- ReleaseInStream();
- }
- class CDecoderFlusher
- {
- CDecoder *_decoder;
- public:
- bool NeedFlush;
- CDecoderFlusher(CDecoder *decoder): _decoder(decoder), NeedFlush(true) {}
- ~CDecoderFlusher()
- {
- if (NeedFlush)
- _decoder->Flush();
- _decoder->ReleaseStreams();
- }
- };
- HRESULT Flush() { return _outWindowStream.Flush(); }
- STDMETHOD(CodeReal)(ISequentialInStream *inStream,
- ISequentialOutStream *outStream, const UInt64 *inSize, const UInt64 *outSize,
- ICompressProgressInfo *progress);
-
- STDMETHOD(Code)(ISequentialInStream *inStream,
- ISequentialOutStream *outStream, const UInt64 *inSize, const UInt64 *outSize,
- ICompressProgressInfo *progress);
- STDMETHOD(SetDecoderProperties2)(const Byte *data, UInt32 size);
- STDMETHOD(GetInStreamProcessedSize)(UInt64 *value);
- STDMETHOD(SetInStream)(ISequentialInStream *inStream);
- STDMETHOD(ReleaseInStream)();
- STDMETHOD(SetOutStreamSize)(const UInt64 *outSize);
- #ifndef NO_READ_FROM_CODER
- STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize);
- #endif
- CDecoder(): _outSizeDefined(false) {}
- virtual ~CDecoder() {}
- };
- }}
- #endif
|