]> git.proxmox.com Git - mirror_edk2.git/blobdiff - EdkCompatibilityPkg/Sample/Tools/Source/EfiCompress/EfiCompressMain.c
Add in the 1st version of ECP.
[mirror_edk2.git] / EdkCompatibilityPkg / Sample / Tools / Source / EfiCompress / EfiCompressMain.c
diff --git a/EdkCompatibilityPkg/Sample/Tools/Source/EfiCompress/EfiCompressMain.c b/EdkCompatibilityPkg/Sample/Tools/Source/EfiCompress/EfiCompressMain.c
new file mode 100644 (file)
index 0000000..180422c
--- /dev/null
@@ -0,0 +1,386 @@
+/*++ \r
+\r
+Copyright 2006 - 2007, Intel Corporation                                                         \r
+All rights reserved. This program and the accompanying materials                          \r
+are licensed and made available under the terms and conditions of the BSD License         \r
+which accompanies this distribution.  The full text of the license may be found at        \r
+http://opensource.org/licenses/bsd-license.php                                            \r
+                                                                                          \r
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,                     \r
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.             \r
+\r
+Module Name:\r
+  EfiCompressMain.c\r
+  \r
+Abstract:\r
+\r
+--*/\r
+\r
+#include <stdlib.h>\r
+#include <string.h>\r
+#include <ctype.h>\r
+#include <assert.h>\r
+#include <stdarg.h>\r
+#include <stdio.h>\r
+#include "TianoCommon.h"\r
+#include "Compress.h"\r
+\r
+typedef enum {\r
+  EFI_COMPRESS   = 1,\r
+  TIANO_COMPRESS = 2\r
+} COMPRESS_TYPE;\r
+\r
+typedef struct _COMPRESS_ACTION_LIST {\r
+  struct _COMPRESS_ACTION_LIST   *NextAction;\r
+  INT32                          CompressType;\r
+  CHAR8                          *InFileName;\r
+  CHAR8                          *OutFileName;\r
+} COMPRESS_ACTION_LIST;\r
+\r
+\r
+STATIC\r
+BOOLEAN\r
+ParseCommandLine (\r
+  INT32                 argc,\r
+  CHAR8                 *argv[],\r
+  COMPRESS_ACTION_LIST  **ActionListHead\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Parse command line options\r
+\r
+Arguments:\r
+  \r
+  argc    - number of arguments passed into the command line.\r
+  argv[]  - files to compress and files to output compressed data to.\r
+  Options - Point to COMMAND_LINE_OPTIONS, receiving command line options.\r
+\r
+Returns:\r
+  \r
+  BOOLEAN: TRUE for a successful parse.\r
+--*/\r
+;\r
+\r
+STATIC\r
+VOID\r
+Usage (\r
+  CHAR8 *ExeName\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Print usage.\r
+\r
+Arguments:\r
+  \r
+  ExeName  - Application's full path\r
+\r
+--*/\r
+;\r
+\r
+\r
+STATIC\r
+BOOLEAN\r
+ProcessFile (\r
+  CHAR8         *InFileName,\r
+  CHAR8         *OutFileName,\r
+  COMPRESS_TYPE CompressType\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+  \r
+  Compress InFileName to OutFileName using algorithm specified by CompressType.\r
+\r
+Arguments:\r
+  \r
+  InFileName    - Input file to compress\r
+  OutFileName   - Output file compress to\r
+  CompressType  - Compress algorithm, can be EFI_COMPRESS or TIANO_COMPRESS\r
+\r
+Returns:\r
+  \r
+  BOOLEAN: TRUE for compress file successfully\r
+\r
+--*/\r
+;\r
+\r
+int\r
+main (\r
+  INT32 argc,\r
+  CHAR8 *argv[]\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Compresses the input files\r
+\r
+Arguments:\r
+\r
+  argc   - number of arguments passed into the command line.\r
+  argv[] - files to compress and files to output compressed data to.\r
+\r
+Returns:\r
+\r
+  int: 0 for successful execution of the function.\r
+\r
+--*/\r
+{\r
+  COMPRESS_ACTION_LIST *ActionList;\r
+  COMPRESS_ACTION_LIST *NextAction;\r
+  UINT32               ActionCount;\r
+  UINT32               SuccessCount;\r
+\r
+  ActionList            = NULL;\r
+  ActionCount          = SuccessCount = 0;\r
+\r
+  if (!ParseCommandLine (argc, argv, &ActionList)) {\r
+    Usage (*argv);\r
+    return 1;\r
+  }\r
+\r
+  while (ActionList != NULL) {\r
+    ++ActionCount;\r
+    if (ProcessFile (\r
+          ActionList->InFileName, \r
+          ActionList->OutFileName, \r
+          ActionList->CompressType)\r
+        ) {\r
+      ++SuccessCount;\r
+    }\r
+    NextAction = ActionList;\r
+    ActionList = ActionList->NextAction;\r
+    free (NextAction);\r
+  }\r
+\r
+  fprintf (stdout, "\nCompressed %d files, %d succeed!\n", ActionCount, SuccessCount);\r
+  if (SuccessCount < ActionCount) {\r
+    return 1;\r
+  }\r
+\r
+  return 0;\r
+}\r
+\r
+STATIC\r
+BOOLEAN\r
+ParseCommandLine (\r
+  INT32                 argc,\r
+  CHAR8                 *argv[],\r
+  COMPRESS_ACTION_LIST  **ActionListHead\r
+  )\r
+{\r
+  COMPRESS_TYPE         CurrentType;\r
+\r
+  COMPRESS_ACTION_LIST  **Action;\r
+  \r
+  Action           =    ActionListHead;\r
+  CurrentType      =    EFI_COMPRESS;     // default compress algorithm\r
+\r
+  // Skip Exe Name\r
+  --argc;\r
+  ++argv;\r
+\r
+  while (argc > 0) {\r
+    if (strcmp (*argv, "-h") == 0 || strcmp (*argv, "-?") == 0) {\r
+      //\r
+      // 1. Directly return, help message will be printed.\r
+      //\r
+      return FALSE;\r
+    \r
+    } else if (strncmp (*argv, "-t", 2) == 0) {\r
+      //\r
+      // 2. Specifying CompressType\r
+      //\r
+      if (_stricmp ((*argv)+2, "EFI") == 0) {\r
+        CurrentType = EFI_COMPRESS;\r
+      } else if (_stricmp ((*argv)+2, "Tiano") == 0) {\r
+        CurrentType = TIANO_COMPRESS;\r
+      } else {\r
+        fprintf (stdout, "  ERROR: CompressType %s not supported!\n", (*argv)+2);\r
+        return FALSE;\r
+      }\r
+    } else {\r
+      //\r
+      // 3. Current parameter is *FileName\r
+      //\r
+      if (*Action == NULL) { \r
+        //\r
+        // need to create a new action item\r
+        //\r
+        *Action = (COMPRESS_ACTION_LIST*) malloc (sizeof **Action);\r
+        if (*Action == NULL) {\r
+          fprintf (stdout, "  ERROR: malloc failed!\n");\r
+          return FALSE;\r
+        }\r
+        memset (*Action, 0, sizeof **Action);\r
+        (*Action)->CompressType = CurrentType;\r
+      }\r
+\r
+      //\r
+      // Assignment to InFileName and OutFileName in order\r
+      // \r
+      if ((*Action)->InFileName == NULL) {\r
+        (*Action)->InFileName  = *argv;\r
+      } else {\r
+        (*Action)->OutFileName = *argv;\r
+        Action                 = &(*Action)->NextAction;\r
+      }\r
+    }\r
+\r
+    --argc;\r
+    ++argv;\r
+\r
+  }\r
+  \r
+  if (*Action != NULL) {\r
+    assert ((*Action)->InFileName != NULL);\r
+    fprintf (stdout, "  ERROR: Compress OutFileName not specified with InFileName: %s!\n", (*Action)->InFileName);\r
+    return FALSE;\r
+  }\r
+\r
+  if (*ActionListHead == NULL) {\r
+    return FALSE;\r
+  }\r
+  return TRUE;\r
+}\r
+\r
+STATIC\r
+BOOLEAN\r
+ProcessFile (\r
+  CHAR8         *InFileName,\r
+  CHAR8         *OutFileName,\r
+  COMPRESS_TYPE CompressType\r
+  )\r
+{\r
+  EFI_STATUS          Status;\r
+  FILE                *InFileP;\r
+  FILE                *OutFileP;\r
+  UINT32              SrcSize;\r
+  UINT32              DstSize;\r
+  UINT8               *SrcBuffer;\r
+  UINT8               *DstBuffer;\r
+  COMPRESS_FUNCTION   CompressFunc;\r
+\r
+  SrcBuffer     =     DstBuffer = NULL;\r
+  InFileP       =     OutFileP  = NULL;\r
+\r
+  fprintf (stdout, "%s --> %s\n", InFileName, OutFileName);\r
+\r
+  if ((OutFileP = fopen (OutFileName, "wb")) == NULL) {\r
+    fprintf (stdout, "  ERROR: Can't open output file %s for write!\n", OutFileName);\r
+    goto ErrorHandle;\r
+  }\r
+\r
+  if ((InFileP = fopen (InFileName, "rb")) == NULL) {\r
+    fprintf (stdout, "  ERROR: Can't open input file %s for read!\n", InFileName);\r
+    goto ErrorHandle;\r
+  }\r
+  \r
+  //\r
+  // Get the size of source file\r
+  //\r
+  fseek (InFileP, 0, SEEK_END);\r
+  SrcSize = ftell (InFileP);\r
+  rewind (InFileP);\r
+  //\r
+  // Read in the source data\r
+  //\r
+  if ((SrcBuffer = malloc (SrcSize)) == NULL) {\r
+    fprintf (stdout, "  ERROR: Can't allocate memory!\n");\r
+    goto ErrorHandle;\r
+  }\r
+\r
+  if (fread (SrcBuffer, 1, SrcSize, InFileP) != SrcSize) {\r
+    fprintf (stdout, "  ERROR: Can't read from source!\n");\r
+    goto ErrorHandle;\r
+  }\r
+\r
+  //\r
+  // Choose the right compress algorithm\r
+  //\r
+  CompressFunc = (CompressType == EFI_COMPRESS) ? EfiCompress : TianoCompress;\r
+\r
+  //\r
+  // Get destination data size and do the compression\r
+  //\r
+  DstSize = 0;\r
+  Status = CompressFunc (SrcBuffer, SrcSize, DstBuffer, &DstSize);\r
+  if (Status != EFI_BUFFER_TOO_SMALL) {\r
+    fprintf (stdout, "  Error: Compress failed: %x!\n", Status);\r
+    goto ErrorHandle;\r
+  }\r
+  if ((DstBuffer = malloc (DstSize)) == NULL) {\r
+    fprintf (stdout, "  ERROR: Can't allocate memory!\n");\r
+    goto ErrorHandle;\r
+  }\r
+\r
+  Status = CompressFunc (SrcBuffer, SrcSize, DstBuffer, &DstSize);\r
+  if (EFI_ERROR (Status)) {\r
+    fprintf (stdout, "  ERROR: Compress Error!\n");\r
+    goto ErrorHandle;\r
+  }\r
+\r
+  fprintf (stdout, "  Orig Size = %ld\tComp Size = %ld\n", SrcSize, DstSize);\r
+\r
+  if (DstBuffer == NULL) {\r
+    fprintf (stdout, "  ERROR: No destination to write to!\n");\r
+    goto ErrorHandle;\r
+  }\r
+\r
+  //\r
+  // Write out the result\r
+  //\r
+  if (fwrite (DstBuffer, 1, DstSize, OutFileP) != DstSize) {\r
+    fprintf (stdout, "  ERROR: Can't write to destination file!\n");\r
+    goto ErrorHandle;\r
+  }\r
+\r
+  return TRUE;\r
+\r
+ErrorHandle:\r
+  if (SrcBuffer) {\r
+    free (SrcBuffer);\r
+  }\r
+\r
+  if (DstBuffer) {\r
+    free (DstBuffer);\r
+  }\r
+\r
+  if (InFileP) {\r
+    fclose (InFileP);\r
+  }\r
+\r
+  if (OutFileP) {\r
+    fclose (OutFileP);\r
+  }\r
+  return FALSE;\r
+}\r
+\r
+VOID\r
+Usage (\r
+  CHAR8 *ExeName\r
+  )\r
+{\r
+  fprintf (\r
+      stdout, \r
+      "\n"\r
+      "Usage: %s [-tCompressType] InFileName OutFileName\n"\r
+      "       %*c [[-tCompressType] InFileName OutFileName ...]\n"\r
+      "\n"\r
+      "where:\n"\r
+      "  CompressType - optional compress algorithm (EFI | Tiano), case insensitive.\n"\r
+      "                 If ommitted, compress type specified ahead is used, \n"\r
+      "                 default is EFI\n"\r
+      "                 e.g.: EfiCompress a.in a.out -tTiano b.in b.out \\ \n"\r
+      "                                     c.in c.out -tEFI d.in d.out\n"\r
+      "                 a.in and d.in are compressed using EFI compress algorithm\n"\r
+      "                 b.in and c.in are compressed using Tiano compress algorithm\n"\r
+      "  InFileName   - input file path\n"\r
+      "  OutFileName  - output file path\n",\r
+      ExeName, strlen(ExeName), ' '\r
+      );\r
+}\r