SkEndian.h 6.3 KB

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