1baa3858d3f5d128a5c8466b700098109edcad5f2repo syncpackage SevenZip.Compression.RangeCoder;
2baa3858d3f5d128a5c8466b700098109edcad5f2repo syncimport java.io.IOException;
3baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
4baa3858d3f5d128a5c8466b700098109edcad5f2repo syncpublic class BitTreeEncoder
5baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{
6baa3858d3f5d128a5c8466b700098109edcad5f2repo sync	short[] Models;
7baa3858d3f5d128a5c8466b700098109edcad5f2repo sync	int NumBitLevels;
8baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
9baa3858d3f5d128a5c8466b700098109edcad5f2repo sync	public BitTreeEncoder(int numBitLevels)
10baa3858d3f5d128a5c8466b700098109edcad5f2repo sync	{
11baa3858d3f5d128a5c8466b700098109edcad5f2repo sync		NumBitLevels = numBitLevels;
12baa3858d3f5d128a5c8466b700098109edcad5f2repo sync		Models = new short[1 << numBitLevels];
13baa3858d3f5d128a5c8466b700098109edcad5f2repo sync	}
14baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
15baa3858d3f5d128a5c8466b700098109edcad5f2repo sync	public void Init()
16baa3858d3f5d128a5c8466b700098109edcad5f2repo sync	{
17baa3858d3f5d128a5c8466b700098109edcad5f2repo sync		Decoder.InitBitModels(Models);
18baa3858d3f5d128a5c8466b700098109edcad5f2repo sync	}
19baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
20baa3858d3f5d128a5c8466b700098109edcad5f2repo sync	public void Encode(Encoder rangeEncoder, int symbol) throws IOException
21baa3858d3f5d128a5c8466b700098109edcad5f2repo sync	{
22baa3858d3f5d128a5c8466b700098109edcad5f2repo sync		int m = 1;
23baa3858d3f5d128a5c8466b700098109edcad5f2repo sync		for (int bitIndex = NumBitLevels; bitIndex != 0; )
24baa3858d3f5d128a5c8466b700098109edcad5f2repo sync		{
25baa3858d3f5d128a5c8466b700098109edcad5f2repo sync			bitIndex--;
26baa3858d3f5d128a5c8466b700098109edcad5f2repo sync			int bit = (symbol >>> bitIndex) & 1;
27baa3858d3f5d128a5c8466b700098109edcad5f2repo sync			rangeEncoder.Encode(Models, m, bit);
28baa3858d3f5d128a5c8466b700098109edcad5f2repo sync			m = (m << 1) | bit;
29baa3858d3f5d128a5c8466b700098109edcad5f2repo sync		}
30baa3858d3f5d128a5c8466b700098109edcad5f2repo sync	}
31baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
32baa3858d3f5d128a5c8466b700098109edcad5f2repo sync	public void ReverseEncode(Encoder rangeEncoder, int symbol) throws IOException
33baa3858d3f5d128a5c8466b700098109edcad5f2repo sync	{
34baa3858d3f5d128a5c8466b700098109edcad5f2repo sync		int m = 1;
35baa3858d3f5d128a5c8466b700098109edcad5f2repo sync		for (int  i = 0; i < NumBitLevels; i++)
36baa3858d3f5d128a5c8466b700098109edcad5f2repo sync		{
37baa3858d3f5d128a5c8466b700098109edcad5f2repo sync			int bit = symbol & 1;
38baa3858d3f5d128a5c8466b700098109edcad5f2repo sync			rangeEncoder.Encode(Models, m, bit);
39baa3858d3f5d128a5c8466b700098109edcad5f2repo sync			m = (m << 1) | bit;
40baa3858d3f5d128a5c8466b700098109edcad5f2repo sync			symbol >>= 1;
41baa3858d3f5d128a5c8466b700098109edcad5f2repo sync		}
42baa3858d3f5d128a5c8466b700098109edcad5f2repo sync	}
43baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
44baa3858d3f5d128a5c8466b700098109edcad5f2repo sync	public int GetPrice(int symbol)
45baa3858d3f5d128a5c8466b700098109edcad5f2repo sync	{
46baa3858d3f5d128a5c8466b700098109edcad5f2repo sync		int price = 0;
47baa3858d3f5d128a5c8466b700098109edcad5f2repo sync		int m = 1;
48baa3858d3f5d128a5c8466b700098109edcad5f2repo sync		for (int bitIndex = NumBitLevels; bitIndex != 0; )
49baa3858d3f5d128a5c8466b700098109edcad5f2repo sync		{
50baa3858d3f5d128a5c8466b700098109edcad5f2repo sync			bitIndex--;
51baa3858d3f5d128a5c8466b700098109edcad5f2repo sync			int bit = (symbol >>> bitIndex) & 1;
52baa3858d3f5d128a5c8466b700098109edcad5f2repo sync			price += Encoder.GetPrice(Models[m], bit);
53baa3858d3f5d128a5c8466b700098109edcad5f2repo sync			m = (m << 1) + bit;
54baa3858d3f5d128a5c8466b700098109edcad5f2repo sync		}
55baa3858d3f5d128a5c8466b700098109edcad5f2repo sync		return price;
56baa3858d3f5d128a5c8466b700098109edcad5f2repo sync	}
57baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
58baa3858d3f5d128a5c8466b700098109edcad5f2repo sync	public int ReverseGetPrice(int symbol)
59baa3858d3f5d128a5c8466b700098109edcad5f2repo sync	{
60baa3858d3f5d128a5c8466b700098109edcad5f2repo sync		int price = 0;
61baa3858d3f5d128a5c8466b700098109edcad5f2repo sync		int m = 1;
62baa3858d3f5d128a5c8466b700098109edcad5f2repo sync		for (int i = NumBitLevels; i != 0; i--)
63baa3858d3f5d128a5c8466b700098109edcad5f2repo sync		{
64baa3858d3f5d128a5c8466b700098109edcad5f2repo sync			int bit = symbol & 1;
65baa3858d3f5d128a5c8466b700098109edcad5f2repo sync			symbol >>>= 1;
66baa3858d3f5d128a5c8466b700098109edcad5f2repo sync			price += Encoder.GetPrice(Models[m], bit);
67baa3858d3f5d128a5c8466b700098109edcad5f2repo sync			m = (m << 1) | bit;
68baa3858d3f5d128a5c8466b700098109edcad5f2repo sync		}
69baa3858d3f5d128a5c8466b700098109edcad5f2repo sync		return price;
70baa3858d3f5d128a5c8466b700098109edcad5f2repo sync	}
71baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
72baa3858d3f5d128a5c8466b700098109edcad5f2repo sync	public static int ReverseGetPrice(short[] Models, int startIndex,
73baa3858d3f5d128a5c8466b700098109edcad5f2repo sync			int NumBitLevels, int symbol)
74baa3858d3f5d128a5c8466b700098109edcad5f2repo sync	{
75baa3858d3f5d128a5c8466b700098109edcad5f2repo sync		int price = 0;
76baa3858d3f5d128a5c8466b700098109edcad5f2repo sync		int m = 1;
77baa3858d3f5d128a5c8466b700098109edcad5f2repo sync		for (int i = NumBitLevels; i != 0; i--)
78baa3858d3f5d128a5c8466b700098109edcad5f2repo sync		{
79baa3858d3f5d128a5c8466b700098109edcad5f2repo sync			int bit = symbol & 1;
80baa3858d3f5d128a5c8466b700098109edcad5f2repo sync			symbol >>>= 1;
81baa3858d3f5d128a5c8466b700098109edcad5f2repo sync			price += Encoder.GetPrice(Models[startIndex + m], bit);
82baa3858d3f5d128a5c8466b700098109edcad5f2repo sync			m = (m << 1) | bit;
83baa3858d3f5d128a5c8466b700098109edcad5f2repo sync		}
84baa3858d3f5d128a5c8466b700098109edcad5f2repo sync		return price;
85baa3858d3f5d128a5c8466b700098109edcad5f2repo sync	}
86baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
87baa3858d3f5d128a5c8466b700098109edcad5f2repo sync	public static void ReverseEncode(short[] Models, int startIndex,
88baa3858d3f5d128a5c8466b700098109edcad5f2repo sync			Encoder rangeEncoder, int NumBitLevels, int symbol) throws IOException
89baa3858d3f5d128a5c8466b700098109edcad5f2repo sync	{
90baa3858d3f5d128a5c8466b700098109edcad5f2repo sync		int m = 1;
91baa3858d3f5d128a5c8466b700098109edcad5f2repo sync		for (int i = 0; i < NumBitLevels; i++)
92baa3858d3f5d128a5c8466b700098109edcad5f2repo sync		{
93baa3858d3f5d128a5c8466b700098109edcad5f2repo sync			int bit = symbol & 1;
94baa3858d3f5d128a5c8466b700098109edcad5f2repo sync			rangeEncoder.Encode(Models, startIndex + m, bit);
95baa3858d3f5d128a5c8466b700098109edcad5f2repo sync			m = (m << 1) | bit;
96baa3858d3f5d128a5c8466b700098109edcad5f2repo sync			symbol >>= 1;
97baa3858d3f5d128a5c8466b700098109edcad5f2repo sync		}
98baa3858d3f5d128a5c8466b700098109edcad5f2repo sync	}
99baa3858d3f5d128a5c8466b700098109edcad5f2repo sync}
100