| 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; |
| } |
| } |
| } |