2 LZMA Compress/Decompress tool (LzmaCompress)
4 Based on LZMA SDK 16.04:
5 LzmaUtil.c -- Test application for LZMA compression
6 2016-10-04 : Igor Pavlov : Public domain
8 Copyright (c) 2006 - 2016, Intel Corporation. All rights reserved.<BR>
9 This program and the accompanying materials
10 are licensed and made available under the terms and conditions of the BSD License
11 which accompanies this distribution. The full text of the license may be found at
12 http://opensource.org/licenses/bsd-license.php
14 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
15 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
19 #define _CRT_SECURE_NO_WARNINGS
25 #include "Sdk/C/Alloc.h"
26 #include "Sdk/C/7zFile.h"
27 #include "Sdk/C/7zVersion.h"
28 #include "Sdk/C/LzmaDec.h"
29 #include "Sdk/C/LzmaEnc.h"
30 #include "Sdk/C/Bra.h"
31 #include "CommonLib.h"
33 #define LZMA_HEADER_SIZE (LZMA_PROPS_SIZE + 8)
41 const char *kCantReadMessage
= "Can not read input file";
42 const char *kCantWriteMessage
= "Can not write output file";
43 const char *kCantAllocateMessage
= "Can not allocate memory";
44 const char *kDataErrorMessage
= "Data error";
46 static Bool mQuietMode
= False
;
47 static CONVERTER_TYPE mConType
= NoConverter
;
49 #define UTILITY_NAME "LzmaCompress"
50 #define UTILITY_MAJOR_VERSION 0
51 #define UTILITY_MINOR_VERSION 2
52 #define INTEL_COPYRIGHT \
53 "Copyright (c) 2009-2016, Intel Corporation. All rights reserved."
54 void PrintHelp(char *buffer
)
57 "\n" UTILITY_NAME
" - " INTEL_COPYRIGHT
"\n"
58 "Based on LZMA Utility " MY_VERSION_COPYRIGHT_DATE
"\n"
59 "\nUsage: LzmaCompress -e|-d [options] <inputFile>\n"
62 " -o FileName, --output FileName: specify the output filename\n"
63 " --f86: enable converter for x86 code\n"
64 " -v, --verbose: increase output messages\n"
65 " -q, --quiet: reduce output messages\n"
66 " --debug [0-9]: set debug level\n"
67 " --version: display the program version and exit\n"
68 " -h, --help: display this help text\n"
72 int PrintError(char *buffer
, const char *message
)
74 strcat(buffer
, "\nError: ");
75 strcat(buffer
, message
);
80 int PrintErrorNumber(char *buffer
, SRes val
)
82 sprintf(buffer
+ strlen(buffer
), "\nError code: %x\n", (unsigned)val
);
86 int PrintUserError(char *buffer
)
88 return PrintError(buffer
, "Incorrect command");
91 void PrintVersion(char *buffer
)
93 sprintf (buffer
, "%s Version %d.%d %s ", UTILITY_NAME
, UTILITY_MAJOR_VERSION
, UTILITY_MINOR_VERSION
, __BUILD_VERSION
);
96 static SRes
Encode(ISeqOutStream
*outStream
, ISeqInStream
*inStream
, UInt64 fileSize
)
99 size_t inSize
= (size_t)fileSize
;
102 Byte
*filteredStream
= 0;
106 LzmaEncProps_Init(&props
);
107 LzmaEncProps_Normalize(&props
);
110 inBuffer
= (Byte
*)MyAlloc(inSize
);
114 return SZ_ERROR_INPUT_EOF
;
117 if (SeqInStream_Read(inStream
, inBuffer
, inSize
) != SZ_OK
) {
122 // we allocate 105% of original size + 64KB for output buffer
123 outSize
= (size_t)fileSize
/ 20 * 21 + (1 << 16);
124 outBuffer
= (Byte
*)MyAlloc(outSize
);
125 if (outBuffer
== 0) {
132 for (i
= 0; i
< 8; i
++)
133 outBuffer
[i
+ LZMA_PROPS_SIZE
] = (Byte
)(fileSize
>> (8 * i
));
136 if (mConType
!= NoConverter
)
138 filteredStream
= (Byte
*)MyAlloc(inSize
);
139 if (filteredStream
== 0) {
143 memcpy(filteredStream
, inBuffer
, inSize
);
145 if (mConType
== X86Converter
) {
148 x86_Convert_Init(x86State
);
149 x86_Convert(filteredStream
, (SizeT
) inSize
, 0, &x86State
, 1);
155 size_t outSizeProcessed
= outSize
- LZMA_HEADER_SIZE
;
156 size_t outPropsSize
= LZMA_PROPS_SIZE
;
158 res
= LzmaEncode(outBuffer
+ LZMA_HEADER_SIZE
, &outSizeProcessed
,
159 mConType
!= NoConverter
? filteredStream
: inBuffer
, inSize
,
160 &props
, outBuffer
, &outPropsSize
, 0,
161 NULL
, &g_Alloc
, &g_Alloc
);
166 outSize
= LZMA_HEADER_SIZE
+ outSizeProcessed
;
169 if (outStream
->Write(outStream
, outBuffer
, outSize
) != outSize
)
170 res
= SZ_ERROR_WRITE
;
175 MyFree(filteredStream
);
180 static SRes
Decode(ISeqOutStream
*outStream
, ISeqInStream
*inStream
, UInt64 fileSize
)
183 size_t inSize
= (size_t)fileSize
;
189 UInt64 outSize64
= 0;
193 if (inSize
< LZMA_HEADER_SIZE
)
194 return SZ_ERROR_INPUT_EOF
;
196 inBuffer
= (Byte
*)MyAlloc(inSize
);
200 if (SeqInStream_Read(inStream
, inBuffer
, inSize
) != SZ_OK
) {
205 for (i
= 0; i
< 8; i
++)
206 outSize64
+= ((UInt64
)inBuffer
[LZMA_PROPS_SIZE
+ i
]) << (i
* 8);
208 outSize
= (size_t)outSize64
;
210 outBuffer
= (Byte
*)MyAlloc(outSize
);
211 if (outBuffer
== 0) {
220 inSizePure
= inSize
- LZMA_HEADER_SIZE
;
221 res
= LzmaDecode(outBuffer
, &outSize
, inBuffer
+ LZMA_HEADER_SIZE
, &inSizePure
,
222 inBuffer
, LZMA_PROPS_SIZE
, LZMA_FINISH_END
, &status
, &g_Alloc
);
227 if (mConType
== X86Converter
)
230 x86_Convert_Init(x86State
);
231 x86_Convert(outBuffer
, (SizeT
) outSize
, 0, &x86State
, 0);
234 if (outStream
->Write(outStream
, outBuffer
, outSize
) != outSize
)
235 res
= SZ_ERROR_WRITE
;
244 int main2(int numArgs
, const char *args
[], char *rs
)
246 CFileSeqInStream inStream
;
247 CFileOutStream outStream
;
250 Bool modeWasSet
= False
;
251 const char *inputFile
= NULL
;
252 const char *outputFile
= "file.tmp";
256 FileSeqInStream_CreateVTable(&inStream
);
257 File_Construct(&inStream
.file
);
259 FileOutStream_CreateVTable(&outStream
);
260 File_Construct(&outStream
.file
);
268 for (param
= 1; param
< numArgs
; param
++) {
269 if (strcmp(args
[param
], "-e") == 0 || strcmp(args
[param
], "-d") == 0) {
270 encodeMode
= (args
[param
][1] == 'e');
272 } else if (strcmp(args
[param
], "--f86") == 0) {
273 mConType
= X86Converter
;
274 } else if (strcmp(args
[param
], "-o") == 0 ||
275 strcmp(args
[param
], "--output") == 0) {
276 if (numArgs
< (param
+ 2)) {
277 return PrintUserError(rs
);
279 outputFile
= args
[++param
];
280 } else if (strcmp(args
[param
], "--debug") == 0) {
281 if (numArgs
< (param
+ 2)) {
282 return PrintUserError(rs
);
285 // For now we silently ignore this parameter to achieve command line
286 // parameter compatibility with other build tools.
290 strcmp(args
[param
], "-h") == 0 ||
291 strcmp(args
[param
], "--help") == 0
296 strcmp(args
[param
], "-v") == 0 ||
297 strcmp(args
[param
], "--verbose") == 0
300 // For now we silently ignore this parameter to achieve command line
301 // parameter compatibility with other build tools.
304 strcmp(args
[param
], "-q") == 0 ||
305 strcmp(args
[param
], "--quiet") == 0
308 } else if (strcmp(args
[param
], "--version") == 0) {
311 } else if (inputFile
== NULL
) {
312 inputFile
= args
[param
];
314 return PrintUserError(rs
);
318 if ((inputFile
== NULL
) || !modeWasSet
) {
319 return PrintUserError(rs
);
323 size_t t4
= sizeof(UInt32
);
324 size_t t8
= sizeof(UInt64
);
325 if (t4
!= 4 || t8
!= 8)
326 return PrintError(rs
, "Incorrect UInt32 or UInt64");
329 if (InFile_Open(&inStream
.file
, inputFile
) != 0)
330 return PrintError(rs
, "Can not open input file");
332 if (OutFile_Open(&outStream
.file
, outputFile
) != 0) {
333 File_Close(&inStream
.file
);
334 return PrintError(rs
, "Can not open output file");
337 File_GetLength(&inStream
.file
, &fileSize
);
342 printf("Encoding\n");
344 res
= Encode(&outStream
.s
, &inStream
.s
, fileSize
);
349 printf("Decoding\n");
351 res
= Decode(&outStream
.s
, &inStream
.s
, fileSize
);
354 File_Close(&outStream
.file
);
355 File_Close(&inStream
.file
);
359 if (res
== SZ_ERROR_MEM
)
360 return PrintError(rs
, kCantAllocateMessage
);
361 else if (res
== SZ_ERROR_DATA
)
362 return PrintError(rs
, kDataErrorMessage
);
363 else if (res
== SZ_ERROR_WRITE
)
364 return PrintError(rs
, kCantWriteMessage
);
365 else if (res
== SZ_ERROR_READ
)
366 return PrintError(rs
, kCantReadMessage
);
367 return PrintErrorNumber(rs
, res
);
372 int MY_CDECL
main(int numArgs
, const char *args
[])
374 char rs
[2000] = { 0 };
375 int res
= main2(numArgs
, args
, rs
);
376 if (strlen(rs
) > 0) {