/// <summary> /// Codes a stream with LZMA algorithm to an output stream /// </summary> /// <param name="inStream">The input stream</param> /// <param name="inSize">The input size</param> /// <param name="outSize">The output size</param> /// <param name="outStream">The output stream</param> /// <param name="progress">Progress interface</param> public void Code(Stream inStream, Stream outStream, Int64 inSize, Int64 outSize, ICodeProgress progress) { Init(inStream, outStream); var state = new Base.State(); state.Init(); uint rep0 = 0, rep1 = 0, rep2 = 0, rep3 = 0; //Outsize == Int64.MaxValue means this is a streamed LZMA file and we don't know how much we have do. When rep0 is 0xFFFFFFFF we are done decoding. UInt64 nowPos64 = 0; var outSize64 = (UInt64)outSize; if (nowPos64 < outSize64 && outSize != -1) { if (m_IsMatchDecoders[state.Index << Base.kNumPosStatesBitsMax].Decode(m_RangeDecoder) != 0) { throw new DataErrorException(); } state.UpdateChar(); byte b = m_LiteralDecoder.DecodeNormal(m_RangeDecoder, 0, 0); m_OutWindow.PutByte(b); nowPos64++; } while (nowPos64 < outSize64 || outSize == -1) { // UInt64 next = Math.Min(nowPos64 + (1 << 18), outSize64); // while(nowPos64 < next) { uint posState = (uint)nowPos64 & m_PosStateMask; if ( m_IsMatchDecoders[(state.Index << Base.kNumPosStatesBitsMax) + posState].Decode(m_RangeDecoder) == 0) { byte b; byte prevByte = m_OutWindow.GetByte(0); if (!state.IsCharState()) { b = m_LiteralDecoder.DecodeWithMatchByte(m_RangeDecoder, (uint)nowPos64, prevByte, m_OutWindow.GetByte(rep0)); } else { b = m_LiteralDecoder.DecodeNormal(m_RangeDecoder, (uint)nowPos64, prevByte); } m_OutWindow.PutByte(b); state.UpdateChar(); nowPos64++; } else { uint len; if (m_IsRepDecoders[state.Index].Decode(m_RangeDecoder) == 1) { if (m_IsRepG0Decoders[state.Index].Decode(m_RangeDecoder) == 0) { if ( m_IsRep0LongDecoders[(state.Index << Base.kNumPosStatesBitsMax) + posState].Decode( m_RangeDecoder) == 0) { state.UpdateShortRep(); m_OutWindow.PutByte(m_OutWindow.GetByte(rep0)); nowPos64++; continue; } } else { UInt32 distance; if (m_IsRepG1Decoders[state.Index].Decode(m_RangeDecoder) == 0) { distance = rep1; } else { if (m_IsRepG2Decoders[state.Index].Decode(m_RangeDecoder) == 0) { distance = rep2; } else { distance = rep3; rep3 = rep2; } rep2 = rep1; } rep1 = rep0; rep0 = distance; } len = m_RepLenDecoder.Decode(m_RangeDecoder, posState) + Base.kMatchMinLen; state.UpdateRep(); } else { rep3 = rep2; rep2 = rep1; rep1 = rep0; len = Base.kMatchMinLen + m_LenDecoder.Decode(m_RangeDecoder, posState); state.UpdateMatch(); uint posSlot = m_PosSlotDecoder[Base.GetLenToPosState(len)].Decode(m_RangeDecoder); if (posSlot >= Base.kStartPosModelIndex) { var numDirectBits = (int)((posSlot >> 1) - 1); rep0 = ((2 | (posSlot & 1)) << numDirectBits); if (posSlot < Base.kEndPosModelIndex) { rep0 += BitTreeDecoder.ReverseDecode(m_PosDecoders, rep0 - posSlot - 1, m_RangeDecoder, numDirectBits); } else { rep0 += (m_RangeDecoder.DecodeDirectBits( numDirectBits - Base.kNumAlignBits) << Base.kNumAlignBits); rep0 += m_PosAlignDecoder.ReverseDecode(m_RangeDecoder); } } else { rep0 = posSlot; } } if (rep0 >= m_OutWindow.TrainSize + nowPos64 || rep0 >= m_DictionarySizeCheck) { if (rep0 == 0xFFFFFFFF) //End of file marker { HasFoundEndOfStream = true; break; } throw new DataErrorException(); } m_OutWindow.CopyBlock(rep0, len); nowPos64 += len; } } } m_OutWindow.Flush(); m_OutWindow.ReleaseStream(); m_RangeDecoder.ReleaseStream(); }
/// <summary> /// Codes a stream with LZMA algorithm to an output stream /// </summary> /// <param name="inStream">The input stream</param> /// <param name="inSize">The input size</param> /// <param name="outSize">The output size</param> /// <param name="outStream">The output stream</param> /// <param name="progress">Progress interface</param> public void Code(Stream inStream, Stream outStream, Int64 inSize, Int64 outSize, ICodeProgress progress) { Init(inStream, outStream); var state = new Base.State(); state.Init(); uint rep0 = 0, rep1 = 0, rep2 = 0, rep3 = 0; UInt64 nowPos64 = 0; var outSize64 = (UInt64) outSize; if (nowPos64 < outSize64) { if (m_IsMatchDecoders[state.Index << Base.kNumPosStatesBitsMax].Decode(m_RangeDecoder) != 0) throw new DataErrorException(); state.UpdateChar(); byte b = m_LiteralDecoder.DecodeNormal(m_RangeDecoder, 0, 0); m_OutWindow.PutByte(b); nowPos64++; } while (nowPos64 < outSize64) { // UInt64 next = Math.Min(nowPos64 + (1 << 18), outSize64); // while(nowPos64 < next) { uint posState = (uint) nowPos64 & m_PosStateMask; if ( m_IsMatchDecoders[(state.Index << Base.kNumPosStatesBitsMax) + posState].Decode(m_RangeDecoder) == 0) { byte b; byte prevByte = m_OutWindow.GetByte(0); if (!state.IsCharState()) b = m_LiteralDecoder.DecodeWithMatchByte(m_RangeDecoder, (uint) nowPos64, prevByte, m_OutWindow.GetByte(rep0)); else b = m_LiteralDecoder.DecodeNormal(m_RangeDecoder, (uint) nowPos64, prevByte); m_OutWindow.PutByte(b); state.UpdateChar(); nowPos64++; } else { uint len; if (m_IsRepDecoders[state.Index].Decode(m_RangeDecoder) == 1) { if (m_IsRepG0Decoders[state.Index].Decode(m_RangeDecoder) == 0) { if ( m_IsRep0LongDecoders[(state.Index << Base.kNumPosStatesBitsMax) + posState].Decode( m_RangeDecoder) == 0) { state.UpdateShortRep(); m_OutWindow.PutByte(m_OutWindow.GetByte(rep0)); nowPos64++; continue; } } else { UInt32 distance; if (m_IsRepG1Decoders[state.Index].Decode(m_RangeDecoder) == 0) { distance = rep1; } else { if (m_IsRepG2Decoders[state.Index].Decode(m_RangeDecoder) == 0) distance = rep2; else { distance = rep3; rep3 = rep2; } rep2 = rep1; } rep1 = rep0; rep0 = distance; } len = m_RepLenDecoder.Decode(m_RangeDecoder, posState) + Base.kMatchMinLen; state.UpdateRep(); } else { rep3 = rep2; rep2 = rep1; rep1 = rep0; len = Base.kMatchMinLen + m_LenDecoder.Decode(m_RangeDecoder, posState); state.UpdateMatch(); uint posSlot = m_PosSlotDecoder[Base.GetLenToPosState(len)].Decode(m_RangeDecoder); if (posSlot >= Base.kStartPosModelIndex) { var numDirectBits = (int) ((posSlot >> 1) - 1); rep0 = ((2 | (posSlot & 1)) << numDirectBits); if (posSlot < Base.kEndPosModelIndex) rep0 += BitTreeDecoder.ReverseDecode(m_PosDecoders, rep0 - posSlot - 1, m_RangeDecoder, numDirectBits); else { rep0 += (m_RangeDecoder.DecodeDirectBits( numDirectBits - Base.kNumAlignBits) << Base.kNumAlignBits); rep0 += m_PosAlignDecoder.ReverseDecode(m_RangeDecoder); } } else rep0 = posSlot; } if (rep0 >= m_OutWindow.TrainSize + nowPos64 || rep0 >= m_DictionarySizeCheck) { if (rep0 == 0xFFFFFFFF) break; throw new DataErrorException(); } m_OutWindow.CopyBlock(rep0, len); nowPos64 += len; } } } m_OutWindow.Flush(); m_OutWindow.ReleaseStream(); m_RangeDecoder.ReleaseStream(); }
/// <summary> /// Codes a stream with LZMA algorithm to an output stream /// </summary> /// <param name="inStream">The input stream</param> /// <param name="inSize">The input size</param> /// <param name="outSize">The output size</param> /// <param name="outStream">The output stream</param> /// <param name="progress">Progress interface</param> public void Code(Stream inStream, Stream outStream, long inSize, long outSize, ICodeProgress progress) { Init(inStream, outStream); var state = new Base.State(); state.Init(); uint rep0 = 0, rep1 = 0, rep2 = 0, rep3 = 0; ulong nowPos64 = 0; var outSize64 = (ulong)outSize; if (nowPos64 < outSize64) { if (m_IsMatchDecoders[state.Index << Base.kNumPosStatesBitsMax].Decode(m_RangeDecoder) != 0) { throw new DataErrorException(); } state.UpdateChar(); var b = m_LiteralDecoder.DecodeNormal(m_RangeDecoder, 0, 0); m_OutWindow.PutByte(b); nowPos64++; } while (nowPos64 < outSize64) // UInt64 next = Math.Min(nowPos64 + (1 << 18), outSize64); // while(nowPos64 < next) { var posState = (uint)nowPos64 & m_PosStateMask; if ( m_IsMatchDecoders[(state.Index << Base.kNumPosStatesBitsMax) + posState].Decode(m_RangeDecoder) == 0) { byte b; var prevByte = m_OutWindow.GetByte(0); if (!state.IsCharState()) { b = m_LiteralDecoder.DecodeWithMatchByte(m_RangeDecoder, (uint)nowPos64, prevByte, m_OutWindow.GetByte(rep0)); } else { b = m_LiteralDecoder.DecodeNormal(m_RangeDecoder, (uint)nowPos64, prevByte); } m_OutWindow.PutByte(b); state.UpdateChar(); nowPos64++; } else { uint len; if (m_IsRepDecoders[state.Index].Decode(m_RangeDecoder) == 1) { if (m_IsRepG0Decoders[state.Index].Decode(m_RangeDecoder) == 0) { if ( m_IsRep0LongDecoders[(state.Index << Base.kNumPosStatesBitsMax) + posState].Decode( m_RangeDecoder) == 0) { state.UpdateShortRep(); m_OutWindow.PutByte(m_OutWindow.GetByte(rep0)); nowPos64++; continue; } } else { uint distance; if (m_IsRepG1Decoders[state.Index].Decode(m_RangeDecoder) == 0) { distance = rep1; } else { if (m_IsRepG2Decoders[state.Index].Decode(m_RangeDecoder) == 0) { distance = rep2; } else { distance = rep3; rep3 = rep2; } rep2 = rep1; } rep1 = rep0; rep0 = distance; } len = m_RepLenDecoder.Decode(m_RangeDecoder, posState) + Base.kMatchMinLen; state.UpdateRep(); } else { rep3 = rep2; rep2 = rep1; rep1 = rep0; len = Base.kMatchMinLen + m_LenDecoder.Decode(m_RangeDecoder, posState); state.UpdateMatch(); var posSlot = m_PosSlotDecoder[Base.GetLenToPosState(len)].Decode(m_RangeDecoder); if (posSlot >= Base.kStartPosModelIndex) { var numDirectBits = (int)((posSlot >> 1) - 1); rep0 = (2 | (posSlot & 1)) << numDirectBits; if (posSlot < Base.kEndPosModelIndex) { rep0 += BitTreeDecoder.ReverseDecode(m_PosDecoders, rep0 - posSlot - 1, m_RangeDecoder, numDirectBits); } else { rep0 += m_RangeDecoder.DecodeDirectBits( numDirectBits - Base.kNumAlignBits) << Base.kNumAlignBits; rep0 += m_PosAlignDecoder.ReverseDecode(m_RangeDecoder); } } else { rep0 = posSlot; } } if (rep0 >= m_OutWindow.TrainSize + nowPos64 || rep0 >= m_DictionarySizeCheck) { if (rep0 == 0xFFFFFFFF) { break; } throw new DataErrorException(); } m_OutWindow.CopyBlock(rep0, len); nowPos64 += len; } } m_OutWindow.Flush(); m_OutWindow.ReleaseStream(); m_RangeDecoder.ReleaseStream(); }