PageRenderTime 62ms CodeModel.GetById 35ms RepoModel.GetById 1ms app.codeStats 0ms

/edk2/BaseTools/Source/C/LzmaCompress/LzmaCompress.c

https://gitlab.com/envieidoc/Clover
C | 382 lines | 301 code | 55 blank | 26 comment | 105 complexity | 2a5cb9881aafc6cb43a4635c17a8121e MD5 | raw file
  1. /** @file
  2. LZMA Compress/Decompress tool (LzmaCompress)
  3. Based on LZMA SDK 4.65:
  4. LzmaUtil.c -- Test application for LZMA compression
  5. 2008-11-23 : Igor Pavlov : Public domain
  6. Copyright (c) 2006 - 2012, Intel Corporation. All rights reserved.<BR>
  7. This program and the accompanying materials
  8. are licensed and made available under the terms and conditions of the BSD License
  9. which accompanies this distribution. The full text of the license may be found at
  10. http://opensource.org/licenses/bsd-license.php
  11. THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
  12. WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
  13. **/
  14. #define _CRT_SECURE_NO_WARNINGS
  15. #include <stdio.h>
  16. #include <stdlib.h>
  17. #include <string.h>
  18. #include "Sdk/C/Alloc.h"
  19. #include "Sdk/C/7zFile.h"
  20. #include "Sdk/C/7zVersion.h"
  21. #include "Sdk/C/LzmaDec.h"
  22. #include "Sdk/C/LzmaEnc.h"
  23. #include "Sdk/C/Bra.h"
  24. #include "CommonLib.h"
  25. #define LZMA_HEADER_SIZE (LZMA_PROPS_SIZE + 8)
  26. typedef enum {
  27. NoConverter,
  28. X86Converter,
  29. MaxConverter
  30. } CONVERTER_TYPE;
  31. const char *kCantReadMessage = "Can not read input file";
  32. const char *kCantWriteMessage = "Can not write output file";
  33. const char *kCantAllocateMessage = "Can not allocate memory";
  34. const char *kDataErrorMessage = "Data error";
  35. static void *SzAlloc(void *p, size_t size) { (void)p; return MyAlloc(size); }
  36. static void SzFree(void *p, void *address) { (void)p; MyFree(address); }
  37. static ISzAlloc g_Alloc = { SzAlloc, SzFree };
  38. static Bool mQuietMode = False;
  39. static CONVERTER_TYPE mConType = NoConverter;
  40. #define UTILITY_NAME "LzmaCompress"
  41. #define UTILITY_MAJOR_VERSION 0
  42. #define UTILITY_MINOR_VERSION 2
  43. #define INTEL_COPYRIGHT \
  44. "Copyright (c) 2009-2012, Intel Corporation. All rights reserved."
  45. void PrintHelp(char *buffer)
  46. {
  47. strcat(buffer,
  48. "\n" UTILITY_NAME " - " INTEL_COPYRIGHT "\n"
  49. "Based on LZMA Utility " MY_VERSION_COPYRIGHT_DATE "\n"
  50. "\nUsage: LzmaCompress -e|-d [options] <inputFile>\n"
  51. " -e: encode file\n"
  52. " -d: decode file\n"
  53. " -o FileName, --output FileName: specify the output filename\n"
  54. " --f86: enable converter for x86 code\n"
  55. " -v, --verbose: increase output messages\n"
  56. " -q, --quiet: reduce output messages\n"
  57. " --debug [0-9]: set debug level\n"
  58. " --version: display the program version and exit\n"
  59. " -h, --help: display this help text\n"
  60. );
  61. }
  62. int PrintError(char *buffer, const char *message)
  63. {
  64. strcat(buffer, "\nError: ");
  65. strcat(buffer, message);
  66. strcat(buffer, "\n");
  67. return 1;
  68. }
  69. int PrintErrorNumber(char *buffer, SRes val)
  70. {
  71. sprintf(buffer + strlen(buffer), "\nError code: %x\n", (unsigned)val);
  72. return 1;
  73. }
  74. int PrintUserError(char *buffer)
  75. {
  76. return PrintError(buffer, "Incorrect command");
  77. }
  78. void PrintVersion(char *buffer)
  79. {
  80. sprintf (buffer, "%s Version %d.%d %s ", UTILITY_NAME, UTILITY_MAJOR_VERSION, UTILITY_MINOR_VERSION, __BUILD_VERSION);
  81. }
  82. static SRes Encode(ISeqOutStream *outStream, ISeqInStream *inStream, UInt64 fileSize)
  83. {
  84. SRes res;
  85. size_t inSize = (size_t)fileSize;
  86. Byte *inBuffer = 0;
  87. Byte *outBuffer = 0;
  88. Byte *filteredStream = 0;
  89. size_t outSize;
  90. CLzmaEncProps props;
  91. LzmaEncProps_Init(&props);
  92. LzmaEncProps_Normalize(&props);
  93. if (inSize != 0) {
  94. inBuffer = (Byte *)MyAlloc(inSize);
  95. if (inBuffer == 0)
  96. return SZ_ERROR_MEM;
  97. } else {
  98. return SZ_ERROR_INPUT_EOF;
  99. }
  100. if (SeqInStream_Read(inStream, inBuffer, inSize) != SZ_OK) {
  101. res = SZ_ERROR_READ;
  102. goto Done;
  103. }
  104. // we allocate 105% of original size + 64KB for output buffer
  105. outSize = (size_t)fileSize / 20 * 21 + (1 << 16);
  106. outBuffer = (Byte *)MyAlloc(outSize);
  107. if (outBuffer == 0) {
  108. res = SZ_ERROR_MEM;
  109. goto Done;
  110. }
  111. {
  112. int i;
  113. for (i = 0; i < 8; i++)
  114. outBuffer[i + LZMA_PROPS_SIZE] = (Byte)(fileSize >> (8 * i));
  115. }
  116. if (mConType != NoConverter)
  117. {
  118. filteredStream = (Byte *)MyAlloc(inSize);
  119. if (filteredStream == 0) {
  120. res = SZ_ERROR_MEM;
  121. goto Done;
  122. }
  123. memcpy(filteredStream, inBuffer, inSize);
  124. if (mConType == X86Converter) {
  125. {
  126. UInt32 x86State;
  127. x86_Convert_Init(x86State);
  128. x86_Convert(filteredStream, (SizeT) inSize, 0, &x86State, 1);
  129. }
  130. }
  131. }
  132. {
  133. size_t outSizeProcessed = outSize - LZMA_HEADER_SIZE;
  134. size_t outPropsSize = LZMA_PROPS_SIZE;
  135. res = LzmaEncode(outBuffer + LZMA_HEADER_SIZE, &outSizeProcessed,
  136. mConType != NoConverter ? filteredStream : inBuffer, inSize,
  137. &props, outBuffer, &outPropsSize, 0,
  138. NULL, &g_Alloc, &g_Alloc);
  139. if (res != SZ_OK)
  140. goto Done;
  141. outSize = LZMA_HEADER_SIZE + outSizeProcessed;
  142. }
  143. if (outStream->Write(outStream, outBuffer, outSize) != outSize)
  144. res = SZ_ERROR_WRITE;
  145. Done:
  146. MyFree(outBuffer);
  147. MyFree(inBuffer);
  148. MyFree(filteredStream);
  149. return res;
  150. }
  151. static SRes Decode(ISeqOutStream *outStream, ISeqInStream *inStream, UInt64 fileSize)
  152. {
  153. SRes res;
  154. size_t inSize = (size_t)fileSize;
  155. Byte *inBuffer = 0;
  156. Byte *outBuffer = 0;
  157. size_t outSize = 0;
  158. size_t inSizePure;
  159. ELzmaStatus status;
  160. UInt64 outSize64 = 0;
  161. int i;
  162. if (inSize < LZMA_HEADER_SIZE)
  163. return SZ_ERROR_INPUT_EOF;
  164. inBuffer = (Byte *)MyAlloc(inSize);
  165. if (inBuffer == 0)
  166. return SZ_ERROR_MEM;
  167. if (SeqInStream_Read(inStream, inBuffer, inSize) != SZ_OK) {
  168. res = SZ_ERROR_READ;
  169. goto Done;
  170. }
  171. for (i = 0; i < 8; i++)
  172. outSize64 += ((UInt64)inBuffer[LZMA_PROPS_SIZE + i]) << (i * 8);
  173. outSize = (size_t)outSize64;
  174. if (outSize != 0) {
  175. outBuffer = (Byte *)MyAlloc(outSize);
  176. if (outBuffer == 0) {
  177. res = SZ_ERROR_MEM;
  178. goto Done;
  179. }
  180. } else {
  181. res = SZ_OK;
  182. goto Done;
  183. }
  184. inSizePure = inSize - LZMA_HEADER_SIZE;
  185. res = LzmaDecode(outBuffer, &outSize, inBuffer + LZMA_HEADER_SIZE, &inSizePure,
  186. inBuffer, LZMA_PROPS_SIZE, LZMA_FINISH_END, &status, &g_Alloc);
  187. if (res != SZ_OK)
  188. goto Done;
  189. if (mConType == X86Converter)
  190. {
  191. UInt32 x86State;
  192. x86_Convert_Init(x86State);
  193. x86_Convert(outBuffer, (SizeT) outSize, 0, &x86State, 0);
  194. }
  195. if (outStream->Write(outStream, outBuffer, outSize) != outSize)
  196. res = SZ_ERROR_WRITE;
  197. Done:
  198. MyFree(outBuffer);
  199. MyFree(inBuffer);
  200. return res;
  201. }
  202. int main2(int numArgs, const char *args[], char *rs)
  203. {
  204. CFileSeqInStream inStream;
  205. CFileOutStream outStream;
  206. int res;
  207. int encodeMode = 0;
  208. Bool modeWasSet = False;
  209. const char *inputFile = NULL;
  210. const char *outputFile = "file.tmp";
  211. int param;
  212. UInt64 fileSize;
  213. FileSeqInStream_CreateVTable(&inStream);
  214. File_Construct(&inStream.file);
  215. FileOutStream_CreateVTable(&outStream);
  216. File_Construct(&outStream.file);
  217. if (numArgs == 1)
  218. {
  219. PrintHelp(rs);
  220. return 0;
  221. }
  222. for (param = 1; param < numArgs; param++) {
  223. if (strcmp(args[param], "-e") == 0 || strcmp(args[param], "-d") == 0) {
  224. encodeMode = (args[param][1] == 'e');
  225. modeWasSet = True;
  226. } else if (strcmp(args[param], "--f86") == 0) {
  227. mConType = X86Converter;
  228. } else if (strcmp(args[param], "-o") == 0 ||
  229. strcmp(args[param], "--output") == 0) {
  230. if (numArgs < (param + 2)) {
  231. return PrintUserError(rs);
  232. }
  233. outputFile = args[++param];
  234. } else if (strcmp(args[param], "--debug") == 0) {
  235. if (numArgs < (param + 2)) {
  236. return PrintUserError(rs);
  237. }
  238. //
  239. // For now we silently ignore this parameter to achieve command line
  240. // parameter compatibility with other build tools.
  241. //
  242. param++;
  243. } else if (
  244. strcmp(args[param], "-h") == 0 ||
  245. strcmp(args[param], "--help") == 0
  246. ) {
  247. PrintHelp(rs);
  248. return 0;
  249. } else if (
  250. strcmp(args[param], "-v") == 0 ||
  251. strcmp(args[param], "--verbose") == 0
  252. ) {
  253. //
  254. // For now we silently ignore this parameter to achieve command line
  255. // parameter compatibility with other build tools.
  256. //
  257. } else if (
  258. strcmp(args[param], "-q") == 0 ||
  259. strcmp(args[param], "--quiet") == 0
  260. ) {
  261. mQuietMode = True;
  262. } else if (strcmp(args[param], "--version") == 0) {
  263. PrintVersion(rs);
  264. return 0;
  265. } else if (inputFile == NULL) {
  266. inputFile = args[param];
  267. } else {
  268. return PrintUserError(rs);
  269. }
  270. }
  271. if ((inputFile == NULL) || !modeWasSet) {
  272. return PrintUserError(rs);
  273. }
  274. {
  275. size_t t4 = sizeof(UInt32);
  276. size_t t8 = sizeof(UInt64);
  277. if (t4 != 4 || t8 != 8)
  278. return PrintError(rs, "Incorrect UInt32 or UInt64");
  279. }
  280. if (InFile_Open(&inStream.file, inputFile) != 0)
  281. return PrintError(rs, "Can not open input file");
  282. if (OutFile_Open(&outStream.file, outputFile) != 0)
  283. return PrintError(rs, "Can not open output file");
  284. File_GetLength(&inStream.file, &fileSize);
  285. if (encodeMode)
  286. {
  287. if (!mQuietMode) {
  288. printf("Encoding\n");
  289. }
  290. res = Encode(&outStream.s, &inStream.s, fileSize);
  291. }
  292. else
  293. {
  294. if (!mQuietMode) {
  295. printf("Decoding\n");
  296. }
  297. res = Decode(&outStream.s, &inStream.s, fileSize);
  298. }
  299. File_Close(&outStream.file);
  300. File_Close(&inStream.file);
  301. if (res != SZ_OK)
  302. {
  303. if (res == SZ_ERROR_MEM)
  304. return PrintError(rs, kCantAllocateMessage);
  305. else if (res == SZ_ERROR_DATA)
  306. return PrintError(rs, kDataErrorMessage);
  307. else if (res == SZ_ERROR_WRITE)
  308. return PrintError(rs, kCantWriteMessage);
  309. else if (res == SZ_ERROR_READ)
  310. return PrintError(rs, kCantReadMessage);
  311. return PrintErrorNumber(rs, res);
  312. }
  313. return 0;
  314. }
  315. int MY_CDECL main(int numArgs, const char *args[])
  316. {
  317. char rs[2000] = { 0 };
  318. int res = main2(numArgs, args, rs);
  319. if (strlen(rs) > 0) {
  320. puts(rs);
  321. }
  322. return res;
  323. }