tcuRGBA.js (8292B)
1 /*------------------------------------------------------------------------- 2 * drawElements Quality Program OpenGL ES Utilities 3 * ------------------------------------------------ 4 * 5 * Copyright 2014 The Android Open Source Project 6 * 7 * Licensed under the Apache License, Version 2.0 (the "License"); 8 * you may not use this file except in compliance with the License. 9 * You may obtain a copy of the License at 10 * 11 * http://www.apache.org/licenses/LICENSE-2.0 12 * 13 * Unless required by applicable law or agreed to in writing, software 14 * distributed under the License is distributed on an "AS IS" BASIS, 15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 * See the License for the specific language governing permissions and 17 * limitations under the License. 18 * 19 */ 20 21 'use strict'; 22 goog.provide('framework.common.tcuRGBA'); 23 goog.require('framework.delibs.debase.deMath'); 24 25 goog.scope(function() { 26 27 var tcuRGBA = framework.common.tcuRGBA; 28 var deMath = framework.delibs.debase.deMath; 29 30 var DE_ASSERT = function(x) { 31 if (!x) 32 throw new Error('Assert failed'); 33 }; 34 35 /** 36 * class tcuRGBA.RGBA 37 * @constructor 38 * @struct 39 * @param {goog.NumberArray=} value 40 */ 41 tcuRGBA.RGBA = function(value) { 42 /** @type {goog.NumberArray} */ this.m_value = value || null; 43 44 }; 45 46 /** 47 * @enum 48 * In JS, these are not shift values, but positions in a typed array 49 */ 50 tcuRGBA.RGBA.Shift = { 51 RED: 0, 52 GREEN: 1, 53 BLUE: 2, 54 ALPHA: 3 55 }; 56 57 /** 58 * @enum 59 * Mask used as flags 60 * Hopefully will not use typed arrays 61 */ 62 tcuRGBA.RGBA.Mask = function() { 63 return { 64 RED: false, 65 GREEN: false, 66 BLUE: false, 67 ALPHA: false 68 }; 69 }; 70 71 /** 72 * Builds an tcuRGBA.RGBA object from color components 73 * @param {number} r 74 * @param {number} g 75 * @param {number} b 76 * @param {number} a 77 * @return {tcuRGBA.RGBA} 78 */ 79 tcuRGBA.newRGBAComponents = function(r, g, b, a) { 80 DE_ASSERT(deMath.deInRange32(r, 0, 255)); 81 DE_ASSERT(deMath.deInRange32(g, 0, 255)); 82 DE_ASSERT(deMath.deInRange32(b, 0, 255)); 83 DE_ASSERT(deMath.deInRange32(a, 0, 255)); 84 85 return new tcuRGBA.RGBA([r, g, b, a]); 86 }; 87 88 /** 89 * Builds an tcuRGBA.RGBA object from a number array 90 * @param {goog.NumberArray} v 91 * @return {tcuRGBA.RGBA} 92 */ 93 tcuRGBA.newRGBAFromArray = function(v) { 94 return new tcuRGBA.RGBA(v.slice(0, 4)); 95 }; 96 97 /** 98 * @param {number} value 99 * @return {tcuRGBA.RGBA} 100 */ 101 tcuRGBA.newRGBAFromValue = function(value) { 102 var rgba = new tcuRGBA.RGBA(); 103 var array32 = new Uint32Array([value]); 104 rgba.m_value = (new Uint8Array(array32.buffer)); 105 return rgba; 106 }; 107 108 /** 109 * @param {Array<number>} v 110 * @return {tcuRGBA.RGBA} 111 */ 112 tcuRGBA.newRGBAFromVec = function (v) { 113 var r = deMath.clamp(v[0] * 255.0, 0, 255); 114 var g = deMath.clamp(v[1] * 255.0, 0, 255); 115 var b = deMath.clamp(v[2] * 255.0, 0, 255); 116 var a = deMath.clamp(v[3] * 255.0, 0, 255); 117 118 return new tcuRGBA.RGBA([r, g, b, a]); 119 }; 120 121 /** 122 * @param {number} v 123 */ 124 tcuRGBA.RGBA.prototype.setRed = function(v) { DE_ASSERT(deMath.deInRange32(v, 0, 255)); this.m_value[tcuRGBA.RGBA.Shift.RED] = v; }; 125 126 /** 127 * @param {number} v 128 */ 129 tcuRGBA.RGBA.prototype.setGreen = function(v) { DE_ASSERT(deMath.deInRange32(v, 0, 255)); this.m_value[tcuRGBA.RGBA.Shift.GREEN] = v; }; 130 131 /** 132 * @param {number} v 133 */ 134 tcuRGBA.RGBA.prototype.setBlue = function(v) { DE_ASSERT(deMath.deInRange32(v, 0, 255)); this.m_value[tcuRGBA.RGBA.Shift.BLUE] = v; }; 135 136 /** 137 * @param {number} v 138 */ 139 tcuRGBA.RGBA.prototype.setAlpha = function(v) { DE_ASSERT(deMath.deInRange32(v, 0, 255)); this.m_value[tcuRGBA.RGBA.Shift.ALPHA] = v; }; 140 141 /** 142 * @return {number} 143 */ 144 tcuRGBA.RGBA.prototype.getRed = function() { return this.m_value[tcuRGBA.RGBA.Shift.RED]; }; 145 146 /** 147 * @return {number} 148 */ 149 tcuRGBA.RGBA.prototype.getGreen = function() { return this.m_value[tcuRGBA.RGBA.Shift.GREEN]; }; 150 151 /** 152 * @return {number} 153 */ 154 tcuRGBA.RGBA.prototype.getBlue = function() { return this.m_value[tcuRGBA.RGBA.Shift.BLUE]; }; 155 156 /** 157 * @return {number} 158 */ 159 tcuRGBA.RGBA.prototype.getAlpha = function() { return this.m_value[tcuRGBA.RGBA.Shift.ALPHA]; }; 160 161 /** 162 * @param {tcuRGBA.RGBA} thr 163 * @return {boolean} 164 */ 165 tcuRGBA.RGBA.prototype.isBelowThreshold = function(thr) { return (this.getRed() <= thr.getRed()) && (this.getGreen() <= thr.getGreen()) && (this.getBlue() <= thr.getBlue()) && (this.getAlpha() <= thr.getAlpha()); }; 166 167 /** 168 * @param {Uint8Array} bytes 169 * @return {tcuRGBA.RGBA} 170 */ 171 tcuRGBA.RGBA.fromBytes = function(bytes) { return tcuRGBA.newRGBAFromArray(bytes); }; 172 173 /** 174 * @param {Uint8Array} bytes 175 */ 176 tcuRGBA.RGBA.prototype.toBytes = function(bytes) { var result = new Uint8Array(this.m_value); bytes[0] = result[0]; bytes[1] = result[1]; bytes[2] = result[2]; bytes[3] = result[3]; }; 177 178 /** 179 * @return {Array<number>} 180 */ 181 tcuRGBA.RGBA.prototype.toVec = function() { 182 return [ 183 this.getRed() / 255.0, 184 this.getGreen() / 255.0, 185 this.getBlue() / 255.0, 186 this.getAlpha() / 255.0 187 ]; 188 }; 189 190 /** 191 * @return {Array<number>} 192 */ 193 tcuRGBA.RGBA.prototype.toIVec = function() { 194 return [ 195 this.getRed(), 196 this.getGreen(), 197 this.getBlue(), 198 this.getAlpha() 199 ]; 200 }; 201 202 /** 203 * @param {tcuRGBA.RGBA} v 204 * @return {boolean} 205 */ 206 tcuRGBA.RGBA.prototype.equals = function(v) { 207 return ( 208 this.m_value[0] == v.m_value[0] && 209 this.m_value[1] == v.m_value[1] && 210 this.m_value[2] == v.m_value[2] && 211 this.m_value[3] == v.m_value[3] 212 ); 213 }; 214 215 /** 216 * @param {tcuRGBA.RGBA} a 217 * @param {tcuRGBA.RGBA} b 218 * @param {tcuRGBA.RGBA} threshold 219 * @return {boolean} 220 */ 221 tcuRGBA.compareThreshold = function(a, b, threshold) { 222 if (a.equals(b)) return true; // Quick-accept 223 return tcuRGBA.computeAbsDiff(a, b).isBelowThreshold(threshold); 224 }; 225 226 /** 227 * @param {tcuRGBA.RGBA} a 228 * @param {tcuRGBA.RGBA} b 229 * @return {tcuRGBA.RGBA} 230 */ 231 tcuRGBA.computeAbsDiff = function(a, b) { 232 return tcuRGBA.newRGBAComponents( 233 Math.abs(a.getRed() - b.getRed()), 234 Math.abs(a.getGreen() - b.getGreen()), 235 Math.abs(a.getBlue() - b.getBlue()), 236 Math.abs(a.getAlpha() - b.getAlpha()) 237 ); 238 }; 239 240 /** 241 * @param {tcuRGBA.RGBA} a 242 * @param {number} b 243 * @return {tcuRGBA.RGBA} 244 */ 245 tcuRGBA.multiply = function(a, b) { 246 return tcuRGBA.newRGBAComponents( 247 deMath.clamp(a.getRed() * b, 0, 255), 248 deMath.clamp(a.getGreen() * b, 0, 255), 249 deMath.clamp(a.getBlue() * b, 0, 255), 250 deMath.clamp(a.getAlpha() * b, 0, 255)); 251 }; 252 253 /** 254 * @param {tcuRGBA.RGBA} a 255 * @param {tcuRGBA.RGBA} b 256 * @return {tcuRGBA.RGBA} 257 */ 258 tcuRGBA.max = function(a, b) { 259 return tcuRGBA.newRGBAComponents( 260 Math.max(a.getRed(), b.getRed()), 261 Math.max(a.getGreen(), b.getGreen()), 262 Math.max(a.getBlue(), b.getBlue()), 263 Math.max(a.getAlpha(), b.getAlpha()) 264 ); 265 }; 266 267 tcuRGBA.RGBA.prototype.toString = function() { 268 return '[' + this.m_value[0] + ',' + this.m_value[1] + ',' + this.m_value[2] + ',' + this.m_value[3] + ']'; 269 }; 270 271 // Color constants 272 tcuRGBA.RGBA.red = tcuRGBA.newRGBAComponents(0xFF, 0, 0, 0xFF); 273 tcuRGBA.RGBA.green = tcuRGBA.newRGBAComponents(0, 0xFF, 0, 0xFF); 274 tcuRGBA.RGBA.blue = tcuRGBA.newRGBAComponents(0, 0, 0xFF, 0xFF); 275 tcuRGBA.RGBA.gray = tcuRGBA.newRGBAComponents(0x80, 0x80, 0x80, 0xFF); 276 tcuRGBA.RGBA.white = tcuRGBA.newRGBAComponents(0xFF, 0xFF, 0xFF, 0xFF); 277 tcuRGBA.RGBA.black = tcuRGBA.newRGBAComponents(0, 0, 0, 0xFF); 278 279 });