/* Pointer to the start of the output buffer. */
u8 *start;
- /* Pointer to the location in the ouput buffer at which to write the
+ /* Pointer to the location in the output buffer at which to write the
* next 16 bits. */
u8 *next_bits;
if (os->bitcount > 16) {
os->bitcount -= 16;
if (os->end - os->next_byte >= 2) {
- put_unaligned_u16_le(os->bitbuf >> os->bitcount, os->next_bits);
+ put_unaligned_le16(os->bitbuf >> os->bitcount, os->next_bits);
os->next_bits = os->next_bits2;
os->next_bits2 = os->next_byte;
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(v, os->next_byte);
+ put_unaligned_le16(v, os->next_byte);
os->next_byte += 2;
}
}
if (os->end - os->next_byte < 2)
return 0;
- 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);
return os->next_byte - os->start;
}
{
const u8 * const in_begin = in;
const u8 *in_next = in_begin;
- const u8 * const in_end = in_begin + in_nbytes;
struct lz_match *cache_ptr = c->match_cache;
- u32 next_hash = 0;
+ u32 next_hashes[2] = {};
+ u32 max_len = in_nbytes;
+ u32 nice_len = min(max_len, c->nice_match_length);
bt_matchfinder_init(&c->bt_mf);
- do {
+ for (;;) {
struct lz_match *matches;
- unsigned best_len;
+ u32 best_len;
/* 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;
matches = cache_ptr;
bt_matchfinder_get_matches(&c->bt_mf,
in_begin,
in_next - in_begin,
- in_end - in_next,
- min(in_end - in_next, c->nice_match_length),
+ max_len,
+ nice_len,
c->max_search_depth,
- &next_hash,
+ next_hashes,
&best_len,
cache_ptr);
cache_ptr->length = cache_ptr - matches;
- cache_ptr->offset = *in_next;
- in_next++;
+ cache_ptr->offset = *in_next++;
cache_ptr++;
+ max_len--;
+ nice_len = min(nice_len, max_len);
/*
* If there was a very long match found, then don't cache any
* 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.
*/
- if (best_len >= c->nice_match_length) {
+ if (best_len >= nice_len) {
+ if (unlikely(best_len +
+ BT_MATCHFINDER_REQUIRED_NBYTES >= max_len))
+ break;
--best_len;
do {
bt_matchfinder_skip_position(&c->bt_mf,
in_begin,
in_next - in_begin,
- in_end - in_next,
- min(in_end - in_next,
- c->nice_match_length),
+ max_len,
+ nice_len,
c->max_search_depth,
- &next_hash);
-
+ next_hashes);
cache_ptr->length = 0;
cache_ptr->offset = *in_next++;
cache_ptr++;
+ max_len--;
+ nice_len = min(nice_len, max_len);
} while (--best_len);
}
- } while (in_next != in_end);
+ }
+
+ while (max_len--) {
+ cache_ptr->length = 0;
+ cache_ptr->offset = *in_next++;
+ cache_ptr++;
+ }
return cache_ptr;
}
if (compression_level < 30) {
c->impl = xpress_compress_greedy;
- 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;
} else {
c->impl = xpress_compress_lazy;
- 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;
/* xpress_compress_lazy() needs max_search_depth >= 2
* because it halves the max_search_depth when
&c->match_cache[max_bufsize * CACHE_RESERVE_PER_POS];
c->impl = xpress_compress_near_optimal;
- 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;
c->num_optim_passes = compression_level / 40;
}
#endif /* SUPPORT_NEAR_OPTIMAL_PARSING */