void UncompressInc( std::vector<unsigned char> &outBuf, const std::vector<unsigned char> &inBuf) { CLzmaDec dec; UInt64 unpackSize = 0; for (int i = 0; i < 8; i++) unpackSize += (UInt64)inBuf[5 + i] << (i * 8); LzmaDec_Construct(&dec); SRes res = LzmaDec_Allocate(&dec, &inBuf[0], LZMA_PROPS_SIZE, &SzAllocForLzma); assert(res == SZ_OK); LzmaDec_Init(&dec); //printf("uint64 resLen : %" PRIu64 "\n", unpackSize); //print uint64 outBuf.resize(unpackSize); unsigned outPos = 0, inPos = LZMA_PROPS_SIZE; ELzmaStatus status; const unsigned BUF_SIZE = 10240; while (outPos < outBuf.size()) { unsigned destLen = min(BUF_SIZE, outBuf.size() - outPos); unsigned srcLen = min(BUF_SIZE, inBuf.size() - 8 - inPos); res = LzmaDec_DecodeToBuf(&dec, &outBuf[outPos], &destLen, &inBuf[inPos+8], &srcLen, (outPos + destLen == outBuf.size()) ? LZMA_FINISH_END : LZMA_FINISH_ANY, &status); assert(res == SZ_OK); inPos += srcLen; outPos += destLen; if (status == LZMA_STATUS_FINISHED_WITH_MARK) break; } LzmaDec_Free(&dec, &g_Alloc); outBuf.resize(outPos); FILE *fout = fopen("data33.dc", "wb+"); fwrite(&outBuf[0], 1, outBuf.size(), fout); fclose(fout); }
int cli_LzmaDecode(struct CLI_LZMA *L) { SRes res; SizeT outbytes, inbytes; ELzmaStatus status; ELzmaFinishMode finish; if(!L->freeme) return cli_LzmaInit(L, 0); inbytes = L->avail_in; if(~L->usize && L->avail_out > L->usize) { outbytes = L->usize; finish = LZMA_FINISH_END; } else { outbytes = L->avail_out; finish = LZMA_FINISH_ANY; } res = LzmaDec_DecodeToBuf(&L->state, L->next_out, &outbytes, L->next_in, &inbytes, finish, &status); L->avail_in -= inbytes; L->next_in += inbytes; L->avail_out -= outbytes; L->next_out += outbytes; if(~L->usize) L->usize -= outbytes; if(res != SZ_OK) return LZMA_RESULT_DATA_ERROR; if(!L->usize || status == LZMA_STATUS_FINISHED_WITH_MARK) return LZMA_STREAM_END; return LZMA_RESULT_OK; }
void* lzma_decode(struct lzma_dec_state *state, void *src, size_t src_len, size_t *dest_len) { ELzmaStatus status; size_t current_size = 4096; void *target = malloc(current_size); *dest_len = 0; int done = 0; size_t pos_in = 0; while (!done) { size_t remain_out = current_size - *dest_len; size_t remain_in = src_len - pos_in; LzmaDec_DecodeToBuf( &state->decoder, target + *dest_len, &remain_out, src + pos_in , &remain_in, LZMA_FINISH_ANY, &status); pos_in += remain_in; *dest_len += remain_out; switch (status) { case LZMA_STATUS_NOT_FINISHED: current_size *= 2; target = realloc(target, current_size); break; default: done = 1; } } return target; }
inline size_t DecompressPortion() { size_t bufLen = sizeof(UncompressedBuf_); size_t availLen = InSize_ - InPos_; ELzmaStatus status; Check(LzmaDec_DecodeToBuf(&H_, (Byte*)UncompressedBuf_, &bufLen, (Byte*)In_ + InPos_, &availLen, LZMA_FINISH_ANY, &status)); InPos_ += availLen; return bufLen; }
static SRes Decode2(CLzmaDec *state, ISeqOutStream *outStream, ISeqInStream *inStream, UInt64 unpackSize) { int thereIsSize = (unpackSize != (UInt64)(Int64)-1); Byte inBuf[IN_BUF_SIZE]; Byte outBuf[OUT_BUF_SIZE]; size_t inPos = 0, inSize = 0, outPos = 0; LzmaDec_Init(state); for (;;) { if (inPos == inSize) { inSize = IN_BUF_SIZE; RINOK(inStream->Read(inStream, inBuf, &inSize)); inPos = 0; } { SRes res; SizeT inProcessed = inSize - inPos; SizeT outProcessed = OUT_BUF_SIZE - outPos; ELzmaFinishMode finishMode = LZMA_FINISH_ANY; ELzmaStatus status; if (thereIsSize && outProcessed > unpackSize) { outProcessed = (SizeT)unpackSize; finishMode = LZMA_FINISH_END; } res = LzmaDec_DecodeToBuf(state, outBuf + outPos, &outProcessed, inBuf + inPos, &inProcessed, finishMode, &status); inPos += inProcessed; outPos += outProcessed; unpackSize -= outProcessed; if (outStream) if (outStream->Write(outStream, outBuf, outPos) != outPos) return SZ_ERROR_WRITE; outPos = 0; if (res != SZ_OK || (thereIsSize && unpackSize == 0)) return res; if (inProcessed == 0 && outProcessed == 0) { if (thereIsSize || status != LZMA_STATUS_FINISHED_WITH_MARK) return SZ_ERROR_DATA; return res; } } } }
long FileReaderLZMA::Read (void *buffer, long len) { int err; Byte *next_out = (Byte *)buffer; do { ELzmaFinishMode finish_mode = LZMA_FINISH_ANY; ELzmaStatus status; size_t out_processed = len; size_t in_processed = InSize; err = LzmaDec_DecodeToBuf(&Streamp->Stream, next_out, &out_processed, InBuff + InPos, &in_processed, finish_mode, &status); InPos += in_processed; InSize -= in_processed; next_out += out_processed; len = (long)(len - out_processed); if (err != SZ_OK) { I_Error ("Corrupt LZMA stream"); } if (in_processed == 0 && out_processed == 0) { if (status != LZMA_STATUS_FINISHED_WITH_MARK) { I_Error ("Corrupt LZMA stream"); } } if (InSize == 0 && !SawEOF) { FillBuffer (); } } while (err == SZ_OK && len != 0); if (err != Z_OK && err != Z_STREAM_END) { I_Error ("Corrupt LZMA stream"); } if (len != 0) { I_Error ("Ran out of data in LZMA stream"); } return (long)(next_out - (Byte *)buffer); }
STDMETHODIMP CDecoder::Read(void *data, UInt32 size, UInt32 *processedSize) { if (processedSize) *processedSize = 0; do { if (_inPos == _inSize) { _inPos = _inSize = 0; RINOK(_inStream->Read(_inBuf, kInBufSize, &_inSize)); } { SizeT inProcessed = _inSize - _inPos; if (_outSizeDefined) { const UInt64 rem = _outSize - _outSizeProcessed; if (rem < size) size = (UInt32)rem; } SizeT outProcessed = size; ELzmaStatus status; SRes res = LzmaDec_DecodeToBuf(&_state, (Byte *)data, &outProcessed, _inBuf + _inPos, &inProcessed, LZMA_FINISH_ANY, &status); _inPos += (UInt32)inProcessed; _inSizeProcessed += inProcessed; _outSizeProcessed += outProcessed; size -= (UInt32)outProcessed; data = (Byte *)data + outProcessed; if (processedSize) *processedSize += (UInt32)outProcessed; RINOK(SResToHRESULT(res)); if (inProcessed == 0 && outProcessed == 0) return S_OK; } } while (size != 0); return S_OK; }
int _tmain(int argc, _TCHAR* argv[]) { HANDLE hFileIn = ::CreateFile(_T("C:\\Users\\Christoph\\Desktop\\S.csv.lzma"), GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); HANDLE hFileOut = ::CreateFile(_T("C:\\Users\\Christoph\\Desktop\\S.csv.decd"), GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); BYTE header[LZMA_PROPS_SIZE + 8]; DWORD dwBytesRead = 0; DWORD dwBytesWritten = 0; ::ReadFile(hFileIn, header, sizeof(header), &dwBytesRead, NULL); ELzmaStatus status; CLzmaDec state; LzmaDec_Construct(&state); LzmaDec_Allocate(&state, header, LZMA_PROPS_SIZE, &g_Alloc); LzmaDec_Init(&state); __int64 nSize = *reinterpret_cast<__int64*>(header + LZMA_PROPS_SIZE); _tprintf(_T("Extracted size: %d\n"), nSize); BYTE *pDataIn = new BYTE[BUFFER_SIZE]; BYTE *pDataOut = new BYTE[BUFFER_SIZE]; size_t nTotalSize = (size_t)nSize; size_t nInSize = BUFFER_SIZE, nInPos = 0; size_t nOutSize = BUFFER_SIZE; while (nTotalSize) { if (!::ReadFile(hFileIn, pDataIn, BUFFER_SIZE, &dwBytesRead, NULL)) break; if (dwBytesRead == 0) break; nInSize = dwBytesRead; nInPos = 0; _tprintf(_T(".")); while (nInPos < nInSize) { size_t nInProcessed = nInSize - nInPos; size_t nOutProcessed = BUFFER_SIZE; LzmaDec_DecodeToBuf(&state, pDataOut, &nOutProcessed, pDataIn + nInPos, &nInProcessed, (nOutProcessed > nTotalSize)? LZMA_FINISH_END : LZMA_FINISH_ANY, &status); ::WriteFile(hFileOut, pDataOut, nOutProcessed, &dwBytesRead, NULL); nInPos += nInProcessed; nTotalSize -= nOutProcessed; if (nInProcessed == 0 && nOutProcessed == 0) { nInPos = nInSize = 0; nTotalSize = 0; } } } delete[] pDataOut; delete[] pDataIn; LzmaDec_Free(&state, &g_Alloc); ::CloseHandle(hFileOut); ::CloseHandle(hFileIn); #ifdef _DEBUG _tsystem(_T("pause")); #endif return 0; }
int BCMINITFN(_nvram_read)(void *buf, int idx) { uint32 *src, *dst; uint i; if (!nvram_header) return -19; /* -ENODEV */ #if defined(_CFE_) && defined(BCM_DEVINFO) if ((!devinfo_nvram_header) && (idx == 1)) { return -19; /* -ENODEV */ } src = idx == 0 ? (uint32 *) nvram_header : (uint32 *) devinfo_nvram_nvh; #else src = (uint32 *) nvram_header; #endif /* _CFE_ && BCM_DEVINFO */ dst = (uint32 *) buf; for (i = 0; i < sizeof(struct nvram_header); i += 4) *dst++ = *src++; /* Since we know what the first 3 bytes of the lzma properties * should be based on what we used to compress, check them * to see if we need to decompress (uncompressed this would show up a * a single [ and then the end of nvram marker so its invalid in an * uncompressed nvram block */ if ((((unsigned char *)src)[0] == 0x5d) && (((unsigned char *)src)[1] == 0) && (((unsigned char *)src)[2] == 0)) { unsigned int dstlen = nvram_header->len; unsigned int srclen = MAX_NVRAM_SPACE-LZMA_PROPS_SIZE-NVRAM_HEADER_SIZE; unsigned char *cp = (unsigned char *)src; CLzmaDec state; SRes res; ELzmaStatus status; LzmaDec_Construct(&state); res = LzmaDec_Allocate(&state, cp, LZMA_PROPS_SIZE, &g_Alloc); if (res != SZ_OK) { printf("Error Initializing LZMA Library\n"); return -19; } LzmaDec_Init(&state); res = LzmaDec_DecodeToBuf(&state, (unsigned char *)dst, &dstlen, &cp[LZMA_PROPS_SIZE], &srclen, LZMA_FINISH_ANY, &status); LzmaDec_Free(&state, &g_Alloc); if (res != SZ_OK) { printf("Error Decompressing eNVRAM\n"); return -19; } } else { for (; i < nvram_header->len && i < MAX_NVRAM_SPACE; i += 4) *dst++ = ltoh32(*src++); } return 0; }
PakEntry Pak::read(uint32_t tag) const { int entryIndex = findEntry(tag); if(entryIndex < 0) { return PakEntry(NULL, 0, false); } const Header *header = reinterpret_cast<const Header*>(m_pakData); const Entry *entry = reinterpret_cast<const Entry*>(header + 1) + entryIndex; size_t entrySize = (entry+1)->offset - entry->offset; if(entry->offset>m_pakDataSize || entrySize>=4*1024*1024 || entry->offset+entrySize>m_pakDataSize) { ERROR("Pak::findEntry: invalid entry offset/size (tag=0x%08x index=%u offset=%u size=%u)", tag, entryIndex, entry->offset, entrySize); return PakEntry(NULL, 0, false); } const uint8_t *entryData = cast<uint8_t>(m_pakData, entry->offset); const LzmaHeader *lzmaHeader = cast<LzmaHeader>(entryData, 0); if(memcmp(lzmaHeader->magic, "lzma", 4) != 0) { DEBUG("Pak::findEntry: found uncompressed 0x%08x at %u size %zu", tag, entry->offset, entrySize); return PakEntry(entryData, entrySize, false); } if(lzmaHeader->decompressedSize<entrySize/2 || lzmaHeader->decompressedSize>=8*1024*1024) { ERROR("Pak::findEntry: invalid uncompressed size (tag=0x%08x size=%u decompressedsize=%u)", tag, entrySize, lzmaHeader->decompressedSize); return PakEntry(NULL, 0, false); } CLzmaDec dec; LzmaDec_Construct(&dec); LzmaDec_Init(&dec); SRes res = LzmaDec_Allocate(&dec, lzmaHeader->props, LZMA_PROPS_SIZE, &lzmaAllocFuncs); if(res != SZ_OK) { ERROR("Pak::findEntry: LzmaDec_Allocate failed: %d (tag=0x%08x)", res, tag); return PakEntry(NULL, 0, false); } void *decdata = malloc(lzmaHeader->decompressedSize); if(decdata == NULL) { ERROR("Pak::findEntry: LzmaDec_Allocate failed to allocate %u bytes", lzmaHeader->decompressedSize); LzmaDec_Free(&dec, &lzmaAllocFuncs); return PakEntry(NULL, 0, false); } size_t destSize = lzmaHeader->decompressedSize; size_t srcSize = entrySize - sizeof(lzmaHeader); ELzmaStatus status; res = LzmaDec_DecodeToBuf(&dec, (Byte*)decdata, &destSize, lzmaHeader->data, &srcSize, LZMA_FINISH_END, &status); if(res != SZ_OK) { ERROR("Pak::findEntry: LzmaDec_DecodeToBuf failed: %d (tag=0x%08x)", res, tag); LzmaDec_Free(&dec, &lzmaAllocFuncs); free(decdata); return PakEntry(NULL, 0, false); } if(!(status==LZMA_STATUS_FINISHED_WITH_MARK || (status==LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK && destSize!=lzmaHeader->decompressedSize))) { ERROR("Pak::findEntry: LzmaDec_DecodeToBuf ended with unexpected status: %d (tag=0x%08x)", status, tag); LzmaDec_Free(&dec, &lzmaAllocFuncs); free(decdata); return PakEntry(NULL, 0, false); } if(destSize != lzmaHeader->decompressedSize) { ERROR("Pak::findEntry: LzmaDec_DecodeToBuf failed to decompress whole buffer: %zu!=%u (tag=0x%08x)", destSize, lzmaHeader->decompressedSize, tag); LzmaDec_Free(&dec, &lzmaAllocFuncs); free(decdata); return PakEntry(NULL, 0, false); } LzmaDec_Free(&dec, &lzmaAllocFuncs); return PakEntry(decdata, lzmaHeader->decompressedSize, true); }
static int Decode(FILE *inFile, FILE *outFile, char *rs) { UInt64 unpackSize; int thereIsSize; /* = 1, if there is uncompressed size in headers */ int i; int res = 0; CLzmaDec state; /* header: 5 bytes of LZMA properties and 8 bytes of uncompressed size */ unsigned char header[LZMA_PROPS_SIZE + 8]; /* Read and parse header */ if (!MyReadFileAndCheck(inFile, header, sizeof(header))) return PrintError(rs, kCantReadMessage); unpackSize = 0; thereIsSize = 0; for (i = 0; i < 8; i++) { unsigned char b = header[LZMA_PROPS_SIZE + i]; if (b != 0xFF) thereIsSize = 1; unpackSize += (UInt64)b << (i * 8); } LzmaDec_Construct(&state); res = LzmaDec_Allocate(&state, header, LZMA_PROPS_SIZE, &g_Alloc); if (res != SZ_OK) return res; { Byte inBuf[IN_BUF_SIZE]; Byte outBuf[OUT_BUF_SIZE]; size_t inPos = 0, inSize = 0, outPos = 0; LzmaDec_Init(&state); for (;;) { if (inPos == inSize) { inSize = MyReadFile(inFile, inBuf, IN_BUF_SIZE); inPos = 0; } { SizeT inProcessed = inSize - inPos; SizeT outProcessed = OUT_BUF_SIZE - outPos; ELzmaFinishMode finishMode = LZMA_FINISH_ANY; ELzmaStatus status; if (thereIsSize && outProcessed > unpackSize) { outProcessed = (SizeT)unpackSize; finishMode = LZMA_FINISH_END; } res = LzmaDec_DecodeToBuf(&state, outBuf + outPos, &outProcessed, inBuf + inPos, &inProcessed, finishMode, &status); inPos += (UInt32)inProcessed; outPos += outProcessed; unpackSize -= outProcessed; if (outFile != 0) MyWriteFile(outFile, outBuf, outPos); outPos = 0; if (res != SZ_OK || thereIsSize && unpackSize == 0) break; if (inProcessed == 0 && outProcessed == 0) { if (thereIsSize || status != LZMA_STATUS_FINISHED_WITH_MARK) res = SZ_ERROR_DATA; break; } } } } LzmaDec_Free(&state, &g_Alloc); return res; }
static int lzmafs_fileop_read(void *ref, uint8_t *buf, int len) { lzmafs_file_t *file = (lzmafs_file_t *) ref; int res = 0; int err; int amtcopy; int ttlcopy = 0; unsigned int in_processed; ELzmaFinishMode finishMode = LZMA_FINISH_ANY; ELzmaStatus status; if (len == 0) return 0; while (len) { /* Figure the amount to copy. This is the min of what we have left to do and what is available. */ amtcopy = len; if (amtcopy > file->lzmafs_outlen) { amtcopy = file->lzmafs_outlen; } /* Copy the data. */ if (buf) { memcpy(buf, file->lzmafs_outptr, amtcopy); buf += amtcopy; } /* Update the pointers. */ file->lzmafs_outptr += amtcopy; file->lzmafs_outlen -= amtcopy; len -= amtcopy; ttlcopy += amtcopy; file->lzmafs_unpackSize -= amtcopy; if (file->lzmafs_unpackSize == 0) { file->lzmafs_eofseen = 1; } /* If we've eaten all of the output, reset and call decode again. */ if (file->lzmafs_outlen == 0) { /* If no input data to decompress, get some more if we can. */ if (file->lzmafs_eofseen) break; if (file->lzmafs_inlen == 0) { file->lzmafs_inlen = BDREAD(file->lzmafs_fsctx->lzmafsctx_subops, file->lzmafs_subfile, file->lzmafs_inbuf, LZMAFS_INBUFSIZE); /* If at EOF or error, get out. */ if (file->lzmafs_inlen <= 0) break; file->lzmafs_inptr = file->lzmafs_inbuf; } in_processed = file->lzmafs_inlen; file->lzmafs_outlen = LZMAFS_OUTBUFSIZE; file->lzmafs_outptr = file->lzmafs_outbuf; if (file->lzmafs_outlen > file->lzmafs_unpackSize) { file->lzmafs_outlen = (SizeT)file->lzmafs_unpackSize; finishMode = LZMA_FINISH_END; } /* decompress the input data. */ err = LzmaDec_DecodeToBuf(file->lzmafs_state, file->lzmafs_outbuf, (SizeT *)&file->lzmafs_outlen, file->lzmafs_inptr, &in_processed, finishMode, &status); file->lzmafs_inptr += in_processed; file->lzmafs_inlen -= in_processed; if (err != SZ_OK) { res = CFE_ERR; break; } } } file->lzmafs_fileoffset += ttlcopy; return (res < 0) ? res : ttlcopy; }
static PyObject * pylzma_decomp_decompress(CDecompressionObject *self, PyObject *args) { PyObject *result=NULL; unsigned char *data; Byte *next_in, *next_out; int length, res, bufsize=BLOCK_SIZE; SizeT avail_in; SizeT inProcessed, outProcessed; ELzmaStatus status; if (!PyArg_ParseTuple(args, "s#|i", &data, &length, &bufsize)){ return NULL; } if (bufsize <= 0) { PyErr_SetString(PyExc_ValueError, "bufsize must be greater than zero"); return NULL; } if (self->unconsumed_length > 0) { self->unconsumed_tail = (unsigned char *) realloc(self->unconsumed_tail, self->unconsumed_length + length); next_in = (unsigned char *) self->unconsumed_tail; memcpy(next_in + self->unconsumed_length, data, length); } else { next_in = data; } if (self->need_properties) { if ((self->unconsumed_length + length) < LZMA_PROPS_SIZE) { // we need enough bytes to read the properties self->unconsumed_tail = (unsigned char *) realloc(self->unconsumed_tail, self->unconsumed_length + length); if (self->unconsumed_tail == NULL) { PyErr_NoMemory(); return NULL; } memcpy(self->unconsumed_tail + self->unconsumed_length, data, length); self->unconsumed_length += length; return PyString_FromString(""); } self->unconsumed_length += length; res = LzmaDec_Allocate(&self->state, next_in, LZMA_PROPS_SIZE, &allocator); if (res != SZ_OK) { PyErr_SetString(PyExc_TypeError, "Incorrect stream properties"); return NULL; } next_in += LZMA_PROPS_SIZE; self->unconsumed_length -= LZMA_PROPS_SIZE; if (self->unconsumed_length > 0) { if (self->unconsumed_tail == NULL) { // No remaining data yet self->unconsumed_tail = (unsigned char *) malloc(self->unconsumed_length); if (self->unconsumed_tail == NULL) { PyErr_NoMemory(); return NULL; } memcpy(self->unconsumed_tail, next_in, self->unconsumed_length); next_in = self->unconsumed_tail; } else { // Skip properties in remaining data memmove(self->unconsumed_tail, self->unconsumed_tail+LZMA_PROPS_SIZE, self->unconsumed_length); self->unconsumed_tail = next_in = (unsigned char *) realloc(self->unconsumed_tail, self->unconsumed_length); if (self->unconsumed_tail == NULL) { PyErr_NoMemory(); return NULL; } } } else { FREE_AND_NULL(self->unconsumed_tail); } self->need_properties = 0; LzmaDec_Init(&self->state); } else { self->unconsumed_length += length; } avail_in = self->unconsumed_length; if (avail_in == 0) { // no more bytes to decompress return PyString_FromString(""); } result = PyString_FromStringAndSize(NULL, bufsize); if (result == NULL) { PyErr_NoMemory(); goto exit; } next_out = (unsigned char *) PyString_AS_STRING(result); Py_BEGIN_ALLOW_THREADS // Decompress until EOS marker is reached inProcessed = avail_in; outProcessed = bufsize; res = LzmaDec_DecodeToBuf(&self->state, next_out, &outProcessed, next_in, &inProcessed, LZMA_FINISH_ANY, &status); Py_END_ALLOW_THREADS self->total_out += outProcessed; next_in += inProcessed; avail_in -= inProcessed; if (res != SZ_OK) { DEC_AND_NULL(result); PyErr_SetString(PyExc_ValueError, "data error during decompression"); goto exit; } // Not all of the compressed data could be accomodated in the output buffer // of specified size. Return the unconsumed tail in an attribute. if (avail_in > 0) { if (self->unconsumed_tail == NULL) { // data are in "data" self->unconsumed_tail = (unsigned char *) malloc(avail_in); if (self->unconsumed_tail == NULL) { Py_DECREF(result); PyErr_NoMemory(); goto exit; } memcpy(self->unconsumed_tail, next_in, avail_in); } else { memmove(self->unconsumed_tail, next_in, avail_in); self->unconsumed_tail = (unsigned char *) realloc(self->unconsumed_tail, avail_in); } } else { FREE_AND_NULL(self->unconsumed_tail); } self->unconsumed_length = avail_in; _PyString_Resize(&result, outProcessed); exit: return result; }
static PyObject * pylzma_decomp_flush(CDecompressionObject *self, PyObject *args) { PyObject *result=NULL; int res; SizeT avail_out, outsize; unsigned char *tmp; SizeT inProcessed, outProcessed; ELzmaStatus status; if (self->max_length != -1) { avail_out = self->max_length - self->total_out; } else { avail_out = BLOCK_SIZE; } if (avail_out == 0) { // no more remaining data return PyString_FromString(""); } result = PyString_FromStringAndSize(NULL, avail_out); if (result == NULL) { return NULL; } tmp = (unsigned char *)PyString_AS_STRING(result); outsize = 0; while (1) { Py_BEGIN_ALLOW_THREADS if (self->unconsumed_length == 0) { // No remaining data inProcessed = 0; outProcessed = avail_out; res = LzmaDec_DecodeToBuf(&self->state, tmp, &outProcessed, (Byte *) "", &inProcessed, LZMA_FINISH_ANY, &status); } else { // Decompress remaining data inProcessed = self->unconsumed_length; outProcessed = avail_out; res = LzmaDec_DecodeToBuf(&self->state, tmp, &outProcessed, self->unconsumed_tail, &inProcessed, LZMA_FINISH_ANY, &status); self->unconsumed_length -= inProcessed; if (self->unconsumed_length > 0) memmove(self->unconsumed_tail, self->unconsumed_tail + inProcessed, self->unconsumed_length); else FREE_AND_NULL(self->unconsumed_tail); } Py_END_ALLOW_THREADS if (res != SZ_OK) { PyErr_SetString(PyExc_ValueError, "data error during decompression"); DEC_AND_NULL(result); goto exit; } if (!outProcessed && self->max_length != -1 && self->total_out < self->max_length) { PyErr_SetString(PyExc_ValueError, "data error during decompression"); DEC_AND_NULL(result); goto exit; } self->total_out += outProcessed; outsize += outProcessed; if (outProcessed < avail_out || (outProcessed == avail_out && self->max_length != -1)) { break; } if (self->max_length != -1) { PyErr_SetString(PyExc_ValueError, "not enough input data for decompression"); DEC_AND_NULL(result); goto exit; } avail_out -= outProcessed; // Output buffer is full, might be more data for decompression if (_PyString_Resize(&result, outsize+BLOCK_SIZE) != 0) { goto exit; } avail_out += BLOCK_SIZE; tmp = (unsigned char *)PyString_AS_STRING(result) + outsize; } if (outsize != PyString_GET_SIZE(result)) { _PyString_Resize(&result, outsize); } exit: return result; }
int elzma_decompress_run(elzma_decompress_handle hand, elzma_read_callback inputStream, void * inputContext, elzma_write_callback outputStream, void * outputContext, elzma_file_format format) { unsigned long long int totalRead = 0; /* total amount read from stream */ unsigned int crc32 = CRC_INIT_VAL; /* running crc32 (lzip case) */ CLzmaDec dec; unsigned int errorCode = ELZMA_E_OK; struct elzma_format_handler formatHandler; struct elzma_file_header h; struct elzma_file_footer f; /* switch between supported formats */ if (format == ELZMA_lzma) { initializeLZMAFormatHandler(&formatHandler); } else if (format == ELZMA_lzip) { CrcGenerateTable(); initializeLZIPFormatHandler(&formatHandler); } else { return ELZMA_E_BAD_PARAMS; } /* initialize footer */ f.crc32 = 0; f.uncompressedSize = 0; /* initialize decoder memory */ memset((void *) &dec, 0, sizeof(dec)); LzmaDec_Init(&dec); /* decode the header. */ { unsigned char * hdr = hand->allocStruct.Alloc(&(hand->allocStruct), formatHandler.header_size); size_t sz = formatHandler.header_size; formatHandler.init_header(&h); if (inputStream(inputContext, hdr, &sz) != 0 || sz != formatHandler.header_size) { hand->allocStruct.Free(&(hand->allocStruct), hdr); return ELZMA_E_INPUT_ERROR; } if (0 != formatHandler.parse_header(hdr, &h)) { hand->allocStruct.Free(&(hand->allocStruct), hdr); return ELZMA_E_CORRUPT_HEADER; } /* the LzmaDec_Allocate call requires 5 bytes which have * compression properties encoded in them. In the case of * lzip, the header format does not already contain what * LzmaDec_Allocate expects, so we must craft it, silly */ { unsigned char propsBuf[13]; const unsigned char * propsPtr = hdr; if (format == ELZMA_lzip) { struct elzma_format_handler lzmaHand; initializeLZMAFormatHandler(&lzmaHand); lzmaHand.serialize_header(propsBuf, &h); propsPtr = propsBuf; } /* now we're ready to allocate the decoder */ LzmaDec_Allocate(&dec, propsPtr, 5, (ISzAlloc *) &(hand->allocStruct)); } hand->allocStruct.Free(&(hand->allocStruct), hdr); } /* perform the decoding */ for (;;) { size_t dstLen = ELZMA_DECOMPRESS_OUTPUT_BUFSIZE; size_t srcLen = ELZMA_DECOMPRESS_INPUT_BUFSIZE; size_t amt = 0; size_t bufOff = 0; ELzmaStatus stat; if (0 != inputStream(inputContext, hand->inbuf, &srcLen)) { errorCode = ELZMA_E_INPUT_ERROR; goto decompressEnd; } /* handle the case where the input prematurely finishes */ if (srcLen == 0) { errorCode = ELZMA_E_INSUFFICIENT_INPUT; goto decompressEnd; } amt = srcLen; /* handle the case where a single read buffer of compressed bytes * will translate into multiple buffers of uncompressed bytes, * with this inner loop */ stat = LZMA_STATUS_NOT_SPECIFIED; while (bufOff < srcLen) { SRes r = LzmaDec_DecodeToBuf(&dec, (Byte *) hand->outbuf, &dstLen, ((Byte *) hand->inbuf + bufOff), &amt, LZMA_FINISH_ANY, &stat); /* XXX deal with result code more granularly*/ if (r != SZ_OK) { errorCode = ELZMA_E_DECOMPRESS_ERROR; goto decompressEnd; } /* write what we've read */ { size_t wt; /* if decoding lzip, update our crc32 value */ if (format == ELZMA_lzip && dstLen > 0) { crc32 = CrcUpdate(crc32, hand->outbuf, dstLen); } totalRead += dstLen; wt = outputStream(outputContext, hand->outbuf, dstLen); if (wt != dstLen) { errorCode = ELZMA_E_OUTPUT_ERROR; goto decompressEnd; } } /* do we have more data on the input buffer? */ bufOff += amt; assert( bufOff <= srcLen ); if (bufOff >= srcLen) break; amt = srcLen - bufOff; /* with lzip, we will have the footer left on the buffer! */ if (stat == LZMA_STATUS_FINISHED_WITH_MARK) { break; } } /* now check status */ if (stat == LZMA_STATUS_FINISHED_WITH_MARK) { /* read a footer if one is expected and * present */ if (formatHandler.footer_size > 0 && amt >= formatHandler.footer_size && formatHandler.parse_footer != NULL) { formatHandler.parse_footer( (unsigned char *) hand->inbuf + bufOff, &f); } break; } /* for LZMA utils, we don't always have a finished mark */ if (!h.isStreamed && totalRead >= h.uncompressedSize) { break; } } /* finish the calculated crc32 */ crc32 ^= 0xFFFFFFFF; /* if we have a footer, check that the calculated crc32 matches * the encoded crc32, and that the sizes match */ if (formatHandler.footer_size) { if (f.crc32 != crc32) { errorCode = ELZMA_E_CRC32_MISMATCH; } else if (f.uncompressedSize != totalRead) { errorCode = ELZMA_E_SIZE_MISMATCH; } } else if (!h.isStreamed) { /* if the format does not support a footer and has an uncompressed * size in the header, let's compare that with how much we actually * read */ if (h.uncompressedSize != totalRead) { errorCode = ELZMA_E_SIZE_MISMATCH; } } decompressEnd: LzmaDec_Free(&dec, (ISzAlloc *) &(hand->allocStruct)); return errorCode; }