1*b2055c35SXin Li // Copyright 2014 Google Inc. All Rights Reserved. 2*b2055c35SXin Li // 3*b2055c35SXin Li // Use of this source code is governed by a BSD-style license 4*b2055c35SXin Li // that can be found in the COPYING file in the root of the source 5*b2055c35SXin Li // tree. An additional intellectual property rights grant can be found 6*b2055c35SXin Li // in the file PATENTS. All contributing project authors may 7*b2055c35SXin Li // be found in the AUTHORS file in the root of the source tree. 8*b2055c35SXin Li // ----------------------------------------------------------------------------- 9*b2055c35SXin Li // 10*b2055c35SXin Li // Endian related functions. 11*b2055c35SXin Li 12*b2055c35SXin Li #ifndef WEBP_UTILS_ENDIAN_INL_UTILS_H_ 13*b2055c35SXin Li #define WEBP_UTILS_ENDIAN_INL_UTILS_H_ 14*b2055c35SXin Li 15*b2055c35SXin Li #ifdef HAVE_CONFIG_H 16*b2055c35SXin Li #include "src/webp/config.h" 17*b2055c35SXin Li #endif 18*b2055c35SXin Li 19*b2055c35SXin Li #include "src/dsp/dsp.h" 20*b2055c35SXin Li #include "src/webp/types.h" 21*b2055c35SXin Li 22*b2055c35SXin Li #if defined(WORDS_BIGENDIAN) 23*b2055c35SXin Li #define HToLE32 BSwap32 24*b2055c35SXin Li #define HToLE16 BSwap16 25*b2055c35SXin Li #else 26*b2055c35SXin Li #define HToLE32(x) (x) 27*b2055c35SXin Li #define HToLE16(x) (x) 28*b2055c35SXin Li #endif 29*b2055c35SXin Li 30*b2055c35SXin Li #if !defined(HAVE_CONFIG_H) 31*b2055c35SXin Li #if LOCAL_GCC_PREREQ(4,8) || __has_builtin(__builtin_bswap16) 32*b2055c35SXin Li #define HAVE_BUILTIN_BSWAP16 33*b2055c35SXin Li #endif 34*b2055c35SXin Li #if LOCAL_GCC_PREREQ(4,3) || __has_builtin(__builtin_bswap32) 35*b2055c35SXin Li #define HAVE_BUILTIN_BSWAP32 36*b2055c35SXin Li #endif 37*b2055c35SXin Li #if LOCAL_GCC_PREREQ(4,3) || __has_builtin(__builtin_bswap64) 38*b2055c35SXin Li #define HAVE_BUILTIN_BSWAP64 39*b2055c35SXin Li #endif 40*b2055c35SXin Li #endif // !HAVE_CONFIG_H 41*b2055c35SXin Li BSwap16(uint16_t x)42*b2055c35SXin Listatic WEBP_INLINE uint16_t BSwap16(uint16_t x) { 43*b2055c35SXin Li #if defined(HAVE_BUILTIN_BSWAP16) 44*b2055c35SXin Li return __builtin_bswap16(x); 45*b2055c35SXin Li #elif defined(_MSC_VER) 46*b2055c35SXin Li return _byteswap_ushort(x); 47*b2055c35SXin Li #else 48*b2055c35SXin Li // gcc will recognize a 'rorw $8, ...' here: 49*b2055c35SXin Li return (x >> 8) | ((x & 0xff) << 8); 50*b2055c35SXin Li #endif // HAVE_BUILTIN_BSWAP16 51*b2055c35SXin Li } 52*b2055c35SXin Li BSwap32(uint32_t x)53*b2055c35SXin Listatic WEBP_INLINE uint32_t BSwap32(uint32_t x) { 54*b2055c35SXin Li #if defined(WEBP_USE_MIPS32_R2) 55*b2055c35SXin Li uint32_t ret; 56*b2055c35SXin Li __asm__ volatile ( 57*b2055c35SXin Li "wsbh %[ret], %[x] \n\t" 58*b2055c35SXin Li "rotr %[ret], %[ret], 16 \n\t" 59*b2055c35SXin Li : [ret]"=r"(ret) 60*b2055c35SXin Li : [x]"r"(x) 61*b2055c35SXin Li ); 62*b2055c35SXin Li return ret; 63*b2055c35SXin Li #elif defined(HAVE_BUILTIN_BSWAP32) 64*b2055c35SXin Li return __builtin_bswap32(x); 65*b2055c35SXin Li #elif defined(__i386__) || defined(__x86_64__) 66*b2055c35SXin Li uint32_t swapped_bytes; 67*b2055c35SXin Li __asm__ volatile("bswap %0" : "=r"(swapped_bytes) : "0"(x)); 68*b2055c35SXin Li return swapped_bytes; 69*b2055c35SXin Li #elif defined(_MSC_VER) 70*b2055c35SXin Li return (uint32_t)_byteswap_ulong(x); 71*b2055c35SXin Li #else 72*b2055c35SXin Li return (x >> 24) | ((x >> 8) & 0xff00) | ((x << 8) & 0xff0000) | (x << 24); 73*b2055c35SXin Li #endif // HAVE_BUILTIN_BSWAP32 74*b2055c35SXin Li } 75*b2055c35SXin Li BSwap64(uint64_t x)76*b2055c35SXin Listatic WEBP_INLINE uint64_t BSwap64(uint64_t x) { 77*b2055c35SXin Li #if defined(HAVE_BUILTIN_BSWAP64) 78*b2055c35SXin Li return __builtin_bswap64(x); 79*b2055c35SXin Li #elif defined(__x86_64__) 80*b2055c35SXin Li uint64_t swapped_bytes; 81*b2055c35SXin Li __asm__ volatile("bswapq %0" : "=r"(swapped_bytes) : "0"(x)); 82*b2055c35SXin Li return swapped_bytes; 83*b2055c35SXin Li #elif defined(_MSC_VER) 84*b2055c35SXin Li return (uint64_t)_byteswap_uint64(x); 85*b2055c35SXin Li #else // generic code for swapping 64-bit values (suggested by bdb@) 86*b2055c35SXin Li x = ((x & 0xffffffff00000000ull) >> 32) | ((x & 0x00000000ffffffffull) << 32); 87*b2055c35SXin Li x = ((x & 0xffff0000ffff0000ull) >> 16) | ((x & 0x0000ffff0000ffffull) << 16); 88*b2055c35SXin Li x = ((x & 0xff00ff00ff00ff00ull) >> 8) | ((x & 0x00ff00ff00ff00ffull) << 8); 89*b2055c35SXin Li return x; 90*b2055c35SXin Li #endif // HAVE_BUILTIN_BSWAP64 91*b2055c35SXin Li } 92*b2055c35SXin Li 93*b2055c35SXin Li #endif // WEBP_UTILS_ENDIAN_INL_UTILS_H_ 94