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