Title: [256822] trunk/Source/WebCore
Revision
256822
Author
commit-qu...@webkit.org
Date
2020-02-18 01:31:31 -0800 (Tue, 18 Feb 2020)

Log Message

Make ImageBuffer::getImageData() and putImageData() return and take ImageData
https://bugs.webkit.org/show_bug.cgi?id=206621

Patch by Said Abou-Hallawa <sabouhall...@apple.com> on 2020-02-18
Reviewed by Tim Horton.

-- Combine ImageBuffer::getUnmultipliedImageData() and getPremultipliedImageData()
   in one function and name it getImageData();

-- Make getImageData() returns a RefPtr<ImageData> since the canvas code
   used to encapsulate the returned the returned Uint8ClampedArray into
   an ImageData and send it to _javascript_Core.

-- Rename ImageBuffer::putByteArray() to ImageBuffer::putImageData() and
   make it take an ImageData since the byte array has to be associated
   with an IntSize and separating them does not look a good design.

-- Remove the enum ImageBuffer::CoordinateSystem. All the callers need to
   pass rectangles and sizes in logical coordinates. The ImageData has to
   be scaled according to the ImgeBuffer::resolutionScale().

* bindings/js/SerializedScriptValue.cpp:
(WebCore::CloneSerializer::dumpImageBitmap):
(WebCore::CloneDeserializer::readImageBitmap):
* html/canvas/CanvasRenderingContext2DBase.cpp:
(WebCore::CanvasRenderingContext2DBase::getImageData const):
(WebCore::CanvasRenderingContext2DBase::putImageData):
* html/canvas/CanvasRenderingContext2DBase.h:
* page/PageConsoleClient.cpp:
(WebCore::PageConsoleClient::screenshot):
* platform/graphics/ImageBuffer.cpp:
(WebCore::ImageBuffer::convertToLuminanceMask):
(WebCore::ImageBuffer::transformColorSpace): Deleted.
Move this function to ImageBufferCairo.cpp.

(WebCore::ImageBuffer::genericConvertToLuminanceMask): Deleted.
convertToLuminanceMask() and genericConvertToLuminanceMask() are not
overridden by any platform. So delete genericConvertToLuminanceMask() and
move its body to convertToLuminanceMask().

* platform/graphics/ImageBuffer.h:
(WebCore::ImageBuffer::draw):
(WebCore::ImageBuffer::drawPattern):
(WebCore::ImageBuffer::drawConsuming):
(WebCore::ImageBuffer::putImageData):
Make the private functions be public and remove the friend classes.

* platform/graphics/ShadowBlur.cpp:
(WebCore::ShadowBlur::blurShadowBuffer):
* platform/graphics/cairo/ImageBufferCairo.cpp:
(WebCore::ImageBuffer::transformColorSpace):
(WebCore::getData):
(WebCore::ImageBuffer::getImageData const):
(WebCore::ImageBuffer::putImageData):
(WebCore::getImageData): Deleted.
(WebCore::logicalUnit): Deleted.
(WebCore::backingStoreUnit): Deleted.
(WebCore::ImageBuffer::getUnmultipliedImageData const): Deleted.
(WebCore::ImageBuffer::getPremultipliedImageData const): Deleted.
(WebCore::ImageBuffer::putByteArray): Deleted.
* platform/graphics/cg/ImageBufferCG.cpp:
(WebCore::ImageBuffer::getImageData const):
(WebCore::ImageBuffer::putImageData):
(WebCore::ImageBuffer::toCFData const):
(WebCore::ImageBuffer::getUnmultipliedImageData const): Deleted.
(WebCore::ImageBuffer::getPremultipliedImageData const): Deleted.
(WebCore::ImageBuffer::putByteArray): Deleted.
* platform/graphics/cg/ImageBufferDataCG.cpp:
(WebCore::ImageBufferData::getData const):
(WebCore::ImageBufferData::putData):
* platform/graphics/cg/ImageBufferDataCG.h:
All the rectangles and sizes have to be passed in logical coordinates. To
deal with the pixels' data we need to scale them by the resolutionScale().

* platform/graphics/cpu/arm/filters/FEBlendNEON.h:
(WebCore::FEBlend::platformApplySoftware):
* platform/graphics/filters/FEColorMatrix.cpp:
(WebCore::FEColorMatrix::platformApplySoftware):
* platform/graphics/filters/FEComponentTransfer.cpp:
(WebCore::FEComponentTransfer::platformApplySoftware):
* platform/graphics/filters/FEComposite.cpp:
(WebCore::FEComposite::platformApplySoftware):
* platform/graphics/filters/FEConvolveMatrix.cpp:
(WebCore::FEConvolveMatrix::platformApplySoftware):
* platform/graphics/filters/FEDisplacementMap.cpp:
(WebCore::FEDisplacementMap::platformApplySoftware):
* platform/graphics/filters/FEDropShadow.cpp:
(WebCore::FEDropShadow::platformApplySoftware):
This was the only place which was passing a rectangle in a the back-end
coordinates along with BackingStoreCoordinateSystem. Instead we can pass
the rectangle in logical coordinates and then use ImageData::size() since
it must be scaled with resolutionScale() when the ImageData is created.

* platform/graphics/filters/FEGaussianBlur.cpp:
(WebCore::FEGaussianBlur::platformApplySoftware):
* platform/graphics/filters/FELighting.cpp:
(WebCore::FELighting::platformApplySoftware):
* platform/graphics/filters/FEMorphology.cpp:
(WebCore::FEMorphology::platformApplySoftware):
* platform/graphics/filters/FETurbulence.cpp:
(WebCore::FETurbulence::platformApplySoftware):
* platform/graphics/filters/FilterEffect.cpp:
(WebCore::FilterEffect::forceValidPreMultipliedPixels):
(WebCore::FilterEffect::imageBufferResult):
(WebCore::FilterEffect::copyUnmultipliedResult):
(WebCore::FilterEffect::copyPremultipliedResult):
(WebCore::FilterEffect::createImageBufferResult):
(WebCore::FilterEffect::createUnmultipliedImageResult):
(WebCore::FilterEffect::createPremultipliedImageResult):
* platform/graphics/filters/FilterEffect.h:
* platform/graphics/win/ImageBufferDataDirect2D.cpp:
(WebCore::ImageBufferData::getData const):
(WebCore::ImageBufferData::putData):
* platform/graphics/win/ImageBufferDataDirect2D.h:
* platform/graphics/win/ImageBufferDirect2D.cpp:
(WebCore::ImageBuffer::getImageData const):
(WebCore::ImageBuffer::putImageData):
(WebCore::ImageBuffer::getUnmultipliedImageData const): Deleted.
(WebCore::ImageBuffer::getPremultipliedImageData const): Deleted.
(WebCore::ImageBuffer::putByteArray): Deleted.
* rendering/shapes/Shape.cpp:
(WebCore::Shape::createRasterShape):

Modified Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (256821 => 256822)


--- trunk/Source/WebCore/ChangeLog	2020-02-18 07:38:10 UTC (rev 256821)
+++ trunk/Source/WebCore/ChangeLog	2020-02-18 09:31:31 UTC (rev 256822)
@@ -1,3 +1,127 @@
+2020-02-18  Said Abou-Hallawa  <sabouhall...@apple.com>
+
+        Make ImageBuffer::getImageData() and putImageData() return and take ImageData
+        https://bugs.webkit.org/show_bug.cgi?id=206621
+
+        Reviewed by Tim Horton.
+
+        -- Combine ImageBuffer::getUnmultipliedImageData() and getPremultipliedImageData()
+           in one function and name it getImageData();
+
+        -- Make getImageData() returns a RefPtr<ImageData> since the canvas code
+           used to encapsulate the returned the returned Uint8ClampedArray into
+           an ImageData and send it to _javascript_Core.
+
+        -- Rename ImageBuffer::putByteArray() to ImageBuffer::putImageData() and
+           make it take an ImageData since the byte array has to be associated
+           with an IntSize and separating them does not look a good design.
+
+        -- Remove the enum ImageBuffer::CoordinateSystem. All the callers need to
+           pass rectangles and sizes in logical coordinates. The ImageData has to
+           be scaled according to the ImgeBuffer::resolutionScale(). 
+
+        * bindings/js/SerializedScriptValue.cpp:
+        (WebCore::CloneSerializer::dumpImageBitmap):
+        (WebCore::CloneDeserializer::readImageBitmap):
+        * html/canvas/CanvasRenderingContext2DBase.cpp:
+        (WebCore::CanvasRenderingContext2DBase::getImageData const):
+        (WebCore::CanvasRenderingContext2DBase::putImageData):
+        * html/canvas/CanvasRenderingContext2DBase.h:
+        * page/PageConsoleClient.cpp:
+        (WebCore::PageConsoleClient::screenshot):
+        * platform/graphics/ImageBuffer.cpp:
+        (WebCore::ImageBuffer::convertToLuminanceMask):
+        (WebCore::ImageBuffer::transformColorSpace): Deleted.
+        Move this function to ImageBufferCairo.cpp.
+
+        (WebCore::ImageBuffer::genericConvertToLuminanceMask): Deleted.
+        convertToLuminanceMask() and genericConvertToLuminanceMask() are not 
+        overridden by any platform. So delete genericConvertToLuminanceMask() and
+        move its body to convertToLuminanceMask().
+
+        * platform/graphics/ImageBuffer.h:
+        (WebCore::ImageBuffer::draw):
+        (WebCore::ImageBuffer::drawPattern):
+        (WebCore::ImageBuffer::drawConsuming):
+        (WebCore::ImageBuffer::putImageData):
+        Make the private functions be public and remove the friend classes.
+
+        * platform/graphics/ShadowBlur.cpp:
+        (WebCore::ShadowBlur::blurShadowBuffer):
+        * platform/graphics/cairo/ImageBufferCairo.cpp:
+        (WebCore::ImageBuffer::transformColorSpace):
+        (WebCore::getData):
+        (WebCore::ImageBuffer::getImageData const):
+        (WebCore::ImageBuffer::putImageData):
+        (WebCore::getImageData): Deleted.
+        (WebCore::logicalUnit): Deleted.
+        (WebCore::backingStoreUnit): Deleted.
+        (WebCore::ImageBuffer::getUnmultipliedImageData const): Deleted.
+        (WebCore::ImageBuffer::getPremultipliedImageData const): Deleted.
+        (WebCore::ImageBuffer::putByteArray): Deleted.
+        * platform/graphics/cg/ImageBufferCG.cpp:
+        (WebCore::ImageBuffer::getImageData const):
+        (WebCore::ImageBuffer::putImageData):
+        (WebCore::ImageBuffer::toCFData const):
+        (WebCore::ImageBuffer::getUnmultipliedImageData const): Deleted.
+        (WebCore::ImageBuffer::getPremultipliedImageData const): Deleted.
+        (WebCore::ImageBuffer::putByteArray): Deleted.
+        * platform/graphics/cg/ImageBufferDataCG.cpp:
+        (WebCore::ImageBufferData::getData const):
+        (WebCore::ImageBufferData::putData):
+        * platform/graphics/cg/ImageBufferDataCG.h:
+        All the rectangles and sizes have to be passed in logical coordinates. To
+        deal with the pixels' data we need to scale them by the resolutionScale().
+
+        * platform/graphics/cpu/arm/filters/FEBlendNEON.h:
+        (WebCore::FEBlend::platformApplySoftware):
+        * platform/graphics/filters/FEColorMatrix.cpp:
+        (WebCore::FEColorMatrix::platformApplySoftware):
+        * platform/graphics/filters/FEComponentTransfer.cpp:
+        (WebCore::FEComponentTransfer::platformApplySoftware):
+        * platform/graphics/filters/FEComposite.cpp:
+        (WebCore::FEComposite::platformApplySoftware):
+        * platform/graphics/filters/FEConvolveMatrix.cpp:
+        (WebCore::FEConvolveMatrix::platformApplySoftware):
+        * platform/graphics/filters/FEDisplacementMap.cpp:
+        (WebCore::FEDisplacementMap::platformApplySoftware):
+        * platform/graphics/filters/FEDropShadow.cpp:
+        (WebCore::FEDropShadow::platformApplySoftware):
+        This was the only place which was passing a rectangle in a the back-end
+        coordinates along with BackingStoreCoordinateSystem. Instead we can pass
+        the rectangle in logical coordinates and then use ImageData::size() since
+        it must be scaled with resolutionScale() when the ImageData is created.
+
+        * platform/graphics/filters/FEGaussianBlur.cpp:
+        (WebCore::FEGaussianBlur::platformApplySoftware):
+        * platform/graphics/filters/FELighting.cpp:
+        (WebCore::FELighting::platformApplySoftware):
+        * platform/graphics/filters/FEMorphology.cpp:
+        (WebCore::FEMorphology::platformApplySoftware):
+        * platform/graphics/filters/FETurbulence.cpp:
+        (WebCore::FETurbulence::platformApplySoftware):
+        * platform/graphics/filters/FilterEffect.cpp:
+        (WebCore::FilterEffect::forceValidPreMultipliedPixels):
+        (WebCore::FilterEffect::imageBufferResult):
+        (WebCore::FilterEffect::copyUnmultipliedResult):
+        (WebCore::FilterEffect::copyPremultipliedResult):
+        (WebCore::FilterEffect::createImageBufferResult):
+        (WebCore::FilterEffect::createUnmultipliedImageResult):
+        (WebCore::FilterEffect::createPremultipliedImageResult):
+        * platform/graphics/filters/FilterEffect.h:
+        * platform/graphics/win/ImageBufferDataDirect2D.cpp:
+        (WebCore::ImageBufferData::getData const):
+        (WebCore::ImageBufferData::putData):
+        * platform/graphics/win/ImageBufferDataDirect2D.h:
+        * platform/graphics/win/ImageBufferDirect2D.cpp:
+        (WebCore::ImageBuffer::getImageData const):
+        (WebCore::ImageBuffer::putImageData):
+        (WebCore::ImageBuffer::getUnmultipliedImageData const): Deleted.
+        (WebCore::ImageBuffer::getPremultipliedImageData const): Deleted.
+        (WebCore::ImageBuffer::putByteArray): Deleted.
+        * rendering/shapes/Shape.cpp:
+        (WebCore::Shape::createRasterShape):
+
 2020-02-17  Wenson Hsieh  <wenson_hs...@apple.com>
 
         Selection cannot be modified via text interaction in some areas of the compose body field in Gmail

