SRes Lzma2Decode(Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen, Byte prop, ELzmaFinishMode finishMode, ELzmaStatus *status, ISzAlloc *alloc) { CLzma2Dec decoder; SRes res; SizeT outSize = *destLen, inSize = *srcLen; Byte props[LZMA_PROPS_SIZE]; Lzma2Dec_Construct(&decoder); *destLen = *srcLen = 0; *status = LZMA_STATUS_NOT_SPECIFIED; decoder.decoder.dic = dest; decoder.decoder.dicBufSize = outSize; RINOK(Lzma2Dec_GetOldProps(prop, props)); RINOK(LzmaDec_AllocateProbs(&decoder.decoder, props, LZMA_PROPS_SIZE, alloc)); *srcLen = inSize; res = Lzma2Dec_DecodeToDic(&decoder, outSize, src, srcLen, finishMode, status); *destLen = decoder.decoder.dicPos; if (res == SZ_OK && *status == LZMA_STATUS_NEEDS_MORE_INPUT) res = SZ_ERROR_INPUT_EOF; LzmaDec_FreeProbs(&decoder.decoder, alloc); return res; }
bool LZMADecoder::TryGetResultSize(const MemoryByteData& data,size_t& outSize) const { const byte* inBuffer=data.GetData(); size_t inSize=data.GetSize(); const size_t propSize=5; ISzAlloc myAlloc; myAlloc.Alloc=LZMAAlloc; myAlloc.Free=LZMAFree; CLzmaDec p; SRes res; if (inSize < propSize) return false; LzmaDec_Construct(&p); res = LzmaDec_AllocateProbs(&p, inBuffer, propSize, &myAlloc); uint64 fileSize = 0; for (int i = 0; i < 8; i++) fileSize |= ((uint64)inBuffer[propSize + i]) << (8 * i); outSize=(size_t)fileSize; LzmaDec_FreeProbs(&p, &myAlloc); return true; }
size_t LZMADecoder::GuessResultSize(const IStream& input) const { uintp pos = input.Position(); auto buffer = input.ReadData(LZMA_PROPS_SIZE + 8); const byte* inBuffer = buffer.Data(); ISzAlloc myAlloc; myAlloc.Alloc = LZMAAlloc; myAlloc.Free = LZMAFree; CLzmaDec p; SRes res; LzmaDec_Construct(&p); res = LzmaDec_AllocateProbs(&p, inBuffer, LZMA_PROPS_SIZE, &myAlloc); uint64 fileSize = 0; for (int i = 0; i < 8; i++) fileSize |= ((uint64)inBuffer[LZMA_PROPS_SIZE + i]) << (8 * i); LzmaDec_FreeProbs(&p, &myAlloc); input.SetPosition(pos); return (size_t)fileSize; }
bool LZMADecoder::CodeTo(const MemoryByteData& data,MemoryByteData& outData) const { const byte* inBuffer=data.GetData(); size_t inSize=data.GetSize(); const size_t propSize=5; ELzmaStatus outStatus; ISzAlloc myAlloc; myAlloc.Alloc=LZMAAlloc; myAlloc.Free=LZMAFree; CLzmaDec p; SRes res; if (inSize < propSize) return false; LzmaDec_Construct(&p); res = LzmaDec_AllocateProbs(&p, inBuffer, propSize, &myAlloc); uint64 fileSize = 0; for (int i = 0; i < 8; i++) fileSize |= ((uint64)inBuffer[propSize + i]) << (8 * i); if (outData.GetSize()!=(size_t)fileSize) { LzmaDec_FreeProbs(&p, &myAlloc); return false; } else { LzmaDec_Init(&p); p.dic = outData.GetData(); p.dicBufSize = (size_t)fileSize; size_t outSize=inSize-13; res = LzmaDec_DecodeToDic(&p, (size_t)fileSize, inBuffer+13, &outSize, LZMA_FINISH_ANY, &outStatus); if (res == SZ_OK && outStatus == LZMA_STATUS_NEEDS_MORE_INPUT) res = SZ_ERROR_INPUT_EOF; LzmaDec_FreeProbs(&p, &myAlloc); return true; } }
size_t LZMADecoder::OnCode(const MemoryData& input, MemoryData& output) const { RETURN_ZERO_IF_EMPTY(input); const byte* inBuffer = input.Data(); size_t inSize = input.Size(); ELzmaStatus outStatus; ISzAlloc myAlloc; myAlloc.Alloc = LZMAAlloc; myAlloc.Free = LZMAFree; CLzmaDec p; SRes res; LzmaDec_Construct(&p); res = LzmaDec_AllocateProbs(&p, inBuffer, LZMA_PROPS_SIZE, &myAlloc); uint64 fileSize = 0; for (int i = 0; i < 8; i++) fileSize |= ((uint64)inBuffer[LZMA_PROPS_SIZE + i]) << (8 * i); if (output.Size()<(size_t)fileSize) { Log::AssertFailedFormat("output size:{} < expected size{}", output.Size(), fileSize); LzmaDec_FreeProbs(&p, &myAlloc); return 0; } LzmaDec_Init(&p); p.dic = output.MutableData(); p.dicBufSize = (size_t)fileSize; size_t outSize = inSize - 13; res = LzmaDec_DecodeToDic(&p, (size_t)fileSize, inBuffer + 13, &outSize, LZMA_FINISH_ANY, &outStatus); if (res == SZ_OK && outStatus == LZMA_STATUS_NEEDS_MORE_INPUT) res = SZ_ERROR_INPUT_EOF; LzmaDec_FreeProbs(&p, &myAlloc); return (size_t)fileSize; }
static SRes SzDecodeLzma(CSzCoderInfo *coder, CFileSize inSize, ISzInStream *inStream, Byte *outBuffer, size_t outSize, ISzAlloc *allocMain) { CLzmaDec state; int res = SZ_OK; size_t _inSize; Byte *inBuf = NULL; LzmaDec_Construct(&state); RINOK(LzmaDec_AllocateProbs(&state, coder->Props.data, (unsigned)coder->Props.size, allocMain)); state.dic = outBuffer; state.dicBufSize = outSize; LzmaDec_Init(&state); _inSize = 0; for (;;) { if (_inSize == 0) { _inSize = (1 << 18); if (_inSize > inSize) _inSize = (size_t)(inSize); res = inStream->Read((void *)inStream, (void **)&inBuf, &_inSize); if (res != SZ_OK) break; inSize -= _inSize; } { SizeT inProcessed = _inSize, dicPos = state.dicPos; ELzmaStatus status; res = LzmaDec_DecodeToDic(&state, outSize, inBuf, &inProcessed, LZMA_FINISH_END, &status); _inSize -= inProcessed; inBuf = (Byte *)inBuf + inProcessed; if (res != SZ_OK) break; if (state.dicPos == state.dicBufSize || (inProcessed == 0 && dicPos == state.dicPos)) { if (state.dicBufSize != outSize || _inSize != 0 || (status != LZMA_STATUS_FINISHED_WITH_MARK && status != LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK)) res = SZ_ERROR_DATA; break; } } } LzmaDec_FreeProbs(&state, allocMain); return res; }
static SRes SzDecodeLzma(CSzCoderInfo *coder, UInt64 inSize, ILookInStream *inStream, Byte *outBuffer, SizeT outSize, ISzAlloc *allocMain) { CLzmaDec state; SRes res = SZ_OK; LzmaDec_Construct(&state); RINOK(LzmaDec_AllocateProbs(&state, coder->Props.data, (unsigned)coder->Props.size, allocMain)); state.dic = outBuffer; state.dicBufSize = outSize; LzmaDec_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.dicPos; ELzmaStatus status; res = LzmaDec_DecodeToDic(&state, outSize, inBuf, &inProcessed, LZMA_FINISH_END, &status); lookahead -= inProcessed; inSize -= inProcessed; if (res != SZ_OK) break; if (state.dicPos == state.dicBufSize || (inProcessed == 0 && dicPos == state.dicPos)) { if (state.dicBufSize != outSize || lookahead != 0 || (status != LZMA_STATUS_FINISHED_WITH_MARK && status != LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK)) res = SZ_ERROR_DATA; break; } res = inStream->Skip((void *)inStream, inProcessed); if (res != SZ_OK) break; } } LzmaDec_FreeProbs(&state, allocMain); return res; }