summaryrefslogtreecommitdiffstats
path: root/encoder.h
diff options
context:
space:
mode:
Diffstat (limited to 'encoder.h')
-rw-r--r--encoder.h125
1 files changed, 84 insertions, 41 deletions
diff --git a/encoder.h b/encoder.h
index f458bd9..2a92228 100644
--- a/encoder.h
+++ b/encoder.h
@@ -476,52 +476,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 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 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;
}
-static 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,
@@ -593,8 +634,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];
@@ -603,9 +646,10 @@ 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;
- int fill_counter;
+ int price_counter;
+ int dis_price_counter;
+ int align_price_counter;
State state;
bool member_finished;
};
@@ -669,14 +713,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];
@@ -711,7 +755,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 );
@@ -729,7 +773,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;
}
}
}