arm, kirkwood: added kw_gpio_set_valid() in gpio.h
[platform/kernel/u-boot.git] / lib_generic / lzma / LzmaTools.c
1 /*
2  * Usefuls routines based on the LzmaTest.c file from LZMA SDK 4.57
3  *
4  * Copyright (C) 2007-2008 Industrie Dial Face S.p.A.
5  * Luigi 'Comio' Mantellini (luigi.mantellini@idf-hit.com)
6  *
7  * Copyright (C) 1999-2005 Igor Pavlov
8  *
9  * See file CREDITS for list of people who contributed to this
10  * project.
11  *
12  * This program is free software; you can redistribute it and/or
13  * modify it under the terms of the GNU General Public License as
14  * published by the Free Software Foundation; either version 2 of
15  * the License, or (at your option) any later version.
16  *
17  * This program is distributed in the hope that it will be useful,
18  * but WITHOUT ANY WARRANTY; without even the implied warranty of
19  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
20  * GNU General Public License for more details.
21  *
22  * You should have received a copy of the GNU General Public License
23  * along with this program; if not, write to the Free Software
24  * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
25  * MA 02111-1307 USA
26  */
27
28 /*
29  * LZMA_Alone stream format:
30  *
31  * uchar   Properties[5]
32  * uint64  Uncompressed size
33  * uchar   data[*]
34  *
35  */
36
37 #include <config.h>
38 #include <common.h>
39
40 #ifdef CONFIG_LZMA
41
42 #define LZMA_PROPERTIES_OFFSET 0
43 #define LZMA_SIZE_OFFSET       LZMA_PROPERTIES_SIZE
44 #define LZMA_DATA_OFFSET       LZMA_SIZE_OFFSET+sizeof(uint64_t)
45
46 #include "LzmaTools.h"
47 #include "LzmaDecode.h"
48
49 #include <linux/string.h>
50 #include <malloc.h>
51
52 int lzmaBuffToBuffDecompress (unsigned char *outStream, SizeT *uncompressedSize,
53                               unsigned char *inStream,  SizeT  length)
54 {
55         int res = LZMA_RESULT_DATA_ERROR;
56         int i;
57
58         SizeT outSizeFull = 0xFFFFFFFF; /* 4GBytes limit */
59         SizeT inProcessed;
60         SizeT outProcessed;
61         SizeT outSize;
62         SizeT outSizeHigh;
63         CLzmaDecoderState state;  /* it's about 24-80 bytes structure, if int is 32-bit */
64         unsigned char properties[LZMA_PROPERTIES_SIZE];
65         SizeT compressedSize = (SizeT)(length - LZMA_DATA_OFFSET);
66
67         debug ("LZMA: Image address............... 0x%lx\n", inStream);
68         debug ("LZMA: Properties address.......... 0x%lx\n", inStream + LZMA_PROPERTIES_OFFSET);
69         debug ("LZMA: Uncompressed size address... 0x%lx\n", inStream + LZMA_SIZE_OFFSET);
70         debug ("LZMA: Compressed data address..... 0x%lx\n", inStream + LZMA_DATA_OFFSET);
71         debug ("LZMA: Destination address......... 0x%lx\n", outStream);
72
73         memcpy(properties, inStream + LZMA_PROPERTIES_OFFSET, LZMA_PROPERTIES_SIZE);
74
75         memset(&state, 0, sizeof(state));
76         res = LzmaDecodeProperties(&state.Properties,
77                                  properties,
78                                  LZMA_PROPERTIES_SIZE);
79         if (res != LZMA_RESULT_OK) {
80                 return res;
81         }
82
83         outSize = 0;
84         outSizeHigh = 0;
85         /* Read the uncompressed size */
86         for (i = 0; i < 8; i++) {
87                 unsigned char b = inStream[LZMA_SIZE_OFFSET + i];
88                 if (i < 4) {
89                         outSize     += (UInt32)(b) << (i * 8);
90                 } else {
91                         outSizeHigh += (UInt32)(b) << ((i - 4) * 8);
92                 }
93         }
94
95         outSizeFull = (SizeT)outSize;
96         if (sizeof(SizeT) >= 8) {
97                 /*
98                  * SizeT is a 64 bit uint => We can manage files larger than 4GB!
99                  *
100                  */
101                 outSizeFull |= (((SizeT)outSizeHigh << 16) << 16);
102         } else if (outSizeHigh != 0 || (UInt32)(SizeT)outSize != outSize) {
103                 /*
104                  * SizeT is a 32 bit uint => We cannot manage files larger than
105                  * 4GB!
106                  *
107                  */
108                 debug ("LZMA: 64bit support not enabled.\n");
109                 return LZMA_RESULT_DATA_ERROR;
110         }
111
112         debug ("LZMA: Uncompresed size............ 0x%lx\n", outSizeFull);
113         debug ("LZMA: Compresed size.............. 0x%lx\n", compressedSize);
114         debug ("LZMA: Dynamic memory needed....... 0x%lx", LzmaGetNumProbs(&state.Properties) * sizeof(CProb));
115
116         state.Probs = (CProb *)malloc(LzmaGetNumProbs(&state.Properties) * sizeof(CProb));
117
118         if (state.Probs == 0
119             || (outStream == 0 && outSizeFull != 0)
120             || (inStream == 0 && compressedSize != 0)) {
121                 free(state.Probs);
122                 debug ("\n");
123                 return LZMA_RESULT_DATA_ERROR;
124         }
125
126         debug (" allocated.\n");
127
128         /* Decompress */
129
130         res = LzmaDecode(&state,
131                 inStream + LZMA_DATA_OFFSET, compressedSize, &inProcessed,
132                 outStream, outSizeFull,  &outProcessed);
133         if (res != LZMA_RESULT_OK)  {
134                 return res;
135         }
136
137         *uncompressedSize = outProcessed;
138         free(state.Probs);
139         return res;
140 }
141
142 #endif