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