00001
00002
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
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
00119
00120
00121
00122
00123
00124
00125
00126
00127
00128
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));
00332 distance = (distance << 1) + (t + 1);
00333 code += range & t;
00334 }
00335
00336
00337
00338
00339
00340
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,
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
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
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
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 }