Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | RSS feed

  1. /* Lzma2Dec.c -- LZMA2 Decoder
  2. 2014-10-29 : 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  -  EOS
  18. 00000001 U U  -  Uncompressed Reset Dic
  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 + new prop
  23. 111uuuuu 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.  
  49. typedef 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.  
  63. static 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.  
  77. SRes 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.  
  84. SRes 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.  
  91. void 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.  
  100. static 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 ", p->decoder.dicPos));
  107.       PRF(printf(" %2X", 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(" %8d", 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(" %8d", 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.  
  161. static 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.  
  170. void LzmaDec_InitDicAndState(CLzmaDec *p, Bool initDic, Bool initState);
  171.  
  172. SRes 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.  
  319. SRes 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.  
  358. SRes 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. }
  379.