]> git.proxmox.com Git - mirror_edk2.git/blobdiff - BaseTools/Source/C/TianoCompress/TianoCompress.c
BaseTools: Replace BSD License with BSD+Patent License
[mirror_edk2.git] / BaseTools / Source / C / TianoCompress / TianoCompress.c
index 145288bb8038a508956d44169fa92cd4146aaa41..56a9f14c8791142ef45a9d69cc669952f06765dd 100644 (file)
@@ -1,29 +1,17 @@
 /** @file\r
+Compression routine. The compression algorithm is a mixture of LZ77 and Huffman\r
+coding. LZ77 transforms the source data into a sequence of Original Characters\r
+and Pointers to repeated strings.\r
+This sequence is further divided into Blocks and Huffman codings are applied to\r
+each Block.\r
 \r
-Copyright (c) 2007 - 2010, Intel Corporation. All rights reserved.<BR>\r
-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
-\r
-  TianoCompress.c\r
-\r
-Abstract:\r
-\r
-  Compression routine. The compression algorithm is a mixture of\r
-  LZ77 and Huffman coding. LZ77 transforms the source data into a\r
-  sequence of Original Characters and Pointers to repeated strings.\r
-  This sequence is further divided into Blocks and Huffman codings\r
-  are applied to each Block.\r
+Copyright (c) 2007 - 2018, Intel Corporation. All rights reserved.<BR>\r
+SPDX-License-Identifier: BSD-2-Clause-Patent\r
 \r
 **/\r
 \r
 #include "Compress.h"\r
+#include "Decompress.h"\r
 #include "TianoCompress.h"\r
 #include "EfiUtilityMsgs.h"\r
 #include "ParseInf.h"\r
@@ -72,6 +60,7 @@ static BOOLEAN QuietMode = FALSE;
 //\r
 STATIC BOOLEAN ENCODE = FALSE;\r
 STATIC BOOLEAN DECODE = FALSE;\r
+STATIC BOOLEAN UEFIMODE = FALSE;\r
 STATIC UINT8  *mSrc, *mDst, *mSrcUpperLimit, *mDstUpperLimit;\r
 STATIC UINT8  *mLevel, *mText, *mChildCount, *mBuf, mCLen[NC], mPTLen[NPT], *mLen;\r
 STATIC INT16  mHeap[NC + 1];\r
@@ -107,7 +96,7 @@ Arguments:
   SrcBuffer   - The buffer storing the source data\r
   SrcSize     - The size of source data\r
   DstBuffer   - The buffer to store the compressed data\r
-  \r
+\r
   Version     - The version of de/compression algorithm.\r
                 Version 1 for EFI 1.1 de/compression algorithm.\r
                 Version 2 for Tiano de/compression algorithm.\r
@@ -142,12 +131,12 @@ Returns:
   mSrcUpperLimit  = mSrc + SrcSize;\r
   mDst            = DstBuffer;\r
   mDstUpperLimit  = mDst +*DstSize;\r
-    \r
+\r
   PutDword (0L);\r
   PutDword (0L);\r
-  \r
+\r
   MakeCrcTable ();\r
-  \r
+\r
   mOrigSize             = mCompSize = 0;\r
   mCrc                  = INIT_CRC;\r
 \r
@@ -158,7 +147,7 @@ Returns:
   if (EFI_ERROR (Status)) {\r
     return EFI_OUT_OF_RESOURCES;\r
   }\r
-  \r
+\r
   //\r
   // Null terminate the compressed data\r
   //\r
@@ -170,8 +159,8 @@ Returns:
   //\r
   // Fill in compressed size and original size\r
   //\r
-  mDst = DstBuffer; \r
\r
+  mDst = DstBuffer;\r
+\r
   PutDword (mCompSize + 1);\r
   PutDword (mOrigSize);\r
   //\r
@@ -179,10 +168,10 @@ Returns:
   //\r
 \r
   if (mCompSize + 1 + 8 > *DstSize) {\r
-    *DstSize = mCompSize + 1 + 8;    \r
+    *DstSize = mCompSize + 1 + 8;\r
     return EFI_BUFFER_TOO_SMALL;\r
   } else {\r
-    *DstSize = mCompSize + 1 + 8;   \r
+    *DstSize = mCompSize + 1 + 8;\r
     return EFI_SUCCESS;\r
   }\r
 }\r
