SVG lighting colors need to be converted into linearSRGB
authorsimon.fraser@apple.com <simon.fraser@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 9 May 2018 15:21:59 +0000 (15:21 +0000)
committersimon.fraser@apple.com <simon.fraser@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 9 May 2018 15:21:59 +0000 (15:21 +0000)
https://bugs.webkit.org/show_bug.cgi?id=181196

Reviewed by Darin Adler.

Address post-commit comments. Don't make a Color that contains linearRGB components,
but use FloatComponents instead. Since these FloatComponents are in the 0-1 range,
FELighting::setPixelInternal() needs to multiply by 255 since the output pixels are
8-bit 0-255.

Change linearToSRGBColorComponent() and sRGBToLinearColorComponent() to do math in
floats without promoting to doubles.

* platform/graphics/ColorUtilities.cpp:
(WebCore::FloatComponents::FloatComponents):
(WebCore::linearToSRGBColorComponent):
(WebCore::sRGBToLinearColorComponent):
(WebCore::sRGBColorToLinearComponents):
(WebCore::linearToSRGBColor): Deleted.
(WebCore::sRGBToLinearColor): Deleted.
* platform/graphics/ColorUtilities.h:
* platform/graphics/filters/FELighting.cpp:
(WebCore::FELighting::setPixelInternal):
(WebCore::FELighting::drawLighting):

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@231559 268f45cc-cd09-0410-ab3c-d52691b4dbfc

Source/WebCore/ChangeLog
Source/WebCore/platform/graphics/ColorUtilities.cpp
Source/WebCore/platform/graphics/ColorUtilities.h
Source/WebCore/platform/graphics/filters/FELighting.cpp

index 28a5dd8..567ff9f 100644 (file)
@@ -1,3 +1,30 @@
+2018-05-08  Simon Fraser  <simon.fraser@apple.com>
+
+        SVG lighting colors need to be converted into linearSRGB
+        https://bugs.webkit.org/show_bug.cgi?id=181196
+
+        Reviewed by Darin Adler.
+
+        Address post-commit comments. Don't make a Color that contains linearRGB components,
+        but use FloatComponents instead. Since these FloatComponents are in the 0-1 range,
+        FELighting::setPixelInternal() needs to multiply by 255 since the output pixels are
+        8-bit 0-255.
+        
+        Change linearToSRGBColorComponent() and sRGBToLinearColorComponent() to do math in
+        floats without promoting to doubles.
+
+        * platform/graphics/ColorUtilities.cpp:
+        (WebCore::FloatComponents::FloatComponents):
+        (WebCore::linearToSRGBColorComponent):
+        (WebCore::sRGBToLinearColorComponent):
+        (WebCore::sRGBColorToLinearComponents):
+        (WebCore::linearToSRGBColor): Deleted.
+        (WebCore::sRGBToLinearColor): Deleted.
+        * platform/graphics/ColorUtilities.h:
+        * platform/graphics/filters/FELighting.cpp:
+        (WebCore::FELighting::setPixelInternal):
+        (WebCore::FELighting::drawLighting):
+
 2018-05-09  Timothy Hatcher  <timothy@apple.com>
 
         Use StyleColor::Options in more places.
