annotate src/win32/7zip/7z/C/LzmaDec.c @ 1:f9f4f1b99eed

importing src directory
author Robert McIntyre <rlm@mit.edu>
date Sat, 03 Mar 2012 10:31:27 -0600
parents
children
rev   line source
rlm@1 1 /* LzmaDec.c -- LZMA Decoder
rlm@1 2 2008-11-06 : Igor Pavlov : Public domain */
rlm@1 3
rlm@1 4 #include "LzmaDec.h"
rlm@1 5
rlm@1 6 #include <string.h>
rlm@1 7
rlm@1 8 #define kNumTopBits 24
rlm@1 9 #define kTopValue ((UInt32)1 << kNumTopBits)
rlm@1 10
rlm@1 11 #define kNumBitModelTotalBits 11
rlm@1 12 #define kBitModelTotal (1 << kNumBitModelTotalBits)
rlm@1 13 #define kNumMoveBits 5
rlm@1 14
rlm@1 15 #define RC_INIT_SIZE 5
rlm@1 16
rlm@1 17 #define NORMALIZE if (range < kTopValue) { range <<= 8; code = (code << 8) | (*buf++); }
rlm@1 18
rlm@1 19 #define IF_BIT_0(p) ttt = *(p); NORMALIZE; bound = (range >> kNumBitModelTotalBits) * ttt; if (code < bound)
rlm@1 20 #define UPDATE_0(p) range = bound; *(p) = (CLzmaProb)(ttt + ((kBitModelTotal - ttt) >> kNumMoveBits));
rlm@1 21 #define UPDATE_1(p) range -= bound; code -= bound; *(p) = (CLzmaProb)(ttt - (ttt >> kNumMoveBits));
rlm@1 22 #define GET_BIT2(p, i, A0, A1) IF_BIT_0(p) \
rlm@1 23 { UPDATE_0(p); i = (i + i); A0; } else \
rlm@1 24 { UPDATE_1(p); i = (i + i) + 1; A1; }
rlm@1 25 #define GET_BIT(p, i) GET_BIT2(p, i, ; , ;)
rlm@1 26
rlm@1 27 #define TREE_GET_BIT(probs, i) { GET_BIT((probs + i), i); }
rlm@1 28 #define TREE_DECODE(probs, limit, i) \
rlm@1 29 { i = 1; do { TREE_GET_BIT(probs, i); } while (i < limit); i -= limit; }
rlm@1 30
rlm@1 31 /* #define _LZMA_SIZE_OPT */
rlm@1 32
rlm@1 33 #ifdef _LZMA_SIZE_OPT
rlm@1 34 #define TREE_6_DECODE(probs, i) TREE_DECODE(probs, (1 << 6), i)
rlm@1 35 #else
rlm@1 36 #define TREE_6_DECODE(probs, i) \
rlm@1 37 { i = 1; \
rlm@1 38 TREE_GET_BIT(probs, i); \
rlm@1 39 TREE_GET_BIT(probs, i); \
rlm@1 40 TREE_GET_BIT(probs, i); \
rlm@1 41 TREE_GET_BIT(probs, i); \
rlm@1 42 TREE_GET_BIT(probs, i); \
rlm@1 43 TREE_GET_BIT(probs, i); \
rlm@1 44 i -= 0x40; }
rlm@1 45 #endif
rlm@1 46
rlm@1 47 #define NORMALIZE_CHECK if (range < kTopValue) { if (buf >= bufLimit) return DUMMY_ERROR; range <<= 8; code = (code << 8) | (*buf++); }
rlm@1 48
rlm@1 49 #define IF_BIT_0_CHECK(p) ttt = *(p); NORMALIZE_CHECK; bound = (range >> kNumBitModelTotalBits) * ttt; if (code < bound)
rlm@1 50 #define UPDATE_0_CHECK range = bound;
rlm@1 51 #define UPDATE_1_CHECK range -= bound; code -= bound;
rlm@1 52 #define GET_BIT2_CHECK(p, i, A0, A1) IF_BIT_0_CHECK(p) \
rlm@1 53 { UPDATE_0_CHECK; i = (i + i); A0; } else \
rlm@1 54 { UPDATE_1_CHECK; i = (i + i) + 1; A1; }
rlm@1 55 #define GET_BIT_CHECK(p, i) GET_BIT2_CHECK(p, i, ; , ;)
rlm@1 56 #define TREE_DECODE_CHECK(probs, limit, i) \
rlm@1 57 { i = 1; do { GET_BIT_CHECK(probs + i, i) } while (i < limit); i -= limit; }
rlm@1 58
rlm@1 59
rlm@1 60 #define kNumPosBitsMax 4
rlm@1 61 #define kNumPosStatesMax (1 << kNumPosBitsMax)
rlm@1 62
rlm@1 63 #define kLenNumLowBits 3
rlm@1 64 #define kLenNumLowSymbols (1 << kLenNumLowBits)
rlm@1 65 #define kLenNumMidBits 3
rlm@1 66 #define kLenNumMidSymbols (1 << kLenNumMidBits)
rlm@1 67 #define kLenNumHighBits 8
rlm@1 68 #define kLenNumHighSymbols (1 << kLenNumHighBits)
rlm@1 69
rlm@1 70 #define LenChoice 0
rlm@1 71 #define LenChoice2 (LenChoice + 1)
rlm@1 72 #define LenLow (LenChoice2 + 1)
rlm@1 73 #define LenMid (LenLow + (kNumPosStatesMax << kLenNumLowBits))
rlm@1 74 #define LenHigh (LenMid + (kNumPosStatesMax << kLenNumMidBits))
rlm@1 75 #define kNumLenProbs (LenHigh + kLenNumHighSymbols)
rlm@1 76
rlm@1 77
rlm@1 78 #define kNumStates 12
rlm@1 79 #define kNumLitStates 7
rlm@1 80
rlm@1 81 #define kStartPosModelIndex 4
rlm@1 82 #define kEndPosModelIndex 14
rlm@1 83 #define kNumFullDistances (1 << (kEndPosModelIndex >> 1))
rlm@1 84
rlm@1 85 #define kNumPosSlotBits 6
rlm@1 86 #define kNumLenToPosStates 4
rlm@1 87
rlm@1 88 #define kNumAlignBits 4
rlm@1 89 #define kAlignTableSize (1 << kNumAlignBits)
rlm@1 90
rlm@1 91 #define kMatchMinLen 2
rlm@1 92 #define kMatchSpecLenStart (kMatchMinLen + kLenNumLowSymbols + kLenNumMidSymbols + kLenNumHighSymbols)
rlm@1 93
rlm@1 94 #define IsMatch 0
rlm@1 95 #define IsRep (IsMatch + (kNumStates << kNumPosBitsMax))
rlm@1 96 #define IsRepG0 (IsRep + kNumStates)
rlm@1 97 #define IsRepG1 (IsRepG0 + kNumStates)
rlm@1 98 #define IsRepG2 (IsRepG1 + kNumStates)
rlm@1 99 #define IsRep0Long (IsRepG2 + kNumStates)
rlm@1 100 #define PosSlot (IsRep0Long + (kNumStates << kNumPosBitsMax))
rlm@1 101 #define SpecPos (PosSlot + (kNumLenToPosStates << kNumPosSlotBits))
rlm@1 102 #define Align (SpecPos + kNumFullDistances - kEndPosModelIndex)
rlm@1 103 #define LenCoder (Align + kAlignTableSize)
rlm@1 104 #define RepLenCoder (LenCoder + kNumLenProbs)
rlm@1 105 #define Literal (RepLenCoder + kNumLenProbs)
rlm@1 106
rlm@1 107 #define LZMA_BASE_SIZE 1846
rlm@1 108 #define LZMA_LIT_SIZE 768
rlm@1 109
rlm@1 110 #define LzmaProps_GetNumProbs(p) ((UInt32)LZMA_BASE_SIZE + (LZMA_LIT_SIZE << ((p)->lc + (p)->lp)))
rlm@1 111
rlm@1 112 #if Literal != LZMA_BASE_SIZE
rlm@1 113 StopCompilingDueBUG
rlm@1 114 #endif
rlm@1 115
rlm@1 116 static const Byte kLiteralNextStates[kNumStates * 2] =
rlm@1 117 {
rlm@1 118 0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 4, 5,
rlm@1 119 7, 7, 7, 7, 7, 7, 7, 10, 10, 10, 10, 10
rlm@1 120 };
rlm@1 121
rlm@1 122 #define LZMA_DIC_MIN (1 << 12)
rlm@1 123
rlm@1 124 /* First LZMA-symbol is always decoded.
rlm@1 125 And it decodes new LZMA-symbols while (buf < bufLimit), but "buf" is without last normalization
rlm@1 126 Out:
rlm@1 127 Result:
rlm@1 128 SZ_OK - OK
rlm@1 129 SZ_ERROR_DATA - Error
rlm@1 130 p->remainLen:
rlm@1 131 < kMatchSpecLenStart : normal remain
rlm@1 132 = kMatchSpecLenStart : finished
rlm@1 133 = kMatchSpecLenStart + 1 : Flush marker
rlm@1 134 = kMatchSpecLenStart + 2 : State Init Marker
rlm@1 135 */
rlm@1 136
rlm@1 137 static int MY_FAST_CALL LzmaDec_DecodeReal(CLzmaDec *p, SizeT limit, const Byte *bufLimit)
rlm@1 138 {
rlm@1 139 CLzmaProb *probs = p->probs;
rlm@1 140
rlm@1 141 unsigned state = p->state;
rlm@1 142 UInt32 rep0 = p->reps[0], rep1 = p->reps[1], rep2 = p->reps[2], rep3 = p->reps[3];
rlm@1 143 unsigned pbMask = ((unsigned)1 << (p->prop.pb)) - 1;
rlm@1 144 unsigned lpMask = ((unsigned)1 << (p->prop.lp)) - 1;
rlm@1 145 unsigned lc = p->prop.lc;
rlm@1 146
rlm@1 147 Byte *dic = p->dic;
rlm@1 148 SizeT dicBufSize = p->dicBufSize;
rlm@1 149 SizeT dicPos = p->dicPos;
rlm@1 150
rlm@1 151 UInt32 processedPos = p->processedPos;
rlm@1 152 UInt32 checkDicSize = p->checkDicSize;
rlm@1 153 unsigned len = 0;
rlm@1 154
rlm@1 155 const Byte *buf = p->buf;
rlm@1 156 UInt32 range = p->range;
rlm@1 157 UInt32 code = p->code;
rlm@1 158
rlm@1 159 do
rlm@1 160 {
rlm@1 161 CLzmaProb *prob;
rlm@1 162 UInt32 bound;
rlm@1 163 unsigned ttt;
rlm@1 164 unsigned posState = processedPos & pbMask;
rlm@1 165
rlm@1 166 prob = probs + IsMatch + (state << kNumPosBitsMax) + posState;
rlm@1 167 IF_BIT_0(prob)
rlm@1 168 {
rlm@1 169 unsigned symbol;
rlm@1 170 UPDATE_0(prob);
rlm@1 171 prob = probs + Literal;
rlm@1 172 if (checkDicSize != 0 || processedPos != 0)
rlm@1 173 prob += (LZMA_LIT_SIZE * (((processedPos & lpMask) << lc) +
rlm@1 174 (dic[(dicPos == 0 ? dicBufSize : dicPos) - 1] >> (8 - lc))));
rlm@1 175
rlm@1 176 if (state < kNumLitStates)
rlm@1 177 {
rlm@1 178 symbol = 1;
rlm@1 179 do { GET_BIT(prob + symbol, symbol) } while (symbol < 0x100);
rlm@1 180 }
rlm@1 181 else
rlm@1 182 {
rlm@1 183 unsigned matchByte = p->dic[(dicPos - rep0) + ((dicPos < rep0) ? dicBufSize : 0)];
rlm@1 184 unsigned offs = 0x100;
rlm@1 185 symbol = 1;
rlm@1 186 do
rlm@1 187 {
rlm@1 188 unsigned bit;
rlm@1 189 CLzmaProb *probLit;
rlm@1 190 matchByte <<= 1;
rlm@1 191 bit = (matchByte & offs);
rlm@1 192 probLit = prob + offs + bit + symbol;
rlm@1 193 GET_BIT2(probLit, symbol, offs &= ~bit, offs &= bit)
rlm@1 194 }
rlm@1 195 while (symbol < 0x100);
rlm@1 196 }
rlm@1 197 dic[dicPos++] = (Byte)(symbol & 0xFF);
rlm@1 198 processedPos++;
rlm@1 199
rlm@1 200 state = kLiteralNextStates[state];
rlm@1 201 /* if (state < 4) state = 0; else if (state < 10) state -= 3; else state -= 6; */
rlm@1 202 continue;
rlm@1 203 }
rlm@1 204 else
rlm@1 205 {
rlm@1 206 UPDATE_1(prob);
rlm@1 207 prob = probs + IsRep + state;
rlm@1 208 IF_BIT_0(prob)
rlm@1 209 {
rlm@1 210 UPDATE_0(prob);
rlm@1 211 state += kNumStates;
rlm@1 212 prob = probs + LenCoder;
rlm@1 213 }
rlm@1 214 else
rlm@1 215 {
rlm@1 216 UPDATE_1(prob);
rlm@1 217 if (checkDicSize == 0 && processedPos == 0)
rlm@1 218 return SZ_ERROR_DATA;
rlm@1 219 prob = probs + IsRepG0 + state;
rlm@1 220 IF_BIT_0(prob)
rlm@1 221 {
rlm@1 222 UPDATE_0(prob);
rlm@1 223 prob = probs + IsRep0Long + (state << kNumPosBitsMax) + posState;
rlm@1 224 IF_BIT_0(prob)
rlm@1 225 {
rlm@1 226 UPDATE_0(prob);
rlm@1 227 dic[dicPos] = dic[(dicPos - rep0) + ((dicPos < rep0) ? dicBufSize : 0)];
rlm@1 228 dicPos++;
rlm@1 229 processedPos++;
rlm@1 230 state = state < kNumLitStates ? 9 : 11;
rlm@1 231 continue;
rlm@1 232 }
rlm@1 233 UPDATE_1(prob);
rlm@1 234 }
rlm@1 235 else
rlm@1 236 {
rlm@1 237 UInt32 distance;
rlm@1 238 UPDATE_1(prob);
rlm@1 239 prob = probs + IsRepG1 + state;
rlm@1 240 IF_BIT_0(prob)
rlm@1 241 {
rlm@1 242 UPDATE_0(prob);
rlm@1 243 distance = rep1;
rlm@1 244 }
rlm@1 245 else
rlm@1 246 {
rlm@1 247 UPDATE_1(prob);
rlm@1 248 prob = probs + IsRepG2 + state;
rlm@1 249 IF_BIT_0(prob)
rlm@1 250 {
rlm@1 251 UPDATE_0(prob);
rlm@1 252 distance = rep2;
rlm@1 253 }
rlm@1 254 else
rlm@1 255 {
rlm@1 256 UPDATE_1(prob);
rlm@1 257 distance = rep3;
rlm@1 258 rep3 = rep2;
rlm@1 259 }
rlm@1 260 rep2 = rep1;
rlm@1 261 }
rlm@1 262 rep1 = rep0;
rlm@1 263 rep0 = distance;
rlm@1 264 }
rlm@1 265 state = state < kNumLitStates ? 8 : 11;
rlm@1 266 prob = probs + RepLenCoder;
rlm@1 267 }
rlm@1 268 {
rlm@1 269 unsigned limit, offset;
rlm@1 270 CLzmaProb *probLen = prob + LenChoice;
rlm@1 271 IF_BIT_0(probLen)
rlm@1 272 {
rlm@1 273 UPDATE_0(probLen);
rlm@1 274 probLen = prob + LenLow + (posState << kLenNumLowBits);
rlm@1 275 offset = 0;
rlm@1 276 limit = (1 << kLenNumLowBits);
rlm@1 277 }
rlm@1 278 else
rlm@1 279 {
rlm@1 280 UPDATE_1(probLen);
rlm@1 281 probLen = prob + LenChoice2;
rlm@1 282 IF_BIT_0(probLen)
rlm@1 283 {
rlm@1 284 UPDATE_0(probLen);
rlm@1 285 probLen = prob + LenMid + (posState << kLenNumMidBits);
rlm@1 286 offset = kLenNumLowSymbols;
rlm@1 287 limit = (1 << kLenNumMidBits);
rlm@1 288 }
rlm@1 289 else
rlm@1 290 {
rlm@1 291 UPDATE_1(probLen);
rlm@1 292 probLen = prob + LenHigh;
rlm@1 293 offset = kLenNumLowSymbols + kLenNumMidSymbols;
rlm@1 294 limit = (1 << kLenNumHighBits);
rlm@1 295 }
rlm@1 296 }
rlm@1 297 TREE_DECODE(probLen, limit, len);
rlm@1 298 len += offset;
rlm@1 299 }
rlm@1 300
rlm@1 301 if (state >= kNumStates)
rlm@1 302 {
rlm@1 303 UInt32 distance;
rlm@1 304 prob = probs + PosSlot +
rlm@1 305 ((len < kNumLenToPosStates ? len : kNumLenToPosStates - 1) << kNumPosSlotBits);
rlm@1 306 TREE_6_DECODE(prob, distance);
rlm@1 307 if (distance >= kStartPosModelIndex)
rlm@1 308 {
rlm@1 309 unsigned posSlot = (unsigned)distance;
rlm@1 310 int numDirectBits = (int)(((distance >> 1) - 1));
rlm@1 311 distance = (2 | (distance & 1));
rlm@1 312 if (posSlot < kEndPosModelIndex)
rlm@1 313 {
rlm@1 314 distance <<= numDirectBits;
rlm@1 315 prob = probs + SpecPos + distance - posSlot - 1;
rlm@1 316 {
rlm@1 317 UInt32 mask = 1;
rlm@1 318 unsigned i = 1;
rlm@1 319 do
rlm@1 320 {
rlm@1 321 GET_BIT2(prob + i, i, ; , distance |= mask);
rlm@1 322 mask <<= 1;
rlm@1 323 }
rlm@1 324 while (--numDirectBits != 0);
rlm@1 325 }
rlm@1 326 }
rlm@1 327 else
rlm@1 328 {
rlm@1 329 numDirectBits -= kNumAlignBits;
rlm@1 330 do
rlm@1 331 {
rlm@1 332 NORMALIZE
rlm@1 333 range >>= 1;
rlm@1 334
rlm@1 335 {
rlm@1 336 UInt32 t;
rlm@1 337 code -= range;
rlm@1 338 t = (0 - ((UInt32)code >> 31)); /* (UInt32)((Int32)code >> 31) */
rlm@1 339 distance = (distance << 1) + (t + 1);
rlm@1 340 code += range & t;
rlm@1 341 }
rlm@1 342 /*
rlm@1 343 distance <<= 1;
rlm@1 344 if (code >= range)
rlm@1 345 {
rlm@1 346 code -= range;
rlm@1 347 distance |= 1;
rlm@1 348 }
rlm@1 349 */
rlm@1 350 }
rlm@1 351 while (--numDirectBits != 0);
rlm@1 352 prob = probs + Align;
rlm@1 353 distance <<= kNumAlignBits;
rlm@1 354 {
rlm@1 355 unsigned i = 1;
rlm@1 356 GET_BIT2(prob + i, i, ; , distance |= 1);
rlm@1 357 GET_BIT2(prob + i, i, ; , distance |= 2);
rlm@1 358 GET_BIT2(prob + i, i, ; , distance |= 4);
rlm@1 359 GET_BIT2(prob + i, i, ; , distance |= 8);
rlm@1 360 }
rlm@1 361 if (distance == (UInt32)0xFFFFFFFF)
rlm@1 362 {
rlm@1 363 len += kMatchSpecLenStart;
rlm@1 364 state -= kNumStates;
rlm@1 365 break;
rlm@1 366 }
rlm@1 367 }
rlm@1 368 }
rlm@1 369 rep3 = rep2;
rlm@1 370 rep2 = rep1;
rlm@1 371 rep1 = rep0;
rlm@1 372 rep0 = distance + 1;
rlm@1 373 if (checkDicSize == 0)
rlm@1 374 {
rlm@1 375 if (distance >= processedPos)
rlm@1 376 return SZ_ERROR_DATA;
rlm@1 377 }
rlm@1 378 else if (distance >= checkDicSize)
rlm@1 379 return SZ_ERROR_DATA;
rlm@1 380 state = (state < kNumStates + kNumLitStates) ? kNumLitStates : kNumLitStates + 3;
rlm@1 381 /* state = kLiteralNextStates[state]; */
rlm@1 382 }
rlm@1 383
rlm@1 384 len += kMatchMinLen;
rlm@1 385
rlm@1 386 if (limit == dicPos)
rlm@1 387 return SZ_ERROR_DATA;
rlm@1 388 {
rlm@1 389 SizeT rem = limit - dicPos;
rlm@1 390 unsigned curLen = ((rem < len) ? (unsigned)rem : len);
rlm@1 391 SizeT pos = (dicPos - rep0) + ((dicPos < rep0) ? dicBufSize : 0);
rlm@1 392
rlm@1 393 processedPos += curLen;
rlm@1 394
rlm@1 395 len -= curLen;
rlm@1 396 if (pos + curLen <= dicBufSize)
rlm@1 397 {
rlm@1 398 Byte *dest = dic + dicPos;
rlm@1 399 ptrdiff_t src = (ptrdiff_t)pos - (ptrdiff_t)dicPos;
rlm@1 400 const Byte *lim = dest + curLen;
rlm@1 401 dicPos += curLen;
rlm@1 402 do
rlm@1 403 *(dest) = (Byte)*(dest + src);
rlm@1 404 while (++dest != lim);
rlm@1 405 }
rlm@1 406 else
rlm@1 407 {
rlm@1 408 do
rlm@1 409 {
rlm@1 410 dic[dicPos++] = dic[pos];
rlm@1 411 if (++pos == dicBufSize)
rlm@1 412 pos = 0;
rlm@1 413 }
rlm@1 414 while (--curLen != 0);
rlm@1 415 }
rlm@1 416 }
rlm@1 417 }
rlm@1 418 }
rlm@1 419 while (dicPos < limit && buf < bufLimit);
rlm@1 420 NORMALIZE;
rlm@1 421 p->buf = buf;
rlm@1 422 p->range = range;
rlm@1 423 p->code = code;
rlm@1 424 p->remainLen = len;
rlm@1 425 p->dicPos = dicPos;
rlm@1 426 p->processedPos = processedPos;
rlm@1 427 p->reps[0] = rep0;
rlm@1 428 p->reps[1] = rep1;
rlm@1 429 p->reps[2] = rep2;
rlm@1 430 p->reps[3] = rep3;
rlm@1 431 p->state = state;
rlm@1 432
rlm@1 433 return SZ_OK;
rlm@1 434 }
rlm@1 435
rlm@1 436 static void MY_FAST_CALL LzmaDec_WriteRem(CLzmaDec *p, SizeT limit)
rlm@1 437 {
rlm@1 438 if (p->remainLen != 0 && p->remainLen < kMatchSpecLenStart)
rlm@1 439 {
rlm@1 440 Byte *dic = p->dic;
rlm@1 441 SizeT dicPos = p->dicPos;
rlm@1 442 SizeT dicBufSize = p->dicBufSize;
rlm@1 443 unsigned len = p->remainLen;
rlm@1 444 UInt32 rep0 = p->reps[0];
rlm@1 445 if (limit - dicPos < len)
rlm@1 446 len = (unsigned)(limit - dicPos);
rlm@1 447
rlm@1 448 if (p->checkDicSize == 0 && p->prop.dicSize - p->processedPos <= len)
rlm@1 449 p->checkDicSize = p->prop.dicSize;
rlm@1 450
rlm@1 451 p->processedPos += len;
rlm@1 452 p->remainLen -= len;
rlm@1 453 while (len-- != 0)
rlm@1 454 {
rlm@1 455 dic[dicPos] = dic[(dicPos - rep0) + ((dicPos < rep0) ? dicBufSize : 0)];
rlm@1 456 dicPos++;
rlm@1 457 }
rlm@1 458 p->dicPos = dicPos;
rlm@1 459 }
rlm@1 460 }
rlm@1 461
rlm@1 462 static int MY_FAST_CALL LzmaDec_DecodeReal2(CLzmaDec *p, SizeT limit, const Byte *bufLimit)
rlm@1 463 {
rlm@1 464 do
rlm@1 465 {
rlm@1 466 SizeT limit2 = limit;
rlm@1 467 if (p->checkDicSize == 0)
rlm@1 468 {
rlm@1 469 UInt32 rem = p->prop.dicSize - p->processedPos;
rlm@1 470 if (limit - p->dicPos > rem)
rlm@1 471 limit2 = p->dicPos + rem;
rlm@1 472 }
rlm@1 473 RINOK(LzmaDec_DecodeReal(p, limit2, bufLimit));
rlm@1 474 if (p->processedPos >= p->prop.dicSize)
rlm@1 475 p->checkDicSize = p->prop.dicSize;
rlm@1 476 LzmaDec_WriteRem(p, limit);
rlm@1 477 }
rlm@1 478 while (p->dicPos < limit && p->buf < bufLimit && p->remainLen < kMatchSpecLenStart);
rlm@1 479
rlm@1 480 if (p->remainLen > kMatchSpecLenStart)
rlm@1 481 {
rlm@1 482 p->remainLen = kMatchSpecLenStart;
rlm@1 483 }
rlm@1 484 return 0;
rlm@1 485 }
rlm@1 486
rlm@1 487 typedef enum
rlm@1 488 {
rlm@1 489 DUMMY_ERROR, /* unexpected end of input stream */
rlm@1 490 DUMMY_LIT,
rlm@1 491 DUMMY_MATCH,
rlm@1 492 DUMMY_REP
rlm@1 493 } ELzmaDummy;
rlm@1 494
rlm@1 495 static ELzmaDummy LzmaDec_TryDummy(const CLzmaDec *p, const Byte *buf, SizeT inSize)
rlm@1 496 {
rlm@1 497 UInt32 range = p->range;
rlm@1 498 UInt32 code = p->code;
rlm@1 499 const Byte *bufLimit = buf + inSize;
rlm@1 500 CLzmaProb *probs = p->probs;
rlm@1 501 unsigned state = p->state;
rlm@1 502 ELzmaDummy res;
rlm@1 503
rlm@1 504 {
rlm@1 505 CLzmaProb *prob;
rlm@1 506 UInt32 bound;
rlm@1 507 unsigned ttt;
rlm@1 508 unsigned posState = (p->processedPos) & ((1 << p->prop.pb) - 1);
rlm@1 509
rlm@1 510 prob = probs + IsMatch + (state << kNumPosBitsMax) + posState;
rlm@1 511 IF_BIT_0_CHECK(prob)
rlm@1 512 {
rlm@1 513 UPDATE_0_CHECK
rlm@1 514
rlm@1 515 /* if (bufLimit - buf >= 7) return DUMMY_LIT; */
rlm@1 516
rlm@1 517 prob = probs + Literal;
rlm@1 518 if (p->checkDicSize != 0 || p->processedPos != 0)
rlm@1 519 prob += (LZMA_LIT_SIZE *
rlm@1 520 ((((p->processedPos) & ((1 << (p->prop.lp)) - 1)) << p->prop.lc) +
rlm@1 521 (p->dic[(p->dicPos == 0 ? p->dicBufSize : p->dicPos) - 1] >> (8 - p->prop.lc))));
rlm@1 522
rlm@1 523 if (state < kNumLitStates)
rlm@1 524 {
rlm@1 525 unsigned symbol = 1;
rlm@1 526 do { GET_BIT_CHECK(prob + symbol, symbol) } while (symbol < 0x100);
rlm@1 527 }
rlm@1 528 else
rlm@1 529 {
rlm@1 530 unsigned matchByte = p->dic[p->dicPos - p->reps[0] +
rlm@1 531 ((p->dicPos < p->reps[0]) ? p->dicBufSize : 0)];
rlm@1 532 unsigned offs = 0x100;
rlm@1 533 unsigned symbol = 1;
rlm@1 534 do
rlm@1 535 {
rlm@1 536 unsigned bit;
rlm@1 537 CLzmaProb *probLit;
rlm@1 538 matchByte <<= 1;
rlm@1 539 bit = (matchByte & offs);
rlm@1 540 probLit = prob + offs + bit + symbol;
rlm@1 541 GET_BIT2_CHECK(probLit, symbol, offs &= ~bit, offs &= bit)
rlm@1 542 }
rlm@1 543 while (symbol < 0x100);
rlm@1 544 }
rlm@1 545 res = DUMMY_LIT;
rlm@1 546 }
rlm@1 547 else
rlm@1 548 {
rlm@1 549 unsigned len;
rlm@1 550 UPDATE_1_CHECK;
rlm@1 551
rlm@1 552 prob = probs + IsRep + state;
rlm@1 553 IF_BIT_0_CHECK(prob)
rlm@1 554 {
rlm@1 555 UPDATE_0_CHECK;
rlm@1 556 state = 0;
rlm@1 557 prob = probs + LenCoder;
rlm@1 558 res = DUMMY_MATCH;
rlm@1 559 }
rlm@1 560 else
rlm@1 561 {
rlm@1 562 UPDATE_1_CHECK;
rlm@1 563 res = DUMMY_REP;
rlm@1 564 prob = probs + IsRepG0 + state;
rlm@1 565 IF_BIT_0_CHECK(prob)
rlm@1 566 {
rlm@1 567 UPDATE_0_CHECK;
rlm@1 568 prob = probs + IsRep0Long + (state << kNumPosBitsMax) + posState;
rlm@1 569 IF_BIT_0_CHECK(prob)
rlm@1 570 {
rlm@1 571 UPDATE_0_CHECK;
rlm@1 572 NORMALIZE_CHECK;
rlm@1 573 return DUMMY_REP;
rlm@1 574 }
rlm@1 575 else
rlm@1 576 {
rlm@1 577 UPDATE_1_CHECK;
rlm@1 578 }
rlm@1 579 }
rlm@1 580 else
rlm@1 581 {
rlm@1 582 UPDATE_1_CHECK;
rlm@1 583 prob = probs + IsRepG1 + state;
rlm@1 584 IF_BIT_0_CHECK(prob)
rlm@1 585 {
rlm@1 586 UPDATE_0_CHECK;
rlm@1 587 }
rlm@1 588 else
rlm@1 589 {
rlm@1 590 UPDATE_1_CHECK;
rlm@1 591 prob = probs + IsRepG2 + state;
rlm@1 592 IF_BIT_0_CHECK(prob)
rlm@1 593 {
rlm@1 594 UPDATE_0_CHECK;
rlm@1 595 }
rlm@1 596 else
rlm@1 597 {
rlm@1 598 UPDATE_1_CHECK;
rlm@1 599 }
rlm@1 600 }
rlm@1 601 }
rlm@1 602 state = kNumStates;
rlm@1 603 prob = probs + RepLenCoder;
rlm@1 604 }
rlm@1 605 {
rlm@1 606 unsigned limit, offset;
rlm@1 607 CLzmaProb *probLen = prob + LenChoice;
rlm@1 608 IF_BIT_0_CHECK(probLen)
rlm@1 609 {
rlm@1 610 UPDATE_0_CHECK;
rlm@1 611 probLen = prob + LenLow + (posState << kLenNumLowBits);
rlm@1 612 offset = 0;
rlm@1 613 limit = 1 << kLenNumLowBits;
rlm@1 614 }
rlm@1 615 else
rlm@1 616 {
rlm@1 617 UPDATE_1_CHECK;
rlm@1 618 probLen = prob + LenChoice2;
rlm@1 619 IF_BIT_0_CHECK(probLen)
rlm@1 620 {
rlm@1 621 UPDATE_0_CHECK;
rlm@1 622 probLen = prob + LenMid + (posState << kLenNumMidBits);
rlm@1 623 offset = kLenNumLowSymbols;
rlm@1 624 limit = 1 << kLenNumMidBits;
rlm@1 625 }
rlm@1 626 else
rlm@1 627 {
rlm@1 628 UPDATE_1_CHECK;
rlm@1 629 probLen = prob + LenHigh;
rlm@1 630 offset = kLenNumLowSymbols + kLenNumMidSymbols;
rlm@1 631 limit = 1 << kLenNumHighBits;
rlm@1 632 }
rlm@1 633 }
rlm@1 634 TREE_DECODE_CHECK(probLen, limit, len);
rlm@1 635 len += offset;
rlm@1 636 }
rlm@1 637
rlm@1 638 if (state < 4)
rlm@1 639 {
rlm@1 640 unsigned posSlot;
rlm@1 641 prob = probs + PosSlot +
rlm@1 642 ((len < kNumLenToPosStates ? len : kNumLenToPosStates - 1) <<
rlm@1 643 kNumPosSlotBits);
rlm@1 644 TREE_DECODE_CHECK(prob, 1 << kNumPosSlotBits, posSlot);
rlm@1 645 if (posSlot >= kStartPosModelIndex)
rlm@1 646 {
rlm@1 647 int numDirectBits = ((posSlot >> 1) - 1);
rlm@1 648
rlm@1 649 /* if (bufLimit - buf >= 8) return DUMMY_MATCH; */
rlm@1 650
rlm@1 651 if (posSlot < kEndPosModelIndex)
rlm@1 652 {
rlm@1 653 prob = probs + SpecPos + ((2 | (posSlot & 1)) << numDirectBits) - posSlot - 1;
rlm@1 654 }
rlm@1 655 else
rlm@1 656 {
rlm@1 657 numDirectBits -= kNumAlignBits;
rlm@1 658 do
rlm@1 659 {
rlm@1 660 NORMALIZE_CHECK
rlm@1 661 range >>= 1;
rlm@1 662 code -= range & (((code - range) >> 31) - 1);
rlm@1 663 /* if (code >= range) code -= range; */
rlm@1 664 }
rlm@1 665 while (--numDirectBits != 0);
rlm@1 666 prob = probs + Align;
rlm@1 667 numDirectBits = kNumAlignBits;
rlm@1 668 }
rlm@1 669 {
rlm@1 670 unsigned i = 1;
rlm@1 671 do
rlm@1 672 {
rlm@1 673 GET_BIT_CHECK(prob + i, i);
rlm@1 674 }
rlm@1 675 while (--numDirectBits != 0);
rlm@1 676 }
rlm@1 677 }
rlm@1 678 }
rlm@1 679 }
rlm@1 680 }
rlm@1 681 NORMALIZE_CHECK;
rlm@1 682 return res;
rlm@1 683 }
rlm@1 684
rlm@1 685
rlm@1 686 static void LzmaDec_InitRc(CLzmaDec *p, const Byte *data)
rlm@1 687 {
rlm@1 688 p->code = ((UInt32)data[1] << 24) | ((UInt32)data[2] << 16) | ((UInt32)data[3] << 8) | ((UInt32)data[4]);
rlm@1 689 p->range = 0xFFFFFFFF;
rlm@1 690 p->needFlush = 0;
rlm@1 691 }
rlm@1 692
rlm@1 693 void LzmaDec_InitDicAndState(CLzmaDec *p, Bool initDic, Bool initState)
rlm@1 694 {
rlm@1 695 p->needFlush = 1;
rlm@1 696 p->remainLen = 0;
rlm@1 697 p->tempBufSize = 0;
rlm@1 698
rlm@1 699 if (initDic)
rlm@1 700 {
rlm@1 701 p->processedPos = 0;
rlm@1 702 p->checkDicSize = 0;
rlm@1 703 p->needInitState = 1;
rlm@1 704 }
rlm@1 705 if (initState)
rlm@1 706 p->needInitState = 1;
rlm@1 707 }
rlm@1 708
rlm@1 709 void LzmaDec_Init(CLzmaDec *p)
rlm@1 710 {
rlm@1 711 p->dicPos = 0;
rlm@1 712 LzmaDec_InitDicAndState(p, True, True);
rlm@1 713 }
rlm@1 714
rlm@1 715 static void LzmaDec_InitStateReal(CLzmaDec *p)
rlm@1 716 {
rlm@1 717 UInt32 numProbs = Literal + ((UInt32)LZMA_LIT_SIZE << (p->prop.lc + p->prop.lp));
rlm@1 718 UInt32 i;
rlm@1 719 CLzmaProb *probs = p->probs;
rlm@1 720 for (i = 0; i < numProbs; i++)
rlm@1 721 probs[i] = kBitModelTotal >> 1;
rlm@1 722 p->reps[0] = p->reps[1] = p->reps[2] = p->reps[3] = 1;
rlm@1 723 p->state = 0;
rlm@1 724 p->needInitState = 0;
rlm@1 725 }
rlm@1 726
rlm@1 727 SRes LzmaDec_DecodeToDic(CLzmaDec *p, SizeT dicLimit, const Byte *src, SizeT *srcLen,
rlm@1 728 ELzmaFinishMode finishMode, ELzmaStatus *status)
rlm@1 729 {
rlm@1 730 SizeT inSize = *srcLen;
rlm@1 731 (*srcLen) = 0;
rlm@1 732 LzmaDec_WriteRem(p, dicLimit);
rlm@1 733
rlm@1 734 *status = LZMA_STATUS_NOT_SPECIFIED;
rlm@1 735
rlm@1 736 while (p->remainLen != kMatchSpecLenStart)
rlm@1 737 {
rlm@1 738 int checkEndMarkNow;
rlm@1 739
rlm@1 740 if (p->needFlush != 0)
rlm@1 741 {
rlm@1 742 for (; inSize > 0 && p->tempBufSize < RC_INIT_SIZE; (*srcLen)++, inSize--)
rlm@1 743 p->tempBuf[p->tempBufSize++] = *src++;
rlm@1 744 if (p->tempBufSize < RC_INIT_SIZE)
rlm@1 745 {
rlm@1 746 *status = LZMA_STATUS_NEEDS_MORE_INPUT;
rlm@1 747 return SZ_OK;
rlm@1 748 }
rlm@1 749 if (p->tempBuf[0] != 0)
rlm@1 750 return SZ_ERROR_DATA;
rlm@1 751
rlm@1 752 LzmaDec_InitRc(p, p->tempBuf);
rlm@1 753 p->tempBufSize = 0;
rlm@1 754 }
rlm@1 755
rlm@1 756 checkEndMarkNow = 0;
rlm@1 757 if (p->dicPos >= dicLimit)
rlm@1 758 {
rlm@1 759 if (p->remainLen == 0 && p->code == 0)
rlm@1 760 {
rlm@1 761 *status = LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK;
rlm@1 762 return SZ_OK;
rlm@1 763 }
rlm@1 764 if (finishMode == LZMA_FINISH_ANY)
rlm@1 765 {
rlm@1 766 *status = LZMA_STATUS_NOT_FINISHED;
rlm@1 767 return SZ_OK;
rlm@1 768 }
rlm@1 769 if (p->remainLen != 0)
rlm@1 770 {
rlm@1 771 *status = LZMA_STATUS_NOT_FINISHED;
rlm@1 772 return SZ_ERROR_DATA;
rlm@1 773 }
rlm@1 774 checkEndMarkNow = 1;
rlm@1 775 }
rlm@1 776
rlm@1 777 if (p->needInitState)
rlm@1 778 LzmaDec_InitStateReal(p);
rlm@1 779
rlm@1 780 if (p->tempBufSize == 0)
rlm@1 781 {
rlm@1 782 SizeT processed;
rlm@1 783 const Byte *bufLimit;
rlm@1 784 if (inSize < LZMA_REQUIRED_INPUT_MAX || checkEndMarkNow)
rlm@1 785 {
rlm@1 786 int dummyRes = LzmaDec_TryDummy(p, src, inSize);
rlm@1 787 if (dummyRes == DUMMY_ERROR)
rlm@1 788 {
rlm@1 789 memcpy(p->tempBuf, src, inSize);
rlm@1 790 p->tempBufSize = (unsigned)inSize;
rlm@1 791 (*srcLen) += inSize;
rlm@1 792 *status = LZMA_STATUS_NEEDS_MORE_INPUT;
rlm@1 793 return SZ_OK;
rlm@1 794 }
rlm@1 795 if (checkEndMarkNow && dummyRes != DUMMY_MATCH)
rlm@1 796 {
rlm@1 797 *status = LZMA_STATUS_NOT_FINISHED;
rlm@1 798 return SZ_ERROR_DATA;
rlm@1 799 }
rlm@1 800 bufLimit = src;
rlm@1 801 }
rlm@1 802 else
rlm@1 803 bufLimit = src + inSize - LZMA_REQUIRED_INPUT_MAX;
rlm@1 804 p->buf = src;
rlm@1 805 if (LzmaDec_DecodeReal2(p, dicLimit, bufLimit) != 0)
rlm@1 806 return SZ_ERROR_DATA;
rlm@1 807 processed = (SizeT)(p->buf - src);
rlm@1 808 (*srcLen) += processed;
rlm@1 809 src += processed;
rlm@1 810 inSize -= processed;
rlm@1 811 }
rlm@1 812 else
rlm@1 813 {
rlm@1 814 unsigned rem = p->tempBufSize, lookAhead = 0;
rlm@1 815 while (rem < LZMA_REQUIRED_INPUT_MAX && lookAhead < inSize)
rlm@1 816 p->tempBuf[rem++] = src[lookAhead++];
rlm@1 817 p->tempBufSize = rem;
rlm@1 818 if (rem < LZMA_REQUIRED_INPUT_MAX || checkEndMarkNow)
rlm@1 819 {
rlm@1 820 int dummyRes = LzmaDec_TryDummy(p, p->tempBuf, rem);
rlm@1 821 if (dummyRes == DUMMY_ERROR)
rlm@1 822 {
rlm@1 823 (*srcLen) += lookAhead;
rlm@1 824 *status = LZMA_STATUS_NEEDS_MORE_INPUT;
rlm@1 825 return SZ_OK;
rlm@1 826 }
rlm@1 827 if (checkEndMarkNow && dummyRes != DUMMY_MATCH)
rlm@1 828 {
rlm@1 829 *status = LZMA_STATUS_NOT_FINISHED;
rlm@1 830 return SZ_ERROR_DATA;
rlm@1 831 }
rlm@1 832 }
rlm@1 833 p->buf = p->tempBuf;
rlm@1 834 if (LzmaDec_DecodeReal2(p, dicLimit, p->buf) != 0)
rlm@1 835 return SZ_ERROR_DATA;
rlm@1 836 lookAhead -= (rem - (unsigned)(p->buf - p->tempBuf));
rlm@1 837 (*srcLen) += lookAhead;
rlm@1 838 src += lookAhead;
rlm@1 839 inSize -= lookAhead;
rlm@1 840 p->tempBufSize = 0;
rlm@1 841 }
rlm@1 842 }
rlm@1 843 if (p->code == 0)
rlm@1 844 *status = LZMA_STATUS_FINISHED_WITH_MARK;
rlm@1 845 return (p->code == 0) ? SZ_OK : SZ_ERROR_DATA;
rlm@1 846 }
rlm@1 847
rlm@1 848 SRes LzmaDec_DecodeToBuf(CLzmaDec *p, Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen, ELzmaFinishMode finishMode, ELzmaStatus *status)
rlm@1 849 {
rlm@1 850 SizeT outSize = *destLen;
rlm@1 851 SizeT inSize = *srcLen;
rlm@1 852 *srcLen = *destLen = 0;
rlm@1 853 for (;;)
rlm@1 854 {
rlm@1 855 SizeT inSizeCur = inSize, outSizeCur, dicPos;
rlm@1 856 ELzmaFinishMode curFinishMode;
rlm@1 857 SRes res;
rlm@1 858 if (p->dicPos == p->dicBufSize)
rlm@1 859 p->dicPos = 0;
rlm@1 860 dicPos = p->dicPos;
rlm@1 861 if (outSize > p->dicBufSize - dicPos)
rlm@1 862 {
rlm@1 863 outSizeCur = p->dicBufSize;
rlm@1 864 curFinishMode = LZMA_FINISH_ANY;
rlm@1 865 }
rlm@1 866 else
rlm@1 867 {
rlm@1 868 outSizeCur = dicPos + outSize;
rlm@1 869 curFinishMode = finishMode;
rlm@1 870 }
rlm@1 871
rlm@1 872 res = LzmaDec_DecodeToDic(p, outSizeCur, src, &inSizeCur, curFinishMode, status);
rlm@1 873 src += inSizeCur;
rlm@1 874 inSize -= inSizeCur;
rlm@1 875 *srcLen += inSizeCur;
rlm@1 876 outSizeCur = p->dicPos - dicPos;
rlm@1 877 memcpy(dest, p->dic + dicPos, outSizeCur);
rlm@1 878 dest += outSizeCur;
rlm@1 879 outSize -= outSizeCur;
rlm@1 880 *destLen += outSizeCur;
rlm@1 881 if (res != 0)
rlm@1 882 return res;
rlm@1 883 if (outSizeCur == 0 || outSize == 0)
rlm@1 884 return SZ_OK;
rlm@1 885 }
rlm@1 886 }
rlm@1 887
rlm@1 888 void LzmaDec_FreeProbs(CLzmaDec *p, ISzAlloc *alloc)
rlm@1 889 {
rlm@1 890 alloc->Free(alloc, p->probs);
rlm@1 891 p->probs = 0;
rlm@1 892 }
rlm@1 893
rlm@1 894 static void LzmaDec_FreeDict(CLzmaDec *p, ISzAlloc *alloc)
rlm@1 895 {
rlm@1 896 alloc->Free(alloc, p->dic);
rlm@1 897 p->dic = 0;
rlm@1 898 }
rlm@1 899
rlm@1 900 void LzmaDec_Free(CLzmaDec *p, ISzAlloc *alloc)
rlm@1 901 {
rlm@1 902 LzmaDec_FreeProbs(p, alloc);
rlm@1 903 LzmaDec_FreeDict(p, alloc);
rlm@1 904 }
rlm@1 905
rlm@1 906 SRes LzmaProps_Decode(CLzmaProps *p, const Byte *data, unsigned size)
rlm@1 907 {
rlm@1 908 UInt32 dicSize;
rlm@1 909 Byte d;
rlm@1 910
rlm@1 911 if (size < LZMA_PROPS_SIZE)
rlm@1 912 return SZ_ERROR_UNSUPPORTED;
rlm@1 913 else
rlm@1 914 dicSize = data[1] | ((UInt32)data[2] << 8) | ((UInt32)data[3] << 16) | ((UInt32)data[4] << 24);
rlm@1 915
rlm@1 916 if (dicSize < LZMA_DIC_MIN)
rlm@1 917 dicSize = LZMA_DIC_MIN;
rlm@1 918 p->dicSize = dicSize;
rlm@1 919
rlm@1 920 d = data[0];
rlm@1 921 if (d >= (9 * 5 * 5))
rlm@1 922 return SZ_ERROR_UNSUPPORTED;
rlm@1 923
rlm@1 924 p->lc = d % 9;
rlm@1 925 d /= 9;
rlm@1 926 p->pb = d / 5;
rlm@1 927 p->lp = d % 5;
rlm@1 928
rlm@1 929 return SZ_OK;
rlm@1 930 }
rlm@1 931
rlm@1 932 static SRes LzmaDec_AllocateProbs2(CLzmaDec *p, const CLzmaProps *propNew, ISzAlloc *alloc)
rlm@1 933 {
rlm@1 934 UInt32 numProbs = LzmaProps_GetNumProbs(propNew);
rlm@1 935 if (p->probs == 0 || numProbs != p->numProbs)
rlm@1 936 {
rlm@1 937 LzmaDec_FreeProbs(p, alloc);
rlm@1 938 p->probs = (CLzmaProb *)alloc->Alloc(alloc, numProbs * sizeof(CLzmaProb));
rlm@1 939 p->numProbs = numProbs;
rlm@1 940 if (p->probs == 0)
rlm@1 941 return SZ_ERROR_MEM;
rlm@1 942 }
rlm@1 943 return SZ_OK;
rlm@1 944 }
rlm@1 945
rlm@1 946 SRes LzmaDec_AllocateProbs(CLzmaDec *p, const Byte *props, unsigned propsSize, ISzAlloc *alloc)
rlm@1 947 {
rlm@1 948 CLzmaProps propNew;
rlm@1 949 RINOK(LzmaProps_Decode(&propNew, props, propsSize));
rlm@1 950 RINOK(LzmaDec_AllocateProbs2(p, &propNew, alloc));
rlm@1 951 p->prop = propNew;
rlm@1 952 return SZ_OK;
rlm@1 953 }
rlm@1 954
rlm@1 955 SRes LzmaDec_Allocate(CLzmaDec *p, const Byte *props, unsigned propsSize, ISzAlloc *alloc)
rlm@1 956 {
rlm@1 957 CLzmaProps propNew;
rlm@1 958 SizeT dicBufSize;
rlm@1 959 RINOK(LzmaProps_Decode(&propNew, props, propsSize));
rlm@1 960 RINOK(LzmaDec_AllocateProbs2(p, &propNew, alloc));
rlm@1 961 dicBufSize = propNew.dicSize;
rlm@1 962 if (p->dic == 0 || dicBufSize != p->dicBufSize)
rlm@1 963 {
rlm@1 964 LzmaDec_FreeDict(p, alloc);
rlm@1 965 p->dic = (Byte *)alloc->Alloc(alloc, dicBufSize);
rlm@1 966 if (p->dic == 0)
rlm@1 967 {
rlm@1 968 LzmaDec_FreeProbs(p, alloc);
rlm@1 969 return SZ_ERROR_MEM;
rlm@1 970 }
rlm@1 971 }
rlm@1 972 p->dicBufSize = dicBufSize;
rlm@1 973 p->prop = propNew;
rlm@1 974 return SZ_OK;
rlm@1 975 }
rlm@1 976
rlm@1 977 SRes LzmaDecode(Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen,
rlm@1 978 const Byte *propData, unsigned propSize, ELzmaFinishMode finishMode,
rlm@1 979 ELzmaStatus *status, ISzAlloc *alloc)
rlm@1 980 {
rlm@1 981 CLzmaDec p;
rlm@1 982 SRes res;
rlm@1 983 SizeT inSize = *srcLen;
rlm@1 984 SizeT outSize = *destLen;
rlm@1 985 *srcLen = *destLen = 0;
rlm@1 986 if (inSize < RC_INIT_SIZE)
rlm@1 987 return SZ_ERROR_INPUT_EOF;
rlm@1 988
rlm@1 989 LzmaDec_Construct(&p);
rlm@1 990 res = LzmaDec_AllocateProbs(&p, propData, propSize, alloc);
rlm@1 991 if (res != 0)
rlm@1 992 return res;
rlm@1 993 p.dic = dest;
rlm@1 994 p.dicBufSize = outSize;
rlm@1 995
rlm@1 996 LzmaDec_Init(&p);
rlm@1 997
rlm@1 998 *srcLen = inSize;
rlm@1 999 res = LzmaDec_DecodeToDic(&p, outSize, src, srcLen, finishMode, status);
rlm@1 1000
rlm@1 1001 if (res == SZ_OK && *status == LZMA_STATUS_NEEDS_MORE_INPUT)
rlm@1 1002 res = SZ_ERROR_INPUT_EOF;
rlm@1 1003
rlm@1 1004 (*destLen) = p.dicPos;
rlm@1 1005 LzmaDec_FreeProbs(&p, alloc);
rlm@1 1006 return res;
rlm@1 1007 }