]> git.proxmox.com Git - mirror_edk2.git/blobdiff - BaseTools/Source/C/LzmaCompress/Sdk/C/LzmaDec.c
BaseTools LzmaCompress: Update LZMA to new 16.04 version
[mirror_edk2.git] / BaseTools / Source / C / LzmaCompress / Sdk / C / LzmaDec.c
index 87bea866e4a1324b0c1586784023f98089988182..64f1164f3de60ad7d400929d6f8ec180c0daa387 100644 (file)
@@ -1,5 +1,7 @@
 /* LzmaDec.c -- LZMA Decoder\r
-2008-11-06 : Igor Pavlov : Public domain */\r
+2016-05-16 : Igor Pavlov : Public domain */\r
+\r
+#include "Precomp.h"\r
 \r
 #include "LzmaDec.h"\r
 \r
   i -= 0x40; }\r
 #endif\r
 \r
+#define NORMAL_LITER_DEC GET_BIT(prob + symbol, symbol)\r
+#define MATCHED_LITER_DEC \\r
+  matchByte <<= 1; \\r
+  bit = (matchByte & offs); \\r
+  probLit = prob + offs + bit + symbol; \\r
+  GET_BIT2(probLit, symbol, offs &= ~bit, offs &= bit)\r
+\r
 #define NORMALIZE_CHECK if (range < kTopValue) { if (buf >= bufLimit) return DUMMY_ERROR; range <<= 8; code = (code << 8) | (*buf++); }\r
 \r
 #define IF_BIT_0_CHECK(p) ttt = *(p); NORMALIZE_CHECK; bound = (range >> kNumBitModelTotalBits) * ttt; if (code < bound)\r
 #define Literal (RepLenCoder + kNumLenProbs)\r
 \r
 #define LZMA_BASE_SIZE 1846\r
-#define LZMA_LIT_SIZE 768\r
-\r
-#define LzmaProps_GetNumProbs(p) ((UInt32)LZMA_BASE_SIZE + (LZMA_LIT_SIZE << ((p)->lc + (p)->lp)))\r
+#define LZMA_LIT_SIZE 0x300\r
 \r
 #if Literal != LZMA_BASE_SIZE\r
 StopCompilingDueBUG\r
 #endif\r
 \r
-static const Byte kLiteralNextStates[kNumStates * 2] =\r
-{\r
-  0, 0, 0, 0, 1, 2, 3,  4,  5,  6,  4,  5,\r
-  7, 7, 7, 7, 7, 7, 7, 10, 10, 10, 10, 10\r
-};\r
+#define LzmaProps_GetNumProbs(p) (Literal + ((UInt32)LZMA_LIT_SIZE << ((p)->lc + (p)->lp)))\r
 \r
 #define LZMA_DIC_MIN (1 << 12)\r
 \r
@@ -130,8 +133,8 @@ Out:
   p->remainLen:\r
     < kMatchSpecLenStart : normal remain\r
     = kMatchSpecLenStart : finished\r
-    = kMatchSpecLenStart + 1 : Flush marker\r
-    = kMatchSpecLenStart + 2 : State Init Marker\r
+    = kMatchSpecLenStart + 1 : Flush marker (unused now)\r
+    = kMatchSpecLenStart + 2 : State Init Marker (unused now)\r
 */\r
 \r
 static int MY_FAST_CALL LzmaDec_DecodeReal(CLzmaDec *p, SizeT limit, const Byte *bufLimit)\r
