Files
sharpcompress/src/SharpCompress/Compressors/LZMA/RangeCoder/RangeCoderBitTree.cs

163 lines
4.7 KiB
C#
Raw Normal View History

2015-12-30 11:19:42 +00:00
using System;
2016-09-26 11:49:49 +01:00
namespace SharpCompress.Compressors.LZMA.RangeCoder
2015-12-30 11:19:42 +00:00
{
internal struct BitTreeEncoder
{
2018-05-06 08:49:32 +01:00
private readonly BitEncoder[] _models;
private readonly int _numBitLevels;
2015-12-30 11:19:42 +00:00
public BitTreeEncoder(int numBitLevels)
{
2018-05-06 08:49:32 +01:00
_numBitLevels = numBitLevels;
_models = new BitEncoder[1 << numBitLevels];
2015-12-30 11:19:42 +00:00
}
public void Init()
{
2018-05-06 08:49:32 +01:00
for (uint i = 1; i < (1 << _numBitLevels); i++)
{
2018-05-06 08:49:32 +01:00
_models[i].Init();
}
2015-12-30 11:19:42 +00:00
}
public void Encode(Encoder rangeEncoder, UInt32 symbol)
{
UInt32 m = 1;
2018-05-06 08:49:32 +01:00
for (int bitIndex = _numBitLevels; bitIndex > 0;)
2015-12-30 11:19:42 +00:00
{
bitIndex--;
UInt32 bit = (symbol >> bitIndex) & 1;
2018-05-06 08:49:32 +01:00
_models[m].Encode(rangeEncoder, bit);
2015-12-30 11:19:42 +00:00
m = (m << 1) | bit;
}
}
public void ReverseEncode(Encoder rangeEncoder, UInt32 symbol)
{
UInt32 m = 1;
2018-05-06 08:49:32 +01:00
for (UInt32 i = 0; i < _numBitLevels; i++)
2015-12-30 11:19:42 +00:00
{
UInt32 bit = symbol & 1;
2018-05-06 08:49:32 +01:00
_models[m].Encode(rangeEncoder, bit);
2015-12-30 11:19:42 +00:00
m = (m << 1) | bit;
symbol >>= 1;
}
}
public UInt32 GetPrice(UInt32 symbol)
{
UInt32 price = 0;
UInt32 m = 1;
2018-05-06 08:49:32 +01:00
for (int bitIndex = _numBitLevels; bitIndex > 0;)
2015-12-30 11:19:42 +00:00
{
bitIndex--;
UInt32 bit = (symbol >> bitIndex) & 1;
2018-05-06 08:49:32 +01:00
price += _models[m].GetPrice(bit);
2015-12-30 11:19:42 +00:00
m = (m << 1) + bit;
}
return price;
}
public UInt32 ReverseGetPrice(UInt32 symbol)
{
UInt32 price = 0;
UInt32 m = 1;
2018-05-06 08:49:32 +01:00
for (int i = _numBitLevels; i > 0; i--)
2015-12-30 11:19:42 +00:00
{
UInt32 bit = symbol & 1;
symbol >>= 1;
2018-05-06 08:49:32 +01:00
price += _models[m].GetPrice(bit);
2015-12-30 11:19:42 +00:00
m = (m << 1) | bit;
}
return price;
}
2018-05-06 08:49:32 +01:00
public static UInt32 ReverseGetPrice(BitEncoder[] models, UInt32 startIndex,
int numBitLevels, UInt32 symbol)
2015-12-30 11:19:42 +00:00
{
UInt32 price = 0;
UInt32 m = 1;
2018-05-06 08:49:32 +01:00
for (int i = numBitLevels; i > 0; i--)
2015-12-30 11:19:42 +00:00
{
UInt32 bit = symbol & 1;
symbol >>= 1;
2018-05-06 08:49:32 +01:00
price += models[startIndex + m].GetPrice(bit);
2015-12-30 11:19:42 +00:00
m = (m << 1) | bit;
}
return price;
}
2018-05-06 08:49:32 +01:00
public static void ReverseEncode(BitEncoder[] models, UInt32 startIndex,
Encoder rangeEncoder, int numBitLevels, UInt32 symbol)
2015-12-30 11:19:42 +00:00
{
UInt32 m = 1;
2018-05-06 08:49:32 +01:00
for (int i = 0; i < numBitLevels; i++)
2015-12-30 11:19:42 +00:00
{
UInt32 bit = symbol & 1;
2018-05-06 08:49:32 +01:00
models[startIndex + m].Encode(rangeEncoder, bit);
2015-12-30 11:19:42 +00:00
m = (m << 1) | bit;
symbol >>= 1;
}
}
}
internal struct BitTreeDecoder
{
2018-05-06 08:49:32 +01:00
private readonly BitDecoder[] _models;
private readonly int _numBitLevels;
2015-12-30 11:19:42 +00:00
public BitTreeDecoder(int numBitLevels)
{
2018-05-06 08:49:32 +01:00
_numBitLevels = numBitLevels;
_models = new BitDecoder[1 << numBitLevels];
2015-12-30 11:19:42 +00:00
}
public void Init()
{
2018-05-06 08:49:32 +01:00
for (uint i = 1; i < (1 << _numBitLevels); i++)
{
2018-05-06 08:49:32 +01:00
_models[i].Init();
}
2015-12-30 11:19:42 +00:00
}
public uint Decode(Decoder rangeDecoder)
2015-12-30 11:19:42 +00:00
{
uint m = 1;
2018-05-06 08:49:32 +01:00
for (int bitIndex = _numBitLevels; bitIndex > 0; bitIndex--)
{
2018-05-06 08:49:32 +01:00
m = (m << 1) + _models[m].Decode(rangeDecoder);
}
2018-05-06 08:49:32 +01:00
return m - ((uint)1 << _numBitLevels);
2015-12-30 11:19:42 +00:00
}
public uint ReverseDecode(Decoder rangeDecoder)
2015-12-30 11:19:42 +00:00
{
uint m = 1;
uint symbol = 0;
2018-05-06 08:49:32 +01:00
for (int bitIndex = 0; bitIndex < _numBitLevels; bitIndex++)
2015-12-30 11:19:42 +00:00
{
2018-05-06 08:49:32 +01:00
uint bit = _models[m].Decode(rangeDecoder);
2015-12-30 11:19:42 +00:00
m <<= 1;
m += bit;
symbol |= (bit << bitIndex);
}
return symbol;
}
2018-05-06 08:49:32 +01:00
public static uint ReverseDecode(BitDecoder[] models, UInt32 startIndex,
Decoder rangeDecoder, int numBitLevels)
2015-12-30 11:19:42 +00:00
{
uint m = 1;
uint symbol = 0;
2018-05-06 08:49:32 +01:00
for (int bitIndex = 0; bitIndex < numBitLevels; bitIndex++)
2015-12-30 11:19:42 +00:00
{
2018-05-06 08:49:32 +01:00
uint bit = models[startIndex + m].Decode(rangeDecoder);
2015-12-30 11:19:42 +00:00
m <<= 1;
m += bit;
symbol |= (bit << bitIndex);
}
return symbol;
}
}
2013-04-28 12:32:55 +01:00
}