Convert bittree_get_price() and bittree_reverse_get_price()

from macros to inline functions.
This commit is contained in:
Lasse Collin 2008-01-15 08:36:25 +02:00
parent 78e85cb1a7
commit 9f9b198301
3 changed files with 58 additions and 57 deletions

View File

@ -116,23 +116,18 @@ lzma_length_encoder_update_table(lzma_length_encoder *lencoder,
uint32_t *prices = lencoder->prices[pos_state]; uint32_t *prices = lencoder->prices[pos_state];
uint32_t i = 0; uint32_t i = 0;
for (i = 0; i < num_symbols && i < LEN_LOW_SYMBOLS; ++i) { for (i = 0; i < num_symbols && i < LEN_LOW_SYMBOLS; ++i)
prices[i] = a0; prices[i] = a0 + bittree_get_price(lencoder->low[pos_state],
bittree_get_price(prices[i], lencoder->low[pos_state],
LEN_LOW_BITS, i); LEN_LOW_BITS, i);
}
for (; i < num_symbols && i < LEN_LOW_SYMBOLS + LEN_MID_SYMBOLS; ++i) { for (; i < num_symbols && i < LEN_LOW_SYMBOLS + LEN_MID_SYMBOLS; ++i)
prices[i] = b0; prices[i] = b0 + bittree_get_price(lencoder->mid[pos_state],
bittree_get_price(prices[i], lencoder->mid[pos_state],
LEN_MID_BITS, i - LEN_LOW_SYMBOLS); LEN_MID_BITS, i - LEN_LOW_SYMBOLS);
}
for (; i < num_symbols; ++i) { for (; i < num_symbols; ++i)
prices[i] = b1; prices[i] = b1 + bittree_get_price(
bittree_get_price(prices[i], lencoder->high, LEN_HIGH_BITS, lencoder->high, LEN_HIGH_BITS,
i - LEN_LOW_SYMBOLS - LEN_MID_SYMBOLS); i - LEN_LOW_SYMBOLS - LEN_MID_SYMBOLS);
}
lencoder->counters[pos_state] = num_symbols; lencoder->counters[pos_state] = num_symbols;

View File

@ -111,8 +111,7 @@ fill_distances_prices(lzma_coder *coder)
const uint32_t pos_slot = get_pos_slot(i); const uint32_t pos_slot = get_pos_slot(i);
const uint32_t footer_bits = ((pos_slot >> 1) - 1); const uint32_t footer_bits = ((pos_slot >> 1) - 1);
const uint32_t base = (2 | (pos_slot & 1)) << footer_bits; const uint32_t base = (2 | (pos_slot & 1)) << footer_bits;
temp_prices[i] = 0; temp_prices[i] = bittree_reverse_get_price(
bittree_reverse_get_price(temp_prices[i],
coder->pos_encoders + base - pos_slot - 1, coder->pos_encoders + base - pos_slot - 1,
footer_bits, i - base); footer_bits, i - base);
} }
@ -129,8 +128,7 @@ fill_distances_prices(lzma_coder *coder)
for (uint32_t pos_slot = 0; for (uint32_t pos_slot = 0;
pos_slot < dist_table_size; pos_slot < dist_table_size;
++pos_slot) { ++pos_slot) {
pos_slot_prices[pos_slot] = 0; pos_slot_prices[pos_slot] = bittree_get_price(encoder,
bittree_get_price(pos_slot_prices[pos_slot], encoder,
POS_SLOT_BITS, pos_slot); POS_SLOT_BITS, pos_slot);
} }
@ -162,14 +160,12 @@ fill_distances_prices(lzma_coder *coder)
static void static void
fill_align_prices(lzma_coder *coder) fill_align_prices(lzma_coder *coder)
{ {
for (uint32_t i = 0; i < ALIGN_TABLE_SIZE; ++i) { for (uint32_t i = 0; i < ALIGN_TABLE_SIZE; ++i)
uint32_t tmp = 0; coder->align_prices[i] = bittree_reverse_get_price(
bittree_reverse_get_price(tmp, coder->pos_align_encoder, coder->pos_align_encoder, ALIGN_BITS, i);
ALIGN_BITS, i);
coder->align_prices[i] = tmp;
}
coder->align_price_count = 0; coder->align_price_count = 0;
return;
} }

