18a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com/* 2ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * Copyright 2006 The Android Open Source Project 38a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com * 4ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * Use of this source code is governed by a BSD-style license that can be 5ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * found in the LICENSE file. 68a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com */ 78a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 88a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#ifndef SkEndian_DEFINED 98a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#define SkEndian_DEFINED 108a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 118a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkTypes.h" 128a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 138a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com/** \file SkEndian.h 148a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 158a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com Macros and helper functions for handling 16 and 32 bit values in 168a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com big and little endian formats. 178a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com*/ 188a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 198a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#if defined(SK_CPU_LENDIAN) && defined(SK_CPU_BENDIAN) 208a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com #error "can't have both LENDIAN and BENDIAN defined" 218a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#endif 228a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 238a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#if !defined(SK_CPU_LENDIAN) && !defined(SK_CPU_BENDIAN) 248a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com #error "need either LENDIAN or BENDIAN defined" 258a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#endif 268a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 278a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com/** Swap the two bytes in the low 16bits of the parameters. 288a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com e.g. 0x1234 -> 0x3412 298a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com*/ 30f117781362ecf673f43f93918781853690f0e145commit-bot@chromium.orgstatic inline uint16_t SkEndianSwap16(uint16_t value) { 31f8d1aee2526a384a570b082b17f3a19fe72bd15ebungeman@google.com return static_cast<uint16_t>((value >> 8) | (value << 8)); 328a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 33f117781362ecf673f43f93918781853690f0e145commit-bot@chromium.org 34f8d1aee2526a384a570b082b17f3a19fe72bd15ebungeman@google.comtemplate<uint16_t N> struct SkTEndianSwap16 { 35f8d1aee2526a384a570b082b17f3a19fe72bd15ebungeman@google.com static const uint16_t value = static_cast<uint16_t>((N >> 8) | ((N & 0xFF) << 8)); 36f8d1aee2526a384a570b082b17f3a19fe72bd15ebungeman@google.com}; 378a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 388a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com/** Vector version of SkEndianSwap16(), which swaps the 398a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com low two bytes of each value in the array. 408a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com*/ 41ad91799832b9ba2a3de30c0f57968148b4be17afreed@google.comstatic inline void SkEndianSwap16s(uint16_t array[], int count) { 4296fcdcc219d2a0d3579719b84b28bede76efba64halcanary SkASSERT(count == 0 || array != nullptr); 438a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 44ad91799832b9ba2a3de30c0f57968148b4be17afreed@google.com while (--count >= 0) { 458a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com *array = SkEndianSwap16(*array); 468a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com array += 1; 478a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 488a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 498a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 508a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com/** Reverse all 4 bytes in a 32bit value. 518a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com e.g. 0x12345678 -> 0x78563412 528a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com*/ 53ab926f0a1bca1c6e17520803d964a0344b4f79b4msarettstatic constexpr uint32_t SkEndianSwap32(uint32_t value) { 54f117781362ecf673f43f93918781853690f0e145commit-bot@chromium.org return ((value & 0xFF) << 24) | 55f117781362ecf673f43f93918781853690f0e145commit-bot@chromium.org ((value & 0xFF00) << 8) | 56f117781362ecf673f43f93918781853690f0e145commit-bot@chromium.org ((value & 0xFF0000) >> 8) | 578a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com (value >> 24); 588a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 59f117781362ecf673f43f93918781853690f0e145commit-bot@chromium.org 60f8d1aee2526a384a570b082b17f3a19fe72bd15ebungeman@google.comtemplate<uint32_t N> struct SkTEndianSwap32 { 61f8d1aee2526a384a570b082b17f3a19fe72bd15ebungeman@google.com static const uint32_t value = ((N & 0xFF) << 24) | 62f8d1aee2526a384a570b082b17f3a19fe72bd15ebungeman@google.com ((N & 0xFF00) << 8) | 63f8d1aee2526a384a570b082b17f3a19fe72bd15ebungeman@google.com ((N & 0xFF0000) >> 8) | 64f8d1aee2526a384a570b082b17f3a19fe72bd15ebungeman@google.com (N >> 24); 65f8d1aee2526a384a570b082b17f3a19fe72bd15ebungeman@google.com}; 668a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 67b4ca46d748364236e82fdaccc08022dd89e29d40epoger@google.com/** Vector version of SkEndianSwap32(), which swaps the 688a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com bytes of each value in the array. 698a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com*/ 70ad91799832b9ba2a3de30c0f57968148b4be17afreed@google.comstatic inline void SkEndianSwap32s(uint32_t array[], int count) { 7196fcdcc219d2a0d3579719b84b28bede76efba64halcanary SkASSERT(count == 0 || array != nullptr); 728a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 73ad91799832b9ba2a3de30c0f57968148b4be17afreed@google.com while (--count >= 0) { 748a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com *array = SkEndianSwap32(*array); 758a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com array += 1; 768a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 778a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 788a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 79b4ca46d748364236e82fdaccc08022dd89e29d40epoger@google.com/** Reverse all 8 bytes in a 64bit value. 80b4ca46d748364236e82fdaccc08022dd89e29d40epoger@google.com e.g. 0x1122334455667788 -> 0x8877665544332211 81b4ca46d748364236e82fdaccc08022dd89e29d40epoger@google.com*/ 82b4ca46d748364236e82fdaccc08022dd89e29d40epoger@google.comstatic inline uint64_t SkEndianSwap64(uint64_t value) { 83b4ca46d748364236e82fdaccc08022dd89e29d40epoger@google.com return (((value & 0x00000000000000FFULL) << (8*7)) | 84b4ca46d748364236e82fdaccc08022dd89e29d40epoger@google.com ((value & 0x000000000000FF00ULL) << (8*5)) | 85b4ca46d748364236e82fdaccc08022dd89e29d40epoger@google.com ((value & 0x0000000000FF0000ULL) << (8*3)) | 86b4ca46d748364236e82fdaccc08022dd89e29d40epoger@google.com ((value & 0x00000000FF000000ULL) << (8*1)) | 87b4ca46d748364236e82fdaccc08022dd89e29d40epoger@google.com ((value & 0x000000FF00000000ULL) >> (8*1)) | 88b4ca46d748364236e82fdaccc08022dd89e29d40epoger@google.com ((value & 0x0000FF0000000000ULL) >> (8*3)) | 89b4ca46d748364236e82fdaccc08022dd89e29d40epoger@google.com ((value & 0x00FF000000000000ULL) >> (8*5)) | 90b4ca46d748364236e82fdaccc08022dd89e29d40epoger@google.com ((value) >> (8*7))); 91b4ca46d748364236e82fdaccc08022dd89e29d40epoger@google.com} 92b4ca46d748364236e82fdaccc08022dd89e29d40epoger@google.comtemplate<uint64_t N> struct SkTEndianSwap64 { 93b4ca46d748364236e82fdaccc08022dd89e29d40epoger@google.com static const uint64_t value = (((N & 0x00000000000000FFULL) << (8*7)) | 94b4ca46d748364236e82fdaccc08022dd89e29d40epoger@google.com ((N & 0x000000000000FF00ULL) << (8*5)) | 95b4ca46d748364236e82fdaccc08022dd89e29d40epoger@google.com ((N & 0x0000000000FF0000ULL) << (8*3)) | 96b4ca46d748364236e82fdaccc08022dd89e29d40epoger@google.com ((N & 0x00000000FF000000ULL) << (8*1)) | 97b4ca46d748364236e82fdaccc08022dd89e29d40epoger@google.com ((N & 0x000000FF00000000ULL) >> (8*1)) | 98b4ca46d748364236e82fdaccc08022dd89e29d40epoger@google.com ((N & 0x0000FF0000000000ULL) >> (8*3)) | 99b4ca46d748364236e82fdaccc08022dd89e29d40epoger@google.com ((N & 0x00FF000000000000ULL) >> (8*5)) | 100b4ca46d748364236e82fdaccc08022dd89e29d40epoger@google.com ((N) >> (8*7))); 101b4ca46d748364236e82fdaccc08022dd89e29d40epoger@google.com}; 102b4ca46d748364236e82fdaccc08022dd89e29d40epoger@google.com 103b4ca46d748364236e82fdaccc08022dd89e29d40epoger@google.com/** Vector version of SkEndianSwap64(), which swaps the 104b4ca46d748364236e82fdaccc08022dd89e29d40epoger@google.com bytes of each value in the array. 105b4ca46d748364236e82fdaccc08022dd89e29d40epoger@google.com*/ 106b4ca46d748364236e82fdaccc08022dd89e29d40epoger@google.comstatic inline void SkEndianSwap64s(uint64_t array[], int count) { 10796fcdcc219d2a0d3579719b84b28bede76efba64halcanary SkASSERT(count == 0 || array != nullptr); 108b4ca46d748364236e82fdaccc08022dd89e29d40epoger@google.com 109b4ca46d748364236e82fdaccc08022dd89e29d40epoger@google.com while (--count >= 0) { 110b4ca46d748364236e82fdaccc08022dd89e29d40epoger@google.com *array = SkEndianSwap64(*array); 111b4ca46d748364236e82fdaccc08022dd89e29d40epoger@google.com array += 1; 112b4ca46d748364236e82fdaccc08022dd89e29d40epoger@google.com } 113b4ca46d748364236e82fdaccc08022dd89e29d40epoger@google.com} 114b4ca46d748364236e82fdaccc08022dd89e29d40epoger@google.com 1158a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#ifdef SK_CPU_LENDIAN 1168a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com #define SkEndian_SwapBE16(n) SkEndianSwap16(n) 1178a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com #define SkEndian_SwapBE32(n) SkEndianSwap32(n) 118b4ca46d748364236e82fdaccc08022dd89e29d40epoger@google.com #define SkEndian_SwapBE64(n) SkEndianSwap64(n) 1198a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com #define SkEndian_SwapLE16(n) (n) 1208a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com #define SkEndian_SwapLE32(n) (n) 121b4ca46d748364236e82fdaccc08022dd89e29d40epoger@google.com #define SkEndian_SwapLE64(n) (n) 122f8d1aee2526a384a570b082b17f3a19fe72bd15ebungeman@google.com 123f8d1aee2526a384a570b082b17f3a19fe72bd15ebungeman@google.com #define SkTEndian_SwapBE16(n) SkTEndianSwap16<n>::value 124f8d1aee2526a384a570b082b17f3a19fe72bd15ebungeman@google.com #define SkTEndian_SwapBE32(n) SkTEndianSwap32<n>::value 125b4ca46d748364236e82fdaccc08022dd89e29d40epoger@google.com #define SkTEndian_SwapBE64(n) SkTEndianSwap64<n>::value 126f8d1aee2526a384a570b082b17f3a19fe72bd15ebungeman@google.com #define SkTEndian_SwapLE16(n) (n) 127f8d1aee2526a384a570b082b17f3a19fe72bd15ebungeman@google.com #define SkTEndian_SwapLE32(n) (n) 128b4ca46d748364236e82fdaccc08022dd89e29d40epoger@google.com #define SkTEndian_SwapLE64(n) (n) 1298a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#else // SK_CPU_BENDIAN 1308a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com #define SkEndian_SwapBE16(n) (n) 1318a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com #define SkEndian_SwapBE32(n) (n) 132b4ca46d748364236e82fdaccc08022dd89e29d40epoger@google.com #define SkEndian_SwapBE64(n) (n) 1338a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com #define SkEndian_SwapLE16(n) SkEndianSwap16(n) 1348a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com #define SkEndian_SwapLE32(n) SkEndianSwap32(n) 135b4ca46d748364236e82fdaccc08022dd89e29d40epoger@google.com #define SkEndian_SwapLE64(n) SkEndianSwap64(n) 136f8d1aee2526a384a570b082b17f3a19fe72bd15ebungeman@google.com 137f8d1aee2526a384a570b082b17f3a19fe72bd15ebungeman@google.com #define SkTEndian_SwapBE16(n) (n) 138f8d1aee2526a384a570b082b17f3a19fe72bd15ebungeman@google.com #define SkTEndian_SwapBE32(n) (n) 139b4ca46d748364236e82fdaccc08022dd89e29d40epoger@google.com #define SkTEndian_SwapBE64(n) (n) 140f8d1aee2526a384a570b082b17f3a19fe72bd15ebungeman@google.com #define SkTEndian_SwapLE16(n) SkTEndianSwap16<n>::value 141f8d1aee2526a384a570b082b17f3a19fe72bd15ebungeman@google.com #define SkTEndian_SwapLE32(n) SkTEndianSwap32<n>::value 142b4ca46d748364236e82fdaccc08022dd89e29d40epoger@google.com #define SkTEndian_SwapLE64(n) SkTEndianSwap64<n>::value 1438a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#endif 1448a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 14501224d5d0a3228fe47e63d8346e0e433a87563a8tomhudson@google.com// When a bytestream is embedded in a 32-bit word, how far we need to 14601224d5d0a3228fe47e63d8346e0e433a87563a8tomhudson@google.com// shift the word to extract each byte from the low 8 bits by anding with 0xff. 14701224d5d0a3228fe47e63d8346e0e433a87563a8tomhudson@google.com#ifdef SK_CPU_LENDIAN 14801224d5d0a3228fe47e63d8346e0e433a87563a8tomhudson@google.com #define SkEndian_Byte0Shift 0 14901224d5d0a3228fe47e63d8346e0e433a87563a8tomhudson@google.com #define SkEndian_Byte1Shift 8 15001224d5d0a3228fe47e63d8346e0e433a87563a8tomhudson@google.com #define SkEndian_Byte2Shift 16 15101224d5d0a3228fe47e63d8346e0e433a87563a8tomhudson@google.com #define SkEndian_Byte3Shift 24 15201224d5d0a3228fe47e63d8346e0e433a87563a8tomhudson@google.com#else // SK_CPU_BENDIAN 15301224d5d0a3228fe47e63d8346e0e433a87563a8tomhudson@google.com #define SkEndian_Byte0Shift 24 15401224d5d0a3228fe47e63d8346e0e433a87563a8tomhudson@google.com #define SkEndian_Byte1Shift 16 15501224d5d0a3228fe47e63d8346e0e433a87563a8tomhudson@google.com #define SkEndian_Byte2Shift 8 15601224d5d0a3228fe47e63d8346e0e433a87563a8tomhudson@google.com #define SkEndian_Byte3Shift 0 15701224d5d0a3228fe47e63d8346e0e433a87563a8tomhudson@google.com#endif 1588a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 159f8d1aee2526a384a570b082b17f3a19fe72bd15ebungeman@google.com 160f8d1aee2526a384a570b082b17f3a19fe72bd15ebungeman@google.com#if defined(SK_UINT8_BITFIELD_LENDIAN) && defined(SK_UINT8_BITFIELD_BENDIAN) 161f8d1aee2526a384a570b082b17f3a19fe72bd15ebungeman@google.com #error "can't have both bitfield LENDIAN and BENDIAN defined" 162f8d1aee2526a384a570b082b17f3a19fe72bd15ebungeman@google.com#endif 163f8d1aee2526a384a570b082b17f3a19fe72bd15ebungeman@google.com 164f8d1aee2526a384a570b082b17f3a19fe72bd15ebungeman@google.com#if !defined(SK_UINT8_BITFIELD_LENDIAN) && !defined(SK_UINT8_BITFIELD_BENDIAN) 165f8d1aee2526a384a570b082b17f3a19fe72bd15ebungeman@google.com #ifdef SK_CPU_LENDIAN 166f8d1aee2526a384a570b082b17f3a19fe72bd15ebungeman@google.com #define SK_UINT8_BITFIELD_LENDIAN 167f8d1aee2526a384a570b082b17f3a19fe72bd15ebungeman@google.com #else 168f8d1aee2526a384a570b082b17f3a19fe72bd15ebungeman@google.com #define SK_UINT8_BITFIELD_BENDIAN 169f8d1aee2526a384a570b082b17f3a19fe72bd15ebungeman@google.com #endif 170f8d1aee2526a384a570b082b17f3a19fe72bd15ebungeman@google.com#endif 171f8d1aee2526a384a570b082b17f3a19fe72bd15ebungeman@google.com 172f8d1aee2526a384a570b082b17f3a19fe72bd15ebungeman@google.com#ifdef SK_UINT8_BITFIELD_LENDIAN 173f8d1aee2526a384a570b082b17f3a19fe72bd15ebungeman@google.com #define SK_UINT8_BITFIELD(f0, f1, f2, f3, f4, f5, f6, f7) \ 174f8d1aee2526a384a570b082b17f3a19fe72bd15ebungeman@google.com SK_OT_BYTE f0 : 1; \ 175f8d1aee2526a384a570b082b17f3a19fe72bd15ebungeman@google.com SK_OT_BYTE f1 : 1; \ 176f8d1aee2526a384a570b082b17f3a19fe72bd15ebungeman@google.com SK_OT_BYTE f2 : 1; \ 177f8d1aee2526a384a570b082b17f3a19fe72bd15ebungeman@google.com SK_OT_BYTE f3 : 1; \ 178f8d1aee2526a384a570b082b17f3a19fe72bd15ebungeman@google.com SK_OT_BYTE f4 : 1; \ 179f8d1aee2526a384a570b082b17f3a19fe72bd15ebungeman@google.com SK_OT_BYTE f5 : 1; \ 180f8d1aee2526a384a570b082b17f3a19fe72bd15ebungeman@google.com SK_OT_BYTE f6 : 1; \ 181f8d1aee2526a384a570b082b17f3a19fe72bd15ebungeman@google.com SK_OT_BYTE f7 : 1; 182f8d1aee2526a384a570b082b17f3a19fe72bd15ebungeman@google.com#else 183f8d1aee2526a384a570b082b17f3a19fe72bd15ebungeman@google.com #define SK_UINT8_BITFIELD(f0, f1, f2, f3, f4, f5, f6, f7) \ 184f8d1aee2526a384a570b082b17f3a19fe72bd15ebungeman@google.com SK_OT_BYTE f7 : 1; \ 185f8d1aee2526a384a570b082b17f3a19fe72bd15ebungeman@google.com SK_OT_BYTE f6 : 1; \ 186f8d1aee2526a384a570b082b17f3a19fe72bd15ebungeman@google.com SK_OT_BYTE f5 : 1; \ 187f8d1aee2526a384a570b082b17f3a19fe72bd15ebungeman@google.com SK_OT_BYTE f4 : 1; \ 188f8d1aee2526a384a570b082b17f3a19fe72bd15ebungeman@google.com SK_OT_BYTE f3 : 1; \ 189f8d1aee2526a384a570b082b17f3a19fe72bd15ebungeman@google.com SK_OT_BYTE f2 : 1; \ 190f8d1aee2526a384a570b082b17f3a19fe72bd15ebungeman@google.com SK_OT_BYTE f1 : 1; \ 191f8d1aee2526a384a570b082b17f3a19fe72bd15ebungeman@google.com SK_OT_BYTE f0 : 1; 192f8d1aee2526a384a570b082b17f3a19fe72bd15ebungeman@google.com#endif 193f8d1aee2526a384a570b082b17f3a19fe72bd15ebungeman@google.com 1948a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#endif 195