1 ///////////////////////////////////////////////////////////////////////////////
4 /// \brief Definitions common to the whole liblzma library
6 // Copyright (C) 2007 Lasse Collin
8 // This library is free software; you can redistribute it and/or
9 // modify it under the terms of the GNU Lesser General Public
10 // License as published by the Free Software Foundation; either
11 // version 2.1 of the License, or (at your option) any later version.
13 // This library is distributed in the hope that it will be useful,
14 // but WITHOUT ANY WARRANTY; without even the implied warranty of
15 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 // Lesser General Public License for more details.
18 ///////////////////////////////////////////////////////////////////////////////
23 #include "../../common/sysdefs.h"
27 # define LZMA_API __attribute__((__visibility__("default")))
33 /// Size of temporary buffers needed in some filters
34 #define LZMA_BUFFER_SIZE 4096
37 /// Internal helper filter used by Subblock decoder. It is mapped to an
38 /// otherwise invalid Filter ID, which is impossible to get from any input
39 /// file (even if malicious file).
40 #define LZMA_FILTER_SUBBLOCK_HELPER (UINT64_MAX - 2)
47 typedef struct lzma_coder_s lzma_coder;
49 typedef struct lzma_next_coder_s lzma_next_coder;
51 typedef struct lzma_filter_info_s lzma_filter_info;
54 typedef lzma_ret (*lzma_init_function)(
55 lzma_next_coder *next, lzma_allocator *allocator,
56 const lzma_filter_info *filters);
58 typedef lzma_ret (*lzma_code_function)(
59 lzma_coder *coder, lzma_allocator *allocator,
60 const uint8_t *restrict in, size_t *restrict in_pos,
61 size_t in_size, uint8_t *restrict out,
62 size_t *restrict out_pos, size_t out_size,
65 typedef void (*lzma_end_function)(
66 lzma_coder *coder, lzma_allocator *allocator);
69 /// Hold data and function pointers of the next filter in the chain.
70 struct lzma_next_coder_s {
71 /// Pointer to coder-specific data
74 /// "Pointer" to init function. This is never called here.
75 /// We need only to detect if we are initializing a coder
76 /// that was allocated earlier. See code.c and next_coder.c.
79 /// Pointer to function to do the actual coding
80 lzma_code_function code;
82 /// Pointer to function to free lzma_next_coder.coder
83 lzma_end_function end;
86 #define LZMA_NEXT_CODER_INIT \
95 struct lzma_internal_s {
107 bool supported_actions[4];
108 bool allow_buf_error;
113 struct lzma_filter_info_s {
114 /// Pointer to function used to initialize the filter.
115 /// This is NULL to indicate end of array.
116 lzma_init_function init;
118 /// Pointer to filter's options structure
121 /// Uncompressed size of the filter, or LZMA_VLI_VALUE_UNKNOWN
123 lzma_vli uncompressed_size;
129 lzma_init_function init;
130 uint32_t (*input_alignment)(lzma_vli id, const void *options);
131 uint32_t (*output_alignment)(lzma_vli id, const void *options);
132 bool changes_uncompressed_size;
143 extern void *lzma_alloc(size_t size, lzma_allocator *allocator)
144 lzma_attribute((malloc));
147 extern void lzma_free(void *ptr, lzma_allocator *allocator);
149 /// Initializes lzma_stream FIXME desc
150 extern lzma_ret lzma_strm_init(lzma_stream *strm);
153 extern lzma_ret lzma_next_filter_init(lzma_next_coder *next,
154 lzma_allocator *allocator, const lzma_filter_info *filters);
157 extern void lzma_next_coder_end(lzma_next_coder *next,
158 lzma_allocator *allocator);
161 extern lzma_ret lzma_filter_flags_decoder_init(lzma_next_coder *next,
162 lzma_allocator *allocator, lzma_options_filter *options);
164 extern lzma_ret lzma_block_header_decoder_init(lzma_next_coder *next,
165 lzma_allocator *allocator, lzma_options_block *options);
167 extern lzma_ret lzma_stream_encoder_single_init(lzma_next_coder *next,
168 lzma_allocator *allocator, const lzma_options_stream *options);
170 extern lzma_ret lzma_stream_decoder_init(
171 lzma_next_coder *next, lzma_allocator *allocator,
172 lzma_extra **header, lzma_extra **footer);
175 /// \brief Wrapper for memcpy()
177 /// This function copies as much data as possible from in[] to out[] and
178 /// updates *in_pos and *out_pos accordingly.
181 bufcpy(const uint8_t *restrict in, size_t *restrict in_pos, size_t in_size,
182 uint8_t *restrict out, size_t *restrict out_pos,
185 const size_t in_avail = in_size - *in_pos;
186 const size_t out_avail = out_size - *out_pos;
187 const size_t copy_size = MIN(in_avail, out_avail);
189 memcpy(out + *out_pos, in + *in_pos, copy_size);
191 *in_pos += copy_size;
192 *out_pos += copy_size;
198 /// \brief Initializing the next coder
200 /// lzma_next_coder can point to different types of coders. The existing
201 /// coder may be different than what we are initializing now. In that case
202 /// we must git rid of the old coder first. Otherwise we reuse the existing
205 #define lzma_next_coder_init2(next, allocator, cmpfunc, func, ...) \
207 if ((uintptr_t)(&cmpfunc) != (next)->init) \
208 lzma_next_coder_end(next, allocator); \
209 const lzma_ret ret = func(next, __VA_ARGS__); \
210 if (ret == LZMA_OK) { \
211 (next)->init = (uintptr_t)(&cmpfunc); \
212 assert((next)->code != NULL); \
213 assert((next)->end != NULL); \
215 lzma_next_coder_end(next, allocator); \
220 /// \brief Initializing lzma_next_coder
222 /// Call the initialization function, which must take at least one
223 /// argument in addition to lzma_next_coder and lzma_allocator.
224 #define lzma_next_coder_init(func, next, allocator, ...) \
225 lzma_next_coder_init2(next, allocator, \
226 func, func, allocator, __VA_ARGS__)
229 /// \brief Initializing lzma_stream
231 /// lzma_strm initialization with more detailed options.
232 #define lzma_next_strm_init2(strm, cmpfunc, func, ...) \
234 lzma_ret ret = lzma_strm_init(strm); \
235 if (ret != LZMA_OK) \
237 if ((uintptr_t)(&cmpfunc) != (strm)->internal->next.init) \
238 lzma_next_coder_end(\
239 &(strm)->internal->next, (strm)->allocator); \
240 ret = func(&(strm)->internal->next, __VA_ARGS__); \
241 if (ret != LZMA_OK) { \
245 (strm)->internal->next.init = (uintptr_t)(&cmpfunc); \
246 assert((strm)->internal->next.code != NULL); \
247 assert((strm)->internal->next.end != NULL); \
250 /// \brief Initializing lzma_stream
252 /// Call the initialization function, which must take at least one
253 /// argument in addition to lzma_next_coder and lzma_allocator.
254 #define lzma_next_strm_init(strm, func, ...) \
255 lzma_next_strm_init2(strm, func, func, (strm)->allocator, __VA_ARGS__)
258 /// \brief Return if expression doesn't evaluate to LZMA_OK
260 /// There are several situations where we want to return immediatelly
261 /// with the value of expr if it isn't LZMA_OK. This macro shortens
264 #define return_if_error(expr) \
266 const lzma_ret ret_ = expr; \
267 if (ret_ != LZMA_OK) \