summaryrefslogtreecommitdiffstats
path: root/encoder.h
diff options
context:
space:
mode:
Diffstat (limited to 'encoder.h')
-rw-r--r--encoder.h134
1 files changed, 87 insertions, 47 deletions
diff --git a/encoder.h b/encoder.h
index 4f14075..54b15e7 100644
--- a/encoder.h
+++ b/encoder.h
@@ -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;
}
}
}