Enable Enterprise enrollment on desktop builds.
[chromium-blink-merge.git] / third_party / lzma_sdk / Lzma2Dec.c
blob7ea1cc9535703e895f9f339a1f22047139f49517
1 /* Lzma2Dec.c -- LZMA2 Decoder
2 2009-05-03 : Igor Pavlov : Public domain */
4 /* #define SHOW_DEBUG_INFO */
6 #ifdef SHOW_DEBUG_INFO
7 #include <stdio.h>
8 #endif
10 #include <string.h>
12 #include "Lzma2Dec.h"
15 00000000 - EOS
16 00000001 U U - Uncompressed Reset Dic
17 00000010 U U - Uncompressed No Reset
18 100uuuuu U U P P - LZMA no reset
19 101uuuuu U U P P - LZMA reset state
20 110uuuuu U U P P S - LZMA reset state + new prop
21 111uuuuu U U P P S - LZMA reset state + new prop + reset dic
23 u, U - Unpack Size
24 P - Pack Size
25 S - Props
28 #define LZMA2_CONTROL_LZMA (1 << 7)
29 #define LZMA2_CONTROL_COPY_NO_RESET 2
30 #define LZMA2_CONTROL_COPY_RESET_DIC 1
31 #define LZMA2_CONTROL_EOF 0
33 #define LZMA2_IS_UNCOMPRESSED_STATE(p) (((p)->control & LZMA2_CONTROL_LZMA) == 0)
35 #define LZMA2_GET_LZMA_MODE(p) (((p)->control >> 5) & 3)
36 #define LZMA2_IS_THERE_PROP(mode) ((mode) >= 2)
38 #define LZMA2_LCLP_MAX 4
39 #define LZMA2_DIC_SIZE_FROM_PROP(p) (((UInt32)2 | ((p) & 1)) << ((p) / 2 + 11))
41 #ifdef SHOW_DEBUG_INFO
42 #define PRF(x) x
43 #else
44 #define PRF(x)
45 #endif
47 typedef enum
49 LZMA2_STATE_CONTROL,
50 LZMA2_STATE_UNPACK0,
51 LZMA2_STATE_UNPACK1,
52 LZMA2_STATE_PACK0,
53 LZMA2_STATE_PACK1,
54 LZMA2_STATE_PROP,
55 LZMA2_STATE_DATA,
56 LZMA2_STATE_DATA_CONT,
57 LZMA2_STATE_FINISHED,
58 LZMA2_STATE_ERROR
59 } ELzma2State;
61 static SRes Lzma2Dec_GetOldProps(Byte prop, Byte *props)
63 UInt32 dicSize;
64 if (prop > 40)
65 return SZ_ERROR_UNSUPPORTED;
66 dicSize = (prop == 40) ? 0xFFFFFFFF : LZMA2_DIC_SIZE_FROM_PROP(prop);
67 props[0] = (Byte)LZMA2_LCLP_MAX;
68 props[1] = (Byte)(dicSize);
69 props[2] = (Byte)(dicSize >> 8);
70 props[3] = (Byte)(dicSize >> 16);
71 props[4] = (Byte)(dicSize >> 24);
72 return SZ_OK;
75 SRes Lzma2Dec_AllocateProbs(CLzma2Dec *p, Byte prop, ISzAlloc *alloc)
77 Byte props[LZMA_PROPS_SIZE];
78 RINOK(Lzma2Dec_GetOldProps(prop, props));
79 return LzmaDec_AllocateProbs(&p->decoder, props, LZMA_PROPS_SIZE, alloc);
82 SRes Lzma2Dec_Allocate(CLzma2Dec *p, Byte prop, ISzAlloc *alloc)
84 Byte props[LZMA_PROPS_SIZE];
85 RINOK(Lzma2Dec_GetOldProps(prop, props));
86 return LzmaDec_Allocate(&p->decoder, props, LZMA_PROPS_SIZE, alloc);
89 void Lzma2Dec_Init(CLzma2Dec *p)
91 p->state = LZMA2_STATE_CONTROL;
92 p->needInitDic = True;
93 p->needInitState = True;
94 p->needInitProp = True;
95 LzmaDec_Init(&p->decoder);
98 static ELzma2State Lzma2Dec_UpdateState(CLzma2Dec *p, Byte b)
100 switch(p->state)
102 case LZMA2_STATE_CONTROL:
103 p->control = b;
104 PRF(printf("\n %4X ", p->decoder.dicPos));
105 PRF(printf(" %2X", b));
106 if (p->control == 0)
107 return LZMA2_STATE_FINISHED;
108 if (LZMA2_IS_UNCOMPRESSED_STATE(p))
110 if ((p->control & 0x7F) > 2)
111 return LZMA2_STATE_ERROR;
112 p->unpackSize = 0;
114 else
115 p->unpackSize = (UInt32)(p->control & 0x1F) << 16;
116 return LZMA2_STATE_UNPACK0;
118 case LZMA2_STATE_UNPACK0:
119 p->unpackSize |= (UInt32)b << 8;
120 return LZMA2_STATE_UNPACK1;
122 case LZMA2_STATE_UNPACK1:
123 p->unpackSize |= (UInt32)b;
124 p->unpackSize++;
125 PRF(printf(" %8d", p->unpackSize));
126 return (LZMA2_IS_UNCOMPRESSED_STATE(p)) ? LZMA2_STATE_DATA : LZMA2_STATE_PACK0;
128 case LZMA2_STATE_PACK0:
129 p->packSize = (UInt32)b << 8;
130 return LZMA2_STATE_PACK1;
132 case LZMA2_STATE_PACK1:
133 p->packSize |= (UInt32)b;
134 p->packSize++;
135 PRF(printf(" %8d", p->packSize));
136 return LZMA2_IS_THERE_PROP(LZMA2_GET_LZMA_MODE(p)) ? LZMA2_STATE_PROP:
137 (p->needInitProp ? LZMA2_STATE_ERROR : LZMA2_STATE_DATA);
139 case LZMA2_STATE_PROP:
141 int lc, lp;
142 if (b >= (9 * 5 * 5))
143 return LZMA2_STATE_ERROR;
144 lc = b % 9;
145 b /= 9;
146 p->decoder.prop.pb = b / 5;
147 lp = b % 5;
148 if (lc + lp > LZMA2_LCLP_MAX)
149 return LZMA2_STATE_ERROR;
150 p->decoder.prop.lc = lc;
151 p->decoder.prop.lp = lp;
152 p->needInitProp = False;
153 return LZMA2_STATE_DATA;
156 return LZMA2_STATE_ERROR;
159 static void LzmaDec_UpdateWithUncompressed(CLzmaDec *p, const Byte *src, SizeT size)
161 memcpy(p->dic + p->dicPos, src, size);
162 p->dicPos += size;
163 if (p->checkDicSize == 0 && p->prop.dicSize - p->processedPos <= size)
164 p->checkDicSize = p->prop.dicSize;
165 p->processedPos += (UInt32)size;
168 void LzmaDec_InitDicAndState(CLzmaDec *p, Bool initDic, Bool initState);
170 SRes Lzma2Dec_DecodeToDic(CLzma2Dec *p, SizeT dicLimit,
171 const Byte *src, SizeT *srcLen, ELzmaFinishMode finishMode, ELzmaStatus *status)
173 SizeT inSize = *srcLen;
174 *srcLen = 0;
175 *status = LZMA_STATUS_NOT_SPECIFIED;
177 while (p->state != LZMA2_STATE_FINISHED)
179 SizeT dicPos = p->decoder.dicPos;
180 if (p->state == LZMA2_STATE_ERROR)
181 return SZ_ERROR_DATA;
182 if (dicPos == dicLimit && finishMode == LZMA_FINISH_ANY)
184 *status = LZMA_STATUS_NOT_FINISHED;
185 return SZ_OK;
187 if (p->state != LZMA2_STATE_DATA && p->state != LZMA2_STATE_DATA_CONT)
189 if (*srcLen == inSize)
191 *status = LZMA_STATUS_NEEDS_MORE_INPUT;
192 return SZ_OK;
194 (*srcLen)++;
195 p->state = Lzma2Dec_UpdateState(p, *src++);
196 continue;
199 SizeT destSizeCur = dicLimit - dicPos;
200 SizeT srcSizeCur = inSize - *srcLen;
201 ELzmaFinishMode curFinishMode = LZMA_FINISH_ANY;
203 if (p->unpackSize <= destSizeCur)
205 destSizeCur = (SizeT)p->unpackSize;
206 curFinishMode = LZMA_FINISH_END;
209 if (LZMA2_IS_UNCOMPRESSED_STATE(p))
211 if (*srcLen == inSize)
213 *status = LZMA_STATUS_NEEDS_MORE_INPUT;
214 return SZ_OK;
217 if (p->state == LZMA2_STATE_DATA)
219 Bool initDic = (p->control == LZMA2_CONTROL_COPY_RESET_DIC);
220 if (initDic)
221 p->needInitProp = p->needInitState = True;
222 else if (p->needInitDic)
223 return SZ_ERROR_DATA;
224 p->needInitDic = False;
225 LzmaDec_InitDicAndState(&p->decoder, initDic, False);
228 if (srcSizeCur > destSizeCur)
229 srcSizeCur = destSizeCur;
231 if (srcSizeCur == 0)
232 return SZ_ERROR_DATA;
234 LzmaDec_UpdateWithUncompressed(&p->decoder, src, srcSizeCur);
236 src += srcSizeCur;
237 *srcLen += srcSizeCur;
238 p->unpackSize -= (UInt32)srcSizeCur;
239 p->state = (p->unpackSize == 0) ? LZMA2_STATE_CONTROL : LZMA2_STATE_DATA_CONT;
241 else
243 SizeT outSizeProcessed;
244 SRes res;
246 if (p->state == LZMA2_STATE_DATA)
248 int mode = LZMA2_GET_LZMA_MODE(p);
249 Bool initDic = (mode == 3);
250 Bool initState = (mode > 0);
251 if ((!initDic && p->needInitDic) || (!initState && p->needInitState))
252 return SZ_ERROR_DATA;
254 LzmaDec_InitDicAndState(&p->decoder, initDic, initState);
255 p->needInitDic = False;
256 p->needInitState = False;
257 p->state = LZMA2_STATE_DATA_CONT;
259 if (srcSizeCur > p->packSize)
260 srcSizeCur = (SizeT)p->packSize;
262 res = LzmaDec_DecodeToDic(&p->decoder, dicPos + destSizeCur, src, &srcSizeCur, curFinishMode, status);
264 src += srcSizeCur;
265 *srcLen += srcSizeCur;
266 p->packSize -= (UInt32)srcSizeCur;
268 outSizeProcessed = p->decoder.dicPos - dicPos;
269 p->unpackSize -= (UInt32)outSizeProcessed;
271 RINOK(res);
272 if (*status == LZMA_STATUS_NEEDS_MORE_INPUT)
273 return res;
275 if (srcSizeCur == 0 && outSizeProcessed == 0)
277 if (*status != LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK ||
278 p->unpackSize != 0 || p->packSize != 0)
279 return SZ_ERROR_DATA;
280 p->state = LZMA2_STATE_CONTROL;
282 if (*status == LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK)
283 *status = LZMA_STATUS_NOT_FINISHED;
287 *status = LZMA_STATUS_FINISHED_WITH_MARK;
288 return SZ_OK;
291 SRes Lzma2Dec_DecodeToBuf(CLzma2Dec *p, Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen, ELzmaFinishMode finishMode, ELzmaStatus *status)
293 SizeT outSize = *destLen, inSize = *srcLen;
294 *srcLen = *destLen = 0;
295 for (;;)
297 SizeT srcSizeCur = inSize, outSizeCur, dicPos;
298 ELzmaFinishMode curFinishMode;
299 SRes res;
300 if (p->decoder.dicPos == p->decoder.dicBufSize)
301 p->decoder.dicPos = 0;
302 dicPos = p->decoder.dicPos;
303 if (outSize > p->decoder.dicBufSize - dicPos)
305 outSizeCur = p->decoder.dicBufSize;
306 curFinishMode = LZMA_FINISH_ANY;
308 else
310 outSizeCur = dicPos + outSize;
311 curFinishMode = finishMode;
314 res = Lzma2Dec_DecodeToDic(p, outSizeCur, src, &srcSizeCur, curFinishMode, status);
315 src += srcSizeCur;
316 inSize -= srcSizeCur;
317 *srcLen += srcSizeCur;
318 outSizeCur = p->decoder.dicPos - dicPos;
319 memcpy(dest, p->decoder.dic + dicPos, outSizeCur);
320 dest += outSizeCur;
321 outSize -= outSizeCur;
322 *destLen += outSizeCur;
323 if (res != 0)
324 return res;
325 if (outSizeCur == 0 || outSize == 0)
326 return SZ_OK;
330 SRes Lzma2Decode(Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen,
331 Byte prop, ELzmaFinishMode finishMode, ELzmaStatus *status, ISzAlloc *alloc)
333 CLzma2Dec decoder;
334 SRes res;
335 SizeT outSize = *destLen, inSize = *srcLen;
336 Byte props[LZMA_PROPS_SIZE];
338 Lzma2Dec_Construct(&decoder);
340 *destLen = *srcLen = 0;
341 *status = LZMA_STATUS_NOT_SPECIFIED;
342 decoder.decoder.dic = dest;
343 decoder.decoder.dicBufSize = outSize;
345 RINOK(Lzma2Dec_GetOldProps(prop, props));
346 RINOK(LzmaDec_AllocateProbs(&decoder.decoder, props, LZMA_PROPS_SIZE, alloc));
348 *srcLen = inSize;
349 res = Lzma2Dec_DecodeToDic(&decoder, outSize, src, srcLen, finishMode, status);
350 *destLen = decoder.decoder.dicPos;
351 if (res == SZ_OK && *status == LZMA_STATUS_NEEDS_MORE_INPUT)
352 res = SZ_ERROR_INPUT_EOF;
354 LzmaDec_FreeProbs(&decoder.decoder, alloc);
355 return res;