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