xref: /aosp_15_r20/external/lzma/C/Lzma2DecMt.c (revision f6dc9357d832569d4d1f5d24eacdb3935a1ae8e6)
1*f6dc9357SAndroid Build Coastguard Worker /* Lzma2DecMt.c -- LZMA2 Decoder Multi-thread
2*f6dc9357SAndroid Build Coastguard Worker 2023-04-13 : 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 // #define SHOW_DEBUG_INFO
7*f6dc9357SAndroid Build Coastguard Worker // #define Z7_ST
8*f6dc9357SAndroid Build Coastguard Worker 
9*f6dc9357SAndroid Build Coastguard Worker #ifdef SHOW_DEBUG_INFO
10*f6dc9357SAndroid Build Coastguard Worker #include <stdio.h>
11*f6dc9357SAndroid Build Coastguard Worker #endif
12*f6dc9357SAndroid Build Coastguard Worker 
13*f6dc9357SAndroid Build Coastguard Worker #include "Alloc.h"
14*f6dc9357SAndroid Build Coastguard Worker 
15*f6dc9357SAndroid Build Coastguard Worker #include "Lzma2Dec.h"
16*f6dc9357SAndroid Build Coastguard Worker #include "Lzma2DecMt.h"
17*f6dc9357SAndroid Build Coastguard Worker 
18*f6dc9357SAndroid Build Coastguard Worker #ifndef Z7_ST
19*f6dc9357SAndroid Build Coastguard Worker #include "MtDec.h"
20*f6dc9357SAndroid Build Coastguard Worker 
21*f6dc9357SAndroid Build Coastguard Worker #define LZMA2DECMT_OUT_BLOCK_MAX_DEFAULT (1 << 28)
22*f6dc9357SAndroid Build Coastguard Worker #endif
23*f6dc9357SAndroid Build Coastguard Worker 
24*f6dc9357SAndroid Build Coastguard Worker 
25*f6dc9357SAndroid Build Coastguard Worker #ifndef Z7_ST
26*f6dc9357SAndroid Build Coastguard Worker #ifdef SHOW_DEBUG_INFO
27*f6dc9357SAndroid Build Coastguard Worker #define PRF(x) x
28*f6dc9357SAndroid Build Coastguard Worker #else
29*f6dc9357SAndroid Build Coastguard Worker #define PRF(x)
30*f6dc9357SAndroid Build Coastguard Worker #endif
31*f6dc9357SAndroid Build Coastguard Worker #define PRF_STR(s) PRF(printf("\n" s "\n");)
32*f6dc9357SAndroid Build Coastguard Worker #define PRF_STR_INT_2(s, d1, d2) PRF(printf("\n" s " %d %d\n", (unsigned)d1, (unsigned)d2);)
33*f6dc9357SAndroid Build Coastguard Worker #endif
34*f6dc9357SAndroid Build Coastguard Worker 
35*f6dc9357SAndroid Build Coastguard Worker 
Lzma2DecMtProps_Init(CLzma2DecMtProps * p)36*f6dc9357SAndroid Build Coastguard Worker void Lzma2DecMtProps_Init(CLzma2DecMtProps *p)
37*f6dc9357SAndroid Build Coastguard Worker {
38*f6dc9357SAndroid Build Coastguard Worker   p->inBufSize_ST = 1 << 20;
39*f6dc9357SAndroid Build Coastguard Worker   p->outStep_ST = 1 << 20;
40*f6dc9357SAndroid Build Coastguard Worker 
41*f6dc9357SAndroid Build Coastguard Worker   #ifndef Z7_ST
42*f6dc9357SAndroid Build Coastguard Worker   p->numThreads = 1;
43*f6dc9357SAndroid Build Coastguard Worker   p->inBufSize_MT = 1 << 18;
44*f6dc9357SAndroid Build Coastguard Worker   p->outBlockMax = LZMA2DECMT_OUT_BLOCK_MAX_DEFAULT;
45*f6dc9357SAndroid Build Coastguard Worker   p->inBlockMax = p->outBlockMax + p->outBlockMax / 16;
46*f6dc9357SAndroid Build Coastguard Worker   #endif
47*f6dc9357SAndroid Build Coastguard Worker }
48*f6dc9357SAndroid Build Coastguard Worker 
49*f6dc9357SAndroid Build Coastguard Worker 
50*f6dc9357SAndroid Build Coastguard Worker 
51*f6dc9357SAndroid Build Coastguard Worker #ifndef Z7_ST
52*f6dc9357SAndroid Build Coastguard Worker 
53*f6dc9357SAndroid Build Coastguard Worker /* ---------- CLzma2DecMtThread ---------- */
54*f6dc9357SAndroid Build Coastguard Worker 
55*f6dc9357SAndroid Build Coastguard Worker typedef struct
56*f6dc9357SAndroid Build Coastguard Worker {
57*f6dc9357SAndroid Build Coastguard Worker   CLzma2Dec dec;
58*f6dc9357SAndroid Build Coastguard Worker   Byte dec_created;
59*f6dc9357SAndroid Build Coastguard Worker   Byte needInit;
60*f6dc9357SAndroid Build Coastguard Worker 
61*f6dc9357SAndroid Build Coastguard Worker   Byte *outBuf;
62*f6dc9357SAndroid Build Coastguard Worker   size_t outBufSize;
63*f6dc9357SAndroid Build Coastguard Worker 
64*f6dc9357SAndroid Build Coastguard Worker   EMtDecParseState state;
65*f6dc9357SAndroid Build Coastguard Worker   ELzma2ParseStatus parseStatus;
66*f6dc9357SAndroid Build Coastguard Worker 
67*f6dc9357SAndroid Build Coastguard Worker   size_t inPreSize;
68*f6dc9357SAndroid Build Coastguard Worker   size_t outPreSize;
69*f6dc9357SAndroid Build Coastguard Worker 
70*f6dc9357SAndroid Build Coastguard Worker   size_t inCodeSize;
71*f6dc9357SAndroid Build Coastguard Worker   size_t outCodeSize;
72*f6dc9357SAndroid Build Coastguard Worker   SRes codeRes;
73*f6dc9357SAndroid Build Coastguard Worker 
74*f6dc9357SAndroid Build Coastguard Worker   CAlignOffsetAlloc alloc;
75*f6dc9357SAndroid Build Coastguard Worker 
76*f6dc9357SAndroid Build Coastguard Worker   Byte mtPad[1 << 7];
77*f6dc9357SAndroid Build Coastguard Worker } CLzma2DecMtThread;
78*f6dc9357SAndroid Build Coastguard Worker 
79*f6dc9357SAndroid Build Coastguard Worker #endif
80*f6dc9357SAndroid Build Coastguard Worker 
81*f6dc9357SAndroid Build Coastguard Worker 
82*f6dc9357SAndroid Build Coastguard Worker /* ---------- CLzma2DecMt ---------- */
83*f6dc9357SAndroid Build Coastguard Worker 
84*f6dc9357SAndroid Build Coastguard Worker struct CLzma2DecMt
85*f6dc9357SAndroid Build Coastguard Worker {
86*f6dc9357SAndroid Build Coastguard Worker   // ISzAllocPtr alloc;
87*f6dc9357SAndroid Build Coastguard Worker   ISzAllocPtr allocMid;
88*f6dc9357SAndroid Build Coastguard Worker 
89*f6dc9357SAndroid Build Coastguard Worker   CAlignOffsetAlloc alignOffsetAlloc;
90*f6dc9357SAndroid Build Coastguard Worker   CLzma2DecMtProps props;
91*f6dc9357SAndroid Build Coastguard Worker   Byte prop;
92*f6dc9357SAndroid Build Coastguard Worker 
93*f6dc9357SAndroid Build Coastguard Worker   ISeqInStreamPtr inStream;
94*f6dc9357SAndroid Build Coastguard Worker   ISeqOutStreamPtr outStream;
95*f6dc9357SAndroid Build Coastguard Worker   ICompressProgressPtr progress;
96*f6dc9357SAndroid Build Coastguard Worker 
97*f6dc9357SAndroid Build Coastguard Worker   BoolInt finishMode;
98*f6dc9357SAndroid Build Coastguard Worker   BoolInt outSize_Defined;
99*f6dc9357SAndroid Build Coastguard Worker   UInt64 outSize;
100*f6dc9357SAndroid Build Coastguard Worker 
101*f6dc9357SAndroid Build Coastguard Worker   UInt64 outProcessed;
102*f6dc9357SAndroid Build Coastguard Worker   UInt64 inProcessed;
103*f6dc9357SAndroid Build Coastguard Worker   BoolInt readWasFinished;
104*f6dc9357SAndroid Build Coastguard Worker   SRes readRes;
105*f6dc9357SAndroid Build Coastguard Worker 
106*f6dc9357SAndroid Build Coastguard Worker   Byte *inBuf;
107*f6dc9357SAndroid Build Coastguard Worker   size_t inBufSize;
108*f6dc9357SAndroid Build Coastguard Worker   Byte dec_created;
109*f6dc9357SAndroid Build Coastguard Worker   CLzma2Dec dec;
110*f6dc9357SAndroid Build Coastguard Worker 
111*f6dc9357SAndroid Build Coastguard Worker   size_t inPos;
112*f6dc9357SAndroid Build Coastguard Worker   size_t inLim;
113*f6dc9357SAndroid Build Coastguard Worker 
114*f6dc9357SAndroid Build Coastguard Worker   #ifndef Z7_ST
115*f6dc9357SAndroid Build Coastguard Worker   UInt64 outProcessed_Parse;
116*f6dc9357SAndroid Build Coastguard Worker   BoolInt mtc_WasConstructed;
117*f6dc9357SAndroid Build Coastguard Worker   CMtDec mtc;
118*f6dc9357SAndroid Build Coastguard Worker   CLzma2DecMtThread coders[MTDEC_THREADS_MAX];
119*f6dc9357SAndroid Build Coastguard Worker   #endif
120*f6dc9357SAndroid Build Coastguard Worker };
121*f6dc9357SAndroid Build Coastguard Worker 
122*f6dc9357SAndroid Build Coastguard Worker 
123*f6dc9357SAndroid Build Coastguard Worker 
Lzma2DecMt_Create(ISzAllocPtr alloc,ISzAllocPtr allocMid)124*f6dc9357SAndroid Build Coastguard Worker CLzma2DecMtHandle Lzma2DecMt_Create(ISzAllocPtr alloc, ISzAllocPtr allocMid)
125*f6dc9357SAndroid Build Coastguard Worker {
126*f6dc9357SAndroid Build Coastguard Worker   CLzma2DecMt *p = (CLzma2DecMt *)ISzAlloc_Alloc(alloc, sizeof(CLzma2DecMt));
127*f6dc9357SAndroid Build Coastguard Worker   if (!p)
128*f6dc9357SAndroid Build Coastguard Worker     return NULL;
129*f6dc9357SAndroid Build Coastguard Worker 
130*f6dc9357SAndroid Build Coastguard Worker   // p->alloc = alloc;
131*f6dc9357SAndroid Build Coastguard Worker   p->allocMid = allocMid;
132*f6dc9357SAndroid Build Coastguard Worker 
133*f6dc9357SAndroid Build Coastguard Worker   AlignOffsetAlloc_CreateVTable(&p->alignOffsetAlloc);
134*f6dc9357SAndroid Build Coastguard Worker   p->alignOffsetAlloc.numAlignBits = 7;
135*f6dc9357SAndroid Build Coastguard Worker   p->alignOffsetAlloc.offset = 0;
136*f6dc9357SAndroid Build Coastguard Worker   p->alignOffsetAlloc.baseAlloc = alloc;
137*f6dc9357SAndroid Build Coastguard Worker 
138*f6dc9357SAndroid Build Coastguard Worker   p->inBuf = NULL;
139*f6dc9357SAndroid Build Coastguard Worker   p->inBufSize = 0;
140*f6dc9357SAndroid Build Coastguard Worker   p->dec_created = False;
141*f6dc9357SAndroid Build Coastguard Worker 
142*f6dc9357SAndroid Build Coastguard Worker   // Lzma2DecMtProps_Init(&p->props);
143*f6dc9357SAndroid Build Coastguard Worker 
144*f6dc9357SAndroid Build Coastguard Worker   #ifndef Z7_ST
145*f6dc9357SAndroid Build Coastguard Worker   p->mtc_WasConstructed = False;
146*f6dc9357SAndroid Build Coastguard Worker   {
147*f6dc9357SAndroid Build Coastguard Worker     unsigned i;
148*f6dc9357SAndroid Build Coastguard Worker     for (i = 0; i < MTDEC_THREADS_MAX; i++)
149*f6dc9357SAndroid Build Coastguard Worker     {
150*f6dc9357SAndroid Build Coastguard Worker       CLzma2DecMtThread *t = &p->coders[i];
151*f6dc9357SAndroid Build Coastguard Worker       t->dec_created = False;
152*f6dc9357SAndroid Build Coastguard Worker       t->outBuf = NULL;
153*f6dc9357SAndroid Build Coastguard Worker       t->outBufSize = 0;
154*f6dc9357SAndroid Build Coastguard Worker     }
155*f6dc9357SAndroid Build Coastguard Worker   }
156*f6dc9357SAndroid Build Coastguard Worker   #endif
157*f6dc9357SAndroid Build Coastguard Worker 
158*f6dc9357SAndroid Build Coastguard Worker   return (CLzma2DecMtHandle)(void *)p;
159*f6dc9357SAndroid Build Coastguard Worker }
160*f6dc9357SAndroid Build Coastguard Worker 
161*f6dc9357SAndroid Build Coastguard Worker 
162*f6dc9357SAndroid Build Coastguard Worker #ifndef Z7_ST
163*f6dc9357SAndroid Build Coastguard Worker 
Lzma2DecMt_FreeOutBufs(CLzma2DecMt * p)164*f6dc9357SAndroid Build Coastguard Worker static void Lzma2DecMt_FreeOutBufs(CLzma2DecMt *p)
165*f6dc9357SAndroid Build Coastguard Worker {
166*f6dc9357SAndroid Build Coastguard Worker   unsigned i;
167*f6dc9357SAndroid Build Coastguard Worker   for (i = 0; i < MTDEC_THREADS_MAX; i++)
168*f6dc9357SAndroid Build Coastguard Worker   {
169*f6dc9357SAndroid Build Coastguard Worker     CLzma2DecMtThread *t = &p->coders[i];
170*f6dc9357SAndroid Build Coastguard Worker     if (t->outBuf)
171*f6dc9357SAndroid Build Coastguard Worker     {
172*f6dc9357SAndroid Build Coastguard Worker       ISzAlloc_Free(p->allocMid, t->outBuf);
173*f6dc9357SAndroid Build Coastguard Worker       t->outBuf = NULL;
174*f6dc9357SAndroid Build Coastguard Worker       t->outBufSize = 0;
175*f6dc9357SAndroid Build Coastguard Worker     }
176*f6dc9357SAndroid Build Coastguard Worker   }
177*f6dc9357SAndroid Build Coastguard Worker }
178*f6dc9357SAndroid Build Coastguard Worker 
179*f6dc9357SAndroid Build Coastguard Worker #endif
180*f6dc9357SAndroid Build Coastguard Worker 
181*f6dc9357SAndroid Build Coastguard Worker 
Lzma2DecMt_FreeSt(CLzma2DecMt * p)182*f6dc9357SAndroid Build Coastguard Worker static void Lzma2DecMt_FreeSt(CLzma2DecMt *p)
183*f6dc9357SAndroid Build Coastguard Worker {
184*f6dc9357SAndroid Build Coastguard Worker   if (p->dec_created)
185*f6dc9357SAndroid Build Coastguard Worker   {
186*f6dc9357SAndroid Build Coastguard Worker     Lzma2Dec_Free(&p->dec, &p->alignOffsetAlloc.vt);
187*f6dc9357SAndroid Build Coastguard Worker     p->dec_created = False;
188*f6dc9357SAndroid Build Coastguard Worker   }
189*f6dc9357SAndroid Build Coastguard Worker   if (p->inBuf)
190*f6dc9357SAndroid Build Coastguard Worker   {
191*f6dc9357SAndroid Build Coastguard Worker     ISzAlloc_Free(p->allocMid, p->inBuf);
192*f6dc9357SAndroid Build Coastguard Worker     p->inBuf = NULL;
193*f6dc9357SAndroid Build Coastguard Worker   }
194*f6dc9357SAndroid Build Coastguard Worker   p->inBufSize = 0;
195*f6dc9357SAndroid Build Coastguard Worker }
196*f6dc9357SAndroid Build Coastguard Worker 
197*f6dc9357SAndroid Build Coastguard Worker 
198*f6dc9357SAndroid Build Coastguard Worker // #define GET_CLzma2DecMt_p CLzma2DecMt *p = (CLzma2DecMt *)(void *)pp;
199*f6dc9357SAndroid Build Coastguard Worker 
Lzma2DecMt_Destroy(CLzma2DecMtHandle p)200*f6dc9357SAndroid Build Coastguard Worker void Lzma2DecMt_Destroy(CLzma2DecMtHandle p)
201*f6dc9357SAndroid Build Coastguard Worker {
202*f6dc9357SAndroid Build Coastguard Worker   // GET_CLzma2DecMt_p
203*f6dc9357SAndroid Build Coastguard Worker 
204*f6dc9357SAndroid Build Coastguard Worker   Lzma2DecMt_FreeSt(p);
205*f6dc9357SAndroid Build Coastguard Worker 
206*f6dc9357SAndroid Build Coastguard Worker   #ifndef Z7_ST
207*f6dc9357SAndroid Build Coastguard Worker 
208*f6dc9357SAndroid Build Coastguard Worker   if (p->mtc_WasConstructed)
209*f6dc9357SAndroid Build Coastguard Worker   {
210*f6dc9357SAndroid Build Coastguard Worker     MtDec_Destruct(&p->mtc);
211*f6dc9357SAndroid Build Coastguard Worker     p->mtc_WasConstructed = False;
212*f6dc9357SAndroid Build Coastguard Worker   }
213*f6dc9357SAndroid Build Coastguard Worker   {
214*f6dc9357SAndroid Build Coastguard Worker     unsigned i;
215*f6dc9357SAndroid Build Coastguard Worker     for (i = 0; i < MTDEC_THREADS_MAX; i++)
216*f6dc9357SAndroid Build Coastguard Worker     {
217*f6dc9357SAndroid Build Coastguard Worker       CLzma2DecMtThread *t = &p->coders[i];
218*f6dc9357SAndroid Build Coastguard Worker       if (t->dec_created)
219*f6dc9357SAndroid Build Coastguard Worker       {
220*f6dc9357SAndroid Build Coastguard Worker         // we don't need to free dict here
221*f6dc9357SAndroid Build Coastguard Worker         Lzma2Dec_FreeProbs(&t->dec, &t->alloc.vt); // p->alloc !!!
222*f6dc9357SAndroid Build Coastguard Worker         t->dec_created = False;
223*f6dc9357SAndroid Build Coastguard Worker       }
224*f6dc9357SAndroid Build Coastguard Worker     }
225*f6dc9357SAndroid Build Coastguard Worker   }
226*f6dc9357SAndroid Build Coastguard Worker   Lzma2DecMt_FreeOutBufs(p);
227*f6dc9357SAndroid Build Coastguard Worker 
228*f6dc9357SAndroid Build Coastguard Worker   #endif
229*f6dc9357SAndroid Build Coastguard Worker 
230*f6dc9357SAndroid Build Coastguard Worker   ISzAlloc_Free(p->alignOffsetAlloc.baseAlloc, p);
231*f6dc9357SAndroid Build Coastguard Worker }
232*f6dc9357SAndroid Build Coastguard Worker 
233*f6dc9357SAndroid Build Coastguard Worker 
234*f6dc9357SAndroid Build Coastguard Worker 
235*f6dc9357SAndroid Build Coastguard Worker #ifndef Z7_ST
236*f6dc9357SAndroid Build Coastguard Worker 
Lzma2DecMt_MtCallback_Parse(void * obj,unsigned coderIndex,CMtDecCallbackInfo * cc)237*f6dc9357SAndroid Build Coastguard Worker static void Lzma2DecMt_MtCallback_Parse(void *obj, unsigned coderIndex, CMtDecCallbackInfo *cc)
238*f6dc9357SAndroid Build Coastguard Worker {
239*f6dc9357SAndroid Build Coastguard Worker   CLzma2DecMt *me = (CLzma2DecMt *)obj;
240*f6dc9357SAndroid Build Coastguard Worker   CLzma2DecMtThread *t = &me->coders[coderIndex];
241*f6dc9357SAndroid Build Coastguard Worker 
242*f6dc9357SAndroid Build Coastguard Worker   PRF_STR_INT_2("Parse", coderIndex, cc->srcSize)
243*f6dc9357SAndroid Build Coastguard Worker 
244*f6dc9357SAndroid Build Coastguard Worker   cc->state = MTDEC_PARSE_CONTINUE;
245*f6dc9357SAndroid Build Coastguard Worker 
246*f6dc9357SAndroid Build Coastguard Worker   if (cc->startCall)
247*f6dc9357SAndroid Build Coastguard Worker   {
248*f6dc9357SAndroid Build Coastguard Worker     if (!t->dec_created)
249*f6dc9357SAndroid Build Coastguard Worker     {
250*f6dc9357SAndroid Build Coastguard Worker       Lzma2Dec_CONSTRUCT(&t->dec)
251*f6dc9357SAndroid Build Coastguard Worker       t->dec_created = True;
252*f6dc9357SAndroid Build Coastguard Worker       AlignOffsetAlloc_CreateVTable(&t->alloc);
253*f6dc9357SAndroid Build Coastguard Worker       {
254*f6dc9357SAndroid Build Coastguard Worker         /* (1 << 12) is expected size of one way in data cache.
255*f6dc9357SAndroid Build Coastguard Worker            We optimize alignment for cache line size of 128 bytes and smaller */
256*f6dc9357SAndroid Build Coastguard Worker         const unsigned kNumAlignBits = 12;
257*f6dc9357SAndroid Build Coastguard Worker         const unsigned kNumCacheLineBits = 7; /* <= kNumAlignBits */
258*f6dc9357SAndroid Build Coastguard Worker         t->alloc.numAlignBits = kNumAlignBits;
259*f6dc9357SAndroid Build Coastguard Worker         t->alloc.offset = ((UInt32)coderIndex * (((unsigned)1 << 11) + (1 << 8) + (1 << 6))) & (((unsigned)1 << kNumAlignBits) - ((unsigned)1 << kNumCacheLineBits));
260*f6dc9357SAndroid Build Coastguard Worker         t->alloc.baseAlloc = me->alignOffsetAlloc.baseAlloc;
261*f6dc9357SAndroid Build Coastguard Worker       }
262*f6dc9357SAndroid Build Coastguard Worker     }
263*f6dc9357SAndroid Build Coastguard Worker     Lzma2Dec_Init(&t->dec);
264*f6dc9357SAndroid Build Coastguard Worker 
265*f6dc9357SAndroid Build Coastguard Worker     t->inPreSize = 0;
266*f6dc9357SAndroid Build Coastguard Worker     t->outPreSize = 0;
267*f6dc9357SAndroid Build Coastguard Worker     // t->blockWasFinished = False;
268*f6dc9357SAndroid Build Coastguard Worker     // t->finishedWithMark = False;
269*f6dc9357SAndroid Build Coastguard Worker     t->parseStatus = (ELzma2ParseStatus)LZMA_STATUS_NOT_SPECIFIED;
270*f6dc9357SAndroid Build Coastguard Worker     t->state = MTDEC_PARSE_CONTINUE;
271*f6dc9357SAndroid Build Coastguard Worker 
272*f6dc9357SAndroid Build Coastguard Worker     t->inCodeSize = 0;
273*f6dc9357SAndroid Build Coastguard Worker     t->outCodeSize = 0;
274*f6dc9357SAndroid Build Coastguard Worker     t->codeRes = SZ_OK;
275*f6dc9357SAndroid Build Coastguard Worker 
276*f6dc9357SAndroid Build Coastguard Worker     // (cc->srcSize == 0) is allowed
277*f6dc9357SAndroid Build Coastguard Worker   }
278*f6dc9357SAndroid Build Coastguard Worker 
279*f6dc9357SAndroid Build Coastguard Worker   {
280*f6dc9357SAndroid Build Coastguard Worker     ELzma2ParseStatus status;
281*f6dc9357SAndroid Build Coastguard Worker     BoolInt overflow;
282*f6dc9357SAndroid Build Coastguard Worker     UInt32 unpackRem = 0;
283*f6dc9357SAndroid Build Coastguard Worker 
284*f6dc9357SAndroid Build Coastguard Worker     int checkFinishBlock = True;
285*f6dc9357SAndroid Build Coastguard Worker     size_t limit = me->props.outBlockMax;
286*f6dc9357SAndroid Build Coastguard Worker     if (me->outSize_Defined)
287*f6dc9357SAndroid Build Coastguard Worker     {
288*f6dc9357SAndroid Build Coastguard Worker       UInt64 rem = me->outSize - me->outProcessed_Parse;
289*f6dc9357SAndroid Build Coastguard Worker       if (limit >= rem)
290*f6dc9357SAndroid Build Coastguard Worker       {
291*f6dc9357SAndroid Build Coastguard Worker         limit = (size_t)rem;
292*f6dc9357SAndroid Build Coastguard Worker         if (!me->finishMode)
293*f6dc9357SAndroid Build Coastguard Worker           checkFinishBlock = False;
294*f6dc9357SAndroid Build Coastguard Worker       }
295*f6dc9357SAndroid Build Coastguard Worker     }
296*f6dc9357SAndroid Build Coastguard Worker 
297*f6dc9357SAndroid Build Coastguard Worker     // checkFinishBlock = False, if we want to decode partial data
298*f6dc9357SAndroid Build Coastguard Worker     // that must be finished at position <= outBlockMax.
299*f6dc9357SAndroid Build Coastguard Worker 
300*f6dc9357SAndroid Build Coastguard Worker     {
301*f6dc9357SAndroid Build Coastguard Worker       const size_t srcOrig = cc->srcSize;
302*f6dc9357SAndroid Build Coastguard Worker       SizeT srcSize_Point = 0;
303*f6dc9357SAndroid Build Coastguard Worker       SizeT dicPos_Point = 0;
304*f6dc9357SAndroid Build Coastguard Worker 
305*f6dc9357SAndroid Build Coastguard Worker       cc->srcSize = 0;
306*f6dc9357SAndroid Build Coastguard Worker       overflow = False;
307*f6dc9357SAndroid Build Coastguard Worker 
308*f6dc9357SAndroid Build Coastguard Worker       for (;;)
309*f6dc9357SAndroid Build Coastguard Worker       {
310*f6dc9357SAndroid Build Coastguard Worker         SizeT srcCur = (SizeT)(srcOrig - cc->srcSize);
311*f6dc9357SAndroid Build Coastguard Worker 
312*f6dc9357SAndroid Build Coastguard Worker         status = Lzma2Dec_Parse(&t->dec,
313*f6dc9357SAndroid Build Coastguard Worker             (SizeT)limit - t->dec.decoder.dicPos,
314*f6dc9357SAndroid Build Coastguard Worker             cc->src + cc->srcSize, &srcCur,
315*f6dc9357SAndroid Build Coastguard Worker             checkFinishBlock);
316*f6dc9357SAndroid Build Coastguard Worker 
317*f6dc9357SAndroid Build Coastguard Worker         cc->srcSize += srcCur;
318*f6dc9357SAndroid Build Coastguard Worker 
319*f6dc9357SAndroid Build Coastguard Worker         if (status == LZMA2_PARSE_STATUS_NEW_CHUNK)
320*f6dc9357SAndroid Build Coastguard Worker         {
321*f6dc9357SAndroid Build Coastguard Worker           if (t->dec.unpackSize > me->props.outBlockMax - t->dec.decoder.dicPos)
322*f6dc9357SAndroid Build Coastguard Worker           {
323*f6dc9357SAndroid Build Coastguard Worker             overflow = True;
324*f6dc9357SAndroid Build Coastguard Worker             break;
325*f6dc9357SAndroid Build Coastguard Worker           }
326*f6dc9357SAndroid Build Coastguard Worker           continue;
327*f6dc9357SAndroid Build Coastguard Worker         }
328*f6dc9357SAndroid Build Coastguard Worker 
329*f6dc9357SAndroid Build Coastguard Worker         if (status == LZMA2_PARSE_STATUS_NEW_BLOCK)
330*f6dc9357SAndroid Build Coastguard Worker         {
331*f6dc9357SAndroid Build Coastguard Worker           if (t->dec.decoder.dicPos == 0)
332*f6dc9357SAndroid Build Coastguard Worker             continue;
333*f6dc9357SAndroid Build Coastguard Worker           // we decode small blocks in one thread
334*f6dc9357SAndroid Build Coastguard Worker           if (t->dec.decoder.dicPos >= (1 << 14))
335*f6dc9357SAndroid Build Coastguard Worker             break;
336*f6dc9357SAndroid Build Coastguard Worker           dicPos_Point = t->dec.decoder.dicPos;
337*f6dc9357SAndroid Build Coastguard Worker           srcSize_Point = (SizeT)cc->srcSize;
338*f6dc9357SAndroid Build Coastguard Worker           continue;
339*f6dc9357SAndroid Build Coastguard Worker         }
340*f6dc9357SAndroid Build Coastguard Worker 
341*f6dc9357SAndroid Build Coastguard Worker         if ((int)status == LZMA_STATUS_NOT_FINISHED && checkFinishBlock
342*f6dc9357SAndroid Build Coastguard Worker             // && limit == t->dec.decoder.dicPos
343*f6dc9357SAndroid Build Coastguard Worker             // && limit == me->props.outBlockMax
344*f6dc9357SAndroid Build Coastguard Worker             )
345*f6dc9357SAndroid Build Coastguard Worker         {
346*f6dc9357SAndroid Build Coastguard Worker           overflow = True;
347*f6dc9357SAndroid Build Coastguard Worker           break;
348*f6dc9357SAndroid Build Coastguard Worker         }
349*f6dc9357SAndroid Build Coastguard Worker 
350*f6dc9357SAndroid Build Coastguard Worker         unpackRem = Lzma2Dec_GetUnpackExtra(&t->dec);
351*f6dc9357SAndroid Build Coastguard Worker         break;
352*f6dc9357SAndroid Build Coastguard Worker       }
353*f6dc9357SAndroid Build Coastguard Worker 
354*f6dc9357SAndroid Build Coastguard Worker       if (dicPos_Point != 0
355*f6dc9357SAndroid Build Coastguard Worker           && (int)status != LZMA2_PARSE_STATUS_NEW_BLOCK
356*f6dc9357SAndroid Build Coastguard Worker           && (int)status != LZMA_STATUS_FINISHED_WITH_MARK
357*f6dc9357SAndroid Build Coastguard Worker           && (int)status != LZMA_STATUS_NOT_SPECIFIED)
358*f6dc9357SAndroid Build Coastguard Worker       {
359*f6dc9357SAndroid Build Coastguard Worker         // we revert to latest newBlock state
360*f6dc9357SAndroid Build Coastguard Worker         status = LZMA2_PARSE_STATUS_NEW_BLOCK;
361*f6dc9357SAndroid Build Coastguard Worker         unpackRem = 0;
362*f6dc9357SAndroid Build Coastguard Worker         t->dec.decoder.dicPos = dicPos_Point;
363*f6dc9357SAndroid Build Coastguard Worker         cc->srcSize = srcSize_Point;
364*f6dc9357SAndroid Build Coastguard Worker         overflow = False;
365*f6dc9357SAndroid Build Coastguard Worker       }
366*f6dc9357SAndroid Build Coastguard Worker     }
367*f6dc9357SAndroid Build Coastguard Worker 
368*f6dc9357SAndroid Build Coastguard Worker     t->inPreSize += cc->srcSize;
369*f6dc9357SAndroid Build Coastguard Worker     t->parseStatus = status;
370*f6dc9357SAndroid Build Coastguard Worker 
371*f6dc9357SAndroid Build Coastguard Worker     if (overflow)
372*f6dc9357SAndroid Build Coastguard Worker       cc->state = MTDEC_PARSE_OVERFLOW;
373*f6dc9357SAndroid Build Coastguard Worker     else
374*f6dc9357SAndroid Build Coastguard Worker     {
375*f6dc9357SAndroid Build Coastguard Worker       size_t dicPos = t->dec.decoder.dicPos;
376*f6dc9357SAndroid Build Coastguard Worker 
377*f6dc9357SAndroid Build Coastguard Worker       if ((int)status != LZMA_STATUS_NEEDS_MORE_INPUT)
378*f6dc9357SAndroid Build Coastguard Worker       {
379*f6dc9357SAndroid Build Coastguard Worker         if (status == LZMA2_PARSE_STATUS_NEW_BLOCK)
380*f6dc9357SAndroid Build Coastguard Worker         {
381*f6dc9357SAndroid Build Coastguard Worker           cc->state = MTDEC_PARSE_NEW;
382*f6dc9357SAndroid Build Coastguard Worker           cc->srcSize--; // we don't need control byte of next block
383*f6dc9357SAndroid Build Coastguard Worker           t->inPreSize--;
384*f6dc9357SAndroid Build Coastguard Worker         }
385*f6dc9357SAndroid Build Coastguard Worker         else
386*f6dc9357SAndroid Build Coastguard Worker         {
387*f6dc9357SAndroid Build Coastguard Worker           cc->state = MTDEC_PARSE_END;
388*f6dc9357SAndroid Build Coastguard Worker           if ((int)status != LZMA_STATUS_FINISHED_WITH_MARK)
389*f6dc9357SAndroid Build Coastguard Worker           {
390*f6dc9357SAndroid Build Coastguard Worker             // (status == LZMA_STATUS_NOT_SPECIFIED)
391*f6dc9357SAndroid Build Coastguard Worker             // (status == LZMA_STATUS_NOT_FINISHED)
392*f6dc9357SAndroid Build Coastguard Worker             if (unpackRem != 0)
393*f6dc9357SAndroid Build Coastguard Worker             {
394*f6dc9357SAndroid Build Coastguard Worker               /* we also reserve space for max possible number of output bytes of current LZMA chunk */
395*f6dc9357SAndroid Build Coastguard Worker               size_t rem = limit - dicPos;
396*f6dc9357SAndroid Build Coastguard Worker               if (rem > unpackRem)
397*f6dc9357SAndroid Build Coastguard Worker                 rem = unpackRem;
398*f6dc9357SAndroid Build Coastguard Worker               dicPos += rem;
399*f6dc9357SAndroid Build Coastguard Worker             }
400*f6dc9357SAndroid Build Coastguard Worker           }
401*f6dc9357SAndroid Build Coastguard Worker         }
402*f6dc9357SAndroid Build Coastguard Worker 
403*f6dc9357SAndroid Build Coastguard Worker         me->outProcessed_Parse += dicPos;
404*f6dc9357SAndroid Build Coastguard Worker       }
405*f6dc9357SAndroid Build Coastguard Worker 
406*f6dc9357SAndroid Build Coastguard Worker       cc->outPos = dicPos;
407*f6dc9357SAndroid Build Coastguard Worker       t->outPreSize = (size_t)dicPos;
408*f6dc9357SAndroid Build Coastguard Worker     }
409*f6dc9357SAndroid Build Coastguard Worker 
410*f6dc9357SAndroid Build Coastguard Worker     t->state = cc->state;
411*f6dc9357SAndroid Build Coastguard Worker     return;
412*f6dc9357SAndroid Build Coastguard Worker   }
413*f6dc9357SAndroid Build Coastguard Worker }
414*f6dc9357SAndroid Build Coastguard Worker 
415*f6dc9357SAndroid Build Coastguard Worker 
Lzma2DecMt_MtCallback_PreCode(void * pp,unsigned coderIndex)416*f6dc9357SAndroid Build Coastguard Worker static SRes Lzma2DecMt_MtCallback_PreCode(void *pp, unsigned coderIndex)
417*f6dc9357SAndroid Build Coastguard Worker {
418*f6dc9357SAndroid Build Coastguard Worker   CLzma2DecMt *me = (CLzma2DecMt *)pp;
419*f6dc9357SAndroid Build Coastguard Worker   CLzma2DecMtThread *t = &me->coders[coderIndex];
420*f6dc9357SAndroid Build Coastguard Worker   Byte *dest = t->outBuf;
421*f6dc9357SAndroid Build Coastguard Worker 
422*f6dc9357SAndroid Build Coastguard Worker   if (t->inPreSize == 0)
423*f6dc9357SAndroid Build Coastguard Worker   {
424*f6dc9357SAndroid Build Coastguard Worker     t->codeRes = SZ_ERROR_DATA;
425*f6dc9357SAndroid Build Coastguard Worker     return t->codeRes;
426*f6dc9357SAndroid Build Coastguard Worker   }
427*f6dc9357SAndroid Build Coastguard Worker 
428*f6dc9357SAndroid Build Coastguard Worker   if (!dest || t->outBufSize < t->outPreSize)
429*f6dc9357SAndroid Build Coastguard Worker   {
430*f6dc9357SAndroid Build Coastguard Worker     if (dest)
431*f6dc9357SAndroid Build Coastguard Worker     {
432*f6dc9357SAndroid Build Coastguard Worker       ISzAlloc_Free(me->allocMid, dest);
433*f6dc9357SAndroid Build Coastguard Worker       t->outBuf = NULL;
434*f6dc9357SAndroid Build Coastguard Worker       t->outBufSize = 0;
435*f6dc9357SAndroid Build Coastguard Worker     }
436*f6dc9357SAndroid Build Coastguard Worker 
437*f6dc9357SAndroid Build Coastguard Worker     dest = (Byte *)ISzAlloc_Alloc(me->allocMid, t->outPreSize
438*f6dc9357SAndroid Build Coastguard Worker         // + (1 << 28)
439*f6dc9357SAndroid Build Coastguard Worker         );
440*f6dc9357SAndroid Build Coastguard Worker     // Sleep(200);
441*f6dc9357SAndroid Build Coastguard Worker     if (!dest)
442*f6dc9357SAndroid Build Coastguard Worker       return SZ_ERROR_MEM;
443*f6dc9357SAndroid Build Coastguard Worker     t->outBuf = dest;
444*f6dc9357SAndroid Build Coastguard Worker     t->outBufSize = t->outPreSize;
445*f6dc9357SAndroid Build Coastguard Worker   }
446*f6dc9357SAndroid Build Coastguard Worker 
447*f6dc9357SAndroid Build Coastguard Worker   t->dec.decoder.dic = dest;
448*f6dc9357SAndroid Build Coastguard Worker   t->dec.decoder.dicBufSize = (SizeT)t->outPreSize;
449*f6dc9357SAndroid Build Coastguard Worker 
450*f6dc9357SAndroid Build Coastguard Worker   t->needInit = True;
451*f6dc9357SAndroid Build Coastguard Worker 
452*f6dc9357SAndroid Build Coastguard Worker   return Lzma2Dec_AllocateProbs(&t->dec, me->prop, &t->alloc.vt); // alloc.vt
453*f6dc9357SAndroid Build Coastguard Worker }
454*f6dc9357SAndroid Build Coastguard Worker 
455*f6dc9357SAndroid Build Coastguard Worker 
Lzma2DecMt_MtCallback_Code(void * pp,unsigned coderIndex,const Byte * src,size_t srcSize,int srcFinished,UInt64 * inCodePos,UInt64 * outCodePos,int * stop)456*f6dc9357SAndroid Build Coastguard Worker static SRes Lzma2DecMt_MtCallback_Code(void *pp, unsigned coderIndex,
457*f6dc9357SAndroid Build Coastguard Worker     const Byte *src, size_t srcSize, int srcFinished,
458*f6dc9357SAndroid Build Coastguard Worker     // int finished, int blockFinished,
459*f6dc9357SAndroid Build Coastguard Worker     UInt64 *inCodePos, UInt64 *outCodePos, int *stop)
460*f6dc9357SAndroid Build Coastguard Worker {
461*f6dc9357SAndroid Build Coastguard Worker   CLzma2DecMt *me = (CLzma2DecMt *)pp;
462*f6dc9357SAndroid Build Coastguard Worker   CLzma2DecMtThread *t = &me->coders[coderIndex];
463*f6dc9357SAndroid Build Coastguard Worker 
464*f6dc9357SAndroid Build Coastguard Worker   UNUSED_VAR(srcFinished)
465*f6dc9357SAndroid Build Coastguard Worker 
466*f6dc9357SAndroid Build Coastguard Worker   PRF_STR_INT_2("Code", coderIndex, srcSize)
467*f6dc9357SAndroid Build Coastguard Worker 
468*f6dc9357SAndroid Build Coastguard Worker   *inCodePos = t->inCodeSize;
469*f6dc9357SAndroid Build Coastguard Worker   *outCodePos = 0;
470*f6dc9357SAndroid Build Coastguard Worker   *stop = True;
471*f6dc9357SAndroid Build Coastguard Worker 
472*f6dc9357SAndroid Build Coastguard Worker   if (t->needInit)
473*f6dc9357SAndroid Build Coastguard Worker   {
474*f6dc9357SAndroid Build Coastguard Worker     Lzma2Dec_Init(&t->dec);
475*f6dc9357SAndroid Build Coastguard Worker     t->needInit = False;
476*f6dc9357SAndroid Build Coastguard Worker   }
477*f6dc9357SAndroid Build Coastguard Worker 
478*f6dc9357SAndroid Build Coastguard Worker   {
479*f6dc9357SAndroid Build Coastguard Worker     ELzmaStatus status;
480*f6dc9357SAndroid Build Coastguard Worker     SizeT srcProcessed = (SizeT)srcSize;
481*f6dc9357SAndroid Build Coastguard Worker     BoolInt blockWasFinished =
482*f6dc9357SAndroid Build Coastguard Worker         ((int)t->parseStatus == LZMA_STATUS_FINISHED_WITH_MARK
483*f6dc9357SAndroid Build Coastguard Worker         || t->parseStatus == LZMA2_PARSE_STATUS_NEW_BLOCK);
484*f6dc9357SAndroid Build Coastguard Worker 
485*f6dc9357SAndroid Build Coastguard Worker     SRes res = Lzma2Dec_DecodeToDic(&t->dec,
486*f6dc9357SAndroid Build Coastguard Worker         (SizeT)t->outPreSize,
487*f6dc9357SAndroid Build Coastguard Worker         src, &srcProcessed,
488*f6dc9357SAndroid Build Coastguard Worker         blockWasFinished ? LZMA_FINISH_END : LZMA_FINISH_ANY,
489*f6dc9357SAndroid Build Coastguard Worker         &status);
490*f6dc9357SAndroid Build Coastguard Worker 
491*f6dc9357SAndroid Build Coastguard Worker     t->codeRes = res;
492*f6dc9357SAndroid Build Coastguard Worker 
493*f6dc9357SAndroid Build Coastguard Worker     t->inCodeSize += srcProcessed;
494*f6dc9357SAndroid Build Coastguard Worker     *inCodePos = t->inCodeSize;
495*f6dc9357SAndroid Build Coastguard Worker     t->outCodeSize = t->dec.decoder.dicPos;
496*f6dc9357SAndroid Build Coastguard Worker     *outCodePos = t->dec.decoder.dicPos;
497*f6dc9357SAndroid Build Coastguard Worker 
498*f6dc9357SAndroid Build Coastguard Worker     if (res != SZ_OK)
499*f6dc9357SAndroid Build Coastguard Worker       return res;
500*f6dc9357SAndroid Build Coastguard Worker 
501*f6dc9357SAndroid Build Coastguard Worker     if (srcProcessed == srcSize)
502*f6dc9357SAndroid Build Coastguard Worker       *stop = False;
503*f6dc9357SAndroid Build Coastguard Worker 
504*f6dc9357SAndroid Build Coastguard Worker     if (blockWasFinished)
505*f6dc9357SAndroid Build Coastguard Worker     {
506*f6dc9357SAndroid Build Coastguard Worker       if (srcSize != srcProcessed)
507*f6dc9357SAndroid Build Coastguard Worker         return SZ_ERROR_FAIL;
508*f6dc9357SAndroid Build Coastguard Worker 
509*f6dc9357SAndroid Build Coastguard Worker       if (t->inPreSize == t->inCodeSize)
510*f6dc9357SAndroid Build Coastguard Worker       {
511*f6dc9357SAndroid Build Coastguard Worker         if (t->outPreSize != t->outCodeSize)
512*f6dc9357SAndroid Build Coastguard Worker           return SZ_ERROR_FAIL;
513*f6dc9357SAndroid Build Coastguard Worker         *stop = True;
514*f6dc9357SAndroid Build Coastguard Worker       }
515*f6dc9357SAndroid Build Coastguard Worker     }
516*f6dc9357SAndroid Build Coastguard Worker     else
517*f6dc9357SAndroid Build Coastguard Worker     {
518*f6dc9357SAndroid Build Coastguard Worker       if (t->outPreSize == t->outCodeSize)
519*f6dc9357SAndroid Build Coastguard Worker         *stop = True;
520*f6dc9357SAndroid Build Coastguard Worker     }
521*f6dc9357SAndroid Build Coastguard Worker 
522*f6dc9357SAndroid Build Coastguard Worker     return SZ_OK;
523*f6dc9357SAndroid Build Coastguard Worker   }
524*f6dc9357SAndroid Build Coastguard Worker }
525*f6dc9357SAndroid Build Coastguard Worker 
526*f6dc9357SAndroid Build Coastguard Worker 
527*f6dc9357SAndroid Build Coastguard Worker #define LZMA2DECMT_STREAM_WRITE_STEP (1 << 24)
528*f6dc9357SAndroid Build Coastguard Worker 
Lzma2DecMt_MtCallback_Write(void * pp,unsigned coderIndex,BoolInt needWriteToStream,const Byte * src,size_t srcSize,BoolInt isCross,BoolInt * needContinue,BoolInt * canRecode)529*f6dc9357SAndroid Build Coastguard Worker static SRes Lzma2DecMt_MtCallback_Write(void *pp, unsigned coderIndex,
530*f6dc9357SAndroid Build Coastguard Worker     BoolInt needWriteToStream,
531*f6dc9357SAndroid Build Coastguard Worker     const Byte *src, size_t srcSize, BoolInt isCross,
532*f6dc9357SAndroid Build Coastguard Worker     BoolInt *needContinue, BoolInt *canRecode)
533*f6dc9357SAndroid Build Coastguard Worker {
534*f6dc9357SAndroid Build Coastguard Worker   CLzma2DecMt *me = (CLzma2DecMt *)pp;
535*f6dc9357SAndroid Build Coastguard Worker   const CLzma2DecMtThread *t = &me->coders[coderIndex];
536*f6dc9357SAndroid Build Coastguard Worker   size_t size = t->outCodeSize;
537*f6dc9357SAndroid Build Coastguard Worker   const Byte *data = t->outBuf;
538*f6dc9357SAndroid Build Coastguard Worker   BoolInt needContinue2 = True;
539*f6dc9357SAndroid Build Coastguard Worker 
540*f6dc9357SAndroid Build Coastguard Worker   UNUSED_VAR(src)
541*f6dc9357SAndroid Build Coastguard Worker   UNUSED_VAR(srcSize)
542*f6dc9357SAndroid Build Coastguard Worker   UNUSED_VAR(isCross)
543*f6dc9357SAndroid Build Coastguard Worker 
544*f6dc9357SAndroid Build Coastguard Worker   PRF_STR_INT_2("Write", coderIndex, srcSize)
545*f6dc9357SAndroid Build Coastguard Worker 
546*f6dc9357SAndroid Build Coastguard Worker   *needContinue = False;
547*f6dc9357SAndroid Build Coastguard Worker   *canRecode = True;
548*f6dc9357SAndroid Build Coastguard Worker 
549*f6dc9357SAndroid Build Coastguard Worker   if (
550*f6dc9357SAndroid Build Coastguard Worker       // t->parseStatus == LZMA_STATUS_FINISHED_WITH_MARK
551*f6dc9357SAndroid Build Coastguard Worker          t->state == MTDEC_PARSE_OVERFLOW
552*f6dc9357SAndroid Build Coastguard Worker       || t->state == MTDEC_PARSE_END)
553*f6dc9357SAndroid Build Coastguard Worker     needContinue2 = False;
554*f6dc9357SAndroid Build Coastguard Worker 
555*f6dc9357SAndroid Build Coastguard Worker 
556*f6dc9357SAndroid Build Coastguard Worker   if (!needWriteToStream)
557*f6dc9357SAndroid Build Coastguard Worker     return SZ_OK;
558*f6dc9357SAndroid Build Coastguard Worker 
559*f6dc9357SAndroid Build Coastguard Worker   me->mtc.inProcessed += t->inCodeSize;
560*f6dc9357SAndroid Build Coastguard Worker 
561*f6dc9357SAndroid Build Coastguard Worker   if (t->codeRes == SZ_OK)
562*f6dc9357SAndroid Build Coastguard Worker   if ((int)t->parseStatus == LZMA_STATUS_FINISHED_WITH_MARK
563*f6dc9357SAndroid Build Coastguard Worker       || t->parseStatus == LZMA2_PARSE_STATUS_NEW_BLOCK)
564*f6dc9357SAndroid Build Coastguard Worker   if (t->outPreSize != t->outCodeSize
565*f6dc9357SAndroid Build Coastguard Worker       || t->inPreSize != t->inCodeSize)
566*f6dc9357SAndroid Build Coastguard Worker     return SZ_ERROR_FAIL;
567*f6dc9357SAndroid Build Coastguard Worker 
568*f6dc9357SAndroid Build Coastguard Worker   *canRecode = False;
569*f6dc9357SAndroid Build Coastguard Worker 
570*f6dc9357SAndroid Build Coastguard Worker   if (me->outStream)
571*f6dc9357SAndroid Build Coastguard Worker   {
572*f6dc9357SAndroid Build Coastguard Worker     for (;;)
573*f6dc9357SAndroid Build Coastguard Worker     {
574*f6dc9357SAndroid Build Coastguard Worker       size_t cur = size;
575*f6dc9357SAndroid Build Coastguard Worker       size_t written;
576*f6dc9357SAndroid Build Coastguard Worker       if (cur > LZMA2DECMT_STREAM_WRITE_STEP)
577*f6dc9357SAndroid Build Coastguard Worker         cur = LZMA2DECMT_STREAM_WRITE_STEP;
578*f6dc9357SAndroid Build Coastguard Worker 
579*f6dc9357SAndroid Build Coastguard Worker       written = ISeqOutStream_Write(me->outStream, data, cur);
580*f6dc9357SAndroid Build Coastguard Worker 
581*f6dc9357SAndroid Build Coastguard Worker       me->outProcessed += written;
582*f6dc9357SAndroid Build Coastguard Worker       // me->mtc.writtenTotal += written;
583*f6dc9357SAndroid Build Coastguard Worker       if (written != cur)
584*f6dc9357SAndroid Build Coastguard Worker         return SZ_ERROR_WRITE;
585*f6dc9357SAndroid Build Coastguard Worker       data += cur;
586*f6dc9357SAndroid Build Coastguard Worker       size -= cur;
587*f6dc9357SAndroid Build Coastguard Worker       if (size == 0)
588*f6dc9357SAndroid Build Coastguard Worker       {
589*f6dc9357SAndroid Build Coastguard Worker         *needContinue = needContinue2;
590*f6dc9357SAndroid Build Coastguard Worker         return SZ_OK;
591*f6dc9357SAndroid Build Coastguard Worker       }
592*f6dc9357SAndroid Build Coastguard Worker       RINOK(MtProgress_ProgressAdd(&me->mtc.mtProgress, 0, 0))
593*f6dc9357SAndroid Build Coastguard Worker     }
594*f6dc9357SAndroid Build Coastguard Worker   }
595*f6dc9357SAndroid Build Coastguard Worker 
596*f6dc9357SAndroid Build Coastguard Worker   return SZ_ERROR_FAIL;
597*f6dc9357SAndroid Build Coastguard Worker   /*
598*f6dc9357SAndroid Build Coastguard Worker   if (size > me->outBufSize)
599*f6dc9357SAndroid Build Coastguard Worker     return SZ_ERROR_OUTPUT_EOF;
600*f6dc9357SAndroid Build Coastguard Worker   memcpy(me->outBuf, data, size);
601*f6dc9357SAndroid Build Coastguard Worker   me->outBufSize -= size;
602*f6dc9357SAndroid Build Coastguard Worker   me->outBuf += size;
603*f6dc9357SAndroid Build Coastguard Worker   *needContinue = needContinue2;
604*f6dc9357SAndroid Build Coastguard Worker   return SZ_OK;
605*f6dc9357SAndroid Build Coastguard Worker   */
606*f6dc9357SAndroid Build Coastguard Worker }
607*f6dc9357SAndroid Build Coastguard Worker 
608*f6dc9357SAndroid Build Coastguard Worker #endif
609*f6dc9357SAndroid Build Coastguard Worker 
610*f6dc9357SAndroid Build Coastguard Worker 
Lzma2Dec_Prepare_ST(CLzma2DecMt * p)611*f6dc9357SAndroid Build Coastguard Worker static SRes Lzma2Dec_Prepare_ST(CLzma2DecMt *p)
612*f6dc9357SAndroid Build Coastguard Worker {
613*f6dc9357SAndroid Build Coastguard Worker   if (!p->dec_created)
614*f6dc9357SAndroid Build Coastguard Worker   {
615*f6dc9357SAndroid Build Coastguard Worker     Lzma2Dec_CONSTRUCT(&p->dec)
616*f6dc9357SAndroid Build Coastguard Worker     p->dec_created = True;
617*f6dc9357SAndroid Build Coastguard Worker   }
618*f6dc9357SAndroid Build Coastguard Worker 
619*f6dc9357SAndroid Build Coastguard Worker   RINOK(Lzma2Dec_Allocate(&p->dec, p->prop, &p->alignOffsetAlloc.vt))
620*f6dc9357SAndroid Build Coastguard Worker 
621*f6dc9357SAndroid Build Coastguard Worker   if (!p->inBuf || p->inBufSize != p->props.inBufSize_ST)
622*f6dc9357SAndroid Build Coastguard Worker   {
623*f6dc9357SAndroid Build Coastguard Worker     ISzAlloc_Free(p->allocMid, p->inBuf);
624*f6dc9357SAndroid Build Coastguard Worker     p->inBufSize = 0;
625*f6dc9357SAndroid Build Coastguard Worker     p->inBuf = (Byte *)ISzAlloc_Alloc(p->allocMid, p->props.inBufSize_ST);
626*f6dc9357SAndroid Build Coastguard Worker     if (!p->inBuf)
627*f6dc9357SAndroid Build Coastguard Worker       return SZ_ERROR_MEM;
628*f6dc9357SAndroid Build Coastguard Worker     p->inBufSize = p->props.inBufSize_ST;
629*f6dc9357SAndroid Build Coastguard Worker   }
630*f6dc9357SAndroid Build Coastguard Worker 
631*f6dc9357SAndroid Build Coastguard Worker   Lzma2Dec_Init(&p->dec);
632*f6dc9357SAndroid Build Coastguard Worker 
633*f6dc9357SAndroid Build Coastguard Worker   return SZ_OK;
634*f6dc9357SAndroid Build Coastguard Worker }
635*f6dc9357SAndroid Build Coastguard Worker 
636*f6dc9357SAndroid Build Coastguard Worker 
Lzma2Dec_Decode_ST(CLzma2DecMt * p,BoolInt tMode)637*f6dc9357SAndroid Build Coastguard Worker static SRes Lzma2Dec_Decode_ST(CLzma2DecMt *p
638*f6dc9357SAndroid Build Coastguard Worker     #ifndef Z7_ST
639*f6dc9357SAndroid Build Coastguard Worker     , BoolInt tMode
640*f6dc9357SAndroid Build Coastguard Worker     #endif
641*f6dc9357SAndroid Build Coastguard Worker     )
642*f6dc9357SAndroid Build Coastguard Worker {
643*f6dc9357SAndroid Build Coastguard Worker   SizeT wrPos;
644*f6dc9357SAndroid Build Coastguard Worker   size_t inPos, inLim;
645*f6dc9357SAndroid Build Coastguard Worker   const Byte *inData;
646*f6dc9357SAndroid Build Coastguard Worker   UInt64 inPrev, outPrev;
647*f6dc9357SAndroid Build Coastguard Worker 
648*f6dc9357SAndroid Build Coastguard Worker   CLzma2Dec *dec;
649*f6dc9357SAndroid Build Coastguard Worker 
650*f6dc9357SAndroid Build Coastguard Worker   #ifndef Z7_ST
651*f6dc9357SAndroid Build Coastguard Worker   if (tMode)
652*f6dc9357SAndroid Build Coastguard Worker   {
653*f6dc9357SAndroid Build Coastguard Worker     Lzma2DecMt_FreeOutBufs(p);
654*f6dc9357SAndroid Build Coastguard Worker     tMode = MtDec_PrepareRead(&p->mtc);
655*f6dc9357SAndroid Build Coastguard Worker   }
656*f6dc9357SAndroid Build Coastguard Worker   #endif
657*f6dc9357SAndroid Build Coastguard Worker 
658*f6dc9357SAndroid Build Coastguard Worker   RINOK(Lzma2Dec_Prepare_ST(p))
659*f6dc9357SAndroid Build Coastguard Worker 
660*f6dc9357SAndroid Build Coastguard Worker   dec = &p->dec;
661*f6dc9357SAndroid Build Coastguard Worker 
662*f6dc9357SAndroid Build Coastguard Worker   inPrev = p->inProcessed;
663*f6dc9357SAndroid Build Coastguard Worker   outPrev = p->outProcessed;
664*f6dc9357SAndroid Build Coastguard Worker 
665*f6dc9357SAndroid Build Coastguard Worker   inPos = 0;
666*f6dc9357SAndroid Build Coastguard Worker   inLim = 0;
667*f6dc9357SAndroid Build Coastguard Worker   inData = NULL;
668*f6dc9357SAndroid Build Coastguard Worker   wrPos = dec->decoder.dicPos;
669*f6dc9357SAndroid Build Coastguard Worker 
670*f6dc9357SAndroid Build Coastguard Worker   for (;;)
671*f6dc9357SAndroid Build Coastguard Worker   {
672*f6dc9357SAndroid Build Coastguard Worker     SizeT dicPos;
673*f6dc9357SAndroid Build Coastguard Worker     SizeT size;
674*f6dc9357SAndroid Build Coastguard Worker     ELzmaFinishMode finishMode;
675*f6dc9357SAndroid Build Coastguard Worker     SizeT inProcessed;
676*f6dc9357SAndroid Build Coastguard Worker     ELzmaStatus status;
677*f6dc9357SAndroid Build Coastguard Worker     SRes res;
678*f6dc9357SAndroid Build Coastguard Worker 
679*f6dc9357SAndroid Build Coastguard Worker     SizeT outProcessed;
680*f6dc9357SAndroid Build Coastguard Worker     BoolInt outFinished;
681*f6dc9357SAndroid Build Coastguard Worker     BoolInt needStop;
682*f6dc9357SAndroid Build Coastguard Worker 
683*f6dc9357SAndroid Build Coastguard Worker     if (inPos == inLim)
684*f6dc9357SAndroid Build Coastguard Worker     {
685*f6dc9357SAndroid Build Coastguard Worker       #ifndef Z7_ST
686*f6dc9357SAndroid Build Coastguard Worker       if (tMode)
687*f6dc9357SAndroid Build Coastguard Worker       {
688*f6dc9357SAndroid Build Coastguard Worker         inData = MtDec_Read(&p->mtc, &inLim);
689*f6dc9357SAndroid Build Coastguard Worker         inPos = 0;
690*f6dc9357SAndroid Build Coastguard Worker         if (inData)
691*f6dc9357SAndroid Build Coastguard Worker           continue;
692*f6dc9357SAndroid Build Coastguard Worker         tMode = False;
693*f6dc9357SAndroid Build Coastguard Worker         inLim = 0;
694*f6dc9357SAndroid Build Coastguard Worker       }
695*f6dc9357SAndroid Build Coastguard Worker       #endif
696*f6dc9357SAndroid Build Coastguard Worker 
697*f6dc9357SAndroid Build Coastguard Worker       if (!p->readWasFinished)
698*f6dc9357SAndroid Build Coastguard Worker       {
699*f6dc9357SAndroid Build Coastguard Worker         inPos = 0;
700*f6dc9357SAndroid Build Coastguard Worker         inLim = p->inBufSize;
701*f6dc9357SAndroid Build Coastguard Worker         inData = p->inBuf;
702*f6dc9357SAndroid Build Coastguard Worker         p->readRes = ISeqInStream_Read(p->inStream, (void *)(p->inBuf), &inLim);
703*f6dc9357SAndroid Build Coastguard Worker         // p->readProcessed += inLim;
704*f6dc9357SAndroid Build Coastguard Worker         // inLim -= 5; p->readWasFinished = True; // for test
705*f6dc9357SAndroid Build Coastguard Worker         if (inLim == 0 || p->readRes != SZ_OK)
706*f6dc9357SAndroid Build Coastguard Worker           p->readWasFinished = True;
707*f6dc9357SAndroid Build Coastguard Worker       }
708*f6dc9357SAndroid Build Coastguard Worker     }
709*f6dc9357SAndroid Build Coastguard Worker 
710*f6dc9357SAndroid Build Coastguard Worker     dicPos = dec->decoder.dicPos;
711*f6dc9357SAndroid Build Coastguard Worker     {
712*f6dc9357SAndroid Build Coastguard Worker       SizeT next = dec->decoder.dicBufSize;
713*f6dc9357SAndroid Build Coastguard Worker       if (next - wrPos > p->props.outStep_ST)
714*f6dc9357SAndroid Build Coastguard Worker         next = wrPos + (SizeT)p->props.outStep_ST;
715*f6dc9357SAndroid Build Coastguard Worker       size = next - dicPos;
716*f6dc9357SAndroid Build Coastguard Worker     }
717*f6dc9357SAndroid Build Coastguard Worker 
718*f6dc9357SAndroid Build Coastguard Worker     finishMode = LZMA_FINISH_ANY;
719*f6dc9357SAndroid Build Coastguard Worker     if (p->outSize_Defined)
720*f6dc9357SAndroid Build Coastguard Worker     {
721*f6dc9357SAndroid Build Coastguard Worker       const UInt64 rem = p->outSize - p->outProcessed;
722*f6dc9357SAndroid Build Coastguard Worker       if (size >= rem)
723*f6dc9357SAndroid Build Coastguard Worker       {
724*f6dc9357SAndroid Build Coastguard Worker         size = (SizeT)rem;
725*f6dc9357SAndroid Build Coastguard Worker         if (p->finishMode)
726*f6dc9357SAndroid Build Coastguard Worker           finishMode = LZMA_FINISH_END;
727*f6dc9357SAndroid Build Coastguard Worker       }
728*f6dc9357SAndroid Build Coastguard Worker     }
729*f6dc9357SAndroid Build Coastguard Worker 
730*f6dc9357SAndroid Build Coastguard Worker     inProcessed = (SizeT)(inLim - inPos);
731*f6dc9357SAndroid Build Coastguard Worker 
732*f6dc9357SAndroid Build Coastguard Worker     res = Lzma2Dec_DecodeToDic(dec, dicPos + size, inData + inPos, &inProcessed, finishMode, &status);
733*f6dc9357SAndroid Build Coastguard Worker 
734*f6dc9357SAndroid Build Coastguard Worker     inPos += inProcessed;
735*f6dc9357SAndroid Build Coastguard Worker     p->inProcessed += inProcessed;
736*f6dc9357SAndroid Build Coastguard Worker     outProcessed = dec->decoder.dicPos - dicPos;
737*f6dc9357SAndroid Build Coastguard Worker     p->outProcessed += outProcessed;
738*f6dc9357SAndroid Build Coastguard Worker 
739*f6dc9357SAndroid Build Coastguard Worker     outFinished = (p->outSize_Defined && p->outSize <= p->outProcessed);
740*f6dc9357SAndroid Build Coastguard Worker 
741*f6dc9357SAndroid Build Coastguard Worker     needStop = (res != SZ_OK
742*f6dc9357SAndroid Build Coastguard Worker         || (inProcessed == 0 && outProcessed == 0)
743*f6dc9357SAndroid Build Coastguard Worker         || status == LZMA_STATUS_FINISHED_WITH_MARK
744*f6dc9357SAndroid Build Coastguard Worker         || (!p->finishMode && outFinished));
745*f6dc9357SAndroid Build Coastguard Worker 
746*f6dc9357SAndroid Build Coastguard Worker     if (needStop || outProcessed >= size)
747*f6dc9357SAndroid Build Coastguard Worker     {
748*f6dc9357SAndroid Build Coastguard Worker       SRes res2;
749*f6dc9357SAndroid Build Coastguard Worker       {
750*f6dc9357SAndroid Build Coastguard Worker         size_t writeSize = dec->decoder.dicPos - wrPos;
751*f6dc9357SAndroid Build Coastguard Worker         size_t written = ISeqOutStream_Write(p->outStream, dec->decoder.dic + wrPos, writeSize);
752*f6dc9357SAndroid Build Coastguard Worker         res2 = (written == writeSize) ? SZ_OK : SZ_ERROR_WRITE;
753*f6dc9357SAndroid Build Coastguard Worker       }
754*f6dc9357SAndroid Build Coastguard Worker 
755*f6dc9357SAndroid Build Coastguard Worker       if (dec->decoder.dicPos == dec->decoder.dicBufSize)
756*f6dc9357SAndroid Build Coastguard Worker         dec->decoder.dicPos = 0;
757*f6dc9357SAndroid Build Coastguard Worker       wrPos = dec->decoder.dicPos;
758*f6dc9357SAndroid Build Coastguard Worker 
759*f6dc9357SAndroid Build Coastguard Worker       RINOK(res2)
760*f6dc9357SAndroid Build Coastguard Worker 
761*f6dc9357SAndroid Build Coastguard Worker       if (needStop)
762*f6dc9357SAndroid Build Coastguard Worker       {
763*f6dc9357SAndroid Build Coastguard Worker         if (res != SZ_OK)
764*f6dc9357SAndroid Build Coastguard Worker           return res;
765*f6dc9357SAndroid Build Coastguard Worker 
766*f6dc9357SAndroid Build Coastguard Worker         if (status == LZMA_STATUS_FINISHED_WITH_MARK)
767*f6dc9357SAndroid Build Coastguard Worker         {
768*f6dc9357SAndroid Build Coastguard Worker           if (p->finishMode)
769*f6dc9357SAndroid Build Coastguard Worker           {
770*f6dc9357SAndroid Build Coastguard Worker             if (p->outSize_Defined && p->outSize != p->outProcessed)
771*f6dc9357SAndroid Build Coastguard Worker               return SZ_ERROR_DATA;
772*f6dc9357SAndroid Build Coastguard Worker           }
773*f6dc9357SAndroid Build Coastguard Worker           return SZ_OK;
774*f6dc9357SAndroid Build Coastguard Worker         }
775*f6dc9357SAndroid Build Coastguard Worker 
776*f6dc9357SAndroid Build Coastguard Worker         if (!p->finishMode && outFinished)
777*f6dc9357SAndroid Build Coastguard Worker           return SZ_OK;
778*f6dc9357SAndroid Build Coastguard Worker 
779*f6dc9357SAndroid Build Coastguard Worker         if (status == LZMA_STATUS_NEEDS_MORE_INPUT)
780*f6dc9357SAndroid Build Coastguard Worker           return SZ_ERROR_INPUT_EOF;
781*f6dc9357SAndroid Build Coastguard Worker 
782*f6dc9357SAndroid Build Coastguard Worker         return SZ_ERROR_DATA;
783*f6dc9357SAndroid Build Coastguard Worker       }
784*f6dc9357SAndroid Build Coastguard Worker     }
785*f6dc9357SAndroid Build Coastguard Worker 
786*f6dc9357SAndroid Build Coastguard Worker     if (p->progress)
787*f6dc9357SAndroid Build Coastguard Worker     {
788*f6dc9357SAndroid Build Coastguard Worker       UInt64 inDelta = p->inProcessed - inPrev;
789*f6dc9357SAndroid Build Coastguard Worker       UInt64 outDelta = p->outProcessed - outPrev;
790*f6dc9357SAndroid Build Coastguard Worker       if (inDelta >= (1 << 22) || outDelta >= (1 << 22))
791*f6dc9357SAndroid Build Coastguard Worker       {
792*f6dc9357SAndroid Build Coastguard Worker         RINOK(ICompressProgress_Progress(p->progress, p->inProcessed, p->outProcessed))
793*f6dc9357SAndroid Build Coastguard Worker         inPrev = p->inProcessed;
794*f6dc9357SAndroid Build Coastguard Worker         outPrev = p->outProcessed;
795*f6dc9357SAndroid Build Coastguard Worker       }
796*f6dc9357SAndroid Build Coastguard Worker     }
797*f6dc9357SAndroid Build Coastguard Worker   }
798*f6dc9357SAndroid Build Coastguard Worker }
799*f6dc9357SAndroid Build Coastguard Worker 
800*f6dc9357SAndroid Build Coastguard Worker 
801*f6dc9357SAndroid Build Coastguard Worker 
Lzma2DecMt_Decode(CLzma2DecMtHandle p,Byte prop,const CLzma2DecMtProps * props,ISeqOutStreamPtr outStream,const UInt64 * outDataSize,int finishMode,ISeqInStreamPtr inStream,UInt64 * inProcessed,int * isMT,ICompressProgressPtr progress)802*f6dc9357SAndroid Build Coastguard Worker SRes Lzma2DecMt_Decode(CLzma2DecMtHandle p,
803*f6dc9357SAndroid Build Coastguard Worker     Byte prop,
804*f6dc9357SAndroid Build Coastguard Worker     const CLzma2DecMtProps *props,
805*f6dc9357SAndroid Build Coastguard Worker     ISeqOutStreamPtr outStream, const UInt64 *outDataSize, int finishMode,
806*f6dc9357SAndroid Build Coastguard Worker     // Byte *outBuf, size_t *outBufSize,
807*f6dc9357SAndroid Build Coastguard Worker     ISeqInStreamPtr inStream,
808*f6dc9357SAndroid Build Coastguard Worker     // const Byte *inData, size_t inDataSize,
809*f6dc9357SAndroid Build Coastguard Worker     UInt64 *inProcessed,
810*f6dc9357SAndroid Build Coastguard Worker     // UInt64 *outProcessed,
811*f6dc9357SAndroid Build Coastguard Worker     int *isMT,
812*f6dc9357SAndroid Build Coastguard Worker     ICompressProgressPtr progress)
813*f6dc9357SAndroid Build Coastguard Worker {
814*f6dc9357SAndroid Build Coastguard Worker   // GET_CLzma2DecMt_p
815*f6dc9357SAndroid Build Coastguard Worker   #ifndef Z7_ST
816*f6dc9357SAndroid Build Coastguard Worker   BoolInt tMode;
817*f6dc9357SAndroid Build Coastguard Worker   #endif
818*f6dc9357SAndroid Build Coastguard Worker 
819*f6dc9357SAndroid Build Coastguard Worker   *inProcessed = 0;
820*f6dc9357SAndroid Build Coastguard Worker 
821*f6dc9357SAndroid Build Coastguard Worker   if (prop > 40)
822*f6dc9357SAndroid Build Coastguard Worker     return SZ_ERROR_UNSUPPORTED;
823*f6dc9357SAndroid Build Coastguard Worker 
824*f6dc9357SAndroid Build Coastguard Worker   p->prop = prop;
825*f6dc9357SAndroid Build Coastguard Worker   p->props = *props;
826*f6dc9357SAndroid Build Coastguard Worker 
827*f6dc9357SAndroid Build Coastguard Worker   p->inStream = inStream;
828*f6dc9357SAndroid Build Coastguard Worker   p->outStream = outStream;
829*f6dc9357SAndroid Build Coastguard Worker   p->progress = progress;
830*f6dc9357SAndroid Build Coastguard Worker 
831*f6dc9357SAndroid Build Coastguard Worker   p->outSize = 0;
832*f6dc9357SAndroid Build Coastguard Worker   p->outSize_Defined = False;
833*f6dc9357SAndroid Build Coastguard Worker   if (outDataSize)
834*f6dc9357SAndroid Build Coastguard Worker   {
835*f6dc9357SAndroid Build Coastguard Worker     p->outSize_Defined = True;
836*f6dc9357SAndroid Build Coastguard Worker     p->outSize = *outDataSize;
837*f6dc9357SAndroid Build Coastguard Worker   }
838*f6dc9357SAndroid Build Coastguard Worker   p->finishMode = finishMode;
839*f6dc9357SAndroid Build Coastguard Worker 
840*f6dc9357SAndroid Build Coastguard Worker   p->outProcessed = 0;
841*f6dc9357SAndroid Build Coastguard Worker   p->inProcessed = 0;
842*f6dc9357SAndroid Build Coastguard Worker 
843*f6dc9357SAndroid Build Coastguard Worker   p->readWasFinished = False;
844*f6dc9357SAndroid Build Coastguard Worker   p->readRes = SZ_OK;
845*f6dc9357SAndroid Build Coastguard Worker 
846*f6dc9357SAndroid Build Coastguard Worker   *isMT = False;
847*f6dc9357SAndroid Build Coastguard Worker 
848*f6dc9357SAndroid Build Coastguard Worker 
849*f6dc9357SAndroid Build Coastguard Worker   #ifndef Z7_ST
850*f6dc9357SAndroid Build Coastguard Worker 
851*f6dc9357SAndroid Build Coastguard Worker   tMode = False;
852*f6dc9357SAndroid Build Coastguard Worker 
853*f6dc9357SAndroid Build Coastguard Worker   // p->mtc.parseRes = SZ_OK;
854*f6dc9357SAndroid Build Coastguard Worker 
855*f6dc9357SAndroid Build Coastguard Worker   // p->mtc.numFilledThreads = 0;
856*f6dc9357SAndroid Build Coastguard Worker   // p->mtc.crossStart = 0;
857*f6dc9357SAndroid Build Coastguard Worker   // p->mtc.crossEnd = 0;
858*f6dc9357SAndroid Build Coastguard Worker   // p->mtc.allocError_for_Read_BlockIndex = 0;
859*f6dc9357SAndroid Build Coastguard Worker   // p->mtc.isAllocError = False;
860*f6dc9357SAndroid Build Coastguard Worker 
861*f6dc9357SAndroid Build Coastguard Worker   if (p->props.numThreads > 1)
862*f6dc9357SAndroid Build Coastguard Worker   {
863*f6dc9357SAndroid Build Coastguard Worker     IMtDecCallback2 vt;
864*f6dc9357SAndroid Build Coastguard Worker 
865*f6dc9357SAndroid Build Coastguard Worker     Lzma2DecMt_FreeSt(p);
866*f6dc9357SAndroid Build Coastguard Worker 
867*f6dc9357SAndroid Build Coastguard Worker     p->outProcessed_Parse = 0;
868*f6dc9357SAndroid Build Coastguard Worker 
869*f6dc9357SAndroid Build Coastguard Worker     if (!p->mtc_WasConstructed)
870*f6dc9357SAndroid Build Coastguard Worker     {
871*f6dc9357SAndroid Build Coastguard Worker       p->mtc_WasConstructed = True;
872*f6dc9357SAndroid Build Coastguard Worker       MtDec_Construct(&p->mtc);
873*f6dc9357SAndroid Build Coastguard Worker     }
874*f6dc9357SAndroid Build Coastguard Worker 
875*f6dc9357SAndroid Build Coastguard Worker     p->mtc.progress = progress;
876*f6dc9357SAndroid Build Coastguard Worker     p->mtc.inStream = inStream;
877*f6dc9357SAndroid Build Coastguard Worker 
878*f6dc9357SAndroid Build Coastguard Worker     // p->outBuf = NULL;
879*f6dc9357SAndroid Build Coastguard Worker     // p->outBufSize = 0;
880*f6dc9357SAndroid Build Coastguard Worker     /*
881*f6dc9357SAndroid Build Coastguard Worker     if (!outStream)
882*f6dc9357SAndroid Build Coastguard Worker     {
883*f6dc9357SAndroid Build Coastguard Worker       // p->outBuf = outBuf;
884*f6dc9357SAndroid Build Coastguard Worker       // p->outBufSize = *outBufSize;
885*f6dc9357SAndroid Build Coastguard Worker       // *outBufSize = 0;
886*f6dc9357SAndroid Build Coastguard Worker       return SZ_ERROR_PARAM;
887*f6dc9357SAndroid Build Coastguard Worker     }
888*f6dc9357SAndroid Build Coastguard Worker     */
889*f6dc9357SAndroid Build Coastguard Worker 
890*f6dc9357SAndroid Build Coastguard Worker     // p->mtc.inBlockMax = p->props.inBlockMax;
891*f6dc9357SAndroid Build Coastguard Worker     p->mtc.alloc = &p->alignOffsetAlloc.vt;
892*f6dc9357SAndroid Build Coastguard Worker       // p->alignOffsetAlloc.baseAlloc;
893*f6dc9357SAndroid Build Coastguard Worker     // p->mtc.inData = inData;
894*f6dc9357SAndroid Build Coastguard Worker     // p->mtc.inDataSize = inDataSize;
895*f6dc9357SAndroid Build Coastguard Worker     p->mtc.mtCallback = &vt;
896*f6dc9357SAndroid Build Coastguard Worker     p->mtc.mtCallbackObject = p;
897*f6dc9357SAndroid Build Coastguard Worker 
898*f6dc9357SAndroid Build Coastguard Worker     p->mtc.inBufSize = p->props.inBufSize_MT;
899*f6dc9357SAndroid Build Coastguard Worker 
900*f6dc9357SAndroid Build Coastguard Worker     p->mtc.numThreadsMax = p->props.numThreads;
901*f6dc9357SAndroid Build Coastguard Worker 
902*f6dc9357SAndroid Build Coastguard Worker     *isMT = True;
903*f6dc9357SAndroid Build Coastguard Worker 
904*f6dc9357SAndroid Build Coastguard Worker     vt.Parse = Lzma2DecMt_MtCallback_Parse;
905*f6dc9357SAndroid Build Coastguard Worker     vt.PreCode = Lzma2DecMt_MtCallback_PreCode;
906*f6dc9357SAndroid Build Coastguard Worker     vt.Code = Lzma2DecMt_MtCallback_Code;
907*f6dc9357SAndroid Build Coastguard Worker     vt.Write = Lzma2DecMt_MtCallback_Write;
908*f6dc9357SAndroid Build Coastguard Worker 
909*f6dc9357SAndroid Build Coastguard Worker     {
910*f6dc9357SAndroid Build Coastguard Worker       BoolInt needContinue = False;
911*f6dc9357SAndroid Build Coastguard Worker 
912*f6dc9357SAndroid Build Coastguard Worker       SRes res = MtDec_Code(&p->mtc);
913*f6dc9357SAndroid Build Coastguard Worker 
914*f6dc9357SAndroid Build Coastguard Worker       /*
915*f6dc9357SAndroid Build Coastguard Worker       if (!outStream)
916*f6dc9357SAndroid Build Coastguard Worker         *outBufSize = p->outBuf - outBuf;
917*f6dc9357SAndroid Build Coastguard Worker       */
918*f6dc9357SAndroid Build Coastguard Worker 
919*f6dc9357SAndroid Build Coastguard Worker       *inProcessed = p->mtc.inProcessed;
920*f6dc9357SAndroid Build Coastguard Worker 
921*f6dc9357SAndroid Build Coastguard Worker       needContinue = False;
922*f6dc9357SAndroid Build Coastguard Worker 
923*f6dc9357SAndroid Build Coastguard Worker       if (res == SZ_OK)
924*f6dc9357SAndroid Build Coastguard Worker       {
925*f6dc9357SAndroid Build Coastguard Worker         if (p->mtc.mtProgress.res != SZ_OK)
926*f6dc9357SAndroid Build Coastguard Worker           res = p->mtc.mtProgress.res;
927*f6dc9357SAndroid Build Coastguard Worker         else
928*f6dc9357SAndroid Build Coastguard Worker           needContinue = p->mtc.needContinue;
929*f6dc9357SAndroid Build Coastguard Worker       }
930*f6dc9357SAndroid Build Coastguard Worker 
931*f6dc9357SAndroid Build Coastguard Worker       if (!needContinue)
932*f6dc9357SAndroid Build Coastguard Worker       {
933*f6dc9357SAndroid Build Coastguard Worker         if (res == SZ_OK)
934*f6dc9357SAndroid Build Coastguard Worker           return p->mtc.readRes;
935*f6dc9357SAndroid Build Coastguard Worker         return res;
936*f6dc9357SAndroid Build Coastguard Worker       }
937*f6dc9357SAndroid Build Coastguard Worker 
938*f6dc9357SAndroid Build Coastguard Worker       tMode = True;
939*f6dc9357SAndroid Build Coastguard Worker       p->readRes = p->mtc.readRes;
940*f6dc9357SAndroid Build Coastguard Worker       p->readWasFinished = p->mtc.readWasFinished;
941*f6dc9357SAndroid Build Coastguard Worker       p->inProcessed = p->mtc.inProcessed;
942*f6dc9357SAndroid Build Coastguard Worker 
943*f6dc9357SAndroid Build Coastguard Worker       PRF_STR("----- decoding ST -----")
944*f6dc9357SAndroid Build Coastguard Worker     }
945*f6dc9357SAndroid Build Coastguard Worker   }
946*f6dc9357SAndroid Build Coastguard Worker 
947*f6dc9357SAndroid Build Coastguard Worker   #endif
948*f6dc9357SAndroid Build Coastguard Worker 
949*f6dc9357SAndroid Build Coastguard Worker 
950*f6dc9357SAndroid Build Coastguard Worker   *isMT = False;
951*f6dc9357SAndroid Build Coastguard Worker 
952*f6dc9357SAndroid Build Coastguard Worker   {
953*f6dc9357SAndroid Build Coastguard Worker     SRes res = Lzma2Dec_Decode_ST(p
954*f6dc9357SAndroid Build Coastguard Worker         #ifndef Z7_ST
955*f6dc9357SAndroid Build Coastguard Worker         , tMode
956*f6dc9357SAndroid Build Coastguard Worker         #endif
957*f6dc9357SAndroid Build Coastguard Worker         );
958*f6dc9357SAndroid Build Coastguard Worker 
959*f6dc9357SAndroid Build Coastguard Worker     *inProcessed = p->inProcessed;
960*f6dc9357SAndroid Build Coastguard Worker 
961*f6dc9357SAndroid Build Coastguard Worker     // res = SZ_OK; // for test
962*f6dc9357SAndroid Build Coastguard Worker     if (res == SZ_ERROR_INPUT_EOF)
963*f6dc9357SAndroid Build Coastguard Worker     {
964*f6dc9357SAndroid Build Coastguard Worker       if (p->readRes != SZ_OK)
965*f6dc9357SAndroid Build Coastguard Worker         res = p->readRes;
966*f6dc9357SAndroid Build Coastguard Worker     }
967*f6dc9357SAndroid Build Coastguard Worker     else if (res == SZ_OK && p->readRes != SZ_OK)
968*f6dc9357SAndroid Build Coastguard Worker       res = p->readRes;
969*f6dc9357SAndroid Build Coastguard Worker 
970*f6dc9357SAndroid Build Coastguard Worker     /*
971*f6dc9357SAndroid Build Coastguard Worker     #ifndef Z7_ST
972*f6dc9357SAndroid Build Coastguard Worker     if (res == SZ_OK && tMode && p->mtc.parseRes != SZ_OK)
973*f6dc9357SAndroid Build Coastguard Worker       res = p->mtc.parseRes;
974*f6dc9357SAndroid Build Coastguard Worker     #endif
975*f6dc9357SAndroid Build Coastguard Worker     */
976*f6dc9357SAndroid Build Coastguard Worker 
977*f6dc9357SAndroid Build Coastguard Worker     return res;
978*f6dc9357SAndroid Build Coastguard Worker   }
979*f6dc9357SAndroid Build Coastguard Worker }
980*f6dc9357SAndroid Build Coastguard Worker 
981*f6dc9357SAndroid Build Coastguard Worker 
982*f6dc9357SAndroid Build Coastguard Worker /* ---------- Read from CLzma2DecMtHandle Interface ---------- */
983*f6dc9357SAndroid Build Coastguard Worker 
Lzma2DecMt_Init(CLzma2DecMtHandle p,Byte prop,const CLzma2DecMtProps * props,const UInt64 * outDataSize,int finishMode,ISeqInStreamPtr inStream)984*f6dc9357SAndroid Build Coastguard Worker SRes Lzma2DecMt_Init(CLzma2DecMtHandle p,
985*f6dc9357SAndroid Build Coastguard Worker     Byte prop,
986*f6dc9357SAndroid Build Coastguard Worker     const CLzma2DecMtProps *props,
987*f6dc9357SAndroid Build Coastguard Worker     const UInt64 *outDataSize, int finishMode,
988*f6dc9357SAndroid Build Coastguard Worker     ISeqInStreamPtr inStream)
989*f6dc9357SAndroid Build Coastguard Worker {
990*f6dc9357SAndroid Build Coastguard Worker   // GET_CLzma2DecMt_p
991*f6dc9357SAndroid Build Coastguard Worker 
992*f6dc9357SAndroid Build Coastguard Worker   if (prop > 40)
993*f6dc9357SAndroid Build Coastguard Worker     return SZ_ERROR_UNSUPPORTED;
994*f6dc9357SAndroid Build Coastguard Worker 
995*f6dc9357SAndroid Build Coastguard Worker   p->prop = prop;
996*f6dc9357SAndroid Build Coastguard Worker   p->props = *props;
997*f6dc9357SAndroid Build Coastguard Worker 
998*f6dc9357SAndroid Build Coastguard Worker   p->inStream = inStream;
999*f6dc9357SAndroid Build Coastguard Worker 
1000*f6dc9357SAndroid Build Coastguard Worker   p->outSize = 0;
1001*f6dc9357SAndroid Build Coastguard Worker   p->outSize_Defined = False;
1002*f6dc9357SAndroid Build Coastguard Worker   if (outDataSize)
1003*f6dc9357SAndroid Build Coastguard Worker   {
1004*f6dc9357SAndroid Build Coastguard Worker     p->outSize_Defined = True;
1005*f6dc9357SAndroid Build Coastguard Worker     p->outSize = *outDataSize;
1006*f6dc9357SAndroid Build Coastguard Worker   }
1007*f6dc9357SAndroid Build Coastguard Worker   p->finishMode = finishMode;
1008*f6dc9357SAndroid Build Coastguard Worker 
1009*f6dc9357SAndroid Build Coastguard Worker   p->outProcessed = 0;
1010*f6dc9357SAndroid Build Coastguard Worker   p->inProcessed = 0;
1011*f6dc9357SAndroid Build Coastguard Worker 
1012*f6dc9357SAndroid Build Coastguard Worker   p->inPos = 0;
1013*f6dc9357SAndroid Build Coastguard Worker   p->inLim = 0;
1014*f6dc9357SAndroid Build Coastguard Worker 
1015*f6dc9357SAndroid Build Coastguard Worker   return Lzma2Dec_Prepare_ST(p);
1016*f6dc9357SAndroid Build Coastguard Worker }
1017*f6dc9357SAndroid Build Coastguard Worker 
1018*f6dc9357SAndroid Build Coastguard Worker 
Lzma2DecMt_Read(CLzma2DecMtHandle p,Byte * data,size_t * outSize,UInt64 * inStreamProcessed)1019*f6dc9357SAndroid Build Coastguard Worker SRes Lzma2DecMt_Read(CLzma2DecMtHandle p,
1020*f6dc9357SAndroid Build Coastguard Worker     Byte *data, size_t *outSize,
1021*f6dc9357SAndroid Build Coastguard Worker     UInt64 *inStreamProcessed)
1022*f6dc9357SAndroid Build Coastguard Worker {
1023*f6dc9357SAndroid Build Coastguard Worker   // GET_CLzma2DecMt_p
1024*f6dc9357SAndroid Build Coastguard Worker   ELzmaFinishMode finishMode;
1025*f6dc9357SAndroid Build Coastguard Worker   SRes readRes;
1026*f6dc9357SAndroid Build Coastguard Worker   size_t size = *outSize;
1027*f6dc9357SAndroid Build Coastguard Worker 
1028*f6dc9357SAndroid Build Coastguard Worker   *outSize = 0;
1029*f6dc9357SAndroid Build Coastguard Worker   *inStreamProcessed = 0;
1030*f6dc9357SAndroid Build Coastguard Worker 
1031*f6dc9357SAndroid Build Coastguard Worker   finishMode = LZMA_FINISH_ANY;
1032*f6dc9357SAndroid Build Coastguard Worker   if (p->outSize_Defined)
1033*f6dc9357SAndroid Build Coastguard Worker   {
1034*f6dc9357SAndroid Build Coastguard Worker     const UInt64 rem = p->outSize - p->outProcessed;
1035*f6dc9357SAndroid Build Coastguard Worker     if (size >= rem)
1036*f6dc9357SAndroid Build Coastguard Worker     {
1037*f6dc9357SAndroid Build Coastguard Worker       size = (size_t)rem;
1038*f6dc9357SAndroid Build Coastguard Worker       if (p->finishMode)
1039*f6dc9357SAndroid Build Coastguard Worker         finishMode = LZMA_FINISH_END;
1040*f6dc9357SAndroid Build Coastguard Worker     }
1041*f6dc9357SAndroid Build Coastguard Worker   }
1042*f6dc9357SAndroid Build Coastguard Worker 
1043*f6dc9357SAndroid Build Coastguard Worker   readRes = SZ_OK;
1044*f6dc9357SAndroid Build Coastguard Worker 
1045*f6dc9357SAndroid Build Coastguard Worker   for (;;)
1046*f6dc9357SAndroid Build Coastguard Worker   {
1047*f6dc9357SAndroid Build Coastguard Worker     SizeT inCur;
1048*f6dc9357SAndroid Build Coastguard Worker     SizeT outCur;
1049*f6dc9357SAndroid Build Coastguard Worker     ELzmaStatus status;
1050*f6dc9357SAndroid Build Coastguard Worker     SRes res;
1051*f6dc9357SAndroid Build Coastguard Worker 
1052*f6dc9357SAndroid Build Coastguard Worker     if (p->inPos == p->inLim && readRes == SZ_OK)
1053*f6dc9357SAndroid Build Coastguard Worker     {
1054*f6dc9357SAndroid Build Coastguard Worker       p->inPos = 0;
1055*f6dc9357SAndroid Build Coastguard Worker       p->inLim = p->props.inBufSize_ST;
1056*f6dc9357SAndroid Build Coastguard Worker       readRes = ISeqInStream_Read(p->inStream, p->inBuf, &p->inLim);
1057*f6dc9357SAndroid Build Coastguard Worker     }
1058*f6dc9357SAndroid Build Coastguard Worker 
1059*f6dc9357SAndroid Build Coastguard Worker     inCur = (SizeT)(p->inLim - p->inPos);
1060*f6dc9357SAndroid Build Coastguard Worker     outCur = (SizeT)size;
1061*f6dc9357SAndroid Build Coastguard Worker 
1062*f6dc9357SAndroid Build Coastguard Worker     res = Lzma2Dec_DecodeToBuf(&p->dec, data, &outCur,
1063*f6dc9357SAndroid Build Coastguard Worker         p->inBuf + p->inPos, &inCur, finishMode, &status);
1064*f6dc9357SAndroid Build Coastguard Worker 
1065*f6dc9357SAndroid Build Coastguard Worker     p->inPos += inCur;
1066*f6dc9357SAndroid Build Coastguard Worker     p->inProcessed += inCur;
1067*f6dc9357SAndroid Build Coastguard Worker     *inStreamProcessed += inCur;
1068*f6dc9357SAndroid Build Coastguard Worker     p->outProcessed += outCur;
1069*f6dc9357SAndroid Build Coastguard Worker     *outSize += outCur;
1070*f6dc9357SAndroid Build Coastguard Worker     size -= outCur;
1071*f6dc9357SAndroid Build Coastguard Worker     data += outCur;
1072*f6dc9357SAndroid Build Coastguard Worker 
1073*f6dc9357SAndroid Build Coastguard Worker     if (res != 0)
1074*f6dc9357SAndroid Build Coastguard Worker       return res;
1075*f6dc9357SAndroid Build Coastguard Worker 
1076*f6dc9357SAndroid Build Coastguard Worker     /*
1077*f6dc9357SAndroid Build Coastguard Worker     if (status == LZMA_STATUS_FINISHED_WITH_MARK)
1078*f6dc9357SAndroid Build Coastguard Worker       return readRes;
1079*f6dc9357SAndroid Build Coastguard Worker 
1080*f6dc9357SAndroid Build Coastguard Worker     if (size == 0 && status != LZMA_STATUS_NEEDS_MORE_INPUT)
1081*f6dc9357SAndroid Build Coastguard Worker     {
1082*f6dc9357SAndroid Build Coastguard Worker       if (p->finishMode && p->outSize_Defined && p->outProcessed >= p->outSize)
1083*f6dc9357SAndroid Build Coastguard Worker         return SZ_ERROR_DATA;
1084*f6dc9357SAndroid Build Coastguard Worker       return readRes;
1085*f6dc9357SAndroid Build Coastguard Worker     }
1086*f6dc9357SAndroid Build Coastguard Worker     */
1087*f6dc9357SAndroid Build Coastguard Worker 
1088*f6dc9357SAndroid Build Coastguard Worker     if (inCur == 0 && outCur == 0)
1089*f6dc9357SAndroid Build Coastguard Worker       return readRes;
1090*f6dc9357SAndroid Build Coastguard Worker   }
1091*f6dc9357SAndroid Build Coastguard Worker }
1092*f6dc9357SAndroid Build Coastguard Worker 
1093*f6dc9357SAndroid Build Coastguard Worker #undef PRF
1094*f6dc9357SAndroid Build Coastguard Worker #undef PRF_STR
1095*f6dc9357SAndroid Build Coastguard Worker #undef PRF_STR_INT_2
1096