]> git.proxmox.com Git - mirror_edk2.git/blame - BaseTools/Source/C/LzmaCompress/LzmaCompress.c
BaseTools: Fix build on FreeBSD and allow use of non-gcc system compiler
[mirror_edk2.git] / BaseTools / Source / C / LzmaCompress / LzmaCompress.c
CommitLineData
30fdf114
LG
1/** @file\r
2 LZMA Compress/Decompress tool (LzmaCompress)\r
3\r
4 Based on LZMA SDK 4.65:\r
5 LzmaUtil.c -- Test application for LZMA compression\r
6 2008-11-23 : Igor Pavlov : Public domain\r
7\r
64b2609f 8 Copyright (c) 2006 - 2012, Intel Corporation. All rights reserved.<BR>\r
40d841f6 9 This program and the accompanying materials\r
30fdf114
LG
10 are licensed and made available under the terms and conditions of the BSD License\r
11 which accompanies this distribution. The full text of the license may be found at\r
12 http://opensource.org/licenses/bsd-license.php\r
13\r
14 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
15 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
16\r
17**/\r
18\r
19#define _CRT_SECURE_NO_WARNINGS\r
20\r
21#include <stdio.h>\r
22#include <stdlib.h>\r
23#include <string.h>\r
24\r
25#include "Sdk/C/Alloc.h"\r
26#include "Sdk/C/7zFile.h"\r
27#include "Sdk/C/7zVersion.h"\r
28#include "Sdk/C/LzmaDec.h"\r
29#include "Sdk/C/LzmaEnc.h"\r
64b2609f 30#include "Sdk/C/Bra.h"\r
b36d134f 31#include "CommonLib.h"\r
30fdf114 32\r
64b2609f
LG
33#define LZMA_HEADER_SIZE (LZMA_PROPS_SIZE + 8)\r
34\r
35typedef enum {\r
36 NoConverter, \r
37 X86Converter,\r
38 MaxConverter\r
39} CONVERTER_TYPE;\r
40\r
30fdf114
LG
41const char *kCantReadMessage = "Can not read input file";\r
42const char *kCantWriteMessage = "Can not write output file";\r
43const char *kCantAllocateMessage = "Can not allocate memory";\r
44const char *kDataErrorMessage = "Data error";\r
45\r
5ddccf34
BC
46static void *SzAlloc(void *p, size_t size) { (void)p; return MyAlloc(size); }\r
47static void SzFree(void *p, void *address) { (void)p; MyFree(address); }\r
30fdf114
LG
48static ISzAlloc g_Alloc = { SzAlloc, SzFree };\r
49\r
50static Bool mQuietMode = False;\r
64b2609f 51static CONVERTER_TYPE mConType = NoConverter;\r
30fdf114
LG
52\r
53#define UTILITY_NAME "LzmaCompress"\r
54#define UTILITY_MAJOR_VERSION 0\r
64b2609f 55#define UTILITY_MINOR_VERSION 2\r
30fdf114 56#define INTEL_COPYRIGHT \\r
64b2609f 57 "Copyright (c) 2009-2012, Intel Corporation. All rights reserved."\r
30fdf114
LG
58void PrintHelp(char *buffer)\r
59{\r
60 strcat(buffer,\r
61 "\n" UTILITY_NAME " - " INTEL_COPYRIGHT "\n"\r
62 "Based on LZMA Utility " MY_VERSION_COPYRIGHT_DATE "\n"\r
63 "\nUsage: LzmaCompress -e|-d [options] <inputFile>\n"\r
64 " -e: encode file\n"\r
65 " -d: decode file\n"\r
66 " -o FileName, --output FileName: specify the output filename\n"\r
64b2609f 67 " --f86: enable converter for x86 code\n"\r
30fdf114
LG
68 " -v, --verbose: increase output messages\n"\r
69 " -q, --quiet: reduce output messages\n"\r
70 " --debug [0-9]: set debug level\n"\r
71 " --version: display the program version and exit\n"\r
72 " -h, --help: display this help text\n"\r
73 );\r
74}\r
75\r
76int PrintError(char *buffer, const char *message)\r
77{\r
78 strcat(buffer, "\nError: ");\r
79 strcat(buffer, message);\r
80 strcat(buffer, "\n");\r
81 return 1;\r
82}\r
83\r
84int PrintErrorNumber(char *buffer, SRes val)\r
85{\r
86 sprintf(buffer + strlen(buffer), "\nError code: %x\n", (unsigned)val);\r
87 return 1;\r
88}\r
89\r
90int PrintUserError(char *buffer)\r
91{\r
92 return PrintError(buffer, "Incorrect command");\r
93}\r
94\r
95void PrintVersion(char *buffer)\r
96{\r
b36d134f 97 sprintf (buffer, "%s Version %d.%d %s ", UTILITY_NAME, UTILITY_MAJOR_VERSION, UTILITY_MINOR_VERSION, __BUILD_VERSION);\r
30fdf114
LG
98}\r
99\r
64b2609f 100static SRes Encode(ISeqOutStream *outStream, ISeqInStream *inStream, UInt64 fileSize)\r
30fdf114 101{\r
64b2609f
LG
102 SRes res;\r
103 size_t inSize = (size_t)fileSize;\r
104 Byte *inBuffer = 0;\r
105 Byte *outBuffer = 0;\r
106 Byte *filteredStream = 0;\r
107 size_t outSize;\r
108 CLzmaEncProps props;\r
30fdf114 109\r
64b2609f
LG
110 LzmaEncProps_Init(&props);\r
111 LzmaEncProps_Normalize(&props);\r
112\r
113 if (inSize != 0) {\r
114 inBuffer = (Byte *)MyAlloc(inSize);\r
115 if (inBuffer == 0)\r
116 return SZ_ERROR_MEM;\r
117 } else {\r
118 return SZ_ERROR_INPUT_EOF;\r
119 }\r
120 \r
121 if (SeqInStream_Read(inStream, inBuffer, inSize) != SZ_OK) {\r
122 res = SZ_ERROR_READ;\r
123 goto Done;\r
124 }\r
30fdf114 125\r
64b2609f
LG
126 // we allocate 105% of original size + 64KB for output buffer\r
127 outSize = (size_t)fileSize / 20 * 21 + (1 << 16);\r
128 outBuffer = (Byte *)MyAlloc(outSize);\r
129 if (outBuffer == 0) {\r
130 res = SZ_ERROR_MEM;\r
131 goto Done;\r
132 }\r
133 \r
134 {\r
135 int i;\r
136 for (i = 0; i < 8; i++)\r
137 outBuffer[i + LZMA_PROPS_SIZE] = (Byte)(fileSize >> (8 * i));\r
138 }\r
30fdf114 139\r
64b2609f
LG
140 if (mConType != NoConverter)\r
141 {\r
142 filteredStream = (Byte *)MyAlloc(inSize);\r
143 if (filteredStream == 0) {\r
144 res = SZ_ERROR_MEM;\r
145 goto Done;\r
146 }\r
147 memcpy(filteredStream, inBuffer, inSize);\r
148 \r
149 if (mConType == X86Converter) {\r
30fdf114 150 {\r
64b2609f
LG
151 UInt32 x86State;\r
152 x86_Convert_Init(x86State);\r
153 x86_Convert(filteredStream, (SizeT) inSize, 0, &x86State, 1);\r
30fdf114
LG
154 }\r
155 }\r
156 }\r
30fdf114 157\r
64b2609f
LG
158 {\r
159 size_t outSizeProcessed = outSize - LZMA_HEADER_SIZE;\r
160 size_t outPropsSize = LZMA_PROPS_SIZE;\r
161 \r
162 res = LzmaEncode(outBuffer + LZMA_HEADER_SIZE, &outSizeProcessed,\r
163 mConType != NoConverter ? filteredStream : inBuffer, inSize,\r
164 &props, outBuffer, &outPropsSize, 0,\r
165 NULL, &g_Alloc, &g_Alloc);\r
166 \r
167 if (res != SZ_OK)\r
168 goto Done;\r
169\r
170 outSize = LZMA_HEADER_SIZE + outSizeProcessed;\r
171 }\r
30fdf114 172\r
64b2609f
LG
173 if (outStream->Write(outStream, outBuffer, outSize) != outSize)\r
174 res = SZ_ERROR_WRITE;\r
30fdf114 175\r
64b2609f
LG
176Done:\r
177 MyFree(outBuffer);\r
178 MyFree(inBuffer);\r
179 MyFree(filteredStream);\r
30fdf114 180\r
30fdf114
LG
181 return res;\r
182}\r
183\r
64b2609f 184static SRes Decode(ISeqOutStream *outStream, ISeqInStream *inStream, UInt64 fileSize)\r
30fdf114 185{\r
30fdf114 186 SRes res;\r
64b2609f
LG
187 size_t inSize = (size_t)fileSize;\r
188 Byte *inBuffer = 0;\r
189 Byte *outBuffer = 0;\r
190 size_t outSize = 0;\r
191 size_t inSizePure;\r
192 ELzmaStatus status;\r
193 UInt64 outSize64 = 0;\r
30fdf114 194\r
64b2609f
LG
195 int i;\r
196\r
197 if (inSize < LZMA_HEADER_SIZE) \r
198 return SZ_ERROR_INPUT_EOF;\r
30fdf114 199\r
64b2609f
LG
200 inBuffer = (Byte *)MyAlloc(inSize);\r
201 if (inBuffer == 0)\r
30fdf114 202 return SZ_ERROR_MEM;\r
64b2609f
LG
203 \r
204 if (SeqInStream_Read(inStream, inBuffer, inSize) != SZ_OK) {\r
205 res = SZ_ERROR_READ;\r
206 goto Done;\r
207 }\r
30fdf114 208\r
64b2609f
LG
209 for (i = 0; i < 8; i++)\r
210 outSize64 += ((UInt64)inBuffer[LZMA_PROPS_SIZE + i]) << (i * 8);\r
211\r
212 outSize = (size_t)outSize64;\r
213 if (outSize != 0) {\r
214 outBuffer = (Byte *)MyAlloc(outSize);\r
215 if (outBuffer == 0) {\r
216 res = SZ_ERROR_MEM;\r
217 goto Done;\r
218 }\r
219 } else {\r
220 res = SZ_OK;\r
221 goto Done;\r
222 }\r
30fdf114 223\r
64b2609f
LG
224 inSizePure = inSize - LZMA_HEADER_SIZE;\r
225 res = LzmaDecode(outBuffer, &outSize, inBuffer + LZMA_HEADER_SIZE, &inSizePure,\r
226 inBuffer, LZMA_PROPS_SIZE, LZMA_FINISH_END, &status, &g_Alloc);\r
30fdf114 227\r
64b2609f
LG
228 if (res != SZ_OK)\r
229 goto Done;\r
230\r
231 if (mConType == X86Converter)\r
232 {\r
233 UInt32 x86State;\r
234 x86_Convert_Init(x86State);\r
235 x86_Convert(outBuffer, (SizeT) outSize, 0, &x86State, 0);\r
30fdf114 236 }\r
64b2609f
LG
237\r
238 if (outStream->Write(outStream, outBuffer, outSize) != outSize)\r
239 res = SZ_ERROR_WRITE;\r
240\r
241Done:\r
242 MyFree(outBuffer);\r
243 MyFree(inBuffer);\r
244\r
30fdf114
LG
245 return res;\r
246}\r
247\r
248int main2(int numArgs, const char *args[], char *rs)\r
249{\r
250 CFileSeqInStream inStream;\r
251 CFileOutStream outStream;\r
252 int res;\r
fd171542 253 int encodeMode = 0;\r
30fdf114
LG
254 Bool modeWasSet = False;\r
255 const char *inputFile = NULL;\r
256 const char *outputFile = "file.tmp";\r
257 int param;\r
64b2609f 258 UInt64 fileSize;\r
30fdf114
LG
259\r
260 FileSeqInStream_CreateVTable(&inStream);\r
261 File_Construct(&inStream.file);\r
262\r
263 FileOutStream_CreateVTable(&outStream);\r
264 File_Construct(&outStream.file);\r
265\r
266 if (numArgs == 1)\r
267 {\r
268 PrintHelp(rs);\r
269 return 0;\r
270 }\r
271\r
272 for (param = 1; param < numArgs; param++) {\r
273 if (strcmp(args[param], "-e") == 0 || strcmp(args[param], "-d") == 0) {\r
274 encodeMode = (args[param][1] == 'e');\r
275 modeWasSet = True;\r
64b2609f
LG
276 } else if (strcmp(args[param], "--f86") == 0) {\r
277 mConType = X86Converter;\r
30fdf114
LG
278 } else if (strcmp(args[param], "-o") == 0 ||\r
279 strcmp(args[param], "--output") == 0) {\r
280 if (numArgs < (param + 2)) {\r
281 return PrintUserError(rs);\r
282 }\r
283 outputFile = args[++param];\r
284 } else if (strcmp(args[param], "--debug") == 0) {\r
285 if (numArgs < (param + 2)) {\r
286 return PrintUserError(rs);\r
287 }\r
288 //\r
289 // For now we silently ignore this parameter to achieve command line\r
290 // parameter compatibility with other build tools.\r
291 //\r
292 param++;\r
293 } else if (\r
294 strcmp(args[param], "-h") == 0 ||\r
295 strcmp(args[param], "--help") == 0\r
296 ) {\r
297 PrintHelp(rs);\r
298 return 0;\r
299 } else if (\r
300 strcmp(args[param], "-v") == 0 ||\r
301 strcmp(args[param], "--verbose") == 0\r
302 ) {\r
303 //\r
304 // For now we silently ignore this parameter to achieve command line\r
305 // parameter compatibility with other build tools.\r
306 //\r
307 } else if (\r
308 strcmp(args[param], "-q") == 0 ||\r
309 strcmp(args[param], "--quiet") == 0\r
310 ) {\r
311 mQuietMode = True;\r
312 } else if (strcmp(args[param], "--version") == 0) {\r
313 PrintVersion(rs);\r
314 return 0;\r
315 } else if (inputFile == NULL) {\r
316 inputFile = args[param];\r
317 } else {\r
318 return PrintUserError(rs);\r
319 }\r
320 }\r
321\r
322 if ((inputFile == NULL) || !modeWasSet) {\r
323 return PrintUserError(rs);\r
324 }\r
325\r
326 {\r
327 size_t t4 = sizeof(UInt32);\r
328 size_t t8 = sizeof(UInt64);\r
329 if (t4 != 4 || t8 != 8)\r
330 return PrintError(rs, "Incorrect UInt32 or UInt64");\r
331 }\r
332\r
333 if (InFile_Open(&inStream.file, inputFile) != 0)\r
334 return PrintError(rs, "Can not open input file");\r
335\r
336 if (OutFile_Open(&outStream.file, outputFile) != 0)\r
337 return PrintError(rs, "Can not open output file");\r
338\r
64b2609f
LG
339 File_GetLength(&inStream.file, &fileSize);\r
340\r
30fdf114
LG
341 if (encodeMode)\r
342 {\r
30fdf114
LG
343 if (!mQuietMode) {\r
344 printf("Encoding\n");\r
345 }\r
64b2609f 346 res = Encode(&outStream.s, &inStream.s, fileSize);\r
30fdf114
LG
347 }\r
348 else\r
349 {\r
350 if (!mQuietMode) {\r
351 printf("Decoding\n");\r
352 }\r
64b2609f 353 res = Decode(&outStream.s, &inStream.s, fileSize);\r
30fdf114
LG
354 }\r
355\r
356 File_Close(&outStream.file);\r
357 File_Close(&inStream.file);\r
358\r
359 if (res != SZ_OK)\r
360 {\r
361 if (res == SZ_ERROR_MEM)\r
362 return PrintError(rs, kCantAllocateMessage);\r
363 else if (res == SZ_ERROR_DATA)\r
364 return PrintError(rs, kDataErrorMessage);\r
365 else if (res == SZ_ERROR_WRITE)\r
366 return PrintError(rs, kCantWriteMessage);\r
367 else if (res == SZ_ERROR_READ)\r
368 return PrintError(rs, kCantReadMessage);\r
369 return PrintErrorNumber(rs, res);\r
370 }\r
371 return 0;\r
372}\r
373\r
374int MY_CDECL main(int numArgs, const char *args[])\r
375{\r
376 char rs[2000] = { 0 };\r
377 int res = main2(numArgs, args, rs);\r
378 if (strlen(rs) > 0) {\r
379 puts(rs);\r
380 }\r
381 return res;\r
382}\r