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 
RangeDecoderReadByte(CRangeDecoder * rd)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 
RangeDecoderInit(CRangeDecoder * rd,const Byte * stream,SizeT bufferSize)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 
RangeDecoderDecodeDirectBits(CRangeDecoder * rd,int numTotalBits)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 
RangeDecoderBitDecode(CProb * prob,CRangeDecoder * rd)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 
RangeDecoderBitTreeDecode(CProb * probs,int numLevels,CRangeDecoder * rd)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 
RangeDecoderReverseBitTreeDecode(CProb * probs,int numLevels,CRangeDecoder * rd)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 
LzmaLiteralDecode(CProb * probs,CRangeDecoder * rd)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 
LzmaLiteralDecodeMatch(CProb * probs,CRangeDecoder * rd,Byte matchByte)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 
LzmaLenDecode(CProb * p,CRangeDecoder * rd,int posState)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 
LzmaDecodeProperties(CLzmaProperties * propsRes,const unsigned char * propsData,int size)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 
LzmaDecode(CLzmaDecoderState * vs,ILzmaInCallback * InCallback,unsigned char * outStream,SizeT outSize,SizeT * outSizeProcessed)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 }
713