add chaos_calmer branch
[15.05/openwrt.git] / package / kernel / lantiq / ltq-vdsl-fw / src / LzmaDecode.c
1 /*
2   LzmaDecode.c
3   LZMA Decoder (optimized for Speed 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 #define RC_READ_BYTE (*Buffer++)
32
33 #define RC_INIT2 Code = 0; Range = 0xFFFFFFFF; \
34   { int i; for(i = 0; i < 5; i++) { RC_TEST; Code = (Code << 8) | RC_READ_BYTE; }}
35
36 #ifdef _LZMA_IN_CB
37
38 #define RC_TEST { if (Buffer == BufferLim) \
39   { SizeT size; int result = InCallback->Read(InCallback, &Buffer, &size); if (result != LZMA_RESULT_OK) return result; \
40   BufferLim = Buffer + size; if (size == 0) return LZMA_RESULT_DATA_ERROR; }}
41
42 #define RC_INIT Buffer = BufferLim = 0; RC_INIT2
43
44 #else
45
46 #define RC_TEST { if (Buffer == BufferLim) return LZMA_RESULT_DATA_ERROR; }
47
48 #define RC_INIT(buffer, bufferSize) Buffer = buffer; BufferLim = buffer + bufferSize; RC_INIT2
49  
50 #endif
51
52 #define RC_NORMALIZE if (Range < kTopValue) { RC_TEST; Range <<= 8; Code = (Code << 8) | RC_READ_BYTE; }
53
54 #define IfBit0(p) RC_NORMALIZE; bound = (Range >> kNumBitModelTotalBits) * *(p); if (Code < bound)
55 #define UpdateBit0(p) Range = bound; *(p) += (kBitModelTotal - *(p)) >> kNumMoveBits;
56 #define UpdateBit1(p) Range -= bound; Code -= bound; *(p) -= (*(p)) >> kNumMoveBits;
57
58 #define RC_GET_BIT2(p, mi, A0, A1) IfBit0(p) \
59   { UpdateBit0(p); mi <<= 1; A0; } else \
60   { UpdateBit1(p); mi = (mi + mi) + 1; A1; } 
61   
62 #define RC_GET_BIT(p, mi) RC_GET_BIT2(p, mi, ; , ;)               
63
64 #define RangeDecoderBitTreeDecode(probs, numLevels, res) \
65   { int i = numLevels; res = 1; \
66   do { CProb *p = probs + res; RC_GET_BIT(p, res) } while(--i != 0); \
67   res -= (1 << numLevels); }
68
69
70 #define kNumPosBitsMax 4
71 #define kNumPosStatesMax (1 << kNumPosBitsMax)
72
73 #define kLenNumLowBits 3
74 #define kLenNumLowSymbols (1 << kLenNumLowBits)
75 #define kLenNumMidBits 3
76 #define kLenNumMidSymbols (1 << kLenNumMidBits)
77 #define kLenNumHighBits 8
78 #define kLenNumHighSymbols (1 << kLenNumHighBits)
79
80 #define LenChoice 0
81 #define LenChoice2 (LenChoice + 1)
82 #define LenLow (LenChoice2 + 1)
83 #define LenMid (LenLow + (kNumPosStatesMax << kLenNumLowBits))
84 #define LenHigh (LenMid + (kNumPosStatesMax << kLenNumMidBits))
85 #define kNumLenProbs (LenHigh + kLenNumHighSymbols) 
86
87
88 #define kNumStates 12
89 #define kNumLitStates 7
90
91 #define kStartPosModelIndex 4
92 #define kEndPosModelIndex 14
93 #define kNumFullDistances (1 << (kEndPosModelIndex >> 1))
94
95 #define kNumPosSlotBits 6
96 #define kNumLenToPosStates 4
97
98 #define kNumAlignBits 4
99 #define kAlignTableSize (1 << kNumAlignBits)
100
101 #define kMatchMinLen 2
102
103 #define IsMatch 0
104 #define IsRep (IsMatch + (kNumStates << kNumPosBitsMax))
105 #define IsRepG0 (IsRep + kNumStates)
106 #define IsRepG1 (IsRepG0 + kNumStates)
107 #define IsRepG2 (IsRepG1 + kNumStates)
108 #define IsRep0Long (IsRepG2 + kNumStates)
109 #define PosSlot (IsRep0Long + (kNumStates << kNumPosBitsMax))
110 #define SpecPos (PosSlot + (kNumLenToPosStates << kNumPosSlotBits))
111 #define Align (SpecPos + kNumFullDistances - kEndPosModelIndex)
112 #define LenCoder (Align + kAlignTableSize)
113 #define RepLenCoder (LenCoder + kNumLenProbs)
114 #define Literal (RepLenCoder + kNumLenProbs)
115
116 #if Literal != LZMA_BASE_SIZE
117 StopCompilingDueBUG
118 #endif
119
120 int LzmaDecodeProperties(CLzmaProperties *propsRes, const unsigned char *propsData, int size)
121 {
122   unsigned char prop0;
123   if (size < LZMA_PROPERTIES_SIZE)
124     return LZMA_RESULT_DATA_ERROR;
125   prop0 = propsData[0];
126   if (prop0 >= (9 * 5 * 5))
127     return LZMA_RESULT_DATA_ERROR;
128   {
129     for (propsRes->pb = 0; prop0 >= (9 * 5); propsRes->pb++, prop0 -= (9 * 5));
130     for (propsRes->lp = 0; prop0 >= 9; propsRes->lp++, prop0 -= 9);
131     propsRes->lc = prop0;
132     /*
133     unsigned char remainder = (unsigned char)(prop0 / 9);
134     propsRes->lc = prop0 % 9;
135     propsRes->pb = remainder / 5;
136     propsRes->lp = remainder % 5;
137     */
138   }
139
140   #ifdef _LZMA_OUT_READ
141   {
142     int i;
143     propsRes->DictionarySize = 0;
144     for (i = 0; i < 4; i++)
145       propsRes->DictionarySize += (UInt32)(propsData[1 + i]) << (i * 8);
146     if (propsRes->DictionarySize == 0)
147       propsRes->DictionarySize = 1;
148   }
149   #endif
150   return LZMA_RESULT_OK;
151 }
152
153 #define kLzmaStreamWasFinishedId (-1)
154
155 int LzmaDecode(CLzmaDecoderState *vs,
156     #ifdef _LZMA_IN_CB
157     ILzmaInCallback *InCallback,
158     #else
159     const unsigned char *inStream, SizeT inSize, SizeT *inSizeProcessed,
160     #endif
161     unsigned char *outStream, SizeT outSize, SizeT *outSizeProcessed)
162 {
163   CProb *p = vs->Probs;
164   SizeT nowPos = 0;
165   Byte previousByte = 0;
166   UInt32 posStateMask = (1 << (vs->Properties.pb)) - 1;
167   UInt32 literalPosMask = (1 << (vs->Properties.lp)) - 1;
168   int lc = vs->Properties.lc;
169
170   #ifdef _LZMA_OUT_READ
171   
172   UInt32 Range = vs->Range;
173   UInt32 Code = vs->Code;
174   #ifdef _LZMA_IN_CB
175   const Byte *Buffer = vs->Buffer;
176   const Byte *BufferLim = vs->BufferLim;
177   #else
178   const Byte *Buffer = inStream;
179   const Byte *BufferLim = inStream + inSize;
180   #endif
181   int state = vs->State;
182   UInt32 rep0 = vs->Reps[0], rep1 = vs->Reps[1], rep2 = vs->Reps[2], rep3 = vs->Reps[3];
183   int len = vs->RemainLen;
184   UInt32 globalPos = vs->GlobalPos;
185   UInt32 distanceLimit = vs->DistanceLimit;
186
187   Byte *dictionary = vs->Dictionary;
188   UInt32 dictionarySize = vs->Properties.DictionarySize;
189   UInt32 dictionaryPos = vs->DictionaryPos;
190
191   Byte tempDictionary[4];
192
193   #ifndef _LZMA_IN_CB
194   *inSizeProcessed = 0;
195   #endif
196   *outSizeProcessed = 0;
197   if (len == kLzmaStreamWasFinishedId)
198     return LZMA_RESULT_OK;
199
200   if (dictionarySize == 0)
201   {
202     dictionary = tempDictionary;
203     dictionarySize = 1;
204     tempDictionary[0] = vs->TempDictionary[0];
205   }
206
207   if (len == kLzmaNeedInitId)
208   {
209     {
210       UInt32 numProbs = Literal + ((UInt32)LZMA_LIT_SIZE << (lc + vs->Properties.lp));
211       UInt32 i;
212       for (i = 0; i < numProbs; i++)
213         p[i] = kBitModelTotal >> 1; 
214       rep0 = rep1 = rep2 = rep3 = 1;
215       state = 0;
216       globalPos = 0;
217       distanceLimit = 0;
218       dictionaryPos = 0;
219       dictionary[dictionarySize - 1] = 0;
220       #ifdef _LZMA_IN_CB
221       RC_INIT;
222       #else
223       RC_INIT(inStream, inSize);
224       #endif
225     }
226     len = 0;
227   }
228   while(len != 0 && nowPos < outSize)
229   {
230     UInt32 pos = dictionaryPos - rep0;
231     if (pos >= dictionarySize)
232       pos += dictionarySize;
233     outStream[nowPos++] = dictionary[dictionaryPos] = dictionary[pos];
234     if (++dictionaryPos == dictionarySize)
235       dictionaryPos = 0;
236     len--;
237   }
238   if (dictionaryPos == 0)
239     previousByte = dictionary[dictionarySize - 1];
240   else
241     previousByte = dictionary[dictionaryPos - 1];
242
243   #else /* if !_LZMA_OUT_READ */
244
245   int state = 0;
246   UInt32 rep0 = 1, rep1 = 1, rep2 = 1, rep3 = 1;
247   int len = 0;
248   const Byte *Buffer;
249   const Byte *BufferLim;
250   UInt32 Range;
251   UInt32 Code;
252
253   #ifndef _LZMA_IN_CB
254   *inSizeProcessed = 0;
255   #endif
256   *outSizeProcessed = 0;
257
258   {
259     UInt32 i;
260     UInt32 numProbs = Literal + ((UInt32)LZMA_LIT_SIZE << (lc + vs->Properties.lp));
261     for (i = 0; i < numProbs; i++)
262       p[i] = kBitModelTotal >> 1;
263   }
264   
265   #ifdef _LZMA_IN_CB
266   RC_INIT;
267   #else
268   RC_INIT(inStream, inSize);
269   #endif
270
271   #endif /* _LZMA_OUT_READ */
272
273   while(nowPos < outSize)
274   {
275     CProb *prob;
276     UInt32 bound;
277     int posState = (int)(
278         (nowPos 
279         #ifdef _LZMA_OUT_READ
280         + globalPos
281         #endif
282         )
283         & posStateMask);
284
285     prob = p + IsMatch + (state << kNumPosBitsMax) + posState;
286     IfBit0(prob)
287     {
288       int symbol = 1;
289       UpdateBit0(prob)
290       prob = p + Literal + (LZMA_LIT_SIZE * 
291         (((
292         (nowPos 
293         #ifdef _LZMA_OUT_READ
294         + globalPos
295         #endif
296         )
297         & literalPosMask) << lc) + (previousByte >> (8 - lc))));
298
299       if (state >= kNumLitStates)
300       {
301         int matchByte;
302         #ifdef _LZMA_OUT_READ
303         UInt32 pos = dictionaryPos - rep0;
304         if (pos >= dictionarySize)
305           pos += dictionarySize;
306         matchByte = dictionary[pos];
307         #else
308         matchByte = outStream[nowPos - rep0];
309         #endif
310         do
311         {
312           int bit;
313           CProb *probLit;
314           matchByte <<= 1;
315           bit = (matchByte & 0x100);
316           probLit = prob + 0x100 + bit + symbol;
317           RC_GET_BIT2(probLit, symbol, if (bit != 0) break, if (bit == 0) break)
318         }
319         while (symbol < 0x100);
320       }
321       while (symbol < 0x100)
322       {
323         CProb *probLit = prob + symbol;
324         RC_GET_BIT(probLit, symbol)
325       }
326       previousByte = (Byte)symbol;
327
328       outStream[nowPos++] = previousByte;
329       #ifdef _LZMA_OUT_READ
330       if (distanceLimit < dictionarySize)
331         distanceLimit++;
332
333       dictionary[dictionaryPos] = previousByte;
334       if (++dictionaryPos == dictionarySize)
335         dictionaryPos = 0;
336       #endif
337       if (state < 4) state = 0;
338       else if (state < 10) state -= 3;
339       else state -= 6;
340     }
341     else             
342     {
343       UpdateBit1(prob);
344       prob = p + IsRep + state;
345       IfBit0(prob)
346       {
347         UpdateBit0(prob);
348         rep3 = rep2;
349         rep2 = rep1;
350         rep1 = rep0;
351         state = state < kNumLitStates ? 0 : 3;
352         prob = p + LenCoder;
353       }
354       else
355       {
356         UpdateBit1(prob);
357         prob = p + IsRepG0 + state;
358         IfBit0(prob)
359         {
360           UpdateBit0(prob);
361           prob = p + IsRep0Long + (state << kNumPosBitsMax) + posState;
362           IfBit0(prob)
363           {
364             #ifdef _LZMA_OUT_READ
365             UInt32 pos;
366             #endif
367             UpdateBit0(prob);
368             
369             #ifdef _LZMA_OUT_READ
370             if (distanceLimit == 0)
371             #else
372             if (nowPos == 0)
373             #endif
374               return LZMA_RESULT_DATA_ERROR;
375             
376             state = state < kNumLitStates ? 9 : 11;
377             #ifdef _LZMA_OUT_READ
378             pos = dictionaryPos - rep0;
379             if (pos >= dictionarySize)
380               pos += dictionarySize;
381             previousByte = dictionary[pos];
382             dictionary[dictionaryPos] = previousByte;
383             if (++dictionaryPos == dictionarySize)
384               dictionaryPos = 0;
385             #else
386             previousByte = outStream[nowPos - rep0];
387             #endif
388             outStream[nowPos++] = previousByte;
389             #ifdef _LZMA_OUT_READ
390             if (distanceLimit < dictionarySize)
391               distanceLimit++;
392             #endif
393
394             continue;
395           }
396           else
397           {
398             UpdateBit1(prob);
399           }
400         }
401         else
402         {
403           UInt32 distance;
404           UpdateBit1(prob);
405           prob = p + IsRepG1 + state;
406           IfBit0(prob)
407           {
408             UpdateBit0(prob);
409             distance = rep1;
410           }
411           else 
412           {
413             UpdateBit1(prob);
414             prob = p + IsRepG2 + state;
415             IfBit0(prob)
416             {
417               UpdateBit0(prob);
418               distance = rep2;
419             }
420             else
421             {
422               UpdateBit1(prob);
423               distance = rep3;
424               rep3 = rep2;
425             }
426             rep2 = rep1;
427           }
428           rep1 = rep0;
429           rep0 = distance;
430         }
431         state = state < kNumLitStates ? 8 : 11;
432         prob = p + RepLenCoder;
433       }
434       {
435         int numBits, offset;
436         CProb *probLen = prob + LenChoice;
437         IfBit0(probLen)
438         {
439           UpdateBit0(probLen);
440           probLen = prob + LenLow + (posState << kLenNumLowBits);
441           offset = 0;
442           numBits = kLenNumLowBits;
443         }
444         else
445         {
446           UpdateBit1(probLen);
447           probLen = prob + LenChoice2;
448           IfBit0(probLen)
449           {
450             UpdateBit0(probLen);
451             probLen = prob + LenMid + (posState << kLenNumMidBits);
452             offset = kLenNumLowSymbols;
453             numBits = kLenNumMidBits;
454           }
455           else
456           {
457             UpdateBit1(probLen);
458             probLen = prob + LenHigh;
459             offset = kLenNumLowSymbols + kLenNumMidSymbols;
460             numBits = kLenNumHighBits;
461           }
462         }
463         RangeDecoderBitTreeDecode(probLen, numBits, len);
464         len += offset;
465       }
466
467       if (state < 4)
468       {
469         int posSlot;
470         state += kNumLitStates;
471         prob = p + PosSlot +
472             ((len < kNumLenToPosStates ? len : kNumLenToPosStates - 1) << 
473             kNumPosSlotBits);
474         RangeDecoderBitTreeDecode(prob, kNumPosSlotBits, posSlot);
475         if (posSlot >= kStartPosModelIndex)
476         {
477           int numDirectBits = ((posSlot >> 1) - 1);
478           rep0 = (2 | ((UInt32)posSlot & 1));
479           if (posSlot < kEndPosModelIndex)
480           {
481             rep0 <<= numDirectBits;
482             prob = p + SpecPos + rep0 - posSlot - 1;
483           }
484           else
485           {
486             numDirectBits -= kNumAlignBits;
487             do
488             {
489               RC_NORMALIZE
490               Range >>= 1;
491               rep0 <<= 1;
492               if (Code >= Range)
493               {
494                 Code -= Range;
495                 rep0 |= 1;
496               }
497             }
498             while (--numDirectBits != 0);
499             prob = p + Align;
500             rep0 <<= kNumAlignBits;
501             numDirectBits = kNumAlignBits;
502           }
503           {
504             int i = 1;
505             int mi = 1;
506             do
507             {
508               CProb *prob3 = prob + mi;
509               RC_GET_BIT2(prob3, mi, ; , rep0 |= i);
510               i <<= 1;
511             }
512             while(--numDirectBits != 0);
513           }
514         }
515         else
516           rep0 = posSlot;
517         if (++rep0 == (UInt32)(0))
518         {
519           /* it's for stream version */
520           len = kLzmaStreamWasFinishedId;
521           break;
522         }
523       }
524
525       len += kMatchMinLen;
526       #ifdef _LZMA_OUT_READ
527       if (rep0 > distanceLimit) 
528       #else
529       if (rep0 > nowPos)
530       #endif
531         return LZMA_RESULT_DATA_ERROR;
532
533       #ifdef _LZMA_OUT_READ
534       if (dictionarySize - distanceLimit > (UInt32)len)
535         distanceLimit += len;
536       else
537         distanceLimit = dictionarySize;
538       #endif
539
540       do
541       {
542         #ifdef _LZMA_OUT_READ
543         UInt32 pos = dictionaryPos - rep0;
544         if (pos >= dictionarySize)
545           pos += dictionarySize;
546         previousByte = dictionary[pos];
547         dictionary[dictionaryPos] = previousByte;
548         if (++dictionaryPos == dictionarySize)
549           dictionaryPos = 0;
550         #else
551         previousByte = outStream[nowPos - rep0];
552         #endif
553         len--;
554         outStream[nowPos++] = previousByte;
555       }
556       while(len != 0 && nowPos < outSize);
557     }
558   }
559   RC_NORMALIZE;
560
561   #ifdef _LZMA_OUT_READ
562   vs->Range = Range;
563   vs->Code = Code;
564   vs->DictionaryPos = dictionaryPos;
565   vs->GlobalPos = globalPos + (UInt32)nowPos;
566   vs->DistanceLimit = distanceLimit;
567   vs->Reps[0] = rep0;
568   vs->Reps[1] = rep1;
569   vs->Reps[2] = rep2;
570   vs->Reps[3] = rep3;
571   vs->State = state;
572   vs->RemainLen = len;
573   vs->TempDictionary[0] = tempDictionary[0];
574   #endif
575
576   #ifdef _LZMA_IN_CB
577   vs->Buffer = Buffer;
578   vs->BufferLim = BufferLim;
579   #else
580   *inSizeProcessed = (SizeT)(Buffer - inStream);
581   #endif
582   *outSizeProcessed = nowPos;
583   return LZMA_RESULT_OK;
584 }