1 using System; 2 3 namespace SevenZip.Compression.RangeCoder 4 { 5 struct BitEncoder 6 { 7 public const int kNumBitModelTotalBits = 11; 8 public const uint kBitModelTotal = (1 << kNumBitModelTotalBits); 9 const int kNumMoveBits = 5; 10 const int kNumMoveReducingBits = 2; 11 public const int kNumBitPriceShiftBits = 6; 12 13 uint Prob; 14 InitSevenZip.Compression.RangeCoder.BitEncoder15 public void Init() { Prob = kBitModelTotal >> 1; } 16 UpdateModelSevenZip.Compression.RangeCoder.BitEncoder17 public void UpdateModel(uint symbol) 18 { 19 if (symbol == 0) 20 Prob += (kBitModelTotal - Prob) >> kNumMoveBits; 21 else 22 Prob -= (Prob) >> kNumMoveBits; 23 } 24 EncodeSevenZip.Compression.RangeCoder.BitEncoder25 public void Encode(Encoder encoder, uint symbol) 26 { 27 // encoder.EncodeBit(Prob, kNumBitModelTotalBits, symbol); 28 // UpdateModel(symbol); 29 uint newBound = (encoder.Range >> kNumBitModelTotalBits) * Prob; 30 if (symbol == 0) 31 { 32 encoder.Range = newBound; 33 Prob += (kBitModelTotal - Prob) >> kNumMoveBits; 34 } 35 else 36 { 37 encoder.Low += newBound; 38 encoder.Range -= newBound; 39 Prob -= (Prob) >> kNumMoveBits; 40 } 41 if (encoder.Range < Encoder.kTopValue) 42 { 43 encoder.Range <<= 8; 44 encoder.ShiftLow(); 45 } 46 } 47 48 private static UInt32[] ProbPrices = new UInt32[kBitModelTotal >> kNumMoveReducingBits]; 49 BitEncoderSevenZip.Compression.RangeCoder.BitEncoder50 static BitEncoder() 51 { 52 const int kNumBits = (kNumBitModelTotalBits - kNumMoveReducingBits); 53 for (int i = kNumBits - 1; i >= 0; i--) 54 { 55 UInt32 start = (UInt32)1 << (kNumBits - i - 1); 56 UInt32 end = (UInt32)1 << (kNumBits - i); 57 for (UInt32 j = start; j < end; j++) 58 ProbPrices[j] = ((UInt32)i << kNumBitPriceShiftBits) + 59 (((end - j) << kNumBitPriceShiftBits) >> (kNumBits - i - 1)); 60 } 61 } 62 GetPriceSevenZip.Compression.RangeCoder.BitEncoder63 public uint GetPrice(uint symbol) 64 { 65 return ProbPrices[(((Prob - symbol) ^ ((-(int)symbol))) & (kBitModelTotal - 1)) >> kNumMoveReducingBits]; 66 } GetPrice0SevenZip.Compression.RangeCoder.BitEncoder67 public uint GetPrice0() { return ProbPrices[Prob >> kNumMoveReducingBits]; } GetPrice1SevenZip.Compression.RangeCoder.BitEncoder68 public uint GetPrice1() { return ProbPrices[(kBitModelTotal - Prob) >> kNumMoveReducingBits]; } 69 } 70 71 struct BitDecoder 72 { 73 public const int kNumBitModelTotalBits = 11; 74 public const uint kBitModelTotal = (1 << kNumBitModelTotalBits); 75 const int kNumMoveBits = 5; 76 77 uint Prob; 78 UpdateModelSevenZip.Compression.RangeCoder.BitDecoder79 public void UpdateModel(int numMoveBits, uint symbol) 80 { 81 if (symbol == 0) 82 Prob += (kBitModelTotal - Prob) >> numMoveBits; 83 else 84 Prob -= (Prob) >> numMoveBits; 85 } 86 InitSevenZip.Compression.RangeCoder.BitDecoder87 public void Init() { Prob = kBitModelTotal >> 1; } 88 DecodeSevenZip.Compression.RangeCoder.BitDecoder89 public uint Decode(RangeCoder.Decoder rangeDecoder) 90 { 91 uint newBound = (uint)(rangeDecoder.Range >> kNumBitModelTotalBits) * (uint)Prob; 92 if (rangeDecoder.Code < newBound) 93 { 94 rangeDecoder.Range = newBound; 95 Prob += (kBitModelTotal - Prob) >> kNumMoveBits; 96 if (rangeDecoder.Range < Decoder.kTopValue) 97 { 98 rangeDecoder.Code = (rangeDecoder.Code << 8) | (byte)rangeDecoder.Stream.ReadByte(); 99 rangeDecoder.Range <<= 8; 100 } 101 return 0; 102 } 103 else 104 { 105 rangeDecoder.Range -= newBound; 106 rangeDecoder.Code -= newBound; 107 Prob -= (Prob) >> kNumMoveBits; 108 if (rangeDecoder.Range < Decoder.kTopValue) 109 { 110 rangeDecoder.Code = (rangeDecoder.Code << 8) | (byte)rangeDecoder.Stream.ReadByte(); 111 rangeDecoder.Range <<= 8; 112 } 113 return 1; 114 } 115 } 116 } 117 } 118