ramips: update mips multi-machine stuff
[openwrt.git] / target / linux / adm5120 / image / lzma-loader / 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 }
This page took 0.083839 seconds and 5 git commands to generate.