/** @file\r
LZMA Compress/Decompress tool (LzmaCompress)\r
\r
- Based on LZMA SDK 4.65:\r
+ Based on LZMA SDK 18.05:\r
LzmaUtil.c -- Test application for LZMA compression\r
- 2008-11-23 : Igor Pavlov : Public domain\r
+ 2018-04-30 : Igor Pavlov : Public domain\r
\r
- Copyright (c) 2006 - 2009, 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
+ Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>\r
+ SPDX-License-Identifier: BSD-2-Clause-Patent\r
\r
**/\r
\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-2018, Intel Corporation. All rights reserved."\r
void PrintHelp(char *buffer)\r
{\r
strcat(buffer,\r
" -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
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
+ 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
- res = LzmaDec_DecodeToBuf(state, outBuf + outPos, &outProcessed,\r
- inBuf + inPos, &inProcessed, finishMode, &status);\r
- inPos += inProcessed;\r
- outPos += outProcessed;\r
- unpackSize -= outProcessed;\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 (outStream)\r
- if (outStream->Write(outStream, outBuf, outPos) != outPos)\r
- return SZ_ERROR_WRITE;\r
+ if (SeqInStream_Read(inStream, inBuffer, inSize) != SZ_OK) {\r
+ res = SZ_ERROR_READ;\r
+ goto Done;\r
+ }\r
+\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
- outPos = 0;\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 (res != SZ_OK || (thereIsSize && unpackSize == 0))\r
- return res;\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 (inProcessed == 0 && outProcessed == 0)\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
+ size_t outSizeProcessed = outSize - LZMA_HEADER_SIZE;\r
+ size_t outPropsSize = LZMA_PROPS_SIZE;\r
\r
- CLzmaDec state;\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
- /* header: 5 bytes of LZMA properties and 8 bytes of uncompressed size */\r
- unsigned char header[LZMA_PROPS_SIZE + 8];\r
+ if (res != SZ_OK)\r
+ goto Done;\r
\r
- /* Read and parse header */\r
+ outSize = LZMA_HEADER_SIZE + outSizeProcessed;\r
+ }\r
\r
- RINOK(SeqInStream_Read(inStream, header, sizeof(header)));\r
+ if (outStream->Write(outStream, outBuffer, outSize) != outSize)\r
+ res = SZ_ERROR_WRITE;\r
\r
- unpackSize = 0;\r
- for (i = 0; i < 8; i++)\r
- unpackSize += (UInt64)header[LZMA_PROPS_SIZE + i] << (i * 8);\r
+Done:\r
+ MyFree(outBuffer);\r
+ MyFree(inBuffer);\r
+ MyFree(filteredStream);\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
- return SZ_ERROR_MEM;\r
+ if (inSize < LZMA_HEADER_SIZE)\r
+ return SZ_ERROR_INPUT_EOF;\r
\r
- LzmaEncProps_Init(&props);\r
- res = LzmaEnc_SetProps(enc, &props);\r
+ inBuffer = (Byte *)MyAlloc(inSize);\r
+ if (inBuffer == 0)\r
+ return SZ_ERROR_MEM;\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
+ if (SeqInStream_Read(inStream, inBuffer, inSize) != SZ_OK) {\r
+ res = SZ_ERROR_READ;\r
+ goto Done;\r
+ }\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
+ 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
+ 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
+ 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
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
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
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.vt, &inStream.vt, fileSize);\r
}\r
else\r
{\r
if (!mQuietMode) {\r
printf("Decoding\n");\r
}\r
- res = Decode(&outStream.s, &inStream.s);\r
+ res = Decode(&outStream.vt, &inStream.vt, fileSize);\r
}\r
\r
File_Close(&outStream.file);\r