lantiq: Tune the XWAY subtarget cflags
[openwrt.git] / package / platform / lantiq / ltq-vdsl-fw / src / LzmaWrapper.c
1 /******************************************************************************
2 **
3 ** FILE NAME    : LzmaWrapper.c
4 ** PROJECT      : bootloader
5 ** MODULES      : U-boot
6 **
7 ** DATE         : 2 Nov 2006
8 ** AUTHOR       : Lin Mars
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
13 **
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.
18 **
19 ** HISTORY
20 ** $Date        $Author         $Comment
21 ** 2 Nov 2006   Lin Mars        init version which derived from LzmaTest.c from
22 **                              LZMA v4.43 SDK
23 ** 24 May 2007  Lin Mars        Fix issue for multiple lzma_inflate involved
24 *******************************************************************************/
25 #include <stdio.h>
26 #include <stdlib.h>
27 #include <string.h>
28
29 #include "LzmaDecode.h"
30 #include "LzmaWrapper.h"
31
32 #if defined(DEBUG_ENABLE_BOOTSTRAP_PRINTF) || !defined(CFG_BOOTSTRAP_CODE)
33 static const char *kCantReadMessage = "Can not read from source buffer";
34 static const char *kCantAllocateMessage = "Not enough buffer for decompression";
35 #endif
36
37 static size_t rpos=0, dpos=0;
38
39 static int MyReadFileAndCheck(unsigned char *src, void *dest, size_t size)
40 {
41   if (size == 0)
42     return 0;
43   memcpy(dest, src + rpos, size);
44   rpos += size;
45   return 1;
46 }
47
48 int lzma_inflate(unsigned char *source, int s_len, unsigned char *dest, int *d_len)
49 {
50   /* We use two 32-bit integers to construct 64-bit integer for file size.
51      You can remove outSizeHigh, if you don't need >= 4GB supporting,
52      or you can use UInt64 outSize, if your compiler supports 64-bit integers*/
53   UInt32 outSize = 0;
54   UInt32 outSizeHigh = 0;
55   SizeT outSizeFull;
56   unsigned char *outStream;
57   
58   int waitEOS = 1; 
59   /* waitEOS = 1, if there is no uncompressed size in headers, 
60    so decoder will wait EOS (End of Stream Marker) in compressed stream */
61
62   SizeT compressedSize;
63   unsigned char *inStream;
64
65   CLzmaDecoderState state;  /* it's about 24-80 bytes structure, if int is 32-bit */
66   unsigned char properties[LZMA_PROPERTIES_SIZE];
67
68   int res;
69
70   rpos=0; dpos=0;
71
72   if (sizeof(UInt32) < 4)
73   {
74 #if defined(DEBUG_ENABLE_BOOTSTRAP_PRINTF) || !defined(CFG_BOOTSTRAP_CODE)
75     printf("LZMA decoder needs correct UInt32\n");
76 #endif
77     return LZMA_RESULT_DATA_ERROR;
78   }
79
80   {
81     long length=s_len;
82     if ((long)(SizeT)length != length)
83     {
84 #if defined(DEBUG_ENABLE_BOOTSTRAP_PRINTF) || !defined(CFG_BOOTSTRAP_CODE)
85       printf("Too big compressed stream\n");
86 #endif
87       return LZMA_RESULT_DATA_ERROR;
88     }
89     compressedSize = (SizeT)(length - (LZMA_PROPERTIES_SIZE + 8));
90   }
91
92   /* Read LZMA properties for compressed stream */
93
94   if (!MyReadFileAndCheck(source, properties, sizeof(properties)))
95   {
96 #if defined(DEBUG_ENABLE_BOOTSTRAP_PRINTF) || !defined(CFG_BOOTSTRAP_CODE)
97     printf("%s\n", kCantReadMessage);
98 #endif
99     return LZMA_RESULT_DATA_ERROR;
100   }
101
102   /* Read uncompressed size */
103   {
104     int i;
105     for (i = 0; i < 8; i++)
106     {
107       unsigned char b;
108       if (!MyReadFileAndCheck(source, &b, 1))
109       {
110 #if defined(DEBUG_ENABLE_BOOTSTRAP_PRINTF) || !defined(CFG_BOOTSTRAP_CODE)
111         printf("%s\n", kCantReadMessage);
112 #endif
113         return LZMA_RESULT_DATA_ERROR;
114       }
115       if (b != 0xFF)
116         waitEOS = 0;
117       if (i < 4)
118         outSize += (UInt32)(b) << (i * 8);
119       else
120         outSizeHigh += (UInt32)(b) << ((i - 4) * 8);
121     }
122     
123     if (waitEOS)
124     {
125 #if defined(DEBUG_ENABLE_BOOTSTRAP_PRINTF) || !defined(CFG_BOOTSTRAP_CODE)
126       printf("Stream with EOS marker is not supported");
127 #endif
128       return LZMA_RESULT_DATA_ERROR;
129     }
130     outSizeFull = (SizeT)outSize;
131     if (sizeof(SizeT) >= 8)
132       outSizeFull |= (((SizeT)outSizeHigh << 16) << 16);
133     else if (outSizeHigh != 0 || (UInt32)(SizeT)outSize != outSize)
134     {
135 #if defined(DEBUG_ENABLE_BOOTSTRAP_PRINTF) || !defined(CFG_BOOTSTRAP_CODE)
136       printf("Too big uncompressed stream");
137 #endif
138       return LZMA_RESULT_DATA_ERROR;
139     }
140   }
141
142   /* Decode LZMA properties and allocate memory */
143   if (LzmaDecodeProperties(&state.Properties, properties, LZMA_PROPERTIES_SIZE) != LZMA_RESULT_OK)
144   {
145 #if defined(DEBUG_ENABLE_BOOTSTRAP_PRINTF) || !defined(CFG_BOOTSTRAP_CODE)
146     printf("Incorrect stream properties");
147 #endif
148     return LZMA_RESULT_DATA_ERROR;
149   }
150   state.Probs = (CProb *)malloc(LzmaGetNumProbs(&state.Properties) * sizeof(CProb));
151
152   if (outSizeFull == 0)
153     outStream = 0;
154   else
155   {
156     if (outSizeFull > d_len)
157       outStream = 0;
158     else
159       outStream = dest;
160   }
161
162   if (compressedSize == 0)
163     inStream = 0;
164   else
165   {
166     if ((compressedSize+rpos) > s_len )
167       inStream = 0;
168     else
169       inStream = source + rpos;
170   }
171
172   if (state.Probs == 0 
173     || (outStream == 0 && outSizeFull != 0)
174     || (inStream == 0 && compressedSize != 0)
175     )
176   {
177     free(state.Probs);
178 #if defined(DEBUG_ENABLE_BOOTSTRAP_PRINTF) || !defined(CFG_BOOTSTRAP_CODE)
179     printf("%s\n", kCantAllocateMessage);
180 #endif
181     return LZMA_RESULT_DATA_ERROR;
182   }
183
184   /* Decompress */
185   {
186     SizeT inProcessed;
187     SizeT outProcessed;
188     res = LzmaDecode(&state,
189       inStream, compressedSize, &inProcessed,
190       outStream, outSizeFull, &outProcessed);
191     if (res != 0)
192     {
193 #if defined(DEBUG_ENABLE_BOOTSTRAP_PRINTF) || !defined(CFG_BOOTSTRAP_CODE)
194       printf("\nDecoding error = %d\n", res);
195 #endif
196       res = 1;
197     }
198     else
199     {
200       *d_len = outProcessed;
201     }
202   }
203
204   free(state.Probs);
205   return res;
206 }