| 1 | // Copyright 2012 Google Inc. All Rights Reserved. | 
|---|
| 2 | // | 
|---|
| 3 | // Use of this source code is governed by a BSD-style license | 
|---|
| 4 | // that can be found in the COPYING file in the root of the source | 
|---|
| 5 | // tree. An additional intellectual property rights grant can be found | 
|---|
| 6 | // in the file PATENTS. All contributing project authors may | 
|---|
| 7 | // be found in the AUTHORS file in the root of the source tree. | 
|---|
| 8 | // ----------------------------------------------------------------------------- | 
|---|
| 9 | // | 
|---|
| 10 | // Misc. common utility functions | 
|---|
| 11 | // | 
|---|
| 12 | // Authors: Skal (pascal.massimino@gmail.com) | 
|---|
| 13 | //          Urvang (urvang@google.com) | 
|---|
| 14 |  | 
|---|
| 15 | #ifndef WEBP_UTILS_UTILS_H_ | 
|---|
| 16 | #define WEBP_UTILS_UTILS_H_ | 
|---|
| 17 |  | 
|---|
| 18 | #ifdef HAVE_CONFIG_H | 
|---|
| 19 | #include "../webp/config.h" | 
|---|
| 20 | #endif | 
|---|
| 21 |  | 
|---|
| 22 | #include <assert.h> | 
|---|
| 23 | #include <limits.h> | 
|---|
| 24 |  | 
|---|
| 25 | #include "../dsp/dsp.h" | 
|---|
| 26 | #include "../webp/types.h" | 
|---|
| 27 |  | 
|---|
| 28 | #ifdef __cplusplus | 
|---|
| 29 | extern "C"{ | 
|---|
| 30 | #endif | 
|---|
| 31 |  | 
|---|
| 32 | //------------------------------------------------------------------------------ | 
|---|
| 33 | // Memory allocation | 
|---|
| 34 |  | 
|---|
| 35 | // This is the maximum memory amount that libwebp will ever try to allocate. | 
|---|
| 36 | #ifndef WEBP_MAX_ALLOCABLE_MEMORY | 
|---|
| 37 | #if SIZE_MAX > (1ULL << 34) | 
|---|
| 38 | #define WEBP_MAX_ALLOCABLE_MEMORY (1ULL << 34) | 
|---|
| 39 | #else | 
|---|
| 40 | // For 32-bit targets keep this below INT_MAX to avoid valgrind warnings. | 
|---|
| 41 | #define WEBP_MAX_ALLOCABLE_MEMORY ((1ULL << 31) - (1 << 16)) | 
|---|
| 42 | #endif | 
|---|
| 43 | #endif  // WEBP_MAX_ALLOCABLE_MEMORY | 
|---|
| 44 |  | 
|---|
| 45 | // size-checking safe malloc/calloc: verify that the requested size is not too | 
|---|
| 46 | // large, or return NULL. You don't need to call these for constructs like | 
|---|
| 47 | // malloc(sizeof(foo)), but only if there's picture-dependent size involved | 
|---|
| 48 | // somewhere (like: malloc(num_pixels * sizeof(*something))). That's why this | 
|---|
| 49 | // safe malloc() borrows the signature from calloc(), pointing at the dangerous | 
|---|
| 50 | // underlying multiply involved. | 
|---|
| 51 | WEBP_EXTERN(void*) WebPSafeMalloc(uint64_t nmemb, size_t size); | 
|---|
| 52 | // Note that WebPSafeCalloc() expects the second argument type to be 'size_t' | 
|---|
| 53 | // in order to favor the "calloc(num_foo, sizeof(foo))" pattern. | 
|---|
| 54 | WEBP_EXTERN(void*) WebPSafeCalloc(uint64_t nmemb, size_t size); | 
|---|
| 55 |  | 
|---|
| 56 | // Companion deallocation function to the above allocations. | 
|---|
| 57 | WEBP_EXTERN(void) WebPSafeFree(void* const ptr); | 
|---|
| 58 |  | 
|---|
| 59 | //------------------------------------------------------------------------------ | 
|---|
| 60 | // Alignment | 
|---|
| 61 |  | 
|---|
| 62 | #define WEBP_ALIGN_CST 31 | 
|---|
| 63 | #define WEBP_ALIGN(PTR) (((uintptr_t)(PTR) + WEBP_ALIGN_CST) & ~WEBP_ALIGN_CST) | 
|---|
| 64 |  | 
|---|
| 65 | #include <string.h> | 
|---|
| 66 | // memcpy() is the safe way of moving potentially unaligned 32b memory. | 
|---|
| 67 | static WEBP_INLINE uint32_t WebPMemToUint32(const uint8_t* const ptr) { | 
|---|
| 68 | uint32_t A; | 
|---|
| 69 | memcpy(&A, (const int*)ptr, sizeof(A)); | 
|---|
| 70 | return A; | 
|---|
| 71 | } | 
|---|
| 72 | static WEBP_INLINE void WebPUint32ToMem(uint8_t* const ptr, uint32_t val) { | 
|---|
| 73 | memcpy(ptr, &val, sizeof(val)); | 
|---|
| 74 | } | 
|---|
| 75 |  | 
|---|
| 76 | //------------------------------------------------------------------------------ | 
|---|
| 77 | // Reading/writing data. | 
|---|
| 78 |  | 
|---|
| 79 | // Read 16, 24 or 32 bits stored in little-endian order. | 
|---|
| 80 | static WEBP_INLINE int GetLE16(const uint8_t* const data) { | 
|---|
| 81 | return (int)(data[0] << 0) | (data[1] << 8); | 
|---|
| 82 | } | 
|---|
| 83 |  | 
|---|
| 84 | static WEBP_INLINE int GetLE24(const uint8_t* const data) { | 
|---|
| 85 | return GetLE16(data) | (data[2] << 16); | 
|---|
| 86 | } | 
|---|
| 87 |  | 
|---|
| 88 | static WEBP_INLINE uint32_t GetLE32(const uint8_t* const data) { | 
|---|
| 89 | return GetLE16(data) | ((uint32_t)GetLE16(data + 2) << 16); | 
|---|
| 90 | } | 
|---|
| 91 |  | 
|---|
| 92 | // Store 16, 24 or 32 bits in little-endian order. | 
|---|
| 93 | static WEBP_INLINE void PutLE16(uint8_t* const data, int val) { | 
|---|
| 94 | assert(val < (1 << 16)); | 
|---|
| 95 | data[0] = (val >> 0); | 
|---|
| 96 | data[1] = (val >> 8); | 
|---|
| 97 | } | 
|---|
| 98 |  | 
|---|
| 99 | static WEBP_INLINE void PutLE24(uint8_t* const data, int val) { | 
|---|
| 100 | assert(val < (1 << 24)); | 
|---|
| 101 | PutLE16(data, val & 0xffff); | 
|---|
| 102 | data[2] = (val >> 16); | 
|---|
| 103 | } | 
|---|
| 104 |  | 
|---|
| 105 | static WEBP_INLINE void PutLE32(uint8_t* const data, uint32_t val) { | 
|---|
| 106 | PutLE16(data, (int)(val & 0xffff)); | 
|---|
| 107 | PutLE16(data + 2, (int)(val >> 16)); | 
|---|
| 108 | } | 
|---|
| 109 |  | 
|---|
| 110 | // Returns 31 ^ clz(n) = log2(n). This is the default C-implementation, either | 
|---|
| 111 | // based on table or not. Can be used as fallback if clz() is not available. | 
|---|
| 112 | #define WEBP_NEED_LOG_TABLE_8BIT | 
|---|
| 113 | extern const uint8_t WebPLogTable8bit[256]; | 
|---|
| 114 | static WEBP_INLINE int WebPLog2FloorC(uint32_t n) { | 
|---|
| 115 | int log = 0; | 
|---|
| 116 | while (n >= 256) { | 
|---|
| 117 | log += 8; | 
|---|
| 118 | n >>= 8; | 
|---|
| 119 | } | 
|---|
| 120 | return log + WebPLogTable8bit[n]; | 
|---|
| 121 | } | 
|---|
| 122 |  | 
|---|
| 123 | // Returns (int)floor(log2(n)). n must be > 0. | 
|---|
| 124 | // use GNU builtins where available. | 
|---|
| 125 | #if defined(__GNUC__) && \ | 
|---|
| 126 | ((__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || __GNUC__ >= 4) | 
|---|
| 127 | static WEBP_INLINE int BitsLog2Floor(uint32_t n) { | 
|---|
| 128 | return 31 ^ __builtin_clz(n); | 
|---|
| 129 | } | 
|---|
| 130 | #elif defined(_MSC_VER) && _MSC_VER > 1310 && \ | 
|---|
| 131 | (defined(_M_X64) || defined(_M_IX86)) | 
|---|
| 132 | #include <intrin.h> | 
|---|
| 133 | #pragma intrinsic(_BitScanReverse) | 
|---|
| 134 |  | 
|---|
| 135 | static WEBP_INLINE int BitsLog2Floor(uint32_t n) { | 
|---|
| 136 | unsigned long first_set_bit; | 
|---|
| 137 | _BitScanReverse(&first_set_bit, n); | 
|---|
| 138 | return first_set_bit; | 
|---|
| 139 | } | 
|---|
| 140 | #else   // default: use the C-version. | 
|---|
| 141 | static WEBP_INLINE int BitsLog2Floor(uint32_t n) { return WebPLog2FloorC(n); } | 
|---|
| 142 | #endif | 
|---|
| 143 |  | 
|---|
| 144 | //------------------------------------------------------------------------------ | 
|---|
| 145 | // Pixel copying. | 
|---|
| 146 |  | 
|---|
| 147 | struct WebPPicture; | 
|---|
| 148 |  | 
|---|
| 149 | // Copy width x height pixels from 'src' to 'dst' honoring the strides. | 
|---|
| 150 | WEBP_EXTERN(void) WebPCopyPlane(const uint8_t* src, int src_stride, | 
|---|
| 151 | uint8_t* dst, int dst_stride, | 
|---|
| 152 | int width, int height); | 
|---|
| 153 |  | 
|---|
| 154 | // Copy ARGB pixels from 'src' to 'dst' honoring strides. 'src' and 'dst' are | 
|---|
| 155 | // assumed to be already allocated and using ARGB data. | 
|---|
| 156 | WEBP_EXTERN(void) WebPCopyPixels(const struct WebPPicture* const src, | 
|---|
| 157 | struct WebPPicture* const dst); | 
|---|
| 158 |  | 
|---|
| 159 | //------------------------------------------------------------------------------ | 
|---|
| 160 | // Unique colors. | 
|---|
| 161 |  | 
|---|
| 162 | // Returns count of unique colors in 'pic', assuming pic->use_argb is true. | 
|---|
| 163 | // If the unique color count is more than MAX_PALETTE_SIZE, returns | 
|---|
| 164 | // MAX_PALETTE_SIZE+1. | 
|---|
| 165 | // If 'palette' is not NULL and number of unique colors is less than or equal to | 
|---|
| 166 | // MAX_PALETTE_SIZE, also outputs the actual unique colors into 'palette'. | 
|---|
| 167 | // Note: 'palette' is assumed to be an array already allocated with at least | 
|---|
| 168 | // MAX_PALETTE_SIZE elements. | 
|---|
| 169 | WEBP_EXTERN(int) WebPGetColorPalette(const struct WebPPicture* const pic, | 
|---|
| 170 | uint32_t* const palette); | 
|---|
| 171 |  | 
|---|
| 172 | //------------------------------------------------------------------------------ | 
|---|
| 173 |  | 
|---|
| 174 | #ifdef __cplusplus | 
|---|
| 175 | }    // extern "C" | 
|---|
| 176 | #endif | 
|---|
| 177 |  | 
|---|
| 178 | #endif  /* WEBP_UTILS_UTILS_H_ */ | 
|---|
| 179 |  | 
|---|