endian_inl.h: add BSwap32

Change-Id: I96e3ae49659307024415d64587e6312888a0070f
This commit is contained in:
James Zern 2014-07-03 11:21:24 -07:00
parent d5104b1ff6
commit 47779d46c8
3 changed files with 28 additions and 34 deletions

View File

@ -17,8 +17,9 @@
#include <math.h>
#include <stdlib.h>
#include "./lossless.h"
#include "../dec/vp8li.h"
#include "../utils/endian_inl.h"
#include "./lossless.h"
#include "./yuv.h"
#define MAX_DIFF_COST (1e30f)
@ -1357,22 +1358,11 @@ static void CopyOrSwap(const uint32_t* src, int num_pixels, uint8_t* dst,
if (is_big_endian() == swap_on_big_endian) {
const uint32_t* const src_end = src + num_pixels;
while (src < src_end) {
uint32_t argb = *src++;
const uint32_t argb = *src++;
#if !defined(__BIG_ENDIAN__)
#if !defined(WEBP_REFERENCE_IMPLEMENTATION)
#if defined(__i386__) || defined(__x86_64__)
__asm__ volatile("bswap %0" : "=r"(argb) : "0"(argb));
*(uint32_t*)dst = argb;
#elif defined(_MSC_VER)
argb = _byteswap_ulong(argb);
*(uint32_t*)dst = argb;
#else
dst[0] = (argb >> 24) & 0xff;
dst[1] = (argb >> 16) & 0xff;
dst[2] = (argb >> 8) & 0xff;
dst[3] = (argb >> 0) & 0xff;
#endif
*(uint32_t*)dst = BSwap32(argb);
#else // WEBP_REFERENCE_IMPLEMENTATION
dst[0] = (argb >> 24) & 0xff;
dst[1] = (argb >> 16) & 0xff;

View File

@ -36,12 +36,6 @@ typedef uint16_t lbit_t;
typedef uint8_t lbit_t;
#endif
// gcc 4.3 has builtin functions for swap32/swap64
#if defined(__GNUC__) && \
(__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3))
#define HAVE_BUILTIN_BSWAP
#endif
extern const uint8_t kVP8Log2Range[128];
extern const range_t kVP8NewRange[128];
@ -95,20 +89,7 @@ static WEBP_INLINE void VP8LoadNewBytes(VP8BitReader* const br) {
#endif
bits >>= 64 - BITS;
#elif (BITS >= 24)
#if defined(HAVE_BUILTIN_BSWAP)
bits = (bit_t)__builtin_bswap32(in_bits);
#elif defined(__i386__) || defined(__x86_64__)
{
lbit_t swapped_in_bits;
__asm__ volatile("bswap %k0" : "=r"(swapped_in_bits) : "0"(in_bits));
bits = (bit_t)swapped_in_bits; // 24b/32b -> 32b/64b zero-extension
}
#elif defined(_MSC_VER)
bits = (bit_t)_byteswap_ulong(in_bits);
#else
bits = (bit_t)(in_bits >> 24) | ((in_bits >> 8) & 0xff00)
| ((in_bits << 8) & 0xff0000) | (in_bits << 24);
#endif // x86
bits = BSwap32(in_bits);
bits >>= (32 - BITS);
#elif (BITS == 16)
// gcc will recognize a 'rorw $8, ...' here:

View File

@ -12,6 +12,8 @@
#ifndef WEBP_UTILS_ENDIAN_INL_H_
#define WEBP_UTILS_ENDIAN_INL_H_
#include "../webp/types.h"
// some endian fix (e.g.: mips-gcc doesn't define __BIG_ENDIAN__)
#if !defined(__BIG_ENDIAN__) && defined(__BYTE_ORDER__) && \
(__BYTE_ORDER__ == __ORDER_BIG_ENDIAN__)
@ -47,4 +49,25 @@
#include <endian.h>
#endif
// gcc 4.3 has builtin functions for swap32/swap64
// TODO(jzern): this should have a corresponding autoconf check.
#if defined(__GNUC__) && \
(__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3))
#define HAVE_BUILTIN_BSWAP
#endif
static WEBP_INLINE uint32_t BSwap32(uint32_t x) {
#if defined(HAVE_BUILTIN_BSWAP)
return __builtin_bswap32(x);
#elif defined(__i386__) || defined(__x86_64__)
uint32_t swapped_bytes;
__asm__ volatile("bswap %0" : "=r"(swapped_bytes) : "0"(x));
return swapped_bytes;
#elif defined(_MSC_VER)
return (uint32_t)_byteswap_ulong(x);
#else
return (x >> 24) | ((x >> 8) & 0xff00) | ((x << 8) & 0xff0000) | (x << 24);
#endif // HAVE_BUILTIN_BSWAP
}
#endif // WEBP_UTILS_ENDIAN_INL_H_