123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481 |
- using System;
- using System.IO;
- using SharpCompress.Compressors.LZMA.LZ;
- using SharpCompress.Compressors.LZMA.RangeCoder;
- namespace SharpCompress.Compressors.LZMA
- {
- internal class Decoder : ICoder, ISetDecoderProperties // ,System.IO.Stream
- {
- private class LenDecoder
- {
- private BitDecoder _choice = new BitDecoder();
- private BitDecoder _choice2 = new BitDecoder();
- private readonly BitTreeDecoder[] _lowCoder = new BitTreeDecoder[Base.K_NUM_POS_STATES_MAX];
- private readonly BitTreeDecoder[] _midCoder = new BitTreeDecoder[Base.K_NUM_POS_STATES_MAX];
- private BitTreeDecoder _highCoder = new BitTreeDecoder(Base.K_NUM_HIGH_LEN_BITS);
- private uint _numPosStates;
- public void Create(uint numPosStates)
- {
- for (uint posState = _numPosStates; posState < numPosStates; posState++)
- {
- _lowCoder[posState] = new BitTreeDecoder(Base.K_NUM_LOW_LEN_BITS);
- _midCoder[posState] = new BitTreeDecoder(Base.K_NUM_MID_LEN_BITS);
- }
- _numPosStates = numPosStates;
- }
- public void Init()
- {
- _choice.Init();
- for (uint posState = 0; posState < _numPosStates; posState++)
- {
- _lowCoder[posState].Init();
- _midCoder[posState].Init();
- }
- _choice2.Init();
- _highCoder.Init();
- }
- public uint Decode(RangeCoder.Decoder rangeDecoder, uint posState)
- {
- if (_choice.Decode(rangeDecoder) == 0)
- {
- return _lowCoder[posState].Decode(rangeDecoder);
- }
- uint symbol = Base.K_NUM_LOW_LEN_SYMBOLS;
- if (_choice2.Decode(rangeDecoder) == 0)
- {
- symbol += _midCoder[posState].Decode(rangeDecoder);
- }
- else
- {
- symbol += Base.K_NUM_MID_LEN_SYMBOLS;
- symbol += _highCoder.Decode(rangeDecoder);
- }
- return symbol;
- }
- }
- private class LiteralDecoder
- {
- private struct Decoder2
- {
- private BitDecoder[] _decoders;
- public void Create()
- {
- _decoders = new BitDecoder[0x300];
- }
- public void Init()
- {
- for (int i = 0; i < 0x300; i++)
- {
- _decoders[i].Init();
- }
- }
- public byte DecodeNormal(RangeCoder.Decoder rangeDecoder)
- {
- uint symbol = 1;
- do
- {
- symbol = (symbol << 1) | _decoders[symbol].Decode(rangeDecoder);
- }
- while (symbol < 0x100);
- return (byte)symbol;
- }
- public byte DecodeWithMatchByte(RangeCoder.Decoder rangeDecoder, byte matchByte)
- {
- uint symbol = 1;
- do
- {
- uint matchBit = (uint)(matchByte >> 7) & 1;
- matchByte <<= 1;
- uint bit = _decoders[((1 + matchBit) << 8) + symbol].Decode(rangeDecoder);
- symbol = (symbol << 1) | bit;
- if (matchBit != bit)
- {
- while (symbol < 0x100)
- {
- symbol = (symbol << 1) | _decoders[symbol].Decode(rangeDecoder);
- }
- break;
- }
- }
- while (symbol < 0x100);
- return (byte)symbol;
- }
- }
- private Decoder2[] _coders;
- private int _numPrevBits;
- private int _numPosBits;
- private uint _posMask;
- public void Create(int numPosBits, int numPrevBits)
- {
- if (_coders != null && _numPrevBits == numPrevBits &&
- _numPosBits == numPosBits)
- {
- return;
- }
- _numPosBits = numPosBits;
- _posMask = ((uint)1 << numPosBits) - 1;
- _numPrevBits = numPrevBits;
- uint numStates = (uint)1 << (_numPrevBits + _numPosBits);
- _coders = new Decoder2[numStates];
- for (uint i = 0; i < numStates; i++)
- {
- _coders[i].Create();
- }
- }
- public void Init()
- {
- uint numStates = (uint)1 << (_numPrevBits + _numPosBits);
- for (uint i = 0; i < numStates; i++)
- {
- _coders[i].Init();
- }
- }
- private uint GetState(uint pos, byte prevByte)
- {
- return ((pos & _posMask) << _numPrevBits) + (uint)(prevByte >> (8 - _numPrevBits));
- }
- public byte DecodeNormal(RangeCoder.Decoder rangeDecoder, uint pos, byte prevByte)
- {
- return _coders[GetState(pos, prevByte)].DecodeNormal(rangeDecoder);
- }
- public byte DecodeWithMatchByte(RangeCoder.Decoder rangeDecoder, uint pos, byte prevByte, byte matchByte)
- {
- return _coders[GetState(pos, prevByte)].DecodeWithMatchByte(rangeDecoder, matchByte);
- }
- }
- private OutWindow _outWindow;
- private readonly BitDecoder[] _isMatchDecoders = new BitDecoder[Base.K_NUM_STATES << Base.K_NUM_POS_STATES_BITS_MAX];
- private readonly BitDecoder[] _isRepDecoders = new BitDecoder[Base.K_NUM_STATES];
- private readonly BitDecoder[] _isRepG0Decoders = new BitDecoder[Base.K_NUM_STATES];
- private readonly BitDecoder[] _isRepG1Decoders = new BitDecoder[Base.K_NUM_STATES];
- private readonly BitDecoder[] _isRepG2Decoders = new BitDecoder[Base.K_NUM_STATES];
- private readonly BitDecoder[] _isRep0LongDecoders = new BitDecoder[Base.K_NUM_STATES << Base.K_NUM_POS_STATES_BITS_MAX];
- private readonly BitTreeDecoder[] _posSlotDecoder = new BitTreeDecoder[Base.K_NUM_LEN_TO_POS_STATES];
- private readonly BitDecoder[] _posDecoders = new BitDecoder[Base.K_NUM_FULL_DISTANCES - Base.K_END_POS_MODEL_INDEX];
- private BitTreeDecoder _posAlignDecoder = new BitTreeDecoder(Base.K_NUM_ALIGN_BITS);
- private readonly LenDecoder _lenDecoder = new LenDecoder();
- private readonly LenDecoder _repLenDecoder = new LenDecoder();
- private readonly LiteralDecoder _literalDecoder = new LiteralDecoder();
- private int _dictionarySize;
- private uint _posStateMask;
- private Base.State _state = new Base.State();
- private uint _rep0, _rep1, _rep2, _rep3;
- public Decoder()
- {
- _dictionarySize = -1;
- for (int i = 0; i < Base.K_NUM_LEN_TO_POS_STATES; i++)
- {
- _posSlotDecoder[i] = new BitTreeDecoder(Base.K_NUM_POS_SLOT_BITS);
- }
- }
- private void CreateDictionary()
- {
- if (_dictionarySize < 0)
- {
- throw new InvalidParamException();
- }
- _outWindow = new OutWindow();
- int blockSize = Math.Max(_dictionarySize, (1 << 12));
- _outWindow.Create(blockSize);
- }
- private void SetLiteralProperties(int lp, int lc)
- {
- if (lp > 8)
- {
- throw new InvalidParamException();
- }
- if (lc > 8)
- {
- throw new InvalidParamException();
- }
- _literalDecoder.Create(lp, lc);
- }
- private void SetPosBitsProperties(int pb)
- {
- if (pb > Base.K_NUM_POS_STATES_BITS_MAX)
- {
- throw new InvalidParamException();
- }
- uint numPosStates = (uint)1 << pb;
- _lenDecoder.Create(numPosStates);
- _repLenDecoder.Create(numPosStates);
- _posStateMask = numPosStates - 1;
- }
- private void Init()
- {
- uint i;
- for (i = 0; i < Base.K_NUM_STATES; i++)
- {
- for (uint j = 0; j <= _posStateMask; j++)
- {
- uint index = (i << Base.K_NUM_POS_STATES_BITS_MAX) + j;
- _isMatchDecoders[index].Init();
- _isRep0LongDecoders[index].Init();
- }
- _isRepDecoders[i].Init();
- _isRepG0Decoders[i].Init();
- _isRepG1Decoders[i].Init();
- _isRepG2Decoders[i].Init();
- }
- _literalDecoder.Init();
- for (i = 0; i < Base.K_NUM_LEN_TO_POS_STATES; i++)
- {
- _posSlotDecoder[i].Init();
- }
- // _PosSpecDecoder.Init();
- for (i = 0; i < Base.K_NUM_FULL_DISTANCES - Base.K_END_POS_MODEL_INDEX; i++)
- {
- _posDecoders[i].Init();
- }
- _lenDecoder.Init();
- _repLenDecoder.Init();
- _posAlignDecoder.Init();
- _state.Init();
- _rep0 = 0;
- _rep1 = 0;
- _rep2 = 0;
- _rep3 = 0;
- }
- public void Code(Stream inStream, Stream outStream,
- Int64 inSize, Int64 outSize, ICodeProgress progress)
- {
- if (_outWindow == null)
- {
- CreateDictionary();
- }
- _outWindow.Init(outStream);
- if (outSize > 0)
- {
- _outWindow.SetLimit(outSize);
- }
- else
- {
- _outWindow.SetLimit(Int64.MaxValue - _outWindow._total);
- }
- RangeCoder.Decoder rangeDecoder = new RangeCoder.Decoder();
- rangeDecoder.Init(inStream);
- Code(_dictionarySize, _outWindow, rangeDecoder);
- _outWindow.ReleaseStream();
- rangeDecoder.ReleaseStream();
- if (!rangeDecoder.IsFinished || (inSize > 0 && rangeDecoder._total != inSize))
- {
- throw new DataErrorException();
- }
- if (_outWindow.HasPending)
- {
- throw new DataErrorException();
- }
- _outWindow = null;
- }
- internal bool Code(int dictionarySize, OutWindow outWindow, RangeCoder.Decoder rangeDecoder)
- {
- int dictionarySizeCheck = Math.Max(dictionarySize, 1);
- outWindow.CopyPending();
- while (outWindow.HasSpace)
- {
- uint posState = (uint)outWindow._total & _posStateMask;
- if (_isMatchDecoders[(_state._index << Base.K_NUM_POS_STATES_BITS_MAX) + posState].Decode(rangeDecoder) == 0)
- {
- byte b;
- byte prevByte = outWindow.GetByte(0);
- if (!_state.IsCharState())
- {
- b = _literalDecoder.DecodeWithMatchByte(rangeDecoder,
- (uint)outWindow._total, prevByte,
- outWindow.GetByte((int)_rep0));
- }
- else
- {
- b = _literalDecoder.DecodeNormal(rangeDecoder, (uint)outWindow._total, prevByte);
- }
- outWindow.PutByte(b);
- _state.UpdateChar();
- }
- else
- {
- uint len;
- if (_isRepDecoders[_state._index].Decode(rangeDecoder) == 1)
- {
- if (_isRepG0Decoders[_state._index].Decode(rangeDecoder) == 0)
- {
- if (
- _isRep0LongDecoders[(_state._index << Base.K_NUM_POS_STATES_BITS_MAX) + posState].Decode(
- rangeDecoder) == 0)
- {
- _state.UpdateShortRep();
- outWindow.PutByte(outWindow.GetByte((int)_rep0));
- continue;
- }
- }
- else
- {
- UInt32 distance;
- if (_isRepG1Decoders[_state._index].Decode(rangeDecoder) == 0)
- {
- distance = _rep1;
- }
- else
- {
- if (_isRepG2Decoders[_state._index].Decode(rangeDecoder) == 0)
- {
- distance = _rep2;
- }
- else
- {
- distance = _rep3;
- _rep3 = _rep2;
- }
- _rep2 = _rep1;
- }
- _rep1 = _rep0;
- _rep0 = distance;
- }
- len = _repLenDecoder.Decode(rangeDecoder, posState) + Base.K_MATCH_MIN_LEN;
- _state.UpdateRep();
- }
- else
- {
- _rep3 = _rep2;
- _rep2 = _rep1;
- _rep1 = _rep0;
- len = Base.K_MATCH_MIN_LEN + _lenDecoder.Decode(rangeDecoder, posState);
- _state.UpdateMatch();
- uint posSlot = _posSlotDecoder[Base.GetLenToPosState(len)].Decode(rangeDecoder);
- if (posSlot >= Base.K_START_POS_MODEL_INDEX)
- {
- int numDirectBits = (int)((posSlot >> 1) - 1);
- _rep0 = ((2 | (posSlot & 1)) << numDirectBits);
- if (posSlot < Base.K_END_POS_MODEL_INDEX)
- {
- _rep0 += BitTreeDecoder.ReverseDecode(_posDecoders,
- _rep0 - posSlot - 1, rangeDecoder, numDirectBits);
- }
- else
- {
- _rep0 += (rangeDecoder.DecodeDirectBits(
- numDirectBits - Base.K_NUM_ALIGN_BITS) << Base.K_NUM_ALIGN_BITS);
- _rep0 += _posAlignDecoder.ReverseDecode(rangeDecoder);
- }
- }
- else
- {
- _rep0 = posSlot;
- }
- }
- if (_rep0 >= outWindow._total || _rep0 >= dictionarySizeCheck)
- {
- if (_rep0 == 0xFFFFFFFF)
- {
- return true;
- }
- throw new DataErrorException();
- }
- outWindow.CopyBlock((int)_rep0, (int)len);
- }
- }
- return false;
- }
- public void SetDecoderProperties(byte[] properties)
- {
- if (properties.Length < 1)
- {
- throw new InvalidParamException();
- }
- int lc = properties[0] % 9;
- int remainder = properties[0] / 9;
- int lp = remainder % 5;
- int pb = remainder / 5;
- if (pb > Base.K_NUM_POS_STATES_BITS_MAX)
- {
- throw new InvalidParamException();
- }
- SetLiteralProperties(lp, lc);
- SetPosBitsProperties(pb);
- Init();
- if (properties.Length >= 5)
- {
- _dictionarySize = 0;
- for (int i = 0; i < 4; i++)
- {
- _dictionarySize += properties[1 + i] << (i * 8);
- }
- }
- }
- public void Train(Stream stream)
- {
- if (_outWindow == null)
- {
- CreateDictionary();
- }
- _outWindow.Train(stream);
- }
- /*
- public override bool CanRead { get { return true; }}
- public override bool CanWrite { get { return true; }}
- public override bool CanSeek { get { return true; }}
- public override long Length { get { return 0; }}
- public override long Position
- {
- get { return 0; }
- set { }
- }
- public override void Flush() { }
- public override int Read(byte[] buffer, int offset, int count)
- {
- return 0;
- }
- public override void Write(byte[] buffer, int offset, int count)
- {
- }
- public override long Seek(long offset, System.IO.SeekOrigin origin)
- {
- return 0;
- }
- public override void SetLength(long value) {}
- */
- }
- }
|