123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140 |
- using System;
- namespace SharpCompress.Compressors.LZMA.RangeCoder
- {
- internal struct BitEncoder
- {
- public const int K_NUM_BIT_MODEL_TOTAL_BITS = 11;
- public const uint K_BIT_MODEL_TOTAL = (1 << K_NUM_BIT_MODEL_TOTAL_BITS);
- private const int K_NUM_MOVE_BITS = 5;
- private const int K_NUM_MOVE_REDUCING_BITS = 2;
- public const int K_NUM_BIT_PRICE_SHIFT_BITS = 6;
- private uint _prob;
- public void Init()
- {
- _prob = K_BIT_MODEL_TOTAL >> 1;
- }
- public void UpdateModel(uint symbol)
- {
- if (symbol == 0)
- {
- _prob += (K_BIT_MODEL_TOTAL - _prob) >> K_NUM_MOVE_BITS;
- }
- else
- {
- _prob -= (_prob) >> K_NUM_MOVE_BITS;
- }
- }
- public void Encode(Encoder encoder, uint symbol)
- {
- // encoder.EncodeBit(Prob, kNumBitModelTotalBits, symbol);
- // UpdateModel(symbol);
- uint newBound = (encoder._range >> K_NUM_BIT_MODEL_TOTAL_BITS) * _prob;
- if (symbol == 0)
- {
- encoder._range = newBound;
- _prob += (K_BIT_MODEL_TOTAL - _prob) >> K_NUM_MOVE_BITS;
- }
- else
- {
- encoder._low += newBound;
- encoder._range -= newBound;
- _prob -= (_prob) >> K_NUM_MOVE_BITS;
- }
- if (encoder._range < Encoder.K_TOP_VALUE)
- {
- encoder._range <<= 8;
- encoder.ShiftLow();
- }
- }
- private static readonly UInt32[] PROB_PRICES = new UInt32[K_BIT_MODEL_TOTAL >> K_NUM_MOVE_REDUCING_BITS];
- static BitEncoder()
- {
- const int kNumBits = (K_NUM_BIT_MODEL_TOTAL_BITS - K_NUM_MOVE_REDUCING_BITS);
- for (int i = kNumBits - 1; i >= 0; i--)
- {
- UInt32 start = (UInt32)1 << (kNumBits - i - 1);
- UInt32 end = (UInt32)1 << (kNumBits - i);
- for (UInt32 j = start; j < end; j++)
- {
- PROB_PRICES[j] = ((UInt32)i << K_NUM_BIT_PRICE_SHIFT_BITS) +
- (((end - j) << K_NUM_BIT_PRICE_SHIFT_BITS) >> (kNumBits - i - 1));
- }
- }
- }
- public uint GetPrice(uint symbol)
- {
- return PROB_PRICES[(((_prob - symbol) ^ ((-(int)symbol))) & (K_BIT_MODEL_TOTAL - 1)) >> K_NUM_MOVE_REDUCING_BITS];
- }
- public uint GetPrice0()
- {
- return PROB_PRICES[_prob >> K_NUM_MOVE_REDUCING_BITS];
- }
- public uint GetPrice1()
- {
- return PROB_PRICES[(K_BIT_MODEL_TOTAL - _prob) >> K_NUM_MOVE_REDUCING_BITS];
- }
- }
- internal struct BitDecoder
- {
- public const int K_NUM_BIT_MODEL_TOTAL_BITS = 11;
- public const uint K_BIT_MODEL_TOTAL = (1 << K_NUM_BIT_MODEL_TOTAL_BITS);
- private const int K_NUM_MOVE_BITS = 5;
- private uint _prob;
- public void UpdateModel(int numMoveBits, uint symbol)
- {
- if (symbol == 0)
- {
- _prob += (K_BIT_MODEL_TOTAL - _prob) >> numMoveBits;
- }
- else
- {
- _prob -= (_prob) >> numMoveBits;
- }
- }
- public void Init()
- {
- _prob = K_BIT_MODEL_TOTAL >> 1;
- }
- public uint Decode(Decoder rangeDecoder)
- {
- uint newBound = (rangeDecoder._range >> K_NUM_BIT_MODEL_TOTAL_BITS) * _prob;
- if (rangeDecoder._code < newBound)
- {
- rangeDecoder._range = newBound;
- _prob += (K_BIT_MODEL_TOTAL - _prob) >> K_NUM_MOVE_BITS;
- if (rangeDecoder._range < Decoder.K_TOP_VALUE)
- {
- rangeDecoder._code = (rangeDecoder._code << 8) | (byte)rangeDecoder._stream.ReadByte();
- rangeDecoder._range <<= 8;
- rangeDecoder._total++;
- }
- return 0;
- }
- rangeDecoder._range -= newBound;
- rangeDecoder._code -= newBound;
- _prob -= (_prob) >> K_NUM_MOVE_BITS;
- if (rangeDecoder._range < Decoder.K_TOP_VALUE)
- {
- rangeDecoder._code = (rangeDecoder._code << 8) | (byte)rangeDecoder._stream.ReadByte();
- rangeDecoder._range <<= 8;
- rangeDecoder._total++;
- }
- return 1;
- }
- }
- }
|