diff options
Diffstat (limited to 'encoder.h')
-rw-r--r-- | encoder.h | 134 |
1 files changed, 87 insertions, 47 deletions
@@ -15,7 +15,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>. */ -enum { max_num_trials = 1 << 12, +enum { max_num_trials = 1 << 13, price_shift_bits = 6, price_step_bits = 2, price_step = 1 << price_step_bits }; @@ -53,19 +53,18 @@ extern Prob_prices prob_prices; static inline void Prob_prices_init( void ) { int i, j; - for( i = price_step / 2; i < bit_model_total; i += price_step ) + for( i = 0; i < bit_model_total >> price_step_bits; ++i ) { - unsigned val = i; - int bits = 0; /* base 2 logarithm of val */ + unsigned val = ( i * price_step ) + ( price_step / 2 ); + int bits = 0; /* base 2 logarithm of val */ for( j = 0; j < price_shift_bits; ++j ) { val = val * val; bits <<= 1; while( val >= 1 << 16 ) { val >>= 1; ++bits; } } - bits += 15; /* remaining bits in val */ - prob_prices[i >> price_step_bits] = - ( bit_model_total_bits << price_shift_bits ) - bits; + bits += 15; /* remaining bits in val */ + prob_prices[i] = ( bit_model_total_bits << price_shift_bits ) - bits; } } @@ -374,52 +373,93 @@ static inline void Re_encode_matched( struct Range_encoder * const renc, while( symbol < 0x10000 ); } +static inline void Re_encode_len( struct Range_encoder * const renc, + struct Len_model * const lm, + int symbol, const int pos_state ) + { + bool bit = ( ( symbol -= min_match_len ) >= len_low_symbols ); + Re_encode_bit( renc, &lm->choice1, bit ); + if( !bit ) + Re_encode_tree( renc, lm->bm_low[pos_state], symbol, len_low_bits ); + else + { + bit = ( symbol >= len_low_symbols + len_mid_symbols ); + Re_encode_bit( renc, &lm->choice2, bit ); + if( !bit ) + Re_encode_tree( renc, lm->bm_mid[pos_state], + symbol - len_low_symbols, len_mid_bits ); + else + Re_encode_tree( renc, lm->bm_high, + symbol - len_low_symbols - len_mid_symbols, len_high_bits ); + } + } + -struct Len_encoder +struct Len_prices { - struct Len_model lm; - int prices[pos_states][max_len_symbols]; + const struct Len_model * lm; int len_symbols; + int count; + int prices[pos_states][max_len_symbols]; int counters[pos_states]; }; -static inline void Lee_update_prices( struct Len_encoder * const le, - const int pos_state ) +static inline void Lp_update_low_mid_prices( struct Len_prices * const lp, + const int pos_state ) { - int * const pps = le->prices[pos_state]; - int tmp = price0( le->lm.choice1 ); + int * const pps = lp->prices[pos_state]; + int tmp = price0( lp->lm->choice1 ); int len = 0; - for( ; len < len_low_symbols && len < le->len_symbols; ++len ) - pps[len] = tmp + price_symbol( le->lm.bm_low[pos_state], len, len_low_bits ); - tmp = price1( le->lm.choice1 ); - for( ; len < len_low_symbols + len_mid_symbols && len < le->len_symbols; ++len ) - pps[len] = tmp + price0( le->lm.choice2 ) + - price_symbol( le->lm.bm_mid[pos_state], len - len_low_symbols, len_mid_bits ); - for( ; len < le->len_symbols; ++len ) - /* using 4 slots per value makes "Lee_price" faster */ - le->prices[3][len] = le->prices[2][len] = - le->prices[1][len] = le->prices[0][len] = - tmp + price1( le->lm.choice2 ) + - price_symbol( le->lm.bm_high, len - len_low_symbols - len_mid_symbols, len_high_bits ); - le->counters[pos_state] = le->len_symbols; - } - -static inline void Lee_init( struct Len_encoder * const le, - const int match_len_limit ) + lp->counters[pos_state] = lp->count; + for( ; len < len_low_symbols && len < lp->len_symbols; ++len ) + pps[len] = tmp + price_symbol( lp->lm->bm_low[pos_state], len, len_low_bits ); + if( len >= lp->len_symbols ) return; + tmp = price1( lp->lm->choice1 ) + price0( lp->lm->choice2 ); + for( ; len < len_low_symbols + len_mid_symbols && len < lp->len_symbols; ++len ) + pps[len] = tmp + + price_symbol( lp->lm->bm_mid[pos_state], len - len_low_symbols, len_mid_bits ); + } + +static inline void Lp_update_high_prices( struct Len_prices * const lp ) + { + const int tmp = price1( lp->lm->choice1 ) + price1( lp->lm->choice2 ); + int len; + for( len = len_low_symbols + len_mid_symbols; len < lp->len_symbols; ++len ) + /* using 4 slots per value makes "Lp_price" faster */ + lp->prices[3][len] = lp->prices[2][len] = + lp->prices[1][len] = lp->prices[0][len] = tmp + + price_symbol( lp->lm->bm_high, len - len_low_symbols - len_mid_symbols, len_high_bits ); + } + +static inline void Lp_init( struct Len_prices * const lp, + const struct Len_model * const lm, + const int match_len_limit ) { int i; - Lm_init( &le->lm ); - le->len_symbols = match_len_limit + 1 - min_match_len; - for( i = 0; i < pos_states; ++i ) Lee_update_prices( le, i ); + lp->lm = lm; + lp->len_symbols = match_len_limit + 1 - min_match_len; + lp->count = ( match_len_limit > 12 ) ? 1 : lp->len_symbols; + for( i = 0; i < pos_states; ++i ) lp->counters[i] = 0; } -void Lee_encode( struct Len_encoder * const le, - struct Range_encoder * const renc, - int symbol, const int pos_state ); +static inline void Lp_decrement_counter( struct Len_prices * const lp, + const int pos_state ) + { --lp->counters[pos_state]; } + +static inline void Lp_update_prices( struct Len_prices * const lp ) + { + int pos_state; + bool high_pending = false; + for( pos_state = 0; pos_state < pos_states; ++pos_state ) + if( lp->counters[pos_state] <= 0 ) + { Lp_update_low_mid_prices( lp, pos_state ); high_pending = true; } + if( high_pending && lp->len_symbols > len_low_symbols + len_mid_symbols ) + Lp_update_high_prices( lp ); + } -static inline int Lee_price( const struct Len_encoder * const le, - const int symbol, const int pos_state ) - { return le->prices[pos_state][symbol - min_match_len]; } +static inline int Lp_price( const struct Len_prices * const lp, + const int symbol, const int pos_state ) + { return lp->prices[pos_state][symbol - min_match_len]; } enum { infinite_price = 0x0FFFFFFF, @@ -490,8 +530,10 @@ struct LZ_encoder struct Matchfinder * matchfinder; struct Range_encoder renc; - struct Len_encoder match_len_encoder; - struct Len_encoder rep_len_encoder; + struct Len_model match_len_model; + struct Len_model rep_len_model; + struct Len_prices match_len_prices; + struct Len_prices rep_len_prices; struct Pair pairs[max_match_len+1]; struct Trial trials[max_num_trials]; @@ -499,7 +541,6 @@ struct LZ_encoder int dis_slot_prices[len_states][2*max_dictionary_bits]; int dis_prices[len_states][modeled_distances]; int align_prices[dis_align_size]; - int align_price_count; int num_dis_slots; }; @@ -558,14 +599,14 @@ static inline int LZe_price_rep0_len( const struct LZ_encoder * const e, const State state, const int pos_state ) { return LZe_price_rep( e, 0, state, pos_state ) + - Lee_price( &e->rep_len_encoder, len, pos_state ); + Lp_price( &e->rep_len_prices, len, pos_state ); } static inline int LZe_price_pair( const struct LZ_encoder * const e, const int dis, const int len, const int pos_state ) { - const int price = Lee_price( &e->match_len_encoder, len, pos_state ); + const int price = Lp_price( &e->match_len_prices, len, pos_state ); const int len_state = get_len_state( len ); if( dis < modeled_distances ) return price + e->dis_prices[len_state][dis]; @@ -600,7 +641,7 @@ static inline void LZe_encode_pair( struct LZ_encoder * const e, const int pos_state ) { const int dis_slot = get_slot( dis ); - Lee_encode( &e->match_len_encoder, &e->renc, len, pos_state ); + Re_encode_len( &e->renc, &e->match_len_model, len, pos_state ); Re_encode_tree( &e->renc, e->bm_dis_slot[get_len_state(len)], dis_slot, dis_slot_bits ); @@ -618,7 +659,6 @@ static inline void LZe_encode_pair( struct LZ_encoder * const e, Re_encode( &e->renc, direct_dis >> dis_align_bits, direct_bits - dis_align_bits ); Re_encode_tree_reversed( &e->renc, e->bm_align, direct_dis, dis_align_bits ); - --e->align_price_count; } } } |