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