src/third-party/lzma/Lzma2Dec.c (view raw)
1/* Lzma2Dec.c -- LZMA2 Decoder
22015-11-09 : Igor Pavlov : Public domain */
3
4/* #define SHOW_DEBUG_INFO */
5
6#include "Precomp.h"
7
8#ifdef SHOW_DEBUG_INFO
9#include <stdio.h>
10#endif
11
12#include <string.h>
13
14#include "Lzma2Dec.h"
15
16/*
1700000000 - EOS
1800000001 U U - Uncompressed Reset Dic
1900000010 U U - Uncompressed No Reset
20100uuuuu U U P P - LZMA no reset
21101uuuuu U U P P - LZMA reset state
22110uuuuu U U P P S - LZMA reset state + new prop
23111uuuuu U U P P S - LZMA reset state + new prop + reset dic
24
25 u, U - Unpack Size
26 P - Pack Size
27 S - Props
28*/
29
30#define LZMA2_CONTROL_LZMA (1 << 7)
31#define LZMA2_CONTROL_COPY_NO_RESET 2
32#define LZMA2_CONTROL_COPY_RESET_DIC 1
33#define LZMA2_CONTROL_EOF 0
34
35#define LZMA2_IS_UNCOMPRESSED_STATE(p) (((p)->control & LZMA2_CONTROL_LZMA) == 0)
36
37#define LZMA2_GET_LZMA_MODE(p) (((p)->control >> 5) & 3)
38#define LZMA2_IS_THERE_PROP(mode) ((mode) >= 2)
39
40#define LZMA2_LCLP_MAX 4
41#define LZMA2_DIC_SIZE_FROM_PROP(p) (((UInt32)2 | ((p) & 1)) << ((p) / 2 + 11))
42
43#ifdef SHOW_DEBUG_INFO
44#define PRF(x) x
45#else
46#define PRF(x)
47#endif
48
49typedef enum
50{
51 LZMA2_STATE_CONTROL,
52 LZMA2_STATE_UNPACK0,
53 LZMA2_STATE_UNPACK1,
54 LZMA2_STATE_PACK0,
55 LZMA2_STATE_PACK1,
56 LZMA2_STATE_PROP,
57 LZMA2_STATE_DATA,
58 LZMA2_STATE_DATA_CONT,
59 LZMA2_STATE_FINISHED,
60 LZMA2_STATE_ERROR
61} ELzma2State;
62
63static SRes Lzma2Dec_GetOldProps(Byte prop, Byte *props)
64{
65 UInt32 dicSize;
66 if (prop > 40)
67 return SZ_ERROR_UNSUPPORTED;
68 dicSize = (prop == 40) ? 0xFFFFFFFF : LZMA2_DIC_SIZE_FROM_PROP(prop);
69 props[0] = (Byte)LZMA2_LCLP_MAX;
70 props[1] = (Byte)(dicSize);
71 props[2] = (Byte)(dicSize >> 8);
72 props[3] = (Byte)(dicSize >> 16);
73 props[4] = (Byte)(dicSize >> 24);
74 return SZ_OK;
75}
76
77SRes Lzma2Dec_AllocateProbs(CLzma2Dec *p, Byte prop, ISzAlloc *alloc)
78{
79 Byte props[LZMA_PROPS_SIZE];
80 RINOK(Lzma2Dec_GetOldProps(prop, props));
81 return LzmaDec_AllocateProbs(&p->decoder, props, LZMA_PROPS_SIZE, alloc);
82}
83
84SRes Lzma2Dec_Allocate(CLzma2Dec *p, Byte prop, ISzAlloc *alloc)
85{
86 Byte props[LZMA_PROPS_SIZE];
87 RINOK(Lzma2Dec_GetOldProps(prop, props));
88 return LzmaDec_Allocate(&p->decoder, props, LZMA_PROPS_SIZE, alloc);
89}
90
91void Lzma2Dec_Init(CLzma2Dec *p)
92{
93 p->state = LZMA2_STATE_CONTROL;
94 p->needInitDic = True;
95 p->needInitState = True;
96 p->needInitProp = True;
97 LzmaDec_Init(&p->decoder);
98}
99
100static ELzma2State Lzma2Dec_UpdateState(CLzma2Dec *p, Byte b)
101{
102 switch (p->state)
103 {
104 case LZMA2_STATE_CONTROL:
105 p->control = b;
106 PRF(printf("\n %4X ", (unsigned)p->decoder.dicPos));
107 PRF(printf(" %2X", (unsigned)b));
108 if (p->control == 0)
109 return LZMA2_STATE_FINISHED;
110 if (LZMA2_IS_UNCOMPRESSED_STATE(p))
111 {
112 if ((p->control & 0x7F) > 2)
113 return LZMA2_STATE_ERROR;
114 p->unpackSize = 0;
115 }
116 else
117 p->unpackSize = (UInt32)(p->control & 0x1F) << 16;
118 return LZMA2_STATE_UNPACK0;
119
120 case LZMA2_STATE_UNPACK0:
121 p->unpackSize |= (UInt32)b << 8;
122 return LZMA2_STATE_UNPACK1;
123
124 case LZMA2_STATE_UNPACK1:
125 p->unpackSize |= (UInt32)b;
126 p->unpackSize++;
127 PRF(printf(" %8u", (unsigned)p->unpackSize));
128 return (LZMA2_IS_UNCOMPRESSED_STATE(p)) ? LZMA2_STATE_DATA : LZMA2_STATE_PACK0;
129
130 case LZMA2_STATE_PACK0:
131 p->packSize = (UInt32)b << 8;
132 return LZMA2_STATE_PACK1;
133
134 case LZMA2_STATE_PACK1:
135 p->packSize |= (UInt32)b;
136 p->packSize++;
137 PRF(printf(" %8u", (unsigned)p->packSize));
138 return LZMA2_IS_THERE_PROP(LZMA2_GET_LZMA_MODE(p)) ? LZMA2_STATE_PROP:
139 (p->needInitProp ? LZMA2_STATE_ERROR : LZMA2_STATE_DATA);
140
141 case LZMA2_STATE_PROP:
142 {
143 unsigned lc, lp;
144 if (b >= (9 * 5 * 5))
145 return LZMA2_STATE_ERROR;
146 lc = b % 9;
147 b /= 9;
148 p->decoder.prop.pb = b / 5;
149 lp = b % 5;
150 if (lc + lp > LZMA2_LCLP_MAX)
151 return LZMA2_STATE_ERROR;
152 p->decoder.prop.lc = lc;
153 p->decoder.prop.lp = lp;
154 p->needInitProp = False;
155 return LZMA2_STATE_DATA;
156 }
157 }
158 return LZMA2_STATE_ERROR;
159}
160
161static void LzmaDec_UpdateWithUncompressed(CLzmaDec *p, const Byte *src, SizeT size)
162{
163 memcpy(p->dic + p->dicPos, src, size);
164 p->dicPos += size;
165 if (p->checkDicSize == 0 && p->prop.dicSize - p->processedPos <= size)
166 p->checkDicSize = p->prop.dicSize;
167 p->processedPos += (UInt32)size;
168}
169
170void LzmaDec_InitDicAndState(CLzmaDec *p, Bool initDic, Bool initState);
171
172SRes Lzma2Dec_DecodeToDic(CLzma2Dec *p, SizeT dicLimit,
173 const Byte *src, SizeT *srcLen, ELzmaFinishMode finishMode, ELzmaStatus *status)
174{
175 SizeT inSize = *srcLen;
176 *srcLen = 0;
177 *status = LZMA_STATUS_NOT_SPECIFIED;
178
179 while (p->state != LZMA2_STATE_FINISHED)
180 {
181 SizeT dicPos = p->decoder.dicPos;
182
183 if (p->state == LZMA2_STATE_ERROR)
184 return SZ_ERROR_DATA;
185
186 if (dicPos == dicLimit && finishMode == LZMA_FINISH_ANY)
187 {
188 *status = LZMA_STATUS_NOT_FINISHED;
189 return SZ_OK;
190 }
191
192 if (p->state != LZMA2_STATE_DATA && p->state != LZMA2_STATE_DATA_CONT)
193 {
194 if (*srcLen == inSize)
195 {
196 *status = LZMA_STATUS_NEEDS_MORE_INPUT;
197 return SZ_OK;
198 }
199 (*srcLen)++;
200 p->state = Lzma2Dec_UpdateState(p, *src++);
201
202 if (dicPos == dicLimit && p->state != LZMA2_STATE_FINISHED)
203 {
204 p->state = LZMA2_STATE_ERROR;
205 return SZ_ERROR_DATA;
206 }
207 continue;
208 }
209
210 {
211 SizeT destSizeCur = dicLimit - dicPos;
212 SizeT srcSizeCur = inSize - *srcLen;
213 ELzmaFinishMode curFinishMode = LZMA_FINISH_ANY;
214
215 if (p->unpackSize <= destSizeCur)
216 {
217 destSizeCur = (SizeT)p->unpackSize;
218 curFinishMode = LZMA_FINISH_END;
219 }
220
221 if (LZMA2_IS_UNCOMPRESSED_STATE(p))
222 {
223 if (*srcLen == inSize)
224 {
225 *status = LZMA_STATUS_NEEDS_MORE_INPUT;
226 return SZ_OK;
227 }
228
229 if (p->state == LZMA2_STATE_DATA)
230 {
231 Bool initDic = (p->control == LZMA2_CONTROL_COPY_RESET_DIC);
232 if (initDic)
233 p->needInitProp = p->needInitState = True;
234 else if (p->needInitDic)
235 {
236 p->state = LZMA2_STATE_ERROR;
237 return SZ_ERROR_DATA;
238 }
239 p->needInitDic = False;
240 LzmaDec_InitDicAndState(&p->decoder, initDic, False);
241 }
242
243 if (srcSizeCur > destSizeCur)
244 srcSizeCur = destSizeCur;
245
246 if (srcSizeCur == 0)
247 {
248 p->state = LZMA2_STATE_ERROR;
249 return SZ_ERROR_DATA;
250 }
251
252 LzmaDec_UpdateWithUncompressed(&p->decoder, src, srcSizeCur);
253
254 src += srcSizeCur;
255 *srcLen += srcSizeCur;
256 p->unpackSize -= (UInt32)srcSizeCur;
257 p->state = (p->unpackSize == 0) ? LZMA2_STATE_CONTROL : LZMA2_STATE_DATA_CONT;
258 }
259 else
260 {
261 SizeT outSizeProcessed;
262 SRes res;
263
264 if (p->state == LZMA2_STATE_DATA)
265 {
266 unsigned mode = LZMA2_GET_LZMA_MODE(p);
267 Bool initDic = (mode == 3);
268 Bool initState = (mode != 0);
269 if ((!initDic && p->needInitDic) || (!initState && p->needInitState))
270 {
271 p->state = LZMA2_STATE_ERROR;
272 return SZ_ERROR_DATA;
273 }
274
275 LzmaDec_InitDicAndState(&p->decoder, initDic, initState);
276 p->needInitDic = False;
277 p->needInitState = False;
278 p->state = LZMA2_STATE_DATA_CONT;
279 }
280
281 if (srcSizeCur > p->packSize)
282 srcSizeCur = (SizeT)p->packSize;
283
284 res = LzmaDec_DecodeToDic(&p->decoder, dicPos + destSizeCur, src, &srcSizeCur, curFinishMode, status);
285
286 src += srcSizeCur;
287 *srcLen += srcSizeCur;
288 p->packSize -= (UInt32)srcSizeCur;
289
290 outSizeProcessed = p->decoder.dicPos - dicPos;
291 p->unpackSize -= (UInt32)outSizeProcessed;
292
293 RINOK(res);
294 if (*status == LZMA_STATUS_NEEDS_MORE_INPUT)
295 return res;
296
297 if (srcSizeCur == 0 && outSizeProcessed == 0)
298 {
299 if (*status != LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK
300 || p->unpackSize != 0
301 || p->packSize != 0)
302 {
303 p->state = LZMA2_STATE_ERROR;
304 return SZ_ERROR_DATA;
305 }
306 p->state = LZMA2_STATE_CONTROL;
307 }
308
309 if (*status == LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK)
310 *status = LZMA_STATUS_NOT_FINISHED;
311 }
312 }
313 }
314
315 *status = LZMA_STATUS_FINISHED_WITH_MARK;
316 return SZ_OK;
317}
318
319SRes Lzma2Dec_DecodeToBuf(CLzma2Dec *p, Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen, ELzmaFinishMode finishMode, ELzmaStatus *status)
320{
321 SizeT outSize = *destLen, inSize = *srcLen;
322 *srcLen = *destLen = 0;
323 for (;;)
324 {
325 SizeT srcSizeCur = inSize, outSizeCur, dicPos;
326 ELzmaFinishMode curFinishMode;
327 SRes res;
328 if (p->decoder.dicPos == p->decoder.dicBufSize)
329 p->decoder.dicPos = 0;
330 dicPos = p->decoder.dicPos;
331 if (outSize > p->decoder.dicBufSize - dicPos)
332 {
333 outSizeCur = p->decoder.dicBufSize;
334 curFinishMode = LZMA_FINISH_ANY;
335 }
336 else
337 {
338 outSizeCur = dicPos + outSize;
339 curFinishMode = finishMode;
340 }
341
342 res = Lzma2Dec_DecodeToDic(p, outSizeCur, src, &srcSizeCur, curFinishMode, status);
343 src += srcSizeCur;
344 inSize -= srcSizeCur;
345 *srcLen += srcSizeCur;
346 outSizeCur = p->decoder.dicPos - dicPos;
347 memcpy(dest, p->decoder.dic + dicPos, outSizeCur);
348 dest += outSizeCur;
349 outSize -= outSizeCur;
350 *destLen += outSizeCur;
351 if (res != 0)
352 return res;
353 if (outSizeCur == 0 || outSize == 0)
354 return SZ_OK;
355 }
356}
357
358SRes Lzma2Decode(Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen,
359 Byte prop, ELzmaFinishMode finishMode, ELzmaStatus *status, ISzAlloc *alloc)
360{
361 CLzma2Dec p;
362 SRes res;
363 SizeT outSize = *destLen, inSize = *srcLen;
364 *destLen = *srcLen = 0;
365 *status = LZMA_STATUS_NOT_SPECIFIED;
366 Lzma2Dec_Construct(&p);
367 RINOK(Lzma2Dec_AllocateProbs(&p, prop, alloc));
368 p.decoder.dic = dest;
369 p.decoder.dicBufSize = outSize;
370 Lzma2Dec_Init(&p);
371 *srcLen = inSize;
372 res = Lzma2Dec_DecodeToDic(&p, outSize, src, srcLen, finishMode, status);
373 *destLen = p.decoder.dicPos;
374 if (res == SZ_OK && *status == LZMA_STATUS_NEEDS_MORE_INPUT)
375 res = SZ_ERROR_INPUT_EOF;
376 Lzma2Dec_FreeProbs(&p, alloc);
377 return res;
378}