1 package SevenZip.Compression.RangeCoder;
2 import java.io.IOException;
3 
4 public 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 
SetStream(java.io.InputStream stream)17 	public final void SetStream(java.io.InputStream stream)
18 	{
19 		Stream = stream;
20 	}
21 
ReleaseStream()22 	public final void ReleaseStream()
23 	{
24 		Stream = null;
25 	}
26 
Init()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 
DecodeDirectBits(int numTotalBits)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 
DecodeBit(short []probs, int index)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 
InitBitModels(short []probs)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