コード例 #1
0
static void
fill_distances_prices(lzma_coder *coder)
{
	for (uint32_t len_to_pos_state = 0;
			len_to_pos_state < LEN_TO_POS_STATES;
			++len_to_pos_state) {

		uint32_t *const pos_slot_prices
				= coder->pos_slot_prices[len_to_pos_state];

		// Price to encode the pos_slot.
		for (uint32_t pos_slot = 0;
				pos_slot < coder->dist_table_size; ++pos_slot)
			pos_slot_prices[pos_slot] = rc_bittree_price(
					coder->pos_slot[len_to_pos_state],
					POS_SLOT_BITS, pos_slot);

		// For matches with distance >= FULL_DISTANCES, add the price
		// of the direct bits part of the match distance. (Align bits
		// are handled by fill_align_prices()).
		for (uint32_t pos_slot = END_POS_MODEL_INDEX;
				pos_slot < coder->dist_table_size; ++pos_slot)
			pos_slot_prices[pos_slot] += rc_direct_price(
					((pos_slot >> 1) - 1) - ALIGN_BITS);

		// Distances in the range [0, 3] are fully encoded with
		// pos_slot, so they are used for coder->distances_prices
		// as is.
		for (uint32_t i = 0; i < START_POS_MODEL_INDEX; ++i)
			coder->distances_prices[len_to_pos_state][i]
					= pos_slot_prices[i];
	}

	// Distances in the range [4, 127] depend on pos_slot and pos_special.
	// We do this in a loop separate from the above loop to avoid
	// redundant calls to get_pos_slot().
	for (uint32_t i = START_POS_MODEL_INDEX; i < FULL_DISTANCES; ++i) {
		const uint32_t pos_slot = get_pos_slot(i);
		const uint32_t footer_bits = ((pos_slot >> 1) - 1);
		const uint32_t base = (2 | (pos_slot & 1)) << footer_bits;
		const uint32_t price = rc_bittree_reverse_price(
				coder->pos_special + base - pos_slot - 1,
				footer_bits, i - base);

		for (uint32_t len_to_pos_state = 0;
				len_to_pos_state < LEN_TO_POS_STATES;
				++len_to_pos_state)
			coder->distances_prices[len_to_pos_state][i]
					= price + coder->pos_slot_prices[
						len_to_pos_state][pos_slot];
	}

	coder->match_price_count = 0;
	return;
}
コード例 #2
0
static inline void
match(lzma_coder *coder, const uint32_t pos_state,
		const uint32_t distance, const uint32_t len)
{
	update_match(coder->state);

	length(&coder->rc, &coder->match_len_encoder, pos_state, len,
			coder->fast_mode);

	const uint32_t pos_slot = get_pos_slot(distance);
	const uint32_t len_to_pos_state = get_len_to_pos_state(len);
	rc_bittree(&coder->rc, coder->pos_slot[len_to_pos_state],
			POS_SLOT_BITS, pos_slot);

	if (pos_slot >= START_POS_MODEL_INDEX) {
		const uint32_t footer_bits = (pos_slot >> 1) - 1;
		const uint32_t base = (2 | (pos_slot & 1)) << footer_bits;
		const uint32_t pos_reduced = distance - base;

		if (pos_slot < END_POS_MODEL_INDEX) {
			// Careful here: base - pos_slot - 1 can be -1, but
			// rc_bittree_reverse starts at probs[1], not probs[0].
			rc_bittree_reverse(&coder->rc,
				coder->pos_special + base - pos_slot - 1,
				footer_bits, pos_reduced);
		} else {
			rc_direct(&coder->rc, pos_reduced >> ALIGN_BITS,
					footer_bits - ALIGN_BITS);
			rc_bittree_reverse(
					&coder->rc, coder->pos_align,
					ALIGN_BITS, pos_reduced & ALIGN_MASK);
			++coder->align_price_count;
		}
	}

	coder->reps[3] = coder->reps[2];
	coder->reps[2] = coder->reps[1];
	coder->reps[1] = coder->reps[0];
	coder->reps[0] = distance;
	++coder->match_price_count;
}