3 Test application for LZMA Decoder (State version)
5 This file written and distributed to public domain by Igor Pavlov.
6 This file is part of LZMA SDK 4.26 (2005-08-02)
13 #include "LzmaStateDecode.h"
15 const char *kCantReadMessage
= "Can not read input file";
16 const char *kCantWriteMessage
= "Can not write output file";
17 const char *kCantAllocateMessage
= "Can not allocate memory";
19 #define kInBufferSize (1 << 15)
20 #define kOutBufferSize (1 << 15)
22 unsigned char g_InBuffer
[kInBufferSize
];
23 unsigned char g_OutBuffer
[kOutBufferSize
];
25 size_t MyReadFile(FILE *file
, void *data
, size_t size
)
26 { return fread(data
, 1, size
, file
); }
28 int MyReadFileAndCheck(FILE *file
, void *data
, size_t size
)
29 { return (MyReadFile(file
, data
, size
) == size
); }
31 int PrintError(char *buffer
, const char *message
)
33 sprintf(buffer
+ strlen(buffer
), "\nError: ");
34 sprintf(buffer
+ strlen(buffer
), message
);
38 int main3(FILE *inFile
, FILE *outFile
, char *rs
)
40 /* We use two 32-bit integers to construct 64-bit integer for file size.
41 You can remove outSizeHigh, if you don't need >= 4GB supporting,
42 or you can use UInt64 outSize, if your compiler supports 64-bit integers*/
44 UInt32 outSizeHigh
= 0;
47 /* waitEOS = 1, if there is no uncompressed size in headers,
48 so decoder will wait EOS (End of Stream Marker) in compressed stream */
52 CLzmaDecoderState state
; /* it's about 140 bytes structure, if int is 32-bit */
53 unsigned char properties
[LZMA_PROPERTIES_SIZE
];
55 unsigned char *inBuffer
= 0;
57 if (sizeof(UInt32
) < 4)
58 return PrintError(rs
, "LZMA decoder needs correct UInt32");
60 /* Read LZMA properties for compressed stream */
62 if (!MyReadFileAndCheck(inFile
, properties
, sizeof(properties
)))
63 return PrintError(rs
, kCantReadMessage
);
65 /* Read uncompressed size */
67 for (i
= 0; i
< 8; i
++)
70 if (!MyReadFileAndCheck(inFile
, &b
, 1))
71 return PrintError(rs
, kCantReadMessage
);
75 outSize
+= (UInt32
)(b
) << (i
* 8);
77 outSizeHigh
+= (UInt32
)(b
) << ((i
- 4) * 8);
80 /* Decode LZMA properties and allocate memory */
82 if (LzmaDecodeProperties(&state
.Properties
, properties
, LZMA_PROPERTIES_SIZE
) != LZMA_RESULT_OK
)
83 return PrintError(rs
, "Incorrect stream properties");
84 state
.Probs
= (CProb
*)malloc(LzmaGetNumProbs(&state
.Properties
) * sizeof(CProb
));
86 return PrintError(rs
, kCantAllocateMessage
);
88 if (state
.Properties
.DictionarySize
== 0)
92 state
.Dictionary
= (unsigned char *)malloc(state
.Properties
.DictionarySize
);
93 if (state
.Dictionary
== 0)
96 return PrintError(rs
, kCantAllocateMessage
);
102 LzmaDecoderInit(&state
);
106 SizeT inProcessed
, outProcessed
;
108 UInt32 outAvail
= kOutBufferSize
;
109 if (!waitEOS
&& outSizeHigh
== 0 && outAvail
> outSize
)
113 inAvail
= (SizeT
)MyReadFile(inFile
, g_InBuffer
, kInBufferSize
);
114 inBuffer
= g_InBuffer
;
116 finishDecoding
= (inAvail
== 0);
117 res
= LzmaDecode(&state
,
118 inBuffer
, inAvail
, &inProcessed
,
119 g_OutBuffer
, outAvail
, &outProcessed
,
123 sprintf(rs
+ strlen(rs
), "\nDecoding error = %d\n", res
);
127 inAvail
-= inProcessed
;
128 inBuffer
+= inProcessed
;
131 if (fwrite(g_OutBuffer
, 1, outProcessed
, outFile
) != outProcessed
)
133 PrintError(rs
, kCantWriteMessage
);
138 if (outSize
< outProcessed
)
140 outSize
-= (UInt32
)outProcessed
;
141 outSize
&= 0xFFFFFFFF;
143 if (outProcessed
== 0 && finishDecoding
)
145 if (!waitEOS
&& (outSize
!= 0 || outSizeHigh
!= 0))
150 while ((outSize
!= 0 && outSizeHigh
== 0) || outSizeHigh
!= 0 || waitEOS
);
152 free(state
.Dictionary
);
157 int main2(int numArgs
, const char *args
[], char *rs
)
163 sprintf(rs
+ strlen(rs
), "\nLZMA Decoder 4.26 Copyright (c) 1999-2005 Igor Pavlov 2005-08-02\n");
164 if (numArgs
< 2 || numArgs
> 3)
166 sprintf(rs
+ strlen(rs
), "\nUsage: lzmadec file.lzma [outFile]\n");
170 inFile
= fopen(args
[1], "rb");
172 return PrintError(rs
, "Can not open input file");
176 outFile
= fopen(args
[2], "wb+");
178 return PrintError(rs
, "Can not open output file");
181 res
= main3(inFile
, outFile
, rs
);
189 int main(int numArgs
, const char *args
[])
191 char rs
[800] = { 0 };
192 int res
= main2(numArgs
, args
, rs
);