OLD | NEW |
| (Empty) |
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.kNumPosSta
tesMax]; | |
14 BitTreeDecoder[] m_MidCoder = new BitTreeDecoder[Base.kNumPosSta
tesMax]; | |
15 BitTreeDecoder m_HighCoder = new BitTreeDecoder(Base.kNumHighLen
Bits); | |
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; posSta
te++) | |
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 rangeD
ecoder, 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(rangeDecod
er); | |
45 else | |
46 symbol += Base.kNumMidLenSymbols + m_HighCoder.D
ecode(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.InitBitM
odels(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.De
codeBit(m_Decoders, symbol); | |
67 while (symbol < 0x100); | |
68 return (byte)symbol; | |
69 } | |
70 | |
71 public byte DecodeWithMatchByte(SevenZip.Compression.Ran
geCoder.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_Decod
ers, ((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.Co
mpression.RangeCoder.Decoder(); | |
125 | |
126 short[] m_IsMatchDecoders = new short[Base.kNumStates << Base.kNumPosSta
tesBitsMax]; | |
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.kNumPos
StatesBitsMax]; | |
132 | |
133 BitTreeDecoder[] m_PosSlotDecoder = new BitTreeDecoder[Base.kNumLenToPos
States]; | |
134 short[] m_PosDecoders = new short[Base.kNumFullDistances - Base.kEndPosM
odelIndex]; | |
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.kNumPosSlo
tBits); | |
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.kNumP
osStatesBitsMax) | |
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_IsMatchD
ecoders); | |
184 SevenZip.Compression.RangeCoder.Decoder.InitBitModels(m_IsRep0Lo
ngDecoders); | |
185 SevenZip.Compression.RangeCoder.Decoder.InitBitModels(m_IsRepDec
oders); | |
186 SevenZip.Compression.RangeCoder.Decoder.InitBitModels(m_IsRepG0D
ecoders); | |
187 SevenZip.Compression.RangeCoder.Decoder.InitBitModels(m_IsRepG1D
ecoders); | |
188 SevenZip.Compression.RangeCoder.Decoder.InitBitModels(m_IsRepG2D
ecoders); | |
189 SevenZip.Compression.RangeCoder.Decoder.InitBitModels(m_PosDecod
ers); | |
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 o
utStream, | |
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_LiteralDeco
der.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_Range
Decoder); | |
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, st
ate) == 1) | |
231 { | |
232 len = 0; | |
233 if (m_RangeDecoder.DecodeBit(m_IsRepG0De
coders, state) == 0) | |
234 { | |
235 if (m_RangeDecoder.DecodeBit(m_I
sRep0LongDecoders, (state << Base.kNumPosStatesBitsMax) + posState) == 0) | |
236 { | |
237 state = Base.StateUpdate
ShortRep(state); | |
238 len = 1; | |
239 } | |
240 } | |
241 else | |
242 { | |
243 int distance; | |
244 if (m_RangeDecoder.DecodeBit(m_I
sRepG1Decoders, state) == 0) | |
245 distance = rep1; | |
246 else | |
247 { | |
248 if (m_RangeDecoder.Decod
eBit(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_R
angeDecoder, posState) + Base.kMatchMinLen; | |
263 state = Base.StateUpdateRep(stat
e); | |
264 } | |
265 } | |
266 else | |
267 { | |
268 rep3 = rep2; | |
269 rep2 = rep1; | |
270 rep1 = rep0; | |
271 len = Base.kMatchMinLen + m_LenDecoder.D
ecode(m_RangeDecoder, posState); | |
272 state = Base.StateUpdateMatch(state); | |
273 int posSlot = m_PosSlotDecoder[Base.GetL
enToPosState(len)].Decode(m_RangeDecoder); | |
274 if (posSlot >= Base.kStartPosModelIndex) | |
275 { | |
276 int numDirectBits = (posSlot >>
1) - 1; | |
277 rep0 = ((2 | (posSlot & 1)) << n
umDirectBits); | |
278 if (posSlot < Base.kEndPosModelI
ndex) | |
279 rep0 += BitTreeDecoder.R
everseDecode(m_PosDecoders, | |
280 rep0 - p
osSlot - 1, m_RangeDecoder, numDirectBits); | |
281 else | |
282 { | |
283 rep0 += (m_RangeDecoder.
DecodeDirectBits( | |
284 numDirec
tBits - Base.kNumAlignBits) << Base.kNumAlignBits); | |
285 rep0 += m_PosAlignDecode
r.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_DictionarySize
Check) | |
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 } | |
OLD | NEW |