|
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 SkEndianSwap32(), 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 /** Reverse all 8 bytes in a 64bit value. |
|
81 e.g. 0x1122334455667788 -> 0x8877665544332211 |
|
82 */ |
|
83 static inline uint64_t SkEndianSwap64(uint64_t value) { |
|
84 return (((value & 0x00000000000000FFULL) << (8*7)) | |
|
85 ((value & 0x000000000000FF00ULL) << (8*5)) | |
|
86 ((value & 0x0000000000FF0000ULL) << (8*3)) | |
|
87 ((value & 0x00000000FF000000ULL) << (8*1)) | |
|
88 ((value & 0x000000FF00000000ULL) >> (8*1)) | |
|
89 ((value & 0x0000FF0000000000ULL) >> (8*3)) | |
|
90 ((value & 0x00FF000000000000ULL) >> (8*5)) | |
|
91 ((value) >> (8*7))); |
|
92 } |
|
93 template<uint64_t N> struct SkTEndianSwap64 { |
|
94 static const uint64_t value = (((N & 0x00000000000000FFULL) << (8*7)) | |
|
95 ((N & 0x000000000000FF00ULL) << (8*5)) | |
|
96 ((N & 0x0000000000FF0000ULL) << (8*3)) | |
|
97 ((N & 0x00000000FF000000ULL) << (8*1)) | |
|
98 ((N & 0x000000FF00000000ULL) >> (8*1)) | |
|
99 ((N & 0x0000FF0000000000ULL) >> (8*3)) | |
|
100 ((N & 0x00FF000000000000ULL) >> (8*5)) | |
|
101 ((N) >> (8*7))); |
|
102 }; |
|
103 |
|
104 /** Vector version of SkEndianSwap64(), which swaps the |
|
105 bytes of each value in the array. |
|
106 */ |
|
107 static inline void SkEndianSwap64s(uint64_t array[], int count) { |
|
108 SkASSERT(count == 0 || array != NULL); |
|
109 |
|
110 while (--count >= 0) { |
|
111 *array = SkEndianSwap64(*array); |
|
112 array += 1; |
|
113 } |
|
114 } |
|
115 |
|
116 #ifdef SK_CPU_LENDIAN |
|
117 #define SkEndian_SwapBE16(n) SkEndianSwap16(n) |
|
118 #define SkEndian_SwapBE32(n) SkEndianSwap32(n) |
|
119 #define SkEndian_SwapBE64(n) SkEndianSwap64(n) |
|
120 #define SkEndian_SwapLE16(n) (n) |
|
121 #define SkEndian_SwapLE32(n) (n) |
|
122 #define SkEndian_SwapLE64(n) (n) |
|
123 |
|
124 #define SkTEndian_SwapBE16(n) SkTEndianSwap16<n>::value |
|
125 #define SkTEndian_SwapBE32(n) SkTEndianSwap32<n>::value |
|
126 #define SkTEndian_SwapBE64(n) SkTEndianSwap64<n>::value |
|
127 #define SkTEndian_SwapLE16(n) (n) |
|
128 #define SkTEndian_SwapLE32(n) (n) |
|
129 #define SkTEndian_SwapLE64(n) (n) |
|
130 #else // SK_CPU_BENDIAN |
|
131 #define SkEndian_SwapBE16(n) (n) |
|
132 #define SkEndian_SwapBE32(n) (n) |
|
133 #define SkEndian_SwapBE64(n) (n) |
|
134 #define SkEndian_SwapLE16(n) SkEndianSwap16(n) |
|
135 #define SkEndian_SwapLE32(n) SkEndianSwap32(n) |
|
136 #define SkEndian_SwapLE64(n) SkEndianSwap64(n) |
|
137 |
|
138 #define SkTEndian_SwapBE16(n) (n) |
|
139 #define SkTEndian_SwapBE32(n) (n) |
|
140 #define SkTEndian_SwapBE64(n) (n) |
|
141 #define SkTEndian_SwapLE16(n) SkTEndianSwap16<n>::value |
|
142 #define SkTEndian_SwapLE32(n) SkTEndianSwap32<n>::value |
|
143 #define SkTEndian_SwapLE64(n) SkTEndianSwap64<n>::value |
|
144 #endif |
|
145 |
|
146 // When a bytestream is embedded in a 32-bit word, how far we need to |
|
147 // shift the word to extract each byte from the low 8 bits by anding with 0xff. |
|
148 #ifdef SK_CPU_LENDIAN |
|
149 #define SkEndian_Byte0Shift 0 |
|
150 #define SkEndian_Byte1Shift 8 |
|
151 #define SkEndian_Byte2Shift 16 |
|
152 #define SkEndian_Byte3Shift 24 |
|
153 #else // SK_CPU_BENDIAN |
|
154 #define SkEndian_Byte0Shift 24 |
|
155 #define SkEndian_Byte1Shift 16 |
|
156 #define SkEndian_Byte2Shift 8 |
|
157 #define SkEndian_Byte3Shift 0 |
|
158 #endif |
|
159 |
|
160 |
|
161 #if defined(SK_UINT8_BITFIELD_LENDIAN) && defined(SK_UINT8_BITFIELD_BENDIAN) |
|
162 #error "can't have both bitfield LENDIAN and BENDIAN defined" |
|
163 #endif |
|
164 |
|
165 #if !defined(SK_UINT8_BITFIELD_LENDIAN) && !defined(SK_UINT8_BITFIELD_BENDIAN) |
|
166 #ifdef SK_CPU_LENDIAN |
|
167 #define SK_UINT8_BITFIELD_LENDIAN |
|
168 #else |
|
169 #define SK_UINT8_BITFIELD_BENDIAN |
|
170 #endif |
|
171 #endif |
|
172 |
|
173 #ifdef SK_UINT8_BITFIELD_LENDIAN |
|
174 #define SK_UINT8_BITFIELD(f0, f1, f2, f3, f4, f5, f6, f7) \ |
|
175 SK_OT_BYTE f0 : 1; \ |
|
176 SK_OT_BYTE f1 : 1; \ |
|
177 SK_OT_BYTE f2 : 1; \ |
|
178 SK_OT_BYTE f3 : 1; \ |
|
179 SK_OT_BYTE f4 : 1; \ |
|
180 SK_OT_BYTE f5 : 1; \ |
|
181 SK_OT_BYTE f6 : 1; \ |
|
182 SK_OT_BYTE f7 : 1; |
|
183 #else |
|
184 #define SK_UINT8_BITFIELD(f0, f1, f2, f3, f4, f5, f6, f7) \ |
|
185 SK_OT_BYTE f7 : 1; \ |
|
186 SK_OT_BYTE f6 : 1; \ |
|
187 SK_OT_BYTE f5 : 1; \ |
|
188 SK_OT_BYTE f4 : 1; \ |
|
189 SK_OT_BYTE f3 : 1; \ |
|
190 SK_OT_BYTE f2 : 1; \ |
|
191 SK_OT_BYTE f1 : 1; \ |
|
192 SK_OT_BYTE f0 : 1; |
|
193 #endif |
|
194 |
|
195 #endif |