Diff
Modified: trunk/LayoutTests/ChangeLog (277568 => 277569)
--- trunk/LayoutTests/ChangeLog 2021-05-16 15:00:51 UTC (rev 277568)
+++ trunk/LayoutTests/ChangeLog 2021-05-16 15:21:34 UTC (rev 277569)
@@ -1,3 +1,33 @@
+2021-05-16 Sam Weinig <wei...@apple.com>
+
+ Add support for creating/accessing/setting non-sRGB ImageData via canvas
+ https://bugs.webkit.org/show_bug.cgi?id=225841
+
+ Reviewed by Darin Adler.
+
+ * TestExpectations:
+ Remove wide-gamut-canvas now that they should pass.
+
+ * fast/canvas/canvas-color-space-display-p3-ImageData-expected.txt: Added.
+ * fast/canvas/canvas-color-space-display-p3-ImageData.html: Added.
+ Add new test exercising getImageData and putImageData with non-sRGB canvases
+ and non-sRGB ImageData.
+
+ * fast/canvas/canvas-imageData-expected.txt:
+ Update results for updated error messages, which are a bit worse due additional
+ ambiguity in signatures.
+
+ * platform/glib/TestExpectations:
+ Mark new test as failing on glib due to lack of display-p3 support.
+
+ * platform/win/TestExpectations:
+ Mark new test as failing on Windows due to lack of display-p3 support.
+ Unskip CanvasRenderingContext2DSettings-colorSpace-enabled.html which
+ should now pass due to adding manual preferences support in WebKitLegacy/win.
+
+ * storage/indexeddb/modern/objectstore-autoincrement-types-expected.txt:
+ Update results due to new attribute in ImageData that is auto printed.
+
2021-05-16 Tim Nguyen <n...@apple.com>
Make will-change: transform-style create a containing block
Modified: trunk/LayoutTests/TestExpectations (277568 => 277569)
--- trunk/LayoutTests/TestExpectations 2021-05-16 15:00:51 UTC (rev 277568)
+++ trunk/LayoutTests/TestExpectations 2021-05-16 15:21:34 UTC (rev 277569)
@@ -3994,9 +3994,6 @@
imported/w3c/web-platform-tests/html/canvas/element/drawing-images-to-the-canvas/image-orientation/drawImage-from-element-swap-width-height.tentative.html [ ImageOnlyFailure ]
imported/w3c/web-platform-tests/html/canvas/element/drawing-images-to-the-canvas/image-orientation/drawImage-from-element.tentative.html [ ImageOnlyFailure ]
-# Sometimes prints weird output at the beginning of the tests.
-imported/w3c/web-platform-tests/html/canvas/element/wide-gamut-canvas [ Failure Pass ]
-
# CSS Masonry Layout not supported.
imported/w3c/web-platform-tests/css/css-grid/masonry.tentative [ Skip ]
webkit.org/b/202115 imported/w3c/web-platform-tests/css/css-grid/subgrid [ Skip ]
Added: trunk/LayoutTests/fast/canvas/canvas-color-space-display-p3-ImageData-expected.txt (0 => 277569)
--- trunk/LayoutTests/fast/canvas/canvas-color-space-display-p3-ImageData-expected.txt (rev 0)
+++ trunk/LayoutTests/fast/canvas/canvas-color-space-display-p3-ImageData-expected.txt 2021-05-16 15:21:34 UTC (rev 277569)
@@ -0,0 +1,159 @@
+Test that pixel access functions work with non-SRGB color spaces.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+PASS imageDataCreatedFromDisplayP3Canvas.colorSpace is "display-p3"
+PASS imageDataCreatedFromDisplayP3CanvasOverridingColorSpaceSRGB.colorSpace is "srgb"
+PASS imageDataCreatedFromDisplayP3CanvasOverridingColorSpaceDisplayP3.colorSpace is "display-p3"
+PASS imageDataCreatedFromSRGBCanvas.colorSpace is "srgb"
+PASS imageDataCreatedFromSRGBCanvasOverridingColorSpaceSRGB.colorSpace is "srgb"
+PASS imageDataCreatedFromSRGBCanvasOverridingColorSpaceDisplayP3.colorSpace is "display-p3"
+PASS imageDataCreatedFromImageDataConstructor.colorSpace is "srgb"
+PASS imageDataCreatedFromImageDataConstructorSettingColorSpaceToSRGB.colorSpace is "srgb"
+PASS imageDataCreatedFromImageDataConstructorSettingColorSpaceToDisplayP3.colorSpace is "display-p3"
+PASS imageDataCreatedFromImageDataConstructorPassingBuffer.colorSpace is "srgb"
+PASS imageDataCreatedFromImageDataConstructorPassingBufferSettingColorSpaceToSRGB.colorSpace is "srgb"
+PASS imageDataCreatedFromImageDataConstructorPassingBufferSettingColorSpaceToDisplayP3.colorSpace is "display-p3"
+
+Testing a display-p3 canvas with color(display-p3 0 1 0) drawn into it
+
+Test getImageData with no specified color space, on a display-p3 canvas (canvas has color(display-p3 0 1 0) drawn in it)
+PASS data.colorSpace is "display-p3"
+PASS data.data[0] is 0
+PASS data.data[1] is 255
+PASS data.data[2] is 0
+PASS data.data[3] is 255
+Test getImageData with srgb specified, on a display-p3 canvas (canvas has color(display-p3 0 1 0) drawn in it)
+PASS data.colorSpace is "srgb"
+PASS data.data[0] is 0
+PASS data.data[1] is 255
+PASS data.data[2] is 0
+PASS data.data[3] is 255
+Test getImageData with display-p3 specified, on a display-p3 canvas (canvas has color(display-p3 0 1 0) drawn in it)
+PASS data.colorSpace is "display-p3"
+PASS data.data[0] is 0
+PASS data.data[1] is 255
+PASS data.data[2] is 0
+PASS data.data[3] is 255
+
+Testing a display-p3 canvas with color(srgb 0 1 0) drawn into it
+
+Test getImageData with no specified color space, on a display-p3 canvas (canvas has color(srgb 0 1 0) drawn in it)
+PASS data.colorSpace is "display-p3"
+PASS data.data[0] is 117
+PASS data.data[1] is 251
+PASS data.data[2] is 76
+PASS data.data[3] is 255
+Test getImageData with srgb specified, on a display-p3 canvas (canvas has color(srgb 0 1 0) drawn in it)
+PASS data.colorSpace is "srgb"
+PASS data.data[0] is 3
+PASS data.data[1] is 255
+PASS data.data[2] is 0
+PASS data.data[3] is 255
+Test getImageData with display-p3 specified, on a display-p3 canvas (canvas has color(srgb 0 1 0) drawn in it)
+PASS data.colorSpace is "display-p3"
+PASS data.data[0] is 117
+PASS data.data[1] is 251
+PASS data.data[2] is 76
+PASS data.data[3] is 255
+
+Testing a srgb canvas with color(display-p3 0 1 0) drawn into it
+
+Test getImageData with no specified color space, on a srgb canvas (canvas has color(display-p3 0 1 0) drawn in it)
+PASS data.colorSpace is "srgb"
+PASS data.data[0] is 0
+PASS data.data[1] is 255
+PASS data.data[2] is 0
+PASS data.data[3] is 255
+Test getImageData with srgb specified, on a srgb canvas (canvas has color(display-p3 0 1 0) drawn in it)
+PASS data.colorSpace is "srgb"
+PASS data.data[0] is 0
+PASS data.data[1] is 255
+PASS data.data[2] is 0
+PASS data.data[3] is 255
+Test getImageData with display-p3 specified, on a srgb canvas (canvas has color(display-p3 0 1 0) drawn in it)
+PASS data.colorSpace is "display-p3"
+PASS data.data[0] is 117
+PASS data.data[1] is 251
+PASS data.data[2] is 76
+PASS data.data[3] is 255
+
+Testing a srgb canvas with color(srgb-p3 0 1 0) drawn into it
+
+Test getImageData with no specified color space, on a srgb canvas (canvas has color(srgb 0 1 0) drawn in it)
+PASS data.colorSpace is "srgb"
+PASS data.data[0] is 0
+PASS data.data[1] is 255
+PASS data.data[2] is 0
+PASS data.data[3] is 255
+Test getImageData with srgb specified, on a srgb canvas (canvas has color(srgb 0 1 0) drawn in it)
+PASS data.colorSpace is "srgb"
+PASS data.data[0] is 0
+PASS data.data[1] is 255
+PASS data.data[2] is 0
+PASS data.data[3] is 255
+Test getImageData with display-p3 specified, on a srgb canvas (canvas has color(srgb 0 1 0) drawn in it)
+PASS data.colorSpace is "display-p3"
+PASS data.data[0] is 117
+PASS data.data[1] is 251
+PASS data.data[2] is 76
+PASS data.data[3] is 255
+
+
+Testing a display-p3 canvas with display-p3 ImageData drawn into it
+
+PASS data.colorSpace is "srgb"
+PASS data.data[0] is 0
+PASS data.data[1] is 255
+PASS data.data[2] is 0
+PASS data.data[3] is 255
+PASS data.colorSpace is "display-p3"
+PASS data.data[0] is 0
+PASS data.data[1] is 255
+PASS data.data[2] is 0
+PASS data.data[3] is 255
+
+Testing a display-p3 canvas with srgb ImageData drawn into it
+
+PASS data.colorSpace is "srgb"
+PASS data.data[0] is 3
+PASS data.data[1] is 255
+PASS data.data[2] is 0
+PASS data.data[3] is 255
+PASS data.colorSpace is "display-p3"
+PASS data.data[0] is 117
+PASS data.data[1] is 251
+PASS data.data[2] is 76
+PASS data.data[3] is 255
+
+Testing a srgb canvas with display-p3 ImageData drawn into it
+
+PASS data.colorSpace is "srgb"
+PASS data.data[0] is 0
+PASS data.data[1] is 255
+PASS data.data[2] is 0
+PASS data.data[3] is 255
+PASS data.colorSpace is "display-p3"
+PASS data.data[0] is 117
+PASS data.data[1] is 251
+PASS data.data[2] is 76
+PASS data.data[3] is 255
+
+Testing a srgb canvas with srgb ImageData drawn into it
+
+PASS data.colorSpace is "srgb"
+PASS data.data[0] is 0
+PASS data.data[1] is 255
+PASS data.data[2] is 0
+PASS data.data[3] is 255
+PASS data.colorSpace is "display-p3"
+PASS data.data[0] is 117
+PASS data.data[1] is 251
+PASS data.data[2] is 76
+PASS data.data[3] is 255
+
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
Added: trunk/LayoutTests/fast/canvas/canvas-color-space-display-p3-ImageData.html (0 => 277569)
--- trunk/LayoutTests/fast/canvas/canvas-color-space-display-p3-ImageData.html (rev 0)
+++ trunk/LayoutTests/fast/canvas/canvas-color-space-display-p3-ImageData.html 2021-05-16 15:21:34 UTC (rev 277569)
@@ -0,0 +1,290 @@
+<!DOCTYPE html>
+<html>
+<head>
+<script src=""
+</head>
+<body>
+<script>
+description("Test that pixel access functions work with non-SRGB color spaces.");
+
+let canvasDisplayP3 = document.createElement("canvas");
+let contextDisplayP3 = canvasDisplayP3.getContext("2d", { colorSpace: "display-p3" });
+
+let canvasSRGB = document.createElement("canvas");
+let contextSRGB = canvasSRGB.getContext("2d", { colorSpace: "srgb" });
+
+const imageDataCreatedFromDisplayP3Canvas = contextDisplayP3.createImageData(50, 50);
+shouldBe("imageDataCreatedFromDisplayP3Canvas.colorSpace", `"display-p3"`);
+
+const imageDataCreatedFromDisplayP3CanvasOverridingColorSpaceSRGB = contextDisplayP3.createImageData(50, 50, { colorSpace: "srgb" });
+shouldBe("imageDataCreatedFromDisplayP3CanvasOverridingColorSpaceSRGB.colorSpace", `"srgb"`);
+
+const imageDataCreatedFromDisplayP3CanvasOverridingColorSpaceDisplayP3 = contextDisplayP3.createImageData(50, 50, { colorSpace: "display-p3" });
+shouldBe("imageDataCreatedFromDisplayP3CanvasOverridingColorSpaceDisplayP3.colorSpace", `"display-p3"`);
+
+const imageDataCreatedFromSRGBCanvas = contextSRGB.createImageData(50, 50);
+shouldBe("imageDataCreatedFromSRGBCanvas.colorSpace", `"srgb"`);
+
+const imageDataCreatedFromSRGBCanvasOverridingColorSpaceSRGB = contextSRGB.createImageData(50, 50, { colorSpace: "srgb" });
+shouldBe("imageDataCreatedFromSRGBCanvasOverridingColorSpaceSRGB.colorSpace", `"srgb"`);
+
+const imageDataCreatedFromSRGBCanvasOverridingColorSpaceDisplayP3 = contextSRGB.createImageData(50, 50, { colorSpace: "display-p3" });
+shouldBe("imageDataCreatedFromSRGBCanvasOverridingColorSpaceDisplayP3.colorSpace", `"display-p3"`);
+
+const imageDataCreatedFromImageDataConstructor = new ImageData(50, 50, { colorSpace: "srgb" });
+shouldBe("imageDataCreatedFromImageDataConstructor.colorSpace", `"srgb"`);
+
+const imageDataCreatedFromImageDataConstructorSettingColorSpaceToSRGB = new ImageData(50, 50, { colorSpace: "srgb" });
+shouldBe("imageDataCreatedFromImageDataConstructorSettingColorSpaceToSRGB.colorSpace", `"srgb"`);
+
+const imageDataCreatedFromImageDataConstructorSettingColorSpaceToDisplayP3 = new ImageData(50, 50, { colorSpace: "display-p3" });
+shouldBe("imageDataCreatedFromImageDataConstructorSettingColorSpaceToDisplayP3.colorSpace", `"display-p3"`);
+
+const imageDataCreatedFromImageDataConstructorPassingBuffer = new ImageData(new Uint8ClampedArray(400), 10, 10, { colorSpace: "srgb" });
+shouldBe("imageDataCreatedFromImageDataConstructorPassingBuffer.colorSpace", `"srgb"`);
+
+const imageDataCreatedFromImageDataConstructorPassingBufferSettingColorSpaceToSRGB = new ImageData(new Uint8ClampedArray(400), 10, 10, { colorSpace: "srgb" });
+shouldBe("imageDataCreatedFromImageDataConstructorPassingBufferSettingColorSpaceToSRGB.colorSpace", `"srgb"`);
+
+const imageDataCreatedFromImageDataConstructorPassingBufferSettingColorSpaceToDisplayP3 = new ImageData(new Uint8ClampedArray(400), 10, 10, { colorSpace: "display-p3" });
+shouldBe("imageDataCreatedFromImageDataConstructorPassingBufferSettingColorSpaceToDisplayP3.colorSpace", `"display-p3"`);
+
+var data = { };
+
+// NOTE:
+// color(srgb 0 1 0) converted to display-p3 is color(display-p3 0.4584 0.98526 0.29829) or [117, 251, 76, 255] in byte form.
+
+debug("");
+debug("Testing a display-p3 canvas with color(display-p3 0 1 0) drawn into it");
+debug("");
+
+contextDisplayP3.fillStyle = "color(display-p3 0 1 0)";
+contextDisplayP3.fillRect(0, 0, 50, 50);
+
+// No specified color space will default to the canvas' color space, in this case, display-p3
+debug("Test getImageData with no specified color space, on a display-p3 canvas (canvas has color(display-p3 0 1 0) drawn in it)");
+data = "" 0, 1, 1);
+shouldBe("data.colorSpace", `"display-p3"`)
+shouldBe("data.data[0]", "0");
+shouldBe("data.data[1]", "255");
+shouldBe("data.data[2]", "0");
+shouldBe("data.data[3]", "255");
+
+debug("Test getImageData with srgb specified, on a display-p3 canvas (canvas has color(display-p3 0 1 0) drawn in it)");
+// NOTE: color(display-p3 0 1 0) is outside the range of sRGB, so it clipped to 255.
+data = "" 0, 1, 1, { colorSpace: "srgb" });
+shouldBe("data.colorSpace", `"srgb"`)
+shouldBe("data.data[0]", "0");
+shouldBe("data.data[1]", "255");
+shouldBe("data.data[2]", "0");
+shouldBe("data.data[3]", "255");
+
+debug("Test getImageData with display-p3 specified, on a display-p3 canvas (canvas has color(display-p3 0 1 0) drawn in it)");
+data = "" 0, 1, 1, { colorSpace: "display-p3" });
+shouldBe("data.colorSpace", `"display-p3"`)
+shouldBe("data.data[0]", "0");
+shouldBe("data.data[1]", "255");
+shouldBe("data.data[2]", "0");
+shouldBe("data.data[3]", "255");
+
+debug("");
+debug("Testing a display-p3 canvas with color(srgb 0 1 0) drawn into it");
+debug("");
+
+contextDisplayP3.fillStyle = "color(srgb 0 1 0)";
+contextDisplayP3.fillRect(0, 0, 50, 50);
+
+// No specified color space will default to the canvas' color space, in this case, display-p3
+debug("Test getImageData with no specified color space, on a display-p3 canvas (canvas has color(srgb 0 1 0) drawn in it)");
+data = "" 0, 1, 1);
+shouldBe("data.colorSpace", `"display-p3"`)
+shouldBe("data.data[0]", "117");
+shouldBe("data.data[1]", "251");
+shouldBe("data.data[2]", "76");
+shouldBe("data.data[3]", "255");
+
+debug("Test getImageData with srgb specified, on a display-p3 canvas (canvas has color(srgb 0 1 0) drawn in it)");
+data = "" 0, 1, 1, { colorSpace: "srgb" });
+shouldBe("data.colorSpace", `"srgb"`)
+// NOTE: This 3 is odd, but due to lack of precision in 8-bit round-tripping.
+shouldBe("data.data[0]", "3");
+shouldBe("data.data[1]", "255");
+shouldBe("data.data[2]", "0");
+shouldBe("data.data[3]", "255");
+
+debug("Test getImageData with display-p3 specified, on a display-p3 canvas (canvas has color(srgb 0 1 0) drawn in it)");
+data = "" 0, 1, 1, { colorSpace: "display-p3" });
+shouldBe("data.colorSpace", `"display-p3"`)
+shouldBe("data.data[0]", "117");
+shouldBe("data.data[1]", "251");
+shouldBe("data.data[2]", "76");
+shouldBe("data.data[3]", "255");
+
+debug("");
+debug("Testing a srgb canvas with color(display-p3 0 1 0) drawn into it");
+debug("");
+
+contextSRGB.fillStyle = "color(display-p3 0 1 0)";
+contextSRGB.fillRect(0, 0, 50, 50);
+
+// No specified color space will default to the canvas' color space, in this case, srgb
+debug("Test getImageData with no specified color space, on a srgb canvas (canvas has color(display-p3 0 1 0) drawn in it)");
+data = "" 0, 1, 1);
+shouldBe("data.colorSpace", `"srgb"`)
+shouldBe("data.data[0]", "0");
+shouldBe("data.data[1]", "255");
+shouldBe("data.data[2]", "0");
+shouldBe("data.data[3]", "255");
+
+debug("Test getImageData with srgb specified, on a srgb canvas (canvas has color(display-p3 0 1 0) drawn in it)");
+data = "" 0, 1, 1, { colorSpace: "srgb" });
+shouldBe("data.colorSpace", `"srgb"`)
+shouldBe("data.data[0]", "0");
+shouldBe("data.data[1]", "255");
+shouldBe("data.data[2]", "0");
+shouldBe("data.data[3]", "255");
+
+debug("Test getImageData with display-p3 specified, on a srgb canvas (canvas has color(display-p3 0 1 0) drawn in it)");
+data = "" 0, 1, 1, { colorSpace: "display-p3" });
+shouldBe("data.colorSpace", `"display-p3"`)
+shouldBe("data.data[0]", "117");
+shouldBe("data.data[1]", "251");
+shouldBe("data.data[2]", "76");
+shouldBe("data.data[3]", "255");
+
+debug("");
+debug("Testing a srgb canvas with color(srgb-p3 0 1 0) drawn into it");
+debug("");
+
+contextSRGB.fillStyle = "color(srgb 0 1 0)";
+contextSRGB.fillRect(0, 0, 50, 50);
+
+// No specified color space will default to the canvas' color space, in this case, srgb
+debug("Test getImageData with no specified color space, on a srgb canvas (canvas has color(srgb 0 1 0) drawn in it)");
+data = "" 0, 1, 1);
+shouldBe("data.colorSpace", `"srgb"`)
+shouldBe("data.data[0]", "0");
+shouldBe("data.data[1]", "255");
+shouldBe("data.data[2]", "0");
+shouldBe("data.data[3]", "255");
+
+debug("Test getImageData with srgb specified, on a srgb canvas (canvas has color(srgb 0 1 0) drawn in it)");
+data = "" 0, 1, 1, { colorSpace: "srgb" });
+shouldBe("data.colorSpace", `"srgb"`)
+shouldBe("data.data[0]", "0");
+shouldBe("data.data[1]", "255");
+shouldBe("data.data[2]", "0");
+shouldBe("data.data[3]", "255");
+
+debug("Test getImageData with display-p3 specified, on a srgb canvas (canvas has color(srgb 0 1 0) drawn in it)");
+data = "" 0, 1, 1, { colorSpace: "display-p3" });
+shouldBe("data.colorSpace", `"display-p3"`)
+shouldBe("data.data[0]", "117");
+shouldBe("data.data[1]", "251");
+shouldBe("data.data[2]", "76");
+shouldBe("data.data[3]", "255");
+
+
+debug("");
+
+
+const imageDataDisplayP3ToPut = new ImageData(1, 1, { colorSpace: "display-p3" });
+imageDataDisplayP3ToPut.data[0] = 0;
+imageDataDisplayP3ToPut.data[1] = 255;
+imageDataDisplayP3ToPut.data[2] = 0;
+imageDataDisplayP3ToPut.data[3] = 255;
+
+const imageDataSRGBToPut = new ImageData(1, 1, { colorSpace: "srgb" });
+imageDataSRGBToPut.data[0] = 0;
+imageDataSRGBToPut.data[1] = 255;
+imageDataSRGBToPut.data[2] = 0;
+imageDataSRGBToPut.data[3] = 255;
+
+
+debug("");
+debug("Testing a display-p3 canvas with display-p3 ImageData drawn into it");
+debug("");
+
+contextDisplayP3.putImageData(imageDataDisplayP3ToPut, 0, 0);
+
+data = "" 0, 1, 1, { colorSpace: "srgb" });
+shouldBe("data.colorSpace", `"srgb"`)
+shouldBe("data.data[0]", "0");
+shouldBe("data.data[1]", "255");
+shouldBe("data.data[2]", "0");
+shouldBe("data.data[3]", "255");
+
+data = "" 0, 1, 1, { colorSpace: "display-p3" });
+shouldBe("data.colorSpace", `"display-p3"`)
+shouldBe("data.data[0]", "0");
+shouldBe("data.data[1]", "255");
+shouldBe("data.data[2]", "0");
+shouldBe("data.data[3]", "255");
+
+debug("");
+debug("Testing a display-p3 canvas with srgb ImageData drawn into it");
+debug("");
+
+contextDisplayP3.putImageData(imageDataSRGBToPut, 0, 0);
+
+data = "" 0, 1, 1, { colorSpace: "srgb" });
+shouldBe("data.colorSpace", `"srgb"`)
+// NOTE: This 3 is odd, but due to lack of precision in 8-bit round-tripping.
+shouldBe("data.data[0]", "3");
+shouldBe("data.data[1]", "255");
+shouldBe("data.data[2]", "0");
+shouldBe("data.data[3]", "255");
+
+data = "" 0, 1, 1, { colorSpace: "display-p3" });
+shouldBe("data.colorSpace", `"display-p3"`)
+shouldBe("data.data[0]", "117");
+shouldBe("data.data[1]", "251");
+shouldBe("data.data[2]", "76");
+shouldBe("data.data[3]", "255");
+
+debug("");
+debug("Testing a srgb canvas with display-p3 ImageData drawn into it");
+debug("");
+
+contextSRGB.putImageData(imageDataDisplayP3ToPut, 0, 0);
+
+data = "" 0, 1, 1, { colorSpace: "srgb" });
+shouldBe("data.colorSpace", `"srgb"`)
+shouldBe("data.data[0]", "0");
+shouldBe("data.data[1]", "255");
+shouldBe("data.data[2]", "0");
+shouldBe("data.data[3]", "255");
+
+data = "" 0, 1, 1, { colorSpace: "display-p3" });
+shouldBe("data.colorSpace", `"display-p3"`)
+shouldBe("data.data[0]", "117");
+shouldBe("data.data[1]", "251");
+shouldBe("data.data[2]", "76");
+shouldBe("data.data[3]", "255");
+
+
+debug("");
+debug("Testing a srgb canvas with srgb ImageData drawn into it");
+debug("");
+
+contextSRGB.putImageData(imageDataSRGBToPut, 0, 0);
+
+data = "" 0, 1, 1, { colorSpace: "srgb" });
+shouldBe("data.colorSpace", `"srgb"`)
+shouldBe("data.data[0]", "0");
+shouldBe("data.data[1]", "255");
+shouldBe("data.data[2]", "0");
+shouldBe("data.data[3]", "255");
+
+data = "" 0, 1, 1, { colorSpace: "display-p3" });
+shouldBe("data.colorSpace", `"display-p3"`)
+shouldBe("data.data[0]", "117");
+shouldBe("data.data[1]", "251");
+shouldBe("data.data[2]", "76");
+shouldBe("data.data[3]", "255");
+
+debug("");
+</script>
+<script src=""
+</body>
+</html>
Modified: trunk/LayoutTests/fast/canvas/canvas-imageData-expected.txt (277568 => 277569)
--- trunk/LayoutTests/fast/canvas/canvas-imageData-expected.txt 2021-05-16 15:00:51 UTC (rev 277568)
+++ trunk/LayoutTests/fast/canvas/canvas-imageData-expected.txt 2021-05-16 15:21:34 UTC (rev 277569)
@@ -14,20 +14,20 @@
PASS new ImageData(20, -20) threw exception RangeError: Cannot allocate a buffer of this size.
PASS new ImageData(null, 20) threw exception IndexSizeError: The index is not in the allowed range..
PASS new ImageData(32768, 32768) threw exception RangeError: Cannot allocate a buffer of this size.
-PASS new ImageData(null, 20, 20) threw exception TypeError: Argument 1 ('data') to the ImageData constructor must be an instance of Uint8ClampedArray.
-PASS new ImageData(imageData, 20, 20) threw exception TypeError: Argument 1 ('data') to the ImageData constructor must be an instance of Uint8ClampedArray.
+PASS new ImageData(null, 20, 20) threw exception TypeError: Type error.
+PASS new ImageData(imageData, 20, 20) threw exception TypeError: Type error.
PASS new ImageData(imageData, 0) threw exception IndexSizeError: The index is not in the allowed range..
-PASS new ImageData(imageData, 20, 0) threw exception TypeError: Argument 1 ('data') to the ImageData constructor must be an instance of Uint8ClampedArray.
-PASS new ImageData(imageData, 0, 20) threw exception TypeError: Argument 1 ('data') to the ImageData constructor must be an instance of Uint8ClampedArray.
-PASS new ImageData(imageData, 10, 5) threw exception TypeError: Argument 1 ('data') to the ImageData constructor must be an instance of Uint8ClampedArray.
+PASS new ImageData(imageData, 20, 0) threw exception TypeError: Type error.
+PASS new ImageData(imageData, 0, 20) threw exception TypeError: Type error.
+PASS new ImageData(imageData, 10, 5) threw exception TypeError: Type error.
PASS new ImageData(imageData.data, 10, 5) threw exception IndexSizeError: sh value is not equal to height.
PASS new ImageData(imageData.data, -10, 5) threw exception IndexSizeError: Length is not a multiple of sw.
PASS new ImageData(imageData.data, 10, -10) threw exception IndexSizeError: sh value is not equal to height.
PASS new ImageData(new Uint8ClampedArray([1,2,3,4,5,6,7,8]),536870913,2); threw exception IndexSizeError: Length is not a multiple of sw.
-PASS new ImageData({},2,2); threw exception TypeError: Argument 1 ('data') to the ImageData constructor must be an instance of Uint8ClampedArray.
-PASS new ImageData(undefined,2,2); threw exception TypeError: Argument 1 ('data') to the ImageData constructor must be an instance of Uint8ClampedArray.
-PASS new ImageData("none",2,2); threw exception TypeError: Argument 1 ('data') to the ImageData constructor must be an instance of Uint8ClampedArray.
-PASS new ImageData(0,2,2); threw exception TypeError: Argument 1 ('data') to the ImageData constructor must be an instance of Uint8ClampedArray.
+PASS new ImageData({},2,2); threw exception TypeError: Type error.
+PASS new ImageData(undefined,2,2); threw exception TypeError: Type error.
+PASS new ImageData("none",2,2); threw exception TypeError: Type error.
+PASS new ImageData(0,2,2); threw exception TypeError: Type error.
PASS new ImageData(imageData.data, 32768, 32768) threw exception IndexSizeError: Length is not a multiple of sw.
PASS new ImageData(imageData.data, Infinity, Infinity) threw exception IndexSizeError: Length is not a multiple of sw.
PASS new ImageData(imageData.data, NaN, NaN) threw exception IndexSizeError: Length is not a multiple of sw.
Modified: trunk/LayoutTests/imported/w3c/ChangeLog (277568 => 277569)
--- trunk/LayoutTests/imported/w3c/ChangeLog 2021-05-16 15:00:51 UTC (rev 277568)
+++ trunk/LayoutTests/imported/w3c/ChangeLog 2021-05-16 15:21:34 UTC (rev 277569)
@@ -1,3 +1,13 @@
+2021-05-16 Sam Weinig <wei...@apple.com>
+
+ Add support for creating/accessing/setting non-sRGB ImageData via canvas
+ https://bugs.webkit.org/show_bug.cgi?id=225841
+
+ Reviewed by Darin Adler.
+
+ * web-platform-tests/html/canvas/element/wide-gamut-canvas/2d.color.space.p3.to.p3-expected.txt:
+ Update result to passing.
+
2021-05-15 Said Abou-Hallawa <s...@apple.com>
Implement CanvasRenderingContext2D.createConicGradient
Modified: trunk/LayoutTests/imported/w3c/web-platform-tests/html/canvas/element/wide-gamut-canvas/2d.color.space.p3.to.p3-expected.txt (277568 => 277569)
--- trunk/LayoutTests/imported/w3c/web-platform-tests/html/canvas/element/wide-gamut-canvas/2d.color.space.p3.to.p3-expected.txt 2021-05-16 15:00:51 UTC (rev 277568)
+++ trunk/LayoutTests/imported/w3c/web-platform-tests/html/canvas/element/wide-gamut-canvas/2d.color.space.p3.to.p3-expected.txt 2021-05-16 15:21:34 UTC (rev 277569)
@@ -2,5 +2,5 @@
test getImageData with display-p3 and uint8 from display p3 uint8 canvas
Actual output:
-FAIL test getImageData with display-p3 and uint8 from display p3 uint8 canvas assert_approx_equals: expected 62 +/- 2 but got 50
+PASS test getImageData with display-p3 and uint8 from display p3 uint8 canvas
Modified: trunk/LayoutTests/platform/glib/TestExpectations (277568 => 277569)
--- trunk/LayoutTests/platform/glib/TestExpectations 2021-05-16 15:00:51 UTC (rev 277568)
+++ trunk/LayoutTests/platform/glib/TestExpectations 2021-05-16 15:21:34 UTC (rev 277569)
@@ -2358,6 +2358,7 @@
webkit.org/b/224112 media/video-as-img-output-pts.html [ Timeout Pass ]
webkit.org/b/225423 fast/canvas/canvas-color-space-display-p3.html [ ImageOnlyFailure ]
+webkit.org/b/225423 fast/canvas/canvas-color-space-display-p3-ImageData.html [ Failure ]
webkit.org/b/225423 fast/canvas/canvas-composite-text-alpha.html [ Failure ]
# Failing after r277073.
Modified: trunk/LayoutTests/platform/win/TestExpectations (277568 => 277569)
--- trunk/LayoutTests/platform/win/TestExpectations 2021-05-16 15:00:51 UTC (rev 277568)
+++ trunk/LayoutTests/platform/win/TestExpectations 2021-05-16 15:21:34 UTC (rev 277569)
@@ -4635,4 +4635,6 @@
fast/text/line-break-with-locale.html [ ImageOnlyFailure ]
-fast/canvas/CanvasRenderingContext2DSettings-colorSpace-enabled.html [ Skip ]
+# Non-SRGB color spaces are not currently supported by the Windows port.
+fast/canvas/canvas-color-space-display-p3.html [ Skip ]
+fast/canvas/canvas-color-space-display-p3-ImageData.html [ Skip ]
Modified: trunk/LayoutTests/storage/indexeddb/modern/objectstore-autoincrement-types-expected.txt (277568 => 277569)
--- trunk/LayoutTests/storage/indexeddb/modern/objectstore-autoincrement-types-expected.txt 2021-05-16 15:00:51 UTC (rev 277568)
+++ trunk/LayoutTests/storage/indexeddb/modern/objectstore-autoincrement-types-expected.txt 2021-05-16 15:21:34 UTC (rev 277569)
@@ -26,6 +26,7 @@
PASS request.result.primaryKey is imageData.primaryKey
PASS request.result.width is imageData.width
PASS request.result.height is imageData.height
+PASS request.result.colorSpace is imageData.colorSpace
PASS key is 4
PASS request.result.primaryKey is fileList.primaryKey
PASS request.result.length is fileList.length
@@ -40,6 +41,7 @@
PASS request.result[2].primaryKey is imageData.primaryKey
PASS request.result[2].width is imageData.width
PASS request.result[2].height is imageData.height
+PASS request.result[2].colorSpace is imageData.colorSpace
PASS request.result[3].primaryKey is fileList.primaryKey
PASS request.result[3].length is fileList.length
PASS successfullyParsed is true
Modified: trunk/Source/WebCore/CMakeLists.txt (277568 => 277569)
--- trunk/Source/WebCore/CMakeLists.txt 2021-05-16 15:00:51 UTC (rev 277568)
+++ trunk/Source/WebCore/CMakeLists.txt 2021-05-16 15:21:34 UTC (rev 277569)
@@ -1017,6 +1017,7 @@
html/ImageBitmap.idl
html/ImageBitmapOptions.idl
html/ImageData.idl
+ html/ImageDataSettings.idl
html/MediaController.idl
html/MediaEncryptedEvent.idl
html/MediaError.idl
Modified: trunk/Source/WebCore/ChangeLog (277568 => 277569)
--- trunk/Source/WebCore/ChangeLog 2021-05-16 15:00:51 UTC (rev 277568)
+++ trunk/Source/WebCore/ChangeLog 2021-05-16 15:21:34 UTC (rev 277569)
@@ -1,3 +1,142 @@
+2021-05-16 Sam Weinig <wei...@apple.com>
+
+ Add support for creating/accessing/setting non-sRGB ImageData via canvas
+ https://bugs.webkit.org/show_bug.cgi?id=225841
+
+ Reviewed by Darin Adler.
+
+ Test: fast/canvas/canvas-color-space-display-p3-ImageData.html
+
+ Add support for accessing non-sRGB (only DisplayP3 for now due
+ to the specification, but the support is general) pixel data in
+ HTML canvas.
+
+ Updates ImageData constructors and CanvasImageData operations to
+ take optional ImageDataSettings dictionaries, which contain an
+ optional color space (otherwise defaulting back to sRGB).
+
+ * CMakeLists.txt:
+ * DerivedSources-input.xcfilelist:
+ * DerivedSources-output.xcfilelist:
+ * DerivedSources.make:
+ * Sources.txt:
+ * WebCore.xcodeproj/project.pbxproj:
+ * html/ImageDataSettings.h: Added.
+ * html/ImageDataSettings.idl: Added.
+ Add new ImageDataSettings.idl and related files.
+
+ * bindings/js/SerializedScriptValue.cpp:
+ (WebCore::CloneDeserializer::readImageBitmap):
+ Fixes FIXME and uses PixelBuffer directly rather than allocating
+ an unnecessary ImageData. This was done now since the relevent
+ ImageData constructor has gone away.
+
+ * html/ImageData.cpp:
+ (WebCore::computeDataSize):
+ (WebCore::ImageData::computeColorSpace):
+ (WebCore::ImageData::create):
+ (WebCore::ImageData::createUninitialized):
+ (WebCore::ImageData::ImageData):
+ (WebCore::ImageData::pixelBuffer const):
+ (WebCore::ImageData::dataSize): Deleted.
+ (WebCore::ImageData::deepClone const): Deleted.
+ * html/ImageData.h:
+ (WebCore::ImageData::size const):
+ (WebCore::ImageData::width const):
+ (WebCore::ImageData::height const):
+ (WebCore::ImageData::data const):
+ (WebCore::ImageData::colorSpace const):
+ (WebCore::ImageData::pixelBuffer const): Deleted.
+
+ - Reworked ImageData to no longer store a PixelBuffer, which has
+ extraneous information in it, but rather to store just what it
+ needs IntSize, Ref<JSC::Uint8ClampedArray>, and now PredefinedColorSpace.
+ - Updates create functions for new optional ImageDataSettings.
+ - Adds createUninitialized which follows spec language for ImageData creation
+ and is used by CanvasRenderingContext2D to create ImageData objects of with
+ the right color spaces, allowing for fallback to the canvas' own color space
+ when no ImageDataSettings color space is provided. It is uninitialized and
+ therefore requires the client to initialize the data to allow for support for
+ no alpha support in the future, which requires a non-zero initialization pattern.
+
+ * html/ImageData.idl:
+ Add optional ImageDataSettings parameters and the new colorSpace attribute.
+
+ * html/canvas/CanvasImageData.idl:
+ Add optional ImageDataSettings parameters.
+
+ * html/canvas/CanvasRenderingContext2DBase.h:
+ * html/canvas/CanvasRenderingContext2DBase.cpp:
+ (WebCore::initializeEmptyImageData):
+ Add helper to initialize the ImageData buffer. Right now it always calls
+ zeroFill(), but in the future it will need to do more.
+
+ (WebCore::CanvasRenderingContext2DBase::createImageData const):
+ Update to account for this function being able to throw an exception (when
+ out of memory) and use the new createUninitialized/initializeEmptyImageData
+ to create a correctly color spaced ImageData.
+
+ (WebCore::CanvasRenderingContext2DBase::createImageData const):
+ Update for new optional ImageDataSettings and use the new createUninitialized
+ initializeEmptyImageData to create a correctly color spaced ImageData.
+
+ (WebCore::CanvasRenderingContext2DBase::getImageData const):
+ Moves parameter checks to the begining to match the spec, and uses new
+ createUninitialized/initializeEmptyImageData to create a correctly color
+ spaced ImageData. Also, use the ImageData's color space when getting
+ the pixel buffer to actually return the right data!
+
+ * html/canvas/PredefinedColorSpace.cpp:
+ (WebCore::toPredefinedColorSpace):
+ * html/canvas/PredefinedColorSpace.h:
+ Add conversion function from DestinationColorSpace to PredefinedColorSpace.
+ Since DestinationColorSpace is a superset of PredefinedColorSpace, this can
+ fail, so this conversion returns an Optional.
+
+ * inspector/InspectorCanvas.cpp:
+ * inspector/InspectorCanvasCallTracer.cpp:
+ * inspector/InspectorCanvasCallTracer.h:
+ Stub out inspector support for ImageDataSettings.
+
+ * platform/graphics/ImageBufferBackend.cpp:
+ (WebCore::ImageBufferBackend::getPixelBuffer const):
+ Use the ImageBuffer's actual color space as the source color space
+ rather than hard coding sRGB. This allows the color space conversion
+ to take place. Also remove some unnecessary temporary variables.
+
+ (WebCore::ImageBufferBackend::putPixelBuffer):
+ Use the ImageBuffer's actual color space as the destination color space
+ rather than hard coding sRGB. This allows the color space conversion
+ to take place. Also remove some unnecessary temporary variables.
+
+ * platform/graphics/PixelBuffer.cpp:
+ (WebCore::PixelBuffer::tryCreate):
+ (WebCore::PixelBuffer::PixelBuffer):
+ * platform/graphics/PixelBuffer.h:
+ (WebCore::PixelBuffer::takeData):
+ Add a few helpers to allow creationg to/from PixelBuffer
+ a bit easier.
+
+ * platform/graphics/PixelBufferConversion.cpp:
+ (WebCore::convertImagePixelsAccelerated):
+ Fix incorrect assertion. We want to assert that there is no error, not that
+ there is one.
+
+ * platform/graphics/filters/FilterEffect.cpp:
+ (WebCore::FilterEffect::convertImageBufferToColorSpace):
+ (WebCore::FilterEffect::copyUnmultipliedResult):
+ (WebCore::FilterEffect::copyPremultipliedResult):
+ (WebCore::FilterEffect::createUnmultipliedImageResult):
+ (WebCore::FilterEffect::createPremultipliedImageResult):
+ Stop hard coding SRGB for PixelBuffer color spaces and use the appropriate
+ color space for the task. We still do color space conversion through ImageBuffer
+ so we should come back and simplify code here to not always require that.
+
+ * testing/Internals.cpp:
+ (WebCore::Internals::videoSampleAvailable):
+ (WebCore::Internals::loadArtworkImage):
+ Update to specify a color space to maintain existing behavior.
+
2021-05-16 Alan Bujtas <za...@apple.com>
[LFC] Cleanup margin collapsing class
Modified: trunk/Source/WebCore/DerivedSources-input.xcfilelist (277568 => 277569)
--- trunk/Source/WebCore/DerivedSources-input.xcfilelist 2021-05-16 15:00:51 UTC (rev 277568)
+++ trunk/Source/WebCore/DerivedSources-input.xcfilelist 2021-05-16 15:21:34 UTC (rev 277569)
@@ -1036,6 +1036,7 @@
$(PROJECT_DIR)/html/ImageBitmap.idl
$(PROJECT_DIR)/html/ImageBitmapOptions.idl
$(PROJECT_DIR)/html/ImageData.idl
+$(PROJECT_DIR)/html/ImageDataSettings.idl
$(PROJECT_DIR)/html/MediaController.idl
$(PROJECT_DIR)/html/MediaEncryptedEvent.idl
$(PROJECT_DIR)/html/MediaError.idl
Modified: trunk/Source/WebCore/DerivedSources-output.xcfilelist (277568 => 277569)
--- trunk/Source/WebCore/DerivedSources-output.xcfilelist 2021-05-16 15:00:51 UTC (rev 277568)
+++ trunk/Source/WebCore/DerivedSources-output.xcfilelist 2021-05-16 15:21:34 UTC (rev 277569)
@@ -1180,6 +1180,8 @@
$(BUILT_PRODUCTS_DIR)/DerivedSources/WebCore/JSImageBitmapRenderingContextSettings.h
$(BUILT_PRODUCTS_DIR)/DerivedSources/WebCore/JSImageData.cpp
$(BUILT_PRODUCTS_DIR)/DerivedSources/WebCore/JSImageData.h
+$(BUILT_PRODUCTS_DIR)/DerivedSources/WebCore/JSImageDataSettings.cpp
+$(BUILT_PRODUCTS_DIR)/DerivedSources/WebCore/JSImageDataSettings.h
$(BUILT_PRODUCTS_DIR)/DerivedSources/WebCore/JSImageSmoothingQuality.cpp
$(BUILT_PRODUCTS_DIR)/DerivedSources/WebCore/JSImageSmoothingQuality.h
$(BUILT_PRODUCTS_DIR)/DerivedSources/WebCore/JSInnerHTML.cpp
Modified: trunk/Source/WebCore/DerivedSources.make (277568 => 277569)
--- trunk/Source/WebCore/DerivedSources.make 2021-05-16 15:00:51 UTC (rev 277568)
+++ trunk/Source/WebCore/DerivedSources.make 2021-05-16 15:21:34 UTC (rev 277569)
@@ -890,6 +890,7 @@
$(WebCore)/html/ImageBitmap.idl \
$(WebCore)/html/ImageBitmapOptions.idl \
$(WebCore)/html/ImageData.idl \
+ $(WebCore)/html/ImageDataSettings.idl \
$(WebCore)/html/MediaController.idl \
$(WebCore)/html/MediaEncryptedEvent.idl \
$(WebCore)/html/MediaError.idl \
Modified: trunk/Source/WebCore/Sources.txt (277568 => 277569)
--- trunk/Source/WebCore/Sources.txt 2021-05-16 15:00:51 UTC (rev 277568)
+++ trunk/Source/WebCore/Sources.txt 2021-05-16 15:21:34 UTC (rev 277569)
@@ -3207,6 +3207,7 @@
JSImageBitmapRenderingContext.cpp
JSImageBitmapRenderingContextSettings.cpp
JSImageData.cpp
+JSImageDataSettings.cpp
JSImageSmoothingQuality.cpp
JSInputEvent.cpp
JSInspectorAuditAccessibilityObject.cpp
Modified: trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj (277568 => 277569)
--- trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj 2021-05-16 15:00:51 UTC (rev 277568)
+++ trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj 2021-05-16 15:21:34 UTC (rev 277569)
@@ -4103,6 +4103,7 @@
BC96DB430F3A880E00573CB3 /* RenderBoxModelObject.h in Headers */ = {isa = PBXBuildFile; fileRef = BC96DB420F3A880E00573CB3 /* RenderBoxModelObject.h */; settings = {ATTRIBUTES = (Private, ); }; };
BC97E23A109144950010D361 /* HTMLAllCollection.h in Headers */ = {isa = PBXBuildFile; fileRef = BC97E238109144950010D361 /* HTMLAllCollection.h */; };
BC97E413109154FA0010D361 /* JSHTMLAllCollection.h in Headers */ = {isa = PBXBuildFile; fileRef = BC97E411109154FA0010D361 /* JSHTMLAllCollection.h */; };
+ BCA088F5264E1C08003E2A6C /* ImageDataSettings.h in Headers */ = {isa = PBXBuildFile; fileRef = BCA088F2264E1BF9003E2A6C /* ImageDataSettings.h */; settings = {ATTRIBUTES = (Private, ); }; };
BCA169A30BFD55B40019CA76 /* JSHTMLTableCaptionElement.h in Headers */ = {isa = PBXBuildFile; fileRef = BCA169A10BFD55B40019CA76 /* JSHTMLTableCaptionElement.h */; };
BCA257151293C010007A263D /* VerticalPositionCache.h in Headers */ = {isa = PBXBuildFile; fileRef = BCA257141293C010007A263D /* VerticalPositionCache.h */; };
BCA2B061105047600043BD1C /* UserScript.h in Headers */ = {isa = PBXBuildFile; fileRef = BCA2B0601050475F0043BD1C /* UserScript.h */; settings = {ATTRIBUTES = (Private, ); }; };
@@ -14331,6 +14332,8 @@
BC9A6142146859D9006057FD /* EventNames.in */ = {isa = PBXFileReference; lastKnownFileType = text; path = EventNames.in; sourceTree = "<group>"; };
BC9A6145146859D9006057FD /* make_event_factory.pl */ = {isa = PBXFileReference; lastKnownFileType = text.script.perl; path = make_event_factory.pl; sourceTree = "<group>"; };
BC9A6146146859D9006057FD /* make_names.pl */ = {isa = PBXFileReference; lastKnownFileType = text.script.perl; path = make_names.pl; sourceTree = "<group>"; };
+ BCA088F2264E1BF9003E2A6C /* ImageDataSettings.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ImageDataSettings.h; sourceTree = "<group>"; };
+ BCA088F4264E1BF9003E2A6C /* ImageDataSettings.idl */ = {isa = PBXFileReference; lastKnownFileType = text; path = ImageDataSettings.idl; sourceTree = "<group>"; };
BCA169A00BFD55B40019CA76 /* JSHTMLTableCaptionElement.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = JSHTMLTableCaptionElement.cpp; sourceTree = "<group>"; };
BCA169A10BFD55B40019CA76 /* JSHTMLTableCaptionElement.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = JSHTMLTableCaptionElement.h; sourceTree = "<group>"; };
BCA257141293C010007A263D /* VerticalPositionCache.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = VerticalPositionCache.h; sourceTree = "<group>"; };
@@ -23950,6 +23953,8 @@
A77979130D6B9D0C003851B9 /* ImageData.cpp */,
A77979140D6B9D0C003851B9 /* ImageData.h */,
A77979150D6B9D0C003851B9 /* ImageData.idl */,
+ BCA088F2264E1BF9003E2A6C /* ImageDataSettings.h */,
+ BCA088F4264E1BF9003E2A6C /* ImageDataSettings.idl */,
97205AB11239291000B17380 /* ImageDocument.cpp */,
97205AB21239291000B17380 /* ImageDocument.h */,
F55B3D8D1251F12D003EF269 /* ImageInputType.cpp */,
@@ -32915,6 +32920,7 @@
B2A10D910B3818BD00099AA4 /* ImageBufferPipe.h in Headers */,
CD3E21DD2183444A00E66F55 /* ImageBufferUtilitiesCG.h in Headers */,
A779791A0D6B9D0C003851B9 /* ImageData.h in Headers */,
+ BCA088F5264E1C08003E2A6C /* ImageDataSettings.h in Headers */,
CD19FEA81F573972000C42FB /* ImageDecoder.h in Headers */,
CD19FEAE1F574B6D000C42FB /* ImageDecoderAVFObjC.h in Headers */,
555B87ED1CAAF0AB00349425 /* ImageDecoderCG.h in Headers */,
Modified: trunk/Source/WebCore/bindings/js/SerializedScriptValue.cpp (277568 => 277569)
--- trunk/Source/WebCore/bindings/js/SerializedScriptValue.cpp 2021-05-16 15:00:51 UTC (rev 277568)
+++ trunk/Source/WebCore/bindings/js/SerializedScriptValue.cpp 2021-05-16 15:21:34 UTC (rev 277569)
@@ -3141,30 +3141,24 @@
return JSValue();
}
- 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);
- // FIXME: Creating this ImageData is not necessary. We should skip right to creating a PixelBuffer directly.
- auto imageData = ImageData::create(imageDataSize, array.releaseNonNull());
- if (!imageData) {
+ auto buffer = ImageBitmap::createImageBuffer(*scriptExecutionContextFromExecState(m_lexicalGlobalObject), logicalSize, RenderingMode::Unaccelerated, resolutionScale);
+ if (!buffer) {
fail();
return JSValue();
}
- auto buffer = ImageBitmap::createImageBuffer(*scriptExecutionContextFromExecState(m_lexicalGlobalObject), logicalSize, RenderingMode::Unaccelerated, resolutionScale);
- if (!buffer) {
+ PixelBufferFormat format { AlphaPremultiplication::Premultiplied, PixelFormat::RGBA8, DestinationColorSpace::SRGB };
+ auto pixelBuffer = PixelBuffer::tryCreate(format, imageDataSize, arrayBuffer.releaseNonNull());
+ if (!pixelBuffer) {
fail();
return JSValue();
}
- buffer->putPixelBuffer(imageData->pixelBuffer(), { IntPoint::zero(), logicalSize });
+ buffer->putPixelBuffer(WTFMove(*pixelBuffer), { IntPoint::zero(), logicalSize });
auto bitmap = ImageBitmap::create(ImageBitmapBacking(WTFMove(buffer), OptionSet<SerializationState>::fromRaw(serializationState)));
return getJSValue(bitmap);
Modified: trunk/Source/WebCore/html/ImageData.cpp (277568 => 277569)
--- trunk/Source/WebCore/html/ImageData.cpp 2021-05-16 15:00:51 UTC (rev 277568)
+++ trunk/Source/WebCore/html/ImageData.cpp 2021-05-16 15:21:34 UTC (rev 277569)
@@ -35,7 +35,7 @@
namespace WebCore {
-Checked<unsigned, RecordOverflow> ImageData::dataSize(const IntSize& size)
+static Checked<unsigned, RecordOverflow> computeDataSize(const IntSize& size)
{
Checked<unsigned, RecordOverflow> checkedDataSize = 4;
checkedDataSize *= static_cast<unsigned>(size.width());
@@ -43,9 +43,17 @@
return checkedDataSize;
}
+PredefinedColorSpace ImageData::computeColorSpace(Optional<ImageDataSettings> settings, PredefinedColorSpace defaultColorSpace)
+{
+ if (settings && settings->colorSpace)
+ return *settings->colorSpace;
+ return defaultColorSpace;
+}
+
Ref<ImageData> ImageData::create(PixelBuffer&& pixelBuffer)
{
- return adoptRef(*new ImageData(WTFMove(pixelBuffer)));
+ auto colorSpace = toPredefinedColorSpace(pixelBuffer.format().colorSpace);
+ return adoptRef(*new ImageData(pixelBuffer.size(), pixelBuffer.takeData(), *colorSpace));
}
RefPtr<ImageData> ImageData::create(Optional<PixelBuffer>&& pixelBuffer)
@@ -52,38 +60,56 @@
{
if (!pixelBuffer)
return nullptr;
- return ImageData::create(WTFMove(*pixelBuffer));
+ return create(WTFMove(*pixelBuffer));
}
RefPtr<ImageData> ImageData::create(const IntSize& size)
{
- auto dataSize = ImageData::dataSize(size);
+ auto dataSize = computeDataSize(size);
if (dataSize.hasOverflowed())
return nullptr;
auto byteArray = Uint8ClampedArray::tryCreateUninitialized(dataSize.unsafeGet());
if (!byteArray)
return nullptr;
-
- return adoptRef(*new ImageData({ { AlphaPremultiplication::Unpremultiplied, PixelFormat::RGBA8, DestinationColorSpace::SRGB }, size, byteArray.releaseNonNull() }));
+ return adoptRef(*new ImageData(size, byteArray.releaseNonNull(), PredefinedColorSpace::SRGB));
}
-RefPtr<ImageData> ImageData::create(const IntSize& size, Ref<Uint8ClampedArray>&& byteArray)
+RefPtr<ImageData> ImageData::create(const IntSize& size, Ref<Uint8ClampedArray>&& byteArray, PredefinedColorSpace colorSpace)
{
- auto dataSize = ImageData::dataSize(size);
- if (dataSize.hasOverflowed() || dataSize.unsafeGet() > byteArray->length())
+ auto dataSize = computeDataSize(size);
+ if (dataSize.hasOverflowed() || dataSize.unsafeGet() != byteArray->length())
return nullptr;
- return adoptRef(*new ImageData({ { AlphaPremultiplication::Unpremultiplied, PixelFormat::RGBA8, DestinationColorSpace::SRGB }, size, WTFMove(byteArray) }));
+ return adoptRef(*new ImageData(size, WTFMove(byteArray), colorSpace));
}
-ExceptionOr<Ref<ImageData>> ImageData::create(unsigned sw, unsigned sh)
+ExceptionOr<Ref<ImageData>> ImageData::createUninitialized(unsigned rows, unsigned pixelsPerRow, PredefinedColorSpace defaultColorSpace, Optional<ImageDataSettings> settings)
{
+ IntSize size(rows, pixelsPerRow);
+ auto dataSize = computeDataSize(size);
+ if (dataSize.hasOverflowed())
+ return Exception { RangeError, "Cannot allocate a buffer of this size"_s };
+
+ auto byteArray = Uint8ClampedArray::tryCreateUninitialized(dataSize.unsafeGet());
+ if (!byteArray) {
+ // FIXME: Does this need to be a "real" out of memory error with setOutOfMemoryError called on it?
+ return Exception { RangeError, "Out of memory"_s };
+ }
+
+ auto colorSpace = computeColorSpace(settings, defaultColorSpace);
+ return adoptRef(*new ImageData(size, byteArray.releaseNonNull(), colorSpace));
+}
+
+ExceptionOr<Ref<ImageData>> ImageData::create(unsigned sw, unsigned sh, Optional<ImageDataSettings> settings)
+{
if (!sw || !sh)
return Exception { IndexSizeError };
+
IntSize size(sw, sh);
- auto dataSize = ImageData::dataSize(size);
+ auto dataSize = computeDataSize(size);
if (dataSize.hasOverflowed())
return Exception { RangeError, "Cannot allocate a buffer of this size"_s };
+
auto byteArray = Uint8ClampedArray::tryCreateUninitialized(dataSize.unsafeGet());
if (!byteArray) {
// FIXME: Does this need to be a "real" out of memory error with setOutOfMemoryError called on it?
@@ -90,10 +116,12 @@
return Exception { RangeError, "Out of memory"_s };
}
byteArray->zeroFill();
- return adoptRef(*new ImageData({ { AlphaPremultiplication::Unpremultiplied, PixelFormat::RGBA8, DestinationColorSpace::SRGB }, size, byteArray.releaseNonNull() }));
+
+ auto colorSpace = computeColorSpace(settings);
+ return adoptRef(*new ImageData(size, byteArray.releaseNonNull(), colorSpace));
}
-ExceptionOr<Ref<ImageData>> ImageData::create(Ref<Uint8ClampedArray>&& byteArray, unsigned sw, Optional<unsigned> sh)
+ExceptionOr<Ref<ImageData>> ImageData::create(Ref<Uint8ClampedArray>&& byteArray, unsigned sw, Optional<unsigned> sh, Optional<ImageDataSettings> settings)
{
unsigned length = byteArray->length();
if (!length || length % 4)
@@ -107,22 +135,28 @@
if (sh && sh.value() != height)
return Exception { IndexSizeError, "sh value is not equal to height"_s };
- auto result = create(IntSize(sw, height), WTFMove(byteArray));
- if (!result)
+ IntSize size(sw, height);
+ auto dataSize = computeDataSize(size);
+ if (dataSize.hasOverflowed() || dataSize.unsafeGet() != byteArray->length())
return Exception { RangeError };
- return result.releaseNonNull();
+
+ auto colorSpace = computeColorSpace(settings);
+ return adoptRef(*new ImageData(size, WTFMove(byteArray), colorSpace));
}
-ImageData::ImageData(PixelBuffer&& pixelBuffer)
- : m_pixelBuffer(WTFMove(pixelBuffer))
+ImageData::ImageData(const IntSize& size, Ref<JSC::Uint8ClampedArray>&& data, PredefinedColorSpace colorSpace)
+ : m_size(size)
+ , m_data(WTFMove(data))
+ , m_colorSpace(colorSpace)
{
}
ImageData::~ImageData() = default;
-Ref<ImageData> ImageData::deepClone() const
+PixelBuffer ImageData::pixelBuffer() const
{
- return adoptRef(*new ImageData(m_pixelBuffer.deepClone()));
+ PixelBufferFormat format { AlphaPremultiplication::Unpremultiplied, PixelFormat::RGBA8, toDestinationColorSpace(m_colorSpace) };
+ return { format, m_size, m_data.get() };
}
TextStream& operator<<(TextStream& ts, const ImageData& imageData)
Modified: trunk/Source/WebCore/html/ImageData.h (277568 => 277569)
--- trunk/Source/WebCore/html/ImageData.h 2021-05-16 15:00:51 UTC (rev 277568)
+++ trunk/Source/WebCore/html/ImageData.h 2021-05-16 15:21:34 UTC (rev 277569)
@@ -29,7 +29,12 @@
#pragma once
#include "ExceptionOr.h"
+#include "ImageDataSettings.h"
+#include "IntSize.h"
#include "PixelBuffer.h"
+#include "PredefinedColorSpace.h"
+#include <_javascript_Core/Uint8ClampedArray.h>
+#include <wtf/Forward.h>
namespace WebCore {
@@ -38,29 +43,32 @@
WEBCORE_EXPORT static Ref<ImageData> create(PixelBuffer&&);
WEBCORE_EXPORT static RefPtr<ImageData> create(Optional<PixelBuffer>&&);
WEBCORE_EXPORT static RefPtr<ImageData> create(const IntSize&);
- WEBCORE_EXPORT static RefPtr<ImageData> create(const IntSize&, Ref<Uint8ClampedArray>&&);
- WEBCORE_EXPORT static ExceptionOr<Ref<ImageData>> create(unsigned sw, unsigned sh);
- WEBCORE_EXPORT static ExceptionOr<Ref<ImageData>> create(Ref<Uint8ClampedArray>&&, unsigned sw, Optional<unsigned> sh);
+ WEBCORE_EXPORT static RefPtr<ImageData> create(const IntSize&, Ref<Uint8ClampedArray>&&, PredefinedColorSpace);
+ WEBCORE_EXPORT static ExceptionOr<Ref<ImageData>> createUninitialized(unsigned rows, unsigned pixelsPerRow, PredefinedColorSpace defaultColorSpace, Optional<ImageDataSettings> = WTF::nullopt);
+ WEBCORE_EXPORT static ExceptionOr<Ref<ImageData>> create(unsigned sw, unsigned sh, Optional<ImageDataSettings>);
+ WEBCORE_EXPORT static ExceptionOr<Ref<ImageData>> create(Ref<Uint8ClampedArray>&&, unsigned sw, Optional<unsigned> sh, Optional<ImageDataSettings>);
+
WEBCORE_EXPORT ~ImageData();
- const IntSize& size() const { return m_pixelBuffer.size(); }
- int width() const { return m_pixelBuffer.size().width(); }
- int height() const { return m_pixelBuffer.size().height(); }
+ static PredefinedColorSpace computeColorSpace(Optional<ImageDataSettings>, PredefinedColorSpace defaultColorSpace = PredefinedColorSpace::SRGB);
- Uint8ClampedArray& data() const { return m_pixelBuffer.data(); }
+ const IntSize& size() const { return m_size; }
- Ref<ImageData> deepClone() const;
+ int width() const { return m_size.width(); }
+ int height() const { return m_size.height(); }
+ Uint8ClampedArray& data() const { return m_data.get(); }
+ PredefinedColorSpace colorSpace() const { return m_colorSpace; }
- const PixelBuffer& pixelBuffer() const { return m_pixelBuffer; }
+ PixelBuffer pixelBuffer() const;
private:
- explicit ImageData(PixelBuffer&&);
+ explicit ImageData(const IntSize&, Ref<JSC::Uint8ClampedArray>&&, PredefinedColorSpace);
- static Checked<unsigned, RecordOverflow> dataSize(const IntSize&);
-
- PixelBuffer m_pixelBuffer;
+ IntSize m_size;
+ Ref<JSC::Uint8ClampedArray> m_data;
+ PredefinedColorSpace m_colorSpace;
};
-WEBCORE_EXPORT WTF::TextStream& operator<<(WTF::TextStream&, const ImageData&);
+WEBCORE_EXPORT TextStream& operator<<(TextStream&, const ImageData&);
} // namespace WebCore
Modified: trunk/Source/WebCore/html/ImageData.idl (277568 => 277569)
--- trunk/Source/WebCore/html/ImageData.idl 2021-05-16 15:00:51 UTC (rev 277568)
+++ trunk/Source/WebCore/html/ImageData.idl 2021-05-16 15:21:34 UTC (rev 277569)
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2008-2009, 2016 Apple Inc. All rights reserved.
+ * Copyright (C) 2008-2021 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -32,10 +32,11 @@
Exposed=(Window,Worker),
ImplementationLacksVTable
] interface ImageData {
- constructor(unsigned long sw, unsigned long sh);
- constructor(Uint8ClampedArray data, unsigned long sw, optional unsigned long sh);
+ constructor(unsigned long sw, unsigned long sh, optional ImageDataSettings settings);
+ constructor(Uint8ClampedArray data, unsigned long sw, optional unsigned long sh, optional ImageDataSettings settings);
readonly attribute unsigned long width;
readonly attribute unsigned long height;
readonly attribute Uint8ClampedArray data;
+ [EnabledBySetting=CanvasColorSpace] readonly attribute PredefinedColorSpace colorSpace;
};
Copied: trunk/Source/WebCore/html/ImageDataSettings.h (from rev 277568, trunk/Source/WebCore/html/canvas/PredefinedColorSpace.cpp) (0 => 277569)
--- trunk/Source/WebCore/html/ImageDataSettings.h (rev 0)
+++ trunk/Source/WebCore/html/ImageDataSettings.h 2021-05-16 15:21:34 UTC (rev 277569)
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2021 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+#include "PredefinedColorSpace.h"
+#include <wtf/Optional.h>
+
+namespace WebCore {
+
+struct ImageDataSettings {
+ Optional<PredefinedColorSpace> colorSpace;
+};
+
+} // namespace WebCore
Copied: trunk/Source/WebCore/html/ImageDataSettings.idl (from rev 277568, trunk/Source/WebCore/html/canvas/PredefinedColorSpace.cpp) (0 => 277569)
--- trunk/Source/WebCore/html/ImageDataSettings.idl (rev 0)
+++ trunk/Source/WebCore/html/ImageDataSettings.idl 2021-05-16 15:21:34 UTC (rev 277569)
@@ -0,0 +1,29 @@
+/*
+ * Copyright (C) 2021 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+// https://html.spec.whatwg.org/multipage/canvas.html#imagedatasettings
+dictionary ImageDataSettings {
+ [EnabledBySetting=CanvasColorSpace] PredefinedColorSpace colorSpace;
+};
Modified: trunk/Source/WebCore/html/canvas/CanvasImageData.idl (277568 => 277569)
--- trunk/Source/WebCore/html/canvas/CanvasImageData.idl 2021-05-16 15:00:51 UTC (rev 277568)
+++ trunk/Source/WebCore/html/canvas/CanvasImageData.idl 2021-05-16 15:21:34 UTC (rev 277569)
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2017 Apple Inc. All rights reserved.
+ * Copyright (C) 2017-2021 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -26,9 +26,9 @@
// https://html.spec.whatwg.org/multipage/canvas.html#canvasimagedata
interface mixin CanvasImageData {
// pixel manipulation
- ImageData createImageData([EnforceRange] long sw, [EnforceRange] long sh);
+ ImageData createImageData([EnforceRange] long sw, [EnforceRange] long sh, optional ImageDataSettings settings);
ImageData createImageData(ImageData imagedata);
- ImageData getImageData([EnforceRange] long sx, [EnforceRange] long sy, [EnforceRange] long sw, [EnforceRange] long sh);
+ ImageData getImageData([EnforceRange] long sx, [EnforceRange] long sy, [EnforceRange] long sw, [EnforceRange] long sh, optional ImageDataSettings settings);
undefined putImageData(ImageData imagedata, [EnforceRange] long dx, [EnforceRange] long dy);
undefined putImageData(ImageData imagedata, [EnforceRange] long dx, [EnforceRange] long dy, [EnforceRange] long dirtyX, [EnforceRange] long dirtyY, [EnforceRange] long dirtyWidth, [EnforceRange] long dirtyHeight);
};
Modified: trunk/Source/WebCore/html/canvas/CanvasRenderingContext2DBase.cpp (277568 => 277569)
--- trunk/Source/WebCore/html/canvas/CanvasRenderingContext2DBase.cpp 2021-05-16 15:00:51 UTC (rev 277568)
+++ trunk/Source/WebCore/html/canvas/CanvasRenderingContext2DBase.cpp 2021-05-16 15:21:34 UTC (rev 277569)
@@ -2160,30 +2160,35 @@
return false;
}
-static RefPtr<ImageData> createEmptyImageData(const IntSize& size)
+static void initializeEmptyImageData(const ImageData& imageData)
{
- auto data = ""
- if (data)
- data->data().zeroFill();
- return data;
+ imageData.data().zeroFill();
}
-RefPtr<ImageData> CanvasRenderingContext2DBase::createImageData(ImageData& imageData) const
+ExceptionOr<Ref<ImageData>> CanvasRenderingContext2DBase::createImageData(ImageData& existingImageData) const
{
- return createEmptyImageData(imageData.size());
+ auto newImageData = ImageData::createUninitialized(existingImageData.width(), existingImageData.height(), existingImageData.colorSpace());
+ if (!newImageData.hasException())
+ initializeEmptyImageData(newImageData.returnValue());
+ return newImageData;
}
-ExceptionOr<RefPtr<ImageData>> CanvasRenderingContext2DBase::createImageData(int sw, int sh) const
+ExceptionOr<Ref<ImageData>> CanvasRenderingContext2DBase::createImageData(int sw, int sh, Optional<ImageDataSettings> settings) const
{
if (!sw || !sh)
return Exception { IndexSizeError };
- IntSize size { std::abs(sw), std::abs(sh) };
- return createEmptyImageData(size);
+ auto imageData = ImageData::createUninitialized(std::abs(sw), std::abs(sh), m_settings.colorSpace, settings);
+ if (!imageData.hasException())
+ initializeEmptyImageData(imageData.returnValue());
+ return imageData;
}
-ExceptionOr<RefPtr<ImageData>> CanvasRenderingContext2DBase::getImageData(int sx, int sy, int sw, int sh) const
+ExceptionOr<Ref<ImageData>> CanvasRenderingContext2DBase::getImageData(int sx, int sy, int sw, int sh, Optional<ImageDataSettings> settings) const
{
+ if (!sw || !sh)
+ return Exception { IndexSizeError };
+
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);
@@ -2190,9 +2195,6 @@
return Exception { SecurityError };
}
- if (!sw || !sh)
- return Exception { IndexSizeError };
-
if (sw < 0) {
sx += sw;
sw = -sw;
@@ -2205,10 +2207,16 @@
IntRect imageDataRect { sx, sy, sw, sh };
ImageBuffer* buffer = canvasBase().buffer();
- if (!buffer)
- return createEmptyImageData(imageDataRect.size());
+ if (!buffer) {
+ auto imageData = ImageData::createUninitialized(imageDataRect.width(), imageDataRect.height(), m_settings.colorSpace, settings);
+ if (!imageData.hasException())
+ initializeEmptyImageData(imageData.returnValue());
+ return imageData;
+ }
- PixelBufferFormat format { AlphaPremultiplication::Unpremultiplied, PixelFormat::RGBA8, DestinationColorSpace::SRGB };
+ auto computedColorSpace = ImageData::computeColorSpace(settings, m_settings.colorSpace);
+
+ PixelBufferFormat format { AlphaPremultiplication::Unpremultiplied, PixelFormat::RGBA8, toDestinationColorSpace(computedColorSpace) };
auto pixelBuffer = buffer->getPixelBuffer(format, imageDataRect);
if (!pixelBuffer) {
canvasBase().scriptExecutionContext()->addConsoleMessage(MessageSource::Rendering, MessageLevel::Error,
@@ -2216,6 +2224,8 @@
return Exception { InvalidStateError };
}
+ ASSERT(pixelBuffer->format().colorSpace == toDestinationColorSpace(computedColorSpace));
+
return { { ImageData::create(WTFMove(*pixelBuffer)) } };
}
Modified: trunk/Source/WebCore/html/canvas/CanvasRenderingContext2DBase.h (277568 => 277569)
--- trunk/Source/WebCore/html/canvas/CanvasRenderingContext2DBase.h 2021-05-16 15:00:51 UTC (rev 277568)
+++ trunk/Source/WebCore/html/canvas/CanvasRenderingContext2DBase.h 2021-05-16 15:21:34 UTC (rev 277569)
@@ -43,6 +43,7 @@
#include "GraphicsContext.h"
#include "GraphicsTypes.h"
#include "ImageBuffer.h"
+#include "ImageDataSettings.h"
#include "ImageSmoothingQuality.h"
#include "Path.h"
#include "PlatformLayer.h"
@@ -192,9 +193,9 @@
ExceptionOr<Ref<CanvasGradient>> createConicGradient(float angleInRadians, float x, float y);
ExceptionOr<RefPtr<CanvasPattern>> createPattern(CanvasImageSource&&, const String& repetition);
- RefPtr<ImageData> createImageData(ImageData&) const;
- ExceptionOr<RefPtr<ImageData>> createImageData(int width, int height) const;
- ExceptionOr<RefPtr<ImageData>> getImageData(int sx, int sy, int sw, int sh) const;
+ ExceptionOr<Ref<ImageData>> createImageData(ImageData&) const;
+ ExceptionOr<Ref<ImageData>> createImageData(int width, int height, Optional<ImageDataSettings>) const;
+ ExceptionOr<Ref<ImageData>> getImageData(int sx, int sy, int sw, int sh, Optional<ImageDataSettings>) const;
void putImageData(ImageData&, int dx, int dy);
void putImageData(ImageData&, int dx, int dy, int dirtyX, int dirtyY, int dirtyWidth, int dirtyHeight);
Modified: trunk/Source/WebCore/html/canvas/PredefinedColorSpace.cpp (277568 => 277569)
--- trunk/Source/WebCore/html/canvas/PredefinedColorSpace.cpp 2021-05-16 15:00:51 UTC (rev 277568)
+++ trunk/Source/WebCore/html/canvas/PredefinedColorSpace.cpp 2021-05-16 15:21:34 UTC (rev 277569)
@@ -27,6 +27,7 @@
#include "PredefinedColorSpace.h"
#include "ColorSpace.h"
+#include <wtf/Optional.h>
namespace WebCore {
@@ -45,4 +46,23 @@
return DestinationColorSpace::SRGB;
}
+Optional<PredefinedColorSpace> toPredefinedColorSpace(DestinationColorSpace colorSpace)
+{
+ switch (colorSpace) {
+ case DestinationColorSpace::SRGB:
+ return PredefinedColorSpace::SRGB;
+#if ENABLE(DESTINATION_COLOR_SPACE_LINEAR_SRGB)
+ case DestinationColorSpace::LinearSRGB:
+ return WTF::nullopt;
+#endif
+#if ENABLE(DESTINATION_COLOR_SPACE_DISPLAY_P3)
+ case DestinationColorSpace::DisplayP3:
+ return PredefinedColorSpace::DisplayP3;
+#endif
+ }
+
+ ASSERT_NOT_REACHED();
+ return WTF::nullopt;
}
+
+}
Modified: trunk/Source/WebCore/html/canvas/PredefinedColorSpace.h (277568 => 277569)
--- trunk/Source/WebCore/html/canvas/PredefinedColorSpace.h 2021-05-16 15:00:51 UTC (rev 277568)
+++ trunk/Source/WebCore/html/canvas/PredefinedColorSpace.h 2021-05-16 15:21:34 UTC (rev 277569)
@@ -26,6 +26,7 @@
#pragma once
#include <wtf/EnumTraits.h>
+#include <wtf/Forward.h>
namespace WebCore {
@@ -39,6 +40,7 @@
};
DestinationColorSpace toDestinationColorSpace(PredefinedColorSpace);
+Optional<PredefinedColorSpace> toPredefinedColorSpace(DestinationColorSpace);
}
Modified: trunk/Source/WebCore/inspector/InspectorCanvas.cpp (277568 => 277569)
--- trunk/Source/WebCore/inspector/InspectorCanvas.cpp 2021-05-16 15:00:51 UTC (rev 277568)
+++ trunk/Source/WebCore/inspector/InspectorCanvas.cpp 2021-05-16 15:21:34 UTC (rev 277569)
@@ -428,6 +428,12 @@
return {{ valueIndexForData(argument), RecordingSwizzleType::ImageData }};
}
+Optional<InspectorCanvasCallTracer::ProcessedArgument> InspectorCanvas::processArgument(ImageDataSettings&)
+{
+ // FIXME: Implement.
+ return WTF::nullopt;
+}
+
Optional<InspectorCanvasCallTracer::ProcessedArgument> InspectorCanvas::processArgument(ImageSmoothingQuality argument)
{
return {{ valueIndexForData(convertEnumerationToString(argument)), RecordingSwizzleType::String }};
Modified: trunk/Source/WebCore/inspector/InspectorCanvasCallTracer.cpp (277568 => 277569)
--- trunk/Source/WebCore/inspector/InspectorCanvasCallTracer.cpp 2021-05-16 15:00:51 UTC (rev 277568)
+++ trunk/Source/WebCore/inspector/InspectorCanvasCallTracer.cpp 2021-05-16 15:21:34 UTC (rev 277569)
@@ -37,6 +37,7 @@
#include "HTMLImageElement.h"
#include "HTMLVideoElement.h"
#include "ImageData.h"
+#include "ImageDataSettings.h"
#include "InspectorCanvasAgent.h"
#include "InspectorInstrumentation.h"
#include "InstrumentingAgents.h"
Modified: trunk/Source/WebCore/inspector/InspectorCanvasCallTracer.h (277568 => 277569)
--- trunk/Source/WebCore/inspector/InspectorCanvasCallTracer.h 2021-05-16 15:00:51 UTC (rev 277568)
+++ trunk/Source/WebCore/inspector/InspectorCanvasCallTracer.h 2021-05-16 15:21:34 UTC (rev 277569)
@@ -70,6 +70,7 @@
class WebGLUniformLocation;
class WebGLVertexArrayObject;
struct DOMMatrix2DInit;
+struct ImageDataSettings;
enum class RecordingSwizzleType : int;
enum class CanvasDirection;
enum class CanvasFillRule;
@@ -150,6 +151,7 @@
macro(HTMLImageElement*) \
macro(ImageBitmap*) \
macro(ImageData*) \
+ macro(ImageDataSettings&) \
macro(ImageSmoothingQuality) \
macro(Optional<float>&) \
macro(Path2D*) \
Modified: trunk/Source/WebCore/platform/graphics/ImageBufferBackend.cpp (277568 => 277569)
--- trunk/Source/WebCore/platform/graphics/ImageBufferBackend.cpp 2021-05-16 15:00:51 UTC (rev 277568)
+++ trunk/Source/WebCore/platform/graphics/ImageBufferBackend.cpp 2021-05-16 15:21:34 UTC (rev 277569)
@@ -116,6 +116,8 @@
Optional<PixelBuffer> ImageBufferBackend::getPixelBuffer(const PixelBufferFormat& destinationFormat, const IntRect& sourceRect, void* data) const
{
+ ASSERT(PixelBuffer::supportedPixelFormat(destinationFormat.pixelFormat));
+
auto sourceRectScaled = toBackendCoordinates(sourceRect);
auto pixelBuffer = PixelBuffer::tryCreate(destinationFormat, sourceRectScaled.size());
@@ -122,8 +124,8 @@
if (!pixelBuffer)
return WTF::nullopt;
- IntRect sourceRectClipped = intersection(backendRect(), sourceRectScaled);
- IntRect destinationRect = { IntPoint::zero(), sourceRectClipped.size() };
+ auto sourceRectClipped = intersection(backendRect(), sourceRectScaled);
+ IntRect destinationRect { IntPoint::zero(), sourceRectClipped.size() };
if (sourceRectScaled.x() < 0)
destinationRect.setX(-sourceRectScaled.x());
@@ -134,23 +136,15 @@
if (destinationRect.size() != sourceRectScaled.size())
pixelBuffer->data().zeroFill();
- unsigned sourceBytesPerRow = bytesPerRow();
- const uint8_t* sourceRows = reinterpret_cast<uint8_t*>(data) + sourceRectClipped.y() * sourceBytesPerRow + sourceRectClipped.x() * 4;
-
- unsigned destinationBytesPerRow = 4 * sourceRectScaled.width();
- uint8_t* destinationRows = pixelBuffer->data().data() + destinationRect.y() * destinationBytesPerRow + destinationRect.x() * 4;
-
- PixelBufferFormat sourceFormat { AlphaPremultiplication::Premultiplied, pixelFormat(), DestinationColorSpace::SRGB };
-
ConstPixelBufferConversionView source;
- source.format = sourceFormat;
- source.bytesPerRow = sourceBytesPerRow;
- source.rows = sourceRows;
+ source.format = { AlphaPremultiplication::Premultiplied, pixelFormat(), colorSpace() };
+ source.bytesPerRow = bytesPerRow();
+ source.rows = reinterpret_cast<uint8_t*>(data) + sourceRectClipped.y() * source.bytesPerRow + sourceRectClipped.x() * 4;
PixelBufferConversionView destination;
destination.format = destinationFormat;
- destination.bytesPerRow = destinationBytesPerRow;
- destination.rows = destinationRows;
+ destination.bytesPerRow = 4 * sourceRectScaled.width();
+ destination.rows = pixelBuffer->data().data() + destinationRect.y() * destination.bytesPerRow + destinationRect.x() * 4;
convertImagePixels(source, destination, destinationRect.size());
@@ -159,14 +153,11 @@
void ImageBufferBackend::putPixelBuffer(const PixelBuffer& sourcePixelBuffer, const IntRect& sourceRect, const IntPoint& destinationPoint, AlphaPremultiplication destinationAlphaFormat, void* data)
{
- // FIXME: Add support for non-RGBA8 pixel formats.
- ASSERT(sourcePixelBuffer.format().pixelFormat == PixelFormat::RGBA8);
-
auto sourceRectScaled = toBackendCoordinates(sourceRect);
auto destinationPointScaled = toBackendCoordinates(destinationPoint);
- IntRect sourceRectClipped = intersection({ IntPoint::zero(), sourcePixelBuffer.size() }, sourceRectScaled);
- IntRect destinationRect = sourceRectClipped;
+ auto sourceRectClipped = intersection({ IntPoint::zero(), sourcePixelBuffer.size() }, sourceRectScaled);
+ auto destinationRect = sourceRectClipped;
destinationRect.moveBy(destinationPointScaled);
if (sourceRectScaled.x() < 0)
@@ -178,24 +169,15 @@
destinationRect.intersect(backendRect());
sourceRectClipped.setSize(destinationRect.size());
- unsigned sourceBytesPerRow = 4 * sourcePixelBuffer.size().width();
- const uint8_t* sourceRows = sourcePixelBuffer.data().data() + sourceRectClipped.y() * sourceBytesPerRow + sourceRectClipped.x() * 4;
+ ConstPixelBufferConversionView source;
+ source.format = sourcePixelBuffer.format();
+ source.bytesPerRow = 4 * sourcePixelBuffer.size().width();
+ source.rows = sourcePixelBuffer.data().data() + sourceRectClipped.y() * source.bytesPerRow + sourceRectClipped.x() * 4;
- unsigned destinationBytesPerRow = bytesPerRow();
- uint8_t* destinationRows = reinterpret_cast<uint8_t*>(data) + destinationRect.y() * destinationBytesPerRow + destinationRect.x() * 4;
-
- PixelBufferFormat sourceFormat = sourcePixelBuffer.format();
- PixelBufferFormat destinationFormat { destinationAlphaFormat, pixelFormat(), DestinationColorSpace::SRGB };
-
- ConstPixelBufferConversionView source;
- source.format = sourceFormat;
- source.bytesPerRow = sourceBytesPerRow;
- source.rows = sourceRows;
-
PixelBufferConversionView destination;
- destination.format = destinationFormat;
- destination.bytesPerRow = destinationBytesPerRow;
- destination.rows = destinationRows;
+ destination.format = { destinationAlphaFormat, pixelFormat(), colorSpace() };
+ destination.bytesPerRow = bytesPerRow();
+ destination.rows = reinterpret_cast<uint8_t*>(data) + destinationRect.y() * destination.bytesPerRow + destinationRect.x() * 4;
convertImagePixels(source, destination, destinationRect.size());
}
Modified: trunk/Source/WebCore/platform/graphics/PixelBuffer.cpp (277568 => 277569)
--- trunk/Source/WebCore/platform/graphics/PixelBuffer.cpp 2021-05-16 15:00:51 UTC (rev 277568)
+++ trunk/Source/WebCore/platform/graphics/PixelBuffer.cpp 2021-05-16 15:21:34 UTC (rev 277569)
@@ -31,10 +31,22 @@
namespace WebCore {
+bool PixelBuffer::supportedPixelFormat(PixelFormat pixelFormat)
+{
+ switch (pixelFormat) {
+ case PixelFormat::RGBA8:
+ case PixelFormat::BGRA8:
+ return true;
+
+ case PixelFormat::RGB10:
+ case PixelFormat::RGB10A8:
+ return false;
+ }
+}
+
Checked<unsigned, RecordOverflow> PixelBuffer::computeBufferSize(const PixelBufferFormat& format, const IntSize& size)
{
- // NOTE: Only 8-bit formats are currently supported.
- ASSERT_UNUSED(format, format.pixelFormat == PixelFormat::RGBA8 || format.pixelFormat == PixelFormat::BGRA8);
+ ASSERT_UNUSED(format, supportedPixelFormat(format.pixelFormat));
constexpr unsigned bytesPerPixel = 4;
@@ -43,7 +55,7 @@
Optional<PixelBuffer> PixelBuffer::tryCreateForDecoding(const PixelBufferFormat& format, const IntSize& size, unsigned dataByteLength)
{
- ASSERT(format.pixelFormat == PixelFormat::RGBA8 || format.pixelFormat == PixelFormat::BGRA8);
+ ASSERT(supportedPixelFormat(format.pixelFormat));
ASSERT(computeBufferSize(format, size).unsafeGet() == dataByteLength);
auto pixelArray = Uint8ClampedArray::tryCreateUninitialized(dataByteLength);
@@ -54,8 +66,7 @@
Optional<PixelBuffer> PixelBuffer::tryCreate(const PixelBufferFormat& format, const IntSize& size)
{
- // NOTE: Only 8-bit formats are currently supported.
- ASSERT(format.pixelFormat == PixelFormat::RGBA8 || format.pixelFormat == PixelFormat::BGRA8);
+ ASSERT(supportedPixelFormat(format.pixelFormat));
auto bufferSize = computeBufferSize(format, size);
if (bufferSize.hasOverflowed())
@@ -66,6 +77,21 @@
return { { format, size, pixelArray.releaseNonNull() } };
}
+Optional<PixelBuffer> PixelBuffer::tryCreate(const PixelBufferFormat& format, const IntSize& size, Ref<JSC::ArrayBuffer>&& arrayBuffer)
+{
+ ASSERT(supportedPixelFormat(format.pixelFormat));
+
+ auto bufferSize = computeBufferSize(format, size);
+ if (bufferSize.hasOverflowed())
+ return WTF::nullopt;
+ if (bufferSize.unsafeGet() != arrayBuffer->byteLength())
+ return WTF::nullopt;
+ auto pixelArray = Uint8ClampedArray::tryCreate(WTFMove(arrayBuffer), 0, bufferSize.unsafeGet());
+ if (!pixelArray)
+ return WTF::nullopt;
+ return { { format, size, pixelArray.releaseNonNull() } };
+}
+
PixelBuffer::PixelBuffer(const PixelBufferFormat& format, const IntSize& size, Ref<JSC::Uint8ClampedArray>&& data)
: m_format { format }
, m_size { size }
@@ -74,6 +100,14 @@
RELEASE_ASSERT_WITH_SECURITY_IMPLICATION((m_size.area() * 4).unsafeGet() <= m_data->length());
}
+PixelBuffer::PixelBuffer(const PixelBufferFormat& format, const IntSize& size, JSC::Uint8ClampedArray& data)
+ : m_format { format }
+ , m_size { size }
+ , m_data { data }
+{
+ RELEASE_ASSERT_WITH_SECURITY_IMPLICATION((m_size.area() * 4).unsafeGet() <= m_data->length());
+}
+
PixelBuffer::~PixelBuffer() = default;
PixelBuffer PixelBuffer::deepClone() const
Modified: trunk/Source/WebCore/platform/graphics/PixelBuffer.h (277568 => 277569)
--- trunk/Source/WebCore/platform/graphics/PixelBuffer.h 2021-05-16 15:00:51 UTC (rev 277568)
+++ trunk/Source/WebCore/platform/graphics/PixelBuffer.h 2021-05-16 15:21:34 UTC (rev 277569)
@@ -41,9 +41,13 @@
class PixelBuffer {
WTF_MAKE_NONCOPYABLE(PixelBuffer);
public:
+ static bool supportedPixelFormat(PixelFormat);
+
WEBCORE_EXPORT static Optional<PixelBuffer> tryCreate(const PixelBufferFormat&, const IntSize&);
+ WEBCORE_EXPORT static Optional<PixelBuffer> tryCreate(const PixelBufferFormat&, const IntSize&, Ref<JSC::ArrayBuffer>&&);
PixelBuffer(const PixelBufferFormat&, const IntSize&, Ref<JSC::Uint8ClampedArray>&&);
+ PixelBuffer(const PixelBufferFormat&, const IntSize&, JSC::Uint8ClampedArray&);
WEBCORE_EXPORT ~PixelBuffer();
PixelBuffer(PixelBuffer&&) = default;
@@ -53,6 +57,8 @@
const IntSize& size() const { return m_size; }
JSC::Uint8ClampedArray& data() const { return m_data.get(); }
+ Ref<JSC::Uint8ClampedArray>&& takeData() { return WTFMove(m_data); }
+
PixelBuffer deepClone() const;
template<class Encoder> void encode(Encoder&) const;
Modified: trunk/Source/WebCore/platform/graphics/PixelBufferConversion.cpp (277568 => 277569)
--- trunk/Source/WebCore/platform/graphics/PixelBufferConversion.cpp 2021-05-16 15:00:51 UTC (rev 277568)
+++ trunk/Source/WebCore/platform/graphics/PixelBufferConversion.cpp 2021-05-16 15:21:34 UTC (rev 277569)
@@ -106,7 +106,7 @@
vImage_Error converterCreateError = kvImageNoError;
auto converter = adoptCF(vImageConverter_CreateWithCGImageFormat(&sourceCGImageFormat, &destinationCGImageFormat, nullptr, kvImageNoFlags, &converterCreateError));
- ASSERT_WITH_MESSAGE_UNUSED(converterCreateError, converterCreateError != kvImageNoError, "vImageConverter creation failed with error: %zd", converterCreateError);
+ ASSERT_WITH_MESSAGE_UNUSED(converterCreateError, converterCreateError == kvImageNoError, "vImageConverter creation failed with error: %zd", converterCreateError);
vImage_Error converterConvertError = vImageConvert_AnyToAny(converter.get(), &sourceVImageBuffer, &destinationVImageBuffer, nullptr, kvImageNoFlags);
ASSERT_WITH_MESSAGE_UNUSED(converterConvertError, converterConvertError == kvImageNoError, "vImageConvert_AnyToAny failed conversion with error: %zd", converterConvertError);
Modified: trunk/Source/WebCore/platform/graphics/filters/FilterEffect.cpp (277568 => 277569)
--- trunk/Source/WebCore/platform/graphics/filters/FilterEffect.cpp 2021-05-16 15:00:51 UTC (rev 277568)
+++ trunk/Source/WebCore/platform/graphics/filters/FilterEffect.cpp 2021-05-16 15:21:34 UTC (rev 277569)
@@ -468,7 +468,7 @@
// Color space conversion happens internally when drawing from one image buffer to another
convertedBuffer->context().drawImageBuffer(inputBuffer, rect);
- PixelBufferFormat format { outputAlphaFormat, PixelFormat::RGBA8, DestinationColorSpace::SRGB };
+ PixelBufferFormat format { outputAlphaFormat, PixelFormat::RGBA8, targetColorSpace };
return convertedBuffer->getPixelBuffer(format, rect);
}
@@ -504,7 +504,9 @@
copyConvertedImageBufferToDestination(destination, *colorSpace, AlphaPremultiplication::Unpremultiplied, rect);
return;
}
- PixelBufferFormat format { AlphaPremultiplication::Unpremultiplied, PixelFormat::RGBA8, DestinationColorSpace::SRGB };
+
+ ASSERT(m_imageBufferResult->colorSpace() == m_resultColorSpace);
+ PixelBufferFormat format { AlphaPremultiplication::Unpremultiplied, PixelFormat::RGBA8, m_resultColorSpace };
m_unmultipliedImageResult = m_imageBufferResult->getPixelBuffer(format, { IntPoint(), m_absolutePaintRect.size() });
if (!m_unmultipliedImageResult)
return;
@@ -512,7 +514,9 @@
IntSize inputSize(m_absolutePaintRect.size());
ASSERT(!ImageBuffer::sizeNeedsClamping(inputSize));
inputSize.scale(m_filter.filterScale());
- PixelBufferFormat format { AlphaPremultiplication::Unpremultiplied, PixelFormat::RGBA8, DestinationColorSpace::SRGB };
+
+ ASSERT(m_premultipliedImageResult->format().colorSpace == m_resultColorSpace);
+ PixelBufferFormat format { AlphaPremultiplication::Unpremultiplied, PixelFormat::RGBA8, m_resultColorSpace };
m_unmultipliedImageResult = PixelBuffer::tryCreate(format, inputSize);
if (!m_unmultipliedImageResult)
return;
@@ -539,7 +543,9 @@
copyConvertedImageBufferToDestination(destination, *colorSpace, AlphaPremultiplication::Premultiplied, rect);
return;
}
- PixelBufferFormat format { AlphaPremultiplication::Premultiplied, PixelFormat::RGBA8, DestinationColorSpace::SRGB };
+
+ ASSERT(m_imageBufferResult->colorSpace() == m_resultColorSpace);
+ PixelBufferFormat format { AlphaPremultiplication::Premultiplied, PixelFormat::RGBA8, m_resultColorSpace };
m_premultipliedImageResult = m_imageBufferResult->getPixelBuffer(format, { IntPoint(), m_absolutePaintRect.size() });
if (!m_premultipliedImageResult)
return;
@@ -547,7 +553,9 @@
IntSize inputSize(m_absolutePaintRect.size());
ASSERT(!ImageBuffer::sizeNeedsClamping(inputSize));
inputSize.scale(m_filter.filterScale());
- PixelBufferFormat format { AlphaPremultiplication::Premultiplied, PixelFormat::RGBA8, DestinationColorSpace::SRGB };
+
+ ASSERT(m_unmultipliedImageResult->format().colorSpace == m_resultColorSpace);
+ PixelBufferFormat format { AlphaPremultiplication::Premultiplied, PixelFormat::RGBA8, m_resultColorSpace };
m_premultipliedImageResult = PixelBuffer::tryCreate(format, inputSize);
if (!m_premultipliedImageResult)
return;
@@ -590,7 +598,7 @@
IntSize resultSize(m_absolutePaintRect.size());
ASSERT(!ImageBuffer::sizeNeedsClamping(resultSize));
resultSize.scale(m_filter.filterScale());
- PixelBufferFormat format { AlphaPremultiplication::Unpremultiplied, PixelFormat::RGBA8, DestinationColorSpace::SRGB };
+ PixelBufferFormat format { AlphaPremultiplication::Unpremultiplied, PixelFormat::RGBA8, m_resultColorSpace };
m_unmultipliedImageResult = PixelBuffer::tryCreate(format, resultSize);
return m_unmultipliedImageResult;
}
@@ -609,7 +617,7 @@
IntSize resultSize(m_absolutePaintRect.size());
ASSERT(!ImageBuffer::sizeNeedsClamping(resultSize));
resultSize.scale(m_filter.filterScale());
- PixelBufferFormat format { AlphaPremultiplication::Premultiplied, PixelFormat::RGBA8, DestinationColorSpace::SRGB };
+ PixelBufferFormat format { AlphaPremultiplication::Premultiplied, PixelFormat::RGBA8, m_resultColorSpace };
m_premultipliedImageResult = PixelBuffer::tryCreate(format, resultSize);
return m_premultipliedImageResult;
}
Modified: trunk/Source/WebCore/testing/Internals.cpp (277568 => 277569)
--- trunk/Source/WebCore/testing/Internals.cpp 2021-05-16 15:00:51 UTC (rev 277568)
+++ trunk/Source/WebCore/testing/Internals.cpp 2021-05-16 15:21:34 UTC (rev 277569)
@@ -5331,7 +5331,7 @@
if (!rgba)
return;
- auto imageData = ImageData::create(rgba.releaseNonNull(), videoSettings.width(), videoSettings.height());
+ auto imageData = ImageData::create(rgba.releaseNonNull(), videoSettings.width(), videoSettings.height(), { { PredefinedColorSpace::SRGB } });
if (!imageData.hasException())
m_nextTrackFramePromise->resolve(imageData.releaseReturnValue());
else
@@ -6203,7 +6203,7 @@
m_artworkImagePromise = makeUnique<ArtworkImagePromise>(WTFMove(promise));
m_artworkLoader = makeUnique<ArtworkImageLoader>(*contextDocument(), url, [this](Image* image) {
if (image) {
- auto imageData = ImageData::create(unsigned(image->width()), unsigned(image->height()));
+ auto imageData = ImageData::create(image->width(), image->height(), { { PredefinedColorSpace::SRGB } });
if (!imageData.hasException())
m_artworkImagePromise->resolve(imageData.releaseReturnValue());
else
Modified: trunk/Source/WebKitLegacy/win/ChangeLog (277568 => 277569)
--- trunk/Source/WebKitLegacy/win/ChangeLog 2021-05-16 15:00:51 UTC (rev 277568)
+++ trunk/Source/WebKitLegacy/win/ChangeLog 2021-05-16 15:21:34 UTC (rev 277569)
@@ -1,3 +1,18 @@
+2021-05-16 Sam Weinig <wei...@apple.com>
+
+ Add support for creating/accessing/setting non-sRGB ImageData via canvas
+ https://bugs.webkit.org/show_bug.cgi?id=225841
+
+ Reviewed by Darin Adler.
+
+ Add support for tests enabling the CanvasColorSpaceEnabled preference.
+
+ * WebPreferences.cpp:
+ (WebPreferences::canvasColorSpaceEnabled):
+ * WebPreferences.h:
+ * WebView.cpp:
+ (WebView::notifyPreferencesChanged):
+
2021-05-15 Ryosuke Niwa <rn...@webkit.org>
Delete WebSQL code from WebKit2
Modified: trunk/Source/WebKitLegacy/win/WebPreferences.cpp (277568 => 277569)
--- trunk/Source/WebKitLegacy/win/WebPreferences.cpp 2021-05-16 15:00:51 UTC (rev 277568)
+++ trunk/Source/WebKitLegacy/win/WebPreferences.cpp 2021-05-16 15:21:34 UTC (rev 277569)
@@ -2631,3 +2631,9 @@
}
return S_OK;
}
+
+bool WebPreferences::canvasColorSpaceEnabled()
+{
+ return boolValueForKey("WebKitCanvasColorSpaceEnabled");
+}
+
Modified: trunk/Source/WebKitLegacy/win/WebPreferences.h (277568 => 277569)
--- trunk/Source/WebKitLegacy/win/WebPreferences.h 2021-05-16 15:00:51 UTC (rev 277568)
+++ trunk/Source/WebKitLegacy/win/WebPreferences.h 2021-05-16 15:21:34 UTC (rev 277569)
@@ -343,6 +343,10 @@
HRESULT postPreferencesChangesNotification();
+ // The following preference accessors are not exposed via IWebPreferences* as they are only
+ // needed for testing purposes and can be toggled via the set*PreferenceForTesting functions.
+ bool canvasColorSpaceEnabled();
+
private:
WebPreferences();
~WebPreferences();
Modified: trunk/Source/WebKitLegacy/win/WebView.cpp (277568 => 277569)
--- trunk/Source/WebKitLegacy/win/WebView.cpp 2021-05-16 15:00:51 UTC (rev 277568)
+++ trunk/Source/WebKitLegacy/win/WebView.cpp 2021-05-16 15:21:34 UTC (rev 277569)
@@ -5667,6 +5667,8 @@
return hr;
settings.setOverscrollBehaviorEnabled(!!enabled);
+ settings.setCanvasColorSpaceEnabled(m_preferences->canvasColorSpaceEnabled());
+
return S_OK;
}