Title: [262810] trunk/Source/WebCore
Revision
262810
Author
[email protected]
Date
2020-06-09 14:05:09 -0700 (Tue, 09 Jun 2020)

Log Message

Extended Color: Streamline SimpleColor premulitply/unpremultiply code
https://bugs.webkit.org/show_bug.cgi?id=212945

Reviewed by Darin Adler.

Simplify / streamline the premulitply/unpremultiply code by:
- Removing the overloads that didn't take individual components, keeping 
  only the ones taking a SimpleColor.
- Replacing the "ceiling" bool in makePremultipliedSimpleColor and converting
  it into two functions.
- Simplifying the names from makePremultipliedSimpleColor/makeUnpremultipliedSimpleColor
  to premultiplyFlooring/premultiplyCeiling/unpremultiply.
- Where component order is important, use valueAsARGB() explicitly to
  show what the resulting value's format will be.

* platform/graphics/Color.cpp:
(WebCore::blend):
Update to call premultiplyCeiling/unpremultiply.

* platform/graphics/ImageBackingStore.h:
(WebCore::ImageBackingStore::blendPixel):
(WebCore::ImageBackingStore::pixelValue const):
Update to call premultiplyFlooring/unpremultiply and valueAsARGB().

* platform/graphics/SimpleColor.h:
* platform/graphics/SimpleColor.cpp:
(WebCore::premultiplyFlooring):
(WebCore::premultiplyCeiling):
(WebCore::unpremultiplyChannel):
(WebCore::unpremultiply):
(WebCore::premultipliedChannel): Deleted.
(WebCore::unpremultipliedChannel): Deleted.
(WebCore::makePremultipliedSimpleColor): Deleted.
(WebCore::makeUnpremultipliedSimpleColor): Deleted.
Simplify premulitply/unpremultiply interfaces. Use structured bindings to make
the code a bit easier to follow as well.
        
* platform/graphics/cairo/ImageBufferCairoImageSurfaceBackend.cpp:
(WebCore::ImageBufferCairoImageSurfaceBackend::platformTransformColorSpace):
Update to call premultiplyFlooring/unpremultiply and valueAsARGB().

* platform/graphics/cairo/NativeImageCairo.cpp:
(WebCore::nativeImageSinglePixelSolidColor):
Update to call premultiplyFlooring/unpremultiply and valueAsARGB(). Also removes
reinterpret cast to SimpleColor, instead following the model in ImageBufferCairoImageSurfaceBackend
and casting to unsigned, and building the SimpleColor from that. This will allow 
SimpleColor to change its underlying representation in the future without breaking things.

Modified Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (262809 => 262810)


--- trunk/Source/WebCore/ChangeLog	2020-06-09 21:04:09 UTC (rev 262809)
+++ trunk/Source/WebCore/ChangeLog	2020-06-09 21:05:09 UTC (rev 262810)
@@ -1,3 +1,53 @@
+2020-06-09  Sam Weinig  <[email protected]>
+
+        Extended Color: Streamline SimpleColor premulitply/unpremultiply code
+        https://bugs.webkit.org/show_bug.cgi?id=212945
+
+        Reviewed by Darin Adler.
+
+        Simplify / streamline the premulitply/unpremultiply code by:
+        - Removing the overloads that didn't take individual components, keeping 
+          only the ones taking a SimpleColor.
+        - Replacing the "ceiling" bool in makePremultipliedSimpleColor and converting
+          it into two functions.
+        - Simplifying the names from makePremultipliedSimpleColor/makeUnpremultipliedSimpleColor
+          to premultiplyFlooring/premultiplyCeiling/unpremultiply.
+        - Where component order is important, use valueAsARGB() explicitly to
+          show what the resulting value's format will be.
+
+        * platform/graphics/Color.cpp:
+        (WebCore::blend):
+        Update to call premultiplyCeiling/unpremultiply.
+
+        * platform/graphics/ImageBackingStore.h:
+        (WebCore::ImageBackingStore::blendPixel):
+        (WebCore::ImageBackingStore::pixelValue const):
+        Update to call premultiplyFlooring/unpremultiply and valueAsARGB().
+
+        * platform/graphics/SimpleColor.h:
+        * platform/graphics/SimpleColor.cpp:
+        (WebCore::premultiplyFlooring):
+        (WebCore::premultiplyCeiling):
+        (WebCore::unpremultiplyChannel):
+        (WebCore::unpremultiply):
+        (WebCore::premultipliedChannel): Deleted.
+        (WebCore::unpremultipliedChannel): Deleted.
+        (WebCore::makePremultipliedSimpleColor): Deleted.
+        (WebCore::makeUnpremultipliedSimpleColor): Deleted.
+        Simplify premulitply/unpremultiply interfaces. Use structured bindings to make
+        the code a bit easier to follow as well.
+        
+        * platform/graphics/cairo/ImageBufferCairoImageSurfaceBackend.cpp:
+        (WebCore::ImageBufferCairoImageSurfaceBackend::platformTransformColorSpace):
+        Update to call premultiplyFlooring/unpremultiply and valueAsARGB().
+
+        * platform/graphics/cairo/NativeImageCairo.cpp:
+        (WebCore::nativeImageSinglePixelSolidColor):
+        Update to call premultiplyFlooring/unpremultiply and valueAsARGB(). Also removes
+        reinterpret cast to SimpleColor, instead following the model in ImageBufferCairoImageSurfaceBackend
+        and casting to unsigned, and building the SimpleColor from that. This will allow 
+        SimpleColor to change its underlying representation in the future without breaking things.
+
 2020-06-09  Commit Queue  <[email protected]>
 
         Unreviewed, reverting r261841.

