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