Path: blob/master/thirdparty/libwebp/src/utils/utils.h
9912 views
// Copyright 2012 Google Inc. All Rights Reserved.1//2// Use of this source code is governed by a BSD-style license3// that can be found in the COPYING file in the root of the source4// tree. An additional intellectual property rights grant can be found5// in the file PATENTS. All contributing project authors may6// be found in the AUTHORS file in the root of the source tree.7// -----------------------------------------------------------------------------8//9// Misc. common utility functions10//11// Authors: Skal ([email protected])12// Urvang ([email protected])1314#ifndef WEBP_UTILS_UTILS_H_15#define WEBP_UTILS_UTILS_H_1617#ifdef HAVE_CONFIG_H18#include "src/webp/config.h"19#endif2021#include <assert.h>2223#include "src/webp/types.h"2425#ifdef __cplusplus26extern "C" {27#endif2829//------------------------------------------------------------------------------30// Memory allocation3132// This is the maximum memory amount that libwebp will ever try to allocate.33#ifndef WEBP_MAX_ALLOCABLE_MEMORY34#if SIZE_MAX > (1ULL << 34)35#define WEBP_MAX_ALLOCABLE_MEMORY (1ULL << 34)36#else37// For 32-bit targets keep this below INT_MAX to avoid valgrind warnings.38#define WEBP_MAX_ALLOCABLE_MEMORY ((1ULL << 31) - (1 << 16))39#endif40#endif // WEBP_MAX_ALLOCABLE_MEMORY4142static WEBP_INLINE int CheckSizeOverflow(uint64_t size) {43return size == (size_t)size;44}4546// size-checking safe malloc/calloc: verify that the requested size is not too47// large, or return NULL. You don't need to call these for constructs like48// malloc(sizeof(foo)), but only if there's picture-dependent size involved49// somewhere (like: malloc(num_pixels * sizeof(*something))). That's why this50// safe malloc() borrows the signature from calloc(), pointing at the dangerous51// underlying multiply involved.52WEBP_EXTERN void* WebPSafeMalloc(uint64_t nmemb, size_t size);53// Note that WebPSafeCalloc() expects the second argument type to be 'size_t'54// in order to favor the "calloc(num_foo, sizeof(foo))" pattern.55WEBP_EXTERN void* WebPSafeCalloc(uint64_t nmemb, size_t size);5657// Companion deallocation function to the above allocations.58WEBP_EXTERN void WebPSafeFree(void* const ptr);5960//------------------------------------------------------------------------------61// Alignment6263#define WEBP_ALIGN_CST 3164#define WEBP_ALIGN(PTR) (((uintptr_t)(PTR) + WEBP_ALIGN_CST) & \65~(uintptr_t)WEBP_ALIGN_CST)6667#include <string.h>68// memcpy() is the safe way of moving potentially unaligned 32b memory.69static WEBP_INLINE uint32_t WebPMemToUint32(const uint8_t* const ptr) {70uint32_t A;71memcpy(&A, ptr, sizeof(A));72return A;73}7475static WEBP_INLINE int32_t WebPMemToInt32(const uint8_t* const ptr) {76return (int32_t)WebPMemToUint32(ptr);77}7879static WEBP_INLINE void WebPUint32ToMem(uint8_t* const ptr, uint32_t val) {80memcpy(ptr, &val, sizeof(val));81}8283static WEBP_INLINE void WebPInt32ToMem(uint8_t* const ptr, int val) {84WebPUint32ToMem(ptr, (uint32_t)val);85}8687//------------------------------------------------------------------------------88// Reading/writing data.8990// Read 16, 24 or 32 bits stored in little-endian order.91static WEBP_INLINE int GetLE16(const uint8_t* const data) {92return (int)(data[0] << 0) | (data[1] << 8);93}9495static WEBP_INLINE int GetLE24(const uint8_t* const data) {96return GetLE16(data) | (data[2] << 16);97}9899static WEBP_INLINE uint32_t GetLE32(const uint8_t* const data) {100return GetLE16(data) | ((uint32_t)GetLE16(data + 2) << 16);101}102103// Store 16, 24 or 32 bits in little-endian order.104static WEBP_INLINE void PutLE16(uint8_t* const data, int val) {105assert(val < (1 << 16));106data[0] = (val >> 0) & 0xff;107data[1] = (val >> 8) & 0xff;108}109110static WEBP_INLINE void PutLE24(uint8_t* const data, int val) {111assert(val < (1 << 24));112PutLE16(data, val & 0xffff);113data[2] = (val >> 16) & 0xff;114}115116static WEBP_INLINE void PutLE32(uint8_t* const data, uint32_t val) {117PutLE16(data, (int)(val & 0xffff));118PutLE16(data + 2, (int)(val >> 16));119}120121// use GNU builtins where available.122#if defined(__GNUC__) && \123((__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || __GNUC__ >= 4)124// Returns (int)floor(log2(n)). n must be > 0.125static WEBP_INLINE int BitsLog2Floor(uint32_t n) {126return 31 ^ __builtin_clz(n);127}128// counts the number of trailing zero129static WEBP_INLINE int BitsCtz(uint32_t n) { return __builtin_ctz(n); }130#elif defined(_MSC_VER) && _MSC_VER > 1310 && \131(defined(_M_X64) || defined(_M_IX86))132#include <intrin.h>133#pragma intrinsic(_BitScanReverse)134#pragma intrinsic(_BitScanForward)135136static WEBP_INLINE int BitsLog2Floor(uint32_t n) {137unsigned long first_set_bit; // NOLINT (runtime/int)138_BitScanReverse(&first_set_bit, n);139return first_set_bit;140}141static WEBP_INLINE int BitsCtz(uint32_t n) {142unsigned long first_set_bit; // NOLINT (runtime/int)143_BitScanForward(&first_set_bit, n);144return first_set_bit;145}146#else // default: use the (slow) C-version.147#define WEBP_HAVE_SLOW_CLZ_CTZ // signal that the Clz/Ctz function are slow148// Returns 31 ^ clz(n) = log2(n). This is the default C-implementation, either149// based on table or not. Can be used as fallback if clz() is not available.150#define WEBP_NEED_LOG_TABLE_8BIT151extern const uint8_t WebPLogTable8bit[256];152static WEBP_INLINE int WebPLog2FloorC(uint32_t n) {153int log_value = 0;154while (n >= 256) {155log_value += 8;156n >>= 8;157}158return log_value + WebPLogTable8bit[n];159}160161static WEBP_INLINE int BitsLog2Floor(uint32_t n) { return WebPLog2FloorC(n); }162163static WEBP_INLINE int BitsCtz(uint32_t n) {164int i;165for (i = 0; i < 32; ++i, n >>= 1) {166if (n & 1) return i;167}168return 32;169}170171#endif172173//------------------------------------------------------------------------------174// Pixel copying.175176struct WebPPicture;177178// Copy width x height pixels from 'src' to 'dst' honoring the strides.179WEBP_EXTERN void WebPCopyPlane(const uint8_t* src, int src_stride,180uint8_t* dst, int dst_stride,181int width, int height);182183// Copy ARGB pixels from 'src' to 'dst' honoring strides. 'src' and 'dst' are184// assumed to be already allocated and using ARGB data.185WEBP_EXTERN void WebPCopyPixels(const struct WebPPicture* const src,186struct WebPPicture* const dst);187188//------------------------------------------------------------------------------189// Unique colors.190191// Returns count of unique colors in 'pic', assuming pic->use_argb is true.192// If the unique color count is more than MAX_PALETTE_SIZE, returns193// MAX_PALETTE_SIZE+1.194// If 'palette' is not NULL and number of unique colors is less than or equal to195// MAX_PALETTE_SIZE, also outputs the actual unique colors into 'palette'.196// Note: 'palette' is assumed to be an array already allocated with at least197// MAX_PALETTE_SIZE elements.198// TODO(vrabaud) remove whenever we can break the ABI.199WEBP_EXTERN int WebPGetColorPalette(const struct WebPPicture* const pic,200uint32_t* const palette);201202//------------------------------------------------------------------------------203204#ifdef __cplusplus205} // extern "C"206#endif207208#endif // WEBP_UTILS_UTILS_H_209210211