all repos — mgba @ dab12cf5c674542cae0db7708c333035255fbc65

mGBA Game Boy Advance Emulator

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}