1 // Copyright 2016 The SwiftShader Authors. All Rights Reserved. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 #ifndef sw_Color_hpp 16 #define sw_Color_hpp 17 18 #include "System/Types.hpp" 19 #include "System/Math.hpp" 20 21 namespace sw 22 { 23 template<class T> 24 struct Color 25 { 26 Color(); 27 28 Color(const Color<byte> &c); 29 Color(const Color<short> &c); 30 Color(const Color<float> &c); 31 32 Color(int c); 33 Color(unsigned short c); 34 Color(unsigned long c); 35 Color(unsigned int c); 36 37 Color(T r, T g, T b, T a = 1); 38 39 operator unsigned int() const; 40 41 T &operator[](int i); 42 const T &operator[](int i) const; 43 44 Color<T> operator+() const; 45 Color<T> operator-() const; 46 47 Color<T>& operator=(const Color<T>& c); 48 49 Color<T> &operator+=(const Color<T> &c); 50 Color<T> &operator*=(float l); 51 52 static Color<T> gradient(const Color<T> &c1, const Color<T> &c2, float d); 53 static Color<T> shade(const Color<T> &c1, const Color<T> &c2, float d); 54 55 template<class S> 56 friend Color<S> operator+(const Color<S> &c1, const Color<S> &c2); 57 template<class S> 58 friend Color<S> operator-(const Color<S> &c1, const Color<S> &c2); 59 60 template<class S> 61 friend Color<S> operator*(float l, const Color<S> &c); 62 template<class S> 63 friend Color<S> operator*(const Color<S> &c1, const Color<S> &c2); 64 template<class S> 65 friend Color<S> operator/(const Color<S> &c, float l); 66 67 T r; 68 T g; 69 T b; 70 T a; 71 }; 72 } 73 74 #include "System/Math.hpp" 75 76 namespace sw 77 { 78 template<class T> Color()79 inline Color<T>::Color() 80 { 81 } 82 83 template<> Color(const Color<byte> & c)84 inline Color<byte>::Color(const Color<byte> &c) 85 { 86 r = c.r; 87 g = c.g; 88 b = c.b; 89 a = c.a; 90 } 91 92 template<> Color(const Color<short> & c)93 inline Color<byte>::Color(const Color<short> &c) 94 { 95 r = clamp(c.r >> 4, 0, 255); 96 g = clamp(c.g >> 4, 0, 255); 97 b = clamp(c.b >> 4, 0, 255); 98 a = clamp(c.a >> 4, 0, 255); 99 } 100 101 template<> Color(const Color<float> & c)102 inline Color<byte>::Color(const Color<float> &c) 103 { 104 r = ifloor(clamp(c.r * 256.0f, 0.0f, 255.0f)); 105 g = ifloor(clamp(c.g * 256.0f, 0.0f, 255.0f)); 106 b = ifloor(clamp(c.b * 256.0f, 0.0f, 255.0f)); 107 a = ifloor(clamp(c.a * 256.0f, 0.0f, 255.0f)); 108 } 109 110 template<> Color(const Color<short> & c)111 inline Color<short>::Color(const Color<short> &c) 112 { 113 r = c.r; 114 g = c.g; 115 b = c.b; 116 a = c.a; 117 } 118 119 template<> Color(const Color<byte> & c)120 inline Color<short>::Color(const Color<byte> &c) 121 { 122 r = c.r << 4; 123 g = c.g << 4; 124 b = c.b << 4; 125 a = c.a << 4; 126 } 127 128 template<> Color(const Color<float> & c)129 inline Color<float>::Color(const Color<float> &c) 130 { 131 r = c.r; 132 g = c.g; 133 b = c.b; 134 a = c.a; 135 } 136 137 template<> Color(const Color<float> & c)138 inline Color<short>::Color(const Color<float> &c) 139 { 140 r = iround(clamp(c.r * 4095.0f, -4096.0f, 4095.0f)); 141 g = iround(clamp(c.g * 4095.0f, -4096.0f, 4095.0f)); 142 b = iround(clamp(c.b * 4095.0f, -4096.0f, 4095.0f)); 143 a = iround(clamp(c.a * 4095.0f, -4096.0f, 4095.0f)); 144 } 145 146 template<> Color(const Color<byte> & c)147 inline Color<float>::Color(const Color<byte> &c) 148 { 149 r = c.r / 255.0f; 150 g = c.g / 255.0f; 151 b = c.b / 255.0f; 152 a = c.a / 255.0f; 153 } 154 155 template<> Color(const Color<short> & c)156 inline Color<float>::Color(const Color<short> &c) 157 { 158 r = c.r / 4095.0f; 159 g = c.g / 4095.0f; 160 b = c.b / 4095.0f; 161 a = c.a / 4095.0f; 162 } 163 164 template<> Color(unsigned short c)165 inline Color<float>::Color(unsigned short c) 166 { 167 r = (float)(c & 0xF800) / (float)0xF800; 168 g = (float)(c & 0x07E0) / (float)0x07E0; 169 b = (float)(c & 0x001F) / (float)0x001F; 170 a = 1; 171 } 172 173 template<> Color(unsigned short c)174 inline Color<short>::Color(unsigned short c) 175 { 176 // 4.12 fixed-point format 177 r = ((c & 0xF800) >> 4) + ((c & 0xF800) >> 9) + ((c & 0xF800) >> 14); 178 g = ((c & 0x07E0) << 1) + ((c & 0x07E0) >> 5); 179 b = ((c & 0x001F) << 7) + ((c & 0x001F) << 2) + ((c & 0x001F) >> 3); 180 a = 0x1000; 181 } 182 183 template<> Color(unsigned short c)184 inline Color<byte>::Color(unsigned short c) 185 { 186 r = (byte)(((c & 0xF800) >> 8) + ((c & 0xE000) >> 13)); 187 g = (byte)(((c & 0x07E0) >> 3) + ((c & 0x0600) >> 9)); 188 b = (byte)(((c & 0x001F) << 3) + ((c & 0x001C) >> 2)); 189 a = 0xFF; 190 } 191 192 template<> Color(int c)193 inline Color<float>::Color(int c) 194 { 195 const float d = 1.0f / 255.0f; 196 197 r = (float)((c & 0x00FF0000) >> 16) * d; 198 g = (float)((c & 0x0000FF00) >> 8) * d; 199 b = (float)((c & 0x000000FF) >> 0) * d; 200 a = (float)((c & 0xFF000000) >> 24) * d; 201 } 202 203 template<> Color(int c)204 inline Color<short>::Color(int c) 205 { 206 // 4.12 fixed-point format 207 r = (short)((c & 0x00FF0000) >> 12); 208 g = (short)((c & 0x0000FF00) >> 4); 209 b = (short)((c & 0x000000FF) << 4); 210 a = (short)((c & 0xFF000000) >> 20); 211 } 212 213 template<> Color(int c)214 inline Color<byte>::Color(int c) 215 { 216 r = (byte)((c & 0x00FF0000) >> 16); 217 g = (byte)((c & 0x0000FF00) >> 8); 218 b = (byte)((c & 0x000000FF) >> 0); 219 a = (byte)((c & 0xFF000000) >> 24); 220 } 221 222 template<> Color(unsigned int c)223 inline Color<float>::Color(unsigned int c) 224 { 225 const float d = 1.0f / 255.0f; 226 227 r = (float)((c & 0x00FF0000) >> 16) * d; 228 g = (float)((c & 0x0000FF00) >> 8) * d; 229 b = (float)((c & 0x000000FF) >> 0) * d; 230 a = (float)((c & 0xFF000000) >> 24) * d; 231 } 232 233 template<> Color(unsigned int c)234 inline Color<short>::Color(unsigned int c) 235 { 236 // 4.12 fixed-point format 237 r = (short)((c & 0x00FF0000) >> 12); 238 g = (short)((c & 0x0000FF00) >> 4); 239 b = (short)((c & 0x000000FF) << 4); 240 a = (short)((c & 0xFF000000) >> 20); 241 } 242 243 template<> Color(unsigned int c)244 inline Color<byte>::Color(unsigned int c) 245 { 246 r = (byte)((c & 0x00FF0000) >> 16); 247 g = (byte)((c & 0x0000FF00) >> 8); 248 b = (byte)((c & 0x000000FF) >> 0); 249 a = (byte)((c & 0xFF000000) >> 24); 250 } 251 252 template<> Color(unsigned long c)253 inline Color<float>::Color(unsigned long c) 254 { 255 const float d = 1.0f / 255.0f; 256 257 r = (float)((c & 0x00FF0000) >> 16) * d; 258 g = (float)((c & 0x0000FF00) >> 8) * d; 259 b = (float)((c & 0x000000FF) >> 0) * d; 260 a = (float)((c & 0xFF000000) >> 24) * d; 261 } 262 263 template<> Color(unsigned long c)264 inline Color<short>::Color(unsigned long c) 265 { 266 // 4.12 fixed-point format 267 r = (short)((c & 0x00FF0000) >> 12); 268 g = (short)((c & 0x0000FF00) >> 4); 269 b = (short)((c & 0x000000FF) << 4); 270 a = (short)((c & 0xFF000000) >> 20); 271 } 272 273 template<> Color(unsigned long c)274 inline Color<byte>::Color(unsigned long c) 275 { 276 r = (byte)((c & 0x00FF0000) >> 16); 277 g = (byte)((c & 0x0000FF00) >> 8); 278 b = (byte)((c & 0x000000FF) >> 0); 279 a = (byte)((c & 0xFF000000) >> 24); 280 } 281 282 template<class T> Color(T r_,T g_,T b_,T a_)283 inline Color<T>::Color(T r_, T g_, T b_, T a_) 284 { 285 r = r_; 286 g = g_; 287 b = b_; 288 a = a_; 289 } 290 291 template<> operator unsigned int() const292 inline Color<float>::operator unsigned int() const 293 { 294 return ((unsigned int)min(b * 255.0f, 255.0f) << 0) | 295 ((unsigned int)min(g * 255.0f, 255.0f) << 8) | 296 ((unsigned int)min(r * 255.0f, 255.0f) << 16) | 297 ((unsigned int)min(a * 255.0f, 255.0f) << 24); 298 } 299 300 template<> operator unsigned int() const301 inline Color<short>::operator unsigned int() const 302 { 303 return ((unsigned int)min(b >> 4, 255) << 0) | 304 ((unsigned int)min(g >> 4, 255) << 8) | 305 ((unsigned int)min(r >> 4, 255) << 16) | 306 ((unsigned int)min(a >> 4, 255) << 24); 307 } 308 309 template<> operator unsigned int() const310 inline Color<byte>::operator unsigned int() const 311 { 312 return (b << 0) + 313 (g << 8) + 314 (r << 16) + 315 (a << 24); 316 } 317 318 template<class T> operator [](int i)319 inline T &Color<T>::operator[](int i) 320 { 321 return (&r)[i]; 322 } 323 324 template<class T> operator [](int i) const325 inline const T &Color<T>::operator[](int i) const 326 { 327 return (&r)[i]; 328 } 329 330 template<class T> operator +() const331 inline Color<T> Color<T>::operator+() const 332 { 333 return *this; 334 } 335 336 template<class T> operator -() const337 inline Color<T> Color<T>::operator-() const 338 { 339 return Color(-r, -g, -b, -a); 340 } 341 342 template<class T> operator =(const Color & c)343 inline Color<T> &Color<T>::operator=(const Color& c) 344 { 345 r = c.r; 346 g = c.g; 347 b = c.b; 348 a = c.a; 349 350 return *this; 351 } 352 353 template<class T> operator +=(const Color & c)354 inline Color<T> &Color<T>::operator+=(const Color &c) 355 { 356 r += c.r; 357 g += c.g; 358 b += c.b; 359 a += c.a; 360 361 return *this; 362 } 363 364 template<class T> operator *=(float l)365 inline Color<T> &Color<T>::operator*=(float l) 366 { 367 *this = l * *this; 368 369 return *this; 370 } 371 372 template<class T> operator +(const Color<T> & c1,const Color<T> & c2)373 inline Color<T> operator+(const Color<T> &c1, const Color<T> &c2) 374 { 375 return Color<T>(c1.r + c2.r, 376 c1.g + c2.g, 377 c1.b + c2.b, 378 c1.a + c2.a); 379 } 380 381 template<class T> operator -(const Color<T> & c1,const Color<T> & c2)382 inline Color<T> operator-(const Color<T> &c1, const Color<T> &c2) 383 { 384 return Color<T>(c1.r - c2.r, 385 c1.g - c2.g, 386 c1.b - c2.b, 387 c1.a - c2.a); 388 } 389 390 template<class T> operator *(float l,const Color<T> & c)391 inline Color<T> operator*(float l, const Color<T> &c) 392 { 393 T r = (T)(l * c.r); 394 T g = (T)(l * c.g); 395 T b = (T)(l * c.b); 396 T a = (T)(l * c.a); 397 398 return Color<T>(r, g, b, a); 399 } 400 401 template<class T> operator *(const Color<T> & c1,const Color<T> & c2)402 inline Color<T> operator*(const Color<T> &c1, const Color<T> &c2) 403 { 404 T r = c1.r * c2.r; 405 T g = c1.g * c2.g; 406 T b = c1.b * c2.b; 407 T a = c1.a * c2.a; 408 409 return Color<T>(r, g, b, a); 410 } 411 412 template<> operator *(const Color<short> & c1,const Color<short> & c2)413 inline Color<short> operator*(const Color<short> &c1, const Color<short> &c2) 414 { 415 short r = c1.r * c2.r >> 12; 416 short g = c1.g * c2.g >> 12; 417 short b = c1.b * c2.b >> 12; 418 short a = c1.a * c2.a >> 12; 419 420 return Color<short>(r, g, b, a); 421 } 422 423 template<> operator *(const Color<byte> & c1,const Color<byte> & c2)424 inline Color<byte> operator*(const Color<byte> &c1, const Color<byte> &c2) 425 { 426 byte r = c1.r * c2.r >> 8; 427 byte g = c1.g * c2.g >> 8; 428 byte b = c1.b * c2.b >> 8; 429 byte a = c1.a * c2.a >> 8; 430 431 return Color<byte>(r, g, b, a); 432 } 433 434 template<class T> operator /(const Color<T> & c,float l)435 inline Color<T> operator/(const Color<T> &c, float l) 436 { 437 l = 1.0f / l; 438 439 T r = (T)(l * c.r); 440 T g = (T)(l * c.g); 441 T b = (T)(l * c.b); 442 T a = (T)(l * c.a); 443 444 return Color<T>(r, g, b, a); 445 } 446 447 template<class T> gradient(const Color<T> & c1,const Color<T> & c2,float d)448 inline Color<T> Color<T>::gradient(const Color<T> &c1, const Color<T> &c2, float d) 449 { 450 d = 1.0f / d; 451 452 T r = (c2.r - c1.r) * d; 453 T g = (c2.g - c1.g) * d; 454 T b = (c2.b - c1.b) * d; 455 T a = (c2.a - c1.a) * d; 456 457 return Color<T>(r, g, b, a); 458 } 459 460 template<class T> shade(const Color<T> & c1,const Color<T> & c2,float d)461 inline Color<T> Color<T>::shade(const Color<T> &c1, const Color<T> &c2, float d) 462 { 463 T r = c1.r + (T)(d * (c2.r - c1.r)); 464 T g = c1.g + (T)(d * (c2.g - c1.g)); 465 T b = c1.b + (T)(d * (c2.b - c1.b)); 466 T a = c1.a + (T)(d * (c2.a - c1.a)); 467 468 return Color<T>(r, g, b, a); 469 } 470 } 471 472 #endif // sw_Color_hpp 473