]> git.proxmox.com Git - mirror_edk2.git/blobdiff - BaseTools/Source/C/LzmaCompress/LzmaCompress.c
BaseTools/LzmaCompress: Fix file handles not being closed
[mirror_edk2.git] / BaseTools / Source / C / LzmaCompress / LzmaCompress.c
index 16b91da177344ed79ca27dc7080466ac01f05a7f..be8790219699279ce831029d28b616eedfcce91f 100644 (file)
@@ -1,12 +1,12 @@
 /** @file\r
   LZMA Compress/Decompress tool (LzmaCompress)\r
 \r
-  Based on LZMA SDK 4.65:\r
+  Based on LZMA SDK 16.04:\r
     LzmaUtil.c -- Test application for LZMA compression\r
-    2008-11-23 : Igor Pavlov : Public domain\r
+    2016-10-04 : Igor Pavlov : Public domain\r
 \r
-  Copyright (c) 2006 - 2009, Intel Corporation<BR>\r
-  All rights reserved. This program and the accompanying materials\r
+  Copyright (c) 2006 - 2016, 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
 #include "Sdk/C/7zVersion.h"\r
 #include "Sdk/C/LzmaDec.h"\r
 #include "Sdk/C/LzmaEnc.h"\r
+#include "Sdk/C/Bra.h"\r
+#include "CommonLib.h"\r
+\r
+#define LZMA_HEADER_SIZE (LZMA_PROPS_SIZE + 8)\r
+\r
+typedef enum {\r
+  NoConverter, \r
+  X86Converter,\r
+  MaxConverter\r
+} CONVERTER_TYPE;\r
 \r
 const char *kCantReadMessage = "Can not read input file";\r
 const char *kCantWriteMessage = "Can not write output file";\r
 const char *kCantAllocateMessage = "Can not allocate memory";\r
 const char *kDataErrorMessage = "Data error";\r
 \r
-static void *SzAlloc(void *p, size_t size) { p = p; return MyAlloc(size); }\r
-static void SzFree(void *p, void *address) { p = p; MyFree(address); }\r
-static ISzAlloc g_Alloc = { SzAlloc, SzFree };\r
-\r
 static Bool mQuietMode = False;\r
+static CONVERTER_TYPE mConType = NoConverter;\r
 \r
 #define UTILITY_NAME "LzmaCompress"\r
 #define UTILITY_MAJOR_VERSION 0\r
-#define UTILITY_MINOR_VERSION 1\r
+#define UTILITY_MINOR_VERSION 2\r
 #define INTEL_COPYRIGHT \\r
-  "Copyright (c) 2009, Intel Corporation. All rights reserved."\r
+  "Copyright (c) 2009-2016, Intel Corporation. All rights reserved."\r
 void PrintHelp(char *buffer)\r
 {\r
   strcat(buffer,\r
@@ -53,6 +60,7 @@ void PrintHelp(char *buffer)
              "  -e: encode file\n"\r
              "  -d: decode file\n"\r
              "  -o FileName, --output FileName: specify the output filename\n"\r
+             "  --f86: enable converter for x86 code\n"\r
              "  -v, --verbose: increase output messages\n"\r
              "  -q, --quiet: reduce output messages\n"\r
              "  --debug [0-9]: set debug level\n"\r
@@ -82,124 +90,154 @@ int PrintUserError(char *buffer)
 \r
 void PrintVersion(char *buffer)\r
 {\r
-  sprintf (buffer, "%s Version %d.%d", UTILITY_NAME, UTILITY_MAJOR_VERSION, UTILITY_MINOR_VERSION);\r
+  sprintf (buffer, "%s Version %d.%d %s ", UTILITY_NAME, UTILITY_MAJOR_VERSION, UTILITY_MINOR_VERSION, __BUILD_VERSION);\r
 }\r
 \r
-#define IN_BUF_SIZE (1 << 16)\r
-#define OUT_BUF_SIZE (1 << 16)\r
-\r
-static SRes Decode2(CLzmaDec *state, ISeqOutStream *outStream, ISeqInStream *inStream,\r
-    UInt64 unpackSize)\r
+static SRes Encode(ISeqOutStream *outStream, ISeqInStream *inStream, UInt64 fileSize)\r
 {\r
-  int thereIsSize = (unpackSize != (UInt64)(Int64)-1);\r
-  Byte inBuf[IN_BUF_SIZE];\r
-  Byte outBuf[OUT_BUF_SIZE];\r
-  size_t inPos = 0, inSize = 0, outPos = 0;\r
-  LzmaDec_Init(state);\r
-  for (;;)\r
-  {\r
-    if (inPos == inSize)\r
-    {\r
-      inSize = IN_BUF_SIZE;\r
-      RINOK(inStream->Read(inStream, inBuf, &inSize));\r
-      inPos = 0;\r
-    }\r
-    {\r
-      SRes res;\r
-      SizeT inProcessed = inSize - inPos;\r
-      SizeT outProcessed = OUT_BUF_SIZE - outPos;\r
-      ELzmaFinishMode finishMode = LZMA_FINISH_ANY;\r
-      ELzmaStatus status;\r
-      if (thereIsSize && outProcessed > unpackSize)\r
-      {\r
-        outProcessed = (SizeT)unpackSize;\r
-        finishMode = LZMA_FINISH_END;\r
-      }\r
-\r
-      res = LzmaDec_DecodeToBuf(state, outBuf + outPos, &outProcessed,\r
-        inBuf + inPos, &inProcessed, finishMode, &status);\r
-      inPos += inProcessed;\r
-      outPos += outProcessed;\r
-      unpackSize -= outProcessed;\r
-\r
-      if (outStream)\r
-        if (outStream->Write(outStream, outBuf, outPos) != outPos)\r
-          return SZ_ERROR_WRITE;\r
+  SRes res;\r
+  size_t inSize = (size_t)fileSize;\r
+  Byte *inBuffer = 0;\r
+  Byte *outBuffer = 0;\r
+  Byte *filteredStream = 0;\r
+  size_t outSize;\r
+  CLzmaEncProps props;\r
 \r
-      outPos = 0;\r
+  LzmaEncProps_Init(&props);\r
+  LzmaEncProps_Normalize(&props);\r
+\r
+  if (inSize != 0) {\r
+    inBuffer = (Byte *)MyAlloc(inSize);\r
+    if (inBuffer == 0)\r
+      return SZ_ERROR_MEM;\r
+  } else {\r
+    return SZ_ERROR_INPUT_EOF;\r
+  }\r
+  \r
+  if (SeqInStream_Read(inStream, inBuffer, inSize) != SZ_OK) {\r
+    res = SZ_ERROR_READ;\r
+    goto Done;\r
+  }\r
 \r
-      if (res != SZ_OK || (thereIsSize && unpackSize == 0))\r
-        return res;\r
+  // we allocate 105% of original size + 64KB for output buffer\r
+  outSize = (size_t)fileSize / 20 * 21 + (1 << 16);\r
+  outBuffer = (Byte *)MyAlloc(outSize);\r
+  if (outBuffer == 0) {\r
+    res = SZ_ERROR_MEM;\r
+    goto Done;\r
+  }\r
+  \r
+  {\r
+    int i;\r
+    for (i = 0; i < 8; i++)\r
+      outBuffer[i + LZMA_PROPS_SIZE] = (Byte)(fileSize >> (8 * i));\r
+  }\r
 \r
-      if (inProcessed == 0 && outProcessed == 0)\r
+  if (mConType != NoConverter)\r
+  {\r
+    filteredStream = (Byte *)MyAlloc(inSize);\r
+    if (filteredStream == 0) {\r
+      res = SZ_ERROR_MEM;\r
+      goto Done;\r
+    }\r
+    memcpy(filteredStream, inBuffer, inSize);\r
+    \r
+    if (mConType == X86Converter) {\r
       {\r
-        if (thereIsSize || status != LZMA_STATUS_FINISHED_WITH_MARK)\r
-          return SZ_ERROR_DATA;\r
-        return res;\r
+        UInt32 x86State;\r
+        x86_Convert_Init(x86State);\r
+        x86_Convert(filteredStream, (SizeT) inSize, 0, &x86State, 1);\r
       }\r
     }\r
   }\r
-}\r
-\r
-static SRes Decode(ISeqOutStream *outStream, ISeqInStream *inStream)\r
-{\r
-  UInt64 unpackSize;\r
-  int i;\r
-  SRes res = 0;\r
 \r
-  CLzmaDec state;\r
-\r
-  /* header: 5 bytes of LZMA properties and 8 bytes of uncompressed size */\r
-  unsigned char header[LZMA_PROPS_SIZE + 8];\r
+  {\r
+    size_t outSizeProcessed = outSize - LZMA_HEADER_SIZE;\r
+    size_t outPropsSize = LZMA_PROPS_SIZE;\r
+    \r
+    res = LzmaEncode(outBuffer + LZMA_HEADER_SIZE, &outSizeProcessed,\r
+        mConType != NoConverter ? filteredStream : inBuffer, inSize,\r
+        &props, outBuffer, &outPropsSize, 0,\r
+        NULL, &g_Alloc, &g_Alloc);\r
+    \r
+    if (res != SZ_OK)\r
+      goto Done;\r
+\r
+    outSize = LZMA_HEADER_SIZE + outSizeProcessed;\r
+  }\r
 \r
