color.h 7.7 KB

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