1 /* Lzma2Dec.c -- LZMA2 Decoder 2 2018-07-04 : Igor Pavlov : Public domain */ 3 4 /* #define SHOW_DEBUG_INFO */ 5 6 #include "Precomp.h" 7 8 #ifdef SHOW_DEBUG_INFO 9 #include <stdio.h> 10 #endif 11 12 #include <string.h> 13 14 #include "Lzma2Dec.h" 15 16 /* 17 00000000 - End of data 18 00000001 U U - Uncompressed, reset dic, need reset state and set new prop 19 00000010 U U - Uncompressed, no reset 20 100uuuuu U U P P - LZMA, no reset 21 101uuuuu U U P P - LZMA, reset state 22 110uuuuu U U P P S - LZMA, reset state + set new prop 23 111uuuuu U U P P S - LZMA, reset state + set new prop, reset dic 24 25 u, U - Unpack Size 26 P - Pack Size 27 S - Props 28 */ 29 30 #define LZMA2_CONTROL_COPY_RESET_DIC 1 31 32 #define LZMA2_IS_UNCOMPRESSED_STATE(p) (((p)->control & (1 << 7)) == 0) 33 34 #define LZMA2_LCLP_MAX 4 35 #define LZMA2_DIC_SIZE_FROM_PROP(p) (((UInt32)2 | ((p) & 1)) << ((p) / 2 + 11)) 36 37 #ifdef SHOW_DEBUG_INFO 38 #define PRF(x) x 39 #else 40 #define PRF(x) 41 #endif 42 43 typedef enum 44 { 45 LZMA2_STATE_CONTROL, 46 LZMA2_STATE_UNPACK0, 47 LZMA2_STATE_UNPACK1, 48 LZMA2_STATE_PACK0, 49 LZMA2_STATE_PACK1, 50 LZMA2_STATE_PROP, 51 LZMA2_STATE_DATA, 52 LZMA2_STATE_DATA_CONT, 53 LZMA2_STATE_FINISHED, 54 LZMA2_STATE_ERROR 55 } ELzma2State; 56 57 static SRes Lzma2Dec_GetOldProps(Byte prop, Byte *props) 58 { 59 UInt32 dicSize; 60 if (prop > 40) 61 return SZ_ERROR_UNSUPPORTED; 62 dicSize = (prop == 40) ? 0xFFFFFFFF : LZMA2_DIC_SIZE_FROM_PROP(prop); 63 props[0] = (Byte)LZMA2_LCLP_MAX; 64 props[1] = (Byte)(dicSize); 65 props[2] = (Byte)(dicSize >> 8); 66 props[3] = (Byte)(dicSize >> 16); 67 props[4] = (Byte)(dicSize >> 24); 68 return SZ_OK; 69 } 70 71 SRes Lzma2Dec_AllocateProbs(CLzma2Dec *p, Byte prop, ISzAllocPtr alloc) 72 { 73 Byte props[LZMA_PROPS_SIZE]; 74 RINOK(Lzma2Dec_GetOldProps(prop, props)); 75 return LzmaDec_AllocateProbs(&p->decoder, props, LZMA_PROPS_SIZE, alloc); 76 } 77 78 SRes Lzma2Dec_Allocate(CLzma2Dec *p, Byte prop, ISzAllocPtr alloc) 79 { 80 Byte props[LZMA_PROPS_SIZE]; 81 RINOK(Lzma2Dec_GetOldProps(prop, props)); 82 return LzmaDec_Allocate(&p->decoder, props, LZMA_PROPS_SIZE, alloc); 83 } 84 85 void Lzma2Dec_Init(CLzma2Dec *p) 86 { 87 p->state = LZMA2_STATE_CONTROL; 88 p->needInitLevel = 0xE0; 89 p->isExtraMode = False; 90 p->unpackSize = 0; 91 92 // p->decoder.dicPos = 0; // we can use it instead of full init 93 LzmaDec_Init(&p->decoder); 94 } 95 96 static ELzma2State Lzma2Dec_UpdateState(CLzma2Dec *p, Byte b) 97 { 98 switch (p->state) 99 { 100 case LZMA2_STATE_CONTROL: 101 p->isExtraMode = False; 102 p->control = b; 103 PRF(printf("\n %8X", (unsigned)p->decoder.dicPos)); 104 PRF(printf(" %02X", (unsigned)b)); 105 if (b == 0) 106 return LZMA2_STATE_FINISHED; 107 if (LZMA2_IS_UNCOMPRESSED_STATE(p)) 108 { 109 if (b == LZMA2_CONTROL_COPY_RESET_DIC) 110 p->needInitLevel = 0xC0; 111 else if (b > 2 || p->needInitLevel == 0xE0) 112 return LZMA2_STATE_ERROR; 113 } 114 else 115 { 116 if (b < p->needInitLevel) 117 return LZMA2_STATE_ERROR; 118 p->needInitLevel = 0; 119 p->unpackSize = (UInt32)(b & 0x1F) << 16; 120 } 121 return LZMA2_STATE_UNPACK0; 122 123 case LZMA2_STATE_UNPACK0: 124 p->unpackSize |= (UInt32)b << 8; 125 return LZMA2_STATE_UNPACK1; 126 127 case LZMA2_STATE_UNPACK1: 128 p->unpackSize |= (UInt32)b; 129 p->unpackSize++; 130 PRF(printf(" %7u", (unsigned)p->unpackSize)); 131 return LZMA2_IS_UNCOMPRESSED_STATE(p) ? LZMA2_STATE_DATA : LZMA2_STATE_PACK0; 132 133 case LZMA2_STATE_PACK0: 134 p->packSize = (UInt32)b << 8; 135 return LZMA2_STATE_PACK1; 136 137 case LZMA2_STATE_PACK1: 138 p->packSize |= (UInt32)b; 139 p->packSize++; 140 // if (p->packSize < 5) return LZMA2_STATE_ERROR; 141 PRF(printf(" %5u", (unsigned)p->packSize)); 142 return (p->control & 0x40) ? LZMA2_STATE_PROP : LZMA2_STATE_DATA; 143 144 case LZMA2_STATE_PROP: 145 { 146 unsigned lc, lp; 147 if (b >= (9 * 5 * 5)) 148 return LZMA2_STATE_ERROR; 149 lc = b % 9; 150 b /= 9; 151 p->decoder.prop.pb = (Byte)(b / 5); 152 lp = b % 5; 153 if (lc + lp > LZMA2_LCLP_MAX) 154 return LZMA2_STATE_ERROR; 155 p->decoder.prop.lc = (Byte)lc; 156 p->decoder.prop.lp = (Byte)lp; 157 return LZMA2_STATE_DATA; 158 } 159 } 160 return LZMA2_STATE_ERROR; 161 } 162 163 static void LzmaDec_UpdateWithUncompressed(CLzmaDec *p, const Byte *src, SizeT size) 164 { 165 memcpy(p->dic + p->dicPos, src, size); 166 p->dicPos += size; 167 if (p->checkDicSize == 0 && p->prop.dicSize - p->processedPos <= size) 168 p->checkDicSize = p->prop.dicSize; 169 p->processedPos += (UInt32)size; 170 } 171 172 void LzmaDec_InitDicAndState(CLzmaDec *p, BoolInt initDic, BoolInt initState); 173 174 175 SRes Lzma2Dec_DecodeToDic(CLzma2Dec *p, SizeT dicLimit, 176 const Byte *src, SizeT *srcLen, ELzmaFinishMode finishMode, ELzmaStatus *status) 177 { 178 SizeT inSize = *srcLen; 179 *srcLen = 0; 180 *status = LZMA_STATUS_NOT_SPECIFIED; 181 182 while (p->state != LZMA2_STATE_ERROR) 183 { 184 SizeT dicPos; 185 186 if (p->state == LZMA2_STATE_FINISHED) 187 { 188 *status = LZMA_STATUS_FINISHED_WITH_MARK; 189 return SZ_OK; 190 } 191 192 dicPos = p->decoder.dicPos; 193 194 if (dicPos == dicLimit && finishMode == LZMA_FINISH_ANY) 195 { 196 *status = LZMA_STATUS_NOT_FINISHED; 197 return SZ_OK; 198 } 199 200 if (p->state != LZMA2_STATE_DATA && p->state != LZMA2_STATE_DATA_CONT) 201 { 202 if (*srcLen == inSize) 203 { 204 *status = LZMA_STATUS_NEEDS_MORE_INPUT; 205 return SZ_OK; 206 } 207 (*srcLen)++; 208 p->state = Lzma2Dec_UpdateState(p, *src++); 209 if (dicPos == dicLimit && p->state != LZMA2_STATE_FINISHED) 210 break; 211 continue; 212 } 213 214 { 215 SizeT inCur = inSize - *srcLen; 216 SizeT outCur = dicLimit - dicPos; 217 ELzmaFinishMode curFinishMode = LZMA_FINISH_ANY; 218 219 if (outCur >= p->unpackSize) 220 { 221 outCur = (SizeT)p->unpackSize; 222 curFinishMode = LZMA_FINISH_END; 223 } 224 225 if (LZMA2_IS_UNCOMPRESSED_STATE(p)) 226 { 227 if (inCur == 0) 228 { 229 *status = LZMA_STATUS_NEEDS_MORE_INPUT; 230 return SZ_OK; 231 } 232 233 if (p->state == LZMA2_STATE_DATA) 234 { 235 BoolInt initDic = (p->control == LZMA2_CONTROL_COPY_RESET_DIC); 236 LzmaDec_InitDicAndState(&p->decoder, initDic, False); 237 } 238 239 if (inCur > outCur) 240 inCur = outCur; 241 if (inCur == 0) 242 break; 243 244 LzmaDec_UpdateWithUncompressed(&p->decoder, src, inCur); 245 246 src += inCur; 247 *srcLen += inCur; 248 p->unpackSize -= (UInt32)inCur; 249 p->state = (p->unpackSize == 0) ? LZMA2_STATE_CONTROL : LZMA2_STATE_DATA_CONT; 250 } 251 else 252 { 253 SRes res; 254 255 if (p->state == LZMA2_STATE_DATA) 256 { 257 BoolInt initDic = (p->control >= 0xE0); 258 BoolInt initState = (p->control >= 0xA0); 259 LzmaDec_InitDicAndState(&p->decoder, initDic, initState); 260 p->state = LZMA2_STATE_DATA_CONT; 261 } 262 263 if (inCur > p->packSize) 264 inCur = (SizeT)p->packSize; 265 266 res = LzmaDec_DecodeToDic(&p->decoder, dicPos + outCur, src, &inCur, curFinishMode, status); 267 268 src += inCur; 269 *srcLen += inCur; 270 p->packSize -= (UInt32)inCur; 271 outCur = p->decoder.dicPos - dicPos; 272 p->unpackSize -= (UInt32)outCur; 273 274 if (res != 0) 275 break; 276 277 if (*status == LZMA_STATUS_NEEDS_MORE_INPUT) 278 { 279 if (p->packSize == 0) 280 break; 281 return SZ_OK; 282 } 283 284 if (inCur == 0 && outCur == 0) 285 { 286 if (*status != LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK 287 || p->unpackSize != 0 288 || p->packSize != 0) 289 break; 290 p->state = LZMA2_STATE_CONTROL; 291 } 292 293 *status = LZMA_STATUS_NOT_SPECIFIED; 294 } 295 } 296 } 297 298 *status = LZMA_STATUS_NOT_SPECIFIED; 299 p->state = LZMA2_STATE_ERROR; 300 return SZ_ERROR_DATA; 301 } 302 303 304 305 306 ELzma2ParseStatus Lzma2Dec_Parse(CLzma2Dec *p, 307 SizeT outSize, 308 const Byte *src, SizeT *srcLen, 309 int checkFinishBlock) 310 { 311 SizeT inSize = *srcLen; 312 *srcLen = 0; 313 314 while (p->state != LZMA2_STATE_ERROR) 315 { 316 if (p->state == LZMA2_STATE_FINISHED) 317 return LZMA_STATUS_FINISHED_WITH_MARK; 318 319 if (outSize == 0 && !checkFinishBlock) 320 return LZMA_STATUS_NOT_FINISHED; 321 322 if (p->state != LZMA2_STATE_DATA && p->state != LZMA2_STATE_DATA_CONT) 323 { 324 if (*srcLen == inSize) 325 return LZMA_STATUS_NEEDS_MORE_INPUT; 326 (*srcLen)++; 327 328 p->state = Lzma2Dec_UpdateState(p, *src++); 329 330 if (p->state == LZMA2_STATE_UNPACK0) 331 { 332 // if (p->decoder.dicPos != 0) 333 if (p->control == LZMA2_CONTROL_COPY_RESET_DIC || p->control >= 0xE0) 334 return LZMA2_PARSE_STATUS_NEW_BLOCK; 335 // if (outSize == 0) return LZMA_STATUS_NOT_FINISHED; 336 } 337 338 // The following code can be commented. 339 // It's not big problem, if we read additional input bytes. 340 // It will be stopped later in LZMA2_STATE_DATA / LZMA2_STATE_DATA_CONT state. 341 342 if (outSize == 0 && p->state != LZMA2_STATE_FINISHED) 343 { 344 // checkFinishBlock is true. So we expect that block must be finished, 345 // We can return LZMA_STATUS_NOT_SPECIFIED or LZMA_STATUS_NOT_FINISHED here 346 // break; 347 return LZMA_STATUS_NOT_FINISHED; 348 } 349 350 if (p->state == LZMA2_STATE_DATA) 351 return LZMA2_PARSE_STATUS_NEW_CHUNK; 352 353 continue; 354 } 355 356 if (outSize == 0) 357 return LZMA_STATUS_NOT_FINISHED; 358 359 { 360 SizeT inCur = inSize - *srcLen; 361 362 if (LZMA2_IS_UNCOMPRESSED_STATE(p)) 363 { 364 if (inCur == 0) 365 return LZMA_STATUS_NEEDS_MORE_INPUT; 366 if (inCur > p->unpackSize) 367 inCur = p->unpackSize; 368 if (inCur > outSize) 369 inCur = outSize; 370 p->decoder.dicPos += inCur; 371 src += inCur; 372 *srcLen += inCur; 373 outSize -= inCur; 374 p->unpackSize -= (UInt32)inCur; 375 p->state = (p->unpackSize == 0) ? LZMA2_STATE_CONTROL : LZMA2_STATE_DATA_CONT; 376 } 377 else 378 { 379 p->isExtraMode = True; 380 381 if (inCur == 0) 382 { 383 if (p->packSize != 0) 384 return LZMA_STATUS_NEEDS_MORE_INPUT; 385 } 386 else if (p->state == LZMA2_STATE_DATA) 387 { 388 p->state = LZMA2_STATE_DATA_CONT; 389 if (*src != 0) 390 { 391 // first byte of lzma chunk must be Zero 392 *srcLen += 1; 393 p->packSize--; 394 break; 395 } 396 } 397 398 if (inCur > p->packSize) 399 inCur = (SizeT)p->packSize; 400 401 src += inCur; 402 *srcLen += inCur; 403 p->packSize -= (UInt32)inCur; 404 405 if (p->packSize == 0) 406 { 407 SizeT rem = outSize; 408 if (rem > p->unpackSize) 409 rem = p->unpackSize; 410 p->decoder.dicPos += rem; 411 p->unpackSize -= (UInt32)rem; 412 outSize -= rem; 413 if (p->unpackSize == 0) 414 p->state = LZMA2_STATE_CONTROL; 415 } 416 } 417 } 418 } 419 420 p->state = LZMA2_STATE_ERROR; 421 return LZMA_STATUS_NOT_SPECIFIED; 422 } 423 424 425 426 427 SRes Lzma2Dec_DecodeToBuf(CLzma2Dec *p, Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen, ELzmaFinishMode finishMode, ELzmaStatus *status) 428 { 429 SizeT outSize = *destLen, inSize = *srcLen; 430 *srcLen = *destLen = 0; 431 432 for (;;) 433 { 434 SizeT inCur = inSize, outCur, dicPos; 435 ELzmaFinishMode curFinishMode; 436 SRes res; 437 438 if (p->decoder.dicPos == p->decoder.dicBufSize) 439 p->decoder.dicPos = 0; 440 dicPos = p->decoder.dicPos; 441 curFinishMode = LZMA_FINISH_ANY; 442 outCur = p->decoder.dicBufSize - dicPos; 443 444 if (outCur >= outSize) 445 { 446 outCur = outSize; 447 curFinishMode = finishMode; 448 } 449 450 res = Lzma2Dec_DecodeToDic(p, dicPos + outCur, src, &inCur, curFinishMode, status); 451 452 src += inCur; 453 inSize -= inCur; 454 *srcLen += inCur; 455 outCur = p->decoder.dicPos - dicPos; 456 memcpy(dest, p->decoder.dic + dicPos, outCur); 457 dest += outCur; 458 outSize -= outCur; 459 *destLen += outCur; 460 if (res != 0) 461 return res; 462 if (outCur == 0 || outSize == 0) 463 return SZ_OK; 464 } 465 } 466 467 468 SRes Lzma2Decode(Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen, 469 Byte prop, ELzmaFinishMode finishMode, ELzmaStatus *status, ISzAllocPtr alloc) 470 { 471 CLzma2Dec p; 472 SRes res; 473 SizeT outSize = *destLen, inSize = *srcLen; 474 *destLen = *srcLen = 0; 475 *status = LZMA_STATUS_NOT_SPECIFIED; 476 Lzma2Dec_Construct(&p); 477 RINOK(Lzma2Dec_AllocateProbs(&p, prop, alloc)); 478 p.decoder.dic = dest; 479 p.decoder.dicBufSize = outSize; 480 Lzma2Dec_Init(&p); 481 *srcLen = inSize; 482 res = Lzma2Dec_DecodeToDic(&p, outSize, src, srcLen, finishMode, status); 483 *destLen = p.decoder.dicPos; 484 if (res == SZ_OK && *status == LZMA_STATUS_NEEDS_MORE_INPUT) 485 res = SZ_ERROR_INPUT_EOF; 486 Lzma2Dec_FreeProbs(&p, alloc); 487 return res; 488 } 489