rockchip/rk3399: Fix rkclk_init() to actually use PERILP1_PCLK_HZ
[coreboot.git] / src / lib / lzmadecode.c
blobfbf15964a66ac32a8fdf8cb619ee21954c434ed6
1 /*
2 LzmaDecode.c
3 LZMA Decoder (optimized for Speed version)
5 LZMA SDK 4.40 Copyright (c) 1999-2006 Igor Pavlov (2006-05-01)
6 http://www.7-zip.org/
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.
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.
22 #include "lzmadecode.h"
23 #include <stdint.h>
25 #define kNumTopBits 24
26 #define kTopValue ((UInt32)1 << kNumTopBits)
28 #define kNumBitModelTotalBits 11
29 #define kBitModelTotal (1 << kNumBitModelTotalBits)
30 #define kNumMoveBits 5
32 /* Use 32-bit reads whenever possible to avoid bad flash performance. Fall back
33 * to byte reads for last 4 bytes since RC_TEST returns an error when BufferLim
34 * is *reached* (not surpassed!), meaning we can't allow that to happen while
35 * there are still bytes to decode from the algorithm's point of view. */
36 #define RC_READ_BYTE (look_ahead_ptr < 4 ? look_ahead.raw[look_ahead_ptr++] \
37 : ((((uintptr_t) Buffer & 3) || ((SizeT) (BufferLim - Buffer) <= 4)) ? (*Buffer++) \
38 : ((look_ahead.dw = *(UInt32 *)Buffer), (Buffer += 4), (look_ahead_ptr = 1), look_ahead.raw[0])))
40 #define RC_INIT2 Code = 0; Range = 0xFFFFFFFF; \
41 { int i; for(i = 0; i < 5; i++) { RC_TEST; Code = (Code << 8) | RC_READ_BYTE; }}
44 #define RC_TEST { if (Buffer == BufferLim) return LZMA_RESULT_DATA_ERROR; }
46 #define RC_INIT(buffer, bufferSize) Buffer = buffer; BufferLim = buffer + bufferSize; RC_INIT2
49 #define RC_NORMALIZE if (Range < kTopValue) { RC_TEST; Range <<= 8; Code = (Code << 8) | RC_READ_BYTE; }
51 #define IfBit0(p) RC_NORMALIZE; bound = (Range >> kNumBitModelTotalBits) * *(p); if (Code < bound)
52 #define UpdateBit0(p) Range = bound; *(p) += (kBitModelTotal - *(p)) >> kNumMoveBits;
53 #define UpdateBit1(p) Range -= bound; Code -= bound; *(p) -= (*(p)) >> kNumMoveBits;
55 #define RC_GET_BIT2(p, mi, A0, A1) IfBit0(p) \
56 { UpdateBit0(p); mi <<= 1; A0; } else \
57 { UpdateBit1(p); mi = (mi + mi) + 1; A1; }
59 #define RC_GET_BIT(p, mi) RC_GET_BIT2(p, mi, ; , ;)
61 #define RangeDecoderBitTreeDecode(probs, numLevels, res) \
62 { int i = numLevels; res = 1; \
63 do { CProb *cp = probs + res; RC_GET_BIT(cp, res) } while(--i != 0); \
64 res -= (1 << numLevels); }
67 #define kNumPosBitsMax 4
68 #define kNumPosStatesMax (1 << kNumPosBitsMax)
70 #define kLenNumLowBits 3
71 #define kLenNumLowSymbols (1 << kLenNumLowBits)
72 #define kLenNumMidBits 3
73 #define kLenNumMidSymbols (1 << kLenNumMidBits)
74 #define kLenNumHighBits 8
75 #define kLenNumHighSymbols (1 << kLenNumHighBits)
77 #define LenChoice 0
78 #define LenChoice2 (LenChoice + 1)
79 #define LenLow (LenChoice2 + 1)
80 #define LenMid (LenLow + (kNumPosStatesMax << kLenNumLowBits))
81 #define LenHigh (LenMid + (kNumPosStatesMax << kLenNumMidBits))
82 #define kNumLenProbs (LenHigh + kLenNumHighSymbols)
85 #define kNumStates 12
86 #define kNumLitStates 7
88 #define kStartPosModelIndex 4
89 #define kEndPosModelIndex 14
90 #define kNumFullDistances (1 << (kEndPosModelIndex >> 1))
92 #define kNumPosSlotBits 6
93 #define kNumLenToPosStates 4
95 #define kNumAlignBits 4
96 #define kAlignTableSize (1 << kNumAlignBits)
98 #define kMatchMinLen 2
100 #define IsMatch 0
101 #define IsRep (IsMatch + (kNumStates << kNumPosBitsMax))
102 #define IsRepG0 (IsRep + kNumStates)
103 #define IsRepG1 (IsRepG0 + kNumStates)
104 #define IsRepG2 (IsRepG1 + kNumStates)
105 #define IsRep0Long (IsRepG2 + kNumStates)
106 #define PosSlot (IsRep0Long + (kNumStates << kNumPosBitsMax))
107 #define SpecPos (PosSlot + (kNumLenToPosStates << kNumPosSlotBits))
108 #define Align (SpecPos + kNumFullDistances - kEndPosModelIndex)
109 #define LenCoder (Align + kAlignTableSize)
110 #define RepLenCoder (LenCoder + kNumLenProbs)
111 #define Literal (RepLenCoder + kNumLenProbs)
113 #if Literal != LZMA_BASE_SIZE
114 StopCompilingDueBUG
115 #endif
117 int LzmaDecodeProperties(CLzmaProperties *propsRes, const unsigned char *propsData, int size)
119 unsigned char prop0;
120 if (size < LZMA_PROPERTIES_SIZE)
121 return LZMA_RESULT_DATA_ERROR;
122 prop0 = propsData[0];
123 if (prop0 >= (9 * 5 * 5))
124 return LZMA_RESULT_DATA_ERROR;
126 for (propsRes->pb = 0; prop0 >= (9 * 5); propsRes->pb++, prop0 -= (9 * 5));
127 for (propsRes->lp = 0; prop0 >= 9; propsRes->lp++, prop0 -= 9);
128 propsRes->lc = prop0;
130 unsigned char remainder = (unsigned char)(prop0 / 9);
131 propsRes->lc = prop0 % 9;
132 propsRes->pb = remainder / 5;
133 propsRes->lp = remainder % 5;
137 return LZMA_RESULT_OK;
140 #define kLzmaStreamWasFinishedId (-1)
142 int LzmaDecode(CLzmaDecoderState *vs,
143 const unsigned char *inStream, SizeT inSize, SizeT *inSizeProcessed,
144 unsigned char *outStream, SizeT outSize, SizeT *outSizeProcessed)
146 CProb *p = vs->Probs;
147 SizeT nowPos = 0;
148 Byte previousByte = 0;
149 UInt32 posStateMask = (1 << (vs->Properties.pb)) - 1;
150 UInt32 literalPosMask = (1 << (vs->Properties.lp)) - 1;
151 int lc = vs->Properties.lc;
154 int state = 0;
155 UInt32 rep0 = 1, rep1 = 1, rep2 = 1, rep3 = 1;
156 int len = 0;
157 const Byte *Buffer;
158 const Byte *BufferLim;
159 int look_ahead_ptr = 4;
160 union
162 Byte raw[4];
163 UInt32 dw;
164 } look_ahead;
165 UInt32 Range;
166 UInt32 Code;
168 *inSizeProcessed = 0;
169 *outSizeProcessed = 0;
172 UInt32 i;
173 UInt32 numProbs = Literal + ((UInt32)LZMA_LIT_SIZE << (lc + vs->Properties.lp));
174 for (i = 0; i < numProbs; i++)
175 p[i] = kBitModelTotal >> 1;
178 RC_INIT(inStream, inSize);
181 while(nowPos < outSize)
183 CProb *prob;
184 UInt32 bound;
185 int posState = (int)(
186 (nowPos
188 & posStateMask);
190 prob = p + IsMatch + (state << kNumPosBitsMax) + posState;
191 IfBit0(prob)
193 int symbol = 1;
194 UpdateBit0(prob)
195 prob = p + Literal + (LZMA_LIT_SIZE *
197 (nowPos
199 & literalPosMask) << lc) + (previousByte >> (8 - lc))));
201 if (state >= kNumLitStates)
203 int matchByte;
204 matchByte = outStream[nowPos - rep0];
207 int bit;
208 CProb *probLit;
209 matchByte <<= 1;
210 bit = (matchByte & 0x100);
211 probLit = prob + 0x100 + bit + symbol;
212 RC_GET_BIT2(probLit, symbol, if (bit != 0) break, if (bit == 0) break)
214 while (symbol < 0x100);
216 while (symbol < 0x100)
218 CProb *probLit = prob + symbol;
219 RC_GET_BIT(probLit, symbol)
221 previousByte = (Byte)symbol;
223 outStream[nowPos++] = previousByte;
224 if (state < 4) state = 0;
225 else if (state < 10) state -= 3;
226 else state -= 6;
228 else
230 UpdateBit1(prob);
231 prob = p + IsRep + state;
232 IfBit0(prob)
234 UpdateBit0(prob);
235 rep3 = rep2;
236 rep2 = rep1;
237 rep1 = rep0;
238 state = state < kNumLitStates ? 0 : 3;
239 prob = p + LenCoder;
241 else
243 UpdateBit1(prob);
244 prob = p + IsRepG0 + state;
245 IfBit0(prob)
247 UpdateBit0(prob);
248 prob = p + IsRep0Long + (state << kNumPosBitsMax) + posState;
249 IfBit0(prob)
251 UpdateBit0(prob);
253 if (nowPos == 0)
254 return LZMA_RESULT_DATA_ERROR;
256 state = state < kNumLitStates ? 9 : 11;
257 previousByte = outStream[nowPos - rep0];
258 outStream[nowPos++] = previousByte;
260 continue;
262 else
264 UpdateBit1(prob);
267 else
269 UInt32 distance;
270 UpdateBit1(prob);
271 prob = p + IsRepG1 + state;
272 IfBit0(prob)
274 UpdateBit0(prob);
275 distance = rep1;
277 else
279 UpdateBit1(prob);
280 prob = p + IsRepG2 + state;
281 IfBit0(prob)
283 UpdateBit0(prob);
284 distance = rep2;
286 else
288 UpdateBit1(prob);
289 distance = rep3;
290 rep3 = rep2;
292 rep2 = rep1;
294 rep1 = rep0;
295 rep0 = distance;
297 state = state < kNumLitStates ? 8 : 11;
298 prob = p + RepLenCoder;
301 int numBits, offset;
302 CProb *probLen = prob + LenChoice;
303 IfBit0(probLen)
305 UpdateBit0(probLen);
306 probLen = prob + LenLow + (posState << kLenNumLowBits);
307 offset = 0;
308 numBits = kLenNumLowBits;
310 else
312 UpdateBit1(probLen);
313 probLen = prob + LenChoice2;
314 IfBit0(probLen)
316 UpdateBit0(probLen);
317 probLen = prob + LenMid + (posState << kLenNumMidBits);
318 offset = kLenNumLowSymbols;
319 numBits = kLenNumMidBits;
321 else
323 UpdateBit1(probLen);
324 probLen = prob + LenHigh;
325 offset = kLenNumLowSymbols + kLenNumMidSymbols;
326 numBits = kLenNumHighBits;
329 RangeDecoderBitTreeDecode(probLen, numBits, len);
330 len += offset;
333 if (state < 4)
335 int posSlot;
336 state += kNumLitStates;
337 prob = p + PosSlot +
338 ((len < kNumLenToPosStates ? len : kNumLenToPosStates - 1) <<
339 kNumPosSlotBits);
340 RangeDecoderBitTreeDecode(prob, kNumPosSlotBits, posSlot);
341 if (posSlot >= kStartPosModelIndex)
343 int numDirectBits = ((posSlot >> 1) - 1);
344 rep0 = (2 | ((UInt32)posSlot & 1));
345 if (posSlot < kEndPosModelIndex)
347 rep0 <<= numDirectBits;
348 prob = p + SpecPos + rep0 - posSlot - 1;
350 else
352 numDirectBits -= kNumAlignBits;
355 RC_NORMALIZE
356 Range >>= 1;
357 rep0 <<= 1;
358 if (Code >= Range)
360 Code -= Range;
361 rep0 |= 1;
364 while (--numDirectBits != 0);
365 prob = p + Align;
366 rep0 <<= kNumAlignBits;
367 numDirectBits = kNumAlignBits;
370 int i = 1;
371 int mi = 1;
374 CProb *prob3 = prob + mi;
375 RC_GET_BIT2(prob3, mi, ; , rep0 |= i);
376 i <<= 1;
378 while(--numDirectBits != 0);
381 else
382 rep0 = posSlot;
383 if (++rep0 == (UInt32)(0))
385 /* it's for stream version */
386 len = kLzmaStreamWasFinishedId;
387 break;
391 len += kMatchMinLen;
392 if (rep0 > nowPos)
393 return LZMA_RESULT_DATA_ERROR;
398 previousByte = outStream[nowPos - rep0];
399 len--;
400 outStream[nowPos++] = previousByte;
402 while(len != 0 && nowPos < outSize);
405 RC_NORMALIZE;
408 *inSizeProcessed = (SizeT)(Buffer - inStream);
409 *outSizeProcessed = nowPos;
410 return LZMA_RESULT_OK;