Modified: trunk/Source/WebCore/bindings/js/SerializedScriptValue.cpp (256821 => 256822)


--- trunk/Source/WebCore/bindings/js/SerializedScriptValue.cpp	2020-02-18 07:38:10 UTC (rev 256821)
+++ trunk/Source/WebCore/bindings/js/SerializedScriptValue.cpp	2020-02-18 09:31:31 UTC (rev 256822)
@@ -943,13 +943,13 @@
         }
 
         const IntSize& logicalSize = buffer->logicalSize();
-        auto imageData = buffer->getPremultipliedImageData(IntRect(0, 0, logicalSize.width(), logicalSize.height()));
+        auto imageData = buffer->getImageData(AlphaPremultiplication::Premultiplied, { IntPoint::zero(), logicalSize });
         if (!imageData) {
             code = SerializationReturnCode::ValidationError;
             return;
         }
 
-        RefPtr<ArrayBuffer> arrayBuffer = imageData->possiblySharedBuffer();
+        RefPtr<ArrayBuffer> arrayBuffer = imageData->data()->possiblySharedBuffer();
         if (!arrayBuffer) {
             code = SerializationReturnCode::ValidationError;
             return;
@@ -2865,19 +2865,29 @@
             return JSValue();
         }
 
-        auto imageData = Uint8ClampedArray::tryCreate(WTFMove(arrayBuffer), 0, arrayBuffer->byteLength());
+        auto array = Uint8ClampedArray::tryCreate(WTFMove(arrayBuffer), 0, arrayBuffer->byteLength());
+        if (!array) {
+            fail();
+            return JSValue();
+        }
+
+        IntSize logicalSize = IntSize(logicalWidth, logicalHeight);
+        IntSize imageDataSize = logicalSize;
+        imageDataSize.scale(resolutionScale);
+
+        auto imageData = ImageData::create(imageDataSize, array.releaseNonNull());
         if (!imageData) {
             fail();
             return JSValue();
         }
 
-        auto buffer = ImageBuffer::create(FloatSize(logicalWidth, logicalHeight), RenderingMode::Unaccelerated, resolutionScale);
+        auto buffer = ImageBuffer::create(FloatSize(logicalSize), RenderingMode::Unaccelerated, resolutionScale);
         if (!buffer) {
             fail();
             return JSValue();
         }
 
-        buffer->putByteArray(*imageData, AlphaPremultiplication::Premultiplied, IntSize(logicalWidth, logicalHeight), IntRect(0, 0, logicalWidth, logicalHeight), IntPoint());
+        buffer->putImageData(AlphaPremultiplication::Premultiplied, *imageData, { IntPoint::zero(), logicalSize });
 
         auto bitmap = ImageBitmap::create({ WTFMove(buffer), static_cast<bool>(originClean) });
         return getJSValue(bitmap);

Modified: trunk/Source/WebCore/html/canvas/CanvasRenderingContext2DBase.cpp (256821 => 256822)


--- trunk/Source/WebCore/html/canvas/CanvasRenderingContext2DBase.cpp	2020-02-18 07:38:10 UTC (rev 256821)
+++ trunk/Source/WebCore/html/canvas/CanvasRenderingContext2DBase.cpp	2020-02-18 09:31:31 UTC (rev 256822)
@@ -2159,11 +2159,6 @@
 
 ExceptionOr<RefPtr<ImageData>> CanvasRenderingContext2DBase::getImageData(float sx, float sy, float sw, float sh) const
 {
-    return getImageData(ImageBuffer::LogicalCoordinateSystem, sx, sy, sw, sh);
-}
-
-ExceptionOr<RefPtr<ImageData>> CanvasRenderingContext2DBase::getImageData(ImageBuffer::CoordinateSystem coordinateSystem, float sx, float sy, float sw, float sh) const
-{
     if (!canvasBase().originClean()) {
         static NeverDestroyed<String> consoleMessage(MAKE_STATIC_STRING_IMPL("Unable to get image data from canvas because the canvas has been tainted by cross-origin data."));
         canvasBase().scriptExecutionContext()->addConsoleMessage(MessageSource::Security, MessageLevel::Error, consoleMessage);
@@ -2196,8 +2191,8 @@
     if (!buffer)
         return createEmptyImageData(imageDataRect.size());
 
-    auto byteArray = buffer->getUnmultipliedImageData(imageDataRect, nullptr, coordinateSystem);
-    if (!byteArray) {
+    auto imageData = buffer->getImageData(AlphaPremultiplication::Unpremultiplied, imageDataRect);
+    if (!imageData) {
         StringBuilder consoleMessage;
         consoleMessage.appendLiteral("Unable to get image data from canvas. Requested size was ");
         consoleMessage.appendNumber(imageDataRect.width());
@@ -2208,7 +2203,7 @@
         return Exception { InvalidStateError };
     }
 
-    return ImageData::create(imageDataRect.size(), byteArray.releaseNonNull());
+    return imageData;
 }
 
 void CanvasRenderingContext2DBase::putImageData(ImageData& data, float dx, float dy)
@@ -2218,11 +2213,6 @@
 
 void CanvasRenderingContext2DBase::putImageData(ImageData& data, float dx, float dy, float dirtyX, float dirtyY, float dirtyWidth, float dirtyHeight)
 {
-    putImageData(data, ImageBuffer::LogicalCoordinateSystem, dx, dy, dirtyX, dirtyY, dirtyWidth, dirtyHeight);
-}
-
-void CanvasRenderingContext2DBase::putImageData(ImageData& data, ImageBuffer::CoordinateSystem coordinateSystem, float dx, float dy, float dirtyX, float dirtyY, float dirtyWidth, float dirtyHeight)
-{
     ImageBuffer* buffer = canvasBase().buffer();
     if (!buffer)
         return;
@@ -2245,7 +2235,7 @@
     IntSize destOffset(static_cast<int>(dx), static_cast<int>(dy));
     IntRect destRect = enclosingIntRect(clipRect);
     destRect.move(destOffset);
-    destRect.intersect(IntRect(IntPoint(), coordinateSystem == ImageBuffer::LogicalCoordinateSystem ? buffer->logicalSize() : buffer->internalSize()));
+    destRect.intersect(IntRect(IntPoint(), buffer->logicalSize()));
     if (destRect.isEmpty())
         return;
     IntRect sourceRect(destRect);
@@ -2253,7 +2243,7 @@
     sourceRect.intersect(IntRect(0, 0, data.width(), data.height()));
 
     if (!sourceRect.isEmpty())
-        buffer->putByteArray(*data.data(), AlphaPremultiplication::Unpremultiplied, IntSize(data.width(), data.height()), sourceRect, IntPoint(destOffset), coordinateSystem);
+        buffer->putImageData(AlphaPremultiplication::Unpremultiplied, data, sourceRect, IntPoint(destOffset));
 
     didDraw(destRect, CanvasDidDrawApplyNone); // ignore transform, shadow and clip
 }

Modified: trunk/Source/WebCore/html/canvas/CanvasRenderingContext2DBase.h (256821 => 256822)


--- trunk/Source/WebCore/html/canvas/CanvasRenderingContext2DBase.h	2020-02-18 07:38:10 UTC (rev 256821)
+++ trunk/Source/WebCore/html/canvas/CanvasRenderingContext2DBase.h	2020-02-18 09:31:31 UTC (rev 256822)
@@ -371,9 +371,6 @@
 
     template<class T> void fullCanvasCompositedDrawImage(T&, const FloatRect&, const FloatRect&, CompositeOperator);
 
-    ExceptionOr<RefPtr<ImageData>> getImageData(ImageBuffer::CoordinateSystem, float sx, float sy, float sw, float sh) const;
-    void putImageData(ImageData&, ImageBuffer::CoordinateSystem, float dx, float dy, float dirtyX, float dirtyY, float dirtyWidth, float dirtyHeight);
-
     bool isAccelerated() const override;
 
     bool hasInvertibleTransform() const override { return state().hasInvertibleTransform; }

Modified: trunk/Source/WebCore/page/PageConsoleClient.cpp (256821 => 256822)


--- trunk/Source/WebCore/page/PageConsoleClient.cpp	2020-02-18 07:38:10 UTC (rev 256821)
+++ trunk/Source/WebCore/page/PageConsoleClient.cpp	2020-02-18 09:31:31 UTC (rev 256822)
@@ -376,7 +376,7 @@
                 auto sourceSize = imageData->size();
                 if (auto imageBuffer = ImageBuffer::create(sourceSize, RenderingMode::Unaccelerated)) {
                     IntRect sourceRect(IntPoint(), sourceSize);
-                    imageBuffer->putByteArray(*imageData->data(), AlphaPremultiplication::Unpremultiplied, sourceSize, sourceRect, IntPoint());
+                    imageBuffer->putImageData(AlphaPremultiplication::Unpremultiplied, *imageData, sourceRect);
                     dataURL = imageBuffer->toDataURL("image/png"_s, WTF::nullopt, PreserveResolution::Yes);
                 }
             }

Modified: trunk/Source/WebCore/platform/graphics/ImageBuffer.cpp (256821 => 256822)


--- trunk/Source/WebCore/platform/graphics/ImageBuffer.cpp	2020-02-18 07:38:10 UTC (rev 256821)
+++ trunk/Source/WebCore/platform/graphics/ImageBuffer.cpp	2020-02-18 09:31:31 UTC (rev 256822)
@@ -28,8 +28,8 @@
 #include "config.h"
 #include "ImageBuffer.h"
 
-#include "ColorUtilities.h"
 #include "GraphicsContext.h"
+#include "ImageData.h"
 #include "IntRect.h"
 #include <wtf/IsoMallocInlines.h>
 #include <wtf/MathExtras.h>
@@ -113,51 +113,14 @@
 }
 #endif
 
