|
1 /* |
|
2 LzmaDecodeSize.c |
|
3 LZMA Decoder (optimized for Size version) |
|
4 |
|
5 LZMA SDK 4.40 Copyright (c) 1999-2006 Igor Pavlov (2006-05-01) |
|
6 http://www.7-zip.org/ |
|
7 |
|
8 LZMA SDK is licensed under two licenses: |
|
9 1) GNU Lesser General Public License (GNU LGPL) |
|
10 2) Common Public License (CPL) |
|
11 It means that you can select one of these two licenses and |
|
12 follow rules of that license. |
|
13 |
|
14 SPECIAL EXCEPTION: |
|
15 Igor Pavlov, as the author of this code, expressly permits you to |
|
16 statically or dynamically link your code (or bind by name) to the |
|
17 interfaces of this file without subjecting your linked code to the |
|
18 terms of the CPL or GNU LGPL. Any modifications or additions |
|
19 to this file, however, are subject to the LGPL or CPL terms. |
|
20 */ |
|
21 |
|
22 #include "LzmaDecode.h" |
|
23 |
|
24 #define kNumTopBits 24 |
|
25 #define kTopValue ((UInt32)1 << kNumTopBits) |
|
26 |
|
27 #define kNumBitModelTotalBits 11 |
|
28 #define kBitModelTotal (1 << kNumBitModelTotalBits) |
|
29 #define kNumMoveBits 5 |
|
30 |
|
31 typedef struct _CRangeDecoder |
|
32 { |
|
33 const Byte *Buffer; |
|
34 const Byte *BufferLim; |
|
35 UInt32 Range; |
|
36 UInt32 Code; |
|
37 #ifdef _LZMA_IN_CB |
|
38 ILzmaInCallback *InCallback; |
|
39 int Result; |
|
40 #endif |
|
41 int ExtraBytes; |
|
42 } CRangeDecoder; |
|
43 |
|
44 Byte RangeDecoderReadByte(CRangeDecoder *rd) |
|
45 { |
|
46 if (rd->Buffer == rd->BufferLim) |
|
47 { |
|
48 #ifdef _LZMA_IN_CB |
|
49 SizeT size; |
|
50 rd->Result = rd->InCallback->Read(rd->InCallback, &rd->Buffer, &size); |
|
51 rd->BufferLim = rd->Buffer + size; |
|
52 if (size == 0) |
|
53 #endif |
|
54 { |
|
55 rd->ExtraBytes = 1; |
|
56 return 0xFF; |
|
57 } |
|
58 } |
|
59 return (*rd->Buffer++); |
|
60 } |
|
61 |
|
62 /* #define ReadByte (*rd->Buffer++) */ |
|
63 #define ReadByte (RangeDecoderReadByte(rd)) |
|
64 |
|
65 void RangeDecoderInit(CRangeDecoder *rd |
|
66 #ifndef _LZMA_IN_CB |
|
67 , const Byte *stream, SizeT bufferSize |
|
68 #endif |
|
69 ) |
|
70 { |
|
71 int i; |
|
72 #ifdef _LZMA_IN_CB |
|
73 rd->Buffer = rd->BufferLim = 0; |
|
74 #else |
|
75 rd->Buffer = stream; |
|
76 rd->BufferLim = stream + bufferSize; |
|
77 #endif |
|
78 rd->ExtraBytes = 0; |
|
79 rd->Code = 0; |
|
80 rd->Range = (0xFFFFFFFF); |
|
81 for(i = 0; i < 5; i++) |
|
82 rd->Code = (rd->Code << 8) | ReadByte; |
|
83 } |
|
84 |
|
85 #define RC_INIT_VAR UInt32 range = rd->Range; UInt32 code = rd->Code; |
|
86 #define RC_FLUSH_VAR rd->Range = range; rd->Code = code; |
|
87 #define RC_NORMALIZE if (range < kTopValue) { range <<= 8; code = (code << 8) | ReadByte; } |
|
88 |
|
89 UInt32 RangeDecoderDecodeDirectBits(CRangeDecoder *rd, int numTotalBits) |
|
90 { |
|
91 RC_INIT_VAR |
|
92 UInt32 result = 0; |
|
93 int i; |
|
94 for (i = numTotalBits; i != 0; i--) |
|
95 { |
|
96 /* UInt32 t; */ |
|
97 range >>= 1; |
|
98 |
|
99 result <<= 1; |
|
100 if (code >= range) |
|
101 { |
|
102 code -= range; |
|
103 result |= 1; |
|
104 } |
|
105 /* |
|
106 t = (code - range) >> 31; |
|
107 t &= 1; |
|
108 code -= range & (t - 1); |
|
109 result = (result + result) | (1 - t); |
|
110 */ |
|
111 RC_NORMALIZE |
|
112 } |
|
113 RC_FLUSH_VAR |
|
114 return result; |
|
115 } |
|
116 |
|
117 int RangeDecoderBitDecode(CProb *prob, CRangeDecoder *rd) |
|
118 { |
|
119 UInt32 bound = (rd->Range >> kNumBitModelTotalBits) * *prob; |
|
120 if (rd->Code < bound) |
|
121 { |
|
122 rd->Range = bound; |
|
123 *prob += (kBitModelTotal - *prob) >> kNumMoveBits; |
|
124 if (rd->Range < kTopValue) |
|
125 { |
|
126 rd->Code = (rd->Code << 8) | ReadByte; |
|
127 rd->Range <<= 8; |
|
128 } |
|
129 return 0; |
|
130 } |
|
131 else |
|
132 { |
|
133 rd->Range -= bound; |
|
134 rd->Code -= bound; |
|
135 *prob -= (*prob) >> kNumMoveBits; |
|
136 if (rd->Range < kTopValue) |
|
137 { |
|
138 rd->Code = (rd->Code << 8) | ReadByte; |
|
139 rd->Range <<= 8; |
|
140 } |
|
141 return 1; |
|
142 } |
|
143 } |
|
144 |
|
145 #define RC_GET_BIT2(prob, mi, A0, A1) \ |
|
146 UInt32 bound = (range >> kNumBitModelTotalBits) * *prob; \ |
|
147 if (code < bound) \ |
|
148 { A0; range = bound; *prob += (kBitModelTotal - *prob) >> kNumMoveBits; mi <<= 1; } \ |
|
149 else \ |
|
150 { A1; range -= bound; code -= bound; *prob -= (*prob) >> kNumMoveBits; mi = (mi + mi) + 1; } \ |
|
151 RC_NORMALIZE |
|
152 |
|
153 #define RC_GET_BIT(prob, mi) RC_GET_BIT2(prob, mi, ; , ;) |
|
154 |
|
155 int RangeDecoderBitTreeDecode(CProb *probs, int numLevels, CRangeDecoder *rd) |
|
156 { |
|
157 int mi = 1; |
|
158 int i; |
|
159 #ifdef _LZMA_LOC_OPT |
|
160 RC_INIT_VAR |
|
161 #endif |
|
162 for(i = numLevels; i != 0; i--) |
|
163 { |
|
164 #ifdef _LZMA_LOC_OPT |
|
165 CProb *prob = probs + mi; |
|
166 RC_GET_BIT(prob, mi) |
|
167 #else |
|
168 mi = (mi + mi) + RangeDecoderBitDecode(probs + mi, rd); |
|
169 #endif |
|
170 } |
|
171 #ifdef _LZMA_LOC_OPT |
|
172 RC_FLUSH_VAR |
|
173 #endif |
|
174 return mi - (1 << numLevels); |
|
175 } |
|
176 |
|
177 int RangeDecoderReverseBitTreeDecode(CProb *probs, int numLevels, CRangeDecoder *rd) |
|
178 { |
|
179 int mi = 1; |
|
180 int i; |
|
181 int symbol = 0; |
|
182 #ifdef _LZMA_LOC_OPT |
|
183 RC_INIT_VAR |
|
184 #endif |
|
185 for(i = 0; i < numLevels; i++) |
|
186 { |
|
187 #ifdef _LZMA_LOC_OPT |
|
188 CProb *prob = probs + mi; |
|
189 RC_GET_BIT2(prob, mi, ; , symbol |= (1 << i)) |
|
190 #else |
|
191 int bit = RangeDecoderBitDecode(probs + mi, rd); |
|
192 mi = mi + mi + bit; |
|
193 symbol |= (bit << i); |
|
194 #endif |
|
195 } |
|
196 #ifdef _LZMA_LOC_OPT |
|
197 RC_FLUSH_VAR |
|
198 #endif |
|
199 return symbol; |
|
200 } |
|
201 |
|
202 Byte LzmaLiteralDecode(CProb *probs, CRangeDecoder *rd) |
|
203 { |
|
204 int symbol = 1; |
|
205 #ifdef _LZMA_LOC_OPT |
|
206 RC_INIT_VAR |
|
207 #endif |
|
208 do |
|
209 { |
|
210 #ifdef _LZMA_LOC_OPT |
|
211 CProb *prob = probs + symbol; |
|
212 RC_GET_BIT(prob, symbol) |
|
213 #else |
|
214 symbol = (symbol + symbol) | RangeDecoderBitDecode(probs + symbol, rd); |
|
215 #endif |
|
216 } |
|
217 while (symbol < 0x100); |
|
218 #ifdef _LZMA_LOC_OPT |
|
219 RC_FLUSH_VAR |
|
220 #endif |
|
221 return symbol; |
|
222 } |
|
223 |
|
224 Byte LzmaLiteralDecodeMatch(CProb *probs, CRangeDecoder *rd, Byte matchByte) |
|
225 { |
|
226 int symbol = 1; |
|
227 #ifdef _LZMA_LOC_OPT |
|
228 RC_INIT_VAR |
|
229 #endif |
|
230 do |
|
231 { |
|
232 int bit; |
|
233 int matchBit = (matchByte >> 7) & 1; |
|
234 matchByte <<= 1; |
|
235 #ifdef _LZMA_LOC_OPT |
|
236 { |
|
237 CProb *prob = probs + 0x100 + (matchBit << 8) + symbol; |
|
238 RC_GET_BIT2(prob, symbol, bit = 0, bit = 1) |
|
239 } |
|
240 #else |
|
241 bit = RangeDecoderBitDecode(probs + 0x100 + (matchBit << 8) + symbol, rd); |
|
242 symbol = (symbol << 1) | bit; |
|
243 #endif |
|
244 if (matchBit != bit) |
|
245 { |
|
246 while (symbol < 0x100) |
|
247 { |
|
248 #ifdef _LZMA_LOC_OPT |
|
249 CProb *prob = probs + symbol; |
|
250 RC_GET_BIT(prob, symbol) |
|
251 #else |
|
252 symbol = (symbol + symbol) | RangeDecoderBitDecode(probs + symbol, rd); |
|
253 #endif |
|
254 } |
|
255 break; |
|
256 } |
|
257 } |
|
258 while (symbol < 0x100); |
|
259 #ifdef _LZMA_LOC_OPT |
|
260 RC_FLUSH_VAR |
|
261 #endif |
|
262 return symbol; |
|
263 } |
|
264 |
|
265 #define kNumPosBitsMax 4 |
|
266 #define kNumPosStatesMax (1 << kNumPosBitsMax) |
|
267 |
|
268 #define kLenNumLowBits 3 |
|
269 #define kLenNumLowSymbols (1 << kLenNumLowBits) |
|
270 #define kLenNumMidBits 3 |
|
271 #define kLenNumMidSymbols (1 << kLenNumMidBits) |
|
272 #define kLenNumHighBits 8 |
|
273 #define kLenNumHighSymbols (1 << kLenNumHighBits) |
|
274 |
|
275 #define LenChoice 0 |
|
276 #define LenChoice2 (LenChoice + 1) |
|
277 #define LenLow (LenChoice2 + 1) |
|
278 #define LenMid (LenLow + (kNumPosStatesMax << kLenNumLowBits)) |
|
279 #define LenHigh (LenMid + (kNumPosStatesMax << kLenNumMidBits)) |
|
280 #define kNumLenProbs (LenHigh + kLenNumHighSymbols) |
|
281 |
|
282 int LzmaLenDecode(CProb *p, CRangeDecoder *rd, int posState) |
|
283 { |
|
284 if(RangeDecoderBitDecode(p + LenChoice, rd) == 0) |
|
285 return RangeDecoderBitTreeDecode(p + LenLow + |
|
286 (posState << kLenNumLowBits), kLenNumLowBits, rd); |
|
287 if(RangeDecoderBitDecode(p + LenChoice2, rd) == 0) |
|
288 return kLenNumLowSymbols + RangeDecoderBitTreeDecode(p + LenMid + |
|
289 (posState << kLenNumMidBits), kLenNumMidBits, rd); |
|
290 return kLenNumLowSymbols + kLenNumMidSymbols + |
|
291 RangeDecoderBitTreeDecode(p + LenHigh, kLenNumHighBits, rd); |
|
292 } |
|
293 |
|
294 #define kNumStates 12 |
|
295 #define kNumLitStates 7 |
|
296 |
|
297 #define kStartPosModelIndex 4 |
|
298 #define kEndPosModelIndex 14 |
|
299 #define kNumFullDistances (1 << (kEndPosModelIndex >> 1)) |
|
300 |
|
301 #define kNumPosSlotBits 6 |
|
302 #define kNumLenToPosStates 4 |
|
303 |
|
304 #define kNumAlignBits 4 |
|
305 #define kAlignTableSize (1 << kNumAlignBits) |
|
306 |
|
307 #define kMatchMinLen 2 |
|
308 |
|
309 #define IsMatch 0 |
|
310 #define IsRep (IsMatch + (kNumStates << kNumPosBitsMax)) |
|
311 #define IsRepG0 (IsRep + kNumStates) |
|
312 #define IsRepG1 (IsRepG0 + kNumStates) |
|
313 #define IsRepG2 (IsRepG1 + kNumStates) |
|
314 #define IsRep0Long (IsRepG2 + kNumStates) |
|
315 #define PosSlot (IsRep0Long + (kNumStates << kNumPosBitsMax)) |
|
316 #define SpecPos (PosSlot + (kNumLenToPosStates << kNumPosSlotBits)) |
|
317 #define Align (SpecPos + kNumFullDistances - kEndPosModelIndex) |
|
318 #define LenCoder (Align + kAlignTableSize) |
|
319 #define RepLenCoder (LenCoder + kNumLenProbs) |
|
320 #define Literal (RepLenCoder + kNumLenProbs) |
|
321 |
|
322 #if Literal != LZMA_BASE_SIZE |
|
323 StopCompilingDueBUG |
|
324 #endif |
|
325 |
|
326 int LzmaDecodeProperties(CLzmaProperties *propsRes, const unsigned char *propsData, int size) |
|
327 { |
|
328 unsigned char prop0; |
|
329 if (size < LZMA_PROPERTIES_SIZE) |
|
330 return LZMA_RESULT_DATA_ERROR; |
|
331 prop0 = propsData[0]; |
|
332 if (prop0 >= (9 * 5 * 5)) |
|
333 return LZMA_RESULT_DATA_ERROR; |
|
334 { |
|
335 for (propsRes->pb = 0; prop0 >= (9 * 5); propsRes->pb++, prop0 -= (9 * 5)); |
|
336 for (propsRes->lp = 0; prop0 >= 9; propsRes->lp++, prop0 -= 9); |
|
337 propsRes->lc = prop0; |
|
338 /* |
|
339 unsigned char remainder = (unsigned char)(prop0 / 9); |
|
340 propsRes->lc = prop0 % 9; |
|
341 propsRes->pb = remainder / 5; |
|
342 propsRes->lp = remainder % 5; |
|
343 */ |
|
344 } |
|
345 |
|
346 #ifdef _LZMA_OUT_READ |
|
347 { |
|
348 int i; |
|
349 propsRes->DictionarySize = 0; |
|
350 for (i = 0; i < 4; i++) |
|
351 propsRes->DictionarySize += (UInt32)(propsData[1 + i]) << (i * 8); |
|
352 if (propsRes->DictionarySize == 0) |
|
353 propsRes->DictionarySize = 1; |
|
354 } |
|
355 #endif |
|
356 return LZMA_RESULT_OK; |
|
357 } |
|
358 |
|
359 #define kLzmaStreamWasFinishedId (-1) |
|
360 |
|
361 int LzmaDecode(CLzmaDecoderState *vs, |
|
362 #ifdef _LZMA_IN_CB |
|
363 ILzmaInCallback *InCallback, |
|
364 #else |
|
365 const unsigned char *inStream, SizeT inSize, SizeT *inSizeProcessed, |
|
366 #endif |
|
367 unsigned char *outStream, SizeT outSize, SizeT *outSizeProcessed) |
|
368 { |
|
369 CProb *p = vs->Probs; |
|
370 SizeT nowPos = 0; |
|
371 Byte previousByte = 0; |
|
372 UInt32 posStateMask = (1 << (vs->Properties.pb)) - 1; |
|
373 UInt32 literalPosMask = (1 << (vs->Properties.lp)) - 1; |
|
374 int lc = vs->Properties.lc; |
|
375 CRangeDecoder rd; |
|
376 |
|
377 #ifdef _LZMA_OUT_READ |
|
378 |
|
379 int state = vs->State; |
|
380 UInt32 rep0 = vs->Reps[0], rep1 = vs->Reps[1], rep2 = vs->Reps[2], rep3 = vs->Reps[3]; |
|
381 int len = vs->RemainLen; |
|
382 UInt32 globalPos = vs->GlobalPos; |
|
383 UInt32 distanceLimit = vs->DistanceLimit; |
|
384 |
|
385 Byte *dictionary = vs->Dictionary; |
|
386 UInt32 dictionarySize = vs->Properties.DictionarySize; |
|
387 UInt32 dictionaryPos = vs->DictionaryPos; |
|
388 |
|
389 Byte tempDictionary[4]; |
|
390 |
|
391 rd.Range = vs->Range; |
|
392 rd.Code = vs->Code; |
|
393 #ifdef _LZMA_IN_CB |
|
394 rd.InCallback = InCallback; |
|
395 rd.Buffer = vs->Buffer; |
|
396 rd.BufferLim = vs->BufferLim; |
|
397 #else |
|
398 rd.Buffer = inStream; |
|
399 rd.BufferLim = inStream + inSize; |
|
400 #endif |
|
401 |
|
402 #ifndef _LZMA_IN_CB |
|
403 *inSizeProcessed = 0; |
|
404 #endif |
|
405 *outSizeProcessed = 0; |
|
406 if (len == kLzmaStreamWasFinishedId) |
|
407 return LZMA_RESULT_OK; |
|
408 |
|
409 if (dictionarySize == 0) |
|
410 { |
|
411 dictionary = tempDictionary; |
|
412 dictionarySize = 1; |
|
413 tempDictionary[0] = vs->TempDictionary[0]; |
|
414 } |
|
415 |
|
416 if (len == kLzmaNeedInitId) |
|
417 { |
|
418 { |
|
419 UInt32 numProbs = Literal + ((UInt32)LZMA_LIT_SIZE << (lc + vs->Properties.lp)); |
|
420 UInt32 i; |
|
421 for (i = 0; i < numProbs; i++) |
|
422 p[i] = kBitModelTotal >> 1; |
|
423 rep0 = rep1 = rep2 = rep3 = 1; |
|
424 state = 0; |
|
425 globalPos = 0; |
|
426 distanceLimit = 0; |
|
427 dictionaryPos = 0; |
|
428 dictionary[dictionarySize - 1] = 0; |
|
429 RangeDecoderInit(&rd |
|
430 #ifndef _LZMA_IN_CB |
|
431 , inStream, inSize |
|
432 #endif |
|
433 ); |
|
434 #ifdef _LZMA_IN_CB |
|
435 if (rd.Result != LZMA_RESULT_OK) |
|
436 return rd.Result; |
|
437 #endif |
|
438 if (rd.ExtraBytes != 0) |
|
439 return LZMA_RESULT_DATA_ERROR; |
|
440 } |
|
441 len = 0; |
|
442 } |
|
443 while(len != 0 && nowPos < outSize) |
|
444 { |
|
445 UInt32 pos = dictionaryPos - rep0; |
|
446 if (pos >= dictionarySize) |
|
447 pos += dictionarySize; |
|
448 outStream[nowPos++] = dictionary[dictionaryPos] = dictionary[pos]; |
|
449 if (++dictionaryPos == dictionarySize) |
|
450 dictionaryPos = 0; |
|
451 len--; |
|
452 } |
|
453 if (dictionaryPos == 0) |
|
454 previousByte = dictionary[dictionarySize - 1]; |
|
455 else |
|
456 previousByte = dictionary[dictionaryPos - 1]; |
|
457 |
|
458 #ifdef _LZMA_IN_CB |
|
459 rd.Result = LZMA_RESULT_OK; |
|
460 #endif |
|
461 rd.ExtraBytes = 0; |
|
462 |
|
463 #else /* if !_LZMA_OUT_READ */ |
|
464 |
|
465 int state = 0; |
|
466 UInt32 rep0 = 1, rep1 = 1, rep2 = 1, rep3 = 1; |
|
467 int len = 0; |
|
468 |
|
469 #ifndef _LZMA_IN_CB |
|
470 *inSizeProcessed = 0; |
|
471 #endif |
|
472 *outSizeProcessed = 0; |
|
473 |
|
474 { |
|
475 UInt32 i; |
|
476 UInt32 numProbs = Literal + ((UInt32)LZMA_LIT_SIZE << (lc + vs->Properties.lp)); |
|
477 for (i = 0; i < numProbs; i++) |
|
478 p[i] = kBitModelTotal >> 1; |
|
479 } |
|
480 |
|
481 #ifdef _LZMA_IN_CB |
|
482 rd.InCallback = InCallback; |
|
483 #endif |
|
484 RangeDecoderInit(&rd |
|
485 #ifndef _LZMA_IN_CB |
|
486 , inStream, inSize |
|
487 #endif |
|
488 ); |
|
489 |
|
490 #ifdef _LZMA_IN_CB |
|
491 if (rd.Result != LZMA_RESULT_OK) |
|
492 return rd.Result; |
|
493 #endif |
|
494 if (rd.ExtraBytes != 0) |
|
495 return LZMA_RESULT_DATA_ERROR; |
|
496 |
|
497 #endif /* _LZMA_OUT_READ */ |
|
498 |
|
499 |
|
500 while(nowPos < outSize) |
|
501 { |
|
502 int posState = (int)( |
|
503 (nowPos |
|
504 #ifdef _LZMA_OUT_READ |
|
505 + globalPos |
|
506 #endif |
|
507 ) |
|
508 & posStateMask); |
|
509 #ifdef _LZMA_IN_CB |
|
510 if (rd.Result != LZMA_RESULT_OK) |
|
511 return rd.Result; |
|
512 #endif |
|
513 if (rd.ExtraBytes != 0) |
|
514 return LZMA_RESULT_DATA_ERROR; |
|
515 if (RangeDecoderBitDecode(p + IsMatch + (state << kNumPosBitsMax) + posState, &rd) == 0) |
|
516 { |
|
517 CProb *probs = p + Literal + (LZMA_LIT_SIZE * |
|
518 ((( |
|
519 (nowPos |
|
520 #ifdef _LZMA_OUT_READ |
|
521 + globalPos |
|
522 #endif |
|
523 ) |
|
524 & literalPosMask) << lc) + (previousByte >> (8 - lc)))); |
|
525 |
|
526 if (state >= kNumLitStates) |
|
527 { |
|
528 Byte matchByte; |
|
529 #ifdef _LZMA_OUT_READ |
|
530 UInt32 pos = dictionaryPos - rep0; |
|
531 if (pos >= dictionarySize) |
|
532 pos += dictionarySize; |
|
533 matchByte = dictionary[pos]; |
|
534 #else |
|
535 matchByte = outStream[nowPos - rep0]; |
|
536 #endif |
|
537 previousByte = LzmaLiteralDecodeMatch(probs, &rd, matchByte); |
|
538 } |
|
539 else |
|
540 previousByte = LzmaLiteralDecode(probs, &rd); |
|
541 outStream[nowPos++] = previousByte; |
|
542 #ifdef _LZMA_OUT_READ |
|
543 if (distanceLimit < dictionarySize) |
|
544 distanceLimit++; |
|
545 |
|
546 dictionary[dictionaryPos] = previousByte; |
|
547 if (++dictionaryPos == dictionarySize) |
|
548 dictionaryPos = 0; |
|
549 #endif |
|
550 if (state < 4) state = 0; |
|
551 else if (state < 10) state -= 3; |
|
552 else state -= 6; |
|
553 } |
|
554 else |
|
555 { |
|
556 if (RangeDecoderBitDecode(p + IsRep + state, &rd) == 1) |
|
557 { |
|
558 if (RangeDecoderBitDecode(p + IsRepG0 + state, &rd) == 0) |
|
559 { |
|
560 if (RangeDecoderBitDecode(p + IsRep0Long + (state << kNumPosBitsMax) + posState, &rd) == 0) |
|
561 { |
|
562 #ifdef _LZMA_OUT_READ |
|
563 UInt32 pos; |
|
564 #endif |
|
565 |
|
566 #ifdef _LZMA_OUT_READ |
|
567 if (distanceLimit == 0) |
|
568 #else |
|
569 if (nowPos == 0) |
|
570 #endif |
|
571 return LZMA_RESULT_DATA_ERROR; |
|
572 |
|
573 state = state < 7 ? 9 : 11; |
|
574 #ifdef _LZMA_OUT_READ |
|
575 pos = dictionaryPos - rep0; |
|
576 if (pos >= dictionarySize) |
|
577 pos += dictionarySize; |
|
578 previousByte = dictionary[pos]; |
|
579 dictionary[dictionaryPos] = previousByte; |
|
580 if (++dictionaryPos == dictionarySize) |
|
581 dictionaryPos = 0; |
|
582 #else |
|
583 previousByte = outStream[nowPos - rep0]; |
|
584 #endif |
|
585 outStream[nowPos++] = previousByte; |
|
586 |
|
587 #ifdef _LZMA_OUT_READ |
|
588 if (distanceLimit < dictionarySize) |
|
589 distanceLimit++; |
|
590 #endif |
|
591 continue; |
|
592 } |
|
593 } |
|
594 else |
|
595 { |
|
596 UInt32 distance; |
|
597 if(RangeDecoderBitDecode(p + IsRepG1 + state, &rd) == 0) |
|
598 distance = rep1; |
|
599 else |
|
600 { |
|
601 if(RangeDecoderBitDecode(p + IsRepG2 + state, &rd) == 0) |
|
602 distance = rep2; |
|
603 else |
|
604 { |
|
605 distance = rep3; |
|
606 rep3 = rep2; |
|
607 } |
|
608 rep2 = rep1; |
|
609 } |
|
610 rep1 = rep0; |
|
611 rep0 = distance; |
|
612 } |
|
613 len = LzmaLenDecode(p + RepLenCoder, &rd, posState); |
|
614 state = state < 7 ? 8 : 11; |
|
615 } |
|
616 else |
|
617 { |
|
618 int posSlot; |
|
619 rep3 = rep2; |
|
620 rep2 = rep1; |
|
621 rep1 = rep0; |
|
622 state = state < 7 ? 7 : 10; |
|
623 len = LzmaLenDecode(p + LenCoder, &rd, posState); |
|
624 posSlot = RangeDecoderBitTreeDecode(p + PosSlot + |
|
625 ((len < kNumLenToPosStates ? len : kNumLenToPosStates - 1) << |
|
626 kNumPosSlotBits), kNumPosSlotBits, &rd); |
|
627 if (posSlot >= kStartPosModelIndex) |
|
628 { |
|
629 int numDirectBits = ((posSlot >> 1) - 1); |
|
630 rep0 = ((2 | ((UInt32)posSlot & 1)) << numDirectBits); |
|
631 if (posSlot < kEndPosModelIndex) |
|
632 { |
|
633 rep0 += RangeDecoderReverseBitTreeDecode( |
|
634 p + SpecPos + rep0 - posSlot - 1, numDirectBits, &rd); |
|
635 } |
|
636 else |
|
637 { |
|
638 rep0 += RangeDecoderDecodeDirectBits(&rd, |
|
639 numDirectBits - kNumAlignBits) << kNumAlignBits; |
|
640 rep0 += RangeDecoderReverseBitTreeDecode(p + Align, kNumAlignBits, &rd); |
|
641 } |
|
642 } |
|
643 else |
|
644 rep0 = posSlot; |
|
645 if (++rep0 == (UInt32)(0)) |
|
646 { |
|
647 /* it's for stream version */ |
|
648 len = kLzmaStreamWasFinishedId; |
|
649 break; |
|
650 } |
|
651 } |
|
652 |
|
653 len += kMatchMinLen; |
|
654 #ifdef _LZMA_OUT_READ |
|
655 if (rep0 > distanceLimit) |
|
656 #else |
|
657 if (rep0 > nowPos) |
|
658 #endif |
|
659 return LZMA_RESULT_DATA_ERROR; |
|
660 |
|
661 #ifdef _LZMA_OUT_READ |
|
662 if (dictionarySize - distanceLimit > (UInt32)len) |
|
663 distanceLimit += len; |
|
664 else |
|
665 distanceLimit = dictionarySize; |
|
666 #endif |
|
667 |
|
668 do |
|
669 { |
|
670 #ifdef _LZMA_OUT_READ |
|
671 UInt32 pos = dictionaryPos - rep0; |
|
672 if (pos >= dictionarySize) |
|
673 pos += dictionarySize; |
|
674 previousByte = dictionary[pos]; |
|
675 dictionary[dictionaryPos] = previousByte; |
|
676 if (++dictionaryPos == dictionarySize) |
|
677 dictionaryPos = 0; |
|
678 #else |
|
679 previousByte = outStream[nowPos - rep0]; |
|
680 #endif |
|
681 len--; |
|
682 outStream[nowPos++] = previousByte; |
|
683 } |
|
684 while(len != 0 && nowPos < outSize); |
|
685 } |
|
686 } |
|
687 |
|
688 |
|
689 #ifdef _LZMA_OUT_READ |
|
690 vs->Range = rd.Range; |
|
691 vs->Code = rd.Code; |
|
692 vs->DictionaryPos = dictionaryPos; |
|
693 vs->GlobalPos = globalPos + (UInt32)nowPos; |
|
694 vs->DistanceLimit = distanceLimit; |
|
695 vs->Reps[0] = rep0; |
|
696 vs->Reps[1] = rep1; |
|
697 vs->Reps[2] = rep2; |
|
698 vs->Reps[3] = rep3; |
|
699 vs->State = state; |
|
700 vs->RemainLen = len; |
|
701 vs->TempDictionary[0] = tempDictionary[0]; |
|
702 #endif |
|
703 |
|
704 #ifdef _LZMA_IN_CB |
|
705 vs->Buffer = rd.Buffer; |
|
706 vs->BufferLim = rd.BufferLim; |
|
707 #else |
|
708 *inSizeProcessed = (SizeT)(rd.Buffer - inStream); |
|
709 #endif |
|
710 *outSizeProcessed = nowPos; |
|
711 return LZMA_RESULT_OK; |
|
712 } |