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