From 5bd2704e30361fc069c10827028b31442f0cb3d4 Mon Sep 17 00:00:00 2001 From: Ilya Kurdyukov Date: Tue, 16 Feb 2021 14:30:26 +0700 Subject: [PATCH] Introduce the BitCtz() function. * Use a WEBP_HAVE_SLOW_CLZ_CTZ flag when they are slow (LUT-based). Change-Id: If707c121b8800438be404594a39bb123ef25b0f0 --- src/utils/utils.h | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/src/utils/utils.h b/src/utils/utils.h index 2a3ec926..d3ebdb58 100644 --- a/src/utils/utils.h +++ b/src/utils/utils.h @@ -114,17 +114,26 @@ static WEBP_INLINE void PutLE32(uint8_t* const data, uint32_t val) { static WEBP_INLINE int BitsLog2Floor(uint32_t n) { return 31 ^ __builtin_clz(n); } +// counts the number of trailing zero +static WEBP_INLINE int BitsCtz(uint32_t n) { return __builtin_ctz(n); } #elif defined(_MSC_VER) && _MSC_VER > 1310 && \ (defined(_M_X64) || defined(_M_IX86)) #include #pragma intrinsic(_BitScanReverse) +#pragma intrinsic(_BitScanForward) static WEBP_INLINE int BitsLog2Floor(uint32_t n) { - unsigned long first_set_bit; + unsigned long first_set_bit; // NOLINT (runtime/int) _BitScanReverse(&first_set_bit, n); return first_set_bit; } -#else // default: use the C-version. +static WEBP_INLINE int BitsCtz(uint32_t n) { + unsigned long first_set_bit; // NOLINT (runtime/int) + _BitScanForward(&first_set_bit, n); + return first_set_bit; +} +#else // default: use the (slow) C-version. +#define WEBP_HAVE_SLOW_CLZ_CTZ // signal that the Clz/Ctz function are slow // Returns 31 ^ clz(n) = log2(n). This is the default C-implementation, either // based on table or not. Can be used as fallback if clz() is not available. #define WEBP_NEED_LOG_TABLE_8BIT