1*103e46e4SHarish Mahendrakar // Copyright (c) 2012 The WebM project authors. All Rights Reserved. 2*103e46e4SHarish Mahendrakar // 3*103e46e4SHarish Mahendrakar // Use of this source code is governed by a BSD-style license 4*103e46e4SHarish Mahendrakar // that can be found in the LICENSE file in the root of the source 5*103e46e4SHarish Mahendrakar // tree. An additional intellectual property rights grant can be found 6*103e46e4SHarish Mahendrakar // in the file PATENTS. All contributing project authors may 7*103e46e4SHarish Mahendrakar // be found in the AUTHORS file in the root of the source tree. 8*103e46e4SHarish Mahendrakar 9*103e46e4SHarish Mahendrakar #include "common/webm_endian.h" 10*103e46e4SHarish Mahendrakar 11*103e46e4SHarish Mahendrakar #include <stdint.h> 12*103e46e4SHarish Mahendrakar 13*103e46e4SHarish Mahendrakar namespace { 14*103e46e4SHarish Mahendrakar 15*103e46e4SHarish Mahendrakar // Swaps unsigned 32 bit values to big endian if needed. Returns |value| 16*103e46e4SHarish Mahendrakar // unmodified if architecture is big endian. Returns swapped bytes of |value| 17*103e46e4SHarish Mahendrakar // if architecture is little endian. Returns 0 otherwise. swap32_check_little_endian(uint32_t value)18*103e46e4SHarish Mahendrakaruint32_t swap32_check_little_endian(uint32_t value) { 19*103e46e4SHarish Mahendrakar // Check endianness. 20*103e46e4SHarish Mahendrakar union { 21*103e46e4SHarish Mahendrakar uint32_t val32; 22*103e46e4SHarish Mahendrakar uint8_t c[4]; 23*103e46e4SHarish Mahendrakar } check; 24*103e46e4SHarish Mahendrakar check.val32 = 0x01234567U; 25*103e46e4SHarish Mahendrakar 26*103e46e4SHarish Mahendrakar // Check for big endian. 27*103e46e4SHarish Mahendrakar if (check.c[3] == 0x67) 28*103e46e4SHarish Mahendrakar return value; 29*103e46e4SHarish Mahendrakar 30*103e46e4SHarish Mahendrakar // Check for not little endian. 31*103e46e4SHarish Mahendrakar if (check.c[0] != 0x67) 32*103e46e4SHarish Mahendrakar return 0; 33*103e46e4SHarish Mahendrakar 34*103e46e4SHarish Mahendrakar return value << 24 | ((value << 8) & 0x0000FF00U) | 35*103e46e4SHarish Mahendrakar ((value >> 8) & 0x00FF0000U) | value >> 24; 36*103e46e4SHarish Mahendrakar } 37*103e46e4SHarish Mahendrakar 38*103e46e4SHarish Mahendrakar // Swaps unsigned 64 bit values to big endian if needed. Returns |value| 39*103e46e4SHarish Mahendrakar // unmodified if architecture is big endian. Returns swapped bytes of |value| 40*103e46e4SHarish Mahendrakar // if architecture is little endian. Returns 0 otherwise. swap64_check_little_endian(uint64_t value)41*103e46e4SHarish Mahendrakaruint64_t swap64_check_little_endian(uint64_t value) { 42*103e46e4SHarish Mahendrakar // Check endianness. 43*103e46e4SHarish Mahendrakar union { 44*103e46e4SHarish Mahendrakar uint64_t val64; 45*103e46e4SHarish Mahendrakar uint8_t c[8]; 46*103e46e4SHarish Mahendrakar } check; 47*103e46e4SHarish Mahendrakar check.val64 = 0x0123456789ABCDEFULL; 48*103e46e4SHarish Mahendrakar 49*103e46e4SHarish Mahendrakar // Check for big endian. 50*103e46e4SHarish Mahendrakar if (check.c[7] == 0xEF) 51*103e46e4SHarish Mahendrakar return value; 52*103e46e4SHarish Mahendrakar 53*103e46e4SHarish Mahendrakar // Check for not little endian. 54*103e46e4SHarish Mahendrakar if (check.c[0] != 0xEF) 55*103e46e4SHarish Mahendrakar return 0; 56*103e46e4SHarish Mahendrakar 57*103e46e4SHarish Mahendrakar return value << 56 | ((value << 40) & 0x00FF000000000000ULL) | 58*103e46e4SHarish Mahendrakar ((value << 24) & 0x0000FF0000000000ULL) | 59*103e46e4SHarish Mahendrakar ((value << 8) & 0x000000FF00000000ULL) | 60*103e46e4SHarish Mahendrakar ((value >> 8) & 0x00000000FF000000ULL) | 61*103e46e4SHarish Mahendrakar ((value >> 24) & 0x0000000000FF0000ULL) | 62*103e46e4SHarish Mahendrakar ((value >> 40) & 0x000000000000FF00ULL) | value >> 56; 63*103e46e4SHarish Mahendrakar } 64*103e46e4SHarish Mahendrakar 65*103e46e4SHarish Mahendrakar } // namespace 66*103e46e4SHarish Mahendrakar 67*103e46e4SHarish Mahendrakar namespace libwebm { 68*103e46e4SHarish Mahendrakar host_to_bigendian(uint32_t value)69*103e46e4SHarish Mahendrakaruint32_t host_to_bigendian(uint32_t value) { 70*103e46e4SHarish Mahendrakar return swap32_check_little_endian(value); 71*103e46e4SHarish Mahendrakar } 72*103e46e4SHarish Mahendrakar bigendian_to_host(uint32_t value)73*103e46e4SHarish Mahendrakaruint32_t bigendian_to_host(uint32_t value) { 74*103e46e4SHarish Mahendrakar return swap32_check_little_endian(value); 75*103e46e4SHarish Mahendrakar } 76*103e46e4SHarish Mahendrakar host_to_bigendian(uint64_t value)77*103e46e4SHarish Mahendrakaruint64_t host_to_bigendian(uint64_t value) { 78*103e46e4SHarish Mahendrakar return swap64_check_little_endian(value); 79*103e46e4SHarish Mahendrakar } 80*103e46e4SHarish Mahendrakar bigendian_to_host(uint64_t value)81*103e46e4SHarish Mahendrakaruint64_t bigendian_to_host(uint64_t value) { 82*103e46e4SHarish Mahendrakar return swap64_check_little_endian(value); 83*103e46e4SHarish Mahendrakar } 84*103e46e4SHarish Mahendrakar 85*103e46e4SHarish Mahendrakar } // namespace libwebm 86