Modified: trunk/Source/WebCore/platform/graphics/Color.cpp (262809 => 262810)


--- trunk/Source/WebCore/platform/graphics/Color.cpp	2020-06-09 21:04:09 UTC (rev 262809)
+++ trunk/Source/WebCore/platform/graphics/Color.cpp	2020-06-09 21:05:09 UTC (rev 262810)
@@ -266,18 +266,18 @@
     if (progress == 1 && !to.isValid())
         return { };
 
-    // Since makePremultipliedSimpleColor() bails on zero alpha, special-case that.
-    auto premultFrom = from.alpha() ? makePremultipliedSimpleColor(from.toSRGBASimpleColorLossy()) : Color::transparent;
-    auto premultTo = to.alpha() ? makePremultipliedSimpleColor(to.toSRGBASimpleColorLossy()) : Color::transparent;
+    // Since premultiplyCeiling() bails on zero alpha, special-case that.
+    auto premultipliedFrom = from.alpha() ? premultiplyCeiling(from.toSRGBASimpleColorLossy()) : Color::transparent;
+    auto premultipliedTo = to.alpha() ? premultiplyCeiling(to.toSRGBASimpleColorLossy()) : Color::transparent;
 
     SimpleColor premultBlended = makeSimpleColor(
-        WebCore::blend(premultFrom.redComponent(), premultTo.redComponent(), progress),
-        WebCore::blend(premultFrom.greenComponent(), premultTo.greenComponent(), progress),
-        WebCore::blend(premultFrom.blueComponent(), premultTo.blueComponent(), progress),
-        WebCore::blend(premultFrom.alphaComponent(), premultTo.alphaComponent(), progress)
+        WebCore::blend(premultipliedFrom.redComponent(), premultipliedTo.redComponent(), progress),
+        WebCore::blend(premultipliedFrom.greenComponent(), premultipliedTo.greenComponent(), progress),
+        WebCore::blend(premultipliedFrom.blueComponent(), premultipliedTo.blueComponent(), progress),
+        WebCore::blend(premultipliedFrom.alphaComponent(), premultipliedTo.alphaComponent(), progress)
     );
 
-    return makeUnpremultipliedSimpleColor(premultBlended);
+    return unpremultiply(premultBlended);
 }
 
 Color blendWithoutPremultiply(const Color& from, const Color& to, double progress)

Modified: trunk/Source/WebCore/platform/graphics/ImageBackingStore.h (262809 => 262810)


--- trunk/Source/WebCore/platform/graphics/ImageBackingStore.h	2020-06-09 21:04:09 UTC (rev 262809)
+++ trunk/Source/WebCore/platform/graphics/ImageBackingStore.h	2020-06-09 21:05:09 UTC (rev 262810)
@@ -160,7 +160,7 @@
         }
 
         if (!m_premultiplyAlpha)
