mirror of
https://github.com/Xevion/easy7zip.git
synced 2025-12-14 10:11:38 -06:00
4.61 beta
This commit is contained in:
committed by
Kornel Lesiński
parent
c10e6b16f6
commit
b717a4dbfe
@@ -1,32 +1,23 @@
|
||||
/* 7zDecode.c Decoding from 7z folder
|
||||
2008-08-05
|
||||
Igor Pavlov
|
||||
Copyright (c) 1999-2008 Igor Pavlov
|
||||
Read 7zDecode.h for license options */
|
||||
/* 7zDecode.c -- Decoding from 7z folder
|
||||
2008-11-23 : Igor Pavlov : Public domain */
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include "7zDecode.h"
|
||||
#include "../../LzmaDec.h"
|
||||
#include "../../Bra.h"
|
||||
#include "../../Bcj2.h"
|
||||
#include "../../Bra.h"
|
||||
#include "../../LzmaDec.h"
|
||||
#include "7zDecode.h"
|
||||
|
||||
#define k_Copy 0
|
||||
#define k_LZMA 0x30101
|
||||
#define k_BCJ 0x03030103
|
||||
#define k_BCJ2 0x0303011B
|
||||
|
||||
/*
|
||||
#ifdef _LZMA_IN_CB
|
||||
*/
|
||||
|
||||
static SRes SzDecodeLzma(CSzCoderInfo *coder, CFileSize inSize, ISzInStream *inStream,
|
||||
Byte *outBuffer, size_t outSize, ISzAlloc *allocMain)
|
||||
static SRes SzDecodeLzma(CSzCoderInfo *coder, UInt64 inSize, ILookInStream *inStream,
|
||||
Byte *outBuffer, SizeT outSize, ISzAlloc *allocMain)
|
||||
{
|
||||
CLzmaDec state;
|
||||
int res = SZ_OK;
|
||||
size_t _inSize;
|
||||
Byte *inBuf = NULL;
|
||||
SRes res = SZ_OK;
|
||||
|
||||
LzmaDec_Construct(&state);
|
||||
RINOK(LzmaDec_AllocateProbs(&state, coder->Props.data, (unsigned)coder->Props.size, allocMain));
|
||||
@@ -34,65 +25,60 @@ static SRes SzDecodeLzma(CSzCoderInfo *coder, CFileSize inSize, ISzInStream *inS
|
||||
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;
|
||||
}
|
||||
Byte *inBuf = NULL;
|
||||
size_t lookahead = (1 << 18);
|
||||
if (lookahead > inSize)
|
||||
lookahead = (size_t)inSize;
|
||||
res = inStream->Look((void *)inStream, (void **)&inBuf, &lookahead);
|
||||
if (res != SZ_OK)
|
||||
break;
|
||||
|
||||
{
|
||||
SizeT inProcessed = _inSize, dicPos = state.dicPos;
|
||||
SizeT inProcessed = (SizeT)lookahead, dicPos = state.dicPos;
|
||||
ELzmaStatus status;
|
||||
res = LzmaDec_DecodeToDic(&state, outSize, inBuf, &inProcessed, LZMA_FINISH_END, &status);
|
||||
_inSize -= inProcessed;
|
||||
inBuf = (Byte *)inBuf + inProcessed;
|
||||
lookahead -= inProcessed;
|
||||
inSize -= inProcessed;
|
||||
if (res != SZ_OK)
|
||||
break;
|
||||
if (state.dicPos == state.dicBufSize || (inProcessed == 0 && dicPos == state.dicPos))
|
||||
{
|
||||
if (state.dicBufSize != outSize || _inSize != 0 ||
|
||||
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;
|
||||
}
|
||||
|
||||
static SRes SzDecodeCopy(CFileSize inSize, ISzInStream *inStream, Byte *outBuffer)
|
||||
static SRes SzDecodeCopy(UInt64 inSize, ILookInStream *inStream, Byte *outBuffer)
|
||||
{
|
||||
while (inSize > 0)
|
||||
{
|
||||
void *inBuffer;
|
||||
void *inBuf;
|
||||
size_t curSize = (1 << 18);
|
||||
if (curSize > inSize)
|
||||
curSize = (size_t)(inSize);
|
||||
RINOK(inStream->Read((void *)inStream, (void **)&inBuffer, &curSize));
|
||||
curSize = (size_t)inSize;
|
||||
RINOK(inStream->Look((void *)inStream, (void **)&inBuf, &curSize));
|
||||
if (curSize == 0)
|
||||
return SZ_ERROR_INPUT_EOF;
|
||||
memcpy(outBuffer, inBuffer, curSize);
|
||||
memcpy(outBuffer, inBuf, curSize);
|
||||
outBuffer += curSize;
|
||||
inSize -= curSize;
|
||||
RINOK(inStream->Skip((void *)inStream, curSize));
|
||||
}
|
||||
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)
|
||||
@@ -141,31 +127,23 @@ SRes CheckSupportedFolder(const CSzFolder *f)
|
||||
return SZ_ERROR_UNSUPPORTED;
|
||||
}
|
||||
|
||||
CFileSize GetSum(const CFileSize *values, UInt32 index)
|
||||
UInt64 GetSum(const UInt64 *values, UInt32 index)
|
||||
{
|
||||
CFileSize sum = 0;
|
||||
UInt64 sum = 0;
|
||||
UInt32 i;
|
||||
for (i = 0; i < index; i++)
|
||||
sum += values[i];
|
||||
return sum;
|
||||
}
|
||||
|
||||
SRes SzDecode2(const CFileSize *packSizes, const CSzFolder *folder,
|
||||
/*
|
||||
#ifdef _LZMA_IN_CB
|
||||
*/
|
||||
ISzInStream *inStream, CFileSize startPos,
|
||||
/*
|
||||
#else
|
||||
const Byte *inBuffer,
|
||||
#endif
|
||||
*/
|
||||
Byte *outBuffer, size_t outSize, ISzAlloc *allocMain,
|
||||
SRes SzDecode2(const UInt64 *packSizes, const CSzFolder *folder,
|
||||
ILookInStream *inStream, UInt64 startPos,
|
||||
Byte *outBuffer, SizeT outSize, ISzAlloc *allocMain,
|
||||
Byte *tempBuf[])
|
||||
{
|
||||
UInt32 ci;
|
||||
size_t tempSizes[3] = { 0, 0, 0};
|
||||
size_t tempSize3 = 0;
|
||||
SizeT tempSizes[3] = { 0, 0, 0};
|
||||
SizeT tempSize3 = 0;
|
||||
Byte *tempBuf3 = 0;
|
||||
|
||||
RINOK(CheckSupportedFolder(folder));
|
||||
@@ -177,19 +155,19 @@ SRes SzDecode2(const CFileSize *packSizes, const CSzFolder *folder,
|
||||
if (coder->MethodID == k_Copy || coder->MethodID == k_LZMA)
|
||||
{
|
||||
UInt32 si = 0;
|
||||
CFileSize offset;
|
||||
CFileSize inSize;
|
||||
UInt64 offset;
|
||||
UInt64 inSize;
|
||||
Byte *outBufCur = outBuffer;
|
||||
size_t outSizeCur = outSize;
|
||||
SizeT outSizeCur = outSize;
|
||||
if (folder->NumCoders == 4)
|
||||
{
|
||||
UInt32 indices[] = { 3, 2, 0 };
|
||||
CFileSize unpackSize = folder->UnpackSizes[ci];
|
||||
UInt64 unpackSize = folder->UnpackSizes[ci];
|
||||
si = indices[ci];
|
||||
if (ci < 2)
|
||||
{
|
||||
Byte *temp;
|
||||
outSizeCur = (size_t)unpackSize;
|
||||
outSizeCur = (SizeT)unpackSize;
|
||||
if (outSizeCur != unpackSize)
|
||||
return SZ_ERROR_MEM;
|
||||
temp = (Byte *)IAlloc_Alloc(allocMain, outSizeCur);
|
||||
@@ -200,58 +178,27 @@ SRes SzDecode2(const CFileSize *packSizes, const CSzFolder *folder,
|
||||
}
|
||||
else if (ci == 2)
|
||||
{
|
||||
if (unpackSize > outSize) // check it
|
||||
return SZ_ERROR_PARAM; // check it
|
||||
if (unpackSize > outSize) /* check it */
|
||||
return SZ_ERROR_PARAM;
|
||||
tempBuf3 = outBufCur = outBuffer + (outSize - (size_t)unpackSize);
|
||||
tempSize3 = outSizeCur = (size_t)unpackSize;
|
||||
tempSize3 = outSizeCur = (SizeT)unpackSize;
|
||||
}
|
||||
else
|
||||
return SZ_ERROR_UNSUPPORTED;
|
||||
}
|
||||
offset = GetSum(packSizes, si);
|
||||
inSize = packSizes[si];
|
||||
/*
|
||||
#ifdef _LZMA_IN_CB
|
||||
*/
|
||||
RINOK(inStream->Seek(inStream, startPos + offset, SZ_SEEK_SET));
|
||||
/*
|
||||
#endif
|
||||
*/
|
||||
RINOK(LookInStream_SeekTo(inStream, startPos + offset));
|
||||
|
||||
if (coder->MethodID == k_Copy)
|
||||
{
|
||||
if (inSize != outSizeCur) // check it
|
||||
if (inSize != outSizeCur) /* check it */
|
||||
return SZ_ERROR_DATA;
|
||||
|
||||
/*
|
||||
#ifdef _LZMA_IN_CB
|
||||
*/
|
||||
RINOK(SzDecodeCopy(inSize, inStream, outBufCur));
|
||||
/*
|
||||
#else
|
||||
memcpy(outBufCur, inBuffer + (size_t)offset, (size_t)inSize);
|
||||
#endif
|
||||
*/
|
||||
}
|
||||
else
|
||||
{
|
||||
/*
|
||||
#ifdef _LZMA_IN_CB
|
||||
*/
|
||||
SRes res = SzDecodeLzma(coder, inSize,
|
||||
inStream,
|
||||
outBufCur, outSizeCur, allocMain);
|
||||
/*
|
||||
#else
|
||||
SizeT lzmaOutSizeT = outSizeCur;
|
||||
SizeT lzmaInSizeT = (SizeT)inSize;
|
||||
SRes res = LzmaDecode(outBufCur, &lzmaOutSizeT,
|
||||
inBuffer + (size_t)offset, &lzmaInSizeT,
|
||||
coder->Props.Items, (unsigned)coder->Props.size, LZMA_FINISH_BYTE, allocMain);
|
||||
#endif
|
||||
*/
|
||||
|
||||
RINOK(res);
|
||||
RINOK(SzDecodeLzma(coder, inSize, inStream, outBufCur, outSizeCur, allocMain));
|
||||
}
|
||||
}
|
||||
else if (coder->MethodID == k_BCJ)
|
||||
@@ -264,17 +211,13 @@ SRes SzDecode2(const CFileSize *packSizes, const CSzFolder *folder,
|
||||
}
|
||||
else if (coder->MethodID == k_BCJ2)
|
||||
{
|
||||
CFileSize offset = GetSum(packSizes, 1);
|
||||
CFileSize s3Size = packSizes[1];
|
||||
UInt64 offset = GetSum(packSizes, 1);
|
||||
UInt64 s3Size = packSizes[1];
|
||||
SRes res;
|
||||
if (ci != 3)
|
||||
return SZ_ERROR_UNSUPPORTED;
|
||||
|
||||
/*
|
||||
#ifdef _LZMA_IN_CB
|
||||
*/
|
||||
RINOK(inStream->Seek(inStream, startPos + offset, SZ_SEEK_SET));
|
||||
tempSizes[2] = (size_t)s3Size;
|
||||
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]);
|
||||
@@ -282,23 +225,12 @@ SRes SzDecode2(const CFileSize *packSizes, const CSzFolder *folder,
|
||||
return SZ_ERROR_MEM;
|
||||
res = SzDecodeCopy(s3Size, inStream, tempBuf[2]);
|
||||
RINOK(res)
|
||||
/*
|
||||
#endif
|
||||
*/
|
||||
|
||||
res = Bcj2_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)
|
||||
}
|
||||
@@ -308,31 +240,14 @@ SRes SzDecode2(const CFileSize *packSizes, const CSzFolder *folder,
|
||||
return SZ_OK;
|
||||
}
|
||||
|
||||
SRes SzDecode(const CFileSize *packSizes, const CSzFolder *folder,
|
||||
/*
|
||||
#ifdef _LZMA_IN_CB
|
||||
*/
|
||||
ISzInStream *inStream, CFileSize startPos,
|
||||
/*
|
||||
#else
|
||||
const Byte *inBuffer,
|
||||
#endif
|
||||
*/
|
||||
SRes SzDecode(const UInt64 *packSizes, const CSzFolder *folder,
|
||||
ILookInStream *inStream, UInt64 startPos,
|
||||
Byte *outBuffer, size_t outSize, ISzAlloc *allocMain)
|
||||
{
|
||||
Byte *tempBuf[3] = { 0, 0, 0};
|
||||
int i;
|
||||
SRes res = SzDecode2(packSizes, folder,
|
||||
/*
|
||||
#ifdef _LZMA_IN_CB
|
||||
*/
|
||||
inStream, startPos,
|
||||
/*
|
||||
#else
|
||||
inBuffer,
|
||||
#endif
|
||||
*/
|
||||
outBuffer, outSize, allocMain, tempBuf);
|
||||
SRes res = SzDecode2(packSizes, folder, inStream, startPos,
|
||||
outBuffer, (SizeT)outSize, allocMain, tempBuf);
|
||||
for (i = 0; i < 3; i++)
|
||||
IAlloc_Free(allocMain, tempBuf[i]);
|
||||
return res;
|
||||
|
||||
Reference in New Issue
Block a user