diff --git a/blink/renderer/core/html/canvas/image_data.cc b/blink/renderer/core/html/canvas/image_data.cc
index 7c2f5aa4d6f7..772f6eebf957 100644
--- a/blink/renderer/core/html/canvas/image_data.cc
+++ b/blink/renderer/core/html/canvas/image_data.cc
@@ -336,8 +336,6 @@ ImageData* ImageData::Create(scoped_refptr image,
if (!image_data)
return nullptr;
- // TODO(crbug.com/1115317): Verify if the color type uint16 needs to be
- // considered separately.
ImageDataArray data = image_data->data();
SkColorType color_type = image_info.colorType();
bool create_f32_image_data = (color_type == kRGBA_1010102_SkColorType ||
@@ -346,9 +344,15 @@ ImageData* ImageData::Create(scoped_refptr image,
color_type == kRGBA_F32_SkColorType);
if (!create_f32_image_data) {
- image_info = image_info.makeColorType(kRGBA_8888_SkColorType);
- paint_image.readPixels(image_info, data.GetAsUint8ClampedArray()->Data(),
- image_info.minRowBytes(), 0, 0);
+ if (color_type == kR16G16B16A16_unorm_SkColorType) {
+ image_info = image_info.makeColorType(kR16G16B16A16_unorm_SkColorType);
+ paint_image.readPixels(image_info, data.GetAsUint16Array()->Data(),
+ image_info.minRowBytes(), 0, 0);
+ } else {
+ image_info = image_info.makeColorType(kRGBA_8888_SkColorType);
+ paint_image.readPixels(image_info, data.GetAsUint8ClampedArray()->Data(),
+ image_info.minRowBytes(), 0, 0);
+ }
} else {
image_info = image_info.makeColorType(kRGBA_F32_SkColorType);
paint_image.readPixels(image_info, data.GetAsFloat32Array()->Data(),
@@ -620,13 +624,11 @@ v8::Local ImageData::AssociateWithWrapper(
ScriptWrappable::AssociateWithWrapper(isolate, wrapper_type, wrapper);
if (!wrapper.IsEmpty() && data_.IsUint8ClampedArray()) {
- // Create a V8 Uint8ClampedArray object and set the "data" property
+ // Create a V8 object with |data_| and set the "data" property
// of the ImageData object to the created v8 object, eliminating the
// C++ callback when accessing the "data" property.
- // TODO(crbug.com/1115317): |pixel_array| should be compatible with uint_8,
- // float16 and float32.
- v8::Local pixel_array =
- ToV8(data_.GetAsUint8ClampedArray().Get(), wrapper, isolate);
+
+ v8::Local pixel_array = ToV8(data_, wrapper, isolate);
bool defined_property;
if (pixel_array.IsEmpty() ||
!wrapper
@@ -793,6 +795,17 @@ CanvasColorParams ImageData::GetCanvasColorParams() {
kNonOpaque);
}
+SkImageInfo ImageData::GetSkImageInfo() {
+ SkColorType color_type = kN32_SkColorType;
+ if (data_u16_) {
+ color_type = kR16G16B16A16_unorm_SkColorType;
+ } else if (data_f32_) {
+ color_type = kRGBA_F32_SkColorType;
+ }
+ return SkImageInfo::Make(width(), height(), color_type,
+ GetCanvasColorParams().GetSkAlphaType());
+}
+
bool ImageData::ImageDataInCanvasColorSettings(
CanvasColorSpace canvas_color_space,
CanvasPixelFormat canvas_pixel_format,
diff --git a/blink/renderer/core/html/canvas/image_data.h b/blink/renderer/core/html/canvas/image_data.h
index 6283c49c9383..66d026c6ff8b 100644
--- a/blink/renderer/core/html/canvas/image_data.h
+++ b/blink/renderer/core/html/canvas/image_data.h
@@ -149,6 +149,7 @@ class CORE_EXPORT ImageData final : public ScriptWrappable,
DOMArrayBufferBase* BufferBase() const;
CanvasColorParams GetCanvasColorParams();
+ SkImageInfo GetSkImageInfo();
// DataU8ColorType param specifies if the converted pixels in uint8 pixel
// format should respect the "native" 32bit ARGB format of Skia's blitters.
diff --git a/blink/renderer/modules/shapedetection/shape_detector.cc b/blink/renderer/modules/shapedetection/shape_detector.cc
index cb8f225eafc1..28715ca1f407 100644
--- a/blink/renderer/modules/shapedetection/shape_detector.cc
+++ b/blink/renderer/modules/shapedetection/shape_detector.cc
@@ -120,24 +120,17 @@ ScriptPromise ShapeDetector::DetectShapesOnImageData(
}
SkBitmap sk_bitmap;
- if (!sk_bitmap.tryAllocPixels(
- SkImageInfo::Make(image_data->width(), image_data->height(),
- kN32_SkColorType, kOpaque_SkAlphaType),
- image_data->width() * 4 /* bytes per pixel */)) {
+ SkImageInfo sk_image_info = image_data->GetSkImageInfo();
+ if (!sk_bitmap.tryAllocPixels(sk_image_info, sk_image_info.minRowBytes())) {
resolver->Reject(MakeGarbageCollected(
DOMExceptionCode::kInvalidStateError,
"Failed to allocate pixels for current frame."));
return promise;
}
- base::CheckedNumeric allocation_size = image_data->Size().Area() * 4;
- CHECK_EQ(allocation_size.ValueOrDefault(0), sk_bitmap.computeByteSize());
-
- // TODO(crbug.com/1115317): Should be compatible with uint_8, float16 and
- // float32.
- memcpy(sk_bitmap.getPixels(),
- image_data->data().GetAsUint8ClampedArray()->Data(),
- sk_bitmap.computeByteSize());
+ size_t byte_size = sk_bitmap.computeByteSize();
+ CHECK_EQ(byte_size, image_data->BufferBase()->ByteLengthAsSizeT());
+ memcpy(sk_bitmap.getPixels(), image_data->BufferBase()->Data(), byte_size);
return DoDetect(resolver, std::move(sk_bitmap));
}