--- /dev/null
+/** @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