1a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora// Copyright 2012 Google Inc. All Rights Reserved.
2a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora//
30406ce1417f76f2034833414dcecc9f56253640cVikas Arora// Use of this source code is governed by a BSD-style license
40406ce1417f76f2034833414dcecc9f56253640cVikas Arora// that can be found in the COPYING file in the root of the source
50406ce1417f76f2034833414dcecc9f56253640cVikas Arora// tree. An additional intellectual property rights grant can be found
60406ce1417f76f2034833414dcecc9f56253640cVikas Arora// in the file PATENTS. All contributing project authors may
70406ce1417f76f2034833414dcecc9f56253640cVikas Arora// be found in the AUTHORS file in the root of the source tree.
8a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora// -----------------------------------------------------------------------------
9a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora//
10a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora// Misc. common utility functions
11a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora//
121e7bf8805bd030c19924a5306837ecd72c295751Vikas Arora// Authors: Skal (pascal.massimino@gmail.com)
131e7bf8805bd030c19924a5306837ecd72c295751Vikas Arora//          Urvang (urvang@google.com)
14a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora
15a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora#ifndef WEBP_UTILS_UTILS_H_
16a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora#define WEBP_UTILS_UTILS_H_
17a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora
181e7bf8805bd030c19924a5306837ecd72c295751Vikas Arora#include <assert.h>
191e7bf8805bd030c19924a5306837ecd72c295751Vikas Arora
20a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora#include "webp/types.h"
21a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora
228b720228d581a84fd173b6dcb2fa295b59db489aVikas Arora#ifdef __cplusplus
23a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Aroraextern "C" {
24a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora#endif
25a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora
26a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora//------------------------------------------------------------------------------
27a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora// Memory allocation
28a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora
29a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora// This is the maximum memory amount that libwebp will ever try to allocate.
30a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora#define WEBP_MAX_ALLOCABLE_MEMORY (1ULL << 40)
31a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora
32a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora// size-checking safe malloc/calloc: verify that the requested size is not too
33a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora// large, or return NULL. You don't need to call these for constructs like
34a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora// malloc(sizeof(foo)), but only if there's picture-dependent size involved
35a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora// somewhere (like: malloc(num_pixels * sizeof(*something))). That's why this
36a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora// safe malloc() borrows the signature from calloc(), pointing at the dangerous
37a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora// underlying multiply involved.
38af51b94a435132e9014c324e25fb686b3d07a8c8Vikas AroraWEBP_EXTERN(void*) WebPSafeMalloc(uint64_t nmemb, size_t size);
39a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora// Note that WebPSafeCalloc() expects the second argument type to be 'size_t'
40a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora// in order to favor the "calloc(num_foo, sizeof(foo))" pattern.
41af51b94a435132e9014c324e25fb686b3d07a8c8Vikas AroraWEBP_EXTERN(void*) WebPSafeCalloc(uint64_t nmemb, size_t size);
42af51b94a435132e9014c324e25fb686b3d07a8c8Vikas Arora
43af51b94a435132e9014c324e25fb686b3d07a8c8Vikas Arora// Companion deallocation function to the above allocations.
44af51b94a435132e9014c324e25fb686b3d07a8c8Vikas AroraWEBP_EXTERN(void) WebPSafeFree(void* const ptr);
45a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora
46a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora//------------------------------------------------------------------------------
471e7bf8805bd030c19924a5306837ecd72c295751Vikas Arora// Reading/writing data.
481e7bf8805bd030c19924a5306837ecd72c295751Vikas Arora
491e7bf8805bd030c19924a5306837ecd72c295751Vikas Arora// Read 16, 24 or 32 bits stored in little-endian order.
501e7bf8805bd030c19924a5306837ecd72c295751Vikas Arorastatic WEBP_INLINE int GetLE16(const uint8_t* const data) {
511e7bf8805bd030c19924a5306837ecd72c295751Vikas Arora  return (int)(data[0] << 0) | (data[1] << 8);
521e7bf8805bd030c19924a5306837ecd72c295751Vikas Arora}
531e7bf8805bd030c19924a5306837ecd72c295751Vikas Arora
541e7bf8805bd030c19924a5306837ecd72c295751Vikas Arorastatic WEBP_INLINE int GetLE24(const uint8_t* const data) {
551e7bf8805bd030c19924a5306837ecd72c295751Vikas Arora  return GetLE16(data) | (data[2] << 16);
561e7bf8805bd030c19924a5306837ecd72c295751Vikas Arora}
571e7bf8805bd030c19924a5306837ecd72c295751Vikas Arora
581e7bf8805bd030c19924a5306837ecd72c295751Vikas Arorastatic WEBP_INLINE uint32_t GetLE32(const uint8_t* const data) {
591e7bf8805bd030c19924a5306837ecd72c295751Vikas Arora  return (uint32_t)GetLE16(data) | (GetLE16(data + 2) << 16);
601e7bf8805bd030c19924a5306837ecd72c295751Vikas Arora}
611e7bf8805bd030c19924a5306837ecd72c295751Vikas Arora
621e7bf8805bd030c19924a5306837ecd72c295751Vikas Arora// Store 16, 24 or 32 bits in little-endian order.
631e7bf8805bd030c19924a5306837ecd72c295751Vikas Arorastatic WEBP_INLINE void PutLE16(uint8_t* const data, int val) {
641e7bf8805bd030c19924a5306837ecd72c295751Vikas Arora  assert(val < (1 << 16));
651e7bf8805bd030c19924a5306837ecd72c295751Vikas Arora  data[0] = (val >> 0);
661e7bf8805bd030c19924a5306837ecd72c295751Vikas Arora  data[1] = (val >> 8);
671e7bf8805bd030c19924a5306837ecd72c295751Vikas Arora}
681e7bf8805bd030c19924a5306837ecd72c295751Vikas Arora
691e7bf8805bd030c19924a5306837ecd72c295751Vikas Arorastatic WEBP_INLINE void PutLE24(uint8_t* const data, int val) {
701e7bf8805bd030c19924a5306837ecd72c295751Vikas Arora  assert(val < (1 << 24));
711e7bf8805bd030c19924a5306837ecd72c295751Vikas Arora  PutLE16(data, val & 0xffff);
721e7bf8805bd030c19924a5306837ecd72c295751Vikas Arora  data[2] = (val >> 16);
731e7bf8805bd030c19924a5306837ecd72c295751Vikas Arora}
741e7bf8805bd030c19924a5306837ecd72c295751Vikas Arora
751e7bf8805bd030c19924a5306837ecd72c295751Vikas Arorastatic WEBP_INLINE void PutLE32(uint8_t* const data, uint32_t val) {
761e7bf8805bd030c19924a5306837ecd72c295751Vikas Arora  PutLE16(data, (int)(val & 0xffff));
771e7bf8805bd030c19924a5306837ecd72c295751Vikas Arora  PutLE16(data + 2, (int)(val >> 16));
781e7bf8805bd030c19924a5306837ecd72c295751Vikas Arora}
791e7bf8805bd030c19924a5306837ecd72c295751Vikas Arora
80af51b94a435132e9014c324e25fb686b3d07a8c8Vikas Arora// Returns (int)floor(log2(n)). n must be > 0.
81af51b94a435132e9014c324e25fb686b3d07a8c8Vikas Arora// use GNU builtins where available.
82af51b94a435132e9014c324e25fb686b3d07a8c8Vikas Arora#if defined(__GNUC__) && \
83af51b94a435132e9014c324e25fb686b3d07a8c8Vikas Arora    ((__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || __GNUC__ >= 4)
84af51b94a435132e9014c324e25fb686b3d07a8c8Vikas Arorastatic WEBP_INLINE int BitsLog2Floor(uint32_t n) {
85af51b94a435132e9014c324e25fb686b3d07a8c8Vikas Arora  return 31 ^ __builtin_clz(n);
86af51b94a435132e9014c324e25fb686b3d07a8c8Vikas Arora}
87af51b94a435132e9014c324e25fb686b3d07a8c8Vikas Arora#elif defined(_MSC_VER) && _MSC_VER > 1310 && \
88af51b94a435132e9014c324e25fb686b3d07a8c8Vikas Arora      (defined(_M_X64) || defined(_M_IX86))
89af51b94a435132e9014c324e25fb686b3d07a8c8Vikas Arora#include <intrin.h>
90af51b94a435132e9014c324e25fb686b3d07a8c8Vikas Arora#pragma intrinsic(_BitScanReverse)
91af51b94a435132e9014c324e25fb686b3d07a8c8Vikas Arora
92af51b94a435132e9014c324e25fb686b3d07a8c8Vikas Arorastatic WEBP_INLINE int BitsLog2Floor(uint32_t n) {
93af51b94a435132e9014c324e25fb686b3d07a8c8Vikas Arora  uint32_t first_set_bit;
94af51b94a435132e9014c324e25fb686b3d07a8c8Vikas Arora  _BitScanReverse(&first_set_bit, n);
95af51b94a435132e9014c324e25fb686b3d07a8c8Vikas Arora  return first_set_bit;
96af51b94a435132e9014c324e25fb686b3d07a8c8Vikas Arora}
97af51b94a435132e9014c324e25fb686b3d07a8c8Vikas Arora#else
98af51b94a435132e9014c324e25fb686b3d07a8c8Vikas Arorastatic WEBP_INLINE int BitsLog2Floor(uint32_t n) {
99af51b94a435132e9014c324e25fb686b3d07a8c8Vikas Arora  int log = 0;
100af51b94a435132e9014c324e25fb686b3d07a8c8Vikas Arora  uint32_t value = n;
101af51b94a435132e9014c324e25fb686b3d07a8c8Vikas Arora  int i;
102af51b94a435132e9014c324e25fb686b3d07a8c8Vikas Arora
103af51b94a435132e9014c324e25fb686b3d07a8c8Vikas Arora  for (i = 4; i >= 0; --i) {
104af51b94a435132e9014c324e25fb686b3d07a8c8Vikas Arora    const int shift = (1 << i);
105af51b94a435132e9014c324e25fb686b3d07a8c8Vikas Arora    const uint32_t x = value >> shift;
106af51b94a435132e9014c324e25fb686b3d07a8c8Vikas Arora    if (x != 0) {
107af51b94a435132e9014c324e25fb686b3d07a8c8Vikas Arora      value = x;
108af51b94a435132e9014c324e25fb686b3d07a8c8Vikas Arora      log += shift;
109af51b94a435132e9014c324e25fb686b3d07a8c8Vikas Arora    }
110af51b94a435132e9014c324e25fb686b3d07a8c8Vikas Arora  }
111af51b94a435132e9014c324e25fb686b3d07a8c8Vikas Arora  return log;
112af51b94a435132e9014c324e25fb686b3d07a8c8Vikas Arora}
113af51b94a435132e9014c324e25fb686b3d07a8c8Vikas Arora#endif
114af51b94a435132e9014c324e25fb686b3d07a8c8Vikas Arora
1151e7bf8805bd030c19924a5306837ecd72c295751Vikas Arora//------------------------------------------------------------------------------
116a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora
1178b720228d581a84fd173b6dcb2fa295b59db489aVikas Arora#ifdef __cplusplus
118a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora}    // extern "C"
119a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora#endif
120a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora
121a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora#endif  /* WEBP_UTILS_UTILS_H_ */
122