View File

@ -32,6 +32,23 @@ typedef struct {
} lzma_range_encoder; } lzma_range_encoder;
#ifdef HAVE_SMALL
/// Probability prices used by *_get_price() macros. This is initialized
/// by lzma_rc_init() and is not modified later.
extern uint32_t lzma_rc_prob_prices[BIT_MODEL_TOTAL >> MOVE_REDUCING_BITS];
/// Initializes lzma_rc_prob_prices[]. This needs to be called only once.
extern void lzma_rc_init(void);
#else
// Not building a size optimized version, so we use a precomputed
// constant table.
extern const uint32_t
lzma_rc_prob_prices[BIT_MODEL_TOTAL >> MOVE_REDUCING_BITS];
#endif
/// Resets the range encoder structure. /// Resets the range encoder structure.
#define rc_reset(rc) \ #define rc_reset(rc) \
do { \ do { \
@ -222,44 +239,37 @@ do { \
lzma_rc_prob_prices[(BIT_MODEL_TOTAL - (prob)) >> MOVE_REDUCING_BITS] lzma_rc_prob_prices[(BIT_MODEL_TOTAL - (prob)) >> MOVE_REDUCING_BITS]
// Adds price to price_target. TODO Optimize/Cleanup? static inline uint32_t
#define bittree_get_price(price_target, probs, bit_levels, symbol) \ bittree_get_price(const probability *probs,
do { \ uint32_t bit_levels, uint32_t symbol)
uint32_t bittree_symbol = (symbol) | (UINT32_C(1) << bit_levels); \ {
while (bittree_symbol != 1) { \ uint32_t price = 0;
price_target += bit_get_price((probs)[bittree_symbol >> 1], \ symbol |= UINT32_C(1) << bit_levels;
bittree_symbol & 1); \
bittree_symbol >>= 1; \ do {
} \ price += bit_get_price(probs[symbol >> 1], symbol & 1);
} while (0) symbol >>= 1;
} while (symbol != 1);
return price;
}
// Adds price to price_target. static inline uint32_t
#define bittree_reverse_get_price(price_target, probs, bit_levels, symbol) \ bittree_reverse_get_price(const probability *probs,
do { \ uint32_t bit_levels, uint32_t symbol)
uint32_t model_index = 1; \ {
for (uint32_t bit_index = 0; bit_index < bit_levels; ++bit_index) { \ uint32_t price = 0;
const uint32_t bit = ((symbol) >> bit_index) & 1; \ uint32_t model_index = 1;
price_target += bit_get_price((probs)[model_index], bit); \
model_index = (model_index << 1) | bit; \
} \
} while (0)
do {
const uint32_t bit = symbol & 1;
symbol >>= 1;
price += bit_get_price(probs[model_index], bit);
model_index = (model_index << 1) | bit;
} while (--bit_levels != 0);
#ifdef HAVE_SMALL return price;
/// Probability prices used by *_get_price() macros. This is initialized }
/// by lzma_rc_init() and is not modified later.
extern uint32_t lzma_rc_prob_prices[BIT_MODEL_TOTAL >> MOVE_REDUCING_BITS];
/// Initializes lzma_rc_prob_prices[]. This needs to be called only once.
extern void lzma_rc_init(void);
#else
// Not building a size optimized version, so we use a precomputed
// constant table.
extern const uint32_t
lzma_rc_prob_prices[BIT_MODEL_TOTAL >> MOVE_REDUCING_BITS];
#endif
#endif #endif