-            pixel = makePremultipliedSimpleColor(pixel.redComponent(), pixel.greenComponent(), pixel.blueComponent(), pixel.alphaComponent(), false);
+            pixel = premultiplyFlooring(pixel);
 
         unsigned d = 255 - a;
 
@@ -169,10 +169,12 @@
         b = fastDivideBy255(b * a + pixel.blueComponent() * d);
         a += fastDivideBy255(d * pixel.alphaComponent());
 
-        if (m_premultiplyAlpha)
-            *dest = makeSimpleColor(r, g, b, a).value();
-        else
-            *dest = makeUnpremultipliedSimpleColor(r, g, b, a).value();
+        auto result = makeSimpleColor(r, g, b, a);
+
+        if (!m_premultiplyAlpha)
+            result = unpremultiply(result);
+
+        *dest = result.valueAsARGB();
     }
 
     static bool isOverSize(const IntSize& size)
@@ -224,10 +226,12 @@
         if (m_premultiplyAlpha && !a)
             return 0;
 
+        auto result = makeSimpleColor(r, g, b, a);
+
         if (m_premultiplyAlpha && a < 255)
-            return makePremultipliedSimpleColor(r, g, b, a, false).value();
+            result = premultiplyFlooring(result);
 
-        return makeSimpleColor(r, g, b, a).value();
+        return result.valueAsARGB();
     }
 
     RefPtr<SharedBuffer::DataSegment> m_pixels;

Modified: trunk/Source/WebCore/platform/graphics/SimpleColor.cpp (262809 => 262810)


