Skip to content

Commit

Permalink
ColorSpace: make image_data and shape_detector to support more data type
Browse files Browse the repository at this point in the history
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: Jeremy Roman <jbroman@chromium.org>
Reviewed-by: Fernando Serboncini <fserb@chromium.org>
Reviewed-by: Aaron Krajeski <aaronhk@chromium.org>
Reviewed-by: ccameron <ccameron@chromium.org>
Cr-Commit-Position: refs/heads/master@{#815886}
GitOrigin-RevId: 2c61200a15ab2d8cc93bf37be739c7a6460039a1
  • Loading branch information
yiyix authored and copybara-github committed Oct 10, 2020
1 parent 2958dc4 commit 7ec753d
Show file tree
Hide file tree
Showing 3 changed files with 29 additions and 22 deletions.
33 changes: 23 additions & 10 deletions blink/renderer/core/html/canvas/image_data.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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 ||
Expand All @@ -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(),
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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,
Expand Down
1 change: 1 addition & 0 deletions blink/renderer/core/html/canvas/image_data.h
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
17 changes: 5 additions & 12 deletions blink/renderer/modules/shapedetection/shape_detector.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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));
}
Expand Down

0 comments on commit 7ec753d

Please sign in to comment.