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