01: package SevenZip.Compression.RangeCoder;
02:
03: import java.io.IOException;
04:
05: public class Decoder {
06: static final int kTopMask = ~((1 << 24) - 1);
07:
08: static final int kNumBitModelTotalBits = 11;
09: 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: Stream = stream;
19: }
20:
21: public final void ReleaseStream() {
22: Stream = null;
23: }
24:
25: public final void Init() throws IOException {
26: Code = 0;
27: Range = -1;
28: for (int i = 0; i < 5; i++)
29: Code = (Code << 8) | Stream.read();
30: }
31:
32: public final int DecodeDirectBits(int numTotalBits)
33: throws IOException {
34: int result = 0;
35: for (int i = numTotalBits; i != 0; i--) {
36: Range >>>= 1;
37: int t = ((Code - Range) >>> 31);
38: Code -= Range & (t - 1);
39: result = (result << 1) | (1 - t);
40:
41: if ((Range & kTopMask) == 0) {
42: Code = (Code << 8) | Stream.read();
43: Range <<= 8;
44: }
45: }
46: return result;
47: }
48:
49: public int DecodeBit(short[] probs, int index) throws IOException {
50: int prob = probs[index];
51: int newBound = (Range >>> kNumBitModelTotalBits) * prob;
52: if ((Code ^ 0x80000000) < (newBound ^ 0x80000000)) {
53: Range = newBound;
54: probs[index] = (short) (prob + ((kBitModelTotal - prob) >>> kNumMoveBits));
55: if ((Range & kTopMask) == 0) {
56: Code = (Code << 8) | Stream.read();
57: Range <<= 8;
58: }
59: return 0;
60: } else {
61: Range -= newBound;
62: Code -= newBound;
63: probs[index] = (short) (prob - ((prob) >>> kNumMoveBits));
64: if ((Range & kTopMask) == 0) {
65: Code = (Code << 8) | Stream.read();
66: Range <<= 8;
67: }
68: return 1;
69: }
70: }
71:
72: public static void InitBitModels(short[] probs) {
73: for (int i = 0; i < probs.length; i++)
74: probs[i] = (kBitModelTotal >>> 1);
75: }
76: }
|