EtcColorFloatRGBA.h 7.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322
  1. /*
  2. * Copyright 2015 The Etc2Comp Authors.
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License");
  5. * you may not use this file except in compliance with the License.
  6. * You may obtain a copy of the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS,
  12. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. * See the License for the specific language governing permissions and
  14. * limitations under the License.
  15. */
  16. #pragma once
  17. #include "EtcConfig.h"
  18. #include "EtcColor.h"
  19. #include <math.h>
  20. namespace Etc
  21. {
  22. class ColorFloatRGBA
  23. {
  24. public:
  25. ColorFloatRGBA(void)
  26. {
  27. fR = fG = fB = fA = 0.0f;
  28. }
  29. ColorFloatRGBA(float a_fR, float a_fG, float a_fB, float a_fA)
  30. {
  31. fR = a_fR;
  32. fG = a_fG;
  33. fB = a_fB;
  34. fA = a_fA;
  35. }
  36. inline ColorFloatRGBA operator+(ColorFloatRGBA& a_rfrgba)
  37. {
  38. ColorFloatRGBA frgba;
  39. frgba.fR = fR + a_rfrgba.fR;
  40. frgba.fG = fG + a_rfrgba.fG;
  41. frgba.fB = fB + a_rfrgba.fB;
  42. frgba.fA = fA + a_rfrgba.fA;
  43. return frgba;
  44. }
  45. inline ColorFloatRGBA operator+(float a_f)
  46. {
  47. ColorFloatRGBA frgba;
  48. frgba.fR = fR + a_f;
  49. frgba.fG = fG + a_f;
  50. frgba.fB = fB + a_f;
  51. frgba.fA = fA;
  52. return frgba;
  53. }
  54. inline ColorFloatRGBA operator-(float a_f)
  55. {
  56. ColorFloatRGBA frgba;
  57. frgba.fR = fR - a_f;
  58. frgba.fG = fG - a_f;
  59. frgba.fB = fB - a_f;
  60. frgba.fA = fA;
  61. return frgba;
  62. }
  63. inline ColorFloatRGBA operator-(ColorFloatRGBA& a_rfrgba)
  64. {
  65. ColorFloatRGBA frgba;
  66. frgba.fR = fR - a_rfrgba.fR;
  67. frgba.fG = fG - a_rfrgba.fG;
  68. frgba.fB = fB - a_rfrgba.fB;
  69. frgba.fA = fA - a_rfrgba.fA;
  70. return frgba;
  71. }
  72. inline ColorFloatRGBA operator*(float a_f)
  73. {
  74. ColorFloatRGBA frgba;
  75. frgba.fR = fR * a_f;
  76. frgba.fG = fG * a_f;
  77. frgba.fB = fB * a_f;
  78. frgba.fA = fA;
  79. return frgba;
  80. }
  81. inline ColorFloatRGBA ScaleRGB(float a_f)
  82. {
  83. ColorFloatRGBA frgba;
  84. frgba.fR = a_f * fR;
  85. frgba.fG = a_f * fG;
  86. frgba.fB = a_f * fB;
  87. frgba.fA = fA;
  88. return frgba;
  89. }
  90. inline ColorFloatRGBA RoundRGB(void)
  91. {
  92. ColorFloatRGBA frgba;
  93. frgba.fR = roundf(fR);
  94. frgba.fG = roundf(fG);
  95. frgba.fB = roundf(fB);
  96. return frgba;
  97. }
  98. inline ColorFloatRGBA ToLinear()
  99. {
  100. ColorFloatRGBA frgbaLinear;
  101. frgbaLinear.fR = LogToLinear(fR);
  102. frgbaLinear.fG = LogToLinear(fG);
  103. frgbaLinear.fB = LogToLinear(fB);
  104. frgbaLinear.fA = fA;
  105. return frgbaLinear;
  106. }
  107. inline ColorFloatRGBA ToLog(void)
  108. {
  109. ColorFloatRGBA frgbaLog;
  110. frgbaLog.fR = LinearToLog(fR);
  111. frgbaLog.fG = LinearToLog(fG);
  112. frgbaLog.fB = LinearToLog(fB);
  113. frgbaLog.fA = fA;
  114. return frgbaLog;
  115. }
  116. inline static ColorFloatRGBA ConvertFromRGBA8(unsigned char a_ucR,
  117. unsigned char a_ucG, unsigned char a_ucB, unsigned char a_ucA)
  118. {
  119. ColorFloatRGBA frgba;
  120. frgba.fR = (float)a_ucR / 255.0f;
  121. frgba.fG = (float)a_ucG / 255.0f;
  122. frgba.fB = (float)a_ucB / 255.0f;
  123. frgba.fA = (float)a_ucA / 255.0f;
  124. return frgba;
  125. }
  126. inline static ColorFloatRGBA ConvertFromRGB4(unsigned char a_ucR4,
  127. unsigned char a_ucG4,
  128. unsigned char a_ucB4)
  129. {
  130. ColorFloatRGBA frgba;
  131. unsigned char ucR8 = (unsigned char)((a_ucR4 << 4) + a_ucR4);
  132. unsigned char ucG8 = (unsigned char)((a_ucG4 << 4) + a_ucG4);
  133. unsigned char ucB8 = (unsigned char)((a_ucB4 << 4) + a_ucB4);
  134. frgba.fR = (float)ucR8 / 255.0f;
  135. frgba.fG = (float)ucG8 / 255.0f;
  136. frgba.fB = (float)ucB8 / 255.0f;
  137. frgba.fA = 1.0f;
  138. return frgba;
  139. }
  140. inline static ColorFloatRGBA ConvertFromRGB5(unsigned char a_ucR5,
  141. unsigned char a_ucG5,
  142. unsigned char a_ucB5)
  143. {
  144. ColorFloatRGBA frgba;
  145. unsigned char ucR8 = (unsigned char)((a_ucR5 << 3) + (a_ucR5 >> 2));
  146. unsigned char ucG8 = (unsigned char)((a_ucG5 << 3) + (a_ucG5 >> 2));
  147. unsigned char ucB8 = (unsigned char)((a_ucB5 << 3) + (a_ucB5 >> 2));
  148. frgba.fR = (float)ucR8 / 255.0f;
  149. frgba.fG = (float)ucG8 / 255.0f;
  150. frgba.fB = (float)ucB8 / 255.0f;
  151. frgba.fA = 1.0f;
  152. return frgba;
  153. }
  154. inline static ColorFloatRGBA ConvertFromR6G7B6(unsigned char a_ucR6,
  155. unsigned char a_ucG7,
  156. unsigned char a_ucB6)
  157. {
  158. ColorFloatRGBA frgba;
  159. unsigned char ucR8 = (unsigned char)((a_ucR6 << 2) + (a_ucR6 >> 4));
  160. unsigned char ucG8 = (unsigned char)((a_ucG7 << 1) + (a_ucG7 >> 6));
  161. unsigned char ucB8 = (unsigned char)((a_ucB6 << 2) + (a_ucB6 >> 4));
  162. frgba.fR = (float)ucR8 / 255.0f;
  163. frgba.fG = (float)ucG8 / 255.0f;
  164. frgba.fB = (float)ucB8 / 255.0f;
  165. frgba.fA = 1.0f;
  166. return frgba;
  167. }
  168. // quantize to 4 bits, expand to 8 bits
  169. inline ColorFloatRGBA QuantizeR4G4B4(void) const
  170. {
  171. ColorFloatRGBA frgba = *this;
  172. // quantize to 4 bits
  173. frgba = frgba.ClampRGB().ScaleRGB(15.0f).RoundRGB();
  174. unsigned int uiR4 = (unsigned int)frgba.fR;
  175. unsigned int uiG4 = (unsigned int)frgba.fG;
  176. unsigned int uiB4 = (unsigned int)frgba.fB;
  177. // expand to 8 bits
  178. frgba.fR = (float) ((uiR4 << 4) + uiR4);
  179. frgba.fG = (float) ((uiG4 << 4) + uiG4);
  180. frgba.fB = (float) ((uiB4 << 4) + uiB4);
  181. frgba = frgba.ScaleRGB(1.0f/255.0f);
  182. return frgba;
  183. }
  184. // quantize to 5 bits, expand to 8 bits
  185. inline ColorFloatRGBA QuantizeR5G5B5(void) const
  186. {
  187. ColorFloatRGBA frgba = *this;
  188. // quantize to 5 bits
  189. frgba = frgba.ClampRGB().ScaleRGB(31.0f).RoundRGB();
  190. unsigned int uiR5 = (unsigned int)frgba.fR;
  191. unsigned int uiG5 = (unsigned int)frgba.fG;
  192. unsigned int uiB5 = (unsigned int)frgba.fB;
  193. // expand to 8 bits
  194. frgba.fR = (float)((uiR5 << 3) + (uiR5 >> 2));
  195. frgba.fG = (float)((uiG5 << 3) + (uiG5 >> 2));
  196. frgba.fB = (float)((uiB5 << 3) + (uiB5 >> 2));
  197. frgba = frgba.ScaleRGB(1.0f / 255.0f);
  198. return frgba;
  199. }
  200. // quantize to 6/7/6 bits, expand to 8 bits
  201. inline ColorFloatRGBA QuantizeR6G7B6(void) const
  202. {
  203. ColorFloatRGBA frgba = *this;
  204. // quantize to 6/7/6 bits
  205. ColorFloatRGBA frgba6 = frgba.ClampRGB().ScaleRGB(63.0f).RoundRGB();
  206. ColorFloatRGBA frgba7 = frgba.ClampRGB().ScaleRGB(127.0f).RoundRGB();
  207. unsigned int uiR6 = (unsigned int)frgba6.fR;
  208. unsigned int uiG7 = (unsigned int)frgba7.fG;
  209. unsigned int uiB6 = (unsigned int)frgba6.fB;
  210. // expand to 8 bits
  211. frgba.fR = (float)((uiR6 << 2) + (uiR6 >> 4));
  212. frgba.fG = (float)((uiG7 << 1) + (uiG7 >> 6));
  213. frgba.fB = (float)((uiB6 << 2) + (uiB6 >> 4));
  214. frgba = frgba.ScaleRGB(1.0f / 255.0f);
  215. return frgba;
  216. }
  217. inline ColorFloatRGBA ClampRGB(void)
  218. {
  219. ColorFloatRGBA frgba = *this;
  220. if (frgba.fR < 0.0f) { frgba.fR = 0.0f; }
  221. if (frgba.fR > 1.0f) { frgba.fR = 1.0f; }
  222. if (frgba.fG < 0.0f) { frgba.fG = 0.0f; }
  223. if (frgba.fG > 1.0f) { frgba.fG = 1.0f; }
  224. if (frgba.fB < 0.0f) { frgba.fB = 0.0f; }
  225. if (frgba.fB > 1.0f) { frgba.fB = 1.0f; }
  226. return frgba;
  227. }
  228. inline ColorFloatRGBA ClampRGBA(void)
  229. {
  230. ColorFloatRGBA frgba = *this;
  231. if (frgba.fR < 0.0f) { frgba.fR = 0.0f; }
  232. if (frgba.fR > 1.0f) { frgba.fR = 1.0f; }
  233. if (frgba.fG < 0.0f) { frgba.fG = 0.0f; }
  234. if (frgba.fG > 1.0f) { frgba.fG = 1.0f; }
  235. if (frgba.fB < 0.0f) { frgba.fB = 0.0f; }
  236. if (frgba.fB > 1.0f) { frgba.fB = 1.0f; }
  237. if (frgba.fA < 0.0f) { frgba.fA = 0.0f; }
  238. if (frgba.fA > 1.0f) { frgba.fA = 1.0f; }
  239. return frgba;
  240. }
  241. inline int IntRed(float a_fScale)
  242. {
  243. return (int)roundf(fR * a_fScale);
  244. }
  245. inline int IntGreen(float a_fScale)
  246. {
  247. return (int)roundf(fG * a_fScale);
  248. }
  249. inline int IntBlue(float a_fScale)
  250. {
  251. return (int)roundf(fB * a_fScale);
  252. }
  253. inline int IntAlpha(float a_fScale)
  254. {
  255. return (int)roundf(fA * a_fScale);
  256. }
  257. float fR, fG, fB, fA;
  258. };
  259. }