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