1
0
Fork 0

Merging upstream version 1.6~pre2.

Signed-off-by: Daniel Baumann <daniel@debian.org>
This commit is contained in:
Daniel Baumann 2025-02-17 20:33:28 +01:00
parent 33502bf60d
commit 26fbdeadfd
Signed by: daniel
GPG key ID: FBB4F0E80A80222F
15 changed files with 364 additions and 296 deletions

132
encoder.h
View file

@ -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 );
}
struct Len_encoder
static inline void Re_encode_len( struct Range_encoder * const renc,
struct Len_model * const lm,
int symbol, const int pos_state )
{
struct Len_model lm;
int prices[pos_states][max_len_symbols];
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_prices
{
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;
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 Lee_init( struct Len_encoder * const le,
const int match_len_limit )
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 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 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 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;
}
}
}