Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(77)

Unified Diff: third_party/WebKit/Source/core/frame/ImageBitmap.cpp

Issue 2845193002: Refactor ImageBitmap constructor from ImageData to be color managed
Patch Set: local commit - all working except unpremultiply Created 3 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: third_party/WebKit/Source/core/frame/ImageBitmap.cpp
diff --git a/third_party/WebKit/Source/core/frame/ImageBitmap.cpp b/third_party/WebKit/Source/core/frame/ImageBitmap.cpp
index 663540f6512bf5d998b12fc8914a6903285018b2..0874cedeed4dca843ee408011a8585811e0d46e2 100644
--- a/third_party/WebKit/Source/core/frame/ImageBitmap.cpp
+++ b/third_party/WebKit/Source/core/frame/ImageBitmap.cpp
@@ -18,6 +18,7 @@
#include "third_party/skia/include/core/SkCanvas.h"
#include "third_party/skia/include/core/SkImageInfo.h"
#include "third_party/skia/include/core/SkSurface.h"
+#include "third_party/skia/include/core/SkSwizzle.h"
namespace blink {
@@ -152,6 +153,9 @@ ParsedOptions ParseOptions(const ImageBitmapOptions& options,
return parsed_options;
}
+// The function dstBufferSizeHasOverflow() is being called at the beginning of
+// each ImageBitmap() constructor, which makes sure that doing
+// width * height * bytesPerPixel will never overflow unsigned.
bool DstBufferSizeHasOverflow(const ParsedOptions& options) {
CheckedNumeric<unsigned> total_bytes = options.crop_rect.Width();
total_bytes *= options.crop_rect.Height();
@@ -174,11 +178,28 @@ bool DstBufferSizeHasOverflow(const ParsedOptions& options) {
} // namespace
+static void PrintSkImage(sk_sp<SkImage> input) {
+ SkImageInfo info =
+ SkImageInfo::Make(input->width(), input->height(), kN32_SkColorType,
+ kPremul_SkAlphaType, input->refColorSpace());
+ LOG(ERROR) << "Printing SkImage:" << input->width() << "," << input->height();
+ std::stringstream str;
+ std::unique_ptr<uint8_t[]> read_pixels(
+ new uint8_t[input->width() * input->height() * 4]());
+ input->readPixels(info, read_pixels.get(), input->width() * 4, 0, 0);
+ for (int i = 0; i < input->width() * input->height(); i++) {
+ if (i % input->width() == 0)
+ str << "\n";
+ str << "[";
+ for (int j = 0; j < 4; j++)
+ str << (int)(read_pixels[i * 4 + j]) << ",";
+ str << "] ";
+ }
+ LOG(ERROR) << str.str();
+}
+
static PassRefPtr<Uint8Array> CopySkImageData(SkImage* input,
const SkImageInfo& info) {
- // The function dstBufferSizeHasOverflow() is being called at the beginning of
- // each ImageBitmap() constructor, which makes sure that doing
- // width * height * bytesPerPixel will never overflow unsigned.
unsigned width = static_cast<unsigned>(input->width());
RefPtr<ArrayBuffer> dst_buffer =
ArrayBuffer::CreateOrNull(width * input->height(), info.bytesPerPixel());
@@ -202,38 +223,6 @@ static sk_sp<SkImage> NewSkImageFromRaster(const SkImageInfo& info,
image_pixels.LeakRef());
}
-static void SwizzleImageData(unsigned char* src_addr,
- unsigned height,
- unsigned bytes_per_row,
- bool flip_y) {
- if (flip_y) {
- for (unsigned i = 0; i < height / 2; i++) {
- unsigned top_row_start_position = i * bytes_per_row;
- unsigned bottom_row_start_position = (height - 1 - i) * bytes_per_row;
- if (kN32_SkColorType == kBGRA_8888_SkColorType) { // needs to swizzle
- for (unsigned j = 0; j < bytes_per_row; j += 4) {
- std::swap(src_addr[top_row_start_position + j],
- src_addr[bottom_row_start_position + j + 2]);
- std::swap(src_addr[top_row_start_position + j + 1],
- src_addr[bottom_row_start_position + j + 1]);
- std::swap(src_addr[top_row_start_position + j + 2],
- src_addr[bottom_row_start_position + j]);
- std::swap(src_addr[top_row_start_position + j + 3],
- src_addr[bottom_row_start_position + j + 3]);
- }
- } else {
- std::swap_ranges(src_addr + top_row_start_position,
- src_addr + top_row_start_position + bytes_per_row,
- src_addr + bottom_row_start_position);
- }
- }
- } else {
- if (kN32_SkColorType == kBGRA_8888_SkColorType) // needs to swizzle
- for (unsigned i = 0; i < height * bytes_per_row; i += 4)
- std::swap(src_addr[i], src_addr[i + 2]);
- }
-}
-
enum AlphaPremultiplyEnforcement {
kEnforceAlphaPremultiply,
kDontEnforceAlphaPremultiply,
@@ -275,9 +264,32 @@ static sk_sp<SkImage> PremulSkImageToUnPremul(
const ParsedOptions& options = DefaultOptions()) {
SkImageInfo info = SkImageInfo::Make(
input->width(), input->height(), options.color_params.GetSkColorType(),
- kUnpremul_SkAlphaType, input->refColorSpace());
+ kPremul_SkAlphaType, options.color_params.GetSkColorSpaceForSkSurfaces());
+
+ LOG(ERROR) << "Premul:";
+ std::stringstream str;
+ std::unique_ptr<uint8_t[]> read_pixels(new uint8_t[64]());
+ input->readPixels(info, read_pixels.get(), input->width() * 4, 0, 0);
+ for (int i = 0; i < 16; i++) {
+ str << "[";
+ for (int j = 0; j < 4; j++)
+ str << (int)(read_pixels[i * 4 + j]) << ",";
+ str << "] ";
+ }
+ LOG(ERROR) << str.str();
+ info = info.makeAlphaType(kUnpremul_SkAlphaType);
RefPtr<Uint8Array> dst_pixels = CopySkImageData(input, info);
+ LOG(ERROR) << "Unpremul:";
+ str.str("");
+ for (int i = 0; i < 16; i++) {
+ str << "[";
+ for (int j = 0; j < 4; j++)
+ str << (int)(dst_pixels->Data()[i * 4 + j]) << ",";
+ str << "] ";
+ }
+ LOG(ERROR) << str.str();
+
if (!dst_pixels)
return nullptr;
return NewSkImageFromRaster(
@@ -305,10 +317,8 @@ static void ApplyColorSpaceConversion(sk_sp<SkImage>& image,
if (!options.color_canvas_extensions_enabled)
return;
- sk_sp<SkColorSpace> dst_color_space = nullptr;
- SkColorType dst_color_type = kN32_SkColorType;
- dst_color_space = options.color_params.GetSkColorSpace();
- dst_color_type = options.color_params.GetSkColorType();
+ SkColorType dst_color_type = options.color_params.GetSkColorType();
+ sk_sp<SkColorSpace> dst_color_space = options.color_params.GetSkColorSpace();
if (SkColorSpace::Equals(image->colorSpace(), dst_color_space.get()))
return;
@@ -321,15 +331,16 @@ static void ApplyColorSpaceConversion(sk_sp<SkImage>& image,
if (dst_data->size() != size)
return;
sk_sp<SkImage> colored_image = nullptr;
+ // The desired way to apply color space conversion on a SkImage is to use
+ // SkImage::readPixels.
if (image->readPixels(dst_info, dst_data->writable_data(),
image->width() * dst_info.bytesPerPixel(), 0, 0)) {
colored_image = SkImage::MakeRasterData(
dst_info, dst_data, image->width() * dst_info.bytesPerPixel());
} else {
- // The desired way to apply color space conversion on a SkImage is to use
- // SkImage::readPixels. However, if the SkImage is GPU-backed, readPixels
- // still might not work properly. In this case, we fall back to drawing
- // the SkImage to a canvas and reading back the result.
+ // However, if the SkImage is GPU-backed, readPixels might not work
+ // properly. In this case, we fall back to drawing the SkImage to a
+ // canvas and reading back the result.
// Skia does not support drawing to unpremul surfaces/canvases.
sk_sp<SkImage> un_premul_image = nullptr;
if (image->alphaType() == kUnpremul_SkAlphaType) {
@@ -411,32 +422,32 @@ static PassRefPtr<StaticBitmapImage> CropImageAndApplyColorSpaceConversion(
IntRect img_rect(IntPoint(), IntSize(image->width(), image->height()));
const IntRect src_rect = Intersection(img_rect, parsed_options.crop_rect);
- // In the case when cropRect doesn't intersect the source image and it
- // requires a umpremul image We immediately return a transparent black image
- // with cropRect.size()
- if (src_rect.IsEmpty() && !parsed_options.premultiply_alpha) {
+ // In the case when cropRect doesn't intersect the source image, we
+ // return a transparent black image, respecting the color_params but
+ // ignoring premultiply_alpha.
+ if (src_rect.IsEmpty()) {
SkImageInfo info = SkImageInfo::Make(
- parsed_options.resize_width, parsed_options.resize_height,
- kN32_SkColorType, kUnpremul_SkAlphaType);
- RefPtr<ArrayBuffer> dst_buffer = ArrayBuffer::CreateOrNull(
- static_cast<unsigned>(info.width()) * info.height(),
- info.bytesPerPixel());
- if (!dst_buffer)
+ parsed_options.crop_rect.Width(), parsed_options.crop_rect.Height(),
+ parsed_options.color_params.GetSkColorType(), kPremul_SkAlphaType,
+ parsed_options.color_params.GetSkColorSpace());
+ if (parsed_options.should_scale_input) {
+ info = info.makeWH(parsed_options.resize_width,
+ parsed_options.resize_height);
+ }
+ sk_sp<SkSurface> surface = SkSurface::MakeRaster(info);
+ if (!surface)
return nullptr;
- RefPtr<Uint8Array> dst_pixels =
- Uint8Array::Create(dst_buffer, 0, dst_buffer->ByteLength());
- return StaticBitmapImage::Create(NewSkImageFromRaster(
- info, std::move(dst_pixels),
- static_cast<unsigned>(info.width()) * info.bytesPerPixel()));
+ return StaticBitmapImage::Create(surface->makeImageSnapshot());
}
sk_sp<SkImage> skia_image = image->ImageForCurrentFrame();
- // Attempt to get raw unpremultiplied image data, executed only when skiaImage
- // is premultiplied.
+ // Attempt to get raw unpremultiplied image data, executed only when
+ // skia_image is premultiplied.
if ((((!parsed_options.premultiply_alpha && !skia_image->isOpaque()) ||
!skia_image) &&
image->Data() && image_format == kPremultiplyAlpha) ||
color_behavior.IsIgnore()) {
+ LOG(ERROR) << "HERE...";
std::unique_ptr<ImageDecoder> decoder(ImageDecoder::Create(
image->Data(), true,
parsed_options.premultiply_alpha ? ImageDecoder::kAlphaPremultiplied
@@ -454,8 +465,7 @@ static PassRefPtr<StaticBitmapImage> CropImageAndApplyColorSpaceConversion(
return nullptr;
}
- if (parsed_options.crop_rect == src_rect &&
- !parsed_options.should_scale_input) {
+ if (!parsed_options.should_scale_input) {
sk_sp<SkImage> cropped_sk_image = skia_image->makeSubset(src_rect);
ApplyColorSpaceConversion(cropped_sk_image, parsed_options);
if (parsed_options.flip_y) {
@@ -473,52 +483,52 @@ static PassRefPtr<StaticBitmapImage> CropImageAndApplyColorSpaceConversion(
return StaticBitmapImage::Create(std::move(cropped_sk_image));
}
- sk_sp<SkSurface> surface = SkSurface::MakeRasterN32Premul(
- parsed_options.resize_width, parsed_options.resize_height);
+ LOG(ERROR) << "HERE...";
+ SkImageInfo info = SkImageInfo::Make(
+ parsed_options.resize_width, parsed_options.resize_height,
+ parsed_options.color_params.GetSkColorType(),
+ parsed_options.premultiply_alpha ? kPremul_SkAlphaType
+ : kUnpremul_SkAlphaType,
+ parsed_options.color_params.GetSkColorSpace());
+ sk_sp<SkSurface> surface = SkSurface::MakeRaster(info);
if (!surface)
return nullptr;
- if (src_rect.IsEmpty())
- return StaticBitmapImage::Create(surface->makeImageSnapshot());
-
- SkScalar dst_left = std::min(0, -parsed_options.crop_rect.X());
- SkScalar dst_top = std::min(0, -parsed_options.crop_rect.Y());
- if (parsed_options.crop_rect.X() < 0)
- dst_left = -parsed_options.crop_rect.X();
- if (parsed_options.crop_rect.Y() < 0)
- dst_top = -parsed_options.crop_rect.Y();
if (parsed_options.flip_y) {
surface->getCanvas()->translate(0, surface->height());
surface->getCanvas()->scale(1, -1);
}
- if (parsed_options.should_scale_input) {
- SkRect draw_src_rect = SkRect::MakeXYWH(
- parsed_options.crop_rect.X(), parsed_options.crop_rect.Y(),
- parsed_options.crop_rect.Width(), parsed_options.crop_rect.Height());
- SkRect draw_dst_rect = SkRect::MakeXYWH(0, 0, parsed_options.resize_width,
- parsed_options.resize_height);
- SkPaint paint;
- paint.setFilterQuality(parsed_options.resize_quality);
- surface->getCanvas()->drawImageRect(skia_image, draw_src_rect,
- draw_dst_rect, &paint);
- } else {
- surface->getCanvas()->drawImage(skia_image, dst_left, dst_top);
- }
+
+ SkRect draw_src_rect(parsed_options.crop_rect);
+ SkRect draw_dst_rect =
+ SkRect::MakeWH(parsed_options.resize_width, parsed_options.resize_height);
+ SkPaint paint;
+ paint.setFilterQuality(parsed_options.resize_quality);
+ surface->getCanvas()->drawImageRect(skia_image, draw_src_rect, draw_dst_rect,
+ &paint);
+
skia_image = surface->makeImageSnapshot();
+ PrintSkImage(skia_image);
ApplyColorSpaceConversion(skia_image, parsed_options);
+ PrintSkImage(skia_image);
if (parsed_options.premultiply_alpha) {
+ LOG(ERROR) << "HERE";
if (image_format == kDontPremultiplyAlpha)
return StaticBitmapImage::Create(
UnPremulSkImageToPremul(skia_image.get()));
return StaticBitmapImage::Create(std::move(skia_image));
}
- return StaticBitmapImage::Create(PremulSkImageToUnPremul(skia_image.get()));
+ LOG(ERROR) << "HERE";
+ return StaticBitmapImage::Create(std::move(skia_image));
+ // return StaticBitmapImage::Create(
+ // PremulSkImageToUnPremul(skia_image.get(), parsed_options));
}
ImageBitmap::ImageBitmap(ImageElementBase* image,
Optional<IntRect> crop_rect,
Document* document,
const ImageBitmapOptions& options) {
+ LOG(ERROR) << "Entering...";
RefPtr<Image> input = image->CachedImage()->GetImage();
ParsedOptions parsed_options =
ParseOptions(options, crop_rect, image->BitmapSourceSize());
@@ -566,6 +576,7 @@ ImageBitmap::ImageBitmap(HTMLVideoElement* video,
Optional<IntRect> crop_rect,
Document* document,
const ImageBitmapOptions& options) {
+ LOG(ERROR) << "Entering...";
IntSize player_size;
if (video->GetWebMediaPlayer())
player_size = video->GetWebMediaPlayer()->NaturalSize();
@@ -604,7 +615,7 @@ ImageBitmap::ImageBitmap(HTMLVideoElement* video,
sk_sp<SkImage> skia_image =
buffer->NewSkImageSnapshot(kPreferNoAcceleration, kSnapshotReasonUnknown);
if (!parsed_options.premultiply_alpha)
- skia_image = PremulSkImageToUnPremul(skia_image.get());
+ skia_image = PremulSkImageToUnPremul(skia_image.get(), parsed_options);
if (!skia_image)
return;
image_ = StaticBitmapImage::Create(std::move(skia_image));
@@ -616,6 +627,7 @@ ImageBitmap::ImageBitmap(HTMLVideoElement* video,
ImageBitmap::ImageBitmap(HTMLCanvasElement* canvas,
Optional<IntRect> crop_rect,
const ImageBitmapOptions& options) {
+ LOG(ERROR) << "Entering...";
DCHECK(canvas->IsPaintable());
RefPtr<Image> input;
if (canvas->PlaceholderFrame()) {
@@ -641,8 +653,8 @@ ImageBitmap::ImageBitmap(HTMLCanvasElement* canvas,
return;
if (is_premultiply_alpha_reverted) {
parsed_options.premultiply_alpha = false;
- image_ = StaticBitmapImage::Create(
- PremulSkImageToUnPremul(image_->ImageForCurrentFrame().get()));
+ image_ = StaticBitmapImage::Create(PremulSkImageToUnPremul(
+ image_->ImageForCurrentFrame().get(), parsed_options));
}
if (!image_)
return;
@@ -653,6 +665,7 @@ ImageBitmap::ImageBitmap(HTMLCanvasElement* canvas,
ImageBitmap::ImageBitmap(OffscreenCanvas* offscreen_canvas,
Optional<IntRect> crop_rect,
const ImageBitmapOptions& options) {
+ LOG(ERROR) << "Entering...";
SourceImageStatus status;
RefPtr<Image> input = offscreen_canvas->GetSourceImageForCanvas(
&status, kPreferNoAcceleration, kSnapshotReasonCreateImageBitmap,
@@ -676,8 +689,8 @@ ImageBitmap::ImageBitmap(OffscreenCanvas* offscreen_canvas,
return;
if (is_premultiply_alpha_reverted) {
parsed_options.premultiply_alpha = false;
- image_ = StaticBitmapImage::Create(
- PremulSkImageToUnPremul(image_->ImageForCurrentFrame().get()));
+ image_ = StaticBitmapImage::Create(PremulSkImageToUnPremul(
+ image_->ImageForCurrentFrame().get(), parsed_options));
}
if (!image_)
return;
@@ -690,6 +703,7 @@ ImageBitmap::ImageBitmap(const void* pixel_data,
uint32_t height,
bool is_image_bitmap_premultiplied,
bool is_image_bitmap_origin_clean) {
+ LOG(ERROR) << "Entering...";
SkImageInfo info = SkImageInfo::MakeN32(width, height,
is_image_bitmap_premultiplied
? kPremul_SkAlphaType
@@ -703,209 +717,156 @@ ImageBitmap::ImageBitmap(const void* pixel_data,
}
static sk_sp<SkImage> ScaleSkImage(sk_sp<SkImage> sk_image,
+ const SkImageInfo& sk_image_info,
unsigned resize_width,
unsigned resize_height,
- SkFilterQuality resize_quality,
- SkColorType color_type = kN32_SkColorType,
- sk_sp<SkColorSpace> color_space = nullptr) {
- SkImageInfo resized_info =
- SkImageInfo::Make(resize_width, resize_height, color_type,
- kUnpremul_SkAlphaType, color_space);
+ SkFilterQuality resize_quality) {
+ SkImageInfo resized_info = sk_image_info.makeWH(resize_width, resize_height);
RefPtr<ArrayBuffer> dst_buffer = ArrayBuffer::CreateOrNull(
resize_width * resize_height, resized_info.bytesPerPixel());
if (!dst_buffer)
return nullptr;
- if (color_type == kN32_SkColorType) {
- RefPtr<Uint8Array> resized_pixels =
- Uint8Array::Create(dst_buffer, 0, dst_buffer->ByteLength());
- SkPixmap pixmap(
- resized_info, resized_pixels->Data(),
- static_cast<unsigned>(resize_width) * resized_info.bytesPerPixel());
- sk_image->scalePixels(pixmap, resize_quality);
- return SkImage::MakeFromRaster(pixmap,
- [](const void*, void* pixels) {
- static_cast<Uint8Array*>(pixels)->Deref();
- },
- resized_pixels.LeakRef());
- }
-
- RefPtr<Float32Array> resized_pixels =
- Float32Array::Create(dst_buffer, 0, dst_buffer->ByteLength());
+ RefPtr<Uint8Array> resized_pixels =
+ Uint8Array::Create(dst_buffer, 0, dst_buffer->ByteLength());
SkPixmap pixmap(
resized_info, resized_pixels->Data(),
static_cast<unsigned>(resize_width) * resized_info.bytesPerPixel());
sk_image->scalePixels(pixmap, resize_quality);
return SkImage::MakeFromRaster(pixmap,
[](const void*, void* pixels) {
- static_cast<Float32Array*>(pixels)->Deref();
+ static_cast<Uint8Array*>(pixels)->Deref();
},
resized_pixels.LeakRef());
}
+static void SwizzleImageData(ImageData* data, bool needs_swizzle) {
+ needs_swizzle = false;
+ if (data && needs_swizzle) {
+ SkSwapRB(reinterpret_cast<uint32_t*>(data->data()->Data()),
+ reinterpret_cast<uint32_t*>(data->data()->Data()),
+ data->Size().Height() * data->Size().Width());
+ }
+}
+
ImageBitmap::ImageBitmap(ImageData* data,
Optional<IntRect> crop_rect,
const ImageBitmapOptions& options) {
- // TODO(xidachen): implement the resize option
- IntRect data_src_rect = IntRect(IntPoint(), data->Size());
+ LOG(ERROR) << "Entering...";
ParsedOptions parsed_options =
ParseOptions(options, crop_rect, data->BitmapSourceSize());
if (DstBufferSizeHasOverflow(parsed_options))
return;
+
+ IntRect data_src_rect = IntRect(IntPoint(), data->Size());
IntRect src_rect = crop_rect
? Intersection(parsed_options.crop_rect, data_src_rect)
: data_src_rect;
+ SkImageInfo unpremul_info = SkImageInfo::Make(
+ src_rect.Width(), src_rect.Height(),
+ parsed_options.color_params.GetSkColorType(), kUnpremul_SkAlphaType,
+ parsed_options.color_params.GetSkColorSpaceForSkSurfaces());
+ // if src_rect is empty, create an empty image bitmap with the requested size
+ // and return
+ if (src_rect.IsEmpty()) {
+ SkImageInfo info = parsed_options.premultiply_alpha
+ ? unpremul_info.makeAlphaType(kPremul_SkAlphaType)
+ : unpremul_info;
+ if (parsed_options.should_scale_input) {
+ info = info.makeWH(parsed_options.resize_width,
+ parsed_options.resize_height);
+ } else if (crop_rect) {
+ info = info.makeWH(crop_rect->Width(), crop_rect->Height());
+ } else {
+ info = info.makeWH(data->Size().Width(), data->Size().Height());
+ }
+ unsigned bytes_per_row =
+ info.width() * parsed_options.color_params.BytesPerPixel();
+ std::unique_ptr<uint8_t[]> pixels(
+ new uint8_t[info.height() * bytes_per_row]);
+ memset(pixels.get(), 0, info.height() * bytes_per_row);
+ sk_sp<SkImage> sk_image =
+ SkImage::MakeRasterCopy(SkPixmap(info, pixels.get(), bytes_per_row));
+ image_ = StaticBitmapImage::Create(sk_image);
+ image_->SetPremultiplied(parsed_options.premultiply_alpha);
+ return;
+ }
+
+ // crop/flip the input and swizzle if needed. we swizzle back later if the
+ // input ImageData is swizzled here.
+ bool crop_or_flip = (src_rect != data_src_rect) || parsed_options.flip_y;
+ bool needs_swizzle =
+ parsed_options.color_params.GetSkColorType() == kBGRA_8888_SkColorType;
+ ImageData* cropped_data = data;
+ if (crop_or_flip)
+ cropped_data = data->CropRect(src_rect, parsed_options.flip_y);
+ SwizzleImageData(cropped_data, needs_swizzle);
+ unsigned bytes_per_row =
+ src_rect.Size().Width() * parsed_options.color_params.BytesPerPixel();
+ unsigned data_size = src_rect.Size().Height() * bytes_per_row;
+ // color convert the pixels if needed
+ unsigned char* color_corrected_pixels = cropped_data->data()->Data();
+ std::unique_ptr<uint8_t[]>* converted_pixels = nullptr;
+ if (!SkColorSpace::Equals(
+ cropped_data->GetCanvasColorParams()
+ .GetSkColorSpaceForSkSurfaces()
+ .get(),
+ parsed_options.color_params.GetSkColorSpaceForSkSurfaces().get()) ||
+ cropped_data->GetCanvasColorParams().GetSkColorType() ==
+ kRGBA_F16_SkColorType) {
+ converted_pixels = new std::unique_ptr<uint8_t[]>(new uint8_t[data_size]);
+ cropped_data->ImageDataInCanvasColorSettings(parsed_options.color_params,
+ *converted_pixels);
+ color_corrected_pixels = converted_pixels->get();
+ }
// treat non-premultiplyAlpha as a special case
if (!parsed_options.premultiply_alpha) {
- unsigned char* src_addr = data->data()->Data();
+ SkImageInfo info = unpremul_info.makeColorType(kRGBA_8888_SkColorType);
+ sk_sp<SkImage> sk_image = SkImage::MakeRasterCopy(
+ SkPixmap(info, color_corrected_pixels, bytes_per_row));
- // Using kN32 type, swizzle input if necessary.
- SkImageInfo info = SkImageInfo::Make(
- parsed_options.crop_rect.Width(), parsed_options.crop_rect.Height(),
- kN32_SkColorType, kUnpremul_SkAlphaType, data->GetSkColorSpace());
- unsigned bytes_per_pixel = static_cast<unsigned>(info.bytesPerPixel());
- unsigned src_pixel_bytes_per_row = bytes_per_pixel * data->Size().Width();
- unsigned dst_pixel_bytes_per_row =
- bytes_per_pixel * parsed_options.crop_rect.Width();
- sk_sp<SkImage> sk_image;
- if (parsed_options.crop_rect == IntRect(IntPoint(), data->Size())) {
- SwizzleImageData(src_addr, data->Size().Height(), src_pixel_bytes_per_row,
- parsed_options.flip_y);
- sk_image = SkImage::MakeRasterCopy(
- SkPixmap(info, src_addr, dst_pixel_bytes_per_row));
- // restore the original ImageData
- SwizzleImageData(src_addr, data->Size().Height(), src_pixel_bytes_per_row,
- parsed_options.flip_y);
- } else {
- RefPtr<ArrayBuffer> dst_buffer = ArrayBuffer::CreateOrNull(
- static_cast<unsigned>(parsed_options.crop_rect.Height()) *
- parsed_options.crop_rect.Width(),
- bytes_per_pixel);
- if (!dst_buffer)
- return;
- RefPtr<Uint8Array> copied_data_buffer =
- Uint8Array::Create(dst_buffer, 0, dst_buffer->ByteLength());
- if (!src_rect.IsEmpty()) {
- IntPoint src_point = IntPoint(
- (parsed_options.crop_rect.X() > 0) ? parsed_options.crop_rect.X()
- : 0,
- (parsed_options.crop_rect.Y() > 0) ? parsed_options.crop_rect.Y()
- : 0);
- IntPoint dst_point = IntPoint((parsed_options.crop_rect.X() >= 0)
- ? 0
- : -parsed_options.crop_rect.X(),
- (parsed_options.crop_rect.Y() >= 0)
- ? 0
- : -parsed_options.crop_rect.Y());
- int copy_height = data->Size().Height() - src_point.Y();
- if (parsed_options.crop_rect.Height() < copy_height)
- copy_height = parsed_options.crop_rect.Height();
- int copy_width = data->Size().Width() - src_point.X();
- if (parsed_options.crop_rect.Width() < copy_width)
- copy_width = parsed_options.crop_rect.Width();
- for (int i = 0; i < copy_height; i++) {
- unsigned src_start_copy_position =
- (i + src_point.Y()) * src_pixel_bytes_per_row +
- src_point.X() * bytes_per_pixel;
- unsigned src_end_copy_position =
- src_start_copy_position + copy_width * bytes_per_pixel;
- unsigned dst_start_copy_position;
- if (parsed_options.flip_y)
- dst_start_copy_position =
- (parsed_options.crop_rect.Height() - 1 - dst_point.Y() - i) *
- dst_pixel_bytes_per_row +
- dst_point.X() * bytes_per_pixel;
- else
- dst_start_copy_position =
- (dst_point.Y() + i) * dst_pixel_bytes_per_row +
- dst_point.X() * bytes_per_pixel;
- for (unsigned j = 0;
- j < src_end_copy_position - src_start_copy_position; j++) {
- // swizzle when necessary
- if (kN32_SkColorType == kBGRA_8888_SkColorType) {
- if (j % 4 == 0)
- copied_data_buffer->Data()[dst_start_copy_position + j] =
- src_addr[src_start_copy_position + j + 2];
- else if (j % 4 == 2)
- copied_data_buffer->Data()[dst_start_copy_position + j] =
- src_addr[src_start_copy_position + j - 2];
- else
- copied_data_buffer->Data()[dst_start_copy_position + j] =
- src_addr[src_start_copy_position + j];
- } else {
- copied_data_buffer->Data()[dst_start_copy_position + j] =
- src_addr[src_start_copy_position + j];
- }
- }
- }
- }
- sk_image = NewSkImageFromRaster(info, std::move(copied_data_buffer),
- dst_pixel_bytes_per_row);
- }
- if (!sk_image)
- return;
- ApplyColorSpaceConversion(sk_image, parsed_options);
if (parsed_options.should_scale_input) {
image_ = StaticBitmapImage::Create(ScaleSkImage(
- sk_image, parsed_options.resize_width, parsed_options.resize_height,
- parsed_options.resize_quality,
- parsed_options.color_params.GetSkColorType(),
- data->GetSkColorSpace()));
+ sk_image, info, parsed_options.resize_width,
+ parsed_options.resize_height, parsed_options.resize_quality));
} else {
image_ = StaticBitmapImage::Create(sk_image);
}
if (!image_)
return;
image_->SetPremultiplied(parsed_options.premultiply_alpha);
+ SwizzleImageData(cropped_data, needs_swizzle);
return;
}
- CanvasColorParams canvas_color_params;
- if (RuntimeEnabledFeatures::colorCanvasExtensionsEnabled()) {
- ImageDataColorSettings color_settings;
- data->getColorSettings(color_settings);
- CanvasColorSpace canvas_color_space =
- ImageData::GetCanvasColorSpace(color_settings.colorSpace());
- CanvasPixelFormat canvas_pixel_format = kRGBA8CanvasPixelFormat;
- if (ImageData::GetImageDataStorageFormat(color_settings.storageFormat()) !=
- kUint8ClampedArrayStorageFormat) {
- canvas_pixel_format = kF16CanvasPixelFormat;
- }
- canvas_color_params =
- CanvasColorParams(canvas_color_space, canvas_pixel_format);
- }
+ IntSize buffer_size =
+ src_rect.IsEmpty() ? parsed_options.crop_rect.Size() : src_rect.Size();
std::unique_ptr<ImageBuffer> buffer =
- ImageBuffer::Create(parsed_options.crop_rect.Size(), kNonOpaque,
- kDoNotInitializeImagePixels, canvas_color_params);
+ ImageBuffer::Create(buffer_size, kNonOpaque, kDoNotInitializeImagePixels,
+ parsed_options.color_params);
if (!buffer)
return;
-
if (src_rect.IsEmpty()) {
image_ = StaticBitmapImage::Create(buffer->NewSkImageSnapshot(
kPreferNoAcceleration, kSnapshotReasonUnknown));
return;
}
- IntPoint dst_point = IntPoint(std::min(0, -parsed_options.crop_rect.X()),
- std::min(0, -parsed_options.crop_rect.Y()));
- if (parsed_options.crop_rect.X() < 0)
- dst_point.SetX(-parsed_options.crop_rect.X());
- if (parsed_options.crop_rect.Y() < 0)
- dst_point.SetY(-parsed_options.crop_rect.Y());
+ buffer->PutByteArray(kUnmultiplied, color_corrected_pixels,
+ cropped_data->Size(),
+ IntRect(IntPoint(), cropped_data->Size()), IntPoint());
- buffer->PutByteArray(kUnmultiplied, data->data()->Data(), data->Size(),
- src_rect, dst_point);
+ SwizzleImageData(cropped_data, needs_swizzle);
sk_sp<SkImage> sk_image =
buffer->NewSkImageSnapshot(kPreferNoAcceleration, kSnapshotReasonUnknown);
- if (parsed_options.flip_y)
- sk_image = FlipSkImageVertically(sk_image.get(), kEnforceAlphaPremultiply);
if (!sk_image)
return;
+
if (parsed_options.should_scale_input) {
sk_sp<SkSurface> surface = SkSurface::MakeRaster(SkImageInfo::MakeN32Premul(
parsed_options.resize_width, parsed_options.resize_height,
- data->GetSkColorSpace()));
+ data->GetCanvasColorParams().GetSkColorSpaceForSkSurfaces()));
if (!surface)
return;
SkPaint paint;
@@ -915,13 +876,13 @@ ImageBitmap::ImageBitmap(ImageData* data,
surface->getCanvas()->drawImageRect(sk_image, dst_draw_rect, &paint);
sk_image = surface->makeImageSnapshot();
}
- ApplyColorSpaceConversion(sk_image, parsed_options);
image_ = StaticBitmapImage::Create(std::move(sk_image));
}
ImageBitmap::ImageBitmap(ImageBitmap* bitmap,
Optional<IntRect> crop_rect,
const ImageBitmapOptions& options) {
+ LOG(ERROR) << "Entering...";
RefPtr<Image> input = bitmap->BitmapImage();
if (!input)
return;
@@ -943,23 +904,33 @@ ImageBitmap::ImageBitmap(ImageBitmap* bitmap,
ImageBitmap::ImageBitmap(RefPtr<StaticBitmapImage> image,
Optional<IntRect> crop_rect,
const ImageBitmapOptions& options) {
+ LOG(ERROR) << "Entering... ";
bool origin_clean = image->OriginClean();
ParsedOptions parsed_options =
ParseOptions(options, crop_rect, image->Size());
if (DstBufferSizeHasOverflow(parsed_options))
return;
+ LOG(ERROR) << "parsed_options.premultiply_alpha: "
+ << parsed_options.premultiply_alpha;
+ PrintSkImage(image.Get()->ImageForCurrentFrame());
+
image_ = CropImageAndApplyColorSpaceConversion(
image.Get(), parsed_options, kPremultiplyAlpha,
ColorBehavior::TransformToGlobalTarget());
+ LOG(ERROR) << "HERE";
if (!image_)
return;
+ LOG(ERROR) << "HERE";
+
+ PrintSkImage(image_.Get()->ImageForCurrentFrame());
image_->SetOriginClean(origin_clean);
image_->SetPremultiplied(parsed_options.premultiply_alpha);
}
ImageBitmap::ImageBitmap(PassRefPtr<StaticBitmapImage> image) {
+ LOG(ERROR) << "Entering...";
image_ = std::move(image);
}
@@ -1044,6 +1015,7 @@ ImageBitmap* ImageBitmap::Take(ScriptPromiseResolver*, sk_sp<SkImage> image) {
PassRefPtr<Uint8Array> ImageBitmap::CopyBitmapData(AlphaDisposition alpha_op,
DataColorFormat format) {
+ LOG(ERROR) << "Entering...";
SkImageInfo info = SkImageInfo::Make(
width(), height(),
(format == kRGBAColorType) ? kRGBA_8888_SkColorType : kN32_SkColorType,
@@ -1100,6 +1072,7 @@ PassRefPtr<Image> ImageBitmap::GetSourceImageForCanvas(
AccelerationHint,
SnapshotReason,
const FloatSize&) {
+ LOG(ERROR) << "HERE too ...";
*status = kNormalSourceImageStatus;
if (!image_)
return nullptr;

Powered by Google App Engine
This is Rietveld 408576698