X-Git-Url: https://wimlib.net/git/?a=blobdiff_plain;f=src%2Flzx-compress.c;h=d71c28dd9068c787b7e1f2ca196ee39f90e91e17;hb=fade5de00b08590d830a1775b90e3490e78cdca5;hp=360ee9c4e49a528da6b90fe6b26a4249f2ef3998;hpb=cf7090dcba4736f4ea56f272b5e0152a8a0a70b5;p=wimlib diff --git a/src/lzx-compress.c b/src/lzx-compress.c index 360ee9c4..d71c28dd 100644 --- a/src/lzx-compress.c +++ b/src/lzx-compress.c @@ -179,9 +179,9 @@ typedef u32 block_cost_t; /* Codewords for the LZX main, length, and aligned offset Huffman codes */ struct lzx_codewords { - u16 main[LZX_MAINCODE_MAX_NUM_SYMBOLS]; - u16 len[LZX_LENCODE_NUM_SYMBOLS]; - u16 aligned[LZX_ALIGNEDCODE_NUM_SYMBOLS]; + u32 main[LZX_MAINCODE_MAX_NUM_SYMBOLS]; + u32 len[LZX_LENCODE_NUM_SYMBOLS]; + u32 aligned[LZX_ALIGNEDCODE_NUM_SYMBOLS]; }; /* Codeword lengths (in bits) for the LZX main, length, and aligned offset @@ -519,7 +519,7 @@ lzx_build_precode(const u8 lens[restrict], input_idx_t precode_freqs[restrict LZX_PRECODE_NUM_SYMBOLS], u8 output_syms[restrict num_syms], u8 precode_lens[restrict LZX_PRECODE_NUM_SYMBOLS], - u16 precode_codewords[restrict LZX_PRECODE_NUM_SYMBOLS], + u32 precode_codewords[restrict LZX_PRECODE_NUM_SYMBOLS], unsigned *num_additional_bits_ret) { memset(precode_freqs, 0, @@ -688,7 +688,7 @@ lzx_write_compressed_code(struct output_bitstream *out, input_idx_t precode_freqs[LZX_PRECODE_NUM_SYMBOLS]; u8 output_syms[num_syms]; u8 precode_lens[LZX_PRECODE_NUM_SYMBOLS]; - u16 precode_codewords[LZX_PRECODE_NUM_SYMBOLS]; + u32 precode_codewords[LZX_PRECODE_NUM_SYMBOLS]; unsigned i; unsigned num_output_syms; u8 precode_sym; @@ -1303,6 +1303,7 @@ lzx_optimize_block(struct lzx_compressor *ctx, struct lzx_block_spec *spec, unsigned orig_window_pos = spec->window_pos; unsigned orig_cached_pos = ctx->cached_matches_pos; + unsigned num_passes_remaining = num_passes; LZX_ASSERT(ctx->match_window_pos == spec->window_pos); @@ -1314,7 +1315,8 @@ lzx_optimize_block(struct lzx_compressor *ctx, struct lzx_block_spec *spec, /* The first optimal parsing pass is done using the cost model already * set in ctx->costs. Each later pass is done using a cost model * computed from the previous pass. */ - for (unsigned pass = 0; pass < num_passes; pass++) { + do { + --num_passes_remaining; ctx->match_window_pos = orig_window_pos; ctx->cached_matches_pos = orig_cached_pos; @@ -1322,7 +1324,12 @@ lzx_optimize_block(struct lzx_compressor *ctx, struct lzx_block_spec *spec, spec->num_chosen_matches = 0; memset(&freqs, 0, sizeof(freqs)); - for (unsigned i = spec->window_pos; i < spec->window_pos + spec->block_size; ) { + const u8 *window_ptr = &ctx->window[spec->window_pos]; + const u8 *window_end = &window_ptr[spec->block_size]; + struct lzx_match *next_chosen_match = + &ctx->chosen_matches[spec->chosen_matches_start_pos]; + + while (window_ptr != window_end) { struct raw_match raw_match; struct lzx_match lzx_match; @@ -1350,36 +1357,33 @@ lzx_optimize_block(struct lzx_compressor *ctx, struct lzx_block_spec *spec, * null value and therefore cannot * generate such matches. */ BUILD_BUG_ON(LZX_MIN_MATCH_LEN != 2); - lzx_match.data = lzx_tally_literal(ctx->window[i], + lzx_match.data = lzx_tally_literal(*window_ptr++, &freqs); - i += 1; - ctx->chosen_matches[spec->chosen_matches_start_pos + - spec->num_chosen_matches++] - = lzx_match; - lzx_match.data = lzx_tally_literal(ctx->window[i], + *next_chosen_match++ = lzx_match; + lzx_match.data = lzx_tally_literal(*window_ptr++, &freqs); - i += 1; } else { lzx_match.data = lzx_tally_match(raw_match.len, raw_match.offset, &freqs, &ctx->queue); - i += raw_match.len; + window_ptr += raw_match.len; } } else { - lzx_match.data = lzx_tally_literal(ctx->window[i], &freqs); - i += 1; + lzx_match.data = lzx_tally_literal(*window_ptr++, &freqs); } - ctx->chosen_matches[spec->chosen_matches_start_pos + - spec->num_chosen_matches++] = lzx_match; + *next_chosen_match++ = lzx_match; } + spec->num_chosen_matches = next_chosen_match - + &ctx->chosen_matches[spec->chosen_matches_start_pos]; lzx_make_huffman_codes(&freqs, &spec->codes, ctx->num_main_syms); - if (pass < num_passes - 1) + if (num_passes_remaining) lzx_set_costs(ctx, &spec->codes.lens); ctx->matches_cached = true; - } + } while (num_passes_remaining); + spec->block_type = lzx_choose_verbatim_or_aligned(&freqs, &spec->codes); ctx->matches_cached = false; }