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