| 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 |