7zDec.c 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673
  1. /* 7zDec.c -- Decoding from 7z folder
  2. : Igor Pavlov : Public domain */
  3. #include "Precomp.h"
  4. #include <string.h>
  5. /* #define Z7_PPMD_SUPPORT */
  6. #include "7z.h"
  7. #include "7zCrc.h"
  8. #include "Bcj2.h"
  9. #include "Bra.h"
  10. #include "CpuArch.h"
  11. #include "Delta.h"
  12. #include "LzmaDec.h"
  13. #include "Lzma2Dec.h"
  14. #ifdef Z7_PPMD_SUPPORT
  15. #include "Ppmd7.h"
  16. #endif
  17. #define k_Copy 0
  18. #ifndef Z7_NO_METHOD_LZMA2
  19. #define k_LZMA2 0x21
  20. #endif
  21. #define k_LZMA 0x30101
  22. #define k_BCJ2 0x303011B
  23. #if !defined(Z7_NO_METHODS_FILTERS)
  24. #define Z7_USE_BRANCH_FILTER
  25. #endif
  26. #if !defined(Z7_NO_METHODS_FILTERS) || \
  27. defined(Z7_USE_NATIVE_BRANCH_FILTER) && defined(MY_CPU_ARM64)
  28. #define Z7_USE_FILTER_ARM64
  29. #ifndef Z7_USE_BRANCH_FILTER
  30. #define Z7_USE_BRANCH_FILTER
  31. #endif
  32. #define k_ARM64 0xa
  33. #endif
  34. #if !defined(Z7_NO_METHODS_FILTERS) || \
  35. defined(Z7_USE_NATIVE_BRANCH_FILTER) && defined(MY_CPU_ARMT)
  36. #define Z7_USE_FILTER_ARMT
  37. #ifndef Z7_USE_BRANCH_FILTER
  38. #define Z7_USE_BRANCH_FILTER
  39. #endif
  40. #define k_ARMT 0x3030701
  41. #endif
  42. #ifndef Z7_NO_METHODS_FILTERS
  43. #define k_Delta 3
  44. #define k_RISCV 0xb
  45. #define k_BCJ 0x3030103
  46. #define k_PPC 0x3030205
  47. #define k_IA64 0x3030401
  48. #define k_ARM 0x3030501
  49. #define k_SPARC 0x3030805
  50. #endif
  51. #ifdef Z7_PPMD_SUPPORT
  52. #define k_PPMD 0x30401
  53. typedef struct
  54. {
  55. IByteIn vt;
  56. const Byte *cur;
  57. const Byte *end;
  58. const Byte *begin;
  59. UInt64 processed;
  60. BoolInt extra;
  61. SRes res;
  62. ILookInStreamPtr inStream;
  63. } CByteInToLook;
  64. static Byte ReadByte(IByteInPtr pp)
  65. {
  66. Z7_CONTAINER_FROM_VTBL_TO_DECL_VAR_pp_vt_p(CByteInToLook)
  67. if (p->cur != p->end)
  68. return *p->cur++;
  69. if (p->res == SZ_OK)
  70. {
  71. size_t size = (size_t)(p->cur - p->begin);
  72. p->processed += size;
  73. p->res = ILookInStream_Skip(p->inStream, size);
  74. size = (1 << 25);
  75. p->res = ILookInStream_Look(p->inStream, (const void **)&p->begin, &size);
  76. p->cur = p->begin;
  77. p->end = p->begin + size;
  78. if (size != 0)
  79. return *p->cur++;
  80. }
  81. p->extra = True;
  82. return 0;
  83. }
  84. static SRes SzDecodePpmd(const Byte *props, unsigned propsSize, UInt64 inSize, ILookInStreamPtr inStream,
  85. Byte *outBuffer, SizeT outSize, ISzAllocPtr allocMain)
  86. {
  87. CPpmd7 ppmd;
  88. CByteInToLook s;
  89. SRes res = SZ_OK;
  90. s.vt.Read = ReadByte;
  91. s.inStream = inStream;
  92. s.begin = s.end = s.cur = NULL;
  93. s.extra = False;
  94. s.res = SZ_OK;
  95. s.processed = 0;
  96. if (propsSize != 5)
  97. return SZ_ERROR_UNSUPPORTED;
  98. {
  99. unsigned order = props[0];
  100. UInt32 memSize = GetUi32(props + 1);
  101. if (order < PPMD7_MIN_ORDER ||
  102. order > PPMD7_MAX_ORDER ||
  103. memSize < PPMD7_MIN_MEM_SIZE ||
  104. memSize > PPMD7_MAX_MEM_SIZE)
  105. return SZ_ERROR_UNSUPPORTED;
  106. Ppmd7_Construct(&ppmd);
  107. if (!Ppmd7_Alloc(&ppmd, memSize, allocMain))
  108. return SZ_ERROR_MEM;
  109. Ppmd7_Init(&ppmd, order);
  110. }
  111. {
  112. ppmd.rc.dec.Stream = &s.vt;
  113. if (!Ppmd7z_RangeDec_Init(&ppmd.rc.dec))
  114. res = SZ_ERROR_DATA;
  115. else if (!s.extra)
  116. {
  117. Byte *buf = outBuffer;
  118. const Byte *lim = buf + outSize;
  119. for (; buf != lim; buf++)
  120. {
  121. int sym = Ppmd7z_DecodeSymbol(&ppmd);
  122. if (s.extra || sym < 0)
  123. break;
  124. *buf = (Byte)sym;
  125. }
  126. if (buf != lim)
  127. res = SZ_ERROR_DATA;
  128. else if (!Ppmd7z_RangeDec_IsFinishedOK(&ppmd.rc.dec))
  129. {
  130. /* if (Ppmd7z_DecodeSymbol(&ppmd) != PPMD7_SYM_END || !Ppmd7z_RangeDec_IsFinishedOK(&ppmd.rc.dec)) */
  131. res = SZ_ERROR_DATA;
  132. }
  133. }
  134. if (s.extra)
  135. res = (s.res != SZ_OK ? s.res : SZ_ERROR_DATA);
  136. else if (s.processed + (size_t)(s.cur - s.begin) != inSize)
  137. res = SZ_ERROR_DATA;
  138. }
  139. Ppmd7_Free(&ppmd, allocMain);
  140. return res;
  141. }
  142. #endif
  143. static SRes SzDecodeLzma(const Byte *props, unsigned propsSize, UInt64 inSize, ILookInStreamPtr inStream,
  144. Byte *outBuffer, SizeT outSize, ISzAllocPtr allocMain)
  145. {
  146. CLzmaDec state;
  147. SRes res = SZ_OK;
  148. LzmaDec_CONSTRUCT(&state)
  149. RINOK(LzmaDec_AllocateProbs(&state, props, propsSize, allocMain))
  150. state.dic = outBuffer;
  151. state.dicBufSize = outSize;
  152. LzmaDec_Init(&state);
  153. for (;;)
  154. {
  155. const void *inBuf = NULL;
  156. size_t lookahead = (1 << 18);
  157. if (lookahead > inSize)
  158. lookahead = (size_t)inSize;
  159. res = ILookInStream_Look(inStream, &inBuf, &lookahead);
  160. if (res != SZ_OK)
  161. break;
  162. {
  163. SizeT inProcessed = (SizeT)lookahead, dicPos = state.dicPos;
  164. ELzmaStatus status;
  165. res = LzmaDec_DecodeToDic(&state, outSize, (const Byte *)inBuf, &inProcessed, LZMA_FINISH_END, &status);
  166. lookahead -= inProcessed;
  167. inSize -= inProcessed;
  168. if (res != SZ_OK)
  169. break;
  170. if (status == LZMA_STATUS_FINISHED_WITH_MARK)
  171. {
  172. if (outSize != state.dicPos || inSize != 0)
  173. res = SZ_ERROR_DATA;
  174. break;
  175. }
  176. if (outSize == state.dicPos && inSize == 0 && status == LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK)
  177. break;
  178. if (inProcessed == 0 && dicPos == state.dicPos)
  179. {
  180. res = SZ_ERROR_DATA;
  181. break;
  182. }
  183. res = ILookInStream_Skip(inStream, inProcessed);
  184. if (res != SZ_OK)
  185. break;
  186. }
  187. }
  188. LzmaDec_FreeProbs(&state, allocMain);
  189. return res;
  190. }
  191. #ifndef Z7_NO_METHOD_LZMA2
  192. static SRes SzDecodeLzma2(const Byte *props, unsigned propsSize, UInt64 inSize, ILookInStreamPtr inStream,
  193. Byte *outBuffer, SizeT outSize, ISzAllocPtr allocMain)
  194. {
  195. CLzma2Dec state;
  196. SRes res = SZ_OK;
  197. Lzma2Dec_CONSTRUCT(&state)
  198. if (propsSize != 1)
  199. return SZ_ERROR_DATA;
  200. RINOK(Lzma2Dec_AllocateProbs(&state, props[0], allocMain))
  201. state.decoder.dic = outBuffer;
  202. state.decoder.dicBufSize = outSize;
  203. Lzma2Dec_Init(&state);
  204. for (;;)
  205. {
  206. const void *inBuf = NULL;
  207. size_t lookahead = (1 << 18);
  208. if (lookahead > inSize)
  209. lookahead = (size_t)inSize;
  210. res = ILookInStream_Look(inStream, &inBuf, &lookahead);
  211. if (res != SZ_OK)
  212. break;
  213. {
  214. SizeT inProcessed = (SizeT)lookahead, dicPos = state.decoder.dicPos;
  215. ELzmaStatus status;
  216. res = Lzma2Dec_DecodeToDic(&state, outSize, (const Byte *)inBuf, &inProcessed, LZMA_FINISH_END, &status);
  217. lookahead -= inProcessed;
  218. inSize -= inProcessed;
  219. if (res != SZ_OK)
  220. break;
  221. if (status == LZMA_STATUS_FINISHED_WITH_MARK)
  222. {
  223. if (outSize != state.decoder.dicPos || inSize != 0)
  224. res = SZ_ERROR_DATA;
  225. break;
  226. }
  227. if (inProcessed == 0 && dicPos == state.decoder.dicPos)
  228. {
  229. res = SZ_ERROR_DATA;
  230. break;
  231. }
  232. res = ILookInStream_Skip(inStream, inProcessed);
  233. if (res != SZ_OK)
  234. break;
  235. }
  236. }
  237. Lzma2Dec_FreeProbs(&state, allocMain);
  238. return res;
  239. }
  240. #endif
  241. static SRes SzDecodeCopy(UInt64 inSize, ILookInStreamPtr inStream, Byte *outBuffer)
  242. {
  243. while (inSize > 0)
  244. {
  245. const void *inBuf;
  246. size_t curSize = (1 << 18);
  247. if (curSize > inSize)
  248. curSize = (size_t)inSize;
  249. RINOK(ILookInStream_Look(inStream, &inBuf, &curSize))
  250. if (curSize == 0)
  251. return SZ_ERROR_INPUT_EOF;
  252. memcpy(outBuffer, inBuf, curSize);
  253. outBuffer += curSize;
  254. inSize -= curSize;
  255. RINOK(ILookInStream_Skip(inStream, curSize))
  256. }
  257. return SZ_OK;
  258. }
  259. static BoolInt IS_MAIN_METHOD(UInt32 m)
  260. {
  261. switch (m)
  262. {
  263. case k_Copy:
  264. case k_LZMA:
  265. #ifndef Z7_NO_METHOD_LZMA2
  266. case k_LZMA2:
  267. #endif
  268. #ifdef Z7_PPMD_SUPPORT
  269. case k_PPMD:
  270. #endif
  271. return True;
  272. default:
  273. return False;
  274. }
  275. }
  276. static BoolInt IS_SUPPORTED_CODER(const CSzCoderInfo *c)
  277. {
  278. return
  279. c->NumStreams == 1
  280. /* && c->MethodID <= (UInt32)0xFFFFFFFF */
  281. && IS_MAIN_METHOD((UInt32)c->MethodID);
  282. }
  283. #define IS_BCJ2(c) ((c)->MethodID == k_BCJ2 && (c)->NumStreams == 4)
  284. static SRes CheckSupportedFolder(const CSzFolder *f)
  285. {
  286. if (f->NumCoders < 1 || f->NumCoders > 4)
  287. return SZ_ERROR_UNSUPPORTED;
  288. if (!IS_SUPPORTED_CODER(&f->Coders[0]))
  289. return SZ_ERROR_UNSUPPORTED;
  290. if (f->NumCoders == 1)
  291. {
  292. if (f->NumPackStreams != 1 || f->PackStreams[0] != 0 || f->NumBonds != 0)
  293. return SZ_ERROR_UNSUPPORTED;
  294. return SZ_OK;
  295. }
  296. #if defined(Z7_USE_BRANCH_FILTER)
  297. if (f->NumCoders == 2)
  298. {
  299. const CSzCoderInfo *c = &f->Coders[1];
  300. if (
  301. /* c->MethodID > (UInt32)0xFFFFFFFF || */
  302. c->NumStreams != 1
  303. || f->NumPackStreams != 1
  304. || f->PackStreams[0] != 0
  305. || f->NumBonds != 1
  306. || f->Bonds[0].InIndex != 1
  307. || f->Bonds[0].OutIndex != 0)
  308. return SZ_ERROR_UNSUPPORTED;
  309. switch ((UInt32)c->MethodID)
  310. {
  311. #if !defined(Z7_NO_METHODS_FILTERS)
  312. case k_Delta:
  313. case k_BCJ:
  314. case k_PPC:
  315. case k_IA64:
  316. case k_SPARC:
  317. case k_ARM:
  318. case k_RISCV:
  319. #endif
  320. #ifdef Z7_USE_FILTER_ARM64
  321. case k_ARM64:
  322. #endif
  323. #ifdef Z7_USE_FILTER_ARMT
  324. case k_ARMT:
  325. #endif
  326. break;
  327. default:
  328. return SZ_ERROR_UNSUPPORTED;
  329. }
  330. return SZ_OK;
  331. }
  332. #endif
  333. if (f->NumCoders == 4)
  334. {
  335. if (!IS_SUPPORTED_CODER(&f->Coders[1])
  336. || !IS_SUPPORTED_CODER(&f->Coders[2])
  337. || !IS_BCJ2(&f->Coders[3]))
  338. return SZ_ERROR_UNSUPPORTED;
  339. if (f->NumPackStreams != 4
  340. || f->PackStreams[0] != 2
  341. || f->PackStreams[1] != 6
  342. || f->PackStreams[2] != 1
  343. || f->PackStreams[3] != 0
  344. || f->NumBonds != 3
  345. || f->Bonds[0].InIndex != 5 || f->Bonds[0].OutIndex != 0
  346. || f->Bonds[1].InIndex != 4 || f->Bonds[1].OutIndex != 1
  347. || f->Bonds[2].InIndex != 3 || f->Bonds[2].OutIndex != 2)
  348. return SZ_ERROR_UNSUPPORTED;
  349. return SZ_OK;
  350. }
  351. return SZ_ERROR_UNSUPPORTED;
  352. }
  353. static SRes SzFolder_Decode2(const CSzFolder *folder,
  354. const Byte *propsData,
  355. const UInt64 *unpackSizes,
  356. const UInt64 *packPositions,
  357. ILookInStreamPtr inStream, UInt64 startPos,
  358. Byte *outBuffer, SizeT outSize, ISzAllocPtr allocMain,
  359. Byte *tempBuf[])
  360. {
  361. UInt32 ci;
  362. SizeT tempSizes[3] = { 0, 0, 0};
  363. SizeT tempSize3 = 0;
  364. Byte *tempBuf3 = 0;
  365. RINOK(CheckSupportedFolder(folder))
  366. for (ci = 0; ci < folder->NumCoders; ci++)
  367. {
  368. const CSzCoderInfo *coder = &folder->Coders[ci];
  369. if (IS_MAIN_METHOD((UInt32)coder->MethodID))
  370. {
  371. UInt32 si = 0;
  372. UInt64 offset;
  373. UInt64 inSize;
  374. Byte *outBufCur = outBuffer;
  375. SizeT outSizeCur = outSize;
  376. if (folder->NumCoders == 4)
  377. {
  378. const UInt32 indices[] = { 3, 2, 0 };
  379. const UInt64 unpackSize = unpackSizes[ci];
  380. si = indices[ci];
  381. if (ci < 2)
  382. {
  383. Byte *temp;
  384. outSizeCur = (SizeT)unpackSize;
  385. if (outSizeCur != unpackSize)
  386. return SZ_ERROR_MEM;
  387. temp = (Byte *)ISzAlloc_Alloc(allocMain, outSizeCur);
  388. if (!temp && outSizeCur != 0)
  389. return SZ_ERROR_MEM;
  390. outBufCur = tempBuf[1 - ci] = temp;
  391. tempSizes[1 - ci] = outSizeCur;
  392. }
  393. else if (ci == 2)
  394. {
  395. if (unpackSize > outSize) /* check it */
  396. return SZ_ERROR_PARAM;
  397. tempBuf3 = outBufCur = outBuffer + (outSize - (size_t)unpackSize);
  398. tempSize3 = outSizeCur = (SizeT)unpackSize;
  399. }
  400. else
  401. return SZ_ERROR_UNSUPPORTED;
  402. }
  403. offset = packPositions[si];
  404. inSize = packPositions[(size_t)si + 1] - offset;
  405. RINOK(LookInStream_SeekTo(inStream, startPos + offset))
  406. if (coder->MethodID == k_Copy)
  407. {
  408. if (inSize != outSizeCur) /* check it */
  409. return SZ_ERROR_DATA;
  410. RINOK(SzDecodeCopy(inSize, inStream, outBufCur))
  411. }
  412. else if (coder->MethodID == k_LZMA)
  413. {
  414. RINOK(SzDecodeLzma(propsData + coder->PropsOffset, coder->PropsSize, inSize, inStream, outBufCur, outSizeCur, allocMain))
  415. }
  416. #ifndef Z7_NO_METHOD_LZMA2
  417. else if (coder->MethodID == k_LZMA2)
  418. {
  419. RINOK(SzDecodeLzma2(propsData + coder->PropsOffset, coder->PropsSize, inSize, inStream, outBufCur, outSizeCur, allocMain))
  420. }
  421. #endif
  422. #ifdef Z7_PPMD_SUPPORT
  423. else if (coder->MethodID == k_PPMD)
  424. {
  425. RINOK(SzDecodePpmd(propsData + coder->PropsOffset, coder->PropsSize, inSize, inStream, outBufCur, outSizeCur, allocMain))
  426. }
  427. #endif
  428. else
  429. return SZ_ERROR_UNSUPPORTED;
  430. }
  431. else if (coder->MethodID == k_BCJ2)
  432. {
  433. const UInt64 offset = packPositions[1];
  434. const UInt64 s3Size = packPositions[2] - offset;
  435. if (ci != 3)
  436. return SZ_ERROR_UNSUPPORTED;
  437. tempSizes[2] = (SizeT)s3Size;
  438. if (tempSizes[2] != s3Size)
  439. return SZ_ERROR_MEM;
  440. tempBuf[2] = (Byte *)ISzAlloc_Alloc(allocMain, tempSizes[2]);
  441. if (!tempBuf[2] && tempSizes[2] != 0)
  442. return SZ_ERROR_MEM;
  443. RINOK(LookInStream_SeekTo(inStream, startPos + offset))
  444. RINOK(SzDecodeCopy(s3Size, inStream, tempBuf[2]))
  445. if ((tempSizes[0] & 3) != 0 ||
  446. (tempSizes[1] & 3) != 0 ||
  447. tempSize3 + tempSizes[0] + tempSizes[1] != outSize)
  448. return SZ_ERROR_DATA;
  449. {
  450. CBcj2Dec p;
  451. p.bufs[0] = tempBuf3; p.lims[0] = tempBuf3 + tempSize3;
  452. p.bufs[1] = tempBuf[0]; p.lims[1] = tempBuf[0] + tempSizes[0];
  453. p.bufs[2] = tempBuf[1]; p.lims[2] = tempBuf[1] + tempSizes[1];
  454. p.bufs[3] = tempBuf[2]; p.lims[3] = tempBuf[2] + tempSizes[2];
  455. p.dest = outBuffer;
  456. p.destLim = outBuffer + outSize;
  457. Bcj2Dec_Init(&p);
  458. RINOK(Bcj2Dec_Decode(&p))
  459. {
  460. unsigned i;
  461. for (i = 0; i < 4; i++)
  462. if (p.bufs[i] != p.lims[i])
  463. return SZ_ERROR_DATA;
  464. if (p.dest != p.destLim || !Bcj2Dec_IsMaybeFinished(&p))
  465. return SZ_ERROR_DATA;
  466. }
  467. }
  468. }
  469. #if defined(Z7_USE_BRANCH_FILTER)
  470. else if (ci == 1)
  471. {
  472. #if !defined(Z7_NO_METHODS_FILTERS)
  473. if (coder->MethodID == k_Delta)
  474. {
  475. if (coder->PropsSize != 1)
  476. return SZ_ERROR_UNSUPPORTED;
  477. {
  478. Byte state[DELTA_STATE_SIZE];
  479. Delta_Init(state);
  480. Delta_Decode(state, (unsigned)(propsData[coder->PropsOffset]) + 1, outBuffer, outSize);
  481. }
  482. continue;
  483. }
  484. #endif
  485. #ifdef Z7_USE_FILTER_ARM64
  486. if (coder->MethodID == k_ARM64)
  487. {
  488. UInt32 pc = 0;
  489. if (coder->PropsSize == 4)
  490. {
  491. pc = GetUi32(propsData + coder->PropsOffset);
  492. if (pc & 3)
  493. return SZ_ERROR_UNSUPPORTED;
  494. }
  495. else if (coder->PropsSize != 0)
  496. return SZ_ERROR_UNSUPPORTED;
  497. z7_BranchConv_ARM64_Dec(outBuffer, outSize, pc);
  498. continue;
  499. }
  500. #endif
  501. #if !defined(Z7_NO_METHODS_FILTERS)
  502. if (coder->MethodID == k_RISCV)
  503. {
  504. UInt32 pc = 0;
  505. if (coder->PropsSize == 4)
  506. {
  507. pc = GetUi32(propsData + coder->PropsOffset);
  508. if (pc & 1)
  509. return SZ_ERROR_UNSUPPORTED;
  510. }
  511. else if (coder->PropsSize != 0)
  512. return SZ_ERROR_UNSUPPORTED;
  513. z7_BranchConv_RISCV_Dec(outBuffer, outSize, pc);
  514. continue;
  515. }
  516. #endif
  517. #if !defined(Z7_NO_METHODS_FILTERS) || defined(Z7_USE_FILTER_ARMT)
  518. {
  519. if (coder->PropsSize != 0)
  520. return SZ_ERROR_UNSUPPORTED;
  521. #define CASE_BRA_CONV(isa) case k_ ## isa: Z7_BRANCH_CONV_DEC(isa)(outBuffer, outSize, 0); break; // pc = 0;
  522. switch (coder->MethodID)
  523. {
  524. #if !defined(Z7_NO_METHODS_FILTERS)
  525. case k_BCJ:
  526. {
  527. UInt32 state = Z7_BRANCH_CONV_ST_X86_STATE_INIT_VAL;
  528. z7_BranchConvSt_X86_Dec(outBuffer, outSize, 0, &state); // pc = 0
  529. break;
  530. }
  531. case k_PPC: Z7_BRANCH_CONV_DEC_2(BranchConv_PPC)(outBuffer, outSize, 0); break; // pc = 0;
  532. // CASE_BRA_CONV(PPC)
  533. CASE_BRA_CONV(IA64)
  534. CASE_BRA_CONV(SPARC)
  535. CASE_BRA_CONV(ARM)
  536. #endif
  537. #if !defined(Z7_NO_METHODS_FILTERS) || defined(Z7_USE_FILTER_ARMT)
  538. CASE_BRA_CONV(ARMT)
  539. #endif
  540. default:
  541. return SZ_ERROR_UNSUPPORTED;
  542. }
  543. continue;
  544. }
  545. #endif
  546. } // (c == 1)
  547. #endif // Z7_USE_BRANCH_FILTER
  548. else
  549. return SZ_ERROR_UNSUPPORTED;
  550. }
  551. return SZ_OK;
  552. }
  553. SRes SzAr_DecodeFolder(const CSzAr *p, UInt32 folderIndex,
  554. ILookInStreamPtr inStream, UInt64 startPos,
  555. Byte *outBuffer, size_t outSize,
  556. ISzAllocPtr allocMain)
  557. {
  558. SRes res;
  559. CSzFolder folder;
  560. CSzData sd;
  561. const Byte *data = p->CodersData + p->FoCodersOffsets[folderIndex];
  562. sd.Data = data;
  563. sd.Size = p->FoCodersOffsets[(size_t)folderIndex + 1] - p->FoCodersOffsets[folderIndex];
  564. res = SzGetNextFolderItem(&folder, &sd);
  565. if (res != SZ_OK)
  566. return res;
  567. if (sd.Size != 0
  568. || folder.UnpackStream != p->FoToMainUnpackSizeIndex[folderIndex]
  569. || outSize != SzAr_GetFolderUnpackSize(p, folderIndex))
  570. return SZ_ERROR_FAIL;
  571. {
  572. unsigned i;
  573. Byte *tempBuf[3] = { 0, 0, 0};
  574. res = SzFolder_Decode2(&folder, data,
  575. &p->CoderUnpackSizes[p->FoToCoderUnpackSizes[folderIndex]],
  576. p->PackPositions + p->FoStartPackStreamIndex[folderIndex],
  577. inStream, startPos,
  578. outBuffer, (SizeT)outSize, allocMain, tempBuf);
  579. for (i = 0; i < 3; i++)
  580. ISzAlloc_Free(allocMain, tempBuf[i]);
  581. if (res == SZ_OK)
  582. if (SzBitWithVals_Check(&p->FolderCRCs, folderIndex))
  583. if (CrcCalc(outBuffer, outSize) != p->FolderCRCs.Vals[folderIndex])
  584. res = SZ_ERROR_CRC;
  585. return res;
  586. }
  587. }