• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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/Math.hpp"
19 #include "System/Types.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 }  // namespace sw
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 = static_cast<byte>(clamp(c.r >> 4, 0, 255));
96 	g = static_cast<byte>(clamp(c.g >> 4, 0, 255));
97 	b = static_cast<byte>(clamp(c.b >> 4, 0, 255));
98 	a = static_cast<byte>(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 = static_cast<byte>(ifloor(clamp(c.r * 256.0f, 0.0f, 255.0f)));
105 	g = static_cast<byte>(ifloor(clamp(c.g * 256.0f, 0.0f, 255.0f)));
106 	b = static_cast<byte>(ifloor(clamp(c.b * 256.0f, 0.0f, 255.0f)));
107 	a = static_cast<byte>(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 = static_cast<short>(iround(clamp(c.r * 4095.0f, -4096.0f, 4095.0f)));
141 	g = static_cast<short>(iround(clamp(c.g * 4095.0f, -4096.0f, 4095.0f)));
142 	b = static_cast<short>(iround(clamp(c.b * 4095.0f, -4096.0f, 4095.0f)));
143 	a = static_cast<short>(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 }  // namespace sw
472 
473 #endif  // sw_Color_hpp
474