Root/target/linux/avr32/image/u-boot/patches/001-add_lzma_decompression_support.patch

1From d37394e9ca1b85407408719feb2468c5affefa4a Mon Sep 17 00:00:00 2001
2From: Gabor Juhos <juhosg at openwrt.org>
3Date: Fri, 9 May 2008 17:26:14 +0200
4Subject: [PATCH] add LZMA decompression support
5
6---
7 common/cmd_bootm.c | 18 ++
8 common/image.c | 1 +
9 include/LzmaWrapper.h | 36 +++
10 include/image.h | 1 +
11 lib_generic/LzmaDecode.c | 602 +++++++++++++++++++++++++++++++++++++++++++++
12 lib_generic/LzmaDecode.h | 113 +++++++++
13 lib_generic/LzmaTypes.h | 45 ++++
14 lib_generic/LzmaWrapper.c | 197 +++++++++++++++
15 lib_generic/Makefile | 2 +
16 9 files changed, 1015 insertions(+), 0 deletions(-)
17 create mode 100644 include/LzmaWrapper.h
18 create mode 100644 lib_generic/LzmaDecode.c
19 create mode 100644 lib_generic/LzmaDecode.h
20 create mode 100644 lib_generic/LzmaTypes.h
21 create mode 100644 lib_generic/LzmaWrapper.c
22
23diff --git a/common/cmd_bootm.c b/common/cmd_bootm.c
24index 0d67132..6071817 100644
25--- a/common/cmd_bootm.c
26+++ b/common/cmd_bootm.c
27@@ -32,6 +32,7 @@
28 #include <malloc.h>
29 #include <zlib.h>
30 #include <bzlib.h>
31+#include <LzmaWrapper.h>
32 #include <environment.h>
33 #include <lmb.h>
34 #include <asm/byteorder.h>
35@@ -237,6 +238,7 @@ int do_bootm (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
36             puts("OK\n");
37         }
38         break;
39+#ifndef CONFIG_NO_GZIP
40     case IH_COMP_GZIP:
41         printf (" Uncompressing %s ... ", type_name);
42         if (gunzip ((void *)load_start, unc_len,
43@@ -249,6 +251,7 @@ int do_bootm (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
44 
45         load_end = load_start + os_len;
46         break;
47+#endif
48 #ifdef CONFIG_BZIP2
49     case IH_COMP_BZIP2:
50         printf (" Uncompressing %s ... ", type_name);
51@@ -270,6 +273,21 @@ int do_bootm (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
52         load_end = load_start + unc_len;
53         break;
54 #endif /* CONFIG_BZIP2 */
55+#ifdef CONFIG_LZMA
56+ case IH_COMP_LZMA:
57+ printf (" Uncompressing %s ... ", type_name);
58+ int i = lzma_inflate ((unsigned char *)os_data, os_len,
59+ (unsigned char *)load_start, &unc_len);
60+ if (i != LZMA_RESULT_OK) {
61+ printf ("LZMA: uncompress or overwrite error %d "
62+ "- must RESET board to recover\n", i);
63+ show_boot_progress (-6);
64+ do_reset (cmdtp, flag, argc, argv);
65+ }
66+
67+ load_end = load_start + unc_len;
68+ break;
69+#endif /* CONFIG_LZMA */
70     default:
71         if (iflag)
72             enable_interrupts();
73diff --git a/common/image.c b/common/image.c
74index 67e594d..9b42ae9 100644
75--- a/common/image.c
76+++ b/common/image.c
77@@ -148,6 +148,7 @@ static table_entry_t uimage_comp[] = {
78     { IH_COMP_NONE, "none", "uncompressed", },
79     { IH_COMP_BZIP2, "bzip2", "bzip2 compressed", },
80     { IH_COMP_GZIP, "gzip", "gzip compressed", },
81+ { IH_COMP_LZMA, "lzma", "lzma compressed", },
82     { -1, "", "", },
83 };
84 
85diff --git a/include/LzmaWrapper.h b/include/LzmaWrapper.h
86new file mode 100644
87index 0000000..2f9a3ff
88--- /dev/null
89+++ b/include/LzmaWrapper.h
90@@ -0,0 +1,36 @@
91+/******************************************************************************
92+**
93+** FILE NAME : LzmaWrapper.h
94+** PROJECT : bootloader
95+** MODULES : U-boot
96+**
97+** DATE : 2 Nov 2006
98+** AUTHOR : Lin Mars
99+** DESCRIPTION : LZMA decoder support for U-boot 1.1.5
100+** COPYRIGHT : Copyright (c) 2006
101+** Infineon Technologies AG
102+** Am Campeon 1-12, 85579 Neubiberg, Germany
103+**
104+** This program is free software; you can redistribute it and/or modify
105+** it under the terms of the GNU General Public License as published by
106+** the Free Software Foundation; either version 2 of the License, or
107+** (at your option) any later version.
108+**
109+** HISTORY
110+** $Date $Author $Comment
111+** 2 Nov 2006 Lin Mars init version which derived from LzmaTest.c from
112+** LZMA v4.43 SDK
113+*******************************************************************************/
114+#ifndef __LZMA_WRAPPER_H__
115+#define __LZMA_WRAPPER_H__
116+
117+#ifndef LZMA_RESULT_OK
118+#define LZMA_RESULT_OK 0
119+#endif
120+#ifndef LZMA_RESULT_DATA_ERROR
121+#define LZMA_RESULT_DATA_ERROR 1
122+#endif
123+
124+extern int lzma_inflate(unsigned char *source, int s_len, unsigned char *dest, int *d_len);
125+
126+#endif /*__LZMA_WRAPPER_H__*/
127diff --git a/include/image.h b/include/image.h
128index 664e51e..6de51c4 100644
129--- a/include/image.h
130+++ b/include/image.h
131@@ -164,6 +164,7 @@
132 #define IH_COMP_NONE 0 /* No Compression Used */
133 #define IH_COMP_GZIP 1 /* gzip Compression Used */
134 #define IH_COMP_BZIP2 2 /* bzip2 Compression Used */
135+#define IH_COMP_LZMA 3 /* lzma Compression used */
136 
137 #define IH_MAGIC 0x27051956 /* Image Magic Number */
138 #define IH_NMLEN 32 /* Image Name Length */
139diff --git a/lib_generic/LzmaDecode.c b/lib_generic/LzmaDecode.c
140new file mode 100644
141index 0000000..d876e8b
142--- /dev/null
143+++ b/lib_generic/LzmaDecode.c
144@@ -0,0 +1,602 @@
145+/*
146+ LzmaDecode.c
147+ LZMA Decoder (optimized for Speed version)
148+
149+ LZMA SDK 4.40 Copyright (c) 1999-2006 Igor Pavlov (2006-05-01)
150+ http://www.7-zip.org/
151+
152+ LZMA SDK is licensed under two licenses:
153+ 1) GNU Lesser General Public License (GNU LGPL)
154+ 2) Common Public License (CPL)
155+ It means that you can select one of these two licenses and
156+ follow rules of that license.
157+
158+ SPECIAL EXCEPTION:
159+ Igor Pavlov, as the author of this Code, expressly permits you to
160+ statically or dynamically link your Code (or bind by name) to the
161+ interfaces of this file without subjecting your linked Code to the
162+ terms of the CPL or GNU LGPL. Any modifications or additions
163+ to this file, however, are subject to the LGPL or CPL terms.
164+*/
165+
166+#include <config.h>
167+
168+#ifdef CONFIG_LZMA
169+
170+#include "LzmaDecode.h"
171+
172+#define kNumTopBits 24
173+#define kTopValue ((UInt32)1 << kNumTopBits)
174+
175+#define kNumBitModelTotalBits 11
176+#define kBitModelTotal (1 << kNumBitModelTotalBits)
177+#define kNumMoveBits 5
178+
179+#define RC_READ_BYTE (*Buffer++)
180+
181+#define RC_INIT2 Code = 0; Range = 0xFFFFFFFF; \
182+ { int i; for(i = 0; i < 5; i++) { RC_TEST; Code = (Code << 8) | RC_READ_BYTE; }}
183+
184+#ifdef _LZMA_IN_CB
185+
186+#define RC_TEST { if (Buffer == BufferLim) \
187+ { SizeT size; int result = InCallback->Read(InCallback, &Buffer, &size); if (result != LZMA_RESULT_OK) { printf("ERROR, %s, %d\n", __FILE__, __LINE__); return result; } \
188+ BufferLim = Buffer + size; if (size == 0) { printf("ERROR, %s, %d\n", __FILE__, __LINE__); return LZMA_RESULT_DATA_ERROR; } }}
189+
190+#define RC_INIT Buffer = BufferLim = 0; RC_INIT2
191+
192+#else
193+
194+#define RC_TEST { if (Buffer == BufferLim) { printf("ERROR, %s, %d\n", __FILE__, __LINE__); return LZMA_RESULT_DATA_ERROR; } }
195+
196+#define RC_INIT(buffer, bufferSize) Buffer = buffer; BufferLim = buffer + bufferSize; RC_INIT2
197+
198+#endif
199+
200+#define RC_NORMALIZE if (Range < kTopValue) { RC_TEST; Range <<= 8; Code = (Code << 8) | RC_READ_BYTE; }
201+
202+#define IfBit0(p) RC_NORMALIZE; bound = (Range >> kNumBitModelTotalBits) * *(p); if (Code < bound)
203+#define UpdateBit0(p) Range = bound; *(p) += (kBitModelTotal - *(p)) >> kNumMoveBits;
204+#define UpdateBit1(p) Range -= bound; Code -= bound; *(p) -= (*(p)) >> kNumMoveBits;
205+
206+#define RC_GET_BIT2(p, mi, A0, A1) IfBit0(p) \
207+ { UpdateBit0(p); mi <<= 1; A0; } else \
208+ { UpdateBit1(p); mi = (mi + mi) + 1; A1; }
209+
210+#define RC_GET_BIT(p, mi) RC_GET_BIT2(p, mi, ; , ;)
211+
212+#define RangeDecoderBitTreeDecode(probs, numLevels, res) \
213+ { int i = numLevels; res = 1; \
214+ do { CProb *p = probs + res; RC_GET_BIT(p, res) } while(--i != 0); \
215+ res -= (1 << numLevels); }
216+
217+
218+#define kNumPosBitsMax 4
219+#define kNumPosStatesMax (1 << kNumPosBitsMax)
220+
221+#define kLenNumLowBits 3
222+#define kLenNumLowSymbols (1 << kLenNumLowBits)
223+#define kLenNumMidBits 3
224+#define kLenNumMidSymbols (1 << kLenNumMidBits)
225+#define kLenNumHighBits 8
226+#define kLenNumHighSymbols (1 << kLenNumHighBits)
227+
228+#define LenChoice 0
229+#define LenChoice2 (LenChoice + 1)
230+#define LenLow (LenChoice2 + 1)
231+#define LenMid (LenLow + (kNumPosStatesMax << kLenNumLowBits))
232+#define LenHigh (LenMid + (kNumPosStatesMax << kLenNumMidBits))
233+#define kNumLenProbs (LenHigh + kLenNumHighSymbols)
234+
235+
236+#define kNumStates 12
237+#define kNumLitStates 7
238+
239+#define kStartPosModelIndex 4
240+#define kEndPosModelIndex 14
241+#define kNumFullDistances (1 << (kEndPosModelIndex >> 1))
242+
243+#define kNumPosSlotBits 6
244+#define kNumLenToPosStates 4
245+
246+#define kNumAlignBits 4
247+#define kAlignTableSize (1 << kNumAlignBits)
248+
249+#define kMatchMinLen 2
250+
251+#define IsMatch 0
252+#define IsRep (IsMatch + (kNumStates << kNumPosBitsMax))
253+#define IsRepG0 (IsRep + kNumStates)
254+#define IsRepG1 (IsRepG0 + kNumStates)
255+#define IsRepG2 (IsRepG1 + kNumStates)
256+#define IsRep0Long (IsRepG2 + kNumStates)
257+#define PosSlot (IsRep0Long + (kNumStates << kNumPosBitsMax))
258+#define SpecPos (PosSlot + (kNumLenToPosStates << kNumPosSlotBits))
259+#define Align (SpecPos + kNumFullDistances - kEndPosModelIndex)
260+#define LenCoder (Align + kAlignTableSize)
261+#define RepLenCoder (LenCoder + kNumLenProbs)
262+#define Literal (RepLenCoder + kNumLenProbs)
263+
264+#if Literal != LZMA_BASE_SIZE
265+StopCompilingDueBUG
266+#endif
267+
268+int LzmaDecodeProperties(CLzmaProperties *propsRes, const unsigned char *propsData, int size)
269+{
270+ unsigned char prop0;
271+ if (size < LZMA_PROPERTIES_SIZE)
272+ {
273+ printf("ERROR: %s, %d\n", __FILE__, __LINE__);
274+ return LZMA_RESULT_DATA_ERROR;
275+ }
276+ prop0 = propsData[0];
277+ if (prop0 >= (9 * 5 * 5))
278+ {
279+ printf("ERROR: %s, %d\n", __FILE__, __LINE__);
280+ return LZMA_RESULT_DATA_ERROR;
281+ }
282+ {
283+ for (propsRes->pb = 0; prop0 >= (9 * 5); propsRes->pb++, prop0 -= (9 * 5));
284+ for (propsRes->lp = 0; prop0 >= 9; propsRes->lp++, prop0 -= 9);
285+ propsRes->lc = prop0;
286+ /*
287+ unsigned char remainder = (unsigned char)(prop0 / 9);
288+ propsRes->lc = prop0 % 9;
289+ propsRes->pb = remainder / 5;
290+ propsRes->lp = remainder % 5;
291+ */
292+ }
293+
294+ #ifdef _LZMA_OUT_READ
295+ {
296+ int i;
297+ propsRes->DictionarySize = 0;
298+ for (i = 0; i < 4; i++)
299+ propsRes->DictionarySize += (UInt32)(propsData[1 + i]) << (i * 8);
300+ if (propsRes->DictionarySize == 0)
301+ propsRes->DictionarySize = 1;
302+ }
303+ #endif
304+ return LZMA_RESULT_OK;
305+}
306+
307+#define kLzmaStreamWasFinishedId (-1)
308+
309+int LzmaDecode(CLzmaDecoderState *vs,
310+ #ifdef _LZMA_IN_CB
311+ ILzmaInCallback *InCallback,
312+ #else
313+ const unsigned char *inStream, SizeT inSize, SizeT *inSizeProcessed,
314+ #endif
315+ unsigned char *outStream, SizeT outSize, SizeT *outSizeProcessed)
316+{
317+ CProb *p = vs->Probs;
318+ SizeT nowPos = 0;
319+ Byte previousByte = 0;
320+ UInt32 posStateMask = (1 << (vs->Properties.pb)) - 1;
321+ UInt32 literalPosMask = (1 << (vs->Properties.lp)) - 1;
322+ int lc = vs->Properties.lc;
323+
324+ #ifdef _LZMA_OUT_READ
325+
326+ UInt32 Range = vs->Range;
327+ UInt32 Code = vs->Code;
328+ #ifdef _LZMA_IN_CB
329+ const Byte *Buffer = vs->Buffer;
330+ const Byte *BufferLim = vs->BufferLim;
331+ #else
332+ const Byte *Buffer = inStream;
333+ const Byte *BufferLim = inStream + inSize;
334+ #endif
335+ int state = vs->State;
336+ UInt32 rep0 = vs->Reps[0], rep1 = vs->Reps[1], rep2 = vs->Reps[2], rep3 = vs->Reps[3];
337+ int len = vs->RemainLen;
338+ UInt32 globalPos = vs->GlobalPos;
339+ UInt32 distanceLimit = vs->DistanceLimit;
340+
341+ Byte *dictionary = vs->Dictionary;
342+ UInt32 dictionarySize = vs->Properties.DictionarySize;
343+ UInt32 dictionaryPos = vs->DictionaryPos;
344+
345+ Byte tempDictionary[4];
346+
347+ #ifndef _LZMA_IN_CB
348+ *inSizeProcessed = 0;
349+ #endif
350+ *outSizeProcessed = 0;
351+ if (len == kLzmaStreamWasFinishedId)
352+ return LZMA_RESULT_OK;
353+
354+ if (dictionarySize == 0)
355+ {
356+ dictionary = tempDictionary;
357+ dictionarySize = 1;
358+ tempDictionary[0] = vs->TempDictionary[0];
359+ }
360+
361+ if (len == kLzmaNeedInitId)
362+ {
363+ {
364+ UInt32 numProbs = Literal + ((UInt32)LZMA_LIT_SIZE << (lc + vs->Properties.lp));
365+ UInt32 i;
366+ for (i = 0; i < numProbs; i++)
367+ p[i] = kBitModelTotal >> 1;
368+ rep0 = rep1 = rep2 = rep3 = 1;
369+ state = 0;
370+ globalPos = 0;
371+ distanceLimit = 0;
372+ dictionaryPos = 0;
373+ dictionary[dictionarySize - 1] = 0;
374+ #ifdef _LZMA_IN_CB
375+ RC_INIT;
376+ #else
377+ RC_INIT(inStream, inSize);
378+ #endif
379+ }
380+ len = 0;
381+ }
382+ while(len != 0 && nowPos < outSize)
383+ {
384+ UInt32 pos = dictionaryPos - rep0;
385+ if (pos >= dictionarySize)
386+ pos += dictionarySize;
387+ outStream[nowPos++] = dictionary[dictionaryPos] = dictionary[pos];
388+ if (++dictionaryPos == dictionarySize)
389+ dictionaryPos = 0;
390+ len--;
391+ }
392+ if (dictionaryPos == 0)
393+ previousByte = dictionary[dictionarySize - 1];
394+ else
395+ previousByte = dictionary[dictionaryPos - 1];
396+
397+ #else /* if !_LZMA_OUT_READ */
398+
399+ int state = 0;
400+ UInt32 rep0 = 1, rep1 = 1, rep2 = 1, rep3 = 1;
401+ int len = 0;
402+ const Byte *Buffer;
403+ const Byte *BufferLim;
404+ UInt32 Range;
405+ UInt32 Code;
406+
407+ #ifndef _LZMA_IN_CB
408+ *inSizeProcessed = 0;
409+ #endif
410+ *outSizeProcessed = 0;
411+
412+ {
413+ UInt32 i;
414+ UInt32 numProbs = Literal + ((UInt32)LZMA_LIT_SIZE << (lc + vs->Properties.lp));
415+ for (i = 0; i < numProbs; i++)
416+ p[i] = kBitModelTotal >> 1;
417+ }
418+
419+ #ifdef _LZMA_IN_CB
420+ RC_INIT;
421+ #else
422+ RC_INIT(inStream, inSize);
423+ #endif
424+
425+ #endif /* _LZMA_OUT_READ */
426+
427+ while(nowPos < outSize)
428+ {
429+ CProb *prob;
430+ UInt32 bound;
431+ int posState = (int)(
432+ (nowPos
433+ #ifdef _LZMA_OUT_READ
434+ + globalPos
435+ #endif
436+ )
437+ & posStateMask);
438+
439+ prob = p + IsMatch + (state << kNumPosBitsMax) + posState;
440+ IfBit0(prob)
441+ {
442+ int symbol = 1;
443+ UpdateBit0(prob)
444+ prob = p + Literal + (LZMA_LIT_SIZE *
445+ (((
446+ (nowPos
447+ #ifdef _LZMA_OUT_READ
448+ + globalPos
449+ #endif
450+ )
451+ & literalPosMask) << lc) + (previousByte >> (8 - lc))));
452+
453+ if (state >= kNumLitStates)
454+ {
455+ int matchByte;
456+ #ifdef _LZMA_OUT_READ
457+ UInt32 pos = dictionaryPos - rep0;
458+ if (pos >= dictionarySize)
459+ pos += dictionarySize;
460+ matchByte = dictionary[pos];
461+ #else
462+ matchByte = outStream[nowPos - rep0];
463+ #endif
464+ do
465+ {
466+ int bit;
467+ CProb *probLit;
468+ matchByte <<= 1;
469+ bit = (matchByte & 0x100);
470+ probLit = prob + 0x100 + bit + symbol;
471+ RC_GET_BIT2(probLit, symbol, if (bit != 0) break, if (bit == 0) break)
472+ }
473+ while (symbol < 0x100);
474+ }
475+ while (symbol < 0x100)
476+ {
477+ CProb *probLit = prob + symbol;
478+ RC_GET_BIT(probLit, symbol)
479+ }
480+ previousByte = (Byte)symbol;
481+
482+ outStream[nowPos++] = previousByte;
483+ #ifdef _LZMA_OUT_READ
484+ if (distanceLimit < dictionarySize)
485+ distanceLimit++;
486+
487+ dictionary[dictionaryPos] = previousByte;
488+ if (++dictionaryPos == dictionarySize)
489+ dictionaryPos = 0;
490+ #endif
491+ if (state < 4) state = 0;
492+ else if (state < 10) state -= 3;
493+ else state -= 6;
494+ }
495+ else
496+ {
497+ UpdateBit1(prob);
498+ prob = p + IsRep + state;
499+ IfBit0(prob)
500+ {
501+ UpdateBit0(prob);
502+ rep3 = rep2;
503+ rep2 = rep1;
504+ rep1 = rep0;
505+ state = state < kNumLitStates ? 0 : 3;
506+ prob = p + LenCoder;
507+ }
508+ else
509+ {
510+ UpdateBit1(prob);
511+ prob = p + IsRepG0 + state;
512+ IfBit0(prob)
513+ {
514+ UpdateBit0(prob);
515+ prob = p + IsRep0Long + (state << kNumPosBitsMax) + posState;
516+ IfBit0(prob)
517+ {
518+ #ifdef _LZMA_OUT_READ
519+ UInt32 pos;
520+ #endif
521+ UpdateBit0(prob);
522+
523+ #ifdef _LZMA_OUT_READ
524+ if (distanceLimit == 0)
525+ #else
526+ if (nowPos == 0)
527+ #endif
528+ {
529+ printf("ERROR: %s, %d\n", __FILE__, __LINE__);
530+ return LZMA_RESULT_DATA_ERROR;
531+ }
532+
533+ state = state < kNumLitStates ? 9 : 11;
534+ #ifdef _LZMA_OUT_READ
535+ pos = dictionaryPos - rep0;
536+ if (pos >= dictionarySize)
537+ pos += dictionarySize;
538+ previousByte = dictionary[pos];
539+ dictionary[dictionaryPos] = previousByte;
540+ if (++dictionaryPos == dictionarySize)
541+ dictionaryPos = 0;
542+ #else
543+ previousByte = outStream[nowPos - rep0];
544+ #endif
545+ outStream[nowPos++] = previousByte;
546+ #ifdef _LZMA_OUT_READ
547+ if (distanceLimit < dictionarySize)
548+ distanceLimit++;
549+ #endif
550+
551+ continue;
552+ }
553+ else
554+ {
555+ UpdateBit1(prob);
556+ }
557+ }
558+ else
559+ {
560+ UInt32 distance;
561+ UpdateBit1(prob);
562+ prob = p + IsRepG1 + state;
563+ IfBit0(prob)
564+ {
565+ UpdateBit0(prob);
566+ distance = rep1;
567+ }
568+ else
569+ {
570+ UpdateBit1(prob);
571+ prob = p + IsRepG2 + state;
572+ IfBit0(prob)
573+ {
574+ UpdateBit0(prob);
575+ distance = rep2;
576+ }
577+ else
578+ {
579+ UpdateBit1(prob);
580+ distance = rep3;
581+ rep3 = rep2;
582+ }
583+ rep2 = rep1;
584+ }
585+ rep1 = rep0;
586+ rep0 = distance;
587+ }
588+ state = state < kNumLitStates ? 8 : 11;
589+ prob = p + RepLenCoder;
590+ }
591+ {
592+ int numBits, offset;
593+ CProb *probLen = prob + LenChoice;
594+ IfBit0(probLen)
595+ {
596+ UpdateBit0(probLen);
597+ probLen = prob + LenLow + (posState << kLenNumLowBits);
598+ offset = 0;
599+ numBits = kLenNumLowBits;
600+ }
601+ else
602+ {
603+ UpdateBit1(probLen);
604+ probLen = prob + LenChoice2;
605+ IfBit0(probLen)
606+ {
607+ UpdateBit0(probLen);
608+ probLen = prob + LenMid + (posState << kLenNumMidBits);
609+ offset = kLenNumLowSymbols;
610+ numBits = kLenNumMidBits;
611+ }
612+ else
613+ {
614+ UpdateBit1(probLen);
615+ probLen = prob + LenHigh;
616+ offset = kLenNumLowSymbols + kLenNumMidSymbols;
617+ numBits = kLenNumHighBits;
618+ }
619+ }
620+ RangeDecoderBitTreeDecode(probLen, numBits, len);
621+ len += offset;
622+ }
623+
624+ if (state < 4)
625+ {
626+ int posSlot;
627+ state += kNumLitStates;
628+ prob = p + PosSlot +
629+ ((len < kNumLenToPosStates ? len : kNumLenToPosStates - 1) <<
630+ kNumPosSlotBits);
631+ RangeDecoderBitTreeDecode(prob, kNumPosSlotBits, posSlot);
632+ if (posSlot >= kStartPosModelIndex)
633+ {
634+ int numDirectBits = ((posSlot >> 1) - 1);
635+ rep0 = (2 | ((UInt32)posSlot & 1));
636+ if (posSlot < kEndPosModelIndex)
637+ {
638+ rep0 <<= numDirectBits;
639+ prob = p + SpecPos + rep0 - posSlot - 1;
640+ }
641+ else
642+ {
643+ numDirectBits -= kNumAlignBits;
644+ do
645+ {
646+ RC_NORMALIZE
647+ Range >>= 1;
648+ rep0 <<= 1;
649+ if (Code >= Range)
650+ {
651+ Code -= Range;
652+ rep0 |= 1;
653+ }
654+ }
655+ while (--numDirectBits != 0);
656+ prob = p + Align;
657+ rep0 <<= kNumAlignBits;
658+ numDirectBits = kNumAlignBits;
659+ }
660+ {
661+ int i = 1;
662+ int mi = 1;
663+ do
664+ {
665+ CProb *prob3 = prob + mi;
666+ RC_GET_BIT2(prob3, mi, ; , rep0 |= i);
667+ i <<= 1;
668+ }
669+ while(--numDirectBits != 0);
670+ }
671+ }
672+ else
673+ rep0 = posSlot;
674+ if (++rep0 == (UInt32)(0))
675+ {
676+ /* it's for stream version */
677+ len = kLzmaStreamWasFinishedId;
678+ break;
679+ }
680+ }
681+
682+ len += kMatchMinLen;
683+ #ifdef _LZMA_OUT_READ
684+ if (rep0 > distanceLimit)
685+ #else
686+ if (rep0 > nowPos)
687+ #endif
688+ {
689+ printf("ERROR: %s, %d\n", __FILE__, __LINE__);
690+ return LZMA_RESULT_DATA_ERROR;
691+ }
692+
693+ #ifdef _LZMA_OUT_READ
694+ if (dictionarySize - distanceLimit > (UInt32)len)
695+ distanceLimit += len;
696+ else
697+ distanceLimit = dictionarySize;
698+ #endif
699+
700+ do
701+ {
702+ #ifdef _LZMA_OUT_READ
703+ UInt32 pos = dictionaryPos - rep0;
704+ if (pos >= dictionarySize)
705+ pos += dictionarySize;
706+ previousByte = dictionary[pos];
707+ dictionary[dictionaryPos] = previousByte;
708+ if (++dictionaryPos == dictionarySize)
709+ dictionaryPos = 0;
710+ #else
711+ previousByte = outStream[nowPos - rep0];
712+ #endif
713+ len--;
714+ outStream[nowPos++] = previousByte;
715+ }
716+ while(len != 0 && nowPos < outSize);
717+ }
718+ }
719+ RC_NORMALIZE;
720+
721+ #ifdef _LZMA_OUT_READ
722+ vs->Range = Range;
723+ vs->Code = Code;
724+ vs->DictionaryPos = dictionaryPos;
725+ vs->GlobalPos = globalPos + (UInt32)nowPos;
726+ vs->DistanceLimit = distanceLimit;
727+ vs->Reps[0] = rep0;
728+ vs->Reps[1] = rep1;
729+ vs->Reps[2] = rep2;
730+ vs->Reps[3] = rep3;
731+ vs->State = state;
732+ vs->RemainLen = len;
733+ vs->TempDictionary[0] = tempDictionary[0];
734+ #endif
735+
736+ #ifdef _LZMA_IN_CB
737+ vs->Buffer = Buffer;
738+ vs->BufferLim = BufferLim;
739+ #else
740+ *inSizeProcessed = (SizeT)(Buffer - inStream);
741+ #endif
742+ *outSizeProcessed = nowPos;
743+ return LZMA_RESULT_OK;
744+}
745+
746+#endif /* CONFIG_LZMA */
747diff --git a/lib_generic/LzmaDecode.h b/lib_generic/LzmaDecode.h
748new file mode 100644
749index 0000000..2870eeb
750--- /dev/null
751+++ b/lib_generic/LzmaDecode.h
752@@ -0,0 +1,113 @@
753+/*
754+ LzmaDecode.h
755+ LZMA Decoder interface
756+
757+ LZMA SDK 4.40 Copyright (c) 1999-2006 Igor Pavlov (2006-05-01)
758+ http://www.7-zip.org/
759+
760+ LZMA SDK is licensed under two licenses:
761+ 1) GNU Lesser General Public License (GNU LGPL)
762+ 2) Common Public License (CPL)
763+ It means that you can select one of these two licenses and
764+ follow rules of that license.
765+
766+ SPECIAL EXCEPTION:
767+ Igor Pavlov, as the author of this code, expressly permits you to
768+ statically or dynamically link your code (or bind by name) to the
769+ interfaces of this file without subjecting your linked code to the
770+ terms of the CPL or GNU LGPL. Any modifications or additions
771+ to this file, however, are subject to the LGPL or CPL terms.
772+*/
773+
774+#ifndef __LZMADECODE_H
775+#define __LZMADECODE_H
776+
777+#include "LzmaTypes.h"
778+
779+/* #define _LZMA_IN_CB */
780+/* Use callback for input data */
781+
782+/* #define _LZMA_OUT_READ */
783+/* Use read function for output data */
784+
785+/* #define _LZMA_PROB32 */
786+/* It can increase speed on some 32-bit CPUs,
787+ but memory usage will be doubled in that case */
788+
789+/* #define _LZMA_LOC_OPT */
790+/* Enable local speed optimizations inside code */
791+
792+#ifdef _LZMA_PROB32
793+#define CProb UInt32
794+#else
795+#define CProb UInt16
796+#endif
797+
798+#define LZMA_RESULT_OK 0
799+#define LZMA_RESULT_DATA_ERROR 1
800+
801+#ifdef _LZMA_IN_CB
802+typedef struct _ILzmaInCallback
803+{
804+ int (*Read)(void *object, const unsigned char **buffer, SizeT *bufferSize);
805+} ILzmaInCallback;
806+#endif
807+
808+#define LZMA_BASE_SIZE 1846
809+#define LZMA_LIT_SIZE 768
810+
811+#define LZMA_PROPERTIES_SIZE 5
812+
813+typedef struct _CLzmaProperties
814+{
815+ int lc;
816+ int lp;
817+ int pb;
818+ #ifdef _LZMA_OUT_READ
819+ UInt32 DictionarySize;
820+ #endif
821+}CLzmaProperties;
822+
823+int LzmaDecodeProperties(CLzmaProperties *propsRes, const unsigned char *propsData, int size);
824+
825+#define LzmaGetNumProbs(Properties) (LZMA_BASE_SIZE + (LZMA_LIT_SIZE << ((Properties)->lc + (Properties)->lp)))
826+
827+#define kLzmaNeedInitId (-2)
828+
829+typedef struct _CLzmaDecoderState
830+{
831+ CLzmaProperties Properties;
832+ CProb *Probs;
833+
834+ #ifdef _LZMA_IN_CB
835+ const unsigned char *Buffer;
836+ const unsigned char *BufferLim;
837+ #endif
838+
839+ #ifdef _LZMA_OUT_READ
840+ unsigned char *Dictionary;
841+ UInt32 Range;
842+ UInt32 Code;
843+ UInt32 DictionaryPos;
844+ UInt32 GlobalPos;
845+ UInt32 DistanceLimit;
846+ UInt32 Reps[4];
847+ int State;
848+ int RemainLen;
849+ unsigned char TempDictionary[4];
850+ #endif
851+} CLzmaDecoderState;
852+
853+#ifdef _LZMA_OUT_READ
854+#define LzmaDecoderInit(vs) { (vs)->RemainLen = kLzmaNeedInitId; }
855+#endif
856+
857+int LzmaDecode(CLzmaDecoderState *vs,
858+ #ifdef _LZMA_IN_CB
859+ ILzmaInCallback *inCallback,
860+ #else
861+ const unsigned char *inStream, SizeT inSize, SizeT *inSizeProcessed,
862+ #endif
863+ unsigned char *outStream, SizeT outSize, SizeT *outSizeProcessed);
864+
865+#endif
866diff --git a/lib_generic/LzmaTypes.h b/lib_generic/LzmaTypes.h
867new file mode 100644
868index 0000000..288c5e4
869--- /dev/null
870+++ b/lib_generic/LzmaTypes.h
871@@ -0,0 +1,45 @@
872+/*
873+LzmaTypes.h
874+
875+Types for LZMA Decoder
876+
877+This file written and distributed to public domain by Igor Pavlov.
878+This file is part of LZMA SDK 4.40 (2006-05-01)
879+*/
880+
881+#ifndef __LZMATYPES_H
882+#define __LZMATYPES_H
883+
884+#ifndef _7ZIP_BYTE_DEFINED
885+#define _7ZIP_BYTE_DEFINED
886+typedef unsigned char Byte;
887+#endif
888+
889+#ifndef _7ZIP_UINT16_DEFINED
890+#define _7ZIP_UINT16_DEFINED
891+typedef unsigned short UInt16;
892+#endif
893+
894+#ifndef _7ZIP_UINT32_DEFINED
895+#define _7ZIP_UINT32_DEFINED
896+#ifdef _LZMA_UINT32_IS_ULONG
897+typedef unsigned long UInt32;
898+#else
899+typedef unsigned int UInt32;
900+#endif
901+#endif
902+
903+/* #define _LZMA_SYSTEM_SIZE_T */
904+/* Use system's size_t. You can use it to enable 64-bit sizes supporting */
905+
906+#ifndef _7ZIP_SIZET_DEFINED
907+#define _7ZIP_SIZET_DEFINED
908+#ifdef _LZMA_SYSTEM_SIZE_T
909+#include <stddef.h>
910+typedef size_t SizeT;
911+#else
912+typedef UInt32 SizeT;
913+#endif
914+#endif
915+
916+#endif
917diff --git a/lib_generic/LzmaWrapper.c b/lib_generic/LzmaWrapper.c
918new file mode 100644
919index 0000000..6c3d702
920--- /dev/null
921+++ b/lib_generic/LzmaWrapper.c
922@@ -0,0 +1,197 @@
923+/******************************************************************************
924+**
925+** FILE NAME : LzmaWrapper.c
926+** PROJECT : bootloader
927+** MODULES : U-boot
928+**
929+** DATE : 2 Nov 2006
930+** AUTHOR : Lin Mars
931+** DESCRIPTION : LZMA decoder support for U-boot 1.1.5
932+** COPYRIGHT : Copyright (c) 2006
933+** Infineon Technologies AG
934+** Am Campeon 1-12, 85579 Neubiberg, Germany
935+**
936+** This program is free software; you can redistribute it and/or modify
937+** it under the terms of the GNU General Public License as published by
938+** the Free Software Foundation; either version 2 of the License, or
939+** (at your option) any later version.
940+**
941+** HISTORY
942+** $Date $Author $Comment
943+** 2 Nov 2006 Lin Mars init version which derived from LzmaTest.c from
944+** LZMA v4.43 SDK
945+*******************************************************************************/
946+#define LZMA_NO_STDIO
947+#ifndef LZMA_NO_STDIO
948+#include <stdio.h>
949+#include <stdlib.h>
950+#include <string.h>
951+#endif
952+
953+#include <config.h>
954+#include <common.h>
955+#include <linux/types.h>
956+#include <linux/string.h>
957+#include <linux/ctype.h>
958+#include <malloc.h>
959+
960+#ifdef CONFIG_LZMA
961+
962+#include "LzmaDecode.h"
963+#include "LzmaWrapper.h"
964+
965+static const char *kCantReadMessage = "Can not read from source buffer";
966+static const char *kCantAllocateMessage = "Not enough buffer for decompression";
967+
968+static size_t rpos=0, dpos=0;
969+
970+static int MyReadFileAndCheck(unsigned char *src, void *dest, size_t size)
971+{
972+ if (size == 0)
973+ return 0;
974+ memcpy(dest, src + rpos, size);
975+ rpos += size;
976+ return 1;
977+}
978+
979+int lzma_inflate(unsigned char *source, int s_len, unsigned char *dest, int *d_len)
980+{
981+ /* We use two 32-bit integers to construct 64-bit integer for file size.
982+ You can remove outSizeHigh, if you don't need >= 4GB supporting,
983+ or you can use UInt64 outSize, if your compiler supports 64-bit integers*/
984+ UInt32 outSize = 0;
985+ UInt32 outSizeHigh = 0;
986+ SizeT outSizeFull;
987+ unsigned char *outStream;
988+
989+ int waitEOS = 1;
990+ /* waitEOS = 1, if there is no uncompressed size in headers,
991+ so decoder will wait EOS (End of Stream Marker) in compressed stream */
992+
993+ SizeT compressedSize;
994+ unsigned char *inStream;
995+
996+ CLzmaDecoderState state; /* it's about 24-80 bytes structure, if int is 32-bit */
997+ unsigned char properties[LZMA_PROPERTIES_SIZE];
998+
999+ int res;
1000+
1001+ if (sizeof(UInt32) < 4)
1002+ {
1003+ printf("LZMA decoder needs correct UInt32\n");
1004+ return LZMA_RESULT_DATA_ERROR;
1005+ }
1006+
1007+ {
1008+ long length=s_len;
1009+ if ((long)(SizeT)length != length)
1010+ {
1011+ printf("Too big compressed stream\n");
1012+ return LZMA_RESULT_DATA_ERROR;
1013+ }
1014+ compressedSize = (SizeT)(length - (LZMA_PROPERTIES_SIZE + 8));
1015+ }
1016+
1017+ /* Read LZMA properties for compressed stream */
1018+
1019+ if (!MyReadFileAndCheck(source, properties, sizeof(properties)))
1020+ {
1021+ printf("%s\n", kCantReadMessage);
1022+ return LZMA_RESULT_DATA_ERROR;
1023+ }
1024+
1025+ /* Read uncompressed size */
1026+ {
1027+ int i;
1028+ for (i = 0; i < 8; i++)
1029+ {
1030+ unsigned char b;
1031+ if (!MyReadFileAndCheck(source, &b, 1))
1032+ {
1033+ printf("%s\n", kCantReadMessage);
1034+ return LZMA_RESULT_DATA_ERROR;
1035+ }
1036+ if (b != 0xFF)
1037+ waitEOS = 0;
1038+ if (i < 4)
1039+ outSize += (UInt32)(b) << (i * 8);
1040+ else
1041+ outSizeHigh += (UInt32)(b) << ((i - 4) * 8);
1042+ }
1043+
1044+ if (waitEOS)
1045+ {
1046+ printf("Stream with EOS marker is not supported");
1047+ return LZMA_RESULT_DATA_ERROR;
1048+ }
1049+ outSizeFull = (SizeT)outSize;
1050+ if (sizeof(SizeT) >= 8)
1051+ outSizeFull |= (((SizeT)outSizeHigh << 16) << 16);
1052+ else if (outSizeHigh != 0 || (UInt32)(SizeT)outSize != outSize)
1053+ {
1054+ printf("Too big uncompressed stream");
1055+ return LZMA_RESULT_DATA_ERROR;
1056+ }
1057+ }
1058+
1059+ /* Decode LZMA properties and allocate memory */
1060+ if (LzmaDecodeProperties(&state.Properties, properties, LZMA_PROPERTIES_SIZE) != LZMA_RESULT_OK)
1061+ {
1062+ printf("Incorrect stream properties");
1063+ return LZMA_RESULT_DATA_ERROR;
1064+ }
1065+ state.Probs = (CProb *)malloc(LzmaGetNumProbs(&state.Properties) * sizeof(CProb));
1066+
1067+ if (outSizeFull == 0)
1068+ outStream = 0;
1069+ else
1070+ {
1071+ if (outSizeFull > d_len)
1072+ outStream = 0;
1073+ else
1074+ outStream = dest;
1075+ }
1076+
1077+ if (compressedSize == 0)
1078+ inStream = 0;
1079+ else
1080+ {
1081+ if ((compressedSize+rpos) > s_len )
1082+ inStream = 0;
1083+ else
1084+ inStream = source + rpos;
1085+ }
1086+
1087+ if (state.Probs == 0
1088+ || (outStream == 0 && outSizeFull != 0)
1089+ || (inStream == 0 && compressedSize != 0)
1090+ )
1091+ {
1092+ free(state.Probs);
1093+ printf("%s\n", kCantAllocateMessage);
1094+ return LZMA_RESULT_DATA_ERROR;
1095+ }
1096+
1097+ /* Decompress */
1098+ {
1099+ SizeT inProcessed;
1100+ SizeT outProcessed;
1101+ res = LzmaDecode(&state,
1102+ inStream, compressedSize, &inProcessed,
1103+ outStream, outSizeFull, &outProcessed);
1104+ if (res != 0)
1105+ {
1106+ printf("\nDecoding error = %d\n", res);
1107+ res = 1;
1108+ }
1109+ else
1110+ {
1111+ *d_len = outProcessed;
1112+ }
1113+ }
1114+
1115+ free(state.Probs);
1116+ return res;
1117+}
1118+
1119+#endif /* CONFIG_LZMA */
1120diff --git a/lib_generic/Makefile b/lib_generic/Makefile
1121index abee19a..449e994 100644
1122--- a/lib_generic/Makefile
1123+++ b/lib_generic/Makefile
1124@@ -41,6 +41,8 @@ COBJS-y += sha1.o
1125 COBJS-y += string.o
1126 COBJS-y += vsprintf.o
1127 COBJS-y += zlib.o
1128+COBJS-y += LzmaDecode.o
1129+COBJS-y += LzmaWrapper.o
1130 
1131 COBJS := $(COBJS-y)
1132 SRCS := $(COBJS:.o=.c)
1133--
11341.5.3.2
1135
1136

Archive Download this file



interactive