--- trunk/Source/WebCore/platform/graphics/SimpleColor.cpp	2020-06-09 21:04:09 UTC (rev 262809)
+++ trunk/Source/WebCore/platform/graphics/SimpleColor.cpp	2020-06-09 21:05:09 UTC (rev 262810)
@@ -33,40 +33,35 @@
 
 namespace WebCore {
 
-static inline unsigned premultipliedChannel(unsigned c, unsigned a, bool ceiling = true)
+SimpleColor premultiplyFlooring(SimpleColor color)
 {
-    return fastDivideBy255(ceiling ? c * a + 254 : c * a);
+    auto [r, g, b, a] = color;
+    if (!a || a == 255)
+        return color;
+    return makeSimpleColor(fastDivideBy255(r * a), fastDivideBy255(g * a), fastDivideBy255(b * a), a);
 }
 
-static inline unsigned unpremultipliedChannel(unsigned c, unsigned a)
+SimpleColor premultiplyCeiling(SimpleColor color)
 {
-    return (fastMultiplyBy255(c) + a - 1) / a;
+    auto [r, g, b, a] = color;
+    if (!a || a == 255)
+        return color;
+    return makeSimpleColor(fastDivideBy255(r * a + 254), fastDivideBy255(g * a + 254), fastDivideBy255(b * a + 254), a);
 }
 
-SimpleColor makePremultipliedSimpleColor(int r, int g, int b, int a, bool ceiling)
+static inline uint16_t unpremultiplyChannel(uint8_t c, uint8_t a)
 {
-    return makeSimpleColor(premultipliedChannel(r, a, ceiling), premultipliedChannel(g, a, ceiling), premultipliedChannel(b, a, ceiling), a);
+    return (fastMultiplyBy255(c) + a - 1) / a;
 }
 
-SimpleColor makePremultipliedSimpleColor(SimpleColor pixelColor)
+SimpleColor unpremultiply(SimpleColor color)
 {
-    if (pixelColor.isOpaque())
-        return pixelColor;
-    return makePremultipliedSimpleColor(pixelColor.redComponent(), pixelColor.greenComponent(), pixelColor.blueComponent(), pixelColor.alphaComponent());
+    auto [r, g, b, a] = color;
+    if (!a || a == 255)
+        return color;
+    return makeSimpleColor(unpremultiplyChannel(r, a), unpremultiplyChannel(g, a), unpremultiplyChannel(b, a), a);
 }
 
-SimpleColor makeUnpremultipliedSimpleColor(int r, int g, int b, int a)
-{
-    return makeSimpleColor(unpremultipliedChannel(r, a), unpremultipliedChannel(g, a), unpremultipliedChannel(b, a), a);
-}
-
-SimpleColor makeUnpremultipliedSimpleColor(SimpleColor pixelColor)
-{
-    if (pixelColor.isVisible() && !pixelColor.isOpaque())
-        return makeUnpremultipliedSimpleColor(pixelColor.redComponent(), pixelColor.greenComponent(), pixelColor.blueComponent(), pixelColor.alphaComponent());
-    return pixelColor;
-}
-
 SimpleColor makeSimpleColorFromCMYKA(float c, float m, float y, float k, float a)
 {
     float colors = 1 - k;

Modified: trunk/Source/WebCore/platform/graphics/SimpleColor.h (262809 => 262810)


--- trunk/Source/WebCore/platform/graphics/SimpleColor.h	2020-06-09 21:04:09 UTC (rev 262809)
+++ trunk/Source/WebCore/platform/graphics/SimpleColor.h	2020-06-09 21:05:09 UTC (rev 262810)
@@ -98,10 +98,9 @@
 SimpleColor makeSimpleColorFromFloats(float r, float g, float b, float a);
 SimpleColor makeSimpleColorFromCMYKA(float c, float m, float y, float k, float a);
 
-SimpleColor makePremultipliedSimpleColor(int r, int g, int b, int a, bool ceiling = true);
-SimpleColor makePremultipliedSimpleColor(SimpleColor);
-SimpleColor makeUnpremultipliedSimpleColor(int r, int g, int b, int a);
-SimpleColor makeUnpremultipliedSimpleColor(SimpleColor);
+SimpleColor premultiplyFlooring(SimpleColor);
+SimpleColor premultiplyCeiling(SimpleColor);
+SimpleColor unpremultiply(SimpleColor);
 
 inline bool operator==(SimpleColor a, SimpleColor b)
 {

Modified: trunk/Source/WebCore/platform/graphics/cairo/ImageBufferCairoImageSurfaceBackend.cpp (262809 => 262810)


--- trunk/Source/WebCore/platform/graphics/cairo/ImageBufferCairoImageSurfaceBackend.cpp	2020-06-09 21:04:09 UTC (rev 262809)
+++ trunk/Source/WebCore/platform/graphics/cairo/ImageBufferCairoImageSurfaceBackend.cpp	2020-06-09 21:05:09 UTC (rev 262810)
@@ -80,9 +80,9 @@
         unsigned* row = reinterpret_cast_ptr<unsigned*>(dataSrc + stride * y);
         for (int x = 0; x < m_logicalSize.width(); x++) {
             unsigned* pixel = row + x;
-            auto pixelColor = makeUnpremultipliedSimpleColor(*pixel);
+            auto pixelColor = unpremultiply(SimpleColor { *pixel });
             pixelColor = makeSimpleColor(lookUpTable[pixelColor.redComponent()], lookUpTable[pixelColor.greenComponent()], lookUpTable[pixelColor.blueComponent()], pixelColor.alphaComponent());
-            *pixel = makePremultipliedSimpleColor(pixelColor).value();
+            *pixel = premultiplyCeiling(pixelColor).valueAsARGB();
         }
     }
     cairo_surface_mark_dirty_rectangle(m_surface.get(), 0, 0, m_logicalSize.width(), m_logicalSize.height());

Modified: trunk/Source/WebCore/platform/graphics/cairo/NativeImageCairo.cpp (262809 => 262810)


--- trunk/Source/WebCore/platform/graphics/cairo/NativeImageCairo.cpp	2020-06-09 21:04:09 UTC (rev 262809)
+++ trunk/Source/WebCore/platform/graphics/cairo/NativeImageCairo.cpp	2020-06-09 21:05:09 UTC (rev 262810)
@@ -53,8 +53,8 @@
     if (cairo_surface_get_type(image.get()) != CAIRO_SURFACE_TYPE_IMAGE)
         return Color();
 
-    SimpleColor* pixel = reinterpret_cast_ptr<SimpleColor*>(cairo_image_surface_get_data(image.get()));
-    return makeUnpremultipliedSimpleColor(*pixel);
+    unsigned* pixel = reinterpret_cast_ptr<unsigned*>(cairo_image_surface_get_data(image.get()));
+    return unpremultiply(SimpleColor { *pixel });
 }
 
 void drawNativeImage(const NativeImagePtr& image, GraphicsContext& context, const FloatRect& destRect, const FloatRect& srcRect, const IntSize& imageSize, const ImagePaintingOptions& options)
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to