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,
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<StaticBitmapImage> 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<v8::Object> 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<v8::Value> pixel_array =
ToV8(data_.GetAsUint8ClampedArray().Get(), wrapper, isolate);
v8::Local<v8::Value> 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,
......
......@@ -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.
......
......@@ -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<DOMException>(
DOMExceptionCode::kInvalidStateError,
"Failed to allocate pixels for current frame."));
return promise;
}
base::CheckedNumeric<int> 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));
}
......
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