crn_pixel_format.cpp 9.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280
  1. // File: crn_pixel_format.cpp
  2. // See Copyright Notice and license at the end of inc/crnlib.h
  3. #include "crn_core.h"
  4. #include "crn_pixel_format.h"
  5. #include "crn_image.h"
  6. namespace crnlib
  7. {
  8. namespace pixel_format_helpers
  9. {
  10. const pixel_format g_all_pixel_formats[] =
  11. {
  12. PIXEL_FMT_DXT1,
  13. PIXEL_FMT_DXT2,
  14. PIXEL_FMT_DXT3,
  15. PIXEL_FMT_DXT4,
  16. PIXEL_FMT_DXT5,
  17. PIXEL_FMT_3DC,
  18. PIXEL_FMT_DXN,
  19. PIXEL_FMT_DXT5A,
  20. PIXEL_FMT_DXT5_CCxY,
  21. PIXEL_FMT_DXT5_xGxR,
  22. PIXEL_FMT_DXT5_xGBR,
  23. PIXEL_FMT_DXT5_AGBR,
  24. PIXEL_FMT_DXT1A,
  25. PIXEL_FMT_ETC1,
  26. PIXEL_FMT_R8G8B8,
  27. PIXEL_FMT_L8,
  28. PIXEL_FMT_A8,
  29. PIXEL_FMT_A8L8,
  30. PIXEL_FMT_A8R8G8B8
  31. };
  32. uint get_num_formats()
  33. {
  34. return sizeof(g_all_pixel_formats) / sizeof(g_all_pixel_formats[0]);
  35. }
  36. pixel_format get_pixel_format_by_index(uint index)
  37. {
  38. CRNLIB_ASSERT(index < get_num_formats());
  39. return g_all_pixel_formats[index];
  40. }
  41. const char* get_pixel_format_string(pixel_format fmt)
  42. {
  43. switch (fmt)
  44. {
  45. case PIXEL_FMT_INVALID: return "INVALID";
  46. case PIXEL_FMT_DXT1: return "DXT1";
  47. case PIXEL_FMT_DXT1A: return "DXT1A";
  48. case PIXEL_FMT_DXT2: return "DXT2";
  49. case PIXEL_FMT_DXT3: return "DXT3";
  50. case PIXEL_FMT_DXT4: return "DXT4";
  51. case PIXEL_FMT_DXT5: return "DXT5";
  52. case PIXEL_FMT_3DC: return "3DC";
  53. case PIXEL_FMT_DXN: return "DXN";
  54. case PIXEL_FMT_DXT5A: return "DXT5A";
  55. case PIXEL_FMT_DXT5_CCxY: return "DXT5_CCxY";
  56. case PIXEL_FMT_DXT5_xGxR: return "DXT5_xGxR";
  57. case PIXEL_FMT_DXT5_xGBR: return "DXT5_xGBR";
  58. case PIXEL_FMT_DXT5_AGBR: return "DXT5_AGBR";
  59. case PIXEL_FMT_ETC1: return "ETC1";
  60. case PIXEL_FMT_R8G8B8: return "R8G8B8";
  61. case PIXEL_FMT_A8R8G8B8: return "A8R8G8B8";
  62. case PIXEL_FMT_A8: return "A8";
  63. case PIXEL_FMT_L8: return "L8";
  64. case PIXEL_FMT_A8L8: return "A8L8";
  65. default: break;
  66. }
  67. CRNLIB_ASSERT(false);
  68. return "?";
  69. }
  70. const char* get_crn_format_string(crn_format fmt)
  71. {
  72. switch (fmt)
  73. {
  74. case cCRNFmtDXT1: return "DXT1";
  75. case cCRNFmtDXT3: return "DXT3";
  76. case cCRNFmtDXT5: return "DXT5";
  77. case cCRNFmtDXT5_CCxY: return "DXT5_CCxY";
  78. case cCRNFmtDXT5_xGBR: return "DXT5_xGBR";
  79. case cCRNFmtDXT5_AGBR: return "DXT5_AGBR";
  80. case cCRNFmtDXT5_xGxR: return "DXT5_xGxR";
  81. case cCRNFmtDXN_XY: return "DXN_XY";
  82. case cCRNFmtDXN_YX: return "DXN_YX";
  83. case cCRNFmtDXT5A: return "DXT5A";
  84. case cCRNFmtETC1: return "ETC1";
  85. default: break;
  86. }
  87. CRNLIB_ASSERT(false);
  88. return "?";
  89. }
  90. component_flags get_component_flags(pixel_format fmt)
  91. {
  92. // These flags are for *uncooked* pixels, i.e. after after adding Z to DXN maps, or converting YCC maps to RGB, etc.
  93. uint flags = cCompFlagRValid | cCompFlagGValid | cCompFlagBValid | cCompFlagAValid | cCompFlagGrayscale;
  94. switch (fmt)
  95. {
  96. case PIXEL_FMT_DXT1:
  97. case PIXEL_FMT_ETC1:
  98. {
  99. flags = cCompFlagRValid | cCompFlagGValid | cCompFlagBValid;
  100. break;
  101. }
  102. case PIXEL_FMT_DXT1A:
  103. {
  104. flags = cCompFlagRValid | cCompFlagGValid | cCompFlagBValid | cCompFlagAValid;
  105. break;
  106. }
  107. case PIXEL_FMT_DXT2:
  108. case PIXEL_FMT_DXT3:
  109. {
  110. flags = cCompFlagRValid | cCompFlagGValid | cCompFlagBValid | cCompFlagAValid;
  111. break;
  112. }
  113. case PIXEL_FMT_DXT4:
  114. case PIXEL_FMT_DXT5:
  115. {
  116. flags = cCompFlagRValid | cCompFlagGValid | cCompFlagBValid | cCompFlagAValid;
  117. break;
  118. }
  119. case PIXEL_FMT_DXT5A:
  120. {
  121. flags = cCompFlagAValid;
  122. break;
  123. }
  124. case PIXEL_FMT_DXT5_CCxY:
  125. {
  126. flags = cCompFlagRValid | cCompFlagGValid | cCompFlagBValid | cCompFlagLumaChroma;
  127. break;
  128. }
  129. case PIXEL_FMT_DXT5_xGBR:
  130. {
  131. flags = cCompFlagRValid | cCompFlagGValid | cCompFlagBValid | cCompFlagNormalMap;
  132. break;
  133. }
  134. case PIXEL_FMT_DXT5_AGBR:
  135. {
  136. flags = cCompFlagRValid | cCompFlagGValid | cCompFlagBValid | cCompFlagAValid | cCompFlagNormalMap;
  137. break;
  138. }
  139. case PIXEL_FMT_DXT5_xGxR:
  140. {
  141. flags = cCompFlagRValid | cCompFlagGValid | cCompFlagBValid | cCompFlagNormalMap;
  142. break;
  143. }
  144. case PIXEL_FMT_3DC:
  145. {
  146. flags = cCompFlagRValid | cCompFlagGValid | cCompFlagBValid | cCompFlagNormalMap;
  147. break;
  148. }
  149. case PIXEL_FMT_DXN:
  150. {
  151. flags = cCompFlagRValid | cCompFlagGValid | cCompFlagBValid | cCompFlagNormalMap;
  152. break;
  153. }
  154. case PIXEL_FMT_R8G8B8:
  155. {
  156. flags = cCompFlagRValid | cCompFlagGValid | cCompFlagBValid;
  157. break;
  158. }
  159. case PIXEL_FMT_A8R8G8B8:
  160. {
  161. flags = cCompFlagRValid | cCompFlagGValid | cCompFlagBValid | cCompFlagAValid;
  162. break;
  163. }
  164. case PIXEL_FMT_A8:
  165. {
  166. flags = cCompFlagAValid;
  167. break;
  168. }
  169. case PIXEL_FMT_L8:
  170. {
  171. flags = cCompFlagRValid | cCompFlagGValid | cCompFlagBValid | cCompFlagGrayscale;
  172. break;
  173. }
  174. case PIXEL_FMT_A8L8:
  175. {
  176. flags = cCompFlagRValid | cCompFlagGValid | cCompFlagBValid | cCompFlagAValid | cCompFlagGrayscale;
  177. break;
  178. }
  179. default:
  180. {
  181. CRNLIB_ASSERT(0);
  182. break;
  183. }
  184. }
  185. return static_cast<component_flags>(flags);
  186. }
  187. crn_format convert_pixel_format_to_best_crn_format(pixel_format crn_fmt)
  188. {
  189. crn_format fmt = cCRNFmtDXT1;
  190. switch (crn_fmt)
  191. {
  192. case PIXEL_FMT_DXT1:
  193. case PIXEL_FMT_DXT1A:
  194. fmt = cCRNFmtDXT1;
  195. break;
  196. case PIXEL_FMT_DXT2:
  197. case PIXEL_FMT_DXT3:
  198. case PIXEL_FMT_DXT4:
  199. case PIXEL_FMT_DXT5:
  200. fmt = cCRNFmtDXT5;
  201. break;
  202. case PIXEL_FMT_3DC:
  203. fmt = cCRNFmtDXN_YX;
  204. break;
  205. case PIXEL_FMT_DXN:
  206. fmt = cCRNFmtDXN_XY;
  207. break;
  208. case PIXEL_FMT_DXT5A:
  209. fmt = cCRNFmtDXT5A;
  210. break;
  211. case PIXEL_FMT_R8G8B8:
  212. case PIXEL_FMT_L8:
  213. fmt = cCRNFmtDXT1;
  214. break;
  215. case PIXEL_FMT_A8R8G8B8:
  216. case PIXEL_FMT_A8:
  217. case PIXEL_FMT_A8L8:
  218. fmt = cCRNFmtDXT5;
  219. break;
  220. case PIXEL_FMT_DXT5_CCxY:
  221. fmt = cCRNFmtDXT5_CCxY;
  222. break;
  223. case PIXEL_FMT_DXT5_xGBR:
  224. fmt = cCRNFmtDXT5_xGBR;
  225. break;
  226. case PIXEL_FMT_DXT5_AGBR:
  227. fmt = cCRNFmtDXT5_AGBR;
  228. break;
  229. case PIXEL_FMT_DXT5_xGxR:
  230. fmt = cCRNFmtDXT5_xGxR;
  231. break;
  232. case PIXEL_FMT_ETC1:
  233. fmt = cCRNFmtETC1;
  234. break;
  235. default:
  236. {
  237. CRNLIB_ASSERT(false);
  238. break;
  239. }
  240. }
  241. return fmt;
  242. }
  243. pixel_format convert_crn_format_to_pixel_format(crn_format fmt)
  244. {
  245. switch (fmt)
  246. {
  247. case cCRNFmtDXT1: return PIXEL_FMT_DXT1;
  248. case cCRNFmtDXT3: return PIXEL_FMT_DXT3;
  249. case cCRNFmtDXT5: return PIXEL_FMT_DXT5;
  250. case cCRNFmtDXT5_CCxY: return PIXEL_FMT_DXT5_CCxY;
  251. case cCRNFmtDXT5_xGxR: return PIXEL_FMT_DXT5_xGxR;
  252. case cCRNFmtDXT5_xGBR: return PIXEL_FMT_DXT5_xGBR;
  253. case cCRNFmtDXT5_AGBR: return PIXEL_FMT_DXT5_AGBR;
  254. case cCRNFmtDXN_XY: return PIXEL_FMT_DXN;
  255. case cCRNFmtDXN_YX: return PIXEL_FMT_3DC;
  256. case cCRNFmtDXT5A: return PIXEL_FMT_DXT5A;
  257. case cCRNFmtETC1: return PIXEL_FMT_ETC1;
  258. default:
  259. {
  260. CRNLIB_ASSERT(false);
  261. break;
  262. }
  263. }
  264. return PIXEL_FMT_INVALID;
  265. }
  266. } // namespace pixel_format
  267. } // namespace crnlib