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
31typedef 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
44Byte 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
65void 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
89UInt32 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
117int 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
155int 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
177int 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
202Byte 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
224Byte 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
282int 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
323StopCompilingDueBUG
324#endif
325
326int 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
361int 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