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