Deleted Added
full compact
lzma2_encoder.c (292588) lzma2_encoder.c (312518)
1///////////////////////////////////////////////////////////////////////////////
2//
3/// \file lzma2_encoder.c
4/// \brief LZMA2 encoder
5///
6// Authors: Igor Pavlov
7// Lasse Collin
8//
9// This file has been put into the public domain.
10// You can do whatever you want with this file.
11//
12///////////////////////////////////////////////////////////////////////////////
13
14#include "lz_encoder.h"
15#include "lzma_encoder.h"
16#include "fastpos.h"
17#include "lzma2_encoder.h"
18
19
1///////////////////////////////////////////////////////////////////////////////
2//
3/// \file lzma2_encoder.c
4/// \brief LZMA2 encoder
5///
6// Authors: Igor Pavlov
7// Lasse Collin
8//
9// This file has been put into the public domain.
10// You can do whatever you want with this file.
11//
12///////////////////////////////////////////////////////////////////////////////
13
14#include "lz_encoder.h"
15#include "lzma_encoder.h"
16#include "fastpos.h"
17#include "lzma2_encoder.h"
18
19
20struct lzma_coder_s {
20typedef struct {
21 enum {
22 SEQ_INIT,
23 SEQ_LZMA_ENCODE,
24 SEQ_LZMA_COPY,
25 SEQ_UNCOMPRESSED_HEADER,
26 SEQ_UNCOMPRESSED_COPY,
27 } sequence;
28
29 /// LZMA encoder
21 enum {
22 SEQ_INIT,
23 SEQ_LZMA_ENCODE,
24 SEQ_LZMA_COPY,
25 SEQ_UNCOMPRESSED_HEADER,
26 SEQ_UNCOMPRESSED_COPY,
27 } sequence;
28
29 /// LZMA encoder
30 lzma_coder *lzma;
30 void *lzma;
31
32 /// LZMA options currently in use.
33 lzma_options_lzma opt_cur;
34
35 bool need_properties;
36 bool need_state_reset;
37 bool need_dictionary_reset;
38

--- 4 unchanged lines hidden (view full) ---

43 /// to indicate the end of buf[] in SEQ_LZMA_COPY.
44 size_t compressed_size;
45
46 /// Read position in buf[]
47 size_t buf_pos;
48
49 /// Buffer to hold the chunk header and LZMA compressed data
50 uint8_t buf[LZMA2_HEADER_MAX + LZMA2_CHUNK_MAX];
31
32 /// LZMA options currently in use.
33 lzma_options_lzma opt_cur;
34
35 bool need_properties;
36 bool need_state_reset;
37 bool need_dictionary_reset;
38

--- 4 unchanged lines hidden (view full) ---

43 /// to indicate the end of buf[] in SEQ_LZMA_COPY.
44 size_t compressed_size;
45
46 /// Read position in buf[]
47 size_t buf_pos;
48
49 /// Buffer to hold the chunk header and LZMA compressed data
50 uint8_t buf[LZMA2_HEADER_MAX + LZMA2_CHUNK_MAX];
51};
51} lzma_lzma2_coder;
52
53
54static void
52
53
54static void
55lzma2_header_lzma(lzma_coder *coder)
55lzma2_header_lzma(lzma_lzma2_coder *coder)
56{
57 assert(coder->uncompressed_size > 0);
58 assert(coder->uncompressed_size <= LZMA2_UNCOMPRESSED_MAX);
59 assert(coder->compressed_size > 0);
60 assert(coder->compressed_size <= LZMA2_CHUNK_MAX);
61
62 size_t pos;
63

--- 39 unchanged lines hidden (view full) ---

103 // of coder->buf[], so we need add the maximum size of the header here.
104 coder->compressed_size += LZMA2_HEADER_MAX;
105
106 return;
107}
108
109
110static void
56{
57 assert(coder->uncompressed_size > 0);
58 assert(coder->uncompressed_size <= LZMA2_UNCOMPRESSED_MAX);
59 assert(coder->compressed_size > 0);
60 assert(coder->compressed_size <= LZMA2_CHUNK_MAX);
61
62 size_t pos;
63

--- 39 unchanged lines hidden (view full) ---

103 // of coder->buf[], so we need add the maximum size of the header here.
104 coder->compressed_size += LZMA2_HEADER_MAX;
105
106 return;
107}
108
109
110static void
111lzma2_header_uncompressed(lzma_coder *coder)
111lzma2_header_uncompressed(lzma_lzma2_coder *coder)
112{
113 assert(coder->uncompressed_size > 0);
114 assert(coder->uncompressed_size <= LZMA2_CHUNK_MAX);
115
116 // If this is the first chunk, we need to include dictionary
117 // reset indicator.
118 if (coder->need_dictionary_reset)
119 coder->buf[0] = 1;

--- 8 unchanged lines hidden (view full) ---

128
129 // Set the start position for copying.
130 coder->buf_pos = 0;
131 return;
132}
133
134
135static lzma_ret
112{
113 assert(coder->uncompressed_size > 0);
114 assert(coder->uncompressed_size <= LZMA2_CHUNK_MAX);
115
116 // If this is the first chunk, we need to include dictionary
117 // reset indicator.
118 if (coder->need_dictionary_reset)
119 coder->buf[0] = 1;

--- 8 unchanged lines hidden (view full) ---

128
129 // Set the start position for copying.
130 coder->buf_pos = 0;
131 return;
132}
133
134
135static lzma_ret
136lzma2_encode(lzma_coder *restrict coder, lzma_mf *restrict mf,
136lzma2_encode(void *coder_ptr, lzma_mf *restrict mf,
137 uint8_t *restrict out, size_t *restrict out_pos,
138 size_t out_size)
139{
137 uint8_t *restrict out, size_t *restrict out_pos,
138 size_t out_size)
139{
140 lzma_lzma2_coder *restrict coder = coder_ptr;
141
140 while (*out_pos < out_size)
141 switch (coder->sequence) {
142 case SEQ_INIT:
143 // If there's no input left and we are flushing or finishing,
144 // don't start a new chunk.
145 if (mf_unencoded(mf) == 0) {
146 // Write end of payload marker if finishing.
147 if (mf->action == LZMA_FINISH)

--- 109 unchanged lines hidden (view full) ---

257 break;
258 }
259
260 return LZMA_OK;
261}
262
263
264static void
142 while (*out_pos < out_size)
143 switch (coder->sequence) {
144 case SEQ_INIT:
145 // If there's no input left and we are flushing or finishing,
146 // don't start a new chunk.
147 if (mf_unencoded(mf) == 0) {
148 // Write end of payload marker if finishing.
149 if (mf->action == LZMA_FINISH)

--- 109 unchanged lines hidden (view full) ---

259 break;
260 }
261
262 return LZMA_OK;
263}
264
265
266static void
265lzma2_encoder_end(lzma_coder *coder, const lzma_allocator *allocator)
267lzma2_encoder_end(void *coder_ptr, const lzma_allocator *allocator)
266{
268{
269 lzma_lzma2_coder *coder = coder_ptr;
267 lzma_free(coder->lzma, allocator);
268 lzma_free(coder, allocator);
269 return;
270}
271
272
273static lzma_ret
270 lzma_free(coder->lzma, allocator);
271 lzma_free(coder, allocator);
272 return;
273}
274
275
276static lzma_ret
274lzma2_encoder_options_update(lzma_coder *coder, const lzma_filter *filter)
277lzma2_encoder_options_update(void *coder_ptr, const lzma_filter *filter)
275{
278{
279 lzma_lzma2_coder *coder = coder_ptr;
280
276 // New options can be set only when there is no incomplete chunk.
277 // This is the case at the beginning of the raw stream and right
278 // after LZMA_SYNC_FLUSH.
279 if (filter->options == NULL || coder->sequence != SEQ_INIT)
280 return LZMA_PROG_ERROR;
281
282 // Look if there are new options. At least for now,
283 // only lc/lp/pb can be changed.

--- 21 unchanged lines hidden (view full) ---

305
306static lzma_ret
307lzma2_encoder_init(lzma_lz_encoder *lz, const lzma_allocator *allocator,
308 const void *options, lzma_lz_options *lz_options)
309{
310 if (options == NULL)
311 return LZMA_PROG_ERROR;
312
281 // New options can be set only when there is no incomplete chunk.
282 // This is the case at the beginning of the raw stream and right
283 // after LZMA_SYNC_FLUSH.
284 if (filter->options == NULL || coder->sequence != SEQ_INIT)
285 return LZMA_PROG_ERROR;
286
287 // Look if there are new options. At least for now,
288 // only lc/lp/pb can be changed.

--- 21 unchanged lines hidden (view full) ---

310
311static lzma_ret
312lzma2_encoder_init(lzma_lz_encoder *lz, const lzma_allocator *allocator,
313 const void *options, lzma_lz_options *lz_options)
314{
315 if (options == NULL)
316 return LZMA_PROG_ERROR;
317
313 if (lz->coder == NULL) {
314 lz->coder = lzma_alloc(sizeof(lzma_coder), allocator);
315 if (lz->coder == NULL)
318 lzma_lzma2_coder *coder = lz->coder;
319 if (coder == NULL) {
320 coder = lzma_alloc(sizeof(lzma_lzma2_coder), allocator);
321 if (coder == NULL)
316 return LZMA_MEM_ERROR;
317
322 return LZMA_MEM_ERROR;
323
324 lz->coder = coder;
318 lz->code = &lzma2_encode;
319 lz->end = &lzma2_encoder_end;
320 lz->options_update = &lzma2_encoder_options_update;
321
325 lz->code = &lzma2_encode;
326 lz->end = &lzma2_encoder_end;
327 lz->options_update = &lzma2_encoder_options_update;
328
322 lz->coder->lzma = NULL;
329 coder->lzma = NULL;
323 }
324
330 }
331
325 lz->coder->opt_cur = *(const lzma_options_lzma *)(options);
332 coder->opt_cur = *(const lzma_options_lzma *)(options);
326
333
327 lz->coder->sequence = SEQ_INIT;
328 lz->coder->need_properties = true;
329 lz->coder->need_state_reset = false;
330 lz->coder->need_dictionary_reset
331 = lz->coder->opt_cur.preset_dict == NULL
332 || lz->coder->opt_cur.preset_dict_size == 0;
334 coder->sequence = SEQ_INIT;
335 coder->need_properties = true;
336 coder->need_state_reset = false;
337 coder->need_dictionary_reset
338 = coder->opt_cur.preset_dict == NULL
339 || coder->opt_cur.preset_dict_size == 0;
333
334 // Initialize LZMA encoder
340
341 // Initialize LZMA encoder
335 return_if_error(lzma_lzma_encoder_create(&lz->coder->lzma, allocator,
336 &lz->coder->opt_cur, lz_options));
342 return_if_error(lzma_lzma_encoder_create(&coder->lzma, allocator,
343 &coder->opt_cur, lz_options));
337
338 // Make sure that we will always have enough history available in
339 // case we need to use uncompressed chunks. They are used when the
340 // compressed size of a chunk is not smaller than the uncompressed
341 // size, so we need to have at least LZMA2_COMPRESSED_MAX bytes
342 // history available.
343 if (lz_options->before_size + lz_options->dict_size < LZMA2_CHUNK_MAX)
344 lz_options->before_size

--- 14 unchanged lines hidden (view full) ---

359
360extern uint64_t
361lzma_lzma2_encoder_memusage(const void *options)
362{
363 const uint64_t lzma_mem = lzma_lzma_encoder_memusage(options);
364 if (lzma_mem == UINT64_MAX)
365 return UINT64_MAX;
366
344
345 // Make sure that we will always have enough history available in
346 // case we need to use uncompressed chunks. They are used when the
347 // compressed size of a chunk is not smaller than the uncompressed
348 // size, so we need to have at least LZMA2_COMPRESSED_MAX bytes
349 // history available.
350 if (lz_options->before_size + lz_options->dict_size < LZMA2_CHUNK_MAX)
351 lz_options->before_size

--- 14 unchanged lines hidden (view full) ---

366
367extern uint64_t
368lzma_lzma2_encoder_memusage(const void *options)
369{
370 const uint64_t lzma_mem = lzma_lzma_encoder_memusage(options);
371 if (lzma_mem == UINT64_MAX)
372 return UINT64_MAX;
373
367 return sizeof(lzma_coder) + lzma_mem;
374 return sizeof(lzma_lzma2_coder) + lzma_mem;
368}
369
370
371extern lzma_ret
372lzma_lzma2_props_encode(const void *options, uint8_t *out)
373{
374 const lzma_options_lzma *const opt = options;
375 uint32_t d = my_max(opt->dict_size, LZMA_DICT_SIZE_MIN);

--- 28 unchanged lines hidden ---
375}
376
377
378extern lzma_ret
379lzma_lzma2_props_encode(const void *options, uint8_t *out)
380{
381 const lzma_options_lzma *const opt = options;
382 uint32_t d = my_max(opt->dict_size, LZMA_DICT_SIZE_MIN);

--- 28 unchanged lines hidden ---