# include "config.h"
#endif
-#include "wimlib.h"
#include "wimlib/assert.h"
#include "wimlib/compiler.h"
#include "wimlib/compressor_ops.h"
#include "wimlib/endianness.h"
#include "wimlib/error.h"
#include "wimlib/lz_mf.h"
+#include "wimlib/lz_repsearch.h"
#include "wimlib/lzms.h"
#include "wimlib/util.h"
lzms_get_length_cost(&ctx->length_encoder, length);
}
+static inline u32
+lzms_repsearch(const u8 * const strptr, const u32 bytes_remaining,
+ const struct lzms_lz_lru_queues *queue, u32 *offset_ret)
+{
+ u32 len;
+ unsigned slot = 0;
+
+ len = lz_repsearch(strptr, bytes_remaining, UINT32_MAX,
+ queue->recent_offsets, LZMS_NUM_RECENT_OFFSETS, &slot);
+ *offset_ret = queue->recent_offsets[slot];
+ return len;
+}
+
+
static struct lz_match
lzms_match_chooser_reverse_list(struct lzms_compressor *ctx, unsigned cur_pos)
{
};
}
-/* This is similar to lzx_choose_near_optimal_match() in lzx-compress.c.
+/* This is similar to lzx_choose_near_optimal_item() in lzx-compress.c.
* Read that one if you want to understand it. */
static struct lz_match
-lzms_get_near_optimal_match(struct lzms_compressor *ctx)
+lzms_get_near_optimal_item(struct lzms_compressor *ctx)
{
u32 num_matches;
struct lz_match *matches;
ctx->optimum_cur_idx = 0;
ctx->optimum_end_idx = 0;
- longest_rep_len = ctx->params.min_match_length - 1;
if (lz_mf_get_position(ctx->mf) >= LZMS_MAX_INIT_RECENT_OFFSET) {
- u32 limit = lz_mf_get_bytes_remaining(ctx->mf);
- for (int i = 0; i < LZMS_NUM_RECENT_OFFSETS; i++) {
- u32 offset = ctx->lru.lz.recent_offsets[i];
- const u8 *strptr = lz_mf_get_window_ptr(ctx->mf);
- const u8 *matchptr = strptr - offset;
- u32 len = 0;
- while (len < limit && strptr[len] == matchptr[len])
- len++;
- if (len > longest_rep_len) {
- longest_rep_len = len;
- longest_rep_offset = offset;
- }
- }
+ longest_rep_len = lzms_repsearch(lz_mf_get_window_ptr(ctx->mf),
+ lz_mf_get_bytes_remaining(ctx->mf),
+ &ctx->lru.lz, &longest_rep_offset);
+ } else {
+ longest_rep_len = 0;
}
if (longest_rep_len >= ctx->params.nice_match_length) {
}
end_pos = longest_len;
- if (longest_rep_len >= ctx->params.min_match_length) {
+ if (longest_rep_len) {
struct lzms_adaptive_state state;
u32 cost;
if (cur_pos == end_pos || cur_pos == ctx->params.optim_array_length)
return lzms_match_chooser_reverse_list(ctx, cur_pos);
- longest_rep_len = ctx->params.min_match_length - 1;
if (lz_mf_get_position(ctx->mf) >= LZMS_MAX_INIT_RECENT_OFFSET) {
- u32 limit = lz_mf_get_bytes_remaining(ctx->mf);
- for (int i = 0; i < LZMS_NUM_RECENT_OFFSETS; i++) {
- u32 offset = ctx->optimum[cur_pos].state.lru.recent_offsets[i];
- const u8 *strptr = lz_mf_get_window_ptr(ctx->mf);
- const u8 *matchptr = strptr - offset;
- u32 len = 0;
- while (len < limit && strptr[len] == matchptr[len])
- len++;
- if (len > longest_rep_len) {
- longest_rep_len = len;
- longest_rep_offset = offset;
- }
- }
+ longest_rep_len = lzms_repsearch(lz_mf_get_window_ptr(ctx->mf),
+ lz_mf_get_bytes_remaining(ctx->mf),
+ &ctx->optimum[cur_pos].state.lru,
+ &longest_rep_offset);
+ } else {
+ longest_rep_len = 0;
}
if (longest_rep_len >= ctx->params.nice_match_length) {
static void
lzms_encode(struct lzms_compressor *ctx)
{
- struct lz_match match;
+ struct lz_match item;
/* Load window into the match-finder. */
lz_mf_load_window(ctx->mf, ctx->window, ctx->window_size);
ctx->optimum_end_idx = 0;
while (ctx->cur_window_pos != ctx->window_size) {
- match = lzms_get_near_optimal_match(ctx);
- if (match.len <= 1)
+ item = lzms_get_near_optimal_item(ctx);
+ if (item.len <= 1)
lzms_encode_literal(ctx, ctx->window[ctx->cur_window_pos]);
else
- lzms_encode_lz_match(ctx, match.len, match.offset);
+ lzms_encode_lz_match(ctx, item.len, item.offset);
}
}
struct lzms_compressor_params *lzms_params)
{
lzms_params->min_match_length = (compression_level >= 50) ? 2 : 3;
- lzms_params->nice_match_length = ((u64)compression_level * 32) / 50;
+ lzms_params->nice_match_length = max(((u64)compression_level * 32) / 50,
+ lzms_params->min_match_length);
lzms_params->max_search_depth = ((u64)compression_level * 50) / 50;
lzms_params->optim_array_length = 224 + compression_level * 16;
}
lzms_get_needed_memory(size_t max_block_size, unsigned int compression_level)
{
struct lzms_compressor_params params;
+ u64 size = 0;
- lzms_build_params(compression_level, ¶ms);
+ if (max_block_size >= INT32_MAX)
+ return 0;
- u64 size = 0;
+ lzms_build_params(compression_level, ¶ms);
size += sizeof(struct lzms_compressor);
size += max_block_size;