1370b324cSopenharmony_ciusing System;
2370b324cSopenharmony_ci
3370b324cSopenharmony_cinamespace SevenZip.Compression.RangeCoder
4370b324cSopenharmony_ci{
5370b324cSopenharmony_ci	struct BitTreeEncoder
6370b324cSopenharmony_ci	{
7370b324cSopenharmony_ci		BitEncoder[] Models;
8370b324cSopenharmony_ci		int NumBitLevels;
9370b324cSopenharmony_ci
10370b324cSopenharmony_ci		public BitTreeEncoder(int numBitLevels)
11370b324cSopenharmony_ci		{
12370b324cSopenharmony_ci			NumBitLevels = numBitLevels;
13370b324cSopenharmony_ci			Models = new BitEncoder[1 << numBitLevels];
14370b324cSopenharmony_ci		}
15370b324cSopenharmony_ci
16370b324cSopenharmony_ci		public void Init()
17370b324cSopenharmony_ci		{
18370b324cSopenharmony_ci			for (uint i = 1; i < (1 << NumBitLevels); i++)
19370b324cSopenharmony_ci				Models[i].Init();
20370b324cSopenharmony_ci		}
21370b324cSopenharmony_ci
22370b324cSopenharmony_ci		public void Encode(Encoder rangeEncoder, UInt32 symbol)
23370b324cSopenharmony_ci		{
24370b324cSopenharmony_ci			UInt32 m = 1;
25370b324cSopenharmony_ci			for (int bitIndex = NumBitLevels; bitIndex > 0; )
26370b324cSopenharmony_ci			{
27370b324cSopenharmony_ci				bitIndex--;
28370b324cSopenharmony_ci				UInt32 bit = (symbol >> bitIndex) & 1;
29370b324cSopenharmony_ci				Models[m].Encode(rangeEncoder, bit);
30370b324cSopenharmony_ci				m = (m << 1) | bit;
31370b324cSopenharmony_ci			}
32370b324cSopenharmony_ci		}
33370b324cSopenharmony_ci
34370b324cSopenharmony_ci		public void ReverseEncode(Encoder rangeEncoder, UInt32 symbol)
35370b324cSopenharmony_ci		{
36370b324cSopenharmony_ci			UInt32 m = 1;
37370b324cSopenharmony_ci			for (UInt32 i = 0; i < NumBitLevels; i++)
38370b324cSopenharmony_ci			{
39370b324cSopenharmony_ci				UInt32 bit = symbol & 1;
40370b324cSopenharmony_ci				Models[m].Encode(rangeEncoder, bit);
41370b324cSopenharmony_ci				m = (m << 1) | bit;
42370b324cSopenharmony_ci				symbol >>= 1;
43370b324cSopenharmony_ci			}
44370b324cSopenharmony_ci		}
45370b324cSopenharmony_ci
46370b324cSopenharmony_ci		public UInt32 GetPrice(UInt32 symbol)
47370b324cSopenharmony_ci		{
48370b324cSopenharmony_ci			UInt32 price = 0;
49370b324cSopenharmony_ci			UInt32 m = 1;
50370b324cSopenharmony_ci			for (int bitIndex = NumBitLevels; bitIndex > 0; )
51370b324cSopenharmony_ci			{
52370b324cSopenharmony_ci				bitIndex--;
53370b324cSopenharmony_ci				UInt32 bit = (symbol >> bitIndex) & 1;
54370b324cSopenharmony_ci				price += Models[m].GetPrice(bit);
55370b324cSopenharmony_ci				m = (m << 1) + bit;
56370b324cSopenharmony_ci			}
57370b324cSopenharmony_ci			return price;
58370b324cSopenharmony_ci		}
59370b324cSopenharmony_ci
60370b324cSopenharmony_ci		public UInt32 ReverseGetPrice(UInt32 symbol)
61370b324cSopenharmony_ci		{
62370b324cSopenharmony_ci			UInt32 price = 0;
63370b324cSopenharmony_ci			UInt32 m = 1;
64370b324cSopenharmony_ci			for (int i = NumBitLevels; i > 0; i--)
65370b324cSopenharmony_ci			{
66370b324cSopenharmony_ci				UInt32 bit = symbol & 1;
67370b324cSopenharmony_ci				symbol >>= 1;
68370b324cSopenharmony_ci				price += Models[m].GetPrice(bit);
69370b324cSopenharmony_ci				m = (m << 1) | bit;
70370b324cSopenharmony_ci			}
71370b324cSopenharmony_ci			return price;
72370b324cSopenharmony_ci		}
73370b324cSopenharmony_ci
74370b324cSopenharmony_ci		public static UInt32 ReverseGetPrice(BitEncoder[] Models, UInt32 startIndex,
75370b324cSopenharmony_ci			int NumBitLevels, UInt32 symbol)
76370b324cSopenharmony_ci		{
77370b324cSopenharmony_ci			UInt32 price = 0;
78370b324cSopenharmony_ci			UInt32 m = 1;
79370b324cSopenharmony_ci			for (int i = NumBitLevels; i > 0; i--)
80370b324cSopenharmony_ci			{
81370b324cSopenharmony_ci				UInt32 bit = symbol & 1;
82370b324cSopenharmony_ci				symbol >>= 1;
83370b324cSopenharmony_ci				price += Models[startIndex + m].GetPrice(bit);
84370b324cSopenharmony_ci				m = (m << 1) | bit;
85370b324cSopenharmony_ci			}
86370b324cSopenharmony_ci			return price;
87370b324cSopenharmony_ci		}
88370b324cSopenharmony_ci
89370b324cSopenharmony_ci		public static void ReverseEncode(BitEncoder[] Models, UInt32 startIndex,
90370b324cSopenharmony_ci			Encoder rangeEncoder, int NumBitLevels, UInt32 symbol)
91370b324cSopenharmony_ci		{
92370b324cSopenharmony_ci			UInt32 m = 1;
93370b324cSopenharmony_ci			for (int i = 0; i < NumBitLevels; i++)
94370b324cSopenharmony_ci			{
95370b324cSopenharmony_ci				UInt32 bit = symbol & 1;
96370b324cSopenharmony_ci				Models[startIndex + m].Encode(rangeEncoder, bit);
97370b324cSopenharmony_ci				m = (m << 1) | bit;
98370b324cSopenharmony_ci				symbol >>= 1;
99370b324cSopenharmony_ci			}
100370b324cSopenharmony_ci		}
101370b324cSopenharmony_ci	}
102370b324cSopenharmony_ci
103370b324cSopenharmony_ci	struct BitTreeDecoder
104370b324cSopenharmony_ci	{
105370b324cSopenharmony_ci		BitDecoder[] Models;
106370b324cSopenharmony_ci		int NumBitLevels;
107370b324cSopenharmony_ci
108370b324cSopenharmony_ci		public BitTreeDecoder(int numBitLevels)
109370b324cSopenharmony_ci		{
110370b324cSopenharmony_ci			NumBitLevels = numBitLevels;
111370b324cSopenharmony_ci			Models = new BitDecoder[1 << numBitLevels];
112370b324cSopenharmony_ci		}
113370b324cSopenharmony_ci
114370b324cSopenharmony_ci		public void Init()
115370b324cSopenharmony_ci		{
116370b324cSopenharmony_ci			for (uint i = 1; i < (1 << NumBitLevels); i++)
117370b324cSopenharmony_ci				Models[i].Init();
118370b324cSopenharmony_ci		}
119370b324cSopenharmony_ci
120370b324cSopenharmony_ci		public uint Decode(RangeCoder.Decoder rangeDecoder)
121370b324cSopenharmony_ci		{
122370b324cSopenharmony_ci			uint m = 1;
123370b324cSopenharmony_ci			for (int bitIndex = NumBitLevels; bitIndex > 0; bitIndex--)
124370b324cSopenharmony_ci				m = (m << 1) + Models[m].Decode(rangeDecoder);
125370b324cSopenharmony_ci			return m - ((uint)1 << NumBitLevels);
126370b324cSopenharmony_ci		}
127370b324cSopenharmony_ci
128370b324cSopenharmony_ci		public uint ReverseDecode(RangeCoder.Decoder rangeDecoder)
129370b324cSopenharmony_ci		{
130370b324cSopenharmony_ci			uint m = 1;
131370b324cSopenharmony_ci			uint symbol = 0;
132370b324cSopenharmony_ci			for (int bitIndex = 0; bitIndex < NumBitLevels; bitIndex++)
133370b324cSopenharmony_ci			{
134370b324cSopenharmony_ci				uint bit = Models[m].Decode(rangeDecoder);
135370b324cSopenharmony_ci				m <<= 1;
136370b324cSopenharmony_ci				m += bit;
137370b324cSopenharmony_ci				symbol |= (bit << bitIndex);
138370b324cSopenharmony_ci			}
139370b324cSopenharmony_ci			return symbol;
140370b324cSopenharmony_ci		}
141370b324cSopenharmony_ci
142370b324cSopenharmony_ci		public static uint ReverseDecode(BitDecoder[] Models, UInt32 startIndex,
143370b324cSopenharmony_ci			RangeCoder.Decoder rangeDecoder, int NumBitLevels)
144370b324cSopenharmony_ci		{
145370b324cSopenharmony_ci			uint m = 1;
146370b324cSopenharmony_ci			uint symbol = 0;
147370b324cSopenharmony_ci			for (int bitIndex = 0; bitIndex < NumBitLevels; bitIndex++)
148370b324cSopenharmony_ci			{
149370b324cSopenharmony_ci				uint bit = Models[startIndex + m].Decode(rangeDecoder);
150370b324cSopenharmony_ci				m <<= 1;
151370b324cSopenharmony_ci				m += bit;
152370b324cSopenharmony_ci				symbol |= (bit << bitIndex);
153370b324cSopenharmony_ci			}
154370b324cSopenharmony_ci			return symbol;
155370b324cSopenharmony_ci		}
156370b324cSopenharmony_ci	}
157370b324cSopenharmony_ci}
158