1baa3858d3f5d128a5c8466b700098109edcad5f2repo syncpackage SevenZip.Compression.RangeCoder;
2baa3858d3f5d128a5c8466b700098109edcad5f2repo syncimport java.io.IOException;
3baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
4baa3858d3f5d128a5c8466b700098109edcad5f2repo syncpublic class Decoder
5baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{
6baa3858d3f5d128a5c8466b700098109edcad5f2repo sync	static final int kTopMask = ~((1 << 24) - 1);
7baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
8baa3858d3f5d128a5c8466b700098109edcad5f2repo sync	static final int kNumBitModelTotalBits = 11;
9baa3858d3f5d128a5c8466b700098109edcad5f2repo sync	static final int kBitModelTotal = (1 << kNumBitModelTotalBits);
10baa3858d3f5d128a5c8466b700098109edcad5f2repo sync	static final int kNumMoveBits = 5;
11baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
12baa3858d3f5d128a5c8466b700098109edcad5f2repo sync	int Range;
13baa3858d3f5d128a5c8466b700098109edcad5f2repo sync	int Code;
14baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
15baa3858d3f5d128a5c8466b700098109edcad5f2repo sync	java.io.InputStream Stream;
16baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
17baa3858d3f5d128a5c8466b700098109edcad5f2repo sync	public final void SetStream(java.io.InputStream stream)
18baa3858d3f5d128a5c8466b700098109edcad5f2repo sync	{
19baa3858d3f5d128a5c8466b700098109edcad5f2repo sync		Stream = stream;
20baa3858d3f5d128a5c8466b700098109edcad5f2repo sync	}
21baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
22baa3858d3f5d128a5c8466b700098109edcad5f2repo sync	public final void ReleaseStream()
23baa3858d3f5d128a5c8466b700098109edcad5f2repo sync	{
24baa3858d3f5d128a5c8466b700098109edcad5f2repo sync		Stream = null;
25baa3858d3f5d128a5c8466b700098109edcad5f2repo sync	}
26baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
27baa3858d3f5d128a5c8466b700098109edcad5f2repo sync	public final void Init() throws IOException
28baa3858d3f5d128a5c8466b700098109edcad5f2repo sync	{
29baa3858d3f5d128a5c8466b700098109edcad5f2repo sync		Code = 0;
30baa3858d3f5d128a5c8466b700098109edcad5f2repo sync		Range = -1;
31baa3858d3f5d128a5c8466b700098109edcad5f2repo sync		for (int i = 0; i < 5; i++)
32baa3858d3f5d128a5c8466b700098109edcad5f2repo sync			Code = (Code << 8) | Stream.read();
33baa3858d3f5d128a5c8466b700098109edcad5f2repo sync	}
34baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
35baa3858d3f5d128a5c8466b700098109edcad5f2repo sync	public final int DecodeDirectBits(int numTotalBits) throws IOException
36baa3858d3f5d128a5c8466b700098109edcad5f2repo sync	{
37baa3858d3f5d128a5c8466b700098109edcad5f2repo sync		int result = 0;
38baa3858d3f5d128a5c8466b700098109edcad5f2repo sync		for (int i = numTotalBits; i != 0; i--)
39baa3858d3f5d128a5c8466b700098109edcad5f2repo sync		{
40baa3858d3f5d128a5c8466b700098109edcad5f2repo sync			Range >>>= 1;
41baa3858d3f5d128a5c8466b700098109edcad5f2repo sync			int t = ((Code - Range) >>> 31);
42baa3858d3f5d128a5c8466b700098109edcad5f2repo sync			Code -= Range & (t - 1);
43baa3858d3f5d128a5c8466b700098109edcad5f2repo sync			result = (result << 1) | (1 - t);
44baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
45baa3858d3f5d128a5c8466b700098109edcad5f2repo sync			if ((Range & kTopMask) == 0)
46baa3858d3f5d128a5c8466b700098109edcad5f2repo sync			{
47baa3858d3f5d128a5c8466b700098109edcad5f2repo sync				Code = (Code << 8) | Stream.read();
48baa3858d3f5d128a5c8466b700098109edcad5f2repo sync				Range <<= 8;
49baa3858d3f5d128a5c8466b700098109edcad5f2repo sync			}
50baa3858d3f5d128a5c8466b700098109edcad5f2repo sync		}
51baa3858d3f5d128a5c8466b700098109edcad5f2repo sync		return result;
52baa3858d3f5d128a5c8466b700098109edcad5f2repo sync	}
53baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
54baa3858d3f5d128a5c8466b700098109edcad5f2repo sync	public int DecodeBit(short []probs, int index) throws IOException
55baa3858d3f5d128a5c8466b700098109edcad5f2repo sync	{
56baa3858d3f5d128a5c8466b700098109edcad5f2repo sync		int prob = probs[index];
57baa3858d3f5d128a5c8466b700098109edcad5f2repo sync		int newBound = (Range >>> kNumBitModelTotalBits) * prob;
58baa3858d3f5d128a5c8466b700098109edcad5f2repo sync		if ((Code ^ 0x80000000) < (newBound ^ 0x80000000))
59baa3858d3f5d128a5c8466b700098109edcad5f2repo sync		{
60baa3858d3f5d128a5c8466b700098109edcad5f2repo sync			Range = newBound;
61baa3858d3f5d128a5c8466b700098109edcad5f2repo sync			probs[index] = (short)(prob + ((kBitModelTotal - prob) >>> kNumMoveBits));
62baa3858d3f5d128a5c8466b700098109edcad5f2repo sync			if ((Range & kTopMask) == 0)
63baa3858d3f5d128a5c8466b700098109edcad5f2repo sync			{
64baa3858d3f5d128a5c8466b700098109edcad5f2repo sync				Code = (Code << 8) | Stream.read();
65baa3858d3f5d128a5c8466b700098109edcad5f2repo sync				Range <<= 8;
66baa3858d3f5d128a5c8466b700098109edcad5f2repo sync			}
67baa3858d3f5d128a5c8466b700098109edcad5f2repo sync			return 0;
68baa3858d3f5d128a5c8466b700098109edcad5f2repo sync		}
69baa3858d3f5d128a5c8466b700098109edcad5f2repo sync		else
70baa3858d3f5d128a5c8466b700098109edcad5f2repo sync		{
71baa3858d3f5d128a5c8466b700098109edcad5f2repo sync			Range -= newBound;
72baa3858d3f5d128a5c8466b700098109edcad5f2repo sync			Code -= newBound;
73baa3858d3f5d128a5c8466b700098109edcad5f2repo sync			probs[index] = (short)(prob - ((prob) >>> kNumMoveBits));
74baa3858d3f5d128a5c8466b700098109edcad5f2repo sync			if ((Range & kTopMask) == 0)
75baa3858d3f5d128a5c8466b700098109edcad5f2repo sync			{
76baa3858d3f5d128a5c8466b700098109edcad5f2repo sync				Code = (Code << 8) | Stream.read();
77baa3858d3f5d128a5c8466b700098109edcad5f2repo sync				Range <<= 8;
78baa3858d3f5d128a5c8466b700098109edcad5f2repo sync			}
79baa3858d3f5d128a5c8466b700098109edcad5f2repo sync			return 1;
80baa3858d3f5d128a5c8466b700098109edcad5f2repo sync		}
81baa3858d3f5d128a5c8466b700098109edcad5f2repo sync	}
82baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
83baa3858d3f5d128a5c8466b700098109edcad5f2repo sync	public static void InitBitModels(short []probs)
84baa3858d3f5d128a5c8466b700098109edcad5f2repo sync	{
85baa3858d3f5d128a5c8466b700098109edcad5f2repo sync		for (int i = 0; i < probs.length; i++)
86baa3858d3f5d128a5c8466b700098109edcad5f2repo sync			probs[i] = (kBitModelTotal >>> 1);
87baa3858d3f5d128a5c8466b700098109edcad5f2repo sync	}
88baa3858d3f5d128a5c8466b700098109edcad5f2repo sync}
89