@@ -197,13 +186,13 @@ PutDword (
 Routine Description:\r
 \r
   Put a dword to output stream\r
-  \r
+\r
 Arguments:\r
 \r
   Data    - the dword to put\r
-  \r
+\r
 Returns: (VOID)\r
-  \r
+\r
 --*/\r
 {\r
   if (mDst < mDstUpperLimit) {\r
@@ -233,8 +222,8 @@ AllocateMemory (
 Routine Description:\r
 \r
   Allocate memory spaces for data structures used in compression process\r
-  \r
-Argements: \r
+\r
+Arguments:\r
   VOID\r
 \r
 Returns:\r
@@ -247,6 +236,10 @@ Returns:
   UINT32  Index;\r
 \r
   mText = malloc (WNDSIZ * 2 + MAXMATCH);\r
+  if (mText == NULL) {\r
+    Error (NULL, 0, 4001, "Resource", "memory cannot be allocated!");\r
+    return EFI_OUT_OF_RESOURCES;\r
+  }\r
   for (Index = 0; Index < WNDSIZ * 2 + MAXMATCH; Index++) {\r
     mText[Index] = 0;\r
   }\r
@@ -257,6 +250,11 @@ Returns:
   mParent     = malloc (WNDSIZ * 2 * sizeof (*mParent));\r
   mPrev       = malloc (WNDSIZ * 2 * sizeof (*mPrev));\r
   mNext       = malloc ((MAX_HASH_VAL + 1) * sizeof (*mNext));\r
+  if (mLevel == NULL || mChildCount == NULL || mPosition == NULL ||\r
+    mParent == NULL || mPrev == NULL || mNext == NULL) {\r
+    Error (NULL, 0, 4001, "Resource", "memory cannot be allocated!");\r
+    return EFI_OUT_OF_RESOURCES;\r
+  }\r
 \r
   mBufSiz     = BLKSIZ;\r
   mBuf        = malloc (mBufSiz);\r
@@ -283,7 +281,7 @@ FreeMemory (
 Routine Description:\r
 \r
   Called when compression is completed to free memory previously allocated.\r
-  \r
+\r
 Arguments: (VOID)\r
 \r
 Returns: (VOID)\r
@@ -335,7 +333,7 @@ InitSlide (
 Routine Description:\r
 \r
   Initialize String Info Log data structures\r
-  \r
+\r
 Arguments: (VOID)\r
 \r
 Returns: (VOID)\r
@@ -375,16 +373,16 @@ Child (
 Routine Description:\r
 \r
   Find child node given the parent node and the edge character\r
-  \r
+\r
 Arguments:\r
 \r
   NodeQ       - the parent node\r
   CharC       - the edge character\r
-  \r
+\r
 Returns:\r
 \r
-  The child node (NIL if not found)  \r
-  \r
+  The child node (NIL if not found)\r
+\r
 --*/\r
 {\r
   NODE  NodeR;\r
@@ -413,13 +411,13 @@ MakeChild (
 Routine Description:\r
 \r
   Create a new child for a given parent node.\r
-  \r
+\r
 Arguments:\r
 \r
   Parent       - the parent node\r
   CharC   - the edge character\r
   Child       - the child node\r
-  \r
+\r
 Returns: (VOID)\r
 \r
 --*/\r
@@ -447,11 +445,11 @@ Split (
 Routine Description:\r
 \r
   Split a node.\r
-  \r
+\r
 Arguments:\r
 \r
   Old     - the node to split\r
-  \r
+\r
 Returns: (VOID)\r
 \r
 --*/\r
@@ -485,7 +483,7 @@ InsertNode (
 Routine Description:\r
 \r
   Insert string info for current position into the String Info Log\r
-  \r
+\r
 Arguments: (VOID)\r
 \r
 Returns: (VOID)\r
@@ -503,7 +501,7 @@ Returns: (VOID)
   if (mMatchLen >= 4) {\r
     //\r
     // We have just got a long match, the target tree\r
-    // can be located by MatchPos + 1. Travese the tree\r
+    // can be located by MatchPos + 1. Traverse the tree\r
     // from bottom up to get to a proper starting point.\r
     // The usage of PERC_FLAG ensures proper node deletion\r
     // in DeleteNode() later.\r
@@ -618,7 +616,7 @@ Routine Description:
 \r
   Delete outdated string info. (The Usage of PERC_FLAG\r
   ensures a clean deletion)\r
-  \r
+\r
 Arguments: (VOID)\r
 \r
 Returns: (VOID)\r
@@ -749,7 +747,7 @@ Routine Description:
 Arguments: (VOID)\r
 \r
 Returns:\r
-  \r
+\r
   EFI_SUCCESS           - The compression is successful\r
   EFI_OUT_0F_RESOURCES  - Not enough memory for compression process\r
 \r
@@ -835,7 +833,7 @@ CountTFreq (
 Routine Description:\r
 \r
   Count the frequencies for the Extra Set\r
-  \r
+\r
 Arguments: (VOID)\r
 \r
 Returns: (VOID)\r
@@ -894,13 +892,13 @@ WritePTLen (
 Routine Description:\r
 \r
   Outputs the code length array for the Extra Set or the Position Set.\r
-  \r
+\r
 Arguments:\r
 \r
   Number       - the number of symbols\r
   nbit    - the number of bits needed to represent 'n'\r
   Special - the special symbol that needs to be take care of\r
-  \r
+\r
 Returns: (VOID)\r
 \r
 --*/\r
@@ -942,7 +940,7 @@ WriteCLen (
 Routine Description:\r
 \r
   Outputs the code length array for Char&Length Set\r
-  \r
+\r
 Arguments: (VOID)\r
 \r
 Returns: (VOID)\r
@@ -1032,11 +1030,11 @@ SendBlock (
 Routine Description:\r
 \r
   Huffman code the block and output it.\r
-  \r
-Arguments: \r
+\r
+Arguments:\r
   (VOID)\r
 \r
-Returns: \r
+Returns:\r
   (VOID)\r
 \r
 --*/\r
@@ -1244,7 +1242,7 @@ Routine Description:
 Arguments:\r
 \r
   Number   - the rightmost n bits of the data is used\r
-  x   - the data \r
+  x   - the data\r
 \r
 Returns: (VOID)\r
 \r
@@ -1281,7 +1279,7 @@ FreadCrc (
 Routine Description:\r
 \r
   Read in source data\r
-  \r
+\r
 Arguments:\r
 \r
   Pointer   - the buffer to hold the data\r
@@ -1290,7 +1288,7 @@ Arguments:
 Returns:\r
 \r
   number of bytes actually read\r
-  \r
+\r
 --*/\r
 {\r
   INT32 Index;\r
@@ -1333,11 +1331,11 @@ CountLen (
 Routine Description:\r
 \r
   Count the number of each code length for a Huffman tree.\r
-  \r
+\r
 Arguments:\r
 \r
   Index   - the top node\r
-  \r
+\r
 Returns: (VOID)\r
 \r
 --*/\r
@@ -1364,11 +1362,11 @@ MakeLen (
 Routine Description:\r
 \r
   Create code length array for a Huffman tree\r
-  \r
+\r
 Arguments:\r
 \r
   Root   - the root of the tree\r
-  \r
+\r
 Returns:\r
 \r
   VOID\r
@@ -1460,7 +1458,7 @@ MakeCode (
 Routine Description:\r
 \r
   Assign code to each symbol based on the code length array\r
-  \r
+\r
 Arguments:\r
 \r
   Number     - number of symbols\r
@@ -1497,18 +1495,18 @@ MakeTree (
 Routine Description:\r
 \r
   Generates Huffman codes given a frequency distribution of symbols\r
-  \r
+\r
 Arguments:\r
 \r
   NParm    - number of symbols\r
   FreqParm - frequency of each symbol\r
   LenParm  - code length for each symbol\r
   CodeParm - code for each symbol\r
-  \r
+\r
 Returns:\r
 \r
   Root of the Huffman tree.\r
-  \r
+\r
 --*/\r
 {\r
   INT32 Index;\r
@@ -1584,22 +1582,22 @@ GetFileContents (
   OUT UINT32  *BufferLength\r
   )\r
 /*++\r
-        \r
+\r
 Routine Description:\r
-           \r
+\r
   Get the contents of file specified in InputFileName\r
   into FileBuffer.\r
-            \r
+\r
 Arguments:\r
-               \r
+\r
   InputFileName  - Name of the input file.\r
-                \r
+\r
   FileBuffer     - Output buffer to contain data\r
 \r
-  BufferLength   - Actual length of the data \r
+  BufferLength   - Actual length of the data\r
 \r
 Returns:\r
-                       \r
+\r
   EFI_SUCCESS on successful return\r
   EFI_ABORTED if unable to open input file.\r
 \r
@@ -1613,18 +1611,18 @@ Returns:
   //\r
   // Copy the file contents to the output buffer.\r
   //\r
-  InputFile = fopen (InputFileName, "rb");\r
+  InputFile = fopen (LongFilePath (InputFileName), "rb");\r
     if (InputFile == NULL) {\r
       Error (NULL, 0, 0001, "Error opening file: %s", InputFileName);\r
       return EFI_ABORTED;\r
     }\r
-  \r
+\r
   fseek (InputFile, 0, SEEK_END);\r
   FileSize = ftell (InputFile);\r
   fseek (InputFile, 0, SEEK_SET);\r
     //\r
     // Now read the contents of the file into the buffer\r
-    // \r
+    //\r
     if (FileSize > 0 && FileBuffer != NULL) {\r
       if (fread (FileBuffer, FileSize, 1, InputFile) != 1) {\r
         Error (NULL, 0, 0004, "Error reading contents of input file: %s", InputFileName);\r
@@ -1636,7 +1634,7 @@ Returns:
   fclose (InputFile);\r
   Size += (UINTN) FileSize;\r
   *BufferLength = Size;\r
-  \r
+\r
   if (FileBuffer != NULL) {\r
     return EFI_SUCCESS;\r
   } else {\r
@@ -1691,18 +1689,20 @@ Returns:
   // Summary usage\r
   //\r
   fprintf (stdout, "Usage: %s -e|-d [options] <input_file>\n\n", UTILITY_NAME);\r
-  \r
+\r
   //\r
   // Copyright declaration\r
-  // \r
-  fprintf (stdout, "Copyright (c) 2007 - 2010, Intel Corporation. All rights reserved.\n\n");\r
+  //\r
+  fprintf (stdout, "Copyright (c) 2007 - 2018, Intel Corporation. All rights reserved.\n\n");\r
 \r
   //\r
   // Details Option\r
   //\r
   fprintf (stdout, "Options:\n");\r
+  fprintf (stdout, "  --uefi\n\\r
+            Enable UefiCompress, use TianoCompress when without this option\n");\r
   fprintf (stdout, "  -o FileName, --output FileName\n\\r
-            File will be created to store the ouput content.\n");\r
+            File will be created to store the output content.\n");\r
   fprintf (stdout, "  -v, --verbose\n\\r
            Turn on verbose output with informational messages.\n");\r
   fprintf (stdout, "  -q, --quiet\n\\r
@@ -1737,7 +1737,7 @@ Returns:
   EFI_ABORTED    Could not generate the section\r
   EFI_OUT_OF_RESOURCES  No resource to complete the operation.\r
 \r
---*/  \r
+--*/\r
 {\r
   FILE       *OutputFile;\r
   char       *OutputFileName;\r
@@ -1751,17 +1751,21 @@ Returns:
   SCRATCH_DATA      *Scratch;\r
   UINT8      *Src;\r
   UINT32     OrigSize;\r
+  UINT32     CompSize;\r
 \r
   SetUtilityName(UTILITY_NAME);\r
-  \r
+\r
   FileBuffer = NULL;\r
   Src = NULL;\r
   OutBuffer = NULL;\r
   Scratch   = NULL;\r
   OrigSize = 0;\r
+  CompSize = 0;\r
   InputLength = 0;\r
   InputFileName = NULL;\r
   OutputFileName = NULL;\r
+  InputFile = NULL;\r
+  OutputFile = NULL;\r
   DstSize=0;\r
   DebugLevel = 0;\r
   DebugMode = FALSE;\r
@@ -1774,12 +1778,12 @@ Returns:
     Usage();\r
     return 0;\r
   }\r
-  \r
+\r
   if ((strcmp(argv[1], "-h") == 0) || (strcmp(argv[1], "--help") == 0)) {\r
     Usage();\r
     return 0;\r
   }\r
-  \r
+\r
   if ((strcmp(argv[1], "--version") == 0)) {\r
     Version();\r
     return 0;\r
@@ -1818,6 +1822,13 @@ Returns:
       continue;\r
     }\r
 \r
+    if (stricmp(argv[0], "--uefi") == 0) {\r
+      UEFIMODE = TRUE;\r
+      argc--;\r
+      argv++;\r
+      continue;\r
+    }\r
+\r
     if (stricmp (argv[0], "--debug") == 0) {\r
       argc-=2;\r
       argv++;\r
@@ -1850,7 +1861,7 @@ Returns:
       OutputFileName = argv[1];\r
       argc -=2;\r
       argv +=2;\r
-      continue; \r
+      continue;\r
     }\r
 \r
     if (argv[0][0]!='-') {\r
@@ -1861,7 +1872,7 @@ Returns:
     }\r
 \r
     Error (NULL, 0, 1000, "Unknown option", argv[0]);\r
-    goto ERROR;     \r
+    goto ERROR;\r
   }\r
 \r
   if (InputFileName == NULL) {\r
@@ -1879,7 +1890,7 @@ Returns:
   } else if (DebugMode) {\r
     SetPrintLevel(DebugLevel);\r
   }\r
-  \r
+\r
   if (VerboseMode) {\r
     VerboseMsg("%s tool start.\n", UTILITY_NAME);\r
    }\r
@@ -1888,13 +1899,13 @@ Returns:
     Error (NULL, 0, 4001, "Resource:", "Memory cannot be allocated!");\r
     goto ERROR;\r
   }\r
-    \r
-  InputFile = fopen (InputFileName, "rb");\r
+\r
+  InputFile = fopen (LongFilePath (InputFileName), "rb");\r
   if (InputFile == NULL) {\r
     Error (NULL, 0, 0001, "Error opening input file", InputFileName);\r
     goto ERROR;\r
   }\r
-        \r
+\r
   Status = GetFileContents(\r
             InputFileName,\r
             FileBuffer,\r
@@ -1904,7 +1915,7 @@ Returns:
     FileBuffer = (UINT8 *) malloc (InputLength);\r
     if (FileBuffer == NULL) {\r
       Error (NULL, 0, 4001, "Resource:", "Memory cannot be allocated!");\r
-      return 1;\r
+      goto ERROR;\r
     }\r
 \r
     Status = GetFileContents (\r
@@ -1915,24 +1926,19 @@ Returns:
   }\r
 \r
   if (EFI_ERROR(Status)) {\r
-    free(FileBuffer);\r
-    return 1;\r
+    Error (NULL, 0, 0004, "Error getting contents of file: %s", InputFileName);\r
+    goto ERROR;\r
   }\r
-   \r
-  if (OutputFileName != NULL) {\r
-    OutputFile = fopen (OutputFileName, "wb");\r
-    if (OutputFile == NULL) {\r
-      Error (NULL, 0, 0001, "Error opening output file for writing", OutputFileName);\r
-    if (InputFile != NULL) {\r
-      fclose (InputFile);\r
-      }\r
-      goto ERROR;\r
-      }\r
-    } else {\r
-      OutputFileName = DEFAULT_OUTPUT_FILE;\r
-      OutputFile = fopen (OutputFileName, "wb");\r
-    }\r
-    \r
+\r
+  if (OutputFileName == NULL) {\r
+    OutputFileName = DEFAULT_OUTPUT_FILE;\r
+  }\r
+  OutputFile = fopen (LongFilePath (OutputFileName), "wb");\r
+  if (OutputFile == NULL) {\r
+    Error (NULL, 0, 0001, "Error opening output file for writing", OutputFileName);\r
+    goto ERROR;\r
+  }\r
+\r
   if (ENCODE) {\r
   //\r
   // First call TianoCompress to get DstSize\r
@@ -1940,8 +1946,12 @@ Returns:
   if (DebugMode) {\r
     DebugMsg(UTILITY_NAME, 0, DebugLevel, "Encoding", NULL);\r
   }\r
-  Status = TianoCompress ((UINT8 *)FileBuffer, InputLength, OutBuffer, &DstSize);\r
-  \r
+  if (UEFIMODE) {\r
+    Status = EfiCompress ((UINT8 *)FileBuffer, InputLength, OutBuffer, &DstSize);\r
+  } else {\r
+    Status = TianoCompress ((UINT8 *)FileBuffer, InputLength, OutBuffer, &DstSize);\r
+  }\r
+\r
   if (Status == EFI_BUFFER_TOO_SMALL) {\r
     OutBuffer = (UINT8 *) malloc (DstSize);\r
     if (OutBuffer == NULL) {\r
@@ -1949,13 +1959,25 @@ Returns:
       goto ERROR;\r
     }\r
   }\r
-  Status = TianoCompress ((UINT8 *)FileBuffer, InputLength, OutBuffer, &DstSize);\r
+\r
+  if (UEFIMODE) {\r
+    Status = EfiCompress ((UINT8 *)FileBuffer, InputLength, OutBuffer, &DstSize);\r
+  } else {\r
+    Status = TianoCompress ((UINT8 *)FileBuffer, InputLength, OutBuffer, &DstSize);\r
+  }\r
   if (Status != EFI_SUCCESS) {\r
     Error (NULL, 0, 0007, "Error compressing file", NULL);\r
     goto ERROR;\r
   }\r
 \r
+  if (OutBuffer == NULL) {\r
+    Error (NULL, 0, 4001, "Resource:", "Memory cannot be allocated!");\r
+    goto ERROR;\r
+  }\r
+\r
   fwrite(OutBuffer,(size_t)DstSize, 1, OutputFile);\r
+  fclose(OutputFile);\r
+  fclose(InputFile);\r
   free(Scratch);\r
   free(FileBuffer);\r
   free(OutBuffer);\r
@@ -1966,47 +1988,72 @@ Returns:
   if (VerboseMode) {\r
     VerboseMsg("Encoding successful\n");\r
   }\r
-  return 0;  \r
+  return 0;\r
   }\r
   else if (DECODE) {\r
   if (DebugMode) {\r
     DebugMsg(UTILITY_NAME, 0, DebugLevel, "Decoding\n", NULL);\r
   }\r
-  //\r
-  // Get Compressed file original size\r
-  // \r
-  Src     = (UINT8 *)FileBuffer;                     \r
-  OrigSize  = Src[4] + (Src[5] << 8) + (Src[6] << 16) + (Src[7] << 24);  \r
-  \r
-  //\r
-  // Allocate OutputBuffer\r
-  //\r
-  OutBuffer = (UINT8 *)malloc(OrigSize);\r
-  if (OutBuffer == NULL) {\r
-    Error (NULL, 0, 4001, "Resource:", "Memory cannot be allocated!");\r
-    goto ERROR;\r
-   }  \r
 \r
-  Status = Decompress((VOID *)FileBuffer, (VOID *)OutBuffer, (VOID *)Scratch, 2);\r
-  if (Status != EFI_SUCCESS) {\r
-   goto ERROR;         \r
-  }\r
+  if (UEFIMODE) {\r
+    Status = Extract((VOID *)FileBuffer, InputLength, (VOID *)&OutBuffer, &DstSize, 1);\r
+    if (Status != EFI_SUCCESS) {\r
+      goto ERROR;\r
+    }\r
+    fwrite(OutBuffer, (size_t)(DstSize), 1, OutputFile);\r
+  } else {\r
+    if (InputLength < 8){\r
+      Error (NULL, 0, 3000, "Invalid", "The input file %s is too small.", InputFileName);\r
+      goto ERROR;\r
+    }\r
+    //\r
+    // Get Compressed file original size\r
+    //\r
+    Src     = (UINT8 *)FileBuffer;\r
+    OrigSize  = Src[4] + (Src[5] << 8) + (Src[6] << 16) + (Src[7] << 24);\r
+    CompSize  = Src[0] + (Src[1] << 8) + (Src[2] <<16) + (Src[3] <<24);\r
 \r
-  fwrite(OutBuffer, (size_t)(Scratch->mOrigSize), 1, OutputFile);\r
-  free(Scratch);\r
-  free(FileBuffer);\r
-  free(OutBuffer);\r
+    //\r
+    // Allocate OutputBuffer\r
+    //\r
+    if (InputLength < CompSize + 8 || (CompSize + 8) < 8) {\r
+      Error (NULL, 0, 3000, "Invalid", "The input file %s data is invalid.", InputFileName);\r
+      goto ERROR;\r
+    }\r
+    OutBuffer = (UINT8 *)malloc(OrigSize);\r
+    if (OutBuffer == NULL) {\r
+      Error (NULL, 0, 4001, "Resource:", "Memory cannot be allocated!");\r
+      goto ERROR;\r
+     }\r
+\r
+    Status = TDecompress((VOID *)FileBuffer, (VOID *)OutBuffer, (VOID *)Scratch, 2);\r
+    if (Status != EFI_SUCCESS) {\r
+      goto ERROR;\r
+    }\r
+    fwrite(OutBuffer, (size_t)(Scratch->mOrigSize), 1, OutputFile);\r
+  }\r
+  fclose(OutputFile);\r
+  fclose(InputFile);\r
+  if (Scratch != NULL) {\r
+    free(Scratch);\r
+  }\r
+  if (FileBuffer != NULL) {\r
+    free(FileBuffer);\r
+  }\r
+  if (OutBuffer != NULL) {\r
+    free(OutBuffer);\r
+  }\r
 \r
   if (DebugMode) {\r
     DebugMsg(UTILITY_NAME, 0, DebugLevel, "Encoding successful!\n", NULL);\r
   }\r
-  \r
+\r
   if (VerboseMode) {\r
     VerboseMsg("Decoding successful\n");\r
   }\r
   return 0;\r
   }\r
-  \r
+\r
 ERROR:\r
   if (DebugMode) {\r
     if (ENCODE) {\r
@@ -2015,6 +2062,12 @@ ERROR:
       DebugMsg(UTILITY_NAME, 0, DebugLevel, "Decoding Error\n", NULL);\r
     }\r
   }\r
+  if (OutputFile != NULL) {\r
+    fclose(OutputFile);\r
+  }\r
+  if (InputFile != NULL) {\r
+    fclose (InputFile);\r
+  }\r
   if (Scratch != NULL) {\r
     free(Scratch);\r
   }\r
@@ -2024,7 +2077,7 @@ ERROR:
   if (OutBuffer != NULL) {\r
     free(OutBuffer);\r
   }\r
-    \r
+\r
   if (VerboseMode) {\r
     VerboseMsg("%s tool done with return code is 0x%x.\n", UTILITY_NAME, GetUtilityStatus ());\r
   }\r
@@ -2051,11 +2104,11 @@ Returns: (VOID)
 \r
 --*/\r
 {\r
-  Sd->mBitBuf = (UINT32) (Sd->mBitBuf << NumOfBits);\r
+  Sd->mBitBuf = (UINT32) (((UINT64)Sd->mBitBuf) << NumOfBits);\r
 \r
   while (NumOfBits > Sd->mBitCount) {\r
 \r
-    Sd->mBitBuf |= (UINT32) (Sd->mSubBitBuf << (NumOfBits = (UINT16) (NumOfBits - Sd->mBitCount)));\r
+    Sd->mBitBuf |= (UINT32) (((UINT64)Sd->mSubBitBuf) << (NumOfBits = (UINT16) (NumOfBits - Sd->mBitCount)));\r
 \r
     if (Sd->mCompSize > 0) {\r
       //\r
@@ -2089,8 +2142,8 @@ GetBits (
 \r
 Routine Description:\r
 \r
-  Get NumOfBits of bits out from mBitBuf. Fill mBitBuf with subsequent \r
-  NumOfBits of bits from source. Returns NumOfBits of bits that are \r
+  Get NumOfBits of bits out from mBitBuf. Fill mBitBuf with subsequent\r
+  NumOfBits of bits from source. Returns NumOfBits of bits that are\r
   popped out.\r
 \r
 Arguments:\r
@@ -2134,9 +2187,9 @@ Arguments:
   BitLen    - Code length array\r
   TableBits - The width of the mapping table\r
   Table     - The table\r
-  \r
+\r
 Returns:\r
-  \r
+\r
   0         - OK.\r
   BAD_TABLE - The table is corrupted.\r
 \r
@@ -2147,7 +2200,7 @@ Returns:
   UINT16  Start[18];\r
   UINT16  *Pointer;\r
   UINT16  Index3;\r
-  volatile UINT16  Index;\r
+  UINT16  Index;\r
   UINT16  Len;\r
   UINT16  Char;\r
   UINT16  JuBits;\r
@@ -2156,15 +2209,20 @@ Returns:
   UINT16  Mask;\r
   UINT16  WordOfStart;\r
   UINT16  WordOfCount;\r
+  UINT16  MaxTableLength;\r
 \r
-  for (Index = 1; Index <= 16; Index++) {\r
+  for (Index = 0; Index <= 16; Index++) {\r
     Count[Index] = 0;\r
   }\r
 \r
   for (Index = 0; Index < NumOfChar; Index++) {\r
+    if (BitLen[Index] > 16) {\r
+      return (UINT16) BAD_TABLE;\r
+    }\r
     Count[BitLen[Index]]++;\r
   }\r
 \r
+  Start[0] = 0;\r
   Start[1] = 0;\r
 \r
   for (Index = 1; Index <= 16; Index++) {\r
@@ -2182,6 +2240,7 @@ Returns:
 \r
   JuBits = (UINT16) (16 - TableBits);\r
 \r
+  Weight[0] = 0;\r
   for (Index = 1; Index <= TableBits; Index++) {\r
     Start[Index] >>= JuBits;\r
     Weight[Index] = (UINT16) (1U << (TableBits - Index));\r
@@ -2203,11 +2262,12 @@ Returns:
 \r
   Avail = NumOfChar;\r
   Mask  = (UINT16) (1U << (15 - TableBits));\r
+  MaxTableLength = (UINT16) (1U << TableBits);\r
 \r
   for (Char = 0; Char < NumOfChar; Char++) {\r
 \r
     Len = BitLen[Char];\r
-    if (Len == 0) {\r
+    if (Len == 0 || Len >= 17) {\r
       continue;\r
     }\r
 \r
@@ -2215,6 +2275,10 @@ Returns:
 \r
     if (Len <= TableBits) {\r
 \r
+      if (Start[Len] >= NextCode || NextCode > MaxTableLength){\r
+        return (UINT16) BAD_TABLE;\r
+      }\r
+\r
       for (Index = Start[Len]; Index < NextCode; Index++) {\r
         Table[Index] = Char;\r
       }\r
@@ -2324,7 +2388,7 @@ Arguments:
   Sd        - The global scratch data\r
   nn        - Number of symbols\r
   nbit      - Number of bits needed to represent nn\r
-  Special   - The special symbol that needs to be taken care of \r
+  Special   - The special symbol that needs to be taken care of\r
 \r
 Returns:\r
 \r
@@ -2338,6 +2402,8 @@ Returns:
   volatile UINT16  Index;\r
   UINT32  Mask;\r
 \r
+  assert (nn <= NPT);\r
+\r
   Number = (UINT16) GetBits (Sd, nbit);\r
 \r
   if (Number == 0) {\r
@@ -2598,14 +2664,25 @@ Returns: (VOID)
       DataIdx     = Sd->mOutBuf - DecodeP (Sd) - 1;\r
 \r
       BytesRemain--;\r
+\r
       while ((INT16) (BytesRemain) >= 0) {\r
-        Sd->mDstBase[Sd->mOutBuf++] = Sd->mDstBase[DataIdx++];\r
         if (Sd->mOutBuf >= Sd->mOrigSize) {\r
           goto Done ;\r
         }\r
+        if (DataIdx >= Sd->mOrigSize) {\r
+          Sd->mBadTableFlag = (UINT16) BAD_TABLE;\r
+          goto Done ;\r
+        }\r
+        Sd->mDstBase[Sd->mOutBuf++] = Sd->mDstBase[DataIdx++];\r
 \r
         BytesRemain--;\r
       }\r
+      //\r
+      // Once mOutBuf is fully filled, directly return\r
+      //\r
+      if (Sd->mOutBuf >= Sd->mOrigSize) {\r
+        goto Done ;\r
+      }\r
     }\r
   }\r
 \r
@@ -2615,7 +2692,7 @@ Done:
 \r
 RETURN_STATUS\r
 EFIAPI\r
-Decompress (\r
+TDecompress (\r
   IN VOID  *Source,\r
   IN OUT VOID    *Destination,\r
   IN OUT VOID    *Scratch,\r
@@ -2632,11 +2709,11 @@ Arguments:
   Source          - The source buffer containing the compressed data.\r
   Destination     - The destination buffer to store the decompressed data\r
   Scratch         - The buffer used internally by the decompress routine. This  buffer is needed to store intermediate data.\r
-  Version         - 1 for EFI1.1 Decompress algoruthm, 2 for Tiano Decompress algorithm\r
+  Version         - 1 for EFI1.1 Decompress algorithm, 2 for Tiano Decompress algorithm\r
 \r
 Returns:\r
 \r
-  RETURN_SUCCESS           - Decompression is successfull\r
+  RETURN_SUCCESS           - Decompression is successful\r
   RETURN_INVALID_PARAMETER - The source data is corrupted\r
 \r
 --*/\r
@@ -2654,14 +2731,14 @@ Returns:
   assert(Source);\r
 //  assert(Destination);\r
   assert(Scratch);\r
-  \r
+\r
   Src     = (UINT8 *)Source;\r
   Dst     = (UINT8 *)Destination;\r
 \r
   Sd      = (SCRATCH_DATA *) Scratch;\r
   CompSize  = Src[0] + (Src[1] << 8) + (Src[2] << 16) + (Src[3] << 24);\r
   OrigSize  = Src[4] + (Src[5] << 8) + (Src[6] << 16) + (Src[7] << 24);\r
-  \r
+\r
   //\r
   // If compressed file size is 0, return\r
   //\r
@@ -2702,9 +2779,9 @@ Returns:
   //\r
   // Decompress it\r
   //\r
-  \r
+\r
   Decode (Sd);\r
-  \r
+\r
   if (Sd->mBadTableFlag != 0) {\r
     //\r
     // Something wrong with the source\r