Upload 2.0.2
[physicsfs] / lzma / Java / SevenZip / Compression / LZMA / Decoder.java
1 package SevenZip.Compression.LZMA;
2
3 import SevenZip.Compression.RangeCoder.BitTreeDecoder;
4 import SevenZip.Compression.LZMA.Base;
5 import SevenZip.Compression.LZ.OutWindow;
6 import java.io.IOException;
7
8 public class Decoder
9 {
10         class LenDecoder
11         {
12                 short[] m_Choice = new short[2];
13                 BitTreeDecoder[] m_LowCoder = new BitTreeDecoder[Base.kNumPosStatesMax];
14                 BitTreeDecoder[] m_MidCoder = new BitTreeDecoder[Base.kNumPosStatesMax];
15                 BitTreeDecoder m_HighCoder = new BitTreeDecoder(Base.kNumHighLenBits);
16                 int m_NumPosStates = 0;
17                 
18                 public void Create(int numPosStates)
19                 {
20                         for (; m_NumPosStates < numPosStates; m_NumPosStates++)
21                         {
22                                 m_LowCoder[m_NumPosStates] = new BitTreeDecoder(Base.kNumLowLenBits);
23                                 m_MidCoder[m_NumPosStates] = new BitTreeDecoder(Base.kNumMidLenBits);
24                         }
25                 }
26                 
27                 public void Init()
28                 {
29                         SevenZip.Compression.RangeCoder.Decoder.InitBitModels(m_Choice);
30                         for (int posState = 0; posState < m_NumPosStates; posState++)
31                         {
32                                 m_LowCoder[posState].Init();
33                                 m_MidCoder[posState].Init();
34                         }
35                         m_HighCoder.Init();
36                 }
37                 
38                 public int Decode(SevenZip.Compression.RangeCoder.Decoder rangeDecoder, int posState) throws IOException
39                 {
40                         if (rangeDecoder.DecodeBit(m_Choice, 0) == 0)
41                                 return m_LowCoder[posState].Decode(rangeDecoder);
42                         int symbol = Base.kNumLowLenSymbols;
43                         if (rangeDecoder.DecodeBit(m_Choice, 1) == 0)
44                                 symbol += m_MidCoder[posState].Decode(rangeDecoder);
45                         else
46                                 symbol += Base.kNumMidLenSymbols + m_HighCoder.Decode(rangeDecoder);
47                         return symbol;
48                 }
49         }
50         
51         class LiteralDecoder
52         {
53                 class Decoder2
54                 {
55                         short[] m_Decoders = new short[0x300];
56                         
57                         public void Init()
58                         {
59                                 SevenZip.Compression.RangeCoder.Decoder.InitBitModels(m_Decoders);
60                         }
61                         
62                         public byte DecodeNormal(SevenZip.Compression.RangeCoder.Decoder rangeDecoder) throws IOException
63                         {
64                                 int symbol = 1;
65                                 do
66                                         symbol = (symbol << 1) | rangeDecoder.DecodeBit(m_Decoders, symbol);
67                                 while (symbol < 0x100);
68                                 return (byte)symbol;
69                         }
70                         
71                         public byte DecodeWithMatchByte(SevenZip.Compression.RangeCoder.Decoder rangeDecoder, byte matchByte) throws IOException
72                         {
73                                 int symbol = 1;
74                                 do
75                                 {
76                                         int matchBit = (matchByte >> 7) & 1;
77                                         matchByte <<= 1;
78                                         int bit = rangeDecoder.DecodeBit(m_Decoders, ((1 + matchBit) << 8) + symbol);
79                                         symbol = (symbol << 1) | bit;
80                                         if (matchBit != bit)
81                                         {
82                                                 while (symbol < 0x100)
83                                                         symbol = (symbol << 1) | rangeDecoder.DecodeBit(m_Decoders, symbol);
84                                                 break;
85                                         }
86                                 }
87                                 while (symbol < 0x100);
88                                 return (byte)symbol;
89                         }
90                 }
91                 
92                 Decoder2[] m_Coders;
93                 int m_NumPrevBits;
94                 int m_NumPosBits;
95                 int m_PosMask;
96                 
97                 public void Create(int numPosBits, int numPrevBits)
98                 {
99                         if (m_Coders != null && m_NumPrevBits == numPrevBits && m_NumPosBits == numPosBits)
100                                 return;
101                         m_NumPosBits = numPosBits;
102                         m_PosMask = (1 << numPosBits) - 1;
103                         m_NumPrevBits = numPrevBits;
104                         int numStates = 1 << (m_NumPrevBits + m_NumPosBits);
105                         m_Coders = new Decoder2[numStates];
106                         for (int i = 0; i < numStates; i++)
107                                 m_Coders[i] = new Decoder2();
108                 }
109                 
110                 public void Init()
111                 {
112                         int numStates = 1 << (m_NumPrevBits + m_NumPosBits);
113                         for (int i = 0; i < numStates; i++)
114                                 m_Coders[i].Init();
115                 }
116                 
117                 Decoder2 GetDecoder(int pos, byte prevByte)
118                 {
119                         return m_Coders[((pos & m_PosMask) << m_NumPrevBits) + ((prevByte & 0xFF) >>> (8 - m_NumPrevBits))];
120                 }
121         }
122         
123         OutWindow m_OutWindow = new OutWindow();
124         SevenZip.Compression.RangeCoder.Decoder m_RangeDecoder = new SevenZip.Compression.RangeCoder.Decoder();
125         
126         short[] m_IsMatchDecoders = new short[Base.kNumStates << Base.kNumPosStatesBitsMax];
127         short[] m_IsRepDecoders = new short[Base.kNumStates];
128         short[] m_IsRepG0Decoders = new short[Base.kNumStates];
129         short[] m_IsRepG1Decoders = new short[Base.kNumStates];
130         short[] m_IsRepG2Decoders = new short[Base.kNumStates];
131         short[] m_IsRep0LongDecoders = new short[Base.kNumStates << Base.kNumPosStatesBitsMax];
132         
133         BitTreeDecoder[] m_PosSlotDecoder = new BitTreeDecoder[Base.kNumLenToPosStates];
134         short[] m_PosDecoders = new short[Base.kNumFullDistances - Base.kEndPosModelIndex];
135         
136         BitTreeDecoder m_PosAlignDecoder = new BitTreeDecoder(Base.kNumAlignBits);
137         
138         LenDecoder m_LenDecoder = new LenDecoder();
139         LenDecoder m_RepLenDecoder = new LenDecoder();
140         
141         LiteralDecoder m_LiteralDecoder = new LiteralDecoder();
142         
143         int m_DictionarySize = -1;
144         int m_DictionarySizeCheck =  -1;
145         
146         int m_PosStateMask;
147         
148         public Decoder()
149         {
150                 for (int i = 0; i < Base.kNumLenToPosStates; i++)
151                         m_PosSlotDecoder[i] = new BitTreeDecoder(Base.kNumPosSlotBits);
152         }
153         
154         boolean SetDictionarySize(int dictionarySize)
155         {
156                 if (dictionarySize < 0)
157                         return false;
158                 if (m_DictionarySize != dictionarySize)
159                 {
160                         m_DictionarySize = dictionarySize;
161                         m_DictionarySizeCheck = Math.max(m_DictionarySize, 1);
162                         m_OutWindow.Create(Math.max(m_DictionarySizeCheck, (1 << 12)));
163                 }
164                 return true;
165         }
166         
167         boolean SetLcLpPb(int lc, int lp, int pb)
168         {
169                 if (lc > Base.kNumLitContextBitsMax || lp > 4 || pb > Base.kNumPosStatesBitsMax)
170                         return false;
171                 m_LiteralDecoder.Create(lp, lc);
172                 int numPosStates = 1 << pb;
173                 m_LenDecoder.Create(numPosStates);
174                 m_RepLenDecoder.Create(numPosStates);
175                 m_PosStateMask = numPosStates - 1;
176                 return true;
177         }
178         
179         void Init() throws IOException
180         {
181                 m_OutWindow.Init(false);
182                 
183                 SevenZip.Compression.RangeCoder.Decoder.InitBitModels(m_IsMatchDecoders);
184                 SevenZip.Compression.RangeCoder.Decoder.InitBitModels(m_IsRep0LongDecoders);
185                 SevenZip.Compression.RangeCoder.Decoder.InitBitModels(m_IsRepDecoders);
186                 SevenZip.Compression.RangeCoder.Decoder.InitBitModels(m_IsRepG0Decoders);
187                 SevenZip.Compression.RangeCoder.Decoder.InitBitModels(m_IsRepG1Decoders);
188                 SevenZip.Compression.RangeCoder.Decoder.InitBitModels(m_IsRepG2Decoders);
189                 SevenZip.Compression.RangeCoder.Decoder.InitBitModels(m_PosDecoders);
190                 
191                 m_LiteralDecoder.Init();
192                 int i;
193                 for (i = 0; i < Base.kNumLenToPosStates; i++)
194                         m_PosSlotDecoder[i].Init();
195                 m_LenDecoder.Init();
196                 m_RepLenDecoder.Init();
197                 m_PosAlignDecoder.Init();
198                 m_RangeDecoder.Init();
199         }
200         
201         public boolean Code(java.io.InputStream inStream, java.io.OutputStream outStream,
202                         long outSize) throws IOException
203         {
204                 m_RangeDecoder.SetStream(inStream);
205                 m_OutWindow.SetStream(outStream);
206                 Init();
207                 
208                 int state = Base.StateInit();
209                 int rep0 = 0, rep1 = 0, rep2 = 0, rep3 = 0;
210                 
211                 long nowPos64 = 0;
212                 byte prevByte = 0;
213                 while (outSize < 0 || nowPos64 < outSize)
214                 {
215                         int posState = (int)nowPos64 & m_PosStateMask;
216                         if (m_RangeDecoder.DecodeBit(m_IsMatchDecoders, (state << Base.kNumPosStatesBitsMax) + posState) == 0)
217                         {
218                                 LiteralDecoder.Decoder2 decoder2 = m_LiteralDecoder.GetDecoder((int)nowPos64, prevByte);
219                                 if (!Base.StateIsCharState(state))
220                                         prevByte = decoder2.DecodeWithMatchByte(m_RangeDecoder, m_OutWindow.GetByte(rep0));
221                                 else
222                                         prevByte = decoder2.DecodeNormal(m_RangeDecoder);
223                                 m_OutWindow.PutByte(prevByte);
224                                 state = Base.StateUpdateChar(state);
225                                 nowPos64++;
226                         }
227                         else
228                         {
229                                 int len;
230                                 if (m_RangeDecoder.DecodeBit(m_IsRepDecoders, state) == 1)
231                                 {
232                                         len = 0;
233                                         if (m_RangeDecoder.DecodeBit(m_IsRepG0Decoders, state) == 0)
234                                         {
235                                                 if (m_RangeDecoder.DecodeBit(m_IsRep0LongDecoders, (state << Base.kNumPosStatesBitsMax) + posState) == 0)
236                                                 {
237                                                         state = Base.StateUpdateShortRep(state);
238                                                         len = 1;
239                                                 }
240                                         }
241                                         else
242                                         {
243                                                 int distance;
244                                                 if (m_RangeDecoder.DecodeBit(m_IsRepG1Decoders, state) == 0)
245                                                         distance = rep1;
246                                                 else
247                                                 {
248                                                         if (m_RangeDecoder.DecodeBit(m_IsRepG2Decoders, state) == 0)
249                                                                 distance = rep2;
250                                                         else
251                                                         {
252                                                                 distance = rep3;
253                                                                 rep3 = rep2;
254                                                         }
255                                                         rep2 = rep1;
256                                                 }
257                                                 rep1 = rep0;
258                                                 rep0 = distance;
259                                         }
260                                         if (len == 0)
261                                         {
262                                                 len = m_RepLenDecoder.Decode(m_RangeDecoder, posState) + Base.kMatchMinLen;
263                                                 state = Base.StateUpdateRep(state);
264                                         }
265                                 }
266                                 else
267                                 {
268                                         rep3 = rep2;
269                                         rep2 = rep1;
270                                         rep1 = rep0;
271                                         len = Base.kMatchMinLen + m_LenDecoder.Decode(m_RangeDecoder, posState);
272                                         state = Base.StateUpdateMatch(state);
273                                         int posSlot = m_PosSlotDecoder[Base.GetLenToPosState(len)].Decode(m_RangeDecoder);
274                                         if (posSlot >= Base.kStartPosModelIndex)
275                                         {
276                                                 int numDirectBits = (posSlot >> 1) - 1;
277                                                 rep0 = ((2 | (posSlot & 1)) << numDirectBits);
278                                                 if (posSlot < Base.kEndPosModelIndex)
279                                                         rep0 += BitTreeDecoder.ReverseDecode(m_PosDecoders,
280                                                                         rep0 - posSlot - 1, m_RangeDecoder, numDirectBits);
281                                                 else
282                                                 {
283                                                         rep0 += (m_RangeDecoder.DecodeDirectBits(
284                                                                         numDirectBits - Base.kNumAlignBits) << Base.kNumAlignBits);
285                                                         rep0 += m_PosAlignDecoder.ReverseDecode(m_RangeDecoder);
286                                                         if (rep0 < 0)
287                                                         {
288                                                                 if (rep0 == -1)
289                                                                         break;
290                                                                 return false;
291                                                         }
292                                                 }
293                                         }
294                                         else
295                                                 rep0 = posSlot;
296                                 }
297                                 if (rep0 >= nowPos64 || rep0 >= m_DictionarySizeCheck)
298                                 {
299                                         // m_OutWindow.Flush();
300                                         return false;
301                                 }
302                                 m_OutWindow.CopyBlock(rep0, len);
303                                 nowPos64 += len;
304                                 prevByte = m_OutWindow.GetByte(0);
305                         }
306                 }
307                 m_OutWindow.Flush();
308                 m_OutWindow.ReleaseStream();
309                 m_RangeDecoder.ReleaseStream();
310                 return true;
311         }
312         
313         public boolean SetDecoderProperties(byte[] properties)
314         {
315                 if (properties.length < 5)
316                         return false;
317                 int val = properties[0] & 0xFF;
318                 int lc = val % 9;
319                 int remainder = val / 9;
320                 int lp = remainder % 5;
321                 int pb = remainder / 5;
322                 int dictionarySize = 0;
323                 for (int i = 0; i < 4; i++)
324                         dictionarySize += ((int)(properties[1 + i]) & 0xFF) << (i * 8);
325                 if (!SetLcLpPb(lc, lp, pb))
326                         return false;
327                 return SetDictionarySize(dictionarySize);
328         }
329 }