mirror of
https://github.com/webmproject/libwebp.git
synced 2025-07-16 22:09:57 +02:00
Create LUT for PrefixEncode.
This speeds up lossless compression by 5%. Change-Id: Ifd114b1d9850dc3aac74593809e7d48529d35e3d
This commit is contained in:
@ -99,6 +99,80 @@ static WEBP_INLINE float VP8LFastSLog2(int v) {
|
||||
return (v < LOG_LOOKUP_IDX_MAX) ? kSLog2Table[v] : VP8LFastSLog2Slow(v);
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// PrefixEncode()
|
||||
|
||||
// use GNU builtins where available.
|
||||
#if defined(__GNUC__) && \
|
||||
((__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || __GNUC__ >= 4)
|
||||
static WEBP_INLINE int BitsLog2Floor(uint32_t n) {
|
||||
return 31 ^ __builtin_clz(n);
|
||||
}
|
||||
#elif defined(_MSC_VER) && (defined(_M_X64) || defined(_M_IX86))
|
||||
#include <intrin.h>
|
||||
#pragma intrinsic(_BitScanReverse)
|
||||
|
||||
static WEBP_INLINE int BitsLog2Floor(uint32_t n) {
|
||||
unsigned long first_set_bit;
|
||||
_BitScanReverse(&first_set_bit, n);
|
||||
return first_set_bit;
|
||||
}
|
||||
#else
|
||||
// Returns (int)floor(log2(n)). n must be > 0.
|
||||
static WEBP_INLINE int BitsLog2Floor(uint32_t n) {
|
||||
int log = 0;
|
||||
uint32_t value = n;
|
||||
int i;
|
||||
|
||||
for (i = 4; i >= 0; --i) {
|
||||
const int shift = (1 << i);
|
||||
const uint32_t x = value >> shift;
|
||||
if (x != 0) {
|
||||
value = x;
|
||||
log += shift;
|
||||
}
|
||||
}
|
||||
return log;
|
||||
}
|
||||
#endif
|
||||
|
||||
static WEBP_INLINE int VP8LBitsLog2Ceiling(uint32_t n) {
|
||||
const int log_floor = BitsLog2Floor(n);
|
||||
if (n == (n & ~(n - 1))) // zero or a power of two.
|
||||
return log_floor;
|
||||
else
|
||||
return log_floor + 1;
|
||||
}
|
||||
|
||||
// Splitting of distance and length codes into prefixes and
|
||||
// extra bits. The prefixes are encoded with an entropy code
|
||||
// while the extra bits are stored just as normal bits.
|
||||
static WEBP_INLINE void VP8LPrefixEncodeNoLUT(int distance, int* const code,
|
||||
int* const extra_bits,
|
||||
int* const extra_bits_value) {
|
||||
const int highest_bit = BitsLog2Floor(--distance);
|
||||
const int second_highest_bit = (distance >> (highest_bit - 1)) & 1;
|
||||
*extra_bits = highest_bit - 1;
|
||||
*extra_bits_value = distance & ((1 << *extra_bits) - 1);
|
||||
*code = 2 * highest_bit + second_highest_bit;
|
||||
}
|
||||
|
||||
#define PREFIX_LOOKUP_IDX_MAX 512
|
||||
// These tables are derived using VP8LPrefixEncodeNoLUT.
|
||||
extern const int8_t kPrefixEncodeCode[PREFIX_LOOKUP_IDX_MAX];
|
||||
extern const int8_t kPrefixEncodeExtraBits[PREFIX_LOOKUP_IDX_MAX];
|
||||
extern const uint8_t kPrefixEncodeExtraBitsVal[PREFIX_LOOKUP_IDX_MAX];
|
||||
static WEBP_INLINE void VP8LPrefixEncode(int distance, int* const code,
|
||||
int* const extra_bits,
|
||||
int* const extra_bits_value) {
|
||||
if (distance < PREFIX_LOOKUP_IDX_MAX) {
|
||||
*code = kPrefixEncodeCode[distance];
|
||||
*extra_bits = kPrefixEncodeExtraBits[distance];
|
||||
*extra_bits_value = kPrefixEncodeExtraBitsVal[distance];
|
||||
} else {
|
||||
VP8LPrefixEncodeNoLUT(distance, code, extra_bits, extra_bits_value);
|
||||
}
|
||||
}
|
||||
|
||||
// In-place difference of each component with mod 256.
|
||||
static WEBP_INLINE uint32_t VP8LSubPixels(uint32_t a, uint32_t b) {
|
||||
|
Reference in New Issue
Block a user