1 /* 2 * Copyright 2006 The Android Open Source Project 3 * 4 * Use of this source code is governed by a BSD-style license that can be 5 * found in the LICENSE file. 6 */ 7 8 #include "SkColor.h" 9 #include "SkColorPriv.h" 10 #include "SkFixed.h" 11 12 SkPMColor SkPreMultiplyARGB(U8CPU a, U8CPU r, U8CPU g, U8CPU b) { 13 return SkPremultiplyARGBInline(a, r, g, b); 14 } 15 16 SkPMColor SkPreMultiplyColor(SkColor c) { 17 return SkPremultiplyARGBInline(SkColorGetA(c), SkColorGetR(c), 18 SkColorGetG(c), SkColorGetB(c)); 19 } 20 21 /////////////////////////////////////////////////////////////////////////////// 22 23 static inline SkScalar ByteToScalar(U8CPU x) { 24 SkASSERT(x <= 255); 25 return SkIntToScalar(x) / 255; 26 } 27 28 static inline SkScalar ByteDivToScalar(int numer, U8CPU denom) { 29 // cast to keep the answer signed 30 return SkIntToScalar(numer) / (int)denom; 31 } 32 33 void SkRGBToHSV(U8CPU r, U8CPU g, U8CPU b, SkScalar hsv[3]) { 34 SkASSERT(hsv); 35 36 unsigned min = SkMin32(r, SkMin32(g, b)); 37 unsigned max = SkMax32(r, SkMax32(g, b)); 38 unsigned delta = max - min; 39 40 SkScalar v = ByteToScalar(max); 41 SkASSERT(v >= 0 && v <= SK_Scalar1); 42 43 if (0 == delta) { // we're a shade of gray 44 hsv[0] = 0; 45 hsv[1] = 0; 46 hsv[2] = v; 47 return; 48 } 49 50 SkScalar s = ByteDivToScalar(delta, max); 51 SkASSERT(s >= 0 && s <= SK_Scalar1); 52 53 SkScalar h; 54 if (r == max) { 55 h = ByteDivToScalar(g - b, delta); 56 } else if (g == max) { 57 h = SkIntToScalar(2) + ByteDivToScalar(b - r, delta); 58 } else { // b == max 59 h = SkIntToScalar(4) + ByteDivToScalar(r - g, delta); 60 } 61 62 h *= 60; 63 if (h < 0) { 64 h += SkIntToScalar(360); 65 } 66 SkASSERT(h >= 0 && h < SkIntToScalar(360)); 67 68 hsv[0] = h; 69 hsv[1] = s; 70 hsv[2] = v; 71 } 72 73 SkColor SkHSVToColor(U8CPU a, const SkScalar hsv[3]) { 74 SkASSERT(hsv); 75 76 SkScalar s = SkScalarPin(hsv[1], 0, 1); 77 SkScalar v = SkScalarPin(hsv[2], 0, 1); 78 79 U8CPU v_byte = SkScalarRoundToInt(v * 255); 80 81 if (SkScalarNearlyZero(s)) { // shade of gray 82 return SkColorSetARGB(a, v_byte, v_byte, v_byte); 83 } 84 SkScalar hx = (hsv[0] < 0 || hsv[0] >= SkIntToScalar(360)) ? 0 : hsv[0]/60; 85 SkScalar w = SkScalarFloorToScalar(hx); 86 SkScalar f = hx - w; 87 88 unsigned p = SkScalarRoundToInt((SK_Scalar1 - s) * v * 255); 89 unsigned q = SkScalarRoundToInt((SK_Scalar1 - (s * f)) * v * 255); 90 unsigned t = SkScalarRoundToInt((SK_Scalar1 - (s * (SK_Scalar1 - f))) * v * 255); 91 92 unsigned r, g, b; 93 94 SkASSERT((unsigned)(w) < 6); 95 switch ((unsigned)(w)) { 96 case 0: r = v_byte; g = t; b = p; break; 97 case 1: r = q; g = v_byte; b = p; break; 98 case 2: r = p; g = v_byte; b = t; break; 99 case 3: r = p; g = q; b = v_byte; break; 100 case 4: r = t; g = p; b = v_byte; break; 101 default: r = v_byte; g = p; b = q; break; 102 } 103 return SkColorSetARGB(a, r, g, b); 104 } 105 106 /////////////////////////////////////////////////////////////////////////////////////////////////// 107 #include "SkPM4fPriv.h" 108 #include "SkHalf.h" 109 110 SkPM4f SkPM4f::FromPMColor(SkPMColor c) { 111 return From4f(swizzle_rb_if_bgra(Sk4f_fromL32(c))); 112 } 113 114 SkColor4f SkPM4f::unpremul() const { 115 float alpha = fVec[A]; 116 if (0 == alpha) { 117 return { 0, 0, 0, 0 }; 118 } else { 119 float invAlpha = 1 / alpha; 120 return { fVec[R] * invAlpha, fVec[G] * invAlpha, fVec[B] * invAlpha, alpha }; 121 } 122 } 123 124 void SkPM4f::toF16(uint16_t half[4]) const { 125 for (int i = 0; i < 4; ++i) { 126 half[i] = SkFloatToHalf(fVec[i]); 127 } 128 } 129 130 uint64_t SkPM4f::toF16() const { 131 uint64_t value; 132 this->toF16(reinterpret_cast<uint16_t*>(&value)); 133 return value; 134 } 135 136 SkPM4f SkPM4f::FromF16(const uint16_t half[4]) { 137 return {{ 138 SkHalfToFloat(half[0]), 139 SkHalfToFloat(half[1]), 140 SkHalfToFloat(half[2]), 141 SkHalfToFloat(half[3]) 142 }}; 143 } 144 145 #ifdef SK_DEBUG 146 void SkPM4f::assertIsUnit() const { 147 auto c4 = Sk4f::Load(fVec); 148 SkASSERT((c4 >= Sk4f(0)).allTrue() && (c4 <= Sk4f(1)).allTrue()); 149 } 150 #endif 151 152 /////////////////////////////////////////////////////////////////////////////////////////////////// 153 154 SkColor4f SkColor4f::FromColor(SkColor bgra) { 155 SkColor4f rgba; 156 swizzle_rb(Sk4f_fromS32(bgra)).store(rgba.vec()); 157 return rgba; 158 } 159 160 SkColor4f SkColor4f::FromColor3f(SkColor3f color3f, float a) { 161 SkColor4f rgba; 162 rgba.fR = color3f.fX; 163 rgba.fG = color3f.fY; 164 rgba.fB = color3f.fZ; 165 rgba.fA = a; 166 return rgba; 167 } 168 169 SkColor SkColor4f::toSkColor() const { 170 return Sk4f_toS32(swizzle_rb(Sk4f::Load(this->vec()))); 171 } 172 173 SkColor4f SkColor4f::Pin(float r, float g, float b, float a) { 174 SkColor4f c4; 175 Sk4f::Min(Sk4f::Max(Sk4f(r, g, b, a), Sk4f(0)), Sk4f(1)).store(c4.vec()); 176 return c4; 177 } 178 179 SkPM4f SkColor4f::premul() const { 180 auto src = Sk4f::Load(this->pin().vec()); 181 float srcAlpha = src[3]; // need the pinned version of our alpha 182 src = src * Sk4f(srcAlpha, srcAlpha, srcAlpha, 1); 183 184 return SkPM4f::From4f(src); 185 } 186