diff options
Diffstat (limited to 'thirdparty/libwebp/utils')
-rw-r--r-- | thirdparty/libwebp/utils/bit_reader_inl_utils.h (renamed from thirdparty/libwebp/utils/bit_reader_inl.h) | 79 | ||||
-rw-r--r-- | thirdparty/libwebp/utils/bit_reader_utils.c (renamed from thirdparty/libwebp/utils/bit_reader.c) | 2 | ||||
-rw-r--r-- | thirdparty/libwebp/utils/bit_reader_utils.h (renamed from thirdparty/libwebp/utils/bit_reader.h) | 0 | ||||
-rw-r--r-- | thirdparty/libwebp/utils/bit_writer_utils.c (renamed from thirdparty/libwebp/utils/bit_writer.c) | 10 | ||||
-rw-r--r-- | thirdparty/libwebp/utils/bit_writer_utils.h (renamed from thirdparty/libwebp/utils/bit_writer.h) | 3 | ||||
-rw-r--r-- | thirdparty/libwebp/utils/color_cache_utils.c (renamed from thirdparty/libwebp/utils/color_cache.c) | 2 | ||||
-rw-r--r-- | thirdparty/libwebp/utils/color_cache_utils.h (renamed from thirdparty/libwebp/utils/color_cache.h) | 15 | ||||
-rw-r--r-- | thirdparty/libwebp/utils/endian_inl_utils.h (renamed from thirdparty/libwebp/utils/endian_inl.h) | 0 | ||||
-rw-r--r-- | thirdparty/libwebp/utils/filters_utils.c (renamed from thirdparty/libwebp/utils/filters.c) | 2 | ||||
-rw-r--r-- | thirdparty/libwebp/utils/filters_utils.h (renamed from thirdparty/libwebp/utils/filters.h) | 0 | ||||
-rw-r--r-- | thirdparty/libwebp/utils/huffman_encode_utils.c (renamed from thirdparty/libwebp/utils/huffman_encode.c) | 2 | ||||
-rw-r--r-- | thirdparty/libwebp/utils/huffman_encode_utils.h (renamed from thirdparty/libwebp/utils/huffman_encode.h) | 0 | ||||
-rw-r--r-- | thirdparty/libwebp/utils/huffman_utils.c (renamed from thirdparty/libwebp/utils/huffman.c) | 48 | ||||
-rw-r--r-- | thirdparty/libwebp/utils/huffman_utils.h (renamed from thirdparty/libwebp/utils/huffman.h) | 0 | ||||
-rw-r--r-- | thirdparty/libwebp/utils/quant_levels_dec_utils.c (renamed from thirdparty/libwebp/utils/quant_levels_dec.c) | 2 | ||||
-rw-r--r-- | thirdparty/libwebp/utils/quant_levels_dec_utils.h (renamed from thirdparty/libwebp/utils/quant_levels_dec.h) | 0 | ||||
-rw-r--r-- | thirdparty/libwebp/utils/quant_levels_utils.c (renamed from thirdparty/libwebp/utils/quant_levels.c) | 2 | ||||
-rw-r--r-- | thirdparty/libwebp/utils/quant_levels_utils.h (renamed from thirdparty/libwebp/utils/quant_levels.h) | 0 | ||||
-rw-r--r-- | thirdparty/libwebp/utils/random_utils.c (renamed from thirdparty/libwebp/utils/random.c) | 2 | ||||
-rw-r--r-- | thirdparty/libwebp/utils/random_utils.h (renamed from thirdparty/libwebp/utils/random.h) | 0 | ||||
-rw-r--r-- | thirdparty/libwebp/utils/rescaler_utils.c (renamed from thirdparty/libwebp/utils/rescaler.c) | 2 | ||||
-rw-r--r-- | thirdparty/libwebp/utils/rescaler_utils.h (renamed from thirdparty/libwebp/utils/rescaler.h) | 0 | ||||
-rw-r--r-- | thirdparty/libwebp/utils/thread_utils.c (renamed from thirdparty/libwebp/utils/thread.c) | 8 | ||||
-rw-r--r-- | thirdparty/libwebp/utils/thread_utils.h (renamed from thirdparty/libwebp/utils/thread.h) | 0 | ||||
-rw-r--r-- | thirdparty/libwebp/utils/utils.c | 37 | ||||
-rw-r--r-- | thirdparty/libwebp/utils/utils.h | 50 |
26 files changed, 157 insertions, 109 deletions
diff --git a/thirdparty/libwebp/utils/bit_reader_inl.h b/thirdparty/libwebp/utils/bit_reader_inl_utils.h index 99ed3137d2..fd7fb0446c 100644 --- a/thirdparty/libwebp/utils/bit_reader_inl.h +++ b/thirdparty/libwebp/utils/bit_reader_inl_utils.h @@ -20,13 +20,12 @@ #include "../webp/config.h" #endif -#ifdef WEBP_FORCE_ALIGNED -#include <string.h> // memcpy -#endif +#include <string.h> // for memcpy #include "../dsp/dsp.h" -#include "./bit_reader.h" -#include "./endian_inl.h" +#include "./bit_reader_utils.h" +#include "./endian_inl_utils.h" +#include "./utils.h" #ifdef __cplusplus extern "C" { @@ -62,10 +61,7 @@ void VP8LoadNewBytes(VP8BitReader* const br) { if (br->buf_ < br->buf_max_) { // convert memory type to register type (with some zero'ing!) bit_t bits; -#if defined(WEBP_FORCE_ALIGNED) - lbit_t in_bits; - memcpy(&in_bits, br->buf_, sizeof(in_bits)); -#elif defined(WEBP_USE_MIPS32) +#if defined(WEBP_USE_MIPS32) // This is needed because of un-aligned read. lbit_t in_bits; lbit_t* p_buf_ = (lbit_t*)br->buf_; @@ -80,7 +76,8 @@ void VP8LoadNewBytes(VP8BitReader* const br) { : "memory", "at" ); #else - const lbit_t in_bits = *(const lbit_t*)br->buf_; + lbit_t in_bits; + memcpy(&in_bits, br->buf_, sizeof(in_bits)); #endif br->buf_ += BITS >> 3; #if !defined(WORDS_BIGENDIAN) @@ -119,37 +116,26 @@ static WEBP_INLINE int VP8GetBit(VP8BitReader* const br, int prob) { const int pos = br->bits_; const range_t split = (range * prob) >> 8; const range_t value = (range_t)(br->value_ >> pos); -#if defined(__arm__) || defined(_M_ARM) // ARM-specific - const int bit = ((int)(split - value) >> 31) & 1; - if (value > split) { - range -= split + 1; - br->value_ -= (bit_t)(split + 1) << pos; - } else { - range = split; - } -#else // faster version on x86 - int bit; // Don't use 'const int bit = (value > split);", it's slower. - if (value > split) { - range -= split + 1; + const int bit = (value > split); + if (bit) { + range -= split; br->value_ -= (bit_t)(split + 1) << pos; - bit = 1; } else { - range = split; - bit = 0; + range = split + 1; } -#endif - if (range <= (range_t)0x7e) { - const int shift = kVP8Log2Range[range]; - range = kVP8NewRange[range]; + { + const int shift = 7 ^ BitsLog2Floor(range); + range <<= shift; br->bits_ -= shift; } - br->range_ = range; + br->range_ = range - 1; return bit; } } // simplified version of VP8GetBit() for prob=0x80 (note shift is always 1 here) -static WEBP_INLINE int VP8GetSigned(VP8BitReader* const br, int v) { +static WEBP_UBSAN_IGNORE_UNSIGNED_OVERFLOW WEBP_INLINE +int VP8GetSigned(VP8BitReader* const br, int v) { if (br->bits_ < 0) { VP8LoadNewBytes(br); } @@ -166,6 +152,37 @@ static WEBP_INLINE int VP8GetSigned(VP8BitReader* const br, int v) { } } +static WEBP_INLINE int VP8GetBitAlt(VP8BitReader* const br, int prob) { + // Don't move this declaration! It makes a big speed difference to store + // 'range' *before* calling VP8LoadNewBytes(), even if this function doesn't + // alter br->range_ value. + range_t range = br->range_; + if (br->bits_ < 0) { + VP8LoadNewBytes(br); + } + { + const int pos = br->bits_; + const range_t split = (range * prob) >> 8; + const range_t value = (range_t)(br->value_ >> pos); + int bit; // Don't use 'const int bit = (value > split);", it's slower. + if (value > split) { + range -= split + 1; + br->value_ -= (bit_t)(split + 1) << pos; + bit = 1; + } else { + range = split; + bit = 0; + } + if (range <= (range_t)0x7e) { + const int shift = kVP8Log2Range[range]; + range = kVP8NewRange[range]; + br->bits_ -= shift; + } + br->range_ = range; + return bit; + } +} + #ifdef __cplusplus } // extern "C" #endif diff --git a/thirdparty/libwebp/utils/bit_reader.c b/thirdparty/libwebp/utils/bit_reader_utils.c index 2eb46e0b4b..053b710bb8 100644 --- a/thirdparty/libwebp/utils/bit_reader.c +++ b/thirdparty/libwebp/utils/bit_reader_utils.c @@ -15,7 +15,7 @@ #include "../webp/config.h" #endif -#include "./bit_reader_inl.h" +#include "./bit_reader_inl_utils.h" #include "../utils/utils.h" //------------------------------------------------------------------------------ diff --git a/thirdparty/libwebp/utils/bit_reader.h b/thirdparty/libwebp/utils/bit_reader_utils.h index ea5c584eb4..ea5c584eb4 100644 --- a/thirdparty/libwebp/utils/bit_reader.h +++ b/thirdparty/libwebp/utils/bit_reader_utils.h diff --git a/thirdparty/libwebp/utils/bit_writer.c b/thirdparty/libwebp/utils/bit_writer_utils.c index 064428691b..ab0c49dce8 100644 --- a/thirdparty/libwebp/utils/bit_writer.c +++ b/thirdparty/libwebp/utils/bit_writer_utils.c @@ -16,8 +16,8 @@ #include <string.h> // for memcpy() #include <stdlib.h> -#include "./bit_writer.h" -#include "./endian_inl.h" +#include "./bit_writer_utils.h" +#include "./endian_inl_utils.h" #include "./utils.h" //------------------------------------------------------------------------------ @@ -143,13 +143,13 @@ int VP8PutBitUniform(VP8BitWriter* const bw, int bit) { void VP8PutBits(VP8BitWriter* const bw, uint32_t value, int nb_bits) { uint32_t mask; assert(nb_bits > 0 && nb_bits < 32); - for (mask = 1u << (nb_bits - 1); mask; mask >>= 1) + for (mask = 1u << (nb_bits - 1); mask; mask >>= 1) { VP8PutBitUniform(bw, value & mask); + } } void VP8PutSignedBits(VP8BitWriter* const bw, int value, int nb_bits) { - if (!VP8PutBitUniform(bw, value != 0)) - return; + if (!VP8PutBitUniform(bw, value != 0)) return; if (value < 0) { VP8PutBits(bw, ((-value) << 1) | 1, nb_bits + 1); } else { diff --git a/thirdparty/libwebp/utils/bit_writer.h b/thirdparty/libwebp/utils/bit_writer_utils.h index ef360d1dc6..9c02bbc06d 100644 --- a/thirdparty/libwebp/utils/bit_writer.h +++ b/thirdparty/libwebp/utils/bit_writer_utils.h @@ -54,7 +54,8 @@ int VP8BitWriterAppend(VP8BitWriter* const bw, // return approximate write position (in bits) static WEBP_INLINE uint64_t VP8BitWriterPos(const VP8BitWriter* const bw) { - return (uint64_t)(bw->pos_ + bw->run_) * 8 + 8 + bw->nb_bits_; + const uint64_t nb_bits = 8 + bw->nb_bits_; // bw->nb_bits_ is <= 0, note + return (bw->pos_ + bw->run_) * 8 + nb_bits; } // Returns a pointer to the internal buffer. diff --git a/thirdparty/libwebp/utils/color_cache.c b/thirdparty/libwebp/utils/color_cache_utils.c index c34b2e7f1a..0172590c48 100644 --- a/thirdparty/libwebp/utils/color_cache.c +++ b/thirdparty/libwebp/utils/color_cache_utils.c @@ -14,7 +14,7 @@ #include <assert.h> #include <stdlib.h> #include <string.h> -#include "./color_cache.h" +#include "./color_cache_utils.h" #include "./utils.h" //------------------------------------------------------------------------------ diff --git a/thirdparty/libwebp/utils/color_cache.h b/thirdparty/libwebp/utils/color_cache_utils.h index a9a9f64270..c373e6b361 100644 --- a/thirdparty/libwebp/utils/color_cache.h +++ b/thirdparty/libwebp/utils/color_cache_utils.h @@ -28,7 +28,11 @@ typedef struct { int hash_bits_; } VP8LColorCache; -static const uint32_t kHashMul = 0x1e35a7bd; +static const uint64_t kHashMul = 0x1e35a7bdull; + +static WEBP_INLINE int HashPix(uint32_t argb, int shift) { + return (int)(((argb * kHashMul) & 0xffffffffu) >> shift); +} static WEBP_INLINE uint32_t VP8LColorCacheLookup( const VP8LColorCache* const cc, uint32_t key) { @@ -44,19 +48,20 @@ static WEBP_INLINE void VP8LColorCacheSet(const VP8LColorCache* const cc, static WEBP_INLINE void VP8LColorCacheInsert(const VP8LColorCache* const cc, uint32_t argb) { - const uint32_t key = (kHashMul * argb) >> cc->hash_shift_; + const int key = HashPix(argb, cc->hash_shift_); cc->colors_[key] = argb; } static WEBP_INLINE int VP8LColorCacheGetIndex(const VP8LColorCache* const cc, uint32_t argb) { - return (kHashMul * argb) >> cc->hash_shift_; + return HashPix(argb, cc->hash_shift_); } +// Return the key if cc contains argb, and -1 otherwise. static WEBP_INLINE int VP8LColorCacheContains(const VP8LColorCache* const cc, uint32_t argb) { - const uint32_t key = (kHashMul * argb) >> cc->hash_shift_; - return (cc->colors_[key] == argb); + const int key = HashPix(argb, cc->hash_shift_); + return (cc->colors_[key] == argb) ? key : -1; } //------------------------------------------------------------------------------ diff --git a/thirdparty/libwebp/utils/endian_inl.h b/thirdparty/libwebp/utils/endian_inl_utils.h index e11260ff7d..e11260ff7d 100644 --- a/thirdparty/libwebp/utils/endian_inl.h +++ b/thirdparty/libwebp/utils/endian_inl_utils.h diff --git a/thirdparty/libwebp/utils/filters.c b/thirdparty/libwebp/utils/filters_utils.c index 15543b1271..49c1d18a22 100644 --- a/thirdparty/libwebp/utils/filters.c +++ b/thirdparty/libwebp/utils/filters_utils.c @@ -11,7 +11,7 @@ // // Author: Urvang (urvang@google.com) -#include "./filters.h" +#include "./filters_utils.h" #include <stdlib.h> #include <string.h> diff --git a/thirdparty/libwebp/utils/filters.h b/thirdparty/libwebp/utils/filters_utils.h index 088b132fc5..088b132fc5 100644 --- a/thirdparty/libwebp/utils/filters.h +++ b/thirdparty/libwebp/utils/filters_utils.h diff --git a/thirdparty/libwebp/utils/huffman_encode.c b/thirdparty/libwebp/utils/huffman_encode_utils.c index 4e5ef6b447..f9504658ea 100644 --- a/thirdparty/libwebp/utils/huffman_encode.c +++ b/thirdparty/libwebp/utils/huffman_encode_utils.c @@ -14,7 +14,7 @@ #include <assert.h> #include <stdlib.h> #include <string.h> -#include "./huffman_encode.h" +#include "./huffman_encode_utils.h" #include "./utils.h" #include "../webp/format_constants.h" diff --git a/thirdparty/libwebp/utils/huffman_encode.h b/thirdparty/libwebp/utils/huffman_encode_utils.h index a157165148..a157165148 100644 --- a/thirdparty/libwebp/utils/huffman_encode.h +++ b/thirdparty/libwebp/utils/huffman_encode_utils.h diff --git a/thirdparty/libwebp/utils/huffman.c b/thirdparty/libwebp/utils/huffman_utils.c index 36e5502836..008b5d746f 100644 --- a/thirdparty/libwebp/utils/huffman.c +++ b/thirdparty/libwebp/utils/huffman_utils.c @@ -14,7 +14,7 @@ #include <assert.h> #include <stdlib.h> #include <string.h> -#include "./huffman.h" +#include "./huffman_utils.h" #include "./utils.h" #include "../webp/format_constants.h" @@ -45,7 +45,7 @@ static WEBP_INLINE uint32_t GetNextKey(uint32_t key, int len) { while (key & step) { step >>= 1; } - return (key & (step - 1)) + step; + return step ? (key & (step - 1)) + step : key; } // Stores code in table[0], table[step], table[2*step], ..., table[end]. @@ -75,11 +75,13 @@ static WEBP_INLINE int NextTableBitSize(const int* const count, return len - root_bits; } -int VP8LBuildHuffmanTable(HuffmanCode* const root_table, int root_bits, - const int code_lengths[], int code_lengths_size) { +// sorted[code_lengths_size] is a pre-allocated array for sorting symbols +// by code length. +static int BuildHuffmanTable(HuffmanCode* const root_table, int root_bits, + const int code_lengths[], int code_lengths_size, + uint16_t sorted[]) { HuffmanCode* table = root_table; // next available space in table int total_size = 1 << root_bits; // total size root table + 2nd level table - int* sorted = NULL; // symbols sorted by code length int len; // current code length int symbol; // symbol index in original or sorted table // number of codes of each length: @@ -114,11 +116,6 @@ int VP8LBuildHuffmanTable(HuffmanCode* const root_table, int root_bits, offset[len + 1] = offset[len] + count[len]; } - sorted = (int*)WebPSafeMalloc(code_lengths_size, sizeof(*sorted)); - if (sorted == NULL) { - return 0; - } - // Sort symbols by length, by symbol order within each length. for (symbol = 0; symbol < code_lengths_size; ++symbol) { const int symbol_code_length = code_lengths[symbol]; @@ -133,7 +130,6 @@ int VP8LBuildHuffmanTable(HuffmanCode* const root_table, int root_bits, code.bits = 0; code.value = (uint16_t)sorted[0]; ReplicateValue(table, 1, total_size, code); - WebPSafeFree(sorted); return total_size; } @@ -153,7 +149,6 @@ int VP8LBuildHuffmanTable(HuffmanCode* const root_table, int root_bits, num_nodes += num_open; num_open -= count[len]; if (num_open < 0) { - WebPSafeFree(sorted); return 0; } for (; count[len] > 0; --count[len]) { @@ -172,7 +167,6 @@ int VP8LBuildHuffmanTable(HuffmanCode* const root_table, int root_bits, num_nodes += num_open; num_open -= count[len]; if (num_open < 0) { - WebPSafeFree(sorted); return 0; } for (; count[len] > 0; --count[len]) { @@ -195,11 +189,35 @@ int VP8LBuildHuffmanTable(HuffmanCode* const root_table, int root_bits, // Check if tree is full. if (num_nodes != 2 * offset[MAX_ALLOWED_CODE_LENGTH] - 1) { - WebPSafeFree(sorted); return 0; } } - WebPSafeFree(sorted); + return total_size; +} + +// Maximum code_lengths_size is 2328 (reached for 11-bit color_cache_bits). +// More commonly, the value is around ~280. +#define MAX_CODE_LENGTHS_SIZE \ + ((1 << MAX_CACHE_BITS) + NUM_LITERAL_CODES + NUM_LENGTH_CODES) +// Cut-off value for switching between heap and stack allocation. +#define SORTED_SIZE_CUTOFF 512 +int VP8LBuildHuffmanTable(HuffmanCode* const root_table, int root_bits, + const int code_lengths[], int code_lengths_size) { + int total_size; + assert(code_lengths_size <= MAX_CODE_LENGTHS_SIZE); + if (code_lengths_size <= SORTED_SIZE_CUTOFF) { + // use local stack-allocated array. + uint16_t sorted[SORTED_SIZE_CUTOFF]; + total_size = BuildHuffmanTable(root_table, root_bits, + code_lengths, code_lengths_size, sorted); + } else { // rare case. Use heap allocation. + uint16_t* const sorted = + (uint16_t*)WebPSafeMalloc(code_lengths_size, sizeof(*sorted)); + if (sorted == NULL) return 0; + total_size = BuildHuffmanTable(root_table, root_bits, + code_lengths, code_lengths_size, sorted); + WebPSafeFree(sorted); + } return total_size; } diff --git a/thirdparty/libwebp/utils/huffman.h b/thirdparty/libwebp/utils/huffman_utils.h index c6dd6aaa45..c6dd6aaa45 100644 --- a/thirdparty/libwebp/utils/huffman.h +++ b/thirdparty/libwebp/utils/huffman_utils.h diff --git a/thirdparty/libwebp/utils/quant_levels_dec.c b/thirdparty/libwebp/utils/quant_levels_dec_utils.c index ee0a3fe127..d4d23d3147 100644 --- a/thirdparty/libwebp/utils/quant_levels_dec.c +++ b/thirdparty/libwebp/utils/quant_levels_dec_utils.c @@ -14,7 +14,7 @@ // // Author: Skal (pascal.massimino@gmail.com) -#include "./quant_levels_dec.h" +#include "./quant_levels_dec_utils.h" #include <string.h> // for memset diff --git a/thirdparty/libwebp/utils/quant_levels_dec.h b/thirdparty/libwebp/utils/quant_levels_dec_utils.h index 59a13495d3..59a13495d3 100644 --- a/thirdparty/libwebp/utils/quant_levels_dec.h +++ b/thirdparty/libwebp/utils/quant_levels_dec_utils.h diff --git a/thirdparty/libwebp/utils/quant_levels.c b/thirdparty/libwebp/utils/quant_levels_utils.c index d7c8aab922..73174e8ab9 100644 --- a/thirdparty/libwebp/utils/quant_levels.c +++ b/thirdparty/libwebp/utils/quant_levels_utils.c @@ -14,7 +14,7 @@ #include <assert.h> -#include "./quant_levels.h" +#include "./quant_levels_utils.h" #define NUM_SYMBOLS 256 diff --git a/thirdparty/libwebp/utils/quant_levels.h b/thirdparty/libwebp/utils/quant_levels_utils.h index 1cb5a32cae..1cb5a32cae 100644 --- a/thirdparty/libwebp/utils/quant_levels.h +++ b/thirdparty/libwebp/utils/quant_levels_utils.h diff --git a/thirdparty/libwebp/utils/random.c b/thirdparty/libwebp/utils/random_utils.c index 24e96ad648..9f1e4154a6 100644 --- a/thirdparty/libwebp/utils/random.c +++ b/thirdparty/libwebp/utils/random_utils.c @@ -12,7 +12,7 @@ // Author: Skal (pascal.massimino@gmail.com) #include <string.h> -#include "./random.h" +#include "./random_utils.h" //------------------------------------------------------------------------------ diff --git a/thirdparty/libwebp/utils/random.h b/thirdparty/libwebp/utils/random_utils.h index c392a615ca..c392a615ca 100644 --- a/thirdparty/libwebp/utils/random.h +++ b/thirdparty/libwebp/utils/random_utils.h diff --git a/thirdparty/libwebp/utils/rescaler.c b/thirdparty/libwebp/utils/rescaler_utils.c index d2278a52ff..0d1f80da24 100644 --- a/thirdparty/libwebp/utils/rescaler.c +++ b/thirdparty/libwebp/utils/rescaler_utils.c @@ -15,7 +15,7 @@ #include <stdlib.h> #include <string.h> #include "../dsp/dsp.h" -#include "./rescaler.h" +#include "./rescaler_utils.h" //------------------------------------------------------------------------------ diff --git a/thirdparty/libwebp/utils/rescaler.h b/thirdparty/libwebp/utils/rescaler_utils.h index 98b01a76d0..98b01a76d0 100644 --- a/thirdparty/libwebp/utils/rescaler.h +++ b/thirdparty/libwebp/utils/rescaler_utils.h diff --git a/thirdparty/libwebp/utils/thread.c b/thirdparty/libwebp/utils/thread_utils.c index 93f7622797..1729060c70 100644 --- a/thirdparty/libwebp/utils/thread.c +++ b/thirdparty/libwebp/utils/thread_utils.c @@ -13,7 +13,7 @@ #include <assert.h> #include <string.h> // for memset() -#include "./thread.h" +#include "./thread_utils.h" #include "./utils.h" #ifdef WEBP_USE_THREAD @@ -183,8 +183,7 @@ static int pthread_cond_wait(pthread_cond_t* const condition, #else // note that there is a consumer available so the signal isn't dropped in // pthread_cond_signal - if (!ReleaseSemaphore(condition->waiting_sem_, 1, NULL)) - return 1; + if (!ReleaseSemaphore(condition->waiting_sem_, 1, NULL)) return 1; // now unlock the mutex so pthread_cond_signal may be issued pthread_mutex_unlock(mutex); ok = (WaitForSingleObject(condition->signal_event_, INFINITE) == @@ -226,8 +225,7 @@ static THREADFN ThreadLoop(void* ptr) { } // main thread state control -static void ChangeState(WebPWorker* const worker, - WebPWorkerStatus new_status) { +static void ChangeState(WebPWorker* const worker, WebPWorkerStatus new_status) { // No-op when attempting to change state on a thread that didn't come up. // Checking status_ without acquiring the lock first would result in a data // race. diff --git a/thirdparty/libwebp/utils/thread.h b/thirdparty/libwebp/utils/thread_utils.h index 8408311855..8408311855 100644 --- a/thirdparty/libwebp/utils/thread.h +++ b/thirdparty/libwebp/utils/thread_utils.h diff --git a/thirdparty/libwebp/utils/utils.c b/thirdparty/libwebp/utils/utils.c index 82dbf8d5e5..504d924b60 100644 --- a/thirdparty/libwebp/utils/utils.c +++ b/thirdparty/libwebp/utils/utils.c @@ -25,7 +25,7 @@ // http://valgrind.org/docs/manual/ms-manual.html // Here is an example command line: /* valgrind --tool=massif --massif-out-file=massif.out \ - --stacks=yes --alloc-fn=WebPSafeAlloc --alloc-fn=WebPSafeCalloc + --stacks=yes --alloc-fn=WebPSafeMalloc --alloc-fn=WebPSafeCalloc ms_print massif.out */ // In addition: @@ -243,8 +243,7 @@ void WebPCopyPixels(const WebPPicture* const src, WebPPicture* const dst) { //------------------------------------------------------------------------------ -#define MAX_COLOR_COUNT MAX_PALETTE_SIZE -#define COLOR_HASH_SIZE (MAX_COLOR_COUNT * 4) +#define COLOR_HASH_SIZE (MAX_PALETTE_SIZE * 4) #define COLOR_HASH_RIGHT_SHIFT 22 // 32 - log2(COLOR_HASH_SIZE). int WebPGetColorPalette(const WebPPicture* const pic, uint32_t* const palette) { @@ -253,7 +252,7 @@ int WebPGetColorPalette(const WebPPicture* const pic, uint32_t* const palette) { int num_colors = 0; uint8_t in_use[COLOR_HASH_SIZE] = { 0 }; uint32_t colors[COLOR_HASH_SIZE]; - static const uint32_t kHashMul = 0x1e35a7bdU; + static const uint64_t kHashMul = 0x1e35a7bdull; const uint32_t* argb = pic->argb; const int width = pic->width; const int height = pic->height; @@ -268,14 +267,14 @@ int WebPGetColorPalette(const WebPPicture* const pic, uint32_t* const palette) { continue; } last_pix = argb[x]; - key = (kHashMul * last_pix) >> COLOR_HASH_RIGHT_SHIFT; + key = ((last_pix * kHashMul) & 0xffffffffu) >> COLOR_HASH_RIGHT_SHIFT; while (1) { if (!in_use[key]) { colors[key] = last_pix; in_use[key] = 1; ++num_colors; - if (num_colors > MAX_COLOR_COUNT) { - return MAX_COLOR_COUNT + 1; // Exact count not needed. + if (num_colors > MAX_PALETTE_SIZE) { + return MAX_PALETTE_SIZE + 1; // Exact count not needed. } break; } else if (colors[key] == last_pix) { @@ -302,8 +301,30 @@ int WebPGetColorPalette(const WebPPicture* const pic, uint32_t* const palette) { return num_colors; } -#undef MAX_COLOR_COUNT #undef COLOR_HASH_SIZE #undef COLOR_HASH_RIGHT_SHIFT //------------------------------------------------------------------------------ + +#if defined(WEBP_NEED_LOG_TABLE_8BIT) +const uint8_t WebPLogTable8bit[256] = { // 31 ^ clz(i) + 0, 0, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, + 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, + 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, + 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7 +}; +#endif + +//------------------------------------------------------------------------------ diff --git a/thirdparty/libwebp/utils/utils.h b/thirdparty/libwebp/utils/utils.h index 3a5d4e6a78..3ab459050a 100644 --- a/thirdparty/libwebp/utils/utils.h +++ b/thirdparty/libwebp/utils/utils.h @@ -62,7 +62,6 @@ WEBP_EXTERN(void) WebPSafeFree(void* const ptr); #define WEBP_ALIGN_CST 31 #define WEBP_ALIGN(PTR) (((uintptr_t)(PTR) + WEBP_ALIGN_CST) & ~WEBP_ALIGN_CST) -#if defined(WEBP_FORCE_ALIGNED) #include <string.h> // memcpy() is the safe way of moving potentially unaligned 32b memory. static WEBP_INLINE uint32_t WebPMemToUint32(const uint8_t* const ptr) { @@ -73,16 +72,6 @@ static WEBP_INLINE uint32_t WebPMemToUint32(const uint8_t* const ptr) { static WEBP_INLINE void WebPUint32ToMem(uint8_t* const ptr, uint32_t val) { memcpy(ptr, &val, sizeof(val)); } -#else -static WEBP_UBSAN_IGNORE_UNDEF WEBP_INLINE -uint32_t WebPMemToUint32(const uint8_t* const ptr) { - return *(const uint32_t*)ptr; -} -static WEBP_UBSAN_IGNORE_UNDEF WEBP_INLINE -void WebPUint32ToMem(uint8_t* const ptr, uint32_t val) { - *(uint32_t*)ptr = val; -} -#endif //------------------------------------------------------------------------------ // Reading/writing data. @@ -118,6 +107,19 @@ static WEBP_INLINE void PutLE32(uint8_t* const data, uint32_t val) { PutLE16(data + 2, (int)(val >> 16)); } +// 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 +extern const uint8_t WebPLogTable8bit[256]; +static WEBP_INLINE int WebPLog2FloorC(uint32_t n) { + int log = 0; + while (n >= 256) { + log += 8; + n >>= 8; + } + return log + WebPLogTable8bit[n]; +} + // Returns (int)floor(log2(n)). n must be > 0. // use GNU builtins where available. #if defined(__GNUC__) && \ @@ -135,22 +137,8 @@ static WEBP_INLINE int BitsLog2Floor(uint32_t n) { _BitScanReverse(&first_set_bit, n); return first_set_bit; } -#else -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; -} +#else // default: use the C-version. +static WEBP_INLINE int BitsLog2Floor(uint32_t n) { return WebPLog2FloorC(n); } #endif //------------------------------------------------------------------------------ @@ -172,12 +160,12 @@ WEBP_EXTERN(void) WebPCopyPixels(const struct WebPPicture* const src, // Unique colors. // Returns count of unique colors in 'pic', assuming pic->use_argb is true. -// If the unique color count is more than MAX_COLOR_COUNT, returns -// MAX_COLOR_COUNT+1. +// If the unique color count is more than MAX_PALETTE_SIZE, returns +// MAX_PALETTE_SIZE+1. // If 'palette' is not NULL and number of unique colors is less than or equal to -// MAX_COLOR_COUNT, also outputs the actual unique colors into 'palette'. +// MAX_PALETTE_SIZE, also outputs the actual unique colors into 'palette'. // Note: 'palette' is assumed to be an array already allocated with at least -// MAX_COLOR_COUNT elements. +// MAX_PALETTE_SIZE elements. WEBP_EXTERN(int) WebPGetColorPalette(const struct WebPPicture* const pic, uint32_t* const palette); |