13c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#ifndef _TCURGBA_HPP
23c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#define _TCURGBA_HPP
33c827367444ee418f129b2c238299f49d3264554Jarkko Poyry/*-------------------------------------------------------------------------
43c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * drawElements Quality Program Tester Core
53c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * ----------------------------------------
63c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *
73c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * Copyright 2014 The Android Open Source Project
83c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *
93c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * Licensed under the Apache License, Version 2.0 (the "License");
103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * you may not use this file except in compliance with the License.
113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * You may obtain a copy of the License at
123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *
133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *      http://www.apache.org/licenses/LICENSE-2.0
143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *
153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * Unless required by applicable law or agreed to in writing, software
163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * distributed under the License is distributed on an "AS IS" BASIS,
173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * See the License for the specific language governing permissions and
193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * limitations under the License.
203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *
213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *//*!
223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \file
233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \brief RGBA8888 color type.
243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *//*--------------------------------------------------------------------*/
253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "tcuDefs.hpp"
273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "deInt32.h"
283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "tcuVectorType.hpp"
293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include <sstream>
313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
323c827367444ee418f129b2c238299f49d3264554Jarkko Poyrynamespace tcu
333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry/*--------------------------------------------------------------------*//*!
363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \brief RGBA8888 color struct
373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *//*--------------------------------------------------------------------*/
383c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass RGBA
393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
403c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic:
413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	enum
423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		RED_SHIFT	= 0,
443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		GREEN_SHIFT	= 8,
453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		BLUE_SHIFT	= 16,
463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		ALPHA_SHIFT	= 24
473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	};
483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	enum
503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		RED_MASK	= (1<<0),
523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		GREEN_MASK	= (1<<1),
533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		BLUE_MASK	= (1<<2),
543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		ALPHA_MASK	= (1<<3)
553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	};
563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	RGBA (void) { m_value = 0; }
583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	RGBA (int r, int g, int b, int a)
603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		DE_ASSERT(deInRange32(r, 0, 255));
623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		DE_ASSERT(deInRange32(g, 0, 255));
633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		DE_ASSERT(deInRange32(b, 0, 255));
643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		DE_ASSERT(deInRange32(a, 0, 255));
6524ceed3e1acf66512ee25ee75002198b6672879dJarkko Pöyry		m_value = ((deUint32)a << ALPHA_SHIFT) | ((deUint32)r << RED_SHIFT) | ((deUint32)g << GREEN_SHIFT) | ((deUint32)b << BLUE_SHIFT);
663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	explicit RGBA (deUint32 val)
693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_value = val;
713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	explicit	RGBA					(const Vec4& v);
743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7524ceed3e1acf66512ee25ee75002198b6672879dJarkko Pöyry	void		setRed					(int v) { DE_ASSERT(deInRange32(v, 0, 255)); m_value = (m_value & ~((deUint32)0xFFu << RED_SHIFT))   | ((deUint32)v << RED_SHIFT);   }
7624ceed3e1acf66512ee25ee75002198b6672879dJarkko Pöyry	void		setGreen				(int v) { DE_ASSERT(deInRange32(v, 0, 255)); m_value = (m_value & ~((deUint32)0xFFu << GREEN_SHIFT)) | ((deUint32)v << GREEN_SHIFT); }
7724ceed3e1acf66512ee25ee75002198b6672879dJarkko Pöyry	void		setBlue					(int v) { DE_ASSERT(deInRange32(v, 0, 255)); m_value = (m_value & ~((deUint32)0xFFu << BLUE_SHIFT))  | ((deUint32)v << BLUE_SHIFT);  }
7824ceed3e1acf66512ee25ee75002198b6672879dJarkko Pöyry	void		setAlpha				(int v) { DE_ASSERT(deInRange32(v, 0, 255)); m_value = (m_value & ~((deUint32)0xFFu << ALPHA_SHIFT)) | ((deUint32)v << ALPHA_SHIFT); }
7924ceed3e1acf66512ee25ee75002198b6672879dJarkko Pöyry	int			getRed					(void) const { return (int)((m_value >> (deUint32)RED_SHIFT)   & 0xFFu); }
8024ceed3e1acf66512ee25ee75002198b6672879dJarkko Pöyry	int			getGreen				(void) const { return (int)((m_value >> (deUint32)GREEN_SHIFT) & 0xFFu); }
8124ceed3e1acf66512ee25ee75002198b6672879dJarkko Pöyry	int			getBlue					(void) const { return (int)((m_value >> (deUint32)BLUE_SHIFT)  & 0xFFu); }
8224ceed3e1acf66512ee25ee75002198b6672879dJarkko Pöyry	int			getAlpha				(void) const { return (int)((m_value >> (deUint32)ALPHA_SHIFT) & 0xFFu); }
833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	deUint32	getPacked				(void) const { return m_value; }
843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	bool		isBelowThreshold		(RGBA thr) const	{ return (getRed() <= thr.getRed()) && (getGreen() <= thr.getGreen()) && (getBlue() <= thr.getBlue()) && (getAlpha() <= thr.getAlpha()); }
863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	static RGBA	fromBytes				(const deUint8* bytes)	{ return RGBA(bytes[0], bytes[1], bytes[2], bytes[3]); }
8809307280328f7fe333960a53cddf8c2962af5536Jarkko Pöyry	void		toBytes					(deUint8* bytes) const	{ bytes[0] = (deUint8)getRed(); bytes[1] = (deUint8)getGreen(); bytes[2] = (deUint8)getBlue(); bytes[3] = (deUint8)getAlpha(); }
893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	Vec4		toVec					(void) const;
903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	IVec4		toIVec					(void) const;
913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	bool		operator==				(const RGBA& v) const { return (m_value == v.m_value); }
933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	bool		operator!=				(const RGBA& v) const { return (m_value != v.m_value); }
943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
95c215aaa83047ebbaabafef7acd71275a256da6abDejan Mircevski	// Color constants.  Designed as methods to avoid static-initialization-order fiasco.
96c215aaa83047ebbaabafef7acd71275a256da6abDejan Mircevski	static inline const RGBA red	(void) { return RGBA(0xFF, 0x0,  0x0,  0xFF); }
97c215aaa83047ebbaabafef7acd71275a256da6abDejan Mircevski	static inline const RGBA green	(void) { return RGBA(0x0,  0xFF, 0x0,  0xFF); }
98c215aaa83047ebbaabafef7acd71275a256da6abDejan Mircevski	static inline const RGBA blue	(void) { return RGBA(0x0,  0x0,  0xFF, 0xFF); }
99c215aaa83047ebbaabafef7acd71275a256da6abDejan Mircevski	static inline const RGBA gray	(void) { return RGBA(0x80, 0x80, 0x80, 0xFF); }
100c215aaa83047ebbaabafef7acd71275a256da6abDejan Mircevski	static inline const RGBA white	(void) { return RGBA(0xFF, 0xFF, 0xFF, 0xFF); }
101c215aaa83047ebbaabafef7acd71275a256da6abDejan Mircevski	static inline const RGBA black	(void) { return RGBA(0x0,  0x0,  0x0,  0xFF); }
1023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1033c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprivate:
1043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	deUint32	m_value;
10593df37596ea66700965094b3aa2830cf4f2ca5aaJarkko Pöyry} DE_WARN_UNUSED_TYPE;
1063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1073c827367444ee418f129b2c238299f49d3264554Jarkko Poyryinline bool compareEqualMasked (RGBA a, RGBA b, deUint32 cmpMask)
1083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	RGBA		mask((cmpMask&RGBA::RED_MASK)?0xFF:0, (cmpMask&RGBA::GREEN_MASK)?0xFF:0, (cmpMask&RGBA::BLUE_MASK)?0xFF:0, (cmpMask&RGBA::ALPHA_MASK)?0xFF:0);
1103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	deUint32	aPacked		= a.getPacked();
1113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	deUint32	bPacked		= b.getPacked();
1123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	deUint32	maskPacked	= mask.getPacked();
1133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return (aPacked & maskPacked) == (bPacked & maskPacked);
1143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
1153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1163c827367444ee418f129b2c238299f49d3264554Jarkko Poyryinline RGBA computeAbsDiff (RGBA a, RGBA b)
1173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return RGBA(
1193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		deAbs32(a.getRed()   - b.getRed()),
1203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		deAbs32(a.getGreen() - b.getGreen()),
1213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		deAbs32(a.getBlue()  - b.getBlue()),
1223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		deAbs32(a.getAlpha() - b.getAlpha()));
1233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
1243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1253c827367444ee418f129b2c238299f49d3264554Jarkko Poyryinline RGBA blend (RGBA a, RGBA b, float t)
1263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(t >= 0.0f && t <= 1.0f);
1283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	float it = 1.0f - t;
1293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// \todo [petri] Handling of alpha!
1303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return RGBA(
1313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		(int)(it*(float)a.getRed() + t*(float)b.getRed() + 0.5f),
1323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		(int)(it*(float)a.getGreen() + t*(float)b.getGreen() + 0.5f),
1333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		(int)(it*(float)a.getBlue() + t*(float)b.getBlue() + 0.5f),
1343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		(int)(it*(float)a.getAlpha() + t*(float)b.getAlpha() + 0.5f));
1353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
1363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1373c827367444ee418f129b2c238299f49d3264554Jarkko Poyryinline bool compareThreshold (RGBA a, RGBA b, RGBA threshold)
1383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (a == b) return true;	// Quick-accept
1403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return computeAbsDiff(a, b).isBelowThreshold(threshold);
1413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
1423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1433c827367444ee418f129b2c238299f49d3264554Jarkko Poyryinline RGBA max (RGBA a, RGBA b)
1443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return RGBA(deMax32(a.getRed(),		b.getRed()),
1463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				deMax32(a.getGreen(),	b.getGreen()),
1473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				deMax32(a.getBlue(),	b.getBlue()),
1483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				deMax32(a.getAlpha(),	b.getAlpha()));
1493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
1503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1513c827367444ee418f129b2c238299f49d3264554Jarkko PoyryRGBA computeAbsDiffMasked	(RGBA a, RGBA b, deUint32 cmpMask);
1523c827367444ee418f129b2c238299f49d3264554Jarkko Poyrybool compareThresholdMasked	(RGBA a, RGBA b, RGBA threshold, deUint32 cmpMask);
1533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// Arithmetic operators (saturating if not stated otherwise).
1553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1563c827367444ee418f129b2c238299f49d3264554Jarkko Poyryinline RGBA operator+ (const RGBA& a, const RGBA& b)
1573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return RGBA(deClamp32(a.getRed()	+ b.getRed(),	0, 255),
1593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				deClamp32(a.getGreen()	+ b.getGreen(),	0, 255),
1603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				deClamp32(a.getBlue()	+ b.getBlue(),	0, 255),
1613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				deClamp32(a.getAlpha()	+ b.getAlpha(),	0, 255));
1623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
1633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1643c827367444ee418f129b2c238299f49d3264554Jarkko Poyryinline RGBA operator- (const RGBA& a, const RGBA& b)
1653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return RGBA(deClamp32(a.getRed()	- b.getRed(),	0, 255),
1673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				deClamp32(a.getGreen()	- b.getGreen(),	0, 255),
1683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				deClamp32(a.getBlue()	- b.getBlue(),	0, 255),
1693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				deClamp32(a.getAlpha()	- b.getAlpha(),	0, 255));
1703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
1713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1723c827367444ee418f129b2c238299f49d3264554Jarkko Poyryinline RGBA operator* (const RGBA& a, const int b)
1733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return RGBA(deClamp32(a.getRed()	* b,	0, 255),
1753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				deClamp32(a.getGreen()	* b,	0, 255),
1763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				deClamp32(a.getBlue()	* b,	0, 255),
1773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				deClamp32(a.getAlpha()	* b,	0, 255));
1783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
1793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1803c827367444ee418f129b2c238299f49d3264554Jarkko Poyryinline std::ostream& operator<< (std::ostream& stream, RGBA c)
1813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return stream << "RGBA(" << c.getRed() << ", " << c.getGreen() << ", " << c.getBlue() << ", " << c.getAlpha() << ")";
1833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
1843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} // tcu
1863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#endif // _TCURGBA_HPP
188