2 LZMA Compress/Decompress tool (LzmaCompress)
4 Based on LZMA SDK 18.05:
5 LzmaUtil.c -- Test application for LZMA compression
6 2018-04-30 : Igor Pavlov : Public domain
8 Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>
9 SPDX-License-Identifier: BSD-2-Clause-Patent
13 #define _CRT_SECURE_NO_WARNINGS
19 #include "Sdk/C/Alloc.h"
20 #include "Sdk/C/7zFile.h"
21 #include "Sdk/C/7zVersion.h"
22 #include "Sdk/C/LzmaDec.h"
23 #include "Sdk/C/LzmaEnc.h"
24 #include "Sdk/C/Bra.h"
25 #include "CommonLib.h"
27 #define LZMA_HEADER_SIZE (LZMA_PROPS_SIZE + 8)
35 const char *kCantReadMessage
= "Can not read input file";
36 const char *kCantWriteMessage
= "Can not write output file";
37 const char *kCantAllocateMessage
= "Can not allocate memory";
38 const char *kDataErrorMessage
= "Data error";
40 static Bool mQuietMode
= False
;
41 static CONVERTER_TYPE mConType
= NoConverter
;
43 #define UTILITY_NAME "LzmaCompress"
44 #define UTILITY_MAJOR_VERSION 0
45 #define UTILITY_MINOR_VERSION 2
46 #define INTEL_COPYRIGHT \
47 "Copyright (c) 2009-2018, Intel Corporation. All rights reserved."
48 void PrintHelp(char *buffer
)
51 "\n" UTILITY_NAME
" - " INTEL_COPYRIGHT
"\n"
52 "Based on LZMA Utility " MY_VERSION_COPYRIGHT_DATE
"\n"
53 "\nUsage: LzmaCompress -e|-d [options] <inputFile>\n"
56 " -o FileName, --output FileName: specify the output filename\n"
57 " --f86: enable converter for x86 code\n"
58 " -v, --verbose: increase output messages\n"
59 " -q, --quiet: reduce output messages\n"
60 " --debug [0-9]: set debug level\n"
61 " --version: display the program version and exit\n"
62 " -h, --help: display this help text\n"
66 int PrintError(char *buffer
, const char *message
)
68 strcat(buffer
, "\nError: ");
69 strcat(buffer
, message
);
74 int PrintErrorNumber(char *buffer
, SRes val
)
76 sprintf(buffer
+ strlen(buffer
), "\nError code: %x\n", (unsigned)val
);
80 int PrintUserError(char *buffer
)
82 return PrintError(buffer
, "Incorrect command");
85 void PrintVersion(char *buffer
)
87 sprintf (buffer
, "%s Version %d.%d %s ", UTILITY_NAME
, UTILITY_MAJOR_VERSION
, UTILITY_MINOR_VERSION
, __BUILD_VERSION
);
90 static SRes
Encode(ISeqOutStream
*outStream
, ISeqInStream
*inStream
, UInt64 fileSize
)
93 size_t inSize
= (size_t)fileSize
;
96 Byte
*filteredStream
= 0;
100 LzmaEncProps_Init(&props
);
101 LzmaEncProps_Normalize(&props
);
104 inBuffer
= (Byte
*)MyAlloc(inSize
);
108 return SZ_ERROR_INPUT_EOF
;
111 if (SeqInStream_Read(inStream
, inBuffer
, inSize
) != SZ_OK
) {
116 // we allocate 105% of original size + 64KB for output buffer
117 outSize
= (size_t)fileSize
/ 20 * 21 + (1 << 16);
118 outBuffer
= (Byte
*)MyAlloc(outSize
);
119 if (outBuffer
== 0) {
126 for (i
= 0; i
< 8; i
++)
127 outBuffer
[i
+ LZMA_PROPS_SIZE
] = (Byte
)(fileSize
>> (8 * i
));
130 if (mConType
!= NoConverter
)
132 filteredStream
= (Byte
*)MyAlloc(inSize
);
133 if (filteredStream
== 0) {
137 memcpy(filteredStream
, inBuffer
, inSize
);
139 if (mConType
== X86Converter
) {
142 x86_Convert_Init(x86State
);
143 x86_Convert(filteredStream
, (SizeT
) inSize
, 0, &x86State
, 1);
149 size_t outSizeProcessed
= outSize
- LZMA_HEADER_SIZE
;
150 size_t outPropsSize
= LZMA_PROPS_SIZE
;
152 res
= LzmaEncode(outBuffer
+ LZMA_HEADER_SIZE
, &outSizeProcessed
,
153 mConType
!= NoConverter
? filteredStream
: inBuffer
, inSize
,
154 &props
, outBuffer
, &outPropsSize
, 0,
155 NULL
, &g_Alloc
, &g_Alloc
);
160 outSize
= LZMA_HEADER_SIZE
+ outSizeProcessed
;
163 if (outStream
->Write(outStream
, outBuffer
, outSize
) != outSize
)
164 res
= SZ_ERROR_WRITE
;
169 MyFree(filteredStream
);
174 static SRes
Decode(ISeqOutStream
*outStream
, ISeqInStream
*inStream
, UInt64 fileSize
)
177 size_t inSize
= (size_t)fileSize
;
183 UInt64 outSize64
= 0;
187 if (inSize
< LZMA_HEADER_SIZE
)
188 return SZ_ERROR_INPUT_EOF
;
190 inBuffer
= (Byte
*)MyAlloc(inSize
);
194 if (SeqInStream_Read(inStream
, inBuffer
, inSize
) != SZ_OK
) {
199 for (i
= 0; i
< 8; i
++)
200 outSize64
+= ((UInt64
)inBuffer
[LZMA_PROPS_SIZE
+ i
]) << (i
* 8);
202 outSize
= (size_t)outSize64
;
204 outBuffer
= (Byte
*)MyAlloc(outSize
);
205 if (outBuffer
== 0) {
214 inSizePure
= inSize
- LZMA_HEADER_SIZE
;
215 res
= LzmaDecode(outBuffer
, &outSize
, inBuffer
+ LZMA_HEADER_SIZE
, &inSizePure
,
216 inBuffer
, LZMA_PROPS_SIZE
, LZMA_FINISH_END
, &status
, &g_Alloc
);
221 if (mConType
== X86Converter
)
224 x86_Convert_Init(x86State
);
225 x86_Convert(outBuffer
, (SizeT
) outSize
, 0, &x86State
, 0);
228 if (outStream
->Write(outStream
, outBuffer
, outSize
) != outSize
)
229 res
= SZ_ERROR_WRITE
;
238 int main2(int numArgs
, const char *args
[], char *rs
)
240 CFileSeqInStream inStream
;
241 CFileOutStream outStream
;
244 Bool modeWasSet
= False
;
245 const char *inputFile
= NULL
;
246 const char *outputFile
= "file.tmp";
250 FileSeqInStream_CreateVTable(&inStream
);
251 File_Construct(&inStream
.file
);
253 FileOutStream_CreateVTable(&outStream
);
254 File_Construct(&outStream
.file
);
262 for (param
= 1; param
< numArgs
; param
++) {
263 if (strcmp(args
[param
], "-e") == 0 || strcmp(args
[param
], "-d") == 0) {
264 encodeMode
= (args
[param
][1] == 'e');
266 } else if (strcmp(args
[param
], "--f86") == 0) {
267 mConType
= X86Converter
;
268 } else if (strcmp(args
[param
], "-o") == 0 ||
269 strcmp(args
[param
], "--output") == 0) {
270 if (numArgs
< (param
+ 2)) {
271 return PrintUserError(rs
);
273 outputFile
= args
[++param
];
274 } else if (strcmp(args
[param
], "--debug") == 0) {
275 if (numArgs
< (param
+ 2)) {
276 return PrintUserError(rs
);
279 // For now we silently ignore this parameter to achieve command line
280 // parameter compatibility with other build tools.
284 strcmp(args
[param
], "-h") == 0 ||
285 strcmp(args
[param
], "--help") == 0
290 strcmp(args
[param
], "-v") == 0 ||
291 strcmp(args
[param
], "--verbose") == 0
294 // For now we silently ignore this parameter to achieve command line
295 // parameter compatibility with other build tools.
298 strcmp(args
[param
], "-q") == 0 ||
299 strcmp(args
[param
], "--quiet") == 0
302 } else if (strcmp(args
[param
], "--version") == 0) {
305 } else if (inputFile
== NULL
) {
306 inputFile
= args
[param
];
308 return PrintUserError(rs
);
312 if ((inputFile
== NULL
) || !modeWasSet
) {
313 return PrintUserError(rs
);
317 size_t t4
= sizeof(UInt32
);
318 size_t t8
= sizeof(UInt64
);
319 if (t4
!= 4 || t8
!= 8)
320 return PrintError(rs
, "Incorrect UInt32 or UInt64");
323 if (InFile_Open(&inStream
.file
, inputFile
) != 0)
324 return PrintError(rs
, "Can not open input file");
326 if (OutFile_Open(&outStream
.file
, outputFile
) != 0) {
327 File_Close(&inStream
.file
);
328 return PrintError(rs
, "Can not open output file");
331 File_GetLength(&inStream
.file
, &fileSize
);
336 printf("Encoding\n");
338 res
= Encode(&outStream
.vt
, &inStream
.vt
, fileSize
);
343 printf("Decoding\n");
345 res
= Decode(&outStream
.vt
, &inStream
.vt
, fileSize
);
348 File_Close(&outStream
.file
);
349 File_Close(&inStream
.file
);
353 if (res
== SZ_ERROR_MEM
)
354 return PrintError(rs
, kCantAllocateMessage
);
355 else if (res
== SZ_ERROR_DATA
)
356 return PrintError(rs
, kDataErrorMessage
);
357 else if (res
== SZ_ERROR_WRITE
)
358 return PrintError(rs
, kCantWriteMessage
);
359 else if (res
== SZ_ERROR_READ
)
360 return PrintError(rs
, kCantReadMessage
);
361 return PrintErrorNumber(rs
, res
);
366 int MY_CDECL
main(int numArgs
, const char *args
[])
368 char rs
[2000] = { 0 };
369 int res
= main2(numArgs
, args
, rs
);
370 if (strlen(rs
) > 0) {