blob: cd56c37f4d1fe2310854245e27838a19dbf98afb [file] [log] [blame]
Vikas Arora33f74da2014-07-25 13:53:32 -07001// Copyright 2014 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// Endian related functions.
11
12#ifndef WEBP_UTILS_ENDIAN_INL_H_
13#define WEBP_UTILS_ENDIAN_INL_H_
14
15#ifdef HAVE_CONFIG_H
James Zern9e80ee92015-03-17 18:54:21 -070016#include "../webp/config.h"
Vikas Arora33f74da2014-07-25 13:53:32 -070017#endif
18
Vikas Arora8c098652015-01-28 14:08:58 -080019#include "../dsp/dsp.h"
James Zern9e80ee92015-03-17 18:54:21 -070020#include "../webp/types.h"
Vikas Arora33f74da2014-07-25 13:53:32 -070021
22// some endian fix (e.g.: mips-gcc doesn't define __BIG_ENDIAN__)
23#if !defined(WORDS_BIGENDIAN) && \
24 (defined(__BIG_ENDIAN__) || defined(_M_PPC) || \
25 (defined(__BYTE_ORDER__) && (__BYTE_ORDER__ == __ORDER_BIG_ENDIAN__)))
26#define WORDS_BIGENDIAN
27#endif
28
29#if defined(WORDS_BIGENDIAN)
30#define HToLE32 BSwap32
31#define HToLE16 BSwap16
32#else
33#define HToLE32(x) (x)
34#define HToLE16(x) (x)
35#endif
36
37#if !defined(HAVE_CONFIG_H)
Vikas Arora33f74da2014-07-25 13:53:32 -070038// clang-3.3 and gcc-4.3 have builtin functions for swap32/swap64
Vikas Arora8c098652015-01-28 14:08:58 -080039#if LOCAL_GCC_PREREQ(4,3) || LOCAL_CLANG_PREREQ(3,3)
Vikas Arora33f74da2014-07-25 13:53:32 -070040#define HAVE_BUILTIN_BSWAP32
41#define HAVE_BUILTIN_BSWAP64
42#endif
43// clang-3.3 and gcc-4.8 have a builtin function for swap16
Vikas Arora8c098652015-01-28 14:08:58 -080044#if LOCAL_GCC_PREREQ(4,8) || LOCAL_CLANG_PREREQ(3,3)
Vikas Arora33f74da2014-07-25 13:53:32 -070045#define HAVE_BUILTIN_BSWAP16
46#endif
47#endif // !HAVE_CONFIG_H
48
49static WEBP_INLINE uint16_t BSwap16(uint16_t x) {
50#if defined(HAVE_BUILTIN_BSWAP16)
51 return __builtin_bswap16(x);
52#elif defined(_MSC_VER)
53 return _byteswap_ushort(x);
54#else
55 // gcc will recognize a 'rorw $8, ...' here:
56 return (x >> 8) | ((x & 0xff) << 8);
57#endif // HAVE_BUILTIN_BSWAP16
58}
59
60static WEBP_INLINE uint32_t BSwap32(uint32_t x) {
Vikas Arora8c098652015-01-28 14:08:58 -080061#if defined(WEBP_USE_MIPS32_R2)
62 uint32_t ret;
63 __asm__ volatile (
64 "wsbh %[ret], %[x] \n\t"
65 "rotr %[ret], %[ret], 16 \n\t"
66 : [ret]"=r"(ret)
67 : [x]"r"(x)
68 );
69 return ret;
70#elif defined(HAVE_BUILTIN_BSWAP32)
Vikas Arora33f74da2014-07-25 13:53:32 -070071 return __builtin_bswap32(x);
72#elif defined(__i386__) || defined(__x86_64__)
73 uint32_t swapped_bytes;
74 __asm__ volatile("bswap %0" : "=r"(swapped_bytes) : "0"(x));
75 return swapped_bytes;
76#elif defined(_MSC_VER)
77 return (uint32_t)_byteswap_ulong(x);
78#else
79 return (x >> 24) | ((x >> 8) & 0xff00) | ((x << 8) & 0xff0000) | (x << 24);
80#endif // HAVE_BUILTIN_BSWAP32
81}
82
83static WEBP_INLINE uint64_t BSwap64(uint64_t x) {
84#if defined(HAVE_BUILTIN_BSWAP64)
85 return __builtin_bswap64(x);
86#elif defined(__x86_64__)
87 uint64_t swapped_bytes;
88 __asm__ volatile("bswapq %0" : "=r"(swapped_bytes) : "0"(x));
89 return swapped_bytes;
90#elif defined(_MSC_VER)
91 return (uint64_t)_byteswap_uint64(x);
92#else // generic code for swapping 64-bit values (suggested by bdb@)
93 x = ((x & 0xffffffff00000000ull) >> 32) | ((x & 0x00000000ffffffffull) << 32);
94 x = ((x & 0xffff0000ffff0000ull) >> 16) | ((x & 0x0000ffff0000ffffull) << 16);
95 x = ((x & 0xff00ff00ff00ff00ull) >> 8) | ((x & 0x00ff00ff00ff00ffull) << 8);
96 return x;
97#endif // HAVE_BUILTIN_BSWAP64
98}
99
100#endif // WEBP_UTILS_ENDIAN_INL_H_