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