1 /* Lzma2Dec.c -- LZMA2 Decoder 2 2010-12-15 : 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 ", p->decoder.dicPos)); 107 PRF(printf(" %2X", 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(" %8d", 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(" %8d", 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 int 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 if (p->state == LZMA2_STATE_ERROR) 183 return SZ_ERROR_DATA; 184 if (dicPos == dicLimit && finishMode == LZMA_FINISH_ANY) 185 { 186 *status = LZMA_STATUS_NOT_FINISHED; 187 return SZ_OK; 188 } 189 if (p->state != LZMA2_STATE_DATA && p->state != LZMA2_STATE_DATA_CONT) 190 { 191 if (*srcLen == inSize) 192 { 193 *status = LZMA_STATUS_NEEDS_MORE_INPUT; 194 return SZ_OK; 195 } 196 (*srcLen)++; 197 p->state = Lzma2Dec_UpdateState(p, *src++); 198 continue; 199 } 200 { 201 SizeT destSizeCur = dicLimit - dicPos; 202 SizeT srcSizeCur = inSize - *srcLen; 203 ELzmaFinishMode curFinishMode = LZMA_FINISH_ANY; 204 205 if (p->unpackSize <= destSizeCur) 206 { 207 destSizeCur = (SizeT)p->unpackSize; 208 curFinishMode = LZMA_FINISH_END; 209 } 210 211 if (LZMA2_IS_UNCOMPRESSED_STATE(p)) 212 { 213 if (*srcLen == inSize) 214 { 215 *status = LZMA_STATUS_NEEDS_MORE_INPUT; 216 return SZ_OK; 217 } 218 219 if (p->state == LZMA2_STATE_DATA) 220 { 221 Bool initDic = (p->control == LZMA2_CONTROL_COPY_RESET_DIC); 222 if (initDic) 223 p->needInitProp = p->needInitState = True; 224 else if (p->needInitDic) 225 return SZ_ERROR_DATA; 226 p->needInitDic = False; 227 LzmaDec_InitDicAndState(&p->decoder, initDic, False); 228 } 229 230 if (srcSizeCur > destSizeCur) 231 srcSizeCur = destSizeCur; 232 233 if (srcSizeCur == 0) 234 return SZ_ERROR_DATA; 235 236 LzmaDec_UpdateWithUncompressed(&p->decoder, src, srcSizeCur); 237 238 src += srcSizeCur; 239 *srcLen += srcSizeCur; 240 p->unpackSize -= (UInt32)srcSizeCur; 241 p->state = (p->unpackSize == 0) ? LZMA2_STATE_CONTROL : LZMA2_STATE_DATA_CONT; 242 } 243 else 244 { 245 SizeT outSizeProcessed; 246 SRes res; 247 248 if (p->state == LZMA2_STATE_DATA) 249 { 250 int mode = LZMA2_GET_LZMA_MODE(p); 251 Bool initDic = (mode == 3); 252 Bool initState = (mode > 0); 253 if ((!initDic && p->needInitDic) || (!initState && p->needInitState)) 254 return SZ_ERROR_DATA; 255 256 LzmaDec_InitDicAndState(&p->decoder, initDic, initState); 257 p->needInitDic = False; 258 p->needInitState = False; 259 p->state = LZMA2_STATE_DATA_CONT; 260 } 261 if (srcSizeCur > p->packSize) 262 srcSizeCur = (SizeT)p->packSize; 263 264 res = LzmaDec_DecodeToDic(&p->decoder, dicPos + destSizeCur, src, &srcSizeCur, curFinishMode, status); 265 266 src += srcSizeCur; 267 *srcLen += srcSizeCur; 268 p->packSize -= (UInt32)srcSizeCur; 269 270 outSizeProcessed = p->decoder.dicPos - dicPos; 271 p->unpackSize -= (UInt32)outSizeProcessed; 272 273 RINOK(res); 274 if (*status == LZMA_STATUS_NEEDS_MORE_INPUT) 275 return res; 276 277 if (srcSizeCur == 0 && outSizeProcessed == 0) 278 { 279 if (*status != LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK || 280 p->unpackSize != 0 || p->packSize != 0) 281 return SZ_ERROR_DATA; 282 p->state = LZMA2_STATE_CONTROL; 283 } 284 if (*status == LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK) 285 *status = LZMA_STATUS_NOT_FINISHED; 286 } 287 } 288 } 289 *status = LZMA_STATUS_FINISHED_WITH_MARK; 290 return SZ_OK; 291 } 292 293 SRes Lzma2Dec_DecodeToBuf(CLzma2Dec *p, Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen, ELzmaFinishMode finishMode, ELzmaStatus *status) 294 { 295 SizeT outSize = *destLen, inSize = *srcLen; 296 *srcLen = *destLen = 0; 297 for (;;) 298 { 299 SizeT srcSizeCur = inSize, outSizeCur, dicPos; 300 ELzmaFinishMode curFinishMode; 301 SRes res; 302 if (p->decoder.dicPos == p->decoder.dicBufSize) 303 p->decoder.dicPos = 0; 304 dicPos = p->decoder.dicPos; 305 if (outSize > p->decoder.dicBufSize - dicPos) 306 { 307 outSizeCur = p->decoder.dicBufSize; 308 curFinishMode = LZMA_FINISH_ANY; 309 } 310 else 311 { 312 outSizeCur = dicPos + outSize; 313 curFinishMode = finishMode; 314 } 315 316 res = Lzma2Dec_DecodeToDic(p, outSizeCur, src, &srcSizeCur, curFinishMode, status); 317 src += srcSizeCur; 318 inSize -= srcSizeCur; 319 *srcLen += srcSizeCur; 320 outSizeCur = p->decoder.dicPos - dicPos; 321 memcpy(dest, p->decoder.dic + dicPos, outSizeCur); 322 dest += outSizeCur; 323 outSize -= outSizeCur; 324 *destLen += outSizeCur; 325 if (res != 0) 326 return res; 327 if (outSizeCur == 0 || outSize == 0) 328 return SZ_OK; 329 } 330 } 331 332 SRes Lzma2Decode(Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen, 333 Byte prop, ELzmaFinishMode finishMode, ELzmaStatus *status, ISzAlloc *alloc) 334 { 335 CLzma2Dec p; 336 SRes res; 337 SizeT outSize = *destLen, inSize = *srcLen; 338 *destLen = *srcLen = 0; 339 *status = LZMA_STATUS_NOT_SPECIFIED; 340 Lzma2Dec_Construct(&p); 341 RINOK(Lzma2Dec_AllocateProbs(&p, prop, alloc)); 342 p.decoder.dic = dest; 343 p.decoder.dicBufSize = outSize; 344 Lzma2Dec_Init(&p); 345 *srcLen = inSize; 346 res = Lzma2Dec_DecodeToDic(&p, outSize, src, srcLen, finishMode, status); 347 *destLen = p.decoder.dicPos; 348 if (res == SZ_OK && *status == LZMA_STATUS_NEEDS_MORE_INPUT) 349 res = SZ_ERROR_INPUT_EOF; 350 Lzma2Dec_FreeProbs(&p, alloc); 351 return res; 352 } 353