index 0ba6c4c..17299a2 100644 (file)
 
 namespace WebCore {
 
+FloatComponents::FloatComponents(const Color& color)
+{
+    color.getRGBA(components[0], components[1], components[2], components[3]);
+}
+
 ColorComponents::ColorComponents(const FloatComponents& floatComponents)
 {
     components[0] = clampedColorComponent(floatComponents.components[0]);
@@ -42,40 +47,30 @@ ColorComponents::ColorComponents(const FloatComponents& floatComponents)
 // These are the standard sRGB <-> linearRGB conversion functions (https://en.wikipedia.org/wiki/SRGB).
 float linearToSRGBColorComponent(float c)
 {
-    if (c < 0.0031308)
-        return 12.92 * c;
+    if (c < 0.0031308f)
+        return 12.92f * c;
 
-    return clampTo<float>(1.055 * powf(c, 1.0 / 2.4) - 0.055, 0, 1);
+    return clampTo<float>(1.055f * std::pow(c, 1.0f / 2.4f) - 0.055f, 0, 1);
 }
 
 float sRGBToLinearColorComponent(float c)
 {
-    if (c <= 0.04045)
-        return c / 12.92;
-
-    return clampTo<float>(powf((c + 0.055) / 1.055, 2.4), 0, 1);
-}
-
-Color linearToSRGBColor(const Color& color)
-{
-    float r, g, b, a;
-    color.getRGBA(r, g, b, a);
-    r = linearToSRGBColorComponent(r);
-    g = linearToSRGBColorComponent(g);
-    b = linearToSRGBColorComponent(b);
+    if (c <= 0.04045f)
+        return c / 12.92f;
 
-    return Color(r, g, b, a);
+    return clampTo<float>(std::pow((c + 0.055f) / 1.055f, 2.4f), 0, 1);
 }
 
-Color sRGBToLinearColor(const Color& color)
+FloatComponents sRGBColorToLinearComponents(const Color& color)
 {
     float r, g, b, a;
     color.getRGBA(r, g, b, a);
-    r = sRGBToLinearColorComponent(r);
-    g = sRGBToLinearColorComponent(g);
-    b = sRGBToLinearColorComponent(b);
-
-    return Color(r, g, b, a);
+    return {
+        sRGBToLinearColorComponent(r),
+        sRGBToLinearColorComponent(g),
+        sRGBToLinearColorComponent(b),
+        a
+    };
 }
 
 
index 502ec19..6f9242e 100644 (file)
@@ -40,6 +40,8 @@ struct FloatComponents {
         components[3] = d;
     }
 
+    FloatComponents(const Color&);
+
     FloatComponents& operator+=(const FloatComponents& rhs)
     {
         components[0] += rhs.components[0];
@@ -151,9 +153,8 @@ inline unsigned byteOffsetOfPixel(unsigned x, unsigned y, unsigned rowBytes)
 // 0-1 components, result is clamped.
 float linearToSRGBColorComponent(float);
 float sRGBToLinearColorComponent(float);
-    
-Color linearToSRGBColor(const Color&);
-Color sRGBToLinearColor(const Color&);
+
+FloatComponents sRGBColorToLinearComponents(const Color&);
 
 class ColorMatrix {
 public:
index 63bc826..781a798 100644 (file)
@@ -295,9 +295,9 @@ void FELighting::setPixelInternal(int offset, const LightingData& data, const Li
         lightStrength = 0;
 
     uint8_t pixelValue[3] = {
-        static_cast<uint8_t>(lightStrength * lightingData.colorVector.x()),
-        static_cast<uint8_t>(lightStrength * lightingData.colorVector.y()),
-        static_cast<uint8_t>(lightStrength * lightingData.colorVector.z())
+        static_cast<uint8_t>(lightStrength * lightingData.colorVector.x() * 255.0f),
+        static_cast<uint8_t>(lightStrength * lightingData.colorVector.y() * 255.0f),
+        static_cast<uint8_t>(lightStrength * lightingData.colorVector.z() * 255.0f)
     };
     
     data.pixels->setRange(pixelValue, 3, offset);
@@ -403,8 +403,8 @@ bool FELighting::drawLighting(Uint8ClampedArray& pixels, int width, int height)
     data.widthDecreasedByOne = width - 1;
     data.heightDecreasedByOne = height - 1;
     
-    Color lightColor = (operatingColorSpace() == ColorSpaceLinearRGB) ? sRGBToLinearColor(m_lightingColor) : m_lightingColor;
-    paintingData.initialLightingData.colorVector = FloatPoint3D(lightColor.red(), lightColor.green(), lightColor.blue());
+    FloatComponents lightColor = (operatingColorSpace() == ColorSpaceLinearRGB) ? sRGBColorToLinearComponents(m_lightingColor) : FloatComponents(m_lightingColor);
+    paintingData.initialLightingData.colorVector = FloatPoint3D(lightColor.components[0], lightColor.components[1], lightColor.components[2]);
     m_lightSource->initPaintingData(*this, paintingData);
 
     // Top left.