implify multitap core options
[pcsx_rearmed.git] / deps / lzma-16.04 / C / Util / Lzma / LzmaUtil.c
CommitLineData
ce188d4d 1/* LzmaUtil.c -- Test application for LZMA compression\r
22015-11-08 : Igor Pavlov : Public domain */\r
3\r
4#include "../../Precomp.h"\r
5\r
6#include <stdio.h>\r
7#include <stdlib.h>\r
8#include <string.h>\r
9\r
10#include "../../Alloc.h"\r
11#include "../../7zFile.h"\r
12#include "../../7zVersion.h"\r
13#include "../../LzmaDec.h"\r
14#include "../../LzmaEnc.h"\r
15\r
16const char *kCantReadMessage = "Can not read input file";\r
17const char *kCantWriteMessage = "Can not write output file";\r
18const char *kCantAllocateMessage = "Can not allocate memory";\r
19const char *kDataErrorMessage = "Data error";\r
20\r
21void PrintHelp(char *buffer)\r
22{\r
23 strcat(buffer, "\nLZMA Utility " MY_VERSION_COPYRIGHT_DATE "\n"\r
24 "\nUsage: lzma <e|d> inputFile outputFile\n"\r
25 " e: encode file\n"\r
26 " d: decode file\n");\r
27}\r
28\r
29int PrintError(char *buffer, const char *message)\r
30{\r
31 strcat(buffer, "\nError: ");\r
32 strcat(buffer, message);\r
33 strcat(buffer, "\n");\r
34 return 1;\r
35}\r
36\r
37int PrintErrorNumber(char *buffer, SRes val)\r
38{\r
39 sprintf(buffer + strlen(buffer), "\nError code: %x\n", (unsigned)val);\r
40 return 1;\r
41}\r
42\r
43int PrintUserError(char *buffer)\r
44{\r
45 return PrintError(buffer, "Incorrect command");\r
46}\r
47\r
48#define IN_BUF_SIZE (1 << 16)\r
49#define OUT_BUF_SIZE (1 << 16)\r
50\r
51static SRes Decode2(CLzmaDec *state, ISeqOutStream *outStream, ISeqInStream *inStream,\r
52 UInt64 unpackSize)\r
53{\r
54 int thereIsSize = (unpackSize != (UInt64)(Int64)-1);\r
55 Byte inBuf[IN_BUF_SIZE];\r
56 Byte outBuf[OUT_BUF_SIZE];\r
57 size_t inPos = 0, inSize = 0, outPos = 0;\r
58 LzmaDec_Init(state);\r
59 for (;;)\r
60 {\r
61 if (inPos == inSize)\r
62 {\r
63 inSize = IN_BUF_SIZE;\r
64 RINOK(inStream->Read(inStream, inBuf, &inSize));\r
65 inPos = 0;\r
66 }\r
67 {\r
68 SRes res;\r
69 SizeT inProcessed = inSize - inPos;\r
70 SizeT outProcessed = OUT_BUF_SIZE - outPos;\r
71 ELzmaFinishMode finishMode = LZMA_FINISH_ANY;\r
72 ELzmaStatus status;\r
73 if (thereIsSize && outProcessed > unpackSize)\r
74 {\r
75 outProcessed = (SizeT)unpackSize;\r
76 finishMode = LZMA_FINISH_END;\r
77 }\r
78 \r
79 res = LzmaDec_DecodeToBuf(state, outBuf + outPos, &outProcessed,\r
80 inBuf + inPos, &inProcessed, finishMode, &status);\r
81 inPos += inProcessed;\r
82 outPos += outProcessed;\r
83 unpackSize -= outProcessed;\r
84 \r
85 if (outStream)\r
86 if (outStream->Write(outStream, outBuf, outPos) != outPos)\r
87 return SZ_ERROR_WRITE;\r
88 \r
89 outPos = 0;\r
90 \r
91 if (res != SZ_OK || (thereIsSize && unpackSize == 0))\r
92 return res;\r
93 \r
94 if (inProcessed == 0 && outProcessed == 0)\r
95 {\r
96 if (thereIsSize || status != LZMA_STATUS_FINISHED_WITH_MARK)\r
97 return SZ_ERROR_DATA;\r
98 return res;\r
99 }\r
100 }\r
101 }\r
102}\r
103\r
104static SRes Decode(ISeqOutStream *outStream, ISeqInStream *inStream)\r
105{\r
106 UInt64 unpackSize;\r
107 int i;\r
108 SRes res = 0;\r
109\r
110 CLzmaDec state;\r
111\r
112 /* header: 5 bytes of LZMA properties and 8 bytes of uncompressed size */\r
113 unsigned char header[LZMA_PROPS_SIZE + 8];\r
114\r
115 /* Read and parse header */\r
116\r
117 RINOK(SeqInStream_Read(inStream, header, sizeof(header)));\r
118\r
119 unpackSize = 0;\r
120 for (i = 0; i < 8; i++)\r
121 unpackSize += (UInt64)header[LZMA_PROPS_SIZE + i] << (i * 8);\r
122\r
123 LzmaDec_Construct(&state);\r
124 RINOK(LzmaDec_Allocate(&state, header, LZMA_PROPS_SIZE, &g_Alloc));\r
125 res = Decode2(&state, outStream, inStream, unpackSize);\r
126 LzmaDec_Free(&state, &g_Alloc);\r
127 return res;\r
128}\r
129\r
130static SRes Encode(ISeqOutStream *outStream, ISeqInStream *inStream, UInt64 fileSize, char *rs)\r
131{\r
132 CLzmaEncHandle enc;\r
133 SRes res;\r
134 CLzmaEncProps props;\r
135\r
136 UNUSED_VAR(rs);\r
137\r
138 enc = LzmaEnc_Create(&g_Alloc);\r
139 if (enc == 0)\r
140 return SZ_ERROR_MEM;\r
141\r
142 LzmaEncProps_Init(&props);\r
143 res = LzmaEnc_SetProps(enc, &props);\r
144\r
145 if (res == SZ_OK)\r
146 {\r
147 Byte header[LZMA_PROPS_SIZE + 8];\r
148 size_t headerSize = LZMA_PROPS_SIZE;\r
149 int i;\r
150\r
151 res = LzmaEnc_WriteProperties(enc, header, &headerSize);\r
152 for (i = 0; i < 8; i++)\r
153 header[headerSize++] = (Byte)(fileSize >> (8 * i));\r
154 if (outStream->Write(outStream, header, headerSize) != headerSize)\r
155 res = SZ_ERROR_WRITE;\r
156 else\r
157 {\r
158 if (res == SZ_OK)\r
159 res = LzmaEnc_Encode(enc, outStream, inStream, NULL, &g_Alloc, &g_Alloc);\r
160 }\r
161 }\r
162 LzmaEnc_Destroy(enc, &g_Alloc, &g_Alloc);\r
163 return res;\r
164}\r
165\r
166int main2(int numArgs, const char *args[], char *rs)\r
167{\r
168 CFileSeqInStream inStream;\r
169 CFileOutStream outStream;\r
170 char c;\r
171 int res;\r
172 int encodeMode;\r
173 Bool useOutFile = False;\r
174\r
175 FileSeqInStream_CreateVTable(&inStream);\r
176 File_Construct(&inStream.file);\r
177\r
178 FileOutStream_CreateVTable(&outStream);\r
179 File_Construct(&outStream.file);\r
180\r
181 if (numArgs == 1)\r
182 {\r
183 PrintHelp(rs);\r
184 return 0;\r
185 }\r
186\r
187 if (numArgs < 3 || numArgs > 4 || strlen(args[1]) != 1)\r
188 return PrintUserError(rs);\r
189\r
190 c = args[1][0];\r
191 encodeMode = (c == 'e' || c == 'E');\r
192 if (!encodeMode && c != 'd' && c != 'D')\r
193 return PrintUserError(rs);\r
194\r
195 {\r
196 size_t t4 = sizeof(UInt32);\r
197 size_t t8 = sizeof(UInt64);\r
198 if (t4 != 4 || t8 != 8)\r
199 return PrintError(rs, "Incorrect UInt32 or UInt64");\r
200 }\r
201\r
202 if (InFile_Open(&inStream.file, args[2]) != 0)\r
203 return PrintError(rs, "Can not open input file");\r
204\r
205 if (numArgs > 3)\r
206 {\r
207 useOutFile = True;\r
208 if (OutFile_Open(&outStream.file, args[3]) != 0)\r
209 return PrintError(rs, "Can not open output file");\r
210 }\r
211 else if (encodeMode)\r
212 PrintUserError(rs);\r
213\r
214 if (encodeMode)\r
215 {\r
216 UInt64 fileSize;\r
217 File_GetLength(&inStream.file, &fileSize);\r
218 res = Encode(&outStream.s, &inStream.s, fileSize, rs);\r
219 }\r
220 else\r
221 {\r
222 res = Decode(&outStream.s, useOutFile ? &inStream.s : NULL);\r
223 }\r
224\r
225 if (useOutFile)\r
226 File_Close(&outStream.file);\r
227 File_Close(&inStream.file);\r
228\r
229 if (res != SZ_OK)\r
230 {\r
231 if (res == SZ_ERROR_MEM)\r
232 return PrintError(rs, kCantAllocateMessage);\r
233 else if (res == SZ_ERROR_DATA)\r
234 return PrintError(rs, kDataErrorMessage);\r
235 else if (res == SZ_ERROR_WRITE)\r
236 return PrintError(rs, kCantWriteMessage);\r
237 else if (res == SZ_ERROR_READ)\r
238 return PrintError(rs, kCantReadMessage);\r
239 return PrintErrorNumber(rs, res);\r
240 }\r
241 return 0;\r
242}\r
243\r
244int MY_CDECL main(int numArgs, const char *args[])\r
245{\r
246 char rs[800] = { 0 };\r
247 int res = main2(numArgs, args, rs);\r
248 fputs(rs, stdout);\r
249 return res;\r
250}\r