2 LZMA Compress/Decompress tool (LzmaCompress)
4 Based on LZMA SDK 4.65:
5 LzmaUtil.c -- Test application for LZMA compression
6 2008-11-23 : Igor Pavlov : Public domain
8 Copyright (c) 2006 - 2012, 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 void *SzAlloc(void *p
, size_t size
) { p
= p
; return MyAlloc(size
); }
47 static void SzFree(void *p
, void *address
) { p
= p
; MyFree(address
); }
48 static ISzAlloc g_Alloc
= { SzAlloc
, SzFree
};
50 static Bool mQuietMode
= False
;
51 static CONVERTER_TYPE mConType
= NoConverter
;
53 #define UTILITY_NAME "LzmaCompress"
54 #define UTILITY_MAJOR_VERSION 0
55 #define UTILITY_MINOR_VERSION 2
56 #define INTEL_COPYRIGHT \
57 "Copyright (c) 2009-2012, Intel Corporation. All rights reserved."
58 void PrintHelp(char *buffer
)
61 "\n" UTILITY_NAME
" - " INTEL_COPYRIGHT
"\n"
62 "Based on LZMA Utility " MY_VERSION_COPYRIGHT_DATE
"\n"
63 "\nUsage: LzmaCompress -e|-d [options] <inputFile>\n"
66 " -o FileName, --output FileName: specify the output filename\n"
67 " --f86: enable converter for x86 code\n"
68 " -v, --verbose: increase output messages\n"
69 " -q, --quiet: reduce output messages\n"
70 " --debug [0-9]: set debug level\n"
71 " --version: display the program version and exit\n"
72 " -h, --help: display this help text\n"
76 int PrintError(char *buffer
, const char *message
)
78 strcat(buffer
, "\nError: ");
79 strcat(buffer
, message
);
84 int PrintErrorNumber(char *buffer
, SRes val
)
86 sprintf(buffer
+ strlen(buffer
), "\nError code: %x\n", (unsigned)val
);
90 int PrintUserError(char *buffer
)
92 return PrintError(buffer
, "Incorrect command");
95 void PrintVersion(char *buffer
)
97 sprintf (buffer
, "%s Version %d.%d %s ", UTILITY_NAME
, UTILITY_MAJOR_VERSION
, UTILITY_MINOR_VERSION
, __BUILD_VERSION
);
100 static SRes
Encode(ISeqOutStream
*outStream
, ISeqInStream
*inStream
, UInt64 fileSize
)
103 size_t inSize
= (size_t)fileSize
;
106 Byte
*filteredStream
= 0;
110 LzmaEncProps_Init(&props
);
111 LzmaEncProps_Normalize(&props
);
114 inBuffer
= (Byte
*)MyAlloc(inSize
);
118 return SZ_ERROR_INPUT_EOF
;
121 if (SeqInStream_Read(inStream
, inBuffer
, inSize
) != SZ_OK
) {
126 // we allocate 105% of original size + 64KB for output buffer
127 outSize
= (size_t)fileSize
/ 20 * 21 + (1 << 16);
128 outBuffer
= (Byte
*)MyAlloc(outSize
);
129 if (outBuffer
== 0) {
136 for (i
= 0; i
< 8; i
++)
137 outBuffer
[i
+ LZMA_PROPS_SIZE
] = (Byte
)(fileSize
>> (8 * i
));
140 if (mConType
!= NoConverter
)
142 filteredStream
= (Byte
*)MyAlloc(inSize
);
143 if (filteredStream
== 0) {
147 memcpy(filteredStream
, inBuffer
, inSize
);
149 if (mConType
== X86Converter
) {
152 x86_Convert_Init(x86State
);
153 x86_Convert(filteredStream
, (SizeT
) inSize
, 0, &x86State
, 1);
159 size_t outSizeProcessed
= outSize
- LZMA_HEADER_SIZE
;
160 size_t outPropsSize
= LZMA_PROPS_SIZE
;
162 res
= LzmaEncode(outBuffer
+ LZMA_HEADER_SIZE
, &outSizeProcessed
,
163 mConType
!= NoConverter
? filteredStream
: inBuffer
, inSize
,
164 &props
, outBuffer
, &outPropsSize
, 0,
165 NULL
, &g_Alloc
, &g_Alloc
);
170 outSize
= LZMA_HEADER_SIZE
+ outSizeProcessed
;
173 if (outStream
->Write(outStream
, outBuffer
, outSize
) != outSize
)
174 res
= SZ_ERROR_WRITE
;
179 MyFree(filteredStream
);
184 static SRes
Decode(ISeqOutStream
*outStream
, ISeqInStream
*inStream
, UInt64 fileSize
)
187 size_t inSize
= (size_t)fileSize
;
193 UInt64 outSize64
= 0;
197 if (inSize
< LZMA_HEADER_SIZE
)
198 return SZ_ERROR_INPUT_EOF
;
200 inBuffer
= (Byte
*)MyAlloc(inSize
);
204 if (SeqInStream_Read(inStream
, inBuffer
, inSize
) != SZ_OK
) {
209 for (i
= 0; i
< 8; i
++)
210 outSize64
+= ((UInt64
)inBuffer
[LZMA_PROPS_SIZE
+ i
]) << (i
* 8);
212 outSize
= (size_t)outSize64
;
214 outBuffer
= (Byte
*)MyAlloc(outSize
);
215 if (outBuffer
== 0) {
224 inSizePure
= inSize
- LZMA_HEADER_SIZE
;
225 res
= LzmaDecode(outBuffer
, &outSize
, inBuffer
+ LZMA_HEADER_SIZE
, &inSizePure
,
226 inBuffer
, LZMA_PROPS_SIZE
, LZMA_FINISH_END
, &status
, &g_Alloc
);
231 if (mConType
== X86Converter
)
234 x86_Convert_Init(x86State
);
235 x86_Convert(outBuffer
, (SizeT
) outSize
, 0, &x86State
, 0);
238 if (outStream
->Write(outStream
, outBuffer
, outSize
) != outSize
)
239 res
= SZ_ERROR_WRITE
;
248 int main2(int numArgs
, const char *args
[], char *rs
)
250 CFileSeqInStream inStream
;
251 CFileOutStream outStream
;
254 Bool modeWasSet
= False
;
255 const char *inputFile
= NULL
;
256 const char *outputFile
= "file.tmp";
260 FileSeqInStream_CreateVTable(&inStream
);
261 File_Construct(&inStream
.file
);
263 FileOutStream_CreateVTable(&outStream
);
264 File_Construct(&outStream
.file
);
272 for (param
= 1; param
< numArgs
; param
++) {
273 if (strcmp(args
[param
], "-e") == 0 || strcmp(args
[param
], "-d") == 0) {
274 encodeMode
= (args
[param
][1] == 'e');
276 } else if (strcmp(args
[param
], "--f86") == 0) {
277 mConType
= X86Converter
;
278 } else if (strcmp(args
[param
], "-o") == 0 ||
279 strcmp(args
[param
], "--output") == 0) {
280 if (numArgs
< (param
+ 2)) {
281 return PrintUserError(rs
);
283 outputFile
= args
[++param
];
284 } else if (strcmp(args
[param
], "--debug") == 0) {
285 if (numArgs
< (param
+ 2)) {
286 return PrintUserError(rs
);
289 // For now we silently ignore this parameter to achieve command line
290 // parameter compatibility with other build tools.
294 strcmp(args
[param
], "-h") == 0 ||
295 strcmp(args
[param
], "--help") == 0
300 strcmp(args
[param
], "-v") == 0 ||
301 strcmp(args
[param
], "--verbose") == 0
304 // For now we silently ignore this parameter to achieve command line
305 // parameter compatibility with other build tools.
308 strcmp(args
[param
], "-q") == 0 ||
309 strcmp(args
[param
], "--quiet") == 0
312 } else if (strcmp(args
[param
], "--version") == 0) {
315 } else if (inputFile
== NULL
) {
316 inputFile
= args
[param
];
318 return PrintUserError(rs
);
322 if ((inputFile
== NULL
) || !modeWasSet
) {
323 return PrintUserError(rs
);
327 size_t t4
= sizeof(UInt32
);
328 size_t t8
= sizeof(UInt64
);
329 if (t4
!= 4 || t8
!= 8)
330 return PrintError(rs
, "Incorrect UInt32 or UInt64");
333 if (InFile_Open(&inStream
.file
, inputFile
) != 0)
334 return PrintError(rs
, "Can not open input file");
336 if (OutFile_Open(&outStream
.file
, outputFile
) != 0)
337 return PrintError(rs
, "Can not open output file");
339 File_GetLength(&inStream
.file
, &fileSize
);
344 printf("Encoding\n");
346 res
= Encode(&outStream
.s
, &inStream
.s
, fileSize
);
351 printf("Decoding\n");
353 res
= Decode(&outStream
.s
, &inStream
.s
, fileSize
);
356 File_Close(&outStream
.file
);
357 File_Close(&inStream
.file
);
361 if (res
== SZ_ERROR_MEM
)
362 return PrintError(rs
, kCantAllocateMessage
);
363 else if (res
== SZ_ERROR_DATA
)
364 return PrintError(rs
, kDataErrorMessage
);
365 else if (res
== SZ_ERROR_WRITE
)
366 return PrintError(rs
, kCantWriteMessage
);
367 else if (res
== SZ_ERROR_READ
)
368 return PrintError(rs
, kCantReadMessage
);
369 return PrintErrorNumber(rs
, res
);
374 int MY_CDECL
main(int numArgs
, const char *args
[])
376 char rs
[2000] = { 0 };
377 int res
= main2(numArgs
, args
, rs
);
378 if (strlen(rs
) > 0) {