-  /* Read and parse header */\r
+  if (outStream->Write(outStream, outBuffer, outSize) != outSize)\r
+    res = SZ_ERROR_WRITE;\r
 \r
-  RINOK(SeqInStream_Read(inStream, header, sizeof(header)));\r
+Done:\r
+  MyFree(outBuffer);\r
+  MyFree(inBuffer);\r
+  MyFree(filteredStream);\r
 \r
-  unpackSize = 0;\r
-  for (i = 0; i < 8; i++)\r
-    unpackSize += (UInt64)header[LZMA_PROPS_SIZE + i] << (i * 8);\r
-\r
-  LzmaDec_Construct(&state);\r
-  RINOK(LzmaDec_Allocate(&state, header, LZMA_PROPS_SIZE, &g_Alloc));\r
-  res = Decode2(&state, outStream, inStream, unpackSize);\r
-  LzmaDec_Free(&state, &g_Alloc);\r
   return res;\r
 }\r
 \r
-static SRes Encode(ISeqOutStream *outStream, ISeqInStream *inStream, UInt64 fileSize, char *rs)\r
+static SRes Decode(ISeqOutStream *outStream, ISeqInStream *inStream, UInt64 fileSize)\r
 {\r
-  CLzmaEncHandle enc;\r
   SRes res;\r
-  CLzmaEncProps props;\r
+  size_t inSize = (size_t)fileSize;\r
+  Byte *inBuffer = 0;\r
+  Byte *outBuffer = 0;\r
+  size_t outSize = 0;\r
+  size_t inSizePure;\r
+  ELzmaStatus status;\r
+  UInt64 outSize64 = 0;\r
 \r
-  rs = rs;\r
+  int i;\r
 \r
-  enc = LzmaEnc_Create(&g_Alloc);\r
-  if (enc == 0)\r
+  if (inSize < LZMA_HEADER_SIZE) \r
+    return SZ_ERROR_INPUT_EOF;\r
+\r
+  inBuffer = (Byte *)MyAlloc(inSize);\r
+  if (inBuffer == 0)\r
     return SZ_ERROR_MEM;\r
+  \r
+  if (SeqInStream_Read(inStream, inBuffer, inSize) != SZ_OK) {\r
+    res = SZ_ERROR_READ;\r
+    goto Done;\r
+  }\r
 \r
-  LzmaEncProps_Init(&props);\r
-  res = LzmaEnc_SetProps(enc, &props);\r
+  for (i = 0; i < 8; i++)\r
+    outSize64 += ((UInt64)inBuffer[LZMA_PROPS_SIZE + i]) << (i * 8);\r
+\r
+  outSize = (size_t)outSize64;\r
+  if (outSize != 0) {\r
+    outBuffer = (Byte *)MyAlloc(outSize);\r
+    if (outBuffer == 0) {\r
+      res = SZ_ERROR_MEM;\r
+      goto Done;\r
+    }\r
+  } else {\r
+    res = SZ_OK;\r
+    goto Done;\r
+  }\r
 \r
-  if (res == SZ_OK)\r
-  {\r
-    Byte header[LZMA_PROPS_SIZE + 8];\r
-    size_t headerSize = LZMA_PROPS_SIZE;\r
-    int i;\r
+  inSizePure = inSize - LZMA_HEADER_SIZE;\r
+  res = LzmaDecode(outBuffer, &outSize, inBuffer + LZMA_HEADER_SIZE, &inSizePure,\r
+      inBuffer, LZMA_PROPS_SIZE, LZMA_FINISH_END, &status, &g_Alloc);\r
 \r
-    res = LzmaEnc_WriteProperties(enc, header, &headerSize);\r
-    for (i = 0; i < 8; i++)\r
-      header[headerSize++] = (Byte)(fileSize >> (8 * i));\r
-    if (outStream->Write(outStream, header, headerSize) != headerSize)\r
-      res = SZ_ERROR_WRITE;\r
-    else\r
-    {\r
-      if (res == SZ_OK)\r
-        res = LzmaEnc_Encode(enc, outStream, inStream, NULL, &g_Alloc, &g_Alloc);\r
-    }\r
+  if (res != SZ_OK)\r
+    goto Done;\r
+\r
+  if (mConType == X86Converter)\r
+  {\r
+    UInt32 x86State;\r
+    x86_Convert_Init(x86State);\r
+    x86_Convert(outBuffer, (SizeT) outSize, 0, &x86State, 0);\r
   }\r
-  LzmaEnc_Destroy(enc, &g_Alloc, &g_Alloc);\r
+\r
+  if (outStream->Write(outStream, outBuffer, outSize) != outSize)\r
+    res = SZ_ERROR_WRITE;\r
+\r
+Done:\r
+  MyFree(outBuffer);\r
+  MyFree(inBuffer);\r
+\r
   return res;\r
 }\r
 \r
@@ -213,6 +251,7 @@ int main2(int numArgs, const char *args[], char *rs)
   const char *inputFile = NULL;\r
   const char *outputFile = "file.tmp";\r
   int param;\r
+  UInt64 fileSize;\r
 \r
   FileSeqInStream_CreateVTable(&inStream);\r
   File_Construct(&inStream.file);\r
@@ -230,6 +269,8 @@ int main2(int numArgs, const char *args[], char *rs)
     if (strcmp(args[param], "-e") == 0 || strcmp(args[param], "-d") == 0) {\r
       encodeMode = (args[param][1] == 'e');\r
       modeWasSet = True;\r
+    } else if (strcmp(args[param], "--f86") == 0) {\r
+      mConType = X86Converter;\r
     } else if (strcmp(args[param], "-o") == 0 ||\r
                strcmp(args[param], "--output") == 0) {\r
       if (numArgs < (param + 2)) {\r
@@ -288,24 +329,26 @@ int main2(int numArgs, const char *args[], char *rs)
   if (InFile_Open(&inStream.file, inputFile) != 0)\r
     return PrintError(rs, "Can not open input file");\r
 \r
-  if (OutFile_Open(&outStream.file, outputFile) != 0)\r
+  if (OutFile_Open(&outStream.file, outputFile) != 0) {\r
+    File_Close(&inStream.file);\r
     return PrintError(rs, "Can not open output file");\r
+  }\r
+\r
+  File_GetLength(&inStream.file, &fileSize);\r
 \r
   if (encodeMode)\r
   {\r
-    UInt64 fileSize;\r
-    File_GetLength(&inStream.file, &fileSize);\r
     if (!mQuietMode) {\r
       printf("Encoding\n");\r
     }\r
-    res = Encode(&outStream.s, &inStream.s, fileSize, rs);\r
+    res = Encode(&outStream.s, &inStream.s, fileSize);\r
   }\r
   else\r
   {\r
     if (!mQuietMode) {\r
       printf("Decoding\n");\r
     }\r
-    res = Decode(&outStream.s, &inStream.s);\r
+    res = Decode(&outStream.s, &inStream.s, fileSize);\r
   }\r
 \r
   File_Close(&outStream.file);\r