gzdoom/libraries/lzma/C/7zDec.c

649 lines
16 KiB
C
Raw Normal View History

2016-03-01 15:47:10 +00:00
/* 7zDec.c -- Decoding from 7z folder
2023-04-02 : Igor Pavlov : Public domain */
2016-03-01 15:47:10 +00:00
#include "Precomp.h"
#include <string.h>
/* #define Z7_PPMD_SUPPORT */
2016-03-01 15:47:10 +00:00
#include "7z.h"
#include "7zCrc.h"
#include "Bcj2.h"
#include "Bra.h"
#include "CpuArch.h"
#include "Delta.h"
#include "LzmaDec.h"
#include "Lzma2Dec.h"
#ifdef Z7_PPMD_SUPPORT
2016-03-01 15:47:10 +00:00
#include "Ppmd7.h"
#endif
#define k_Copy 0
#ifndef Z7_NO_METHOD_LZMA2
2016-03-01 15:47:10 +00:00
#define k_LZMA2 0x21
#endif
2016-03-01 15:47:10 +00:00
#define k_LZMA 0x30101
#define k_BCJ2 0x303011B
#if !defined(Z7_NO_METHODS_FILTERS)
#define Z7_USE_BRANCH_FILTER
#endif
#if !defined(Z7_NO_METHODS_FILTERS) || \
defined(Z7_USE_NATIVE_BRANCH_FILTER) && defined(MY_CPU_ARM64)
#define Z7_USE_FILTER_ARM64
#ifndef Z7_USE_BRANCH_FILTER
#define Z7_USE_BRANCH_FILTER
#endif
#define k_ARM64 0xa
#endif
#if !defined(Z7_NO_METHODS_FILTERS) || \
defined(Z7_USE_NATIVE_BRANCH_FILTER) && defined(MY_CPU_ARMT)
#define Z7_USE_FILTER_ARMT
#ifndef Z7_USE_BRANCH_FILTER
#define Z7_USE_BRANCH_FILTER
#endif
#define k_ARMT 0x3030701
#endif
#ifndef Z7_NO_METHODS_FILTERS
#define k_Delta 3
#define k_BCJ 0x3030103
2016-03-01 15:47:10 +00:00
#define k_PPC 0x3030205
#define k_IA64 0x3030401
#define k_ARM 0x3030501
#define k_SPARC 0x3030805
#endif
2016-03-01 15:47:10 +00:00
#ifdef Z7_PPMD_SUPPORT
2016-03-01 15:47:10 +00:00
#define k_PPMD 0x30401
typedef struct
{
2018-01-08 12:00:01 +00:00
IByteIn vt;
2016-03-01 15:47:10 +00:00
const Byte *cur;
const Byte *end;
const Byte *begin;
UInt64 processed;
BoolInt extra;
2016-03-01 15:47:10 +00:00
SRes res;
ILookInStreamPtr inStream;
2016-03-01 15:47:10 +00:00
} CByteInToLook;
static Byte ReadByte(IByteInPtr pp)
2016-03-01 15:47:10 +00:00
{
Z7_CONTAINER_FROM_VTBL_TO_DECL_VAR_pp_vt_p(CByteInToLook)
2016-03-01 15:47:10 +00:00
if (p->cur != p->end)
return *p->cur++;
if (p->res == SZ_OK)
{
size_t size = (size_t)(p->cur - p->begin);
2016-03-01 15:47:10 +00:00
p->processed += size;
2018-01-08 12:00:01 +00:00
p->res = ILookInStream_Skip(p->inStream, size);
2016-03-01 15:47:10 +00:00
size = (1 << 25);
2018-01-08 12:00:01 +00:00
p->res = ILookInStream_Look(p->inStream, (const void **)&p->begin, &size);
2016-03-01 15:47:10 +00:00
p->cur = p->begin;
p->end = p->begin + size;
if (size != 0)
return *p->cur++;
2016-03-01 15:47:10 +00:00
}
p->extra = True;
return 0;
}
static SRes SzDecodePpmd(const Byte *props, unsigned propsSize, UInt64 inSize, ILookInStreamPtr inStream,
2018-01-08 12:00:01 +00:00
Byte *outBuffer, SizeT outSize, ISzAllocPtr allocMain)
2016-03-01 15:47:10 +00:00
{
CPpmd7 ppmd;
CByteInToLook s;
SRes res = SZ_OK;
2018-01-08 12:00:01 +00:00
s.vt.Read = ReadByte;
2016-03-01 15:47:10 +00:00
s.inStream = inStream;
s.begin = s.end = s.cur = NULL;
s.extra = False;
s.res = SZ_OK;
s.processed = 0;
if (propsSize != 5)
return SZ_ERROR_UNSUPPORTED;
{
unsigned order = props[0];
UInt32 memSize = GetUi32(props + 1);
if (order < PPMD7_MIN_ORDER ||
order > PPMD7_MAX_ORDER ||
memSize < PPMD7_MIN_MEM_SIZE ||
memSize > PPMD7_MAX_MEM_SIZE)
return SZ_ERROR_UNSUPPORTED;
Ppmd7_Construct(&ppmd);
if (!Ppmd7_Alloc(&ppmd, memSize, allocMain))
return SZ_ERROR_MEM;
Ppmd7_Init(&ppmd, order);
}
{
ppmd.rc.dec.Stream = &s.vt;
if (!Ppmd7z_RangeDec_Init(&ppmd.rc.dec))
2016-03-01 15:47:10 +00:00
res = SZ_ERROR_DATA;
else if (!s.extra)
2016-03-01 15:47:10 +00:00
{
Byte *buf = outBuffer;
const Byte *lim = buf + outSize;
for (; buf != lim; buf++)
2016-03-01 15:47:10 +00:00
{
int sym = Ppmd7z_DecodeSymbol(&ppmd);
2016-03-01 15:47:10 +00:00
if (s.extra || sym < 0)
break;
*buf = (Byte)sym;
2016-03-01 15:47:10 +00:00
}
if (buf != lim)
res = SZ_ERROR_DATA;
else if (!Ppmd7z_RangeDec_IsFinishedOK(&ppmd.rc.dec))
{
/* if (Ppmd7z_DecodeSymbol(&ppmd) != PPMD7_SYM_END || !Ppmd7z_RangeDec_IsFinishedOK(&ppmd.rc.dec)) */
2016-03-01 15:47:10 +00:00
res = SZ_ERROR_DATA;
}
2016-03-01 15:47:10 +00:00
}
if (s.extra)
res = (s.res != SZ_OK ? s.res : SZ_ERROR_DATA);
else if (s.processed + (size_t)(s.cur - s.begin) != inSize)
res = SZ_ERROR_DATA;
2016-03-01 15:47:10 +00:00
}
Ppmd7_Free(&ppmd, allocMain);
return res;
}
#endif
static SRes SzDecodeLzma(const Byte *props, unsigned propsSize, UInt64 inSize, ILookInStreamPtr inStream,
2018-01-08 12:00:01 +00:00
Byte *outBuffer, SizeT outSize, ISzAllocPtr allocMain)
2016-03-01 15:47:10 +00:00
{
CLzmaDec state;
SRes res = SZ_OK;
LzmaDec_CONSTRUCT(&state)
RINOK(LzmaDec_AllocateProbs(&state, props, propsSize, allocMain))
2016-03-01 15:47:10 +00:00
state.dic = outBuffer;
state.dicBufSize = outSize;
LzmaDec_Init(&state);
for (;;)
{
const void *inBuf = NULL;
size_t lookahead = (1 << 18);
if (lookahead > inSize)
lookahead = (size_t)inSize;
2018-01-08 12:00:01 +00:00
res = ILookInStream_Look(inStream, &inBuf, &lookahead);
2016-03-01 15:47:10 +00:00
if (res != SZ_OK)
break;
{
SizeT inProcessed = (SizeT)lookahead, dicPos = state.dicPos;
ELzmaStatus status;
res = LzmaDec_DecodeToDic(&state, outSize, (const Byte *)inBuf, &inProcessed, LZMA_FINISH_END, &status);
2016-03-01 15:47:10 +00:00
lookahead -= inProcessed;
inSize -= inProcessed;
if (res != SZ_OK)
break;
if (status == LZMA_STATUS_FINISHED_WITH_MARK)
{
if (outSize != state.dicPos || inSize != 0)
res = SZ_ERROR_DATA;
break;
}
if (outSize == state.dicPos && inSize == 0 && status == LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK)
break;
if (inProcessed == 0 && dicPos == state.dicPos)
{
res = SZ_ERROR_DATA;
break;
}
2018-01-08 12:00:01 +00:00
res = ILookInStream_Skip(inStream, inProcessed);
2016-03-01 15:47:10 +00:00
if (res != SZ_OK)
break;
}
}
LzmaDec_FreeProbs(&state, allocMain);
return res;
}
#ifndef Z7_NO_METHOD_LZMA2
2016-03-01 15:47:10 +00:00
static SRes SzDecodeLzma2(const Byte *props, unsigned propsSize, UInt64 inSize, ILookInStreamPtr inStream,
2018-01-08 12:00:01 +00:00
Byte *outBuffer, SizeT outSize, ISzAllocPtr allocMain)
2016-03-01 15:47:10 +00:00
{
CLzma2Dec state;
SRes res = SZ_OK;
Lzma2Dec_CONSTRUCT(&state)
2016-03-01 15:47:10 +00:00
if (propsSize != 1)
return SZ_ERROR_DATA;
RINOK(Lzma2Dec_AllocateProbs(&state, props[0], allocMain))
2016-03-01 15:47:10 +00:00
state.decoder.dic = outBuffer;
state.decoder.dicBufSize = outSize;
Lzma2Dec_Init(&state);
for (;;)
{
const void *inBuf = NULL;
size_t lookahead = (1 << 18);
if (lookahead > inSize)
lookahead = (size_t)inSize;
2018-01-08 12:00:01 +00:00
res = ILookInStream_Look(inStream, &inBuf, &lookahead);
2016-03-01 15:47:10 +00:00
if (res != SZ_OK)
break;
{
SizeT inProcessed = (SizeT)lookahead, dicPos = state.decoder.dicPos;
ELzmaStatus status;
res = Lzma2Dec_DecodeToDic(&state, outSize, (const Byte *)inBuf, &inProcessed, LZMA_FINISH_END, &status);
2016-03-01 15:47:10 +00:00
lookahead -= inProcessed;
inSize -= inProcessed;
if (res != SZ_OK)
break;
if (status == LZMA_STATUS_FINISHED_WITH_MARK)
{
if (outSize != state.decoder.dicPos || inSize != 0)
res = SZ_ERROR_DATA;
break;
}
if (inProcessed == 0 && dicPos == state.decoder.dicPos)
{
res = SZ_ERROR_DATA;
break;
}
2018-01-08 12:00:01 +00:00
res = ILookInStream_Skip(inStream, inProcessed);
2016-03-01 15:47:10 +00:00
if (res != SZ_OK)
break;
}
}
Lzma2Dec_FreeProbs(&state, allocMain);
return res;
}
#endif
static SRes SzDecodeCopy(UInt64 inSize, ILookInStreamPtr inStream, Byte *outBuffer)
2016-03-01 15:47:10 +00:00
{
while (inSize > 0)
{
const void *inBuf;
size_t curSize = (1 << 18);
if (curSize > inSize)
curSize = (size_t)inSize;
RINOK(ILookInStream_Look(inStream, &inBuf, &curSize))
2016-03-01 15:47:10 +00:00
if (curSize == 0)
return SZ_ERROR_INPUT_EOF;
memcpy(outBuffer, inBuf, curSize);
outBuffer += curSize;
inSize -= curSize;
RINOK(ILookInStream_Skip(inStream, curSize))
2016-03-01 15:47:10 +00:00
}
return SZ_OK;
}
static BoolInt IS_MAIN_METHOD(UInt32 m)
2016-03-01 15:47:10 +00:00
{
switch (m)
{
case k_Copy:
case k_LZMA:
#ifndef Z7_NO_METHOD_LZMA2
2016-03-01 15:47:10 +00:00
case k_LZMA2:
#endif
#ifdef Z7_PPMD_SUPPORT
2016-03-01 15:47:10 +00:00
case k_PPMD:
#endif
2016-03-01 15:47:10 +00:00
return True;
}
return False;
}
static BoolInt IS_SUPPORTED_CODER(const CSzCoderInfo *c)
2016-03-01 15:47:10 +00:00
{
return
c->NumStreams == 1
/* && c->MethodID <= (UInt32)0xFFFFFFFF */
&& IS_MAIN_METHOD((UInt32)c->MethodID);
}
#define IS_BCJ2(c) ((c)->MethodID == k_BCJ2 && (c)->NumStreams == 4)
static SRes CheckSupportedFolder(const CSzFolder *f)
{
if (f->NumCoders < 1 || f->NumCoders > 4)
return SZ_ERROR_UNSUPPORTED;
if (!IS_SUPPORTED_CODER(&f->Coders[0]))
return SZ_ERROR_UNSUPPORTED;
if (f->NumCoders == 1)
{
if (f->NumPackStreams != 1 || f->PackStreams[0] != 0 || f->NumBonds != 0)
return SZ_ERROR_UNSUPPORTED;
return SZ_OK;
}
#if defined(Z7_USE_BRANCH_FILTER)
2016-03-01 15:47:10 +00:00
if (f->NumCoders == 2)
{
const CSzCoderInfo *c = &f->Coders[1];
if (
/* c->MethodID > (UInt32)0xFFFFFFFF || */
c->NumStreams != 1
|| f->NumPackStreams != 1
|| f->PackStreams[0] != 0
|| f->NumBonds != 1
|| f->Bonds[0].InIndex != 1
|| f->Bonds[0].OutIndex != 0)
return SZ_ERROR_UNSUPPORTED;
switch ((UInt32)c->MethodID)
{
#if !defined(Z7_NO_METHODS_FILTERS)
2016-03-01 15:47:10 +00:00
case k_Delta:
case k_BCJ:
case k_PPC:
case k_IA64:
case k_SPARC:
case k_ARM:
#endif
#ifdef Z7_USE_FILTER_ARM64
case k_ARM64:
#endif
#ifdef Z7_USE_FILTER_ARMT
2016-03-01 15:47:10 +00:00
case k_ARMT:
#endif
2016-03-01 15:47:10 +00:00
break;
default:
return SZ_ERROR_UNSUPPORTED;
}
return SZ_OK;
}
#endif
if (f->NumCoders == 4)
{
if (!IS_SUPPORTED_CODER(&f->Coders[1])
|| !IS_SUPPORTED_CODER(&f->Coders[2])
|| !IS_BCJ2(&f->Coders[3]))
return SZ_ERROR_UNSUPPORTED;
if (f->NumPackStreams != 4
|| f->PackStreams[0] != 2
|| f->PackStreams[1] != 6
|| f->PackStreams[2] != 1
|| f->PackStreams[3] != 0
|| f->NumBonds != 3
|| f->Bonds[0].InIndex != 5 || f->Bonds[0].OutIndex != 0
|| f->Bonds[1].InIndex != 4 || f->Bonds[1].OutIndex != 1
|| f->Bonds[2].InIndex != 3 || f->Bonds[2].OutIndex != 2)
return SZ_ERROR_UNSUPPORTED;
return SZ_OK;
}
return SZ_ERROR_UNSUPPORTED;
}
2016-03-01 15:47:10 +00:00
static SRes SzFolder_Decode2(const CSzFolder *folder,
const Byte *propsData,
const UInt64 *unpackSizes,
const UInt64 *packPositions,
ILookInStreamPtr inStream, UInt64 startPos,
2018-01-08 12:00:01 +00:00
Byte *outBuffer, SizeT outSize, ISzAllocPtr allocMain,
2016-03-01 15:47:10 +00:00
Byte *tempBuf[])
{
UInt32 ci;
SizeT tempSizes[3] = { 0, 0, 0};
SizeT tempSize3 = 0;
Byte *tempBuf3 = 0;
RINOK(CheckSupportedFolder(folder))
2016-03-01 15:47:10 +00:00
for (ci = 0; ci < folder->NumCoders; ci++)
{
const CSzCoderInfo *coder = &folder->Coders[ci];
if (IS_MAIN_METHOD((UInt32)coder->MethodID))
{
UInt32 si = 0;
UInt64 offset;
UInt64 inSize;
Byte *outBufCur = outBuffer;
SizeT outSizeCur = outSize;
if (folder->NumCoders == 4)
{
const UInt32 indices[] = { 3, 2, 0 };
const UInt64 unpackSize = unpackSizes[ci];
2016-03-01 15:47:10 +00:00
si = indices[ci];
if (ci < 2)
{
Byte *temp;
outSizeCur = (SizeT)unpackSize;
if (outSizeCur != unpackSize)
return SZ_ERROR_MEM;
2018-01-08 12:00:01 +00:00
temp = (Byte *)ISzAlloc_Alloc(allocMain, outSizeCur);
2016-03-01 15:47:10 +00:00
if (!temp && 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 = packPositions[si];
2018-01-08 12:00:01 +00:00
inSize = packPositions[(size_t)si + 1] - offset;
RINOK(LookInStream_SeekTo(inStream, startPos + offset))
2016-03-01 15:47:10 +00:00
if (coder->MethodID == k_Copy)
{
if (inSize != outSizeCur) /* check it */
return SZ_ERROR_DATA;
RINOK(SzDecodeCopy(inSize, inStream, outBufCur))
2016-03-01 15:47:10 +00:00
}
else if (coder->MethodID == k_LZMA)
{
RINOK(SzDecodeLzma(propsData + coder->PropsOffset, coder->PropsSize, inSize, inStream, outBufCur, outSizeCur, allocMain))
2016-03-01 15:47:10 +00:00
}
#ifndef Z7_NO_METHOD_LZMA2
2016-03-01 15:47:10 +00:00
else if (coder->MethodID == k_LZMA2)
{
RINOK(SzDecodeLzma2(propsData + coder->PropsOffset, coder->PropsSize, inSize, inStream, outBufCur, outSizeCur, allocMain))
2016-03-01 15:47:10 +00:00
}
#endif
#ifdef Z7_PPMD_SUPPORT
2016-03-01 15:47:10 +00:00
else if (coder->MethodID == k_PPMD)
{
RINOK(SzDecodePpmd(propsData + coder->PropsOffset, coder->PropsSize, inSize, inStream, outBufCur, outSizeCur, allocMain))
2016-03-01 15:47:10 +00:00
}
#endif
2016-03-01 15:47:10 +00:00
else
return SZ_ERROR_UNSUPPORTED;
}
else if (coder->MethodID == k_BCJ2)
{
const UInt64 offset = packPositions[1];
const UInt64 s3Size = packPositions[2] - offset;
2016-03-01 15:47:10 +00:00
if (ci != 3)
return SZ_ERROR_UNSUPPORTED;
tempSizes[2] = (SizeT)s3Size;
if (tempSizes[2] != s3Size)
return SZ_ERROR_MEM;
2018-01-08 12:00:01 +00:00
tempBuf[2] = (Byte *)ISzAlloc_Alloc(allocMain, tempSizes[2]);
2016-03-01 15:47:10 +00:00
if (!tempBuf[2] && tempSizes[2] != 0)
return SZ_ERROR_MEM;
RINOK(LookInStream_SeekTo(inStream, startPos + offset))
RINOK(SzDecodeCopy(s3Size, inStream, tempBuf[2]))
2016-03-01 15:47:10 +00:00
if ((tempSizes[0] & 3) != 0 ||
(tempSizes[1] & 3) != 0 ||
tempSize3 + tempSizes[0] + tempSizes[1] != outSize)
return SZ_ERROR_DATA;
{
CBcj2Dec p;
p.bufs[0] = tempBuf3; p.lims[0] = tempBuf3 + tempSize3;
p.bufs[1] = tempBuf[0]; p.lims[1] = tempBuf[0] + tempSizes[0];
p.bufs[2] = tempBuf[1]; p.lims[2] = tempBuf[1] + tempSizes[1];
p.bufs[3] = tempBuf[2]; p.lims[3] = tempBuf[2] + tempSizes[2];
p.dest = outBuffer;
p.destLim = outBuffer + outSize;
Bcj2Dec_Init(&p);
RINOK(Bcj2Dec_Decode(&p))
2016-03-01 15:47:10 +00:00
{
unsigned i;
for (i = 0; i < 4; i++)
if (p.bufs[i] != p.lims[i])
return SZ_ERROR_DATA;
if (p.dest != p.destLim || !Bcj2Dec_IsMaybeFinished(&p))
2016-03-01 15:47:10 +00:00
return SZ_ERROR_DATA;
}
}
}
#if defined(Z7_USE_BRANCH_FILTER)
2016-03-01 15:47:10 +00:00
else if (ci == 1)
{
#if !defined(Z7_NO_METHODS_FILTERS)
2016-03-01 15:47:10 +00:00
if (coder->MethodID == k_Delta)
{
if (coder->PropsSize != 1)
return SZ_ERROR_UNSUPPORTED;
{
Byte state[DELTA_STATE_SIZE];
Delta_Init(state);
Delta_Decode(state, (unsigned)(propsData[coder->PropsOffset]) + 1, outBuffer, outSize);
}
continue;
2016-03-01 15:47:10 +00:00
}
#endif
#ifdef Z7_USE_FILTER_ARM64
if (coder->MethodID == k_ARM64)
{
UInt32 pc = 0;
if (coder->PropsSize == 4)
pc = GetUi32(propsData + coder->PropsOffset);
else if (coder->PropsSize != 0)
return SZ_ERROR_UNSUPPORTED;
z7_BranchConv_ARM64_Dec(outBuffer, outSize, pc);
continue;
}
#endif
#if !defined(Z7_NO_METHODS_FILTERS) || defined(Z7_USE_FILTER_ARMT)
2016-03-01 15:47:10 +00:00
{
if (coder->PropsSize != 0)
return SZ_ERROR_UNSUPPORTED;
#define CASE_BRA_CONV(isa) case k_ ## isa: Z7_BRANCH_CONV_DEC(isa)(outBuffer, outSize, 0); break; // pc = 0;
2016-03-01 15:47:10 +00:00
switch (coder->MethodID)
{
#if !defined(Z7_NO_METHODS_FILTERS)
2016-03-01 15:47:10 +00:00
case k_BCJ:
{
UInt32 state = Z7_BRANCH_CONV_ST_X86_STATE_INIT_VAL;
z7_BranchConvSt_X86_Dec(outBuffer, outSize, 0, &state); // pc = 0
2016-03-01 15:47:10 +00:00
break;
}
CASE_BRA_CONV(PPC)
CASE_BRA_CONV(IA64)
CASE_BRA_CONV(SPARC)
CASE_BRA_CONV(ARM)
#endif
#if !defined(Z7_NO_METHODS_FILTERS) || defined(Z7_USE_FILTER_ARMT)
2016-03-01 15:47:10 +00:00
CASE_BRA_CONV(ARMT)
#endif
2016-03-01 15:47:10 +00:00
default:
return SZ_ERROR_UNSUPPORTED;
}
continue;
2016-03-01 15:47:10 +00:00
}
#endif
} // (c == 1)
#endif
2016-03-01 15:47:10 +00:00
else
return SZ_ERROR_UNSUPPORTED;
}
return SZ_OK;
}
SRes SzAr_DecodeFolder(const CSzAr *p, UInt32 folderIndex,
ILookInStreamPtr inStream, UInt64 startPos,
2016-03-01 15:47:10 +00:00
Byte *outBuffer, size_t outSize,
2018-01-08 12:00:01 +00:00
ISzAllocPtr allocMain)
2016-03-01 15:47:10 +00:00
{
SRes res;
CSzFolder folder;
CSzData sd;
const Byte *data = p->CodersData + p->FoCodersOffsets[folderIndex];
sd.Data = data;
2018-01-08 12:00:01 +00:00
sd.Size = p->FoCodersOffsets[(size_t)folderIndex + 1] - p->FoCodersOffsets[folderIndex];
2016-03-01 15:47:10 +00:00
res = SzGetNextFolderItem(&folder, &sd);
if (res != SZ_OK)
return res;
if (sd.Size != 0
|| folder.UnpackStream != p->FoToMainUnpackSizeIndex[folderIndex]
|| outSize != SzAr_GetFolderUnpackSize(p, folderIndex))
return SZ_ERROR_FAIL;
{
unsigned i;
Byte *tempBuf[3] = { 0, 0, 0};
res = SzFolder_Decode2(&folder, data,
&p->CoderUnpackSizes[p->FoToCoderUnpackSizes[folderIndex]],
p->PackPositions + p->FoStartPackStreamIndex[folderIndex],
inStream, startPos,
outBuffer, (SizeT)outSize, allocMain, tempBuf);
for (i = 0; i < 3; i++)
2018-01-08 12:00:01 +00:00
ISzAlloc_Free(allocMain, tempBuf[i]);
2016-03-01 15:47:10 +00:00
if (res == SZ_OK)
if (SzBitWithVals_Check(&p->FolderCRCs, folderIndex))
if (CrcCalc(outBuffer, outSize) != p->FolderCRCs.Vals[folderIndex])
res = SZ_ERROR_CRC;
return res;
}
}