SRes Lzma86_Decode(Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen) { SRes res; int useFilter; SizeT inSizePure; ELzmaStatus status; if (*srcLen < LZMA86_HEADER_SIZE) return SZ_ERROR_INPUT_EOF; useFilter = src[0]; if (useFilter > 1) { *destLen = 0; return SZ_ERROR_UNSUPPORTED; } inSizePure = *srcLen - LZMA86_HEADER_SIZE; res = LzmaDecode(dest, destLen, src + LZMA86_HEADER_SIZE, &inSizePure, src + 1, LZMA_PROPS_SIZE, LZMA_FINISH_ANY, &status, &g_Alloc); *srcLen = inSizePure + LZMA86_HEADER_SIZE; if (res != SZ_OK) return res; if (useFilter == 1) { UInt32 x86State; x86_Convert_Init(x86State); x86_Convert(dest, *destLen, 0, &x86State, 0); } return SZ_OK; }
int LzmaRamDecompress( unsigned char *inBuffer, size_t inSize, unsigned char *outBuffer, size_t outSize, size_t *outSizeProcessed, void * (*allocFunc)(size_t size), void (*freeFunc)(void *)) { int lc, lp, pb; size_t lzmaInternalSize; void *lzmaInternalData; int result; UInt32 outSizeProcessedLoc; int useFilter = inBuffer[0]; *outSizeProcessed = 0; if (useFilter > 1) return 1; if (inSize < LZMA_PROPS_SIZE) return 1; lc = inBuffer[1]; if (lc >= (9 * 5 * 5)) return 1; for (pb = 0; lc >= (9 * 5); pb++, lc -= (9 * 5)); for (lp = 0; lc >= 9; lp++, lc -= 9); lzmaInternalSize = (LZMA_BASE_SIZE + (LZMA_LIT_SIZE << (lc + lp))) * sizeof(CProb); lzmaInternalData = allocFunc(lzmaInternalSize); if (lzmaInternalData == 0) return SZE_OUTOFMEMORY; result = LzmaDecode((unsigned char *)lzmaInternalData, (UInt32)lzmaInternalSize, lc, lp, pb, inBuffer + LZMA_PROPS_SIZE, (UInt32)inSize - LZMA_PROPS_SIZE, outBuffer, (UInt32)outSize, &outSizeProcessedLoc); freeFunc(lzmaInternalData); if (result != LZMA_RESULT_OK) return 1; *outSizeProcessed = (size_t)outSizeProcessedLoc; if (useFilter == 1) { UInt32 _prevMask; UInt32 _prevPos; x86_Convert_Init(_prevMask, _prevPos); x86_Convert(outBuffer, (UInt32)outSizeProcessedLoc, 0, &_prevMask, &_prevPos, 0); } return 0; }
static bool Compress(const char *uncompressed, size_t uncompressedSize, char *compressed, size_t *compressedSize) { ISzCrtAlloc lzmaAlloc; CrashIf(*compressedSize < uncompressedSize + 1); if (*compressedSize < uncompressedSize + 1) return false; if (*compressedSize < LZMA_HEADER_SIZE) goto StoreUncompressed; CLzmaEncProps props; LzmaEncProps_Init(&props); // always apply the BCJ filter for speed (else two or three compression passes would be required) size_t lzma_size = (size_t)-1; uint8_t *bcj_enc = (uint8_t *)malloc(uncompressedSize); if (bcj_enc) { memcpy(bcj_enc, uncompressed, uncompressedSize); UInt32 x86State; x86_Convert_Init(x86State); x86_Convert(bcj_enc, uncompressedSize, 0, &x86State, 1); } SizeT outSize = *compressedSize - LZMA_HEADER_SIZE; SizeT propsSize = LZMA_PROPS_SIZE; SRes res = LzmaEncode((Byte *)compressed + LZMA_HEADER_SIZE, &outSize, bcj_enc ? bcj_enc : (const Byte *)uncompressed, uncompressedSize, &props, (Byte *)compressed + 1, &propsSize, TRUE /* add EOS marker */, NULL, &lzmaAlloc, &lzmaAlloc); if (SZ_OK == res && propsSize == LZMA_PROPS_SIZE) lzma_size = outSize + LZMA_HEADER_SIZE; free(bcj_enc); if (lzma_size < uncompressedSize + 1) { compressed[0] = bcj_enc ? 1 : 0; *compressedSize = lzma_size; } else { StoreUncompressed: compressed[0] = (uint8_t)-1; memcpy(compressed + 1, uncompressed, uncompressedSize); *compressedSize = uncompressedSize + 1; } return true; }
int LzmaRamDecompress( const unsigned char *inBuffer, size_t inSize, unsigned char *outBuffer, size_t outSize, size_t *outSizeProcessed, void * (*allocFunc)(size_t size), void (*freeFunc)(void *)) { CLzmaDecoderState state; /* it's about 24 bytes structure, if int is 32-bit */ int result; SizeT outSizeProcessedLoc; SizeT inProcessed; int useFilter; if (inSize < LZMA_PROPS_SIZE) return 1; useFilter = inBuffer[0]; *outSizeProcessed = 0; if (useFilter > 1) return 1; if (LzmaDecodeProperties(&state.Properties, inBuffer + 1, LZMA_PROPERTIES_SIZE) != LZMA_RESULT_OK) return 1; state.Probs = (CProb *)allocFunc(LzmaGetNumProbs(&state.Properties) * sizeof(CProb)); if (state.Probs == 0) return SZE_OUTOFMEMORY; result = LzmaDecode(&state, inBuffer + LZMA_PROPS_SIZE, (SizeT)inSize - LZMA_PROPS_SIZE, &inProcessed, outBuffer, (SizeT)outSize, &outSizeProcessedLoc); freeFunc(state.Probs); if (result != LZMA_RESULT_OK) return 1; *outSizeProcessed = (size_t)outSizeProcessedLoc; if (useFilter == 1) { UInt32 _prevMask; UInt32 _prevPos; x86_Convert_Init(_prevMask, _prevPos); x86_Convert(outBuffer, (UInt32)outSizeProcessedLoc, 0, &_prevMask, &_prevPos, 0); } return 0; }
char* Decompress(const char *compressed, size_t compressedSize, size_t* uncompressedSizeOut, Allocator *allocator) { ISzAllocatorAlloc lzmaAlloc; lzmaAlloc.Alloc = LzmaAllocatorAlloc; lzmaAlloc.Free = LzmaAllocatorFree; lzmaAlloc.allocator = allocator; if (compressedSize < LZMA86_HEADER_SIZE) return NULL; uint8_t usesX86Filter = (uint8_t)compressed[0]; if (usesX86Filter > 1) return NULL; const uint8_t* compressed2 = (const uint8_t*)compressed; SizeT uncompressedSize = Read4(compressed2 + LZMA86_SIZE_OFFSET); uint8_t* uncompressed = (uint8_t*)Allocator::Alloc(allocator, uncompressedSize); if (!uncompressed) return NULL; SizeT compressedSizeTmp = compressedSize - LZMA86_HEADER_SIZE; SizeT uncompressedSizeTmp = uncompressedSize; ELzmaStatus status; // Note: would be nice to understand why status returns LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK and // not LZMA_STATUS_FINISHED_WITH_MARK. It seems to work, though. int res = LzmaDecode(uncompressed, &uncompressedSizeTmp, compressed2 + LZMA86_HEADER_SIZE, &compressedSizeTmp, compressed2 + 1, LZMA_PROPS_SIZE, LZMA_FINISH_END, &status, &lzmaAlloc); if (SZ_OK != res) { Allocator::Free(allocator, uncompressed); return NULL; } if (usesX86Filter) { UInt32 x86State; x86_Convert_Init(x86State); x86_Convert(uncompressed, uncompressedSizeTmp, 0, &x86State, 0); } *uncompressedSizeOut = uncompressedSize; return (char*)uncompressed; }
// the first compressed byte indicates whether compression is LZMA (0), LZMA+BJC (1) or none (-1) static bool Decompress(const char *compressed, size_t compressedSize, char *uncompressed, size_t uncompressedSize, Allocator *allocator) { if (compressedSize < 1) return false; uint8_t usesX86Filter = compressed[0]; // handle stored data if (usesX86Filter == (uint8_t)-1) { if (uncompressedSize != compressedSize - 1) return false; memcpy(uncompressed, compressed + 1, compressedSize - 1); return true; } if (compressedSize < LZMA_HEADER_SIZE || usesX86Filter > 1) return false; SizeT uncompressedSizeCmp = uncompressedSize; SizeT compressedSizeTmp = compressedSize - LZMA_HEADER_SIZE; ISzAllocatorAlloc lzmaAlloc(allocator); ELzmaStatus status; int res = LzmaDecode((Byte *)uncompressed, &uncompressedSizeCmp, (Byte *)compressed + LZMA_HEADER_SIZE, &compressedSizeTmp, (Byte *)compressed + 1, LZMA_PROPS_SIZE, LZMA_FINISH_END, &status, &lzmaAlloc); if (SZ_OK != res || status != LZMA_STATUS_FINISHED_WITH_MARK) return false; if (uncompressedSizeCmp != uncompressedSize) return false; if (usesX86Filter) { UInt32 x86State; x86_Convert_Init(x86State); x86_Convert((Byte *)uncompressed, uncompressedSize, 0, &x86State, 0); } return true; }
static PyObject * pylzma_bcj_x86_convert(PyObject *self, PyObject *args) { char *data; PARSE_LENGTH_TYPE length; int encoding=0; PyObject *result; if (!PyArg_ParseTuple(args, "s#|i", &data, &length, &encoding)) { return NULL; } if (!length) { return PyBytes_FromString(""); } result = PyBytes_FromStringAndSize(data, length); if (result != NULL) { UInt32 state; Py_BEGIN_ALLOW_THREADS x86_Convert_Init(state); x86_Convert((Byte *) PyBytes_AS_STRING(result), length, 0, &state, encoding); Py_END_ALLOW_THREADS }
int Lzma86_Encode(Byte *dest, size_t *destLen, const Byte *src, size_t srcLen, int level, UInt32 dictSize, int filterMode) { ISzAlloc g_Alloc = { SzAlloc, SzFree }; size_t outSize2 = *destLen; Byte *filteredStream; Bool useFilter; int mainResult = SZ_ERROR_OUTPUT_EOF; CLzmaEncProps props; LzmaEncProps_Init(&props); props.level = level; props.dictSize = dictSize; *destLen = 0; if (outSize2 < LZMA86_HEADER_SIZE) return SZ_ERROR_OUTPUT_EOF; { int i; UInt64 t = srcLen; for (i = 0; i < 8; i++, t >>= 8) dest[LZMA86_SIZE_OFFSET + i] = (Byte)t; } filteredStream = 0; useFilter = (filterMode != SZ_FILTER_NO); if (useFilter) { if (srcLen != 0) { filteredStream = (Byte *)MyAlloc(srcLen); if (filteredStream == 0) return SZ_ERROR_MEM; memcpy(filteredStream, src, srcLen); } { UInt32 x86State; x86_Convert_Init(x86State); x86_Convert(filteredStream, srcLen, 0, &x86State, 1); } } { size_t minSize = 0; Bool bestIsFiltered = False; /* passes for SZ_FILTER_AUTO: 0 - BCJ + LZMA 1 - LZMA 2 - BCJ + LZMA agaian, if pass 0 (BCJ + LZMA) is better. */ int numPasses = (filterMode == SZ_FILTER_AUTO) ? 3 : 1; int i; for (i = 0; i < numPasses; i++) { size_t outSizeProcessed = outSize2 - LZMA86_HEADER_SIZE; size_t outPropsSize = 5; SRes curRes; Bool curModeIsFiltered = (numPasses > 1 && i == numPasses - 1); if (curModeIsFiltered && !bestIsFiltered) break; if (useFilter && i == 0) curModeIsFiltered = True; curRes = LzmaEncode(dest + LZMA86_HEADER_SIZE, &outSizeProcessed, curModeIsFiltered ? filteredStream : src, srcLen, &props, dest + 1, &outPropsSize, 0, NULL, &g_Alloc, &g_Alloc); if (curRes != SZ_ERROR_OUTPUT_EOF) { if (curRes != SZ_OK) { mainResult = curRes; break; } if (outSizeProcessed <= minSize || mainResult != SZ_OK) { minSize = outSizeProcessed; bestIsFiltered = curModeIsFiltered; mainResult = SZ_OK; } } } dest[0] = (Byte)(bestIsFiltered ? 1 : 0); *destLen = LZMA86_HEADER_SIZE + minSize; } if (useFilter) MyFree(filteredStream); return mainResult; }
static SRes SzDecode2(const UInt64 *packSizes, const CSzFolder *folder, ILookInStream *inStream, UInt64 startPos, Byte *outBuffer, SizeT outSize, ISzAlloc *allocMain, Byte *tempBuf[]) { UInt32 ci; SizeT tempSizes[3] = { 0, 0, 0}; SizeT tempSize3 = 0; Byte *tempBuf3 = 0; RINOK(CheckSupportedFolder(folder)); for (ci = 0; ci < folder->NumCoders; ci++) { CSzCoderInfo *coder = &folder->Coders[ci]; if (coder->MethodID == k_Copy || coder->MethodID == k_LZMA) { UInt32 si = 0; UInt64 offset; UInt64 inSize; Byte *outBufCur = outBuffer; SizeT outSizeCur = outSize; if (folder->NumCoders == 4) { UInt32 indices[] = { 3, 2, 0 }; UInt64 unpackSize = folder->UnpackSizes[ci]; si = indices[ci]; if (ci < 2) { Byte *temp; outSizeCur = (SizeT)unpackSize; if (outSizeCur != unpackSize) return SZ_ERROR_MEM; temp = (Byte *)IAlloc_Alloc(allocMain, outSizeCur); if (temp == 0 && outSizeCur != 0) return SZ_ERROR_MEM; outBufCur = tempBuf[1 - ci] = temp; tempSizes[1 - ci] = outSizeCur; } else if (ci == 2) { if (unpackSize > outSize) /* check it */ return SZ_ERROR_PARAM; tempBuf3 = outBufCur = outBuffer + (outSize - (size_t)unpackSize); tempSize3 = outSizeCur = (SizeT)unpackSize; } else return SZ_ERROR_UNSUPPORTED; } offset = GetSum(packSizes, si); inSize = packSizes[si]; RINOK(LookInStream_SeekTo(inStream, startPos + offset)); if (coder->MethodID == k_Copy) { if (inSize != outSizeCur) /* check it */ return SZ_ERROR_DATA; RINOK(SzDecodeCopy(inSize, inStream, outBufCur)); } else { RINOK(SzDecodeLzma(coder, inSize, inStream, outBufCur, outSizeCur, allocMain)); } } else if (coder->MethodID == k_BCJ) { UInt32 state; if (ci != 1) return SZ_ERROR_UNSUPPORTED; x86_Convert_Init(state); x86_Convert(outBuffer, outSize, 0, &state, 0); } else if (coder->MethodID == k_BCJ2) { UInt64 offset = GetSum(packSizes, 1); UInt64 s3Size = packSizes[1]; SRes res; if (ci != 3) return SZ_ERROR_UNSUPPORTED; RINOK(LookInStream_SeekTo(inStream, startPos + offset)); tempSizes[2] = (SizeT)s3Size; if (tempSizes[2] != s3Size) return SZ_ERROR_MEM; tempBuf[2] = (Byte *)IAlloc_Alloc(allocMain, tempSizes[2]); if (tempBuf[2] == 0 && tempSizes[2] != 0) return SZ_ERROR_MEM; res = SzDecodeCopy(s3Size, inStream, tempBuf[2]); RINOK(res) res = Bcj2_Decode( tempBuf3, tempSize3, tempBuf[0], tempSizes[0], tempBuf[1], tempSizes[1], tempBuf[2], tempSizes[2], outBuffer, outSize); RINOK(res) } else return SZ_ERROR_UNSUPPORTED;
static SRes Encode(ISeqOutStream *outStream, ISeqInStream *inStream, UInt64 fileSize) { SRes res; size_t inSize = (size_t)fileSize; Byte *inBuffer = 0; Byte *outBuffer = 0; Byte *filteredStream = 0; size_t outSize; CLzmaEncProps props; LzmaEncProps_Init(&props); LzmaEncProps_Normalize(&props); if (inSize != 0) { inBuffer = (Byte *)MyAlloc(inSize); if (inBuffer == 0) return SZ_ERROR_MEM; } else { return SZ_ERROR_INPUT_EOF; } if (SeqInStream_Read(inStream, inBuffer, inSize) != SZ_OK) { res = SZ_ERROR_READ; goto Done; } // we allocate 105% of original size + 64KB for output buffer outSize = (size_t)fileSize / 20 * 21 + (1 << 16); outBuffer = (Byte *)MyAlloc(outSize); if (outBuffer == 0) { res = SZ_ERROR_MEM; goto Done; } { int i; for (i = 0; i < 8; i++) outBuffer[i + LZMA_PROPS_SIZE] = (Byte)(fileSize >> (8 * i)); } if (mConType != NoConverter) { filteredStream = (Byte *)MyAlloc(inSize); if (filteredStream == 0) { res = SZ_ERROR_MEM; goto Done; } memcpy(filteredStream, inBuffer, inSize); if (mConType == X86Converter) { { UInt32 x86State; x86_Convert_Init(x86State); x86_Convert(filteredStream, (SizeT) inSize, 0, &x86State, 1); } } } { size_t outSizeProcessed = outSize - LZMA_HEADER_SIZE; size_t outPropsSize = LZMA_PROPS_SIZE; res = LzmaEncode(outBuffer + LZMA_HEADER_SIZE, &outSizeProcessed, mConType != NoConverter ? filteredStream : inBuffer, inSize, &props, outBuffer, &outPropsSize, 0, NULL, &g_Alloc, &g_Alloc); if (res != SZ_OK) goto Done; outSize = LZMA_HEADER_SIZE + outSizeProcessed; } if (outStream->Write(outStream, outBuffer, outSize) != outSize) res = SZ_ERROR_WRITE; Done: MyFree(outBuffer); MyFree(inBuffer); MyFree(filteredStream); return res; }
static SRes Decode(ISeqOutStream *outStream, ISeqInStream *inStream, UInt64 fileSize) { SRes res; size_t inSize = (size_t)fileSize; Byte *inBuffer = 0; Byte *outBuffer = 0; size_t outSize = 0; size_t inSizePure; ELzmaStatus status; UInt64 outSize64 = 0; int i; if (inSize < LZMA_HEADER_SIZE) return SZ_ERROR_INPUT_EOF; inBuffer = (Byte *)MyAlloc(inSize); if (inBuffer == 0) return SZ_ERROR_MEM; if (SeqInStream_Read(inStream, inBuffer, inSize) != SZ_OK) { res = SZ_ERROR_READ; goto Done; } for (i = 0; i < 8; i++) outSize64 += ((UInt64)inBuffer[LZMA_PROPS_SIZE + i]) << (i * 8); outSize = (size_t)outSize64; if (outSize != 0) { outBuffer = (Byte *)MyAlloc(outSize); if (outBuffer == 0) { res = SZ_ERROR_MEM; goto Done; } } else { res = SZ_OK; goto Done; } inSizePure = inSize - LZMA_HEADER_SIZE; res = LzmaDecode(outBuffer, &outSize, inBuffer + LZMA_HEADER_SIZE, &inSizePure, inBuffer, LZMA_PROPS_SIZE, LZMA_FINISH_END, &status, &g_Alloc); if (res != SZ_OK) goto Done; if (mConType == X86Converter) { UInt32 x86State; x86_Convert_Init(x86State); x86_Convert(outBuffer, (SizeT) outSize, 0, &x86State, 0); } if (outStream->Write(outStream, outBuffer, outSize) != outSize) res = SZ_ERROR_WRITE; Done: MyFree(outBuffer); MyFree(inBuffer); return res; }
STDMETHODIMP CBcjCoder::Init() { _bufferPos = 0; x86_Convert_Init(_prevMask); return S_OK; }