1 /* Lzma2Dec.c -- LZMA2 Decoder
2 2019-02-02 : Igor Pavlov : Public domain */
4 /* #define SHOW_DEBUG_INFO */
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
30 #define LZMA2_CONTROL_COPY_RESET_DIC 1
32 #define LZMA2_IS_UNCOMPRESSED_STATE(p) (((p)->control & (1 << 7)) == 0)
34 #define LZMA2_LCLP_MAX 4
35 #define LZMA2_DIC_SIZE_FROM_PROP(p) (((UInt32)2 | ((p) & 1)) << ((p) / 2 + 11))
37 #ifdef SHOW_DEBUG_INFO
52 LZMA2_STATE_DATA_CONT
,
57 static SRes
Lzma2Dec_GetOldProps(Byte prop
, Byte
*props
)
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);
71 SRes
Lzma2Dec_AllocateProbs(CLzma2Dec
*p
, Byte prop
, ISzAllocPtr alloc
)
73 Byte props
[LZMA_PROPS_SIZE
];
74 RINOK(Lzma2Dec_GetOldProps(prop
, props
));
75 return LzmaDec_AllocateProbs(&p
->decoder
, props
, LZMA_PROPS_SIZE
, alloc
);
78 SRes
Lzma2Dec_Allocate(CLzma2Dec
*p
, Byte prop
, ISzAllocPtr alloc
)
80 Byte props
[LZMA_PROPS_SIZE
];
81 RINOK(Lzma2Dec_GetOldProps(prop
, props
));
82 return LzmaDec_Allocate(&p
->decoder
, props
, LZMA_PROPS_SIZE
, alloc
);
85 void Lzma2Dec_Init(CLzma2Dec
*p
)
87 p
->state
= LZMA2_STATE_CONTROL
;
88 p
->needInitLevel
= 0xE0;
89 p
->isExtraMode
= False
;
92 // p->decoder.dicPos = 0; // we can use it instead of full init
93 LzmaDec_Init(&p
->decoder
);
96 static ELzma2State
Lzma2Dec_UpdateState(CLzma2Dec
*p
, Byte b
)
100 case LZMA2_STATE_CONTROL
:
101 p
->isExtraMode
= False
;
103 PRF(printf("\n %8X", (unsigned)p
->decoder
.dicPos
));
104 PRF(printf(" %02X", (unsigned)b
));
106 return LZMA2_STATE_FINISHED
;
107 if (LZMA2_IS_UNCOMPRESSED_STATE(p
))
109 if (b
== LZMA2_CONTROL_COPY_RESET_DIC
)
110 p
->needInitLevel
= 0xC0;
111 else if (b
> 2 || p
->needInitLevel
== 0xE0)
112 return LZMA2_STATE_ERROR
;
116 if (b
< p
->needInitLevel
)
117 return LZMA2_STATE_ERROR
;
118 p
->needInitLevel
= 0;
119 p
->unpackSize
= (UInt32
)(b
& 0x1F) << 16;
121 return LZMA2_STATE_UNPACK0
;
123 case LZMA2_STATE_UNPACK0
:
124 p
->unpackSize
|= (UInt32
)b
<< 8;
125 return LZMA2_STATE_UNPACK1
;
127 case LZMA2_STATE_UNPACK1
:
128 p
->unpackSize
|= (UInt32
)b
;
130 PRF(printf(" %7u", (unsigned)p
->unpackSize
));
131 return LZMA2_IS_UNCOMPRESSED_STATE(p
) ? LZMA2_STATE_DATA
: LZMA2_STATE_PACK0
;
133 case LZMA2_STATE_PACK0
:
134 p
->packSize
= (UInt32
)b
<< 8;
135 return LZMA2_STATE_PACK1
;
137 case LZMA2_STATE_PACK1
:
138 p
->packSize
|= (UInt32
)b
;
140 // if (p->packSize < 5) return LZMA2_STATE_ERROR;
141 PRF(printf(" %5u", (unsigned)p
->packSize
));
142 return (p
->control
& 0x40) ? LZMA2_STATE_PROP
: LZMA2_STATE_DATA
;
144 case LZMA2_STATE_PROP
:
147 if (b
>= (9 * 5 * 5))
148 return LZMA2_STATE_ERROR
;
151 p
->decoder
.prop
.pb
= (Byte
)(b
/ 5);
153 if (lc
+ lp
> LZMA2_LCLP_MAX
)
154 return LZMA2_STATE_ERROR
;
155 p
->decoder
.prop
.lc
= (Byte
)lc
;
156 p
->decoder
.prop
.lp
= (Byte
)lp
;
157 return LZMA2_STATE_DATA
;
160 return LZMA2_STATE_ERROR
;
163 static void LzmaDec_UpdateWithUncompressed(CLzmaDec
*p
, const Byte
*src
, SizeT size
)
165 memcpy(p
->dic
+ p
->dicPos
, src
, size
);
167 if (p
->checkDicSize
== 0 && p
->prop
.dicSize
- p
->processedPos
<= size
)
168 p
->checkDicSize
= p
->prop
.dicSize
;
169 p
->processedPos
+= (UInt32
)size
;
172 void LzmaDec_InitDicAndState(CLzmaDec
*p
, BoolInt initDic
, BoolInt initState
);
175 SRes
Lzma2Dec_DecodeToDic(CLzma2Dec
*p
, SizeT dicLimit
,
176 const Byte
*src
, SizeT
*srcLen
, ELzmaFinishMode finishMode
, ELzmaStatus
*status
)
178 SizeT inSize
= *srcLen
;
180 *status
= LZMA_STATUS_NOT_SPECIFIED
;
182 while (p
->state
!= LZMA2_STATE_ERROR
)
186 if (p
->state
== LZMA2_STATE_FINISHED
)
188 *status
= LZMA_STATUS_FINISHED_WITH_MARK
;
192 dicPos
= p
->decoder
.dicPos
;
194 if (dicPos
== dicLimit
&& finishMode
== LZMA_FINISH_ANY
)
196 *status
= LZMA_STATUS_NOT_FINISHED
;
200 if (p
->state
!= LZMA2_STATE_DATA
&& p
->state
!= LZMA2_STATE_DATA_CONT
)
202 if (*srcLen
== inSize
)
204 *status
= LZMA_STATUS_NEEDS_MORE_INPUT
;
208 p
->state
= Lzma2Dec_UpdateState(p
, *src
++);
209 if (dicPos
== dicLimit
&& p
->state
!= LZMA2_STATE_FINISHED
)
215 SizeT inCur
= inSize
- *srcLen
;
216 SizeT outCur
= dicLimit
- dicPos
;
217 ELzmaFinishMode curFinishMode
= LZMA_FINISH_ANY
;
219 if (outCur
>= p
->unpackSize
)
221 outCur
= (SizeT
)p
->unpackSize
;
222 curFinishMode
= LZMA_FINISH_END
;
225 if (LZMA2_IS_UNCOMPRESSED_STATE(p
))
229 *status
= LZMA_STATUS_NEEDS_MORE_INPUT
;
233 if (p
->state
== LZMA2_STATE_DATA
)
235 BoolInt initDic
= (p
->control
== LZMA2_CONTROL_COPY_RESET_DIC
);
236 LzmaDec_InitDicAndState(&p
->decoder
, initDic
, False
);
244 LzmaDec_UpdateWithUncompressed(&p
->decoder
, src
, inCur
);
248 p
->unpackSize
-= (UInt32
)inCur
;
249 p
->state
= (p
->unpackSize
== 0) ? LZMA2_STATE_CONTROL
: LZMA2_STATE_DATA_CONT
;
255 if (p
->state
== LZMA2_STATE_DATA
)
257 BoolInt initDic
= (p
->control
>= 0xE0);
258 BoolInt initState
= (p
->control
>= 0xA0);
259 LzmaDec_InitDicAndState(&p
->decoder
, initDic
, initState
);
260 p
->state
= LZMA2_STATE_DATA_CONT
;
263 if (inCur
> p
->packSize
)
264 inCur
= (SizeT
)p
->packSize
;
266 res
= LzmaDec_DecodeToDic(&p
->decoder
, dicPos
+ outCur
, src
, &inCur
, curFinishMode
, status
);
270 p
->packSize
-= (UInt32
)inCur
;
271 outCur
= p
->decoder
.dicPos
- dicPos
;
272 p
->unpackSize
-= (UInt32
)outCur
;
277 if (*status
== LZMA_STATUS_NEEDS_MORE_INPUT
)
279 if (p
->packSize
== 0)
284 if (inCur
== 0 && outCur
== 0)
286 if (*status
!= LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK
287 || p
->unpackSize
!= 0
290 p
->state
= LZMA2_STATE_CONTROL
;
293 *status
= LZMA_STATUS_NOT_SPECIFIED
;
298 *status
= LZMA_STATUS_NOT_SPECIFIED
;
299 p
->state
= LZMA2_STATE_ERROR
;
300 return SZ_ERROR_DATA
;
306 ELzma2ParseStatus
Lzma2Dec_Parse(CLzma2Dec
*p
,
308 const Byte
*src
, SizeT
*srcLen
,
309 int checkFinishBlock
)
311 SizeT inSize
= *srcLen
;
314 while (p
->state
!= LZMA2_STATE_ERROR
)
316 if (p
->state
== LZMA2_STATE_FINISHED
)
317 return (ELzma2ParseStatus
)LZMA_STATUS_FINISHED_WITH_MARK
;
319 if (outSize
== 0 && !checkFinishBlock
)
320 return (ELzma2ParseStatus
)LZMA_STATUS_NOT_FINISHED
;
322 if (p
->state
!= LZMA2_STATE_DATA
&& p
->state
!= LZMA2_STATE_DATA_CONT
)
324 if (*srcLen
== inSize
)
325 return (ELzma2ParseStatus
)LZMA_STATUS_NEEDS_MORE_INPUT
;
328 p
->state
= Lzma2Dec_UpdateState(p
, *src
++);
330 if (p
->state
== LZMA2_STATE_UNPACK0
)
332 // if (p->decoder.dicPos != 0)
333 if (p
->control
== LZMA2_CONTROL_COPY_RESET_DIC
|| p
->control
>= 0xE0)
334 return LZMA2_PARSE_STATUS_NEW_BLOCK
;
335 // if (outSize == 0) return LZMA_STATUS_NOT_FINISHED;
338 // The following code can be commented.
339 // It's not big problem, if we read additional input bytes.
340 // It will be stopped later in LZMA2_STATE_DATA / LZMA2_STATE_DATA_CONT state.
342 if (outSize
== 0 && p
->state
!= LZMA2_STATE_FINISHED
)
344 // checkFinishBlock is true. So we expect that block must be finished,
345 // We can return LZMA_STATUS_NOT_SPECIFIED or LZMA_STATUS_NOT_FINISHED here
347 return (ELzma2ParseStatus
)LZMA_STATUS_NOT_FINISHED
;
350 if (p
->state
== LZMA2_STATE_DATA
)
351 return LZMA2_PARSE_STATUS_NEW_CHUNK
;
357 return (ELzma2ParseStatus
)LZMA_STATUS_NOT_FINISHED
;
360 SizeT inCur
= inSize
- *srcLen
;
362 if (LZMA2_IS_UNCOMPRESSED_STATE(p
))
365 return (ELzma2ParseStatus
)LZMA_STATUS_NEEDS_MORE_INPUT
;
366 if (inCur
> p
->unpackSize
)
367 inCur
= p
->unpackSize
;
370 p
->decoder
.dicPos
+= inCur
;
374 p
->unpackSize
-= (UInt32
)inCur
;
375 p
->state
= (p
->unpackSize
== 0) ? LZMA2_STATE_CONTROL
: LZMA2_STATE_DATA_CONT
;
379 p
->isExtraMode
= True
;
383 if (p
->packSize
!= 0)
384 return (ELzma2ParseStatus
)LZMA_STATUS_NEEDS_MORE_INPUT
;
386 else if (p
->state
== LZMA2_STATE_DATA
)
388 p
->state
= LZMA2_STATE_DATA_CONT
;
391 // first byte of lzma chunk must be Zero
398 if (inCur
> p
->packSize
)
399 inCur
= (SizeT
)p
->packSize
;
403 p
->packSize
-= (UInt32
)inCur
;
405 if (p
->packSize
== 0)
408 if (rem
> p
->unpackSize
)
410 p
->decoder
.dicPos
+= rem
;
411 p
->unpackSize
-= (UInt32
)rem
;
413 if (p
->unpackSize
== 0)
414 p
->state
= LZMA2_STATE_CONTROL
;
420 p
->state
= LZMA2_STATE_ERROR
;
421 return (ELzma2ParseStatus
)LZMA_STATUS_NOT_SPECIFIED
;
427 SRes
Lzma2Dec_DecodeToBuf(CLzma2Dec
*p
, Byte
*dest
, SizeT
*destLen
, const Byte
*src
, SizeT
*srcLen
, ELzmaFinishMode finishMode
, ELzmaStatus
*status
)
429 SizeT outSize
= *destLen
, inSize
= *srcLen
;
430 *srcLen
= *destLen
= 0;
434 SizeT inCur
= inSize
, outCur
, dicPos
;
435 ELzmaFinishMode curFinishMode
;
438 if (p
->decoder
.dicPos
== p
->decoder
.dicBufSize
)
439 p
->decoder
.dicPos
= 0;
440 dicPos
= p
->decoder
.dicPos
;
441 curFinishMode
= LZMA_FINISH_ANY
;
442 outCur
= p
->decoder
.dicBufSize
- dicPos
;
444 if (outCur
>= outSize
)
447 curFinishMode
= finishMode
;
450 res
= Lzma2Dec_DecodeToDic(p
, dicPos
+ outCur
, src
, &inCur
, curFinishMode
, status
);
455 outCur
= p
->decoder
.dicPos
- dicPos
;
456 memcpy(dest
, p
->decoder
.dic
+ dicPos
, outCur
);
462 if (outCur
== 0 || outSize
== 0)
468 SRes
Lzma2Decode(Byte
*dest
, SizeT
*destLen
, const Byte
*src
, SizeT
*srcLen
,
469 Byte prop
, ELzmaFinishMode finishMode
, ELzmaStatus
*status
, ISzAllocPtr alloc
)
473 SizeT outSize
= *destLen
, inSize
= *srcLen
;
474 *destLen
= *srcLen
= 0;
475 *status
= LZMA_STATUS_NOT_SPECIFIED
;
476 Lzma2Dec_Construct(&p
);
477 RINOK(Lzma2Dec_AllocateProbs(&p
, prop
, alloc
));
478 p
.decoder
.dic
= dest
;
479 p
.decoder
.dicBufSize
= outSize
;
482 res
= Lzma2Dec_DecodeToDic(&p
, outSize
, src
, srcLen
, finishMode
, status
);
483 *destLen
= p
.decoder
.dicPos
;
484 if (res
== SZ_OK
&& *status
== LZMA_STATUS_NEEDS_MORE_INPUT
)
485 res
= SZ_ERROR_INPUT_EOF
;
486 Lzma2Dec_FreeProbs(&p
, alloc
);