#include "wimlib/bitops.h"
#include "wimlib/compress_common.h"
#include "wimlib/compressor_ops.h"
#include "wimlib/bitops.h"
#include "wimlib/compress_common.h"
#include "wimlib/compressor_ops.h"
* If the output buffer space is exhausted, then the bits will be ignored, and
* xpress_flush_output() will return 0 when it gets called.
*/
* If the output buffer space is exhausted, then the bits will be ignored, and
* xpress_flush_output() will return 0 when it gets called.
*/
xpress_write_bits(struct xpress_output_bitstream *os,
const u32 bits, const unsigned num_bits)
{
xpress_write_bits(struct xpress_output_bitstream *os,
const u32 bits, const unsigned num_bits)
{
xpress_write_byte(struct xpress_output_bitstream *os, u8 byte)
{
if (os->next_byte < os->end)
xpress_write_byte(struct xpress_output_bitstream *os, u8 byte)
{
if (os->next_byte < os->end)
xpress_write_u16(struct xpress_output_bitstream *os, u16 v)
{
if (os->end - os->next_byte >= 2) {
xpress_write_u16(struct xpress_output_bitstream *os, u16 v)
{
if (os->end - os->next_byte >= 2) {
- put_unaligned_u16_le(os->bitbuf << (16 - os->bitcount), os->next_bits);
- put_unaligned_u16_le(0, os->next_bits2);
+ put_unaligned_le16(os->bitbuf << (16 - os->bitcount), os->next_bits);
+ put_unaligned_le16(0, os->next_bits2);
xpress_write_item(struct xpress_item item, struct xpress_output_bitstream *os,
const u32 codewords[], const u8 lens[])
{
xpress_write_item(struct xpress_item item, struct xpress_output_bitstream *os,
const u32 codewords[], const u8 lens[])
{
struct xpress_optimum_node *optimum_nodes,
size_t count, const u32 codewords[], const u8 lens[])
{
struct xpress_optimum_node *optimum_nodes,
size_t count, const u32 codewords[], const u8 lens[])
{
- struct xpress_optimum_node *cur_optimum_ptr = optimum_nodes;
- struct xpress_optimum_node *end_optimum_ptr = optimum_nodes + count;
+ struct xpress_optimum_node *cur_node = optimum_nodes;
+ struct xpress_optimum_node *end_node = optimum_nodes + count;
- unsigned length = cur_optimum_ptr->item & OPTIMUM_LEN_MASK;
- unsigned offset = cur_optimum_ptr->item >> OPTIMUM_OFFSET_SHIFT;
+ unsigned length = cur_node->item & OPTIMUM_LEN_MASK;
+ unsigned offset = cur_node->item >> OPTIMUM_OFFSET_SHIFT;
xpress_write_bits(os, codewords[sym], lens[sym]);
xpress_write_extra_length_bytes(os, adjusted_len);
xpress_write_bits(os, codewords[sym], lens[sym]);
xpress_write_extra_length_bytes(os, adjusted_len);
/* Tally the Huffman symbol for a literal and return the intermediate
* representation of that literal. */
/* Tally the Huffman symbol for a literal and return the intermediate
* representation of that literal. */
/* Tally the Huffman symbol for a match and return the intermediate
* representation of that match. */
/* Tally the Huffman symbol for a match and return the intermediate
* representation of that match. */
xpress_record_match(struct xpress_compressor *c, unsigned length, unsigned offset)
{
unsigned adjusted_len = length - XPRESS_MIN_MATCH_LEN;
unsigned len_hdr = min(adjusted_len, 0xF);
xpress_record_match(struct xpress_compressor *c, unsigned length, unsigned offset)
{
unsigned adjusted_len = length - XPRESS_MIN_MATCH_LEN;
unsigned len_hdr = min(adjusted_len, 0xF);
- unsigned offset_high_bit = fls32(offset);
- unsigned sym = XPRESS_NUM_CHARS + ((offset_high_bit << 4) | len_hdr);
+ unsigned log2_offset = bsr32(offset);
+ unsigned sym = XPRESS_NUM_CHARS + ((log2_offset << 4) | len_hdr);
- ((u64)offset_high_bit << 25) |
- ((u64)(offset ^ (1U << offset_high_bit)) << 29),
+ ((u64)log2_offset << 25) |
+ ((u64)(offset ^ (1U << log2_offset)) << 29),
const u8 * const in_end = in_begin + in_nbytes;
struct xpress_item *next_chosen_item = c->chosen_items;
unsigned len_3_too_far;
const u8 * const in_end = in_begin + in_nbytes;
struct xpress_item *next_chosen_item = c->chosen_items;
unsigned len_3_too_far;
XPRESS_MIN_MATCH_LEN - 1,
in_end - in_next,
min(in_end - in_next, c->nice_match_length),
c->max_search_depth,
XPRESS_MIN_MATCH_LEN - 1,
in_end - in_next,
min(in_end - in_next, c->nice_match_length),
c->max_search_depth,
const u8 * const in_end = in_begin + in_nbytes;
struct xpress_item *next_chosen_item = c->chosen_items;
unsigned len_3_too_far;
const u8 * const in_end = in_begin + in_nbytes;
struct xpress_item *next_chosen_item = c->chosen_items;
unsigned len_3_too_far;
/* Find the longest match at the current position. */
cur_len = hc_matchfinder_longest_match(&c->hc_mf,
in_begin,
/* Find the longest match at the current position. */
cur_len = hc_matchfinder_longest_match(&c->hc_mf,
in_begin,
XPRESS_MIN_MATCH_LEN - 1,
in_end - in_next,
min(in_end - in_next, c->nice_match_length),
c->max_search_depth,
XPRESS_MIN_MATCH_LEN - 1,
in_end - in_next,
min(in_end - in_next, c->nice_match_length),
c->max_search_depth,
xpress_record_match(c, cur_len, cur_offset);
hc_matchfinder_skip_positions(&c->hc_mf,
in_begin,
xpress_record_match(c, cur_len, cur_offset);
hc_matchfinder_skip_positions(&c->hc_mf,
in_begin,
- unsigned length = cur_optimum_ptr->item & OPTIMUM_LEN_MASK;
- unsigned offset = cur_optimum_ptr->item >> OPTIMUM_OFFSET_SHIFT;
+ unsigned length = cur_node->item & OPTIMUM_LEN_MASK;
+ unsigned offset = cur_node->item >> OPTIMUM_OFFSET_SHIFT;
xpress_find_min_cost_path(struct xpress_compressor *c, size_t in_nbytes,
struct lz_match *end_cache_ptr)
{
xpress_find_min_cost_path(struct xpress_compressor *c, size_t in_nbytes,
struct lz_match *end_cache_ptr)
{
/* Consider coding a literal. */
best_item = ((u32)literal << OPTIMUM_OFFSET_SHIFT) | 1;
best_cost_to_end = c->costs[literal] +
/* Consider coding a literal. */
best_item = ((u32)literal << OPTIMUM_OFFSET_SHIFT) | 1;
best_cost_to_end = c->costs[literal] +
adjusted_len = len - XPRESS_MIN_MATCH_LEN;
len_hdr = min(adjusted_len, 0xF);
sym = XPRESS_NUM_CHARS +
adjusted_len = len - XPRESS_MIN_MATCH_LEN;
len_hdr = min(adjusted_len, 0xF);
sym = XPRESS_NUM_CHARS +
- cur_optimum_ptr->cost_to_end = best_cost_to_end;
- cur_optimum_ptr->item = best_item;
- } while (cur_optimum_ptr != c->optimum_nodes);
+ cur_node->cost_to_end = best_cost_to_end;
+ cur_node->item = best_item;
+ } while (cur_node != c->optimum_nodes);
/* If we've found so many matches that the cache might overflow
* if we keep finding more, then stop finding matches. This
* case is very unlikely. */
/* If we've found so many matches that the cache might overflow
* if we keep finding more, then stop finding matches. This
* case is very unlikely. */
- if (unlikely(cache_ptr >= c->cache_overflow_mark)) {
- do {
- cache_ptr->length = 0;
- cache_ptr->offset = *in_next++;
- cache_ptr++;
- } while (in_next != in_end);
- return cache_ptr;
- }
+ if (unlikely(cache_ptr >= c->cache_overflow_mark ||
+ max_len < BT_MATCHFINDER_REQUIRED_NBYTES))
+ break;
* very much. If there's a long match, then the data must be
* highly compressible, so it doesn't matter as much what we do.
*/
* very much. If there's a long match, then the data must be
* highly compressible, so it doesn't matter as much what we do.
*/
- c = ALIGNED_MALLOC(xpress_get_compressor_size(max_bufsize, compression_level),
- MATCHFINDER_ALIGNMENT);
+ c = MALLOC(xpress_get_compressor_size(max_bufsize, compression_level));
- c->max_search_depth = (compression_level * 24) / 16;
- c->nice_match_length = (compression_level * 48) / 16;
+ c->max_search_depth = (compression_level * 30) / 16;
+ c->nice_match_length = (compression_level * 60) / 16;
- c->max_search_depth = (compression_level * 24) / 32;
- c->nice_match_length = (compression_level * 48) / 32;
+ c->max_search_depth = (compression_level * 30) / 32;
+ c->nice_match_length = (compression_level * 60) / 32;
- c->max_search_depth = (compression_level * 32) / 100;
- c->nice_match_length = (compression_level * 50) / 100;
+ c->max_search_depth = (compression_level * 28) / 100;
+ c->nice_match_length = (compression_level * 56) / 100;