const u8 * const in_end = in_begin + in_nbytes;
struct xpress_item *next_chosen_item = c->chosen_items;
unsigned len_3_too_far;
+ u32 next_hashes[2] = {};
if (in_nbytes <= 8192)
len_3_too_far = 2048;
length = hc_matchfinder_longest_match(&c->hc_mf,
in_begin,
- in_next,
+ in_next - in_begin,
XPRESS_MIN_MATCH_LEN - 1,
in_end - in_next,
min(in_end - in_next, c->nice_match_length),
c->max_search_depth,
+ next_hashes,
&offset);
if (length >= XPRESS_MIN_MATCH_LEN &&
!(length == XPRESS_MIN_MATCH_LEN && offset >= len_3_too_far))
in_next += 1;
hc_matchfinder_skip_positions(&c->hc_mf,
in_begin,
- in_next,
- in_end,
- length - 1);
+ in_next - in_begin,
+ in_end - in_begin,
+ length - 1,
+ next_hashes);
in_next += length - 1;
} else {
/* No match found */
const u8 * const in_end = in_begin + in_nbytes;
struct xpress_item *next_chosen_item = c->chosen_items;
unsigned len_3_too_far;
+ u32 next_hashes[2] = {};
if (in_nbytes <= 8192)
len_3_too_far = 2048;
/* Find the longest match at the current position. */
cur_len = hc_matchfinder_longest_match(&c->hc_mf,
in_begin,
- in_next,
+ in_next - in_begin,
XPRESS_MIN_MATCH_LEN - 1,
in_end - in_next,
min(in_end - in_next, c->nice_match_length),
c->max_search_depth,
+ next_hashes,
&cur_offset);
in_next += 1;
hc_matchfinder_skip_positions(&c->hc_mf,
in_begin,
- in_next,
- in_end,
- cur_len - 1);
+ in_next - in_begin,
+ in_end - in_begin,
+ cur_len - 1,
+ next_hashes);
in_next += cur_len - 1;
continue;
}
*/
next_len = hc_matchfinder_longest_match(&c->hc_mf,
in_begin,
- in_next,
+ in_next - in_begin,
cur_len,
in_end - in_next,
min(in_end - in_next, c->nice_match_length),
c->max_search_depth / 2,
+ next_hashes,
&next_offset);
in_next += 1;
xpress_record_match(c, cur_len, cur_offset);
hc_matchfinder_skip_positions(&c->hc_mf,
in_begin,
- in_next,
- in_end,
- cur_len - 2);
+ in_next - in_begin,
+ in_end - in_begin,
+ cur_len - 2,
+ next_hashes);
in_next += cur_len - 2;
continue;
}
}
static u64
-xpress_get_needed_memory(size_t max_bufsize, unsigned compression_level)
+xpress_get_needed_memory(size_t max_bufsize, unsigned compression_level,
+ bool destructive)
{
u64 size = 0;
static int
xpress_create_compressor(size_t max_bufsize, unsigned compression_level,
- void **c_ret)
+ bool destructive, void **c_ret)
{
struct xpress_compressor *c;
if (max_bufsize > XPRESS_MAX_BUFSIZE)
return WIMLIB_ERR_INVALID_PARAM;
- c = ALIGNED_MALLOC(xpress_get_compressor_size(max_bufsize, compression_level),
- MATCHFINDER_ALIGNMENT);
+ c = MALLOC(xpress_get_compressor_size(max_bufsize, compression_level));
if (!c)
goto oom0;
c->impl = xpress_compress_lazy;
c->max_search_depth = (compression_level * 24) / 32;
c->nice_match_length = (compression_level * 48) / 32;
+
+ /* xpress_compress_lazy() needs max_search_depth >= 2
+ * because it halves the max_search_depth when
+ * attempting a lazy match, and max_search_depth cannot
+ * be 0. */
+ if (c->max_search_depth < 2)
+ c->max_search_depth = 2;
}
}
#if SUPPORT_NEAR_OPTIMAL_PARSING
}
#endif /* SUPPORT_NEAR_OPTIMAL_PARSING */
+ /* max_search_depth == 0 is invalid. */
+ if (c->max_search_depth < 1)
+ c->max_search_depth = 1;
+
*c_ret = c;
return 0;
oom1:
- ALIGNED_FREE(c);
+ FREE(c);
oom0:
return WIMLIB_ERR_NOMEM;
}
static size_t
-xpress_compress(const void *in, size_t in_nbytes,
- void *out, size_t out_nbytes_avail, void *_c)
+xpress_compress(const void *restrict in, size_t in_nbytes,
+ void *restrict out, size_t out_nbytes_avail, void *restrict _c)
{
struct xpress_compressor *c = _c;
} else
#endif
FREE(c->chosen_items);
- ALIGNED_FREE(c);
+ FREE(c);
}
const struct compressor_ops xpress_compressor_ops = {