]> git.proxmox.com Git - mirror_edk2.git/blobdiff - BaseTools/Source/C/LzmaCompress/LzmaCompress.c
Check In tool source code based on Build tool project revision r1655.
[mirror_edk2.git] / BaseTools / Source / C / LzmaCompress / LzmaCompress.c
diff --git a/BaseTools/Source/C/LzmaCompress/LzmaCompress.c b/BaseTools/Source/C/LzmaCompress/LzmaCompress.c
new file mode 100644 (file)
index 0000000..7207a75
--- /dev/null
@@ -0,0 +1,337 @@
+/** @file\r
+  LZMA Compress/Decompress tool (LzmaCompress)\r
+\r
+  Based on LZMA SDK 4.65:\r
+    LzmaUtil.c -- Test application for LZMA compression\r
+    2008-11-23 : Igor Pavlov : Public domain\r
+\r
+  Copyright (c) 2006 - 2009, Intel Corporation<BR>\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
+**/\r
+\r
+#define _CRT_SECURE_NO_WARNINGS\r
+\r
+#include <stdio.h>\r
+#include <stdlib.h>\r
+#include <string.h>\r
+\r
+#include "Sdk/C/Alloc.h"\r
+#include "Sdk/C/7zFile.h"\r
+#include "Sdk/C/7zVersion.h"\r
+#include "Sdk/C/LzmaDec.h"\r
+#include "Sdk/C/LzmaEnc.h"\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
+\r
+#define UTILITY_NAME "LzmaCompress"\r
+#define UTILITY_MAJOR_VERSION 0\r
+#define UTILITY_MINOR_VERSION 1\r
+#define INTEL_COPYRIGHT \\r
+  "Copyright (c) 2009, Intel Corporation. All rights reserved."\r
+void PrintHelp(char *buffer)\r
+{\r
+  strcat(buffer,\r
+      "\n" UTILITY_NAME " - " INTEL_COPYRIGHT "\n"\r
+      "Based on LZMA Utility " MY_VERSION_COPYRIGHT_DATE "\n"\r
+      "\nUsage:  LzmaCompress -e|-d [options] <inputFile>\n"\r
+             "  -e: encode file\n"\r
+             "  -d: decode file\n"\r
+             "  -o FileName, --output FileName: specify the output filename\n"\r
+             "  -v, --verbose: increase output messages\n"\r
+             "  -q, --quiet: reduce output messages\n"\r
+             "  --debug [0-9]: set debug level\n"\r
+             "  --version: display the program version and exit\n"\r
+             "  -h, --help: display this help text\n"\r
+             );\r
+}\r
+\r
+int PrintError(char *buffer, const char *message)\r
+{\r
+  strcat(buffer, "\nError: ");\r
+  strcat(buffer, message);\r
+  strcat(buffer, "\n");\r
+  return 1;\r
+}\r
+\r
+int PrintErrorNumber(char *buffer, SRes val)\r
+{\r
+  sprintf(buffer + strlen(buffer), "\nError code: %x\n", (unsigned)val);\r
+  return 1;\r
+}\r
+\r
+int PrintUserError(char *buffer)\r
+{\r
+  return PrintError(buffer, "Incorrect command");\r
+}\r
+\r
+void PrintVersion(char *buffer)\r
+{\r
+  sprintf (buffer, "%s Version %d.%d", UTILITY_NAME, UTILITY_MAJOR_VERSION, UTILITY_MINOR_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
+{\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
+\r
+      outPos = 0;\r
+\r
+      if (res != SZ_OK || (thereIsSize && unpackSize == 0))\r
+        return res;\r
+\r
+      if (inProcessed == 0 && outProcessed == 0)\r
+      {\r
+        if (thereIsSize || status != LZMA_STATUS_FINISHED_WITH_MARK)\r
+          return SZ_ERROR_DATA;\r
+        return res;\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
+  /* Read and parse header */\r
+\r
+  RINOK(SeqInStream_Read(inStream, header, sizeof(header)));\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
+{\r
+  CLzmaEncHandle enc;\r
+  SRes res;\r
+  CLzmaEncProps props;\r
+\r
+  rs = rs;\r
+\r
+  enc = LzmaEnc_Create(&g_Alloc);\r
+  if (enc == 0)\r
+    return SZ_ERROR_MEM;\r
+\r
+  LzmaEncProps_Init(&props);\r
+  res = LzmaEnc_SetProps(enc, &props);\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
+\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
+  }\r
+  LzmaEnc_Destroy(enc, &g_Alloc, &g_Alloc);\r
+  return res;\r
+}\r
+\r
+int main2(int numArgs, const char *args[], char *rs)\r
+{\r
+  CFileSeqInStream inStream;\r
+  CFileOutStream outStream;\r
+  int res;\r
+  int encodeMode;\r
+  Bool modeWasSet = False;\r
+  const char *inputFile = NULL;\r
+  const char *outputFile = "file.tmp";\r
+  int param;\r
+\r
+  FileSeqInStream_CreateVTable(&inStream);\r
+  File_Construct(&inStream.file);\r
+\r
+  FileOutStream_CreateVTable(&outStream);\r
+  File_Construct(&outStream.file);\r
+\r
+  if (numArgs == 1)\r
+  {\r
+    PrintHelp(rs);\r
+    return 0;\r
+  }\r
+\r
+  for (param = 1; param < numArgs; param++) {\r
+    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], "-o") == 0 ||\r
+               strcmp(args[param], "--output") == 0) {\r
+      if (numArgs < (param + 2)) {\r
+        return PrintUserError(rs);\r
+      }\r
+      outputFile = args[++param];\r
+    } else if (strcmp(args[param], "--debug") == 0) {\r
+      if (numArgs < (param + 2)) {\r
+        return PrintUserError(rs);\r
+      }\r
+      //\r
+      // For now we silently ignore this parameter to achieve command line\r
+      // parameter compatibility with other build tools.\r
+      //\r
+      param++;\r
+    } else if (\r
+                strcmp(args[param], "-h") == 0 ||\r
+                strcmp(args[param], "--help") == 0\r
+              ) {\r
+      PrintHelp(rs);\r
+      return 0;\r
+    } else if (\r
+                strcmp(args[param], "-v") == 0 ||\r
+                strcmp(args[param], "--verbose") == 0\r
+              ) {\r
+      //\r
+      // For now we silently ignore this parameter to achieve command line\r
+      // parameter compatibility with other build tools.\r
+      //\r
+    } else if (\r
+                strcmp(args[param], "-q") == 0 ||\r
+                strcmp(args[param], "--quiet") == 0\r
+              ) {\r
+      mQuietMode = True;\r
+    } else if (strcmp(args[param], "--version") == 0) {\r
+      PrintVersion(rs);\r
+      return 0;\r
+    } else if (inputFile == NULL) {\r
+      inputFile = args[param];\r
+    } else {\r
+      return PrintUserError(rs);\r
+    }\r
+  }\r
+\r
+  if ((inputFile == NULL) || !modeWasSet) {\r
+    return PrintUserError(rs);\r
+  }\r
+\r
+  {\r
+    size_t t4 = sizeof(UInt32);\r
+    size_t t8 = sizeof(UInt64);\r
+    if (t4 != 4 || t8 != 8)\r
+      return PrintError(rs, "Incorrect UInt32 or UInt64");\r
+  }\r
+\r
+  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
+    return PrintError(rs, "Can not open output file");\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
+  }\r
+  else\r
+  {\r
+    if (!mQuietMode) {\r
+      printf("Decoding\n");\r
+    }\r
+    res = Decode(&outStream.s, &inStream.s);\r
+  }\r
+\r
+  File_Close(&outStream.file);\r
+  File_Close(&inStream.file);\r
+\r
+  if (res != SZ_OK)\r
+  {\r
+    if (res == SZ_ERROR_MEM)\r
+      return PrintError(rs, kCantAllocateMessage);\r
+    else if (res == SZ_ERROR_DATA)\r
+      return PrintError(rs, kDataErrorMessage);\r
+    else if (res == SZ_ERROR_WRITE)\r
+      return PrintError(rs, kCantWriteMessage);\r
+    else if (res == SZ_ERROR_READ)\r
+      return PrintError(rs, kCantReadMessage);\r
+    return PrintErrorNumber(rs, res);\r
+  }\r
+  return 0;\r
+}\r
+\r
+int MY_CDECL main(int numArgs, const char *args[])\r
+{\r
+  char rs[2000] = { 0 };\r
+  int res = main2(numArgs, args, rs);\r
+  if (strlen(rs) > 0) {\r
+    puts(rs);\r
+  }\r
+  return res;\r
+}\r