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