1370b324cSopenharmony_cipackage SevenZip.Compression.LZMA; 2370b324cSopenharmony_ci 3370b324cSopenharmony_ciimport SevenZip.Compression.RangeCoder.BitTreeDecoder; 4370b324cSopenharmony_ciimport SevenZip.Compression.LZMA.Base; 5370b324cSopenharmony_ciimport SevenZip.Compression.LZ.OutWindow; 6370b324cSopenharmony_ciimport java.io.IOException; 7370b324cSopenharmony_ci 8370b324cSopenharmony_cipublic class Decoder 9370b324cSopenharmony_ci{ 10370b324cSopenharmony_ci class LenDecoder 11370b324cSopenharmony_ci { 12370b324cSopenharmony_ci short[] m_Choice = new short[2]; 13370b324cSopenharmony_ci BitTreeDecoder[] m_LowCoder = new BitTreeDecoder[Base.kNumPosStatesMax]; 14370b324cSopenharmony_ci BitTreeDecoder[] m_MidCoder = new BitTreeDecoder[Base.kNumPosStatesMax]; 15370b324cSopenharmony_ci BitTreeDecoder m_HighCoder = new BitTreeDecoder(Base.kNumHighLenBits); 16370b324cSopenharmony_ci int m_NumPosStates = 0; 17370b324cSopenharmony_ci 18370b324cSopenharmony_ci public void Create(int numPosStates) 19370b324cSopenharmony_ci { 20370b324cSopenharmony_ci for (; m_NumPosStates < numPosStates; m_NumPosStates++) 21370b324cSopenharmony_ci { 22370b324cSopenharmony_ci m_LowCoder[m_NumPosStates] = new BitTreeDecoder(Base.kNumLowLenBits); 23370b324cSopenharmony_ci m_MidCoder[m_NumPosStates] = new BitTreeDecoder(Base.kNumMidLenBits); 24370b324cSopenharmony_ci } 25370b324cSopenharmony_ci } 26370b324cSopenharmony_ci 27370b324cSopenharmony_ci public void Init() 28370b324cSopenharmony_ci { 29370b324cSopenharmony_ci SevenZip.Compression.RangeCoder.Decoder.InitBitModels(m_Choice); 30370b324cSopenharmony_ci for (int posState = 0; posState < m_NumPosStates; posState++) 31370b324cSopenharmony_ci { 32370b324cSopenharmony_ci m_LowCoder[posState].Init(); 33370b324cSopenharmony_ci m_MidCoder[posState].Init(); 34370b324cSopenharmony_ci } 35370b324cSopenharmony_ci m_HighCoder.Init(); 36370b324cSopenharmony_ci } 37370b324cSopenharmony_ci 38370b324cSopenharmony_ci public int Decode(SevenZip.Compression.RangeCoder.Decoder rangeDecoder, int posState) throws IOException 39370b324cSopenharmony_ci { 40370b324cSopenharmony_ci if (rangeDecoder.DecodeBit(m_Choice, 0) == 0) 41370b324cSopenharmony_ci return m_LowCoder[posState].Decode(rangeDecoder); 42370b324cSopenharmony_ci int symbol = Base.kNumLowLenSymbols; 43370b324cSopenharmony_ci if (rangeDecoder.DecodeBit(m_Choice, 1) == 0) 44370b324cSopenharmony_ci symbol += m_MidCoder[posState].Decode(rangeDecoder); 45370b324cSopenharmony_ci else 46370b324cSopenharmony_ci symbol += Base.kNumMidLenSymbols + m_HighCoder.Decode(rangeDecoder); 47370b324cSopenharmony_ci return symbol; 48370b324cSopenharmony_ci } 49370b324cSopenharmony_ci } 50370b324cSopenharmony_ci 51370b324cSopenharmony_ci class LiteralDecoder 52370b324cSopenharmony_ci { 53370b324cSopenharmony_ci class Decoder2 54370b324cSopenharmony_ci { 55370b324cSopenharmony_ci short[] m_Decoders = new short[0x300]; 56370b324cSopenharmony_ci 57370b324cSopenharmony_ci public void Init() 58370b324cSopenharmony_ci { 59370b324cSopenharmony_ci SevenZip.Compression.RangeCoder.Decoder.InitBitModels(m_Decoders); 60370b324cSopenharmony_ci } 61370b324cSopenharmony_ci 62370b324cSopenharmony_ci public byte DecodeNormal(SevenZip.Compression.RangeCoder.Decoder rangeDecoder) throws IOException 63370b324cSopenharmony_ci { 64370b324cSopenharmony_ci int symbol = 1; 65370b324cSopenharmony_ci do 66370b324cSopenharmony_ci symbol = (symbol << 1) | rangeDecoder.DecodeBit(m_Decoders, symbol); 67370b324cSopenharmony_ci while (symbol < 0x100); 68370b324cSopenharmony_ci return (byte)symbol; 69370b324cSopenharmony_ci } 70370b324cSopenharmony_ci 71370b324cSopenharmony_ci public byte DecodeWithMatchByte(SevenZip.Compression.RangeCoder.Decoder rangeDecoder, byte matchByte) throws IOException 72370b324cSopenharmony_ci { 73370b324cSopenharmony_ci int symbol = 1; 74370b324cSopenharmony_ci do 75370b324cSopenharmony_ci { 76370b324cSopenharmony_ci int matchBit = (matchByte >> 7) & 1; 77370b324cSopenharmony_ci matchByte <<= 1; 78370b324cSopenharmony_ci int bit = rangeDecoder.DecodeBit(m_Decoders, ((1 + matchBit) << 8) + symbol); 79370b324cSopenharmony_ci symbol = (symbol << 1) | bit; 80370b324cSopenharmony_ci if (matchBit != bit) 81370b324cSopenharmony_ci { 82370b324cSopenharmony_ci while (symbol < 0x100) 83370b324cSopenharmony_ci symbol = (symbol << 1) | rangeDecoder.DecodeBit(m_Decoders, symbol); 84370b324cSopenharmony_ci break; 85370b324cSopenharmony_ci } 86370b324cSopenharmony_ci } 87370b324cSopenharmony_ci while (symbol < 0x100); 88370b324cSopenharmony_ci return (byte)symbol; 89370b324cSopenharmony_ci } 90370b324cSopenharmony_ci } 91370b324cSopenharmony_ci 92370b324cSopenharmony_ci Decoder2[] m_Coders; 93370b324cSopenharmony_ci int m_NumPrevBits; 94370b324cSopenharmony_ci int m_NumPosBits; 95370b324cSopenharmony_ci int m_PosMask; 96370b324cSopenharmony_ci 97370b324cSopenharmony_ci public void Create(int numPosBits, int numPrevBits) 98370b324cSopenharmony_ci { 99370b324cSopenharmony_ci if (m_Coders != null && m_NumPrevBits == numPrevBits && m_NumPosBits == numPosBits) 100370b324cSopenharmony_ci return; 101370b324cSopenharmony_ci m_NumPosBits = numPosBits; 102370b324cSopenharmony_ci m_PosMask = (1 << numPosBits) - 1; 103370b324cSopenharmony_ci m_NumPrevBits = numPrevBits; 104370b324cSopenharmony_ci int numStates = 1 << (m_NumPrevBits + m_NumPosBits); 105370b324cSopenharmony_ci m_Coders = new Decoder2[numStates]; 106370b324cSopenharmony_ci for (int i = 0; i < numStates; i++) 107370b324cSopenharmony_ci m_Coders[i] = new Decoder2(); 108370b324cSopenharmony_ci } 109370b324cSopenharmony_ci 110370b324cSopenharmony_ci public void Init() 111370b324cSopenharmony_ci { 112370b324cSopenharmony_ci int numStates = 1 << (m_NumPrevBits + m_NumPosBits); 113370b324cSopenharmony_ci for (int i = 0; i < numStates; i++) 114370b324cSopenharmony_ci m_Coders[i].Init(); 115370b324cSopenharmony_ci } 116370b324cSopenharmony_ci 117370b324cSopenharmony_ci Decoder2 GetDecoder(int pos, byte prevByte) 118370b324cSopenharmony_ci { 119370b324cSopenharmony_ci return m_Coders[((pos & m_PosMask) << m_NumPrevBits) + ((prevByte & 0xFF) >>> (8 - m_NumPrevBits))]; 120370b324cSopenharmony_ci } 121370b324cSopenharmony_ci } 122370b324cSopenharmony_ci 123370b324cSopenharmony_ci OutWindow m_OutWindow = new OutWindow(); 124370b324cSopenharmony_ci SevenZip.Compression.RangeCoder.Decoder m_RangeDecoder = new SevenZip.Compression.RangeCoder.Decoder(); 125370b324cSopenharmony_ci 126370b324cSopenharmony_ci short[] m_IsMatchDecoders = new short[Base.kNumStates << Base.kNumPosStatesBitsMax]; 127370b324cSopenharmony_ci short[] m_IsRepDecoders = new short[Base.kNumStates]; 128370b324cSopenharmony_ci short[] m_IsRepG0Decoders = new short[Base.kNumStates]; 129370b324cSopenharmony_ci short[] m_IsRepG1Decoders = new short[Base.kNumStates]; 130370b324cSopenharmony_ci short[] m_IsRepG2Decoders = new short[Base.kNumStates]; 131370b324cSopenharmony_ci short[] m_IsRep0LongDecoders = new short[Base.kNumStates << Base.kNumPosStatesBitsMax]; 132370b324cSopenharmony_ci 133370b324cSopenharmony_ci BitTreeDecoder[] m_PosSlotDecoder = new BitTreeDecoder[Base.kNumLenToPosStates]; 134370b324cSopenharmony_ci short[] m_PosDecoders = new short[Base.kNumFullDistances - Base.kEndPosModelIndex]; 135370b324cSopenharmony_ci 136370b324cSopenharmony_ci BitTreeDecoder m_PosAlignDecoder = new BitTreeDecoder(Base.kNumAlignBits); 137370b324cSopenharmony_ci 138370b324cSopenharmony_ci LenDecoder m_LenDecoder = new LenDecoder(); 139370b324cSopenharmony_ci LenDecoder m_RepLenDecoder = new LenDecoder(); 140370b324cSopenharmony_ci 141370b324cSopenharmony_ci LiteralDecoder m_LiteralDecoder = new LiteralDecoder(); 142370b324cSopenharmony_ci 143370b324cSopenharmony_ci int m_DictionarySize = -1; 144370b324cSopenharmony_ci int m_DictionarySizeCheck = -1; 145370b324cSopenharmony_ci 146370b324cSopenharmony_ci int m_PosStateMask; 147370b324cSopenharmony_ci 148370b324cSopenharmony_ci public Decoder() 149370b324cSopenharmony_ci { 150370b324cSopenharmony_ci for (int i = 0; i < Base.kNumLenToPosStates; i++) 151370b324cSopenharmony_ci m_PosSlotDecoder[i] = new BitTreeDecoder(Base.kNumPosSlotBits); 152370b324cSopenharmony_ci } 153370b324cSopenharmony_ci 154370b324cSopenharmony_ci boolean SetDictionarySize(int dictionarySize) 155370b324cSopenharmony_ci { 156370b324cSopenharmony_ci if (dictionarySize < 0) 157370b324cSopenharmony_ci return false; 158370b324cSopenharmony_ci if (m_DictionarySize != dictionarySize) 159370b324cSopenharmony_ci { 160370b324cSopenharmony_ci m_DictionarySize = dictionarySize; 161370b324cSopenharmony_ci m_DictionarySizeCheck = Math.max(m_DictionarySize, 1); 162370b324cSopenharmony_ci m_OutWindow.Create(Math.max(m_DictionarySizeCheck, (1 << 12))); 163370b324cSopenharmony_ci } 164370b324cSopenharmony_ci return true; 165370b324cSopenharmony_ci } 166370b324cSopenharmony_ci 167370b324cSopenharmony_ci boolean SetLcLpPb(int lc, int lp, int pb) 168370b324cSopenharmony_ci { 169370b324cSopenharmony_ci if (lc > Base.kNumLitContextBitsMax || lp > 4 || pb > Base.kNumPosStatesBitsMax) 170370b324cSopenharmony_ci return false; 171370b324cSopenharmony_ci m_LiteralDecoder.Create(lp, lc); 172370b324cSopenharmony_ci int numPosStates = 1 << pb; 173370b324cSopenharmony_ci m_LenDecoder.Create(numPosStates); 174370b324cSopenharmony_ci m_RepLenDecoder.Create(numPosStates); 175370b324cSopenharmony_ci m_PosStateMask = numPosStates - 1; 176370b324cSopenharmony_ci return true; 177370b324cSopenharmony_ci } 178370b324cSopenharmony_ci 179370b324cSopenharmony_ci void Init() throws IOException 180370b324cSopenharmony_ci { 181370b324cSopenharmony_ci m_OutWindow.Init(false); 182370b324cSopenharmony_ci 183370b324cSopenharmony_ci SevenZip.Compression.RangeCoder.Decoder.InitBitModels(m_IsMatchDecoders); 184370b324cSopenharmony_ci SevenZip.Compression.RangeCoder.Decoder.InitBitModels(m_IsRep0LongDecoders); 185370b324cSopenharmony_ci SevenZip.Compression.RangeCoder.Decoder.InitBitModels(m_IsRepDecoders); 186370b324cSopenharmony_ci SevenZip.Compression.RangeCoder.Decoder.InitBitModels(m_IsRepG0Decoders); 187370b324cSopenharmony_ci SevenZip.Compression.RangeCoder.Decoder.InitBitModels(m_IsRepG1Decoders); 188370b324cSopenharmony_ci SevenZip.Compression.RangeCoder.Decoder.InitBitModels(m_IsRepG2Decoders); 189370b324cSopenharmony_ci SevenZip.Compression.RangeCoder.Decoder.InitBitModels(m_PosDecoders); 190370b324cSopenharmony_ci 191370b324cSopenharmony_ci m_LiteralDecoder.Init(); 192370b324cSopenharmony_ci int i; 193370b324cSopenharmony_ci for (i = 0; i < Base.kNumLenToPosStates; i++) 194370b324cSopenharmony_ci m_PosSlotDecoder[i].Init(); 195370b324cSopenharmony_ci m_LenDecoder.Init(); 196370b324cSopenharmony_ci m_RepLenDecoder.Init(); 197370b324cSopenharmony_ci m_PosAlignDecoder.Init(); 198370b324cSopenharmony_ci m_RangeDecoder.Init(); 199370b324cSopenharmony_ci } 200370b324cSopenharmony_ci 201370b324cSopenharmony_ci public boolean Code(java.io.InputStream inStream, java.io.OutputStream outStream, 202370b324cSopenharmony_ci long outSize) throws IOException 203370b324cSopenharmony_ci { 204370b324cSopenharmony_ci m_RangeDecoder.SetStream(inStream); 205370b324cSopenharmony_ci m_OutWindow.SetStream(outStream); 206370b324cSopenharmony_ci Init(); 207370b324cSopenharmony_ci 208370b324cSopenharmony_ci int state = Base.StateInit(); 209370b324cSopenharmony_ci int rep0 = 0, rep1 = 0, rep2 = 0, rep3 = 0; 210370b324cSopenharmony_ci 211370b324cSopenharmony_ci long nowPos64 = 0; 212370b324cSopenharmony_ci byte prevByte = 0; 213370b324cSopenharmony_ci while (outSize < 0 || nowPos64 < outSize) 214370b324cSopenharmony_ci { 215370b324cSopenharmony_ci int posState = (int)nowPos64 & m_PosStateMask; 216370b324cSopenharmony_ci if (m_RangeDecoder.DecodeBit(m_IsMatchDecoders, (state << Base.kNumPosStatesBitsMax) + posState) == 0) 217370b324cSopenharmony_ci { 218370b324cSopenharmony_ci LiteralDecoder.Decoder2 decoder2 = m_LiteralDecoder.GetDecoder((int)nowPos64, prevByte); 219370b324cSopenharmony_ci if (!Base.StateIsCharState(state)) 220370b324cSopenharmony_ci prevByte = decoder2.DecodeWithMatchByte(m_RangeDecoder, m_OutWindow.GetByte(rep0)); 221370b324cSopenharmony_ci else 222370b324cSopenharmony_ci prevByte = decoder2.DecodeNormal(m_RangeDecoder); 223370b324cSopenharmony_ci m_OutWindow.PutByte(prevByte); 224370b324cSopenharmony_ci state = Base.StateUpdateChar(state); 225370b324cSopenharmony_ci nowPos64++; 226370b324cSopenharmony_ci } 227370b324cSopenharmony_ci else 228370b324cSopenharmony_ci { 229370b324cSopenharmony_ci int len; 230370b324cSopenharmony_ci if (m_RangeDecoder.DecodeBit(m_IsRepDecoders, state) == 1) 231370b324cSopenharmony_ci { 232370b324cSopenharmony_ci len = 0; 233370b324cSopenharmony_ci if (m_RangeDecoder.DecodeBit(m_IsRepG0Decoders, state) == 0) 234370b324cSopenharmony_ci { 235370b324cSopenharmony_ci if (m_RangeDecoder.DecodeBit(m_IsRep0LongDecoders, (state << Base.kNumPosStatesBitsMax) + posState) == 0) 236370b324cSopenharmony_ci { 237370b324cSopenharmony_ci state = Base.StateUpdateShortRep(state); 238370b324cSopenharmony_ci len = 1; 239370b324cSopenharmony_ci } 240370b324cSopenharmony_ci } 241370b324cSopenharmony_ci else 242370b324cSopenharmony_ci { 243370b324cSopenharmony_ci int distance; 244370b324cSopenharmony_ci if (m_RangeDecoder.DecodeBit(m_IsRepG1Decoders, state) == 0) 245370b324cSopenharmony_ci distance = rep1; 246370b324cSopenharmony_ci else 247370b324cSopenharmony_ci { 248370b324cSopenharmony_ci if (m_RangeDecoder.DecodeBit(m_IsRepG2Decoders, state) == 0) 249370b324cSopenharmony_ci distance = rep2; 250370b324cSopenharmony_ci else 251370b324cSopenharmony_ci { 252370b324cSopenharmony_ci distance = rep3; 253370b324cSopenharmony_ci rep3 = rep2; 254370b324cSopenharmony_ci } 255370b324cSopenharmony_ci rep2 = rep1; 256370b324cSopenharmony_ci } 257370b324cSopenharmony_ci rep1 = rep0; 258370b324cSopenharmony_ci rep0 = distance; 259370b324cSopenharmony_ci } 260370b324cSopenharmony_ci if (len == 0) 261370b324cSopenharmony_ci { 262370b324cSopenharmony_ci len = m_RepLenDecoder.Decode(m_RangeDecoder, posState) + Base.kMatchMinLen; 263370b324cSopenharmony_ci state = Base.StateUpdateRep(state); 264370b324cSopenharmony_ci } 265370b324cSopenharmony_ci } 266370b324cSopenharmony_ci else 267370b324cSopenharmony_ci { 268370b324cSopenharmony_ci rep3 = rep2; 269370b324cSopenharmony_ci rep2 = rep1; 270370b324cSopenharmony_ci rep1 = rep0; 271370b324cSopenharmony_ci len = Base.kMatchMinLen + m_LenDecoder.Decode(m_RangeDecoder, posState); 272370b324cSopenharmony_ci state = Base.StateUpdateMatch(state); 273370b324cSopenharmony_ci int posSlot = m_PosSlotDecoder[Base.GetLenToPosState(len)].Decode(m_RangeDecoder); 274370b324cSopenharmony_ci if (posSlot >= Base.kStartPosModelIndex) 275370b324cSopenharmony_ci { 276370b324cSopenharmony_ci int numDirectBits = (posSlot >> 1) - 1; 277370b324cSopenharmony_ci rep0 = ((2 | (posSlot & 1)) << numDirectBits); 278370b324cSopenharmony_ci if (posSlot < Base.kEndPosModelIndex) 279370b324cSopenharmony_ci rep0 += BitTreeDecoder.ReverseDecode(m_PosDecoders, 280370b324cSopenharmony_ci rep0 - posSlot - 1, m_RangeDecoder, numDirectBits); 281370b324cSopenharmony_ci else 282370b324cSopenharmony_ci { 283370b324cSopenharmony_ci rep0 += (m_RangeDecoder.DecodeDirectBits( 284370b324cSopenharmony_ci numDirectBits - Base.kNumAlignBits) << Base.kNumAlignBits); 285370b324cSopenharmony_ci rep0 += m_PosAlignDecoder.ReverseDecode(m_RangeDecoder); 286370b324cSopenharmony_ci if (rep0 < 0) 287370b324cSopenharmony_ci { 288370b324cSopenharmony_ci if (rep0 == -1) 289370b324cSopenharmony_ci break; 290370b324cSopenharmony_ci return false; 291370b324cSopenharmony_ci } 292370b324cSopenharmony_ci } 293370b324cSopenharmony_ci } 294370b324cSopenharmony_ci else 295370b324cSopenharmony_ci rep0 = posSlot; 296370b324cSopenharmony_ci } 297370b324cSopenharmony_ci if (rep0 >= nowPos64 || rep0 >= m_DictionarySizeCheck) 298370b324cSopenharmony_ci { 299370b324cSopenharmony_ci // m_OutWindow.Flush(); 300370b324cSopenharmony_ci return false; 301370b324cSopenharmony_ci } 302370b324cSopenharmony_ci m_OutWindow.CopyBlock(rep0, len); 303370b324cSopenharmony_ci nowPos64 += len; 304370b324cSopenharmony_ci prevByte = m_OutWindow.GetByte(0); 305370b324cSopenharmony_ci } 306370b324cSopenharmony_ci } 307370b324cSopenharmony_ci m_OutWindow.Flush(); 308370b324cSopenharmony_ci m_OutWindow.ReleaseStream(); 309370b324cSopenharmony_ci m_RangeDecoder.ReleaseStream(); 310370b324cSopenharmony_ci return true; 311370b324cSopenharmony_ci } 312370b324cSopenharmony_ci 313370b324cSopenharmony_ci public boolean SetDecoderProperties(byte[] properties) 314370b324cSopenharmony_ci { 315370b324cSopenharmony_ci if (properties.length < 5) 316370b324cSopenharmony_ci return false; 317370b324cSopenharmony_ci int val = properties[0] & 0xFF; 318370b324cSopenharmony_ci int lc = val % 9; 319370b324cSopenharmony_ci int remainder = val / 9; 320370b324cSopenharmony_ci int lp = remainder % 5; 321370b324cSopenharmony_ci int pb = remainder / 5; 322370b324cSopenharmony_ci int dictionarySize = 0; 323370b324cSopenharmony_ci for (int i = 0; i < 4; i++) 324370b324cSopenharmony_ci dictionarySize += ((int)(properties[1 + i]) & 0xFF) << (i * 8); 325370b324cSopenharmony_ci if (!SetLcLpPb(lc, lp, pb)) 326370b324cSopenharmony_ci return false; 327370b324cSopenharmony_ci return SetDictionarySize(dictionarySize); 328370b324cSopenharmony_ci } 329370b324cSopenharmony_ci} 330