diff -r 0135e64c6c66 -r c4fd2813b127 misc/libphysfs/lzma/C/Archive/7z/7zDecode.c --- a/misc/libphysfs/lzma/C/Archive/7z/7zDecode.c Wed May 16 18:22:28 2018 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,345 +0,0 @@ -/* 7zDecode.c */ - -#include - -/* BEGIN PHYSFS CHANGE */ -#include -/* END PHYSFS CHANGE */ - -#include "7zDecode.h" -#ifdef _SZ_ONE_DIRECTORY -#include "LzmaDecode.h" -#else -#include "../../Compress/Lzma/LzmaDecode.h" -#include "../../Compress/Branch/BranchX86.h" -#include "../../Compress/Branch/BranchX86_2.h" -#endif - -#define k_Copy 0 -#define k_LZMA 0x30101 -#define k_BCJ 0x03030103 -#define k_BCJ2 0x0303011B - -#ifdef _LZMA_IN_CB - -typedef struct _CLzmaInCallbackImp -{ - ILzmaInCallback InCallback; - ISzInStream *InStream; - CFileSize Size; -} CLzmaInCallbackImp; - -int LzmaReadImp(void *object, const unsigned char **buffer, SizeT *size) -{ - CLzmaInCallbackImp *cb = (CLzmaInCallbackImp *)object; - size_t processedSize; - SZ_RESULT res; - size_t curSize = (1 << 20); - if (curSize > cb->Size) - curSize = (size_t)cb->Size; - *size = 0; - res = cb->InStream->Read((void *)cb->InStream, (void **)buffer, curSize, &processedSize); - *size = (SizeT)processedSize; - if (processedSize > curSize) - return (int)SZE_FAIL; - cb->Size -= processedSize; - if (res == SZ_OK) - return 0; - return (int)res; -} - -#endif - -SZ_RESULT SzDecodeLzma(CCoderInfo *coder, CFileSize inSize, - #ifdef _LZMA_IN_CB - ISzInStream *inStream, - #else - const Byte *inBuffer, - #endif - Byte *outBuffer, size_t outSize, ISzAlloc *allocMain) -{ - #ifdef _LZMA_IN_CB - CLzmaInCallbackImp lzmaCallback; - #else - SizeT inProcessed; - #endif - - CLzmaDecoderState state; /* it's about 24-80 bytes structure, if int is 32-bit */ - int result; - SizeT outSizeProcessedLoc; - - #ifdef _LZMA_IN_CB - lzmaCallback.Size = inSize; - lzmaCallback.InStream = inStream; - lzmaCallback.InCallback.Read = LzmaReadImp; - #endif - - if (LzmaDecodeProperties(&state.Properties, coder->Properties.Items, - (unsigned)coder->Properties.Capacity) != LZMA_RESULT_OK) - return SZE_FAIL; - - state.Probs = (CProb *)allocMain->Alloc(LzmaGetNumProbs(&state.Properties) * sizeof(CProb)); - if (state.Probs == 0) - return SZE_OUTOFMEMORY; - - #ifdef _LZMA_OUT_READ - if (state.Properties.DictionarySize == 0) - state.Dictionary = 0; - else - { - state.Dictionary = (unsigned char *)allocMain->Alloc(state.Properties.DictionarySize); - if (state.Dictionary == 0) - { - allocMain->Free(state.Probs); - return SZE_OUTOFMEMORY; - } - } - LzmaDecoderInit(&state); - #endif - - result = LzmaDecode(&state, - #ifdef _LZMA_IN_CB - &lzmaCallback.InCallback, - #else - inBuffer, (SizeT)inSize, &inProcessed, - #endif - outBuffer, (SizeT)outSize, &outSizeProcessedLoc); - allocMain->Free(state.Probs); - #ifdef _LZMA_OUT_READ - allocMain->Free(state.Dictionary); - #endif - if (result == LZMA_RESULT_DATA_ERROR) - return SZE_DATA_ERROR; - if (result != LZMA_RESULT_OK) - return SZE_FAIL; - return (outSizeProcessedLoc == outSize) ? SZ_OK : SZE_DATA_ERROR; -} - -#ifdef _LZMA_IN_CB -SZ_RESULT SzDecodeCopy(CFileSize inSize, ISzInStream *inStream, Byte *outBuffer) -{ - while (inSize > 0) - { - void *inBuffer; - size_t processedSize, curSize = (1 << 18); - if (curSize > inSize) - curSize = (size_t)(inSize); - RINOK(inStream->Read((void *)inStream, (void **)&inBuffer, curSize, &processedSize)); - if (processedSize == 0) - return SZE_DATA_ERROR; - if (processedSize > curSize) - return SZE_FAIL; - memcpy(outBuffer, inBuffer, processedSize); - outBuffer += processedSize; - inSize -= processedSize; - } - return SZ_OK; -} -#endif - -#define IS_UNSUPPORTED_METHOD(m) ((m) != k_Copy && (m) != k_LZMA) -#define IS_UNSUPPORTED_CODER(c) (IS_UNSUPPORTED_METHOD(c.MethodID) || c.NumInStreams != 1 || c.NumOutStreams != 1) -#define IS_NO_BCJ(c) (c.MethodID != k_BCJ || c.NumInStreams != 1 || c.NumOutStreams != 1) -#define IS_NO_BCJ2(c) (c.MethodID != k_BCJ2 || c.NumInStreams != 4 || c.NumOutStreams != 1) - -SZ_RESULT CheckSupportedFolder(const CFolder *f) -{ - if (f->NumCoders < 1 || f->NumCoders > 4) - return SZE_NOTIMPL; - if (IS_UNSUPPORTED_CODER(f->Coders[0])) - return SZE_NOTIMPL; - if (f->NumCoders == 1) - { - if (f->NumPackStreams != 1 || f->PackStreams[0] != 0 || f->NumBindPairs != 0) - return SZE_NOTIMPL; - return SZ_OK; - } - if (f->NumCoders == 2) - { - if (IS_NO_BCJ(f->Coders[1]) || - f->NumPackStreams != 1 || f->PackStreams[0] != 0 || - f->NumBindPairs != 1 || - f->BindPairs[0].InIndex != 1 || f->BindPairs[0].OutIndex != 0) - return SZE_NOTIMPL; - return SZ_OK; - } - if (f->NumCoders == 4) - { - if (IS_UNSUPPORTED_CODER(f->Coders[1]) || - IS_UNSUPPORTED_CODER(f->Coders[2]) || - IS_NO_BCJ2(f->Coders[3])) - return SZE_NOTIMPL; - if (f->NumPackStreams != 4 || - f->PackStreams[0] != 2 || - f->PackStreams[1] != 6 || - f->PackStreams[2] != 1 || - f->PackStreams[3] != 0 || - f->NumBindPairs != 3 || - f->BindPairs[0].InIndex != 5 || f->BindPairs[0].OutIndex != 0 || - f->BindPairs[1].InIndex != 4 || f->BindPairs[1].OutIndex != 1 || - f->BindPairs[2].InIndex != 3 || f->BindPairs[2].OutIndex != 2) - return SZE_NOTIMPL; - return SZ_OK; - } - return SZE_NOTIMPL; -} - -CFileSize GetSum(const CFileSize *values, UInt32 index) -{ - CFileSize sum = 0; - UInt32 i; - for (i = 0; i < index; i++) - sum += values[i]; - return sum; -} - -SZ_RESULT SzDecode2(const CFileSize *packSizes, const CFolder *folder, - #ifdef _LZMA_IN_CB - ISzInStream *inStream, CFileSize startPos, - #else - const Byte *inBuffer, - #endif - Byte *outBuffer, size_t outSize, ISzAlloc *allocMain, - Byte *tempBuf[]) -{ - UInt32 ci; - size_t tempSizes[3] = { 0, 0, 0}; - size_t tempSize3 = 0; - Byte *tempBuf3 = 0; - - RINOK(CheckSupportedFolder(folder)); - - for (ci = 0; ci < folder->NumCoders; ci++) - { - CCoderInfo *coder = &folder->Coders[ci]; - - if (coder->MethodID == k_Copy || coder->MethodID == k_LZMA) - { - UInt32 si = 0; - CFileSize offset; - CFileSize inSize; - Byte *outBufCur = outBuffer; - size_t outSizeCur = outSize; - if (folder->NumCoders == 4) - { - UInt32 indices[] = { 3, 2, 0 }; - CFileSize unpackSize = folder->UnPackSizes[ci]; - si = indices[ci]; - if (ci < 2) - { - Byte *temp; - outSizeCur = (size_t)unpackSize; - if (outSizeCur != unpackSize) - return SZE_OUTOFMEMORY; - temp = (Byte *)allocMain->Alloc(outSizeCur); - if (temp == 0 && outSizeCur != 0) - return SZE_OUTOFMEMORY; - outBufCur = tempBuf[1 - ci] = temp; - tempSizes[1 - ci] = outSizeCur; - } - else if (ci == 2) - { - if (unpackSize > outSize) - return SZE_OUTOFMEMORY; - tempBuf3 = outBufCur = outBuffer + (outSize - (size_t)unpackSize); - tempSize3 = outSizeCur = (size_t)unpackSize; - } - else - return SZE_NOTIMPL; - } - offset = GetSum(packSizes, si); - inSize = packSizes[si]; - #ifdef _LZMA_IN_CB - RINOK(inStream->Seek(inStream, startPos + offset)); - #endif - - if (coder->MethodID == k_Copy) - { - if (inSize != outSizeCur) - return SZE_DATA_ERROR; - - #ifdef _LZMA_IN_CB - RINOK(SzDecodeCopy(inSize, inStream, outBufCur)); - #else - memcpy(outBufCur, inBuffer + (size_t)offset, (size_t)inSize); - #endif - } - else - { - SZ_RESULT res = SzDecodeLzma(coder, inSize, - #ifdef _LZMA_IN_CB - inStream, - #else - inBuffer + (size_t)offset, - #endif - outBufCur, outSizeCur, allocMain); - RINOK(res) - } - } - else if (coder->MethodID == k_BCJ) - { - UInt32 state; - if (ci != 1) - return SZE_NOTIMPL; - x86_Convert_Init(state); - x86_Convert(outBuffer, outSize, 0, &state, 0); - } - else if (coder->MethodID == k_BCJ2) - { - CFileSize offset = GetSum(packSizes, 1); - CFileSize s3Size = packSizes[1]; - SZ_RESULT res; - if (ci != 3) - return SZE_NOTIMPL; - - #ifdef _LZMA_IN_CB - RINOK(inStream->Seek(inStream, startPos + offset)); - tempSizes[2] = (size_t)s3Size; - if (tempSizes[2] != s3Size) - return SZE_OUTOFMEMORY; - tempBuf[2] = (Byte *)allocMain->Alloc(tempSizes[2]); - if (tempBuf[2] == 0 && tempSizes[2] != 0) - return SZE_OUTOFMEMORY; - res = SzDecodeCopy(s3Size, inStream, tempBuf[2]); - RINOK(res) - #endif - - res = x86_2_Decode( - tempBuf3, tempSize3, - tempBuf[0], tempSizes[0], - tempBuf[1], tempSizes[1], - #ifdef _LZMA_IN_CB - tempBuf[2], tempSizes[2], - #else - inBuffer + (size_t)offset, (size_t)s3Size, - #endif - outBuffer, outSize); - RINOK(res) - } - else - return SZE_NOTIMPL; - } - return SZ_OK; -} - -SZ_RESULT SzDecode(const CFileSize *packSizes, const CFolder *folder, - #ifdef _LZMA_IN_CB - ISzInStream *inStream, CFileSize startPos, - #else - const Byte *inBuffer, - #endif - Byte *outBuffer, size_t outSize, ISzAlloc *allocMain) -{ - Byte *tempBuf[3] = { 0, 0, 0}; - int i; - SZ_RESULT res = SzDecode2(packSizes, folder, - #ifdef _LZMA_IN_CB - inStream, startPos, - #else - inBuffer, - #endif - outBuffer, outSize, allocMain, tempBuf); - for (i = 0; i < 3; i++) - allocMain->Free(tempBuf[i]); - return res; -}