1 ///////////////////////////////////////////////////////////////////////////////
3 /// \file simple_coder.c
4 /// \brief Wrapper for simple filters
6 /// Simple filters don't change the size of the data i.e. number of bytes
7 /// in equals the number of bytes out.
9 // Author: Lasse Collin
11 // This file has been put into the public domain.
12 // You can do whatever you want with this file.
14 ///////////////////////////////////////////////////////////////////////////////
16 #include "simple_private.h"
19 /// Copied or encodes/decodes more data to out[].
21 copy_or_code(lzma_simple_coder
*coder
, const lzma_allocator
*allocator
,
22 const uint8_t *restrict in
, size_t *restrict in_pos
,
23 size_t in_size
, uint8_t *restrict out
,
24 size_t *restrict out_pos
, size_t out_size
, lzma_action action
)
26 assert(!coder
->end_was_reached
);
28 if (coder
->next
.code
== NULL
) {
29 lzma_bufcpy(in
, in_pos
, in_size
, out
, out_pos
, out_size
);
31 // Check if end of stream was reached.
32 if (coder
->is_encoder
&& action
== LZMA_FINISH
33 && *in_pos
== in_size
)
34 coder
->end_was_reached
= true;
37 // Call the next coder in the chain to provide us some data.
38 const lzma_ret ret
= coder
->next
.code(
39 coder
->next
.coder
, allocator
,
41 out
, out_pos
, out_size
, action
);
43 if (ret
== LZMA_STREAM_END
) {
44 assert(!coder
->is_encoder
45 || action
== LZMA_FINISH
);
46 coder
->end_was_reached
= true;
48 } else if (ret
!= LZMA_OK
) {
58 call_filter(lzma_simple_coder
*coder
, uint8_t *buffer
, size_t size
)
60 const size_t filtered
= coder
->filter(coder
->simple
,
61 coder
->now_pos
, coder
->is_encoder
,
63 coder
->now_pos
+= filtered
;
69 simple_code(void *coder_ptr
, const lzma_allocator
*allocator
,
70 const uint8_t *restrict in
, size_t *restrict in_pos
,
71 size_t in_size
, uint8_t *restrict out
,
72 size_t *restrict out_pos
, size_t out_size
, lzma_action action
)
74 lzma_simple_coder
*coder
= coder_ptr
;
76 // TODO: Add partial support for LZMA_SYNC_FLUSH. We can support it
77 // in cases when the filter is able to filter everything. With most
78 // simple filters it can be done at offset that is a multiple of 2,
79 // 4, or 16. With x86 filter, it needs good luck, and thus cannot
80 // be made to work predictably.
81 if (action
== LZMA_SYNC_FLUSH
)
82 return LZMA_OPTIONS_ERROR
;
84 // Flush already filtered data from coder->buffer[] to out[].
85 if (coder
->pos
< coder
->filtered
) {
86 lzma_bufcpy(coder
->buffer
, &coder
->pos
, coder
->filtered
,
87 out
, out_pos
, out_size
);
89 // If we couldn't flush all the filtered data, return to
90 // application immediately.
91 if (coder
->pos
< coder
->filtered
)
94 if (coder
->end_was_reached
) {
95 assert(coder
->filtered
== coder
->size
);
96 return LZMA_STREAM_END
;
100 // If we get here, there is no filtered data left in the buffer.
103 assert(!coder
->end_was_reached
);
105 // If there is more output space left than there is unfiltered data
106 // in coder->buffer[], flush coder->buffer[] to out[], and copy/code
107 // more data to out[] hopefully filling it completely. Then filter
108 // the data in out[]. This step is where most of the data gets
109 // filtered if the buffer sizes used by the application are reasonable.
110 const size_t out_avail
= out_size
- *out_pos
;
111 const size_t buf_avail
= coder
->size
- coder
->pos
;
112 if (out_avail
> buf_avail
|| buf_avail
== 0) {
113 // Store the old position so that we know from which byte
114 // to start filtering.
115 const size_t out_start
= *out_pos
;
117 // Flush data from coder->buffer[] to out[], but don't reset
118 // coder->pos and coder->size yet. This way the coder can be
119 // restarted if the next filter in the chain returns e.g.
121 memcpy(out
+ *out_pos
, coder
->buffer
+ coder
->pos
, buf_avail
);
122 *out_pos
+= buf_avail
;
124 // Copy/Encode/Decode more data to out[].
126 const lzma_ret ret
= copy_or_code(coder
, allocator
,
128 out
, out_pos
, out_size
, action
);
129 assert(ret
!= LZMA_STREAM_END
);
135 const size_t size
= *out_pos
- out_start
;
136 const size_t filtered
= call_filter(
137 coder
, out
+ out_start
, size
);
139 const size_t unfiltered
= size
- filtered
;
140 assert(unfiltered
<= coder
->allocated
/ 2);
142 // Now we can update coder->pos and coder->size, because
143 // the next coder in the chain (if any) was successful.
145 coder
->size
= unfiltered
;
147 if (coder
->end_was_reached
) {
148 // The last byte has been copied to out[] already.
149 // They are left as is.
152 } else if (unfiltered
> 0) {
153 // There is unfiltered data left in out[]. Copy it to
154 // coder->buffer[] and rewind *out_pos appropriately.
155 *out_pos
-= unfiltered
;
156 memcpy(coder
->buffer
, out
+ *out_pos
, unfiltered
);
158 } else if (coder
->pos
> 0) {
159 memmove(coder
->buffer
, coder
->buffer
+ coder
->pos
, buf_avail
);
160 coder
->size
-= coder
->pos
;
164 assert(coder
->pos
== 0);
166 // If coder->buffer[] isn't empty, try to fill it by copying/decoding
167 // more data. Then filter coder->buffer[] and copy the successfully
168 // filtered data to out[]. It is probable, that some filtered and
169 // unfiltered data will be left to coder->buffer[].
170 if (coder
->size
> 0) {
172 const lzma_ret ret
= copy_or_code(coder
, allocator
,
174 coder
->buffer
, &coder
->size
,
175 coder
->allocated
, action
);
176 assert(ret
!= LZMA_STREAM_END
);
181 coder
->filtered
= call_filter(
182 coder
, coder
->buffer
, coder
->size
);
184 // Everything is considered to be filtered if coder->buffer[]
185 // contains the last bytes of the data.
186 if (coder
->end_was_reached
)
187 coder
->filtered
= coder
->size
;
189 // Flush as much as possible.
190 lzma_bufcpy(coder
->buffer
, &coder
->pos
, coder
->filtered
,
191 out
, out_pos
, out_size
);
194 // Check if we got everything done.
195 if (coder
->end_was_reached
&& coder
->pos
== coder
->size
)
196 return LZMA_STREAM_END
;
203 simple_coder_end(void *coder_ptr
, const lzma_allocator
*allocator
)
205 lzma_simple_coder
*coder
= coder_ptr
;
206 lzma_next_end(&coder
->next
, allocator
);
207 lzma_free(coder
->simple
, allocator
);
208 lzma_free(coder
, allocator
);
214 simple_coder_update(void *coder_ptr
, const lzma_allocator
*allocator
,
215 const lzma_filter
*filters_null
lzma_attribute((__unused__
)),
216 const lzma_filter
*reversed_filters
)
218 lzma_simple_coder
*coder
= coder_ptr
;
220 // No update support, just call the next filter in the chain.
221 return lzma_next_filter_update(
222 &coder
->next
, allocator
, reversed_filters
+ 1);
227 lzma_simple_coder_init(lzma_next_coder
*next
, const lzma_allocator
*allocator
,
228 const lzma_filter_info
*filters
,
229 size_t (*filter
)(void *simple
, uint32_t now_pos
,
230 bool is_encoder
, uint8_t *buffer
, size_t size
),
231 size_t simple_size
, size_t unfiltered_max
,
232 uint32_t alignment
, bool is_encoder
)
234 // Allocate memory for the lzma_simple_coder structure if needed.
235 lzma_simple_coder
*coder
= next
->coder
;
237 // Here we allocate space also for the temporary buffer. We
238 // need twice the size of unfiltered_max, because then it
239 // is always possible to filter at least unfiltered_max bytes
240 // more data in coder->buffer[] if it can be filled completely.
241 coder
= lzma_alloc(sizeof(lzma_simple_coder
)
242 + 2 * unfiltered_max
, allocator
);
244 return LZMA_MEM_ERROR
;
247 next
->code
= &simple_code
;
248 next
->end
= &simple_coder_end
;
249 next
->update
= &simple_coder_update
;
251 coder
->next
= LZMA_NEXT_CODER_INIT
;
252 coder
->filter
= filter
;
253 coder
->allocated
= 2 * unfiltered_max
;
255 // Allocate memory for filter-specific data structure.
256 if (simple_size
> 0) {
257 coder
->simple
= lzma_alloc(simple_size
, allocator
);
258 if (coder
->simple
== NULL
)
259 return LZMA_MEM_ERROR
;
261 coder
->simple
= NULL
;
265 if (filters
[0].options
!= NULL
) {
266 const lzma_options_bcj
*simple
= filters
[0].options
;
267 coder
->now_pos
= simple
->start_offset
;
268 if (coder
->now_pos
& (alignment
- 1))
269 return LZMA_OPTIONS_ERROR
;
275 coder
->is_encoder
= is_encoder
;
276 coder
->end_was_reached
= false;
281 return lzma_next_filter_init(&coder
->next
, allocator
, filters
+ 1);