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