-#if !(USE(CG) || USE(DIRECT2D))
-void ImageBuffer::transformColorSpace(ColorSpace srcColorSpace, ColorSpace dstColorSpace)
+void ImageBuffer::convertToLuminanceMask()
 {
-    if (srcColorSpace == dstColorSpace)
+    IntRect logicalRect = { IntPoint(), logicalSize() };
+    auto imageData = getImageData(AlphaPremultiplication::Unpremultiplied, logicalRect);
+    if (!imageData)
         return;
-
-    // only sRGB <-> linearRGB are supported at the moment
-    if ((srcColorSpace != ColorSpace::LinearRGB && srcColorSpace != ColorSpace::SRGB)
-        || (dstColorSpace != ColorSpace::LinearRGB && dstColorSpace != ColorSpace::SRGB))
-        return;
-
-    if (dstColorSpace == ColorSpace::LinearRGB) {
-        static const std::array<uint8_t, 256> linearRgbLUT = [] {
-            std::array<uint8_t, 256> array;
-            for (unsigned i = 0; i < 256; i++) {
-                float color = i / 255.0f;
-                color = sRGBToLinearColorComponent(color);
-                array[i] = static_cast<uint8_t>(round(color * 255));
-            }
-            return array;
-        }();
-        platformTransformColorSpace(linearRgbLUT);
-    } else if (dstColorSpace == ColorSpace::SRGB) {
-        static const std::array<uint8_t, 256> deviceRgbLUT= [] {
-            std::array<uint8_t, 256> array;
-            for (unsigned i = 0; i < 256; i++) {
-                float color = i / 255.0f;
-                color = linearToSRGBColorComponent(color);
-                array[i] = static_cast<uint8_t>(round(color * 255));
-            }
-            return array;
-        }();
-        platformTransformColorSpace(deviceRgbLUT);
-    }
-}
-
-#endif // USE(CG)
-
-inline void ImageBuffer::genericConvertToLuminanceMask()
-{
-    IntRect luminanceRect(IntPoint(), internalSize());
-    auto srcPixelArray = getUnmultipliedImageData(luminanceRect);
-    if (!srcPixelArray)
-        return;
     
+    auto* srcPixelArray = imageData->data();
     unsigned pixelArrayLength = srcPixelArray->length();
     for (unsigned pixelOffset = 0; pixelOffset < pixelArrayLength; pixelOffset += 4) {
         uint8_t a = srcPixelArray->item(pixelOffset + 3);
@@ -170,15 +133,9 @@
         double luma = (r * 0.2125 + g * 0.7154 + b * 0.0721) * ((double)a / 255.0);
         srcPixelArray->set(pixelOffset + 3, luma);
     }
-    putByteArray(*srcPixelArray, AlphaPremultiplication::Unpremultiplied, luminanceRect.size(), luminanceRect, IntPoint());
+    putImageData(AlphaPremultiplication::Unpremultiplied, *imageData, logicalRect);
 }
 
-void ImageBuffer::convertToLuminanceMask()
-{
-    // Add platform specific functions with platformConvertToLuminanceMask here later.
-    genericConvertToLuminanceMask();
-}
-
 #if !USE(CAIRO)
 PlatformLayer* ImageBuffer::platformLayer() const
 {

Modified: trunk/Source/WebCore/platform/graphics/ImageBuffer.h (256821 => 256822)


--- trunk/Source/WebCore/platform/graphics/ImageBuffer.h	2020-02-18 07:38:10 UTC (rev 256821)
+++ trunk/Source/WebCore/platform/graphics/ImageBuffer.h	2020-02-18 09:31:31 UTC (rev 256822)
@@ -37,7 +37,6 @@
 #include "IntSize.h"
 #include "PlatformLayer.h"
 #include "RenderingMode.h"
-#include <_javascript_Core/Uint8ClampedArray.h>
 #include <memory>
 #include <wtf/Forward.h>
 #include <wtf/IsoMalloc.h>
@@ -84,37 +83,48 @@
     static std::unique_ptr<ImageBuffer> createCompatibleBuffer(const FloatSize&, ColorSpace, const GraphicsContext&);
     static std::unique_ptr<ImageBuffer> createCompatibleBuffer(const FloatSize&, float resolutionScale, ColorSpace, const GraphicsContext&);
 
+    // These functions are used when clamping the ImageBuffer which is created for filter, masker or clipper.
+    static bool sizeNeedsClamping(const FloatSize&);
+    static bool sizeNeedsClamping(const FloatSize&, FloatSize& scale);
+    static FloatSize clampedSize(const FloatSize&);
+    static FloatSize clampedSize(const FloatSize&, FloatSize& scale);
+    static FloatRect clampedRect(const FloatRect&);
+
     static IntSize compatibleBufferSize(const FloatSize&, const GraphicsContext&);
-
+    
     WEBCORE_EXPORT ~ImageBuffer();
 
+    WEBCORE_EXPORT GraphicsContext& context() const;
+#if USE(CG) || USE(DIRECT2D)
+    void flushContext() const;
+#endif
+
     // The actual resolution of the backing store
     const IntSize& internalSize() const { return m_size; }
     const IntSize& logicalSize() const { return m_logicalSize; }
     float resolutionScale() const { return m_resolutionScale; }
+    
+    size_t memoryCost() const;
+    size_t externalMemoryCost() const;
 
-    WEBCORE_EXPORT GraphicsContext& context() const;
+#if USE(CG) || USE(DIRECT2D)
+    NativeImagePtr copyNativeImage(BackingStoreCopy = CopyBackingStore) const;
+#elif USE(CAIRO)
+    NativeImagePtr nativeImage() const;
+#endif
 
     WEBCORE_EXPORT RefPtr<Image> copyImage(BackingStoreCopy = CopyBackingStore, PreserveResolution = PreserveResolution::No) const;
-    WEBCORE_EXPORT static RefPtr<Image> sinkIntoImage(std::unique_ptr<ImageBuffer>, PreserveResolution = PreserveResolution::No);
-
-    enum CoordinateSystem { LogicalCoordinateSystem, BackingStoreCoordinateSystem };
-
-    RefPtr<Uint8ClampedArray> getUnmultipliedImageData(const IntRect&, IntSize* pixelArrayDimensions = nullptr, CoordinateSystem = LogicalCoordinateSystem) const;
-    RefPtr<Uint8ClampedArray> getPremultipliedImageData(const IntRect&, IntSize* pixelArrayDimensions = nullptr, CoordinateSystem = LogicalCoordinateSystem) const;
-
-    void putByteArray(const Uint8ClampedArray&, AlphaPremultiplication bufferFormat, const IntSize& sourceSize, const IntRect& sourceRect, const IntPoint& destPoint, CoordinateSystem = LogicalCoordinateSystem);
     
-    void convertToLuminanceMask();
+    void draw(GraphicsContext&, const FloatRect& destRect, const FloatRect& srcRect = FloatRect(0, 0, -1, -1), const ImagePaintingOptions& = { });
+    void drawPattern(GraphicsContext&, const FloatRect& destRect, const FloatRect& srcRect, const AffineTransform& patternTransform, const FloatPoint& phase, const FloatSize& spacing, const ImagePaintingOptions& = { });
 
-    String toDataURL(const String& mimeType, Optional<double> quality = WTF::nullopt, PreserveResolution = PreserveResolution::No) const;
-    Vector<uint8_t> toData(const String& mimeType, Optional<double> quality = WTF::nullopt) const;
-    Vector<uint8_t> toBGRAData() const;
-
-#if USE(CAIRO)
-    NativeImagePtr nativeImage() const;
+#if USE(CG) || USE(DIRECT2D)
+    static NativeImagePtr sinkIntoNativeImage(std::unique_ptr<ImageBuffer>);
 #endif
+    WEBCORE_EXPORT static RefPtr<Image> sinkIntoImage(std::unique_ptr<ImageBuffer>, PreserveResolution = PreserveResolution::No);
+    static void drawConsuming(std::unique_ptr<ImageBuffer>, GraphicsContext&, const FloatRect& destRect, const FloatRect& srcRect = FloatRect(0, 0, -1, -1), const ImagePaintingOptions& = { });
 
+    void convertToLuminanceMask();
 #if !USE(CG)
     AffineTransform baseTransform() const { return AffineTransform(); }
     void transformColorSpace(ColorSpace srcColorSpace, ColorSpace dstColorSpace);
@@ -122,51 +132,21 @@
 #else
     AffineTransform baseTransform() const { return AffineTransform(1, 0, 0, -1, 0, m_data.backingStoreSize.height()); }
 #endif
+
+    String toDataURL(const String& mimeType, Optional<double> quality = WTF::nullopt, PreserveResolution = PreserveResolution::No) const;
+    Vector<uint8_t> toData(const String& mimeType, Optional<double> quality = WTF::nullopt) const;
+    Vector<uint8_t> toBGRAData() const;
+
+    RefPtr<ImageData> getImageData(AlphaPremultiplication outputFormat, const IntRect& srcRect) const;
+    void putImageData(AlphaPremultiplication inputFormat, const ImageData&, const IntRect& srcRect, const IntPoint& destPoint = { });
+    
     PlatformLayer* platformLayer() const;
 
-    size_t memoryCost() const;
-    size_t externalMemoryCost() const;
-
     // FIXME: current implementations of this method have the restriction that they only work
     // with textures that are RGB or RGBA format, and UNSIGNED_BYTE type.
     bool copyToPlatformTexture(GraphicsContextGLOpenGL&, GCGLenum, PlatformGLObject, GCGLenum, bool, bool);
 
-    // These functions are used when clamping the ImageBuffer which is created for filter, masker or clipper.
-    static bool sizeNeedsClamping(const FloatSize&);
-    static bool sizeNeedsClamping(const FloatSize&, FloatSize& scale);
-    static FloatSize clampedSize(const FloatSize&);
-    static FloatSize clampedSize(const FloatSize&, FloatSize& scale);
-    static FloatRect clampedRect(const FloatRect&);
-
 private:
-#if USE(CG)
-    // The returned image might be larger than the internalSize(). If you want the smaller
-    // image, crop the result.
-    RetainPtr<CGImageRef> copyNativeImage(BackingStoreCopy = CopyBackingStore) const;
-    static RetainPtr<CGImageRef> sinkIntoNativeImage(std::unique_ptr<ImageBuffer>);
-    void flushContext() const;
-#elif USE(DIRECT2D)
-    COMPtr<ID2D1Bitmap> copyNativeImage(BackingStoreCopy = CopyBackingStore) const;
-    static COMPtr<ID2D1Bitmap> sinkIntoNativeImage(std::unique_ptr<ImageBuffer>);
-    void flushContext() const;
-#endif
-    
-    void draw(GraphicsContext&, const FloatRect& destRect, const FloatRect& srcRect = FloatRect(0, 0, -1, -1), const ImagePaintingOptions& = { });
-    void drawPattern(GraphicsContext&, const FloatRect& destRect, const FloatRect& srcRect, const AffineTransform& patternTransform, const FloatPoint& phase, const FloatSize& spacing, const ImagePaintingOptions& = { });
-
-    static void drawConsuming(std::unique_ptr<ImageBuffer>, GraphicsContext&, const FloatRect& destRect, const FloatRect& srcRect = FloatRect(0, 0, -1, -1), const ImagePaintingOptions& = { });
-
-    inline void genericConvertToLuminanceMask();
-
-    friend class GraphicsContext;
-    friend class GeneratedImage;
-    friend class CrossfadeGeneratedImage;
-    friend class NamedImageGeneratedImage;
-    friend class GradientImage;
-    friend class CustomPaintImage;
-    friend class BitmapImage;
-
-private:
     ImageBufferData m_data;
     IntSize m_size;
     IntSize m_logicalSize;

Modified: trunk/Source/WebCore/platform/graphics/ShadowBlur.cpp (256821 => 256822)


--- trunk/Source/WebCore/platform/graphics/ShadowBlur.cpp	2020-02-18 07:38:10 UTC (rev 256821)
+++ trunk/Source/WebCore/platform/graphics/ShadowBlur.cpp	2020-02-18 09:31:31 UTC (rev 256822)
@@ -34,6 +34,7 @@
 #include "FloatQuad.h"
 #include "GraphicsContext.h"
 #include "ImageBuffer.h"
+#include "ImageData.h"
 #include "Timer.h"
 #include <wtf/MathExtras.h>
 #include <wtf/NeverDestroyed.h>
@@ -884,12 +885,13 @@
         return;
 
     IntRect blurRect(IntPoint(), templateSize);
-    auto layerData = layerImage.getUnmultipliedImageData(blurRect);
+    auto layerData = layerImage.getImageData(AlphaPremultiplication::Unpremultiplied, blurRect);
     if (!layerData)
         return;
 
-    blurLayerImage(layerData->data(), blurRect.size(), blurRect.width() * 4);
-    layerImage.putByteArray(*layerData, AlphaPremultiplication::Unpremultiplied, blurRect.size(), blurRect, { });
+    auto* blurPixelArray = layerData->data();
+    blurLayerImage(blurPixelArray->data(), blurRect.size(), blurRect.width() * 4);
+    layerImage.putImageData(AlphaPremultiplication::Unpremultiplied, *layerData, blurRect);
 }
 
 void ShadowBlur::blurAndColorShadowBuffer(ImageBuffer& layerImage, const IntSize& templateSize)

