Rizin
unix-like reverse engineering framework and cli tools
lz_encoder.c
Go to the documentation of this file.
1 //
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 //
13 
14 #include "lz_encoder.h"
15 #include "lz_encoder_hash.h"
16 
17 // See lz_encoder_hash.h. This is a bit hackish but avoids making
18 // endianness a conditional in makefiles.
19 #if defined(WORDS_BIGENDIAN) && !defined(HAVE_SMALL)
20 # include "lz_encoder_hash_table.h"
21 #endif
22 
23 #include "memcmplen.h"
24 
25 
26 typedef struct {
29 
32 
34  lzma_next_coder next;
35 } lzma_coder;
36 
37 
45 static void
47 {
48  // Align the move to a multiple of 16 bytes. Some LZ-based encoders
49  // like LZMA use the lowest bits of mf->read_pos to know the
50  // alignment of the uncompressed data. We also get better speed
51  // for memmove() with aligned buffers.
52  assert(mf->read_pos > mf->keep_size_before);
53  const uint32_t move_offset
54  = (mf->read_pos - mf->keep_size_before) & ~UINT32_C(15);
55 
56  assert(mf->write_pos > move_offset);
57  const size_t move_size = mf->write_pos - move_offset;
58 
59  assert(move_offset + move_size <= mf->size);
60 
61  memmove(mf->buffer, mf->buffer + move_offset, move_size);
62 
63  mf->offset += move_offset;
64  mf->read_pos -= move_offset;
65  mf->read_limit -= move_offset;
66  mf->write_pos -= move_offset;
67 
68  return;
69 }
70 
71 
80 static lzma_ret
82  const uint8_t *in, size_t *in_pos, size_t in_size,
84 {
85  assert(coder->mf.read_pos <= coder->mf.write_pos);
86 
87  // Move the sliding window if needed.
88  if (coder->mf.read_pos >= coder->mf.size - coder->mf.keep_size_after)
89  move_window(&coder->mf);
90 
91  // Maybe this is ugly, but lzma_mf uses uint32_t for most things
92  // (which I find cleanest), but we need size_t here when filling
93  // the history window.
94  size_t write_pos = coder->mf.write_pos;
95  lzma_ret ret;
96  if (coder->next.code == NULL) {
97  // Not using a filter, simply memcpy() as much as possible.
99  &write_pos, coder->mf.size);
100 
101  ret = action != LZMA_RUN && *in_pos == in_size
103 
104  } else {
105  ret = coder->next.code(coder->next.coder, allocator,
106  in, in_pos, in_size,
107  coder->mf.buffer, &write_pos,
108  coder->mf.size, action);
109  }
110 
111  coder->mf.write_pos = write_pos;
112 
113  // Silence Valgrind. lzma_memcmplen() can read extra bytes
114  // and Valgrind will give warnings if those bytes are uninitialized
115  // because Valgrind cannot see that the values of the uninitialized
116  // bytes are eventually ignored.
117  memzero(coder->mf.buffer + write_pos, LZMA_MEMCMPLEN_EXTRA);
118 
119  // If end of stream has been reached or flushing completed, we allow
120  // the encoder to process all the input (that is, read_pos is allowed
121  // to reach write_pos). Otherwise we keep keep_size_after bytes
122  // available as prebuffer.
123  if (ret == LZMA_STREAM_END) {
124  assert(*in_pos == in_size);
125  ret = LZMA_OK;
126  coder->mf.action = action;
127  coder->mf.read_limit = coder->mf.write_pos;
128 
129  } else if (coder->mf.write_pos > coder->mf.keep_size_after) {
130  // This needs to be done conditionally, because if we got
131  // only little new input, there may be too little input
132  // to do any encoding yet.
133  coder->mf.read_limit = coder->mf.write_pos
134  - coder->mf.keep_size_after;
135  }
136 
137  // Restart the match finder after finished LZMA_SYNC_FLUSH.
138  if (coder->mf.pending > 0
139  && coder->mf.read_pos < coder->mf.read_limit) {
140  // Match finder may update coder->pending and expects it to
141  // start from zero, so use a temporary variable.
142  const uint32_t pending = coder->mf.pending;
143  coder->mf.pending = 0;
144 
145  // Rewind read_pos so that the match finder can hash
146  // the pending bytes.
147  assert(coder->mf.read_pos >= pending);
148  coder->mf.read_pos -= pending;
149 
150  // Call the skip function directly instead of using
151  // mf_skip(), since we don't want to touch mf->read_ahead.
152  coder->mf.skip(&coder->mf, pending);
153  }
154 
155  return ret;
156 }
157 
158 
159 static lzma_ret
160 lz_encode(void *coder_ptr, const lzma_allocator *allocator,
161  const uint8_t *restrict in, size_t *restrict in_pos,
162  size_t in_size,
163  uint8_t *restrict out, size_t *restrict out_pos,
164  size_t out_size, lzma_action action)
165 {
166  lzma_coder *coder = coder_ptr;
167 
168  while (*out_pos < out_size
169  && (*in_pos < in_size || action != LZMA_RUN)) {
170  // Read more data to coder->mf.buffer if needed.
171  if (coder->mf.action == LZMA_RUN && coder->mf.read_pos
172  >= coder->mf.read_limit)
174  in, in_pos, in_size, action));
175 
176  // Encode
177  const lzma_ret ret = coder->lz.code(coder->lz.coder,
178  &coder->mf, out, out_pos, out_size);
179  if (ret != LZMA_OK) {
180  // Setting this to LZMA_RUN for cases when we are
181  // flushing. It doesn't matter when finishing or if
182  // an error occurred.
183  coder->mf.action = LZMA_RUN;
184  return ret;
185  }
186  }
187 
188  return LZMA_OK;
189 }
190 
191 
192 static bool
194  const lzma_lz_options *lz_options)
195 {
196  // For now, the dictionary size is limited to 1.5 GiB. This may grow
197  // in the future if needed, but it needs a little more work than just
198  // changing this check.
199  if (lz_options->dict_size < LZMA_DICT_SIZE_MIN
200  || lz_options->dict_size
201  > (UINT32_C(1) << 30) + (UINT32_C(1) << 29)
202  || lz_options->nice_len > lz_options->match_len_max)
203  return true;
204 
205  mf->keep_size_before = lz_options->before_size + lz_options->dict_size;
206 
207  mf->keep_size_after = lz_options->after_size
208  + lz_options->match_len_max;
209 
210  // To avoid constant memmove()s, allocate some extra space. Since
211  // memmove()s become more expensive when the size of the buffer
212  // increases, we reserve more space when a large dictionary is
213  // used to make the memmove() calls rarer.
214  //
215  // This works with dictionaries up to about 3 GiB. If bigger
216  // dictionary is wanted, some extra work is needed:
217  // - Several variables in lzma_mf have to be changed from uint32_t
218  // to size_t.
219  // - Memory usage calculation needs something too, e.g. use uint64_t
220  // for mf->size.
221  uint32_t reserve = lz_options->dict_size / 2;
222  if (reserve > (UINT32_C(1) << 30))
223  reserve /= 2;
224 
225  reserve += (lz_options->before_size + lz_options->match_len_max
226  + lz_options->after_size) / 2 + (UINT32_C(1) << 19);
227 
228  const uint32_t old_size = mf->size;
229  mf->size = mf->keep_size_before + reserve + mf->keep_size_after;
230 
231  // Deallocate the old history buffer if it exists but has different
232  // size than what is needed now.
233  if (mf->buffer != NULL && old_size != mf->size) {
234  lzma_free(mf->buffer, allocator);
235  mf->buffer = NULL;
236  }
237 
238  // Match finder options
239  mf->match_len_max = lz_options->match_len_max;
240  mf->nice_len = lz_options->nice_len;
241 
242  // cyclic_size has to stay smaller than 2 Gi. Note that this doesn't
243  // mean limiting dictionary size to less than 2 GiB. With a match
244  // finder that uses multibyte resolution (hashes start at e.g. every
245  // fourth byte), cyclic_size would stay below 2 Gi even when
246  // dictionary size is greater than 2 GiB.
247  //
248  // It would be possible to allow cyclic_size >= 2 Gi, but then we
249  // would need to be careful to use 64-bit types in various places
250  // (size_t could do since we would need bigger than 32-bit address
251  // space anyway). It would also require either zeroing a multigigabyte
252  // buffer at initialization (waste of time and RAM) or allow
253  // normalization in lz_encoder_mf.c to access uninitialized
254  // memory to keep the code simpler. The current way is simple and
255  // still allows pretty big dictionaries, so I don't expect these
256  // limits to change.
257  mf->cyclic_size = lz_options->dict_size + 1;
258 
259  // Validate the match finder ID and setup the function pointers.
260  switch (lz_options->match_finder) {
261 #ifdef HAVE_MF_HC3
262  case LZMA_MF_HC3:
263  mf->find = &lzma_mf_hc3_find;
264  mf->skip = &lzma_mf_hc3_skip;
265  break;
266 #endif
267 #ifdef HAVE_MF_HC4
268  case LZMA_MF_HC4:
269  mf->find = &lzma_mf_hc4_find;
270  mf->skip = &lzma_mf_hc4_skip;
271  break;
272 #endif
273 #ifdef HAVE_MF_BT2
274  case LZMA_MF_BT2:
275  mf->find = &lzma_mf_bt2_find;
276  mf->skip = &lzma_mf_bt2_skip;
277  break;
278 #endif
279 #ifdef HAVE_MF_BT3
280  case LZMA_MF_BT3:
281  mf->find = &lzma_mf_bt3_find;
282  mf->skip = &lzma_mf_bt3_skip;
283  break;
284 #endif
285 #ifdef HAVE_MF_BT4
286  case LZMA_MF_BT4:
287  mf->find = &lzma_mf_bt4_find;
288  mf->skip = &lzma_mf_bt4_skip;
289  break;
290 #endif
291 
292  default:
293  return true;
294  }
295 
296  // Calculate the sizes of mf->hash and mf->son and check that
297  // nice_len is big enough for the selected match finder.
298  const uint32_t hash_bytes = lz_options->match_finder & 0x0F;
299  if (hash_bytes > mf->nice_len)
300  return true;
301 
302  const bool is_bt = (lz_options->match_finder & 0x10) != 0;
303  uint32_t hs;
304 
305  if (hash_bytes == 2) {
306  hs = 0xFFFF;
307  } else {
308  // Round dictionary size up to the next 2^n - 1 so it can
309  // be used as a hash mask.
310  hs = lz_options->dict_size - 1;
311  hs |= hs >> 1;
312  hs |= hs >> 2;
313  hs |= hs >> 4;
314  hs |= hs >> 8;
315  hs >>= 1;
316  hs |= 0xFFFF;
317 
318  if (hs > (UINT32_C(1) << 24)) {
319  if (hash_bytes == 3)
320  hs = (UINT32_C(1) << 24) - 1;
321  else
322  hs >>= 1;
323  }
324  }
325 
326  mf->hash_mask = hs;
327 
328  ++hs;
329  if (hash_bytes > 2)
330  hs += HASH_2_SIZE;
331  if (hash_bytes > 3)
332  hs += HASH_3_SIZE;
333 /*
334  No match finder uses this at the moment.
335  if (mf->hash_bytes > 4)
336  hs += HASH_4_SIZE;
337 */
338 
339  const uint32_t old_hash_count = mf->hash_count;
340  const uint32_t old_sons_count = mf->sons_count;
341  mf->hash_count = hs;
342  mf->sons_count = mf->cyclic_size;
343  if (is_bt)
344  mf->sons_count *= 2;
345 
346  // Deallocate the old hash array if it exists and has different size
347  // than what is needed now.
348  if (old_hash_count != mf->hash_count
349  || old_sons_count != mf->sons_count) {
350  lzma_free(mf->hash, allocator);
351  mf->hash = NULL;
352 
353  lzma_free(mf->son, allocator);
354  mf->son = NULL;
355  }
356 
357  // Maximum number of match finder cycles
358  mf->depth = lz_options->depth;
359  if (mf->depth == 0) {
360  if (is_bt)
361  mf->depth = 16 + mf->nice_len / 2;
362  else
363  mf->depth = 4 + mf->nice_len / 4;
364  }
365 
366  return false;
367 }
368 
369 
370 static bool
372  const lzma_lz_options *lz_options)
373 {
374  // Allocate the history buffer.
375  if (mf->buffer == NULL) {
376  // lzma_memcmplen() is used for the dictionary buffer
377  // so we need to allocate a few extra bytes to prevent
378  // it from reading past the end of the buffer.
380  allocator);
381  if (mf->buffer == NULL)
382  return true;
383 
384  // Keep Valgrind happy with lzma_memcmplen() and initialize
385  // the extra bytes whose value may get read but which will
386  // effectively get ignored.
388  }
389 
390  // Use cyclic_size as initial mf->offset. This allows
391  // avoiding a few branches in the match finders. The downside is
392  // that match finder needs to be normalized more often, which may
393  // hurt performance with huge dictionaries.
394  mf->offset = mf->cyclic_size;
395  mf->read_pos = 0;
396  mf->read_ahead = 0;
397  mf->read_limit = 0;
398  mf->write_pos = 0;
399  mf->pending = 0;
400 
401 #if UINT32_MAX >= SIZE_MAX / 4
402  // Check for integer overflow. (Huge dictionaries are not
403  // possible on 32-bit CPU.)
404  if (mf->hash_count > SIZE_MAX / sizeof(uint32_t)
405  || mf->sons_count > SIZE_MAX / sizeof(uint32_t))
406  return true;
407 #endif
408 
409  // Allocate and initialize the hash table. Since EMPTY_HASH_VALUE
410  // is zero, we can use lzma_alloc_zero() or memzero() for mf->hash.
411  //
412  // We don't need to initialize mf->son, but not doing that may
413  // make Valgrind complain in normalization (see normalize() in
414  // lz_encoder_mf.c). Skipping the initialization is *very* good
415  // when big dictionary is used but only small amount of data gets
416  // actually compressed: most of the mf->son won't get actually
417  // allocated by the kernel, so we avoid wasting RAM and improve
418  // initialization speed a lot.
419  if (mf->hash == NULL) {
420  mf->hash = lzma_alloc_zero(mf->hash_count * sizeof(uint32_t),
421  allocator);
422  mf->son = lzma_alloc(mf->sons_count * sizeof(uint32_t),
423  allocator);
424 
425  if (mf->hash == NULL || mf->son == NULL) {
426  lzma_free(mf->hash, allocator);
427  mf->hash = NULL;
428 
429  lzma_free(mf->son, allocator);
430  mf->son = NULL;
431 
432  return true;
433  }
434  } else {
435 /*
436  for (uint32_t i = 0; i < mf->hash_count; ++i)
437  mf->hash[i] = EMPTY_HASH_VALUE;
438 */
439  memzero(mf->hash, mf->hash_count * sizeof(uint32_t));
440  }
441 
442  mf->cyclic_pos = 0;
443 
444  // Handle preset dictionary.
445  if (lz_options->preset_dict != NULL
446  && lz_options->preset_dict_size > 0) {
447  // If the preset dictionary is bigger than the actual
448  // dictionary, use only the tail.
449  mf->write_pos = my_min(lz_options->preset_dict_size, mf->size);
450  memcpy(mf->buffer, lz_options->preset_dict
451  + lz_options->preset_dict_size - mf->write_pos,
452  mf->write_pos);
453  mf->action = LZMA_SYNC_FLUSH;
454  mf->skip(mf, mf->write_pos);
455  }
456 
457  mf->action = LZMA_RUN;
458 
459  return false;
460 }
461 
462 
463 extern uint64_t
465 {
466  // Old buffers must not exist when calling lz_encoder_prepare().
467  lzma_mf mf = {
468  .buffer = NULL,
469  .hash = NULL,
470  .son = NULL,
471  .hash_count = 0,
472  .sons_count = 0,
473  };
474 
475  // Setup the size information into mf.
476  if (lz_encoder_prepare(&mf, NULL, lz_options))
477  return UINT64_MAX;
478 
479  // Calculate the memory usage.
480  return ((uint64_t)(mf.hash_count) + mf.sons_count) * sizeof(uint32_t)
481  + mf.size + sizeof(lzma_coder);
482 }
483 
484 
485 static void
486 lz_encoder_end(void *coder_ptr, const lzma_allocator *allocator)
487 {
488  lzma_coder *coder = coder_ptr;
489 
490  lzma_next_end(&coder->next, allocator);
491 
492  lzma_free(coder->mf.son, allocator);
493  lzma_free(coder->mf.hash, allocator);
494  lzma_free(coder->mf.buffer, allocator);
495 
496  if (coder->lz.end != NULL)
497  coder->lz.end(coder->lz.coder, allocator);
498  else
499  lzma_free(coder->lz.coder, allocator);
500 
501  lzma_free(coder, allocator);
502  return;
503 }
504 
505 
506 static lzma_ret
508  const lzma_filter *filters_null lzma_attribute((__unused__)),
509  const lzma_filter *reversed_filters)
510 {
511  lzma_coder *coder = coder_ptr;
512 
513  if (coder->lz.options_update == NULL)
514  return LZMA_PROG_ERROR;
515 
516  return_if_error(coder->lz.options_update(
517  coder->lz.coder, reversed_filters));
518 
520  &coder->next, allocator, reversed_filters + 1);
521 }
522 
523 
524 extern lzma_ret
526  const lzma_filter_info *filters,
527  lzma_ret (*lz_init)(lzma_lz_encoder *lz,
528  const lzma_allocator *allocator, const void *options,
529  lzma_lz_options *lz_options))
530 {
531 #ifdef HAVE_SMALL
532  // We need that the CRC32 table has been initialized.
533  lzma_crc32_init();
534 #endif
535 
536  // Allocate and initialize the base data structure.
537  lzma_coder *coder = next->coder;
538  if (coder == NULL) {
539  coder = lzma_alloc(sizeof(lzma_coder), allocator);
540  if (coder == NULL)
541  return LZMA_MEM_ERROR;
542 
543  next->coder = coder;
544  next->code = &lz_encode;
545  next->end = &lz_encoder_end;
546  next->update = &lz_encoder_update;
547 
548  coder->lz.coder = NULL;
549  coder->lz.code = NULL;
550  coder->lz.end = NULL;
551 
552  // mf.size is initialized to silence Valgrind
553  // when used on optimized binaries (GCC may reorder
554  // code in a way that Valgrind gets unhappy).
555  coder->mf.buffer = NULL;
556  coder->mf.size = 0;
557  coder->mf.hash = NULL;
558  coder->mf.son = NULL;
559  coder->mf.hash_count = 0;
560  coder->mf.sons_count = 0;
561 
562  coder->next = LZMA_NEXT_CODER_INIT;
563  }
564 
565  // Initialize the LZ-based encoder.
566  lzma_lz_options lz_options;
567  return_if_error(lz_init(&coder->lz, allocator,
568  filters[0].options, &lz_options));
569 
570  // Setup the size information into coder->mf and deallocate
571  // old buffers if they have wrong size.
572  if (lz_encoder_prepare(&coder->mf, allocator, &lz_options))
573  return LZMA_OPTIONS_ERROR;
574 
575  // Allocate new buffers if needed, and do the rest of
576  // the initialization.
577  if (lz_encoder_init(&coder->mf, allocator, &lz_options))
578  return LZMA_MEM_ERROR;
579 
580  // Initialize the next filter in the chain, if any.
581  return lzma_next_filter_init(&coder->next, allocator, filters + 1);
582 }
583 
584 
586 lzma_mf_is_supported(lzma_match_finder mf)
587 {
588  bool ret = false;
589 
590 #ifdef HAVE_MF_HC3
591  if (mf == LZMA_MF_HC3)
592  ret = true;
593 #endif
594 
595 #ifdef HAVE_MF_HC4
596  if (mf == LZMA_MF_HC4)
597  ret = true;
598 #endif
599 
600 #ifdef HAVE_MF_BT2
601  if (mf == LZMA_MF_BT2)
602  ret = true;
603 #endif
604 
605 #ifdef HAVE_MF_BT3
606  if (mf == LZMA_MF_BT3)
607  ret = true;
608 #endif
609 
610 #ifdef HAVE_MF_BT4
611  if (mf == LZMA_MF_BT4)
612  ret = true;
613 #endif
614 
615  return ret;
616 }
const lzma_allocator const uint8_t size_t uint8_t size_t * out_pos
Definition: block.h:528
const lzma_allocator const uint8_t size_t * in_pos
Definition: block.h:579
const lzma_allocator const uint8_t size_t in_size
Definition: block.h:527
const lzma_allocator * allocator
Definition: block.h:377
const lzma_allocator const uint8_t * in
Definition: block.h:527
const lzma_allocator const uint8_t size_t uint8_t * out
Definition: block.h:528
const lzma_filter * filters
Definition: container.h:315
void lzma_crc32_init(void)
Definition: crc32_small.c:41
#define NULL
Definition: cris-opc.c:27
voidpf void uLong size
Definition: ioapi.h:138
#define restrict
memcpy(mem, inblock.get(), min(CONTAINING_RECORD(inblock.get(), MEMBLOCK, data) ->size, size))
static const char struct stat static buf struct stat static buf static vhangup int options
Definition: sflib.h:145
static void move_window(lzma_mf *mf)
Moves the data in the input window to free space for new data.
Definition: lz_encoder.c:46
LZMA_API(lzma_bool)
Definition: lz_encoder.c:585
static lzma_ret lz_encoder_update(void *coder_ptr, const lzma_allocator *allocator, const lzma_filter *filters_null lzma_attribute((__unused__)), const lzma_filter *reversed_filters)
Definition: lz_encoder.c:507
static lzma_ret lz_encode(void *coder_ptr, const lzma_allocator *allocator, const uint8_t *restrict in, size_t *restrict in_pos, size_t in_size, uint8_t *restrict out, size_t *restrict out_pos, size_t out_size, lzma_action action)
Definition: lz_encoder.c:160
static void lz_encoder_end(void *coder_ptr, const lzma_allocator *allocator)
Definition: lz_encoder.c:486
uint64_t lzma_lz_encoder_memusage(const lzma_lz_options *lz_options)
Definition: lz_encoder.c:464
static bool lz_encoder_init(lzma_mf *mf, const lzma_allocator *allocator, const lzma_lz_options *lz_options)
Definition: lz_encoder.c:371
static bool lz_encoder_prepare(lzma_mf *mf, const lzma_allocator *allocator, const lzma_lz_options *lz_options)
Definition: lz_encoder.c:193
lzma_ret lzma_lz_encoder_init(lzma_next_coder *next, const lzma_allocator *allocator, const lzma_filter_info *filters, lzma_ret(*lz_init)(lzma_lz_encoder *lz, const lzma_allocator *allocator, const void *options, lzma_lz_options *lz_options))
Definition: lz_encoder.c:525
static lzma_ret fill_window(lzma_coder *coder, const lzma_allocator *allocator, const uint8_t *in, size_t *in_pos, size_t in_size, lzma_action action)
Tries to fill the input window (mf->buffer)
Definition: lz_encoder.c:81
LZ in window and match finder API.
void lzma_mf_hc4_skip(lzma_mf *dict, uint32_t amount)
uint32_t lzma_mf_hc3_find(lzma_mf *dict, lzma_match *matches)
uint32_t lzma_mf_bt2_find(lzma_mf *dict, lzma_match *matches)
uint32_t lzma_mf_bt3_find(lzma_mf *dict, lzma_match *matches)
uint32_t lzma_mf_bt4_find(lzma_mf *dict, lzma_match *matches)
void lzma_mf_bt2_skip(lzma_mf *dict, uint32_t amount)
void lzma_mf_bt3_skip(lzma_mf *dict, uint32_t amount)
void lzma_mf_hc3_skip(lzma_mf *dict, uint32_t amount)
void lzma_mf_bt4_skip(lzma_mf *dict, uint32_t amount)
uint32_t lzma_mf_hc4_find(lzma_mf *dict, lzma_match *matches)
Hash macros for match finders.
#define HASH_2_SIZE
#define HASH_3_SIZE
#define LZMA_DICT_SIZE_MIN
Definition: lzma12.h:218
lzma_match_finder
Match finders.
Definition: lzma12.h:58
@ LZMA_MF_HC4
Hash Chain with 2-, 3-, and 4-byte hashing.
Definition: lzma12.h:70
@ LZMA_MF_BT4
Binary Tree with 2-, 3-, and 4-byte hashing.
Definition: lzma12.h:101
@ LZMA_MF_HC3
Hash Chain with 2- and 3-byte hashing.
Definition: lzma12.h:59
@ LZMA_MF_BT2
Binary Tree with 2-byte hashing.
Definition: lzma12.h:81
@ LZMA_MF_BT3
Binary Tree with 2- and 3-byte hashing.
Definition: lzma12.h:90
#define lzma_attribute(attr)
Definition: lzma.h:259
Optimized comparison of two buffers.
assert(limit<=UINT32_MAX/2)
#define LZMA_MEMCMPLEN_EXTRA
Definition: memcmplen.h:156
unsigned int uint32_t
Definition: sftypes.h:29
unsigned long uint64_t
Definition: sftypes.h:28
unsigned char uint8_t
Definition: sftypes.h:31
#define UINT32_C(val)
#define UINT64_MAX
#define SIZE_MAX
Custom functions for memory handling.
Definition: base.h:372
lzma_lz_encoder lz
LZ-based encoder e.g. LZMA.
Definition: lz_encoder.c:28
lzma_next_coder next
Next coder in the chain.
Definition: lz_decoder.c:33
lzma_lz_decoder lz
The actual LZ-based decoder e.g. LZMA.
Definition: lz_decoder.c:28
lzma_mf mf
History buffer and match finder.
Definition: lz_encoder.c:31
Filter options.
Definition: filter.h:43
void * options
Pointer to filter-specific options structure.
Definition: filter.h:63
void * coder
Data specific to the LZ-based decoder.
Definition: lz_decoder.h:56
void(* end)(void *coder, const lzma_allocator *allocator)
Free allocated resources.
Definition: lz_decoder.h:69
lzma_ret(* code)(void *coder, lzma_dict *restrict dict, const uint8_t *restrict in, size_t *restrict in_pos, size_t in_size)
Function to decode from in[] to *dict.
Definition: lz_decoder.h:59
const uint8_t * preset_dict
TODO: Comment.
Definition: lz_decoder.h:49
size_t after_size
Definition: lz_encoder.h:139
size_t preset_dict_size
Definition: lz_decoder.h:50
size_t match_len_max
Definition: lz_encoder.h:144
uint32_t depth
Maximum search depth.
Definition: lz_encoder.h:154
size_t dict_size
Size of the history buffer.
Definition: lz_decoder.h:48
size_t before_size
Definition: lz_encoder.h:132
lzma_match_finder match_finder
Type of the match finder to use.
Definition: lz_encoder.h:151
uint32_t hash_count
Number of elements in hash[].
Definition: lz_encoder.h:122
uint32_t read_pos
Definition: lz_encoder.h:63
uint32_t offset
Definition: lz_encoder.h:58
uint32_t cyclic_size
Definition: lz_encoder.h:102
uint8_t * buffer
Pointer to buffer with data to be compressed.
Definition: lz_encoder.h:35
uint32_t hash_mask
Definition: lz_encoder.h:103
lzma_action action
Definition: lz_encoder.h:119
uint32_t * son
Definition: lz_encoder.h:100
uint32_t depth
Maximum number of loops in the match finder.
Definition: lz_encoder.h:106
uint32_t match_len_max
Definition: lz_encoder.h:114
uint32_t cyclic_pos
Definition: lz_encoder.h:101
uint32_t keep_size_after
Definition: lz_encoder.h:51
uint32_t(* find)(lzma_mf *mf, lzma_match *matches)
Definition: lz_encoder.h:92
uint32_t read_limit
Definition: lz_encoder.h:75
uint32_t nice_len
Maximum length of a match that the match finder will try to find.
Definition: lz_encoder.h:109
uint32_t * hash
Definition: lz_encoder.h:99
uint32_t read_ahead
Definition: lz_encoder.h:67
uint32_t sons_count
Number of elements in son[].
Definition: lz_encoder.h:125
void(* skip)(lzma_mf *mf, uint32_t num)
Definition: lz_encoder.h:97
uint32_t keep_size_before
Definition: lz_encoder.h:45
uint32_t pending
Definition: lz_encoder.h:84
uint32_t write_pos
Definition: lz_encoder.h:80
uint32_t size
Definition: lz_encoder.h:39
Hold data and function pointers of the next filter in the chain.
Definition: common.h:135
lzma_code_function code
Pointer to function to do the actual coding.
Definition: common.h:150
void * coder
Pointer to coder-specific data.
Definition: common.h:137
lzma_end_function end
Definition: common.h:155
lzma_ret(* update)(void *coder, const lzma_allocator *allocator, const lzma_filter *filters, const lzma_filter *reversed_filters)
Definition: common.h:173
#define LZMA_NEXT_CODER_INIT
Macro to initialize lzma_next_coder structure.
Definition: common.h:180
#define return_if_error(expr)
Return if expression doesn't evaluate to LZMA_OK.
Definition: common.h:278
void * lzma_alloc(size_t size, const lzma_allocator *allocator) lzma_attribute((__malloc__)) lzma_attr_alloc_size(1)
Allocates memory.
#define my_min(x, y)
Definition: sysdefs.h:185
#define memzero(s, n)
Definition: sysdefs.h:180
lzma_ret
Return values used by several functions in liblzma.
Definition: base.h:57
@ LZMA_PROG_ERROR
Programming error.
Definition: base.h:218
@ LZMA_MEM_ERROR
Cannot allocate memory.
Definition: base.h:128
@ LZMA_STREAM_END
End of stream was reached.
Definition: base.h:63
@ LZMA_OPTIONS_ERROR
Invalid or unsupported options.
Definition: base.h:160
@ LZMA_OK
Operation completed successfully.
Definition: base.h:58
lzma_action
The ‘action’ argument for lzma_code()
Definition: base.h:250
@ LZMA_SYNC_FLUSH
Make all the input available at output.
Definition: base.h:265
@ LZMA_RUN
Continue coding.
Definition: base.h:251
unsigned char lzma_bool
Boolean.
Definition: base.h:29
lzma_ret lzma_next_filter_init(lzma_next_coder *next, const lzma_allocator *allocator, const lzma_filter_info *filters)
Definition: common.c:116
void lzma_free(void *ptr, const lzma_allocator *allocator)
Frees memory.
Definition: common.c:78
size_t lzma_bufcpy(const uint8_t *restrict in, size_t *restrict in_pos, size_t in_size, uint8_t *restrict out, size_t *restrict out_pos, size_t out_size)
Definition: common.c:94
lzma_ret lzma_next_filter_update(lzma_next_coder *next, const lzma_allocator *allocator, const lzma_filter *reversed_filters)
Definition: common.c:127
void lzma_next_end(lzma_next_coder *next, const lzma_allocator *allocator)
Definition: common.c:145