Index: third_party/WebKit/Source/core/html/ImageData.cpp |
diff --git a/third_party/WebKit/Source/core/html/ImageData.cpp b/third_party/WebKit/Source/core/html/ImageData.cpp |
index 71f62d53ec0f11a90325a9f64cf1f43c52ad19a3..c9caef7366f8e2d9b12123cdcf1d3a32c921c9e6 100644 |
--- a/third_party/WebKit/Source/core/html/ImageData.cpp |
+++ b/third_party/WebKit/Source/core/html/ImageData.cpp |
@@ -367,6 +367,77 @@ ImageData* ImageData::CreateForTest( |
return new ImageData(size, buffer_view, color_settings); |
} |
+bool ImageData::CompareImageDataColorSettingsForTest(ImageData* image_data_1, |
+ ImageData* image_data_2) { |
+ ImageDataColorSettings color_settings_1, color_settings_2; |
+ image_data_1->getColorSettings(color_settings_1); |
+ image_data_2->getColorSettings(color_settings_2); |
+ return color_settings_1.colorSpace() == color_settings_2.colorSpace() && |
+ color_settings_1.storageFormat() == color_settings_2.storageFormat(); |
+} |
+ |
+ImageData* ImageData::MakeCopy() { |
+ unsigned data_length = size_.Width() * size_.Height() * 4; |
+ DOMArrayBufferView* buffer_view = AllocateAndValidateDataArray( |
+ data_length, |
+ ImageData::GetImageDataStorageFormat(color_settings_.storageFormat())); |
+ if (!buffer_view) |
+ return nullptr; |
+ std::memcpy(buffer_view->View()->Buffer()->Data(), BufferBase()->Data(), |
+ data_length * buffer_view->TypeSize()); |
+ return new ImageData(size_, buffer_view, &color_settings_); |
+} |
+ |
+// Crops ImageData to the intersect of its size and the given rectangle. If the |
+// intersection is empty or it cannot create the cropped ImageData it returns |
+// nullptr. This function leaves the source ImageData intact. When crop_rect |
+// covers all the ImageData and the copy parameter is false, "this" is returned. |
+// Otherwise, a copy of the ImageData is returned. |
+ImageData* ImageData::MakeSubset(const IntRect& crop_rect, bool enforce_copy) { |
+ IntRect src_rect(IntPoint(), size_); |
+ const IntRect dst_rect = Intersection(src_rect, crop_rect); |
+ if (dst_rect.IsEmpty()) |
+ return nullptr; |
+ if (src_rect == dst_rect) { |
+ if (enforce_copy) |
+ return MakeCopy(); |
+ return this; |
+ } |
+ |
+ unsigned data_size = 4 * dst_rect.Width() * dst_rect.Height(); |
+ DOMUint8ClampedArray* data_u8 = nullptr; |
+ DOMUint16Array* data_u16 = nullptr; |
+ DOMFloat32Array* data_f32 = nullptr; |
+ if (data_) |
+ data_u8 = AllocateAndValidateUint8ClampedArray(data_size); |
+ else if (data_u16_) |
+ data_u16 = AllocateAndValidateUint16Array(data_size); |
+ else if (data_f32_) |
+ data_f32 = AllocateAndValidateFloat32Array(data_size); |
+ |
+ int src_index = 0, dst_index = 0; |
+ for (int i = 0; i < dst_rect.Height(); i++) { |
+ src_index = ((i + dst_rect.X()) * src_rect.Width() + dst_rect.Y()) * 4; |
+ dst_index = i * dst_rect.Width() * 4; |
+ if (data_) { |
+ std::memcpy(data_u8->Data() + dst_index, data_->Data() + src_index, |
+ dst_rect.Width() * 4); |
+ } else if (data_u16_) { |
+ std::memcpy(data_u16->Data() + dst_index, data_u16_->Data() + src_index, |
+ dst_rect.Width() * 8); |
+ } else if (data_f32_) { |
+ std::memcpy(data_f32->Data() + dst_index, data_f32_->Data() + src_index, |
+ dst_rect.Width() * 16); |
+ } |
+ } |
+ |
+ if (data_) |
+ return new ImageData(dst_rect.Size(), data_u8, &color_settings_); |
+ if (data_u16_) |
+ return new ImageData(dst_rect.Size(), data_u16, &color_settings_); |
+ return new ImageData(dst_rect.Size(), data_f32, &color_settings_); |
+} |
+ |
ScriptPromise ImageData::CreateImageBitmap(ScriptState* script_state, |
EventTarget& event_target, |
Optional<IntRect> crop_rect, |
@@ -603,38 +674,6 @@ sk_sp<SkColorSpace> ImageData::GetSkColorSpace() { |
return SkColorSpace::MakeSRGB(); |
} |
-// This function returns the proper SkColorSpace to color correct the pixels |
-// stored in ImageData before copying to the canvas. For now, it assumes that |
-// both ImageData and canvas use a linear gamma curve. |
-sk_sp<SkColorSpace> ImageData::GetSkColorSpace( |
- const CanvasColorSpace& color_space, |
- const CanvasPixelFormat& pixel_format) { |
- switch (color_space) { |
- case kLegacyCanvasColorSpace: |
- return (gfx::ColorSpace::CreateSRGB()).ToSkColorSpace(); |
- case kSRGBCanvasColorSpace: |
- if (pixel_format == kF16CanvasPixelFormat) |
- return (gfx::ColorSpace::CreateSCRGBLinear()).ToSkColorSpace(); |
- return (gfx::ColorSpace::CreateSRGB()).ToSkColorSpace(); |
- case kRec2020CanvasColorSpace: |
- return (gfx::ColorSpace(gfx::ColorSpace::PrimaryID::BT2020, |
- gfx::ColorSpace::TransferID::LINEAR)) |
- .ToSkColorSpace(); |
- case kP3CanvasColorSpace: |
- return (gfx::ColorSpace(gfx::ColorSpace::PrimaryID::SMPTEST432_1, |
- gfx::ColorSpace::TransferID::LINEAR)) |
- .ToSkColorSpace(); |
- } |
- NOTREACHED(); |
- return nullptr; |
-} |
- |
-sk_sp<SkColorSpace> ImageData::GetSkColorSpaceForTest( |
- const CanvasColorSpace& color_space, |
- const CanvasPixelFormat& pixel_format) { |
- return GetSkColorSpace(color_space, pixel_format); |
-} |
- |
bool ImageData::ImageDataInCanvasColorSettings( |
const CanvasColorSpace& canvas_color_space, |
const CanvasPixelFormat& canvas_pixel_format, |
@@ -693,16 +732,18 @@ bool ImageData::ImageDataInCanvasColorSettings( |
sk_sp<SkColorSpace> src_color_space = nullptr; |
if (data_) { |
- src_color_space = ImageData::GetSkColorSpace(image_data_color_space, |
- kRGBA8CanvasPixelFormat); |
+ src_color_space = |
+ CanvasColorParams(image_data_color_space, kRGBA8CanvasPixelFormat) |
+ .GetSkColorSpaceForSkSurfaces(); |
} else { |
- src_color_space = ImageData::GetSkColorSpace(image_data_color_space, |
- kF16CanvasPixelFormat); |
+ src_color_space = |
+ CanvasColorParams(image_data_color_space, kF16CanvasPixelFormat) |
+ .GetSkColorSpaceForSkSurfaces(); |
} |
sk_sp<SkColorSpace> dst_color_space = |
- ImageData::GetSkColorSpace(canvas_color_space, canvas_pixel_format); |
- |
+ CanvasColorParams(canvas_color_space, canvas_pixel_format) |
+ .GetSkColorSpaceForSkSurfaces(); |
SkColorSpaceXform::ColorFormat dst_color_format = |
SkColorSpaceXform::ColorFormat::kRGBA_8888_ColorFormat; |
if (canvas_pixel_format == kF16CanvasPixelFormat) |