Modified: trunk/Source/WebCore/platform/graphics/cairo/ImageBufferCairo.cpp (256821 => 256822)


--- trunk/Source/WebCore/platform/graphics/cairo/ImageBufferCairo.cpp	2020-02-18 07:38:10 UTC (rev 256821)
+++ trunk/Source/WebCore/platform/graphics/cairo/ImageBufferCairo.cpp	2020-02-18 09:31:31 UTC (rev 256822)
@@ -35,9 +35,11 @@
 #include "CairoOperations.h"
 #include "CairoUtilities.h"
 #include "Color.h"
+#include "ColorUtilities.h"
 #include "GraphicsContext.h"
 #include "GraphicsContextImplCairo.h"
 #include "ImageBufferUtilitiesCairo.h"
+#include "ImageData.h"
 #include "IntRect.h"
 #include "MIMETypeRegistry.h"
 #include "NotImplemented.h"
@@ -382,6 +384,41 @@
         Cairo::drawPattern(*context.platformContext(), surface.get(), m_size, destRect, srcRect, patternTransform, phase, options);
 }
 
+void ImageBuffer::transformColorSpace(ColorSpace srcColorSpace, ColorSpace dstColorSpace)
+{
+    if (srcColorSpace == dstColorSpace)
+        return;
+
+    // only sRGB <-> linearRGB are supported at the moment
+    if ((srcColorSpace != ColorSpace::LinearRGB && srcColorSpace != ColorSpace::SRGB)
+        || (dstColorSpace != ColorSpace::LinearRGB && dstColorSpace != ColorSpace::SRGB))
+        return;
+
+    if (dstColorSpace == ColorSpace::LinearRGB) {
+        static const std::array<uint8_t, 256> linearRgbLUT = [] {
+            std::array<uint8_t, 256> array;
+            for (unsigned i = 0; i < 256; i++) {
+                float color = i / 255.0f;
+                color = sRGBToLinearColorComponent(color);
+                array[i] = static_cast<uint8_t>(round(color * 255));
+            }
+            return array;
+        }();
+        platformTransformColorSpace(linearRgbLUT);
+    } else if (dstColorSpace == ColorSpace::SRGB) {
+        static const std::array<uint8_t, 256> deviceRgbLUT= [] {
+            std::array<uint8_t, 256> array;
+            for (unsigned i = 0; i < 256; i++) {
+                float color = i / 255.0f;
+                color = linearToSRGBColorComponent(color);
+                array[i] = static_cast<uint8_t>(round(color * 255));
+            }
+            return array;
+        }();
+        platformTransformColorSpace(deviceRgbLUT);
+    }
+}
+
 void ImageBuffer::platformTransformColorSpace(const std::array<uint8_t, 256>& lookUpTable)
 {
     // FIXME: Enable color space conversions on accelerated canvases.
@@ -420,16 +457,10 @@
 }
 
 template <AlphaPremultiplication premultiplied>
-RefPtr<Uint8ClampedArray> getImageData(const IntRect& rect, const IntRect& logicalRect, const ImageBufferData& data, const IntSize& size, const IntSize& logicalSize, float resolutionScale)
+RefPtr<ImageData> getData(const IntRect& rect, const IntRect& logicalRect, const ImageBufferData& data, const IntSize& size, const IntSize& logicalSize, float resolutionScale)
 {
-    // The area can overflow if the rect is too big.
-    Checked<unsigned, RecordOverflow> area = 4;
-    area *= rect.width();
-    area *= rect.height();
-    if (area.hasOverflowed())
-        return nullptr;
-
-    auto result = Uint8ClampedArray::tryCreateUninitialized(area.unsafeGet());
+    auto result = ImageData::create(rect.size());
+    auto* pixelArray = result ? result->data() : nullptr;
     if (!result)
         return nullptr;
 
@@ -444,7 +475,7 @@
         return nullptr;
 
     if (rect.x() < 0 || rect.y() < 0 || endx > size.width() || endy > size.height())
-        result->zeroFill();
+        pixelArray->zeroFill();
 
     int originx = rect.x();
     int destx = 0;
@@ -486,7 +517,7 @@
     }
 
     unsigned char* dataSrc = ""
-    unsigned char* dataDst = result->data();
+    unsigned char* dataDst = pixelArray->data();
     int stride = cairo_image_surface_get_stride(imageSurface.get());
     unsigned destBytesPerRow = 4 * rect.width();
 
@@ -523,52 +554,29 @@
     return result;
 }
 
-template<typename Unit>
-inline Unit logicalUnit(const Unit& value, ImageBuffer::CoordinateSystem coordinateSystemOfValue, float resolutionScale)
+RefPtr<ImageData> ImageBuffer::getImageData(AlphaPremultiplication outputFormat, const IntRect& srcRect) const
 {
-    if (coordinateSystemOfValue == ImageBuffer::LogicalCoordinateSystem || resolutionScale == 1.0)
-        return value;
-    Unit result(value);
-    result.scale(1.0 / resolutionScale);
-    return result;
+    IntRect logicalRect = srcRect;
+    IntRect backingStoreRect = srcRect;
+    backingStoreRect.scale(m_resolutionScale);
+    
+    if (outputFormat == AlphaPremultiplication::Unpremultiplied)
+        return getData<AlphaPremultiplication::Unpremultiplied>(backingStoreRect, logicalRect, m_data, m_size, m_logicalSize, m_resolutionScale);
+    return getData<AlphaPremultiplication::Premultiplied>(backingStoreRect, logicalRect, m_data, m_size, m_logicalSize, m_resolutionScale);
 }
 
-template<typename Unit>
-inline Unit backingStoreUnit(const Unit& value, ImageBuffer::CoordinateSystem coordinateSystemOfValue, float resolutionScale)
+void ImageBuffer::putImageData(AlphaPremultiplication sourceFormat, const ImageData& imageData, const IntRect& sourceRect, const IntPoint& destPoint)
 {
-    if (coordinateSystemOfValue == ImageBuffer::BackingStoreCoordinateSystem || resolutionScale == 1.0)
-        return value;
-    Unit result(value);
-    result.scale(resolutionScale);
-    return result;
-}
+    IntRect logicalSourceRect = sourceRect;
+    IntPoint logicalDestPoint = destPoint;
 
-RefPtr<Uint8ClampedArray> ImageBuffer::getUnmultipliedImageData(const IntRect& rect, IntSize* pixelArrayDimensions, CoordinateSystem coordinateSystem) const
-{
-    IntRect logicalRect = logicalUnit(rect, coordinateSystem, m_resolutionScale);
-    IntRect backingStoreRect = backingStoreUnit(rect, coordinateSystem, m_resolutionScale);
-    if (pixelArrayDimensions)
-        *pixelArrayDimensions = backingStoreRect.size();
-    return getImageData<AlphaPremultiplication::Unpremultiplied>(backingStoreRect, logicalRect, m_data, m_size, m_logicalSize, m_resolutionScale);
-}
+    IntRect scaledSourceRect = sourceRect;
+    IntSize scaledSourceSize = imageData.size();
+    IntPoint scaledDestPoint = destPoint;
 
-RefPtr<Uint8ClampedArray> ImageBuffer::getPremultipliedImageData(const IntRect& rect, IntSize* pixelArrayDimensions, CoordinateSystem coordinateSystem) const
-{
-    IntRect logicalRect = logicalUnit(rect, coordinateSystem, m_resolutionScale);
-    IntRect backingStoreRect = backingStoreUnit(rect, coordinateSystem, m_resolutionScale);
-    if (pixelArrayDimensions)
-        *pixelArrayDimensions = backingStoreRect.size();
-    return getImageData<AlphaPremultiplication::Premultiplied>(backingStoreRect, logicalRect, m_data, m_size, m_logicalSize, m_resolutionScale);
-}
+    scaledSourceRect.scale(m_resolutionScale);
+    scaledDestPoint.scale(m_resolutionScale);
 
