static SRes SzDecodeLzma2(CSzCoderInfo *coder, UInt64 inSize, ILookInStream *inStream, Byte *outBuffer, SizeT outSize, ISzAlloc *allocMain) { CLzma2Dec state; SRes res = SZ_OK; Lzma2Dec_Construct(&state); if (coder->Props.size != 1) return SZ_ERROR_DATA; RINOK(Lzma2Dec_AllocateProbs(&state, coder->Props.data[0], allocMain)); state.decoder.dic = outBuffer; state.decoder.dicBufSize = outSize; Lzma2Dec_Init(&state); for (;;) { Byte *inBuf = NULL; size_t lookahead = (1 << 18); if (lookahead > inSize) lookahead = (size_t)inSize; res = inStream->Look((void *)inStream, (const void **)&inBuf, &lookahead); if (res != SZ_OK) break; { SizeT inProcessed = (SizeT)lookahead, dicPos = state.decoder.dicPos; ELzmaStatus status; res = Lzma2Dec_DecodeToDic(&state, outSize, inBuf, &inProcessed, LZMA_FINISH_END, &status); lookahead -= inProcessed; inSize -= inProcessed; if (res != SZ_OK) break; if (state.decoder.dicPos == state.decoder.dicBufSize || (inProcessed == 0 && dicPos == state.decoder.dicPos)) { if (state.decoder.dicBufSize != outSize || lookahead != 0 || (status != LZMA_STATUS_FINISHED_WITH_MARK)) res = SZ_ERROR_DATA; break; } res = inStream->Skip((void *)inStream, inProcessed); if (res != SZ_OK) break; } } Lzma2Dec_FreeProbs(&state, allocMain); return res; }
SRes Lzma2Decode(Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen, Byte prop, ELzmaFinishMode finishMode, ELzmaStatus *status, ISzAllocPtr alloc) { CLzma2Dec p; SRes res; SizeT outSize = *destLen, inSize = *srcLen; *destLen = *srcLen = 0; *status = LZMA_STATUS_NOT_SPECIFIED; Lzma2Dec_Construct(&p); RINOK(Lzma2Dec_AllocateProbs(&p, prop, alloc)); p.decoder.dic = dest; p.decoder.dicBufSize = outSize; Lzma2Dec_Init(&p); *srcLen = inSize; res = Lzma2Dec_DecodeToDic(&p, outSize, src, srcLen, finishMode, status); *destLen = p.decoder.dicPos; if (res == SZ_OK && *status == LZMA_STATUS_NEEDS_MORE_INPUT) res = SZ_ERROR_INPUT_EOF; Lzma2Dec_FreeProbs(&p, alloc); return res; }