@@ -169,39 +172,62 @@ static int MY_FAST_CALL LzmaDec_DecodeReal(CLzmaDec *p, SizeT limit, const Byte
       unsigned symbol;\r
       UPDATE_0(prob);\r
       prob = probs + Literal;\r
-      if (checkDicSize != 0 || processedPos != 0)\r
-        prob += (LZMA_LIT_SIZE * (((processedPos & lpMask) << lc) +\r
-        (dic[(dicPos == 0 ? dicBufSize : dicPos) - 1] >> (8 - lc))));\r
+      if (processedPos != 0 || checkDicSize != 0)\r
+        prob += ((UInt32)LZMA_LIT_SIZE * (((processedPos & lpMask) << lc) +\r
+            (dic[(dicPos == 0 ? dicBufSize : dicPos) - 1] >> (8 - lc))));\r
+      processedPos++;\r
 \r
       if (state < kNumLitStates)\r
       {\r
+        state -= (state < 4) ? state : 3;\r
         symbol = 1;\r
-        do { GET_BIT(prob + symbol, symbol) } while (symbol < 0x100);\r
+        #ifdef _LZMA_SIZE_OPT\r
+        do { NORMAL_LITER_DEC } while (symbol < 0x100);\r
+        #else\r
+        NORMAL_LITER_DEC\r
+        NORMAL_LITER_DEC\r
+        NORMAL_LITER_DEC\r
+        NORMAL_LITER_DEC\r
+        NORMAL_LITER_DEC\r
+        NORMAL_LITER_DEC\r
+        NORMAL_LITER_DEC\r
+        NORMAL_LITER_DEC\r
+        #endif\r
       }\r
       else\r
       {\r
-        unsigned matchByte = p->dic[(dicPos - rep0) + ((dicPos < rep0) ? dicBufSize : 0)];\r
+        unsigned matchByte = dic[dicPos - rep0 + (dicPos < rep0 ? dicBufSize : 0)];\r
         unsigned offs = 0x100;\r
+        state -= (state < 10) ? 3 : 6;\r
         symbol = 1;\r
+        #ifdef _LZMA_SIZE_OPT\r
         do\r
         {\r
           unsigned bit;\r
           CLzmaProb *probLit;\r
-          matchByte <<= 1;\r
-          bit = (matchByte & offs);\r
-          probLit = prob + offs + bit + symbol;\r
-          GET_BIT2(probLit, symbol, offs &= ~bit, offs &= bit)\r
+          MATCHED_LITER_DEC\r
         }\r
         while (symbol < 0x100);\r
+        #else\r
+        {\r
+          unsigned bit;\r
+          CLzmaProb *probLit;\r
+          MATCHED_LITER_DEC\r
+          MATCHED_LITER_DEC\r
+          MATCHED_LITER_DEC\r
+          MATCHED_LITER_DEC\r
+          MATCHED_LITER_DEC\r
+          MATCHED_LITER_DEC\r
+          MATCHED_LITER_DEC\r
+          MATCHED_LITER_DEC\r
+        }\r
+        #endif\r
       }\r
-      dic[dicPos++] = (Byte)symbol;\r
-      processedPos++;\r
 \r
-      state = kLiteralNextStates[state];\r
-      /* if (state < 4) state = 0; else if (state < 10) state -= 3; else state -= 6; */\r
+      dic[dicPos++] = (Byte)symbol;\r
       continue;\r
     }\r
