5 namespace SevenZip
.Compression
.LZMA
9 public class Decoder
: ICoder
, ISetDecoderProperties
// ,System.IO.Stream
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
;
33 for (uint posState
= 0; posState
< m_NumPosStates
; posState
++)
35 m_LowCoder
[posState
].Init();
36 m_MidCoder
[posState
].Init();
42 public uint Decode(RangeCoder
.Decoder rangeDecoder
, uint posState
)
44 if (m_Choice
.Decode(rangeDecoder
) == 0)
45 return m_LowCoder
[posState
].Decode(rangeDecoder
);
48 uint symbol
= Base
.kNumLowLenSymbols
;
49 if (m_Choice2
.Decode(rangeDecoder
) == 0)
50 symbol
+= m_MidCoder
[posState
].Decode(rangeDecoder
);
53 symbol
+= Base
.kNumMidLenSymbols
;
54 symbol
+= m_HighCoder
.Decode(rangeDecoder
);
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
)
73 symbol
= (symbol
<< 1) | m_Decoders
[symbol
].Decode(rangeDecoder
);
74 while (symbol
< 0x100);
78 public byte DecodeWithMatchByte(RangeCoder
.Decoder rangeDecoder
, byte matchByte
)
83 uint matchBit
= (uint)(matchByte
>> 7) & 1;
85 uint bit
= m_Decoders
[((1 + matchBit
) << 8) + symbol
].Decode(rangeDecoder
);
86 symbol
= (symbol
<< 1) | bit
;
89 while (symbol
< 0x100)
90 symbol
= (symbol
<< 1) | m_Decoders
[symbol
].Decode(rangeDecoder
);
94 while (symbol
< 0x100);
104 public void Create(int numPosBits
, int numPrevBits
)
106 if (m_Coders
!= null && m_NumPrevBits
== numPrevBits
&&
107 m_NumPosBits
== numPosBits
)
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();
120 uint numStates
= (uint)1 << (m_NumPrevBits
+ m_NumPosBits
);
121 for (uint i
= 0; i
< numStates
; i
++)
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
;
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
)
181 throw new InvalidParamException();
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
);
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();
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();
236 uint rep0
= 0, rep1
= 0, rep2
= 0, rep3
= 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();
245 byte b
= m_LiteralDecoder
.DecodeNormal(m_RangeDecoder
, 0, 0);
246 m_OutWindow
.PutByte(b
);
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)
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
));
263 b
= m_LiteralDecoder
.DecodeNormal(m_RangeDecoder
, (uint)nowPos64
, prevByte
);
264 m_OutWindow
.PutByte(b
);
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
));
286 if (m_IsRepG1Decoders
[state
.Index
].Decode(m_RangeDecoder
) == 0)
292 if (m_IsRepG2Decoders
[state
.Index
].Decode(m_RangeDecoder
) == 0)
304 len
= m_RepLenDecoder
.Decode(m_RangeDecoder
, posState
) + Base
.kMatchMinLen
;
312 len
= Base
.kMatchMinLen
+ m_LenDecoder
.Decode(m_RangeDecoder
, posState
);
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
);
324 rep0
+= (m_RangeDecoder
.DecodeDirectBits(
325 numDirectBits
- Base
.kNumAlignBits
) << Base
.kNumAlignBits
);
326 rep0
+= m_PosAlignDecoder
.ReverseDecode(m_RangeDecoder
);
332 if (rep0
>= nowPos64
|| rep0
>= m_DictionarySizeCheck
)
334 if (rep0
== 0xFFFFFFFF)
336 throw new DataErrorException();
338 m_OutWindow
.CopyBlock(rep0
, len
);
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
376 public override void Flush() { }
377 public override int Read(byte[] buffer, int offset, int count)
381 public override void Write(byte[] buffer, int offset, int count)
384 public override long Seek(long offset, System.IO.SeekOrigin origin)
388 public override void SetLength(long value) {}