WebKit Bugzilla
New
Browse
Search+
Log In
×
Sign in with GitHub
or
Remember my login
Create Account
·
Forgot Password
Forgotten password account recovery
[patch]
Patch
bug-225841-20210515193752.patch (text/plain), 88.35 KB, created by
Sam Weinig
on 2021-05-15 19:37:53 PDT
(
hide
)
Description:
Patch
Filename:
MIME Type:
Creator:
Sam Weinig
Created:
2021-05-15 19:37:53 PDT
Size:
88.35 KB
patch
obsolete
>Index: Source/WebCore/ChangeLog >=================================================================== >--- Source/WebCore/ChangeLog (revision 277544) >+++ Source/WebCore/ChangeLog (working copy) >@@ -1,3 +1,142 @@ >+2021-05-15 Sam Weinig <weinig@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-15 Alan Bujtas <zalan@apple.com> > > [LFC] Move table wrapper quirks to its own class >Index: Source/WebCore/CMakeLists.txt >=================================================================== >--- Source/WebCore/CMakeLists.txt (revision 277544) >+++ Source/WebCore/CMakeLists.txt (working copy) >@@ -1017,6 +1017,7 @@ set(WebCore_NON_SVG_IDL_FILES > html/ImageBitmap.idl > html/ImageBitmapOptions.idl > html/ImageData.idl >+ html/ImageDataSettings.idl > html/MediaController.idl > html/MediaEncryptedEvent.idl > html/MediaError.idl >Index: Source/WebCore/DerivedSources-input.xcfilelist >=================================================================== >--- Source/WebCore/DerivedSources-input.xcfilelist (revision 277544) >+++ Source/WebCore/DerivedSources-input.xcfilelist (working copy) >@@ -1036,6 +1036,7 @@ $(PROJECT_DIR)/html/HTMLVideoElement.idl > $(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 >Index: Source/WebCore/DerivedSources-output.xcfilelist >=================================================================== >--- Source/WebCore/DerivedSources-output.xcfilelist (revision 277544) >+++ Source/WebCore/DerivedSources-output.xcfilelist (working copy) >@@ -1180,6 +1180,8 @@ $(BUILT_PRODUCTS_DIR)/DerivedSources/Web > $(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 >Index: Source/WebCore/DerivedSources.make >=================================================================== >--- Source/WebCore/DerivedSources.make (revision 277544) >+++ Source/WebCore/DerivedSources.make (working copy) >@@ -890,6 +890,7 @@ JS_BINDING_IDLS := \ > $(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 \ >Index: Source/WebCore/Sources.txt >=================================================================== >--- Source/WebCore/Sources.txt (revision 277544) >+++ Source/WebCore/Sources.txt (working copy) >@@ -3207,6 +3207,7 @@ JSImageBitmapOptions.cpp > JSImageBitmapRenderingContext.cpp > JSImageBitmapRenderingContextSettings.cpp > JSImageData.cpp >+JSImageDataSettings.cpp > JSImageSmoothingQuality.cpp > JSInputEvent.cpp > JSInspectorAuditAccessibilityObject.cpp >Index: Source/WebCore/WebCore.xcodeproj/project.pbxproj >=================================================================== >--- Source/WebCore/WebCore.xcodeproj/project.pbxproj (revision 277544) >+++ Source/WebCore/WebCore.xcodeproj/project.pbxproj (working copy) >@@ -4095,6 +4095,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, ); }; }; >@@ -14315,6 +14316,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>"; }; >@@ -23926,6 +23929,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 */, >@@ -32887,6 +32892,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 */, >Index: Source/WebCore/bindings/js/SerializedScriptValue.cpp >=================================================================== >--- Source/WebCore/bindings/js/SerializedScriptValue.cpp (revision 277544) >+++ Source/WebCore/bindings/js/SerializedScriptValue.cpp (working copy) >@@ -3141,30 +3141,24 @@ private: > 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); >Index: Source/WebCore/html/ImageData.cpp >=================================================================== >--- Source/WebCore/html/ImageData.cpp (revision 277544) >+++ Source/WebCore/html/ImageData.cpp (working copy) >@@ -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,57 +43,85 @@ Checked<unsigned, RecordOverflow> ImageD > 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) > { > 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? > 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 @@ ExceptionOr<Ref<ImageData>> ImageData::c > 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) >Index: Source/WebCore/html/ImageData.h >=================================================================== >--- Source/WebCore/html/ImageData.h (revision 277544) >+++ Source/WebCore/html/ImageData.h (working copy) >@@ -29,7 +29,12 @@ > #pragma once > > #include "ExceptionOr.h" >+#include "ImageDataSettings.h" >+#include "IntSize.h" > #include "PixelBuffer.h" >+#include "PredefinedColorSpace.h" >+#include <JavaScriptCore/Uint8ClampedArray.h> >+#include <wtf/Forward.h> > > namespace WebCore { > >@@ -38,29 +43,32 @@ public: > 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&&); >- >- static Checked<unsigned, RecordOverflow> dataSize(const IntSize&); >+ explicit ImageData(const IntSize&, Ref<JSC::Uint8ClampedArray>&&, PredefinedColorSpace); > >- 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 >Index: Source/WebCore/html/ImageData.idl >=================================================================== >--- Source/WebCore/html/ImageData.idl (revision 277544) >+++ Source/WebCore/html/ImageData.idl (working copy) >@@ -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; > }; >Index: Source/WebCore/html/ImageDataSettings.h >=================================================================== >--- Source/WebCore/html/ImageDataSettings.h (nonexistent) >+++ Source/WebCore/html/ImageDataSettings.h (working copy) >@@ -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 >Index: Source/WebCore/html/ImageDataSettings.idl >=================================================================== >--- Source/WebCore/html/ImageDataSettings.idl (nonexistent) >+++ Source/WebCore/html/ImageDataSettings.idl (working copy) >@@ -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; >+}; >Index: Source/WebCore/html/canvas/CanvasImageData.idl >=================================================================== >--- Source/WebCore/html/canvas/CanvasImageData.idl (revision 277544) >+++ Source/WebCore/html/canvas/CanvasImageData.idl (working copy) >@@ -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); > }; >Index: Source/WebCore/html/canvas/CanvasRenderingContext2DBase.cpp >=================================================================== >--- Source/WebCore/html/canvas/CanvasRenderingContext2DBase.cpp (revision 277544) >+++ Source/WebCore/html/canvas/CanvasRenderingContext2DBase.cpp (working copy) >@@ -2152,39 +2152,41 @@ bool CanvasRenderingContext2DBase::needs > return false; > } > >-static RefPtr<ImageData> createEmptyImageData(const IntSize& size) >+static void initializeEmptyImageData(const ImageData& imageData) > { >- auto data = ImageData::create(size); >- 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); > return Exception { SecurityError }; > } > >- if (!sw || !sh) >- return Exception { IndexSizeError }; >- > if (sw < 0) { > sx += sw; > sw = -sw; >@@ -2197,10 +2199,16 @@ ExceptionOr<RefPtr<ImageData>> CanvasRen > 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, >@@ -2208,6 +2216,8 @@ ExceptionOr<RefPtr<ImageData>> CanvasRen > return Exception { InvalidStateError }; > } > >+ ASSERT(pixelBuffer->format().colorSpace == toDestinationColorSpace(computedColorSpace)); >+ > return { { ImageData::create(WTFMove(*pixelBuffer)) } }; > } > >Index: Source/WebCore/html/canvas/CanvasRenderingContext2DBase.h >=================================================================== >--- Source/WebCore/html/canvas/CanvasRenderingContext2DBase.h (revision 277544) >+++ Source/WebCore/html/canvas/CanvasRenderingContext2DBase.h (working copy) >@@ -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" >@@ -191,9 +192,9 @@ public: > ExceptionOr<Ref<CanvasGradient>> createRadialGradient(float x0, float y0, float r0, float x1, float y1, float r1); > 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); > >Index: Source/WebCore/html/canvas/PredefinedColorSpace.cpp >=================================================================== >--- Source/WebCore/html/canvas/PredefinedColorSpace.cpp (revision 277544) >+++ Source/WebCore/html/canvas/PredefinedColorSpace.cpp (working copy) >@@ -27,6 +27,7 @@ > #include "PredefinedColorSpace.h" > > #include "ColorSpace.h" >+#include <wtf/Optional.h> > > namespace WebCore { > >@@ -45,4 +46,23 @@ DestinationColorSpace toDestinationColor > 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; >+} >+ > } >Index: Source/WebCore/html/canvas/PredefinedColorSpace.h >=================================================================== >--- Source/WebCore/html/canvas/PredefinedColorSpace.h (revision 277544) >+++ Source/WebCore/html/canvas/PredefinedColorSpace.h (working copy) >@@ -26,6 +26,7 @@ > #pragma once > > #include <wtf/EnumTraits.h> >+#include <wtf/Forward.h> > > namespace WebCore { > >@@ -39,6 +40,7 @@ enum class PredefinedColorSpace { > }; > > DestinationColorSpace toDestinationColorSpace(PredefinedColorSpace); >+Optional<PredefinedColorSpace> toPredefinedColorSpace(DestinationColorSpace); > > } > >Index: Source/WebCore/inspector/InspectorCanvas.cpp >=================================================================== >--- Source/WebCore/inspector/InspectorCanvas.cpp (revision 277544) >+++ Source/WebCore/inspector/InspectorCanvas.cpp (working copy) >@@ -428,6 +428,12 @@ Optional<InspectorCanvasCallTracer::Proc > 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 }}; >Index: Source/WebCore/inspector/InspectorCanvasCallTracer.cpp >=================================================================== >--- Source/WebCore/inspector/InspectorCanvasCallTracer.cpp (revision 277544) >+++ Source/WebCore/inspector/InspectorCanvasCallTracer.cpp (working copy) >@@ -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" >Index: Source/WebCore/inspector/InspectorCanvasCallTracer.h >=================================================================== >--- Source/WebCore/inspector/InspectorCanvasCallTracer.h (revision 277544) >+++ Source/WebCore/inspector/InspectorCanvasCallTracer.h (working copy) >@@ -70,6 +70,7 @@ class WebGLTransformFeedback; > class WebGLUniformLocation; > class WebGLVertexArrayObject; > struct DOMMatrix2DInit; >+struct ImageDataSettings; > enum class RecordingSwizzleType : int; > enum class CanvasDirection; > enum class CanvasFillRule; >@@ -150,6 +151,7 @@ enum ImageSmoothingQuality; > macro(HTMLImageElement*) \ > macro(ImageBitmap*) \ > macro(ImageData*) \ >+ macro(ImageDataSettings&) \ > macro(ImageSmoothingQuality) \ > macro(Optional<float>&) \ > macro(Path2D*) \ >Index: Source/WebCore/platform/graphics/ImageBufferBackend.cpp >=================================================================== >--- Source/WebCore/platform/graphics/ImageBufferBackend.cpp (revision 277544) >+++ Source/WebCore/platform/graphics/ImageBufferBackend.cpp (working copy) >@@ -116,14 +116,16 @@ Vector<uint8_t> ImageBufferBackend::toBG > > 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()); > 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 @@ Optional<PixelBuffer> ImageBufferBackend > 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 @@ Optional<PixelBuffer> ImageBufferBackend > > 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 @@ void ImageBufferBackend::putPixelBuffer( > 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; >- >- 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; >- >+ source.format = sourcePixelBuffer.format(); >+ source.bytesPerRow = 4 * sourcePixelBuffer.size().width(); >+ source.rows = sourcePixelBuffer.data().data() + sourceRectClipped.y() * source.bytesPerRow + sourceRectClipped.x() * 4; >+ > 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()); > } >Index: Source/WebCore/platform/graphics/PixelBuffer.cpp >=================================================================== >--- Source/WebCore/platform/graphics/PixelBuffer.cpp (revision 277544) >+++ Source/WebCore/platform/graphics/PixelBuffer.cpp (working copy) >@@ -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 @@ Checked<unsigned, RecordOverflow> PixelB > > 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::tryCr > > 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 @@ Optional<PixelBuffer> PixelBuffer::tryCr > 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 @@ PixelBuffer::PixelBuffer(const PixelBuff > 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 >Index: Source/WebCore/platform/graphics/PixelBuffer.h >=================================================================== >--- Source/WebCore/platform/graphics/PixelBuffer.h (revision 277544) >+++ Source/WebCore/platform/graphics/PixelBuffer.h (working copy) >@@ -41,9 +41,13 @@ namespace WebCore { > 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 @@ public: > 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; >Index: Source/WebCore/platform/graphics/PixelBufferConversion.cpp >=================================================================== >--- Source/WebCore/platform/graphics/PixelBufferConversion.cpp (revision 277544) >+++ Source/WebCore/platform/graphics/PixelBufferConversion.cpp (working copy) >@@ -106,7 +106,7 @@ static void convertImagePixelsAccelerate > > 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); >Index: Source/WebCore/platform/graphics/filters/FilterEffect.cpp >=================================================================== >--- Source/WebCore/platform/graphics/filters/FilterEffect.cpp (revision 277544) >+++ Source/WebCore/platform/graphics/filters/FilterEffect.cpp (working copy) >@@ -468,7 +468,7 @@ Optional<PixelBuffer> FilterEffect::conv > // 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 @@ void FilterEffect::copyUnmultipliedResul > 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 @@ void FilterEffect::copyUnmultipliedResul > 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 @@ void FilterEffect::copyPremultipliedResu > 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 @@ void FilterEffect::copyPremultipliedResu > 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 @@ Optional<PixelBuffer>& FilterEffect::cre > 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 @@ Optional<PixelBuffer>& FilterEffect::cre > 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; > } >Index: Source/WebCore/testing/Internals.cpp >=================================================================== >--- Source/WebCore/testing/Internals.cpp (revision 277544) >+++ Source/WebCore/testing/Internals.cpp (working copy) >@@ -5331,7 +5331,7 @@ void Internals::videoSampleAvailable(Med > 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 @@ void Internals::loadArtworkImage(String& > 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 >Index: Source/WebKitLegacy/win/ChangeLog >=================================================================== >--- Source/WebKitLegacy/win/ChangeLog (revision 277552) >+++ Source/WebKitLegacy/win/ChangeLog (working copy) >@@ -1,3 +1,18 @@ >+2021-05-15 Sam Weinig <weinig@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-14 Chris Dumez <cdumez@apple.com> > > Drop legacy / prefixed WebAudio implementation >Index: Source/WebKitLegacy/win/WebPreferences.cpp >=================================================================== >--- Source/WebKitLegacy/win/WebPreferences.cpp (revision 277544) >+++ Source/WebKitLegacy/win/WebPreferences.cpp (working copy) >@@ -2631,3 +2631,9 @@ HRESULT WebPreferences::stopBatchingUpda > } > return S_OK; > } >+ >+bool WebPreferences::canvasColorSpaceEnabled() >+{ >+ return boolValueForKey("WebKitCanvasColorSpaceBehaviorEnabled"); >+} >+ >Index: Source/WebKitLegacy/win/WebPreferences.h >=================================================================== >--- Source/WebKitLegacy/win/WebPreferences.h (revision 277544) >+++ Source/WebKitLegacy/win/WebPreferences.h (working copy) >@@ -343,6 +343,10 @@ public: > > 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(); >Index: Source/WebKitLegacy/win/WebView.cpp >=================================================================== >--- Source/WebKitLegacy/win/WebView.cpp (revision 277544) >+++ Source/WebKitLegacy/win/WebView.cpp (working copy) >@@ -5667,6 +5667,8 @@ HRESULT WebView::notifyPreferencesChange > return hr; > settings.setOverscrollBehaviorEnabled(!!enabled); > >+ settings.setCanvasColorSpaceEnabled(m_preferences->canvasColorSpaceEnabled()); >+ > return S_OK; > } > >Index: LayoutTests/ChangeLog >=================================================================== >--- LayoutTests/ChangeLog (revision 277551) >+++ LayoutTests/ChangeLog (working copy) >@@ -1,3 +1,33 @@ >+2021-05-15 Sam Weinig <weinig@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-15 Said Abou-Hallawa <said@apple.com> > > Implement CanvasRenderingContext2D.createConicGradient >Index: LayoutTests/TestExpectations >=================================================================== >--- LayoutTests/TestExpectations (revision 277544) >+++ LayoutTests/TestExpectations (working copy) >@@ -3994,9 +3994,6 @@ imported/w3c/web-platform-tests/html/can > 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 ] >Index: LayoutTests/fast/canvas/canvas-color-space-display-p3-ImageData-expected.txt >=================================================================== >--- LayoutTests/fast/canvas/canvas-color-space-display-p3-ImageData-expected.txt (nonexistent) >+++ LayoutTests/fast/canvas/canvas-color-space-display-p3-ImageData-expected.txt (working copy) >@@ -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 >+ >Index: LayoutTests/fast/canvas/canvas-color-space-display-p3-ImageData.html >=================================================================== >--- LayoutTests/fast/canvas/canvas-color-space-display-p3-ImageData.html (nonexistent) >+++ LayoutTests/fast/canvas/canvas-color-space-display-p3-ImageData.html (working copy) >@@ -0,0 +1,290 @@ >+<!DOCTYPE html> >+<html> >+<head> >+<script src="../../resources/js-test-pre.js"></script> >+</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 = contextDisplayP3.getImageData(0, 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 = contextDisplayP3.getImageData(0, 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 = contextDisplayP3.getImageData(0, 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 = contextDisplayP3.getImageData(0, 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 = contextDisplayP3.getImageData(0, 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 = contextDisplayP3.getImageData(0, 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 = contextSRGB.getImageData(0, 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 = contextSRGB.getImageData(0, 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 = contextSRGB.getImageData(0, 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 = contextSRGB.getImageData(0, 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 = contextSRGB.getImageData(0, 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 = contextSRGB.getImageData(0, 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 = contextDisplayP3.getImageData(0, 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 = contextDisplayP3.getImageData(0, 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 = contextDisplayP3.getImageData(0, 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 = contextDisplayP3.getImageData(0, 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 = contextSRGB.getImageData(0, 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 = contextSRGB.getImageData(0, 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 = contextSRGB.getImageData(0, 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 = contextSRGB.getImageData(0, 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="../../resources/js-test-post.js"></script> >+</body> >+</html> >Index: LayoutTests/fast/canvas/canvas-imageData-expected.txt >=================================================================== >--- LayoutTests/fast/canvas/canvas-imageData-expected.txt (revision 277544) >+++ LayoutTests/fast/canvas/canvas-imageData-expected.txt (working copy) >@@ -14,20 +14,20 @@ PASS new ImageData(-20, 20) threw except > 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. >Index: LayoutTests/imported/w3c/ChangeLog >=================================================================== >--- LayoutTests/imported/w3c/ChangeLog (revision 277544) >+++ LayoutTests/imported/w3c/ChangeLog (working copy) >@@ -1,3 +1,13 @@ >+2021-05-15 Sam Weinig <weinig@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-14 Darin Adler <darin@apple.com> > > output element doesn't react properly to node tree mutations >Index: LayoutTests/imported/w3c/web-platform-tests/html/canvas/element/wide-gamut-canvas/2d.color.space.p3.to.p3-expected.txt >=================================================================== >--- LayoutTests/imported/w3c/web-platform-tests/html/canvas/element/wide-gamut-canvas/2d.color.space.p3.to.p3-expected.txt (revision 277544) >+++ LayoutTests/imported/w3c/web-platform-tests/html/canvas/element/wide-gamut-canvas/2d.color.space.p3.to.p3-expected.txt (working copy) >@@ -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 > >Index: LayoutTests/platform/glib/TestExpectations >=================================================================== >--- LayoutTests/platform/glib/TestExpectations (revision 277544) >+++ LayoutTests/platform/glib/TestExpectations (working copy) >@@ -2358,6 +2358,7 @@ fast/replaced/pdf-as-embed-with-no-mime- > 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. >Index: LayoutTests/platform/win/TestExpectations >=================================================================== >--- LayoutTests/platform/win/TestExpectations (revision 277544) >+++ LayoutTests/platform/win/TestExpectations (working copy) >@@ -4633,4 +4633,5 @@ webexposed/counter-style-image-symbols-n > > 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-ImageData.html [ Skip ] >Index: LayoutTests/storage/indexeddb/modern/objectstore-autoincrement-types-expected.txt >=================================================================== >--- LayoutTests/storage/indexeddb/modern/objectstore-autoincrement-types-expected.txt (revision 277544) >+++ LayoutTests/storage/indexeddb/modern/objectstore-autoincrement-types-expected.txt (working copy) >@@ -26,6 +26,7 @@ PASS key is 3 > 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[1].type is file.type > 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
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Flags:
ews-feeder
:
commit-queue-
Actions:
View
|
Formatted Diff
|
Diff
Attachments on
bug 225841
:
428713
|
428728
|
428733
|
428734
|
428735
|
428751
|
428766
|
428772
|
428787