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