xref: /freebsd/contrib/xz/src/liblzma/rangecoder/price.h (revision 3b35e7ee8de9b0260149a2b77e87a2b9c7a36244)
1*3b35e7eeSXin LI // SPDX-License-Identifier: 0BSD
2*3b35e7eeSXin LI 
381ad8388SMartin Matuska ///////////////////////////////////////////////////////////////////////////////
481ad8388SMartin Matuska //
581ad8388SMartin Matuska /// \file       price.h
681ad8388SMartin Matuska /// \brief      Probability price calculation
781ad8388SMartin Matuska //
881ad8388SMartin Matuska //  Author:     Igor Pavlov
981ad8388SMartin Matuska //
1081ad8388SMartin Matuska ///////////////////////////////////////////////////////////////////////////////
1181ad8388SMartin Matuska 
1281ad8388SMartin Matuska #ifndef LZMA_PRICE_H
1381ad8388SMartin Matuska #define LZMA_PRICE_H
1481ad8388SMartin Matuska 
1581ad8388SMartin Matuska 
1681ad8388SMartin Matuska #define RC_MOVE_REDUCING_BITS 4
1781ad8388SMartin Matuska #define RC_BIT_PRICE_SHIFT_BITS 4
1881ad8388SMartin Matuska #define RC_PRICE_TABLE_SIZE (RC_BIT_MODEL_TOTAL >> RC_MOVE_REDUCING_BITS)
1981ad8388SMartin Matuska 
2081ad8388SMartin Matuska #define RC_INFINITY_PRICE (UINT32_C(1) << 30)
2181ad8388SMartin Matuska 
2281ad8388SMartin Matuska 
2381ad8388SMartin Matuska /// Lookup table for the inline functions defined in this file.
24ca6a6373SXin LI lzma_attr_visibility_hidden
2581ad8388SMartin Matuska extern const uint8_t lzma_rc_prices[RC_PRICE_TABLE_SIZE];
2681ad8388SMartin Matuska 
2781ad8388SMartin Matuska 
2881ad8388SMartin Matuska static inline uint32_t
2981ad8388SMartin Matuska rc_bit_price(const probability prob, const uint32_t bit)
3081ad8388SMartin Matuska {
3181ad8388SMartin Matuska 	return lzma_rc_prices[(prob ^ ((UINT32_C(0) - bit)
3281ad8388SMartin Matuska 			& (RC_BIT_MODEL_TOTAL - 1))) >> RC_MOVE_REDUCING_BITS];
3381ad8388SMartin Matuska }
3481ad8388SMartin Matuska 
3581ad8388SMartin Matuska 
3681ad8388SMartin Matuska static inline uint32_t
3781ad8388SMartin Matuska rc_bit_0_price(const probability prob)
3881ad8388SMartin Matuska {
3981ad8388SMartin Matuska 	return lzma_rc_prices[prob >> RC_MOVE_REDUCING_BITS];
4081ad8388SMartin Matuska }
4181ad8388SMartin Matuska 
4281ad8388SMartin Matuska 
4381ad8388SMartin Matuska static inline uint32_t
4481ad8388SMartin Matuska rc_bit_1_price(const probability prob)
4581ad8388SMartin Matuska {
4681ad8388SMartin Matuska 	return lzma_rc_prices[(prob ^ (RC_BIT_MODEL_TOTAL - 1))
4781ad8388SMartin Matuska 			>> RC_MOVE_REDUCING_BITS];
4881ad8388SMartin Matuska }
4981ad8388SMartin Matuska 
5081ad8388SMartin Matuska 
5181ad8388SMartin Matuska static inline uint32_t
5281ad8388SMartin Matuska rc_bittree_price(const probability *const probs,
5381ad8388SMartin Matuska 		const uint32_t bit_levels, uint32_t symbol)
5481ad8388SMartin Matuska {
5581ad8388SMartin Matuska 	uint32_t price = 0;
5681ad8388SMartin Matuska 	symbol += UINT32_C(1) << bit_levels;
5781ad8388SMartin Matuska 
5881ad8388SMartin Matuska 	do {
5981ad8388SMartin Matuska 		const uint32_t bit = symbol & 1;
6081ad8388SMartin Matuska 		symbol >>= 1;
6181ad8388SMartin Matuska 		price += rc_bit_price(probs[symbol], bit);
6281ad8388SMartin Matuska 	} while (symbol != 1);
6381ad8388SMartin Matuska 
6481ad8388SMartin Matuska 	return price;
6581ad8388SMartin Matuska }
6681ad8388SMartin Matuska 
6781ad8388SMartin Matuska 
6881ad8388SMartin Matuska static inline uint32_t
6981ad8388SMartin Matuska rc_bittree_reverse_price(const probability *const probs,
7081ad8388SMartin Matuska 		uint32_t bit_levels, uint32_t symbol)
7181ad8388SMartin Matuska {
7281ad8388SMartin Matuska 	uint32_t price = 0;
7381ad8388SMartin Matuska 	uint32_t model_index = 1;
7481ad8388SMartin Matuska 
7581ad8388SMartin Matuska 	do {
7681ad8388SMartin Matuska 		const uint32_t bit = symbol & 1;
7781ad8388SMartin Matuska 		symbol >>= 1;
7881ad8388SMartin Matuska 		price += rc_bit_price(probs[model_index], bit);
7981ad8388SMartin Matuska 		model_index = (model_index << 1) + bit;
8081ad8388SMartin Matuska 	} while (--bit_levels != 0);
8181ad8388SMartin Matuska 
8281ad8388SMartin Matuska 	return price;
8381ad8388SMartin Matuska }
8481ad8388SMartin Matuska 
8581ad8388SMartin Matuska 
8681ad8388SMartin Matuska static inline uint32_t
8781ad8388SMartin Matuska rc_direct_price(const uint32_t bits)
8881ad8388SMartin Matuska {
8981ad8388SMartin Matuska 	 return bits << RC_BIT_PRICE_SHIFT_BITS;
9081ad8388SMartin Matuska }
9181ad8388SMartin Matuska 
9281ad8388SMartin Matuska #endif
93