BCM WL 6.30.102.9 (r366174)
[tomato.git] / release / src-rt / linux / linux-2.6 / scripts / squashfs / lzma / CS / 7zip / Compress / LZMA / LzmaDecoder.cs
blob30952e5a826f7c9e7844ad648c5a116af374da9b
1 // LzmaDecoder.cs
3 using System;
5 namespace SevenZip.Compression.LZMA
7 using RangeCoder;
9 public class Decoder : ICoder, ISetDecoderProperties // ,System.IO.Stream
11 class LenDecoder
13 BitDecoder m_Choice = new BitDecoder();
14 BitDecoder m_Choice2 = new BitDecoder();
15 BitTreeDecoder[] m_LowCoder = new BitTreeDecoder[Base.kNumPosStatesMax];
16 BitTreeDecoder[] m_MidCoder = new BitTreeDecoder[Base.kNumPosStatesMax];
17 BitTreeDecoder m_HighCoder = new BitTreeDecoder(Base.kNumHighLenBits);
18 uint m_NumPosStates = 0;
20 public void Create(uint numPosStates)
22 for (uint posState = m_NumPosStates; posState < numPosStates; posState++)
24 m_LowCoder[posState] = new BitTreeDecoder(Base.kNumLowLenBits);
25 m_MidCoder[posState] = new BitTreeDecoder(Base.kNumMidLenBits);
27 m_NumPosStates = numPosStates;
30 public void Init()
32 m_Choice.Init();
33 for (uint posState = 0; posState < m_NumPosStates; posState++)
35 m_LowCoder[posState].Init();
36 m_MidCoder[posState].Init();
38 m_Choice2.Init();
39 m_HighCoder.Init();
42 public uint Decode(RangeCoder.Decoder rangeDecoder, uint posState)
44 if (m_Choice.Decode(rangeDecoder) == 0)
45 return m_LowCoder[posState].Decode(rangeDecoder);
46 else
48 uint symbol = Base.kNumLowLenSymbols;
49 if (m_Choice2.Decode(rangeDecoder) == 0)
50 symbol += m_MidCoder[posState].Decode(rangeDecoder);
51 else
53 symbol += Base.kNumMidLenSymbols;
54 symbol += m_HighCoder.Decode(rangeDecoder);
56 return symbol;
61 class LiteralDecoder
63 struct Decoder2
65 BitDecoder[] m_Decoders;
66 public void Create() { m_Decoders = new BitDecoder[0x300]; }
67 public void Init() { for (int i = 0; i < 0x300; i++) m_Decoders[i].Init(); }
69 public byte DecodeNormal(RangeCoder.Decoder rangeDecoder)
71 uint symbol = 1;
73 symbol = (symbol << 1) | m_Decoders[symbol].Decode(rangeDecoder);
74 while (symbol < 0x100);
75 return (byte)symbol;
78 public byte DecodeWithMatchByte(RangeCoder.Decoder rangeDecoder, byte matchByte)
80 uint symbol = 1;
83 uint matchBit = (uint)(matchByte >> 7) & 1;
84 matchByte <<= 1;
85 uint bit = m_Decoders[((1 + matchBit) << 8) + symbol].Decode(rangeDecoder);
86 symbol = (symbol << 1) | bit;
87 if (matchBit != bit)
89 while (symbol < 0x100)
90 symbol = (symbol << 1) | m_Decoders[symbol].Decode(rangeDecoder);
91 break;
94 while (symbol < 0x100);
95 return (byte)symbol;
99 Decoder2[] m_Coders;
100 int m_NumPrevBits;
101 int m_NumPosBits;
102 uint m_PosMask;
104 public void Create(int numPosBits, int numPrevBits)
106 if (m_Coders != null && m_NumPrevBits == numPrevBits &&
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_NumPosBits);
113 m_Coders = new Decoder2[numStates];
114 for (uint i = 0; i < numStates; i++)
115 m_Coders[i].Create();
118 public void Init()
120 uint numStates = (uint)1 << (m_NumPrevBits + m_NumPosBits);
121 for (uint i = 0; i < numStates; i++)
122 m_Coders[i].Init();
125 uint GetState(uint pos, byte prevByte)
126 { return ((pos & m_PosMask) << m_NumPrevBits) + (uint)(prevByte >> (8 - m_NumPrevBits)); }
128 public byte DecodeNormal(RangeCoder.Decoder rangeDecoder, uint pos, byte prevByte)
129 { return m_Coders[GetState(pos, prevByte)].DecodeNormal(rangeDecoder); }
131 public byte DecodeWithMatchByte(RangeCoder.Decoder rangeDecoder, uint pos, byte prevByte, byte matchByte)
132 { return m_Coders[GetState(pos, prevByte)].DecodeWithMatchByte(rangeDecoder, matchByte); }
135 LZ.OutWindow m_OutWindow = new LZ.OutWindow();
136 RangeCoder.Decoder m_RangeDecoder = new RangeCoder.Decoder();
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.kNumStates << Base.kNumPosStatesBitsMax];
145 BitTreeDecoder[] m_PosSlotDecoder = new BitTreeDecoder[Base.kNumLenToPosStates];
146 BitDecoder[] m_PosDecoders = new BitDecoder[Base.kNumFullDistances - Base.kEndPosModelIndex];
148 BitTreeDecoder m_PosAlignDecoder = new BitTreeDecoder(Base.kNumAlignBits);
150 LenDecoder m_LenDecoder = new LenDecoder();
151 LenDecoder m_RepLenDecoder = new LenDecoder();
153 LiteralDecoder m_LiteralDecoder = new LiteralDecoder();
155 uint m_DictionarySize;
156 uint m_DictionarySizeCheck;
158 uint m_PosStateMask;
160 public Decoder()
162 m_DictionarySize = 0xFFFFFFFF;
163 for (int i = 0; i < Base.kNumLenToPosStates; i++)
164 m_PosSlotDecoder[i] = new BitTreeDecoder(Base.kNumPosSlotBits);
167 void SetDictionarySize(uint dictionarySize)
169 if (m_DictionarySize != dictionarySize)
171 m_DictionarySize = dictionarySize;
172 m_DictionarySizeCheck = Math.Max(m_DictionarySize, 1);
173 uint blockSize = Math.Max(m_DictionarySizeCheck, (1 << 12));
174 m_OutWindow.Create(blockSize);
178 void SetLiteralProperties(int lp, int lc)
180 if (lp > 8)
181 throw new InvalidParamException();
182 if (lc > 8)
183 throw new InvalidParamException();
184 m_LiteralDecoder.Create(lp, lc);
187 void SetPosBitsProperties(int pb)
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;
197 void Init(System.IO.Stream inStream, System.IO.Stream outStream)
199 m_RangeDecoder.Init(inStream);
200 m_OutWindow.Init(outStream);
202 uint i;
203 for (i = 0; i < Base.kNumStates; i++)
205 for (uint j = 0; j <= m_PosStateMask; j++)
207 uint index = (i << Base.kNumPosStatesBitsMax) + j;
208 m_IsMatchDecoders[index].Init();
209 m_IsRep0LongDecoders[index].Init();
211 m_IsRepDecoders[i].Init();
212 m_IsRepG0Decoders[i].Init();
213 m_IsRepG1Decoders[i].Init();
214 m_IsRepG2Decoders[i].Init();
217 m_LiteralDecoder.Init();
218 for (i = 0; i < Base.kNumLenToPosStates; i++)
219 m_PosSlotDecoder[i].Init();
220 // m_PosSpecDecoder.Init();
221 for (i = 0; i < Base.kNumFullDistances - Base.kEndPosModelIndex; i++)
222 m_PosDecoders[i].Init();
224 m_LenDecoder.Init();
225 m_RepLenDecoder.Init();
226 m_PosAlignDecoder.Init();
229 public void Code(System.IO.Stream inStream, System.IO.Stream outStream,
230 Int64 inSize, Int64 outSize, ICodeProgress progress)
232 Init(inStream, outStream);
234 Base.State state = new Base.State();
235 state.Init();
236 uint rep0 = 0, rep1 = 0, rep2 = 0, rep3 = 0;
238 UInt64 nowPos64 = 0;
239 UInt64 outSize64 = (UInt64)outSize;
240 if (nowPos64 < outSize64)
242 if (m_IsMatchDecoders[state.Index << Base.kNumPosStatesBitsMax].Decode(m_RangeDecoder) != 0)
243 throw new DataErrorException();
244 state.UpdateChar();
245 byte b = m_LiteralDecoder.DecodeNormal(m_RangeDecoder, 0, 0);
246 m_OutWindow.PutByte(b);
247 nowPos64++;
249 while (nowPos64 < outSize64)
251 // UInt64 next = Math.Min(nowPos64 + (1 << 18), outSize64);
252 // while(nowPos64 < next)
254 uint posState = (uint)nowPos64 & m_PosStateMask;
255 if (m_IsMatchDecoders[(state.Index << Base.kNumPosStatesBitsMax) + posState].Decode(m_RangeDecoder) == 0)
257 byte b;
258 byte prevByte = m_OutWindow.GetByte(0);
259 if (!state.IsCharState())
260 b = m_LiteralDecoder.DecodeWithMatchByte(m_RangeDecoder,
261 (uint)nowPos64, prevByte, m_OutWindow.GetByte(rep0));
262 else
263 b = m_LiteralDecoder.DecodeNormal(m_RangeDecoder, (uint)nowPos64, prevByte);
264 m_OutWindow.PutByte(b);
265 state.UpdateChar();
266 nowPos64++;
268 else
270 uint len;
271 if (m_IsRepDecoders[state.Index].Decode(m_RangeDecoder) == 1)
273 if (m_IsRepG0Decoders[state.Index].Decode(m_RangeDecoder) == 0)
275 if (m_IsRep0LongDecoders[(state.Index << Base.kNumPosStatesBitsMax) + posState].Decode(m_RangeDecoder) == 0)
277 state.UpdateShortRep();
278 m_OutWindow.PutByte(m_OutWindow.GetByte(rep0));
279 nowPos64++;
280 continue;
283 else
285 UInt32 distance;
286 if (m_IsRepG1Decoders[state.Index].Decode(m_RangeDecoder) == 0)
288 distance = rep1;
290 else
292 if (m_IsRepG2Decoders[state.Index].Decode(m_RangeDecoder) == 0)
293 distance = rep2;
294 else
296 distance = rep3;
297 rep3 = rep2;
299 rep2 = rep1;
301 rep1 = rep0;
302 rep0 = distance;
304 len = m_RepLenDecoder.Decode(m_RangeDecoder, posState) + Base.kMatchMinLen;
305 state.UpdateRep();
307 else
309 rep3 = rep2;
310 rep2 = rep1;
311 rep1 = rep0;
312 len = Base.kMatchMinLen + m_LenDecoder.Decode(m_RangeDecoder, posState);
313 state.UpdateMatch();
314 uint posSlot = m_PosSlotDecoder[Base.GetLenToPosState(len)].Decode(m_RangeDecoder);
315 if (posSlot >= Base.kStartPosModelIndex)
317 int numDirectBits = (int)((posSlot >> 1) - 1);
318 rep0 = ((2 | (posSlot & 1)) << numDirectBits);
319 if (posSlot < Base.kEndPosModelIndex)
320 rep0 += BitTreeDecoder.ReverseDecode(m_PosDecoders,
321 rep0 - posSlot - 1, m_RangeDecoder, numDirectBits);
322 else
324 rep0 += (m_RangeDecoder.DecodeDirectBits(
325 numDirectBits - Base.kNumAlignBits) << Base.kNumAlignBits);
326 rep0 += m_PosAlignDecoder.ReverseDecode(m_RangeDecoder);
329 else
330 rep0 = posSlot;
332 if (rep0 >= nowPos64 || rep0 >= m_DictionarySizeCheck)
334 if (rep0 == 0xFFFFFFFF)
335 break;
336 throw new DataErrorException();
338 m_OutWindow.CopyBlock(rep0, len);
339 nowPos64 += len;
343 m_OutWindow.Flush();
344 m_OutWindow.ReleaseStream();
345 m_RangeDecoder.ReleaseStream();
348 public void SetDecoderProperties(byte[] properties)
350 if (properties.Length < 5)
351 throw new InvalidParamException();
352 int lc = properties[0] % 9;
353 int remainder = properties[0] / 9;
354 int lp = remainder % 5;
355 int pb = remainder / 5;
356 if (pb > Base.kNumPosStatesBitsMax)
357 throw new InvalidParamException();
358 UInt32 dictionarySize = 0;
359 for (int i = 0; i < 4; i++)
360 dictionarySize += ((UInt32)(properties[1 + i])) << (i * 8);
361 SetDictionarySize(dictionarySize);
362 SetLiteralProperties(lp, lc);
363 SetPosBitsProperties(pb);
367 public override bool CanRead { get { return true; }}
368 public override bool CanWrite { get { return true; }}
369 public override bool CanSeek { get { return true; }}
370 public override long Length { get { return 0; }}
371 public override long Position
373 get { return 0; }
374 set { }
376 public override void Flush() { }
377 public override int Read(byte[] buffer, int offset, int count)
379 return 0;
381 public override void Write(byte[] buffer, int offset, int count)
384 public override long Seek(long offset, System.IO.SeekOrigin origin)
386 return 0;
388 public override void SetLength(long value) {}