-void ImageBuffer::putByteArray(const Uint8ClampedArray& source, AlphaPremultiplication sourceFormat, const IntSize& sourceSize, const IntRect& sourceRect, const IntPoint& destPoint, CoordinateSystem coordinateSystem)
-{
-    IntRect scaledSourceRect = backingStoreUnit(sourceRect, coordinateSystem, m_resolutionScale);
-    IntSize scaledSourceSize = backingStoreUnit(sourceSize, coordinateSystem, m_resolutionScale);
-    IntPoint scaledDestPoint = backingStoreUnit(destPoint, coordinateSystem, m_resolutionScale);
-    IntRect logicalSourceRect = logicalUnit(sourceRect, coordinateSystem, m_resolutionScale);
-    IntPoint logicalDestPoint = logicalUnit(destPoint, coordinateSystem, m_resolutionScale);
-
     ASSERT(scaledSourceRect.width() > 0);
     ASSERT(scaledSourceRect.height() > 0);
 
@@ -614,7 +622,7 @@
     unsigned srcBytesPerRow = 4 * scaledSourceSize.width();
     int stride = cairo_image_surface_get_stride(imageSurface.get());
 
-    const uint8_t* srcRows = source.data() + originy * srcBytesPerRow + originx * 4;
+    const uint8_t* srcRows = imageData.data()->data() + originy * srcBytesPerRow + originx * 4;
     for (int y = 0; y < numRows; ++y) {
         unsigned* row = reinterpret_cast_ptr<unsigned*>(pixelData + stride * (y + desty));
         for (int x = 0; x < numColumns; x++) {

Modified: trunk/Source/WebCore/platform/graphics/cg/ImageBufferCG.cpp (256821 => 256822)


--- trunk/Source/WebCore/platform/graphics/cg/ImageBufferCG.cpp	2020-02-18 07:38:10 UTC (rev 256821)
+++ trunk/Source/WebCore/platform/graphics/cg/ImageBufferCG.cpp	2020-02-18 09:31:31 UTC (rev 256822)
@@ -377,49 +377,28 @@
     }
 }
 
-RefPtr<Uint8ClampedArray> ImageBuffer::getUnmultipliedImageData(const IntRect& rect, IntSize* pixelArrayDimensions, CoordinateSystem coordinateSystem) const
+RefPtr<ImageData> ImageBuffer::getImageData(AlphaPremultiplication outputFormat, const IntRect& srcRect) const
 {
     if (context().isAcceleratedContext())
         flushContext();
 
-    IntRect srcRect = rect;
-    if (coordinateSystem == LogicalCoordinateSystem)
-        srcRect.scale(m_resolutionScale);
+    IntRect scaledSrcRect = srcRect;
+    scaledSrcRect.scale(m_resolutionScale);
 
-    if (pixelArrayDimensions)
-        *pixelArrayDimensions = srcRect.size();
-
-    return m_data.getData(AlphaPremultiplication::Unpremultiplied, srcRect, internalSize(), context().isAcceleratedContext());
+    return m_data.getData(outputFormat, scaledSrcRect, internalSize(), context().isAcceleratedContext());
 }
 
-RefPtr<Uint8ClampedArray> ImageBuffer::getPremultipliedImageData(const IntRect& rect, IntSize* pixelArrayDimensions, CoordinateSystem coordinateSystem) const
+void ImageBuffer::putImageData(AlphaPremultiplication inputFormat, const ImageData& imageData, const IntRect& srcRect, const IntPoint& destPoint)
 {
     if (context().isAcceleratedContext())
         flushContext();
 
-    IntRect srcRect = rect;
-    if (coordinateSystem == LogicalCoordinateSystem)
-        srcRect.scale(m_resolutionScale);
+    IntRect scaledSrcRect = srcRect;
+    IntPoint scaledDestPoint = destPoint;
+    scaledSrcRect.scale(m_resolutionScale);
+    scaledDestPoint.scale(m_resolutionScale);
 
-    if (pixelArrayDimensions)
-        *pixelArrayDimensions = srcRect.size();
-
-    return m_data.getData(AlphaPremultiplication::Premultiplied, srcRect, internalSize(), context().isAcceleratedContext());
-}
-
-void ImageBuffer::putByteArray(const Uint8ClampedArray& source, AlphaPremultiplication sourceFormat, const IntSize& sourceSize, const IntRect& sourceRect, const IntPoint& destPoint, CoordinateSystem coordinateSystem)
-{
-    if (context().isAcceleratedContext())
-        flushContext();
-
-    IntRect scaledSourceRect = sourceRect;
-    IntSize scaledSourceSize = sourceSize;
-    if (coordinateSystem == LogicalCoordinateSystem) {
-        scaledSourceRect.scale(m_resolutionScale);
-        scaledSourceSize.scale(m_resolutionScale);
-    }
-
-    m_data.putData(source, sourceFormat, scaledSourceSize, scaledSourceRect, destPoint, internalSize(), context().isAcceleratedContext());
+    m_data.putData(inputFormat, imageData, scaledSrcRect, scaledDestPoint, internalSize(), context().isAcceleratedContext());
     
     // Force recreating the IOSurface cached image if it is requested through CGIOSurfaceContextCreateImage().
     // See https://bugs.webkit.org/show_bug.cgi?id=157966 for explaining why this is necessary.
@@ -452,17 +431,19 @@
     ASSERT(uti);
 
     RetainPtr<CGImageRef> image;
-    RefPtr<Uint8ClampedArray> premultipliedData;
+    RefPtr<Uint8ClampedArray> protectedPixelArray;
 
     if (CFEqual(uti.get(), jpegUTI())) {
         // JPEGs don't have an alpha channel, so we have to manually composite on top of black.
-        premultipliedData = getPremultipliedImageData(IntRect(IntPoint(), logicalSize()));
-        if (!premultipliedData)
+        auto imageData = getImageData(AlphaPremultiplication::Premultiplied, { IntPoint(), logicalSize() });
+        if (!imageData)
             return nullptr;
 
         size_t dataSize = 4 * logicalSize().width() * logicalSize().height();
-        verifyImageBufferIsBigEnough(premultipliedData->data(), dataSize);
-        auto dataProvider = adoptCF(CGDataProviderCreateWithData(nullptr, premultipliedData->data(), dataSize, nullptr));
+        protectedPixelArray = makeRefPtr(imageData->data());
+        verifyImageBufferIsBigEnough(protectedPixelArray->data(), dataSize);
+
+        auto dataProvider = adoptCF(CGDataProviderCreateWithData(nullptr, protectedPixelArray->data(), dataSize, nullptr));
         if (!dataProvider)
             return nullptr;
 

Modified: trunk/Source/WebCore/platform/graphics/cg/ImageBufferDataCG.cpp (256821 => 256822)


--- trunk/Source/WebCore/platform/graphics/cg/ImageBufferDataCG.cpp	2020-02-18 07:38:10 UTC (rev 256821)
+++ trunk/Source/WebCore/platform/graphics/cg/ImageBufferDataCG.cpp	2020-02-18 09:31:31 UTC (rev 256822)
@@ -29,6 +29,7 @@
 #if USE(CG)
 
 #include "GraphicsContext.h"
+#include "ImageData.h"
 #include "IntRect.h"
 #include <CoreGraphics/CoreGraphics.h>
 #include <_javascript_Core/JSCInlines.h>
@@ -125,23 +126,17 @@
     return result;
 }
 
-RefPtr<Uint8ClampedArray> ImageBufferData::getData(AlphaPremultiplication outputFormat, const IntRect& rect, const IntSize& size, bool accelerateRendering) const
+RefPtr<ImageData> ImageBufferData::getData(AlphaPremultiplication outputFormat, const IntRect& rect, const IntSize& size, bool accelerateRendering) const
 {
-    Checked<unsigned, RecordOverflow> area = 4;
-    area *= rect.width();
-    area *= rect.height();
-    if (area.hasOverflowed())
+    auto result = ImageData::create(rect.size());
+    auto* pixelArray = result ? result->data() : nullptr;
+    if (!pixelArray)
         return nullptr;
 
-    auto result = Uint8ClampedArray::tryCreateUninitialized(area.unsafeGet());
-    uint8_t* resultData = result ? result->data() : nullptr;
-    if (!resultData)
-        return nullptr;
-
     Checked<int> endx = rect.maxX();
     Checked<int> endy = rect.maxY();
     if (rect.x() < 0 || rect.y() < 0 || endx.unsafeGet() > size.width() || endy.unsafeGet() > size.height())
-        result->zeroFill();
+        pixelArray->zeroFill();
     
     int originx = rect.x();
     int destx = 0;
@@ -173,7 +168,7 @@
         return result;
     
     unsigned destBytesPerRow = 4 * rect.width();
-    uint8_t* destRows = resultData + desty * destBytesPerRow + destx * 4;
+    uint8_t* destRows = pixelArray->data() + desty * destBytesPerRow + destx * 4;
     
     unsigned srcBytesPerRow;
     uint8_t* srcRows;
@@ -334,7 +329,7 @@
     return result;
 }
 
-void ImageBufferData::putData(const Uint8ClampedArray& source, AlphaPremultiplication sourceFormat, const IntSize& sourceSize, const IntRect& sourceRect, const IntPoint& destPoint, const IntSize& size, bool accelerateRendering)
+void ImageBufferData::putData(AlphaPremultiplication sourceFormat, const ImageData& imageData, const IntRect& sourceRect, const IntPoint& destPoint, const IntSize& size, bool accelerateRendering)
 {
     ASSERT(sourceRect.width() > 0);
     ASSERT(sourceRect.height() > 0);
@@ -368,8 +363,8 @@
     if (width <= 0 || height <= 0)
         return;
     
-    unsigned srcBytesPerRow = 4 * sourceSize.width();
-    const uint8_t* srcRows = source.data() + (originy * srcBytesPerRow + originx * 4).unsafeGet();
+    unsigned srcBytesPerRow = 4 * imageData.size().width();
+    const uint8_t* srcRows = imageData.data()->data() + (originy * srcBytesPerRow + originx * 4).unsafeGet();
     unsigned destBytesPerRow;
     uint8_t* destRows;
     

Modified: trunk/Source/WebCore/platform/graphics/cg/ImageBufferDataCG.h (256821 => 256822)


--- trunk/Source/WebCore/platform/graphics/cg/ImageBufferDataCG.h	2020-02-18 07:38:10 UTC (rev 256821)
+++ trunk/Source/WebCore/platform/graphics/cg/ImageBufferDataCG.h	2020-02-18 09:31:31 UTC (rev 256822)
@@ -40,6 +40,7 @@
 
 namespace WebCore {
 
+class ImageData;
 class IOSurface;
 
 struct ImageBufferData {
@@ -59,8 +60,8 @@
 #endif
 
     Vector<uint8_t> toBGRAData(bool accelerateRendering, int width, int height) const;
-    RefPtr<Uint8ClampedArray> getData(AlphaPremultiplication, const IntRect&, const IntSize&, bool accelerateRendering) const;
-    void putData(const Uint8ClampedArray& source, AlphaPremultiplication sourceFormat, const IntSize& sourceSize, const IntRect& sourceRect, const IntPoint& destPoint, const IntSize&, bool accelerateRendering);
+    RefPtr<ImageData> getData(AlphaPremultiplication outputFormat, const IntRect&, const IntSize&, bool accelerateRendering) const;
+    void putData(AlphaPremultiplication inputFormat, const ImageData&, const IntRect& sourceRect, const IntPoint& destPoint, const IntSize&, bool accelerateRendering);
 };
 
 } // namespace WebCore

Modified: trunk/Source/WebCore/platform/graphics/cpu/arm/filters/FEBlendNEON.h (256821 => 256822)


--- trunk/Source/WebCore/platform/graphics/cpu/arm/filters/FEBlendNEON.h	2020-02-18 07:38:10 UTC (rev 256821)
+++ trunk/Source/WebCore/platform/graphics/cpu/arm/filters/FEBlendNEON.h	2020-02-18 09:31:31 UTC (rev 256822)
@@ -111,7 +111,8 @@
     FilterEffect* in = inputEffect(0);
     FilterEffect* in2 = inputEffect(1);
 
-    Uint8ClampedArray* dstPixelArray = createPremultipliedImageResult();
+    auto* imageResult = createPremultipliedImageResult();
+    auto* dstPixelArray = imageResult ? imageResult->data() : nullptr;
     if (!dstPixelArray)
         return;
 

Modified: trunk/Source/WebCore/platform/graphics/filters/FEColorMatrix.cpp (256821 => 256822)


--- trunk/Source/WebCore/platform/graphics/filters/FEColorMatrix.cpp	2020-02-18 07:38:10 UTC (rev 256821)
+++ trunk/Source/WebCore/platform/graphics/filters/FEColorMatrix.cpp	2020-02-18 09:31:31 UTC (rev 256822)
@@ -25,7 +25,7 @@
 
 #include "Filter.h"
 #include "GraphicsContext.h"
-#include <_javascript_Core/Uint8ClampedArray.h>
+#include "ImageData.h"
 #include <wtf/MathExtras.h>
 #include <wtf/text/TextStream.h>
 
@@ -286,13 +286,15 @@
         resultImage->context().drawImageBuffer(*inBuffer, drawingRegionOfInputImage(in->absolutePaintRect()));
 
     IntRect imageRect(IntPoint(), resultImage->logicalSize());
-    IntSize pixelArrayDimensions;
-    auto pixelArray = resultImage->getUnmultipliedImageData(imageRect, &pixelArrayDimensions);
-    if (!pixelArray)
+    auto imageData = resultImage->getImageData(AlphaPremultiplication::Unpremultiplied, imageRect);
+    if (!imageData)
         return;
 
+    auto* pixelArray = imageData->data();
+    IntSize pixelArrayDimensions = imageData->size();
+
     Vector<float> values = normalizedFloats(m_values);
-
+    
     switch (m_type) {
     case FECOLORMATRIX_TYPE_UNKNOWN:
         break;
@@ -311,7 +313,7 @@
         break;
     }
 
-    resultImage->putByteArray(*pixelArray, AlphaPremultiplication::Unpremultiplied, imageRect.size(), imageRect, IntPoint());
+    resultImage->putImageData(AlphaPremultiplication::Unpremultiplied, *imageData, imageRect);
 }
 
 static TextStream& operator<<(TextStream& ts, const ColorMatrixType& type)

Modified: trunk/Source/WebCore/platform/graphics/filters/FEComponentTransfer.cpp (256821 => 256822)


--- trunk/Source/WebCore/platform/graphics/filters/FEComponentTransfer.cpp	2020-02-18 07:38:10 UTC (rev 256821)
+++ trunk/Source/WebCore/platform/graphics/filters/FEComponentTransfer.cpp	2020-02-18 09:31:31 UTC (rev 256822)
@@ -26,7 +26,7 @@
 
 #include "Filter.h"
 #include "GraphicsContext.h"
-#include <_javascript_Core/Uint8ClampedArray.h>
+#include "ImageData.h"
 #include <wtf/MathExtras.h>
 #include <wtf/StdLibExtras.h>
 #include <wtf/text/TextStream.h>
@@ -108,7 +108,8 @@
 {
     FilterEffect* in = inputEffect(0);
 
-    Uint8ClampedArray* pixelArray = createUnmultipliedImageResult();
+    auto* imageResult = createUnmultipliedImageResult();
+    auto* pixelArray = imageResult ? imageResult->data() : nullptr;
     if (!pixelArray)
         return;
 

Modified: trunk/Source/WebCore/platform/graphics/filters/FEComposite.cpp (256821 => 256822)


--- trunk/Source/WebCore/platform/graphics/filters/FEComposite.cpp	2020-02-18 07:38:10 UTC (rev 256821)
+++ trunk/Source/WebCore/platform/graphics/filters/FEComposite.cpp	2020-02-18 09:31:31 UTC (rev 256822)
@@ -27,7 +27,7 @@
 #include "FECompositeArithmeticNEON.h"
 #include "Filter.h"
 #include "GraphicsContext.h"
-#include <_javascript_Core/Uint8ClampedArray.h>
+#include "ImageData.h"
 #include <wtf/text/TextStream.h>
 
 namespace WebCore {
@@ -229,7 +229,8 @@
     FilterEffect* in2 = inputEffect(1);
 
     if (m_type == FECOMPOSITE_OPERATOR_ARITHMETIC) {
-        Uint8ClampedArray* dstPixelArray = createPremultipliedImageResult();
+        auto* resultImage = createPremultipliedImageResult();
+        auto* dstPixelArray = resultImage ? resultImage->data() : nullptr;
         if (!dstPixelArray)
             return;
 

Modified: trunk/Source/WebCore/platform/graphics/filters/FEConvolveMatrix.cpp (256821 => 256822)


--- trunk/Source/WebCore/platform/graphics/filters/FEConvolveMatrix.cpp	2020-02-18 07:38:10 UTC (rev 256821)
+++ trunk/Source/WebCore/platform/graphics/filters/FEConvolveMatrix.cpp	2020-02-18 09:31:31 UTC (rev 256822)
@@ -25,7 +25,7 @@
 #include "FEConvolveMatrix.h"
 
 #include "Filter.h"
-#include <_javascript_Core/Uint8ClampedArray.h>
+#include "ImageData.h"
 #include <wtf/ParallelJobs.h>
 #include <wtf/WorkQueue.h>
 #include <wtf/text/TextStream.h>
@@ -371,12 +371,13 @@
 {
     FilterEffect* in = inputEffect(0);
 
-    Uint8ClampedArray* resultImage;
+    ImageData* resultImage;
     if (m_preserveAlpha)
         resultImage = createUnmultipliedImageResult();
     else
         resultImage = createPremultipliedImageResult();
-    if (!resultImage)
+    auto* dstPixelArray = resultImage ? resultImage->data() : nullptr;
+    if (!dstPixelArray)
         return;
 
     IntRect effectDrawingRect = requestedRegionOfInputImageData(in->absolutePaintRect());
@@ -395,7 +396,7 @@
 
     PaintingData paintingData = {
         *srcPixelArray,
-        *resultImage,
+        *dstPixelArray,
         paintSize.width(),
         paintSize.height(),
         m_bias * 255,

Modified: trunk/Source/WebCore/platform/graphics/filters/FEDisplacementMap.cpp (256821 => 256822)


--- trunk/Source/WebCore/platform/graphics/filters/FEDisplacementMap.cpp	2020-02-18 07:38:10 UTC (rev 256821)
+++ trunk/Source/WebCore/platform/graphics/filters/FEDisplacementMap.cpp	2020-02-18 09:31:31 UTC (rev 256822)
@@ -27,7 +27,7 @@
 #include "ColorUtilities.h"
 #include "Filter.h"
 #include "GraphicsContext.h"
-#include <_javascript_Core/Uint8ClampedArray.h>
+#include "ImageData.h"
 #include <wtf/text/TextStream.h>
 
 namespace WebCore {
@@ -94,7 +94,8 @@
     ASSERT(m_xChannelSelector != CHANNEL_UNKNOWN);
     ASSERT(m_yChannelSelector != CHANNEL_UNKNOWN);
 
-    Uint8ClampedArray* dstPixelArray = createPremultipliedImageResult();
+    auto* resultImage = createPremultipliedImageResult();
+    auto* dstPixelArray = resultImage ? resultImage->data() : nullptr;
     if (!dstPixelArray)
         return;
 

Modified: trunk/Source/WebCore/platform/graphics/filters/FEDropShadow.cpp (256821 => 256822)


--- trunk/Source/WebCore/platform/graphics/filters/FEDropShadow.cpp	2020-02-18 07:38:10 UTC (rev 256821)
+++ trunk/Source/WebCore/platform/graphics/filters/FEDropShadow.cpp	2020-02-18 09:31:31 UTC (rev 256822)
@@ -23,8 +23,8 @@
 #include "FEGaussianBlur.h"
 #include "Filter.h"
 #include "GraphicsContext.h"
+#include "ImageData.h"
 #include "ShadowBlur.h"
-#include <_javascript_Core/Uint8ClampedArray.h>
 #include <wtf/MathExtras.h>
 #include <wtf/text/TextStream.h>
 
@@ -99,15 +99,16 @@
     ShadowBlur contextShadow(blurRadius, offset, m_shadowColor);
 
     // TODO: Direct pixel access to ImageBuffer would avoid copying the ImageData.
-    IntRect shadowArea(IntPoint(), resultImage->internalSize());
-    auto srcPixelArray = resultImage->getPremultipliedImageData(shadowArea, nullptr, ImageBuffer::BackingStoreCoordinateSystem);
-    if (!srcPixelArray)
+    IntRect shadowArea(IntPoint(), resultImage->logicalSize());
+    auto imageData = resultImage->getImageData(AlphaPremultiplication::Premultiplied, shadowArea);
+    if (!imageData)
         return;
 
-    contextShadow.blurLayerImage(srcPixelArray->data(), shadowArea.size(), 4 * shadowArea.size().width());
+    auto* srcPixelArray = imageData->data();
+    contextShadow.blurLayerImage(srcPixelArray->data(), imageData->size(), 4 * imageData->size().width());
+    
+    resultImage->putImageData(AlphaPremultiplication::Premultiplied, *imageData, shadowArea);
 
-    resultImage->putByteArray(*srcPixelArray, AlphaPremultiplication::Premultiplied, shadowArea.size(), shadowArea, IntPoint(), ImageBuffer::BackingStoreCoordinateSystem);
-
     resultContext.setCompositeOperation(CompositeOperator::SourceIn);
     resultContext.fillRect(FloatRect(FloatPoint(), absolutePaintRect().size()), m_shadowColor);
     resultContext.setCompositeOperation(CompositeOperator::DestinationOver);

Modified: trunk/Source/WebCore/platform/graphics/filters/FEGaussianBlur.cpp (256821 => 256822)


--- trunk/Source/WebCore/platform/graphics/filters/FEGaussianBlur.cpp	2020-02-18 07:38:10 UTC (rev 256821)
+++ trunk/Source/WebCore/platform/graphics/filters/FEGaussianBlur.cpp	2020-02-18 09:31:31 UTC (rev 256822)
@@ -29,6 +29,7 @@
 #include "FEGaussianBlurNEON.h"
 #include "Filter.h"
 #include "GraphicsContext.h"
+#include "ImageData.h"
 #include <wtf/text/TextStream.h>
 
 #if USE(ACCELERATE)
@@ -522,14 +523,15 @@
 {
     FilterEffect* in = inputEffect(0);
 
-    Uint8ClampedArray* resultPixelArray = createPremultipliedImageResult();
-    if (!resultPixelArray)
+    auto* resultImage = createPremultipliedImageResult();
+    auto* dstPixelArray = resultImage ? resultImage->data() : nullptr;
+    if (!dstPixelArray)
         return;
 
     setIsAlphaImage(in->isAlphaImage());
 
     IntRect effectDrawingRect = requestedRegionOfInputImageData(in->absolutePaintRect());
-    in->copyPremultipliedResult(*resultPixelArray, effectDrawingRect);
+    in->copyPremultipliedResult(*dstPixelArray, effectDrawingRect);
 
     if (!m_stdX && !m_stdY)
         return;
@@ -543,7 +545,7 @@
     if (!tmpImageData)
         return;
 
-    platformApply(*resultPixelArray, *tmpImageData, kernelSize.width(), kernelSize.height(), paintSize);
+    platformApply(*dstPixelArray, *tmpImageData, kernelSize.width(), kernelSize.height(), paintSize);
 }
 
 IntOutsets FEGaussianBlur::outsets() const

Modified: trunk/Source/WebCore/platform/graphics/filters/FELighting.cpp (256821 => 256822)


--- trunk/Source/WebCore/platform/graphics/filters/FELighting.cpp	2020-02-18 07:38:10 UTC (rev 256821)
+++ trunk/Source/WebCore/platform/graphics/filters/FELighting.cpp	2020-02-18 09:31:31 UTC (rev 256822)
@@ -30,6 +30,7 @@
 
 #include "ColorUtilities.h"
 #include "FELightingNEON.h"
+#include "ImageData.h"
 #include <wtf/ParallelJobs.h>
 
 namespace WebCore {
@@ -473,7 +474,8 @@
 {
     FilterEffect* in = inputEffect(0);
 
-    Uint8ClampedArray* resutPixelArray = createPremultipliedImageResult();
+    auto* resultImage = createPremultipliedImageResult();
+    auto* resutPixelArray = resultImage ? resultImage->data() : nullptr;
     if (!resutPixelArray)
         return;
 

Modified: trunk/Source/WebCore/platform/graphics/filters/FEMorphology.cpp (256821 => 256822)


--- trunk/Source/WebCore/platform/graphics/filters/FEMorphology.cpp	2020-02-18 07:38:10 UTC (rev 256821)
+++ trunk/Source/WebCore/platform/graphics/filters/FEMorphology.cpp	2020-02-18 09:31:31 UTC (rev 256822)
@@ -27,7 +27,7 @@
 
 #include "ColorUtilities.h"
 #include "Filter.h"
-#include <_javascript_Core/Uint8ClampedArray.h>
+#include "ImageData.h"
 #include <wtf/ParallelJobs.h>
 #include <wtf/Vector.h>
 #include <wtf/text/TextStream.h>
@@ -234,7 +234,8 @@
 {
     FilterEffect* in = inputEffect(0);
 
-    Uint8ClampedArray* dstPixelArray = createPremultipliedImageResult();
+    auto* resultImage = createPremultipliedImageResult();
+    auto* dstPixelArray = resultImage ? resultImage->data() : nullptr;
     if (!dstPixelArray)
         return;
 

Modified: trunk/Source/WebCore/platform/graphics/filters/FETurbulence.cpp (256821 => 256822)


--- trunk/Source/WebCore/platform/graphics/filters/FETurbulence.cpp	2020-02-18 07:38:10 UTC (rev 256821)
+++ trunk/Source/WebCore/platform/graphics/filters/FETurbulence.cpp	2020-02-18 09:31:31 UTC (rev 256822)
@@ -27,7 +27,7 @@
 #include "FETurbulence.h"
 
 #include "Filter.h"
-#include <_javascript_Core/Uint8ClampedArray.h>
+#include "ImageData.h"
 #include <wtf/MathExtras.h>
 #include <wtf/ParallelJobs.h>
 #include <wtf/text/TextStream.h>
@@ -395,7 +395,8 @@
 
 void FETurbulence::platformApplySoftware()
 {
-    Uint8ClampedArray* pixelArray = createUnmultipliedImageResult();
+    auto* resultImage = createUnmultipliedImageResult();
+    auto* pixelArray = resultImage ? resultImage->data() : nullptr;
     if (!pixelArray)
         return;
 

Modified: trunk/Source/WebCore/platform/graphics/filters/FilterEffect.cpp (256821 => 256822)


--- trunk/Source/WebCore/platform/graphics/filters/FilterEffect.cpp	2020-02-18 07:38:10 UTC (rev 256821)
+++ trunk/Source/WebCore/platform/graphics/filters/FilterEffect.cpp	2020-02-18 09:31:31 UTC (rev 256822)
@@ -27,10 +27,10 @@
 #include "Filter.h"
 #include "GeometryUtilities.h"
 #include "ImageBuffer.h"
+#include "ImageData.h"
 #include "Logging.h"
 #include <_javascript_Core/JSCInlines.h>
 #include <_javascript_Core/TypedArrayInlines.h>
-#include <_javascript_Core/Uint8ClampedArray.h>
 #include <wtf/text/TextStream.h>
 
 #if HAVE(ARM_NEON_INTRINSICS)
@@ -199,7 +199,7 @@
     if (!m_premultipliedImageResult)
         return;
 
-    Uint8ClampedArray* imageArray = m_premultipliedImageResult.get();
+    Uint8ClampedArray* imageArray = m_premultipliedImageResult->data();
     uint8_t* pixelData = imageArray->data();
     int pixelArrayLength = imageArray->length();
 
@@ -265,7 +265,7 @@
 
 ImageBuffer* FilterEffect::imageBufferResult()
 {
-    LOG_WITH_STREAM(Filters, stream << "FilterEffect " << filterName() << " " << this << " imageBufferResult(). Existing image buffer " << m_imageBufferResult.get() <<  " m_premultipliedImageResult " << m_premultipliedImageResult.get() << " m_unmultipliedImageResult " << m_unmultipliedImageResult.get());
+    LOG_WITH_STREAM(Filters, stream << "FilterEffect " << filterName() << " " << this << " imageBufferResult(). Existing image buffer " << m_imageBufferResult.get() <<  " m_premultipliedImageResult " << m_premultipliedImageResult->data() << " m_unmultipliedImageResult " << m_unmultipliedImageResult->data());
 
     if (!hasResult())
         return nullptr;
@@ -279,9 +279,9 @@
 
     IntRect destinationRect(IntPoint(), m_absolutePaintRect.size());
     if (m_premultipliedImageResult)
-        m_imageBufferResult->putByteArray(*m_premultipliedImageResult, AlphaPremultiplication::Premultiplied, destinationRect.size(), destinationRect, IntPoint());
+        m_imageBufferResult->putImageData(AlphaPremultiplication::Premultiplied, *m_premultipliedImageResult, destinationRect);
     else
-        m_imageBufferResult->putByteArray(*m_unmultipliedImageResult, AlphaPremultiplication::Unpremultiplied, destinationRect.size(), destinationRect, IntPoint());
+        m_imageBufferResult->putImageData(AlphaPremultiplication::Unpremultiplied, *m_unmultipliedImageResult, destinationRect);
     return m_imageBufferResult.get();
 }
 
@@ -438,12 +438,12 @@
 {
     ASSERT(hasResult());
     
-    LOG_WITH_STREAM(Filters, stream << "FilterEffect " << filterName() << " " << this << " copyUnmultipliedResult(). Existing image buffer " << m_imageBufferResult.get() <<  " m_premultipliedImageResult " << m_premultipliedImageResult.get() << " m_unmultipliedImageResult " << m_unmultipliedImageResult.get());
+    LOG_WITH_STREAM(Filters, stream << "FilterEffect " << filterName() << " " << this << " copyUnmultipliedResult(). Existing image buffer " << m_imageBufferResult.get() <<  " m_premultipliedImageResult " << m_premultipliedImageResult->data() << " m_unmultipliedImageResult " << m_unmultipliedImageResult->data());
 
     if (!m_unmultipliedImageResult) {
         // We prefer a conversion from the image buffer.
         if (m_imageBufferResult) {
-            m_unmultipliedImageResult = m_imageBufferResult->getUnmultipliedImageData(IntRect(IntPoint(), m_absolutePaintRect.size()));
+            m_unmultipliedImageResult = m_imageBufferResult->getImageData(AlphaPremultiplication::Unpremultiplied, { IntPoint(), m_absolutePaintRect.size() });
             if (!m_unmultipliedImageResult)
                 return;
         } else {
@@ -450,14 +450,14 @@
             IntSize inputSize(m_absolutePaintRect.size());
             ASSERT(!ImageBuffer::sizeNeedsClamping(inputSize));
             inputSize.scale(m_filter.filterScale());
-            m_unmultipliedImageResult = Uint8ClampedArray::tryCreateUninitialized((inputSize.area() * 4).unsafeGet());
+            m_unmultipliedImageResult = ImageData::create(inputSize);
             if (!m_unmultipliedImageResult)
                 return;
             
-            copyUnpremultiplyingAlpha(*m_premultipliedImageResult, *m_unmultipliedImageResult, inputSize);
+            copyUnpremultiplyingAlpha(*m_premultipliedImageResult->data(), *m_unmultipliedImageResult->data(), inputSize);
         }
     }
-    copyImageBytes(*m_unmultipliedImageResult, destination, rect);
+    copyImageBytes(*m_unmultipliedImageResult->data(), destination, rect);
 }
 
 void FilterEffect::copyPremultipliedResult(Uint8ClampedArray& destination, const IntRect& rect)
@@ -464,12 +464,12 @@
 {
     ASSERT(hasResult());
 
-    LOG_WITH_STREAM(Filters, stream << "FilterEffect " << filterName() << " " << this << " copyPremultipliedResult(). Existing image buffer " << m_imageBufferResult.get() <<  " m_premultipliedImageResult " << m_premultipliedImageResult.get() << " m_unmultipliedImageResult " << m_unmultipliedImageResult.get());
+    LOG_WITH_STREAM(Filters, stream << "FilterEffect " << filterName() << " " << this << " copyPremultipliedResult(). Existing image buffer " << m_imageBufferResult.get() <<  " m_premultipliedImageResult " << m_premultipliedImageResult->data() << " m_unmultipliedImageResult " << m_unmultipliedImageResult->data());
 
     if (!m_premultipliedImageResult) {
         // We prefer a conversion from the image buffer.
         if (m_imageBufferResult) {
-            m_premultipliedImageResult = m_imageBufferResult->getPremultipliedImageData(IntRect(IntPoint(), m_absolutePaintRect.size()));
+            m_premultipliedImageResult = m_imageBufferResult->getImageData(AlphaPremultiplication::Premultiplied, { IntPoint(), m_absolutePaintRect.size() });
             if (!m_premultipliedImageResult)
                 return;
         } else {
@@ -476,14 +476,14 @@
             IntSize inputSize(m_absolutePaintRect.size());
             ASSERT(!ImageBuffer::sizeNeedsClamping(inputSize));
             inputSize.scale(m_filter.filterScale());
-            m_premultipliedImageResult = Uint8ClampedArray::tryCreateUninitialized((inputSize.area() * 4).unsafeGet());
+            m_premultipliedImageResult = ImageData::create(inputSize);
             if (!m_premultipliedImageResult)
                 return;
             
-            copyPremultiplyingAlpha(*m_unmultipliedImageResult, *m_premultipliedImageResult, inputSize);
+            copyPremultiplyingAlpha(*m_unmultipliedImageResult->data(), *m_premultipliedImageResult->data(), inputSize);
         }
     }
-    copyImageBytes(*m_premultipliedImageResult, destination, rect);
+    copyImageBytes(*m_premultipliedImageResult->data(), destination, rect);
 }
 
 ImageBuffer* FilterEffect::createImageBufferResult()
@@ -497,13 +497,10 @@
 
     FloatSize clampedSize = ImageBuffer::clampedSize(m_absolutePaintRect.size());
     m_imageBufferResult = ImageBuffer::create(clampedSize, m_filter.renderingMode(), m_filter.filterScale(), m_resultColorSpace);
-    if (!m_imageBufferResult)
-        return nullptr;
-
     return m_imageBufferResult.get();
 }
 
-Uint8ClampedArray* FilterEffect::createUnmultipliedImageResult()
+ImageData* FilterEffect::createUnmultipliedImageResult()
 {
     LOG(Filters, "FilterEffect %s %p createUnmultipliedImageResult", filterName(), this);
 
@@ -515,11 +512,11 @@
     IntSize resultSize(m_absolutePaintRect.size());
     ASSERT(!ImageBuffer::sizeNeedsClamping(resultSize));
     resultSize.scale(m_filter.filterScale());
-    m_unmultipliedImageResult = Uint8ClampedArray::tryCreateUninitialized((resultSize.area() * 4).unsafeGet());
+    m_unmultipliedImageResult = ImageData::create(resultSize);
     return m_unmultipliedImageResult.get();
 }
 
-Uint8ClampedArray* FilterEffect::createPremultipliedImageResult()
+ImageData* FilterEffect::createPremultipliedImageResult()
 {
     LOG(Filters, "FilterEffect %s %p createPremultipliedImageResult", filterName(), this);
 
@@ -531,7 +528,7 @@
     IntSize resultSize(m_absolutePaintRect.size());
     ASSERT(!ImageBuffer::sizeNeedsClamping(resultSize));
     resultSize.scale(m_filter.filterScale());
-    m_premultipliedImageResult = Uint8ClampedArray::tryCreateUninitialized((resultSize.area() * 4).unsafeGet());
+    m_premultipliedImageResult = ImageData::create(resultSize);
     return m_premultipliedImageResult.get();
 }
 

Modified: trunk/Source/WebCore/platform/graphics/filters/FilterEffect.h (256821 => 256822)


--- trunk/Source/WebCore/platform/graphics/filters/FilterEffect.h	2020-02-18 07:38:10 UTC (rev 256821)
+++ trunk/Source/WebCore/platform/graphics/filters/FilterEffect.h	2020-02-18 09:31:31 UTC (rev 256822)
@@ -40,6 +40,7 @@
 class Filter;
 class FilterEffect;
 class ImageBuffer;
+class ImageData;
 
 typedef Vector<RefPtr<FilterEffect>> FilterEffectVector;
 
@@ -153,8 +154,8 @@
     virtual const char* filterName() const = 0;
 
     ImageBuffer* createImageBufferResult();
-    Uint8ClampedArray* createUnmultipliedImageResult();
-    Uint8ClampedArray* createPremultipliedImageResult();
+    ImageData* createUnmultipliedImageResult();
+    ImageData* createPremultipliedImageResult();
 
     // Return true if the filter will only operate correctly on valid RGBA values, with
     // alpha in [0,255] and each color component in [0, alpha].
@@ -182,8 +183,8 @@
     FilterEffectVector m_inputEffects;
 
     std::unique_ptr<ImageBuffer> m_imageBufferResult;
-    RefPtr<Uint8ClampedArray> m_unmultipliedImageResult;
-    RefPtr<Uint8ClampedArray> m_premultipliedImageResult;
+    RefPtr<ImageData> m_unmultipliedImageResult;
+    RefPtr<ImageData> m_premultipliedImageResult;
 
     IntRect m_absolutePaintRect;
     

Modified: trunk/Source/WebCore/platform/graphics/win/ImageBufferDataDirect2D.cpp (256821 => 256822)


--- trunk/Source/WebCore/platform/graphics/win/ImageBufferDataDirect2D.cpp	2020-02-18 07:38:10 UTC (rev 256821)
+++ trunk/Source/WebCore/platform/graphics/win/ImageBufferDataDirect2D.cpp	2020-02-18 09:31:31 UTC (rev 256822)
@@ -255,16 +255,13 @@
     }
 }
 
-RefPtr<Uint8ClampedArray> ImageBufferData::getData(AlphaPremultiplication desiredFormat, const IntRect& rect, const IntSize& size, bool /* accelerateRendering */, float /* resolutionScale */) const
+RefPtr<ImageData> ImageBufferData::getData(AlphaPremultiplication desiredFormat, const IntRect& rect, const IntSize& size) const
 {
-    auto numBytes = rect.area<RecordOverflow>() * 4;
-    if (numBytes.hasOverflowed())
+    auto result = ImageData::create(rect.size());
+    auto* pixelArray = result ? result->data() : nullptr;
+    if (!pixelArray)
         return nullptr;
 
-    auto result = Uint8ClampedArray::tryCreateUninitialized(numBytes.unsafeGet());
-    if (!result)
-        return nullptr;
-
     if (!bitmap)
         return result;
 
@@ -354,7 +351,7 @@
     return true;
 }
 
-void ImageBufferData::putData(const Uint8ClampedArray& source, AlphaPremultiplication sourceFormat, const IntSize& sourceSize, const IntRect& sourceRect, const IntPoint& destPoint, const IntSize& size, bool /* accelerateRendering */, float resolutionScale)
+void ImageBufferData::putData(AlphaPremultiplication sourceFormat, const ImageData& imageData, const IntRect& sourceRect, const IntPoint& destPoint, const IntSize& size)
 {
     ASSERT(sourceRect.width() > 0);
     ASSERT(sourceRect.height() > 0);
@@ -361,7 +358,6 @@
 
     Checked<int> originx = sourceRect.x();
     Checked<int> destx = (Checked<int>(destPoint.x()) + sourceRect.x());
-    destx *= resolutionScale;
     ASSERT(destx.unsafeGet() >= 0);
     ASSERT(destx.unsafeGet() < size.width());
     ASSERT(originx.unsafeGet() >= 0);
@@ -368,7 +364,6 @@
     ASSERT(originx.unsafeGet() <= sourceRect.maxX());
 
     Checked<int> endx = (Checked<int>(destPoint.x()) + sourceRect.maxX());
-    endx *= resolutionScale;
     ASSERT(endx.unsafeGet() <= size.width());
 
     Checked<int> width = sourceRect.width();
@@ -376,7 +371,6 @@
 
     Checked<int> originy = sourceRect.y();
     Checked<int> desty = (Checked<int>(destPoint.y()) + sourceRect.y());
-    desty *= resolutionScale;
     ASSERT(desty.unsafeGet() >= 0);
     ASSERT(desty.unsafeGet() < size.height());
     ASSERT(originy.unsafeGet() >= 0);
@@ -383,7 +377,6 @@
     ASSERT(originy.unsafeGet() <= sourceRect.maxY());
 
     Checked<int> endy = (Checked<int>(destPoint.y()) + sourceRect.maxY());
-    endy *= resolutionScale;
     ASSERT(endy.unsafeGet() <= size.height());
 
     Checked<int> height = sourceRect.height();
@@ -395,9 +388,9 @@
 #if ASSERT_ENABLED
     if (bitmap) {
         auto pixelSize = bitmap->GetPixelSize();
-        ASSERT(pixelSize.width >= sourceSize.width());
+        ASSERT(pixelSize.width >= imageData.size().width());
         ASSERT(pixelSize.width >= size.width());
-        ASSERT(pixelSize.height >= sourceSize.height());
+        ASSERT(pixelSize.height >= imageData.size().height());
         ASSERT(pixelSize.height >= size.height());
     }
 #endif
@@ -405,6 +398,7 @@
     if (!ensureBackingStore(size))
         return;
 
+    autoz* source = imageData.data();
     if (sourceSize == size) {
         memcpy(data.data(), source.data(), source.length());
         byteFormat = sourceFormat;

Modified: trunk/Source/WebCore/platform/graphics/win/ImageBufferDataDirect2D.h (256821 => 256822)


--- trunk/Source/WebCore/platform/graphics/win/ImageBufferDataDirect2D.h	2020-02-18 07:38:10 UTC (rev 256821)
+++ trunk/Source/WebCore/platform/graphics/win/ImageBufferDataDirect2D.h	2020-02-18 09:31:31 UTC (rev 256822)
@@ -54,8 +54,8 @@
     enum class BitmapBufferSync { InSync, BitmapOutOfSync, BufferOutOfSync };
     mutable BitmapBufferSync bitmapBufferSync { BitmapBufferSync::BufferOutOfSync };
 
-    RefPtr<Uint8ClampedArray> getData(AlphaPremultiplication, const IntRect&, const IntSize&, bool accelerateRendering, float resolutionScale) const;
-    void putData(const Uint8ClampedArray& source, AlphaPremultiplication sourceFormat, const IntSize& sourceSize, const IntRect& sourceRect, const IntPoint& destPoint, const IntSize&, bool accelerateRendering, float resolutionScale);
+    RefPtr<ImageData> getData(AlphaPremultiplication outputFormat, const IntRect&, const IntSize&) const;
+    void putData(AlphaPremultiplication inputFormat, const ImageData&, const IntRect& sourceRect, const IntPoint& destPoint, const IntSize&);
 
     COMPtr<ID2D1Bitmap> compatibleBitmap(ID2D1RenderTarget*);
 

Modified: trunk/Source/WebCore/platform/graphics/win/ImageBufferDirect2D.cpp (256821 => 256822)


--- trunk/Source/WebCore/platform/graphics/win/ImageBufferDirect2D.cpp	2020-02-18 07:38:10 UTC (rev 256821)
+++ trunk/Source/WebCore/platform/graphics/win/ImageBufferDirect2D.cpp	2020-02-18 09:31:31 UTC (rev 256822)
@@ -278,51 +278,30 @@
     }
 }
 
-RefPtr<Uint8ClampedArray> ImageBuffer::getUnmultipliedImageData(const IntRect& rect, IntSize* pixelArrayDimensions, CoordinateSystem coordinateSystem) const
+RefPtr<ImageData> ImageBuffer::getImageData(AlphaPremultiplication outputFormat, const IntRect& srcRect) const
 {
     if (context().isAcceleratedContext())
         flushContext();
 
-    IntRect srcRect = rect;
-    if (coordinateSystem == LogicalCoordinateSystem)
-        srcRect.scale(m_resolutionScale);
+    IntRect scaledSrcRect = srcRect;
+    scaledSrcRect.scale(m_resolutionScale);
 
-    if (pixelArrayDimensions)
-        *pixelArrayDimensions = srcRect.size();
-
-    return m_data.getData(AlphaPremultiplication::Unpremultiplied, srcRect, internalSize(), context().isAcceleratedContext(), 1);
+    return m_data.getData(outputFormat, scaledSrcRect, internalSize());
 }
 
-RefPtr<Uint8ClampedArray> ImageBuffer::getPremultipliedImageData(const IntRect& rect, IntSize* pixelArrayDimensions, CoordinateSystem coordinateSystem) const
+void ImageBuffer::putImageData(AlphaPremultiplication inputFormat, const ImageData& imageData, const IntRect& srcRect, const IntPoint& destPoint)
 {
     if (context().isAcceleratedContext())
         flushContext();
 
-    IntRect srcRect = rect;
-    if (coordinateSystem == LogicalCoordinateSystem)
-        srcRect.scale(m_resolutionScale);
+    IntRect scaledSrcRect = srcRect;
+    IntRect scaledDestPoint = destPoint;
+    scaledSrcRect.scale(m_resolutionScale);
+    scaledDestPoint.scale(m_resolutionScale);
 
-    if (pixelArrayDimensions)
-        *pixelArrayDimensions = srcRect.size();
-
-    return m_data.getData(AlphaPremultiplication::Premultiplied, srcRect, internalSize(), context().isAcceleratedContext(), 1);
+    m_data.putData(inputFormat, imageData, scaledSrcRect, scaledDestPoint, internalSize());
 }
 
-void ImageBuffer::putByteArray(const Uint8ClampedArray& source, AlphaPremultiplication bufferFormat, const IntSize& sourceSize, const IntRect& sourceRect, const IntPoint& destPoint, CoordinateSystem coordinateSystem)
-{
-    if (context().isAcceleratedContext())
-        flushContext();
-
-    IntRect scaledSourceRect = sourceRect;
-    IntSize scaledSourceSize = sourceSize;
-    if (coordinateSystem == LogicalCoordinateSystem) {
-        scaledSourceRect.scale(m_resolutionScale);
-        scaledSourceSize.scale(m_resolutionScale);
-    }
-
-    m_data.putData(source, bufferFormat, scaledSourceSize, scaledSourceRect, destPoint, internalSize(), context().isAcceleratedContext(), 1);
-}
-
 String ImageBuffer::toDataURL(const String&, Optional<double>, PreserveResolution) const
 {
     notImplemented();

Modified: trunk/Source/WebCore/rendering/shapes/Shape.cpp (256821 => 256822)


--- trunk/Source/WebCore/rendering/shapes/Shape.cpp	2020-02-18 07:38:10 UTC (rev 256821)
+++ trunk/Source/WebCore/rendering/shapes/Shape.cpp	2020-02-18 09:31:31 UTC (rev 256822)
@@ -35,6 +35,7 @@
 #include "BoxShape.h"
 #include "GraphicsContext.h"
 #include "ImageBuffer.h"
+#include "ImageData.h"
 #include "LengthFunctions.h"
 #include "PolygonShape.h"
 #include "RasterShape.h"
@@ -188,8 +189,9 @@
         if (image)
             graphicsContext.drawImage(*image, IntRect(IntPoint(), imageRect.size()));
 
-        RefPtr<Uint8ClampedArray> pixelArray = imageBuffer->getUnmultipliedImageData(IntRect(IntPoint(), imageRect.size()));
-        RELEASE_ASSERT(pixelArray);
+        auto imageData = imageBuffer->getImageData(AlphaPremultiplication::Unpremultiplied, { IntPoint(), imageRect.size() });
+        RELEASE_ASSERT(imageData && imageData->data());
+        auto* pixelArray = imageData->data();
         unsigned pixelArrayLength = pixelArray->length();
         unsigned pixelArrayOffset = 3; // Each pixel is four bytes: RGBA.
         uint8_t alphaPixelThreshold = static_cast<uint8_t>(lroundf(clampTo<float>(threshold, 0, 1) * 255.0f));
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to