Files
sharpcompress/src/SharpCompress/Compressors/LZMA/RangeCoder/RangeCoderBitTree.cs
2018-05-06 08:49:32 +01:00

163 lines
4.7 KiB
C#

using System;
namespace SharpCompress.Compressors.LZMA.RangeCoder
{
internal struct BitTreeEncoder
{
private readonly BitEncoder[] _models;
private readonly int _numBitLevels;
public BitTreeEncoder(int numBitLevels)
{
_numBitLevels = numBitLevels;
_models = new BitEncoder[1 << numBitLevels];
}
public void Init()
{
for (uint i = 1; i < (1 << _numBitLevels); i++)
{
_models[i].Init();
}
}
public void Encode(Encoder rangeEncoder, UInt32 symbol)
{
UInt32 m = 1;
for (int bitIndex = _numBitLevels; bitIndex > 0;)
{
bitIndex--;
UInt32 bit = (symbol >> bitIndex) & 1;
_models[m].Encode(rangeEncoder, bit);
m = (m << 1) | bit;
}
}
public void ReverseEncode(Encoder rangeEncoder, UInt32 symbol)
{
UInt32 m = 1;
for (UInt32 i = 0; i < _numBitLevels; i++)
{
UInt32 bit = symbol & 1;
_models[m].Encode(rangeEncoder, bit);
m = (m << 1) | bit;
symbol >>= 1;
}
}
public UInt32 GetPrice(UInt32 symbol)
{
UInt32 price = 0;
UInt32 m = 1;
for (int bitIndex = _numBitLevels; bitIndex > 0;)
{
bitIndex--;
UInt32 bit = (symbol >> bitIndex) & 1;
price += _models[m].GetPrice(bit);
m = (m << 1) + bit;
}
return price;
}
public UInt32 ReverseGetPrice(UInt32 symbol)
{
UInt32 price = 0;
UInt32 m = 1;
for (int i = _numBitLevels; i > 0; i--)
{
UInt32 bit = symbol & 1;
symbol >>= 1;
price += _models[m].GetPrice(bit);
m = (m << 1) | bit;
}
return price;
}
public static UInt32 ReverseGetPrice(BitEncoder[] models, UInt32 startIndex,
int numBitLevels, UInt32 symbol)
{
UInt32 price = 0;
UInt32 m = 1;
for (int i = numBitLevels; i > 0; i--)
{
UInt32 bit = symbol & 1;
symbol >>= 1;
price += models[startIndex + m].GetPrice(bit);
m = (m << 1) | bit;
}
return price;
}
public static void ReverseEncode(BitEncoder[] models, UInt32 startIndex,
Encoder rangeEncoder, int numBitLevels, UInt32 symbol)
{
UInt32 m = 1;
for (int i = 0; i < numBitLevels; i++)
{
UInt32 bit = symbol & 1;
models[startIndex + m].Encode(rangeEncoder, bit);
m = (m << 1) | bit;
symbol >>= 1;
}
}
}
internal 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;
}
}
}