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

Archive Download this file



interactive