1 /* Lzma2Dec.c -- LZMA2 Decoder 2 2015-11-09 : 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 - EOS 18 00000001 U U - Uncompressed Reset Dic 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 + new prop 23 111uuuuu U U P P S - LZMA reset state + new prop + reset dic 24 25 u, U - Unpack Size 26 P - Pack Size 27 S - Props 28 */ 29 30 #define LZMA2_CONTROL_LZMA (1 << 7) 31 #define LZMA2_CONTROL_COPY_NO_RESET 2 32 #define LZMA2_CONTROL_COPY_RESET_DIC 1 33 #define LZMA2_CONTROL_EOF 0 34 35 #define LZMA2_IS_UNCOMPRESSED_STATE(p) (((p)->control & LZMA2_CONTROL_LZMA) == 0) 36 37 #define LZMA2_GET_LZMA_MODE(p) (((p)->control >> 5) & 3) 38 #define LZMA2_IS_THERE_PROP(mode) ((mode) >= 2) 39 40 #define LZMA2_LCLP_MAX 4 41 #define LZMA2_DIC_SIZE_FROM_PROP(p) (((UInt32)2 | ((p) & 1)) << ((p) / 2 + 11)) 42 43 #ifdef SHOW_DEBUG_INFO 44 #define PRF(x) x 45 #else 46 #define PRF(x) 47 #endif 48 49 typedef enum 50 { 51 LZMA2_STATE_CONTROL, 52 LZMA2_STATE_UNPACK0, 53 LZMA2_STATE_UNPACK1, 54 LZMA2_STATE_PACK0, 55 LZMA2_STATE_PACK1, 56 LZMA2_STATE_PROP, 57 LZMA2_STATE_DATA, 58 LZMA2_STATE_DATA_CONT, 59 LZMA2_STATE_FINISHED, 60 LZMA2_STATE_ERROR 61 } ELzma2State; 62 63 static SRes Lzma2Dec_GetOldProps(Byte prop, Byte *props) 64 { 65 UInt32 dicSize; 66 if (prop > 40) 67 return SZ_ERROR_UNSUPPORTED; 68 dicSize = (prop == 40) ? 0xFFFFFFFF : LZMA2_DIC_SIZE_FROM_PROP(prop); 69 props[0] = (Byte)LZMA2_LCLP_MAX; 70 props[1] = (Byte)(dicSize); 71 props[2] = (Byte)(dicSize >> 8); 72 props[3] = (Byte)(dicSize >> 16); 73 props[4] = (Byte)(dicSize >> 24); 74 return SZ_OK; 75 } 76 77 SRes Lzma2Dec_AllocateProbs(CLzma2Dec *p, Byte prop, ISzAlloc *alloc) 78 { 79 Byte props[LZMA_PROPS_SIZE]; 80 RINOK(Lzma2Dec_GetOldProps(prop, props)); 81 return LzmaDec_AllocateProbs(&p->decoder, props, LZMA_PROPS_SIZE, alloc); 82 } 83 84 SRes Lzma2Dec_Allocate(CLzma2Dec *p, Byte prop, ISzAlloc *alloc) 85 { 86 Byte props[LZMA_PROPS_SIZE]; 87 RINOK(Lzma2Dec_GetOldProps(prop, props)); 88 return LzmaDec_Allocate(&p->decoder, props, LZMA_PROPS_SIZE, alloc); 89 } 90 91 void Lzma2Dec_Init(CLzma2Dec *p) 92 { 93 p->state = LZMA2_STATE_CONTROL; 94 p->needInitDic = True; 95 p->needInitState = True; 96 p->needInitProp = True; 97 LzmaDec_Init(&p->decoder); 98 } 99 100 static ELzma2State Lzma2Dec_UpdateState(CLzma2Dec *p, Byte b) 101 { 102 switch (p->state) 103 { 104 case LZMA2_STATE_CONTROL: 105 p->control = b; 106 PRF(printf("\n %4X ", (unsigned)p->decoder.dicPos)); 107 PRF(printf(" %2X", (unsigned)b)); 108 if (p->control == 0) 109 return LZMA2_STATE_FINISHED; 110 if (LZMA2_IS_UNCOMPRESSED_STATE(p)) 111 { 112 if ((p->control & 0x7F) > 2) 113 return LZMA2_STATE_ERROR; 114 p->unpackSize = 0; 115 } 116 else 117 p->unpackSize = (UInt32)(p->control & 0x1F) << 16; 118 return LZMA2_STATE_UNPACK0; 119 120 case LZMA2_STATE_UNPACK0: 121 p->unpackSize |= (UInt32)b << 8; 122 return LZMA2_STATE_UNPACK1; 123 124 case LZMA2_STATE_UNPACK1: 125 p->unpackSize |= (UInt32)b; 126 p->unpackSize++; 127 PRF(printf(" %8u", (unsigned)p->unpackSize)); 128 return (LZMA2_IS_UNCOMPRESSED_STATE(p)) ? LZMA2_STATE_DATA : LZMA2_STATE_PACK0; 129 130 case LZMA2_STATE_PACK0: 131 p->packSize = (UInt32)b << 8; 132 return LZMA2_STATE_PACK1; 133 134 case LZMA2_STATE_PACK1: 135 p->packSize |= (UInt32)b; 136 p->packSize++; 137 PRF(printf(" %8u", (unsigned)p->packSize)); 138 return LZMA2_IS_THERE_PROP(LZMA2_GET_LZMA_MODE(p)) ? LZMA2_STATE_PROP: 139 (p->needInitProp ? LZMA2_STATE_ERROR : LZMA2_STATE_DATA); 140 141 case LZMA2_STATE_PROP: 142 { 143 unsigned lc, lp; 144 if (b >= (9 * 5 * 5)) 145 return LZMA2_STATE_ERROR; 146 lc = b % 9; 147 b /= 9; 148 p->decoder.prop.pb = b / 5; 149 lp = b % 5; 150 if (lc + lp > LZMA2_LCLP_MAX) 151 return LZMA2_STATE_ERROR; 152 p->decoder.prop.lc = lc; 153 p->decoder.prop.lp = lp; 154 p->needInitProp = False; 155 return LZMA2_STATE_DATA; 156 } 157 } 158 return LZMA2_STATE_ERROR; 159 } 160 161 static void LzmaDec_UpdateWithUncompressed(CLzmaDec *p, const Byte *src, SizeT size) 162 { 163 memcpy(p->dic + p->dicPos, src, size); 164 p->dicPos += size; 165 if (p->checkDicSize == 0 && p->prop.dicSize - p->processedPos <= size) 166 p->checkDicSize = p->prop.dicSize; 167 p->processedPos += (UInt32)size; 168 } 169 170 void LzmaDec_InitDicAndState(CLzmaDec *p, Bool initDic, Bool initState); 171 172 SRes Lzma2Dec_DecodeToDic(CLzma2Dec *p, SizeT dicLimit, 173 const Byte *src, SizeT *srcLen, ELzmaFinishMode finishMode, ELzmaStatus *status) 174 { 175 SizeT inSize = *srcLen; 176 *srcLen = 0; 177 *status = LZMA_STATUS_NOT_SPECIFIED; 178 179 while (p->state != LZMA2_STATE_FINISHED) 180 { 181 SizeT dicPos = p->decoder.dicPos; 182 183 if (p->state == LZMA2_STATE_ERROR) 184 return SZ_ERROR_DATA; 185 186 if (dicPos == dicLimit && finishMode == LZMA_FINISH_ANY) 187 { 188 *status = LZMA_STATUS_NOT_FINISHED; 189 return SZ_OK; 190 } 191 192 if (p->state != LZMA2_STATE_DATA && p->state != LZMA2_STATE_DATA_CONT) 193 { 194 if (*srcLen == inSize) 195 { 196 *status = LZMA_STATUS_NEEDS_MORE_INPUT; 197 return SZ_OK; 198 } 199 (*srcLen)++; 200 p->state = Lzma2Dec_UpdateState(p, *src++); 201 202 if (dicPos == dicLimit && p->state != LZMA2_STATE_FINISHED) 203 { 204 p->state = LZMA2_STATE_ERROR; 205 return SZ_ERROR_DATA; 206 } 207 continue; 208 } 209 210 { 211 SizeT destSizeCur = dicLimit - dicPos; 212 SizeT srcSizeCur = inSize - *srcLen; 213 ELzmaFinishMode curFinishMode = LZMA_FINISH_ANY; 214 215 if (p->unpackSize <= destSizeCur) 216 { 217 destSizeCur = (SizeT)p->unpackSize; 218 curFinishMode = LZMA_FINISH_END; 219 } 220 221 if (LZMA2_IS_UNCOMPRESSED_STATE(p)) 222 { 223 if (*srcLen == inSize) 224 { 225 *status = LZMA_STATUS_NEEDS_MORE_INPUT; 226 return SZ_OK; 227 } 228 229 if (p->state == LZMA2_STATE_DATA) 230 { 231 Bool initDic = (p->control == LZMA2_CONTROL_COPY_RESET_DIC); 232 if (initDic) 233 p->needInitProp = p->needInitState = True; 234 else if (p->needInitDic) 235 { 236 p->state = LZMA2_STATE_ERROR; 237 return SZ_ERROR_DATA; 238 } 239 p->needInitDic = False; 240 LzmaDec_InitDicAndState(&p->decoder, initDic, False); 241 } 242 243 if (srcSizeCur > destSizeCur) 244 srcSizeCur = destSizeCur; 245 246 if (srcSizeCur == 0) 247 { 248 p->state = LZMA2_STATE_ERROR; 249 return SZ_ERROR_DATA; 250 } 251 252 LzmaDec_UpdateWithUncompressed(&p->decoder, src, srcSizeCur); 253 254 src += srcSizeCur; 255 *srcLen += srcSizeCur; 256 p->unpackSize -= (UInt32)srcSizeCur; 257 p->state = (p->unpackSize == 0) ? LZMA2_STATE_CONTROL : LZMA2_STATE_DATA_CONT; 258 } 259 else 260 { 261 SizeT outSizeProcessed; 262 SRes res; 263 264 if (p->state == LZMA2_STATE_DATA) 265 { 266 unsigned mode = LZMA2_GET_LZMA_MODE(p); 267 Bool initDic = (mode == 3); 268 Bool initState = (mode != 0); 269 if ((!initDic && p->needInitDic) || (!initState && p->needInitState)) 270 { 271 p->state = LZMA2_STATE_ERROR; 272 return SZ_ERROR_DATA; 273 } 274 275 LzmaDec_InitDicAndState(&p->decoder, initDic, initState); 276 p->needInitDic = False; 277 p->needInitState = False; 278 p->state = LZMA2_STATE_DATA_CONT; 279 } 280 281 if (srcSizeCur > p->packSize) 282 srcSizeCur = (SizeT)p->packSize; 283 284 res = LzmaDec_DecodeToDic(&p->decoder, dicPos + destSizeCur, src, &srcSizeCur, curFinishMode, status); 285 286 src += srcSizeCur; 287 *srcLen += srcSizeCur; 288 p->packSize -= (UInt32)srcSizeCur; 289 290 outSizeProcessed = p->decoder.dicPos - dicPos; 291 p->unpackSize -= (UInt32)outSizeProcessed; 292 293 RINOK(res); 294 if (*status == LZMA_STATUS_NEEDS_MORE_INPUT) 295 return res; 296 297 if (srcSizeCur == 0 && outSizeProcessed == 0) 298 { 299 if (*status != LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK 300 || p->unpackSize != 0 301 || p->packSize != 0) 302 { 303 p->state = LZMA2_STATE_ERROR; 304 return SZ_ERROR_DATA; 305 } 306 p->state = LZMA2_STATE_CONTROL; 307 } 308 309 if (*status == LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK) 310 *status = LZMA_STATUS_NOT_FINISHED; 311 } 312 } 313 } 314 315 *status = LZMA_STATUS_FINISHED_WITH_MARK; 316 return SZ_OK; 317 } 318 319 SRes Lzma2Dec_DecodeToBuf(CLzma2Dec *p, Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen, ELzmaFinishMode finishMode, ELzmaStatus *status) 320 { 321 SizeT outSize = *destLen, inSize = *srcLen; 322 *srcLen = *destLen = 0; 323 for (;;) 324 { 325 SizeT srcSizeCur = inSize, outSizeCur, dicPos; 326 ELzmaFinishMode curFinishMode; 327 SRes res; 328 if (p->decoder.dicPos == p->decoder.dicBufSize) 329 p->decoder.dicPos = 0; 330 dicPos = p->decoder.dicPos; 331 if (outSize > p->decoder.dicBufSize - dicPos) 332 { 333 outSizeCur = p->decoder.dicBufSize; 334 curFinishMode = LZMA_FINISH_ANY; 335 } 336 else 337 { 338 outSizeCur = dicPos + outSize; 339 curFinishMode = finishMode; 340 } 341 342 res = Lzma2Dec_DecodeToDic(p, outSizeCur, src, &srcSizeCur, curFinishMode, status); 343 src += srcSizeCur; 344 inSize -= srcSizeCur; 345 *srcLen += srcSizeCur; 346 outSizeCur = p->decoder.dicPos - dicPos; 347 memcpy(dest, p->decoder.dic + dicPos, outSizeCur); 348 dest += outSizeCur; 349 outSize -= outSizeCur; 350 *destLen += outSizeCur; 351 if (res != 0) 352 return res; 353 if (outSizeCur == 0 || outSize == 0) 354 return SZ_OK; 355 } 356 } 357 358 SRes Lzma2Decode(Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen, 359 Byte prop, ELzmaFinishMode finishMode, ELzmaStatus *status, ISzAlloc *alloc) 360 { 361 CLzma2Dec p; 362 SRes res; 363 SizeT outSize = *destLen, inSize = *srcLen; 364 *destLen = *srcLen = 0; 365 *status = LZMA_STATUS_NOT_SPECIFIED; 366 Lzma2Dec_Construct(&p); 367 RINOK(Lzma2Dec_AllocateProbs(&p, prop, alloc)); 368 p.decoder.dic = dest; 369 p.decoder.dicBufSize = outSize; 370 Lzma2Dec_Init(&p); 371 *srcLen = inSize; 372 res = Lzma2Dec_DecodeToDic(&p, outSize, src, srcLen, finishMode, status); 373 *destLen = p.decoder.dicPos; 374 if (res == SZ_OK && *status == LZMA_STATUS_NEEDS_MORE_INPUT) 375 res = SZ_ERROR_INPUT_EOF; 376 Lzma2Dec_FreeProbs(&p, alloc); 377 return res; 378 } 379