using System; | |
namespace SevenZip.Compression.RangeCoder | |
{ | |
struct BitTreeEncoder | |
{ | |
BitEncoder[] Models; | |
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; | |
} | |
} | |
} | |
struct BitTreeDecoder | |
{ | |
BitDecoder[] Models; | |
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(RangeCoder.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(RangeCoder.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, | |
RangeCoder.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; | |
} | |
} | |
} |