1*f6dc9357SAndroid Build Coastguard Worker /* XzDec.c -- Xz Decode
2*f6dc9357SAndroid Build Coastguard Worker 2024-03-01 : 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 <stdio.h>
7*f6dc9357SAndroid Build Coastguard Worker
8*f6dc9357SAndroid Build Coastguard Worker // #define XZ_DUMP
9*f6dc9357SAndroid Build Coastguard Worker
10*f6dc9357SAndroid Build Coastguard Worker /* #define XZ_DUMP */
11*f6dc9357SAndroid Build Coastguard Worker
12*f6dc9357SAndroid Build Coastguard Worker #ifdef XZ_DUMP
13*f6dc9357SAndroid Build Coastguard Worker #include <stdio.h>
14*f6dc9357SAndroid Build Coastguard Worker #endif
15*f6dc9357SAndroid Build Coastguard Worker
16*f6dc9357SAndroid Build Coastguard Worker // #define SHOW_DEBUG_INFO
17*f6dc9357SAndroid Build Coastguard Worker
18*f6dc9357SAndroid Build Coastguard Worker #ifdef SHOW_DEBUG_INFO
19*f6dc9357SAndroid Build Coastguard Worker #include <stdio.h>
20*f6dc9357SAndroid Build Coastguard Worker #endif
21*f6dc9357SAndroid Build Coastguard Worker
22*f6dc9357SAndroid Build Coastguard Worker #ifdef SHOW_DEBUG_INFO
23*f6dc9357SAndroid Build Coastguard Worker #define PRF(x) x
24*f6dc9357SAndroid Build Coastguard Worker #else
25*f6dc9357SAndroid Build Coastguard Worker #define PRF(x)
26*f6dc9357SAndroid Build Coastguard Worker #endif
27*f6dc9357SAndroid Build Coastguard Worker
28*f6dc9357SAndroid Build Coastguard Worker #define PRF_STR(s) PRF(printf("\n" s "\n"))
29*f6dc9357SAndroid Build Coastguard Worker #define PRF_STR_INT(s, d) PRF(printf("\n" s " %d\n", (unsigned)d))
30*f6dc9357SAndroid Build Coastguard Worker
31*f6dc9357SAndroid Build Coastguard Worker #include <stdlib.h>
32*f6dc9357SAndroid Build Coastguard Worker #include <string.h>
33*f6dc9357SAndroid Build Coastguard Worker
34*f6dc9357SAndroid Build Coastguard Worker #include "7zCrc.h"
35*f6dc9357SAndroid Build Coastguard Worker #include "Alloc.h"
36*f6dc9357SAndroid Build Coastguard Worker #include "Bra.h"
37*f6dc9357SAndroid Build Coastguard Worker #include "CpuArch.h"
38*f6dc9357SAndroid Build Coastguard Worker #include "Delta.h"
39*f6dc9357SAndroid Build Coastguard Worker #include "Lzma2Dec.h"
40*f6dc9357SAndroid Build Coastguard Worker
41*f6dc9357SAndroid Build Coastguard Worker // #define USE_SUBBLOCK
42*f6dc9357SAndroid Build Coastguard Worker
43*f6dc9357SAndroid Build Coastguard Worker #ifdef USE_SUBBLOCK
44*f6dc9357SAndroid Build Coastguard Worker #include "Bcj3Dec.c"
45*f6dc9357SAndroid Build Coastguard Worker #include "SbDec.h"
46*f6dc9357SAndroid Build Coastguard Worker #endif
47*f6dc9357SAndroid Build Coastguard Worker
48*f6dc9357SAndroid Build Coastguard Worker #include "Xz.h"
49*f6dc9357SAndroid Build Coastguard Worker
50*f6dc9357SAndroid Build Coastguard Worker #define XZ_CHECK_SIZE_MAX 64
51*f6dc9357SAndroid Build Coastguard Worker
52*f6dc9357SAndroid Build Coastguard Worker #define CODER_BUF_SIZE ((size_t)1 << 17)
53*f6dc9357SAndroid Build Coastguard Worker
Xz_ReadVarInt(const Byte * p,size_t maxSize,UInt64 * value)54*f6dc9357SAndroid Build Coastguard Worker unsigned Xz_ReadVarInt(const Byte *p, size_t maxSize, UInt64 *value)
55*f6dc9357SAndroid Build Coastguard Worker {
56*f6dc9357SAndroid Build Coastguard Worker unsigned i, limit;
57*f6dc9357SAndroid Build Coastguard Worker *value = 0;
58*f6dc9357SAndroid Build Coastguard Worker limit = (maxSize > 9) ? 9 : (unsigned)maxSize;
59*f6dc9357SAndroid Build Coastguard Worker
60*f6dc9357SAndroid Build Coastguard Worker for (i = 0; i < limit;)
61*f6dc9357SAndroid Build Coastguard Worker {
62*f6dc9357SAndroid Build Coastguard Worker Byte b = p[i];
63*f6dc9357SAndroid Build Coastguard Worker *value |= (UInt64)(b & 0x7F) << (7 * i++);
64*f6dc9357SAndroid Build Coastguard Worker if ((b & 0x80) == 0)
65*f6dc9357SAndroid Build Coastguard Worker return (b == 0 && i != 1) ? 0 : i;
66*f6dc9357SAndroid Build Coastguard Worker }
67*f6dc9357SAndroid Build Coastguard Worker return 0;
68*f6dc9357SAndroid Build Coastguard Worker }
69*f6dc9357SAndroid Build Coastguard Worker
70*f6dc9357SAndroid Build Coastguard Worker
71*f6dc9357SAndroid Build Coastguard Worker /* ---------- XzBcFilterState ---------- */
72*f6dc9357SAndroid Build Coastguard Worker
73*f6dc9357SAndroid Build Coastguard Worker #define BRA_BUF_SIZE (1 << 14)
74*f6dc9357SAndroid Build Coastguard Worker
75*f6dc9357SAndroid Build Coastguard Worker typedef struct
76*f6dc9357SAndroid Build Coastguard Worker {
77*f6dc9357SAndroid Build Coastguard Worker size_t bufPos;
78*f6dc9357SAndroid Build Coastguard Worker size_t bufConv;
79*f6dc9357SAndroid Build Coastguard Worker size_t bufTotal;
80*f6dc9357SAndroid Build Coastguard Worker Byte *buf; // must be aligned for 4 bytes
81*f6dc9357SAndroid Build Coastguard Worker Xz_Func_BcFilterStateBase_Filter filter_func;
82*f6dc9357SAndroid Build Coastguard Worker // int encodeMode;
83*f6dc9357SAndroid Build Coastguard Worker CXzBcFilterStateBase base;
84*f6dc9357SAndroid Build Coastguard Worker // Byte buf[BRA_BUF_SIZE];
85*f6dc9357SAndroid Build Coastguard Worker } CXzBcFilterState;
86*f6dc9357SAndroid Build Coastguard Worker
87*f6dc9357SAndroid Build Coastguard Worker
XzBcFilterState_Free(void * pp,ISzAllocPtr alloc)88*f6dc9357SAndroid Build Coastguard Worker static void XzBcFilterState_Free(void *pp, ISzAllocPtr alloc)
89*f6dc9357SAndroid Build Coastguard Worker {
90*f6dc9357SAndroid Build Coastguard Worker if (pp)
91*f6dc9357SAndroid Build Coastguard Worker {
92*f6dc9357SAndroid Build Coastguard Worker CXzBcFilterState *p = ((CXzBcFilterState *)pp);
93*f6dc9357SAndroid Build Coastguard Worker ISzAlloc_Free(alloc, p->buf);
94*f6dc9357SAndroid Build Coastguard Worker ISzAlloc_Free(alloc, pp);
95*f6dc9357SAndroid Build Coastguard Worker }
96*f6dc9357SAndroid Build Coastguard Worker }
97*f6dc9357SAndroid Build Coastguard Worker
98*f6dc9357SAndroid Build Coastguard Worker
XzBcFilterState_SetProps(void * pp,const Byte * props,size_t propSize,ISzAllocPtr alloc)99*f6dc9357SAndroid Build Coastguard Worker static SRes XzBcFilterState_SetProps(void *pp, const Byte *props, size_t propSize, ISzAllocPtr alloc)
100*f6dc9357SAndroid Build Coastguard Worker {
101*f6dc9357SAndroid Build Coastguard Worker CXzBcFilterStateBase *p = &((CXzBcFilterState *)pp)->base;
102*f6dc9357SAndroid Build Coastguard Worker UNUSED_VAR(alloc)
103*f6dc9357SAndroid Build Coastguard Worker p->ip = 0;
104*f6dc9357SAndroid Build Coastguard Worker if (p->methodId == XZ_ID_Delta)
105*f6dc9357SAndroid Build Coastguard Worker {
106*f6dc9357SAndroid Build Coastguard Worker if (propSize != 1)
107*f6dc9357SAndroid Build Coastguard Worker return SZ_ERROR_UNSUPPORTED;
108*f6dc9357SAndroid Build Coastguard Worker p->delta = (UInt32)props[0] + 1;
109*f6dc9357SAndroid Build Coastguard Worker }
110*f6dc9357SAndroid Build Coastguard Worker else
111*f6dc9357SAndroid Build Coastguard Worker {
112*f6dc9357SAndroid Build Coastguard Worker if (propSize == 4)
113*f6dc9357SAndroid Build Coastguard Worker {
114*f6dc9357SAndroid Build Coastguard Worker const UInt32 v = GetUi32(props);
115*f6dc9357SAndroid Build Coastguard Worker switch (p->methodId)
116*f6dc9357SAndroid Build Coastguard Worker {
117*f6dc9357SAndroid Build Coastguard Worker case XZ_ID_PPC:
118*f6dc9357SAndroid Build Coastguard Worker case XZ_ID_ARM:
119*f6dc9357SAndroid Build Coastguard Worker case XZ_ID_SPARC:
120*f6dc9357SAndroid Build Coastguard Worker case XZ_ID_ARM64:
121*f6dc9357SAndroid Build Coastguard Worker if (v & 3)
122*f6dc9357SAndroid Build Coastguard Worker return SZ_ERROR_UNSUPPORTED;
123*f6dc9357SAndroid Build Coastguard Worker break;
124*f6dc9357SAndroid Build Coastguard Worker case XZ_ID_ARMT:
125*f6dc9357SAndroid Build Coastguard Worker case XZ_ID_RISCV:
126*f6dc9357SAndroid Build Coastguard Worker if (v & 1)
127*f6dc9357SAndroid Build Coastguard Worker return SZ_ERROR_UNSUPPORTED;
128*f6dc9357SAndroid Build Coastguard Worker break;
129*f6dc9357SAndroid Build Coastguard Worker case XZ_ID_IA64:
130*f6dc9357SAndroid Build Coastguard Worker if (v & 0xf)
131*f6dc9357SAndroid Build Coastguard Worker return SZ_ERROR_UNSUPPORTED;
132*f6dc9357SAndroid Build Coastguard Worker break;
133*f6dc9357SAndroid Build Coastguard Worker default: break;
134*f6dc9357SAndroid Build Coastguard Worker }
135*f6dc9357SAndroid Build Coastguard Worker p->ip = v;
136*f6dc9357SAndroid Build Coastguard Worker }
137*f6dc9357SAndroid Build Coastguard Worker else if (propSize != 0)
138*f6dc9357SAndroid Build Coastguard Worker return SZ_ERROR_UNSUPPORTED;
139*f6dc9357SAndroid Build Coastguard Worker }
140*f6dc9357SAndroid Build Coastguard Worker return SZ_OK;
141*f6dc9357SAndroid Build Coastguard Worker }
142*f6dc9357SAndroid Build Coastguard Worker
143*f6dc9357SAndroid Build Coastguard Worker
XzBcFilterState_Init(void * pp)144*f6dc9357SAndroid Build Coastguard Worker static void XzBcFilterState_Init(void *pp)
145*f6dc9357SAndroid Build Coastguard Worker {
146*f6dc9357SAndroid Build Coastguard Worker CXzBcFilterState *p = ((CXzBcFilterState *)pp);
147*f6dc9357SAndroid Build Coastguard Worker p->bufPos = p->bufConv = p->bufTotal = 0;
148*f6dc9357SAndroid Build Coastguard Worker p->base.X86_State = Z7_BRANCH_CONV_ST_X86_STATE_INIT_VAL;
149*f6dc9357SAndroid Build Coastguard Worker if (p->base.methodId == XZ_ID_Delta)
150*f6dc9357SAndroid Build Coastguard Worker Delta_Init(p->base.delta_State);
151*f6dc9357SAndroid Build Coastguard Worker }
152*f6dc9357SAndroid Build Coastguard Worker
153*f6dc9357SAndroid Build Coastguard Worker
154*f6dc9357SAndroid Build Coastguard Worker static const z7_Func_BranchConv g_Funcs_BranchConv_RISC_Dec[] =
155*f6dc9357SAndroid Build Coastguard Worker {
156*f6dc9357SAndroid Build Coastguard Worker Z7_BRANCH_CONV_DEC_2 (BranchConv_PPC),
157*f6dc9357SAndroid Build Coastguard Worker Z7_BRANCH_CONV_DEC_2 (BranchConv_IA64),
158*f6dc9357SAndroid Build Coastguard Worker Z7_BRANCH_CONV_DEC_2 (BranchConv_ARM),
159*f6dc9357SAndroid Build Coastguard Worker Z7_BRANCH_CONV_DEC_2 (BranchConv_ARMT),
160*f6dc9357SAndroid Build Coastguard Worker Z7_BRANCH_CONV_DEC_2 (BranchConv_SPARC),
161*f6dc9357SAndroid Build Coastguard Worker Z7_BRANCH_CONV_DEC_2 (BranchConv_ARM64),
162*f6dc9357SAndroid Build Coastguard Worker Z7_BRANCH_CONV_DEC_2 (BranchConv_RISCV)
163*f6dc9357SAndroid Build Coastguard Worker };
164*f6dc9357SAndroid Build Coastguard Worker
XzBcFilterStateBase_Filter_Dec(CXzBcFilterStateBase * p,Byte * data,SizeT size)165*f6dc9357SAndroid Build Coastguard Worker static SizeT XzBcFilterStateBase_Filter_Dec(CXzBcFilterStateBase *p, Byte *data, SizeT size)
166*f6dc9357SAndroid Build Coastguard Worker {
167*f6dc9357SAndroid Build Coastguard Worker switch (p->methodId)
168*f6dc9357SAndroid Build Coastguard Worker {
169*f6dc9357SAndroid Build Coastguard Worker case XZ_ID_Delta:
170*f6dc9357SAndroid Build Coastguard Worker Delta_Decode(p->delta_State, p->delta, data, size);
171*f6dc9357SAndroid Build Coastguard Worker break;
172*f6dc9357SAndroid Build Coastguard Worker case XZ_ID_X86:
173*f6dc9357SAndroid Build Coastguard Worker size = (SizeT)(z7_BranchConvSt_X86_Dec(data, size, p->ip, &p->X86_State) - data);
174*f6dc9357SAndroid Build Coastguard Worker break;
175*f6dc9357SAndroid Build Coastguard Worker default:
176*f6dc9357SAndroid Build Coastguard Worker if (p->methodId >= XZ_ID_PPC)
177*f6dc9357SAndroid Build Coastguard Worker {
178*f6dc9357SAndroid Build Coastguard Worker const UInt32 i = p->methodId - XZ_ID_PPC;
179*f6dc9357SAndroid Build Coastguard Worker if (i < Z7_ARRAY_SIZE(g_Funcs_BranchConv_RISC_Dec))
180*f6dc9357SAndroid Build Coastguard Worker size = (SizeT)(g_Funcs_BranchConv_RISC_Dec[i](data, size, p->ip) - data);
181*f6dc9357SAndroid Build Coastguard Worker }
182*f6dc9357SAndroid Build Coastguard Worker break;
183*f6dc9357SAndroid Build Coastguard Worker }
184*f6dc9357SAndroid Build Coastguard Worker p->ip += (UInt32)size;
185*f6dc9357SAndroid Build Coastguard Worker return size;
186*f6dc9357SAndroid Build Coastguard Worker }
187*f6dc9357SAndroid Build Coastguard Worker
188*f6dc9357SAndroid Build Coastguard Worker
XzBcFilterState_Filter(void * pp,Byte * data,SizeT size)189*f6dc9357SAndroid Build Coastguard Worker static SizeT XzBcFilterState_Filter(void *pp, Byte *data, SizeT size)
190*f6dc9357SAndroid Build Coastguard Worker {
191*f6dc9357SAndroid Build Coastguard Worker CXzBcFilterState *p = ((CXzBcFilterState *)pp);
192*f6dc9357SAndroid Build Coastguard Worker return p->filter_func(&p->base, data, size);
193*f6dc9357SAndroid Build Coastguard Worker }
194*f6dc9357SAndroid Build Coastguard Worker
195*f6dc9357SAndroid Build Coastguard Worker
XzBcFilterState_Code2(void * pp,Byte * dest,SizeT * destLen,const Byte * src,SizeT * srcLen,int srcWasFinished,ECoderFinishMode finishMode,ECoderStatus * status)196*f6dc9357SAndroid Build Coastguard Worker static SRes XzBcFilterState_Code2(void *pp,
197*f6dc9357SAndroid Build Coastguard Worker Byte *dest, SizeT *destLen,
198*f6dc9357SAndroid Build Coastguard Worker const Byte *src, SizeT *srcLen, int srcWasFinished,
199*f6dc9357SAndroid Build Coastguard Worker ECoderFinishMode finishMode,
200*f6dc9357SAndroid Build Coastguard Worker // int *wasFinished
201*f6dc9357SAndroid Build Coastguard Worker ECoderStatus *status)
202*f6dc9357SAndroid Build Coastguard Worker {
203*f6dc9357SAndroid Build Coastguard Worker CXzBcFilterState *p = ((CXzBcFilterState *)pp);
204*f6dc9357SAndroid Build Coastguard Worker SizeT destRem = *destLen;
205*f6dc9357SAndroid Build Coastguard Worker SizeT srcRem = *srcLen;
206*f6dc9357SAndroid Build Coastguard Worker UNUSED_VAR(finishMode)
207*f6dc9357SAndroid Build Coastguard Worker
208*f6dc9357SAndroid Build Coastguard Worker *destLen = 0;
209*f6dc9357SAndroid Build Coastguard Worker *srcLen = 0;
210*f6dc9357SAndroid Build Coastguard Worker // *wasFinished = False;
211*f6dc9357SAndroid Build Coastguard Worker *status = CODER_STATUS_NOT_FINISHED;
212*f6dc9357SAndroid Build Coastguard Worker
213*f6dc9357SAndroid Build Coastguard Worker while (destRem != 0)
214*f6dc9357SAndroid Build Coastguard Worker {
215*f6dc9357SAndroid Build Coastguard Worker {
216*f6dc9357SAndroid Build Coastguard Worker size_t size = p->bufConv - p->bufPos;
217*f6dc9357SAndroid Build Coastguard Worker if (size)
218*f6dc9357SAndroid Build Coastguard Worker {
219*f6dc9357SAndroid Build Coastguard Worker if (size > destRem)
220*f6dc9357SAndroid Build Coastguard Worker size = destRem;
221*f6dc9357SAndroid Build Coastguard Worker memcpy(dest, p->buf + p->bufPos, size);
222*f6dc9357SAndroid Build Coastguard Worker p->bufPos += size;
223*f6dc9357SAndroid Build Coastguard Worker *destLen += size;
224*f6dc9357SAndroid Build Coastguard Worker dest += size;
225*f6dc9357SAndroid Build Coastguard Worker destRem -= size;
226*f6dc9357SAndroid Build Coastguard Worker continue;
227*f6dc9357SAndroid Build Coastguard Worker }
228*f6dc9357SAndroid Build Coastguard Worker }
229*f6dc9357SAndroid Build Coastguard Worker
230*f6dc9357SAndroid Build Coastguard Worker p->bufTotal -= p->bufPos;
231*f6dc9357SAndroid Build Coastguard Worker memmove(p->buf, p->buf + p->bufPos, p->bufTotal);
232*f6dc9357SAndroid Build Coastguard Worker p->bufPos = 0;
233*f6dc9357SAndroid Build Coastguard Worker p->bufConv = 0;
234*f6dc9357SAndroid Build Coastguard Worker {
235*f6dc9357SAndroid Build Coastguard Worker size_t size = BRA_BUF_SIZE - p->bufTotal;
236*f6dc9357SAndroid Build Coastguard Worker if (size > srcRem)
237*f6dc9357SAndroid Build Coastguard Worker size = srcRem;
238*f6dc9357SAndroid Build Coastguard Worker memcpy(p->buf + p->bufTotal, src, size);
239*f6dc9357SAndroid Build Coastguard Worker *srcLen += size;
240*f6dc9357SAndroid Build Coastguard Worker src += size;
241*f6dc9357SAndroid Build Coastguard Worker srcRem -= size;
242*f6dc9357SAndroid Build Coastguard Worker p->bufTotal += size;
243*f6dc9357SAndroid Build Coastguard Worker }
244*f6dc9357SAndroid Build Coastguard Worker if (p->bufTotal == 0)
245*f6dc9357SAndroid Build Coastguard Worker break;
246*f6dc9357SAndroid Build Coastguard Worker
247*f6dc9357SAndroid Build Coastguard Worker p->bufConv = p->filter_func(&p->base, p->buf, p->bufTotal);
248*f6dc9357SAndroid Build Coastguard Worker
249*f6dc9357SAndroid Build Coastguard Worker if (p->bufConv == 0)
250*f6dc9357SAndroid Build Coastguard Worker {
251*f6dc9357SAndroid Build Coastguard Worker if (!srcWasFinished)
252*f6dc9357SAndroid Build Coastguard Worker break;
253*f6dc9357SAndroid Build Coastguard Worker p->bufConv = p->bufTotal;
254*f6dc9357SAndroid Build Coastguard Worker }
255*f6dc9357SAndroid Build Coastguard Worker }
256*f6dc9357SAndroid Build Coastguard Worker
257*f6dc9357SAndroid Build Coastguard Worker if (p->bufTotal == p->bufPos && srcRem == 0 && srcWasFinished)
258*f6dc9357SAndroid Build Coastguard Worker {
259*f6dc9357SAndroid Build Coastguard Worker *status = CODER_STATUS_FINISHED_WITH_MARK;
260*f6dc9357SAndroid Build Coastguard Worker // *wasFinished = 1;
261*f6dc9357SAndroid Build Coastguard Worker }
262*f6dc9357SAndroid Build Coastguard Worker
263*f6dc9357SAndroid Build Coastguard Worker return SZ_OK;
264*f6dc9357SAndroid Build Coastguard Worker }
265*f6dc9357SAndroid Build Coastguard Worker
266*f6dc9357SAndroid Build Coastguard Worker
267*f6dc9357SAndroid Build Coastguard Worker #define XZ_IS_SUPPORTED_FILTER_ID(id) \
268*f6dc9357SAndroid Build Coastguard Worker ((id) >= XZ_ID_Delta && (id) <= XZ_ID_RISCV)
269*f6dc9357SAndroid Build Coastguard Worker
Xz_StateCoder_Bc_SetFromMethod_Func(IStateCoder * p,UInt64 id,Xz_Func_BcFilterStateBase_Filter func,ISzAllocPtr alloc)270*f6dc9357SAndroid Build Coastguard Worker SRes Xz_StateCoder_Bc_SetFromMethod_Func(IStateCoder *p, UInt64 id,
271*f6dc9357SAndroid Build Coastguard Worker Xz_Func_BcFilterStateBase_Filter func, ISzAllocPtr alloc)
272*f6dc9357SAndroid Build Coastguard Worker {
273*f6dc9357SAndroid Build Coastguard Worker CXzBcFilterState *decoder;
274*f6dc9357SAndroid Build Coastguard Worker if (!XZ_IS_SUPPORTED_FILTER_ID(id))
275*f6dc9357SAndroid Build Coastguard Worker return SZ_ERROR_UNSUPPORTED;
276*f6dc9357SAndroid Build Coastguard Worker decoder = (CXzBcFilterState *)p->p;
277*f6dc9357SAndroid Build Coastguard Worker if (!decoder)
278*f6dc9357SAndroid Build Coastguard Worker {
279*f6dc9357SAndroid Build Coastguard Worker decoder = (CXzBcFilterState *)ISzAlloc_Alloc(alloc, sizeof(CXzBcFilterState));
280*f6dc9357SAndroid Build Coastguard Worker if (!decoder)
281*f6dc9357SAndroid Build Coastguard Worker return SZ_ERROR_MEM;
282*f6dc9357SAndroid Build Coastguard Worker decoder->buf = ISzAlloc_Alloc(alloc, BRA_BUF_SIZE);
283*f6dc9357SAndroid Build Coastguard Worker if (!decoder->buf)
284*f6dc9357SAndroid Build Coastguard Worker {
285*f6dc9357SAndroid Build Coastguard Worker ISzAlloc_Free(alloc, decoder);
286*f6dc9357SAndroid Build Coastguard Worker return SZ_ERROR_MEM;
287*f6dc9357SAndroid Build Coastguard Worker }
288*f6dc9357SAndroid Build Coastguard Worker p->p = decoder;
289*f6dc9357SAndroid Build Coastguard Worker p->Free = XzBcFilterState_Free;
290*f6dc9357SAndroid Build Coastguard Worker p->SetProps = XzBcFilterState_SetProps;
291*f6dc9357SAndroid Build Coastguard Worker p->Init = XzBcFilterState_Init;
292*f6dc9357SAndroid Build Coastguard Worker p->Code2 = XzBcFilterState_Code2;
293*f6dc9357SAndroid Build Coastguard Worker p->Filter = XzBcFilterState_Filter;
294*f6dc9357SAndroid Build Coastguard Worker decoder->filter_func = func;
295*f6dc9357SAndroid Build Coastguard Worker }
296*f6dc9357SAndroid Build Coastguard Worker decoder->base.methodId = (UInt32)id;
297*f6dc9357SAndroid Build Coastguard Worker // decoder->encodeMode = encodeMode;
298*f6dc9357SAndroid Build Coastguard Worker return SZ_OK;
299*f6dc9357SAndroid Build Coastguard Worker }
300*f6dc9357SAndroid Build Coastguard Worker
301*f6dc9357SAndroid Build Coastguard Worker
302*f6dc9357SAndroid Build Coastguard Worker
303*f6dc9357SAndroid Build Coastguard Worker /* ---------- SbState ---------- */
304*f6dc9357SAndroid Build Coastguard Worker
305*f6dc9357SAndroid Build Coastguard Worker #ifdef USE_SUBBLOCK
306*f6dc9357SAndroid Build Coastguard Worker
SbState_Free(void * pp,ISzAllocPtr alloc)307*f6dc9357SAndroid Build Coastguard Worker static void SbState_Free(void *pp, ISzAllocPtr alloc)
308*f6dc9357SAndroid Build Coastguard Worker {
309*f6dc9357SAndroid Build Coastguard Worker CSbDec *p = (CSbDec *)pp;
310*f6dc9357SAndroid Build Coastguard Worker SbDec_Free(p);
311*f6dc9357SAndroid Build Coastguard Worker ISzAlloc_Free(alloc, pp);
312*f6dc9357SAndroid Build Coastguard Worker }
313*f6dc9357SAndroid Build Coastguard Worker
SbState_SetProps(void * pp,const Byte * props,size_t propSize,ISzAllocPtr alloc)314*f6dc9357SAndroid Build Coastguard Worker static SRes SbState_SetProps(void *pp, const Byte *props, size_t propSize, ISzAllocPtr alloc)
315*f6dc9357SAndroid Build Coastguard Worker {
316*f6dc9357SAndroid Build Coastguard Worker UNUSED_VAR(pp)
317*f6dc9357SAndroid Build Coastguard Worker UNUSED_VAR(props)
318*f6dc9357SAndroid Build Coastguard Worker UNUSED_VAR(alloc)
319*f6dc9357SAndroid Build Coastguard Worker return (propSize == 0) ? SZ_OK : SZ_ERROR_UNSUPPORTED;
320*f6dc9357SAndroid Build Coastguard Worker }
321*f6dc9357SAndroid Build Coastguard Worker
SbState_Init(void * pp)322*f6dc9357SAndroid Build Coastguard Worker static void SbState_Init(void *pp)
323*f6dc9357SAndroid Build Coastguard Worker {
324*f6dc9357SAndroid Build Coastguard Worker SbDec_Init((CSbDec *)pp);
325*f6dc9357SAndroid Build Coastguard Worker }
326*f6dc9357SAndroid Build Coastguard Worker
SbState_Code2(void * pp,Byte * dest,SizeT * destLen,const Byte * src,SizeT * srcLen,int srcWasFinished,ECoderFinishMode finishMode,ECoderStatus * status)327*f6dc9357SAndroid Build Coastguard Worker static SRes SbState_Code2(void *pp, Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen,
328*f6dc9357SAndroid Build Coastguard Worker int srcWasFinished, ECoderFinishMode finishMode,
329*f6dc9357SAndroid Build Coastguard Worker // int *wasFinished
330*f6dc9357SAndroid Build Coastguard Worker ECoderStatus *status)
331*f6dc9357SAndroid Build Coastguard Worker {
332*f6dc9357SAndroid Build Coastguard Worker CSbDec *p = (CSbDec *)pp;
333*f6dc9357SAndroid Build Coastguard Worker SRes res;
334*f6dc9357SAndroid Build Coastguard Worker UNUSED_VAR(srcWasFinished)
335*f6dc9357SAndroid Build Coastguard Worker p->dest = dest;
336*f6dc9357SAndroid Build Coastguard Worker p->destLen = *destLen;
337*f6dc9357SAndroid Build Coastguard Worker p->src = src;
338*f6dc9357SAndroid Build Coastguard Worker p->srcLen = *srcLen;
339*f6dc9357SAndroid Build Coastguard Worker p->finish = finishMode; /* change it */
340*f6dc9357SAndroid Build Coastguard Worker res = SbDec_Decode((CSbDec *)pp);
341*f6dc9357SAndroid Build Coastguard Worker *destLen -= p->destLen;
342*f6dc9357SAndroid Build Coastguard Worker *srcLen -= p->srcLen;
343*f6dc9357SAndroid Build Coastguard Worker // *wasFinished = (*destLen == 0 && *srcLen == 0); /* change it */
344*f6dc9357SAndroid Build Coastguard Worker *status = (*destLen == 0 && *srcLen == 0) ?
345*f6dc9357SAndroid Build Coastguard Worker CODER_STATUS_FINISHED_WITH_MARK :
346*f6dc9357SAndroid Build Coastguard Worker CODER_STATUS_NOT_FINISHED;
347*f6dc9357SAndroid Build Coastguard Worker return res;
348*f6dc9357SAndroid Build Coastguard Worker }
349*f6dc9357SAndroid Build Coastguard Worker
SbState_SetFromMethod(IStateCoder * p,ISzAllocPtr alloc)350*f6dc9357SAndroid Build Coastguard Worker static SRes SbState_SetFromMethod(IStateCoder *p, ISzAllocPtr alloc)
351*f6dc9357SAndroid Build Coastguard Worker {
352*f6dc9357SAndroid Build Coastguard Worker CSbDec *decoder = (CSbDec *)p->p;
353*f6dc9357SAndroid Build Coastguard Worker if (!decoder)
354*f6dc9357SAndroid Build Coastguard Worker {
355*f6dc9357SAndroid Build Coastguard Worker decoder = (CSbDec *)ISzAlloc_Alloc(alloc, sizeof(CSbDec));
356*f6dc9357SAndroid Build Coastguard Worker if (!decoder)
357*f6dc9357SAndroid Build Coastguard Worker return SZ_ERROR_MEM;
358*f6dc9357SAndroid Build Coastguard Worker p->p = decoder;
359*f6dc9357SAndroid Build Coastguard Worker p->Free = SbState_Free;
360*f6dc9357SAndroid Build Coastguard Worker p->SetProps = SbState_SetProps;
361*f6dc9357SAndroid Build Coastguard Worker p->Init = SbState_Init;
362*f6dc9357SAndroid Build Coastguard Worker p->Code2 = SbState_Code2;
363*f6dc9357SAndroid Build Coastguard Worker p->Filter = NULL;
364*f6dc9357SAndroid Build Coastguard Worker }
365*f6dc9357SAndroid Build Coastguard Worker SbDec_Construct(decoder);
366*f6dc9357SAndroid Build Coastguard Worker SbDec_SetAlloc(decoder, alloc);
367*f6dc9357SAndroid Build Coastguard Worker return SZ_OK;
368*f6dc9357SAndroid Build Coastguard Worker }
369*f6dc9357SAndroid Build Coastguard Worker
370*f6dc9357SAndroid Build Coastguard Worker #endif
371*f6dc9357SAndroid Build Coastguard Worker
372*f6dc9357SAndroid Build Coastguard Worker
373*f6dc9357SAndroid Build Coastguard Worker
374*f6dc9357SAndroid Build Coastguard Worker /* ---------- Lzma2 ---------- */
375*f6dc9357SAndroid Build Coastguard Worker
376*f6dc9357SAndroid Build Coastguard Worker typedef struct
377*f6dc9357SAndroid Build Coastguard Worker {
378*f6dc9357SAndroid Build Coastguard Worker CLzma2Dec decoder;
379*f6dc9357SAndroid Build Coastguard Worker BoolInt outBufMode;
380*f6dc9357SAndroid Build Coastguard Worker } CLzma2Dec_Spec;
381*f6dc9357SAndroid Build Coastguard Worker
382*f6dc9357SAndroid Build Coastguard Worker
Lzma2State_Free(void * pp,ISzAllocPtr alloc)383*f6dc9357SAndroid Build Coastguard Worker static void Lzma2State_Free(void *pp, ISzAllocPtr alloc)
384*f6dc9357SAndroid Build Coastguard Worker {
385*f6dc9357SAndroid Build Coastguard Worker CLzma2Dec_Spec *p = (CLzma2Dec_Spec *)pp;
386*f6dc9357SAndroid Build Coastguard Worker if (p->outBufMode)
387*f6dc9357SAndroid Build Coastguard Worker Lzma2Dec_FreeProbs(&p->decoder, alloc);
388*f6dc9357SAndroid Build Coastguard Worker else
389*f6dc9357SAndroid Build Coastguard Worker Lzma2Dec_Free(&p->decoder, alloc);
390*f6dc9357SAndroid Build Coastguard Worker ISzAlloc_Free(alloc, pp);
391*f6dc9357SAndroid Build Coastguard Worker }
392*f6dc9357SAndroid Build Coastguard Worker
Lzma2State_SetProps(void * pp,const Byte * props,size_t propSize,ISzAllocPtr alloc)393*f6dc9357SAndroid Build Coastguard Worker static SRes Lzma2State_SetProps(void *pp, const Byte *props, size_t propSize, ISzAllocPtr alloc)
394*f6dc9357SAndroid Build Coastguard Worker {
395*f6dc9357SAndroid Build Coastguard Worker if (propSize != 1)
396*f6dc9357SAndroid Build Coastguard Worker return SZ_ERROR_UNSUPPORTED;
397*f6dc9357SAndroid Build Coastguard Worker {
398*f6dc9357SAndroid Build Coastguard Worker CLzma2Dec_Spec *p = (CLzma2Dec_Spec *)pp;
399*f6dc9357SAndroid Build Coastguard Worker if (p->outBufMode)
400*f6dc9357SAndroid Build Coastguard Worker return Lzma2Dec_AllocateProbs(&p->decoder, props[0], alloc);
401*f6dc9357SAndroid Build Coastguard Worker else
402*f6dc9357SAndroid Build Coastguard Worker return Lzma2Dec_Allocate(&p->decoder, props[0], alloc);
403*f6dc9357SAndroid Build Coastguard Worker }
404*f6dc9357SAndroid Build Coastguard Worker }
405*f6dc9357SAndroid Build Coastguard Worker
Lzma2State_Init(void * pp)406*f6dc9357SAndroid Build Coastguard Worker static void Lzma2State_Init(void *pp)
407*f6dc9357SAndroid Build Coastguard Worker {
408*f6dc9357SAndroid Build Coastguard Worker Lzma2Dec_Init(&((CLzma2Dec_Spec *)pp)->decoder);
409*f6dc9357SAndroid Build Coastguard Worker }
410*f6dc9357SAndroid Build Coastguard Worker
411*f6dc9357SAndroid Build Coastguard Worker
412*f6dc9357SAndroid Build Coastguard Worker /*
413*f6dc9357SAndroid Build Coastguard Worker if (outBufMode), then (dest) is not used. Use NULL.
414*f6dc9357SAndroid Build Coastguard Worker Data is unpacked to (spec->decoder.decoder.dic) output buffer.
415*f6dc9357SAndroid Build Coastguard Worker */
416*f6dc9357SAndroid Build Coastguard Worker
Lzma2State_Code2(void * pp,Byte * dest,SizeT * destLen,const Byte * src,SizeT * srcLen,int srcWasFinished,ECoderFinishMode finishMode,ECoderStatus * status)417*f6dc9357SAndroid Build Coastguard Worker static SRes Lzma2State_Code2(void *pp, Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen,
418*f6dc9357SAndroid Build Coastguard Worker int srcWasFinished, ECoderFinishMode finishMode,
419*f6dc9357SAndroid Build Coastguard Worker // int *wasFinished,
420*f6dc9357SAndroid Build Coastguard Worker ECoderStatus *status)
421*f6dc9357SAndroid Build Coastguard Worker {
422*f6dc9357SAndroid Build Coastguard Worker CLzma2Dec_Spec *spec = (CLzma2Dec_Spec *)pp;
423*f6dc9357SAndroid Build Coastguard Worker ELzmaStatus status2;
424*f6dc9357SAndroid Build Coastguard Worker /* ELzmaFinishMode fm = (finishMode == LZMA_FINISH_ANY) ? LZMA_FINISH_ANY : LZMA_FINISH_END; */
425*f6dc9357SAndroid Build Coastguard Worker SRes res;
426*f6dc9357SAndroid Build Coastguard Worker UNUSED_VAR(srcWasFinished)
427*f6dc9357SAndroid Build Coastguard Worker if (spec->outBufMode)
428*f6dc9357SAndroid Build Coastguard Worker {
429*f6dc9357SAndroid Build Coastguard Worker SizeT dicPos = spec->decoder.decoder.dicPos;
430*f6dc9357SAndroid Build Coastguard Worker SizeT dicLimit = dicPos + *destLen;
431*f6dc9357SAndroid Build Coastguard Worker res = Lzma2Dec_DecodeToDic(&spec->decoder, dicLimit, src, srcLen, (ELzmaFinishMode)finishMode, &status2);
432*f6dc9357SAndroid Build Coastguard Worker *destLen = spec->decoder.decoder.dicPos - dicPos;
433*f6dc9357SAndroid Build Coastguard Worker }
434*f6dc9357SAndroid Build Coastguard Worker else
435*f6dc9357SAndroid Build Coastguard Worker res = Lzma2Dec_DecodeToBuf(&spec->decoder, dest, destLen, src, srcLen, (ELzmaFinishMode)finishMode, &status2);
436*f6dc9357SAndroid Build Coastguard Worker // *wasFinished = (status2 == LZMA_STATUS_FINISHED_WITH_MARK);
437*f6dc9357SAndroid Build Coastguard Worker // ECoderStatus values are identical to ELzmaStatus values of LZMA2 decoder
438*f6dc9357SAndroid Build Coastguard Worker *status = (ECoderStatus)status2;
439*f6dc9357SAndroid Build Coastguard Worker return res;
440*f6dc9357SAndroid Build Coastguard Worker }
441*f6dc9357SAndroid Build Coastguard Worker
442*f6dc9357SAndroid Build Coastguard Worker
Lzma2State_SetFromMethod(IStateCoder * p,Byte * outBuf,size_t outBufSize,ISzAllocPtr alloc)443*f6dc9357SAndroid Build Coastguard Worker static SRes Lzma2State_SetFromMethod(IStateCoder *p, Byte *outBuf, size_t outBufSize, ISzAllocPtr alloc)
444*f6dc9357SAndroid Build Coastguard Worker {
445*f6dc9357SAndroid Build Coastguard Worker CLzma2Dec_Spec *spec = (CLzma2Dec_Spec *)p->p;
446*f6dc9357SAndroid Build Coastguard Worker if (!spec)
447*f6dc9357SAndroid Build Coastguard Worker {
448*f6dc9357SAndroid Build Coastguard Worker spec = (CLzma2Dec_Spec *)ISzAlloc_Alloc(alloc, sizeof(CLzma2Dec_Spec));
449*f6dc9357SAndroid Build Coastguard Worker if (!spec)
450*f6dc9357SAndroid Build Coastguard Worker return SZ_ERROR_MEM;
451*f6dc9357SAndroid Build Coastguard Worker p->p = spec;
452*f6dc9357SAndroid Build Coastguard Worker p->Free = Lzma2State_Free;
453*f6dc9357SAndroid Build Coastguard Worker p->SetProps = Lzma2State_SetProps;
454*f6dc9357SAndroid Build Coastguard Worker p->Init = Lzma2State_Init;
455*f6dc9357SAndroid Build Coastguard Worker p->Code2 = Lzma2State_Code2;
456*f6dc9357SAndroid Build Coastguard Worker p->Filter = NULL;
457*f6dc9357SAndroid Build Coastguard Worker Lzma2Dec_CONSTRUCT(&spec->decoder)
458*f6dc9357SAndroid Build Coastguard Worker }
459*f6dc9357SAndroid Build Coastguard Worker spec->outBufMode = False;
460*f6dc9357SAndroid Build Coastguard Worker if (outBuf)
461*f6dc9357SAndroid Build Coastguard Worker {
462*f6dc9357SAndroid Build Coastguard Worker spec->outBufMode = True;
463*f6dc9357SAndroid Build Coastguard Worker spec->decoder.decoder.dic = outBuf;
464*f6dc9357SAndroid Build Coastguard Worker spec->decoder.decoder.dicBufSize = outBufSize;
465*f6dc9357SAndroid Build Coastguard Worker }
466*f6dc9357SAndroid Build Coastguard Worker return SZ_OK;
467*f6dc9357SAndroid Build Coastguard Worker }
468*f6dc9357SAndroid Build Coastguard Worker
469*f6dc9357SAndroid Build Coastguard Worker
Lzma2State_ResetOutBuf(IStateCoder * p,Byte * outBuf,size_t outBufSize)470*f6dc9357SAndroid Build Coastguard Worker static SRes Lzma2State_ResetOutBuf(IStateCoder *p, Byte *outBuf, size_t outBufSize)
471*f6dc9357SAndroid Build Coastguard Worker {
472*f6dc9357SAndroid Build Coastguard Worker CLzma2Dec_Spec *spec = (CLzma2Dec_Spec *)p->p;
473*f6dc9357SAndroid Build Coastguard Worker if ((spec->outBufMode && !outBuf) || (!spec->outBufMode && outBuf))
474*f6dc9357SAndroid Build Coastguard Worker return SZ_ERROR_FAIL;
475*f6dc9357SAndroid Build Coastguard Worker if (outBuf)
476*f6dc9357SAndroid Build Coastguard Worker {
477*f6dc9357SAndroid Build Coastguard Worker spec->decoder.decoder.dic = outBuf;
478*f6dc9357SAndroid Build Coastguard Worker spec->decoder.decoder.dicBufSize = outBufSize;
479*f6dc9357SAndroid Build Coastguard Worker }
480*f6dc9357SAndroid Build Coastguard Worker return SZ_OK;
481*f6dc9357SAndroid Build Coastguard Worker }
482*f6dc9357SAndroid Build Coastguard Worker
483*f6dc9357SAndroid Build Coastguard Worker
484*f6dc9357SAndroid Build Coastguard Worker
MixCoder_Construct(CMixCoder * p,ISzAllocPtr alloc)485*f6dc9357SAndroid Build Coastguard Worker static void MixCoder_Construct(CMixCoder *p, ISzAllocPtr alloc)
486*f6dc9357SAndroid Build Coastguard Worker {
487*f6dc9357SAndroid Build Coastguard Worker unsigned i;
488*f6dc9357SAndroid Build Coastguard Worker p->alloc = alloc;
489*f6dc9357SAndroid Build Coastguard Worker p->buf = NULL;
490*f6dc9357SAndroid Build Coastguard Worker p->numCoders = 0;
491*f6dc9357SAndroid Build Coastguard Worker
492*f6dc9357SAndroid Build Coastguard Worker p->outBufSize = 0;
493*f6dc9357SAndroid Build Coastguard Worker p->outBuf = NULL;
494*f6dc9357SAndroid Build Coastguard Worker // p->SingleBufMode = False;
495*f6dc9357SAndroid Build Coastguard Worker
496*f6dc9357SAndroid Build Coastguard Worker for (i = 0; i < MIXCODER_NUM_FILTERS_MAX; i++)
497*f6dc9357SAndroid Build Coastguard Worker p->coders[i].p = NULL;
498*f6dc9357SAndroid Build Coastguard Worker }
499*f6dc9357SAndroid Build Coastguard Worker
500*f6dc9357SAndroid Build Coastguard Worker
MixCoder_Free(CMixCoder * p)501*f6dc9357SAndroid Build Coastguard Worker static void MixCoder_Free(CMixCoder *p)
502*f6dc9357SAndroid Build Coastguard Worker {
503*f6dc9357SAndroid Build Coastguard Worker unsigned i;
504*f6dc9357SAndroid Build Coastguard Worker p->numCoders = 0;
505*f6dc9357SAndroid Build Coastguard Worker for (i = 0; i < MIXCODER_NUM_FILTERS_MAX; i++)
506*f6dc9357SAndroid Build Coastguard Worker {
507*f6dc9357SAndroid Build Coastguard Worker IStateCoder *sc = &p->coders[i];
508*f6dc9357SAndroid Build Coastguard Worker if (sc->p)
509*f6dc9357SAndroid Build Coastguard Worker {
510*f6dc9357SAndroid Build Coastguard Worker sc->Free(sc->p, p->alloc);
511*f6dc9357SAndroid Build Coastguard Worker sc->p = NULL;
512*f6dc9357SAndroid Build Coastguard Worker }
513*f6dc9357SAndroid Build Coastguard Worker }
514*f6dc9357SAndroid Build Coastguard Worker if (p->buf)
515*f6dc9357SAndroid Build Coastguard Worker {
516*f6dc9357SAndroid Build Coastguard Worker ISzAlloc_Free(p->alloc, p->buf);
517*f6dc9357SAndroid Build Coastguard Worker p->buf = NULL; /* 9.31: the BUG was fixed */
518*f6dc9357SAndroid Build Coastguard Worker }
519*f6dc9357SAndroid Build Coastguard Worker }
520*f6dc9357SAndroid Build Coastguard Worker
MixCoder_Init(CMixCoder * p)521*f6dc9357SAndroid Build Coastguard Worker static void MixCoder_Init(CMixCoder *p)
522*f6dc9357SAndroid Build Coastguard Worker {
523*f6dc9357SAndroid Build Coastguard Worker unsigned i;
524*f6dc9357SAndroid Build Coastguard Worker for (i = 0; i < MIXCODER_NUM_FILTERS_MAX - 1; i++)
525*f6dc9357SAndroid Build Coastguard Worker {
526*f6dc9357SAndroid Build Coastguard Worker p->size[i] = 0;
527*f6dc9357SAndroid Build Coastguard Worker p->pos[i] = 0;
528*f6dc9357SAndroid Build Coastguard Worker p->finished[i] = 0;
529*f6dc9357SAndroid Build Coastguard Worker }
530*f6dc9357SAndroid Build Coastguard Worker for (i = 0; i < p->numCoders; i++)
531*f6dc9357SAndroid Build Coastguard Worker {
532*f6dc9357SAndroid Build Coastguard Worker IStateCoder *coder = &p->coders[i];
533*f6dc9357SAndroid Build Coastguard Worker coder->Init(coder->p);
534*f6dc9357SAndroid Build Coastguard Worker p->results[i] = SZ_OK;
535*f6dc9357SAndroid Build Coastguard Worker }
536*f6dc9357SAndroid Build Coastguard Worker p->outWritten = 0;
537*f6dc9357SAndroid Build Coastguard Worker p->wasFinished = False;
538*f6dc9357SAndroid Build Coastguard Worker p->res = SZ_OK;
539*f6dc9357SAndroid Build Coastguard Worker p->status = CODER_STATUS_NOT_SPECIFIED;
540*f6dc9357SAndroid Build Coastguard Worker }
541*f6dc9357SAndroid Build Coastguard Worker
542*f6dc9357SAndroid Build Coastguard Worker
MixCoder_SetFromMethod(CMixCoder * p,unsigned coderIndex,UInt64 methodId,Byte * outBuf,size_t outBufSize)543*f6dc9357SAndroid Build Coastguard Worker static SRes MixCoder_SetFromMethod(CMixCoder *p, unsigned coderIndex, UInt64 methodId, Byte *outBuf, size_t outBufSize)
544*f6dc9357SAndroid Build Coastguard Worker {
545*f6dc9357SAndroid Build Coastguard Worker IStateCoder *sc = &p->coders[coderIndex];
546*f6dc9357SAndroid Build Coastguard Worker p->ids[coderIndex] = methodId;
547*f6dc9357SAndroid Build Coastguard Worker if (methodId == XZ_ID_LZMA2)
548*f6dc9357SAndroid Build Coastguard Worker return Lzma2State_SetFromMethod(sc, outBuf, outBufSize, p->alloc);
549*f6dc9357SAndroid Build Coastguard Worker #ifdef USE_SUBBLOCK
550*f6dc9357SAndroid Build Coastguard Worker if (methodId == XZ_ID_Subblock)
551*f6dc9357SAndroid Build Coastguard Worker return SbState_SetFromMethod(sc, p->alloc);
552*f6dc9357SAndroid Build Coastguard Worker #endif
553*f6dc9357SAndroid Build Coastguard Worker if (coderIndex == 0)
554*f6dc9357SAndroid Build Coastguard Worker return SZ_ERROR_UNSUPPORTED;
555*f6dc9357SAndroid Build Coastguard Worker return Xz_StateCoder_Bc_SetFromMethod_Func(sc, methodId,
556*f6dc9357SAndroid Build Coastguard Worker XzBcFilterStateBase_Filter_Dec, p->alloc);
557*f6dc9357SAndroid Build Coastguard Worker }
558*f6dc9357SAndroid Build Coastguard Worker
559*f6dc9357SAndroid Build Coastguard Worker
MixCoder_ResetFromMethod(CMixCoder * p,unsigned coderIndex,UInt64 methodId,Byte * outBuf,size_t outBufSize)560*f6dc9357SAndroid Build Coastguard Worker static SRes MixCoder_ResetFromMethod(CMixCoder *p, unsigned coderIndex, UInt64 methodId, Byte *outBuf, size_t outBufSize)
561*f6dc9357SAndroid Build Coastguard Worker {
562*f6dc9357SAndroid Build Coastguard Worker IStateCoder *sc = &p->coders[coderIndex];
563*f6dc9357SAndroid Build Coastguard Worker if (methodId == XZ_ID_LZMA2)
564*f6dc9357SAndroid Build Coastguard Worker return Lzma2State_ResetOutBuf(sc, outBuf, outBufSize);
565*f6dc9357SAndroid Build Coastguard Worker return SZ_ERROR_UNSUPPORTED;
566*f6dc9357SAndroid Build Coastguard Worker }
567*f6dc9357SAndroid Build Coastguard Worker
568*f6dc9357SAndroid Build Coastguard Worker
569*f6dc9357SAndroid Build Coastguard Worker
570*f6dc9357SAndroid Build Coastguard Worker /*
571*f6dc9357SAndroid Build Coastguard Worker if (destFinish) - then unpack data block is finished at (*destLen) position,
572*f6dc9357SAndroid Build Coastguard Worker and we can return data that were not processed by filter
573*f6dc9357SAndroid Build Coastguard Worker
574*f6dc9357SAndroid Build Coastguard Worker output (status) can be :
575*f6dc9357SAndroid Build Coastguard Worker CODER_STATUS_NOT_FINISHED
576*f6dc9357SAndroid Build Coastguard Worker CODER_STATUS_FINISHED_WITH_MARK
577*f6dc9357SAndroid Build Coastguard Worker CODER_STATUS_NEEDS_MORE_INPUT - not implemented still
578*f6dc9357SAndroid Build Coastguard Worker */
579*f6dc9357SAndroid Build Coastguard Worker
MixCoder_Code(CMixCoder * p,Byte * dest,SizeT * destLen,int destFinish,const Byte * src,SizeT * srcLen,int srcWasFinished,ECoderFinishMode finishMode)580*f6dc9357SAndroid Build Coastguard Worker static SRes MixCoder_Code(CMixCoder *p,
581*f6dc9357SAndroid Build Coastguard Worker Byte *dest, SizeT *destLen, int destFinish,
582*f6dc9357SAndroid Build Coastguard Worker const Byte *src, SizeT *srcLen, int srcWasFinished,
583*f6dc9357SAndroid Build Coastguard Worker ECoderFinishMode finishMode)
584*f6dc9357SAndroid Build Coastguard Worker {
585*f6dc9357SAndroid Build Coastguard Worker SizeT destLenOrig = *destLen;
586*f6dc9357SAndroid Build Coastguard Worker SizeT srcLenOrig = *srcLen;
587*f6dc9357SAndroid Build Coastguard Worker
588*f6dc9357SAndroid Build Coastguard Worker *destLen = 0;
589*f6dc9357SAndroid Build Coastguard Worker *srcLen = 0;
590*f6dc9357SAndroid Build Coastguard Worker
591*f6dc9357SAndroid Build Coastguard Worker if (p->wasFinished)
592*f6dc9357SAndroid Build Coastguard Worker return p->res;
593*f6dc9357SAndroid Build Coastguard Worker
594*f6dc9357SAndroid Build Coastguard Worker p->status = CODER_STATUS_NOT_FINISHED;
595*f6dc9357SAndroid Build Coastguard Worker
596*f6dc9357SAndroid Build Coastguard Worker // if (p->SingleBufMode)
597*f6dc9357SAndroid Build Coastguard Worker if (p->outBuf)
598*f6dc9357SAndroid Build Coastguard Worker {
599*f6dc9357SAndroid Build Coastguard Worker SRes res;
600*f6dc9357SAndroid Build Coastguard Worker SizeT destLen2, srcLen2;
601*f6dc9357SAndroid Build Coastguard Worker int wasFinished;
602*f6dc9357SAndroid Build Coastguard Worker
603*f6dc9357SAndroid Build Coastguard Worker PRF_STR("------- MixCoder Single ----------")
604*f6dc9357SAndroid Build Coastguard Worker
605*f6dc9357SAndroid Build Coastguard Worker srcLen2 = srcLenOrig;
606*f6dc9357SAndroid Build Coastguard Worker destLen2 = destLenOrig;
607*f6dc9357SAndroid Build Coastguard Worker
608*f6dc9357SAndroid Build Coastguard Worker {
609*f6dc9357SAndroid Build Coastguard Worker IStateCoder *coder = &p->coders[0];
610*f6dc9357SAndroid Build Coastguard Worker res = coder->Code2(coder->p, NULL, &destLen2, src, &srcLen2, srcWasFinished, finishMode,
611*f6dc9357SAndroid Build Coastguard Worker // &wasFinished,
612*f6dc9357SAndroid Build Coastguard Worker &p->status);
613*f6dc9357SAndroid Build Coastguard Worker wasFinished = (p->status == CODER_STATUS_FINISHED_WITH_MARK);
614*f6dc9357SAndroid Build Coastguard Worker }
615*f6dc9357SAndroid Build Coastguard Worker
616*f6dc9357SAndroid Build Coastguard Worker p->res = res;
617*f6dc9357SAndroid Build Coastguard Worker
618*f6dc9357SAndroid Build Coastguard Worker /*
619*f6dc9357SAndroid Build Coastguard Worker if (wasFinished)
620*f6dc9357SAndroid Build Coastguard Worker p->status = CODER_STATUS_FINISHED_WITH_MARK;
621*f6dc9357SAndroid Build Coastguard Worker else
622*f6dc9357SAndroid Build Coastguard Worker {
623*f6dc9357SAndroid Build Coastguard Worker if (res == SZ_OK)
624*f6dc9357SAndroid Build Coastguard Worker if (destLen2 != destLenOrig)
625*f6dc9357SAndroid Build Coastguard Worker p->status = CODER_STATUS_NEEDS_MORE_INPUT;
626*f6dc9357SAndroid Build Coastguard Worker }
627*f6dc9357SAndroid Build Coastguard Worker */
628*f6dc9357SAndroid Build Coastguard Worker
629*f6dc9357SAndroid Build Coastguard Worker
630*f6dc9357SAndroid Build Coastguard Worker *srcLen = srcLen2;
631*f6dc9357SAndroid Build Coastguard Worker src += srcLen2;
632*f6dc9357SAndroid Build Coastguard Worker p->outWritten += destLen2;
633*f6dc9357SAndroid Build Coastguard Worker
634*f6dc9357SAndroid Build Coastguard Worker if (res != SZ_OK || srcWasFinished || wasFinished)
635*f6dc9357SAndroid Build Coastguard Worker p->wasFinished = True;
636*f6dc9357SAndroid Build Coastguard Worker
637*f6dc9357SAndroid Build Coastguard Worker if (p->numCoders == 1)
638*f6dc9357SAndroid Build Coastguard Worker *destLen = destLen2;
639*f6dc9357SAndroid Build Coastguard Worker else if (p->wasFinished)
640*f6dc9357SAndroid Build Coastguard Worker {
641*f6dc9357SAndroid Build Coastguard Worker unsigned i;
642*f6dc9357SAndroid Build Coastguard Worker size_t processed = p->outWritten;
643*f6dc9357SAndroid Build Coastguard Worker
644*f6dc9357SAndroid Build Coastguard Worker for (i = 1; i < p->numCoders; i++)
645*f6dc9357SAndroid Build Coastguard Worker {
646*f6dc9357SAndroid Build Coastguard Worker IStateCoder *coder = &p->coders[i];
647*f6dc9357SAndroid Build Coastguard Worker processed = coder->Filter(coder->p, p->outBuf, processed);
648*f6dc9357SAndroid Build Coastguard Worker if (wasFinished || (destFinish && p->outWritten == destLenOrig))
649*f6dc9357SAndroid Build Coastguard Worker processed = p->outWritten;
650*f6dc9357SAndroid Build Coastguard Worker PRF_STR_INT("filter", i)
651*f6dc9357SAndroid Build Coastguard Worker }
652*f6dc9357SAndroid Build Coastguard Worker *destLen = processed;
653*f6dc9357SAndroid Build Coastguard Worker }
654*f6dc9357SAndroid Build Coastguard Worker return res;
655*f6dc9357SAndroid Build Coastguard Worker }
656*f6dc9357SAndroid Build Coastguard Worker
657*f6dc9357SAndroid Build Coastguard Worker PRF_STR("standard mix")
658*f6dc9357SAndroid Build Coastguard Worker
659*f6dc9357SAndroid Build Coastguard Worker if (p->numCoders != 1)
660*f6dc9357SAndroid Build Coastguard Worker {
661*f6dc9357SAndroid Build Coastguard Worker if (!p->buf)
662*f6dc9357SAndroid Build Coastguard Worker {
663*f6dc9357SAndroid Build Coastguard Worker p->buf = (Byte *)ISzAlloc_Alloc(p->alloc, CODER_BUF_SIZE * (MIXCODER_NUM_FILTERS_MAX - 1));
664*f6dc9357SAndroid Build Coastguard Worker if (!p->buf)
665*f6dc9357SAndroid Build Coastguard Worker return SZ_ERROR_MEM;
666*f6dc9357SAndroid Build Coastguard Worker }
667*f6dc9357SAndroid Build Coastguard Worker
668*f6dc9357SAndroid Build Coastguard Worker finishMode = CODER_FINISH_ANY;
669*f6dc9357SAndroid Build Coastguard Worker }
670*f6dc9357SAndroid Build Coastguard Worker
671*f6dc9357SAndroid Build Coastguard Worker for (;;)
672*f6dc9357SAndroid Build Coastguard Worker {
673*f6dc9357SAndroid Build Coastguard Worker BoolInt processed = False;
674*f6dc9357SAndroid Build Coastguard Worker BoolInt allFinished = True;
675*f6dc9357SAndroid Build Coastguard Worker SRes resMain = SZ_OK;
676*f6dc9357SAndroid Build Coastguard Worker unsigned i;
677*f6dc9357SAndroid Build Coastguard Worker
678*f6dc9357SAndroid Build Coastguard Worker p->status = CODER_STATUS_NOT_FINISHED;
679*f6dc9357SAndroid Build Coastguard Worker /*
680*f6dc9357SAndroid Build Coastguard Worker if (p->numCoders == 1 && *destLen == destLenOrig && finishMode == LZMA_FINISH_ANY)
681*f6dc9357SAndroid Build Coastguard Worker break;
682*f6dc9357SAndroid Build Coastguard Worker */
683*f6dc9357SAndroid Build Coastguard Worker
684*f6dc9357SAndroid Build Coastguard Worker for (i = 0; i < p->numCoders; i++)
685*f6dc9357SAndroid Build Coastguard Worker {
686*f6dc9357SAndroid Build Coastguard Worker SRes res;
687*f6dc9357SAndroid Build Coastguard Worker IStateCoder *coder = &p->coders[i];
688*f6dc9357SAndroid Build Coastguard Worker Byte *dest2;
689*f6dc9357SAndroid Build Coastguard Worker SizeT destLen2, srcLen2; // destLen2_Orig;
690*f6dc9357SAndroid Build Coastguard Worker const Byte *src2;
691*f6dc9357SAndroid Build Coastguard Worker int srcFinished2;
692*f6dc9357SAndroid Build Coastguard Worker int encodingWasFinished;
693*f6dc9357SAndroid Build Coastguard Worker ECoderStatus status2;
694*f6dc9357SAndroid Build Coastguard Worker
695*f6dc9357SAndroid Build Coastguard Worker if (i == 0)
696*f6dc9357SAndroid Build Coastguard Worker {
697*f6dc9357SAndroid Build Coastguard Worker src2 = src;
698*f6dc9357SAndroid Build Coastguard Worker srcLen2 = srcLenOrig - *srcLen;
699*f6dc9357SAndroid Build Coastguard Worker srcFinished2 = srcWasFinished;
700*f6dc9357SAndroid Build Coastguard Worker }
701*f6dc9357SAndroid Build Coastguard Worker else
702*f6dc9357SAndroid Build Coastguard Worker {
703*f6dc9357SAndroid Build Coastguard Worker size_t k = i - 1;
704*f6dc9357SAndroid Build Coastguard Worker src2 = p->buf + (CODER_BUF_SIZE * k) + p->pos[k];
705*f6dc9357SAndroid Build Coastguard Worker srcLen2 = p->size[k] - p->pos[k];
706*f6dc9357SAndroid Build Coastguard Worker srcFinished2 = p->finished[k];
707*f6dc9357SAndroid Build Coastguard Worker }
708*f6dc9357SAndroid Build Coastguard Worker
709*f6dc9357SAndroid Build Coastguard Worker if (i == p->numCoders - 1)
710*f6dc9357SAndroid Build Coastguard Worker {
711*f6dc9357SAndroid Build Coastguard Worker dest2 = dest;
712*f6dc9357SAndroid Build Coastguard Worker destLen2 = destLenOrig - *destLen;
713*f6dc9357SAndroid Build Coastguard Worker }
714*f6dc9357SAndroid Build Coastguard Worker else
715*f6dc9357SAndroid Build Coastguard Worker {
716*f6dc9357SAndroid Build Coastguard Worker if (p->pos[i] != p->size[i])
717*f6dc9357SAndroid Build Coastguard Worker continue;
718*f6dc9357SAndroid Build Coastguard Worker dest2 = p->buf + (CODER_BUF_SIZE * i);
719*f6dc9357SAndroid Build Coastguard Worker destLen2 = CODER_BUF_SIZE;
720*f6dc9357SAndroid Build Coastguard Worker }
721*f6dc9357SAndroid Build Coastguard Worker
722*f6dc9357SAndroid Build Coastguard Worker // destLen2_Orig = destLen2;
723*f6dc9357SAndroid Build Coastguard Worker
724*f6dc9357SAndroid Build Coastguard Worker if (p->results[i] != SZ_OK)
725*f6dc9357SAndroid Build Coastguard Worker {
726*f6dc9357SAndroid Build Coastguard Worker if (resMain == SZ_OK)
727*f6dc9357SAndroid Build Coastguard Worker resMain = p->results[i];
728*f6dc9357SAndroid Build Coastguard Worker continue;
729*f6dc9357SAndroid Build Coastguard Worker }
730*f6dc9357SAndroid Build Coastguard Worker
731*f6dc9357SAndroid Build Coastguard Worker res = coder->Code2(coder->p,
732*f6dc9357SAndroid Build Coastguard Worker dest2, &destLen2,
733*f6dc9357SAndroid Build Coastguard Worker src2, &srcLen2, srcFinished2,
734*f6dc9357SAndroid Build Coastguard Worker finishMode,
735*f6dc9357SAndroid Build Coastguard Worker // &encodingWasFinished,
736*f6dc9357SAndroid Build Coastguard Worker &status2);
737*f6dc9357SAndroid Build Coastguard Worker
738*f6dc9357SAndroid Build Coastguard Worker if (res != SZ_OK)
739*f6dc9357SAndroid Build Coastguard Worker {
740*f6dc9357SAndroid Build Coastguard Worker p->results[i] = res;
741*f6dc9357SAndroid Build Coastguard Worker if (resMain == SZ_OK)
742*f6dc9357SAndroid Build Coastguard Worker resMain = res;
743*f6dc9357SAndroid Build Coastguard Worker }
744*f6dc9357SAndroid Build Coastguard Worker
745*f6dc9357SAndroid Build Coastguard Worker encodingWasFinished = (status2 == CODER_STATUS_FINISHED_WITH_MARK);
746*f6dc9357SAndroid Build Coastguard Worker
747*f6dc9357SAndroid Build Coastguard Worker if (!encodingWasFinished)
748*f6dc9357SAndroid Build Coastguard Worker {
749*f6dc9357SAndroid Build Coastguard Worker allFinished = False;
750*f6dc9357SAndroid Build Coastguard Worker if (p->numCoders == 1 && res == SZ_OK)
751*f6dc9357SAndroid Build Coastguard Worker p->status = status2;
752*f6dc9357SAndroid Build Coastguard Worker }
753*f6dc9357SAndroid Build Coastguard Worker
754*f6dc9357SAndroid Build Coastguard Worker if (i == 0)
755*f6dc9357SAndroid Build Coastguard Worker {
756*f6dc9357SAndroid Build Coastguard Worker *srcLen += srcLen2;
757*f6dc9357SAndroid Build Coastguard Worker src += srcLen2;
758*f6dc9357SAndroid Build Coastguard Worker }
759*f6dc9357SAndroid Build Coastguard Worker else
760*f6dc9357SAndroid Build Coastguard Worker p->pos[(size_t)i - 1] += srcLen2;
761*f6dc9357SAndroid Build Coastguard Worker
762*f6dc9357SAndroid Build Coastguard Worker if (i == p->numCoders - 1)
763*f6dc9357SAndroid Build Coastguard Worker {
764*f6dc9357SAndroid Build Coastguard Worker *destLen += destLen2;
765*f6dc9357SAndroid Build Coastguard Worker dest += destLen2;
766*f6dc9357SAndroid Build Coastguard Worker }
767*f6dc9357SAndroid Build Coastguard Worker else
768*f6dc9357SAndroid Build Coastguard Worker {
769*f6dc9357SAndroid Build Coastguard Worker p->size[i] = destLen2;
770*f6dc9357SAndroid Build Coastguard Worker p->pos[i] = 0;
771*f6dc9357SAndroid Build Coastguard Worker p->finished[i] = encodingWasFinished;
772*f6dc9357SAndroid Build Coastguard Worker }
773*f6dc9357SAndroid Build Coastguard Worker
774*f6dc9357SAndroid Build Coastguard Worker if (destLen2 != 0 || srcLen2 != 0)
775*f6dc9357SAndroid Build Coastguard Worker processed = True;
776*f6dc9357SAndroid Build Coastguard Worker }
777*f6dc9357SAndroid Build Coastguard Worker
778*f6dc9357SAndroid Build Coastguard Worker if (!processed)
779*f6dc9357SAndroid Build Coastguard Worker {
780*f6dc9357SAndroid Build Coastguard Worker if (allFinished)
781*f6dc9357SAndroid Build Coastguard Worker p->status = CODER_STATUS_FINISHED_WITH_MARK;
782*f6dc9357SAndroid Build Coastguard Worker return resMain;
783*f6dc9357SAndroid Build Coastguard Worker }
784*f6dc9357SAndroid Build Coastguard Worker }
785*f6dc9357SAndroid Build Coastguard Worker }
786*f6dc9357SAndroid Build Coastguard Worker
787*f6dc9357SAndroid Build Coastguard Worker
Xz_ParseHeader(CXzStreamFlags * p,const Byte * buf)788*f6dc9357SAndroid Build Coastguard Worker SRes Xz_ParseHeader(CXzStreamFlags *p, const Byte *buf)
789*f6dc9357SAndroid Build Coastguard Worker {
790*f6dc9357SAndroid Build Coastguard Worker *p = (CXzStreamFlags)GetBe16(buf + XZ_SIG_SIZE);
791*f6dc9357SAndroid Build Coastguard Worker if (CrcCalc(buf + XZ_SIG_SIZE, XZ_STREAM_FLAGS_SIZE) !=
792*f6dc9357SAndroid Build Coastguard Worker GetUi32(buf + XZ_SIG_SIZE + XZ_STREAM_FLAGS_SIZE))
793*f6dc9357SAndroid Build Coastguard Worker return SZ_ERROR_NO_ARCHIVE;
794*f6dc9357SAndroid Build Coastguard Worker return XzFlags_IsSupported(*p) ? SZ_OK : SZ_ERROR_UNSUPPORTED;
795*f6dc9357SAndroid Build Coastguard Worker }
796*f6dc9357SAndroid Build Coastguard Worker
Xz_CheckFooter(CXzStreamFlags flags,UInt64 indexSize,const Byte * buf)797*f6dc9357SAndroid Build Coastguard Worker static BoolInt Xz_CheckFooter(CXzStreamFlags flags, UInt64 indexSize, const Byte *buf)
798*f6dc9357SAndroid Build Coastguard Worker {
799*f6dc9357SAndroid Build Coastguard Worker return indexSize == (((UInt64)GetUi32(buf + 4) + 1) << 2)
800*f6dc9357SAndroid Build Coastguard Worker && GetUi32(buf) == CrcCalc(buf + 4, 6)
801*f6dc9357SAndroid Build Coastguard Worker && flags == GetBe16(buf + 8)
802*f6dc9357SAndroid Build Coastguard Worker && buf[10] == XZ_FOOTER_SIG_0
803*f6dc9357SAndroid Build Coastguard Worker && buf[11] == XZ_FOOTER_SIG_1;
804*f6dc9357SAndroid Build Coastguard Worker }
805*f6dc9357SAndroid Build Coastguard Worker
806*f6dc9357SAndroid Build Coastguard Worker #define READ_VARINT_AND_CHECK(buf, pos, size, res) \
807*f6dc9357SAndroid Build Coastguard Worker { const unsigned s = Xz_ReadVarInt(buf + pos, size - pos, res); \
808*f6dc9357SAndroid Build Coastguard Worker if (s == 0) return SZ_ERROR_ARCHIVE; \
809*f6dc9357SAndroid Build Coastguard Worker pos += s; }
810*f6dc9357SAndroid Build Coastguard Worker
811*f6dc9357SAndroid Build Coastguard Worker
XzBlock_AreSupportedFilters(const CXzBlock * p)812*f6dc9357SAndroid Build Coastguard Worker static BoolInt XzBlock_AreSupportedFilters(const CXzBlock *p)
813*f6dc9357SAndroid Build Coastguard Worker {
814*f6dc9357SAndroid Build Coastguard Worker const unsigned numFilters = XzBlock_GetNumFilters(p) - 1;
815*f6dc9357SAndroid Build Coastguard Worker unsigned i;
816*f6dc9357SAndroid Build Coastguard Worker {
817*f6dc9357SAndroid Build Coastguard Worker const CXzFilter *f = &p->filters[numFilters];
818*f6dc9357SAndroid Build Coastguard Worker if (f->id != XZ_ID_LZMA2 || f->propsSize != 1 || f->props[0] > 40)
819*f6dc9357SAndroid Build Coastguard Worker return False;
820*f6dc9357SAndroid Build Coastguard Worker }
821*f6dc9357SAndroid Build Coastguard Worker
822*f6dc9357SAndroid Build Coastguard Worker for (i = 0; i < numFilters; i++)
823*f6dc9357SAndroid Build Coastguard Worker {
824*f6dc9357SAndroid Build Coastguard Worker const CXzFilter *f = &p->filters[i];
825*f6dc9357SAndroid Build Coastguard Worker if (f->id == XZ_ID_Delta)
826*f6dc9357SAndroid Build Coastguard Worker {
827*f6dc9357SAndroid Build Coastguard Worker if (f->propsSize != 1)
828*f6dc9357SAndroid Build Coastguard Worker return False;
829*f6dc9357SAndroid Build Coastguard Worker }
830*f6dc9357SAndroid Build Coastguard Worker else if (!XZ_IS_SUPPORTED_FILTER_ID(f->id)
831*f6dc9357SAndroid Build Coastguard Worker || (f->propsSize != 0 && f->propsSize != 4))
832*f6dc9357SAndroid Build Coastguard Worker return False;
833*f6dc9357SAndroid Build Coastguard Worker }
834*f6dc9357SAndroid Build Coastguard Worker return True;
835*f6dc9357SAndroid Build Coastguard Worker }
836*f6dc9357SAndroid Build Coastguard Worker
837*f6dc9357SAndroid Build Coastguard Worker
XzBlock_Parse(CXzBlock * p,const Byte * header)838*f6dc9357SAndroid Build Coastguard Worker SRes XzBlock_Parse(CXzBlock *p, const Byte *header)
839*f6dc9357SAndroid Build Coastguard Worker {
840*f6dc9357SAndroid Build Coastguard Worker unsigned pos;
841*f6dc9357SAndroid Build Coastguard Worker unsigned numFilters, i;
842*f6dc9357SAndroid Build Coastguard Worker unsigned headerSize = (unsigned)header[0] << 2;
843*f6dc9357SAndroid Build Coastguard Worker
844*f6dc9357SAndroid Build Coastguard Worker /* (headerSize != 0) : another code checks */
845*f6dc9357SAndroid Build Coastguard Worker
846*f6dc9357SAndroid Build Coastguard Worker if (CrcCalc(header, headerSize) != GetUi32(header + headerSize))
847*f6dc9357SAndroid Build Coastguard Worker return SZ_ERROR_ARCHIVE;
848*f6dc9357SAndroid Build Coastguard Worker
849*f6dc9357SAndroid Build Coastguard Worker pos = 1;
850*f6dc9357SAndroid Build Coastguard Worker p->flags = header[pos++];
851*f6dc9357SAndroid Build Coastguard Worker
852*f6dc9357SAndroid Build Coastguard Worker p->packSize = (UInt64)(Int64)-1;
853*f6dc9357SAndroid Build Coastguard Worker if (XzBlock_HasPackSize(p))
854*f6dc9357SAndroid Build Coastguard Worker {
855*f6dc9357SAndroid Build Coastguard Worker READ_VARINT_AND_CHECK(header, pos, headerSize, &p->packSize)
856*f6dc9357SAndroid Build Coastguard Worker if (p->packSize == 0 || p->packSize + headerSize >= (UInt64)1 << 63)
857*f6dc9357SAndroid Build Coastguard Worker return SZ_ERROR_ARCHIVE;
858*f6dc9357SAndroid Build Coastguard Worker }
859*f6dc9357SAndroid Build Coastguard Worker
860*f6dc9357SAndroid Build Coastguard Worker p->unpackSize = (UInt64)(Int64)-1;
861*f6dc9357SAndroid Build Coastguard Worker if (XzBlock_HasUnpackSize(p))
862*f6dc9357SAndroid Build Coastguard Worker {
863*f6dc9357SAndroid Build Coastguard Worker READ_VARINT_AND_CHECK(header, pos, headerSize, &p->unpackSize)
864*f6dc9357SAndroid Build Coastguard Worker }
865*f6dc9357SAndroid Build Coastguard Worker
866*f6dc9357SAndroid Build Coastguard Worker numFilters = XzBlock_GetNumFilters(p);
867*f6dc9357SAndroid Build Coastguard Worker for (i = 0; i < numFilters; i++)
868*f6dc9357SAndroid Build Coastguard Worker {
869*f6dc9357SAndroid Build Coastguard Worker CXzFilter *filter = p->filters + i;
870*f6dc9357SAndroid Build Coastguard Worker UInt64 size;
871*f6dc9357SAndroid Build Coastguard Worker READ_VARINT_AND_CHECK(header, pos, headerSize, &filter->id)
872*f6dc9357SAndroid Build Coastguard Worker READ_VARINT_AND_CHECK(header, pos, headerSize, &size)
873*f6dc9357SAndroid Build Coastguard Worker if (size > headerSize - pos || size > XZ_FILTER_PROPS_SIZE_MAX)
874*f6dc9357SAndroid Build Coastguard Worker return SZ_ERROR_ARCHIVE;
875*f6dc9357SAndroid Build Coastguard Worker filter->propsSize = (UInt32)size;
876*f6dc9357SAndroid Build Coastguard Worker memcpy(filter->props, header + pos, (size_t)size);
877*f6dc9357SAndroid Build Coastguard Worker pos += (unsigned)size;
878*f6dc9357SAndroid Build Coastguard Worker
879*f6dc9357SAndroid Build Coastguard Worker #ifdef XZ_DUMP
880*f6dc9357SAndroid Build Coastguard Worker printf("\nf[%u] = %2X: ", i, (unsigned)filter->id);
881*f6dc9357SAndroid Build Coastguard Worker {
882*f6dc9357SAndroid Build Coastguard Worker unsigned i;
883*f6dc9357SAndroid Build Coastguard Worker for (i = 0; i < size; i++)
884*f6dc9357SAndroid Build Coastguard Worker printf(" %2X", filter->props[i]);
885*f6dc9357SAndroid Build Coastguard Worker }
886*f6dc9357SAndroid Build Coastguard Worker #endif
887*f6dc9357SAndroid Build Coastguard Worker }
888*f6dc9357SAndroid Build Coastguard Worker
889*f6dc9357SAndroid Build Coastguard Worker if (XzBlock_HasUnsupportedFlags(p))
890*f6dc9357SAndroid Build Coastguard Worker return SZ_ERROR_UNSUPPORTED;
891*f6dc9357SAndroid Build Coastguard Worker
892*f6dc9357SAndroid Build Coastguard Worker while (pos < headerSize)
893*f6dc9357SAndroid Build Coastguard Worker if (header[pos++] != 0)
894*f6dc9357SAndroid Build Coastguard Worker return SZ_ERROR_ARCHIVE;
895*f6dc9357SAndroid Build Coastguard Worker return SZ_OK;
896*f6dc9357SAndroid Build Coastguard Worker }
897*f6dc9357SAndroid Build Coastguard Worker
898*f6dc9357SAndroid Build Coastguard Worker
899*f6dc9357SAndroid Build Coastguard Worker
900*f6dc9357SAndroid Build Coastguard Worker
XzDecMix_Init(CMixCoder * p,const CXzBlock * block,Byte * outBuf,size_t outBufSize)901*f6dc9357SAndroid Build Coastguard Worker static SRes XzDecMix_Init(CMixCoder *p, const CXzBlock *block, Byte *outBuf, size_t outBufSize)
902*f6dc9357SAndroid Build Coastguard Worker {
903*f6dc9357SAndroid Build Coastguard Worker unsigned i;
904*f6dc9357SAndroid Build Coastguard Worker BoolInt needReInit = True;
905*f6dc9357SAndroid Build Coastguard Worker unsigned numFilters = XzBlock_GetNumFilters(block);
906*f6dc9357SAndroid Build Coastguard Worker
907*f6dc9357SAndroid Build Coastguard Worker if (numFilters == p->numCoders && ((p->outBuf && outBuf) || (!p->outBuf && !outBuf)))
908*f6dc9357SAndroid Build Coastguard Worker {
909*f6dc9357SAndroid Build Coastguard Worker needReInit = False;
910*f6dc9357SAndroid Build Coastguard Worker for (i = 0; i < numFilters; i++)
911*f6dc9357SAndroid Build Coastguard Worker if (p->ids[i] != block->filters[numFilters - 1 - i].id)
912*f6dc9357SAndroid Build Coastguard Worker {
913*f6dc9357SAndroid Build Coastguard Worker needReInit = True;
914*f6dc9357SAndroid Build Coastguard Worker break;
915*f6dc9357SAndroid Build Coastguard Worker }
916*f6dc9357SAndroid Build Coastguard Worker }
917*f6dc9357SAndroid Build Coastguard Worker
918*f6dc9357SAndroid Build Coastguard Worker // p->SingleBufMode = (outBuf != NULL);
919*f6dc9357SAndroid Build Coastguard Worker p->outBuf = outBuf;
920*f6dc9357SAndroid Build Coastguard Worker p->outBufSize = outBufSize;
921*f6dc9357SAndroid Build Coastguard Worker
922*f6dc9357SAndroid Build Coastguard Worker // p->SingleBufMode = False;
923*f6dc9357SAndroid Build Coastguard Worker // outBuf = NULL;
924*f6dc9357SAndroid Build Coastguard Worker
925*f6dc9357SAndroid Build Coastguard Worker if (needReInit)
926*f6dc9357SAndroid Build Coastguard Worker {
927*f6dc9357SAndroid Build Coastguard Worker MixCoder_Free(p);
928*f6dc9357SAndroid Build Coastguard Worker for (i = 0; i < numFilters; i++)
929*f6dc9357SAndroid Build Coastguard Worker {
930*f6dc9357SAndroid Build Coastguard Worker RINOK(MixCoder_SetFromMethod(p, i, block->filters[numFilters - 1 - i].id, outBuf, outBufSize))
931*f6dc9357SAndroid Build Coastguard Worker }
932*f6dc9357SAndroid Build Coastguard Worker p->numCoders = numFilters;
933*f6dc9357SAndroid Build Coastguard Worker }
934*f6dc9357SAndroid Build Coastguard Worker else
935*f6dc9357SAndroid Build Coastguard Worker {
936*f6dc9357SAndroid Build Coastguard Worker RINOK(MixCoder_ResetFromMethod(p, 0, block->filters[numFilters - 1].id, outBuf, outBufSize))
937*f6dc9357SAndroid Build Coastguard Worker }
938*f6dc9357SAndroid Build Coastguard Worker
939*f6dc9357SAndroid Build Coastguard Worker for (i = 0; i < numFilters; i++)
940*f6dc9357SAndroid Build Coastguard Worker {
941*f6dc9357SAndroid Build Coastguard Worker const CXzFilter *f = &block->filters[numFilters - 1 - i];
942*f6dc9357SAndroid Build Coastguard Worker IStateCoder *sc = &p->coders[i];
943*f6dc9357SAndroid Build Coastguard Worker RINOK(sc->SetProps(sc->p, f->props, f->propsSize, p->alloc))
944*f6dc9357SAndroid Build Coastguard Worker }
945*f6dc9357SAndroid Build Coastguard Worker
946*f6dc9357SAndroid Build Coastguard Worker MixCoder_Init(p);
947*f6dc9357SAndroid Build Coastguard Worker return SZ_OK;
948*f6dc9357SAndroid Build Coastguard Worker }
949*f6dc9357SAndroid Build Coastguard Worker
950*f6dc9357SAndroid Build Coastguard Worker
951*f6dc9357SAndroid Build Coastguard Worker
XzUnpacker_Init(CXzUnpacker * p)952*f6dc9357SAndroid Build Coastguard Worker void XzUnpacker_Init(CXzUnpacker *p)
953*f6dc9357SAndroid Build Coastguard Worker {
954*f6dc9357SAndroid Build Coastguard Worker p->state = XZ_STATE_STREAM_HEADER;
955*f6dc9357SAndroid Build Coastguard Worker p->pos = 0;
956*f6dc9357SAndroid Build Coastguard Worker p->numStartedStreams = 0;
957*f6dc9357SAndroid Build Coastguard Worker p->numFinishedStreams = 0;
958*f6dc9357SAndroid Build Coastguard Worker p->numTotalBlocks = 0;
959*f6dc9357SAndroid Build Coastguard Worker p->padSize = 0;
960*f6dc9357SAndroid Build Coastguard Worker p->decodeOnlyOneBlock = 0;
961*f6dc9357SAndroid Build Coastguard Worker
962*f6dc9357SAndroid Build Coastguard Worker p->parseMode = False;
963*f6dc9357SAndroid Build Coastguard Worker p->decodeToStreamSignature = False;
964*f6dc9357SAndroid Build Coastguard Worker
965*f6dc9357SAndroid Build Coastguard Worker // p->outBuf = NULL;
966*f6dc9357SAndroid Build Coastguard Worker // p->outBufSize = 0;
967*f6dc9357SAndroid Build Coastguard Worker p->outDataWritten = 0;
968*f6dc9357SAndroid Build Coastguard Worker }
969*f6dc9357SAndroid Build Coastguard Worker
970*f6dc9357SAndroid Build Coastguard Worker
XzUnpacker_SetOutBuf(CXzUnpacker * p,Byte * outBuf,size_t outBufSize)971*f6dc9357SAndroid Build Coastguard Worker void XzUnpacker_SetOutBuf(CXzUnpacker *p, Byte *outBuf, size_t outBufSize)
972*f6dc9357SAndroid Build Coastguard Worker {
973*f6dc9357SAndroid Build Coastguard Worker p->outBuf = outBuf;
974*f6dc9357SAndroid Build Coastguard Worker p->outBufSize = outBufSize;
975*f6dc9357SAndroid Build Coastguard Worker }
976*f6dc9357SAndroid Build Coastguard Worker
977*f6dc9357SAndroid Build Coastguard Worker
XzUnpacker_Construct(CXzUnpacker * p,ISzAllocPtr alloc)978*f6dc9357SAndroid Build Coastguard Worker void XzUnpacker_Construct(CXzUnpacker *p, ISzAllocPtr alloc)
979*f6dc9357SAndroid Build Coastguard Worker {
980*f6dc9357SAndroid Build Coastguard Worker MixCoder_Construct(&p->decoder, alloc);
981*f6dc9357SAndroid Build Coastguard Worker p->outBuf = NULL;
982*f6dc9357SAndroid Build Coastguard Worker p->outBufSize = 0;
983*f6dc9357SAndroid Build Coastguard Worker XzUnpacker_Init(p);
984*f6dc9357SAndroid Build Coastguard Worker }
985*f6dc9357SAndroid Build Coastguard Worker
986*f6dc9357SAndroid Build Coastguard Worker
XzUnpacker_Free(CXzUnpacker * p)987*f6dc9357SAndroid Build Coastguard Worker void XzUnpacker_Free(CXzUnpacker *p)
988*f6dc9357SAndroid Build Coastguard Worker {
989*f6dc9357SAndroid Build Coastguard Worker MixCoder_Free(&p->decoder);
990*f6dc9357SAndroid Build Coastguard Worker }
991*f6dc9357SAndroid Build Coastguard Worker
992*f6dc9357SAndroid Build Coastguard Worker
XzUnpacker_PrepareToRandomBlockDecoding(CXzUnpacker * p)993*f6dc9357SAndroid Build Coastguard Worker void XzUnpacker_PrepareToRandomBlockDecoding(CXzUnpacker *p)
994*f6dc9357SAndroid Build Coastguard Worker {
995*f6dc9357SAndroid Build Coastguard Worker p->indexSize = 0;
996*f6dc9357SAndroid Build Coastguard Worker p->numBlocks = 0;
997*f6dc9357SAndroid Build Coastguard Worker Sha256_Init(&p->sha);
998*f6dc9357SAndroid Build Coastguard Worker p->state = XZ_STATE_BLOCK_HEADER;
999*f6dc9357SAndroid Build Coastguard Worker p->pos = 0;
1000*f6dc9357SAndroid Build Coastguard Worker p->decodeOnlyOneBlock = 1;
1001*f6dc9357SAndroid Build Coastguard Worker }
1002*f6dc9357SAndroid Build Coastguard Worker
1003*f6dc9357SAndroid Build Coastguard Worker
XzUnpacker_UpdateIndex(CXzUnpacker * p,UInt64 packSize,UInt64 unpackSize)1004*f6dc9357SAndroid Build Coastguard Worker static void XzUnpacker_UpdateIndex(CXzUnpacker *p, UInt64 packSize, UInt64 unpackSize)
1005*f6dc9357SAndroid Build Coastguard Worker {
1006*f6dc9357SAndroid Build Coastguard Worker Byte temp[32];
1007*f6dc9357SAndroid Build Coastguard Worker unsigned num = Xz_WriteVarInt(temp, packSize);
1008*f6dc9357SAndroid Build Coastguard Worker num += Xz_WriteVarInt(temp + num, unpackSize);
1009*f6dc9357SAndroid Build Coastguard Worker Sha256_Update(&p->sha, temp, num);
1010*f6dc9357SAndroid Build Coastguard Worker p->indexSize += num;
1011*f6dc9357SAndroid Build Coastguard Worker p->numBlocks++;
1012*f6dc9357SAndroid Build Coastguard Worker }
1013*f6dc9357SAndroid Build Coastguard Worker
1014*f6dc9357SAndroid Build Coastguard Worker
1015*f6dc9357SAndroid Build Coastguard Worker
XzUnpacker_Code(CXzUnpacker * p,Byte * dest,SizeT * destLen,const Byte * src,SizeT * srcLen,int srcFinished,ECoderFinishMode finishMode,ECoderStatus * status)1016*f6dc9357SAndroid Build Coastguard Worker SRes XzUnpacker_Code(CXzUnpacker *p, Byte *dest, SizeT *destLen,
1017*f6dc9357SAndroid Build Coastguard Worker const Byte *src, SizeT *srcLen, int srcFinished,
1018*f6dc9357SAndroid Build Coastguard Worker ECoderFinishMode finishMode, ECoderStatus *status)
1019*f6dc9357SAndroid Build Coastguard Worker {
1020*f6dc9357SAndroid Build Coastguard Worker SizeT destLenOrig = *destLen;
1021*f6dc9357SAndroid Build Coastguard Worker SizeT srcLenOrig = *srcLen;
1022*f6dc9357SAndroid Build Coastguard Worker *destLen = 0;
1023*f6dc9357SAndroid Build Coastguard Worker *srcLen = 0;
1024*f6dc9357SAndroid Build Coastguard Worker *status = CODER_STATUS_NOT_SPECIFIED;
1025*f6dc9357SAndroid Build Coastguard Worker
1026*f6dc9357SAndroid Build Coastguard Worker for (;;)
1027*f6dc9357SAndroid Build Coastguard Worker {
1028*f6dc9357SAndroid Build Coastguard Worker SizeT srcRem;
1029*f6dc9357SAndroid Build Coastguard Worker
1030*f6dc9357SAndroid Build Coastguard Worker if (p->state == XZ_STATE_BLOCK)
1031*f6dc9357SAndroid Build Coastguard Worker {
1032*f6dc9357SAndroid Build Coastguard Worker SizeT destLen2 = destLenOrig - *destLen;
1033*f6dc9357SAndroid Build Coastguard Worker SizeT srcLen2 = srcLenOrig - *srcLen;
1034*f6dc9357SAndroid Build Coastguard Worker SRes res;
1035*f6dc9357SAndroid Build Coastguard Worker
1036*f6dc9357SAndroid Build Coastguard Worker ECoderFinishMode finishMode2 = finishMode;
1037*f6dc9357SAndroid Build Coastguard Worker BoolInt srcFinished2 = (BoolInt)srcFinished;
1038*f6dc9357SAndroid Build Coastguard Worker BoolInt destFinish = False;
1039*f6dc9357SAndroid Build Coastguard Worker
1040*f6dc9357SAndroid Build Coastguard Worker if (p->block.packSize != (UInt64)(Int64)-1)
1041*f6dc9357SAndroid Build Coastguard Worker {
1042*f6dc9357SAndroid Build Coastguard Worker UInt64 rem = p->block.packSize - p->packSize;
1043*f6dc9357SAndroid Build Coastguard Worker if (srcLen2 >= rem)
1044*f6dc9357SAndroid Build Coastguard Worker {
1045*f6dc9357SAndroid Build Coastguard Worker srcFinished2 = True;
1046*f6dc9357SAndroid Build Coastguard Worker srcLen2 = (SizeT)rem;
1047*f6dc9357SAndroid Build Coastguard Worker }
1048*f6dc9357SAndroid Build Coastguard Worker if (rem == 0 && p->block.unpackSize == p->unpackSize)
1049*f6dc9357SAndroid Build Coastguard Worker return SZ_ERROR_DATA;
1050*f6dc9357SAndroid Build Coastguard Worker }
1051*f6dc9357SAndroid Build Coastguard Worker
1052*f6dc9357SAndroid Build Coastguard Worker if (p->block.unpackSize != (UInt64)(Int64)-1)
1053*f6dc9357SAndroid Build Coastguard Worker {
1054*f6dc9357SAndroid Build Coastguard Worker UInt64 rem = p->block.unpackSize - p->unpackSize;
1055*f6dc9357SAndroid Build Coastguard Worker if (destLen2 >= rem)
1056*f6dc9357SAndroid Build Coastguard Worker {
1057*f6dc9357SAndroid Build Coastguard Worker destFinish = True;
1058*f6dc9357SAndroid Build Coastguard Worker finishMode2 = CODER_FINISH_END;
1059*f6dc9357SAndroid Build Coastguard Worker destLen2 = (SizeT)rem;
1060*f6dc9357SAndroid Build Coastguard Worker }
1061*f6dc9357SAndroid Build Coastguard Worker }
1062*f6dc9357SAndroid Build Coastguard Worker
1063*f6dc9357SAndroid Build Coastguard Worker /*
1064*f6dc9357SAndroid Build Coastguard Worker if (srcLen2 == 0 && destLen2 == 0)
1065*f6dc9357SAndroid Build Coastguard Worker {
1066*f6dc9357SAndroid Build Coastguard Worker *status = CODER_STATUS_NOT_FINISHED;
1067*f6dc9357SAndroid Build Coastguard Worker return SZ_OK;
1068*f6dc9357SAndroid Build Coastguard Worker }
1069*f6dc9357SAndroid Build Coastguard Worker */
1070*f6dc9357SAndroid Build Coastguard Worker
1071*f6dc9357SAndroid Build Coastguard Worker {
1072*f6dc9357SAndroid Build Coastguard Worker res = MixCoder_Code(&p->decoder,
1073*f6dc9357SAndroid Build Coastguard Worker (p->outBuf ? NULL : dest), &destLen2, destFinish,
1074*f6dc9357SAndroid Build Coastguard Worker src, &srcLen2, srcFinished2,
1075*f6dc9357SAndroid Build Coastguard Worker finishMode2);
1076*f6dc9357SAndroid Build Coastguard Worker
1077*f6dc9357SAndroid Build Coastguard Worker *status = p->decoder.status;
1078*f6dc9357SAndroid Build Coastguard Worker XzCheck_Update(&p->check, (p->outBuf ? p->outBuf + p->outDataWritten : dest), destLen2);
1079*f6dc9357SAndroid Build Coastguard Worker if (!p->outBuf)
1080*f6dc9357SAndroid Build Coastguard Worker dest += destLen2;
1081*f6dc9357SAndroid Build Coastguard Worker p->outDataWritten += destLen2;
1082*f6dc9357SAndroid Build Coastguard Worker }
1083*f6dc9357SAndroid Build Coastguard Worker
1084*f6dc9357SAndroid Build Coastguard Worker (*srcLen) += srcLen2;
1085*f6dc9357SAndroid Build Coastguard Worker src += srcLen2;
1086*f6dc9357SAndroid Build Coastguard Worker p->packSize += srcLen2;
1087*f6dc9357SAndroid Build Coastguard Worker (*destLen) += destLen2;
1088*f6dc9357SAndroid Build Coastguard Worker p->unpackSize += destLen2;
1089*f6dc9357SAndroid Build Coastguard Worker
1090*f6dc9357SAndroid Build Coastguard Worker RINOK(res)
1091*f6dc9357SAndroid Build Coastguard Worker
1092*f6dc9357SAndroid Build Coastguard Worker if (*status != CODER_STATUS_FINISHED_WITH_MARK)
1093*f6dc9357SAndroid Build Coastguard Worker {
1094*f6dc9357SAndroid Build Coastguard Worker if (p->block.packSize == p->packSize
1095*f6dc9357SAndroid Build Coastguard Worker && *status == CODER_STATUS_NEEDS_MORE_INPUT)
1096*f6dc9357SAndroid Build Coastguard Worker {
1097*f6dc9357SAndroid Build Coastguard Worker PRF_STR("CODER_STATUS_NEEDS_MORE_INPUT")
1098*f6dc9357SAndroid Build Coastguard Worker *status = CODER_STATUS_NOT_SPECIFIED;
1099*f6dc9357SAndroid Build Coastguard Worker return SZ_ERROR_DATA;
1100*f6dc9357SAndroid Build Coastguard Worker }
1101*f6dc9357SAndroid Build Coastguard Worker
1102*f6dc9357SAndroid Build Coastguard Worker return SZ_OK;
1103*f6dc9357SAndroid Build Coastguard Worker }
1104*f6dc9357SAndroid Build Coastguard Worker {
1105*f6dc9357SAndroid Build Coastguard Worker XzUnpacker_UpdateIndex(p, XzUnpacker_GetPackSizeForIndex(p), p->unpackSize);
1106*f6dc9357SAndroid Build Coastguard Worker p->state = XZ_STATE_BLOCK_FOOTER;
1107*f6dc9357SAndroid Build Coastguard Worker p->pos = 0;
1108*f6dc9357SAndroid Build Coastguard Worker p->alignPos = 0;
1109*f6dc9357SAndroid Build Coastguard Worker *status = CODER_STATUS_NOT_SPECIFIED;
1110*f6dc9357SAndroid Build Coastguard Worker
1111*f6dc9357SAndroid Build Coastguard Worker if ((p->block.packSize != (UInt64)(Int64)-1 && p->block.packSize != p->packSize)
1112*f6dc9357SAndroid Build Coastguard Worker || (p->block.unpackSize != (UInt64)(Int64)-1 && p->block.unpackSize != p->unpackSize))
1113*f6dc9357SAndroid Build Coastguard Worker {
1114*f6dc9357SAndroid Build Coastguard Worker PRF_STR("ERROR: block.size mismatch")
1115*f6dc9357SAndroid Build Coastguard Worker return SZ_ERROR_DATA;
1116*f6dc9357SAndroid Build Coastguard Worker }
1117*f6dc9357SAndroid Build Coastguard Worker }
1118*f6dc9357SAndroid Build Coastguard Worker // continue;
1119*f6dc9357SAndroid Build Coastguard Worker }
1120*f6dc9357SAndroid Build Coastguard Worker
1121*f6dc9357SAndroid Build Coastguard Worker srcRem = srcLenOrig - *srcLen;
1122*f6dc9357SAndroid Build Coastguard Worker
1123*f6dc9357SAndroid Build Coastguard Worker // XZ_STATE_BLOCK_FOOTER can transit to XZ_STATE_BLOCK_HEADER without input bytes
1124*f6dc9357SAndroid Build Coastguard Worker if (srcRem == 0 && p->state != XZ_STATE_BLOCK_FOOTER)
1125*f6dc9357SAndroid Build Coastguard Worker {
1126*f6dc9357SAndroid Build Coastguard Worker *status = CODER_STATUS_NEEDS_MORE_INPUT;
1127*f6dc9357SAndroid Build Coastguard Worker return SZ_OK;
1128*f6dc9357SAndroid Build Coastguard Worker }
1129*f6dc9357SAndroid Build Coastguard Worker
1130*f6dc9357SAndroid Build Coastguard Worker switch ((int)p->state)
1131*f6dc9357SAndroid Build Coastguard Worker {
1132*f6dc9357SAndroid Build Coastguard Worker case XZ_STATE_STREAM_HEADER:
1133*f6dc9357SAndroid Build Coastguard Worker {
1134*f6dc9357SAndroid Build Coastguard Worker if (p->pos < XZ_STREAM_HEADER_SIZE)
1135*f6dc9357SAndroid Build Coastguard Worker {
1136*f6dc9357SAndroid Build Coastguard Worker if (p->pos < XZ_SIG_SIZE && *src != XZ_SIG[p->pos])
1137*f6dc9357SAndroid Build Coastguard Worker return SZ_ERROR_NO_ARCHIVE;
1138*f6dc9357SAndroid Build Coastguard Worker if (p->decodeToStreamSignature)
1139*f6dc9357SAndroid Build Coastguard Worker return SZ_OK;
1140*f6dc9357SAndroid Build Coastguard Worker p->buf[p->pos++] = *src++;
1141*f6dc9357SAndroid Build Coastguard Worker (*srcLen)++;
1142*f6dc9357SAndroid Build Coastguard Worker }
1143*f6dc9357SAndroid Build Coastguard Worker else
1144*f6dc9357SAndroid Build Coastguard Worker {
1145*f6dc9357SAndroid Build Coastguard Worker RINOK(Xz_ParseHeader(&p->streamFlags, p->buf))
1146*f6dc9357SAndroid Build Coastguard Worker p->numStartedStreams++;
1147*f6dc9357SAndroid Build Coastguard Worker p->indexSize = 0;
1148*f6dc9357SAndroid Build Coastguard Worker p->numBlocks = 0;
1149*f6dc9357SAndroid Build Coastguard Worker Sha256_Init(&p->sha);
1150*f6dc9357SAndroid Build Coastguard Worker p->state = XZ_STATE_BLOCK_HEADER;
1151*f6dc9357SAndroid Build Coastguard Worker p->pos = 0;
1152*f6dc9357SAndroid Build Coastguard Worker }
1153*f6dc9357SAndroid Build Coastguard Worker break;
1154*f6dc9357SAndroid Build Coastguard Worker }
1155*f6dc9357SAndroid Build Coastguard Worker
1156*f6dc9357SAndroid Build Coastguard Worker case XZ_STATE_BLOCK_HEADER:
1157*f6dc9357SAndroid Build Coastguard Worker {
1158*f6dc9357SAndroid Build Coastguard Worker if (p->pos == 0)
1159*f6dc9357SAndroid Build Coastguard Worker {
1160*f6dc9357SAndroid Build Coastguard Worker p->buf[p->pos++] = *src++;
1161*f6dc9357SAndroid Build Coastguard Worker (*srcLen)++;
1162*f6dc9357SAndroid Build Coastguard Worker if (p->buf[0] == 0)
1163*f6dc9357SAndroid Build Coastguard Worker {
1164*f6dc9357SAndroid Build Coastguard Worker if (p->decodeOnlyOneBlock)
1165*f6dc9357SAndroid Build Coastguard Worker return SZ_ERROR_DATA;
1166*f6dc9357SAndroid Build Coastguard Worker p->indexPreSize = 1 + Xz_WriteVarInt(p->buf + 1, p->numBlocks);
1167*f6dc9357SAndroid Build Coastguard Worker p->indexPos = p->indexPreSize;
1168*f6dc9357SAndroid Build Coastguard Worker p->indexSize += p->indexPreSize;
1169*f6dc9357SAndroid Build Coastguard Worker Sha256_Final(&p->sha, p->shaDigest);
1170*f6dc9357SAndroid Build Coastguard Worker Sha256_Init(&p->sha);
1171*f6dc9357SAndroid Build Coastguard Worker p->crc = CrcUpdate(CRC_INIT_VAL, p->buf, p->indexPreSize);
1172*f6dc9357SAndroid Build Coastguard Worker p->state = XZ_STATE_STREAM_INDEX;
1173*f6dc9357SAndroid Build Coastguard Worker break;
1174*f6dc9357SAndroid Build Coastguard Worker }
1175*f6dc9357SAndroid Build Coastguard Worker p->blockHeaderSize = ((unsigned)p->buf[0] << 2) + 4;
1176*f6dc9357SAndroid Build Coastguard Worker break;
1177*f6dc9357SAndroid Build Coastguard Worker }
1178*f6dc9357SAndroid Build Coastguard Worker
1179*f6dc9357SAndroid Build Coastguard Worker if (p->pos != p->blockHeaderSize)
1180*f6dc9357SAndroid Build Coastguard Worker {
1181*f6dc9357SAndroid Build Coastguard Worker unsigned cur = p->blockHeaderSize - p->pos;
1182*f6dc9357SAndroid Build Coastguard Worker if (cur > srcRem)
1183*f6dc9357SAndroid Build Coastguard Worker cur = (unsigned)srcRem;
1184*f6dc9357SAndroid Build Coastguard Worker memcpy(p->buf + p->pos, src, cur);
1185*f6dc9357SAndroid Build Coastguard Worker p->pos += cur;
1186*f6dc9357SAndroid Build Coastguard Worker (*srcLen) += cur;
1187*f6dc9357SAndroid Build Coastguard Worker src += cur;
1188*f6dc9357SAndroid Build Coastguard Worker }
1189*f6dc9357SAndroid Build Coastguard Worker else
1190*f6dc9357SAndroid Build Coastguard Worker {
1191*f6dc9357SAndroid Build Coastguard Worker RINOK(XzBlock_Parse(&p->block, p->buf))
1192*f6dc9357SAndroid Build Coastguard Worker if (!XzBlock_AreSupportedFilters(&p->block))
1193*f6dc9357SAndroid Build Coastguard Worker return SZ_ERROR_UNSUPPORTED;
1194*f6dc9357SAndroid Build Coastguard Worker p->numTotalBlocks++;
1195*f6dc9357SAndroid Build Coastguard Worker p->state = XZ_STATE_BLOCK;
1196*f6dc9357SAndroid Build Coastguard Worker p->packSize = 0;
1197*f6dc9357SAndroid Build Coastguard Worker p->unpackSize = 0;
1198*f6dc9357SAndroid Build Coastguard Worker XzCheck_Init(&p->check, XzFlags_GetCheckType(p->streamFlags));
1199*f6dc9357SAndroid Build Coastguard Worker if (p->parseMode)
1200*f6dc9357SAndroid Build Coastguard Worker {
1201*f6dc9357SAndroid Build Coastguard Worker p->headerParsedOk = True;
1202*f6dc9357SAndroid Build Coastguard Worker return SZ_OK;
1203*f6dc9357SAndroid Build Coastguard Worker }
1204*f6dc9357SAndroid Build Coastguard Worker RINOK(XzDecMix_Init(&p->decoder, &p->block, p->outBuf, p->outBufSize))
1205*f6dc9357SAndroid Build Coastguard Worker }
1206*f6dc9357SAndroid Build Coastguard Worker break;
1207*f6dc9357SAndroid Build Coastguard Worker }
1208*f6dc9357SAndroid Build Coastguard Worker
1209*f6dc9357SAndroid Build Coastguard Worker case XZ_STATE_BLOCK_FOOTER:
1210*f6dc9357SAndroid Build Coastguard Worker {
1211*f6dc9357SAndroid Build Coastguard Worker if ((((unsigned)p->packSize + p->alignPos) & 3) != 0)
1212*f6dc9357SAndroid Build Coastguard Worker {
1213*f6dc9357SAndroid Build Coastguard Worker if (srcRem == 0)
1214*f6dc9357SAndroid Build Coastguard Worker {
1215*f6dc9357SAndroid Build Coastguard Worker *status = CODER_STATUS_NEEDS_MORE_INPUT;
1216*f6dc9357SAndroid Build Coastguard Worker return SZ_OK;
1217*f6dc9357SAndroid Build Coastguard Worker }
1218*f6dc9357SAndroid Build Coastguard Worker (*srcLen)++;
1219*f6dc9357SAndroid Build Coastguard Worker p->alignPos++;
1220*f6dc9357SAndroid Build Coastguard Worker if (*src++ != 0)
1221*f6dc9357SAndroid Build Coastguard Worker return SZ_ERROR_CRC;
1222*f6dc9357SAndroid Build Coastguard Worker }
1223*f6dc9357SAndroid Build Coastguard Worker else
1224*f6dc9357SAndroid Build Coastguard Worker {
1225*f6dc9357SAndroid Build Coastguard Worker const unsigned checkSize = XzFlags_GetCheckSize(p->streamFlags);
1226*f6dc9357SAndroid Build Coastguard Worker unsigned cur = checkSize - p->pos;
1227*f6dc9357SAndroid Build Coastguard Worker if (cur != 0)
1228*f6dc9357SAndroid Build Coastguard Worker {
1229*f6dc9357SAndroid Build Coastguard Worker if (srcRem == 0)
1230*f6dc9357SAndroid Build Coastguard Worker {
1231*f6dc9357SAndroid Build Coastguard Worker *status = CODER_STATUS_NEEDS_MORE_INPUT;
1232*f6dc9357SAndroid Build Coastguard Worker return SZ_OK;
1233*f6dc9357SAndroid Build Coastguard Worker }
1234*f6dc9357SAndroid Build Coastguard Worker if (cur > srcRem)
1235*f6dc9357SAndroid Build Coastguard Worker cur = (unsigned)srcRem;
1236*f6dc9357SAndroid Build Coastguard Worker memcpy(p->buf + p->pos, src, cur);
1237*f6dc9357SAndroid Build Coastguard Worker p->pos += cur;
1238*f6dc9357SAndroid Build Coastguard Worker (*srcLen) += cur;
1239*f6dc9357SAndroid Build Coastguard Worker src += cur;
1240*f6dc9357SAndroid Build Coastguard Worker if (checkSize != p->pos)
1241*f6dc9357SAndroid Build Coastguard Worker break;
1242*f6dc9357SAndroid Build Coastguard Worker }
1243*f6dc9357SAndroid Build Coastguard Worker {
1244*f6dc9357SAndroid Build Coastguard Worker Byte digest[XZ_CHECK_SIZE_MAX];
1245*f6dc9357SAndroid Build Coastguard Worker p->state = XZ_STATE_BLOCK_HEADER;
1246*f6dc9357SAndroid Build Coastguard Worker p->pos = 0;
1247*f6dc9357SAndroid Build Coastguard Worker if (XzCheck_Final(&p->check, digest) && memcmp(digest, p->buf, checkSize) != 0)
1248*f6dc9357SAndroid Build Coastguard Worker return SZ_ERROR_CRC;
1249*f6dc9357SAndroid Build Coastguard Worker if (p->decodeOnlyOneBlock)
1250*f6dc9357SAndroid Build Coastguard Worker {
1251*f6dc9357SAndroid Build Coastguard Worker *status = CODER_STATUS_FINISHED_WITH_MARK;
1252*f6dc9357SAndroid Build Coastguard Worker return SZ_OK;
1253*f6dc9357SAndroid Build Coastguard Worker }
1254*f6dc9357SAndroid Build Coastguard Worker }
1255*f6dc9357SAndroid Build Coastguard Worker }
1256*f6dc9357SAndroid Build Coastguard Worker break;
1257*f6dc9357SAndroid Build Coastguard Worker }
1258*f6dc9357SAndroid Build Coastguard Worker
1259*f6dc9357SAndroid Build Coastguard Worker case XZ_STATE_STREAM_INDEX:
1260*f6dc9357SAndroid Build Coastguard Worker {
1261*f6dc9357SAndroid Build Coastguard Worker if (p->pos < p->indexPreSize)
1262*f6dc9357SAndroid Build Coastguard Worker {
1263*f6dc9357SAndroid Build Coastguard Worker (*srcLen)++;
1264*f6dc9357SAndroid Build Coastguard Worker if (*src++ != p->buf[p->pos++])
1265*f6dc9357SAndroid Build Coastguard Worker return SZ_ERROR_CRC;
1266*f6dc9357SAndroid Build Coastguard Worker }
1267*f6dc9357SAndroid Build Coastguard Worker else
1268*f6dc9357SAndroid Build Coastguard Worker {
1269*f6dc9357SAndroid Build Coastguard Worker if (p->indexPos < p->indexSize)
1270*f6dc9357SAndroid Build Coastguard Worker {
1271*f6dc9357SAndroid Build Coastguard Worker UInt64 cur = p->indexSize - p->indexPos;
1272*f6dc9357SAndroid Build Coastguard Worker if (srcRem > cur)
1273*f6dc9357SAndroid Build Coastguard Worker srcRem = (SizeT)cur;
1274*f6dc9357SAndroid Build Coastguard Worker p->crc = CrcUpdate(p->crc, src, srcRem);
1275*f6dc9357SAndroid Build Coastguard Worker Sha256_Update(&p->sha, src, srcRem);
1276*f6dc9357SAndroid Build Coastguard Worker (*srcLen) += srcRem;
1277*f6dc9357SAndroid Build Coastguard Worker src += srcRem;
1278*f6dc9357SAndroid Build Coastguard Worker p->indexPos += srcRem;
1279*f6dc9357SAndroid Build Coastguard Worker }
1280*f6dc9357SAndroid Build Coastguard Worker else if ((p->indexPos & 3) != 0)
1281*f6dc9357SAndroid Build Coastguard Worker {
1282*f6dc9357SAndroid Build Coastguard Worker Byte b = *src++;
1283*f6dc9357SAndroid Build Coastguard Worker p->crc = CRC_UPDATE_BYTE(p->crc, b);
1284*f6dc9357SAndroid Build Coastguard Worker (*srcLen)++;
1285*f6dc9357SAndroid Build Coastguard Worker p->indexPos++;
1286*f6dc9357SAndroid Build Coastguard Worker p->indexSize++;
1287*f6dc9357SAndroid Build Coastguard Worker if (b != 0)
1288*f6dc9357SAndroid Build Coastguard Worker return SZ_ERROR_CRC;
1289*f6dc9357SAndroid Build Coastguard Worker }
1290*f6dc9357SAndroid Build Coastguard Worker else
1291*f6dc9357SAndroid Build Coastguard Worker {
1292*f6dc9357SAndroid Build Coastguard Worker Byte digest[SHA256_DIGEST_SIZE];
1293*f6dc9357SAndroid Build Coastguard Worker p->state = XZ_STATE_STREAM_INDEX_CRC;
1294*f6dc9357SAndroid Build Coastguard Worker p->indexSize += 4;
1295*f6dc9357SAndroid Build Coastguard Worker p->pos = 0;
1296*f6dc9357SAndroid Build Coastguard Worker Sha256_Final(&p->sha, digest);
1297*f6dc9357SAndroid Build Coastguard Worker if (memcmp(digest, p->shaDigest, SHA256_DIGEST_SIZE) != 0)
1298*f6dc9357SAndroid Build Coastguard Worker return SZ_ERROR_CRC;
1299*f6dc9357SAndroid Build Coastguard Worker }
1300*f6dc9357SAndroid Build Coastguard Worker }
1301*f6dc9357SAndroid Build Coastguard Worker break;
1302*f6dc9357SAndroid Build Coastguard Worker }
1303*f6dc9357SAndroid Build Coastguard Worker
1304*f6dc9357SAndroid Build Coastguard Worker case XZ_STATE_STREAM_INDEX_CRC:
1305*f6dc9357SAndroid Build Coastguard Worker {
1306*f6dc9357SAndroid Build Coastguard Worker if (p->pos < 4)
1307*f6dc9357SAndroid Build Coastguard Worker {
1308*f6dc9357SAndroid Build Coastguard Worker (*srcLen)++;
1309*f6dc9357SAndroid Build Coastguard Worker p->buf[p->pos++] = *src++;
1310*f6dc9357SAndroid Build Coastguard Worker }
1311*f6dc9357SAndroid Build Coastguard Worker else
1312*f6dc9357SAndroid Build Coastguard Worker {
1313*f6dc9357SAndroid Build Coastguard Worker const Byte *ptr = p->buf;
1314*f6dc9357SAndroid Build Coastguard Worker p->state = XZ_STATE_STREAM_FOOTER;
1315*f6dc9357SAndroid Build Coastguard Worker p->pos = 0;
1316*f6dc9357SAndroid Build Coastguard Worker if (CRC_GET_DIGEST(p->crc) != GetUi32(ptr))
1317*f6dc9357SAndroid Build Coastguard Worker return SZ_ERROR_CRC;
1318*f6dc9357SAndroid Build Coastguard Worker }
1319*f6dc9357SAndroid Build Coastguard Worker break;
1320*f6dc9357SAndroid Build Coastguard Worker }
1321*f6dc9357SAndroid Build Coastguard Worker
1322*f6dc9357SAndroid Build Coastguard Worker case XZ_STATE_STREAM_FOOTER:
1323*f6dc9357SAndroid Build Coastguard Worker {
1324*f6dc9357SAndroid Build Coastguard Worker unsigned cur = XZ_STREAM_FOOTER_SIZE - p->pos;
1325*f6dc9357SAndroid Build Coastguard Worker if (cur > srcRem)
1326*f6dc9357SAndroid Build Coastguard Worker cur = (unsigned)srcRem;
1327*f6dc9357SAndroid Build Coastguard Worker memcpy(p->buf + p->pos, src, cur);
1328*f6dc9357SAndroid Build Coastguard Worker p->pos += cur;
1329*f6dc9357SAndroid Build Coastguard Worker (*srcLen) += cur;
1330*f6dc9357SAndroid Build Coastguard Worker src += cur;
1331*f6dc9357SAndroid Build Coastguard Worker if (p->pos == XZ_STREAM_FOOTER_SIZE)
1332*f6dc9357SAndroid Build Coastguard Worker {
1333*f6dc9357SAndroid Build Coastguard Worker p->state = XZ_STATE_STREAM_PADDING;
1334*f6dc9357SAndroid Build Coastguard Worker p->numFinishedStreams++;
1335*f6dc9357SAndroid Build Coastguard Worker p->padSize = 0;
1336*f6dc9357SAndroid Build Coastguard Worker if (!Xz_CheckFooter(p->streamFlags, p->indexSize, p->buf))
1337*f6dc9357SAndroid Build Coastguard Worker return SZ_ERROR_CRC;
1338*f6dc9357SAndroid Build Coastguard Worker }
1339*f6dc9357SAndroid Build Coastguard Worker break;
1340*f6dc9357SAndroid Build Coastguard Worker }
1341*f6dc9357SAndroid Build Coastguard Worker
1342*f6dc9357SAndroid Build Coastguard Worker case XZ_STATE_STREAM_PADDING:
1343*f6dc9357SAndroid Build Coastguard Worker {
1344*f6dc9357SAndroid Build Coastguard Worker if (*src != 0)
1345*f6dc9357SAndroid Build Coastguard Worker {
1346*f6dc9357SAndroid Build Coastguard Worker if (((UInt32)p->padSize & 3) != 0)
1347*f6dc9357SAndroid Build Coastguard Worker return SZ_ERROR_NO_ARCHIVE;
1348*f6dc9357SAndroid Build Coastguard Worker p->pos = 0;
1349*f6dc9357SAndroid Build Coastguard Worker p->state = XZ_STATE_STREAM_HEADER;
1350*f6dc9357SAndroid Build Coastguard Worker }
1351*f6dc9357SAndroid Build Coastguard Worker else
1352*f6dc9357SAndroid Build Coastguard Worker {
1353*f6dc9357SAndroid Build Coastguard Worker (*srcLen)++;
1354*f6dc9357SAndroid Build Coastguard Worker src++;
1355*f6dc9357SAndroid Build Coastguard Worker p->padSize++;
1356*f6dc9357SAndroid Build Coastguard Worker }
1357*f6dc9357SAndroid Build Coastguard Worker break;
1358*f6dc9357SAndroid Build Coastguard Worker }
1359*f6dc9357SAndroid Build Coastguard Worker
1360*f6dc9357SAndroid Build Coastguard Worker case XZ_STATE_BLOCK: break; /* to disable GCC warning */
1361*f6dc9357SAndroid Build Coastguard Worker
1362*f6dc9357SAndroid Build Coastguard Worker default: return SZ_ERROR_FAIL;
1363*f6dc9357SAndroid Build Coastguard Worker }
1364*f6dc9357SAndroid Build Coastguard Worker }
1365*f6dc9357SAndroid Build Coastguard Worker /*
1366*f6dc9357SAndroid Build Coastguard Worker if (p->state == XZ_STATE_FINISHED)
1367*f6dc9357SAndroid Build Coastguard Worker *status = CODER_STATUS_FINISHED_WITH_MARK;
1368*f6dc9357SAndroid Build Coastguard Worker return SZ_OK;
1369*f6dc9357SAndroid Build Coastguard Worker */
1370*f6dc9357SAndroid Build Coastguard Worker }
1371*f6dc9357SAndroid Build Coastguard Worker
1372*f6dc9357SAndroid Build Coastguard Worker
XzUnpacker_CodeFull(CXzUnpacker * p,Byte * dest,SizeT * destLen,const Byte * src,SizeT * srcLen,ECoderFinishMode finishMode,ECoderStatus * status)1373*f6dc9357SAndroid Build Coastguard Worker SRes XzUnpacker_CodeFull(CXzUnpacker *p, Byte *dest, SizeT *destLen,
1374*f6dc9357SAndroid Build Coastguard Worker const Byte *src, SizeT *srcLen,
1375*f6dc9357SAndroid Build Coastguard Worker ECoderFinishMode finishMode, ECoderStatus *status)
1376*f6dc9357SAndroid Build Coastguard Worker {
1377*f6dc9357SAndroid Build Coastguard Worker XzUnpacker_Init(p);
1378*f6dc9357SAndroid Build Coastguard Worker XzUnpacker_SetOutBuf(p, dest, *destLen);
1379*f6dc9357SAndroid Build Coastguard Worker
1380*f6dc9357SAndroid Build Coastguard Worker return XzUnpacker_Code(p,
1381*f6dc9357SAndroid Build Coastguard Worker NULL, destLen,
1382*f6dc9357SAndroid Build Coastguard Worker src, srcLen, True,
1383*f6dc9357SAndroid Build Coastguard Worker finishMode, status);
1384*f6dc9357SAndroid Build Coastguard Worker }
1385*f6dc9357SAndroid Build Coastguard Worker
1386*f6dc9357SAndroid Build Coastguard Worker
XzUnpacker_IsBlockFinished(const CXzUnpacker * p)1387*f6dc9357SAndroid Build Coastguard Worker BoolInt XzUnpacker_IsBlockFinished(const CXzUnpacker *p)
1388*f6dc9357SAndroid Build Coastguard Worker {
1389*f6dc9357SAndroid Build Coastguard Worker return (p->state == XZ_STATE_BLOCK_HEADER) && (p->pos == 0);
1390*f6dc9357SAndroid Build Coastguard Worker }
1391*f6dc9357SAndroid Build Coastguard Worker
XzUnpacker_IsStreamWasFinished(const CXzUnpacker * p)1392*f6dc9357SAndroid Build Coastguard Worker BoolInt XzUnpacker_IsStreamWasFinished(const CXzUnpacker *p)
1393*f6dc9357SAndroid Build Coastguard Worker {
1394*f6dc9357SAndroid Build Coastguard Worker return (p->state == XZ_STATE_STREAM_PADDING) && (((UInt32)p->padSize & 3) == 0);
1395*f6dc9357SAndroid Build Coastguard Worker }
1396*f6dc9357SAndroid Build Coastguard Worker
XzUnpacker_GetExtraSize(const CXzUnpacker * p)1397*f6dc9357SAndroid Build Coastguard Worker UInt64 XzUnpacker_GetExtraSize(const CXzUnpacker *p)
1398*f6dc9357SAndroid Build Coastguard Worker {
1399*f6dc9357SAndroid Build Coastguard Worker UInt64 num = 0;
1400*f6dc9357SAndroid Build Coastguard Worker if (p->state == XZ_STATE_STREAM_PADDING)
1401*f6dc9357SAndroid Build Coastguard Worker num = p->padSize;
1402*f6dc9357SAndroid Build Coastguard Worker else if (p->state == XZ_STATE_STREAM_HEADER)
1403*f6dc9357SAndroid Build Coastguard Worker num = p->padSize + p->pos;
1404*f6dc9357SAndroid Build Coastguard Worker return num;
1405*f6dc9357SAndroid Build Coastguard Worker }
1406*f6dc9357SAndroid Build Coastguard Worker
1407*f6dc9357SAndroid Build Coastguard Worker
1408*f6dc9357SAndroid Build Coastguard Worker
1409*f6dc9357SAndroid Build Coastguard Worker
1410*f6dc9357SAndroid Build Coastguard Worker
1411*f6dc9357SAndroid Build Coastguard Worker
1412*f6dc9357SAndroid Build Coastguard Worker
1413*f6dc9357SAndroid Build Coastguard Worker
1414*f6dc9357SAndroid Build Coastguard Worker
1415*f6dc9357SAndroid Build Coastguard Worker
1416*f6dc9357SAndroid Build Coastguard Worker
1417*f6dc9357SAndroid Build Coastguard Worker
1418*f6dc9357SAndroid Build Coastguard Worker
1419*f6dc9357SAndroid Build Coastguard Worker
1420*f6dc9357SAndroid Build Coastguard Worker
1421*f6dc9357SAndroid Build Coastguard Worker
1422*f6dc9357SAndroid Build Coastguard Worker
1423*f6dc9357SAndroid Build Coastguard Worker
1424*f6dc9357SAndroid Build Coastguard Worker
1425*f6dc9357SAndroid Build Coastguard Worker
1426*f6dc9357SAndroid Build Coastguard Worker
1427*f6dc9357SAndroid Build Coastguard Worker #ifndef Z7_ST
1428*f6dc9357SAndroid Build Coastguard Worker #include "MtDec.h"
1429*f6dc9357SAndroid Build Coastguard Worker #endif
1430*f6dc9357SAndroid Build Coastguard Worker
1431*f6dc9357SAndroid Build Coastguard Worker
XzDecMtProps_Init(CXzDecMtProps * p)1432*f6dc9357SAndroid Build Coastguard Worker void XzDecMtProps_Init(CXzDecMtProps *p)
1433*f6dc9357SAndroid Build Coastguard Worker {
1434*f6dc9357SAndroid Build Coastguard Worker p->inBufSize_ST = 1 << 18;
1435*f6dc9357SAndroid Build Coastguard Worker p->outStep_ST = 1 << 20;
1436*f6dc9357SAndroid Build Coastguard Worker p->ignoreErrors = False;
1437*f6dc9357SAndroid Build Coastguard Worker
1438*f6dc9357SAndroid Build Coastguard Worker #ifndef Z7_ST
1439*f6dc9357SAndroid Build Coastguard Worker p->numThreads = 1;
1440*f6dc9357SAndroid Build Coastguard Worker p->inBufSize_MT = 1 << 18;
1441*f6dc9357SAndroid Build Coastguard Worker p->memUseMax = sizeof(size_t) << 28;
1442*f6dc9357SAndroid Build Coastguard Worker #endif
1443*f6dc9357SAndroid Build Coastguard Worker }
1444*f6dc9357SAndroid Build Coastguard Worker
1445*f6dc9357SAndroid Build Coastguard Worker
1446*f6dc9357SAndroid Build Coastguard Worker
1447*f6dc9357SAndroid Build Coastguard Worker #ifndef Z7_ST
1448*f6dc9357SAndroid Build Coastguard Worker
1449*f6dc9357SAndroid Build Coastguard Worker /* ---------- CXzDecMtThread ---------- */
1450*f6dc9357SAndroid Build Coastguard Worker
1451*f6dc9357SAndroid Build Coastguard Worker typedef struct
1452*f6dc9357SAndroid Build Coastguard Worker {
1453*f6dc9357SAndroid Build Coastguard Worker Byte *outBuf;
1454*f6dc9357SAndroid Build Coastguard Worker size_t outBufSize;
1455*f6dc9357SAndroid Build Coastguard Worker size_t outPreSize;
1456*f6dc9357SAndroid Build Coastguard Worker size_t inPreSize;
1457*f6dc9357SAndroid Build Coastguard Worker size_t inPreHeaderSize;
1458*f6dc9357SAndroid Build Coastguard Worker size_t blockPackSize_for_Index; // including block header and checksum.
1459*f6dc9357SAndroid Build Coastguard Worker size_t blockPackTotal; // including stream header, block header and checksum.
1460*f6dc9357SAndroid Build Coastguard Worker size_t inCodeSize;
1461*f6dc9357SAndroid Build Coastguard Worker size_t outCodeSize;
1462*f6dc9357SAndroid Build Coastguard Worker ECoderStatus status;
1463*f6dc9357SAndroid Build Coastguard Worker SRes codeRes;
1464*f6dc9357SAndroid Build Coastguard Worker BoolInt skipMode;
1465*f6dc9357SAndroid Build Coastguard Worker // BoolInt finishedWithMark;
1466*f6dc9357SAndroid Build Coastguard Worker EMtDecParseState parseState;
1467*f6dc9357SAndroid Build Coastguard Worker BoolInt parsing_Truncated;
1468*f6dc9357SAndroid Build Coastguard Worker BoolInt atBlockHeader;
1469*f6dc9357SAndroid Build Coastguard Worker CXzStreamFlags streamFlags;
1470*f6dc9357SAndroid Build Coastguard Worker // UInt64 numFinishedStreams
1471*f6dc9357SAndroid Build Coastguard Worker UInt64 numStreams;
1472*f6dc9357SAndroid Build Coastguard Worker UInt64 numTotalBlocks;
1473*f6dc9357SAndroid Build Coastguard Worker UInt64 numBlocks;
1474*f6dc9357SAndroid Build Coastguard Worker
1475*f6dc9357SAndroid Build Coastguard Worker BoolInt dec_created;
1476*f6dc9357SAndroid Build Coastguard Worker CXzUnpacker dec;
1477*f6dc9357SAndroid Build Coastguard Worker
1478*f6dc9357SAndroid Build Coastguard Worker Byte mtPad[1 << 7];
1479*f6dc9357SAndroid Build Coastguard Worker } CXzDecMtThread;
1480*f6dc9357SAndroid Build Coastguard Worker
1481*f6dc9357SAndroid Build Coastguard Worker #endif
1482*f6dc9357SAndroid Build Coastguard Worker
1483*f6dc9357SAndroid Build Coastguard Worker
1484*f6dc9357SAndroid Build Coastguard Worker /* ---------- CXzDecMt ---------- */
1485*f6dc9357SAndroid Build Coastguard Worker
1486*f6dc9357SAndroid Build Coastguard Worker struct CXzDecMt
1487*f6dc9357SAndroid Build Coastguard Worker {
1488*f6dc9357SAndroid Build Coastguard Worker CAlignOffsetAlloc alignOffsetAlloc;
1489*f6dc9357SAndroid Build Coastguard Worker ISzAllocPtr allocMid;
1490*f6dc9357SAndroid Build Coastguard Worker
1491*f6dc9357SAndroid Build Coastguard Worker CXzDecMtProps props;
1492*f6dc9357SAndroid Build Coastguard Worker size_t unpackBlockMaxSize;
1493*f6dc9357SAndroid Build Coastguard Worker
1494*f6dc9357SAndroid Build Coastguard Worker ISeqInStreamPtr inStream;
1495*f6dc9357SAndroid Build Coastguard Worker ISeqOutStreamPtr outStream;
1496*f6dc9357SAndroid Build Coastguard Worker ICompressProgressPtr progress;
1497*f6dc9357SAndroid Build Coastguard Worker
1498*f6dc9357SAndroid Build Coastguard Worker BoolInt finishMode;
1499*f6dc9357SAndroid Build Coastguard Worker BoolInt outSize_Defined;
1500*f6dc9357SAndroid Build Coastguard Worker UInt64 outSize;
1501*f6dc9357SAndroid Build Coastguard Worker
1502*f6dc9357SAndroid Build Coastguard Worker UInt64 outProcessed;
1503*f6dc9357SAndroid Build Coastguard Worker UInt64 inProcessed;
1504*f6dc9357SAndroid Build Coastguard Worker UInt64 readProcessed;
1505*f6dc9357SAndroid Build Coastguard Worker BoolInt readWasFinished;
1506*f6dc9357SAndroid Build Coastguard Worker SRes readRes;
1507*f6dc9357SAndroid Build Coastguard Worker SRes writeRes;
1508*f6dc9357SAndroid Build Coastguard Worker
1509*f6dc9357SAndroid Build Coastguard Worker Byte *outBuf;
1510*f6dc9357SAndroid Build Coastguard Worker size_t outBufSize;
1511*f6dc9357SAndroid Build Coastguard Worker Byte *inBuf;
1512*f6dc9357SAndroid Build Coastguard Worker size_t inBufSize;
1513*f6dc9357SAndroid Build Coastguard Worker
1514*f6dc9357SAndroid Build Coastguard Worker CXzUnpacker dec;
1515*f6dc9357SAndroid Build Coastguard Worker
1516*f6dc9357SAndroid Build Coastguard Worker ECoderStatus status;
1517*f6dc9357SAndroid Build Coastguard Worker SRes codeRes;
1518*f6dc9357SAndroid Build Coastguard Worker
1519*f6dc9357SAndroid Build Coastguard Worker #ifndef Z7_ST
1520*f6dc9357SAndroid Build Coastguard Worker BoolInt mainDecoderWasCalled;
1521*f6dc9357SAndroid Build Coastguard Worker // int statErrorDefined;
1522*f6dc9357SAndroid Build Coastguard Worker int finishedDecoderIndex;
1523*f6dc9357SAndroid Build Coastguard Worker
1524*f6dc9357SAndroid Build Coastguard Worker // global values that are used in Parse stage
1525*f6dc9357SAndroid Build Coastguard Worker CXzStreamFlags streamFlags;
1526*f6dc9357SAndroid Build Coastguard Worker // UInt64 numFinishedStreams
1527*f6dc9357SAndroid Build Coastguard Worker UInt64 numStreams;
1528*f6dc9357SAndroid Build Coastguard Worker UInt64 numTotalBlocks;
1529*f6dc9357SAndroid Build Coastguard Worker UInt64 numBlocks;
1530*f6dc9357SAndroid Build Coastguard Worker
1531*f6dc9357SAndroid Build Coastguard Worker // UInt64 numBadBlocks;
1532*f6dc9357SAndroid Build Coastguard Worker SRes mainErrorCode; // it's set to error code, if the size Code() output doesn't patch the size from Parsing stage
1533*f6dc9357SAndroid Build Coastguard Worker // it can be = SZ_ERROR_INPUT_EOF
1534*f6dc9357SAndroid Build Coastguard Worker // it can be = SZ_ERROR_DATA, in some another cases
1535*f6dc9357SAndroid Build Coastguard Worker BoolInt isBlockHeaderState_Parse;
1536*f6dc9357SAndroid Build Coastguard Worker BoolInt isBlockHeaderState_Write;
1537*f6dc9357SAndroid Build Coastguard Worker UInt64 outProcessed_Parse;
1538*f6dc9357SAndroid Build Coastguard Worker BoolInt parsing_Truncated;
1539*f6dc9357SAndroid Build Coastguard Worker
1540*f6dc9357SAndroid Build Coastguard Worker BoolInt mtc_WasConstructed;
1541*f6dc9357SAndroid Build Coastguard Worker CMtDec mtc;
1542*f6dc9357SAndroid Build Coastguard Worker CXzDecMtThread coders[MTDEC_THREADS_MAX];
1543*f6dc9357SAndroid Build Coastguard Worker #endif
1544*f6dc9357SAndroid Build Coastguard Worker };
1545*f6dc9357SAndroid Build Coastguard Worker
1546*f6dc9357SAndroid Build Coastguard Worker
1547*f6dc9357SAndroid Build Coastguard Worker
XzDecMt_Create(ISzAllocPtr alloc,ISzAllocPtr allocMid)1548*f6dc9357SAndroid Build Coastguard Worker CXzDecMtHandle XzDecMt_Create(ISzAllocPtr alloc, ISzAllocPtr allocMid)
1549*f6dc9357SAndroid Build Coastguard Worker {
1550*f6dc9357SAndroid Build Coastguard Worker CXzDecMt *p = (CXzDecMt *)ISzAlloc_Alloc(alloc, sizeof(CXzDecMt));
1551*f6dc9357SAndroid Build Coastguard Worker if (!p)
1552*f6dc9357SAndroid Build Coastguard Worker return NULL;
1553*f6dc9357SAndroid Build Coastguard Worker
1554*f6dc9357SAndroid Build Coastguard Worker AlignOffsetAlloc_CreateVTable(&p->alignOffsetAlloc);
1555*f6dc9357SAndroid Build Coastguard Worker p->alignOffsetAlloc.baseAlloc = alloc;
1556*f6dc9357SAndroid Build Coastguard Worker p->alignOffsetAlloc.numAlignBits = 7;
1557*f6dc9357SAndroid Build Coastguard Worker p->alignOffsetAlloc.offset = 0;
1558*f6dc9357SAndroid Build Coastguard Worker
1559*f6dc9357SAndroid Build Coastguard Worker p->allocMid = allocMid;
1560*f6dc9357SAndroid Build Coastguard Worker
1561*f6dc9357SAndroid Build Coastguard Worker p->outBuf = NULL;
1562*f6dc9357SAndroid Build Coastguard Worker p->outBufSize = 0;
1563*f6dc9357SAndroid Build Coastguard Worker p->inBuf = NULL;
1564*f6dc9357SAndroid Build Coastguard Worker p->inBufSize = 0;
1565*f6dc9357SAndroid Build Coastguard Worker
1566*f6dc9357SAndroid Build Coastguard Worker XzUnpacker_Construct(&p->dec, &p->alignOffsetAlloc.vt);
1567*f6dc9357SAndroid Build Coastguard Worker
1568*f6dc9357SAndroid Build Coastguard Worker p->unpackBlockMaxSize = 0;
1569*f6dc9357SAndroid Build Coastguard Worker
1570*f6dc9357SAndroid Build Coastguard Worker XzDecMtProps_Init(&p->props);
1571*f6dc9357SAndroid Build Coastguard Worker
1572*f6dc9357SAndroid Build Coastguard Worker #ifndef Z7_ST
1573*f6dc9357SAndroid Build Coastguard Worker p->mtc_WasConstructed = False;
1574*f6dc9357SAndroid Build Coastguard Worker {
1575*f6dc9357SAndroid Build Coastguard Worker unsigned i;
1576*f6dc9357SAndroid Build Coastguard Worker for (i = 0; i < MTDEC_THREADS_MAX; i++)
1577*f6dc9357SAndroid Build Coastguard Worker {
1578*f6dc9357SAndroid Build Coastguard Worker CXzDecMtThread *coder = &p->coders[i];
1579*f6dc9357SAndroid Build Coastguard Worker coder->dec_created = False;
1580*f6dc9357SAndroid Build Coastguard Worker coder->outBuf = NULL;
1581*f6dc9357SAndroid Build Coastguard Worker coder->outBufSize = 0;
1582*f6dc9357SAndroid Build Coastguard Worker }
1583*f6dc9357SAndroid Build Coastguard Worker }
1584*f6dc9357SAndroid Build Coastguard Worker #endif
1585*f6dc9357SAndroid Build Coastguard Worker
1586*f6dc9357SAndroid Build Coastguard Worker return (CXzDecMtHandle)p;
1587*f6dc9357SAndroid Build Coastguard Worker }
1588*f6dc9357SAndroid Build Coastguard Worker
1589*f6dc9357SAndroid Build Coastguard Worker
1590*f6dc9357SAndroid Build Coastguard Worker #ifndef Z7_ST
1591*f6dc9357SAndroid Build Coastguard Worker
XzDecMt_FreeOutBufs(CXzDecMt * p)1592*f6dc9357SAndroid Build Coastguard Worker static void XzDecMt_FreeOutBufs(CXzDecMt *p)
1593*f6dc9357SAndroid Build Coastguard Worker {
1594*f6dc9357SAndroid Build Coastguard Worker unsigned i;
1595*f6dc9357SAndroid Build Coastguard Worker for (i = 0; i < MTDEC_THREADS_MAX; i++)
1596*f6dc9357SAndroid Build Coastguard Worker {
1597*f6dc9357SAndroid Build Coastguard Worker CXzDecMtThread *coder = &p->coders[i];
1598*f6dc9357SAndroid Build Coastguard Worker if (coder->outBuf)
1599*f6dc9357SAndroid Build Coastguard Worker {
1600*f6dc9357SAndroid Build Coastguard Worker ISzAlloc_Free(p->allocMid, coder->outBuf);
1601*f6dc9357SAndroid Build Coastguard Worker coder->outBuf = NULL;
1602*f6dc9357SAndroid Build Coastguard Worker coder->outBufSize = 0;
1603*f6dc9357SAndroid Build Coastguard Worker }
1604*f6dc9357SAndroid Build Coastguard Worker }
1605*f6dc9357SAndroid Build Coastguard Worker p->unpackBlockMaxSize = 0;
1606*f6dc9357SAndroid Build Coastguard Worker }
1607*f6dc9357SAndroid Build Coastguard Worker
1608*f6dc9357SAndroid Build Coastguard Worker #endif
1609*f6dc9357SAndroid Build Coastguard Worker
1610*f6dc9357SAndroid Build Coastguard Worker
1611*f6dc9357SAndroid Build Coastguard Worker
XzDecMt_FreeSt(CXzDecMt * p)1612*f6dc9357SAndroid Build Coastguard Worker static void XzDecMt_FreeSt(CXzDecMt *p)
1613*f6dc9357SAndroid Build Coastguard Worker {
1614*f6dc9357SAndroid Build Coastguard Worker XzUnpacker_Free(&p->dec);
1615*f6dc9357SAndroid Build Coastguard Worker
1616*f6dc9357SAndroid Build Coastguard Worker if (p->outBuf)
1617*f6dc9357SAndroid Build Coastguard Worker {
1618*f6dc9357SAndroid Build Coastguard Worker ISzAlloc_Free(p->allocMid, p->outBuf);
1619*f6dc9357SAndroid Build Coastguard Worker p->outBuf = NULL;
1620*f6dc9357SAndroid Build Coastguard Worker }
1621*f6dc9357SAndroid Build Coastguard Worker p->outBufSize = 0;
1622*f6dc9357SAndroid Build Coastguard Worker
1623*f6dc9357SAndroid Build Coastguard Worker if (p->inBuf)
1624*f6dc9357SAndroid Build Coastguard Worker {
1625*f6dc9357SAndroid Build Coastguard Worker ISzAlloc_Free(p->allocMid, p->inBuf);
1626*f6dc9357SAndroid Build Coastguard Worker p->inBuf = NULL;
1627*f6dc9357SAndroid Build Coastguard Worker }
1628*f6dc9357SAndroid Build Coastguard Worker p->inBufSize = 0;
1629*f6dc9357SAndroid Build Coastguard Worker }
1630*f6dc9357SAndroid Build Coastguard Worker
1631*f6dc9357SAndroid Build Coastguard Worker
1632*f6dc9357SAndroid Build Coastguard Worker // #define GET_CXzDecMt_p CXzDecMt *p = pp;
1633*f6dc9357SAndroid Build Coastguard Worker
XzDecMt_Destroy(CXzDecMtHandle p)1634*f6dc9357SAndroid Build Coastguard Worker void XzDecMt_Destroy(CXzDecMtHandle p)
1635*f6dc9357SAndroid Build Coastguard Worker {
1636*f6dc9357SAndroid Build Coastguard Worker // GET_CXzDecMt_p
1637*f6dc9357SAndroid Build Coastguard Worker
1638*f6dc9357SAndroid Build Coastguard Worker XzDecMt_FreeSt(p);
1639*f6dc9357SAndroid Build Coastguard Worker
1640*f6dc9357SAndroid Build Coastguard Worker #ifndef Z7_ST
1641*f6dc9357SAndroid Build Coastguard Worker
1642*f6dc9357SAndroid Build Coastguard Worker if (p->mtc_WasConstructed)
1643*f6dc9357SAndroid Build Coastguard Worker {
1644*f6dc9357SAndroid Build Coastguard Worker MtDec_Destruct(&p->mtc);
1645*f6dc9357SAndroid Build Coastguard Worker p->mtc_WasConstructed = False;
1646*f6dc9357SAndroid Build Coastguard Worker }
1647*f6dc9357SAndroid Build Coastguard Worker {
1648*f6dc9357SAndroid Build Coastguard Worker unsigned i;
1649*f6dc9357SAndroid Build Coastguard Worker for (i = 0; i < MTDEC_THREADS_MAX; i++)
1650*f6dc9357SAndroid Build Coastguard Worker {
1651*f6dc9357SAndroid Build Coastguard Worker CXzDecMtThread *t = &p->coders[i];
1652*f6dc9357SAndroid Build Coastguard Worker if (t->dec_created)
1653*f6dc9357SAndroid Build Coastguard Worker {
1654*f6dc9357SAndroid Build Coastguard Worker // we don't need to free dict here
1655*f6dc9357SAndroid Build Coastguard Worker XzUnpacker_Free(&t->dec);
1656*f6dc9357SAndroid Build Coastguard Worker t->dec_created = False;
1657*f6dc9357SAndroid Build Coastguard Worker }
1658*f6dc9357SAndroid Build Coastguard Worker }
1659*f6dc9357SAndroid Build Coastguard Worker }
1660*f6dc9357SAndroid Build Coastguard Worker XzDecMt_FreeOutBufs(p);
1661*f6dc9357SAndroid Build Coastguard Worker
1662*f6dc9357SAndroid Build Coastguard Worker #endif
1663*f6dc9357SAndroid Build Coastguard Worker
1664*f6dc9357SAndroid Build Coastguard Worker ISzAlloc_Free(p->alignOffsetAlloc.baseAlloc, p);
1665*f6dc9357SAndroid Build Coastguard Worker }
1666*f6dc9357SAndroid Build Coastguard Worker
1667*f6dc9357SAndroid Build Coastguard Worker
1668*f6dc9357SAndroid Build Coastguard Worker
1669*f6dc9357SAndroid Build Coastguard Worker #ifndef Z7_ST
1670*f6dc9357SAndroid Build Coastguard Worker
XzDecMt_Callback_Parse(void * obj,unsigned coderIndex,CMtDecCallbackInfo * cc)1671*f6dc9357SAndroid Build Coastguard Worker static void XzDecMt_Callback_Parse(void *obj, unsigned coderIndex, CMtDecCallbackInfo *cc)
1672*f6dc9357SAndroid Build Coastguard Worker {
1673*f6dc9357SAndroid Build Coastguard Worker CXzDecMt *me = (CXzDecMt *)obj;
1674*f6dc9357SAndroid Build Coastguard Worker CXzDecMtThread *coder = &me->coders[coderIndex];
1675*f6dc9357SAndroid Build Coastguard Worker size_t srcSize = cc->srcSize;
1676*f6dc9357SAndroid Build Coastguard Worker
1677*f6dc9357SAndroid Build Coastguard Worker cc->srcSize = 0;
1678*f6dc9357SAndroid Build Coastguard Worker cc->outPos = 0;
1679*f6dc9357SAndroid Build Coastguard Worker cc->state = MTDEC_PARSE_CONTINUE;
1680*f6dc9357SAndroid Build Coastguard Worker
1681*f6dc9357SAndroid Build Coastguard Worker cc->canCreateNewThread = True;
1682*f6dc9357SAndroid Build Coastguard Worker
1683*f6dc9357SAndroid Build Coastguard Worker if (cc->startCall)
1684*f6dc9357SAndroid Build Coastguard Worker {
1685*f6dc9357SAndroid Build Coastguard Worker coder->outPreSize = 0;
1686*f6dc9357SAndroid Build Coastguard Worker coder->inPreSize = 0;
1687*f6dc9357SAndroid Build Coastguard Worker coder->inPreHeaderSize = 0;
1688*f6dc9357SAndroid Build Coastguard Worker coder->parseState = MTDEC_PARSE_CONTINUE;
1689*f6dc9357SAndroid Build Coastguard Worker coder->parsing_Truncated = False;
1690*f6dc9357SAndroid Build Coastguard Worker coder->skipMode = False;
1691*f6dc9357SAndroid Build Coastguard Worker coder->codeRes = SZ_OK;
1692*f6dc9357SAndroid Build Coastguard Worker coder->status = CODER_STATUS_NOT_SPECIFIED;
1693*f6dc9357SAndroid Build Coastguard Worker coder->inCodeSize = 0;
1694*f6dc9357SAndroid Build Coastguard Worker coder->outCodeSize = 0;
1695*f6dc9357SAndroid Build Coastguard Worker
1696*f6dc9357SAndroid Build Coastguard Worker coder->numStreams = me->numStreams;
1697*f6dc9357SAndroid Build Coastguard Worker coder->numTotalBlocks = me->numTotalBlocks;
1698*f6dc9357SAndroid Build Coastguard Worker coder->numBlocks = me->numBlocks;
1699*f6dc9357SAndroid Build Coastguard Worker
1700*f6dc9357SAndroid Build Coastguard Worker if (!coder->dec_created)
1701*f6dc9357SAndroid Build Coastguard Worker {
1702*f6dc9357SAndroid Build Coastguard Worker XzUnpacker_Construct(&coder->dec, &me->alignOffsetAlloc.vt);
1703*f6dc9357SAndroid Build Coastguard Worker coder->dec_created = True;
1704*f6dc9357SAndroid Build Coastguard Worker }
1705*f6dc9357SAndroid Build Coastguard Worker
1706*f6dc9357SAndroid Build Coastguard Worker XzUnpacker_Init(&coder->dec);
1707*f6dc9357SAndroid Build Coastguard Worker
1708*f6dc9357SAndroid Build Coastguard Worker if (me->isBlockHeaderState_Parse)
1709*f6dc9357SAndroid Build Coastguard Worker {
1710*f6dc9357SAndroid Build Coastguard Worker coder->dec.streamFlags = me->streamFlags;
1711*f6dc9357SAndroid Build Coastguard Worker coder->atBlockHeader = True;
1712*f6dc9357SAndroid Build Coastguard Worker XzUnpacker_PrepareToRandomBlockDecoding(&coder->dec);
1713*f6dc9357SAndroid Build Coastguard Worker }
1714*f6dc9357SAndroid Build Coastguard Worker else
1715*f6dc9357SAndroid Build Coastguard Worker {
1716*f6dc9357SAndroid Build Coastguard Worker coder->atBlockHeader = False;
1717*f6dc9357SAndroid Build Coastguard Worker me->isBlockHeaderState_Parse = True;
1718*f6dc9357SAndroid Build Coastguard Worker }
1719*f6dc9357SAndroid Build Coastguard Worker
1720*f6dc9357SAndroid Build Coastguard Worker coder->dec.numStartedStreams = me->numStreams;
1721*f6dc9357SAndroid Build Coastguard Worker coder->dec.numTotalBlocks = me->numTotalBlocks;
1722*f6dc9357SAndroid Build Coastguard Worker coder->dec.numBlocks = me->numBlocks;
1723*f6dc9357SAndroid Build Coastguard Worker }
1724*f6dc9357SAndroid Build Coastguard Worker
1725*f6dc9357SAndroid Build Coastguard Worker while (!coder->skipMode)
1726*f6dc9357SAndroid Build Coastguard Worker {
1727*f6dc9357SAndroid Build Coastguard Worker ECoderStatus status;
1728*f6dc9357SAndroid Build Coastguard Worker SRes res;
1729*f6dc9357SAndroid Build Coastguard Worker size_t srcSize2 = srcSize;
1730*f6dc9357SAndroid Build Coastguard Worker size_t destSize = (size_t)0 - 1;
1731*f6dc9357SAndroid Build Coastguard Worker
1732*f6dc9357SAndroid Build Coastguard Worker coder->dec.parseMode = True;
1733*f6dc9357SAndroid Build Coastguard Worker coder->dec.headerParsedOk = False;
1734*f6dc9357SAndroid Build Coastguard Worker
1735*f6dc9357SAndroid Build Coastguard Worker PRF_STR_INT("Parse", srcSize2)
1736*f6dc9357SAndroid Build Coastguard Worker
1737*f6dc9357SAndroid Build Coastguard Worker res = XzUnpacker_Code(&coder->dec,
1738*f6dc9357SAndroid Build Coastguard Worker NULL, &destSize,
1739*f6dc9357SAndroid Build Coastguard Worker cc->src, &srcSize2, cc->srcFinished,
1740*f6dc9357SAndroid Build Coastguard Worker CODER_FINISH_END, &status);
1741*f6dc9357SAndroid Build Coastguard Worker
1742*f6dc9357SAndroid Build Coastguard Worker // PRF(printf(" res = %d, srcSize2 = %d", res, (unsigned)srcSize2));
1743*f6dc9357SAndroid Build Coastguard Worker
1744*f6dc9357SAndroid Build Coastguard Worker coder->codeRes = res;
1745*f6dc9357SAndroid Build Coastguard Worker coder->status = status;
1746*f6dc9357SAndroid Build Coastguard Worker cc->srcSize += srcSize2;
1747*f6dc9357SAndroid Build Coastguard Worker srcSize -= srcSize2;
1748*f6dc9357SAndroid Build Coastguard Worker coder->inPreHeaderSize += srcSize2;
1749*f6dc9357SAndroid Build Coastguard Worker coder->inPreSize = coder->inPreHeaderSize;
1750*f6dc9357SAndroid Build Coastguard Worker
1751*f6dc9357SAndroid Build Coastguard Worker if (res != SZ_OK)
1752*f6dc9357SAndroid Build Coastguard Worker {
1753*f6dc9357SAndroid Build Coastguard Worker cc->state =
1754*f6dc9357SAndroid Build Coastguard Worker coder->parseState = MTDEC_PARSE_END;
1755*f6dc9357SAndroid Build Coastguard Worker /*
1756*f6dc9357SAndroid Build Coastguard Worker if (res == SZ_ERROR_MEM)
1757*f6dc9357SAndroid Build Coastguard Worker return res;
1758*f6dc9357SAndroid Build Coastguard Worker return SZ_OK;
1759*f6dc9357SAndroid Build Coastguard Worker */
1760*f6dc9357SAndroid Build Coastguard Worker return; // res;
1761*f6dc9357SAndroid Build Coastguard Worker }
1762*f6dc9357SAndroid Build Coastguard Worker
1763*f6dc9357SAndroid Build Coastguard Worker if (coder->dec.headerParsedOk)
1764*f6dc9357SAndroid Build Coastguard Worker {
1765*f6dc9357SAndroid Build Coastguard Worker const CXzBlock *block = &coder->dec.block;
1766*f6dc9357SAndroid Build Coastguard Worker if (XzBlock_HasUnpackSize(block)
1767*f6dc9357SAndroid Build Coastguard Worker // && block->unpackSize <= me->props.outBlockMax
1768*f6dc9357SAndroid Build Coastguard Worker && XzBlock_HasPackSize(block))
1769*f6dc9357SAndroid Build Coastguard Worker {
1770*f6dc9357SAndroid Build Coastguard Worker {
1771*f6dc9357SAndroid Build Coastguard Worker if (block->unpackSize * 2 * me->mtc.numStartedThreads > me->props.memUseMax)
1772*f6dc9357SAndroid Build Coastguard Worker {
1773*f6dc9357SAndroid Build Coastguard Worker cc->state = MTDEC_PARSE_OVERFLOW;
1774*f6dc9357SAndroid Build Coastguard Worker return; // SZ_OK;
1775*f6dc9357SAndroid Build Coastguard Worker }
1776*f6dc9357SAndroid Build Coastguard Worker }
1777*f6dc9357SAndroid Build Coastguard Worker {
1778*f6dc9357SAndroid Build Coastguard Worker const UInt64 packSize = block->packSize;
1779*f6dc9357SAndroid Build Coastguard Worker const UInt64 packSizeAligned = packSize + ((0 - (unsigned)packSize) & 3);
1780*f6dc9357SAndroid Build Coastguard Worker const unsigned checkSize = XzFlags_GetCheckSize(coder->dec.streamFlags);
1781*f6dc9357SAndroid Build Coastguard Worker const UInt64 blockPackSum = coder->inPreSize + packSizeAligned + checkSize;
1782*f6dc9357SAndroid Build Coastguard Worker // if (blockPackSum <= me->props.inBlockMax)
1783*f6dc9357SAndroid Build Coastguard Worker // unpackBlockMaxSize
1784*f6dc9357SAndroid Build Coastguard Worker {
1785*f6dc9357SAndroid Build Coastguard Worker coder->blockPackSize_for_Index = (size_t)(coder->dec.blockHeaderSize + packSize + checkSize);
1786*f6dc9357SAndroid Build Coastguard Worker coder->blockPackTotal = (size_t)blockPackSum;
1787*f6dc9357SAndroid Build Coastguard Worker coder->outPreSize = (size_t)block->unpackSize;
1788*f6dc9357SAndroid Build Coastguard Worker coder->streamFlags = coder->dec.streamFlags;
1789*f6dc9357SAndroid Build Coastguard Worker me->streamFlags = coder->dec.streamFlags;
1790*f6dc9357SAndroid Build Coastguard Worker coder->skipMode = True;
1791*f6dc9357SAndroid Build Coastguard Worker break;
1792*f6dc9357SAndroid Build Coastguard Worker }
1793*f6dc9357SAndroid Build Coastguard Worker }
1794*f6dc9357SAndroid Build Coastguard Worker }
1795*f6dc9357SAndroid Build Coastguard Worker }
1796*f6dc9357SAndroid Build Coastguard Worker else
1797*f6dc9357SAndroid Build Coastguard Worker // if (coder->inPreSize <= me->props.inBlockMax)
1798*f6dc9357SAndroid Build Coastguard Worker {
1799*f6dc9357SAndroid Build Coastguard Worker if (!cc->srcFinished)
1800*f6dc9357SAndroid Build Coastguard Worker return; // SZ_OK;
1801*f6dc9357SAndroid Build Coastguard Worker cc->state =
1802*f6dc9357SAndroid Build Coastguard Worker coder->parseState = MTDEC_PARSE_END;
1803*f6dc9357SAndroid Build Coastguard Worker return; // SZ_OK;
1804*f6dc9357SAndroid Build Coastguard Worker }
1805*f6dc9357SAndroid Build Coastguard Worker cc->state = MTDEC_PARSE_OVERFLOW;
1806*f6dc9357SAndroid Build Coastguard Worker return; // SZ_OK;
1807*f6dc9357SAndroid Build Coastguard Worker }
1808*f6dc9357SAndroid Build Coastguard Worker
1809*f6dc9357SAndroid Build Coastguard Worker // ---------- skipMode ----------
1810*f6dc9357SAndroid Build Coastguard Worker {
1811*f6dc9357SAndroid Build Coastguard Worker UInt64 rem = coder->blockPackTotal - coder->inPreSize;
1812*f6dc9357SAndroid Build Coastguard Worker size_t cur = srcSize;
1813*f6dc9357SAndroid Build Coastguard Worker if (cur > rem)
1814*f6dc9357SAndroid Build Coastguard Worker cur = (size_t)rem;
1815*f6dc9357SAndroid Build Coastguard Worker cc->srcSize += cur;
1816*f6dc9357SAndroid Build Coastguard Worker coder->inPreSize += cur;
1817*f6dc9357SAndroid Build Coastguard Worker srcSize -= cur;
1818*f6dc9357SAndroid Build Coastguard Worker
1819*f6dc9357SAndroid Build Coastguard Worker if (coder->inPreSize == coder->blockPackTotal)
1820*f6dc9357SAndroid Build Coastguard Worker {
1821*f6dc9357SAndroid Build Coastguard Worker if (srcSize == 0)
1822*f6dc9357SAndroid Build Coastguard Worker {
1823*f6dc9357SAndroid Build Coastguard Worker if (!cc->srcFinished)
1824*f6dc9357SAndroid Build Coastguard Worker return; // SZ_OK;
1825*f6dc9357SAndroid Build Coastguard Worker cc->state = MTDEC_PARSE_END;
1826*f6dc9357SAndroid Build Coastguard Worker }
1827*f6dc9357SAndroid Build Coastguard Worker else if ((cc->src)[cc->srcSize] == 0) // we check control byte of next block
1828*f6dc9357SAndroid Build Coastguard Worker cc->state = MTDEC_PARSE_END;
1829*f6dc9357SAndroid Build Coastguard Worker else
1830*f6dc9357SAndroid Build Coastguard Worker {
1831*f6dc9357SAndroid Build Coastguard Worker cc->state = MTDEC_PARSE_NEW;
1832*f6dc9357SAndroid Build Coastguard Worker
1833*f6dc9357SAndroid Build Coastguard Worker {
1834*f6dc9357SAndroid Build Coastguard Worker size_t blockMax = me->unpackBlockMaxSize;
1835*f6dc9357SAndroid Build Coastguard Worker if (blockMax < coder->outPreSize)
1836*f6dc9357SAndroid Build Coastguard Worker blockMax = coder->outPreSize;
1837*f6dc9357SAndroid Build Coastguard Worker {
1838*f6dc9357SAndroid Build Coastguard Worker UInt64 required = (UInt64)blockMax * (me->mtc.numStartedThreads + 1) * 2;
1839*f6dc9357SAndroid Build Coastguard Worker if (me->props.memUseMax < required)
1840*f6dc9357SAndroid Build Coastguard Worker cc->canCreateNewThread = False;
1841*f6dc9357SAndroid Build Coastguard Worker }
1842*f6dc9357SAndroid Build Coastguard Worker }
1843*f6dc9357SAndroid Build Coastguard Worker
1844*f6dc9357SAndroid Build Coastguard Worker if (me->outSize_Defined)
1845*f6dc9357SAndroid Build Coastguard Worker {
1846*f6dc9357SAndroid Build Coastguard Worker // next block can be zero size
1847*f6dc9357SAndroid Build Coastguard Worker const UInt64 rem2 = me->outSize - me->outProcessed_Parse;
1848*f6dc9357SAndroid Build Coastguard Worker if (rem2 < coder->outPreSize)
1849*f6dc9357SAndroid Build Coastguard Worker {
1850*f6dc9357SAndroid Build Coastguard Worker coder->parsing_Truncated = True;
1851*f6dc9357SAndroid Build Coastguard Worker cc->state = MTDEC_PARSE_END;
1852*f6dc9357SAndroid Build Coastguard Worker }
1853*f6dc9357SAndroid Build Coastguard Worker me->outProcessed_Parse += coder->outPreSize;
1854*f6dc9357SAndroid Build Coastguard Worker }
1855*f6dc9357SAndroid Build Coastguard Worker }
1856*f6dc9357SAndroid Build Coastguard Worker }
1857*f6dc9357SAndroid Build Coastguard Worker else if (cc->srcFinished)
1858*f6dc9357SAndroid Build Coastguard Worker cc->state = MTDEC_PARSE_END;
1859*f6dc9357SAndroid Build Coastguard Worker else
1860*f6dc9357SAndroid Build Coastguard Worker return; // SZ_OK;
1861*f6dc9357SAndroid Build Coastguard Worker
1862*f6dc9357SAndroid Build Coastguard Worker coder->parseState = cc->state;
1863*f6dc9357SAndroid Build Coastguard Worker cc->outPos = coder->outPreSize;
1864*f6dc9357SAndroid Build Coastguard Worker
1865*f6dc9357SAndroid Build Coastguard Worker me->numStreams = coder->dec.numStartedStreams;
1866*f6dc9357SAndroid Build Coastguard Worker me->numTotalBlocks = coder->dec.numTotalBlocks;
1867*f6dc9357SAndroid Build Coastguard Worker me->numBlocks = coder->dec.numBlocks + 1;
1868*f6dc9357SAndroid Build Coastguard Worker return; // SZ_OK;
1869*f6dc9357SAndroid Build Coastguard Worker }
1870*f6dc9357SAndroid Build Coastguard Worker }
1871*f6dc9357SAndroid Build Coastguard Worker
1872*f6dc9357SAndroid Build Coastguard Worker
XzDecMt_Callback_PreCode(void * pp,unsigned coderIndex)1873*f6dc9357SAndroid Build Coastguard Worker static SRes XzDecMt_Callback_PreCode(void *pp, unsigned coderIndex)
1874*f6dc9357SAndroid Build Coastguard Worker {
1875*f6dc9357SAndroid Build Coastguard Worker CXzDecMt *me = (CXzDecMt *)pp;
1876*f6dc9357SAndroid Build Coastguard Worker CXzDecMtThread *coder = &me->coders[coderIndex];
1877*f6dc9357SAndroid Build Coastguard Worker Byte *dest;
1878*f6dc9357SAndroid Build Coastguard Worker
1879*f6dc9357SAndroid Build Coastguard Worker if (!coder->dec.headerParsedOk)
1880*f6dc9357SAndroid Build Coastguard Worker return SZ_OK;
1881*f6dc9357SAndroid Build Coastguard Worker
1882*f6dc9357SAndroid Build Coastguard Worker dest = coder->outBuf;
1883*f6dc9357SAndroid Build Coastguard Worker
1884*f6dc9357SAndroid Build Coastguard Worker if (!dest || coder->outBufSize < coder->outPreSize)
1885*f6dc9357SAndroid Build Coastguard Worker {
1886*f6dc9357SAndroid Build Coastguard Worker if (dest)
1887*f6dc9357SAndroid Build Coastguard Worker {
1888*f6dc9357SAndroid Build Coastguard Worker ISzAlloc_Free(me->allocMid, dest);
1889*f6dc9357SAndroid Build Coastguard Worker coder->outBuf = NULL;
1890*f6dc9357SAndroid Build Coastguard Worker coder->outBufSize = 0;
1891*f6dc9357SAndroid Build Coastguard Worker }
1892*f6dc9357SAndroid Build Coastguard Worker {
1893*f6dc9357SAndroid Build Coastguard Worker size_t outPreSize = coder->outPreSize;
1894*f6dc9357SAndroid Build Coastguard Worker if (outPreSize == 0)
1895*f6dc9357SAndroid Build Coastguard Worker outPreSize = 1;
1896*f6dc9357SAndroid Build Coastguard Worker dest = (Byte *)ISzAlloc_Alloc(me->allocMid, outPreSize);
1897*f6dc9357SAndroid Build Coastguard Worker }
1898*f6dc9357SAndroid Build Coastguard Worker if (!dest)
1899*f6dc9357SAndroid Build Coastguard Worker return SZ_ERROR_MEM;
1900*f6dc9357SAndroid Build Coastguard Worker coder->outBuf = dest;
1901*f6dc9357SAndroid Build Coastguard Worker coder->outBufSize = coder->outPreSize;
1902*f6dc9357SAndroid Build Coastguard Worker
1903*f6dc9357SAndroid Build Coastguard Worker if (coder->outBufSize > me->unpackBlockMaxSize)
1904*f6dc9357SAndroid Build Coastguard Worker me->unpackBlockMaxSize = coder->outBufSize;
1905*f6dc9357SAndroid Build Coastguard Worker }
1906*f6dc9357SAndroid Build Coastguard Worker
1907*f6dc9357SAndroid Build Coastguard Worker // return SZ_ERROR_MEM;
1908*f6dc9357SAndroid Build Coastguard Worker
1909*f6dc9357SAndroid Build Coastguard Worker XzUnpacker_SetOutBuf(&coder->dec, coder->outBuf, coder->outBufSize);
1910*f6dc9357SAndroid Build Coastguard Worker
1911*f6dc9357SAndroid Build Coastguard Worker {
1912*f6dc9357SAndroid Build Coastguard Worker SRes res = XzDecMix_Init(&coder->dec.decoder, &coder->dec.block, coder->outBuf, coder->outBufSize);
1913*f6dc9357SAndroid Build Coastguard Worker // res = SZ_ERROR_UNSUPPORTED; // to test
1914*f6dc9357SAndroid Build Coastguard Worker coder->codeRes = res;
1915*f6dc9357SAndroid Build Coastguard Worker if (res != SZ_OK)
1916*f6dc9357SAndroid Build Coastguard Worker {
1917*f6dc9357SAndroid Build Coastguard Worker // if (res == SZ_ERROR_MEM) return res;
1918*f6dc9357SAndroid Build Coastguard Worker if (me->props.ignoreErrors && res != SZ_ERROR_MEM)
1919*f6dc9357SAndroid Build Coastguard Worker return SZ_OK;
1920*f6dc9357SAndroid Build Coastguard Worker return res;
1921*f6dc9357SAndroid Build Coastguard Worker }
1922*f6dc9357SAndroid Build Coastguard Worker }
1923*f6dc9357SAndroid Build Coastguard Worker
1924*f6dc9357SAndroid Build Coastguard Worker return SZ_OK;
1925*f6dc9357SAndroid Build Coastguard Worker }
1926*f6dc9357SAndroid Build Coastguard Worker
1927*f6dc9357SAndroid Build Coastguard Worker
XzDecMt_Callback_Code(void * pp,unsigned coderIndex,const Byte * src,size_t srcSize,int srcFinished,UInt64 * inCodePos,UInt64 * outCodePos,int * stop)1928*f6dc9357SAndroid Build Coastguard Worker static SRes XzDecMt_Callback_Code(void *pp, unsigned coderIndex,
1929*f6dc9357SAndroid Build Coastguard Worker const Byte *src, size_t srcSize, int srcFinished,
1930*f6dc9357SAndroid Build Coastguard Worker // int finished, int blockFinished,
1931*f6dc9357SAndroid Build Coastguard Worker UInt64 *inCodePos, UInt64 *outCodePos, int *stop)
1932*f6dc9357SAndroid Build Coastguard Worker {
1933*f6dc9357SAndroid Build Coastguard Worker CXzDecMt *me = (CXzDecMt *)pp;
1934*f6dc9357SAndroid Build Coastguard Worker CXzDecMtThread *coder = &me->coders[coderIndex];
1935*f6dc9357SAndroid Build Coastguard Worker
1936*f6dc9357SAndroid Build Coastguard Worker *inCodePos = coder->inCodeSize;
1937*f6dc9357SAndroid Build Coastguard Worker *outCodePos = coder->outCodeSize;
1938*f6dc9357SAndroid Build Coastguard Worker *stop = True;
1939*f6dc9357SAndroid Build Coastguard Worker
1940*f6dc9357SAndroid Build Coastguard Worker if (srcSize > coder->inPreSize - coder->inCodeSize)
1941*f6dc9357SAndroid Build Coastguard Worker return SZ_ERROR_FAIL;
1942*f6dc9357SAndroid Build Coastguard Worker
1943*f6dc9357SAndroid Build Coastguard Worker if (coder->inCodeSize < coder->inPreHeaderSize)
1944*f6dc9357SAndroid Build Coastguard Worker {
1945*f6dc9357SAndroid Build Coastguard Worker size_t step = coder->inPreHeaderSize - coder->inCodeSize;
1946*f6dc9357SAndroid Build Coastguard Worker if (step > srcSize)
1947*f6dc9357SAndroid Build Coastguard Worker step = srcSize;
1948*f6dc9357SAndroid Build Coastguard Worker src += step;
1949*f6dc9357SAndroid Build Coastguard Worker srcSize -= step;
1950*f6dc9357SAndroid Build Coastguard Worker coder->inCodeSize += step;
1951*f6dc9357SAndroid Build Coastguard Worker *inCodePos = coder->inCodeSize;
1952*f6dc9357SAndroid Build Coastguard Worker if (coder->inCodeSize < coder->inPreHeaderSize)
1953*f6dc9357SAndroid Build Coastguard Worker {
1954*f6dc9357SAndroid Build Coastguard Worker *stop = False;
1955*f6dc9357SAndroid Build Coastguard Worker return SZ_OK;
1956*f6dc9357SAndroid Build Coastguard Worker }
1957*f6dc9357SAndroid Build Coastguard Worker }
1958*f6dc9357SAndroid Build Coastguard Worker
1959*f6dc9357SAndroid Build Coastguard Worker if (!coder->dec.headerParsedOk)
1960*f6dc9357SAndroid Build Coastguard Worker return SZ_OK;
1961*f6dc9357SAndroid Build Coastguard Worker if (!coder->outBuf)
1962*f6dc9357SAndroid Build Coastguard Worker return SZ_OK;
1963*f6dc9357SAndroid Build Coastguard Worker
1964*f6dc9357SAndroid Build Coastguard Worker if (coder->codeRes == SZ_OK)
1965*f6dc9357SAndroid Build Coastguard Worker {
1966*f6dc9357SAndroid Build Coastguard Worker ECoderStatus status;
1967*f6dc9357SAndroid Build Coastguard Worker SRes res;
1968*f6dc9357SAndroid Build Coastguard Worker size_t srcProcessed = srcSize;
1969*f6dc9357SAndroid Build Coastguard Worker size_t outSizeCur = coder->outPreSize - coder->dec.outDataWritten;
1970*f6dc9357SAndroid Build Coastguard Worker
1971*f6dc9357SAndroid Build Coastguard Worker // PRF(printf("\nCallback_Code: Code %d %d\n", (unsigned)srcSize, (unsigned)outSizeCur));
1972*f6dc9357SAndroid Build Coastguard Worker
1973*f6dc9357SAndroid Build Coastguard Worker res = XzUnpacker_Code(&coder->dec,
1974*f6dc9357SAndroid Build Coastguard Worker NULL, &outSizeCur,
1975*f6dc9357SAndroid Build Coastguard Worker src, &srcProcessed, srcFinished,
1976*f6dc9357SAndroid Build Coastguard Worker // coder->finishedWithMark ? CODER_FINISH_END : CODER_FINISH_ANY,
1977*f6dc9357SAndroid Build Coastguard Worker CODER_FINISH_END,
1978*f6dc9357SAndroid Build Coastguard Worker &status);
1979*f6dc9357SAndroid Build Coastguard Worker
1980*f6dc9357SAndroid Build Coastguard Worker // PRF(printf(" res = %d, srcSize2 = %d, outSizeCur = %d", res, (unsigned)srcProcessed, (unsigned)outSizeCur));
1981*f6dc9357SAndroid Build Coastguard Worker
1982*f6dc9357SAndroid Build Coastguard Worker coder->codeRes = res;
1983*f6dc9357SAndroid Build Coastguard Worker coder->status = status;
1984*f6dc9357SAndroid Build Coastguard Worker coder->inCodeSize += srcProcessed;
1985*f6dc9357SAndroid Build Coastguard Worker coder->outCodeSize = coder->dec.outDataWritten;
1986*f6dc9357SAndroid Build Coastguard Worker *inCodePos = coder->inCodeSize;
1987*f6dc9357SAndroid Build Coastguard Worker *outCodePos = coder->outCodeSize;
1988*f6dc9357SAndroid Build Coastguard Worker
1989*f6dc9357SAndroid Build Coastguard Worker if (res == SZ_OK)
1990*f6dc9357SAndroid Build Coastguard Worker {
1991*f6dc9357SAndroid Build Coastguard Worker if (srcProcessed == srcSize)
1992*f6dc9357SAndroid Build Coastguard Worker *stop = False;
1993*f6dc9357SAndroid Build Coastguard Worker return SZ_OK;
1994*f6dc9357SAndroid Build Coastguard Worker }
1995*f6dc9357SAndroid Build Coastguard Worker }
1996*f6dc9357SAndroid Build Coastguard Worker
1997*f6dc9357SAndroid Build Coastguard Worker if (me->props.ignoreErrors && coder->codeRes != SZ_ERROR_MEM)
1998*f6dc9357SAndroid Build Coastguard Worker {
1999*f6dc9357SAndroid Build Coastguard Worker *inCodePos = coder->inPreSize;
2000*f6dc9357SAndroid Build Coastguard Worker *outCodePos = coder->outPreSize;
2001*f6dc9357SAndroid Build Coastguard Worker return SZ_OK;
2002*f6dc9357SAndroid Build Coastguard Worker }
2003*f6dc9357SAndroid Build Coastguard Worker return coder->codeRes;
2004*f6dc9357SAndroid Build Coastguard Worker }
2005*f6dc9357SAndroid Build Coastguard Worker
2006*f6dc9357SAndroid Build Coastguard Worker
2007*f6dc9357SAndroid Build Coastguard Worker #define XZDECMT_STREAM_WRITE_STEP (1 << 24)
2008*f6dc9357SAndroid Build Coastguard Worker
XzDecMt_Callback_Write(void * pp,unsigned coderIndex,BoolInt needWriteToStream,const Byte * src,size_t srcSize,BoolInt isCross,BoolInt * needContinue,BoolInt * canRecode)2009*f6dc9357SAndroid Build Coastguard Worker static SRes XzDecMt_Callback_Write(void *pp, unsigned coderIndex,
2010*f6dc9357SAndroid Build Coastguard Worker BoolInt needWriteToStream,
2011*f6dc9357SAndroid Build Coastguard Worker const Byte *src, size_t srcSize, BoolInt isCross,
2012*f6dc9357SAndroid Build Coastguard Worker // int srcFinished,
2013*f6dc9357SAndroid Build Coastguard Worker BoolInt *needContinue,
2014*f6dc9357SAndroid Build Coastguard Worker BoolInt *canRecode)
2015*f6dc9357SAndroid Build Coastguard Worker {
2016*f6dc9357SAndroid Build Coastguard Worker CXzDecMt *me = (CXzDecMt *)pp;
2017*f6dc9357SAndroid Build Coastguard Worker const CXzDecMtThread *coder = &me->coders[coderIndex];
2018*f6dc9357SAndroid Build Coastguard Worker
2019*f6dc9357SAndroid Build Coastguard Worker // PRF(printf("\nWrite processed = %d srcSize = %d\n", (unsigned)me->mtc.inProcessed, (unsigned)srcSize));
2020*f6dc9357SAndroid Build Coastguard Worker
2021*f6dc9357SAndroid Build Coastguard Worker *needContinue = False;
2022*f6dc9357SAndroid Build Coastguard Worker *canRecode = True;
2023*f6dc9357SAndroid Build Coastguard Worker
2024*f6dc9357SAndroid Build Coastguard Worker if (!needWriteToStream)
2025*f6dc9357SAndroid Build Coastguard Worker return SZ_OK;
2026*f6dc9357SAndroid Build Coastguard Worker
2027*f6dc9357SAndroid Build Coastguard Worker if (!coder->dec.headerParsedOk || !coder->outBuf)
2028*f6dc9357SAndroid Build Coastguard Worker {
2029*f6dc9357SAndroid Build Coastguard Worker if (me->finishedDecoderIndex < 0)
2030*f6dc9357SAndroid Build Coastguard Worker me->finishedDecoderIndex = (int)coderIndex;
2031*f6dc9357SAndroid Build Coastguard Worker return SZ_OK;
2032*f6dc9357SAndroid Build Coastguard Worker }
2033*f6dc9357SAndroid Build Coastguard Worker
2034*f6dc9357SAndroid Build Coastguard Worker if (me->finishedDecoderIndex >= 0)
2035*f6dc9357SAndroid Build Coastguard Worker return SZ_OK;
2036*f6dc9357SAndroid Build Coastguard Worker
2037*f6dc9357SAndroid Build Coastguard Worker me->mtc.inProcessed += coder->inCodeSize;
2038*f6dc9357SAndroid Build Coastguard Worker
2039*f6dc9357SAndroid Build Coastguard Worker *canRecode = False;
2040*f6dc9357SAndroid Build Coastguard Worker
2041*f6dc9357SAndroid Build Coastguard Worker {
2042*f6dc9357SAndroid Build Coastguard Worker SRes res;
2043*f6dc9357SAndroid Build Coastguard Worker size_t size = coder->outCodeSize;
2044*f6dc9357SAndroid Build Coastguard Worker Byte *data = coder->outBuf;
2045*f6dc9357SAndroid Build Coastguard Worker
2046*f6dc9357SAndroid Build Coastguard Worker // we use in me->dec: sha, numBlocks, indexSize
2047*f6dc9357SAndroid Build Coastguard Worker
2048*f6dc9357SAndroid Build Coastguard Worker if (!me->isBlockHeaderState_Write)
2049*f6dc9357SAndroid Build Coastguard Worker {
2050*f6dc9357SAndroid Build Coastguard Worker XzUnpacker_PrepareToRandomBlockDecoding(&me->dec);
2051*f6dc9357SAndroid Build Coastguard Worker me->dec.decodeOnlyOneBlock = False;
2052*f6dc9357SAndroid Build Coastguard Worker me->dec.numStartedStreams = coder->dec.numStartedStreams;
2053*f6dc9357SAndroid Build Coastguard Worker me->dec.streamFlags = coder->streamFlags;
2054*f6dc9357SAndroid Build Coastguard Worker
2055*f6dc9357SAndroid Build Coastguard Worker me->isBlockHeaderState_Write = True;
2056*f6dc9357SAndroid Build Coastguard Worker }
2057*f6dc9357SAndroid Build Coastguard Worker
2058*f6dc9357SAndroid Build Coastguard Worker me->dec.numTotalBlocks = coder->dec.numTotalBlocks;
2059*f6dc9357SAndroid Build Coastguard Worker XzUnpacker_UpdateIndex(&me->dec, coder->blockPackSize_for_Index, coder->outPreSize);
2060*f6dc9357SAndroid Build Coastguard Worker
2061*f6dc9357SAndroid Build Coastguard Worker if (coder->outPreSize != size)
2062*f6dc9357SAndroid Build Coastguard Worker {
2063*f6dc9357SAndroid Build Coastguard Worker if (me->props.ignoreErrors)
2064*f6dc9357SAndroid Build Coastguard Worker {
2065*f6dc9357SAndroid Build Coastguard Worker memset(data + size, 0, coder->outPreSize - size);
2066*f6dc9357SAndroid Build Coastguard Worker size = coder->outPreSize;
2067*f6dc9357SAndroid Build Coastguard Worker }
2068*f6dc9357SAndroid Build Coastguard Worker // me->numBadBlocks++;
2069*f6dc9357SAndroid Build Coastguard Worker if (me->mainErrorCode == SZ_OK)
2070*f6dc9357SAndroid Build Coastguard Worker {
2071*f6dc9357SAndroid Build Coastguard Worker if ((int)coder->status == LZMA_STATUS_NEEDS_MORE_INPUT)
2072*f6dc9357SAndroid Build Coastguard Worker me->mainErrorCode = SZ_ERROR_INPUT_EOF;
2073*f6dc9357SAndroid Build Coastguard Worker else
2074*f6dc9357SAndroid Build Coastguard Worker me->mainErrorCode = SZ_ERROR_DATA;
2075*f6dc9357SAndroid Build Coastguard Worker }
2076*f6dc9357SAndroid Build Coastguard Worker }
2077*f6dc9357SAndroid Build Coastguard Worker
2078*f6dc9357SAndroid Build Coastguard Worker if (me->writeRes != SZ_OK)
2079*f6dc9357SAndroid Build Coastguard Worker return me->writeRes;
2080*f6dc9357SAndroid Build Coastguard Worker
2081*f6dc9357SAndroid Build Coastguard Worker res = SZ_OK;
2082*f6dc9357SAndroid Build Coastguard Worker {
2083*f6dc9357SAndroid Build Coastguard Worker if (me->outSize_Defined)
2084*f6dc9357SAndroid Build Coastguard Worker {
2085*f6dc9357SAndroid Build Coastguard Worker const UInt64 rem = me->outSize - me->outProcessed;
2086*f6dc9357SAndroid Build Coastguard Worker if (size > rem)
2087*f6dc9357SAndroid Build Coastguard Worker size = (SizeT)rem;
2088*f6dc9357SAndroid Build Coastguard Worker }
2089*f6dc9357SAndroid Build Coastguard Worker
2090*f6dc9357SAndroid Build Coastguard Worker for (;;)
2091*f6dc9357SAndroid Build Coastguard Worker {
2092*f6dc9357SAndroid Build Coastguard Worker size_t cur = size;
2093*f6dc9357SAndroid Build Coastguard Worker size_t written;
2094*f6dc9357SAndroid Build Coastguard Worker if (cur > XZDECMT_STREAM_WRITE_STEP)
2095*f6dc9357SAndroid Build Coastguard Worker cur = XZDECMT_STREAM_WRITE_STEP;
2096*f6dc9357SAndroid Build Coastguard Worker
2097*f6dc9357SAndroid Build Coastguard Worker written = ISeqOutStream_Write(me->outStream, data, cur);
2098*f6dc9357SAndroid Build Coastguard Worker
2099*f6dc9357SAndroid Build Coastguard Worker // PRF(printf("\nWritten ask = %d written = %d\n", (unsigned)cur, (unsigned)written));
2100*f6dc9357SAndroid Build Coastguard Worker
2101*f6dc9357SAndroid Build Coastguard Worker me->outProcessed += written;
2102*f6dc9357SAndroid Build Coastguard Worker if (written != cur)
2103*f6dc9357SAndroid Build Coastguard Worker {
2104*f6dc9357SAndroid Build Coastguard Worker me->writeRes = SZ_ERROR_WRITE;
2105*f6dc9357SAndroid Build Coastguard Worker res = me->writeRes;
2106*f6dc9357SAndroid Build Coastguard Worker break;
2107*f6dc9357SAndroid Build Coastguard Worker }
2108*f6dc9357SAndroid Build Coastguard Worker data += cur;
2109*f6dc9357SAndroid Build Coastguard Worker size -= cur;
2110*f6dc9357SAndroid Build Coastguard Worker // PRF_STR_INT("Written size =", size)
2111*f6dc9357SAndroid Build Coastguard Worker if (size == 0)
2112*f6dc9357SAndroid Build Coastguard Worker break;
2113*f6dc9357SAndroid Build Coastguard Worker res = MtProgress_ProgressAdd(&me->mtc.mtProgress, 0, 0);
2114*f6dc9357SAndroid Build Coastguard Worker if (res != SZ_OK)
2115*f6dc9357SAndroid Build Coastguard Worker break;
2116*f6dc9357SAndroid Build Coastguard Worker }
2117*f6dc9357SAndroid Build Coastguard Worker }
2118*f6dc9357SAndroid Build Coastguard Worker
2119*f6dc9357SAndroid Build Coastguard Worker if (coder->codeRes != SZ_OK)
2120*f6dc9357SAndroid Build Coastguard Worker if (!me->props.ignoreErrors)
2121*f6dc9357SAndroid Build Coastguard Worker {
2122*f6dc9357SAndroid Build Coastguard Worker me->finishedDecoderIndex = (int)coderIndex;
2123*f6dc9357SAndroid Build Coastguard Worker return res;
2124*f6dc9357SAndroid Build Coastguard Worker }
2125*f6dc9357SAndroid Build Coastguard Worker
2126*f6dc9357SAndroid Build Coastguard Worker RINOK(res)
2127*f6dc9357SAndroid Build Coastguard Worker
2128*f6dc9357SAndroid Build Coastguard Worker if (coder->inPreSize != coder->inCodeSize
2129*f6dc9357SAndroid Build Coastguard Worker || coder->blockPackTotal != coder->inCodeSize)
2130*f6dc9357SAndroid Build Coastguard Worker {
2131*f6dc9357SAndroid Build Coastguard Worker me->finishedDecoderIndex = (int)coderIndex;
2132*f6dc9357SAndroid Build Coastguard Worker return SZ_OK;
2133*f6dc9357SAndroid Build Coastguard Worker }
2134*f6dc9357SAndroid Build Coastguard Worker
2135*f6dc9357SAndroid Build Coastguard Worker if (coder->parseState != MTDEC_PARSE_END)
2136*f6dc9357SAndroid Build Coastguard Worker {
2137*f6dc9357SAndroid Build Coastguard Worker *needContinue = True;
2138*f6dc9357SAndroid Build Coastguard Worker return SZ_OK;
2139*f6dc9357SAndroid Build Coastguard Worker }
2140*f6dc9357SAndroid Build Coastguard Worker }
2141*f6dc9357SAndroid Build Coastguard Worker
2142*f6dc9357SAndroid Build Coastguard Worker // (coder->state == MTDEC_PARSE_END) means that there are no other working threads
2143*f6dc9357SAndroid Build Coastguard Worker // so we can use mtc variables without lock
2144*f6dc9357SAndroid Build Coastguard Worker
2145*f6dc9357SAndroid Build Coastguard Worker PRF_STR_INT("Write MTDEC_PARSE_END", me->mtc.inProcessed)
2146*f6dc9357SAndroid Build Coastguard Worker
2147*f6dc9357SAndroid Build Coastguard Worker me->mtc.mtProgress.totalInSize = me->mtc.inProcessed;
2148*f6dc9357SAndroid Build Coastguard Worker {
2149*f6dc9357SAndroid Build Coastguard Worker CXzUnpacker *dec = &me->dec;
2150*f6dc9357SAndroid Build Coastguard Worker
2151*f6dc9357SAndroid Build Coastguard Worker PRF_STR_INT("PostSingle", srcSize)
2152*f6dc9357SAndroid Build Coastguard Worker
2153*f6dc9357SAndroid Build Coastguard Worker {
2154*f6dc9357SAndroid Build Coastguard Worker size_t srcProcessed = srcSize;
2155*f6dc9357SAndroid Build Coastguard Worker ECoderStatus status;
2156*f6dc9357SAndroid Build Coastguard Worker size_t outSizeCur = 0;
2157*f6dc9357SAndroid Build Coastguard Worker SRes res;
2158*f6dc9357SAndroid Build Coastguard Worker
2159*f6dc9357SAndroid Build Coastguard Worker // dec->decodeOnlyOneBlock = False;
2160*f6dc9357SAndroid Build Coastguard Worker dec->decodeToStreamSignature = True;
2161*f6dc9357SAndroid Build Coastguard Worker
2162*f6dc9357SAndroid Build Coastguard Worker me->mainDecoderWasCalled = True;
2163*f6dc9357SAndroid Build Coastguard Worker
2164*f6dc9357SAndroid Build Coastguard Worker if (coder->parsing_Truncated)
2165*f6dc9357SAndroid Build Coastguard Worker {
2166*f6dc9357SAndroid Build Coastguard Worker me->parsing_Truncated = True;
2167*f6dc9357SAndroid Build Coastguard Worker return SZ_OK;
2168*f6dc9357SAndroid Build Coastguard Worker }
2169*f6dc9357SAndroid Build Coastguard Worker
2170*f6dc9357SAndroid Build Coastguard Worker /*
2171*f6dc9357SAndroid Build Coastguard Worker We have processed all xz-blocks of stream,
2172*f6dc9357SAndroid Build Coastguard Worker And xz unpacker is at XZ_STATE_BLOCK_HEADER state, where
2173*f6dc9357SAndroid Build Coastguard Worker (src) is a pointer to xz-Index structure.
2174*f6dc9357SAndroid Build Coastguard Worker We finish reading of current xz-Stream, including Zero padding after xz-Stream.
2175*f6dc9357SAndroid Build Coastguard Worker We exit, if we reach extra byte (first byte of new-Stream or another data).
2176*f6dc9357SAndroid Build Coastguard Worker But we don't update input stream pointer for that new extra byte.
2177*f6dc9357SAndroid Build Coastguard Worker If extra byte is not correct first byte of xz-signature,
2178*f6dc9357SAndroid Build Coastguard Worker we have SZ_ERROR_NO_ARCHIVE error here.
2179*f6dc9357SAndroid Build Coastguard Worker */
2180*f6dc9357SAndroid Build Coastguard Worker
2181*f6dc9357SAndroid Build Coastguard Worker res = XzUnpacker_Code(dec,
2182*f6dc9357SAndroid Build Coastguard Worker NULL, &outSizeCur,
2183*f6dc9357SAndroid Build Coastguard Worker src, &srcProcessed,
2184*f6dc9357SAndroid Build Coastguard Worker me->mtc.readWasFinished, // srcFinished
2185*f6dc9357SAndroid Build Coastguard Worker CODER_FINISH_END, // CODER_FINISH_ANY,
2186*f6dc9357SAndroid Build Coastguard Worker &status);
2187*f6dc9357SAndroid Build Coastguard Worker
2188*f6dc9357SAndroid Build Coastguard Worker // res = SZ_ERROR_ARCHIVE; // for failure test
2189*f6dc9357SAndroid Build Coastguard Worker
2190*f6dc9357SAndroid Build Coastguard Worker me->status = status;
2191*f6dc9357SAndroid Build Coastguard Worker me->codeRes = res;
2192*f6dc9357SAndroid Build Coastguard Worker
2193*f6dc9357SAndroid Build Coastguard Worker if (isCross)
2194*f6dc9357SAndroid Build Coastguard Worker me->mtc.crossStart += srcProcessed;
2195*f6dc9357SAndroid Build Coastguard Worker
2196*f6dc9357SAndroid Build Coastguard Worker me->mtc.inProcessed += srcProcessed;
2197*f6dc9357SAndroid Build Coastguard Worker me->mtc.mtProgress.totalInSize = me->mtc.inProcessed;
2198*f6dc9357SAndroid Build Coastguard Worker
2199*f6dc9357SAndroid Build Coastguard Worker srcSize -= srcProcessed;
2200*f6dc9357SAndroid Build Coastguard Worker src += srcProcessed;
2201*f6dc9357SAndroid Build Coastguard Worker
2202*f6dc9357SAndroid Build Coastguard Worker if (res != SZ_OK)
2203*f6dc9357SAndroid Build Coastguard Worker {
2204*f6dc9357SAndroid Build Coastguard Worker return SZ_OK;
2205*f6dc9357SAndroid Build Coastguard Worker // return res;
2206*f6dc9357SAndroid Build Coastguard Worker }
2207*f6dc9357SAndroid Build Coastguard Worker
2208*f6dc9357SAndroid Build Coastguard Worker if (dec->state == XZ_STATE_STREAM_HEADER)
2209*f6dc9357SAndroid Build Coastguard Worker {
2210*f6dc9357SAndroid Build Coastguard Worker *needContinue = True;
2211*f6dc9357SAndroid Build Coastguard Worker me->isBlockHeaderState_Parse = False;
2212*f6dc9357SAndroid Build Coastguard Worker me->isBlockHeaderState_Write = False;
2213*f6dc9357SAndroid Build Coastguard Worker
2214*f6dc9357SAndroid Build Coastguard Worker if (!isCross)
2215*f6dc9357SAndroid Build Coastguard Worker {
2216*f6dc9357SAndroid Build Coastguard Worker Byte *crossBuf = MtDec_GetCrossBuff(&me->mtc);
2217*f6dc9357SAndroid Build Coastguard Worker if (!crossBuf)
2218*f6dc9357SAndroid Build Coastguard Worker return SZ_ERROR_MEM;
2219*f6dc9357SAndroid Build Coastguard Worker if (srcSize != 0)
2220*f6dc9357SAndroid Build Coastguard Worker memcpy(crossBuf, src, srcSize);
2221*f6dc9357SAndroid Build Coastguard Worker me->mtc.crossStart = 0;
2222*f6dc9357SAndroid Build Coastguard Worker me->mtc.crossEnd = srcSize;
2223*f6dc9357SAndroid Build Coastguard Worker }
2224*f6dc9357SAndroid Build Coastguard Worker
2225*f6dc9357SAndroid Build Coastguard Worker PRF_STR_INT("XZ_STATE_STREAM_HEADER crossEnd = ", (unsigned)me->mtc.crossEnd)
2226*f6dc9357SAndroid Build Coastguard Worker
2227*f6dc9357SAndroid Build Coastguard Worker return SZ_OK;
2228*f6dc9357SAndroid Build Coastguard Worker }
2229*f6dc9357SAndroid Build Coastguard Worker
2230*f6dc9357SAndroid Build Coastguard Worker if (status != CODER_STATUS_NEEDS_MORE_INPUT || srcSize != 0)
2231*f6dc9357SAndroid Build Coastguard Worker {
2232*f6dc9357SAndroid Build Coastguard Worker return SZ_ERROR_FAIL;
2233*f6dc9357SAndroid Build Coastguard Worker }
2234*f6dc9357SAndroid Build Coastguard Worker
2235*f6dc9357SAndroid Build Coastguard Worker if (me->mtc.readWasFinished)
2236*f6dc9357SAndroid Build Coastguard Worker {
2237*f6dc9357SAndroid Build Coastguard Worker return SZ_OK;
2238*f6dc9357SAndroid Build Coastguard Worker }
2239*f6dc9357SAndroid Build Coastguard Worker }
2240*f6dc9357SAndroid Build Coastguard Worker
2241*f6dc9357SAndroid Build Coastguard Worker {
2242*f6dc9357SAndroid Build Coastguard Worker size_t inPos;
2243*f6dc9357SAndroid Build Coastguard Worker size_t inLim;
2244*f6dc9357SAndroid Build Coastguard Worker // const Byte *inData;
2245*f6dc9357SAndroid Build Coastguard Worker UInt64 inProgressPrev = me->mtc.inProcessed;
2246*f6dc9357SAndroid Build Coastguard Worker
2247*f6dc9357SAndroid Build Coastguard Worker // XzDecMt_Prepare_InBuf_ST(p);
2248*f6dc9357SAndroid Build Coastguard Worker Byte *crossBuf = MtDec_GetCrossBuff(&me->mtc);
2249*f6dc9357SAndroid Build Coastguard Worker if (!crossBuf)
2250*f6dc9357SAndroid Build Coastguard Worker return SZ_ERROR_MEM;
2251*f6dc9357SAndroid Build Coastguard Worker
2252*f6dc9357SAndroid Build Coastguard Worker inPos = 0;
2253*f6dc9357SAndroid Build Coastguard Worker inLim = 0;
2254*f6dc9357SAndroid Build Coastguard Worker
2255*f6dc9357SAndroid Build Coastguard Worker // inData = crossBuf;
2256*f6dc9357SAndroid Build Coastguard Worker
2257*f6dc9357SAndroid Build Coastguard Worker for (;;)
2258*f6dc9357SAndroid Build Coastguard Worker {
2259*f6dc9357SAndroid Build Coastguard Worker SizeT inProcessed;
2260*f6dc9357SAndroid Build Coastguard Worker SizeT outProcessed;
2261*f6dc9357SAndroid Build Coastguard Worker ECoderStatus status;
2262*f6dc9357SAndroid Build Coastguard Worker SRes res;
2263*f6dc9357SAndroid Build Coastguard Worker
2264*f6dc9357SAndroid Build Coastguard Worker if (inPos == inLim)
2265*f6dc9357SAndroid Build Coastguard Worker {
2266*f6dc9357SAndroid Build Coastguard Worker if (!me->mtc.readWasFinished)
2267*f6dc9357SAndroid Build Coastguard Worker {
2268*f6dc9357SAndroid Build Coastguard Worker inPos = 0;
2269*f6dc9357SAndroid Build Coastguard Worker inLim = me->mtc.inBufSize;
2270*f6dc9357SAndroid Build Coastguard Worker me->mtc.readRes = ISeqInStream_Read(me->inStream, (void *)crossBuf, &inLim);
2271*f6dc9357SAndroid Build Coastguard Worker me->mtc.readProcessed += inLim;
2272*f6dc9357SAndroid Build Coastguard Worker if (inLim == 0 || me->mtc.readRes != SZ_OK)
2273*f6dc9357SAndroid Build Coastguard Worker me->mtc.readWasFinished = True;
2274*f6dc9357SAndroid Build Coastguard Worker }
2275*f6dc9357SAndroid Build Coastguard Worker }
2276*f6dc9357SAndroid Build Coastguard Worker
2277*f6dc9357SAndroid Build Coastguard Worker inProcessed = inLim - inPos;
2278*f6dc9357SAndroid Build Coastguard Worker outProcessed = 0;
2279*f6dc9357SAndroid Build Coastguard Worker
2280*f6dc9357SAndroid Build Coastguard Worker res = XzUnpacker_Code(dec,
2281*f6dc9357SAndroid Build Coastguard Worker NULL, &outProcessed,
2282*f6dc9357SAndroid Build Coastguard Worker crossBuf + inPos, &inProcessed,
2283*f6dc9357SAndroid Build Coastguard Worker (inProcessed == 0), // srcFinished
2284*f6dc9357SAndroid Build Coastguard Worker CODER_FINISH_END, &status);
2285*f6dc9357SAndroid Build Coastguard Worker
2286*f6dc9357SAndroid Build Coastguard Worker me->codeRes = res;
2287*f6dc9357SAndroid Build Coastguard Worker me->status = status;
2288*f6dc9357SAndroid Build Coastguard Worker inPos += inProcessed;
2289*f6dc9357SAndroid Build Coastguard Worker me->mtc.inProcessed += inProcessed;
2290*f6dc9357SAndroid Build Coastguard Worker me->mtc.mtProgress.totalInSize = me->mtc.inProcessed;
2291*f6dc9357SAndroid Build Coastguard Worker
2292*f6dc9357SAndroid Build Coastguard Worker if (res != SZ_OK)
2293*f6dc9357SAndroid Build Coastguard Worker {
2294*f6dc9357SAndroid Build Coastguard Worker return SZ_OK;
2295*f6dc9357SAndroid Build Coastguard Worker // return res;
2296*f6dc9357SAndroid Build Coastguard Worker }
2297*f6dc9357SAndroid Build Coastguard Worker
2298*f6dc9357SAndroid Build Coastguard Worker if (dec->state == XZ_STATE_STREAM_HEADER)
2299*f6dc9357SAndroid Build Coastguard Worker {
2300*f6dc9357SAndroid Build Coastguard Worker *needContinue = True;
2301*f6dc9357SAndroid Build Coastguard Worker me->mtc.crossStart = inPos;
2302*f6dc9357SAndroid Build Coastguard Worker me->mtc.crossEnd = inLim;
2303*f6dc9357SAndroid Build Coastguard Worker me->isBlockHeaderState_Parse = False;
2304*f6dc9357SAndroid Build Coastguard Worker me->isBlockHeaderState_Write = False;
2305*f6dc9357SAndroid Build Coastguard Worker return SZ_OK;
2306*f6dc9357SAndroid Build Coastguard Worker }
2307*f6dc9357SAndroid Build Coastguard Worker
2308*f6dc9357SAndroid Build Coastguard Worker if (status != CODER_STATUS_NEEDS_MORE_INPUT)
2309*f6dc9357SAndroid Build Coastguard Worker return SZ_ERROR_FAIL;
2310*f6dc9357SAndroid Build Coastguard Worker
2311*f6dc9357SAndroid Build Coastguard Worker if (me->mtc.progress)
2312*f6dc9357SAndroid Build Coastguard Worker {
2313*f6dc9357SAndroid Build Coastguard Worker UInt64 inDelta = me->mtc.inProcessed - inProgressPrev;
2314*f6dc9357SAndroid Build Coastguard Worker if (inDelta >= (1 << 22))
2315*f6dc9357SAndroid Build Coastguard Worker {
2316*f6dc9357SAndroid Build Coastguard Worker RINOK(MtProgress_Progress_ST(&me->mtc.mtProgress))
2317*f6dc9357SAndroid Build Coastguard Worker inProgressPrev = me->mtc.inProcessed;
2318*f6dc9357SAndroid Build Coastguard Worker }
2319*f6dc9357SAndroid Build Coastguard Worker }
2320*f6dc9357SAndroid Build Coastguard Worker if (me->mtc.readWasFinished)
2321*f6dc9357SAndroid Build Coastguard Worker return SZ_OK;
2322*f6dc9357SAndroid Build Coastguard Worker }
2323*f6dc9357SAndroid Build Coastguard Worker }
2324*f6dc9357SAndroid Build Coastguard Worker }
2325*f6dc9357SAndroid Build Coastguard Worker }
2326*f6dc9357SAndroid Build Coastguard Worker
2327*f6dc9357SAndroid Build Coastguard Worker
2328*f6dc9357SAndroid Build Coastguard Worker #endif
2329*f6dc9357SAndroid Build Coastguard Worker
2330*f6dc9357SAndroid Build Coastguard Worker
2331*f6dc9357SAndroid Build Coastguard Worker
XzStatInfo_Clear(CXzStatInfo * p)2332*f6dc9357SAndroid Build Coastguard Worker void XzStatInfo_Clear(CXzStatInfo *p)
2333*f6dc9357SAndroid Build Coastguard Worker {
2334*f6dc9357SAndroid Build Coastguard Worker p->InSize = 0;
2335*f6dc9357SAndroid Build Coastguard Worker p->OutSize = 0;
2336*f6dc9357SAndroid Build Coastguard Worker
2337*f6dc9357SAndroid Build Coastguard Worker p->NumStreams = 0;
2338*f6dc9357SAndroid Build Coastguard Worker p->NumBlocks = 0;
2339*f6dc9357SAndroid Build Coastguard Worker
2340*f6dc9357SAndroid Build Coastguard Worker p->UnpackSize_Defined = False;
2341*f6dc9357SAndroid Build Coastguard Worker
2342*f6dc9357SAndroid Build Coastguard Worker p->NumStreams_Defined = False;
2343*f6dc9357SAndroid Build Coastguard Worker p->NumBlocks_Defined = False;
2344*f6dc9357SAndroid Build Coastguard Worker
2345*f6dc9357SAndroid Build Coastguard Worker p->DataAfterEnd = False;
2346*f6dc9357SAndroid Build Coastguard Worker p->DecodingTruncated = False;
2347*f6dc9357SAndroid Build Coastguard Worker
2348*f6dc9357SAndroid Build Coastguard Worker p->DecodeRes = SZ_OK;
2349*f6dc9357SAndroid Build Coastguard Worker p->ReadRes = SZ_OK;
2350*f6dc9357SAndroid Build Coastguard Worker p->ProgressRes = SZ_OK;
2351*f6dc9357SAndroid Build Coastguard Worker
2352*f6dc9357SAndroid Build Coastguard Worker p->CombinedRes = SZ_OK;
2353*f6dc9357SAndroid Build Coastguard Worker p->CombinedRes_Type = SZ_OK;
2354*f6dc9357SAndroid Build Coastguard Worker }
2355*f6dc9357SAndroid Build Coastguard Worker
2356*f6dc9357SAndroid Build Coastguard Worker
2357*f6dc9357SAndroid Build Coastguard Worker
2358*f6dc9357SAndroid Build Coastguard Worker /*
2359*f6dc9357SAndroid Build Coastguard Worker XzDecMt_Decode_ST() can return SZ_OK or the following errors
2360*f6dc9357SAndroid Build Coastguard Worker - SZ_ERROR_MEM for memory allocation error
2361*f6dc9357SAndroid Build Coastguard Worker - error from XzUnpacker_Code() function
2362*f6dc9357SAndroid Build Coastguard Worker - SZ_ERROR_WRITE for ISeqOutStream::Write(). stat->CombinedRes_Type = SZ_ERROR_WRITE in that case
2363*f6dc9357SAndroid Build Coastguard Worker - ICompressProgress::Progress() error, stat->CombinedRes_Type = SZ_ERROR_PROGRESS.
2364*f6dc9357SAndroid Build Coastguard Worker But XzDecMt_Decode_ST() doesn't return ISeqInStream::Read() errors.
2365*f6dc9357SAndroid Build Coastguard Worker ISeqInStream::Read() result is set to p->readRes.
2366*f6dc9357SAndroid Build Coastguard Worker also it can set stat->CombinedRes_Type to SZ_ERROR_WRITE or SZ_ERROR_PROGRESS.
2367*f6dc9357SAndroid Build Coastguard Worker */
2368*f6dc9357SAndroid Build Coastguard Worker
XzDecMt_Decode_ST(CXzDecMt * p,BoolInt tMode,CXzStatInfo * stat)2369*f6dc9357SAndroid Build Coastguard Worker static SRes XzDecMt_Decode_ST(CXzDecMt *p
2370*f6dc9357SAndroid Build Coastguard Worker #ifndef Z7_ST
2371*f6dc9357SAndroid Build Coastguard Worker , BoolInt tMode
2372*f6dc9357SAndroid Build Coastguard Worker #endif
2373*f6dc9357SAndroid Build Coastguard Worker , CXzStatInfo *stat)
2374*f6dc9357SAndroid Build Coastguard Worker {
2375*f6dc9357SAndroid Build Coastguard Worker size_t outPos;
2376*f6dc9357SAndroid Build Coastguard Worker size_t inPos, inLim;
2377*f6dc9357SAndroid Build Coastguard Worker const Byte *inData;
2378*f6dc9357SAndroid Build Coastguard Worker UInt64 inPrev, outPrev;
2379*f6dc9357SAndroid Build Coastguard Worker
2380*f6dc9357SAndroid Build Coastguard Worker CXzUnpacker *dec;
2381*f6dc9357SAndroid Build Coastguard Worker
2382*f6dc9357SAndroid Build Coastguard Worker #ifndef Z7_ST
2383*f6dc9357SAndroid Build Coastguard Worker if (tMode)
2384*f6dc9357SAndroid Build Coastguard Worker {
2385*f6dc9357SAndroid Build Coastguard Worker XzDecMt_FreeOutBufs(p);
2386*f6dc9357SAndroid Build Coastguard Worker tMode = (BoolInt)MtDec_PrepareRead(&p->mtc);
2387*f6dc9357SAndroid Build Coastguard Worker }
2388*f6dc9357SAndroid Build Coastguard Worker #endif
2389*f6dc9357SAndroid Build Coastguard Worker
2390*f6dc9357SAndroid Build Coastguard Worker if (!p->outBuf || p->outBufSize != p->props.outStep_ST)
2391*f6dc9357SAndroid Build Coastguard Worker {
2392*f6dc9357SAndroid Build Coastguard Worker ISzAlloc_Free(p->allocMid, p->outBuf);
2393*f6dc9357SAndroid Build Coastguard Worker p->outBufSize = 0;
2394*f6dc9357SAndroid Build Coastguard Worker p->outBuf = (Byte *)ISzAlloc_Alloc(p->allocMid, p->props.outStep_ST);
2395*f6dc9357SAndroid Build Coastguard Worker if (!p->outBuf)
2396*f6dc9357SAndroid Build Coastguard Worker return SZ_ERROR_MEM;
2397*f6dc9357SAndroid Build Coastguard Worker p->outBufSize = p->props.outStep_ST;
2398*f6dc9357SAndroid Build Coastguard Worker }
2399*f6dc9357SAndroid Build Coastguard Worker
2400*f6dc9357SAndroid Build Coastguard Worker if (!p->inBuf || p->inBufSize != p->props.inBufSize_ST)
2401*f6dc9357SAndroid Build Coastguard Worker {
2402*f6dc9357SAndroid Build Coastguard Worker ISzAlloc_Free(p->allocMid, p->inBuf);
2403*f6dc9357SAndroid Build Coastguard Worker p->inBufSize = 0;
2404*f6dc9357SAndroid Build Coastguard Worker p->inBuf = (Byte *)ISzAlloc_Alloc(p->allocMid, p->props.inBufSize_ST);
2405*f6dc9357SAndroid Build Coastguard Worker if (!p->inBuf)
2406*f6dc9357SAndroid Build Coastguard Worker return SZ_ERROR_MEM;
2407*f6dc9357SAndroid Build Coastguard Worker p->inBufSize = p->props.inBufSize_ST;
2408*f6dc9357SAndroid Build Coastguard Worker }
2409*f6dc9357SAndroid Build Coastguard Worker
2410*f6dc9357SAndroid Build Coastguard Worker dec = &p->dec;
2411*f6dc9357SAndroid Build Coastguard Worker dec->decodeToStreamSignature = False;
2412*f6dc9357SAndroid Build Coastguard Worker // dec->decodeOnlyOneBlock = False;
2413*f6dc9357SAndroid Build Coastguard Worker
2414*f6dc9357SAndroid Build Coastguard Worker XzUnpacker_SetOutBuf(dec, NULL, 0);
2415*f6dc9357SAndroid Build Coastguard Worker
2416*f6dc9357SAndroid Build Coastguard Worker inPrev = p->inProcessed;
2417*f6dc9357SAndroid Build Coastguard Worker outPrev = p->outProcessed;
2418*f6dc9357SAndroid Build Coastguard Worker
2419*f6dc9357SAndroid Build Coastguard Worker inPos = 0;
2420*f6dc9357SAndroid Build Coastguard Worker inLim = 0;
2421*f6dc9357SAndroid Build Coastguard Worker inData = NULL;
2422*f6dc9357SAndroid Build Coastguard Worker outPos = 0;
2423*f6dc9357SAndroid Build Coastguard Worker
2424*f6dc9357SAndroid Build Coastguard Worker for (;;)
2425*f6dc9357SAndroid Build Coastguard Worker {
2426*f6dc9357SAndroid Build Coastguard Worker SizeT outSize;
2427*f6dc9357SAndroid Build Coastguard Worker BoolInt finished;
2428*f6dc9357SAndroid Build Coastguard Worker ECoderFinishMode finishMode;
2429*f6dc9357SAndroid Build Coastguard Worker SizeT inProcessed;
2430*f6dc9357SAndroid Build Coastguard Worker ECoderStatus status;
2431*f6dc9357SAndroid Build Coastguard Worker SRes res;
2432*f6dc9357SAndroid Build Coastguard Worker
2433*f6dc9357SAndroid Build Coastguard Worker SizeT outProcessed;
2434*f6dc9357SAndroid Build Coastguard Worker
2435*f6dc9357SAndroid Build Coastguard Worker
2436*f6dc9357SAndroid Build Coastguard Worker
2437*f6dc9357SAndroid Build Coastguard Worker if (inPos == inLim)
2438*f6dc9357SAndroid Build Coastguard Worker {
2439*f6dc9357SAndroid Build Coastguard Worker #ifndef Z7_ST
2440*f6dc9357SAndroid Build Coastguard Worker if (tMode)
2441*f6dc9357SAndroid Build Coastguard Worker {
2442*f6dc9357SAndroid Build Coastguard Worker inData = MtDec_Read(&p->mtc, &inLim);
2443*f6dc9357SAndroid Build Coastguard Worker inPos = 0;
2444*f6dc9357SAndroid Build Coastguard Worker if (inData)
2445*f6dc9357SAndroid Build Coastguard Worker continue;
2446*f6dc9357SAndroid Build Coastguard Worker tMode = False;
2447*f6dc9357SAndroid Build Coastguard Worker inLim = 0;
2448*f6dc9357SAndroid Build Coastguard Worker }
2449*f6dc9357SAndroid Build Coastguard Worker #endif
2450*f6dc9357SAndroid Build Coastguard Worker
2451*f6dc9357SAndroid Build Coastguard Worker if (!p->readWasFinished)
2452*f6dc9357SAndroid Build Coastguard Worker {
2453*f6dc9357SAndroid Build Coastguard Worker inPos = 0;
2454*f6dc9357SAndroid Build Coastguard Worker inLim = p->inBufSize;
2455*f6dc9357SAndroid Build Coastguard Worker inData = p->inBuf;
2456*f6dc9357SAndroid Build Coastguard Worker p->readRes = ISeqInStream_Read(p->inStream, (void *)p->inBuf, &inLim);
2457*f6dc9357SAndroid Build Coastguard Worker p->readProcessed += inLim;
2458*f6dc9357SAndroid Build Coastguard Worker if (inLim == 0 || p->readRes != SZ_OK)
2459*f6dc9357SAndroid Build Coastguard Worker p->readWasFinished = True;
2460*f6dc9357SAndroid Build Coastguard Worker }
2461*f6dc9357SAndroid Build Coastguard Worker }
2462*f6dc9357SAndroid Build Coastguard Worker
2463*f6dc9357SAndroid Build Coastguard Worker outSize = p->props.outStep_ST - outPos;
2464*f6dc9357SAndroid Build Coastguard Worker
2465*f6dc9357SAndroid Build Coastguard Worker finishMode = CODER_FINISH_ANY;
2466*f6dc9357SAndroid Build Coastguard Worker if (p->outSize_Defined)
2467*f6dc9357SAndroid Build Coastguard Worker {
2468*f6dc9357SAndroid Build Coastguard Worker const UInt64 rem = p->outSize - p->outProcessed;
2469*f6dc9357SAndroid Build Coastguard Worker if (outSize >= rem)
2470*f6dc9357SAndroid Build Coastguard Worker {
2471*f6dc9357SAndroid Build Coastguard Worker outSize = (SizeT)rem;
2472*f6dc9357SAndroid Build Coastguard Worker if (p->finishMode)
2473*f6dc9357SAndroid Build Coastguard Worker finishMode = CODER_FINISH_END;
2474*f6dc9357SAndroid Build Coastguard Worker }
2475*f6dc9357SAndroid Build Coastguard Worker }
2476*f6dc9357SAndroid Build Coastguard Worker
2477*f6dc9357SAndroid Build Coastguard Worker inProcessed = inLim - inPos;
2478*f6dc9357SAndroid Build Coastguard Worker outProcessed = outSize;
2479*f6dc9357SAndroid Build Coastguard Worker
2480*f6dc9357SAndroid Build Coastguard Worker res = XzUnpacker_Code(dec, p->outBuf + outPos, &outProcessed,
2481*f6dc9357SAndroid Build Coastguard Worker inData + inPos, &inProcessed,
2482*f6dc9357SAndroid Build Coastguard Worker (inPos == inLim), // srcFinished
2483*f6dc9357SAndroid Build Coastguard Worker finishMode, &status);
2484*f6dc9357SAndroid Build Coastguard Worker
2485*f6dc9357SAndroid Build Coastguard Worker p->codeRes = res;
2486*f6dc9357SAndroid Build Coastguard Worker p->status = status;
2487*f6dc9357SAndroid Build Coastguard Worker
2488*f6dc9357SAndroid Build Coastguard Worker inPos += inProcessed;
2489*f6dc9357SAndroid Build Coastguard Worker outPos += outProcessed;
2490*f6dc9357SAndroid Build Coastguard Worker p->inProcessed += inProcessed;
2491*f6dc9357SAndroid Build Coastguard Worker p->outProcessed += outProcessed;
2492*f6dc9357SAndroid Build Coastguard Worker
2493*f6dc9357SAndroid Build Coastguard Worker finished = ((inProcessed == 0 && outProcessed == 0) || res != SZ_OK);
2494*f6dc9357SAndroid Build Coastguard Worker
2495*f6dc9357SAndroid Build Coastguard Worker if (finished || outProcessed >= outSize)
2496*f6dc9357SAndroid Build Coastguard Worker if (outPos != 0)
2497*f6dc9357SAndroid Build Coastguard Worker {
2498*f6dc9357SAndroid Build Coastguard Worker const size_t written = ISeqOutStream_Write(p->outStream, p->outBuf, outPos);
2499*f6dc9357SAndroid Build Coastguard Worker // p->outProcessed += written; // 21.01: BUG fixed
2500*f6dc9357SAndroid Build Coastguard Worker if (written != outPos)
2501*f6dc9357SAndroid Build Coastguard Worker {
2502*f6dc9357SAndroid Build Coastguard Worker stat->CombinedRes_Type = SZ_ERROR_WRITE;
2503*f6dc9357SAndroid Build Coastguard Worker return SZ_ERROR_WRITE;
2504*f6dc9357SAndroid Build Coastguard Worker }
2505*f6dc9357SAndroid Build Coastguard Worker outPos = 0;
2506*f6dc9357SAndroid Build Coastguard Worker }
2507*f6dc9357SAndroid Build Coastguard Worker
2508*f6dc9357SAndroid Build Coastguard Worker if (p->progress && res == SZ_OK)
2509*f6dc9357SAndroid Build Coastguard Worker {
2510*f6dc9357SAndroid Build Coastguard Worker if (p->inProcessed - inPrev >= (1 << 22) ||
2511*f6dc9357SAndroid Build Coastguard Worker p->outProcessed - outPrev >= (1 << 22))
2512*f6dc9357SAndroid Build Coastguard Worker {
2513*f6dc9357SAndroid Build Coastguard Worker res = ICompressProgress_Progress(p->progress, p->inProcessed, p->outProcessed);
2514*f6dc9357SAndroid Build Coastguard Worker if (res != SZ_OK)
2515*f6dc9357SAndroid Build Coastguard Worker {
2516*f6dc9357SAndroid Build Coastguard Worker stat->CombinedRes_Type = SZ_ERROR_PROGRESS;
2517*f6dc9357SAndroid Build Coastguard Worker stat->ProgressRes = res;
2518*f6dc9357SAndroid Build Coastguard Worker return res;
2519*f6dc9357SAndroid Build Coastguard Worker }
2520*f6dc9357SAndroid Build Coastguard Worker inPrev = p->inProcessed;
2521*f6dc9357SAndroid Build Coastguard Worker outPrev = p->outProcessed;
2522*f6dc9357SAndroid Build Coastguard Worker }
2523*f6dc9357SAndroid Build Coastguard Worker }
2524*f6dc9357SAndroid Build Coastguard Worker
2525*f6dc9357SAndroid Build Coastguard Worker if (finished)
2526*f6dc9357SAndroid Build Coastguard Worker {
2527*f6dc9357SAndroid Build Coastguard Worker // p->codeRes is preliminary error from XzUnpacker_Code.
2528*f6dc9357SAndroid Build Coastguard Worker // and it can be corrected later as final result
2529*f6dc9357SAndroid Build Coastguard Worker // so we return SZ_OK here instead of (res);
2530*f6dc9357SAndroid Build Coastguard Worker return SZ_OK;
2531*f6dc9357SAndroid Build Coastguard Worker // return res;
2532*f6dc9357SAndroid Build Coastguard Worker }
2533*f6dc9357SAndroid Build Coastguard Worker }
2534*f6dc9357SAndroid Build Coastguard Worker }
2535*f6dc9357SAndroid Build Coastguard Worker
2536*f6dc9357SAndroid Build Coastguard Worker
2537*f6dc9357SAndroid Build Coastguard Worker
2538*f6dc9357SAndroid Build Coastguard Worker /*
2539*f6dc9357SAndroid Build Coastguard Worker XzStatInfo_SetStat() transforms
2540*f6dc9357SAndroid Build Coastguard Worker CXzUnpacker return code and status to combined CXzStatInfo results.
2541*f6dc9357SAndroid Build Coastguard Worker it can convert SZ_OK to SZ_ERROR_INPUT_EOF
2542*f6dc9357SAndroid Build Coastguard Worker it can convert SZ_ERROR_NO_ARCHIVE to SZ_OK and (DataAfterEnd = 1)
2543*f6dc9357SAndroid Build Coastguard Worker */
2544*f6dc9357SAndroid Build Coastguard Worker
XzStatInfo_SetStat(const CXzUnpacker * dec,int finishMode,UInt64 inProcessed,SRes res,ECoderStatus status,BoolInt decodingTruncated,CXzStatInfo * stat)2545*f6dc9357SAndroid Build Coastguard Worker static void XzStatInfo_SetStat(const CXzUnpacker *dec,
2546*f6dc9357SAndroid Build Coastguard Worker int finishMode,
2547*f6dc9357SAndroid Build Coastguard Worker // UInt64 readProcessed,
2548*f6dc9357SAndroid Build Coastguard Worker UInt64 inProcessed,
2549*f6dc9357SAndroid Build Coastguard Worker SRes res, // it's result from CXzUnpacker unpacker
2550*f6dc9357SAndroid Build Coastguard Worker ECoderStatus status,
2551*f6dc9357SAndroid Build Coastguard Worker BoolInt decodingTruncated,
2552*f6dc9357SAndroid Build Coastguard Worker CXzStatInfo *stat)
2553*f6dc9357SAndroid Build Coastguard Worker {
2554*f6dc9357SAndroid Build Coastguard Worker UInt64 extraSize;
2555*f6dc9357SAndroid Build Coastguard Worker
2556*f6dc9357SAndroid Build Coastguard Worker stat->DecodingTruncated = (Byte)(decodingTruncated ? 1 : 0);
2557*f6dc9357SAndroid Build Coastguard Worker stat->InSize = inProcessed;
2558*f6dc9357SAndroid Build Coastguard Worker stat->NumStreams = dec->numStartedStreams;
2559*f6dc9357SAndroid Build Coastguard Worker stat->NumBlocks = dec->numTotalBlocks;
2560*f6dc9357SAndroid Build Coastguard Worker
2561*f6dc9357SAndroid Build Coastguard Worker stat->UnpackSize_Defined = True;
2562*f6dc9357SAndroid Build Coastguard Worker stat->NumStreams_Defined = True;
2563*f6dc9357SAndroid Build Coastguard Worker stat->NumBlocks_Defined = True;
2564*f6dc9357SAndroid Build Coastguard Worker
2565*f6dc9357SAndroid Build Coastguard Worker extraSize = XzUnpacker_GetExtraSize(dec);
2566*f6dc9357SAndroid Build Coastguard Worker
2567*f6dc9357SAndroid Build Coastguard Worker if (res == SZ_OK)
2568*f6dc9357SAndroid Build Coastguard Worker {
2569*f6dc9357SAndroid Build Coastguard Worker if (status == CODER_STATUS_NEEDS_MORE_INPUT)
2570*f6dc9357SAndroid Build Coastguard Worker {
2571*f6dc9357SAndroid Build Coastguard Worker // CODER_STATUS_NEEDS_MORE_INPUT is expected status for correct xz streams
2572*f6dc9357SAndroid Build Coastguard Worker // any extra data is part of correct data
2573*f6dc9357SAndroid Build Coastguard Worker extraSize = 0;
2574*f6dc9357SAndroid Build Coastguard Worker // if xz stream was not finished, then we need more data
2575*f6dc9357SAndroid Build Coastguard Worker if (!XzUnpacker_IsStreamWasFinished(dec))
2576*f6dc9357SAndroid Build Coastguard Worker res = SZ_ERROR_INPUT_EOF;
2577*f6dc9357SAndroid Build Coastguard Worker }
2578*f6dc9357SAndroid Build Coastguard Worker else
2579*f6dc9357SAndroid Build Coastguard Worker {
2580*f6dc9357SAndroid Build Coastguard Worker // CODER_STATUS_FINISHED_WITH_MARK is not possible for multi stream xz decoding
2581*f6dc9357SAndroid Build Coastguard Worker // so he we have (status == CODER_STATUS_NOT_FINISHED)
2582*f6dc9357SAndroid Build Coastguard Worker // if (status != CODER_STATUS_FINISHED_WITH_MARK)
2583*f6dc9357SAndroid Build Coastguard Worker if (!decodingTruncated || finishMode)
2584*f6dc9357SAndroid Build Coastguard Worker res = SZ_ERROR_DATA;
2585*f6dc9357SAndroid Build Coastguard Worker }
2586*f6dc9357SAndroid Build Coastguard Worker }
2587*f6dc9357SAndroid Build Coastguard Worker else if (res == SZ_ERROR_NO_ARCHIVE)
2588*f6dc9357SAndroid Build Coastguard Worker {
2589*f6dc9357SAndroid Build Coastguard Worker /*
2590*f6dc9357SAndroid Build Coastguard Worker SZ_ERROR_NO_ARCHIVE is possible for 2 states:
2591*f6dc9357SAndroid Build Coastguard Worker XZ_STATE_STREAM_HEADER - if bad signature or bad CRC
2592*f6dc9357SAndroid Build Coastguard Worker XZ_STATE_STREAM_PADDING - if non-zero padding data
2593*f6dc9357SAndroid Build Coastguard Worker extraSize and inProcessed don't include "bad" byte
2594*f6dc9357SAndroid Build Coastguard Worker */
2595*f6dc9357SAndroid Build Coastguard Worker // if (inProcessed == extraSize), there was no any good xz stream header, and we keep error
2596*f6dc9357SAndroid Build Coastguard Worker if (inProcessed != extraSize) // if there were good xz streams before error
2597*f6dc9357SAndroid Build Coastguard Worker {
2598*f6dc9357SAndroid Build Coastguard Worker // if (extraSize != 0 || readProcessed != inProcessed)
2599*f6dc9357SAndroid Build Coastguard Worker {
2600*f6dc9357SAndroid Build Coastguard Worker // he we suppose that all xz streams were finsihed OK, and we have
2601*f6dc9357SAndroid Build Coastguard Worker // some extra data after all streams
2602*f6dc9357SAndroid Build Coastguard Worker stat->DataAfterEnd = True;
2603*f6dc9357SAndroid Build Coastguard Worker res = SZ_OK;
2604*f6dc9357SAndroid Build Coastguard Worker }
2605*f6dc9357SAndroid Build Coastguard Worker }
2606*f6dc9357SAndroid Build Coastguard Worker }
2607*f6dc9357SAndroid Build Coastguard Worker
2608*f6dc9357SAndroid Build Coastguard Worker if (stat->DecodeRes == SZ_OK)
2609*f6dc9357SAndroid Build Coastguard Worker stat->DecodeRes = res;
2610*f6dc9357SAndroid Build Coastguard Worker
2611*f6dc9357SAndroid Build Coastguard Worker stat->InSize -= extraSize;
2612*f6dc9357SAndroid Build Coastguard Worker }
2613*f6dc9357SAndroid Build Coastguard Worker
2614*f6dc9357SAndroid Build Coastguard Worker
2615*f6dc9357SAndroid Build Coastguard Worker
XzDecMt_Decode(CXzDecMtHandle p,const CXzDecMtProps * props,const UInt64 * outDataSize,int finishMode,ISeqOutStreamPtr outStream,ISeqInStreamPtr inStream,CXzStatInfo * stat,int * isMT,ICompressProgressPtr progress)2616*f6dc9357SAndroid Build Coastguard Worker SRes XzDecMt_Decode(CXzDecMtHandle p,
2617*f6dc9357SAndroid Build Coastguard Worker const CXzDecMtProps *props,
2618*f6dc9357SAndroid Build Coastguard Worker const UInt64 *outDataSize, int finishMode,
2619*f6dc9357SAndroid Build Coastguard Worker ISeqOutStreamPtr outStream,
2620*f6dc9357SAndroid Build Coastguard Worker // Byte *outBuf, size_t *outBufSize,
2621*f6dc9357SAndroid Build Coastguard Worker ISeqInStreamPtr inStream,
2622*f6dc9357SAndroid Build Coastguard Worker // const Byte *inData, size_t inDataSize,
2623*f6dc9357SAndroid Build Coastguard Worker CXzStatInfo *stat,
2624*f6dc9357SAndroid Build Coastguard Worker int *isMT,
2625*f6dc9357SAndroid Build Coastguard Worker ICompressProgressPtr progress)
2626*f6dc9357SAndroid Build Coastguard Worker {
2627*f6dc9357SAndroid Build Coastguard Worker // GET_CXzDecMt_p
2628*f6dc9357SAndroid Build Coastguard Worker #ifndef Z7_ST
2629*f6dc9357SAndroid Build Coastguard Worker BoolInt tMode;
2630*f6dc9357SAndroid Build Coastguard Worker #endif
2631*f6dc9357SAndroid Build Coastguard Worker
2632*f6dc9357SAndroid Build Coastguard Worker XzStatInfo_Clear(stat);
2633*f6dc9357SAndroid Build Coastguard Worker
2634*f6dc9357SAndroid Build Coastguard Worker p->props = *props;
2635*f6dc9357SAndroid Build Coastguard Worker
2636*f6dc9357SAndroid Build Coastguard Worker p->inStream = inStream;
2637*f6dc9357SAndroid Build Coastguard Worker p->outStream = outStream;
2638*f6dc9357SAndroid Build Coastguard Worker p->progress = progress;
2639*f6dc9357SAndroid Build Coastguard Worker // p->stat = stat;
2640*f6dc9357SAndroid Build Coastguard Worker
2641*f6dc9357SAndroid Build Coastguard Worker p->outSize = 0;
2642*f6dc9357SAndroid Build Coastguard Worker p->outSize_Defined = False;
2643*f6dc9357SAndroid Build Coastguard Worker if (outDataSize)
2644*f6dc9357SAndroid Build Coastguard Worker {
2645*f6dc9357SAndroid Build Coastguard Worker p->outSize_Defined = True;
2646*f6dc9357SAndroid Build Coastguard Worker p->outSize = *outDataSize;
2647*f6dc9357SAndroid Build Coastguard Worker }
2648*f6dc9357SAndroid Build Coastguard Worker
2649*f6dc9357SAndroid Build Coastguard Worker p->finishMode = (BoolInt)finishMode;
2650*f6dc9357SAndroid Build Coastguard Worker
2651*f6dc9357SAndroid Build Coastguard Worker // p->outSize = 457; p->outSize_Defined = True; p->finishMode = False; // for test
2652*f6dc9357SAndroid Build Coastguard Worker
2653*f6dc9357SAndroid Build Coastguard Worker p->writeRes = SZ_OK;
2654*f6dc9357SAndroid Build Coastguard Worker p->outProcessed = 0;
2655*f6dc9357SAndroid Build Coastguard Worker p->inProcessed = 0;
2656*f6dc9357SAndroid Build Coastguard Worker p->readProcessed = 0;
2657*f6dc9357SAndroid Build Coastguard Worker p->readWasFinished = False;
2658*f6dc9357SAndroid Build Coastguard Worker p->readRes = SZ_OK;
2659*f6dc9357SAndroid Build Coastguard Worker
2660*f6dc9357SAndroid Build Coastguard Worker p->codeRes = SZ_OK;
2661*f6dc9357SAndroid Build Coastguard Worker p->status = CODER_STATUS_NOT_SPECIFIED;
2662*f6dc9357SAndroid Build Coastguard Worker
2663*f6dc9357SAndroid Build Coastguard Worker XzUnpacker_Init(&p->dec);
2664*f6dc9357SAndroid Build Coastguard Worker
2665*f6dc9357SAndroid Build Coastguard Worker *isMT = False;
2666*f6dc9357SAndroid Build Coastguard Worker
2667*f6dc9357SAndroid Build Coastguard Worker /*
2668*f6dc9357SAndroid Build Coastguard Worker p->outBuf = NULL;
2669*f6dc9357SAndroid Build Coastguard Worker p->outBufSize = 0;
2670*f6dc9357SAndroid Build Coastguard Worker if (!outStream)
2671*f6dc9357SAndroid Build Coastguard Worker {
2672*f6dc9357SAndroid Build Coastguard Worker p->outBuf = outBuf;
2673*f6dc9357SAndroid Build Coastguard Worker p->outBufSize = *outBufSize;
2674*f6dc9357SAndroid Build Coastguard Worker *outBufSize = 0;
2675*f6dc9357SAndroid Build Coastguard Worker }
2676*f6dc9357SAndroid Build Coastguard Worker */
2677*f6dc9357SAndroid Build Coastguard Worker
2678*f6dc9357SAndroid Build Coastguard Worker
2679*f6dc9357SAndroid Build Coastguard Worker #ifndef Z7_ST
2680*f6dc9357SAndroid Build Coastguard Worker
2681*f6dc9357SAndroid Build Coastguard Worker p->isBlockHeaderState_Parse = False;
2682*f6dc9357SAndroid Build Coastguard Worker p->isBlockHeaderState_Write = False;
2683*f6dc9357SAndroid Build Coastguard Worker // p->numBadBlocks = 0;
2684*f6dc9357SAndroid Build Coastguard Worker p->mainErrorCode = SZ_OK;
2685*f6dc9357SAndroid Build Coastguard Worker p->mainDecoderWasCalled = False;
2686*f6dc9357SAndroid Build Coastguard Worker
2687*f6dc9357SAndroid Build Coastguard Worker tMode = False;
2688*f6dc9357SAndroid Build Coastguard Worker
2689*f6dc9357SAndroid Build Coastguard Worker if (p->props.numThreads > 1)
2690*f6dc9357SAndroid Build Coastguard Worker {
2691*f6dc9357SAndroid Build Coastguard Worker IMtDecCallback2 vt;
2692*f6dc9357SAndroid Build Coastguard Worker BoolInt needContinue;
2693*f6dc9357SAndroid Build Coastguard Worker SRes res;
2694*f6dc9357SAndroid Build Coastguard Worker // we just free ST buffers here
2695*f6dc9357SAndroid Build Coastguard Worker // but we still keep state variables, that was set in XzUnpacker_Init()
2696*f6dc9357SAndroid Build Coastguard Worker XzDecMt_FreeSt(p);
2697*f6dc9357SAndroid Build Coastguard Worker
2698*f6dc9357SAndroid Build Coastguard Worker p->outProcessed_Parse = 0;
2699*f6dc9357SAndroid Build Coastguard Worker p->parsing_Truncated = False;
2700*f6dc9357SAndroid Build Coastguard Worker
2701*f6dc9357SAndroid Build Coastguard Worker p->numStreams = 0;
2702*f6dc9357SAndroid Build Coastguard Worker p->numTotalBlocks = 0;
2703*f6dc9357SAndroid Build Coastguard Worker p->numBlocks = 0;
2704*f6dc9357SAndroid Build Coastguard Worker p->finishedDecoderIndex = -1;
2705*f6dc9357SAndroid Build Coastguard Worker
2706*f6dc9357SAndroid Build Coastguard Worker if (!p->mtc_WasConstructed)
2707*f6dc9357SAndroid Build Coastguard Worker {
2708*f6dc9357SAndroid Build Coastguard Worker p->mtc_WasConstructed = True;
2709*f6dc9357SAndroid Build Coastguard Worker MtDec_Construct(&p->mtc);
2710*f6dc9357SAndroid Build Coastguard Worker }
2711*f6dc9357SAndroid Build Coastguard Worker
2712*f6dc9357SAndroid Build Coastguard Worker p->mtc.mtCallback = &vt;
2713*f6dc9357SAndroid Build Coastguard Worker p->mtc.mtCallbackObject = p;
2714*f6dc9357SAndroid Build Coastguard Worker
2715*f6dc9357SAndroid Build Coastguard Worker p->mtc.progress = progress;
2716*f6dc9357SAndroid Build Coastguard Worker p->mtc.inStream = inStream;
2717*f6dc9357SAndroid Build Coastguard Worker p->mtc.alloc = &p->alignOffsetAlloc.vt;
2718*f6dc9357SAndroid Build Coastguard Worker // p->mtc.inData = inData;
2719*f6dc9357SAndroid Build Coastguard Worker // p->mtc.inDataSize = inDataSize;
2720*f6dc9357SAndroid Build Coastguard Worker p->mtc.inBufSize = p->props.inBufSize_MT;
2721*f6dc9357SAndroid Build Coastguard Worker // p->mtc.inBlockMax = p->props.inBlockMax;
2722*f6dc9357SAndroid Build Coastguard Worker p->mtc.numThreadsMax = p->props.numThreads;
2723*f6dc9357SAndroid Build Coastguard Worker
2724*f6dc9357SAndroid Build Coastguard Worker *isMT = True;
2725*f6dc9357SAndroid Build Coastguard Worker
2726*f6dc9357SAndroid Build Coastguard Worker vt.Parse = XzDecMt_Callback_Parse;
2727*f6dc9357SAndroid Build Coastguard Worker vt.PreCode = XzDecMt_Callback_PreCode;
2728*f6dc9357SAndroid Build Coastguard Worker vt.Code = XzDecMt_Callback_Code;
2729*f6dc9357SAndroid Build Coastguard Worker vt.Write = XzDecMt_Callback_Write;
2730*f6dc9357SAndroid Build Coastguard Worker
2731*f6dc9357SAndroid Build Coastguard Worker
2732*f6dc9357SAndroid Build Coastguard Worker res = MtDec_Code(&p->mtc);
2733*f6dc9357SAndroid Build Coastguard Worker
2734*f6dc9357SAndroid Build Coastguard Worker
2735*f6dc9357SAndroid Build Coastguard Worker stat->InSize = p->mtc.inProcessed;
2736*f6dc9357SAndroid Build Coastguard Worker
2737*f6dc9357SAndroid Build Coastguard Worker p->inProcessed = p->mtc.inProcessed;
2738*f6dc9357SAndroid Build Coastguard Worker p->readRes = p->mtc.readRes;
2739*f6dc9357SAndroid Build Coastguard Worker p->readWasFinished = p->mtc.readWasFinished;
2740*f6dc9357SAndroid Build Coastguard Worker p->readProcessed = p->mtc.readProcessed;
2741*f6dc9357SAndroid Build Coastguard Worker
2742*f6dc9357SAndroid Build Coastguard Worker tMode = True;
2743*f6dc9357SAndroid Build Coastguard Worker needContinue = False;
2744*f6dc9357SAndroid Build Coastguard Worker
2745*f6dc9357SAndroid Build Coastguard Worker if (res == SZ_OK)
2746*f6dc9357SAndroid Build Coastguard Worker {
2747*f6dc9357SAndroid Build Coastguard Worker if (p->mtc.mtProgress.res != SZ_OK)
2748*f6dc9357SAndroid Build Coastguard Worker {
2749*f6dc9357SAndroid Build Coastguard Worker res = p->mtc.mtProgress.res;
2750*f6dc9357SAndroid Build Coastguard Worker stat->ProgressRes = res;
2751*f6dc9357SAndroid Build Coastguard Worker stat->CombinedRes_Type = SZ_ERROR_PROGRESS;
2752*f6dc9357SAndroid Build Coastguard Worker }
2753*f6dc9357SAndroid Build Coastguard Worker else
2754*f6dc9357SAndroid Build Coastguard Worker needContinue = p->mtc.needContinue;
2755*f6dc9357SAndroid Build Coastguard Worker }
2756*f6dc9357SAndroid Build Coastguard Worker
2757*f6dc9357SAndroid Build Coastguard Worker if (!needContinue)
2758*f6dc9357SAndroid Build Coastguard Worker {
2759*f6dc9357SAndroid Build Coastguard Worker {
2760*f6dc9357SAndroid Build Coastguard Worker SRes codeRes;
2761*f6dc9357SAndroid Build Coastguard Worker BoolInt truncated = False;
2762*f6dc9357SAndroid Build Coastguard Worker ECoderStatus status;
2763*f6dc9357SAndroid Build Coastguard Worker const CXzUnpacker *dec;
2764*f6dc9357SAndroid Build Coastguard Worker
2765*f6dc9357SAndroid Build Coastguard Worker stat->OutSize = p->outProcessed;
2766*f6dc9357SAndroid Build Coastguard Worker
2767*f6dc9357SAndroid Build Coastguard Worker if (p->finishedDecoderIndex >= 0)
2768*f6dc9357SAndroid Build Coastguard Worker {
2769*f6dc9357SAndroid Build Coastguard Worker const CXzDecMtThread *coder = &p->coders[(unsigned)p->finishedDecoderIndex];
2770*f6dc9357SAndroid Build Coastguard Worker codeRes = coder->codeRes;
2771*f6dc9357SAndroid Build Coastguard Worker dec = &coder->dec;
2772*f6dc9357SAndroid Build Coastguard Worker status = coder->status;
2773*f6dc9357SAndroid Build Coastguard Worker }
2774*f6dc9357SAndroid Build Coastguard Worker else if (p->mainDecoderWasCalled)
2775*f6dc9357SAndroid Build Coastguard Worker {
2776*f6dc9357SAndroid Build Coastguard Worker codeRes = p->codeRes;
2777*f6dc9357SAndroid Build Coastguard Worker dec = &p->dec;
2778*f6dc9357SAndroid Build Coastguard Worker status = p->status;
2779*f6dc9357SAndroid Build Coastguard Worker truncated = p->parsing_Truncated;
2780*f6dc9357SAndroid Build Coastguard Worker }
2781*f6dc9357SAndroid Build Coastguard Worker else
2782*f6dc9357SAndroid Build Coastguard Worker return SZ_ERROR_FAIL;
2783*f6dc9357SAndroid Build Coastguard Worker
2784*f6dc9357SAndroid Build Coastguard Worker if (p->mainErrorCode != SZ_OK)
2785*f6dc9357SAndroid Build Coastguard Worker stat->DecodeRes = p->mainErrorCode;
2786*f6dc9357SAndroid Build Coastguard Worker
2787*f6dc9357SAndroid Build Coastguard Worker XzStatInfo_SetStat(dec, p->finishMode,
2788*f6dc9357SAndroid Build Coastguard Worker // p->mtc.readProcessed,
2789*f6dc9357SAndroid Build Coastguard Worker p->mtc.inProcessed,
2790*f6dc9357SAndroid Build Coastguard Worker codeRes, status,
2791*f6dc9357SAndroid Build Coastguard Worker truncated,
2792*f6dc9357SAndroid Build Coastguard Worker stat);
2793*f6dc9357SAndroid Build Coastguard Worker }
2794*f6dc9357SAndroid Build Coastguard Worker
2795*f6dc9357SAndroid Build Coastguard Worker if (res == SZ_OK)
2796*f6dc9357SAndroid Build Coastguard Worker {
2797*f6dc9357SAndroid Build Coastguard Worker stat->ReadRes = p->mtc.readRes;
2798*f6dc9357SAndroid Build Coastguard Worker
2799*f6dc9357SAndroid Build Coastguard Worker if (p->writeRes != SZ_OK)
2800*f6dc9357SAndroid Build Coastguard Worker {
2801*f6dc9357SAndroid Build Coastguard Worker res = p->writeRes;
2802*f6dc9357SAndroid Build Coastguard Worker stat->CombinedRes_Type = SZ_ERROR_WRITE;
2803*f6dc9357SAndroid Build Coastguard Worker }
2804*f6dc9357SAndroid Build Coastguard Worker else if (p->mtc.readRes != SZ_OK
2805*f6dc9357SAndroid Build Coastguard Worker // && p->mtc.inProcessed == p->mtc.readProcessed
2806*f6dc9357SAndroid Build Coastguard Worker && stat->DecodeRes == SZ_ERROR_INPUT_EOF)
2807*f6dc9357SAndroid Build Coastguard Worker {
2808*f6dc9357SAndroid Build Coastguard Worker res = p->mtc.readRes;
2809*f6dc9357SAndroid Build Coastguard Worker stat->CombinedRes_Type = SZ_ERROR_READ;
2810*f6dc9357SAndroid Build Coastguard Worker }
2811*f6dc9357SAndroid Build Coastguard Worker else if (stat->DecodeRes != SZ_OK)
2812*f6dc9357SAndroid Build Coastguard Worker res = stat->DecodeRes;
2813*f6dc9357SAndroid Build Coastguard Worker }
2814*f6dc9357SAndroid Build Coastguard Worker
2815*f6dc9357SAndroid Build Coastguard Worker stat->CombinedRes = res;
2816*f6dc9357SAndroid Build Coastguard Worker if (stat->CombinedRes_Type == SZ_OK)
2817*f6dc9357SAndroid Build Coastguard Worker stat->CombinedRes_Type = res;
2818*f6dc9357SAndroid Build Coastguard Worker return res;
2819*f6dc9357SAndroid Build Coastguard Worker }
2820*f6dc9357SAndroid Build Coastguard Worker
2821*f6dc9357SAndroid Build Coastguard Worker PRF_STR("----- decoding ST -----")
2822*f6dc9357SAndroid Build Coastguard Worker }
2823*f6dc9357SAndroid Build Coastguard Worker
2824*f6dc9357SAndroid Build Coastguard Worker #endif
2825*f6dc9357SAndroid Build Coastguard Worker
2826*f6dc9357SAndroid Build Coastguard Worker
2827*f6dc9357SAndroid Build Coastguard Worker *isMT = False;
2828*f6dc9357SAndroid Build Coastguard Worker
2829*f6dc9357SAndroid Build Coastguard Worker {
2830*f6dc9357SAndroid Build Coastguard Worker SRes res = XzDecMt_Decode_ST(p
2831*f6dc9357SAndroid Build Coastguard Worker #ifndef Z7_ST
2832*f6dc9357SAndroid Build Coastguard Worker , tMode
2833*f6dc9357SAndroid Build Coastguard Worker #endif
2834*f6dc9357SAndroid Build Coastguard Worker , stat
2835*f6dc9357SAndroid Build Coastguard Worker );
2836*f6dc9357SAndroid Build Coastguard Worker
2837*f6dc9357SAndroid Build Coastguard Worker #ifndef Z7_ST
2838*f6dc9357SAndroid Build Coastguard Worker // we must set error code from MT decoding at first
2839*f6dc9357SAndroid Build Coastguard Worker if (p->mainErrorCode != SZ_OK)
2840*f6dc9357SAndroid Build Coastguard Worker stat->DecodeRes = p->mainErrorCode;
2841*f6dc9357SAndroid Build Coastguard Worker #endif
2842*f6dc9357SAndroid Build Coastguard Worker
2843*f6dc9357SAndroid Build Coastguard Worker XzStatInfo_SetStat(&p->dec,
2844*f6dc9357SAndroid Build Coastguard Worker p->finishMode,
2845*f6dc9357SAndroid Build Coastguard Worker // p->readProcessed,
2846*f6dc9357SAndroid Build Coastguard Worker p->inProcessed,
2847*f6dc9357SAndroid Build Coastguard Worker p->codeRes, p->status,
2848*f6dc9357SAndroid Build Coastguard Worker False, // truncated
2849*f6dc9357SAndroid Build Coastguard Worker stat);
2850*f6dc9357SAndroid Build Coastguard Worker
2851*f6dc9357SAndroid Build Coastguard Worker stat->ReadRes = p->readRes;
2852*f6dc9357SAndroid Build Coastguard Worker
2853*f6dc9357SAndroid Build Coastguard Worker if (res == SZ_OK)
2854*f6dc9357SAndroid Build Coastguard Worker {
2855*f6dc9357SAndroid Build Coastguard Worker if (p->readRes != SZ_OK
2856*f6dc9357SAndroid Build Coastguard Worker // && p->inProcessed == p->readProcessed
2857*f6dc9357SAndroid Build Coastguard Worker && stat->DecodeRes == SZ_ERROR_INPUT_EOF)
2858*f6dc9357SAndroid Build Coastguard Worker {
2859*f6dc9357SAndroid Build Coastguard Worker // we set read error as combined error, only if that error was the reason
2860*f6dc9357SAndroid Build Coastguard Worker // of decoding problem
2861*f6dc9357SAndroid Build Coastguard Worker res = p->readRes;
2862*f6dc9357SAndroid Build Coastguard Worker stat->CombinedRes_Type = SZ_ERROR_READ;
2863*f6dc9357SAndroid Build Coastguard Worker }
2864*f6dc9357SAndroid Build Coastguard Worker else if (stat->DecodeRes != SZ_OK)
2865*f6dc9357SAndroid Build Coastguard Worker res = stat->DecodeRes;
2866*f6dc9357SAndroid Build Coastguard Worker }
2867*f6dc9357SAndroid Build Coastguard Worker
2868*f6dc9357SAndroid Build Coastguard Worker stat->CombinedRes = res;
2869*f6dc9357SAndroid Build Coastguard Worker if (stat->CombinedRes_Type == SZ_OK)
2870*f6dc9357SAndroid Build Coastguard Worker stat->CombinedRes_Type = res;
2871*f6dc9357SAndroid Build Coastguard Worker return res;
2872*f6dc9357SAndroid Build Coastguard Worker }
2873*f6dc9357SAndroid Build Coastguard Worker }
2874*f6dc9357SAndroid Build Coastguard Worker
2875*f6dc9357SAndroid Build Coastguard Worker #undef PRF
2876*f6dc9357SAndroid Build Coastguard Worker #undef PRF_STR
2877*f6dc9357SAndroid Build Coastguard Worker #undef PRF_STR_INT_2
2878