1 2 /* 3 * Copyright 2006 The Android Open Source Project 4 * 5 * Use of this source code is governed by a BSD-style license that can be 6 * found in the LICENSE file. 7 */ 8 9 10 #ifndef SkEndian_DEFINED 11 #define SkEndian_DEFINED 12 13 #include "SkTypes.h" 14 15 /** \file SkEndian.h 16 17 Macros and helper functions for handling 16 and 32 bit values in 18 big and little endian formats. 19 */ 20 21 #if defined(SK_CPU_LENDIAN) && defined(SK_CPU_BENDIAN) 22 #error "can't have both LENDIAN and BENDIAN defined" 23 #endif 24 25 #if !defined(SK_CPU_LENDIAN) && !defined(SK_CPU_BENDIAN) 26 #error "need either LENDIAN or BENDIAN defined" 27 #endif 28 29 /** Swap the two bytes in the low 16bits of the parameters. 30 e.g. 0x1234 -> 0x3412 31 */ 32 static inline uint16_t SkEndianSwap16(U16CPU value) { 33 SkASSERT(value == (uint16_t)value); 34 return static_cast<uint16_t>((value >> 8) | (value << 8)); 35 } 36 template<uint16_t N> struct SkTEndianSwap16 { 37 static const uint16_t value = static_cast<uint16_t>((N >> 8) | ((N & 0xFF) << 8)); 38 }; 39 40 /** Vector version of SkEndianSwap16(), which swaps the 41 low two bytes of each value in the array. 42 */ 43 static inline void SkEndianSwap16s(uint16_t array[], int count) { 44 SkASSERT(count == 0 || array != NULL); 45 46 while (--count >= 0) { 47 *array = SkEndianSwap16(*array); 48 array += 1; 49 } 50 } 51 52 /** Reverse all 4 bytes in a 32bit value. 53 e.g. 0x12345678 -> 0x78563412 54 */ 55 static inline uint32_t SkEndianSwap32(uint32_t value) { 56 return ((value & 0xFF) << 24) | 57 ((value & 0xFF00) << 8) | 58 ((value & 0xFF0000) >> 8) | 59 (value >> 24); 60 } 61 template<uint32_t N> struct SkTEndianSwap32 { 62 static const uint32_t value = ((N & 0xFF) << 24) | 63 ((N & 0xFF00) << 8) | 64 ((N & 0xFF0000) >> 8) | 65 (N >> 24); 66 }; 67 68 /** Vector version of SkEndianSwap16(), which swaps the 69 bytes of each value in the array. 70 */ 71 static inline void SkEndianSwap32s(uint32_t array[], int count) { 72 SkASSERT(count == 0 || array != NULL); 73 74 while (--count >= 0) { 75 *array = SkEndianSwap32(*array); 76 array += 1; 77 } 78 } 79 80 #ifdef SK_CPU_LENDIAN 81 #define SkEndian_SwapBE16(n) SkEndianSwap16(n) 82 #define SkEndian_SwapBE32(n) SkEndianSwap32(n) 83 #define SkEndian_SwapLE16(n) (n) 84 #define SkEndian_SwapLE32(n) (n) 85 86 #define SkTEndian_SwapBE16(n) SkTEndianSwap16<n>::value 87 #define SkTEndian_SwapBE32(n) SkTEndianSwap32<n>::value 88 #define SkTEndian_SwapLE16(n) (n) 89 #define SkTEndian_SwapLE32(n) (n) 90 #else // SK_CPU_BENDIAN 91 #define SkEndian_SwapBE16(n) (n) 92 #define SkEndian_SwapBE32(n) (n) 93 #define SkEndian_SwapLE16(n) SkEndianSwap16(n) 94 #define SkEndian_SwapLE32(n) SkEndianSwap32(n) 95 96 #define SkTEndian_SwapBE16(n) (n) 97 #define SkTEndian_SwapBE32(n) (n) 98 #define SkTEndian_SwapLE16(n) SkTEndianSwap16<n>::value 99 #define SkTEndian_SwapLE32(n) SkTEndianSwap32<n>::value 100 #endif 101 102 // When a bytestream is embedded in a 32-bit word, how far we need to 103 // shift the word to extract each byte from the low 8 bits by anding with 0xff. 104 #ifdef SK_CPU_LENDIAN 105 #define SkEndian_Byte0Shift 0 106 #define SkEndian_Byte1Shift 8 107 #define SkEndian_Byte2Shift 16 108 #define SkEndian_Byte3Shift 24 109 #else // SK_CPU_BENDIAN 110 #define SkEndian_Byte0Shift 24 111 #define SkEndian_Byte1Shift 16 112 #define SkEndian_Byte2Shift 8 113 #define SkEndian_Byte3Shift 0 114 #endif 115 116 117 #if defined(SK_UINT8_BITFIELD_LENDIAN) && defined(SK_UINT8_BITFIELD_BENDIAN) 118 #error "can't have both bitfield LENDIAN and BENDIAN defined" 119 #endif 120 121 #if !defined(SK_UINT8_BITFIELD_LENDIAN) && !defined(SK_UINT8_BITFIELD_BENDIAN) 122 #ifdef SK_CPU_LENDIAN 123 #define SK_UINT8_BITFIELD_LENDIAN 124 #else 125 #define SK_UINT8_BITFIELD_BENDIAN 126 #endif 127 #endif 128 129 #ifdef SK_UINT8_BITFIELD_LENDIAN 130 #define SK_UINT8_BITFIELD(f0, f1, f2, f3, f4, f5, f6, f7) \ 131 SK_OT_BYTE f0 : 1; \ 132 SK_OT_BYTE f1 : 1; \ 133 SK_OT_BYTE f2 : 1; \ 134 SK_OT_BYTE f3 : 1; \ 135 SK_OT_BYTE f4 : 1; \ 136 SK_OT_BYTE f5 : 1; \ 137 SK_OT_BYTE f6 : 1; \ 138 SK_OT_BYTE f7 : 1; 139 #else 140 #define SK_UINT8_BITFIELD(f0, f1, f2, f3, f4, f5, f6, f7) \ 141 SK_OT_BYTE f7 : 1; \ 142 SK_OT_BYTE f6 : 1; \ 143 SK_OT_BYTE f5 : 1; \ 144 SK_OT_BYTE f4 : 1; \ 145 SK_OT_BYTE f3 : 1; \ 146 SK_OT_BYTE f2 : 1; \ 147 SK_OT_BYTE f1 : 1; \ 148 SK_OT_BYTE f0 : 1; 149 #endif 150 151 #endif 152 153