Upload 2.0.2
[physicsfs] / lzma / Java / SevenZip / Compression / RangeCoder / Decoder.java
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 }