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