1 /* Lzma2Dec.c -- LZMA2 Decoder
2 2024-03-01 : 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 /*
17 00000000 - End of data
18 00000001 U U - Uncompressed, reset dic, need reset state and set new prop
19 00000010 U U - Uncompressed, no reset
20 100uuuuu U U P P - LZMA, no reset
21 101uuuuu U U P P - LZMA, reset state
22 110uuuuu U U P P S - LZMA, reset state + set new prop
23 111uuuuu U U P P S - LZMA, reset state + set new prop, reset dic
24
25 u, U - Unpack Size
26 P - Pack Size
27 S - Props
28 */
29
30 #define LZMA2_CONTROL_COPY_RESET_DIC 1
31
32 #define LZMA2_IS_UNCOMPRESSED_STATE(p) (((p)->control & (1 << 7)) == 0)
33
34 #define LZMA2_LCLP_MAX 4
35 #define LZMA2_DIC_SIZE_FROM_PROP(p) (((UInt32)2 | ((p) & 1)) << ((p) / 2 + 11))
36
37 #ifdef SHOW_DEBUG_INFO
38 #define PRF(x) x
39 #else
40 #define PRF(x)
41 #endif
42
43 typedef enum
44 {
45 LZMA2_STATE_CONTROL,
46 LZMA2_STATE_UNPACK0,
47 LZMA2_STATE_UNPACK1,
48 LZMA2_STATE_PACK0,
49 LZMA2_STATE_PACK1,
50 LZMA2_STATE_PROP,
51 LZMA2_STATE_DATA,
52 LZMA2_STATE_DATA_CONT,
53 LZMA2_STATE_FINISHED,
54 LZMA2_STATE_ERROR
55 } ELzma2State;
56
Lzma2Dec_GetOldProps(Byte prop,Byte * props)57 static SRes Lzma2Dec_GetOldProps(Byte prop, Byte *props)
58 {
59 UInt32 dicSize;
60 if (prop > 40)
61 return SZ_ERROR_UNSUPPORTED;
62 dicSize = (prop == 40) ? 0xFFFFFFFF : LZMA2_DIC_SIZE_FROM_PROP(prop);
63 props[0] = (Byte)LZMA2_LCLP_MAX;
64 props[1] = (Byte)(dicSize);
65 props[2] = (Byte)(dicSize >> 8);
66 props[3] = (Byte)(dicSize >> 16);
67 props[4] = (Byte)(dicSize >> 24);
68 return SZ_OK;
69 }
70
Lzma2Dec_AllocateProbs(CLzma2Dec * p,Byte prop,ISzAllocPtr alloc)71 SRes Lzma2Dec_AllocateProbs(CLzma2Dec *p, Byte prop, ISzAllocPtr alloc)
72 {
73 Byte props[LZMA_PROPS_SIZE];
74 RINOK(Lzma2Dec_GetOldProps(prop, props))
75 return LzmaDec_AllocateProbs(&p->decoder, props, LZMA_PROPS_SIZE, alloc);
76 }
77
Lzma2Dec_Allocate(CLzma2Dec * p,Byte prop,ISzAllocPtr alloc)78 SRes Lzma2Dec_Allocate(CLzma2Dec *p, Byte prop, ISzAllocPtr alloc)
79 {
80 Byte props[LZMA_PROPS_SIZE];
81 RINOK(Lzma2Dec_GetOldProps(prop, props))
82 return LzmaDec_Allocate(&p->decoder, props, LZMA_PROPS_SIZE, alloc);
83 }
84
Lzma2Dec_Init(CLzma2Dec * p)85 void Lzma2Dec_Init(CLzma2Dec *p)
86 {
87 p->state = LZMA2_STATE_CONTROL;
88 p->needInitLevel = 0xE0;
89 p->isExtraMode = False;
90 p->unpackSize = 0;
91
92 // p->decoder.dicPos = 0; // we can use it instead of full init
93 LzmaDec_Init(&p->decoder);
94 }
95
96 // ELzma2State
Lzma2Dec_UpdateState(CLzma2Dec * p,Byte b)97 static unsigned Lzma2Dec_UpdateState(CLzma2Dec *p, Byte b)
98 {
99 switch (p->state)
100 {
101 case LZMA2_STATE_CONTROL:
102 p->isExtraMode = False;
103 p->control = b;
104 PRF(printf("\n %8X", (unsigned)p->decoder.dicPos));
105 PRF(printf(" %02X", (unsigned)b));
106 if (b == 0)
107 return LZMA2_STATE_FINISHED;
108 if (LZMA2_IS_UNCOMPRESSED_STATE(p))
109 {
110 if (b == LZMA2_CONTROL_COPY_RESET_DIC)
111 p->needInitLevel = 0xC0;
112 else if (b > 2 || p->needInitLevel == 0xE0)
113 return LZMA2_STATE_ERROR;
114 }
115 else
116 {
117 if (b < p->needInitLevel)
118 return LZMA2_STATE_ERROR;
119 p->needInitLevel = 0;
120 p->unpackSize = (UInt32)(b & 0x1F) << 16;
121 }
122 return LZMA2_STATE_UNPACK0;
123
124 case LZMA2_STATE_UNPACK0:
125 p->unpackSize |= (UInt32)b << 8;
126 return LZMA2_STATE_UNPACK1;
127
128 case LZMA2_STATE_UNPACK1:
129 p->unpackSize |= (UInt32)b;
130 p->unpackSize++;
131 PRF(printf(" %7u", (unsigned)p->unpackSize));
132 return LZMA2_IS_UNCOMPRESSED_STATE(p) ? LZMA2_STATE_DATA : LZMA2_STATE_PACK0;
133
134 case LZMA2_STATE_PACK0:
135 p->packSize = (UInt32)b << 8;
136 return LZMA2_STATE_PACK1;
137
138 case LZMA2_STATE_PACK1:
139 p->packSize |= (UInt32)b;
140 p->packSize++;
141 // if (p->packSize < 5) return LZMA2_STATE_ERROR;
142 PRF(printf(" %5u", (unsigned)p->packSize));
143 return (p->control & 0x40) ? LZMA2_STATE_PROP : LZMA2_STATE_DATA;
144
145 case LZMA2_STATE_PROP:
146 {
147 unsigned lc, lp;
148 if (b >= (9 * 5 * 5))
149 return LZMA2_STATE_ERROR;
150 lc = b % 9;
151 b /= 9;
152 p->decoder.prop.pb = (Byte)(b / 5);
153 lp = b % 5;
154 if (lc + lp > LZMA2_LCLP_MAX)
155 return LZMA2_STATE_ERROR;
156 p->decoder.prop.lc = (Byte)lc;
157 p->decoder.prop.lp = (Byte)lp;
158 return LZMA2_STATE_DATA;
159 }
160
161 default:
162 return LZMA2_STATE_ERROR;
163 }
164 }
165
LzmaDec_UpdateWithUncompressed(CLzmaDec * p,const Byte * src,SizeT size)166 static void LzmaDec_UpdateWithUncompressed(CLzmaDec *p, const Byte *src, SizeT size)
167 {
168 memcpy(p->dic + p->dicPos, src, size);
169 p->dicPos += size;
170 if (p->checkDicSize == 0 && p->prop.dicSize - p->processedPos <= size)
171 p->checkDicSize = p->prop.dicSize;
172 p->processedPos += (UInt32)size;
173 }
174
175 void LzmaDec_InitDicAndState(CLzmaDec *p, BoolInt initDic, BoolInt initState);
176
177
Lzma2Dec_DecodeToDic(CLzma2Dec * p,SizeT dicLimit,const Byte * src,SizeT * srcLen,ELzmaFinishMode finishMode,ELzmaStatus * status)178 SRes Lzma2Dec_DecodeToDic(CLzma2Dec *p, SizeT dicLimit,
179 const Byte *src, SizeT *srcLen, ELzmaFinishMode finishMode, ELzmaStatus *status)
180 {
181 SizeT inSize = *srcLen;
182 *srcLen = 0;
183 *status = LZMA_STATUS_NOT_SPECIFIED;
184
185 while (p->state != LZMA2_STATE_ERROR)
186 {
187 SizeT dicPos;
188
189 if (p->state == LZMA2_STATE_FINISHED)
190 {
191 *status = LZMA_STATUS_FINISHED_WITH_MARK;
192 return SZ_OK;
193 }
194
195 dicPos = p->decoder.dicPos;
196
197 if (dicPos == dicLimit && finishMode == LZMA_FINISH_ANY)
198 {
199 *status = LZMA_STATUS_NOT_FINISHED;
200 return SZ_OK;
201 }
202
203 if (p->state != LZMA2_STATE_DATA && p->state != LZMA2_STATE_DATA_CONT)
204 {
205 if (*srcLen == inSize)
206 {
207 *status = LZMA_STATUS_NEEDS_MORE_INPUT;
208 return SZ_OK;
209 }
210 (*srcLen)++;
211 p->state = Lzma2Dec_UpdateState(p, *src++);
212 if (dicPos == dicLimit && p->state != LZMA2_STATE_FINISHED)
213 break;
214 continue;
215 }
216
217 {
218 SizeT inCur = inSize - *srcLen;
219 SizeT outCur = dicLimit - dicPos;
220 ELzmaFinishMode curFinishMode = LZMA_FINISH_ANY;
221
222 if (outCur >= p->unpackSize)
223 {
224 outCur = (SizeT)p->unpackSize;
225 curFinishMode = LZMA_FINISH_END;
226 }
227
228 if (LZMA2_IS_UNCOMPRESSED_STATE(p))
229 {
230 if (inCur == 0)
231 {
232 *status = LZMA_STATUS_NEEDS_MORE_INPUT;
233 return SZ_OK;
234 }
235
236 if (p->state == LZMA2_STATE_DATA)
237 {
238 BoolInt initDic = (p->control == LZMA2_CONTROL_COPY_RESET_DIC);
239 LzmaDec_InitDicAndState(&p->decoder, initDic, False);
240 }
241
242 if (inCur > outCur)
243 inCur = outCur;
244 if (inCur == 0)
245 break;
246
247 LzmaDec_UpdateWithUncompressed(&p->decoder, src, inCur);
248
249 src += inCur;
250 *srcLen += inCur;
251 p->unpackSize -= (UInt32)inCur;
252 p->state = (p->unpackSize == 0) ? LZMA2_STATE_CONTROL : LZMA2_STATE_DATA_CONT;
253 }
254 else
255 {
256 SRes res;
257
258 if (p->state == LZMA2_STATE_DATA)
259 {
260 BoolInt initDic = (p->control >= 0xE0);
261 BoolInt initState = (p->control >= 0xA0);
262 LzmaDec_InitDicAndState(&p->decoder, initDic, initState);
263 p->state = LZMA2_STATE_DATA_CONT;
264 }
265
266 if (inCur > p->packSize)
267 inCur = (SizeT)p->packSize;
268
269 res = LzmaDec_DecodeToDic(&p->decoder, dicPos + outCur, src, &inCur, curFinishMode, status);
270
271 src += inCur;
272 *srcLen += inCur;
273 p->packSize -= (UInt32)inCur;
274 outCur = p->decoder.dicPos - dicPos;
275 p->unpackSize -= (UInt32)outCur;
276
277 if (res != 0)
278 break;
279
280 if (*status == LZMA_STATUS_NEEDS_MORE_INPUT)
281 {
282 if (p->packSize == 0)
283 break;
284 return SZ_OK;
285 }
286
287 if (inCur == 0 && outCur == 0)
288 {
289 if (*status != LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK
290 || p->unpackSize != 0
291 || p->packSize != 0)
292 break;
293 p->state = LZMA2_STATE_CONTROL;
294 }
295
296 *status = LZMA_STATUS_NOT_SPECIFIED;
297 }
298 }
299 }
300
301 *status = LZMA_STATUS_NOT_SPECIFIED;
302 p->state = LZMA2_STATE_ERROR;
303 return SZ_ERROR_DATA;
304 }
305
306
307
308
Lzma2Dec_Parse(CLzma2Dec * p,SizeT outSize,const Byte * src,SizeT * srcLen,int checkFinishBlock)309 ELzma2ParseStatus Lzma2Dec_Parse(CLzma2Dec *p,
310 SizeT outSize,
311 const Byte *src, SizeT *srcLen,
312 int checkFinishBlock)
313 {
314 SizeT inSize = *srcLen;
315 *srcLen = 0;
316
317 while (p->state != LZMA2_STATE_ERROR)
318 {
319 if (p->state == LZMA2_STATE_FINISHED)
320 return (ELzma2ParseStatus)LZMA_STATUS_FINISHED_WITH_MARK;
321
322 if (outSize == 0 && !checkFinishBlock)
323 return (ELzma2ParseStatus)LZMA_STATUS_NOT_FINISHED;
324
325 if (p->state != LZMA2_STATE_DATA && p->state != LZMA2_STATE_DATA_CONT)
326 {
327 if (*srcLen == inSize)
328 return (ELzma2ParseStatus)LZMA_STATUS_NEEDS_MORE_INPUT;
329 (*srcLen)++;
330
331 p->state = Lzma2Dec_UpdateState(p, *src++);
332
333 if (p->state == LZMA2_STATE_UNPACK0)
334 {
335 // if (p->decoder.dicPos != 0)
336 if (p->control == LZMA2_CONTROL_COPY_RESET_DIC || p->control >= 0xE0)
337 return LZMA2_PARSE_STATUS_NEW_BLOCK;
338 // if (outSize == 0) return LZMA_STATUS_NOT_FINISHED;
339 }
340
341 // The following code can be commented.
342 // It's not big problem, if we read additional input bytes.
343 // It will be stopped later in LZMA2_STATE_DATA / LZMA2_STATE_DATA_CONT state.
344
345 if (outSize == 0 && p->state != LZMA2_STATE_FINISHED)
346 {
347 // checkFinishBlock is true. So we expect that block must be finished,
348 // We can return LZMA_STATUS_NOT_SPECIFIED or LZMA_STATUS_NOT_FINISHED here
349 // break;
350 return (ELzma2ParseStatus)LZMA_STATUS_NOT_FINISHED;
351 }
352
353 if (p->state == LZMA2_STATE_DATA)
354 return LZMA2_PARSE_STATUS_NEW_CHUNK;
355
356 continue;
357 }
358
359 if (outSize == 0)
360 return (ELzma2ParseStatus)LZMA_STATUS_NOT_FINISHED;
361
362 {
363 SizeT inCur = inSize - *srcLen;
364
365 if (LZMA2_IS_UNCOMPRESSED_STATE(p))
366 {
367 if (inCur == 0)
368 return (ELzma2ParseStatus)LZMA_STATUS_NEEDS_MORE_INPUT;
369 if (inCur > p->unpackSize)
370 inCur = p->unpackSize;
371 if (inCur > outSize)
372 inCur = outSize;
373 p->decoder.dicPos += inCur;
374 src += inCur;
375 *srcLen += inCur;
376 outSize -= inCur;
377 p->unpackSize -= (UInt32)inCur;
378 p->state = (p->unpackSize == 0) ? LZMA2_STATE_CONTROL : LZMA2_STATE_DATA_CONT;
379 }
380 else
381 {
382 p->isExtraMode = True;
383
384 if (inCur == 0)
385 {
386 if (p->packSize != 0)
387 return (ELzma2ParseStatus)LZMA_STATUS_NEEDS_MORE_INPUT;
388 }
389 else if (p->state == LZMA2_STATE_DATA)
390 {
391 p->state = LZMA2_STATE_DATA_CONT;
392 if (*src != 0)
393 {
394 // first byte of lzma chunk must be Zero
395 *srcLen += 1;
396 p->packSize--;
397 break;
398 }
399 }
400
401 if (inCur > p->packSize)
402 inCur = (SizeT)p->packSize;
403
404 src += inCur;
405 *srcLen += inCur;
406 p->packSize -= (UInt32)inCur;
407
408 if (p->packSize == 0)
409 {
410 SizeT rem = outSize;
411 if (rem > p->unpackSize)
412 rem = p->unpackSize;
413 p->decoder.dicPos += rem;
414 p->unpackSize -= (UInt32)rem;
415 outSize -= rem;
416 if (p->unpackSize == 0)
417 p->state = LZMA2_STATE_CONTROL;
418 }
419 }
420 }
421 }
422
423 p->state = LZMA2_STATE_ERROR;
424 return (ELzma2ParseStatus)LZMA_STATUS_NOT_SPECIFIED;
425 }
426
427
428
429
Lzma2Dec_DecodeToBuf(CLzma2Dec * p,Byte * dest,SizeT * destLen,const Byte * src,SizeT * srcLen,ELzmaFinishMode finishMode,ELzmaStatus * status)430 SRes Lzma2Dec_DecodeToBuf(CLzma2Dec *p, Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen, ELzmaFinishMode finishMode, ELzmaStatus *status)
431 {
432 SizeT outSize = *destLen, inSize = *srcLen;
433 *srcLen = *destLen = 0;
434
435 for (;;)
436 {
437 SizeT inCur = inSize, outCur, dicPos;
438 ELzmaFinishMode curFinishMode;
439 SRes res;
440
441 if (p->decoder.dicPos == p->decoder.dicBufSize)
442 p->decoder.dicPos = 0;
443 dicPos = p->decoder.dicPos;
444 curFinishMode = LZMA_FINISH_ANY;
445 outCur = p->decoder.dicBufSize - dicPos;
446
447 if (outCur >= outSize)
448 {
449 outCur = outSize;
450 curFinishMode = finishMode;
451 }
452
453 res = Lzma2Dec_DecodeToDic(p, dicPos + outCur, src, &inCur, curFinishMode, status);
454
455 src += inCur;
456 inSize -= inCur;
457 *srcLen += inCur;
458 outCur = p->decoder.dicPos - dicPos;
459 memcpy(dest, p->decoder.dic + dicPos, outCur);
460 dest += outCur;
461 outSize -= outCur;
462 *destLen += outCur;
463 if (res != 0)
464 return res;
465 if (outCur == 0 || outSize == 0)
466 return SZ_OK;
467 }
468 }
469
470
Lzma2Decode(Byte * dest,SizeT * destLen,const Byte * src,SizeT * srcLen,Byte prop,ELzmaFinishMode finishMode,ELzmaStatus * status,ISzAllocPtr alloc)471 SRes Lzma2Decode(Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen,
472 Byte prop, ELzmaFinishMode finishMode, ELzmaStatus *status, ISzAllocPtr alloc)
473 {
474 CLzma2Dec p;
475 SRes res;
476 SizeT outSize = *destLen, inSize = *srcLen;
477 *destLen = *srcLen = 0;
478 *status = LZMA_STATUS_NOT_SPECIFIED;
479 Lzma2Dec_CONSTRUCT(&p)
480 RINOK(Lzma2Dec_AllocateProbs(&p, prop, alloc))
481 p.decoder.dic = dest;
482 p.decoder.dicBufSize = outSize;
483 Lzma2Dec_Init(&p);
484 *srcLen = inSize;
485 res = Lzma2Dec_DecodeToDic(&p, outSize, src, srcLen, finishMode, status);
486 *destLen = p.decoder.dicPos;
487 if (res == SZ_OK && *status == LZMA_STATUS_NEEDS_MORE_INPUT)
488 res = SZ_ERROR_INPUT_EOF;
489 Lzma2Dec_FreeProbs(&p, alloc);
490 return res;
491 }
492
493 #undef PRF
494