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