15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* 7zDec.c -- Decoding from 7z folder 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)2010-11-02 : Igor Pavlov : Public domain */ 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <string.h> 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* #define _7ZIP_PPMD_SUPPPORT */ 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "7z.h" 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "Bcj2.h" 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "Bra.h" 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "CpuArch.h" 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "LzmaDec.h" 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "Lzma2Dec.h" 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef _7ZIP_PPMD_SUPPPORT 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "Ppmd7.h" 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define k_Copy 0 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define k_LZMA2 0x21 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define k_LZMA 0x30101 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define k_BCJ 0x03030103 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define k_PPC 0x03030205 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define k_ARM 0x03030501 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define k_ARMT 0x03030701 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define k_SPARC 0x03030805 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define k_BCJ2 0x0303011B 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef _7ZIP_PPMD_SUPPPORT 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define k_PPMD 0x30401 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)typedef struct 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) IByteIn p; 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const Byte *cur; 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const Byte *end; 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const Byte *begin; 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) UInt64 processed; 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Bool extra; 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SRes res; 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ILookInStream *inStream; 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} CByteInToLook; 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static Byte ReadByte(void *pp) 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CByteInToLook *p = (CByteInToLook *)pp; 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (p->cur != p->end) 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return *p->cur++; 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (p->res == SZ_OK) 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size_t size = p->cur - p->begin; 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) p->processed += size; 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) p->res = p->inStream->Skip(p->inStream, size); 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size = (1 << 25); 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) p->res = p->inStream->Look(p->inStream, (const void **)&p->begin, &size); 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) p->cur = p->begin; 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) p->end = p->begin + size; 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (size != 0) 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return *p->cur++;; 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) p->extra = True; 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return 0; 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static SRes SzDecodePpmd(CSzCoderInfo *coder, UInt64 inSize, ILookInStream *inStream, 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Byte *outBuffer, SizeT outSize, ISzAlloc *allocMain) 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CPpmd7 ppmd; 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CByteInToLook s; 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SRes res = SZ_OK; 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) s.p.Read = ReadByte; 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) s.inStream = inStream; 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) s.begin = s.end = s.cur = NULL; 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) s.extra = False; 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) s.res = SZ_OK; 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) s.processed = 0; 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (coder->Props.size != 5) 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SZ_ERROR_UNSUPPORTED; 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned order = coder->Props.data[0]; 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) UInt32 memSize = GetUi32(coder->Props.data + 1); 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (order < PPMD7_MIN_ORDER || 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) order > PPMD7_MAX_ORDER || 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) memSize < PPMD7_MIN_MEM_SIZE || 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) memSize > PPMD7_MAX_MEM_SIZE) 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SZ_ERROR_UNSUPPORTED; 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Ppmd7_Construct(&ppmd); 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!Ppmd7_Alloc(&ppmd, memSize, allocMain)) 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SZ_ERROR_MEM; 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Ppmd7_Init(&ppmd, order); 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CPpmd7z_RangeDec rc; 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Ppmd7z_RangeDec_CreateVTable(&rc); 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rc.Stream = &s.p; 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!Ppmd7z_RangeDec_Init(&rc)) 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) res = SZ_ERROR_DATA; 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else if (s.extra) 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) res = (s.res != SZ_OK ? s.res : SZ_ERROR_DATA); 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SizeT i; 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (i = 0; i < outSize; i++) 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int sym = Ppmd7_DecodeSymbol(&ppmd, &rc.p); 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (s.extra || sym < 0) 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) outBuffer[i] = (Byte)sym; 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (i != outSize) 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) res = (s.res != SZ_OK ? s.res : SZ_ERROR_DATA); 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else if (s.processed + (s.cur - s.begin) != inSize || !Ppmd7z_RangeDec_IsFinishedOK(&rc)) 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) res = SZ_ERROR_DATA; 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Ppmd7_Free(&ppmd, allocMain); 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return res; 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static SRes SzDecodeLzma(CSzCoderInfo *coder, UInt64 inSize, ILookInStream *inStream, 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Byte *outBuffer, SizeT outSize, ISzAlloc *allocMain) 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CLzmaDec state; 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SRes res = SZ_OK; 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LzmaDec_Construct(&state); 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) RINOK(LzmaDec_AllocateProbs(&state, coder->Props.data, (unsigned)coder->Props.size, allocMain)); 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) state.dic = outBuffer; 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) state.dicBufSize = outSize; 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LzmaDec_Init(&state); 1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (;;) 1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Byte *inBuf = NULL; 1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size_t lookahead = (1 << 18); 1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (lookahead > inSize) 1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) lookahead = (size_t)inSize; 1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) res = inStream->Look((void *)inStream, (const void **)&inBuf, &lookahead); 1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (res != SZ_OK) 1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SizeT inProcessed = (SizeT)lookahead, dicPos = state.dicPos; 1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ELzmaStatus status; 1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) res = LzmaDec_DecodeToDic(&state, outSize, inBuf, &inProcessed, LZMA_FINISH_END, &status); 1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) lookahead -= inProcessed; 1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) inSize -= inProcessed; 1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (res != SZ_OK) 1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (state.dicPos == state.dicBufSize || (inProcessed == 0 && dicPos == state.dicPos)) 1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (state.dicBufSize != outSize || lookahead != 0 || 1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (status != LZMA_STATUS_FINISHED_WITH_MARK && 1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) status != LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK)) 1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) res = SZ_ERROR_DATA; 1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) res = inStream->Skip((void *)inStream, inProcessed); 1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (res != SZ_OK) 1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LzmaDec_FreeProbs(&state, allocMain); 1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return res; 1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static SRes SzDecodeLzma2(CSzCoderInfo *coder, UInt64 inSize, ILookInStream *inStream, 1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Byte *outBuffer, SizeT outSize, ISzAlloc *allocMain) 1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CLzma2Dec state; 1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SRes res = SZ_OK; 1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Lzma2Dec_Construct(&state); 1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (coder->Props.size != 1) 1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SZ_ERROR_DATA; 1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) RINOK(Lzma2Dec_AllocateProbs(&state, coder->Props.data[0], allocMain)); 1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) state.decoder.dic = outBuffer; 1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) state.decoder.dicBufSize = outSize; 1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Lzma2Dec_Init(&state); 1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (;;) 1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Byte *inBuf = NULL; 1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size_t lookahead = (1 << 18); 1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (lookahead > inSize) 1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) lookahead = (size_t)inSize; 1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) res = inStream->Look((void *)inStream, (const void **)&inBuf, &lookahead); 1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (res != SZ_OK) 1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SizeT inProcessed = (SizeT)lookahead, dicPos = state.decoder.dicPos; 2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ELzmaStatus status; 2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) res = Lzma2Dec_DecodeToDic(&state, outSize, inBuf, &inProcessed, LZMA_FINISH_END, &status); 2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) lookahead -= inProcessed; 2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) inSize -= inProcessed; 2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (res != SZ_OK) 2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (state.decoder.dicPos == state.decoder.dicBufSize || (inProcessed == 0 && dicPos == state.decoder.dicPos)) 2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (state.decoder.dicBufSize != outSize || lookahead != 0 || 2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (status != LZMA_STATUS_FINISHED_WITH_MARK)) 2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) res = SZ_ERROR_DATA; 2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) res = inStream->Skip((void *)inStream, inProcessed); 2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (res != SZ_OK) 2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Lzma2Dec_FreeProbs(&state, allocMain); 2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return res; 2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static SRes SzDecodeCopy(UInt64 inSize, ILookInStream *inStream, Byte *outBuffer) 2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) while (inSize > 0) 2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void *inBuf; 2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size_t curSize = (1 << 18); 2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (curSize > inSize) 2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) curSize = (size_t)inSize; 2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) RINOK(inStream->Look((void *)inStream, (const void **)&inBuf, &curSize)); 2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (curSize == 0) 2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SZ_ERROR_INPUT_EOF; 2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) memcpy(outBuffer, inBuf, curSize); 2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) outBuffer += curSize; 2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) inSize -= curSize; 2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) RINOK(inStream->Skip((void *)inStream, curSize)); 2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SZ_OK; 2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static Bool IS_MAIN_METHOD(UInt32 m) 2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switch(m) 2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case k_Copy: 2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case k_LZMA: 2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case k_LZMA2: 2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #ifdef _7ZIP_PPMD_SUPPPORT 2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case k_PPMD: 2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #endif 2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return True; 2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return False; 2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static Bool IS_SUPPORTED_CODER(const CSzCoderInfo *c) 2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return 2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) c->NumInStreams == 1 && 2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) c->NumOutStreams == 1 && 2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) c->MethodID <= (UInt32)0xFFFFFFFF && 2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) IS_MAIN_METHOD((UInt32)c->MethodID); 2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define IS_BCJ2(c) ((c)->MethodID == k_BCJ2 && (c)->NumInStreams == 4 && (c)->NumOutStreams == 1) 2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static SRes CheckSupportedFolder(const CSzFolder *f) 2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (f->NumCoders < 1 || f->NumCoders > 4) 2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SZ_ERROR_UNSUPPORTED; 2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!IS_SUPPORTED_CODER(&f->Coders[0])) 2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SZ_ERROR_UNSUPPORTED; 2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (f->NumCoders == 1) 2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (f->NumPackStreams != 1 || f->PackStreams[0] != 0 || f->NumBindPairs != 0) 2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SZ_ERROR_UNSUPPORTED; 2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SZ_OK; 2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (f->NumCoders == 2) 2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CSzCoderInfo *c = &f->Coders[1]; 2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (c->MethodID > (UInt32)0xFFFFFFFF || 2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) c->NumInStreams != 1 || 2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) c->NumOutStreams != 1 || 2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) f->NumPackStreams != 1 || 2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) f->PackStreams[0] != 0 || 2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) f->NumBindPairs != 1 || 2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) f->BindPairs[0].InIndex != 1 || 2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) f->BindPairs[0].OutIndex != 0) 2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SZ_ERROR_UNSUPPORTED; 2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switch ((UInt32)c->MethodID) 2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case k_BCJ: 2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case k_ARM: 2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) default: 2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SZ_ERROR_UNSUPPORTED; 3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SZ_OK; 3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (f->NumCoders == 4) 3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!IS_SUPPORTED_CODER(&f->Coders[1]) || 3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) !IS_SUPPORTED_CODER(&f->Coders[2]) || 3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) !IS_BCJ2(&f->Coders[3])) 3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SZ_ERROR_UNSUPPORTED; 3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (f->NumPackStreams != 4 || 3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) f->PackStreams[0] != 2 || 3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) f->PackStreams[1] != 6 || 3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) f->PackStreams[2] != 1 || 3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) f->PackStreams[3] != 0 || 3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) f->NumBindPairs != 3 || 3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) f->BindPairs[0].InIndex != 5 || f->BindPairs[0].OutIndex != 0 || 3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) f->BindPairs[1].InIndex != 4 || f->BindPairs[1].OutIndex != 1 || 3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) f->BindPairs[2].InIndex != 3 || f->BindPairs[2].OutIndex != 2) 3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SZ_ERROR_UNSUPPORTED; 3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SZ_OK; 3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SZ_ERROR_UNSUPPORTED; 3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static UInt64 GetSum(const UInt64 *values, UInt32 index) 3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) UInt64 sum = 0; 3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) UInt32 i; 3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (i = 0; i < index; i++) 3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sum += values[i]; 3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return sum; 3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define CASE_BRA_CONV(isa) case k_ ## isa: isa ## _Convert(outBuffer, outSize, 0, 0); break; 3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static SRes SzFolder_Decode2(const CSzFolder *folder, const UInt64 *packSizes, 3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ILookInStream *inStream, UInt64 startPos, 3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Byte *outBuffer, SizeT outSize, ISzAlloc *allocMain, 3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Byte *tempBuf[]) 3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) UInt32 ci; 3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SizeT tempSizes[3] = { 0, 0, 0}; 3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SizeT tempSize3 = 0; 3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Byte *tempBuf3 = 0; 3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) RINOK(CheckSupportedFolder(folder)); 3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (ci = 0; ci < folder->NumCoders; ci++) 3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CSzCoderInfo *coder = &folder->Coders[ci]; 3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (IS_MAIN_METHOD((UInt32)coder->MethodID)) 3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) UInt32 si = 0; 3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) UInt64 offset; 3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) UInt64 inSize; 3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Byte *outBufCur = outBuffer; 3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SizeT outSizeCur = outSize; 3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (folder->NumCoders == 4) 3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) UInt32 indices[] = { 3, 2, 0 }; 3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) UInt64 unpackSize = folder->UnpackSizes[ci]; 3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) si = indices[ci]; 3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ci < 2) 3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Byte *temp; 3665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) outSizeCur = (SizeT)unpackSize; 3675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (outSizeCur != unpackSize) 3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SZ_ERROR_MEM; 3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) temp = (Byte *)IAlloc_Alloc(allocMain, outSizeCur); 3705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (temp == 0 && outSizeCur != 0) 3715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SZ_ERROR_MEM; 3725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) outBufCur = tempBuf[1 - ci] = temp; 3735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) tempSizes[1 - ci] = outSizeCur; 3745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else if (ci == 2) 3765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 3775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (unpackSize > outSize) /* check it */ 3785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SZ_ERROR_PARAM; 3795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) tempBuf3 = outBufCur = outBuffer + (outSize - (size_t)unpackSize); 3805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) tempSize3 = outSizeCur = (SizeT)unpackSize; 3815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else 3835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SZ_ERROR_UNSUPPORTED; 3845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) offset = GetSum(packSizes, si); 3865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) inSize = packSizes[si]; 3875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) RINOK(LookInStream_SeekTo(inStream, startPos + offset)); 3885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (coder->MethodID == k_Copy) 3905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 3915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (inSize != outSizeCur) /* check it */ 3925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SZ_ERROR_DATA; 3935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) RINOK(SzDecodeCopy(inSize, inStream, outBufCur)); 3945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else if (coder->MethodID == k_LZMA) 3965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 3975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) RINOK(SzDecodeLzma(coder, inSize, inStream, outBufCur, outSizeCur, allocMain)); 3985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else if (coder->MethodID == k_LZMA2) 4005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 4015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) RINOK(SzDecodeLzma2(coder, inSize, inStream, outBufCur, outSizeCur, allocMain)); 4025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else 4045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 4055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #ifdef _7ZIP_PPMD_SUPPPORT 4065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) RINOK(SzDecodePpmd(coder, inSize, inStream, outBufCur, outSizeCur, allocMain)); 4075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #else 4085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SZ_ERROR_UNSUPPORTED; 4095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #endif 4105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else if (coder->MethodID == k_BCJ2) 4135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 4145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) UInt64 offset = GetSum(packSizes, 1); 4155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) UInt64 s3Size = packSizes[1]; 4165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SRes res; 4175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ci != 3) 4185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SZ_ERROR_UNSUPPORTED; 4195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) RINOK(LookInStream_SeekTo(inStream, startPos + offset)); 4205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) tempSizes[2] = (SizeT)s3Size; 4215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (tempSizes[2] != s3Size) 4225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SZ_ERROR_MEM; 4235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) tempBuf[2] = (Byte *)IAlloc_Alloc(allocMain, tempSizes[2]); 4245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (tempBuf[2] == 0 && tempSizes[2] != 0) 4255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SZ_ERROR_MEM; 4265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) res = SzDecodeCopy(s3Size, inStream, tempBuf[2]); 4275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) RINOK(res) 4285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) res = Bcj2_Decode( 4305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) tempBuf3, tempSize3, 4315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) tempBuf[0], tempSizes[0], 4325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) tempBuf[1], tempSizes[1], 4335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) tempBuf[2], tempSizes[2], 4345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) outBuffer, outSize); 4355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) RINOK(res) 4365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else 4385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 4395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ci != 1) 4405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SZ_ERROR_UNSUPPORTED; 4415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switch(coder->MethodID) 4425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 4435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case k_BCJ: 4445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 4455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) UInt32 state; 4465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) x86_Convert_Init(state); 4475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) x86_Convert(outBuffer, outSize, 0, &state, 0); 4485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 4495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CASE_BRA_CONV(ARM) 4515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) default: 4525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SZ_ERROR_UNSUPPORTED; 4535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SZ_OK; 4575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SRes SzFolder_Decode(const CSzFolder *folder, const UInt64 *packSizes, 4605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ILookInStream *inStream, UInt64 startPos, 4615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Byte *outBuffer, size_t outSize, ISzAlloc *allocMain) 4625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 4635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Byte *tempBuf[3] = { 0, 0, 0}; 4645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int i; 4655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SRes res = SzFolder_Decode2(folder, packSizes, inStream, startPos, 4665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) outBuffer, (SizeT)outSize, allocMain, tempBuf); 4675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (i = 0; i < 3; i++) 4685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) IAlloc_Free(allocMain, tempBuf[i]); 4695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return res; 4705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 471