X-Git-Url: https://wimlib.net/git/?a=blobdiff_plain;ds=sidebyside;f=include%2Fwimlib%2Flzms_common.h;h=1cb8c5660f7eff73a99a433e578105e62a9a1234;hb=5fce6aa92826ec69fdeeea13e28292fa1fbb43a8;hp=10dc4d020a3b3240252366abee98b4c070064e6b;hpb=40a690416a3951361ec77d33a723dd4497fb7585;p=wimlib diff --git a/include/wimlib/lzms_common.h b/include/wimlib/lzms_common.h index 10dc4d02..1cb8c566 100644 --- a/include/wimlib/lzms_common.h +++ b/include/wimlib/lzms_common.h @@ -11,36 +11,6 @@ #include "wimlib/lzms_constants.h" #include "wimlib/types.h" -//#define ENABLE_LZMS_DEBUG -#ifdef ENABLE_LZMS_DEBUG -# define LZMS_DEBUG DEBUG -# define LZMS_ASSERT wimlib_assert -# include "wimlib/assert.h" -# include "wimlib/error.h" -#else -# define LZMS_DEBUG(format, ...) -# define LZMS_ASSERT(...) -#endif - -extern void -lzms_x86_filter(u8 data[], s32 size, s32 last_target_usages[], bool undo); - -/* Probability entry for use by the range coder when in a specific state. */ -struct lzms_probability_entry { - - /* Number of zeroes in the most recent LZMS_PROBABILITY_MAX bits that - * have been coded using this probability entry. This is a cached value - * because it can be computed as LZMS_PROBABILITY_MAX minus the number - * of bits set in the low-order LZMS_PROBABILITY_MAX bits of - * @recent_bits. */ - u32 num_recent_zero_bits; - - /* The most recent LZMS_PROBABILITY_MAX bits that have been coded using - * this probability entry. The size of this variable, in bits, must be - * at least LZMS_PROBABILITY_MAX. */ - u64 recent_bits; -}; - /* Offset slot tables */ extern const u32 lzms_offset_slot_base[LZMS_MAX_NUM_OFFSET_SYMS + 1]; extern const u8 lzms_extra_offset_bits[LZMS_MAX_NUM_OFFSET_SYMS]; @@ -69,42 +39,62 @@ lzms_get_length_slot(u32 length) extern unsigned lzms_get_num_offset_slots(size_t uncompressed_size); -extern void -lzms_init_probability_entries(struct lzms_probability_entry *entries, size_t count); + +/* Probability entry for use by the range coder when in a specific state */ +struct lzms_probability_entry { + + /* The number of zeroes in the most recent LZMS_PROBABILITY_DENOMINATOR + * bits that have been decoded or encoded using this probability entry. + * The probability of the next bit being 0 is this value over + * LZMS_PROBABILITY_DENOMINATOR, except for the cases where this would + * imply 0% or 100% probability. */ + u32 num_recent_zero_bits; + + /* The most recent LZMS_PROBABILITY_DENOMINATOR bits that have been + * coded using this probability entry. The bits are ordered such that + * low order is newest and high order is oldest. */ + u64 recent_bits; +}; extern void -lzms_init_symbol_frequencies(u32 freqs[], size_t num_syms); +lzms_init_probability_entries(struct lzms_probability_entry *entries, size_t count); -/* Given a decoded bit, update the probability entry. */ +/* Given a decoded or encoded bit, update the probability entry. */ static inline void -lzms_update_probability_entry(struct lzms_probability_entry *prob_entry, int bit) +lzms_update_probability_entry(struct lzms_probability_entry *entry, int bit) { - s32 delta_zero_bits; + BUILD_BUG_ON(LZMS_PROBABILITY_DENOMINATOR != sizeof(entry->recent_bits) * 8); - BUILD_BUG_ON(LZMS_PROBABILITY_MAX != sizeof(prob_entry->recent_bits) * 8); + s32 delta_zero_bits = (s32)(entry->recent_bits >> + (LZMS_PROBABILITY_DENOMINATOR - 1)) - bit; - delta_zero_bits = (s32)(prob_entry->recent_bits >> (LZMS_PROBABILITY_MAX - 1)) - bit; - - prob_entry->num_recent_zero_bits += delta_zero_bits; - prob_entry->recent_bits <<= 1; - prob_entry->recent_bits |= bit; + entry->num_recent_zero_bits += delta_zero_bits; + entry->recent_bits = (entry->recent_bits << 1) | bit; } -/* Given a probability entry, return the chance out of LZMS_PROBABILITY_MAX that - * the next decoded bit will be a 0. */ +/* Given a probability entry, return the chance out of + * LZMS_PROBABILITY_DENOMINATOR that the next decoded bit will be a 0. */ static inline u32 lzms_get_probability(const struct lzms_probability_entry *prob_entry) { - u32 prob; - - prob = prob_entry->num_recent_zero_bits; + u32 prob = prob_entry->num_recent_zero_bits; /* 0% and 100% probabilities aren't allowed. */ if (prob == 0) prob++; - if (prob == LZMS_PROBABILITY_MAX) + else if (prob == LZMS_PROBABILITY_DENOMINATOR) prob--; return prob; } +extern void +lzms_init_symbol_frequencies(u32 freqs[], unsigned num_syms); + +extern void +lzms_dilute_symbol_frequencies(u32 freqs[], unsigned num_syms); + +/* Pre/post-processing */ +extern void +lzms_x86_filter(u8 data[], s32 size, s32 last_target_usages[], bool undo); + #endif /* _LZMS_COMMON_H */