Changeset 261828 in webkit
- Timestamp:
- May 18, 2020 1:22:15 PM (4 years ago)
- Location:
- trunk
- Files:
-
- 9 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/WebCore/ChangeLog
r261825 r261828 1 2020-05-18 Simon Fraser <simon.fraser@apple.com> 2 3 Implement conversion between P3 and sRGB color 4 https://bugs.webkit.org/show_bug.cgi?id=211998 5 6 Reviewed by Daniel Bates. 7 8 Color::toSRGBAComponentsLossy() was a lie because it didn't actually convert extended 9 colors into sRGB. Fix that by converting P3 and linaerRGB colors into sRGB, using the color 10 math from CSS Color 4. 11 12 Renamed the various "linear to sRGB" functions because they work for any RGB colors, 13 not just sRGB. 14 15 * platform/graphics/Color.cpp: 16 (WebCore::Color::toSRGBAComponentsLossy const): 17 * platform/graphics/Color.h: 18 * platform/graphics/ColorUtilities.cpp: 19 (WebCore::linearToRGBColorComponent): 20 (WebCore::RGBToLinearColorComponent): 21 (WebCore::sRGBColorToLinearComponents): 22 (WebCore::RGBToLinearComponents): 23 (WebCore::linearToRGBComponents): 24 (WebCore::XYZToLinearSRGB): 25 (WebCore::linearSRGBToXYZ): 26 (WebCore::XYZToLinearP3): 27 (WebCore::linearP3ToXYZ): 28 (WebCore::P3ToSRGB): 29 (WebCore::sRGBToP3): 30 (WebCore::ColorMatrix::transformedColorComponents const): 31 (WebCore::linearToSRGBColorComponent): Deleted. 32 (WebCore::sRGBToLinearColorComponent): Deleted. 33 (WebCore::sRGBToLinearComponents): Deleted. 34 (WebCore::linearToSRGBComponents): Deleted. 35 * platform/graphics/ColorUtilities.h: 36 1 37 2020-05-18 Wenson Hsieh <wenson_hsieh@apple.com> 2 38 -
trunk/Source/WebCore/platform/graphics/Color.cpp
r261794 r261828 80 80 { 81 81 const float scaleFactor = 255.0; 82 FloatComponents floatResult = HSLToSRGB({ hue, saturation, lightness, alpha });82 FloatComponents floatResult = hslToSRGB({ hue, saturation, lightness, alpha }); 83 83 return makeRGBA( 84 84 round(floatResult.components[0] * scaleFactor), … … 562 562 switch (extendedColor.colorSpace()) { 563 563 case ColorSpace::SRGB: 564 return extendedColor.channels(); 564 565 case ColorSpace::LinearRGB: 566 return linearToRGBComponents(extendedColor.channels()); 565 567 case ColorSpace::DisplayP3: 566 // FIXME: This doesn't convert into sRGB and should. 567 return extendedColor.channels(); 568 return p3ToSRGB(extendedColor.channels()); 568 569 } 569 570 } -
trunk/Source/WebCore/platform/graphics/Color.h
r261794 r261828 212 212 WEBCORE_EXPORT void getRGBA(float& r, float& g, float& b, float& a) const; 213 213 WEBCORE_EXPORT void getRGBA(double& r, double& g, double& b, double& a) const; 214 214 215 WEBCORE_EXPORT void getHSL(double& h, double& s, double& l) const; 215 216 WEBCORE_EXPORT void getHSV(double& h, double& s, double& v) const; 216 217 217 218 // This will convert non-sRGB colorspace colors into sRGB. 218 FloatComponents toSRGBAComponentsLossy() const;219 WEBCORE_EXPORT FloatComponents toSRGBAComponentsLossy() const; 219 220 220 221 Color light() const; -
trunk/Source/WebCore/platform/graphics/ColorUtilities.cpp
r261794 r261828 54 54 55 55 // These are the standard sRGB <-> linearRGB conversion functions (https://en.wikipedia.org/wiki/SRGB). 56 float linearTo SRGBColorComponent(float c)56 float linearToRGBColorComponent(float c) 57 57 { 58 58 if (c < 0.0031308f) … … 62 62 } 63 63 64 float sRGBToLinearColorComponent(float c)64 float rgbToLinearColorComponent(float c) 65 65 { 66 66 if (c <= 0.04045f) … … 75 75 color.getRGBA(r, g, b, a); 76 76 return { 77 sRGBToLinearColorComponent(r),78 sRGBToLinearColorComponent(g),79 sRGBToLinearColorComponent(b),77 rgbToLinearColorComponent(r), 78 rgbToLinearColorComponent(g), 79 rgbToLinearColorComponent(b), 80 80 a 81 81 }; 82 82 } 83 83 84 FloatComponents sRGBToLinearComponents(const FloatComponents& sRGBColor)85 { 86 return { 87 sRGBToLinearColorComponent(sRGBColor.components[0]),88 sRGBToLinearColorComponent(sRGBColor.components[1]),89 sRGBToLinearColorComponent(sRGBColor.components[2]),90 sRGBColor.components[3]91 }; 92 } 93 94 FloatComponents linearTo SRGBComponents(const FloatComponents& linearRGB)95 { 96 return { 97 linearTo SRGBColorComponent(linearRGB.components[0]),98 linearTo SRGBColorComponent(linearRGB.components[1]),99 linearTo SRGBColorComponent(linearRGB.components[2]),84 FloatComponents rgbToLinearComponents(const FloatComponents& RGBColor) 85 { 86 return { 87 rgbToLinearColorComponent(RGBColor.components[0]), 88 rgbToLinearColorComponent(RGBColor.components[1]), 89 rgbToLinearColorComponent(RGBColor.components[2]), 90 RGBColor.components[3] 91 }; 92 } 93 94 FloatComponents linearToRGBComponents(const FloatComponents& linearRGB) 95 { 96 return { 97 linearToRGBColorComponent(linearRGB.components[0]), 98 linearToRGBColorComponent(linearRGB.components[1]), 99 linearToRGBColorComponent(linearRGB.components[2]), 100 100 linearRGB.components[3] 101 101 }; 102 } 103 104 static FloatComponents xyzToLinearSRGB(const FloatComponents& XYZComponents) 105 { 106 // https://en.wikipedia.org/wiki/SRGB 107 // http://www.brucelindbloom.com/index.html?Eqn_RGB_XYZ_Matrix.html 108 const float values[] = { 109 3.2404542f, -1.5371385f, -0.4985314f, 0.0f, 0.0f, 110 -0.9692660f, 1.8760108f, 0.0415560f, 0.0f, 0.0f, 111 0.0556434f, -0.2040259f, 1.0572252f, 0.0f, 0.0f, 112 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 113 }; 114 ColorMatrix xyzToLinearSRGBMatrix(values); 115 return xyzToLinearSRGBMatrix.transformedColorComponents(XYZComponents); 116 } 117 118 static FloatComponents linearSRGBToXYZ(const FloatComponents& XYZComponents) 119 { 120 // https://en.wikipedia.org/wiki/SRGB 121 // http://www.brucelindbloom.com/index.html?Eqn_RGB_XYZ_Matrix.html 122 const float values[] = { 123 0.4124564f, 0.3575761f, 0.1804375f, 0.0f, 0.0f, 124 0.2126729f, 0.7151522f, 0.0721750f, 0.0f, 0.0f, 125 0.0193339f, 0.1191920f, 0.9503041f, 0.0f, 0.0f, 126 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 127 }; 128 ColorMatrix linearSRGBToXYZMatrix(values); 129 return linearSRGBToXYZMatrix.transformedColorComponents(XYZComponents); 130 } 131 132 static FloatComponents XYZToLinearP3(const FloatComponents& XYZComponents) 133 { 134 // https://drafts.csswg.org/css-color/#color-conversion-code 135 const float values[] = { 136 2.493496911941425f, -0.9313836179191239f, -0.4027107844507168f, 0.0f, 0.0f, 137 -0.8294889695615747f, 1.7626640603183463f, 0.0236246858419436f, 0.0f, 0.0f, 138 0.0358458302437845f, -0.0761723892680418f, 0.9568845240076872f, 0.0f, 0.0f, 139 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 140 }; 141 ColorMatrix xyzToLinearSRGBMatrix(values); 142 return xyzToLinearSRGBMatrix.transformedColorComponents(XYZComponents); 143 } 144 145 static FloatComponents linearP3ToXYZ(const FloatComponents& XYZComponents) 146 { 147 // https://drafts.csswg.org/css-color/#color-conversion-code 148 const float values[] = { 149 0.4865709486482162f, 0.2656676931690931f, 0.198217285234363f, 0.0f, 0.0f, 150 0.2289745640697488f, 0.6917385218365064f, 0.079286914093745f, 0.0f, 0.0f, 151 0.0f, 0.0451133818589026f, 1.043944368900976f, 0.0f, 0.0f, 152 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 153 }; 154 ColorMatrix linearP3ToXYZMatrix(values); 155 return linearP3ToXYZMatrix.transformedColorComponents(XYZComponents); 156 } 157 158 FloatComponents p3ToSRGB(const FloatComponents& p3) 159 { 160 auto linearP3 = rgbToLinearComponents(p3); 161 auto xyz = linearP3ToXYZ(linearP3); 162 auto linearSRGB = xyzToLinearSRGB(xyz); 163 return linearToRGBComponents(linearSRGB); 164 } 165 166 FloatComponents sRGBToP3(const FloatComponents& sRGB) 167 { 168 auto linearSRGB = rgbToLinearComponents(sRGB); 169 auto xyz = linearSRGBToXYZ(linearSRGB); 170 auto linearP3 = XYZToLinearP3(xyz); 171 return linearToRGBComponents(linearP3); 102 172 } 103 173 … … 196 266 // specification at https://drafts.csswg.org/css-color-4/#hsl-to-rgb with 197 267 // further explanation available at http://en.wikipedia.org/wiki/HSL_color_space 198 FloatComponents HSLToSRGB(const FloatComponents& hslColor)268 FloatComponents hslToSRGB(const FloatComponents& hslColor) 199 269 { 200 270 float hue = hslColor.components[0]; … … 352 422 } 353 423 354 void ColorMatrix::transformColorComponents(FloatComponents& colorComonents) const 355 { 356 float red = colorComonents.components[0]; 357 float green = colorComonents.components[1]; 358 float blue = colorComonents.components[2]; 359 float alpha = colorComonents.components[3]; 360 361 colorComonents.components[0] = m_matrix[0][0] * red + m_matrix[0][1] * green + m_matrix[0][2] * blue + m_matrix[0][3] * alpha + m_matrix[0][4]; 362 colorComonents.components[1] = m_matrix[1][0] * red + m_matrix[1][1] * green + m_matrix[1][2] * blue + m_matrix[1][3] * alpha + m_matrix[1][4]; 363 colorComonents.components[2] = m_matrix[2][0] * red + m_matrix[2][1] * green + m_matrix[2][2] * blue + m_matrix[2][3] * alpha + m_matrix[2][4]; 364 colorComonents.components[3] = m_matrix[3][0] * red + m_matrix[3][1] * green + m_matrix[3][2] * blue + m_matrix[3][3] * alpha + m_matrix[3][4]; 424 void ColorMatrix::transformColorComponents(FloatComponents& colorComponents) const 425 { 426 float red = colorComponents.components[0]; 427 float green = colorComponents.components[1]; 428 float blue = colorComponents.components[2]; 429 float alpha = colorComponents.components[3]; 430 431 colorComponents.components[0] = m_matrix[0][0] * red + m_matrix[0][1] * green + m_matrix[0][2] * blue + m_matrix[0][3] * alpha + m_matrix[0][4]; 432 colorComponents.components[1] = m_matrix[1][0] * red + m_matrix[1][1] * green + m_matrix[1][2] * blue + m_matrix[1][3] * alpha + m_matrix[1][4]; 433 colorComponents.components[2] = m_matrix[2][0] * red + m_matrix[2][1] * green + m_matrix[2][2] * blue + m_matrix[2][3] * alpha + m_matrix[2][4]; 434 colorComponents.components[3] = m_matrix[3][0] * red + m_matrix[3][1] * green + m_matrix[3][2] * blue + m_matrix[3][3] * alpha + m_matrix[3][4]; 435 } 436 437 FloatComponents ColorMatrix::transformedColorComponents(const FloatComponents& colorComponents) const 438 { 439 float red = colorComponents.components[0]; 440 float green = colorComponents.components[1]; 441 float blue = colorComponents.components[2]; 442 float alpha = colorComponents.components[3]; 443 444 return { 445 m_matrix[0][0] * red + m_matrix[0][1] * green + m_matrix[0][2] * blue + m_matrix[0][3] * alpha + m_matrix[0][4], 446 m_matrix[1][0] * red + m_matrix[1][1] * green + m_matrix[1][2] * blue + m_matrix[1][3] * alpha + m_matrix[1][4], 447 m_matrix[2][0] * red + m_matrix[2][1] * green + m_matrix[2][2] * blue + m_matrix[2][3] * alpha + m_matrix[2][4], 448 m_matrix[3][0] * red + m_matrix[3][1] * green + m_matrix[3][2] * blue + m_matrix[3][3] * alpha + m_matrix[3][4] 449 }; 365 450 } 366 451 -
trunk/Source/WebCore/platform/graphics/ColorUtilities.h
r261794 r261828 174 174 175 175 // 0-1 components, result is clamped. 176 float linearTo SRGBColorComponent(float);177 float sRGBToLinearColorComponent(float);176 float linearToRGBColorComponent(float); 177 float rgbToLinearColorComponent(float); 178 178 179 179 FloatComponents sRGBColorToLinearComponents(const Color&); 180 FloatComponents sRGBToLinearComponents(const FloatComponents&); 181 FloatComponents linearToSRGBComponents(const FloatComponents&); 180 FloatComponents rgbToLinearComponents(const FloatComponents&); 181 FloatComponents linearToRGBComponents(const FloatComponents&); 182 183 FloatComponents p3ToSRGB(const FloatComponents&); 184 FloatComponents sRGBToP3(const FloatComponents&); 182 185 183 186 FloatComponents sRGBToHSL(const FloatComponents&); 184 FloatComponents HSLToSRGB(const FloatComponents&);187 FloatComponents hslToSRGB(const FloatComponents&); 185 188 186 189 float luminance(const FloatComponents& sRGBCompontents); … … 198 201 199 202 void transformColorComponents(FloatComponents&) const; 203 FloatComponents transformedColorComponents(const FloatComponents&) const; 200 204 201 205 private: -
trunk/Source/WebCore/platform/graphics/cairo/ImageBufferCairoBackend.cpp
r256892 r261828 83 83 for (unsigned i = 0; i < 256; i++) { 84 84 float color = i / 255.0f; 85 color = sRGBToLinearColorComponent(color);85 color = rgbToLinearColorComponent(color); 86 86 array[i] = static_cast<uint8_t>(round(color * 255)); 87 87 } … … 94 94 for (unsigned i = 0; i < 256; i++) { 95 95 float color = i / 255.0f; 96 color = linearTo SRGBColorComponent(color);96 color = linearToRGBColorComponent(color); 97 97 array[i] = static_cast<uint8_t>(round(color * 255)); 98 98 } -
trunk/Source/WebCore/platform/graphics/filters/FilterOperation.cpp
r261791 r261828 234 234 235 235 // Convert back to RGB. 236 sRGBColorComponents = HSLToSRGB(hslComponents);236 sRGBColorComponents = hslToSRGB(hslComponents); 237 237 238 238 // Apply the matrix. See rdar://problem/41146650 for how this matrix was derived. … … 267 267 hslComponents.components[0] = fmod(hslComponents.components[0] + 0.5f, 1.0f); 268 268 // And return RGB. 269 sRGBColorComponents = HSLToSRGB(hslComponents);269 sRGBColorComponents = hslToSRGB(hslComponents); 270 270 return true; 271 271 } -
trunk/Tools/ChangeLog
r261827 r261828 1 2020-05-18 Simon Fraser <simon.fraser@apple.com> 2 3 Implement conversion between P3 and sRGB color 4 https://bugs.webkit.org/show_bug.cgi?id=211998 5 6 Reviewed by Daniel Bates. 7 8 API test for conversions from P3 to sRGB, and linearRGB to sRGB. Values were confirmed 9 as close to those provided by ColorSync Utility. 10 11 * TestWebKitAPI/Tests/WebCore/ExtendedColorTests.cpp: 12 (TestWebKitAPI::TEST): 13 1 14 2020-05-18 Mark Lam <mark.lam@apple.com> 2 15 -
trunk/Tools/TestWebKitAPI/Tests/WebCore/ExtendedColorTests.cpp
r261794 r261828 29 29 #include "WTFStringUtilities.h" 30 30 #include <WebCore/Color.h> 31 #include <wtf/MathExtras.h> 31 32 32 33 using namespace WebCore; … … 222 223 } 223 224 225 TEST(ExtendedColor, P3ConversionToSRGB) 226 { 227 { 228 Color p3Color(1.0, 0.5, 0.25, 0.75, ColorSpace::DisplayP3); 229 EXPECT_TRUE(p3Color.isExtended()); 230 231 auto sRGBComponents = p3Color.toSRGBAComponentsLossy(); 232 EXPECT_TRUE(WTF::areEssentiallyEqual(sRGBComponents.components[0], 1.0f)); 233 EXPECT_TRUE(WTF::areEssentiallyEqual(sRGBComponents.components[1], 0.462537885f)); 234 EXPECT_TRUE(WTF::areEssentiallyEqual(sRGBComponents.components[2], 0.149147838f)); 235 EXPECT_TRUE(WTF::areEssentiallyEqual(sRGBComponents.components[3], 0.75f)); 236 } 237 238 { 239 Color linearColor(1.0, 0.5, 0.25, 0.75, ColorSpace::LinearRGB); 240 EXPECT_TRUE(linearColor.isExtended()); 241 auto sRGBComponents = linearColor.toSRGBAComponentsLossy(); 242 EXPECT_TRUE(WTF::areEssentiallyEqual(sRGBComponents.components[0], 1.0f)); 243 EXPECT_TRUE(WTF::areEssentiallyEqual(sRGBComponents.components[1], 0.735356927f)); 244 EXPECT_TRUE(WTF::areEssentiallyEqual(sRGBComponents.components[2], 0.537098706f)); 245 EXPECT_TRUE(WTF::areEssentiallyEqual(sRGBComponents.components[3], 0.75f)); 246 } 247 } 248 224 249 225 250 } // namespace TestWebKitAPI
Note: See TracChangeset
for help on using the changeset viewer.