1 /******************************************************************************
3 ** FILE NAME : LzmaWrapper.c
4 ** PROJECT : bootloader
9 ** DESCRIPTION : LZMA decoder support for U-boot 1.1.5
10 ** COPYRIGHT : Copyright (c) 2006
11 ** Infineon Technologies AG
12 ** Am Campeon 1-12, 85579 Neubiberg, Germany
14 ** This program is free software; you can redistribute it and/or modify
15 ** it under the terms of the GNU General Public License as published by
16 ** the Free Software Foundation; either version 2 of the License, or
17 ** (at your option) any later version.
20 ** $Date $Author $Comment
21 ** 2 Nov 2006 Lin Mars init version which derived from LzmaTest.c from
23 *******************************************************************************/
33 #include <linux/types.h>
34 #include <linux/string.h>
35 #include <linux/ctype.h>
40 #include "LzmaDecode.h"
41 #include "LzmaWrapper.h"
43 static const char *kCantReadMessage = "Can not read from source buffer";
44 static const char *kCantAllocateMessage = "Not enough buffer for decompression";
46 static size_t rpos=0, dpos=0;
48 static int MyReadFileAndCheck(unsigned char *src, void *dest, size_t size)
52 memcpy(dest, src + rpos, size);
57 int lzma_inflate(unsigned char *source, int s_len, unsigned char *dest, int *d_len)
59 /* We use two 32-bit integers to construct 64-bit integer for file size.
60 You can remove outSizeHigh, if you don't need >= 4GB supporting,
61 or you can use UInt64 outSize, if your compiler supports 64-bit integers*/
63 UInt32 outSizeHigh = 0;
65 unsigned char *outStream;
68 /* waitEOS = 1, if there is no uncompressed size in headers,
69 so decoder will wait EOS (End of Stream Marker) in compressed stream */
72 unsigned char *inStream;
74 CLzmaDecoderState state; /* it's about 24-80 bytes structure, if int is 32-bit */
75 unsigned char properties[LZMA_PROPERTIES_SIZE];
79 if (sizeof(UInt32) < 4)
81 #ifdef DEBUG_ENABLE_BOOTSTRAP_PRINTF
82 printf("LZMA decoder needs correct UInt32\n");
84 return LZMA_RESULT_DATA_ERROR;
89 if ((long)(SizeT)length != length)
92 #ifdef DEBUG_ENABLE_BOOTSTRAP_PRINTF
93 printf("Too big compressed stream\n");
95 return LZMA_RESULT_DATA_ERROR;
97 compressedSize = (SizeT)(length - (LZMA_PROPERTIES_SIZE + 8));
100 /* Read LZMA properties for compressed stream */
102 if (!MyReadFileAndCheck(source, properties, sizeof(properties)))
105 #ifdef DEBUG_ENABLE_BOOTSTRAP_PRINTF
106 printf("%s\n", kCantReadMessage);
108 return LZMA_RESULT_DATA_ERROR;
111 /* Read uncompressed size */
114 for (i = 0; i < 8; i++)
117 if (!MyReadFileAndCheck(source, &b, 1))
120 #ifdef DEBUG_ENABLE_BOOTSTRAP_PRINTF
121 printf("%s\n", kCantReadMessage);
123 return LZMA_RESULT_DATA_ERROR;
128 outSize += (UInt32)(b) << (i * 8);
130 outSizeHigh += (UInt32)(b) << ((i - 4) * 8);
136 #ifdef DEBUG_ENABLE_BOOTSTRAP_PRINTF
137 printf("Stream with EOS marker is not supported");
139 return LZMA_RESULT_DATA_ERROR;
141 outSizeFull = (SizeT)outSize;
142 if (sizeof(SizeT) >= 8)
143 outSizeFull |= (((SizeT)outSizeHigh << 16) << 16);
144 else if (outSizeHigh != 0 || (UInt32)(SizeT)outSize != outSize)
147 #ifdef DEBUG_ENABLE_BOOTSTRAP_PRINTF
148 printf("Too big uncompressed stream");
150 return LZMA_RESULT_DATA_ERROR;
154 /* Decode LZMA properties and allocate memory */
155 if (LzmaDecodeProperties(&state.Properties, properties, LZMA_PROPERTIES_SIZE) != LZMA_RESULT_OK)
158 #ifdef DEBUG_ENABLE_BOOTSTRAP_PRINTF
159 printf("Incorrect stream properties");
161 return LZMA_RESULT_DATA_ERROR;
163 state.Probs = (CProb *)malloc(LzmaGetNumProbs(&state.Properties) * sizeof(CProb));
165 if (outSizeFull == 0)
169 if (outSizeFull > d_len)
175 if (compressedSize == 0)
179 if ((compressedSize+rpos) > s_len )
182 inStream = source + rpos;
186 || (outStream == 0 && outSizeFull != 0)
187 || (inStream == 0 && compressedSize != 0)
192 #ifdef DEBUG_ENABLE_BOOTSTRAP_PRINTF
193 printf("%s\n", kCantAllocateMessage);
195 return LZMA_RESULT_DATA_ERROR;
202 res = LzmaDecode(&state,
203 inStream, compressedSize, &inProcessed,
204 outStream, outSizeFull, &outProcessed);
208 #ifdef DEBUG_ENABLE_BOOTSTRAP_PRINTF
209 printf("\nDecoding error = %d\n", res);
215 *d_len = outProcessed;
223 #endif /* CONFIG_LZMA */