• 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 "Common/Types.hpp"
19 #include "Common/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 "Common/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