]> git.proxmox.com Git - mirror_edk2.git/blob - EdkCompatibilityPkg/Sample/Tools/Source/EfiCompress/EfiCompressMain.c
Sync all bug fixes between EDK1.04 and EDK1.06 into EdkCompatibilityPkg.
[mirror_edk2.git] / EdkCompatibilityPkg / Sample / Tools / Source / EfiCompress / EfiCompressMain.c
1 /*++
2
3 Copyright (c) 2006 - 2010, Intel Corporation. All rights reserved.<BR>
4 This program and the accompanying materials
5 are licensed and made available under the terms and conditions of the BSD License
6 which accompanies this distribution. The full text of the license may be found at
7 http://opensource.org/licenses/bsd-license.php
8
9 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
10 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
11
12 Module Name:
13 EfiCompressMain.c
14
15 Abstract:
16
17 --*/
18
19 #include <stdlib.h>
20 #include <string.h>
21 #include <ctype.h>
22 #include <assert.h>
23 #include <stdarg.h>
24 #include <stdio.h>
25 #include "TianoCommon.h"
26 #include "Compress.h"
27
28 #define UTILITY_VERSION "v1.0"
29 #define UTILITY_NAME "EfiCompress"
30
31 typedef enum {
32 EFI_COMPRESS = 1,
33 TIANO_COMPRESS = 2
34 } COMPRESS_TYPE;
35
36 typedef struct _COMPRESS_ACTION_LIST {
37 struct _COMPRESS_ACTION_LIST *NextAction;
38 INT32 CompressType;
39 CHAR8 *InFileName;
40 CHAR8 *OutFileName;
41 } COMPRESS_ACTION_LIST;
42
43
44 STATIC
45 BOOLEAN
46 ParseCommandLine (
47 INT32 argc,
48 CHAR8 *argv[],
49 COMPRESS_ACTION_LIST **ActionListHead
50 )
51 /*++
52
53 Routine Description:
54
55 Parse command line options
56
57 Arguments:
58
59 argc - number of arguments passed into the command line.
60 argv[] - files to compress and files to output compressed data to.
61 Options - Point to COMMAND_LINE_OPTIONS, receiving command line options.
62
63 Returns:
64
65 BOOLEAN: TRUE for a successful parse.
66 --*/
67 ;
68
69 STATIC
70 VOID
71 Usage (
72 CHAR8 *ExeName
73 )
74 /*++
75
76 Routine Description:
77
78 Print usage.
79
80 Arguments:
81
82 ExeName - Application's full path
83
84 --*/
85 ;
86
87
88 STATIC
89 BOOLEAN
90 ProcessFile (
91 CHAR8 *InFileName,
92 CHAR8 *OutFileName,
93 COMPRESS_TYPE CompressType
94 )
95 /*++
96
97 Routine Description:
98
99 Compress InFileName to OutFileName using algorithm specified by CompressType.
100
101 Arguments:
102
103 InFileName - Input file to compress
104 OutFileName - Output file compress to
105 CompressType - Compress algorithm, can be EFI_COMPRESS or TIANO_COMPRESS
106
107 Returns:
108
109 BOOLEAN: TRUE for compress file successfully
110
111 --*/
112 ;
113
114 int
115 main (
116 INT32 argc,
117 CHAR8 *argv[]
118 )
119 /*++
120
121 Routine Description:
122
123 Compresses the input files
124
125 Arguments:
126
127 argc - number of arguments passed into the command line.
128 argv[] - files to compress and files to output compressed data to.
129
130 Returns:
131
132 int: 0 for successful execution of the function.
133
134 --*/
135 {
136 COMPRESS_ACTION_LIST *ActionList;
137 COMPRESS_ACTION_LIST *NextAction;
138 UINT32 ActionCount;
139 UINT32 SuccessCount;
140
141 ActionList = NULL;
142 ActionCount = SuccessCount = 0;
143
144 if (!ParseCommandLine (argc, argv, &ActionList)) {
145 Usage (*argv);
146 return 1;
147 }
148
149 while (ActionList != NULL) {
150 ++ActionCount;
151 if (ProcessFile (
152 ActionList->InFileName,
153 ActionList->OutFileName,
154 ActionList->CompressType)
155 ) {
156 ++SuccessCount;
157 }
158 NextAction = ActionList;
159 ActionList = ActionList->NextAction;
160 free (NextAction);
161 }
162
163 fprintf (stdout, "\nCompressed %d files, %d succeed!\n", ActionCount, SuccessCount);
164 if (SuccessCount < ActionCount) {
165 return 1;
166 }
167
168 return 0;
169 }
170
171 STATIC
172 BOOLEAN
173 ParseCommandLine (
174 INT32 argc,
175 CHAR8 *argv[],
176 COMPRESS_ACTION_LIST **ActionListHead
177 )
178 {
179 COMPRESS_TYPE CurrentType;
180
181 COMPRESS_ACTION_LIST **Action;
182
183 Action = ActionListHead;
184 CurrentType = EFI_COMPRESS; // default compress algorithm
185
186 // Skip Exe Name
187 --argc;
188 ++argv;
189
190 while (argc > 0) {
191 if (strcmp (*argv, "-h") == 0 || strcmp (*argv, "-?") == 0) {
192 //
193 // 1. Directly return, help message will be printed.
194 //
195 return FALSE;
196
197 } else if (strncmp (*argv, "-t", 2) == 0) {
198 //
199 // 2. Specifying CompressType
200 //
201 if (_stricmp ((*argv)+2, "EFI") == 0) {
202 CurrentType = EFI_COMPRESS;
203 } else if (_stricmp ((*argv)+2, "Tiano") == 0) {
204 CurrentType = TIANO_COMPRESS;
205 } else {
206 fprintf (stdout, " ERROR: CompressType %s not supported!\n", (*argv)+2);
207 return FALSE;
208 }
209 } else {
210 //
211 // 3. Current parameter is *FileName
212 //
213 if (*Action == NULL) {
214 //
215 // need to create a new action item
216 //
217 *Action = (COMPRESS_ACTION_LIST*) malloc (sizeof **Action);
218 if (*Action == NULL) {
219 fprintf (stdout, " ERROR: malloc failed!\n");
220 return FALSE;
221 }
222 memset (*Action, 0, sizeof **Action);
223 (*Action)->CompressType = CurrentType;
224 }
225
226 //
227 // Assignment to InFileName and OutFileName in order
228 //
229 if ((*Action)->InFileName == NULL) {
230 (*Action)->InFileName = *argv;
231 } else {
232 (*Action)->OutFileName = *argv;
233 Action = &(*Action)->NextAction;
234 }
235 }
236
237 --argc;
238 ++argv;
239
240 }
241
242 if (*Action != NULL) {
243 assert ((*Action)->InFileName != NULL);
244 fprintf (stdout, " ERROR: Compress OutFileName not specified with InFileName: %s!\n", (*Action)->InFileName);
245 return FALSE;
246 }
247
248 if (*ActionListHead == NULL) {
249 return FALSE;
250 }
251 return TRUE;
252 }
253
254 STATIC
255 BOOLEAN
256 ProcessFile (
257 CHAR8 *InFileName,
258 CHAR8 *OutFileName,
259 COMPRESS_TYPE CompressType
260 )
261 {
262 EFI_STATUS Status;
263 FILE *InFileP;
264 FILE *OutFileP;
265 UINT32 SrcSize;
266 UINT32 DstSize;
267 UINT8 *SrcBuffer;
268 UINT8 *DstBuffer;
269 COMPRESS_FUNCTION CompressFunc;
270
271 SrcBuffer = DstBuffer = NULL;
272 InFileP = OutFileP = NULL;
273
274 fprintf (stdout, "%s --> %s\n", InFileName, OutFileName);
275
276 if ((OutFileP = fopen (OutFileName, "wb")) == NULL) {
277 fprintf (stdout, " ERROR: Can't open output file %s for write!\n", OutFileName);
278 goto ErrorHandle;
279 }
280
281 if ((InFileP = fopen (InFileName, "rb")) == NULL) {
282 fprintf (stdout, " ERROR: Can't open input file %s for read!\n", InFileName);
283 goto ErrorHandle;
284 }
285
286 //
287 // Get the size of source file
288 //
289 fseek (InFileP, 0, SEEK_END);
290 SrcSize = ftell (InFileP);
291 rewind (InFileP);
292 //
293 // Read in the source data
294 //
295 if ((SrcBuffer = malloc (SrcSize)) == NULL) {
296 fprintf (stdout, " ERROR: Can't allocate memory!\n");
297 goto ErrorHandle;
298 }
299
300 if (fread (SrcBuffer, 1, SrcSize, InFileP) != SrcSize) {
301 fprintf (stdout, " ERROR: Can't read from source!\n");
302 goto ErrorHandle;
303 }
304
305 //
306 // Choose the right compress algorithm
307 //
308 CompressFunc = (CompressType == EFI_COMPRESS) ? EfiCompress : TianoCompress;
309
310 //
311 // Get destination data size and do the compression
312 //
313 DstSize = 0;
314 Status = CompressFunc (SrcBuffer, SrcSize, DstBuffer, &DstSize);
315 if (Status != EFI_BUFFER_TOO_SMALL) {
316 fprintf (stdout, " Error: Compress failed: %x!\n", Status);
317 goto ErrorHandle;
318 }
319 if ((DstBuffer = malloc (DstSize)) == NULL) {
320 fprintf (stdout, " ERROR: Can't allocate memory!\n");
321 goto ErrorHandle;
322 }
323
324 Status = CompressFunc (SrcBuffer, SrcSize, DstBuffer, &DstSize);
325 if (EFI_ERROR (Status)) {
326 fprintf (stdout, " ERROR: Compress Error!\n");
327 goto ErrorHandle;
328 }
329
330 fprintf (stdout, " Orig Size = %ld\tComp Size = %ld\n", SrcSize, DstSize);
331
332 if (DstBuffer == NULL) {
333 fprintf (stdout, " ERROR: No destination to write to!\n");
334 goto ErrorHandle;
335 }
336
337 //
338 // Write out the result
339 //
340 if (fwrite (DstBuffer, 1, DstSize, OutFileP) != DstSize) {
341 fprintf (stdout, " ERROR: Can't write to destination file!\n");
342 goto ErrorHandle;
343 }
344
345 return TRUE;
346
347 ErrorHandle:
348 if (SrcBuffer) {
349 free (SrcBuffer);
350 }
351
352 if (DstBuffer) {
353 free (DstBuffer);
354 }
355
356 if (InFileP) {
357 fclose (InFileP);
358 }
359
360 if (OutFileP) {
361 fclose (OutFileP);
362 }
363 return FALSE;
364 }
365
366 VOID
367 Usage (
368 CHAR8 *ExeName
369 )
370 {
371 int Index;
372 const char *Str[] = {
373 UTILITY_NAME" "UTILITY_VERSION" - Intel EFI Compress Utility",
374 " Copyright (C), 2006 - 2008 Intel Corporation",
375
376 #if ( defined(UTILITY_BUILD) && defined(UTILITY_VENDOR) )
377 " Built from "UTILITY_BUILD", project of "UTILITY_VENDOR,
378 #endif
379 "",
380 "Usage:",
381 " "UTILITY_NAME" [OPTION] SOURCE DEST ...",
382 "Description:",
383 " Compress a list of SOURCE(s) to accordingly DEST(s) using the specified",
384 " compress algorithm.",
385 "Options:",
386 " -tCompressAlgo Optional compress algorithm (EFI | Tiano), case insensitive.",
387 " If ommitted, compress type specified ahead is used,",
388 " default is EFI\n"
389 " e.g.: EfiCompress a.in a.out -tTiano b.in b.out \\",
390 " c.in c.out -tEFI d.in d.out",
391 " a.in and d.in are compressed using EFI compress algorithm",
392 " b.in and c.in are compressed using Tiano compress algorithm",
393 NULL
394 };
395 for (Index = 0; Str[Index] != NULL; Index++) {
396 fprintf (stdout, "%s\n", Str[Index]);
397 }
398
399 }