CMS 3D CMS Logo

/data/refman/pasoursint/CMSSW_6_1_2_SLHC2/src/GeneratorInterface/ReggeGribovPartonMCInterface/src/LzmaDec.cc

Go to the documentation of this file.
00001 /* LzmaDec.c -- LZMA Decoder
00002 2009-09-20 : Igor Pavlov : Public domain */
00003 
00004 #include "LzmaDec.h"
00005 
00006 #include <string.h>
00007 
00008 #define kNumTopBits 24
00009 #define kTopValue ((UInt32)1 << kNumTopBits)
00010 
00011 #define kNumBitModelTotalBits 11
00012 #define kBitModelTotal (1 << kNumBitModelTotalBits)
00013 #define kNumMoveBits 5
00014 
00015 #define RC_INIT_SIZE 5
00016 
00017 #define NORMALIZE if (range < kTopValue) { range <<= 8; code = (code << 8) | (*buf++); }
00018 
00019 #define IF_BIT_0(p) ttt = *(p); NORMALIZE; bound = (range >> kNumBitModelTotalBits) * ttt; if (code < bound)
00020 #define UPDATE_0(p) range = bound; *(p) = (CLzmaProb)(ttt + ((kBitModelTotal - ttt) >> kNumMoveBits));
00021 #define UPDATE_1(p) range -= bound; code -= bound; *(p) = (CLzmaProb)(ttt - (ttt >> kNumMoveBits));
00022 #define GET_BIT2(p, i, A0, A1) IF_BIT_0(p) \
00023   { UPDATE_0(p); i = (i + i); A0; } else \
00024   { UPDATE_1(p); i = (i + i) + 1; A1; }
00025 #define GET_BIT(p, i) GET_BIT2(p, i, ; , ;)
00026 
00027 #define TREE_GET_BIT(probs, i) { GET_BIT((probs + i), i); }
00028 #define TREE_DECODE(probs, limit, i) \
00029   { i = 1; do { TREE_GET_BIT(probs, i); } while (i < limit); i -= limit; }
00030 
00031 /* #define _LZMA_SIZE_OPT */
00032 
00033 #ifdef _LZMA_SIZE_OPT
00034 #define TREE_6_DECODE(probs, i) TREE_DECODE(probs, (1 << 6), i)
00035 #else
00036 #define TREE_6_DECODE(probs, i) \
00037   { i = 1; \
00038   TREE_GET_BIT(probs, i); \
00039   TREE_GET_BIT(probs, i); \
00040   TREE_GET_BIT(probs, i); \
00041   TREE_GET_BIT(probs, i); \
00042   TREE_GET_BIT(probs, i); \
00043   TREE_GET_BIT(probs, i); \
00044   i -= 0x40; }
00045 #endif
00046 
00047 #define NORMALIZE_CHECK if (range < kTopValue) { if (buf >= bufLimit) return DUMMY_ERROR; range <<= 8; code = (code << 8) | (*buf++); }
00048 
00049 #define IF_BIT_0_CHECK(p) ttt = *(p); NORMALIZE_CHECK; bound = (range >> kNumBitModelTotalBits) * ttt; if (code < bound)
00050 #define UPDATE_0_CHECK range = bound;
00051 #define UPDATE_1_CHECK range -= bound; code -= bound;
00052 #define GET_BIT2_CHECK(p, i, A0, A1) IF_BIT_0_CHECK(p) \
00053   { UPDATE_0_CHECK; i = (i + i); A0; } else \
00054   { UPDATE_1_CHECK; i = (i + i) + 1; A1; }
00055 #define GET_BIT_CHECK(p, i) GET_BIT2_CHECK(p, i, ; , ;)
00056 #define TREE_DECODE_CHECK(probs, limit, i) \
00057   { i = 1; do { GET_BIT_CHECK(probs + i, i) } while (i < limit); i -= limit; }
00058 
00059 
00060 #define kNumPosBitsMax 4
00061 #define kNumPosStatesMax (1 << kNumPosBitsMax)
00062 
00063 #define kLenNumLowBits 3
00064 #define kLenNumLowSymbols (1 << kLenNumLowBits)
00065 #define kLenNumMidBits 3
00066 #define kLenNumMidSymbols (1 << kLenNumMidBits)
00067 #define kLenNumHighBits 8
00068 #define kLenNumHighSymbols (1 << kLenNumHighBits)
00069 
00070 #define LenChoice 0
00071 #define LenChoice2 (LenChoice + 1)
00072 #define LenLow (LenChoice2 + 1)
00073 #define LenMid (LenLow + (kNumPosStatesMax << kLenNumLowBits))
00074 #define LenHigh (LenMid + (kNumPosStatesMax << kLenNumMidBits))
00075 #define kNumLenProbs (LenHigh + kLenNumHighSymbols)
00076 
00077 
00078 #define kNumStates 12
00079 #define kNumLitStates 7
00080 
00081 #define kStartPosModelIndex 4
00082 #define kEndPosModelIndex 14
00083 #define kNumFullDistances (1 << (kEndPosModelIndex >> 1))
00084 
00085 #define kNumPosSlotBits 6
00086 #define kNumLenToPosStates 4
00087 
00088 #define kNumAlignBits 4
00089 #define kAlignTableSize (1 << kNumAlignBits)
00090 
00091 #define kMatchMinLen 2
00092 #define kMatchSpecLenStart (kMatchMinLen + kLenNumLowSymbols + kLenNumMidSymbols + kLenNumHighSymbols)
00093 
00094 #define IsMatch 0
00095 #define IsRep (IsMatch + (kNumStates << kNumPosBitsMax))
00096 #define IsRepG0 (IsRep + kNumStates)
00097 #define IsRepG1 (IsRepG0 + kNumStates)
00098 #define IsRepG2 (IsRepG1 + kNumStates)
00099 #define IsRep0Long (IsRepG2 + kNumStates)
00100 #define PosSlot (IsRep0Long + (kNumStates << kNumPosBitsMax))
00101 #define SpecPos (PosSlot + (kNumLenToPosStates << kNumPosSlotBits))
00102 #define Align (SpecPos + kNumFullDistances - kEndPosModelIndex)
00103 #define LenCoder (Align + kAlignTableSize)
00104 #define RepLenCoder (LenCoder + kNumLenProbs)
00105 #define Literal (RepLenCoder + kNumLenProbs)
00106 
00107 #define LZMA_BASE_SIZE 1846
00108 #define LZMA_LIT_SIZE 768
00109 
00110 #define LzmaProps_GetNumProbs(p) ((UInt32)LZMA_BASE_SIZE + (LZMA_LIT_SIZE << ((p)->lc + (p)->lp)))
00111 
00112 #if Literal != LZMA_BASE_SIZE
00113 StopCompilingDueBUG
00114 #endif
00115 
00116 #define LZMA_DIC_MIN (1 << 12)
00117 
00118 /* First LZMA-symbol is always decoded.
00119 And it decodes new LZMA-symbols while (buf < bufLimit), but "buf" is without last normalization
00120 Out:
00121   Result:
00122     SZ_OK - OK
00123     SZ_ERROR_DATA - Error
00124   p->remainLen:
00125     < kMatchSpecLenStart : normal remain
00126     = kMatchSpecLenStart : finished
00127     = kMatchSpecLenStart + 1 : Flush marker
00128     = kMatchSpecLenStart + 2 : State Init Marker
00129 */
00130 
00131 static int MY_FAST_CALL LzmaDec_DecodeReal(CLzmaDec *p, SizeT limit, const Byte *bufLimit)
00132 {
00133   CLzmaProb *probs = p->probs;
00134 
00135   unsigned state = p->state;
00136   UInt32 rep0 = p->reps[0], rep1 = p->reps[1], rep2 = p->reps[2], rep3 = p->reps[3];
00137   unsigned pbMask = ((unsigned)1 << (p->prop.pb)) - 1;
00138   unsigned lpMask = ((unsigned)1 << (p->prop.lp)) - 1;
00139   unsigned lc = p->prop.lc;
00140 
00141   Byte *dic = p->dic;
00142   SizeT dicBufSize = p->dicBufSize;
00143   SizeT dicPos = p->dicPos;
00144   
00145   UInt32 processedPos = p->processedPos;
00146   UInt32 checkDicSize = p->checkDicSize;
00147   unsigned len = 0;
00148 
00149   const Byte *buf = p->buf;
00150   UInt32 range = p->range;
00151   UInt32 code = p->code;
00152 
00153   do
00154   {
00155     CLzmaProb *prob;
00156     UInt32 bound;
00157     unsigned ttt;
00158     unsigned posState = processedPos & pbMask;
00159 
00160     prob = probs + IsMatch + (state << kNumPosBitsMax) + posState;
00161     IF_BIT_0(prob)
00162     {
00163       unsigned symbol;
00164       UPDATE_0(prob);
00165       prob = probs + Literal;
00166       if (checkDicSize != 0 || processedPos != 0)
00167         prob += (LZMA_LIT_SIZE * (((processedPos & lpMask) << lc) +
00168         (dic[(dicPos == 0 ? dicBufSize : dicPos) - 1] >> (8 - lc))));
00169 
00170       if (state < kNumLitStates)
00171       {
00172         state -= (state < 4) ? state : 3;
00173         symbol = 1;
00174         do { GET_BIT(prob + symbol, symbol) } while (symbol < 0x100);
00175       }
00176       else
00177       {
00178         unsigned matchByte = p->dic[(dicPos - rep0) + ((dicPos < rep0) ? dicBufSize : 0)];
00179         unsigned offs = 0x100;
00180         state -= (state < 10) ? 3 : 6;
00181         symbol = 1;
00182         do
00183         {
00184           unsigned bit;
00185           CLzmaProb *probLit;
00186           matchByte <<= 1;
00187           bit = (matchByte & offs);
00188           probLit = prob + offs + bit + symbol;
00189           GET_BIT2(probLit, symbol, offs &= ~bit, offs &= bit)
00190         }
00191         while (symbol < 0x100);
00192       }
00193       dic[dicPos++] = (Byte)symbol;
00194       processedPos++;
00195       continue;
00196     }
00197     else
00198     {
00199       UPDATE_1(prob);
00200       prob = probs + IsRep + state;
00201       IF_BIT_0(prob)
00202       {
00203         UPDATE_0(prob);
00204         state += kNumStates;
00205         prob = probs + LenCoder;
00206       }
00207       else
00208       {
00209         UPDATE_1(prob);
00210         if (checkDicSize == 0 && processedPos == 0)
00211           return SZ_ERROR_DATA;
00212         prob = probs + IsRepG0 + state;
00213         IF_BIT_0(prob)
00214         {
00215           UPDATE_0(prob);
00216           prob = probs + IsRep0Long + (state << kNumPosBitsMax) + posState;
00217           IF_BIT_0(prob)
00218           {
00219             UPDATE_0(prob);
00220             dic[dicPos] = dic[(dicPos - rep0) + ((dicPos < rep0) ? dicBufSize : 0)];
00221             dicPos++;
00222             processedPos++;
00223             state = state < kNumLitStates ? 9 : 11;
00224             continue;
00225           }
00226           UPDATE_1(prob);
00227         }
00228         else
00229         {
00230           UInt32 distance;
00231           UPDATE_1(prob);
00232           prob = probs + IsRepG1 + state;
00233           IF_BIT_0(prob)
00234           {
00235             UPDATE_0(prob);
00236             distance = rep1;
00237           }
00238           else
00239           {
00240             UPDATE_1(prob);
00241             prob = probs + IsRepG2 + state;
00242             IF_BIT_0(prob)
00243             {
00244               UPDATE_0(prob);
00245               distance = rep2;
00246             }
00247             else
00248             {
00249               UPDATE_1(prob);
00250               distance = rep3;
00251               rep3 = rep2;
00252             }
00253             rep2 = rep1;
00254           }
00255           rep1 = rep0;
00256           rep0 = distance;
00257         }
00258         state = state < kNumLitStates ? 8 : 11;
00259         prob = probs + RepLenCoder;
00260       }
00261       {
00262         unsigned limit, offset;
00263         CLzmaProb *probLen = prob + LenChoice;
00264         IF_BIT_0(probLen)
00265         {
00266           UPDATE_0(probLen);
00267           probLen = prob + LenLow + (posState << kLenNumLowBits);
00268           offset = 0;
00269           limit = (1 << kLenNumLowBits);
00270         }
00271         else
00272         {
00273           UPDATE_1(probLen);
00274           probLen = prob + LenChoice2;
00275           IF_BIT_0(probLen)
00276           {
00277             UPDATE_0(probLen);
00278             probLen = prob + LenMid + (posState << kLenNumMidBits);
00279             offset = kLenNumLowSymbols;
00280             limit = (1 << kLenNumMidBits);
00281           }
00282           else
00283           {
00284             UPDATE_1(probLen);
00285             probLen = prob + LenHigh;
00286             offset = kLenNumLowSymbols + kLenNumMidSymbols;
00287             limit = (1 << kLenNumHighBits);
00288           }
00289         }
00290         TREE_DECODE(probLen, limit, len);
00291         len += offset;
00292       }
00293 
00294       if (state >= kNumStates)
00295       {
00296         UInt32 distance;
00297         prob = probs + PosSlot +
00298             ((len < kNumLenToPosStates ? len : kNumLenToPosStates - 1) << kNumPosSlotBits);
00299         TREE_6_DECODE(prob, distance);
00300         if (distance >= kStartPosModelIndex)
00301         {
00302           unsigned posSlot = (unsigned)distance;
00303           int numDirectBits = (int)(((distance >> 1) - 1));
00304           distance = (2 | (distance & 1));
00305           if (posSlot < kEndPosModelIndex)
00306           {
00307             distance <<= numDirectBits;
00308             prob = probs + SpecPos + distance - posSlot - 1;
00309             {
00310               UInt32 mask = 1;
00311               unsigned i = 1;
00312               do
00313               {
00314                 GET_BIT2(prob + i, i, ; , distance |= mask);
00315                 mask <<= 1;
00316               }
00317               while (--numDirectBits != 0);
00318             }
00319           }
00320           else
00321           {
00322             numDirectBits -= kNumAlignBits;
00323             do
00324             {
00325               NORMALIZE
00326               range >>= 1;
00327               
00328               {
00329                 UInt32 t;
00330                 code -= range;
00331                 t = (0 - ((UInt32)code >> 31)); /* (UInt32)((Int32)code >> 31) */
00332                 distance = (distance << 1) + (t + 1);
00333                 code += range & t;
00334               }
00335               /*
00336               distance <<= 1;
00337               if (code >= range)
00338               {
00339                 code -= range;
00340                 distance |= 1;
00341               }
00342               */
00343             }
00344             while (--numDirectBits != 0);
00345             prob = probs + Align;
00346             distance <<= kNumAlignBits;
00347             {
00348               unsigned i = 1;
00349               GET_BIT2(prob + i, i, ; , distance |= 1);
00350               GET_BIT2(prob + i, i, ; , distance |= 2);
00351               GET_BIT2(prob + i, i, ; , distance |= 4);
00352               GET_BIT2(prob + i, i, ; , distance |= 8);
00353             }
00354             if (distance == (UInt32)0xFFFFFFFF)
00355             {
00356               len += kMatchSpecLenStart;
00357               state -= kNumStates;
00358               break;
00359             }
00360           }
00361         }
00362         rep3 = rep2;
00363         rep2 = rep1;
00364         rep1 = rep0;
00365         rep0 = distance + 1;
00366         if (checkDicSize == 0)
00367         {
00368           if (distance >= processedPos)
00369             return SZ_ERROR_DATA;
00370         }
00371         else if (distance >= checkDicSize)
00372           return SZ_ERROR_DATA;
00373         state = (state < kNumStates + kNumLitStates) ? kNumLitStates : kNumLitStates + 3;
00374       }
00375 
00376       len += kMatchMinLen;
00377 
00378       if (limit == dicPos)
00379         return SZ_ERROR_DATA;
00380       {
00381         SizeT rem = limit - dicPos;
00382         unsigned curLen = ((rem < len) ? (unsigned)rem : len);
00383         SizeT pos = (dicPos - rep0) + ((dicPos < rep0) ? dicBufSize : 0);
00384 
00385         processedPos += curLen;
00386 
00387         len -= curLen;
00388         if (pos + curLen <= dicBufSize)
00389         {
00390           Byte *dest = dic + dicPos;
00391           ptrdiff_t src = (ptrdiff_t)pos - (ptrdiff_t)dicPos;
00392           const Byte *lim = dest + curLen;
00393           dicPos += curLen;
00394           do
00395             *(dest) = (Byte)*(dest + src);
00396           while (++dest != lim);
00397         }
00398         else
00399         {
00400           do
00401           {
00402             dic[dicPos++] = dic[pos];
00403             if (++pos == dicBufSize)
00404               pos = 0;
00405           }
00406           while (--curLen != 0);
00407         }
00408       }
00409     }
00410   }
00411   while (dicPos < limit && buf < bufLimit);
00412   NORMALIZE;
00413   p->buf = buf;
00414   p->range = range;
00415   p->code = code;
00416   p->remainLen = len;
00417   p->dicPos = dicPos;
00418   p->processedPos = processedPos;
00419   p->reps[0] = rep0;
00420   p->reps[1] = rep1;
00421   p->reps[2] = rep2;
00422   p->reps[3] = rep3;
00423   p->state = state;
00424 
00425   return SZ_OK;
00426 }
00427 
00428 static void MY_FAST_CALL LzmaDec_WriteRem(CLzmaDec *p, SizeT limit)
00429 {
00430   if (p->remainLen != 0 && p->remainLen < kMatchSpecLenStart)
00431   {
00432     Byte *dic = p->dic;
00433     SizeT dicPos = p->dicPos;
00434     SizeT dicBufSize = p->dicBufSize;
00435     unsigned len = p->remainLen;
00436     UInt32 rep0 = p->reps[0];
00437     if (limit - dicPos < len)
00438       len = (unsigned)(limit - dicPos);
00439 
00440     if (p->checkDicSize == 0 && p->prop.dicSize - p->processedPos <= len)
00441       p->checkDicSize = p->prop.dicSize;
00442 
00443     p->processedPos += len;
00444     p->remainLen -= len;
00445     while (len-- != 0)
00446     {
00447       dic[dicPos] = dic[(dicPos - rep0) + ((dicPos < rep0) ? dicBufSize : 0)];
00448       dicPos++;
00449     }
00450     p->dicPos = dicPos;
00451   }
00452 }
00453 
00454 static int MY_FAST_CALL LzmaDec_DecodeReal2(CLzmaDec *p, SizeT limit, const Byte *bufLimit)
00455 {
00456   do
00457   {
00458     SizeT limit2 = limit;
00459     if (p->checkDicSize == 0)
00460     {
00461       UInt32 rem = p->prop.dicSize - p->processedPos;
00462       if (limit - p->dicPos > rem)
00463         limit2 = p->dicPos + rem;
00464     }
00465     RINOK(LzmaDec_DecodeReal(p, limit2, bufLimit));
00466     if (p->processedPos >= p->prop.dicSize)
00467       p->checkDicSize = p->prop.dicSize;
00468     LzmaDec_WriteRem(p, limit);
00469   }
00470   while (p->dicPos < limit && p->buf < bufLimit && p->remainLen < kMatchSpecLenStart);
00471 
00472   if (p->remainLen > kMatchSpecLenStart)
00473   {
00474     p->remainLen = kMatchSpecLenStart;
00475   }
00476   return 0;
00477 }
00478 
00479 typedef enum
00480 {
00481   DUMMY_ERROR, /* unexpected end of input stream */
00482   DUMMY_LIT,
00483   DUMMY_MATCH,
00484   DUMMY_REP
00485 } ELzmaDummy;
00486 
00487 static ELzmaDummy LzmaDec_TryDummy(const CLzmaDec *p, const Byte *buf, SizeT inSize)
00488 {
00489   UInt32 range = p->range;
00490   UInt32 code = p->code;
00491   const Byte *bufLimit = buf + inSize;
00492   CLzmaProb *probs = p->probs;
00493   unsigned state = p->state;
00494   ELzmaDummy res;
00495 
00496   {
00497     CLzmaProb *prob;
00498     UInt32 bound;
00499     unsigned ttt;
00500     unsigned posState = (p->processedPos) & ((1 << p->prop.pb) - 1);
00501 
00502     prob = probs + IsMatch + (state << kNumPosBitsMax) + posState;
00503     IF_BIT_0_CHECK(prob)
00504     {
00505       UPDATE_0_CHECK
00506 
00507       /* if (bufLimit - buf >= 7) return DUMMY_LIT; */
00508 
00509       prob = probs + Literal;
00510       if (p->checkDicSize != 0 || p->processedPos != 0)
00511         prob += (LZMA_LIT_SIZE *
00512           ((((p->processedPos) & ((1 << (p->prop.lp)) - 1)) << p->prop.lc) +
00513           (p->dic[(p->dicPos == 0 ? p->dicBufSize : p->dicPos) - 1] >> (8 - p->prop.lc))));
00514 
00515       if (state < kNumLitStates)
00516       {
00517         unsigned symbol = 1;
00518         do { GET_BIT_CHECK(prob + symbol, symbol) } while (symbol < 0x100);
00519       }
00520       else
00521       {
00522         unsigned matchByte = p->dic[p->dicPos - p->reps[0] +
00523             ((p->dicPos < p->reps[0]) ? p->dicBufSize : 0)];
00524         unsigned offs = 0x100;
00525         unsigned symbol = 1;
00526         do
00527         {
00528           unsigned bit;
00529           CLzmaProb *probLit;
00530           matchByte <<= 1;
00531           bit = (matchByte & offs);
00532           probLit = prob + offs + bit + symbol;
00533           GET_BIT2_CHECK(probLit, symbol, offs &= ~bit, offs &= bit)
00534         }
00535         while (symbol < 0x100);
00536       }
00537       res = DUMMY_LIT;
00538     }
00539     else
00540     {
00541       unsigned len;
00542       UPDATE_1_CHECK;
00543 
00544       prob = probs + IsRep + state;
00545       IF_BIT_0_CHECK(prob)
00546       {
00547         UPDATE_0_CHECK;
00548         state = 0;
00549         prob = probs + LenCoder;
00550         res = DUMMY_MATCH;
00551       }
00552       else
00553       {
00554         UPDATE_1_CHECK;
00555         res = DUMMY_REP;
00556         prob = probs + IsRepG0 + state;
00557         IF_BIT_0_CHECK(prob)
00558         {
00559           UPDATE_0_CHECK;
00560           prob = probs + IsRep0Long + (state << kNumPosBitsMax) + posState;
00561           IF_BIT_0_CHECK(prob)
00562           {
00563             UPDATE_0_CHECK;
00564             NORMALIZE_CHECK;
00565             return DUMMY_REP;
00566           }
00567           else
00568           {
00569             UPDATE_1_CHECK;
00570           }
00571         }
00572         else
00573         {
00574           UPDATE_1_CHECK;
00575           prob = probs + IsRepG1 + state;
00576           IF_BIT_0_CHECK(prob)
00577           {
00578             UPDATE_0_CHECK;
00579           }
00580           else
00581           {
00582             UPDATE_1_CHECK;
00583             prob = probs + IsRepG2 + state;
00584             IF_BIT_0_CHECK(prob)
00585             {
00586               UPDATE_0_CHECK;
00587             }
00588             else
00589             {
00590               UPDATE_1_CHECK;
00591             }
00592           }
00593         }
00594         state = kNumStates;
00595         prob = probs + RepLenCoder;
00596       }
00597       {
00598         unsigned limit, offset;
00599         CLzmaProb *probLen = prob + LenChoice;
00600         IF_BIT_0_CHECK(probLen)
00601         {
00602           UPDATE_0_CHECK;
00603           probLen = prob + LenLow + (posState << kLenNumLowBits);
00604           offset = 0;
00605           limit = 1 << kLenNumLowBits;
00606         }
00607         else
00608         {
00609           UPDATE_1_CHECK;
00610           probLen = prob + LenChoice2;
00611           IF_BIT_0_CHECK(probLen)
00612           {
00613             UPDATE_0_CHECK;
00614             probLen = prob + LenMid + (posState << kLenNumMidBits);
00615             offset = kLenNumLowSymbols;
00616             limit = 1 << kLenNumMidBits;
00617           }
00618           else
00619           {
00620             UPDATE_1_CHECK;
00621             probLen = prob + LenHigh;
00622             offset = kLenNumLowSymbols + kLenNumMidSymbols;
00623             limit = 1 << kLenNumHighBits;
00624           }
00625         }
00626         TREE_DECODE_CHECK(probLen, limit, len);
00627         len += offset;
00628       }
00629 
00630       if (state < 4)
00631       {
00632         unsigned posSlot;
00633         prob = probs + PosSlot +
00634             ((len < kNumLenToPosStates ? len : kNumLenToPosStates - 1) <<
00635             kNumPosSlotBits);
00636         TREE_DECODE_CHECK(prob, 1 << kNumPosSlotBits, posSlot);
00637         if (posSlot >= kStartPosModelIndex)
00638         {
00639           int numDirectBits = ((posSlot >> 1) - 1);
00640 
00641           /* if (bufLimit - buf >= 8) return DUMMY_MATCH; */
00642 
00643           if (posSlot < kEndPosModelIndex)
00644           {
00645             prob = probs + SpecPos + ((2 | (posSlot & 1)) << numDirectBits) - posSlot - 1;
00646           }
00647           else
00648           {
00649             numDirectBits -= kNumAlignBits;
00650             do
00651             {
00652               NORMALIZE_CHECK
00653               range >>= 1;
00654               code -= range & (((code - range) >> 31) - 1);
00655               /* if (code >= range) code -= range; */
00656             }
00657             while (--numDirectBits != 0);
00658             prob = probs + Align;
00659             numDirectBits = kNumAlignBits;
00660           }
00661           {
00662             unsigned i = 1;
00663             do
00664             {
00665               GET_BIT_CHECK(prob + i, i);
00666             }
00667             while (--numDirectBits != 0);
00668           }
00669         }
00670       }
00671     }
00672   }
00673   NORMALIZE_CHECK;
00674   return res;
00675 }
00676 
00677 
00678 static void LzmaDec_InitRc(CLzmaDec *p, const Byte *data)
00679 {
00680   p->code = ((UInt32)data[1] << 24) | ((UInt32)data[2] << 16) | ((UInt32)data[3] << 8) | ((UInt32)data[4]);
00681   p->range = 0xFFFFFFFF;
00682   p->needFlush = 0;
00683 }
00684 
00685 void LzmaDec_InitDicAndState(CLzmaDec *p, Bool initDic, Bool initState)
00686 {
00687   p->needFlush = 1;
00688   p->remainLen = 0;
00689   p->tempBufSize = 0;
00690 
00691   if (initDic)
00692   {
00693     p->processedPos = 0;
00694     p->checkDicSize = 0;
00695     p->needInitState = 1;
00696   }
00697   if (initState)
00698     p->needInitState = 1;
00699 }
00700 
00701 void LzmaDec_Init(CLzmaDec *p)
00702 {
00703   p->dicPos = 0;
00704   LzmaDec_InitDicAndState(p, True, True);
00705 }
00706 
00707 static void LzmaDec_InitStateReal(CLzmaDec *p)
00708 {
00709   UInt32 numProbs = Literal + ((UInt32)LZMA_LIT_SIZE << (p->prop.lc + p->prop.lp));
00710   UInt32 i;
00711   CLzmaProb *probs = p->probs;
00712   for (i = 0; i < numProbs; i++)
00713     probs[i] = kBitModelTotal >> 1;
00714   p->reps[0] = p->reps[1] = p->reps[2] = p->reps[3] = 1;
00715   p->state = 0;
00716   p->needInitState = 0;
00717 }
00718 
00719 SRes LzmaDec_DecodeToDic(CLzmaDec *p, SizeT dicLimit, const Byte *src, SizeT *srcLen,
00720     ELzmaFinishMode finishMode, ELzmaStatus *status)
00721 {
00722   SizeT inSize = *srcLen;
00723   (*srcLen) = 0;
00724   LzmaDec_WriteRem(p, dicLimit);
00725   
00726   *status = LZMA_STATUS_NOT_SPECIFIED;
00727 
00728   while (p->remainLen != kMatchSpecLenStart)
00729   {
00730       int checkEndMarkNow;
00731 
00732       if (p->needFlush != 0)
00733       {
00734         for (; inSize > 0 && p->tempBufSize < RC_INIT_SIZE; (*srcLen)++, inSize--)
00735           p->tempBuf[p->tempBufSize++] = *src++;
00736         if (p->tempBufSize < RC_INIT_SIZE)
00737         {
00738           *status = LZMA_STATUS_NEEDS_MORE_INPUT;
00739           return SZ_OK;
00740         }
00741         if (p->tempBuf[0] != 0)
00742           return SZ_ERROR_DATA;
00743 
00744         LzmaDec_InitRc(p, p->tempBuf);
00745         p->tempBufSize = 0;
00746       }
00747 
00748       checkEndMarkNow = 0;
00749       if (p->dicPos >= dicLimit)
00750       {
00751         if (p->remainLen == 0 && p->code == 0)
00752         {
00753           *status = LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK;
00754           return SZ_OK;
00755         }
00756         if (finishMode == LZMA_FINISH_ANY)
00757         {
00758           *status = LZMA_STATUS_NOT_FINISHED;
00759           return SZ_OK;
00760         }
00761         if (p->remainLen != 0)
00762         {
00763           *status = LZMA_STATUS_NOT_FINISHED;
00764           return SZ_ERROR_DATA;
00765         }
00766         checkEndMarkNow = 1;
00767       }
00768 
00769       if (p->needInitState)
00770         LzmaDec_InitStateReal(p);
00771   
00772       if (p->tempBufSize == 0)
00773       {
00774         SizeT processed;
00775         const Byte *bufLimit;
00776         if (inSize < LZMA_REQUIRED_INPUT_MAX || checkEndMarkNow)
00777         {
00778           int dummyRes = LzmaDec_TryDummy(p, src, inSize);
00779           if (dummyRes == DUMMY_ERROR)
00780           {
00781             memcpy(p->tempBuf, src, inSize);
00782             p->tempBufSize = (unsigned)inSize;
00783             (*srcLen) += inSize;
00784             *status = LZMA_STATUS_NEEDS_MORE_INPUT;
00785             return SZ_OK;
00786           }
00787           if (checkEndMarkNow && dummyRes != DUMMY_MATCH)
00788           {
00789             *status = LZMA_STATUS_NOT_FINISHED;
00790             return SZ_ERROR_DATA;
00791           }
00792           bufLimit = src;
00793         }
00794         else
00795           bufLimit = src + inSize - LZMA_REQUIRED_INPUT_MAX;
00796         p->buf = src;
00797         if (LzmaDec_DecodeReal2(p, dicLimit, bufLimit) != 0)
00798           return SZ_ERROR_DATA;
00799         processed = (SizeT)(p->buf - src);
00800         (*srcLen) += processed;
00801         src += processed;
00802         inSize -= processed;
00803       }
00804       else
00805       {
00806         unsigned rem = p->tempBufSize, lookAhead = 0;
00807         while (rem < LZMA_REQUIRED_INPUT_MAX && lookAhead < inSize)
00808           p->tempBuf[rem++] = src[lookAhead++];
00809         p->tempBufSize = rem;
00810         if (rem < LZMA_REQUIRED_INPUT_MAX || checkEndMarkNow)
00811         {
00812           int dummyRes = LzmaDec_TryDummy(p, p->tempBuf, rem);
00813           if (dummyRes == DUMMY_ERROR)
00814           {
00815             (*srcLen) += lookAhead;
00816             *status = LZMA_STATUS_NEEDS_MORE_INPUT;
00817             return SZ_OK;
00818           }
00819           if (checkEndMarkNow && dummyRes != DUMMY_MATCH)
00820           {
00821             *status = LZMA_STATUS_NOT_FINISHED;
00822             return SZ_ERROR_DATA;
00823           }
00824         }
00825         p->buf = p->tempBuf;
00826         if (LzmaDec_DecodeReal2(p, dicLimit, p->buf) != 0)
00827           return SZ_ERROR_DATA;
00828         lookAhead -= (rem - (unsigned)(p->buf - p->tempBuf));
00829         (*srcLen) += lookAhead;
00830         src += lookAhead;
00831         inSize -= lookAhead;
00832         p->tempBufSize = 0;
00833       }
00834   }
00835   if (p->code == 0)
00836     *status = LZMA_STATUS_FINISHED_WITH_MARK;
00837   return (p->code == 0) ? SZ_OK : SZ_ERROR_DATA;
00838 }
00839 
00840 SRes LzmaDec_DecodeToBuf(CLzmaDec *p, Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen, ELzmaFinishMode finishMode, ELzmaStatus *status)
00841 {
00842   SizeT outSize = *destLen;
00843   SizeT inSize = *srcLen;
00844   *srcLen = *destLen = 0;
00845   for (;;)
00846   {
00847     SizeT inSizeCur = inSize, outSizeCur, dicPos;
00848     ELzmaFinishMode curFinishMode;
00849     SRes res;
00850     if (p->dicPos == p->dicBufSize)
00851       p->dicPos = 0;
00852     dicPos = p->dicPos;
00853     if (outSize > p->dicBufSize - dicPos)
00854     {
00855       outSizeCur = p->dicBufSize;
00856       curFinishMode = LZMA_FINISH_ANY;
00857     }
00858     else
00859     {
00860       outSizeCur = dicPos + outSize;
00861       curFinishMode = finishMode;
00862     }
00863 
00864     res = LzmaDec_DecodeToDic(p, outSizeCur, src, &inSizeCur, curFinishMode, status);
00865     src += inSizeCur;
00866     inSize -= inSizeCur;
00867     *srcLen += inSizeCur;
00868     outSizeCur = p->dicPos - dicPos;
00869     memcpy(dest, p->dic + dicPos, outSizeCur);
00870     dest += outSizeCur;
00871     outSize -= outSizeCur;
00872     *destLen += outSizeCur;
00873     if (res != 0)
00874       return res;
00875     if (outSizeCur == 0 || outSize == 0)
00876       return SZ_OK;
00877   }
00878 }
00879 
00880 void LzmaDec_FreeProbs(CLzmaDec *p, ISzAlloc *alloc)
00881 {
00882   alloc->Free(alloc, p->probs);
00883   p->probs = 0;
00884 }
00885 
00886 static void LzmaDec_FreeDict(CLzmaDec *p, ISzAlloc *alloc)
00887 {
00888   alloc->Free(alloc, p->dic);
00889   p->dic = 0;
00890 }
00891 
00892 void LzmaDec_Free(CLzmaDec *p, ISzAlloc *alloc)
00893 {
00894   LzmaDec_FreeProbs(p, alloc);
00895   LzmaDec_FreeDict(p, alloc);
00896 }
00897 
00898 SRes LzmaProps_Decode(CLzmaProps *p, const Byte *data, unsigned size)
00899 {
00900   UInt32 dicSize;
00901   Byte d;
00902   
00903   if (size < LZMA_PROPS_SIZE)
00904     return SZ_ERROR_UNSUPPORTED;
00905   else
00906     dicSize = data[1] | ((UInt32)data[2] << 8) | ((UInt32)data[3] << 16) | ((UInt32)data[4] << 24);
00907  
00908   if (dicSize < LZMA_DIC_MIN)
00909     dicSize = LZMA_DIC_MIN;
00910   p->dicSize = dicSize;
00911 
00912   d = data[0];
00913   if (d >= (9 * 5 * 5))
00914     return SZ_ERROR_UNSUPPORTED;
00915 
00916   p->lc = d % 9;
00917   d /= 9;
00918   p->pb = d / 5;
00919   p->lp = d % 5;
00920 
00921   return SZ_OK;
00922 }
00923 
00924 static SRes LzmaDec_AllocateProbs2(CLzmaDec *p, const CLzmaProps *propNew, ISzAlloc *alloc)
00925 {
00926   UInt32 numProbs = LzmaProps_GetNumProbs(propNew);
00927   if (p->probs == 0 || numProbs != p->numProbs)
00928   {
00929     LzmaDec_FreeProbs(p, alloc);
00930     p->probs = (CLzmaProb *)alloc->Alloc(alloc, numProbs * sizeof(CLzmaProb));
00931     p->numProbs = numProbs;
00932     if (p->probs == 0)
00933       return SZ_ERROR_MEM;
00934   }
00935   return SZ_OK;
00936 }
00937 
00938 SRes LzmaDec_AllocateProbs(CLzmaDec *p, const Byte *props, unsigned propsSize, ISzAlloc *alloc)
00939 {
00940   CLzmaProps propNew;
00941   RINOK(LzmaProps_Decode(&propNew, props, propsSize));
00942   RINOK(LzmaDec_AllocateProbs2(p, &propNew, alloc));
00943   p->prop = propNew;
00944   return SZ_OK;
00945 }
00946 
00947 SRes LzmaDec_Allocate(CLzmaDec *p, const Byte *props, unsigned propsSize, ISzAlloc *alloc)
00948 {
00949   CLzmaProps propNew;
00950   SizeT dicBufSize;
00951   RINOK(LzmaProps_Decode(&propNew, props, propsSize));
00952   RINOK(LzmaDec_AllocateProbs2(p, &propNew, alloc));
00953   dicBufSize = propNew.dicSize;
00954   if (p->dic == 0 || dicBufSize != p->dicBufSize)
00955   {
00956     LzmaDec_FreeDict(p, alloc);
00957     p->dic = (Byte *)alloc->Alloc(alloc, dicBufSize);
00958     if (p->dic == 0)
00959     {
00960       LzmaDec_FreeProbs(p, alloc);
00961       return SZ_ERROR_MEM;
00962     }
00963   }
00964   p->dicBufSize = dicBufSize;
00965   p->prop = propNew;
00966   return SZ_OK;
00967 }
00968 
00969 SRes LzmaDecode(Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen,
00970     const Byte *propData, unsigned propSize, ELzmaFinishMode finishMode,
00971     ELzmaStatus *status, ISzAlloc *alloc)
00972 {
00973   CLzmaDec p;
00974   SRes res;
00975   SizeT inSize = *srcLen;
00976   SizeT outSize = *destLen;
00977   *srcLen = *destLen = 0;
00978   if (inSize < RC_INIT_SIZE)
00979     return SZ_ERROR_INPUT_EOF;
00980 
00981   LzmaDec_Construct(&p);
00982   res = LzmaDec_AllocateProbs(&p, propData, propSize, alloc);
00983   if (res != 0)
00984     return res;
00985   p.dic = dest;
00986   p.dicBufSize = outSize;
00987 
00988   LzmaDec_Init(&p);
00989   
00990   *srcLen = inSize;
00991   res = LzmaDec_DecodeToDic(&p, outSize, src, srcLen, finishMode, status);
00992 
00993   if (res == SZ_OK && *status == LZMA_STATUS_NEEDS_MORE_INPUT)
00994     res = SZ_ERROR_INPUT_EOF;
00995 
00996   (*destLen) = p.dicPos;
00997   LzmaDec_FreeProbs(&p, alloc);
00998   return res;
00999 }