Home | History | Annotate | Download | only in common
      1 #ifndef _TCURGBA_HPP
      2 #define _TCURGBA_HPP
      3 /*-------------------------------------------------------------------------
      4  * drawElements Quality Program Tester Core
      5  * ----------------------------------------
      6  *
      7  * Copyright 2014 The Android Open Source Project
      8  *
      9  * Licensed under the Apache License, Version 2.0 (the "License");
     10  * you may not use this file except in compliance with the License.
     11  * You may obtain a copy of the License at
     12  *
     13  *      http://www.apache.org/licenses/LICENSE-2.0
     14  *
     15  * Unless required by applicable law or agreed to in writing, software
     16  * distributed under the License is distributed on an "AS IS" BASIS,
     17  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     18  * See the License for the specific language governing permissions and
     19  * limitations under the License.
     20  *
     21  *//*!
     22  * \file
     23  * \brief RGBA8888 color type.
     24  *//*--------------------------------------------------------------------*/
     25 
     26 #include "tcuDefs.hpp"
     27 #include "deInt32.h"
     28 #include "tcuVectorType.hpp"
     29 
     30 #include <sstream>
     31 
     32 namespace tcu
     33 {
     34 
     35 /*--------------------------------------------------------------------*//*!
     36  * \brief RGBA8888 color struct
     37  *//*--------------------------------------------------------------------*/
     38 class RGBA
     39 {
     40 public:
     41 	enum
     42 	{
     43 		RED_SHIFT	= 0,
     44 		GREEN_SHIFT	= 8,
     45 		BLUE_SHIFT	= 16,
     46 		ALPHA_SHIFT	= 24
     47 	};
     48 
     49 	enum
     50 	{
     51 		RED_MASK	= (1<<0),
     52 		GREEN_MASK	= (1<<1),
     53 		BLUE_MASK	= (1<<2),
     54 		ALPHA_MASK	= (1<<3)
     55 	};
     56 
     57 	RGBA (void) { m_value = 0; }
     58 
     59 	RGBA (int r, int g, int b, int a)
     60 	{
     61 		DE_ASSERT(deInRange32(r, 0, 255));
     62 		DE_ASSERT(deInRange32(g, 0, 255));
     63 		DE_ASSERT(deInRange32(b, 0, 255));
     64 		DE_ASSERT(deInRange32(a, 0, 255));
     65 		m_value = ((deUint32)a << ALPHA_SHIFT) | ((deUint32)r << RED_SHIFT) | ((deUint32)g << GREEN_SHIFT) | ((deUint32)b << BLUE_SHIFT);
     66 	}
     67 
     68 	explicit RGBA (deUint32 val)
     69 	{
     70 		m_value = val;
     71 	}
     72 
     73 	explicit	RGBA					(const Vec4& v);
     74 
     75 	void		setRed					(int v) { DE_ASSERT(deInRange32(v, 0, 255)); m_value = (m_value & ~((deUint32)0xFFu << RED_SHIFT))   | ((deUint32)v << RED_SHIFT);   }
     76 	void		setGreen				(int v) { DE_ASSERT(deInRange32(v, 0, 255)); m_value = (m_value & ~((deUint32)0xFFu << GREEN_SHIFT)) | ((deUint32)v << GREEN_SHIFT); }
     77 	void		setBlue					(int v) { DE_ASSERT(deInRange32(v, 0, 255)); m_value = (m_value & ~((deUint32)0xFFu << BLUE_SHIFT))  | ((deUint32)v << BLUE_SHIFT);  }
     78 	void		setAlpha				(int v) { DE_ASSERT(deInRange32(v, 0, 255)); m_value = (m_value & ~((deUint32)0xFFu << ALPHA_SHIFT)) | ((deUint32)v << ALPHA_SHIFT); }
     79 	int			getRed					(void) const { return (int)((m_value >> (deUint32)RED_SHIFT)   & 0xFFu); }
     80 	int			getGreen				(void) const { return (int)((m_value >> (deUint32)GREEN_SHIFT) & 0xFFu); }
     81 	int			getBlue					(void) const { return (int)((m_value >> (deUint32)BLUE_SHIFT)  & 0xFFu); }
     82 	int			getAlpha				(void) const { return (int)((m_value >> (deUint32)ALPHA_SHIFT) & 0xFFu); }
     83 	deUint32	getPacked				(void) const { return m_value; }
     84 
     85 	bool		isBelowThreshold		(RGBA thr) const	{ return (getRed() <= thr.getRed()) && (getGreen() <= thr.getGreen()) && (getBlue() <= thr.getBlue()) && (getAlpha() <= thr.getAlpha()); }
     86 
     87 	static RGBA	fromBytes				(const deUint8* bytes)	{ return RGBA(bytes[0], bytes[1], bytes[2], bytes[3]); }
     88 	void		toBytes					(deUint8* bytes) const	{ bytes[0] = (deUint8)getRed(); bytes[1] = (deUint8)getGreen(); bytes[2] = (deUint8)getBlue(); bytes[3] = (deUint8)getAlpha(); }
     89 	Vec4		toVec					(void) const;
     90 	IVec4		toIVec					(void) const;
     91 
     92 	bool		operator==				(const RGBA& v) const { return (m_value == v.m_value); }
     93 	bool		operator!=				(const RGBA& v) const { return (m_value != v.m_value); }
     94 
     95 	// Color constants.  Designed as methods to avoid static-initialization-order fiasco.
     96 	static inline const RGBA red	(void) { return RGBA(0xFF, 0x0,  0x0,  0xFF); }
     97 	static inline const RGBA green	(void) { return RGBA(0x0,  0xFF, 0x0,  0xFF); }
     98 	static inline const RGBA blue	(void) { return RGBA(0x0,  0x0,  0xFF, 0xFF); }
     99 	static inline const RGBA gray	(void) { return RGBA(0x80, 0x80, 0x80, 0xFF); }
    100 	static inline const RGBA white	(void) { return RGBA(0xFF, 0xFF, 0xFF, 0xFF); }
    101 	static inline const RGBA black	(void) { return RGBA(0x0,  0x0,  0x0,  0xFF); }
    102 
    103 private:
    104 	deUint32	m_value;
    105 } DE_WARN_UNUSED_TYPE;
    106 
    107 inline bool compareEqualMasked (RGBA a, RGBA b, deUint32 cmpMask)
    108 {
    109 	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);
    110 	deUint32	aPacked		= a.getPacked();
    111 	deUint32	bPacked		= b.getPacked();
    112 	deUint32	maskPacked	= mask.getPacked();
    113 	return (aPacked & maskPacked) == (bPacked & maskPacked);
    114 }
    115 
    116 inline RGBA computeAbsDiff (RGBA a, RGBA b)
    117 {
    118 	return RGBA(
    119 		deAbs32(a.getRed()   - b.getRed()),
    120 		deAbs32(a.getGreen() - b.getGreen()),
    121 		deAbs32(a.getBlue()  - b.getBlue()),
    122 		deAbs32(a.getAlpha() - b.getAlpha()));
    123 }
    124 
    125 inline RGBA blend (RGBA a, RGBA b, float t)
    126 {
    127 	DE_ASSERT(t >= 0.0f && t <= 1.0f);
    128 	float it = 1.0f - t;
    129 	// \todo [petri] Handling of alpha!
    130 	return RGBA(
    131 		(int)(it*(float)a.getRed() + t*(float)b.getRed() + 0.5f),
    132 		(int)(it*(float)a.getGreen() + t*(float)b.getGreen() + 0.5f),
    133 		(int)(it*(float)a.getBlue() + t*(float)b.getBlue() + 0.5f),
    134 		(int)(it*(float)a.getAlpha() + t*(float)b.getAlpha() + 0.5f));
    135 }
    136 
    137 inline bool compareThreshold (RGBA a, RGBA b, RGBA threshold)
    138 {
    139 	if (a == b) return true;	// Quick-accept
    140 	return computeAbsDiff(a, b).isBelowThreshold(threshold);
    141 }
    142 
    143 inline RGBA max (RGBA a, RGBA b)
    144 {
    145 	return RGBA(deMax32(a.getRed(),		b.getRed()),
    146 				deMax32(a.getGreen(),	b.getGreen()),
    147 				deMax32(a.getBlue(),	b.getBlue()),
    148 				deMax32(a.getAlpha(),	b.getAlpha()));
    149 }
    150 
    151 RGBA computeAbsDiffMasked	(RGBA a, RGBA b, deUint32 cmpMask);
    152 bool compareThresholdMasked	(RGBA a, RGBA b, RGBA threshold, deUint32 cmpMask);
    153 
    154 // Arithmetic operators (saturating if not stated otherwise).
    155 
    156 inline RGBA operator+ (const RGBA& a, const RGBA& b)
    157 {
    158 	return RGBA(deClamp32(a.getRed()	+ b.getRed(),	0, 255),
    159 				deClamp32(a.getGreen()	+ b.getGreen(),	0, 255),
    160 				deClamp32(a.getBlue()	+ b.getBlue(),	0, 255),
    161 				deClamp32(a.getAlpha()	+ b.getAlpha(),	0, 255));
    162 }
    163 
    164 inline RGBA operator- (const RGBA& a, const RGBA& b)
    165 {
    166 	return RGBA(deClamp32(a.getRed()	- b.getRed(),	0, 255),
    167 				deClamp32(a.getGreen()	- b.getGreen(),	0, 255),
    168 				deClamp32(a.getBlue()	- b.getBlue(),	0, 255),
    169 				deClamp32(a.getAlpha()	- b.getAlpha(),	0, 255));
    170 }
    171 
    172 inline RGBA operator* (const RGBA& a, const int b)
    173 {
    174 	return RGBA(deClamp32(a.getRed()	* b,	0, 255),
    175 				deClamp32(a.getGreen()	* b,	0, 255),
    176 				deClamp32(a.getBlue()	* b,	0, 255),
    177 				deClamp32(a.getAlpha()	* b,	0, 255));
    178 }
    179 
    180 inline std::ostream& operator<< (std::ostream& stream, RGBA c)
    181 {
    182 	return stream << "RGBA(" << c.getRed() << ", " << c.getGreen() << ", " << c.getBlue() << ", " << c.getAlpha() << ")";
    183 }
    184 
    185 } // tcu
    186 
    187 #endif // _TCURGBA_HPP
    188