Source code
Revision control
Copy as Markdown
Other Tools
using System;↩
↩
namespace SevenZip.Compression.RangeCoder↩
{↩
class Encoder↩
{↩
public const uint kTopValue = (1 << 24);↩
↩
System.IO.Stream Stream;↩
↩
public UInt64 Low;↩
public uint Range;↩
uint _cacheSize;↩
byte _cache;↩
↩
long StartPosition;↩
↩
public void SetStream(System.IO.Stream stream)↩
{↩
Stream = stream;↩
}↩
↩
public void ReleaseStream()↩
{↩
Stream = null;↩
}↩
↩
public void Init()↩
{↩
StartPosition = Stream.Position;↩
↩
Low = 0;↩
Range = 0xFFFFFFFF;↩
_cacheSize = 1;↩
_cache = 0;↩
}↩
↩
public void FlushData()↩
{↩
for (int i = 0; i < 5; i++)↩
ShiftLow();↩
}↩
↩
public void FlushStream()↩
{↩
Stream.Flush();↩
}↩
↩
public void CloseStream()↩
{↩
Stream.Close();↩
}↩
↩
public void Encode(uint start, uint size, uint total)↩
{↩
Low += start * (Range /= total);↩
Range *= size;↩
while (Range < kTopValue)↩
{↩
Range <<= 8;↩
ShiftLow();↩
}↩
}↩
↩
public void ShiftLow()↩
{↩
if ((uint)Low < (uint)0xFF000000 || (uint)(Low >> 32) == 1)↩
{↩
byte temp = _cache;↩
do↩
{↩
Stream.WriteByte((byte)(temp + (Low >> 32)));↩
temp = 0xFF;↩
}↩
while (--_cacheSize != 0);↩
_cache = (byte)(((uint)Low) >> 24);↩
}↩
_cacheSize++;↩
Low = ((uint)Low) << 8;↩
}↩
↩
public void EncodeDirectBits(uint v, int numTotalBits)↩
{↩
for (int i = numTotalBits - 1; i >= 0; i--)↩
{↩
Range >>= 1;↩
if (((v >> i) & 1) == 1)↩
Low += Range;↩
if (Range < kTopValue)↩
{↩
Range <<= 8;↩
ShiftLow();↩
}↩
}↩
}↩
↩
public void EncodeBit(uint size0, int numTotalBits, uint symbol)↩
{↩
uint newBound = (Range >> numTotalBits) * size0;↩
if (symbol == 0)↩
Range = newBound;↩
else↩
{↩
Low += newBound;↩
Range -= newBound;↩
}↩
while (Range < kTopValue)↩
{↩
Range <<= 8;↩
ShiftLow();↩
}↩
}↩
↩
public long GetProcessedSizeAdd()↩
{↩
return _cacheSize +↩
Stream.Position - StartPosition + 4;↩
// (long)Stream.GetProcessedSize();↩
}↩
}↩
↩
class Decoder↩
{↩
public const uint kTopValue = (1 << 24);↩
public uint Range;↩
public uint Code;↩
// public Buffer.InBuffer Stream = new Buffer.InBuffer(1 << 16);↩
public System.IO.Stream Stream;↩
↩
public void Init(System.IO.Stream stream)↩
{↩
// Stream.Init(stream);↩
Stream = stream;↩
↩
Code = 0;↩
Range = 0xFFFFFFFF;↩
for (int i = 0; i < 5; i++)↩
Code = (Code << 8) | (byte)Stream.ReadByte();↩
}↩
↩
public void ReleaseStream()↩
{↩
// Stream.ReleaseStream();↩
Stream = null;↩
}↩
↩
public void CloseStream()↩
{↩
Stream.Close();↩
}↩
↩
public void Normalize()↩
{↩
while (Range < kTopValue)↩
{↩
Code = (Code << 8) | (byte)Stream.ReadByte();↩
Range <<= 8;↩
}↩
}↩
↩
public void Normalize2()↩
{↩
if (Range < kTopValue)↩
{↩
Code = (Code << 8) | (byte)Stream.ReadByte();↩
Range <<= 8;↩
}↩
}↩
↩
public uint GetThreshold(uint total)↩
{↩
return Code / (Range /= total);↩
}↩
↩
public void Decode(uint start, uint size, uint total)↩
{↩
Code -= start * Range;↩
Range *= size;↩
Normalize();↩
}↩
↩
public uint DecodeDirectBits(int numTotalBits)↩
{↩
uint range = Range;↩
uint code = Code;↩
uint result = 0;↩
for (int i = numTotalBits; i > 0; i--)↩
{↩
range >>= 1;↩
/*↩
result <<= 1;↩
if (code >= range)↩
{↩
code -= range;↩
result |= 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;↩
}↩
↩
public uint DecodeBit(uint size0, int numTotalBits)↩
{↩
uint newBound = (Range >> numTotalBits) * size0;↩
uint symbol;↩
if (Code < newBound)↩
{↩
symbol = 0;↩
Range = newBound;↩
}↩
else↩
{↩
symbol = 1;↩
Code -= newBound;↩
Range -= newBound;↩
}↩
Normalize();↩
return symbol;↩
}↩
↩
// ulong GetProcessedSize() {return Stream.GetProcessedSize(); }↩
}↩
}↩