/* finishMode: It has meaning only if the decoding reaches output limit (*destLen). LZMA_FINISH_ANY - use smallest number of input bytes LZMA_FINISH_END - read EndOfStream marker after decoding Returns: SZ_OK status: LZMA_STATUS_FINISHED_WITH_MARK LZMA_STATUS_NOT_FINISHED SZ_ERROR_DATA - Data error SZ_ERROR_MEM - Memory allocation error SZ_ERROR_UNSUPPORTED - Unsupported properties SZ_ERROR_INPUT_EOF - It needs more bytes in input buffer (src). */ public static SRes Lzma2Decode(P<byte> dest, ref long destLen, P<byte> src, ref long srcLen, byte prop, ELzmaFinishMode finishMode, out ELzmaStatus status, ISzAlloc alloc) { long outSize = destLen; long inSize = srcLen; destLen = 0; srcLen = 0; status = ELzmaStatus.LZMA_STATUS_NOT_SPECIFIED; CLzma2Dec p = new CLzma2Dec(); p.Lzma2Dec_Construct(); SRes res; if ((res = p.Lzma2Dec_AllocateProbs(prop, alloc)) != SZ_OK) return res; p.mDecoder.mDic = dest; p.mDecoder.mDicBufSize = outSize; p.Lzma2Dec_Init(); srcLen = inSize; res = p.Lzma2Dec_DecodeToDic(outSize, src, ref srcLen, finishMode, out status); destLen = p.mDecoder.mDicPos; if (res == SZ_OK && status == ELzmaStatus.LZMA_STATUS_NEEDS_MORE_INPUT) res = SZ_ERROR_INPUT_EOF; p.Lzma2Dec_FreeProbs(alloc); return res; }
/* * finishMode: * It has meaning only if the decoding reaches output limit (*destLen). * LZMA_FINISH_ANY - use smallest number of input bytes * LZMA_FINISH_END - read EndOfStream marker after decoding * * Returns: * SZ_OK * status: * LZMA_STATUS_FINISHED_WITH_MARK * LZMA_STATUS_NOT_FINISHED * SZ_ERROR_DATA - Data error * SZ_ERROR_MEM - Memory allocation error * SZ_ERROR_UNSUPPORTED - Unsupported properties * SZ_ERROR_INPUT_EOF - It needs more bytes in input buffer (src). */ public static SRes Lzma2Decode(P <byte> dest, ref long destLen, P <byte> src, ref long srcLen, byte prop, ELzmaFinishMode finishMode, out ELzmaStatus status, ISzAlloc alloc) { long outSize = destLen; long inSize = srcLen; destLen = 0; srcLen = 0; status = ELzmaStatus.LZMA_STATUS_NOT_SPECIFIED; CLzma2Dec p = new CLzma2Dec(); p.Lzma2Dec_Construct(); SRes res; if ((res = p.Lzma2Dec_AllocateProbs(prop, alloc)) != SZ_OK) { return(res); } p.mDecoder.mDic = dest; p.mDecoder.mDicBufSize = outSize; p.Lzma2Dec_Init(); srcLen = inSize; res = p.Lzma2Dec_DecodeToDic(outSize, src, ref srcLen, finishMode, out status); destLen = p.mDecoder.mDicPos; if (res == SZ_OK && status == ELzmaStatus.LZMA_STATUS_NEEDS_MORE_INPUT) { res = SZ_ERROR_INPUT_EOF; } p.Lzma2Dec_FreeProbs(alloc); return(res); }
public SRes Lzma2Dec_DecodeToBuf(P <byte> dest, ref long destLen, P <byte> src, ref long srcLen, ELzmaFinishMode finishMode, out ELzmaStatus status) { long outSize = destLen; long inSize = srcLen; srcLen = 0; destLen = 0; for (;;) { if (mDecoder.mDicPos == mDecoder.mDicBufSize) { mDecoder.mDicPos = 0; } long outSizeCur; ELzmaFinishMode curFinishMode; long dicPos = mDecoder.mDicPos; if (outSize > mDecoder.mDicBufSize - dicPos) { outSizeCur = mDecoder.mDicBufSize; curFinishMode = ELzmaFinishMode.LZMA_FINISH_ANY; } else { outSizeCur = dicPos + outSize; curFinishMode = finishMode; } long srcSizeCur = inSize; SRes res = Lzma2Dec_DecodeToDic(outSizeCur, src, ref srcSizeCur, curFinishMode, out status); src += srcSizeCur; inSize -= srcSizeCur; srcLen += srcSizeCur; outSizeCur = mDecoder.mDicPos - dicPos; CUtils.memcpy(dest, mDecoder.mDic + dicPos, outSizeCur); dest += outSizeCur; outSize -= outSizeCur; destLen += outSizeCur; if (res != 0) { return(res); } if (outSizeCur == 0 || outSize == 0) { return(SZ_OK); } } }
/* * finishMode: * It has meaning only if the decoding reaches output limit (*destLen or dicLimit). * LZMA_FINISH_ANY - use smallest number of input bytes * LZMA_FINISH_END - read EndOfStream marker after decoding * * Returns: * SZ_OK * status: * LZMA_STATUS_FINISHED_WITH_MARK * LZMA_STATUS_NOT_FINISHED * LZMA_STATUS_NEEDS_MORE_INPUT * SZ_ERROR_DATA - Data error */ public SRes Lzma2Dec_DecodeToDic(long dicLimit, P <byte> src, ref long srcLen, ELzmaFinishMode finishMode, out ELzmaStatus status) { long inSize = srcLen; srcLen = 0; status = ELzmaStatus.LZMA_STATUS_NOT_SPECIFIED; while (mState != Lzma2State.Finished) { long dicPos = mDecoder.mDicPos; if (mState == Lzma2State.Error) { return(SZ_ERROR_DATA); } if (dicPos == dicLimit && finishMode == ELzmaFinishMode.LZMA_FINISH_ANY) { status = ELzmaStatus.LZMA_STATUS_NOT_FINISHED; return(SZ_OK); } if (mState != Lzma2State.Data && mState != Lzma2State.DataCont) { if (srcLen == inSize) { status = ELzmaStatus.LZMA_STATUS_NEEDS_MORE_INPUT; return(SZ_OK); } srcLen++; mState = Lzma2Dec_UpdateState(src[0]); src++; continue; } long destSizeCur = dicLimit - dicPos; long srcSizeCur = inSize - srcLen; ELzmaFinishMode curFinishMode = ELzmaFinishMode.LZMA_FINISH_ANY; if (mUnpackSize <= destSizeCur) { destSizeCur = mUnpackSize; curFinishMode = ELzmaFinishMode.LZMA_FINISH_END; } if (IsUncompressedState()) { if (srcLen == inSize) { status = ELzmaStatus.LZMA_STATUS_NEEDS_MORE_INPUT; return(SZ_OK); } if (mState == Lzma2State.Data) { bool initDic = (mControl == LZMA2_CONTROL_COPY_RESET_DIC); if (initDic) { mNeedInitProp = mNeedInitState = true; } else if (mNeedInitDic) { return(SZ_ERROR_DATA); } mNeedInitDic = false; mDecoder.LzmaDec_InitDicAndState(initDic, false); } if (srcSizeCur > destSizeCur) { srcSizeCur = destSizeCur; } if (srcSizeCur == 0) { return(SZ_ERROR_DATA); } LzmaDec_UpdateWithUncompressed(mDecoder, src, srcSizeCur); src += srcSizeCur; srcLen += srcSizeCur; mUnpackSize -= (uint)srcSizeCur; mState = (mUnpackSize == 0) ? Lzma2State.Control : Lzma2State.DataCont; } else { long outSizeProcessed; if (mState == Lzma2State.Data) { int mode = GetLzmaMode(); bool initDic = (mode == 3); bool initState = (mode > 0); if ((!initDic && mNeedInitDic) || (!initState && mNeedInitState)) { return(SZ_ERROR_DATA); } mDecoder.LzmaDec_InitDicAndState(initDic, initState); mNeedInitDic = false; mNeedInitState = false; mState = Lzma2State.DataCont; } if (srcSizeCur > mPackSize) { srcSizeCur = mPackSize; } SRes res = mDecoder.LzmaDec_DecodeToDic(dicPos + destSizeCur, src, ref srcSizeCur, curFinishMode, out status); src += srcSizeCur; srcLen += srcSizeCur; mPackSize -= (uint)srcSizeCur; outSizeProcessed = mDecoder.mDicPos - dicPos; mUnpackSize -= (uint)outSizeProcessed; if (res != SZ_OK) { return(res); } if (status == ELzmaStatus.LZMA_STATUS_NEEDS_MORE_INPUT) { return(res); } if (srcSizeCur == 0 && outSizeProcessed == 0) { if (status != ELzmaStatus.LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK || mUnpackSize != 0 || mPackSize != 0) { return(SZ_ERROR_DATA); } mState = Lzma2State.Control; } if (status == ELzmaStatus.LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK) { status = ELzmaStatus.LZMA_STATUS_NOT_FINISHED; } } } status = ELzmaStatus.LZMA_STATUS_FINISHED_WITH_MARK; return(SZ_OK); }
/* finishMode: It has meaning only if the decoding reaches output limit (*destLen or dicLimit). LZMA_FINISH_ANY - use smallest number of input bytes LZMA_FINISH_END - read EndOfStream marker after decoding Returns: SZ_OK status: LZMA_STATUS_FINISHED_WITH_MARK LZMA_STATUS_NOT_FINISHED LZMA_STATUS_NEEDS_MORE_INPUT SZ_ERROR_DATA - Data error */ public SRes Lzma2Dec_DecodeToDic(long dicLimit, P<byte> src, ref long srcLen, ELzmaFinishMode finishMode, out ELzmaStatus status) { long inSize = srcLen; srcLen = 0; status = ELzmaStatus.LZMA_STATUS_NOT_SPECIFIED; while (mState != Lzma2State.Finished) { long dicPos = mDecoder.mDicPos; if (mState == Lzma2State.Error) return SZ_ERROR_DATA; if (dicPos == dicLimit && finishMode == ELzmaFinishMode.LZMA_FINISH_ANY) { status = ELzmaStatus.LZMA_STATUS_NOT_FINISHED; return SZ_OK; } if (mState != Lzma2State.Data && mState != Lzma2State.DataCont) { if (srcLen == inSize) { status = ELzmaStatus.LZMA_STATUS_NEEDS_MORE_INPUT; return SZ_OK; } srcLen++; mState = Lzma2Dec_UpdateState(src[0]); src++; continue; } long destSizeCur = dicLimit - dicPos; long srcSizeCur = inSize - srcLen; ELzmaFinishMode curFinishMode = ELzmaFinishMode.LZMA_FINISH_ANY; if (mUnpackSize <= destSizeCur) { destSizeCur = mUnpackSize; curFinishMode = ELzmaFinishMode.LZMA_FINISH_END; } if (IsUncompressedState()) { if (srcLen == inSize) { status = ELzmaStatus.LZMA_STATUS_NEEDS_MORE_INPUT; return SZ_OK; } if (mState == Lzma2State.Data) { bool initDic = (mControl == LZMA2_CONTROL_COPY_RESET_DIC); if (initDic) mNeedInitProp = mNeedInitState = true; else if (mNeedInitDic) return SZ_ERROR_DATA; mNeedInitDic = false; mDecoder.LzmaDec_InitDicAndState(initDic, false); } if (srcSizeCur > destSizeCur) srcSizeCur = destSizeCur; if (srcSizeCur == 0) return SZ_ERROR_DATA; LzmaDec_UpdateWithUncompressed(mDecoder, src, srcSizeCur); src += srcSizeCur; srcLen += srcSizeCur; mUnpackSize -= (uint)srcSizeCur; mState = (mUnpackSize == 0) ? Lzma2State.Control : Lzma2State.DataCont; } else { long outSizeProcessed; if (mState == Lzma2State.Data) { int mode = GetLzmaMode(); bool initDic = (mode == 3); bool initState = (mode > 0); if ((!initDic && mNeedInitDic) || (!initState && mNeedInitState)) return SZ_ERROR_DATA; mDecoder.LzmaDec_InitDicAndState(initDic, initState); mNeedInitDic = false; mNeedInitState = false; mState = Lzma2State.DataCont; } if (srcSizeCur > mPackSize) srcSizeCur = mPackSize; SRes res = mDecoder.LzmaDec_DecodeToDic(dicPos + destSizeCur, src, ref srcSizeCur, curFinishMode, out status); src += srcSizeCur; srcLen += srcSizeCur; mPackSize -= (uint)srcSizeCur; outSizeProcessed = mDecoder.mDicPos - dicPos; mUnpackSize -= (uint)outSizeProcessed; if (res != SZ_OK) return res; if (status == ELzmaStatus.LZMA_STATUS_NEEDS_MORE_INPUT) return res; if (srcSizeCur == 0 && outSizeProcessed == 0) { if (status != ELzmaStatus.LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK || mUnpackSize != 0 || mPackSize != 0) return SZ_ERROR_DATA; mState = Lzma2State.Control; } if (status == ELzmaStatus.LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK) status = ELzmaStatus.LZMA_STATUS_NOT_FINISHED; } } status = ELzmaStatus.LZMA_STATUS_FINISHED_WITH_MARK; return SZ_OK; }
public SRes Lzma2Dec_DecodeToBuf(P<byte> dest, ref long destLen, P<byte> src, ref long srcLen, ELzmaFinishMode finishMode, out ELzmaStatus status) { long outSize = destLen; long inSize = srcLen; srcLen = 0; destLen = 0; for (;;) { if (mDecoder.mDicPos == mDecoder.mDicBufSize) mDecoder.mDicPos = 0; long outSizeCur; ELzmaFinishMode curFinishMode; long dicPos = mDecoder.mDicPos; if (outSize > mDecoder.mDicBufSize - dicPos) { outSizeCur = mDecoder.mDicBufSize; curFinishMode = ELzmaFinishMode.LZMA_FINISH_ANY; } else { outSizeCur = dicPos + outSize; curFinishMode = finishMode; } long srcSizeCur = inSize; SRes res = Lzma2Dec_DecodeToDic(outSizeCur, src, ref srcSizeCur, curFinishMode, out status); src += srcSizeCur; inSize -= srcSizeCur; srcLen += srcSizeCur; outSizeCur = mDecoder.mDicPos - dicPos; CUtils.memcpy(dest, mDecoder.mDic + dicPos, outSizeCur); dest += outSizeCur; outSize -= outSizeCur; destLen += outSizeCur; if (res != 0) return res; if (outSizeCur == 0 || outSize == 0) return SZ_OK; } }
/* ---------- Dictionary Interface ---------- */ /* You can use it, if you want to eliminate the overhead for data copying from dictionary to some other external buffer. You must work with CLzmaDec variables directly in this interface. STEPS: LzmaDec_Constr() LzmaDec_Allocate() for (each new stream) { LzmaDec_Init() while (it needs more decompression) { LzmaDec_DecodeToDic() use data from CLzmaDec::dic and update CLzmaDec::dicPos } } LzmaDec_Free() */ /* LzmaDec_DecodeToDic The decoding to internal dictionary buffer (CLzmaDec::dic). You must manually update CLzmaDec::dicPos, if it reaches CLzmaDec::dicBufSize !!! finishMode: It has meaning only if the decoding reaches output limit (dicLimit). LZMA_FINISH_ANY - Decode just dicLimit bytes. LZMA_FINISH_END - Stream must be finished after dicLimit. Returns: SZ_OK status: LZMA_STATUS_FINISHED_WITH_MARK LZMA_STATUS_NOT_FINISHED LZMA_STATUS_NEEDS_MORE_INPUT LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK SZ_ERROR_DATA - Data error */ public SRes LzmaDec_DecodeToDic(long dicLimit, P<byte> src, ref long srcLen, ELzmaFinishMode finishMode, out ELzmaStatus status) { long inSize = srcLen; srcLen = 0; LzmaDec_WriteRem(dicLimit); status = ELzmaStatus.LZMA_STATUS_NOT_SPECIFIED; while (mRemainLen != kMatchSpecLenStart) { if (mNeedFlush) { while (inSize > 0 && mTempBufSize < RC_INIT_SIZE) { mTempBuf[mTempBufSize] = src[0]; mTempBufSize++; src++; srcLen++; inSize--; } if (mTempBufSize < RC_INIT_SIZE) { status = ELzmaStatus.LZMA_STATUS_NEEDS_MORE_INPUT; return SZ_OK; } if (mTempBuf[0] != 0) return SZ_ERROR_DATA; LzmaDec_InitRc(mTempBuf); mTempBufSize = 0; } bool checkEndMarkNow = false; if (mDicPos >= dicLimit) { if (mRemainLen == 0 && mCode == 0) { status = ELzmaStatus.LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK; return SZ_OK; } if (finishMode == ELzmaFinishMode.LZMA_FINISH_ANY) { status = ELzmaStatus.LZMA_STATUS_NOT_FINISHED; return SZ_OK; } if (mRemainLen != 0) { status = ELzmaStatus.LZMA_STATUS_NOT_FINISHED; return SZ_ERROR_DATA; } checkEndMarkNow = true; } if (mNeedInitState) LzmaDec_InitStateReal(); if (mTempBufSize == 0) { P<byte> bufLimit; if (inSize < LZMA_REQUIRED_INPUT_MAX || checkEndMarkNow) { ELzmaDummy dummyRes = LzmaDec_TryDummy(src, inSize); if (dummyRes == ELzmaDummy.DUMMY_ERROR) { CUtils.memcpy(mTempBuf, src, inSize); mTempBufSize = (uint)inSize; srcLen += inSize; status = ELzmaStatus.LZMA_STATUS_NEEDS_MORE_INPUT; return SZ_OK; } if (checkEndMarkNow && dummyRes != ELzmaDummy.DUMMY_MATCH) { status = ELzmaStatus.LZMA_STATUS_NOT_FINISHED; return SZ_ERROR_DATA; } bufLimit = src; } else { bufLimit = src + inSize - LZMA_REQUIRED_INPUT_MAX; } mBuf = src; if (LzmaDec_DecodeReal2(dicLimit, bufLimit) != 0) return SZ_ERROR_DATA; long processed = mBuf - src; srcLen += processed; src += processed; inSize -= processed; } else { uint rem = mTempBufSize; uint lookAhead = 0; while (rem < LZMA_REQUIRED_INPUT_MAX && lookAhead < inSize) mTempBuf[rem++] = src[lookAhead++]; mTempBufSize = rem; if (rem < LZMA_REQUIRED_INPUT_MAX || checkEndMarkNow) { ELzmaDummy dummyRes = LzmaDec_TryDummy(mTempBuf, rem); if (dummyRes == ELzmaDummy.DUMMY_ERROR) { srcLen += lookAhead; status = ELzmaStatus.LZMA_STATUS_NEEDS_MORE_INPUT; return SZ_OK; } if (checkEndMarkNow && dummyRes != ELzmaDummy.DUMMY_MATCH) { status = ELzmaStatus.LZMA_STATUS_NOT_FINISHED; return SZ_ERROR_DATA; } } mBuf = mTempBuf; if (LzmaDec_DecodeReal2(dicLimit, mBuf) != 0) return SZ_ERROR_DATA; lookAhead -= rem - (uint)(mBuf - mTempBuf); srcLen += lookAhead; src += lookAhead; inSize -= lookAhead; mTempBufSize = 0; } } if (mCode != 0) return SZ_ERROR_DATA; status = ELzmaStatus.LZMA_STATUS_FINISHED_WITH_MARK; return SZ_OK; }