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