Commit 2c61200a authored by yiyix's avatar yiyix Committed by Commit Bot

ColorSpace: make image_data and shape_detector to support more data type

After the cl, Merge ImageData::data_union into ImageData::data. Some
code assume the data type is uint8 array and the size per pixel is 4. I
left some TODOs in the code to address all the remaining problems. This
cl addresses all issues in image_data and shape_detector.

ref cl: https://chromium-review.googlesource.com/c/chromium/src/+/2379653

Bug: 1115317
Change-Id: If46ea1cc6986d8e2c1e4b40e8f98ecd55b31d9dc
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2437606
Commit-Queue: Yi Xu <yiyix@chromium.org>
Reviewed-by: default avatarJeremy Roman <jbroman@chromium.org>
Reviewed-by: default avatarFernando Serboncini <fserb@chromium.org>
Reviewed-by: default avatarAaron Krajeski <aaronhk@chromium.org>
Reviewed-by: default avatarccameron <ccameron@chromium.org>
Cr-Commit-Position: refs/heads/master@{#815886}
parent 17172936
...@@ -336,8 +336,6 @@ ImageData* ImageData::Create(scoped_refptr<StaticBitmapImage> image, ...@@ -336,8 +336,6 @@ ImageData* ImageData::Create(scoped_refptr<StaticBitmapImage> image,
if (!image_data) if (!image_data)
return nullptr; return nullptr;
// TODO(crbug.com/1115317): Verify if the color type uint16 needs to be
// considered separately.
ImageDataArray data = image_data->data(); ImageDataArray data = image_data->data();
SkColorType color_type = image_info.colorType(); SkColorType color_type = image_info.colorType();
bool create_f32_image_data = (color_type == kRGBA_1010102_SkColorType || bool create_f32_image_data = (color_type == kRGBA_1010102_SkColorType ||
...@@ -346,9 +344,15 @@ ImageData* ImageData::Create(scoped_refptr<StaticBitmapImage> image, ...@@ -346,9 +344,15 @@ ImageData* ImageData::Create(scoped_refptr<StaticBitmapImage> image,
color_type == kRGBA_F32_SkColorType); color_type == kRGBA_F32_SkColorType);
if (!create_f32_image_data) { if (!create_f32_image_data) {
image_info = image_info.makeColorType(kRGBA_8888_SkColorType); if (color_type == kR16G16B16A16_unorm_SkColorType) {
paint_image.readPixels(image_info, data.GetAsUint8ClampedArray()->Data(), image_info = image_info.makeColorType(kR16G16B16A16_unorm_SkColorType);
image_info.minRowBytes(), 0, 0); 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 { } else {
image_info = image_info.makeColorType(kRGBA_F32_SkColorType); image_info = image_info.makeColorType(kRGBA_F32_SkColorType);
paint_image.readPixels(image_info, data.GetAsFloat32Array()->Data(), paint_image.readPixels(image_info, data.GetAsFloat32Array()->Data(),
...@@ -620,13 +624,11 @@ v8::Local<v8::Object> ImageData::AssociateWithWrapper( ...@@ -620,13 +624,11 @@ v8::Local<v8::Object> ImageData::AssociateWithWrapper(
ScriptWrappable::AssociateWithWrapper(isolate, wrapper_type, wrapper); ScriptWrappable::AssociateWithWrapper(isolate, wrapper_type, wrapper);
if (!wrapper.IsEmpty() && data_.IsUint8ClampedArray()) { 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 // of the ImageData object to the created v8 object, eliminating the
// C++ callback when accessing the "data" property. // C++ callback when accessing the "data" property.
// TODO(crbug.com/1115317): |pixel_array| should be compatible with uint_8,
// float16 and float32. v8::Local<v8::Value> pixel_array = ToV8(data_, wrapper, isolate);
v8::Local<v8::Value> pixel_array =
ToV8(data_.GetAsUint8ClampedArray().Get(), wrapper, isolate);
bool defined_property; bool defined_property;
if (pixel_array.IsEmpty() || if (pixel_array.IsEmpty() ||
!wrapper !wrapper
...@@ -793,6 +795,17 @@ CanvasColorParams ImageData::GetCanvasColorParams() { ...@@ -793,6 +795,17 @@ CanvasColorParams ImageData::GetCanvasColorParams() {
kNonOpaque); 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( bool ImageData::ImageDataInCanvasColorSettings(
CanvasColorSpace canvas_color_space, CanvasColorSpace canvas_color_space,
CanvasPixelFormat canvas_pixel_format, CanvasPixelFormat canvas_pixel_format,
......
...@@ -149,6 +149,7 @@ class CORE_EXPORT ImageData final : public ScriptWrappable, ...@@ -149,6 +149,7 @@ class CORE_EXPORT ImageData final : public ScriptWrappable,
DOMArrayBufferBase* BufferBase() const; DOMArrayBufferBase* BufferBase() const;
CanvasColorParams GetCanvasColorParams(); CanvasColorParams GetCanvasColorParams();
SkImageInfo GetSkImageInfo();
// DataU8ColorType param specifies if the converted pixels in uint8 pixel // DataU8ColorType param specifies if the converted pixels in uint8 pixel
// format should respect the "native" 32bit ARGB format of Skia's blitters. // format should respect the "native" 32bit ARGB format of Skia's blitters.
......
...@@ -120,24 +120,17 @@ ScriptPromise ShapeDetector::DetectShapesOnImageData( ...@@ -120,24 +120,17 @@ ScriptPromise ShapeDetector::DetectShapesOnImageData(
} }
SkBitmap sk_bitmap; SkBitmap sk_bitmap;
if (!sk_bitmap.tryAllocPixels( SkImageInfo sk_image_info = image_data->GetSkImageInfo();
SkImageInfo::Make(image_data->width(), image_data->height(), if (!sk_bitmap.tryAllocPixels(sk_image_info, sk_image_info.minRowBytes())) {
kN32_SkColorType, kOpaque_SkAlphaType),
image_data->width() * 4 /* bytes per pixel */)) {
resolver->Reject(MakeGarbageCollected<DOMException>( resolver->Reject(MakeGarbageCollected<DOMException>(
DOMExceptionCode::kInvalidStateError, DOMExceptionCode::kInvalidStateError,
"Failed to allocate pixels for current frame.")); "Failed to allocate pixels for current frame."));
return promise; return promise;
} }
base::CheckedNumeric<int> allocation_size = image_data->Size().Area() * 4; size_t byte_size = sk_bitmap.computeByteSize();
CHECK_EQ(allocation_size.ValueOrDefault(0), sk_bitmap.computeByteSize()); CHECK_EQ(byte_size, image_data->BufferBase()->ByteLengthAsSizeT());
memcpy(sk_bitmap.getPixels(), image_data->BufferBase()->Data(), byte_size);
// 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());
return DoDetect(resolver, std::move(sk_bitmap)); return DoDetect(resolver, std::move(sk_bitmap));
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment