OLD | NEW |
| (Empty) |
1 // LzmaDecoder.cs | |
2 | |
3 using System; | |
4 | |
5 namespace SevenZip.Compression.LZMA | |
6 { | |
7 using RangeCoder; | |
8 | |
9 public class Decoder : ICoder, ISetDecoderProperties // ,System.IO.Strea
m | |
10 { | |
11 class LenDecoder | |
12 { | |
13 BitDecoder m_Choice = new BitDecoder(); | |
14 BitDecoder m_Choice2 = new BitDecoder(); | |
15 BitTreeDecoder[] m_LowCoder = new BitTreeDecoder[Base.kN
umPosStatesMax]; | |
16 BitTreeDecoder[] m_MidCoder = new BitTreeDecoder[Base.kN
umPosStatesMax]; | |
17 BitTreeDecoder m_HighCoder = new BitTreeDecoder(Base.kNu
mHighLenBits); | |
18 uint m_NumPosStates = 0; | |
19 | |
20 public void Create(uint numPosStates) | |
21 { | |
22 for (uint posState = m_NumPosStates; posState <
numPosStates; posState++) | |
23 { | |
24 m_LowCoder[posState] = new BitTreeDecode
r(Base.kNumLowLenBits); | |
25 m_MidCoder[posState] = new BitTreeDecode
r(Base.kNumMidLenBits); | |
26 } | |
27 m_NumPosStates = numPosStates; | |
28 } | |
29 | |
30 public void Init() | |
31 { | |
32 m_Choice.Init(); | |
33 for (uint posState = 0; posState < m_NumPosState
s; posState++) | |
34 { | |
35 m_LowCoder[posState].Init(); | |
36 m_MidCoder[posState].Init(); | |
37 } | |
38 m_Choice2.Init(); | |
39 m_HighCoder.Init(); | |
40 } | |
41 | |
42 public uint Decode(RangeCoder.Decoder rangeDecoder, uint
posState) | |
43 { | |
44 if (m_Choice.Decode(rangeDecoder) == 0) | |
45 return m_LowCoder[posState].Decode(range
Decoder); | |
46 else | |
47 { | |
48 uint symbol = Base.kNumLowLenSymbols; | |
49 if (m_Choice2.Decode(rangeDecoder) == 0) | |
50 symbol += m_MidCoder[posState].D
ecode(rangeDecoder); | |
51 else | |
52 { | |
53 symbol += Base.kNumMidLenSymbols
; | |
54 symbol += m_HighCoder.Decode(ran
geDecoder); | |
55 } | |
56 return symbol; | |
57 } | |
58 } | |
59 } | |
60 | |
61 class LiteralDecoder | |
62 { | |
63 struct Decoder2 | |
64 { | |
65 BitDecoder[] m_Decoders; | |
66 public void Create() { m_Decoders = new BitDecod
er[0x300]; } | |
67 public void Init() { for (int i = 0; i < 0x300;
i++) m_Decoders[i].Init(); } | |
68 | |
69 public byte DecodeNormal(RangeCoder.Decoder rang
eDecoder) | |
70 { | |
71 uint symbol = 1; | |
72 do | |
73 symbol = (symbol << 1) | m_Decod
ers[symbol].Decode(rangeDecoder); | |
74 while (symbol < 0x100); | |
75 return (byte)symbol; | |
76 } | |
77 | |
78 public byte DecodeWithMatchByte(RangeCoder.Decod
er rangeDecoder, byte matchByte) | |
79 { | |
80 uint symbol = 1; | |
81 do | |
82 { | |
83 uint matchBit = (uint)(matchByte
>> 7) & 1; | |
84 matchByte <<= 1; | |
85 uint bit = m_Decoders[((1 + matc
hBit) << 8) + symbol].Decode(rangeDecoder); | |
86 symbol = (symbol << 1) | bit; | |
87 if (matchBit != bit) | |
88 { | |
89 while (symbol < 0x100) | |
90 symbol = (symbol
<< 1) | m_Decoders[symbol].Decode(rangeDecoder); | |
91 break; | |
92 } | |
93 } | |
94 while (symbol < 0x100); | |
95 return (byte)symbol; | |
96 } | |
97 } | |
98 | |
99 Decoder2[] m_Coders; | |
100 int m_NumPrevBits; | |
101 int m_NumPosBits; | |
102 uint m_PosMask; | |
103 | |
104 public void Create(int numPosBits, int numPrevBits) | |
105 { | |
106 if (m_Coders != null && m_NumPrevBits == numPrev
Bits && | |
107 m_NumPosBits == numPosBits) | |
108 return; | |
109 m_NumPosBits = numPosBits; | |
110 m_PosMask = ((uint)1 << numPosBits) - 1; | |
111 m_NumPrevBits = numPrevBits; | |
112 uint numStates = (uint)1 << (m_NumPrevBits + m_N
umPosBits); | |
113 m_Coders = new Decoder2[numStates]; | |
114 for (uint i = 0; i < numStates; i++) | |
115 m_Coders[i].Create(); | |
116 } | |
117 | |
118 public void Init() | |
119 { | |
120 uint numStates = (uint)1 << (m_NumPrevBits + m_N
umPosBits); | |
121 for (uint i = 0; i < numStates; i++) | |
122 m_Coders[i].Init(); | |
123 } | |
124 | |
125 uint GetState(uint pos, byte prevByte) | |
126 { return ((pos & m_PosMask) << m_NumPrevBits) + (uint)(p
revByte >> (8 - m_NumPrevBits)); } | |
127 | |
128 public byte DecodeNormal(RangeCoder.Decoder rangeDecoder
, uint pos, byte prevByte) | |
129 { return m_Coders[GetState(pos, prevByte)].DecodeNormal(
rangeDecoder); } | |
130 | |
131 public byte DecodeWithMatchByte(RangeCoder.Decoder range
Decoder, uint pos, byte prevByte, byte matchByte) | |
132 { return m_Coders[GetState(pos, prevByte)].DecodeWithMat
chByte(rangeDecoder, matchByte); } | |
133 }; | |
134 | |
135 LZ.OutWindow m_OutWindow = new LZ.OutWindow(); | |
136 RangeCoder.Decoder m_RangeDecoder = new RangeCoder.Decoder(); | |
137 | |
138 BitDecoder[] m_IsMatchDecoders = new BitDecoder[Base.kNumStates
<< Base.kNumPosStatesBitsMax]; | |
139 BitDecoder[] m_IsRepDecoders = new BitDecoder[Base.kNumStates]; | |
140 BitDecoder[] m_IsRepG0Decoders = new BitDecoder[Base.kNumStates]
; | |
141 BitDecoder[] m_IsRepG1Decoders = new BitDecoder[Base.kNumStates]
; | |
142 BitDecoder[] m_IsRepG2Decoders = new BitDecoder[Base.kNumStates]
; | |
143 BitDecoder[] m_IsRep0LongDecoders = new BitDecoder[Base.kNumStat
es << Base.kNumPosStatesBitsMax]; | |
144 | |
145 BitTreeDecoder[] m_PosSlotDecoder = new BitTreeDecoder[Base.kNum
LenToPosStates]; | |
146 BitDecoder[] m_PosDecoders = new BitDecoder[Base.kNumFullDistanc
es - Base.kEndPosModelIndex]; | |
147 | |
148 BitTreeDecoder m_PosAlignDecoder = new BitTreeDecoder(Base.kNumA
lignBits); | |
149 | |
150 LenDecoder m_LenDecoder = new LenDecoder(); | |
151 LenDecoder m_RepLenDecoder = new LenDecoder(); | |
152 | |
153 LiteralDecoder m_LiteralDecoder = new LiteralDecoder(); | |
154 | |
155 uint m_DictionarySize; | |
156 uint m_DictionarySizeCheck; | |
157 | |
158 uint m_PosStateMask; | |
159 | |
160 public Decoder() | |
161 { | |
162 m_DictionarySize = 0xFFFFFFFF; | |
163 for (int i = 0; i < Base.kNumLenToPosStates; i++) | |
164 m_PosSlotDecoder[i] = new BitTreeDecoder(Base.kN
umPosSlotBits); | |
165 } | |
166 | |
167 void SetDictionarySize(uint dictionarySize) | |
168 { | |
169 if (m_DictionarySize != dictionarySize) | |
170 { | |
171 m_DictionarySize = dictionarySize; | |
172 m_DictionarySizeCheck = Math.Max(m_DictionarySiz
e, 1); | |
173 uint blockSize = Math.Max(m_DictionarySizeCheck,
(1 << 12)); | |
174 m_OutWindow.Create(blockSize); | |
175 } | |
176 } | |
177 | |
178 void SetLiteralProperties(int lp, int lc) | |
179 { | |
180 if (lp > 8) | |
181 throw new InvalidParamException(); | |
182 if (lc > 8) | |
183 throw new InvalidParamException(); | |
184 m_LiteralDecoder.Create(lp, lc); | |
185 } | |
186 | |
187 void SetPosBitsProperties(int pb) | |
188 { | |
189 if (pb > Base.kNumPosStatesBitsMax) | |
190 throw new InvalidParamException(); | |
191 uint numPosStates = (uint)1 << pb; | |
192 m_LenDecoder.Create(numPosStates); | |
193 m_RepLenDecoder.Create(numPosStates); | |
194 m_PosStateMask = numPosStates - 1; | |
195 } | |
196 | |
197 bool _solid = false; | |
198 void Init(System.IO.Stream inStream, System.IO.Stream outStream) | |
199 { | |
200 m_RangeDecoder.Init(inStream); | |
201 m_OutWindow.Init(outStream, _solid); | |
202 | |
203 uint i; | |
204 for (i = 0; i < Base.kNumStates; i++) | |
205 { | |
206 for (uint j = 0; j <= m_PosStateMask; j++) | |
207 { | |
208 uint index = (i << Base.kNumPosStatesBit
sMax) + j; | |
209 m_IsMatchDecoders[index].Init(); | |
210 m_IsRep0LongDecoders[index].Init(); | |
211 } | |
212 m_IsRepDecoders[i].Init(); | |
213 m_IsRepG0Decoders[i].Init(); | |
214 m_IsRepG1Decoders[i].Init(); | |
215 m_IsRepG2Decoders[i].Init(); | |
216 } | |
217 | |
218 m_LiteralDecoder.Init(); | |
219 for (i = 0; i < Base.kNumLenToPosStates; i++) | |
220 m_PosSlotDecoder[i].Init(); | |
221 // m_PosSpecDecoder.Init(); | |
222 for (i = 0; i < Base.kNumFullDistances - Base.kEndPosMod
elIndex; i++) | |
223 m_PosDecoders[i].Init(); | |
224 | |
225 m_LenDecoder.Init(); | |
226 m_RepLenDecoder.Init(); | |
227 m_PosAlignDecoder.Init(); | |
228 } | |
229 | |
230 public void Code(System.IO.Stream inStream, System.IO.Stream out
Stream, | |
231 Int64 inSize, Int64 outSize, ICodeProgress progress) | |
232 { | |
233 Init(inStream, outStream); | |
234 | |
235 Base.State state = new Base.State(); | |
236 state.Init(); | |
237 uint rep0 = 0, rep1 = 0, rep2 = 0, rep3 = 0; | |
238 | |
239 UInt64 nowPos64 = 0; | |
240 UInt64 outSize64 = (UInt64)outSize; | |
241 if (nowPos64 < outSize64) | |
242 { | |
243 if (m_IsMatchDecoders[state.Index << Base.kNumPo
sStatesBitsMax].Decode(m_RangeDecoder) != 0) | |
244 throw new DataErrorException(); | |
245 state.UpdateChar(); | |
246 byte b = m_LiteralDecoder.DecodeNormal(m_RangeDe
coder, 0, 0); | |
247 m_OutWindow.PutByte(b); | |
248 nowPos64++; | |
249 } | |
250 while (nowPos64 < outSize64) | |
251 { | |
252 // UInt64 next = Math.Min(nowPos64 + (1 << 18),
outSize64); | |
253 // while(nowPos64 < next) | |
254 { | |
255 uint posState = (uint)nowPos64 & m_PosSt
ateMask; | |
256 if (m_IsMatchDecoders[(state.Index << Ba
se.kNumPosStatesBitsMax) + posState].Decode(m_RangeDecoder) == 0) | |
257 { | |
258 byte b; | |
259 byte prevByte = m_OutWindow.GetB
yte(0); | |
260 if (!state.IsCharState()) | |
261 b = m_LiteralDecoder.Dec
odeWithMatchByte(m_RangeDecoder, | |
262 (uint)nowPos64,
prevByte, m_OutWindow.GetByte(rep0)); | |
263 else | |
264 b = m_LiteralDecoder.Dec
odeNormal(m_RangeDecoder, (uint)nowPos64, prevByte); | |
265 m_OutWindow.PutByte(b); | |
266 state.UpdateChar(); | |
267 nowPos64++; | |
268 } | |
269 else | |
270 { | |
271 uint len; | |
272 if (m_IsRepDecoders[state.Index]
.Decode(m_RangeDecoder) == 1) | |
273 { | |
274 if (m_IsRepG0Decoders[st
ate.Index].Decode(m_RangeDecoder) == 0) | |
275 { | |
276 if (m_IsRep0Long
Decoders[(state.Index << Base.kNumPosStatesBitsMax) + posState].Decode(m_RangeDe
coder) == 0) | |
277 { | |
278 state.Up
dateShortRep(); | |
279 m_OutWin
dow.PutByte(m_OutWindow.GetByte(rep0)); | |
280 nowPos64
++; | |
281 continue
; | |
282 } | |
283 } | |
284 else | |
285 { | |
286 UInt32 distance; | |
287 if (m_IsRepG1Dec
oders[state.Index].Decode(m_RangeDecoder) == 0) | |
288 { | |
289 distance
= rep1; | |
290 } | |
291 else | |
292 { | |
293 if (m_Is
RepG2Decoders[state.Index].Decode(m_RangeDecoder) == 0) | |
294
distance = rep2; | |
295 else | |
296 { | |
297
distance = rep3; | |
298
rep3 = rep2; | |
299 } | |
300 rep2 = r
ep1; | |
301 } | |
302 rep1 = rep0; | |
303 rep0 = distance; | |
304 } | |
305 len = m_RepLenDecoder.De
code(m_RangeDecoder, posState) + Base.kMatchMinLen; | |
306 state.UpdateRep(); | |
307 } | |
308 else | |
309 { | |
310 rep3 = rep2; | |
311 rep2 = rep1; | |
312 rep1 = rep0; | |
313 len = Base.kMatchMinLen
+ m_LenDecoder.Decode(m_RangeDecoder, posState); | |
314 state.UpdateMatch(); | |
315 uint posSlot = m_PosSlot
Decoder[Base.GetLenToPosState(len)].Decode(m_RangeDecoder); | |
316 if (posSlot >= Base.kSta
rtPosModelIndex) | |
317 { | |
318 int numDirectBit
s = (int)((posSlot >> 1) - 1); | |
319 rep0 = ((2 | (po
sSlot & 1)) << numDirectBits); | |
320 if (posSlot < Ba
se.kEndPosModelIndex) | |
321 rep0 +=
BitTreeDecoder.ReverseDecode(m_PosDecoders, | |
322
rep0 - posSlot - 1, m_RangeDecoder, numDirectBits); | |
323 else | |
324 { | |
325 rep0 +=
(m_RangeDecoder.DecodeDirectBits( | |
326
numDirectBits - Base.kNumAlignBits) << Base.kNumAlignBits); | |
327 rep0 +=
m_PosAlignDecoder.ReverseDecode(m_RangeDecoder); | |
328 } | |
329 } | |
330 else | |
331 rep0 = posSlot; | |
332 } | |
333 if (rep0 >= m_OutWindow.TrainSiz
e + nowPos64 || rep0 >= m_DictionarySizeCheck) | |
334 { | |
335 if (rep0 == 0xFFFFFFFF) | |
336 break; | |
337 throw new DataErrorExcep
tion(); | |
338 } | |
339 m_OutWindow.CopyBlock(rep0, len)
; | |
340 nowPos64 += len; | |
341 } | |
342 } | |
343 } | |
344 m_OutWindow.Flush(); | |
345 m_OutWindow.ReleaseStream(); | |
346 m_RangeDecoder.ReleaseStream(); | |
347 } | |
348 | |
349 public void SetDecoderProperties(byte[] properties) | |
350 { | |
351 if (properties.Length < 5) | |
352 throw new InvalidParamException(); | |
353 int lc = properties[0] % 9; | |
354 int remainder = properties[0] / 9; | |
355 int lp = remainder % 5; | |
356 int pb = remainder / 5; | |
357 if (pb > Base.kNumPosStatesBitsMax) | |
358 throw new InvalidParamException(); | |
359 UInt32 dictionarySize = 0; | |
360 for (int i = 0; i < 4; i++) | |
361 dictionarySize += ((UInt32)(properties[1 + i]))
<< (i * 8); | |
362 SetDictionarySize(dictionarySize); | |
363 SetLiteralProperties(lp, lc); | |
364 SetPosBitsProperties(pb); | |
365 } | |
366 | |
367 public bool Train(System.IO.Stream stream) | |
368 { | |
369 _solid = true; | |
370 return m_OutWindow.Train(stream); | |
371 } | |
372 | |
373 /* | |
374 public override bool CanRead { get { return true; }} | |
375 public override bool CanWrite { get { return true; }} | |
376 public override bool CanSeek { get { return true; }} | |
377 public override long Length { get { return 0; }} | |
378 public override long Position | |
379 { | |
380 get { return 0; } | |
381 set { } | |
382 } | |
383 public override void Flush() { } | |
384 public override int Read(byte[] buffer, int offset, int count) | |
385 { | |
386 return 0; | |
387 } | |
388 public override void Write(byte[] buffer, int offset, int count) | |
389 { | |
390 } | |
391 public override long Seek(long offset, System.IO.SeekOrigin orig
in) | |
392 { | |
393 return 0; | |
394 } | |
395 public override void SetLength(long value) {} | |
396 */ | |
397 } | |
398 } | |
OLD | NEW |