aboutsummaryrefslogtreecommitdiff
path: root/C/7zDec.c
diff options
context:
space:
mode:
Diffstat (limited to 'C/7zDec.c')
-rw-r--r--C/7zDec.c172
1 files changed, 110 insertions, 62 deletions
diff --git a/C/7zDec.c b/C/7zDec.c
index fbfd016..96c6035 100644
--- a/C/7zDec.c
+++ b/C/7zDec.c
@@ -1,11 +1,11 @@
1/* 7zDec.c -- Decoding from 7z folder 1/* 7zDec.c -- Decoding from 7z folder
22021-02-09 : Igor Pavlov : Public domain */ 22023-04-02 : Igor Pavlov : Public domain */
3 3
4#include "Precomp.h" 4#include "Precomp.h"
5 5
6#include <string.h> 6#include <string.h>
7 7
8/* #define _7ZIP_PPMD_SUPPPORT */ 8/* #define Z7_PPMD_SUPPORT */
9 9
10#include "7z.h" 10#include "7z.h"
11#include "7zCrc.h" 11#include "7zCrc.h"
@@ -16,27 +16,49 @@
16#include "Delta.h" 16#include "Delta.h"
17#include "LzmaDec.h" 17#include "LzmaDec.h"
18#include "Lzma2Dec.h" 18#include "Lzma2Dec.h"
19#ifdef _7ZIP_PPMD_SUPPPORT 19#ifdef Z7_PPMD_SUPPORT
20#include "Ppmd7.h" 20#include "Ppmd7.h"
21#endif 21#endif
22 22
23#define k_Copy 0 23#define k_Copy 0
24#ifndef _7Z_NO_METHOD_LZMA2 24#ifndef Z7_NO_METHOD_LZMA2
25#define k_LZMA2 0x21 25#define k_LZMA2 0x21
26#endif 26#endif
27#define k_LZMA 0x30101 27#define k_LZMA 0x30101
28#define k_BCJ2 0x303011B 28#define k_BCJ2 0x303011B
29#ifndef _7Z_NO_METHODS_FILTERS 29
30#if !defined(Z7_NO_METHODS_FILTERS)
31#define Z7_USE_BRANCH_FILTER
32#endif
33
34#if !defined(Z7_NO_METHODS_FILTERS) || \
35 defined(Z7_USE_NATIVE_BRANCH_FILTER) && defined(MY_CPU_ARM64)
36#define Z7_USE_FILTER_ARM64
37#ifndef Z7_USE_BRANCH_FILTER
38#define Z7_USE_BRANCH_FILTER
39#endif
40#define k_ARM64 0xa
41#endif
42
43#if !defined(Z7_NO_METHODS_FILTERS) || \
44 defined(Z7_USE_NATIVE_BRANCH_FILTER) && defined(MY_CPU_ARMT)
45#define Z7_USE_FILTER_ARMT
46#ifndef Z7_USE_BRANCH_FILTER
47#define Z7_USE_BRANCH_FILTER
48#endif
49#define k_ARMT 0x3030701
50#endif
51
52#ifndef Z7_NO_METHODS_FILTERS
30#define k_Delta 3 53#define k_Delta 3
31#define k_BCJ 0x3030103 54#define k_BCJ 0x3030103
32#define k_PPC 0x3030205 55#define k_PPC 0x3030205
33#define k_IA64 0x3030401 56#define k_IA64 0x3030401
34#define k_ARM 0x3030501 57#define k_ARM 0x3030501
35#define k_ARMT 0x3030701
36#define k_SPARC 0x3030805 58#define k_SPARC 0x3030805
37#endif 59#endif
38 60
39#ifdef _7ZIP_PPMD_SUPPPORT 61#ifdef Z7_PPMD_SUPPORT
40 62
41#define k_PPMD 0x30401 63#define k_PPMD 0x30401
42 64
@@ -49,12 +71,12 @@ typedef struct
49 UInt64 processed; 71 UInt64 processed;
50 BoolInt extra; 72 BoolInt extra;
51 SRes res; 73 SRes res;
52 const ILookInStream *inStream; 74 ILookInStreamPtr inStream;
53} CByteInToLook; 75} CByteInToLook;
54 76
55static Byte ReadByte(const IByteIn *pp) 77static Byte ReadByte(IByteInPtr pp)
56{ 78{
57 CByteInToLook *p = CONTAINER_FROM_VTBL(pp, CByteInToLook, vt); 79 Z7_CONTAINER_FROM_VTBL_TO_DECL_VAR_pp_vt_p(CByteInToLook)
58 if (p->cur != p->end) 80 if (p->cur != p->end)
59 return *p->cur++; 81 return *p->cur++;
60 if (p->res == SZ_OK) 82 if (p->res == SZ_OK)
@@ -67,13 +89,13 @@ static Byte ReadByte(const IByteIn *pp)
67 p->cur = p->begin; 89 p->cur = p->begin;
68 p->end = p->begin + size; 90 p->end = p->begin + size;
69 if (size != 0) 91 if (size != 0)
70 return *p->cur++;; 92 return *p->cur++;
71 } 93 }
72 p->extra = True; 94 p->extra = True;
73 return 0; 95 return 0;
74} 96}
75 97
76static SRes SzDecodePpmd(const Byte *props, unsigned propsSize, UInt64 inSize, const ILookInStream *inStream, 98static SRes SzDecodePpmd(const Byte *props, unsigned propsSize, UInt64 inSize, ILookInStreamPtr inStream,
77 Byte *outBuffer, SizeT outSize, ISzAllocPtr allocMain) 99 Byte *outBuffer, SizeT outSize, ISzAllocPtr allocMain)
78{ 100{
79 CPpmd7 ppmd; 101 CPpmd7 ppmd;
@@ -138,14 +160,14 @@ static SRes SzDecodePpmd(const Byte *props, unsigned propsSize, UInt64 inSize, c
138#endif 160#endif
139 161
140 162
141static SRes SzDecodeLzma(const Byte *props, unsigned propsSize, UInt64 inSize, ILookInStream *inStream, 163static SRes SzDecodeLzma(const Byte *props, unsigned propsSize, UInt64 inSize, ILookInStreamPtr inStream,
142 Byte *outBuffer, SizeT outSize, ISzAllocPtr allocMain) 164 Byte *outBuffer, SizeT outSize, ISzAllocPtr allocMain)
143{ 165{
144 CLzmaDec state; 166 CLzmaDec state;
145 SRes res = SZ_OK; 167 SRes res = SZ_OK;
146 168
147 LzmaDec_Construct(&state); 169 LzmaDec_CONSTRUCT(&state)
148 RINOK(LzmaDec_AllocateProbs(&state, props, propsSize, allocMain)); 170 RINOK(LzmaDec_AllocateProbs(&state, props, propsSize, allocMain))
149 state.dic = outBuffer; 171 state.dic = outBuffer;
150 state.dicBufSize = outSize; 172 state.dicBufSize = outSize;
151 LzmaDec_Init(&state); 173 LzmaDec_Init(&state);
@@ -196,18 +218,18 @@ static SRes SzDecodeLzma(const Byte *props, unsigned propsSize, UInt64 inSize, I
196} 218}
197 219
198 220
199#ifndef _7Z_NO_METHOD_LZMA2 221#ifndef Z7_NO_METHOD_LZMA2
200 222
201static SRes SzDecodeLzma2(const Byte *props, unsigned propsSize, UInt64 inSize, ILookInStream *inStream, 223static SRes SzDecodeLzma2(const Byte *props, unsigned propsSize, UInt64 inSize, ILookInStreamPtr inStream,
202 Byte *outBuffer, SizeT outSize, ISzAllocPtr allocMain) 224 Byte *outBuffer, SizeT outSize, ISzAllocPtr allocMain)
203{ 225{
204 CLzma2Dec state; 226 CLzma2Dec state;
205 SRes res = SZ_OK; 227 SRes res = SZ_OK;
206 228
207 Lzma2Dec_Construct(&state); 229 Lzma2Dec_CONSTRUCT(&state)
208 if (propsSize != 1) 230 if (propsSize != 1)
209 return SZ_ERROR_DATA; 231 return SZ_ERROR_DATA;
210 RINOK(Lzma2Dec_AllocateProbs(&state, props[0], allocMain)); 232 RINOK(Lzma2Dec_AllocateProbs(&state, props[0], allocMain))
211 state.decoder.dic = outBuffer; 233 state.decoder.dic = outBuffer;
212 state.decoder.dicBufSize = outSize; 234 state.decoder.dicBufSize = outSize;
213 Lzma2Dec_Init(&state); 235 Lzma2Dec_Init(&state);
@@ -257,7 +279,7 @@ static SRes SzDecodeLzma2(const Byte *props, unsigned propsSize, UInt64 inSize,
257#endif 279#endif
258 280
259 281
260static SRes SzDecodeCopy(UInt64 inSize, ILookInStream *inStream, Byte *outBuffer) 282static SRes SzDecodeCopy(UInt64 inSize, ILookInStreamPtr inStream, Byte *outBuffer)
261{ 283{
262 while (inSize > 0) 284 while (inSize > 0)
263 { 285 {
@@ -265,13 +287,13 @@ static SRes SzDecodeCopy(UInt64 inSize, ILookInStream *inStream, Byte *outBuffer
265 size_t curSize = (1 << 18); 287 size_t curSize = (1 << 18);
266 if (curSize > inSize) 288 if (curSize > inSize)
267 curSize = (size_t)inSize; 289 curSize = (size_t)inSize;
268 RINOK(ILookInStream_Look(inStream, &inBuf, &curSize)); 290 RINOK(ILookInStream_Look(inStream, &inBuf, &curSize))
269 if (curSize == 0) 291 if (curSize == 0)
270 return SZ_ERROR_INPUT_EOF; 292 return SZ_ERROR_INPUT_EOF;
271 memcpy(outBuffer, inBuf, curSize); 293 memcpy(outBuffer, inBuf, curSize);
272 outBuffer += curSize; 294 outBuffer += curSize;
273 inSize -= curSize; 295 inSize -= curSize;
274 RINOK(ILookInStream_Skip(inStream, curSize)); 296 RINOK(ILookInStream_Skip(inStream, curSize))
275 } 297 }
276 return SZ_OK; 298 return SZ_OK;
277} 299}
@@ -282,12 +304,12 @@ static BoolInt IS_MAIN_METHOD(UInt32 m)
282 { 304 {
283 case k_Copy: 305 case k_Copy:
284 case k_LZMA: 306 case k_LZMA:
285 #ifndef _7Z_NO_METHOD_LZMA2 307 #ifndef Z7_NO_METHOD_LZMA2
286 case k_LZMA2: 308 case k_LZMA2:
287 #endif 309 #endif
288 #ifdef _7ZIP_PPMD_SUPPPORT 310 #ifdef Z7_PPMD_SUPPORT
289 case k_PPMD: 311 case k_PPMD:
290 #endif 312 #endif
291 return True; 313 return True;
292 } 314 }
293 return False; 315 return False;
@@ -317,7 +339,7 @@ static SRes CheckSupportedFolder(const CSzFolder *f)
317 } 339 }
318 340
319 341
320 #ifndef _7Z_NO_METHODS_FILTERS 342 #if defined(Z7_USE_BRANCH_FILTER)
321 343
322 if (f->NumCoders == 2) 344 if (f->NumCoders == 2)
323 { 345 {
@@ -333,13 +355,20 @@ static SRes CheckSupportedFolder(const CSzFolder *f)
333 return SZ_ERROR_UNSUPPORTED; 355 return SZ_ERROR_UNSUPPORTED;
334 switch ((UInt32)c->MethodID) 356 switch ((UInt32)c->MethodID)
335 { 357 {
358 #if !defined(Z7_NO_METHODS_FILTERS)
336 case k_Delta: 359 case k_Delta:
337 case k_BCJ: 360 case k_BCJ:
338 case k_PPC: 361 case k_PPC:
339 case k_IA64: 362 case k_IA64:
340 case k_SPARC: 363 case k_SPARC:
341 case k_ARM: 364 case k_ARM:
365 #endif
366 #ifdef Z7_USE_FILTER_ARM64
367 case k_ARM64:
368 #endif
369 #ifdef Z7_USE_FILTER_ARMT
342 case k_ARMT: 370 case k_ARMT:
371 #endif
343 break; 372 break;
344 default: 373 default:
345 return SZ_ERROR_UNSUPPORTED; 374 return SZ_ERROR_UNSUPPORTED;
@@ -372,15 +401,16 @@ static SRes CheckSupportedFolder(const CSzFolder *f)
372 return SZ_ERROR_UNSUPPORTED; 401 return SZ_ERROR_UNSUPPORTED;
373} 402}
374 403
375#ifndef _7Z_NO_METHODS_FILTERS 404
376#define CASE_BRA_CONV(isa) case k_ ## isa: isa ## _Convert(outBuffer, outSize, 0, 0); break; 405
377#endif 406
407
378 408
379static SRes SzFolder_Decode2(const CSzFolder *folder, 409static SRes SzFolder_Decode2(const CSzFolder *folder,
380 const Byte *propsData, 410 const Byte *propsData,
381 const UInt64 *unpackSizes, 411 const UInt64 *unpackSizes,
382 const UInt64 *packPositions, 412 const UInt64 *packPositions,
383 ILookInStream *inStream, UInt64 startPos, 413 ILookInStreamPtr inStream, UInt64 startPos,
384 Byte *outBuffer, SizeT outSize, ISzAllocPtr allocMain, 414 Byte *outBuffer, SizeT outSize, ISzAllocPtr allocMain,
385 Byte *tempBuf[]) 415 Byte *tempBuf[])
386{ 416{
@@ -389,7 +419,7 @@ static SRes SzFolder_Decode2(const CSzFolder *folder,
389 SizeT tempSize3 = 0; 419 SizeT tempSize3 = 0;
390 Byte *tempBuf3 = 0; 420 Byte *tempBuf3 = 0;
391 421
392 RINOK(CheckSupportedFolder(folder)); 422 RINOK(CheckSupportedFolder(folder))
393 423
394 for (ci = 0; ci < folder->NumCoders; ci++) 424 for (ci = 0; ci < folder->NumCoders; ci++)
395 { 425 {
@@ -404,8 +434,8 @@ static SRes SzFolder_Decode2(const CSzFolder *folder,
404 SizeT outSizeCur = outSize; 434 SizeT outSizeCur = outSize;
405 if (folder->NumCoders == 4) 435 if (folder->NumCoders == 4)
406 { 436 {
407 UInt32 indices[] = { 3, 2, 0 }; 437 const UInt32 indices[] = { 3, 2, 0 };
408 UInt64 unpackSize = unpackSizes[ci]; 438 const UInt64 unpackSize = unpackSizes[ci];
409 si = indices[ci]; 439 si = indices[ci];
410 if (ci < 2) 440 if (ci < 2)
411 { 441 {
@@ -431,37 +461,37 @@ static SRes SzFolder_Decode2(const CSzFolder *folder,
431 } 461 }
432 offset = packPositions[si]; 462 offset = packPositions[si];
433 inSize = packPositions[(size_t)si + 1] - offset; 463 inSize = packPositions[(size_t)si + 1] - offset;
434 RINOK(LookInStream_SeekTo(inStream, startPos + offset)); 464 RINOK(LookInStream_SeekTo(inStream, startPos + offset))
435 465
436 if (coder->MethodID == k_Copy) 466 if (coder->MethodID == k_Copy)
437 { 467 {
438 if (inSize != outSizeCur) /* check it */ 468 if (inSize != outSizeCur) /* check it */
439 return SZ_ERROR_DATA; 469 return SZ_ERROR_DATA;
440 RINOK(SzDecodeCopy(inSize, inStream, outBufCur)); 470 RINOK(SzDecodeCopy(inSize, inStream, outBufCur))
441 } 471 }
442 else if (coder->MethodID == k_LZMA) 472 else if (coder->MethodID == k_LZMA)
443 { 473 {
444 RINOK(SzDecodeLzma(propsData + coder->PropsOffset, coder->PropsSize, inSize, inStream, outBufCur, outSizeCur, allocMain)); 474 RINOK(SzDecodeLzma(propsData + coder->PropsOffset, coder->PropsSize, inSize, inStream, outBufCur, outSizeCur, allocMain))
445 } 475 }
446 #ifndef _7Z_NO_METHOD_LZMA2 476 #ifndef Z7_NO_METHOD_LZMA2
447 else if (coder->MethodID == k_LZMA2) 477 else if (coder->MethodID == k_LZMA2)
448 { 478 {
449 RINOK(SzDecodeLzma2(propsData + coder->PropsOffset, coder->PropsSize, inSize, inStream, outBufCur, outSizeCur, allocMain)); 479 RINOK(SzDecodeLzma2(propsData + coder->PropsOffset, coder->PropsSize, inSize, inStream, outBufCur, outSizeCur, allocMain))
450 } 480 }
451 #endif 481 #endif
452 #ifdef _7ZIP_PPMD_SUPPPORT 482 #ifdef Z7_PPMD_SUPPORT
453 else if (coder->MethodID == k_PPMD) 483 else if (coder->MethodID == k_PPMD)
454 { 484 {
455 RINOK(SzDecodePpmd(propsData + coder->PropsOffset, coder->PropsSize, inSize, inStream, outBufCur, outSizeCur, allocMain)); 485 RINOK(SzDecodePpmd(propsData + coder->PropsOffset, coder->PropsSize, inSize, inStream, outBufCur, outSizeCur, allocMain))
456 } 486 }
457 #endif 487 #endif
458 else 488 else
459 return SZ_ERROR_UNSUPPORTED; 489 return SZ_ERROR_UNSUPPORTED;
460 } 490 }
461 else if (coder->MethodID == k_BCJ2) 491 else if (coder->MethodID == k_BCJ2)
462 { 492 {
463 UInt64 offset = packPositions[1]; 493 const UInt64 offset = packPositions[1];
464 UInt64 s3Size = packPositions[2] - offset; 494 const UInt64 s3Size = packPositions[2] - offset;
465 495
466 if (ci != 3) 496 if (ci != 3)
467 return SZ_ERROR_UNSUPPORTED; 497 return SZ_ERROR_UNSUPPORTED;
@@ -473,8 +503,8 @@ static SRes SzFolder_Decode2(const CSzFolder *folder,
473 if (!tempBuf[2] && tempSizes[2] != 0) 503 if (!tempBuf[2] && tempSizes[2] != 0)
474 return SZ_ERROR_MEM; 504 return SZ_ERROR_MEM;
475 505
476 RINOK(LookInStream_SeekTo(inStream, startPos + offset)); 506 RINOK(LookInStream_SeekTo(inStream, startPos + offset))
477 RINOK(SzDecodeCopy(s3Size, inStream, tempBuf[2])); 507 RINOK(SzDecodeCopy(s3Size, inStream, tempBuf[2]))
478 508
479 if ((tempSizes[0] & 3) != 0 || 509 if ((tempSizes[0] & 3) != 0 ||
480 (tempSizes[1] & 3) != 0 || 510 (tempSizes[1] & 3) != 0 ||
@@ -493,26 +523,22 @@ static SRes SzFolder_Decode2(const CSzFolder *folder,
493 p.destLim = outBuffer + outSize; 523 p.destLim = outBuffer + outSize;
494 524
495 Bcj2Dec_Init(&p); 525 Bcj2Dec_Init(&p);
496 RINOK(Bcj2Dec_Decode(&p)); 526 RINOK(Bcj2Dec_Decode(&p))
497 527
498 { 528 {
499 unsigned i; 529 unsigned i;
500 for (i = 0; i < 4; i++) 530 for (i = 0; i < 4; i++)
501 if (p.bufs[i] != p.lims[i]) 531 if (p.bufs[i] != p.lims[i])
502 return SZ_ERROR_DATA; 532 return SZ_ERROR_DATA;
503 533 if (p.dest != p.destLim || !Bcj2Dec_IsMaybeFinished(&p))
504 if (!Bcj2Dec_IsFinished(&p))
505 return SZ_ERROR_DATA;
506
507 if (p.dest != p.destLim
508 || p.state != BCJ2_STREAM_MAIN)
509 return SZ_ERROR_DATA; 534 return SZ_ERROR_DATA;
510 } 535 }
511 } 536 }
512 } 537 }
513 #ifndef _7Z_NO_METHODS_FILTERS 538 #if defined(Z7_USE_BRANCH_FILTER)
514 else if (ci == 1) 539 else if (ci == 1)
515 { 540 {
541 #if !defined(Z7_NO_METHODS_FILTERS)
516 if (coder->MethodID == k_Delta) 542 if (coder->MethodID == k_Delta)
517 { 543 {
518 if (coder->PropsSize != 1) 544 if (coder->PropsSize != 1)
@@ -522,31 +548,53 @@ static SRes SzFolder_Decode2(const CSzFolder *folder,
522 Delta_Init(state); 548 Delta_Init(state);
523 Delta_Decode(state, (unsigned)(propsData[coder->PropsOffset]) + 1, outBuffer, outSize); 549 Delta_Decode(state, (unsigned)(propsData[coder->PropsOffset]) + 1, outBuffer, outSize);
524 } 550 }
551 continue;
525 } 552 }
526 else 553 #endif
554
555 #ifdef Z7_USE_FILTER_ARM64
556 if (coder->MethodID == k_ARM64)
557 {
558 UInt32 pc = 0;
559 if (coder->PropsSize == 4)
560 pc = GetUi32(propsData + coder->PropsOffset);
561 else if (coder->PropsSize != 0)
562 return SZ_ERROR_UNSUPPORTED;
563 z7_BranchConv_ARM64_Dec(outBuffer, outSize, pc);
564 continue;
565 }
566 #endif
567
568 #if !defined(Z7_NO_METHODS_FILTERS) || defined(Z7_USE_FILTER_ARMT)
527 { 569 {
528 if (coder->PropsSize != 0) 570 if (coder->PropsSize != 0)
529 return SZ_ERROR_UNSUPPORTED; 571 return SZ_ERROR_UNSUPPORTED;
572 #define CASE_BRA_CONV(isa) case k_ ## isa: Z7_BRANCH_CONV_DEC(isa)(outBuffer, outSize, 0); break; // pc = 0;
530 switch (coder->MethodID) 573 switch (coder->MethodID)
531 { 574 {
575 #if !defined(Z7_NO_METHODS_FILTERS)
532 case k_BCJ: 576 case k_BCJ:
533 { 577 {
534 UInt32 state; 578 UInt32 state = Z7_BRANCH_CONV_ST_X86_STATE_INIT_VAL;
535 x86_Convert_Init(state); 579 z7_BranchConvSt_X86_Dec(outBuffer, outSize, 0, &state); // pc = 0
536 x86_Convert(outBuffer, outSize, 0, &state, 0);
537 break; 580 break;
538 } 581 }
539 CASE_BRA_CONV(PPC) 582 CASE_BRA_CONV(PPC)
540 CASE_BRA_CONV(IA64) 583 CASE_BRA_CONV(IA64)
541 CASE_BRA_CONV(SPARC) 584 CASE_BRA_CONV(SPARC)
542 CASE_BRA_CONV(ARM) 585 CASE_BRA_CONV(ARM)
586 #endif
587 #if !defined(Z7_NO_METHODS_FILTERS) || defined(Z7_USE_FILTER_ARMT)
543 CASE_BRA_CONV(ARMT) 588 CASE_BRA_CONV(ARMT)
589 #endif
544 default: 590 default:
545 return SZ_ERROR_UNSUPPORTED; 591 return SZ_ERROR_UNSUPPORTED;
546 } 592 }
593 continue;
547 } 594 }
548 } 595 #endif
549 #endif 596 } // (c == 1)
597 #endif
550 else 598 else
551 return SZ_ERROR_UNSUPPORTED; 599 return SZ_ERROR_UNSUPPORTED;
552 } 600 }
@@ -556,7 +604,7 @@ static SRes SzFolder_Decode2(const CSzFolder *folder,
556 604
557 605
558SRes SzAr_DecodeFolder(const CSzAr *p, UInt32 folderIndex, 606SRes SzAr_DecodeFolder(const CSzAr *p, UInt32 folderIndex,
559 ILookInStream *inStream, UInt64 startPos, 607 ILookInStreamPtr inStream, UInt64 startPos,
560 Byte *outBuffer, size_t outSize, 608 Byte *outBuffer, size_t outSize,
561 ISzAllocPtr allocMain) 609 ISzAllocPtr allocMain)
562{ 610{