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 |
|
---|
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 | }
|
---|