xref: /aosp_15_r20/external/deqp/framework/common/tcuRGBA.hpp (revision 35238bce31c2a825756842865a792f8cf7f89930)
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 
RGBA(void)57     RGBA(void)
58     {
59         m_value = 0;
60     }
61 
RGBA(int r,int g,int b,int a)62     RGBA(int r, int g, int b, int a)
63     {
64         DE_ASSERT(deInRange32(r, 0, 255));
65         DE_ASSERT(deInRange32(g, 0, 255));
66         DE_ASSERT(deInRange32(b, 0, 255));
67         DE_ASSERT(deInRange32(a, 0, 255));
68         m_value = ((uint32_t)a << ALPHA_SHIFT) | ((uint32_t)r << RED_SHIFT) | ((uint32_t)g << GREEN_SHIFT) |
69                   ((uint32_t)b << BLUE_SHIFT);
70     }
71 
RGBA(uint32_t val)72     explicit RGBA(uint32_t val)
73     {
74         m_value = val;
75     }
76 
77     explicit RGBA(const Vec4 &v);
78 
setRed(int v)79     void setRed(int v)
80     {
81         DE_ASSERT(deInRange32(v, 0, 255));
82         m_value = (m_value & ~((uint32_t)0xFFu << RED_SHIFT)) | ((uint32_t)v << RED_SHIFT);
83     }
setGreen(int v)84     void setGreen(int v)
85     {
86         DE_ASSERT(deInRange32(v, 0, 255));
87         m_value = (m_value & ~((uint32_t)0xFFu << GREEN_SHIFT)) | ((uint32_t)v << GREEN_SHIFT);
88     }
setBlue(int v)89     void setBlue(int v)
90     {
91         DE_ASSERT(deInRange32(v, 0, 255));
92         m_value = (m_value & ~((uint32_t)0xFFu << BLUE_SHIFT)) | ((uint32_t)v << BLUE_SHIFT);
93     }
setAlpha(int v)94     void setAlpha(int v)
95     {
96         DE_ASSERT(deInRange32(v, 0, 255));
97         m_value = (m_value & ~((uint32_t)0xFFu << ALPHA_SHIFT)) | ((uint32_t)v << ALPHA_SHIFT);
98     }
getRed(void) const99     int getRed(void) const
100     {
101         return (int)((m_value >> (uint32_t)RED_SHIFT) & 0xFFu);
102     }
getGreen(void) const103     int getGreen(void) const
104     {
105         return (int)((m_value >> (uint32_t)GREEN_SHIFT) & 0xFFu);
106     }
getBlue(void) const107     int getBlue(void) const
108     {
109         return (int)((m_value >> (uint32_t)BLUE_SHIFT) & 0xFFu);
110     }
getAlpha(void) const111     int getAlpha(void) const
112     {
113         return (int)((m_value >> (uint32_t)ALPHA_SHIFT) & 0xFFu);
114     }
getPacked(void) const115     uint32_t getPacked(void) const
116     {
117         return m_value;
118     }
119 
isBelowThreshold(RGBA thr) const120     bool isBelowThreshold(RGBA thr) const
121     {
122         return (getRed() <= thr.getRed()) && (getGreen() <= thr.getGreen()) && (getBlue() <= thr.getBlue()) &&
123                (getAlpha() <= thr.getAlpha());
124     }
125 
fromBytes(const uint8_t * bytes)126     static RGBA fromBytes(const uint8_t *bytes)
127     {
128         return RGBA(bytes[0], bytes[1], bytes[2], bytes[3]);
129     }
toBytes(uint8_t * bytes) const130     void toBytes(uint8_t *bytes) const
131     {
132         bytes[0] = (uint8_t)getRed();
133         bytes[1] = (uint8_t)getGreen();
134         bytes[2] = (uint8_t)getBlue();
135         bytes[3] = (uint8_t)getAlpha();
136     }
137     Vec4 toVec(void) const;
138     IVec4 toIVec(void) const;
139 
operator ==(const RGBA & v) const140     bool operator==(const RGBA &v) const
141     {
142         return (m_value == v.m_value);
143     }
operator !=(const RGBA & v) const144     bool operator!=(const RGBA &v) const
145     {
146         return (m_value != v.m_value);
147     }
148 
149     // Color constants.  Designed as methods to avoid static-initialization-order fiasco.
red(void)150     static inline const RGBA red(void)
151     {
152         return RGBA(0xFF, 0x0, 0x0, 0xFF);
153     }
green(void)154     static inline const RGBA green(void)
155     {
156         return RGBA(0x0, 0xFF, 0x0, 0xFF);
157     }
blue(void)158     static inline const RGBA blue(void)
159     {
160         return RGBA(0x0, 0x0, 0xFF, 0xFF);
161     }
gray(void)162     static inline const RGBA gray(void)
163     {
164         return RGBA(0x80, 0x80, 0x80, 0xFF);
165     }
white(void)166     static inline const RGBA white(void)
167     {
168         return RGBA(0xFF, 0xFF, 0xFF, 0xFF);
169     }
black(void)170     static inline const RGBA black(void)
171     {
172         return RGBA(0x0, 0x0, 0x0, 0xFF);
173     }
174 
175 private:
176     uint32_t m_value;
177 } DE_WARN_UNUSED_TYPE;
178 
compareEqualMasked(RGBA a,RGBA b,uint32_t cmpMask)179 inline bool compareEqualMasked(RGBA a, RGBA b, uint32_t cmpMask)
180 {
181     RGBA mask((cmpMask & RGBA::RED_MASK) ? 0xFF : 0, (cmpMask & RGBA::GREEN_MASK) ? 0xFF : 0,
182               (cmpMask & RGBA::BLUE_MASK) ? 0xFF : 0, (cmpMask & RGBA::ALPHA_MASK) ? 0xFF : 0);
183     uint32_t aPacked    = a.getPacked();
184     uint32_t bPacked    = b.getPacked();
185     uint32_t maskPacked = mask.getPacked();
186     return (aPacked & maskPacked) == (bPacked & maskPacked);
187 }
188 
computeAbsDiff(RGBA a,RGBA b)189 inline RGBA computeAbsDiff(RGBA a, RGBA b)
190 {
191     return RGBA(deAbs32(a.getRed() - b.getRed()), deAbs32(a.getGreen() - b.getGreen()),
192                 deAbs32(a.getBlue() - b.getBlue()), deAbs32(a.getAlpha() - b.getAlpha()));
193 }
194 
blend(RGBA a,RGBA b,float t)195 inline RGBA blend(RGBA a, RGBA b, float t)
196 {
197     DE_ASSERT(t >= 0.0f && t <= 1.0f);
198     float it = 1.0f - t;
199     // \todo [petri] Handling of alpha!
200     return RGBA((int)(it * (float)a.getRed() + t * (float)b.getRed() + 0.5f),
201                 (int)(it * (float)a.getGreen() + t * (float)b.getGreen() + 0.5f),
202                 (int)(it * (float)a.getBlue() + t * (float)b.getBlue() + 0.5f),
203                 (int)(it * (float)a.getAlpha() + t * (float)b.getAlpha() + 0.5f));
204 }
205 
compareThreshold(RGBA a,RGBA b,RGBA threshold)206 inline bool compareThreshold(RGBA a, RGBA b, RGBA threshold)
207 {
208     if (a == b)
209         return true; // Quick-accept
210     return computeAbsDiff(a, b).isBelowThreshold(threshold);
211 }
212 
max(RGBA a,RGBA b)213 inline RGBA max(RGBA a, RGBA b)
214 {
215     return RGBA(deMax32(a.getRed(), b.getRed()), deMax32(a.getGreen(), b.getGreen()), deMax32(a.getBlue(), b.getBlue()),
216                 deMax32(a.getAlpha(), b.getAlpha()));
217 }
218 
219 RGBA computeAbsDiffMasked(RGBA a, RGBA b, uint32_t cmpMask);
220 bool compareThresholdMasked(RGBA a, RGBA b, RGBA threshold, uint32_t cmpMask);
221 
222 // Arithmetic operators (saturating if not stated otherwise).
223 
operator +(const RGBA & a,const RGBA & b)224 inline RGBA operator+(const RGBA &a, const RGBA &b)
225 {
226     return RGBA(deClamp32(a.getRed() + b.getRed(), 0, 255), deClamp32(a.getGreen() + b.getGreen(), 0, 255),
227                 deClamp32(a.getBlue() + b.getBlue(), 0, 255), deClamp32(a.getAlpha() + b.getAlpha(), 0, 255));
228 }
229 
operator -(const RGBA & a,const RGBA & b)230 inline RGBA operator-(const RGBA &a, const RGBA &b)
231 {
232     return RGBA(deClamp32(a.getRed() - b.getRed(), 0, 255), deClamp32(a.getGreen() - b.getGreen(), 0, 255),
233                 deClamp32(a.getBlue() - b.getBlue(), 0, 255), deClamp32(a.getAlpha() - b.getAlpha(), 0, 255));
234 }
235 
operator *(const RGBA & a,const int b)236 inline RGBA operator*(const RGBA &a, const int b)
237 {
238     return RGBA(deClamp32(a.getRed() * b, 0, 255), deClamp32(a.getGreen() * b, 0, 255),
239                 deClamp32(a.getBlue() * b, 0, 255), deClamp32(a.getAlpha() * b, 0, 255));
240 }
241 
operator <<(std::ostream & stream,RGBA c)242 inline std::ostream &operator<<(std::ostream &stream, RGBA c)
243 {
244     return stream << "RGBA(" << c.getRed() << ", " << c.getGreen() << ", " << c.getBlue() << ", " << c.getAlpha()
245                   << ")";
246 }
247 
248 } // namespace tcu
249 
250 #endif // _TCURGBA_HPP
251