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)); }