mirror of
https://github.com/Obfuscator-Collections/VMProtect.git
synced 2026-09-01 12:54:42 +03:00
first commit
Version 3.x.x
This commit is contained in:
@@ -0,0 +1,651 @@
|
||||
// LzmaDecoder.cs
|
||||
|
||||
using System;
|
||||
using System.IO;
|
||||
using SevenZip.Compression.RangeCoder;
|
||||
#pragma warning disable 414
|
||||
|
||||
namespace SevenZip.Compression.LZ
|
||||
{
|
||||
public class OutWindow
|
||||
{
|
||||
byte[] _buffer;
|
||||
uint _pos;
|
||||
uint _windowSize;
|
||||
uint _streamPos;
|
||||
Stream _stream;
|
||||
uint _id = 1;
|
||||
|
||||
public uint TrainSize;
|
||||
|
||||
public void Create(uint windowSize)
|
||||
{
|
||||
if (_windowSize != windowSize)
|
||||
{
|
||||
_buffer = new byte[windowSize];
|
||||
}
|
||||
_windowSize = windowSize;
|
||||
_pos = 0;
|
||||
_streamPos = 0;
|
||||
}
|
||||
|
||||
public void Init(Stream stream, bool solid)
|
||||
{
|
||||
ReleaseStream();
|
||||
_stream = stream;
|
||||
if (!solid)
|
||||
{
|
||||
_streamPos = 0;
|
||||
_pos = 0;
|
||||
TrainSize = 0;
|
||||
}
|
||||
}
|
||||
|
||||
public void ReleaseStream()
|
||||
{
|
||||
Flush();
|
||||
_stream = null;
|
||||
}
|
||||
|
||||
public void Flush()
|
||||
{
|
||||
uint size = _pos - _streamPos;
|
||||
if (size == 0)
|
||||
return;
|
||||
_stream.Write(_buffer, (int)_streamPos, (int)size);
|
||||
if (_pos >= _windowSize)
|
||||
_pos = 0;
|
||||
_streamPos = _pos;
|
||||
}
|
||||
|
||||
public void CopyBlock(uint distance, uint len)
|
||||
{
|
||||
uint pos = _pos - distance - 1;
|
||||
if (pos >= _windowSize)
|
||||
pos += _windowSize;
|
||||
for (; len > 0; len--)
|
||||
{
|
||||
if (pos >= _windowSize)
|
||||
pos = 0;
|
||||
_buffer[_pos++] = _buffer[pos++];
|
||||
if (_pos >= _windowSize)
|
||||
Flush();
|
||||
}
|
||||
}
|
||||
|
||||
public void PutByte(byte b)
|
||||
{
|
||||
_buffer[_pos++] = b;
|
||||
if (_pos >= _windowSize)
|
||||
Flush();
|
||||
}
|
||||
|
||||
public byte GetByte(uint distance)
|
||||
{
|
||||
uint pos = _pos - distance - 1;
|
||||
if (pos >= _windowSize)
|
||||
pos += _windowSize;
|
||||
return _buffer[pos];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
namespace SevenZip.Compression.RangeCoder
|
||||
{
|
||||
class Decoder
|
||||
{
|
||||
uint _id = 1;
|
||||
|
||||
public const uint KTopValue = (1 << 24);
|
||||
public uint Range;
|
||||
public uint Code;
|
||||
public Stream Stream;
|
||||
|
||||
public void Init(Stream stream)
|
||||
{
|
||||
Stream = stream;
|
||||
|
||||
Code = 0;
|
||||
Range = 0xFFFFFFFF;
|
||||
for (int i = 0; i < 5; i++)
|
||||
Code = (Code << 8) | (byte)Stream.ReadByte();
|
||||
}
|
||||
|
||||
public void ReleaseStream()
|
||||
{
|
||||
Stream = null;
|
||||
}
|
||||
|
||||
|
||||
public uint DecodeDirectBits(int numTotalBits)
|
||||
{
|
||||
uint range = Range;
|
||||
uint code = Code;
|
||||
uint result = 0;
|
||||
for (int i = numTotalBits; i > 0; i--)
|
||||
{
|
||||
range >>= 1;
|
||||
uint t = (code - range) >> 31;
|
||||
code -= range & (t - 1);
|
||||
result = (result << 1) | (1 - t);
|
||||
|
||||
if (range < KTopValue)
|
||||
{
|
||||
code = (code << 8) | (byte)Stream.ReadByte();
|
||||
range <<= 8;
|
||||
}
|
||||
}
|
||||
Range = range;
|
||||
Code = code;
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
struct BitDecoder
|
||||
{
|
||||
private const int KNumBitModelTotalBits = 11;
|
||||
private const uint KBitModelTotal = (1 << KNumBitModelTotalBits);
|
||||
const int KNumMoveBits = 5;
|
||||
|
||||
uint _prob;
|
||||
|
||||
public void Init() { _prob = KBitModelTotal >> 1; }
|
||||
|
||||
public uint Decode(Decoder rangeDecoder)
|
||||
{
|
||||
uint newBound = (rangeDecoder.Range >> KNumBitModelTotalBits) * _prob;
|
||||
if (rangeDecoder.Code < newBound)
|
||||
{
|
||||
rangeDecoder.Range = newBound;
|
||||
_prob += (KBitModelTotal - _prob) >> KNumMoveBits;
|
||||
if (rangeDecoder.Range < Decoder.KTopValue)
|
||||
{
|
||||
rangeDecoder.Code = (rangeDecoder.Code << 8) | (byte)rangeDecoder.Stream.ReadByte();
|
||||
rangeDecoder.Range <<= 8;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
rangeDecoder.Range -= newBound;
|
||||
rangeDecoder.Code -= newBound;
|
||||
_prob -= (_prob) >> KNumMoveBits;
|
||||
if (rangeDecoder.Range < Decoder.KTopValue)
|
||||
{
|
||||
rangeDecoder.Code = (rangeDecoder.Code << 8) | (byte)rangeDecoder.Stream.ReadByte();
|
||||
rangeDecoder.Range <<= 8;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
struct BitTreeDecoder
|
||||
{
|
||||
private readonly BitDecoder[] _models;
|
||||
private readonly int _numBitLevels;
|
||||
|
||||
public BitTreeDecoder(int numBitLevels)
|
||||
{
|
||||
_numBitLevels = numBitLevels;
|
||||
_models = new BitDecoder[1 << numBitLevels];
|
||||
}
|
||||
|
||||
public void Init()
|
||||
{
|
||||
for (uint i = 1; i < (1 << _numBitLevels); i++)
|
||||
_models[i].Init();
|
||||
}
|
||||
|
||||
public uint Decode(Decoder rangeDecoder)
|
||||
{
|
||||
uint m = 1;
|
||||
for (int bitIndex = _numBitLevels; bitIndex > 0; bitIndex--)
|
||||
m = (m << 1) + _models[m].Decode(rangeDecoder);
|
||||
return m - ((uint)1 << _numBitLevels);
|
||||
}
|
||||
|
||||
public uint ReverseDecode(Decoder rangeDecoder)
|
||||
{
|
||||
uint m = 1;
|
||||
uint symbol = 0;
|
||||
for (int bitIndex = 0; bitIndex < _numBitLevels; bitIndex++)
|
||||
{
|
||||
uint bit = _models[m].Decode(rangeDecoder);
|
||||
m <<= 1;
|
||||
m += bit;
|
||||
symbol |= (bit << bitIndex);
|
||||
}
|
||||
return symbol;
|
||||
}
|
||||
|
||||
public static uint ReverseDecode(BitDecoder[] models, UInt32 startIndex,
|
||||
Decoder rangeDecoder, int numBitLevels)
|
||||
{
|
||||
uint m = 1;
|
||||
uint symbol = 0;
|
||||
for (int bitIndex = 0; bitIndex < numBitLevels; bitIndex++)
|
||||
{
|
||||
uint bit = models[startIndex + m].Decode(rangeDecoder);
|
||||
m <<= 1;
|
||||
m += bit;
|
||||
symbol |= (bit << bitIndex);
|
||||
}
|
||||
return symbol;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
namespace SevenZip.Compression.LZMA
|
||||
{
|
||||
internal abstract class Base
|
||||
{
|
||||
public const uint KNumStates = 12;
|
||||
|
||||
public struct State
|
||||
{
|
||||
public uint Index;
|
||||
public void Init() { Index = 0; }
|
||||
public void UpdateChar()
|
||||
{
|
||||
if (Index < 4) Index = 0;
|
||||
else if (Index < 10) Index -= 3;
|
||||
else Index -= 6;
|
||||
}
|
||||
public void UpdateMatch() { Index = (uint)(Index < 7 ? 7 : 10); }
|
||||
public void UpdateRep() { Index = (uint)(Index < 7 ? 8 : 11); }
|
||||
public void UpdateShortRep() { Index = (uint)(Index < 7 ? 9 : 11); }
|
||||
public bool IsCharState() { return Index < 7; }
|
||||
}
|
||||
|
||||
public const int KNumPosSlotBits = 6;
|
||||
|
||||
private const int KNumLenToPosStatesBits = 2; // it's for speed optimization
|
||||
public const uint KNumLenToPosStates = 1 << KNumLenToPosStatesBits;
|
||||
|
||||
public const uint KMatchMinLen = 2;
|
||||
|
||||
public static uint GetLenToPosState(uint len)
|
||||
{
|
||||
len -= KMatchMinLen;
|
||||
if (len < KNumLenToPosStates)
|
||||
return len;
|
||||
return KNumLenToPosStates - 1;
|
||||
}
|
||||
|
||||
public const int KNumAlignBits = 4;
|
||||
|
||||
public const uint KStartPosModelIndex = 4;
|
||||
public const uint KEndPosModelIndex = 14;
|
||||
|
||||
public const uint KNumFullDistances = 1 << ((int)KEndPosModelIndex / 2);
|
||||
|
||||
public const int KNumPosStatesBitsMax = 4;
|
||||
public const uint KNumPosStatesMax = (1 << KNumPosStatesBitsMax);
|
||||
|
||||
public const int KNumLowLenBits = 3;
|
||||
public const int KNumMidLenBits = 3;
|
||||
public const int KNumHighLenBits = 8;
|
||||
public const uint KNumLowLenSymbols = 1 << KNumLowLenBits;
|
||||
public const uint KNumMidLenSymbols = 1 << KNumMidLenBits;
|
||||
}
|
||||
public class Decoder
|
||||
{
|
||||
uint _id = 1;
|
||||
|
||||
class LenDecoder
|
||||
{
|
||||
BitDecoder _mChoice = new BitDecoder();
|
||||
BitDecoder _mChoice2 = new BitDecoder();
|
||||
readonly BitTreeDecoder[] _mLowCoder = new BitTreeDecoder[Base.KNumPosStatesMax];
|
||||
readonly BitTreeDecoder[] _mMidCoder = new BitTreeDecoder[Base.KNumPosStatesMax];
|
||||
BitTreeDecoder _mHighCoder = new BitTreeDecoder(Base.KNumHighLenBits);
|
||||
uint _mNumPosStates;
|
||||
|
||||
public void Create(uint numPosStates)
|
||||
{
|
||||
for (uint posState = _mNumPosStates; posState < numPosStates; posState++)
|
||||
{
|
||||
_mLowCoder[posState] = new BitTreeDecoder(Base.KNumLowLenBits);
|
||||
_mMidCoder[posState] = new BitTreeDecoder(Base.KNumMidLenBits);
|
||||
}
|
||||
_mNumPosStates = numPosStates;
|
||||
}
|
||||
|
||||
public void Init()
|
||||
{
|
||||
_mChoice.Init();
|
||||
for (uint posState = 0; posState < _mNumPosStates; posState++)
|
||||
{
|
||||
_mLowCoder[posState].Init();
|
||||
_mMidCoder[posState].Init();
|
||||
}
|
||||
_mChoice2.Init();
|
||||
_mHighCoder.Init();
|
||||
}
|
||||
|
||||
public uint Decode(RangeCoder.Decoder rangeDecoder, uint posState)
|
||||
{
|
||||
if (_mChoice.Decode(rangeDecoder) == 0)
|
||||
return _mLowCoder[posState].Decode(rangeDecoder);
|
||||
else
|
||||
{
|
||||
uint symbol = Base.KNumLowLenSymbols;
|
||||
if (_mChoice2.Decode(rangeDecoder) == 0)
|
||||
symbol += _mMidCoder[posState].Decode(rangeDecoder);
|
||||
else
|
||||
{
|
||||
symbol += Base.KNumMidLenSymbols;
|
||||
symbol += _mHighCoder.Decode(rangeDecoder);
|
||||
}
|
||||
return symbol;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class LiteralDecoder
|
||||
{
|
||||
uint _id = 1;
|
||||
|
||||
struct Decoder2
|
||||
{
|
||||
BitDecoder[] _mDecoders;
|
||||
public void Create() { _mDecoders = new BitDecoder[0x300]; }
|
||||
public void Init() { for (int i = 0; i < 0x300; i++) _mDecoders[i].Init(); }
|
||||
|
||||
public byte DecodeNormal(RangeCoder.Decoder rangeDecoder)
|
||||
{
|
||||
uint symbol = 1;
|
||||
do
|
||||
symbol = (symbol << 1) | _mDecoders[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 = _mDecoders[((1 + matchBit) << 8) + symbol].Decode(rangeDecoder);
|
||||
symbol = (symbol << 1) | bit;
|
||||
if (matchBit != bit)
|
||||
{
|
||||
while (symbol < 0x100)
|
||||
symbol = (symbol << 1) | _mDecoders[symbol].Decode(rangeDecoder);
|
||||
break;
|
||||
}
|
||||
}
|
||||
while (symbol < 0x100);
|
||||
return (byte)symbol;
|
||||
}
|
||||
}
|
||||
|
||||
Decoder2[] _mCoders;
|
||||
int _mNumPrevBits;
|
||||
int _mNumPosBits;
|
||||
uint _mPosMask;
|
||||
|
||||
public void Create(int numPosBits, int numPrevBits)
|
||||
{
|
||||
if (_mCoders != null && _mNumPrevBits == numPrevBits &&
|
||||
_mNumPosBits == numPosBits)
|
||||
return;
|
||||
_mNumPosBits = numPosBits;
|
||||
_mPosMask = ((uint)1 << numPosBits) - 1;
|
||||
_mNumPrevBits = numPrevBits;
|
||||
uint numStates = (uint)1 << (_mNumPrevBits + _mNumPosBits);
|
||||
_mCoders = new Decoder2[numStates];
|
||||
for (uint i = 0; i < numStates; i++)
|
||||
_mCoders[i].Create();
|
||||
}
|
||||
|
||||
public void Init()
|
||||
{
|
||||
uint numStates = (uint)1 << (_mNumPrevBits + _mNumPosBits);
|
||||
for (uint i = 0; i < numStates; i++)
|
||||
_mCoders[i].Init();
|
||||
}
|
||||
|
||||
uint GetState(uint pos, byte prevByte)
|
||||
{ return ((pos & _mPosMask) << _mNumPrevBits) + (uint)(prevByte >> (8 - _mNumPrevBits)); }
|
||||
|
||||
public byte DecodeNormal(RangeCoder.Decoder rangeDecoder, uint pos, byte prevByte)
|
||||
{ return _mCoders[GetState(pos, prevByte)].DecodeNormal(rangeDecoder); }
|
||||
|
||||
public byte DecodeWithMatchByte(RangeCoder.Decoder rangeDecoder, uint pos, byte prevByte, byte matchByte)
|
||||
{ return _mCoders[GetState(pos, prevByte)].DecodeWithMatchByte(rangeDecoder, matchByte); }
|
||||
};
|
||||
|
||||
readonly LZ.OutWindow _mOutWindow = new LZ.OutWindow();
|
||||
readonly RangeCoder.Decoder _mRangeDecoder = new RangeCoder.Decoder();
|
||||
|
||||
readonly BitDecoder[] _mIsMatchDecoders = new BitDecoder[Base.KNumStates << Base.KNumPosStatesBitsMax];
|
||||
readonly BitDecoder[] _mIsRepDecoders = new BitDecoder[Base.KNumStates];
|
||||
readonly BitDecoder[] _mIsRepG0Decoders = new BitDecoder[Base.KNumStates];
|
||||
readonly BitDecoder[] _mIsRepG1Decoders = new BitDecoder[Base.KNumStates];
|
||||
readonly BitDecoder[] _mIsRepG2Decoders = new BitDecoder[Base.KNumStates];
|
||||
readonly BitDecoder[] _mIsRep0LongDecoders = new BitDecoder[Base.KNumStates << Base.KNumPosStatesBitsMax];
|
||||
|
||||
readonly BitTreeDecoder[] _mPosSlotDecoder = new BitTreeDecoder[Base.KNumLenToPosStates];
|
||||
readonly BitDecoder[] _mPosDecoders = new BitDecoder[Base.KNumFullDistances - Base.KEndPosModelIndex];
|
||||
|
||||
BitTreeDecoder _mPosAlignDecoder = new BitTreeDecoder(Base.KNumAlignBits);
|
||||
|
||||
readonly LenDecoder _mLenDecoder = new LenDecoder();
|
||||
readonly LenDecoder _mRepLenDecoder = new LenDecoder();
|
||||
|
||||
readonly LiteralDecoder _mLiteralDecoder = new LiteralDecoder();
|
||||
|
||||
uint _mDictionarySize;
|
||||
uint _mDictionarySizeCheck;
|
||||
|
||||
uint _mPosStateMask;
|
||||
|
||||
public Decoder()
|
||||
{
|
||||
_mDictionarySize = 0xFFFFFFFF;
|
||||
for (int i = 0; i < Base.KNumLenToPosStates; i++)
|
||||
_mPosSlotDecoder[i] = new BitTreeDecoder(Base.KNumPosSlotBits);
|
||||
}
|
||||
|
||||
void SetDictionarySize(uint dictionarySize)
|
||||
{
|
||||
if (_mDictionarySize != dictionarySize)
|
||||
{
|
||||
_mDictionarySize = dictionarySize;
|
||||
_mDictionarySizeCheck = Math.Max(_mDictionarySize, 1);
|
||||
uint blockSize = Math.Max(_mDictionarySizeCheck, (1 << 12));
|
||||
_mOutWindow.Create(blockSize);
|
||||
}
|
||||
}
|
||||
|
||||
void SetLiteralProperties(int lp, int lc)
|
||||
{
|
||||
if (lp > 8)
|
||||
throw new ArgumentException("lp > 8");
|
||||
if (lc > 8)
|
||||
throw new ArgumentException("lc > 8");
|
||||
_mLiteralDecoder.Create(lp, lc);
|
||||
}
|
||||
|
||||
void SetPosBitsProperties(int pb)
|
||||
{
|
||||
if (pb > Base.KNumPosStatesBitsMax)
|
||||
throw new ArgumentException("pb > Base.KNumPosStatesBitsMax");
|
||||
uint numPosStates = (uint)1 << pb;
|
||||
_mLenDecoder.Create(numPosStates);
|
||||
_mRepLenDecoder.Create(numPosStates);
|
||||
_mPosStateMask = numPosStates - 1;
|
||||
}
|
||||
|
||||
void Init(Stream inStream, Stream outStream)
|
||||
{
|
||||
_mRangeDecoder.Init(inStream);
|
||||
_mOutWindow.Init(outStream, false);
|
||||
|
||||
uint i;
|
||||
for (i = 0; i < Base.KNumStates; i++)
|
||||
{
|
||||
for (uint j = 0; j <= _mPosStateMask; j++)
|
||||
{
|
||||
uint index = (i << Base.KNumPosStatesBitsMax) + j;
|
||||
_mIsMatchDecoders[index].Init();
|
||||
_mIsRep0LongDecoders[index].Init();
|
||||
}
|
||||
_mIsRepDecoders[i].Init();
|
||||
_mIsRepG0Decoders[i].Init();
|
||||
_mIsRepG1Decoders[i].Init();
|
||||
_mIsRepG2Decoders[i].Init();
|
||||
}
|
||||
|
||||
_mLiteralDecoder.Init();
|
||||
for (i = 0; i < Base.KNumLenToPosStates; i++)
|
||||
_mPosSlotDecoder[i].Init();
|
||||
for (i = 0; i < Base.KNumFullDistances - Base.KEndPosModelIndex; i++)
|
||||
_mPosDecoders[i].Init();
|
||||
|
||||
_mLenDecoder.Init();
|
||||
_mRepLenDecoder.Init();
|
||||
_mPosAlignDecoder.Init();
|
||||
}
|
||||
|
||||
public void Code(Stream inStream, Stream outStream, Int64 outSize)
|
||||
{
|
||||
Init(inStream, outStream);
|
||||
|
||||
Base.State state = new Base.State();
|
||||
state.Init();
|
||||
uint rep0 = 0, rep1 = 0, rep2 = 0, rep3 = 0;
|
||||
|
||||
UInt64 nowPos64 = 0;
|
||||
UInt64 outSize64 = (UInt64)outSize;
|
||||
if (nowPos64 < outSize64)
|
||||
{
|
||||
if (_mIsMatchDecoders[state.Index << Base.KNumPosStatesBitsMax].Decode(_mRangeDecoder) != 0)
|
||||
throw new InvalidDataException("IsMatchDecoders");
|
||||
state.UpdateChar();
|
||||
byte b = _mLiteralDecoder.DecodeNormal(_mRangeDecoder, 0, 0);
|
||||
_mOutWindow.PutByte(b);
|
||||
nowPos64++;
|
||||
}
|
||||
while (nowPos64 < outSize64)
|
||||
{
|
||||
// UInt64 next = Math.Min(nowPos64 + (1 << 18), outSize64);
|
||||
// while(nowPos64 < next)
|
||||
{
|
||||
uint posState = (uint)nowPos64 & _mPosStateMask;
|
||||
if (_mIsMatchDecoders[(state.Index << Base.KNumPosStatesBitsMax) + posState].Decode(_mRangeDecoder) == 0)
|
||||
{
|
||||
byte b;
|
||||
byte prevByte = _mOutWindow.GetByte(0);
|
||||
if (!state.IsCharState())
|
||||
b = _mLiteralDecoder.DecodeWithMatchByte(_mRangeDecoder,
|
||||
(uint)nowPos64, prevByte, _mOutWindow.GetByte(rep0));
|
||||
else
|
||||
b = _mLiteralDecoder.DecodeNormal(_mRangeDecoder, (uint)nowPos64, prevByte);
|
||||
_mOutWindow.PutByte(b);
|
||||
state.UpdateChar();
|
||||
nowPos64++;
|
||||
}
|
||||
else
|
||||
{
|
||||
uint len;
|
||||
if (_mIsRepDecoders[state.Index].Decode(_mRangeDecoder) == 1)
|
||||
{
|
||||
if (_mIsRepG0Decoders[state.Index].Decode(_mRangeDecoder) == 0)
|
||||
{
|
||||
if (_mIsRep0LongDecoders[(state.Index << Base.KNumPosStatesBitsMax) + posState].Decode(_mRangeDecoder) == 0)
|
||||
{
|
||||
state.UpdateShortRep();
|
||||
_mOutWindow.PutByte(_mOutWindow.GetByte(rep0));
|
||||
nowPos64++;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
UInt32 distance;
|
||||
if (_mIsRepG1Decoders[state.Index].Decode(_mRangeDecoder) == 0)
|
||||
{
|
||||
distance = rep1;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (_mIsRepG2Decoders[state.Index].Decode(_mRangeDecoder) == 0)
|
||||
distance = rep2;
|
||||
else
|
||||
{
|
||||
distance = rep3;
|
||||
rep3 = rep2;
|
||||
}
|
||||
rep2 = rep1;
|
||||
}
|
||||
rep1 = rep0;
|
||||
rep0 = distance;
|
||||
}
|
||||
len = _mRepLenDecoder.Decode(_mRangeDecoder, posState) + Base.KMatchMinLen;
|
||||
state.UpdateRep();
|
||||
}
|
||||
else
|
||||
{
|
||||
rep3 = rep2;
|
||||
rep2 = rep1;
|
||||
rep1 = rep0;
|
||||
len = Base.KMatchMinLen + _mLenDecoder.Decode(_mRangeDecoder, posState);
|
||||
state.UpdateMatch();
|
||||
uint posSlot = _mPosSlotDecoder[Base.GetLenToPosState(len)].Decode(_mRangeDecoder);
|
||||
if (posSlot >= Base.KStartPosModelIndex)
|
||||
{
|
||||
int numDirectBits = (int)((posSlot >> 1) - 1);
|
||||
rep0 = ((2 | (posSlot & 1)) << numDirectBits);
|
||||
if (posSlot < Base.KEndPosModelIndex)
|
||||
rep0 += BitTreeDecoder.ReverseDecode(_mPosDecoders,
|
||||
rep0 - posSlot - 1, _mRangeDecoder, numDirectBits);
|
||||
else
|
||||
{
|
||||
rep0 += (_mRangeDecoder.DecodeDirectBits(
|
||||
numDirectBits - Base.KNumAlignBits) << Base.KNumAlignBits);
|
||||
rep0 += _mPosAlignDecoder.ReverseDecode(_mRangeDecoder);
|
||||
}
|
||||
}
|
||||
else
|
||||
rep0 = posSlot;
|
||||
}
|
||||
if (rep0 >= _mOutWindow.TrainSize + nowPos64 || rep0 >= _mDictionarySizeCheck)
|
||||
{
|
||||
if (rep0 == 0xFFFFFFFF)
|
||||
break;
|
||||
throw new InvalidDataException("rep0");
|
||||
}
|
||||
_mOutWindow.CopyBlock(rep0, len);
|
||||
nowPos64 += len;
|
||||
}
|
||||
}
|
||||
}
|
||||
_mOutWindow.Flush();
|
||||
_mOutWindow.ReleaseStream();
|
||||
_mRangeDecoder.ReleaseStream();
|
||||
}
|
||||
|
||||
public void SetDecoderProperties(byte[] properties)
|
||||
{
|
||||
if (properties.Length < 5)
|
||||
throw new ArgumentException("properties.Length < 5");
|
||||
int lc = properties[0] % 9;
|
||||
int remainder = properties[0] / 9;
|
||||
int lp = remainder % 5;
|
||||
int pb = remainder / 5;
|
||||
if (pb > Base.KNumPosStatesBitsMax)
|
||||
throw new ArgumentException("pb > Base.kNumPosStatesBitsMax");
|
||||
UInt32 dictionarySize = 0;
|
||||
for (int i = 0; i < 4; i++)
|
||||
dictionarySize += ((UInt32)(properties[1 + i])) << (i * 8);
|
||||
SetDictionarySize(dictionarySize);
|
||||
SetLiteralProperties(lp, lc);
|
||||
SetPosBitsProperties(pb);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user