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); Lzma2Dec_Init(&decoder); // TKA: Bugfix *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; }
// TODO: Remove this ASAP. Rewrite the decompression routines to allow easy decompression of multiple patch file versions. To future me: Consider using a C++ class for decompression. bool ZPatcher::FileDecompress_Version_1(CLzma2Dec* decoder, FILE* sourceFile, FILE* destFile) { ELzmaStatus status; const SizeT buffer_size = 1 << 16; Byte sourceBuffer[buffer_size]; Byte destBuffer[buffer_size]; SizeT sourceLen = 0; SizeT destLen = buffer_size; int64_t sourceFilePos = ftell64(sourceFile); // We must reinitialize every time we want a decode a new file. Lzma2Dec_Init(decoder); while (true) { sourceLen = fread(sourceBuffer, 1, buffer_size, sourceFile); SRes res = Lzma2Dec_DecodeToBuf(decoder, destBuffer, &destLen, sourceBuffer, &sourceLen, LZMA_FINISH_ANY, &status); assert(res == SZ_OK); fwrite(destBuffer, 1, destLen, destFile); sourceFilePos += sourceLen; res = fseek64(sourceFile, sourceFilePos, SEEK_SET); assert(res == 0); if (res == SZ_OK && status == LZMA_STATUS_FINISHED_WITH_MARK) break; } return true; }
void UnCompressWithLZMA2(std::vector<unsigned char> &outBuf, const std::vector<unsigned char> &inBuf) { CLzma2Dec dec; Lzma2Dec_Construct(&dec); UInt64 unpackSize = 0; SRes res = Lzma2Dec_Allocate(&dec, inBuf[0], &g_Alloc); assert(res == SZ_OK); Lzma2Dec_Init(&dec); for (int i = 0; i < 8; i++) unpackSize += (UInt64)inBuf[1+i] << (i * 8); outBuf.resize(unpackSize); unsigned outPos = 0, inPos = 9; ELzmaStatus status; const unsigned BUF_SIZE = 10240; while (outPos < outBuf.size()) { SizeT destLen = min(BUF_SIZE, outBuf.size() - outPos); SizeT srcLen = min(BUF_SIZE, inBuf.size() - inPos); res = Lzma2Dec_DecodeToBuf(&dec, &outBuf[outPos], &destLen, &inBuf[inPos], &srcLen, (outPos + destLen == outBuf.size()) ? LZMA_FINISH_END : LZMA_FINISH_ANY, &status); unsigned int outbufsize = outBuf.size(); assert(res == SZ_OK); inPos += srcLen; outPos += destLen; if (status == LZMA_STATUS_FINISHED_WITH_MARK) { break; } } Lzma2Dec_Free(&dec, &g_Alloc); outBuf.resize(outPos); FILE *fout = fopen("data22.dc", "wb+"); fwrite(&outBuf[0], 1, outBuf.size(), fout); fclose(fout); }
STDMETHODIMP CDecoder::SetOutStreamSize(const UInt64 *outSize) { _outSizeDefined = (outSize != NULL); if (_outSizeDefined) _outSize = *outSize; Lzma2Dec_Init(&_state); _inPos = _inSize = 0; _inSizeProcessed = _outSizeProcessed = 0; return S_OK; }
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; }