color.h 7.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259
  1. // Copyright 2014 Citra Emulator Project
  2. // Licensed under GPLv2 or any later version
  3. // Refer to the license.txt file included.
  4. #pragma once
  5. #include "common/common_types.h"
  6. #include "common/swap.h"
  7. #include "common/vector_math.h"
  8. namespace Color {
  9. /// Convert a 1-bit color component to 8 bit
  10. constexpr u8 Convert1To8(u8 value) {
  11. return value * 255;
  12. }
  13. /// Convert a 4-bit color component to 8 bit
  14. constexpr u8 Convert4To8(u8 value) {
  15. return (value << 4) | value;
  16. }
  17. /// Convert a 5-bit color component to 8 bit
  18. constexpr u8 Convert5To8(u8 value) {
  19. return (value << 3) | (value >> 2);
  20. }
  21. /// Convert a 6-bit color component to 8 bit
  22. constexpr u8 Convert6To8(u8 value) {
  23. return (value << 2) | (value >> 4);
  24. }
  25. /// Convert a 8-bit color component to 1 bit
  26. constexpr u8 Convert8To1(u8 value) {
  27. return value >> 7;
  28. }
  29. /// Convert a 8-bit color component to 4 bit
  30. constexpr u8 Convert8To4(u8 value) {
  31. return value >> 4;
  32. }
  33. /// Convert a 8-bit color component to 5 bit
  34. constexpr u8 Convert8To5(u8 value) {
  35. return value >> 3;
  36. }
  37. /// Convert a 8-bit color component to 6 bit
  38. constexpr u8 Convert8To6(u8 value) {
  39. return value >> 2;
  40. }
  41. /**
  42. * Decode a color stored in RGBA8 format
  43. * @param bytes Pointer to encoded source color
  44. * @return Result color decoded as Math::Vec4<u8>
  45. */
  46. inline const Math::Vec4<u8> DecodeRGBA8(const u8* bytes) {
  47. return {bytes[3], bytes[2], bytes[1], bytes[0]};
  48. }
  49. /**
  50. * Decode a color stored in RGB8 format
  51. * @param bytes Pointer to encoded source color
  52. * @return Result color decoded as Math::Vec4<u8>
  53. */
  54. inline const Math::Vec4<u8> DecodeRGB8(const u8* bytes) {
  55. return {bytes[2], bytes[1], bytes[0], 255};
  56. }
  57. /**
  58. * Decode a color stored in RG8 (aka HILO8) format
  59. * @param bytes Pointer to encoded source color
  60. * @return Result color decoded as Math::Vec4<u8>
  61. */
  62. inline const Math::Vec4<u8> DecodeRG8(const u8* bytes) {
  63. return {bytes[1], bytes[0], 0, 255};
  64. }
  65. /**
  66. * Decode a color stored in RGB565 format
  67. * @param bytes Pointer to encoded source color
  68. * @return Result color decoded as Math::Vec4<u8>
  69. */
  70. inline const Math::Vec4<u8> DecodeRGB565(const u8* bytes) {
  71. const u16_le pixel = *reinterpret_cast<const u16_le*>(bytes);
  72. return {Convert5To8((pixel >> 11) & 0x1F), Convert6To8((pixel >> 5) & 0x3F),
  73. Convert5To8(pixel & 0x1F), 255};
  74. }
  75. /**
  76. * Decode a color stored in RGB5A1 format
  77. * @param bytes Pointer to encoded source color
  78. * @return Result color decoded as Math::Vec4<u8>
  79. */
  80. inline const Math::Vec4<u8> DecodeRGB5A1(const u8* bytes) {
  81. const u16_le pixel = *reinterpret_cast<const u16_le*>(bytes);
  82. return {Convert5To8((pixel >> 11) & 0x1F), Convert5To8((pixel >> 6) & 0x1F),
  83. Convert5To8((pixel >> 1) & 0x1F), Convert1To8(pixel & 0x1)};
  84. }
  85. /**
  86. * Decode a color stored in RGBA4 format
  87. * @param bytes Pointer to encoded source color
  88. * @return Result color decoded as Math::Vec4<u8>
  89. */
  90. inline const Math::Vec4<u8> DecodeRGBA4(const u8* bytes) {
  91. const u16_le pixel = *reinterpret_cast<const u16_le*>(bytes);
  92. return {Convert4To8((pixel >> 12) & 0xF), Convert4To8((pixel >> 8) & 0xF),
  93. Convert4To8((pixel >> 4) & 0xF), Convert4To8(pixel & 0xF)};
  94. }
  95. /**
  96. * Decode a depth value stored in D16 format
  97. * @param bytes Pointer to encoded source value
  98. * @return Depth value as an u32
  99. */
  100. inline u32 DecodeD16(const u8* bytes) {
  101. return *reinterpret_cast<const u16_le*>(bytes);
  102. }
  103. /**
  104. * Decode a depth value stored in D24 format
  105. * @param bytes Pointer to encoded source value
  106. * @return Depth value as an u32
  107. */
  108. inline u32 DecodeD24(const u8* bytes) {
  109. return (bytes[2] << 16) | (bytes[1] << 8) | bytes[0];
  110. }
  111. /**
  112. * Decode a depth value and a stencil value stored in D24S8 format
  113. * @param bytes Pointer to encoded source values
  114. * @return Resulting values stored as a Math::Vec2
  115. */
  116. inline const Math::Vec2<u32> DecodeD24S8(const u8* bytes) {
  117. return {static_cast<u32>((bytes[2] << 16) | (bytes[1] << 8) | bytes[0]), bytes[3]};
  118. }
  119. /**
  120. * Encode a color as RGBA8 format
  121. * @param color Source color to encode
  122. * @param bytes Destination pointer to store encoded color
  123. */
  124. inline void EncodeRGBA8(const Math::Vec4<u8>& color, u8* bytes) {
  125. bytes[3] = color.r();
  126. bytes[2] = color.g();
  127. bytes[1] = color.b();
  128. bytes[0] = color.a();
  129. }
  130. /**
  131. * Encode a color as RGB8 format
  132. * @param color Source color to encode
  133. * @param bytes Destination pointer to store encoded color
  134. */
  135. inline void EncodeRGB8(const Math::Vec4<u8>& color, u8* bytes) {
  136. bytes[2] = color.r();
  137. bytes[1] = color.g();
  138. bytes[0] = color.b();
  139. }
  140. /**
  141. * Encode a color as RG8 (aka HILO8) format
  142. * @param color Source color to encode
  143. * @param bytes Destination pointer to store encoded color
  144. */
  145. inline void EncodeRG8(const Math::Vec4<u8>& color, u8* bytes) {
  146. bytes[1] = color.r();
  147. bytes[0] = color.g();
  148. }
  149. /**
  150. * Encode a color as RGB565 format
  151. * @param color Source color to encode
  152. * @param bytes Destination pointer to store encoded color
  153. */
  154. inline void EncodeRGB565(const Math::Vec4<u8>& color, u8* bytes) {
  155. *reinterpret_cast<u16_le*>(bytes) =
  156. (Convert8To5(color.r()) << 11) | (Convert8To6(color.g()) << 5) | Convert8To5(color.b());
  157. }
  158. /**
  159. * Encode a color as RGB5A1 format
  160. * @param color Source color to encode
  161. * @param bytes Destination pointer to store encoded color
  162. */
  163. inline void EncodeRGB5A1(const Math::Vec4<u8>& color, u8* bytes) {
  164. *reinterpret_cast<u16_le*>(bytes) = (Convert8To5(color.r()) << 11) |
  165. (Convert8To5(color.g()) << 6) |
  166. (Convert8To5(color.b()) << 1) | Convert8To1(color.a());
  167. }
  168. /**
  169. * Encode a color as RGBA4 format
  170. * @param color Source color to encode
  171. * @param bytes Destination pointer to store encoded color
  172. */
  173. inline void EncodeRGBA4(const Math::Vec4<u8>& color, u8* bytes) {
  174. *reinterpret_cast<u16_le*>(bytes) = (Convert8To4(color.r()) << 12) |
  175. (Convert8To4(color.g()) << 8) |
  176. (Convert8To4(color.b()) << 4) | Convert8To4(color.a());
  177. }
  178. /**
  179. * Encode a 16 bit depth value as D16 format
  180. * @param value 16 bit source depth value to encode
  181. * @param bytes Pointer where to store the encoded value
  182. */
  183. inline void EncodeD16(u32 value, u8* bytes) {
  184. *reinterpret_cast<u16_le*>(bytes) = value & 0xFFFF;
  185. }
  186. /**
  187. * Encode a 24 bit depth value as D24 format
  188. * @param value 24 bit source depth value to encode
  189. * @param bytes Pointer where to store the encoded value
  190. */
  191. inline void EncodeD24(u32 value, u8* bytes) {
  192. bytes[0] = value & 0xFF;
  193. bytes[1] = (value >> 8) & 0xFF;
  194. bytes[2] = (value >> 16) & 0xFF;
  195. }
  196. /**
  197. * Encode a 24 bit depth and 8 bit stencil values as D24S8 format
  198. * @param depth 24 bit source depth value to encode
  199. * @param stencil 8 bit source stencil value to encode
  200. * @param bytes Pointer where to store the encoded value
  201. */
  202. inline void EncodeD24S8(u32 depth, u8 stencil, u8* bytes) {
  203. bytes[0] = depth & 0xFF;
  204. bytes[1] = (depth >> 8) & 0xFF;
  205. bytes[2] = (depth >> 16) & 0xFF;
  206. bytes[3] = stencil;
  207. }
  208. /**
  209. * Encode a 24 bit depth value as D24X8 format (32 bits per pixel with 8 bits unused)
  210. * @param depth 24 bit source depth value to encode
  211. * @param bytes Pointer where to store the encoded value
  212. * @note unused bits will not be modified
  213. */
  214. inline void EncodeD24X8(u32 depth, u8* bytes) {
  215. bytes[0] = depth & 0xFF;
  216. bytes[1] = (depth >> 8) & 0xFF;
  217. bytes[2] = (depth >> 16) & 0xFF;
  218. }
  219. /**
  220. * Encode an 8 bit stencil value as X24S8 format (32 bits per pixel with 24 bits unused)
  221. * @param stencil 8 bit source stencil value to encode
  222. * @param bytes Pointer where to store the encoded value
  223. * @note unused bits will not be modified
  224. */
  225. inline void EncodeX24S8(u8 stencil, u8* bytes) {
  226. bytes[3] = stencil;
  227. }
  228. } // namespace