xref: /aosp_15_r20/external/lzma/C/Util/Lzma/LzmaUtil.c (revision f6dc9357d832569d4d1f5d24eacdb3935a1ae8e6)
1*f6dc9357SAndroid Build Coastguard Worker /* LzmaUtil.c -- Test application for LZMA compression
2*f6dc9357SAndroid Build Coastguard Worker 2023-03-07 : Igor Pavlov : Public domain */
3*f6dc9357SAndroid Build Coastguard Worker 
4*f6dc9357SAndroid Build Coastguard Worker #include "Precomp.h"
5*f6dc9357SAndroid Build Coastguard Worker 
6*f6dc9357SAndroid Build Coastguard Worker #include <stdio.h>
7*f6dc9357SAndroid Build Coastguard Worker #include <stdlib.h>
8*f6dc9357SAndroid Build Coastguard Worker #include <string.h>
9*f6dc9357SAndroid Build Coastguard Worker 
10*f6dc9357SAndroid Build Coastguard Worker #include "../../CpuArch.h"
11*f6dc9357SAndroid Build Coastguard Worker 
12*f6dc9357SAndroid Build Coastguard Worker #include "../../Alloc.h"
13*f6dc9357SAndroid Build Coastguard Worker #include "../../7zFile.h"
14*f6dc9357SAndroid Build Coastguard Worker #include "../../7zVersion.h"
15*f6dc9357SAndroid Build Coastguard Worker #include "../../LzFind.h"
16*f6dc9357SAndroid Build Coastguard Worker #include "../../LzmaDec.h"
17*f6dc9357SAndroid Build Coastguard Worker #include "../../LzmaEnc.h"
18*f6dc9357SAndroid Build Coastguard Worker 
19*f6dc9357SAndroid Build Coastguard Worker static const char * const kCantReadMessage = "Cannot read input file";
20*f6dc9357SAndroid Build Coastguard Worker static const char * const kCantWriteMessage = "Cannot write output file";
21*f6dc9357SAndroid Build Coastguard Worker static const char * const kCantAllocateMessage = "Cannot allocate memory";
22*f6dc9357SAndroid Build Coastguard Worker static const char * const kDataErrorMessage = "Data error";
23*f6dc9357SAndroid Build Coastguard Worker 
Print(const char * s)24*f6dc9357SAndroid Build Coastguard Worker static void Print(const char *s)
25*f6dc9357SAndroid Build Coastguard Worker {
26*f6dc9357SAndroid Build Coastguard Worker   fputs(s, stdout);
27*f6dc9357SAndroid Build Coastguard Worker }
28*f6dc9357SAndroid Build Coastguard Worker 
PrintHelp(void)29*f6dc9357SAndroid Build Coastguard Worker static void PrintHelp(void)
30*f6dc9357SAndroid Build Coastguard Worker {
31*f6dc9357SAndroid Build Coastguard Worker   Print(
32*f6dc9357SAndroid Build Coastguard Worker     "\n" "LZMA-C " MY_VERSION_CPU " : " MY_COPYRIGHT_DATE
33*f6dc9357SAndroid Build Coastguard Worker     "\n"
34*f6dc9357SAndroid Build Coastguard Worker     "\n" "Usage:  lzma <e|d> inputFile outputFile"
35*f6dc9357SAndroid Build Coastguard Worker     "\n" "  e: encode file"
36*f6dc9357SAndroid Build Coastguard Worker     "\n" "  d: decode file"
37*f6dc9357SAndroid Build Coastguard Worker     "\n");
38*f6dc9357SAndroid Build Coastguard Worker }
39*f6dc9357SAndroid Build Coastguard Worker 
PrintError(const char * message)40*f6dc9357SAndroid Build Coastguard Worker static int PrintError(const char *message)
41*f6dc9357SAndroid Build Coastguard Worker {
42*f6dc9357SAndroid Build Coastguard Worker   Print("\nError: ");
43*f6dc9357SAndroid Build Coastguard Worker   Print(message);
44*f6dc9357SAndroid Build Coastguard Worker   Print("\n");
45*f6dc9357SAndroid Build Coastguard Worker   return 1;
46*f6dc9357SAndroid Build Coastguard Worker }
47*f6dc9357SAndroid Build Coastguard Worker 
48*f6dc9357SAndroid Build Coastguard Worker #define CONVERT_INT_TO_STR(charType, tempSize) \
49*f6dc9357SAndroid Build Coastguard Worker   unsigned char temp[tempSize]; unsigned i = 0; \
50*f6dc9357SAndroid Build Coastguard Worker   while (val >= 10) { temp[i++] = (unsigned char)('0' + (unsigned)(val % 10)); val /= 10; } \
51*f6dc9357SAndroid Build Coastguard Worker   *s++ = (charType)('0' + (unsigned)val); \
52*f6dc9357SAndroid Build Coastguard Worker   while (i != 0) { i--; *s++ = (charType)temp[i]; } \
53*f6dc9357SAndroid Build Coastguard Worker   *s = 0; \
54*f6dc9357SAndroid Build Coastguard Worker   return s;
55*f6dc9357SAndroid Build Coastguard Worker 
Convert_unsigned_To_str(unsigned val,char * s)56*f6dc9357SAndroid Build Coastguard Worker static char * Convert_unsigned_To_str(unsigned val, char *s)
57*f6dc9357SAndroid Build Coastguard Worker {
58*f6dc9357SAndroid Build Coastguard Worker   CONVERT_INT_TO_STR(char, 32)
59*f6dc9357SAndroid Build Coastguard Worker }
60*f6dc9357SAndroid Build Coastguard Worker 
Print_unsigned(unsigned code)61*f6dc9357SAndroid Build Coastguard Worker static void Print_unsigned(unsigned code)
62*f6dc9357SAndroid Build Coastguard Worker {
63*f6dc9357SAndroid Build Coastguard Worker   char str[32];
64*f6dc9357SAndroid Build Coastguard Worker   Convert_unsigned_To_str(code, str);
65*f6dc9357SAndroid Build Coastguard Worker   Print(str);
66*f6dc9357SAndroid Build Coastguard Worker }
67*f6dc9357SAndroid Build Coastguard Worker 
PrintError_WRes(const char * message,WRes wres)68*f6dc9357SAndroid Build Coastguard Worker static int PrintError_WRes(const char *message, WRes wres)
69*f6dc9357SAndroid Build Coastguard Worker {
70*f6dc9357SAndroid Build Coastguard Worker   PrintError(message);
71*f6dc9357SAndroid Build Coastguard Worker   Print("\nSystem error code: ");
72*f6dc9357SAndroid Build Coastguard Worker   Print_unsigned((unsigned)wres);
73*f6dc9357SAndroid Build Coastguard Worker   #ifndef _WIN32
74*f6dc9357SAndroid Build Coastguard Worker   {
75*f6dc9357SAndroid Build Coastguard Worker     const char *s = strerror(wres);
76*f6dc9357SAndroid Build Coastguard Worker     if (s)
77*f6dc9357SAndroid Build Coastguard Worker     {
78*f6dc9357SAndroid Build Coastguard Worker       Print(" : ");
79*f6dc9357SAndroid Build Coastguard Worker       Print(s);
80*f6dc9357SAndroid Build Coastguard Worker     }
81*f6dc9357SAndroid Build Coastguard Worker   }
82*f6dc9357SAndroid Build Coastguard Worker   #endif
83*f6dc9357SAndroid Build Coastguard Worker   Print("\n");
84*f6dc9357SAndroid Build Coastguard Worker   return 1;
85*f6dc9357SAndroid Build Coastguard Worker }
86*f6dc9357SAndroid Build Coastguard Worker 
PrintErrorNumber(SRes val)87*f6dc9357SAndroid Build Coastguard Worker static int PrintErrorNumber(SRes val)
88*f6dc9357SAndroid Build Coastguard Worker {
89*f6dc9357SAndroid Build Coastguard Worker   Print("\n7-Zip error code: ");
90*f6dc9357SAndroid Build Coastguard Worker   Print_unsigned((unsigned)val);
91*f6dc9357SAndroid Build Coastguard Worker   Print("\n");
92*f6dc9357SAndroid Build Coastguard Worker   return 1;
93*f6dc9357SAndroid Build Coastguard Worker }
94*f6dc9357SAndroid Build Coastguard Worker 
PrintUserError(void)95*f6dc9357SAndroid Build Coastguard Worker static int PrintUserError(void)
96*f6dc9357SAndroid Build Coastguard Worker {
97*f6dc9357SAndroid Build Coastguard Worker   return PrintError("Incorrect command");
98*f6dc9357SAndroid Build Coastguard Worker }
99*f6dc9357SAndroid Build Coastguard Worker 
100*f6dc9357SAndroid Build Coastguard Worker 
101*f6dc9357SAndroid Build Coastguard Worker #define IN_BUF_SIZE (1 << 16)
102*f6dc9357SAndroid Build Coastguard Worker #define OUT_BUF_SIZE (1 << 16)
103*f6dc9357SAndroid Build Coastguard Worker 
104*f6dc9357SAndroid Build Coastguard Worker 
Decode2(CLzmaDec * state,ISeqOutStreamPtr outStream,ISeqInStreamPtr inStream,UInt64 unpackSize)105*f6dc9357SAndroid Build Coastguard Worker static SRes Decode2(CLzmaDec *state, ISeqOutStreamPtr outStream, ISeqInStreamPtr inStream,
106*f6dc9357SAndroid Build Coastguard Worker     UInt64 unpackSize)
107*f6dc9357SAndroid Build Coastguard Worker {
108*f6dc9357SAndroid Build Coastguard Worker   const int thereIsSize = (unpackSize != (UInt64)(Int64)-1);
109*f6dc9357SAndroid Build Coastguard Worker   Byte inBuf[IN_BUF_SIZE];
110*f6dc9357SAndroid Build Coastguard Worker   Byte outBuf[OUT_BUF_SIZE];
111*f6dc9357SAndroid Build Coastguard Worker   size_t inPos = 0, inSize = 0, outPos = 0;
112*f6dc9357SAndroid Build Coastguard Worker   LzmaDec_Init(state);
113*f6dc9357SAndroid Build Coastguard Worker   for (;;)
114*f6dc9357SAndroid Build Coastguard Worker   {
115*f6dc9357SAndroid Build Coastguard Worker     if (inPos == inSize)
116*f6dc9357SAndroid Build Coastguard Worker     {
117*f6dc9357SAndroid Build Coastguard Worker       inSize = IN_BUF_SIZE;
118*f6dc9357SAndroid Build Coastguard Worker       RINOK(inStream->Read(inStream, inBuf, &inSize))
119*f6dc9357SAndroid Build Coastguard Worker       inPos = 0;
120*f6dc9357SAndroid Build Coastguard Worker     }
121*f6dc9357SAndroid Build Coastguard Worker     {
122*f6dc9357SAndroid Build Coastguard Worker       SRes res;
123*f6dc9357SAndroid Build Coastguard Worker       SizeT inProcessed = inSize - inPos;
124*f6dc9357SAndroid Build Coastguard Worker       SizeT outProcessed = OUT_BUF_SIZE - outPos;
125*f6dc9357SAndroid Build Coastguard Worker       ELzmaFinishMode finishMode = LZMA_FINISH_ANY;
126*f6dc9357SAndroid Build Coastguard Worker       ELzmaStatus status;
127*f6dc9357SAndroid Build Coastguard Worker       if (thereIsSize && outProcessed > unpackSize)
128*f6dc9357SAndroid Build Coastguard Worker       {
129*f6dc9357SAndroid Build Coastguard Worker         outProcessed = (SizeT)unpackSize;
130*f6dc9357SAndroid Build Coastguard Worker         finishMode = LZMA_FINISH_END;
131*f6dc9357SAndroid Build Coastguard Worker       }
132*f6dc9357SAndroid Build Coastguard Worker 
133*f6dc9357SAndroid Build Coastguard Worker       res = LzmaDec_DecodeToBuf(state, outBuf + outPos, &outProcessed,
134*f6dc9357SAndroid Build Coastguard Worker         inBuf + inPos, &inProcessed, finishMode, &status);
135*f6dc9357SAndroid Build Coastguard Worker       inPos += inProcessed;
136*f6dc9357SAndroid Build Coastguard Worker       outPos += outProcessed;
137*f6dc9357SAndroid Build Coastguard Worker       unpackSize -= outProcessed;
138*f6dc9357SAndroid Build Coastguard Worker 
139*f6dc9357SAndroid Build Coastguard Worker       if (outStream)
140*f6dc9357SAndroid Build Coastguard Worker         if (outStream->Write(outStream, outBuf, outPos) != outPos)
141*f6dc9357SAndroid Build Coastguard Worker           return SZ_ERROR_WRITE;
142*f6dc9357SAndroid Build Coastguard Worker 
143*f6dc9357SAndroid Build Coastguard Worker       outPos = 0;
144*f6dc9357SAndroid Build Coastguard Worker 
145*f6dc9357SAndroid Build Coastguard Worker       if (res != SZ_OK || (thereIsSize && unpackSize == 0))
146*f6dc9357SAndroid Build Coastguard Worker         return res;
147*f6dc9357SAndroid Build Coastguard Worker 
148*f6dc9357SAndroid Build Coastguard Worker       if (inProcessed == 0 && outProcessed == 0)
149*f6dc9357SAndroid Build Coastguard Worker       {
150*f6dc9357SAndroid Build Coastguard Worker         if (thereIsSize || status != LZMA_STATUS_FINISHED_WITH_MARK)
151*f6dc9357SAndroid Build Coastguard Worker           return SZ_ERROR_DATA;
152*f6dc9357SAndroid Build Coastguard Worker         return res;
153*f6dc9357SAndroid Build Coastguard Worker       }
154*f6dc9357SAndroid Build Coastguard Worker     }
155*f6dc9357SAndroid Build Coastguard Worker   }
156*f6dc9357SAndroid Build Coastguard Worker }
157*f6dc9357SAndroid Build Coastguard Worker 
158*f6dc9357SAndroid Build Coastguard Worker 
Decode(ISeqOutStreamPtr outStream,ISeqInStreamPtr inStream)159*f6dc9357SAndroid Build Coastguard Worker static SRes Decode(ISeqOutStreamPtr outStream, ISeqInStreamPtr inStream)
160*f6dc9357SAndroid Build Coastguard Worker {
161*f6dc9357SAndroid Build Coastguard Worker   UInt64 unpackSize;
162*f6dc9357SAndroid Build Coastguard Worker   int i;
163*f6dc9357SAndroid Build Coastguard Worker   SRes res = 0;
164*f6dc9357SAndroid Build Coastguard Worker 
165*f6dc9357SAndroid Build Coastguard Worker   CLzmaDec state;
166*f6dc9357SAndroid Build Coastguard Worker 
167*f6dc9357SAndroid Build Coastguard Worker   /* header: 5 bytes of LZMA properties and 8 bytes of uncompressed size */
168*f6dc9357SAndroid Build Coastguard Worker   unsigned char header[LZMA_PROPS_SIZE + 8];
169*f6dc9357SAndroid Build Coastguard Worker 
170*f6dc9357SAndroid Build Coastguard Worker   /* Read and parse header */
171*f6dc9357SAndroid Build Coastguard Worker 
172*f6dc9357SAndroid Build Coastguard Worker   {
173*f6dc9357SAndroid Build Coastguard Worker     size_t size = sizeof(header);
174*f6dc9357SAndroid Build Coastguard Worker     RINOK(SeqInStream_ReadMax(inStream, header, &size))
175*f6dc9357SAndroid Build Coastguard Worker     if (size != sizeof(header))
176*f6dc9357SAndroid Build Coastguard Worker       return SZ_ERROR_INPUT_EOF;
177*f6dc9357SAndroid Build Coastguard Worker   }
178*f6dc9357SAndroid Build Coastguard Worker   unpackSize = 0;
179*f6dc9357SAndroid Build Coastguard Worker   for (i = 0; i < 8; i++)
180*f6dc9357SAndroid Build Coastguard Worker     unpackSize += (UInt64)header[LZMA_PROPS_SIZE + i] << (i * 8);
181*f6dc9357SAndroid Build Coastguard Worker 
182*f6dc9357SAndroid Build Coastguard Worker   LzmaDec_CONSTRUCT(&state)
183*f6dc9357SAndroid Build Coastguard Worker   RINOK(LzmaDec_Allocate(&state, header, LZMA_PROPS_SIZE, &g_Alloc))
184*f6dc9357SAndroid Build Coastguard Worker   res = Decode2(&state, outStream, inStream, unpackSize);
185*f6dc9357SAndroid Build Coastguard Worker   LzmaDec_Free(&state, &g_Alloc);
186*f6dc9357SAndroid Build Coastguard Worker   return res;
187*f6dc9357SAndroid Build Coastguard Worker }
188*f6dc9357SAndroid Build Coastguard Worker 
Encode(ISeqOutStreamPtr outStream,ISeqInStreamPtr inStream,UInt64 fileSize)189*f6dc9357SAndroid Build Coastguard Worker static SRes Encode(ISeqOutStreamPtr outStream, ISeqInStreamPtr inStream, UInt64 fileSize)
190*f6dc9357SAndroid Build Coastguard Worker {
191*f6dc9357SAndroid Build Coastguard Worker   CLzmaEncHandle enc;
192*f6dc9357SAndroid Build Coastguard Worker   SRes res;
193*f6dc9357SAndroid Build Coastguard Worker   CLzmaEncProps props;
194*f6dc9357SAndroid Build Coastguard Worker 
195*f6dc9357SAndroid Build Coastguard Worker   enc = LzmaEnc_Create(&g_Alloc);
196*f6dc9357SAndroid Build Coastguard Worker   if (enc == 0)
197*f6dc9357SAndroid Build Coastguard Worker     return SZ_ERROR_MEM;
198*f6dc9357SAndroid Build Coastguard Worker 
199*f6dc9357SAndroid Build Coastguard Worker   LzmaEncProps_Init(&props);
200*f6dc9357SAndroid Build Coastguard Worker   res = LzmaEnc_SetProps(enc, &props);
201*f6dc9357SAndroid Build Coastguard Worker 
202*f6dc9357SAndroid Build Coastguard Worker   if (res == SZ_OK)
203*f6dc9357SAndroid Build Coastguard Worker   {
204*f6dc9357SAndroid Build Coastguard Worker     Byte header[LZMA_PROPS_SIZE + 8];
205*f6dc9357SAndroid Build Coastguard Worker     size_t headerSize = LZMA_PROPS_SIZE;
206*f6dc9357SAndroid Build Coastguard Worker     int i;
207*f6dc9357SAndroid Build Coastguard Worker 
208*f6dc9357SAndroid Build Coastguard Worker     res = LzmaEnc_WriteProperties(enc, header, &headerSize);
209*f6dc9357SAndroid Build Coastguard Worker     for (i = 0; i < 8; i++)
210*f6dc9357SAndroid Build Coastguard Worker       header[headerSize++] = (Byte)(fileSize >> (8 * i));
211*f6dc9357SAndroid Build Coastguard Worker     if (outStream->Write(outStream, header, headerSize) != headerSize)
212*f6dc9357SAndroid Build Coastguard Worker       res = SZ_ERROR_WRITE;
213*f6dc9357SAndroid Build Coastguard Worker     else
214*f6dc9357SAndroid Build Coastguard Worker     {
215*f6dc9357SAndroid Build Coastguard Worker       if (res == SZ_OK)
216*f6dc9357SAndroid Build Coastguard Worker         res = LzmaEnc_Encode(enc, outStream, inStream, NULL, &g_Alloc, &g_Alloc);
217*f6dc9357SAndroid Build Coastguard Worker     }
218*f6dc9357SAndroid Build Coastguard Worker   }
219*f6dc9357SAndroid Build Coastguard Worker   LzmaEnc_Destroy(enc, &g_Alloc, &g_Alloc);
220*f6dc9357SAndroid Build Coastguard Worker   return res;
221*f6dc9357SAndroid Build Coastguard Worker }
222*f6dc9357SAndroid Build Coastguard Worker 
223*f6dc9357SAndroid Build Coastguard Worker 
main(int numArgs,const char * args[])224*f6dc9357SAndroid Build Coastguard Worker int Z7_CDECL main(int numArgs, const char *args[])
225*f6dc9357SAndroid Build Coastguard Worker {
226*f6dc9357SAndroid Build Coastguard Worker   CFileSeqInStream inStream;
227*f6dc9357SAndroid Build Coastguard Worker   CFileOutStream outStream;
228*f6dc9357SAndroid Build Coastguard Worker   char c;
229*f6dc9357SAndroid Build Coastguard Worker   int res;
230*f6dc9357SAndroid Build Coastguard Worker   int encodeMode;
231*f6dc9357SAndroid Build Coastguard Worker   BoolInt useOutFile = False;
232*f6dc9357SAndroid Build Coastguard Worker 
233*f6dc9357SAndroid Build Coastguard Worker   LzFindPrepare();
234*f6dc9357SAndroid Build Coastguard Worker 
235*f6dc9357SAndroid Build Coastguard Worker   FileSeqInStream_CreateVTable(&inStream);
236*f6dc9357SAndroid Build Coastguard Worker   File_Construct(&inStream.file);
237*f6dc9357SAndroid Build Coastguard Worker   inStream.wres = 0;
238*f6dc9357SAndroid Build Coastguard Worker 
239*f6dc9357SAndroid Build Coastguard Worker   FileOutStream_CreateVTable(&outStream);
240*f6dc9357SAndroid Build Coastguard Worker   File_Construct(&outStream.file);
241*f6dc9357SAndroid Build Coastguard Worker   outStream.wres = 0;
242*f6dc9357SAndroid Build Coastguard Worker 
243*f6dc9357SAndroid Build Coastguard Worker   if (numArgs == 1)
244*f6dc9357SAndroid Build Coastguard Worker   {
245*f6dc9357SAndroid Build Coastguard Worker     PrintHelp();
246*f6dc9357SAndroid Build Coastguard Worker     return 0;
247*f6dc9357SAndroid Build Coastguard Worker   }
248*f6dc9357SAndroid Build Coastguard Worker 
249*f6dc9357SAndroid Build Coastguard Worker   if (numArgs < 3 || numArgs > 4 || strlen(args[1]) != 1)
250*f6dc9357SAndroid Build Coastguard Worker     return PrintUserError();
251*f6dc9357SAndroid Build Coastguard Worker 
252*f6dc9357SAndroid Build Coastguard Worker   c = args[1][0];
253*f6dc9357SAndroid Build Coastguard Worker   encodeMode = (c == 'e' || c == 'E');
254*f6dc9357SAndroid Build Coastguard Worker   if (!encodeMode && c != 'd' && c != 'D')
255*f6dc9357SAndroid Build Coastguard Worker     return PrintUserError();
256*f6dc9357SAndroid Build Coastguard Worker 
257*f6dc9357SAndroid Build Coastguard Worker   /*
258*f6dc9357SAndroid Build Coastguard Worker   {
259*f6dc9357SAndroid Build Coastguard Worker     size_t t4 = sizeof(UInt32);
260*f6dc9357SAndroid Build Coastguard Worker     size_t t8 = sizeof(UInt64);
261*f6dc9357SAndroid Build Coastguard Worker     if (t4 != 4 || t8 != 8)
262*f6dc9357SAndroid Build Coastguard Worker       return PrintError("Incorrect UInt32 or UInt64");
263*f6dc9357SAndroid Build Coastguard Worker   }
264*f6dc9357SAndroid Build Coastguard Worker   */
265*f6dc9357SAndroid Build Coastguard Worker 
266*f6dc9357SAndroid Build Coastguard Worker   {
267*f6dc9357SAndroid Build Coastguard Worker     const WRes wres = InFile_Open(&inStream.file, args[2]);
268*f6dc9357SAndroid Build Coastguard Worker     if (wres != 0)
269*f6dc9357SAndroid Build Coastguard Worker       return PrintError_WRes("Cannot open input file", wres);
270*f6dc9357SAndroid Build Coastguard Worker   }
271*f6dc9357SAndroid Build Coastguard Worker 
272*f6dc9357SAndroid Build Coastguard Worker   if (numArgs > 3)
273*f6dc9357SAndroid Build Coastguard Worker   {
274*f6dc9357SAndroid Build Coastguard Worker     WRes wres;
275*f6dc9357SAndroid Build Coastguard Worker     useOutFile = True;
276*f6dc9357SAndroid Build Coastguard Worker     wres = OutFile_Open(&outStream.file, args[3]);
277*f6dc9357SAndroid Build Coastguard Worker     if (wres != 0)
278*f6dc9357SAndroid Build Coastguard Worker       return PrintError_WRes("Cannot open output file", wres);
279*f6dc9357SAndroid Build Coastguard Worker   }
280*f6dc9357SAndroid Build Coastguard Worker   else if (encodeMode)
281*f6dc9357SAndroid Build Coastguard Worker     PrintUserError();
282*f6dc9357SAndroid Build Coastguard Worker 
283*f6dc9357SAndroid Build Coastguard Worker   if (encodeMode)
284*f6dc9357SAndroid Build Coastguard Worker   {
285*f6dc9357SAndroid Build Coastguard Worker     UInt64 fileSize;
286*f6dc9357SAndroid Build Coastguard Worker     const WRes wres = File_GetLength(&inStream.file, &fileSize);
287*f6dc9357SAndroid Build Coastguard Worker     if (wres != 0)
288*f6dc9357SAndroid Build Coastguard Worker       return PrintError_WRes("Cannot get file length", wres);
289*f6dc9357SAndroid Build Coastguard Worker     res = Encode(&outStream.vt, &inStream.vt, fileSize);
290*f6dc9357SAndroid Build Coastguard Worker   }
291*f6dc9357SAndroid Build Coastguard Worker   else
292*f6dc9357SAndroid Build Coastguard Worker   {
293*f6dc9357SAndroid Build Coastguard Worker     res = Decode(&outStream.vt, useOutFile ? &inStream.vt : NULL);
294*f6dc9357SAndroid Build Coastguard Worker   }
295*f6dc9357SAndroid Build Coastguard Worker 
296*f6dc9357SAndroid Build Coastguard Worker   if (useOutFile)
297*f6dc9357SAndroid Build Coastguard Worker     File_Close(&outStream.file);
298*f6dc9357SAndroid Build Coastguard Worker   File_Close(&inStream.file);
299*f6dc9357SAndroid Build Coastguard Worker 
300*f6dc9357SAndroid Build Coastguard Worker   if (res != SZ_OK)
301*f6dc9357SAndroid Build Coastguard Worker   {
302*f6dc9357SAndroid Build Coastguard Worker     if (res == SZ_ERROR_MEM)
303*f6dc9357SAndroid Build Coastguard Worker       return PrintError(kCantAllocateMessage);
304*f6dc9357SAndroid Build Coastguard Worker     else if (res == SZ_ERROR_DATA)
305*f6dc9357SAndroid Build Coastguard Worker       return PrintError(kDataErrorMessage);
306*f6dc9357SAndroid Build Coastguard Worker     else if (res == SZ_ERROR_WRITE)
307*f6dc9357SAndroid Build Coastguard Worker       return PrintError_WRes(kCantWriteMessage, outStream.wres);
308*f6dc9357SAndroid Build Coastguard Worker     else if (res == SZ_ERROR_READ)
309*f6dc9357SAndroid Build Coastguard Worker       return PrintError_WRes(kCantReadMessage, inStream.wres);
310*f6dc9357SAndroid Build Coastguard Worker     return PrintErrorNumber(res);
311*f6dc9357SAndroid Build Coastguard Worker   }
312*f6dc9357SAndroid Build Coastguard Worker   return 0;
313*f6dc9357SAndroid Build Coastguard Worker }
314