From: elasota 1137273+elasota@users.noreply.github.com
--- dlls/cabinet/liblzx_compiler.h | 13 ++++++------ dlls/cabinet/liblzx_lzx_common.c | 10 ++++----- dlls/cabinet/liblzx_lzx_compress.c | 33 +++++++++++++++++++++++++---- dlls/cabinet/liblzx_lzx_constants.h | 2 ++ 4 files changed, 43 insertions(+), 15 deletions(-)
diff --git a/dlls/cabinet/liblzx_compiler.h b/dlls/cabinet/liblzx_compiler.h index 666f4d8f273..e492874cc12 100644 --- a/dlls/cabinet/liblzx_compiler.h +++ b/dlls/cabinet/liblzx_compiler.h @@ -31,8 +31,15 @@ #ifndef _LIBLZX_COMPILER_H #define _LIBLZX_COMPILER_H
+#if defined(_MSC_VER) && !defined(__clang__) && !defined(__GNUC__) +#define LIBLZX_IS_MSVC_COMPILER 1 +#else +#define LIBLZX_IS_MSVC_COMPILER 0 +#endif + #if LIBLZX_IS_MSVC_COMPILER #include <stdint.h> +#include <stddef.h>
#pragma warning(error:4013) #endif @@ -54,12 +61,6 @@ (__GNUC__ > major || \ (__GNUC__ == major && __GNUC_MINOR__ >= minor)))
-#if defined(_MSC_VER) && !defined(__clang__) && !defined(__GNUC__) -#define LIBLZX_IS_MSVC_COMPILER 1 -#else -#define LIBLZX_IS_MSVC_COMPILER 0 -#endif - /* Feature-test macros defined by recent versions of clang. */ #ifndef __has_attribute # define __has_attribute(attribute) 0 diff --git a/dlls/cabinet/liblzx_lzx_common.c b/dlls/cabinet/liblzx_lzx_common.c index d04a7edae82..d8619e0965f 100644 --- a/dlls/cabinet/liblzx_lzx_common.c +++ b/dlls/cabinet/liblzx_lzx_common.c @@ -178,10 +178,10 @@ lzx_e8_filter(uint8_t *data, uint32_t size, uint32_t chunk_offset, uint32_t e8_f uint8_t *tail; uint8_t *p;
- if (size <= 10) + if (size <= LZX_E8_FILTER_TAIL_SIZE) return;
- tail = &data[size - 10]; + tail = &data[size - LZX_E8_FILTER_TAIL_SIZE]; p = data; while (p < tail) { if (*p != 0xE8) { @@ -199,7 +199,7 @@ lzx_e8_filter(uint8_t *data, uint32_t size, uint32_t chunk_offset, uint32_t e8_f uint8_t *p = data; uint64_t valid_mask = ~0;
- if (size <= 10) + if (size <= LZX_E8_FILTER_TAIL_SIZE) return; #ifdef __AVX2__ # define ALIGNMENT_REQUIRED 32 @@ -209,7 +209,7 @@ lzx_e8_filter(uint8_t *data, uint32_t size, uint32_t chunk_offset, uint32_t e8_f
/* Process one byte at a time until the pointer is properly aligned. */ while ((uintptr_t)p % ALIGNMENT_REQUIRED != 0) { - if (p >= data + size - 10) + if (p >= data + size - LZX_E8_FILTER_TAIL_SIZE) return; if (*p == 0xE8 && (valid_mask & 1)) { (*process_target)(p + 1, p - data + chunk_offset, @@ -297,7 +297,7 @@ lzx_e8_filter(uint8_t *data, uint32_t size, uint32_t chunk_offset, uint32_t e8_f }
/* Approaching the end of the buffer; process one byte a time. */ - while (p < data + size - 10) { + while (p < data + size - LZX_E8_FILTER_TAIL_SIZE) { if (*p == 0xE8 && (valid_mask & 1)) { (*process_target)(p + 1, p - data + chunk_offset, e8_file_size); diff --git a/dlls/cabinet/liblzx_lzx_compress.c b/dlls/cabinet/liblzx_lzx_compress.c index da34e748190..77092969839 100644 --- a/dlls/cabinet/liblzx_lzx_compress.c +++ b/dlls/cabinet/liblzx_lzx_compress.c @@ -2634,8 +2634,7 @@ lzx_compress_near_optimal(struct liblzx_compressor * restrict c, resume_matchfinding: do { size_t min_match_pos = in_next - in_begin; - min_match_pos -= - min_size(min_match_pos, max_offset); + min_match_pos -= min_size(min_match_pos, max_offset);
if (in_next >= next_search_pos && likely(nice_len >= LZX_MIN_MATCH_LEN)) { @@ -3432,7 +3431,8 @@ liblzx_compress_create(const struct liblzx_compress_properties *props) /* Pad out to include past blocks and extra * matchfinding space */ c->in_buffer_capacity *= 2; - c->in_buffer_capacity += LZX_MAX_MATCH_LEN; + c->in_buffer_capacity += + LZX_MAX_MATCH_LEN + LZX_E8_FILTER_TAIL_SIZE; }
if (c->variant == LIBLZX_VARIANT_WIM) @@ -3531,7 +3531,10 @@ lzx_compress_chunk(struct liblzx_compressor *c) struct lzx_output_bitstream os; size_t result; bool e8_preprocess_enabled = (c->e8_chunk_offset < 0x40000000); + bool next_e8_preprocess_enabled = + (c->e8_chunk_offset + c->chunk_size < 0x40000000); uint32_t chunk_size = min_u32(c->chunk_size, c->in_used); + uint32_t next_chunk_preprocess_size = 0;
uint8_t *in = (uint8_t *)c->in_buffer + c->in_prefix_size;
@@ -3541,12 +3544,33 @@ lzx_compress_chunk(struct liblzx_compressor *c) c->e8_file_size); }
+ if (c->in_used > c->chunk_size && next_e8_preprocess_enabled) { + next_chunk_preprocess_size = + min_u32(LZX_MAX_MATCH_LEN + LZX_E8_FILTER_TAIL_SIZE, + c->in_used - c->chunk_size); + } + + /* Preprocess enough of the next block input data for the + matchfinder */ + if (next_chunk_preprocess_size > 0) { + lzx_preprocess(in + c->chunk_size, next_chunk_preprocess_size, + c->e8_chunk_offset + c->chunk_size, + c->e8_file_size); + } + /* Initialize the output bitstream. */ lzx_init_output(&os, c->out_buffer, c->out_buffer_capacity);
/* Call the compression level-specific compress() function. */ (*c->impl)(c, in, chunk_size, c->in_used, &os);
+ /* Undo next block preprocessing */ + if (next_chunk_preprocess_size > 0) { + lzx_postprocess(in + c->chunk_size, next_chunk_preprocess_size, + c->e8_chunk_offset + c->chunk_size, + c->e8_file_size); + } + /* Flush the output bitstream. */ result = lzx_flush_output(&os);
@@ -3593,7 +3617,8 @@ liblzx_compress_add_input(liblzx_compressor_t *c, const void *in_data, return 0;
max_used = min_uint(c->in_buffer_capacity - c->in_prefix_size, - c->chunk_size + LZX_MAX_MATCH_LEN); + c->chunk_size + LZX_MAX_MATCH_LEN + + LZX_E8_FILTER_TAIL_SIZE); fill_amount = min_size(in_data_size, max_used - c->in_used);
memcpy(((uint8_t *)c->in_buffer) + c->in_prefix_size + c->in_used, in_data, diff --git a/dlls/cabinet/liblzx_lzx_constants.h b/dlls/cabinet/liblzx_lzx_constants.h index dbe468d6adf..f11ce407873 100644 --- a/dlls/cabinet/liblzx_lzx_constants.h +++ b/dlls/cabinet/liblzx_lzx_constants.h @@ -97,6 +97,8 @@ * This is probably WIM-specific. */ #define LZX_DEFAULT_BLOCK_SIZE 32768
+#define LZX_E8_FILTER_TAIL_SIZE 10 + /* Number of offsets in the recent (or "repeat") offsets queue. */ #define LZX_NUM_RECENT_OFFSETS 3