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; }
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; }
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; }
/* should be the first function */ void entry(unsigned long icache_size, unsigned long icache_lsize, unsigned long dcache_size, unsigned long dcache_lsize, unsigned long fw_arg0, unsigned long fw_arg1, unsigned long fw_arg2, unsigned long fw_arg3) { CLzmaDec state; ISzAlloc dummy; ISeqInStream stream; ELzmaStatus status; unsigned int i; /* temp value */ unsigned int osize; /* uncompressed size */ dummy.Alloc = dummy_alloc; dummy.Free = dummy_free; stream.Read = read_bytes; /* look for trx header, 32-bit data access */ for (data = ((unsigned char *)KSEG1ADDR(BCM4710_FLASH)); ((struct trx_header *)data)->magic != TRX_MAGIC; data += 65536); /* compressed kernel is in the partition 1 */ data += ((struct trx_header *)data)->offsets[1]; offset = 0; /* read lzma stream header */ SeqInStream_Read(&stream, workspace, LZMA_PROPS_SIZE + 8); /* read the lower half of uncompressed size in the header */ osize = (workspace[LZMA_PROPS_SIZE + 0]) + (workspace[LZMA_PROPS_SIZE + 1] << 8) + (workspace[LZMA_PROPS_SIZE + 2] << 16) + (workspace[LZMA_PROPS_SIZE + 3] << 24); LzmaDec_Construct(&state); LzmaDec_AllocateProbs(&state, workspace, LZMA_PROPS_SIZE, &dummy); state.dic = (unsigned char *)LOADADDR; state.dicBufSize = osize; /* decompress kernel */ LzmaDec_Init(&state); do { i = LZMA_REQUIRED_INPUT_MAX; SeqInStream_Read(&stream, workspace, i); if (LzmaDec_DecodeToDic(&state, osize, workspace, &i, LZMA_FINISH_ANY, &status) != SZ_OK) { /* something went wrong */ return; } } while (status == LZMA_STATUS_NEEDS_MORE_INPUT); blast_dcache(dcache_size, dcache_lsize); blast_icache(icache_size, icache_lsize); /* jump to load address */ ((void (*)(unsigned long, unsigned long, unsigned long, unsigned long))LOADADDR)(fw_arg0, fw_arg1, fw_arg2, fw_arg3); }
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; }
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; }
SRes Lzma2Dec_AllocateProbs(CLzma2Dec *p, Byte prop, ISzAllocPtr alloc) { Byte props[LZMA_PROPS_SIZE]; RINOK(Lzma2Dec_GetOldProps(prop, props)); return LzmaDec_AllocateProbs(&p->decoder, props, LZMA_PROPS_SIZE, alloc); }