Annotation of elwix/tools/oldlzma/SRC/7zip/Compress/LZMA/LZMADecoder.h, revision 1.1
1.1 ! misho 1: // LZMA/Decoder.h
! 2:
! 3: #ifndef __LZMA_DECODER_H
! 4: #define __LZMA_DECODER_H
! 5:
! 6: #include "../../../Common/MyCom.h"
! 7: #include "../../../Common/Alloc.h"
! 8: #include "../../ICoder.h"
! 9: #include "../LZ/LZOutWindow.h"
! 10: #include "../RangeCoder/RangeCoderBitTree.h"
! 11:
! 12: #include "LZMA.h"
! 13:
! 14: namespace NCompress {
! 15: namespace NLZMA {
! 16:
! 17: typedef NRangeCoder::CBitDecoder<kNumMoveBits> CMyBitDecoder;
! 18:
! 19: class CLiteralDecoder2
! 20: {
! 21: CMyBitDecoder _decoders[0x300];
! 22: public:
! 23: void Init()
! 24: {
! 25: for (int i = 0; i < 0x300; i++)
! 26: _decoders[i].Init();
! 27: }
! 28: Byte DecodeNormal(NRangeCoder::CDecoder *rangeDecoder)
! 29: {
! 30: UInt32 symbol = 1;
! 31: RC_INIT_VAR
! 32: do
! 33: {
! 34: // symbol = (symbol << 1) | _decoders[0][symbol].Decode(rangeDecoder);
! 35: RC_GETBIT(kNumMoveBits, _decoders[symbol].Prob, symbol)
! 36: }
! 37: while (symbol < 0x100);
! 38: RC_FLUSH_VAR
! 39: return (Byte)symbol;
! 40: }
! 41: Byte DecodeWithMatchByte(NRangeCoder::CDecoder *rangeDecoder, Byte matchByte)
! 42: {
! 43: UInt32 symbol = 1;
! 44: RC_INIT_VAR
! 45: do
! 46: {
! 47: UInt32 matchBit = (matchByte >> 7) & 1;
! 48: matchByte <<= 1;
! 49: // UInt32 bit = _decoders[1 + matchBit][symbol].Decode(rangeDecoder);
! 50: // symbol = (symbol << 1) | bit;
! 51: UInt32 bit;
! 52: RC_GETBIT2(kNumMoveBits, _decoders[0x100 + (matchBit << 8) + symbol].Prob, symbol,
! 53: bit = 0, bit = 1)
! 54: if (matchBit != bit)
! 55: {
! 56: while (symbol < 0x100)
! 57: {
! 58: // symbol = (symbol << 1) | _decoders[0][symbol].Decode(rangeDecoder);
! 59: RC_GETBIT(kNumMoveBits, _decoders[symbol].Prob, symbol)
! 60: }
! 61: break;
! 62: }
! 63: }
! 64: while (symbol < 0x100);
! 65: RC_FLUSH_VAR
! 66: return (Byte)symbol;
! 67: }
! 68: };
! 69:
! 70: class CLiteralDecoder
! 71: {
! 72: CLiteralDecoder2 *_coders;
! 73: int _numPrevBits;
! 74: int _numPosBits;
! 75: UInt32 _posMask;
! 76: public:
! 77: CLiteralDecoder(): _coders(0) {}
! 78: ~CLiteralDecoder() { Free(); }
! 79: void Free()
! 80: {
! 81: MyFree(_coders);
! 82: _coders = 0;
! 83: }
! 84: bool Create(int numPosBits, int numPrevBits)
! 85: {
! 86: if (_coders == 0 || (numPosBits + numPrevBits) !=
! 87: (_numPrevBits + _numPosBits) )
! 88: {
! 89: Free();
! 90: UInt32 numStates = 1 << (numPosBits + numPrevBits);
! 91: _coders = (CLiteralDecoder2 *)MyAlloc(numStates * sizeof(CLiteralDecoder2));
! 92: }
! 93: _numPosBits = numPosBits;
! 94: _posMask = (1 << numPosBits) - 1;
! 95: _numPrevBits = numPrevBits;
! 96: return (_coders != 0);
! 97: }
! 98: void Init()
! 99: {
! 100: UInt32 numStates = 1 << (_numPrevBits + _numPosBits);
! 101: for (UInt32 i = 0; i < numStates; i++)
! 102: _coders[i].Init();
! 103: }
! 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); }
! 110: };
! 111:
! 112: namespace NLength {
! 113:
! 114: class CDecoder
! 115: {
! 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;
! 121: public:
! 122: void Init(UInt32 numPosStates)
! 123: {
! 124: _choice.Init();
! 125: _choice2.Init();
! 126: for (UInt32 posState = 0; posState < numPosStates; posState++)
! 127: {
! 128: _lowCoder[posState].Init();
! 129: _midCoder[posState].Init();
! 130: }
! 131: _highCoder.Init();
! 132: }
! 133: UInt32 Decode(NRangeCoder::CDecoder *rangeDecoder, UInt32 posState)
! 134: {
! 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);
! 140: }
! 141: };
! 142:
! 143: }
! 144:
! 145: class CDecoder:
! 146: public ICompressCoder,
! 147: public ICompressSetDecoderProperties2,
! 148: public ICompressSetInStream,
! 149: public ICompressSetOutStreamSize,
! 150: public ISequentialInStream,
! 151: public CMyUnknownImp
! 152: {
! 153: CLZOutWindow _outWindowStream;
! 154: NRangeCoder::CDecoder _rangeDecoder;
! 155:
! 156: CMyBitDecoder _isMatch[kNumStates][NLength::kNumPosStatesMax];
! 157: CMyBitDecoder _isRep[kNumStates];
! 158: CMyBitDecoder _isRepG0[kNumStates];
! 159: CMyBitDecoder _isRepG1[kNumStates];
! 160: CMyBitDecoder _isRepG2[kNumStates];
! 161: CMyBitDecoder _isRep0Long[kNumStates][NLength::kNumPosStatesMax];
! 162:
! 163: NRangeCoder::CBitTreeDecoder<kNumMoveBits, kNumPosSlotBits> _posSlotDecoder[kNumLenToPosStates];
! 164:
! 165: CMyBitDecoder _posDecoders[kNumFullDistances - kEndPosModelIndex];
! 166: NRangeCoder::CBitTreeDecoder<kNumMoveBits, kNumAlignBits> _posAlignDecoder;
! 167:
! 168: NLength::CDecoder _lenDecoder;
! 169: NLength::CDecoder _repMatchLenDecoder;
! 170:
! 171: CLiteralDecoder _literalDecoder;
! 172:
! 173: UInt32 _dictionarySizeCheck;
! 174:
! 175: UInt32 _posStateMask;
! 176:
! 177: ///////////////////
! 178: // State
! 179: UInt64 _outSize;
! 180: UInt64 _nowPos64;
! 181: UInt32 _reps[4];
! 182: CState _state;
! 183: Int32 _remainLen; // -1 means end of stream. // -2 means need Init
! 184:
! 185: void Init();
! 186: HRESULT CodeSpec(Byte *buffer, UInt32 size);
! 187: public:
! 188: MY_UNKNOWN_IMP4(
! 189: ICompressSetDecoderProperties2,
! 190: ICompressSetInStream,
! 191: ICompressSetOutStreamSize,
! 192: ISequentialInStream)
! 193:
! 194: void ReleaseStreams()
! 195: {
! 196: _outWindowStream.ReleaseStream();
! 197: ReleaseInStream();
! 198: }
! 199:
! 200: class CDecoderFlusher
! 201: {
! 202: CDecoder *_decoder;
! 203: public:
! 204: bool NeedFlush;
! 205: CDecoderFlusher(CDecoder *decoder): _decoder(decoder), NeedFlush(true) {}
! 206: ~CDecoderFlusher()
! 207: {
! 208: if (NeedFlush)
! 209: _decoder->Flush();
! 210: _decoder->ReleaseStreams();
! 211: }
! 212: };
! 213:
! 214: HRESULT Flush() { return _outWindowStream.Flush(); }
! 215:
! 216: STDMETHOD(CodeReal)(ISequentialInStream *inStream,
! 217: ISequentialOutStream *outStream, const UInt64 *inSize, const UInt64 *outSize,
! 218: ICompressProgressInfo *progress);
! 219:
! 220: STDMETHOD(Code)(ISequentialInStream *inStream,
! 221: ISequentialOutStream *outStream, const UInt64 *inSize, const UInt64 *outSize,
! 222: ICompressProgressInfo *progress);
! 223:
! 224: STDMETHOD(SetDecoderProperties2)(const Byte *data, UInt32 size);
! 225:
! 226: STDMETHOD(GetInStreamProcessedSize)(UInt64 *value);
! 227:
! 228: STDMETHOD(SetInStream)(ISequentialInStream *inStream);
! 229: STDMETHOD(ReleaseInStream)();
! 230: STDMETHOD(SetOutStreamSize)(const UInt64 *outSize);
! 231: STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize);
! 232: STDMETHOD(ReadPart)(void *data, UInt32 size, UInt32 *processedSize);
! 233:
! 234: virtual ~CDecoder() {}
! 235: };
! 236:
! 237: }}
! 238:
! 239: #endif
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>