-    else\r
+    \r
     {\r
       UPDATE_1(prob);\r
       prob = probs + IsRep + state;\r
@@ -224,7 +250,7 @@ static int MY_FAST_CALL LzmaDec_DecodeReal(CLzmaDec *p, SizeT limit, const Byte
           IF_BIT_0(prob)\r
           {\r
             UPDATE_0(prob);\r
-            dic[dicPos] = dic[(dicPos - rep0) + ((dicPos < rep0) ? dicBufSize : 0)];\r
+            dic[dicPos] = dic[dicPos - rep0 + (dicPos < rep0 ? dicBufSize : 0)];\r
             dicPos++;\r
             processedPos++;\r
             state = state < kNumLitStates ? 9 : 11;\r
@@ -265,15 +291,17 @@ static int MY_FAST_CALL LzmaDec_DecodeReal(CLzmaDec *p, SizeT limit, const Byte
         state = state < kNumLitStates ? 8 : 11;\r
         prob = probs + RepLenCoder;\r
       }\r
+      \r
+      #ifdef _LZMA_SIZE_OPT\r
       {\r
-        unsigned offset;\r
+        unsigned lim, offset;\r
         CLzmaProb *probLen = prob + LenChoice;\r
         IF_BIT_0(probLen)\r
         {\r
           UPDATE_0(probLen);\r
           probLen = prob + LenLow + (posState << kLenNumLowBits);\r
           offset = 0;\r
-          limit = (1 << kLenNumLowBits);\r
+          lim = (1 << kLenNumLowBits);\r
         }\r
         else\r
         {\r
@@ -284,19 +312,55 @@ static int MY_FAST_CALL LzmaDec_DecodeReal(CLzmaDec *p, SizeT limit, const Byte
             UPDATE_0(probLen);\r
             probLen = prob + LenMid + (posState << kLenNumMidBits);\r
             offset = kLenNumLowSymbols;\r
-            limit = (1 << kLenNumMidBits);\r
+            lim = (1 << kLenNumMidBits);\r
           }\r
           else\r
           {\r
             UPDATE_1(probLen);\r
             probLen = prob + LenHigh;\r
             offset = kLenNumLowSymbols + kLenNumMidSymbols;\r
-            limit = (1 << kLenNumHighBits);\r
+            lim = (1 << kLenNumHighBits);\r
           }\r
         }\r
-        TREE_DECODE(probLen, limit, len);\r
+        TREE_DECODE(probLen, lim, len);\r
         len += offset;\r
       }\r
+      #else\r
+      {\r
+        CLzmaProb *probLen = prob + LenChoice;\r
+        IF_BIT_0(probLen)\r
+        {\r
+          UPDATE_0(probLen);\r
+          probLen = prob + LenLow + (posState << kLenNumLowBits);\r
+          len = 1;\r
+          TREE_GET_BIT(probLen, len);\r
+          TREE_GET_BIT(probLen, len);\r
+          TREE_GET_BIT(probLen, len);\r
+          len -= 8;\r
+        }\r
+        else\r
+        {\r
+          UPDATE_1(probLen);\r
+          probLen = prob + LenChoice2;\r
+          IF_BIT_0(probLen)\r
+          {\r
+            UPDATE_0(probLen);\r
+            probLen = prob + LenMid + (posState << kLenNumMidBits);\r
+            len = 1;\r
+            TREE_GET_BIT(probLen, len);\r
+            TREE_GET_BIT(probLen, len);\r
+            TREE_GET_BIT(probLen, len);\r
+          }\r
+          else\r
+          {\r
+            UPDATE_1(probLen);\r
+            probLen = prob + LenHigh;\r
+            TREE_DECODE(probLen, (1 << kLenNumHighBits), len);\r
+            len += kLenNumLowSymbols + kLenNumMidSymbols;\r
+          }\r
+        }\r
+      }\r
+      #endif\r
 \r
       if (state >= kNumStates)\r
       {\r
@@ -307,7 +371,7 @@ static int MY_FAST_CALL LzmaDec_DecodeReal(CLzmaDec *p, SizeT limit, const Byte
         if (distance >= kStartPosModelIndex)\r
         {\r
           unsigned posSlot = (unsigned)distance;\r
-          int numDirectBits = (int)(((distance >> 1) - 1));\r
+          unsigned numDirectBits = (unsigned)(((distance >> 1) - 1));\r
           distance = (2 | (distance & 1));\r
           if (posSlot < kEndPosModelIndex)\r
           {\r
@@ -366,6 +430,7 @@ static int MY_FAST_CALL LzmaDec_DecodeReal(CLzmaDec *p, SizeT limit, const Byte
             }\r
           }\r
         }\r
+        \r
         rep3 = rep2;\r
         rep2 = rep1;\r
         rep1 = rep0;\r
@@ -373,27 +438,39 @@ static int MY_FAST_CALL LzmaDec_DecodeReal(CLzmaDec *p, SizeT limit, const Byte
         if (checkDicSize == 0)\r
         {\r
           if (distance >= processedPos)\r
+          {\r
+            p->dicPos = dicPos;\r
             return SZ_ERROR_DATA;\r
+          }\r
         }\r
         else if (distance >= checkDicSize)\r
+        {\r
+          p->dicPos = dicPos;\r
           return SZ_ERROR_DATA;\r
+        }\r
         state = (state < kNumStates + kNumLitStates) ? kNumLitStates : kNumLitStates + 3;\r
-        /* state = kLiteralNextStates[state]; */\r
       }\r
 \r
       len += kMatchMinLen;\r
 \r
-      if (limit == dicPos)\r
-        return SZ_ERROR_DATA;\r
       {\r
-        SizeT rem = limit - dicPos;\r
-        unsigned curLen = ((rem < len) ? (unsigned)rem : len);\r
-        SizeT pos = (dicPos - rep0) + ((dicPos < rep0) ? dicBufSize : 0);\r
+        SizeT rem;\r
+        unsigned curLen;\r
+        SizeT pos;\r
+        \r
+        if ((rem = limit - dicPos) == 0)\r
+        {\r
+          p->dicPos = dicPos;\r
+          return SZ_ERROR_DATA;\r
+        }\r
+        \r
+        curLen = ((rem < len) ? (unsigned)rem : len);\r
+        pos = dicPos - rep0 + (dicPos < rep0 ? dicBufSize : 0);\r
 \r
         processedPos += curLen;\r
 \r
         len -= curLen;\r
-        if (pos + curLen <= dicBufSize)\r
+        if (curLen <= dicBufSize - pos)\r
         {\r
           Byte *dest = dic + dicPos;\r
           ptrdiff_t src = (ptrdiff_t)pos - (ptrdiff_t)dicPos;\r
@@ -417,7 +494,9 @@ static int MY_FAST_CALL LzmaDec_DecodeReal(CLzmaDec *p, SizeT limit, const Byte
     }\r
   }\r
   while (dicPos < limit && buf < bufLimit);\r
+\r
   NORMALIZE;\r
+  \r
   p->buf = buf;\r
   p->range = range;\r
   p->code = code;\r
@@ -441,18 +520,20 @@ static void MY_FAST_CALL LzmaDec_WriteRem(CLzmaDec *p, SizeT limit)
     SizeT dicPos = p->dicPos;\r
     SizeT dicBufSize = p->dicBufSize;\r
     unsigned len = p->remainLen;\r
-    UInt32 rep0 = p->reps[0];\r
-    if (limit - dicPos < len)\r
-      len = (unsigned)(limit - dicPos);\r
+    SizeT rep0 = p->reps[0]; /* we use SizeT to avoid the BUG of VC14 for AMD64 */\r
+    SizeT rem = limit - dicPos;\r
+    if (rem < len)\r
+      len = (unsigned)(rem);\r
 \r
     if (p->checkDicSize == 0 && p->prop.dicSize - p->processedPos <= len)\r
       p->checkDicSize = p->prop.dicSize;\r
 \r
     p->processedPos += len;\r
     p->remainLen -= len;\r
-    while (len-- != 0)\r
+    while (len != 0)\r
     {\r
-      dic[dicPos] = dic[(dicPos - rep0) + ((dicPos < rep0) ? dicBufSize : 0)];\r
+      len--;\r
+      dic[dicPos] = dic[dicPos - rep0 + (dicPos < rep0 ? dicBufSize : 0)];\r
       dicPos++;\r
     }\r
     p->dicPos = dicPos;\r
@@ -470,17 +551,19 @@ static int MY_FAST_CALL LzmaDec_DecodeReal2(CLzmaDec *p, SizeT limit, const Byte
       if (limit - p->dicPos > rem)\r
         limit2 = p->dicPos + rem;\r
     }\r
+    \r
     RINOK(LzmaDec_DecodeReal(p, limit2, bufLimit));\r
-    if (p->processedPos >= p->prop.dicSize)\r
+    \r
+    if (p->checkDicSize == 0 && p->processedPos >= p->prop.dicSize)\r
       p->checkDicSize = p->prop.dicSize;\r
+    \r
     LzmaDec_WriteRem(p, limit);\r
   }\r
   while (p->dicPos < limit && p->buf < bufLimit && p->remainLen < kMatchSpecLenStart);\r
 \r
   if (p->remainLen > kMatchSpecLenStart)\r
-  {\r
     p->remainLen = kMatchSpecLenStart;\r
-  }\r
+\r
   return 0;\r
 }\r
 \r
@@ -497,12 +580,12 @@ static ELzmaDummy LzmaDec_TryDummy(const CLzmaDec *p, const Byte *buf, SizeT inS
   UInt32 range = p->range;\r
   UInt32 code = p->code;\r
   const Byte *bufLimit = buf + inSize;\r
-  CLzmaProb *probs = p->probs;\r
+  const CLzmaProb *probs = p->probs;\r
   unsigned state = p->state;\r
   ELzmaDummy res;\r
 \r
   {\r
-    CLzmaProb *prob;\r
+    const CLzmaProb *prob;\r
     UInt32 bound;\r
     unsigned ttt;\r
     unsigned posState = (p->processedPos) & ((1 << p->prop.pb) - 1);\r
@@ -516,9 +599,9 @@ static ELzmaDummy LzmaDec_TryDummy(const CLzmaDec *p, const Byte *buf, SizeT inS
 \r
       prob = probs + Literal;\r
       if (p->checkDicSize != 0 || p->processedPos != 0)\r
-        prob += (LZMA_LIT_SIZE *\r
-          ((((p->processedPos) & ((1 << (p->prop.lp)) - 1)) << p->prop.lc) +\r
-          (p->dic[(p->dicPos == 0 ? p->dicBufSize : p->dicPos) - 1] >> (8 - p->prop.lc))));\r
+        prob += ((UInt32)LZMA_LIT_SIZE *\r
+            ((((p->processedPos) & ((1 << (p->prop.lp)) - 1)) << p->prop.lc) +\r
+            (p->dic[(p->dicPos == 0 ? p->dicBufSize : p->dicPos) - 1] >> (8 - p->prop.lc))));\r
 \r
       if (state < kNumLitStates)\r
       {\r
@@ -528,13 +611,13 @@ static ELzmaDummy LzmaDec_TryDummy(const CLzmaDec *p, const Byte *buf, SizeT inS
       else\r
       {\r
         unsigned matchByte = p->dic[p->dicPos - p->reps[0] +\r
-            ((p->dicPos < p->reps[0]) ? p->dicBufSize : 0)];\r
+            (p->dicPos < p->reps[0] ? p->dicBufSize : 0)];\r
         unsigned offs = 0x100;\r
         unsigned symbol = 1;\r
         do\r
         {\r
           unsigned bit;\r
-          CLzmaProb *probLit;\r
+          const CLzmaProb *probLit;\r
           matchByte <<= 1;\r
           bit = (matchByte & offs);\r
           probLit = prob + offs + bit + symbol;\r
@@ -604,7 +687,7 @@ static ELzmaDummy LzmaDec_TryDummy(const CLzmaDec *p, const Byte *buf, SizeT inS
       }\r
       {\r
         unsigned limit, offset;\r
-        CLzmaProb *probLen = prob + LenChoice;\r
+        const CLzmaProb *probLen = prob + LenChoice;\r
         IF_BIT_0_CHECK(probLen)\r
         {\r
           UPDATE_0_CHECK;\r
@@ -644,7 +727,7 @@ static ELzmaDummy LzmaDec_TryDummy(const CLzmaDec *p, const Byte *buf, SizeT inS
         TREE_DECODE_CHECK(prob, 1 << kNumPosSlotBits, posSlot);\r
         if (posSlot >= kStartPosModelIndex)\r
         {\r
-          int numDirectBits = ((posSlot >> 1) - 1);\r
+          unsigned numDirectBits = ((posSlot >> 1) - 1);\r
 \r
           /* if (bufLimit - buf >= 8) return DUMMY_MATCH; */\r
 \r
@@ -683,13 +766,6 @@ static ELzmaDummy LzmaDec_TryDummy(const CLzmaDec *p, const Byte *buf, SizeT inS
 }\r
 \r
 \r
-static void LzmaDec_InitRc(CLzmaDec *p, const Byte *data)\r
-{\r
-  p->code = ((UInt32)data[1] << 24) | ((UInt32)data[2] << 16) | ((UInt32)data[3] << 8) | ((UInt32)data[4]);\r
-  p->range = 0xFFFFFFFF;\r
-  p->needFlush = 0;\r
-}\r
-\r
 void LzmaDec_InitDicAndState(CLzmaDec *p, Bool initDic, Bool initState)\r
 {\r
   p->needFlush = 1;\r
@@ -714,8 +790,8 @@ void LzmaDec_Init(CLzmaDec *p)
 \r
 static void LzmaDec_InitStateReal(CLzmaDec *p)\r
 {\r
-  UInt32 numProbs = Literal + ((UInt32)LZMA_LIT_SIZE << (p->prop.lc + p->prop.lp));\r
-  UInt32 i;\r
+  SizeT numProbs = LzmaProps_GetNumProbs(&p->prop);\r
+  SizeT i;\r
   CLzmaProb *probs = p->probs;\r
   for (i = 0; i < numProbs; i++)\r
     probs[i] = kBitModelTotal >> 1;\r
@@ -737,7 +813,7 @@ SRes LzmaDec_DecodeToDic(CLzmaDec *p, SizeT dicLimit, const Byte *src, SizeT *sr
   {\r
       int checkEndMarkNow;\r
 \r
-      if (p->needFlush != 0)\r
+      if (p->needFlush)\r
       {\r
         for (; inSize > 0 && p->tempBufSize < RC_INIT_SIZE; (*srcLen)++, inSize--)\r
           p->tempBuf[p->tempBufSize++] = *src++;\r
@@ -748,8 +824,13 @@ SRes LzmaDec_DecodeToDic(CLzmaDec *p, SizeT dicLimit, const Byte *src, SizeT *sr
         }\r
         if (p->tempBuf[0] != 0)\r
           return SZ_ERROR_DATA;\r
-\r
-        LzmaDec_InitRc(p, p->tempBuf);\r
+        p->code =\r
+              ((UInt32)p->tempBuf[1] << 24)\r
+            | ((UInt32)p->tempBuf[2] << 16)\r
+            | ((UInt32)p->tempBuf[3] << 8)\r
+            | ((UInt32)p->tempBuf[4]);\r
+        p->range = 0xFFFFFFFF;\r
+        p->needFlush = 0;\r
         p->tempBufSize = 0;\r
       }\r
 \r
@@ -833,7 +914,16 @@ SRes LzmaDec_DecodeToDic(CLzmaDec *p, SizeT dicLimit, const Byte *src, SizeT *sr
         p->buf = p->tempBuf;\r
         if (LzmaDec_DecodeReal2(p, dicLimit, p->buf) != 0)\r
           return SZ_ERROR_DATA;\r
-        lookAhead -= (rem - (unsigned)(p->buf - p->tempBuf));\r
+        \r
+        {\r
+          unsigned kkk = (unsigned)(p->buf - p->tempBuf);\r
+          if (rem < kkk)\r
+            return SZ_ERROR_FAIL; /* some internal error */\r
+          rem -= kkk;\r
+          if (lookAhead < rem)\r
+            return SZ_ERROR_FAIL; /* some internal error */\r
+          lookAhead -= rem;\r
+        }\r
         (*srcLen) += lookAhead;\r
         src += lookAhead;\r
         inSize -= lookAhead;\r
@@ -888,13 +978,13 @@ SRes LzmaDec_DecodeToBuf(CLzmaDec *p, Byte *dest, SizeT *destLen, const Byte *sr
 void LzmaDec_FreeProbs(CLzmaDec *p, ISzAlloc *alloc)\r
 {\r
   alloc->Free(alloc, p->probs);\r
-  p->probs = 0;\r
+  p->probs = NULL;\r
 }\r
 \r
 static void LzmaDec_FreeDict(CLzmaDec *p, ISzAlloc *alloc)\r
 {\r
   alloc->Free(alloc, p->dic);\r
-  p->dic = 0;\r
+  p->dic = NULL;\r
 }\r
 \r
 void LzmaDec_Free(CLzmaDec *p, ISzAlloc *alloc)\r
@@ -932,12 +1022,12 @@ SRes LzmaProps_Decode(CLzmaProps *p, const Byte *data, unsigned size)
 static SRes LzmaDec_AllocateProbs2(CLzmaDec *p, const CLzmaProps *propNew, ISzAlloc *alloc)\r
 {\r
   UInt32 numProbs = LzmaProps_GetNumProbs(propNew);\r
-  if (p->probs == 0 || numProbs != p->numProbs)\r
+  if (!p->probs || numProbs != p->numProbs)\r
   {\r
     LzmaDec_FreeProbs(p, alloc);\r
     p->probs = (CLzmaProb *)alloc->Alloc(alloc, numProbs * sizeof(CLzmaProb));\r
     p->numProbs = numProbs;\r
-    if (p->probs == 0)\r
+    if (!p->probs)\r
       return SZ_ERROR_MEM;\r
   }\r
   return SZ_OK;\r
@@ -958,12 +1048,22 @@ SRes LzmaDec_Allocate(CLzmaDec *p, const Byte *props, unsigned propsSize, ISzAll
   SizeT dicBufSize;\r
   RINOK(LzmaProps_Decode(&propNew, props, propsSize));\r
   RINOK(LzmaDec_AllocateProbs2(p, &propNew, alloc));\r
-  dicBufSize = propNew.dicSize;\r
-  if (p->dic == 0 || dicBufSize != p->dicBufSize)\r
+\r
+  {\r
+    UInt32 dictSize = propNew.dicSize;\r
+    SizeT mask = ((UInt32)1 << 12) - 1;\r
+         if (dictSize >= ((UInt32)1 << 30)) mask = ((UInt32)1 << 22) - 1;\r
+    else if (dictSize >= ((UInt32)1 << 22)) mask = ((UInt32)1 << 20) - 1;;\r
+    dicBufSize = ((SizeT)dictSize + mask) & ~mask;\r
+    if (dicBufSize < dictSize)\r
+      dicBufSize = dictSize;\r
+  }\r
+\r
+  if (!p->dic || dicBufSize != p->dicBufSize)\r
   {\r
     LzmaDec_FreeDict(p, alloc);\r
     p->dic = (Byte *)alloc->Alloc(alloc, dicBufSize);\r
-    if (p->dic == 0)\r
+    if (!p->dic)\r
     {\r
       LzmaDec_FreeProbs(p, alloc);\r
       return SZ_ERROR_MEM;\r
@@ -980,28 +1080,21 @@ SRes LzmaDecode(Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen,
 {\r
   CLzmaDec p;\r
   SRes res;\r
-  SizeT inSize = *srcLen;\r
-  SizeT outSize = *destLen;\r
-  *srcLen = *destLen = 0;\r
+  SizeT outSize = *destLen, inSize = *srcLen;\r
+  *destLen = *srcLen = 0;\r
+  *status = LZMA_STATUS_NOT_SPECIFIED;\r
   if (inSize < RC_INIT_SIZE)\r
     return SZ_ERROR_INPUT_EOF;\r
-\r
   LzmaDec_Construct(&p);\r
-  res = LzmaDec_AllocateProbs(&p, propData, propSize, alloc);\r
-  if (res != 0)\r
-    return res;\r
+  RINOK(LzmaDec_AllocateProbs(&p, propData, propSize, alloc));\r
   p.dic = dest;\r
   p.dicBufSize = outSize;\r
-\r
   LzmaDec_Init(&p);\r
-  \r
   *srcLen = inSize;\r
   res = LzmaDec_DecodeToDic(&p, outSize, src, srcLen, finishMode, status);\r
-\r
+  *destLen = p.dicPos;\r
   if (res == SZ_OK && *status == LZMA_STATUS_NEEDS_MORE_INPUT)\r
     res = SZ_ERROR_INPUT_EOF;\r
-\r
-  (*destLen) = p.dicPos;\r
   LzmaDec_FreeProbs(&p, alloc);\r
   return res;\r
 }\r