00cc9309cb
de6e324bdseparate emu thread10d3daf86Roms List improvements95d202f37Let's make the rom list process on a separate thread so the emulator doesnt take ages to load.fc306967fWow the ROM Header was just completely busted. Game list view works nowbad1691eefuck this shit2b59e5f46game list in progressd26417b83remappable inputs in progressac4af8106inpute72abc240update readme430139dc9Qt6 frontend3080d4d45Fix this small bug too08cd13b85Cop0 unused functions do not actually pose a threat (as per manual). They don't do anything, so shall we.61bb4fb44make idle loop detection a little more specific with where the load goesb037de4c3SAZDFsdff12e81e73eneed to figure out why n64-systemtest loops indefinitely at some address that appears to be valid (i think it's me not invalidating the cache properly)204f0e13bidle skipping seems to work!cb8bb634asdkfjlasdf58e5c89c1Fix compilation issue on my machine (no idea)24fb2898eattempting more serious idle skipping214719577Place rsp.Step inside cached interpreter. Gains about 3 more fpsbb97dcc23mmmmm920b77d38wjkhasdfjhkasdf430ccdab4it's a start...4f42a673aCached interpreter plays Mario 64. Start looking into RSP as wellc9a030787idle skipping works!5fbda03cenew idea366637abaIdle skipping... maybe?609fa2fb0Cache instructions implemented but broken lmao. Commented out for nowe140a6d12- Stop using inheritance for CPU, instead use composition. - Introduce KAIZEN_JIT_ENABLED optional define instead of relying on __aarch64__ and the like. - More cache work68e613057prep cache impl811b4d809fix clang formatfda755f7didkd5024ebbfsmall MI refactor in preparation of (eventually) implementing the RDRAM interface properly694b45341Merge commit '206dcdedf195fb320913584180edb12c7731e396' as 'external/SDL'206dcdedfSquashed 'external/SDL/' content from commit 4d17b99d0a4d16e1cb4need to update sdl848b19920Fix compilation errordb61b5299Merge commit 'e94a94559f28e49678fbcf72199a5258137b0fe9' as 'external/imgui'e94a94559Squashed 'external/imgui/' content from commit 02e9b8cac52edb3757need to update imguic1a705e86Emulate weird JALR behaviour4b4c32f4bFix exception for "unusable COP1" in 4 instructions i missed accidentally (again)df5828142Bug putting 0s in the log everywheref8b580048Make isviewer a sink to file8241e9735Fix exception for "unusable COP1" in 4 instructions i missed accidentallyb29715f20small changesd9a620bc1make use of my new small utility library0d1aa938eAdd 'external/ircolib/' from commit 'ce3cd726c8df8388d554abf8bb55d55020eb4450'e64eb40b3Fuck git git-subtree-dir: external/ircolib git-subtree-split:de6e324bde
649 lines
16 KiB
C
649 lines
16 KiB
C
/* 7zDec.c -- Decoding from 7z folder
|
|
2023-04-02 : Igor Pavlov : Public domain */
|
|
|
|
#include "Precomp.h"
|
|
|
|
#include <string.h>
|
|
|
|
/* #define Z7_PPMD_SUPPORT */
|
|
|
|
#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
|
|
#include "Ppmd7.h"
|
|
#endif
|
|
|
|
#define k_Copy 0
|
|
#ifndef Z7_NO_METHOD_LZMA2
|
|
#define k_LZMA2 0x21
|
|
#endif
|
|
#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
|
|
#define k_PPC 0x3030205
|
|
#define k_IA64 0x3030401
|
|
#define k_ARM 0x3030501
|
|
#define k_SPARC 0x3030805
|
|
#endif
|
|
|
|
#ifdef Z7_PPMD_SUPPORT
|
|
|
|
#define k_PPMD 0x30401
|
|
|
|
typedef struct
|
|
{
|
|
IByteIn vt;
|
|
const Byte *cur;
|
|
const Byte *end;
|
|
const Byte *begin;
|
|
UInt64 processed;
|
|
BoolInt extra;
|
|
SRes res;
|
|
ILookInStreamPtr inStream;
|
|
} CByteInToLook;
|
|
|
|
static Byte ReadByte(IByteInPtr pp)
|
|
{
|
|
Z7_CONTAINER_FROM_VTBL_TO_DECL_VAR_pp_vt_p(CByteInToLook)
|
|
if (p->cur != p->end)
|
|
return *p->cur++;
|
|
if (p->res == SZ_OK)
|
|
{
|
|
size_t size = (size_t)(p->cur - p->begin);
|
|
p->processed += size;
|
|
p->res = ILookInStream_Skip(p->inStream, size);
|
|
size = (1 << 25);
|
|
p->res = ILookInStream_Look(p->inStream, (const void **)&p->begin, &size);
|
|
p->cur = p->begin;
|
|
p->end = p->begin + size;
|
|
if (size != 0)
|
|
return *p->cur++;
|
|
}
|
|
p->extra = True;
|
|
return 0;
|
|
}
|
|
|
|
static SRes SzDecodePpmd(const Byte *props, unsigned propsSize, UInt64 inSize, ILookInStreamPtr inStream,
|
|
Byte *outBuffer, SizeT outSize, ISzAllocPtr allocMain)
|
|
{
|
|
CPpmd7 ppmd;
|
|
CByteInToLook s;
|
|
SRes res = SZ_OK;
|
|
|
|
s.vt.Read = ReadByte;
|
|
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))
|
|
res = SZ_ERROR_DATA;
|
|
else if (!s.extra)
|
|
{
|
|
Byte *buf = outBuffer;
|
|
const Byte *lim = buf + outSize;
|
|
for (; buf != lim; buf++)
|
|
{
|
|
int sym = Ppmd7z_DecodeSymbol(&ppmd);
|
|
if (s.extra || sym < 0)
|
|
break;
|
|
*buf = (Byte)sym;
|
|
}
|
|
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)) */
|
|
res = SZ_ERROR_DATA;
|
|
}
|
|
}
|
|
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;
|
|
}
|
|
Ppmd7_Free(&ppmd, allocMain);
|
|
return res;
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
static SRes SzDecodeLzma(const Byte *props, unsigned propsSize, UInt64 inSize, ILookInStreamPtr inStream,
|
|
Byte *outBuffer, SizeT outSize, ISzAllocPtr allocMain)
|
|
{
|
|
CLzmaDec state;
|
|
SRes res = SZ_OK;
|
|
|
|
LzmaDec_CONSTRUCT(&state)
|
|
RINOK(LzmaDec_AllocateProbs(&state, props, propsSize, allocMain))
|
|
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;
|
|
res = ILookInStream_Look(inStream, &inBuf, &lookahead);
|
|
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);
|
|
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;
|
|
}
|
|
|
|
res = ILookInStream_Skip(inStream, inProcessed);
|
|
if (res != SZ_OK)
|
|
break;
|
|
}
|
|
}
|
|
|
|
LzmaDec_FreeProbs(&state, allocMain);
|
|
return res;
|
|
}
|
|
|
|
|
|
#ifndef Z7_NO_METHOD_LZMA2
|
|
|
|
static SRes SzDecodeLzma2(const Byte *props, unsigned propsSize, UInt64 inSize, ILookInStreamPtr inStream,
|
|
Byte *outBuffer, SizeT outSize, ISzAllocPtr allocMain)
|
|
{
|
|
CLzma2Dec state;
|
|
SRes res = SZ_OK;
|
|
|
|
Lzma2Dec_CONSTRUCT(&state)
|
|
if (propsSize != 1)
|
|
return SZ_ERROR_DATA;
|
|
RINOK(Lzma2Dec_AllocateProbs(&state, props[0], allocMain))
|
|
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;
|
|
res = ILookInStream_Look(inStream, &inBuf, &lookahead);
|
|
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);
|
|
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;
|
|
}
|
|
|
|
res = ILookInStream_Skip(inStream, inProcessed);
|
|
if (res != SZ_OK)
|
|
break;
|
|
}
|
|
}
|
|
|
|
Lzma2Dec_FreeProbs(&state, allocMain);
|
|
return res;
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
static SRes SzDecodeCopy(UInt64 inSize, ILookInStreamPtr inStream, Byte *outBuffer)
|
|
{
|
|
while (inSize > 0)
|
|
{
|
|
const void *inBuf;
|
|
size_t curSize = (1 << 18);
|
|
if (curSize > inSize)
|
|
curSize = (size_t)inSize;
|
|
RINOK(ILookInStream_Look(inStream, &inBuf, &curSize))
|
|
if (curSize == 0)
|
|
return SZ_ERROR_INPUT_EOF;
|
|
memcpy(outBuffer, inBuf, curSize);
|
|
outBuffer += curSize;
|
|
inSize -= curSize;
|
|
RINOK(ILookInStream_Skip(inStream, curSize))
|
|
}
|
|
return SZ_OK;
|
|
}
|
|
|
|
static BoolInt IS_MAIN_METHOD(UInt32 m)
|
|
{
|
|
switch (m)
|
|
{
|
|
case k_Copy:
|
|
case k_LZMA:
|
|
#ifndef Z7_NO_METHOD_LZMA2
|
|
case k_LZMA2:
|
|
#endif
|
|
#ifdef Z7_PPMD_SUPPORT
|
|
case k_PPMD:
|
|
#endif
|
|
return True;
|
|
}
|
|
return False;
|
|
}
|
|
|
|
static BoolInt IS_SUPPORTED_CODER(const CSzCoderInfo *c)
|
|
{
|
|
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)
|
|
|
|
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)
|
|
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
|
|
case k_ARMT:
|
|
#endif
|
|
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;
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static SRes SzFolder_Decode2(const CSzFolder *folder,
|
|
const Byte *propsData,
|
|
const UInt64 *unpackSizes,
|
|
const UInt64 *packPositions,
|
|
ILookInStreamPtr inStream, UInt64 startPos,
|
|
Byte *outBuffer, SizeT outSize, ISzAllocPtr 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++)
|
|
{
|
|
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];
|
|
si = indices[ci];
|
|
if (ci < 2)
|
|
{
|
|
Byte *temp;
|
|
outSizeCur = (SizeT)unpackSize;
|
|
if (outSizeCur != unpackSize)
|
|
return SZ_ERROR_MEM;
|
|
temp = (Byte *)ISzAlloc_Alloc(allocMain, outSizeCur);
|
|
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];
|
|
inSize = packPositions[(size_t)si + 1] - offset;
|
|
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 if (coder->MethodID == k_LZMA)
|
|
{
|
|
RINOK(SzDecodeLzma(propsData + coder->PropsOffset, coder->PropsSize, inSize, inStream, outBufCur, outSizeCur, allocMain))
|
|
}
|
|
#ifndef Z7_NO_METHOD_LZMA2
|
|
else if (coder->MethodID == k_LZMA2)
|
|
{
|
|
RINOK(SzDecodeLzma2(propsData + coder->PropsOffset, coder->PropsSize, inSize, inStream, outBufCur, outSizeCur, allocMain))
|
|
}
|
|
#endif
|
|
#ifdef Z7_PPMD_SUPPORT
|
|
else if (coder->MethodID == k_PPMD)
|
|
{
|
|
RINOK(SzDecodePpmd(propsData + coder->PropsOffset, coder->PropsSize, inSize, inStream, outBufCur, outSizeCur, allocMain))
|
|
}
|
|
#endif
|
|
else
|
|
return SZ_ERROR_UNSUPPORTED;
|
|
}
|
|
else if (coder->MethodID == k_BCJ2)
|
|
{
|
|
const UInt64 offset = packPositions[1];
|
|
const UInt64 s3Size = packPositions[2] - offset;
|
|
|
|
if (ci != 3)
|
|
return SZ_ERROR_UNSUPPORTED;
|
|
|
|
tempSizes[2] = (SizeT)s3Size;
|
|
if (tempSizes[2] != s3Size)
|
|
return SZ_ERROR_MEM;
|
|
tempBuf[2] = (Byte *)ISzAlloc_Alloc(allocMain, tempSizes[2]);
|
|
if (!tempBuf[2] && tempSizes[2] != 0)
|
|
return SZ_ERROR_MEM;
|
|
|
|
RINOK(LookInStream_SeekTo(inStream, startPos + offset))
|
|
RINOK(SzDecodeCopy(s3Size, inStream, tempBuf[2]))
|
|
|
|
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))
|
|
|
|
{
|
|
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))
|
|
return SZ_ERROR_DATA;
|
|
}
|
|
}
|
|
}
|
|
#if defined(Z7_USE_BRANCH_FILTER)
|
|
else if (ci == 1)
|
|
{
|
|
#if !defined(Z7_NO_METHODS_FILTERS)
|
|
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;
|
|
}
|
|
#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)
|
|
{
|
|
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;
|
|
switch (coder->MethodID)
|
|
{
|
|
#if !defined(Z7_NO_METHODS_FILTERS)
|
|
case k_BCJ:
|
|
{
|
|
UInt32 state = Z7_BRANCH_CONV_ST_X86_STATE_INIT_VAL;
|
|
z7_BranchConvSt_X86_Dec(outBuffer, outSize, 0, &state); // pc = 0
|
|
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)
|
|
CASE_BRA_CONV(ARMT)
|
|
#endif
|
|
default:
|
|
return SZ_ERROR_UNSUPPORTED;
|
|
}
|
|
continue;
|
|
}
|
|
#endif
|
|
} // (c == 1)
|
|
#endif
|
|
else
|
|
return SZ_ERROR_UNSUPPORTED;
|
|
}
|
|
|
|
return SZ_OK;
|
|
}
|
|
|
|
|
|
SRes SzAr_DecodeFolder(const CSzAr *p, UInt32 folderIndex,
|
|
ILookInStreamPtr inStream, UInt64 startPos,
|
|
Byte *outBuffer, size_t outSize,
|
|
ISzAllocPtr allocMain)
|
|
{
|
|
SRes res;
|
|
CSzFolder folder;
|
|
CSzData sd;
|
|
|
|
const Byte *data = p->CodersData + p->FoCodersOffsets[folderIndex];
|
|
sd.Data = data;
|
|
sd.Size = p->FoCodersOffsets[(size_t)folderIndex + 1] - p->FoCodersOffsets[folderIndex];
|
|
|
|
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++)
|
|
ISzAlloc_Free(allocMain, tempBuf[i]);
|
|
|
|
if (res == SZ_OK)
|
|
if (SzBitWithVals_Check(&p->FolderCRCs, folderIndex))
|
|
if (CrcCalc(outBuffer, outSize) != p->FolderCRCs.Vals[folderIndex])
|
|
res = SZ_ERROR_CRC;
|
|
|
|
return res;
|
|
}
|
|
}
|