1370b324cSopenharmony_ciusing System; 2370b324cSopenharmony_ci 3370b324cSopenharmony_cinamespace SevenZip.Compression.RangeCoder 4370b324cSopenharmony_ci{ 5370b324cSopenharmony_ci struct BitEncoder 6370b324cSopenharmony_ci { 7370b324cSopenharmony_ci public const int kNumBitModelTotalBits = 11; 8370b324cSopenharmony_ci public const uint kBitModelTotal = (1 << kNumBitModelTotalBits); 9370b324cSopenharmony_ci const int kNumMoveBits = 5; 10370b324cSopenharmony_ci const int kNumMoveReducingBits = 2; 11370b324cSopenharmony_ci public const int kNumBitPriceShiftBits = 6; 12370b324cSopenharmony_ci 13370b324cSopenharmony_ci uint Prob; 14370b324cSopenharmony_ci 15370b324cSopenharmony_ci public void Init() { Prob = kBitModelTotal >> 1; } 16370b324cSopenharmony_ci 17370b324cSopenharmony_ci public void UpdateModel(uint symbol) 18370b324cSopenharmony_ci { 19370b324cSopenharmony_ci if (symbol == 0) 20370b324cSopenharmony_ci Prob += (kBitModelTotal - Prob) >> kNumMoveBits; 21370b324cSopenharmony_ci else 22370b324cSopenharmony_ci Prob -= (Prob) >> kNumMoveBits; 23370b324cSopenharmony_ci } 24370b324cSopenharmony_ci 25370b324cSopenharmony_ci public void Encode(Encoder encoder, uint symbol) 26370b324cSopenharmony_ci { 27370b324cSopenharmony_ci // encoder.EncodeBit(Prob, kNumBitModelTotalBits, symbol); 28370b324cSopenharmony_ci // UpdateModel(symbol); 29370b324cSopenharmony_ci uint newBound = (encoder.Range >> kNumBitModelTotalBits) * Prob; 30370b324cSopenharmony_ci if (symbol == 0) 31370b324cSopenharmony_ci { 32370b324cSopenharmony_ci encoder.Range = newBound; 33370b324cSopenharmony_ci Prob += (kBitModelTotal - Prob) >> kNumMoveBits; 34370b324cSopenharmony_ci } 35370b324cSopenharmony_ci else 36370b324cSopenharmony_ci { 37370b324cSopenharmony_ci encoder.Low += newBound; 38370b324cSopenharmony_ci encoder.Range -= newBound; 39370b324cSopenharmony_ci Prob -= (Prob) >> kNumMoveBits; 40370b324cSopenharmony_ci } 41370b324cSopenharmony_ci if (encoder.Range < Encoder.kTopValue) 42370b324cSopenharmony_ci { 43370b324cSopenharmony_ci encoder.Range <<= 8; 44370b324cSopenharmony_ci encoder.ShiftLow(); 45370b324cSopenharmony_ci } 46370b324cSopenharmony_ci } 47370b324cSopenharmony_ci 48370b324cSopenharmony_ci private static UInt32[] ProbPrices = new UInt32[kBitModelTotal >> kNumMoveReducingBits]; 49370b324cSopenharmony_ci 50370b324cSopenharmony_ci static BitEncoder() 51370b324cSopenharmony_ci { 52370b324cSopenharmony_ci const int kNumBits = (kNumBitModelTotalBits - kNumMoveReducingBits); 53370b324cSopenharmony_ci for (int i = kNumBits - 1; i >= 0; i--) 54370b324cSopenharmony_ci { 55370b324cSopenharmony_ci UInt32 start = (UInt32)1 << (kNumBits - i - 1); 56370b324cSopenharmony_ci UInt32 end = (UInt32)1 << (kNumBits - i); 57370b324cSopenharmony_ci for (UInt32 j = start; j < end; j++) 58370b324cSopenharmony_ci ProbPrices[j] = ((UInt32)i << kNumBitPriceShiftBits) + 59370b324cSopenharmony_ci (((end - j) << kNumBitPriceShiftBits) >> (kNumBits - i - 1)); 60370b324cSopenharmony_ci } 61370b324cSopenharmony_ci } 62370b324cSopenharmony_ci 63370b324cSopenharmony_ci public uint GetPrice(uint symbol) 64370b324cSopenharmony_ci { 65370b324cSopenharmony_ci return ProbPrices[(((Prob - symbol) ^ ((-(int)symbol))) & (kBitModelTotal - 1)) >> kNumMoveReducingBits]; 66370b324cSopenharmony_ci } 67370b324cSopenharmony_ci public uint GetPrice0() { return ProbPrices[Prob >> kNumMoveReducingBits]; } 68370b324cSopenharmony_ci public uint GetPrice1() { return ProbPrices[(kBitModelTotal - Prob) >> kNumMoveReducingBits]; } 69370b324cSopenharmony_ci } 70370b324cSopenharmony_ci 71370b324cSopenharmony_ci struct BitDecoder 72370b324cSopenharmony_ci { 73370b324cSopenharmony_ci public const int kNumBitModelTotalBits = 11; 74370b324cSopenharmony_ci public const uint kBitModelTotal = (1 << kNumBitModelTotalBits); 75370b324cSopenharmony_ci const int kNumMoveBits = 5; 76370b324cSopenharmony_ci 77370b324cSopenharmony_ci uint Prob; 78370b324cSopenharmony_ci 79370b324cSopenharmony_ci public void UpdateModel(int numMoveBits, uint symbol) 80370b324cSopenharmony_ci { 81370b324cSopenharmony_ci if (symbol == 0) 82370b324cSopenharmony_ci Prob += (kBitModelTotal - Prob) >> numMoveBits; 83370b324cSopenharmony_ci else 84370b324cSopenharmony_ci Prob -= (Prob) >> numMoveBits; 85370b324cSopenharmony_ci } 86370b324cSopenharmony_ci 87370b324cSopenharmony_ci public void Init() { Prob = kBitModelTotal >> 1; } 88370b324cSopenharmony_ci 89370b324cSopenharmony_ci public uint Decode(RangeCoder.Decoder rangeDecoder) 90370b324cSopenharmony_ci { 91370b324cSopenharmony_ci uint newBound = (uint)(rangeDecoder.Range >> kNumBitModelTotalBits) * (uint)Prob; 92370b324cSopenharmony_ci if (rangeDecoder.Code < newBound) 93370b324cSopenharmony_ci { 94370b324cSopenharmony_ci rangeDecoder.Range = newBound; 95370b324cSopenharmony_ci Prob += (kBitModelTotal - Prob) >> kNumMoveBits; 96370b324cSopenharmony_ci if (rangeDecoder.Range < Decoder.kTopValue) 97370b324cSopenharmony_ci { 98370b324cSopenharmony_ci rangeDecoder.Code = (rangeDecoder.Code << 8) | (byte)rangeDecoder.Stream.ReadByte(); 99370b324cSopenharmony_ci rangeDecoder.Range <<= 8; 100370b324cSopenharmony_ci } 101370b324cSopenharmony_ci return 0; 102370b324cSopenharmony_ci } 103370b324cSopenharmony_ci else 104370b324cSopenharmony_ci { 105370b324cSopenharmony_ci rangeDecoder.Range -= newBound; 106370b324cSopenharmony_ci rangeDecoder.Code -= newBound; 107370b324cSopenharmony_ci Prob -= (Prob) >> kNumMoveBits; 108370b324cSopenharmony_ci if (rangeDecoder.Range < Decoder.kTopValue) 109370b324cSopenharmony_ci { 110370b324cSopenharmony_ci rangeDecoder.Code = (rangeDecoder.Code << 8) | (byte)rangeDecoder.Stream.ReadByte(); 111370b324cSopenharmony_ci rangeDecoder.Range <<= 8; 112370b324cSopenharmony_ci } 113370b324cSopenharmony_ci return 1; 114370b324cSopenharmony_ci } 115370b324cSopenharmony_ci } 116370b324cSopenharmony_ci } 117370b324cSopenharmony_ci} 118