1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
|
/******************************************************************************
LZMA decoder library with a zlib like API
* WARNING WARNING WARNING WARNING WARNING WARNING *
* *
* This library hasn't been maintained since 2005. *
* This will be replaced by liblzma once it is *
* finished. liblzma will provide all the features *
* of liblzmadec and a lot more. *
* *
* WARNING WARNING WARNING WARNING WARNING WARNING *
Copyright (C) 1999-2005 Igor Pavlov (http://7-zip.org/)
Copyright (C) 2005 Lasse Collin <lasse.collin@tukaani.org>
Based on zlib.h and bzlib.h.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
******************************************************************************/
/*************************
WARNING WARNING WARNING
Comments about return
codes etc. are not up
to date.
*************************/
#ifndef LZMADEC_H
#define LZMADEC_H
#ifdef __cplusplus
extern "C" {
#endif
/**********
Includes
**********/
#include <sys/types.h>
#include <inttypes.h>
/* Define LZMADEC_NO_STDIO to not include stdio.h and lzmadec_FILE functions. */
#ifndef LZMADEC_NO_STDIO
#include <stdio.h>
#endif
/*******************
Defines/Constants
*******************/
/* Size in bytes of the smallest possible LZMA encoded file */
#define LZMADEC_MINIMUM_SIZE 18
/* Return values */
#define LZMADEC_OK 0
#define LZMADEC_STREAM_END 1
#define LZMADEC_HEADER_ERROR (-2)
#define LZMADEC_DATA_ERROR (-3)
#define LZMADEC_MEM_ERROR (-4)
#define LZMADEC_BUF_ERROR (-5)
#define LZMADEC_SEQUENCE_ERROR (-6)
/*
LZMADEC_OK
Operation succeeded or some progress has been made.
LZMADEC_STREAM_END
The end of the encoded data has been reached. Note that this is
a possible return value even when finish_decoding == LZMADEC_RUN.
LZMADEC_DATA_ERROR
Something wrong with the input data.
LZMADEC_MEM_ERROR
The memory allocation function returned a NULL pointer. The same
function can be called again with the same arguments to try again.
LZMADEC_BUF_ERROR
You should provide more input in next_in and set avail_in accordingly.
The first call to lzmadec_decode() must provide at least 18 bytes of
input data. Subsequent calls can any amount of data (or no data at all).
Note that LZMADEC_BUF_ERROR is not fatal and decoding can continue by
supplying more input data.
*/
/**********
typedefs
**********/
typedef struct {
uint8_t *next_in;
size_t avail_in;
uint_fast64_t total_in;
uint8_t *next_out;
size_t avail_out;
uint_fast64_t total_out;
void *state; /* Internal state, not visible outside the library */
void *(*lzma_alloc)(void *, size_t, size_t);
void (*lzma_free)(void *, void *);
void *opaque;
} lzmadec_stream;
typedef struct {
uint_fast64_t uncompressed_size;
uint_fast32_t dictionary_size;
uint_fast32_t internal_data_size;
uint_fast8_t is_streamed;
uint_fast8_t pb;
uint_fast8_t lp;
uint_fast8_t lc;
} lzmadec_info;
#ifndef LZMADEC_NO_STDIO
typedef void lzmadec_FILE;
#endif
/*********************
Single call decoding
*********************/
extern int_fast8_t lzmadec_buffer (
uint8_t *dest, size_t *dest_len,
uint8_t *source, const size_t source_len);
/*
Decode the data from source buffer to destination buffer with
a single pass.
Return values:
LZMADEC_OK Decoding successful
LZMADEC_HEADER_ERROR Invalid header
LZMADEC_MEM_ERROR Not enough memory
LZMADEC_DATA_ERROR Corrupted source data
LZMADEC_BUF_ERROR Destination buffer too small
Equivalent in zlib: uncompress()
*/
/*********************
Multi call decoding
*********************/
extern int_fast8_t lzmadec_init (lzmadec_stream *strm);
/*
Initialize the decoder.
Return values:
LZMADEC_OK
LZMADEC_HEADER_ERROR
LZMADEC_MEM_ERROR
Equivalent in zlib: inflateInit()
*/
extern int_fast8_t
lzmadec_decode (lzmadec_stream *strm, const int_fast8_t finish_decoding);
/*
The finish_decoding flag
In contrast to zlib and bzlib, liblzmadec can detect the end of the
compressed stream only with streamed LZMA data. Non-streamed data
does not contain any end of stream marker and thus needs the
finish_decoding flag to be set to decode the last bytes of the data.
When the finish_decoding is zero,
This is a sign to the decoder that even if avail_in == 0 happened to
be true, there can still be more input data not passed to the library
yet. It is safe to call lzmadec_decode with LZMADEC_RUN even if all
the data has been passed to the library already; in that case there
there will usually be bytes left in the internal output buffer.
Set the finish_decoding to non-zero to sign the decoder that all
the input has been given to it via next_in buffer. Once called with
non-zero finish_decoding flag, it should not be unset or an error
will be returned.
If you can assure that (avail_in > 0) on every lzmadec_decode() call
before all the data has been passed to the decoder library, the
simplest way is to use (strm.avail_in == 0) as the finish_decoding
value.
Return values:
LZMADEC_OK
LZMADEC_STREAM_END
LZMADEC_DATA_ERROR
LZMADEC_HEADER_ERROR (only right after initialization)
LZMADEC_MEM_ERROR (only right after initialization)
Equivalent in zlib: inflate()
*/
int_fast8_t lzmadec_end (lzmadec_stream *strm);
/*
Return values:
LZMADEC_OK
LZMADEC_STREAM_ERROR FIXME
Equivalent in zlib: inflateEnd()
*/
/*************
Information
*************/
extern int_fast8_t lzmadec_buffer_info (
lzmadec_info *info, const uint8_t *buffer, const size_t len);
/*
Parse the header of a LZMA stream. The header size is
13 bytes; make sure there is at least 13 bytes available
in the buffer. Information about parsed header will be stored
to *info.
Most common uses for this function are checking
- the uncompressed size of the file (if availabe)
- how much RAM is needed to decompress the data.
uncompressed_size Uncompressed size of the data as bytes
dictionary_size Dictionary size as bytes; depends only on
settings used when compressing the data.
internal_data_size The amount of memory needed by liblzmadec
to decode the data excluding the dictionary
size. Note that this value depends not only
about the used compression settings but
also the implementation and/or compile time
settings; specifically sizeof(uint_fast16_t).
is_streamed Zero if the data is non-streamed LZMA, and
non-zero for streamed. This flag is set
simply by checking the size field.
pb Number of pos bits; can be from 0 to 4.
lp Number of literal pos bits; from 0 to 4.
lc Number of literal context bits; from 0 to 8.
To know how much memory is needed to compress a specific stream,
add up dictionary_size and internal_data_size. Note that if the
dictionary is extremely huge, the result might not fit in
uint_fast32_t. ;-)
WARNING: LZMA streams have no magic first bytes. All data
that has 0x00 - 0xE1 as the first byte in the buffer will
return LZMADEC_OK.
Return values:
LZMADEC_OK All OK, the information was stored to *info.
LZMADEC_BUF_ERROR len is too small.
LZMADEC_HEADER_ERROR Invalid header data.
*/
extern const uint8_t *lzmadec_version (void);
/*
Return a pointer to a statically allocated string containing the version
number of the liblzmadec. The version number format is x.yy.z where
x.yy is the version of LZMA SDK from http://7-zip.org/sdk.html, and x
is
Equivalent in zlib: zlibVersion()
*/
/**********
File I/O
**********/
#ifndef LZMADEC_NO_STDIO
extern lzmadec_FILE *lzmadec_open (const char *path);
extern lzmadec_FILE *lzmadec_dopen (int fd);
extern ssize_t lzmadec_read (lzmadec_FILE *file, uint8_t *buf, size_t len);
extern uint8_t *lzmadec_gets (lzmadec_FILE *file, uint8_t *buf, size_t len);
extern int lzmadec_getc (lzmadec_FILE *file);
extern int_fast8_t lzmadec_seek (lzmadec_FILE *file, off_t offset, int whence);
extern off_t lzmadec_tell (lzmadec_FILE *file);
extern int_fast8_t lzmadec_rewind (lzmadec_FILE *file);
extern int_fast8_t lzmadec_eof (lzmadec_FILE *file);
extern int_fast8_t lzmadec_close (lzmadec_FILE *file);
/* extern const char *lzmadec_error (lzmadec_FILE *file, int *errnum) */
#endif /* ifndef LZMADEC_NO_STDIO */
#ifdef __cplusplus
}
#endif
#endif /* ifndef LZMADEC_H */
|