Upload 2.0.2
[physicsfs] / lzma / Java / SevenZip / Compression / RangeCoder / Encoder.java
1 package SevenZip.Compression.RangeCoder;
2 import java.io.IOException;
3
4 public class Encoder
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         java.io.OutputStream Stream;
13
14         long Low;
15         int Range;
16         int _cacheSize;
17         int _cache;
18         
19         long _position;
20         
21         public void SetStream(java.io.OutputStream stream)
22         {
23                 Stream = stream;
24         }
25         
26         public void ReleaseStream()
27         {
28                 Stream = null;
29         }
30         
31         public void Init()
32         {
33                 _position = 0;
34                 Low = 0;
35                 Range = -1;
36                 _cacheSize = 1;
37                 _cache = 0;
38         }
39         
40         public void FlushData() throws IOException
41         {
42                 for (int i = 0; i < 5; i++)
43                         ShiftLow();
44         }
45         
46         public void FlushStream() throws IOException
47         {
48                 Stream.flush();
49         }
50         
51         public void ShiftLow() throws IOException
52         {
53                 int LowHi = (int)(Low >>> 32);
54                 if (LowHi != 0 || Low < 0xFF000000L)
55                 {
56                         _position += _cacheSize;
57                         int temp = _cache;
58                         do
59                         {
60                                 Stream.write(temp + LowHi);
61                                 temp = 0xFF;
62                         }
63                         while(--_cacheSize != 0);
64                         _cache = (((int)Low) >>> 24);
65                 }
66                 _cacheSize++;
67                 Low = (Low & 0xFFFFFF) << 8;
68         }
69         
70         public void EncodeDirectBits(int v, int numTotalBits) throws IOException
71         {
72                 for (int i = numTotalBits - 1; i >= 0; i--)
73                 {
74                         Range >>>= 1;
75                         if (((v >>> i) & 1) == 1)
76                                 Low += Range;
77                         if ((Range & Encoder.kTopMask) == 0)
78                         {
79                                 Range <<= 8;
80                                 ShiftLow();
81                         }
82                 }
83         }
84         
85         
86         public long GetProcessedSizeAdd()
87         {
88                 return _cacheSize + _position + 4;
89         }
90         
91         
92         
93         static final int kNumMoveReducingBits = 2;
94         public static final int kNumBitPriceShiftBits = 6;
95         
96         public static void InitBitModels(short []probs)
97         {
98                 for (int i = 0; i < probs.length; i++)
99                         probs[i] = (kBitModelTotal >>> 1);
100         }
101         
102         public void Encode(short []probs, int index, int symbol) throws IOException
103         {
104                 int prob = probs[index];
105                 int newBound = (Range >>> kNumBitModelTotalBits) * prob;
106                 if (symbol == 0)
107                 {
108                         Range = newBound;
109                         probs[index] = (short)(prob + ((kBitModelTotal - prob) >>> kNumMoveBits));
110                 }
111                 else
112                 {
113                         Low += (newBound & 0xFFFFFFFFL);
114                         Range -= newBound;
115                         probs[index] = (short)(prob - ((prob) >>> kNumMoveBits));
116                 }
117                 if ((Range & kTopMask) == 0)
118                 {
119                         Range <<= 8;
120                         ShiftLow();
121                 }
122         }
123         
124         private static int[] ProbPrices = new int[kBitModelTotal >>> kNumMoveReducingBits];
125         
126         static
127         {
128                 int kNumBits = (kNumBitModelTotalBits - kNumMoveReducingBits);
129                 for (int i = kNumBits - 1; i >= 0; i--)
130                 {
131                         int start = 1 << (kNumBits - i - 1);
132                         int end = 1 << (kNumBits - i);
133                         for (int j = start; j < end; j++)
134                                 ProbPrices[j] = (i << kNumBitPriceShiftBits) +
135                                                 (((end - j) << kNumBitPriceShiftBits) >>> (kNumBits - i - 1));
136                 }
137         }
138         
139         static public int GetPrice(int Prob, int symbol)
140         {
141                 return ProbPrices[(((Prob - symbol) ^ ((-symbol))) & (kBitModelTotal - 1)) >>> kNumMoveReducingBits];
142         }
143         static public int GetPrice0(int Prob)
144         { 
145                 return ProbPrices[Prob >>> kNumMoveReducingBits]; 
146         }
147         static public int GetPrice1(int Prob)
148         { 
149                 return ProbPrices[(kBitModelTotal - Prob) >>> kNumMoveReducingBits]; 
150         }
151 }