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

Side by Side Diff: third_party/WebKit/Source/core/frame/ImageBitmap.cpp

Issue 2924373002: color: Convert BitmapImage to sRGB ahead of time (Closed)
Patch Set: Rebase 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 unified diff | Download patch
« no previous file with comments | « third_party/WebKit/LayoutTests/TestExpectations ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2013 The Chromium Authors. All rights reserved. 1 // Copyright 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "core/frame/ImageBitmap.h" 5 #include "core/frame/ImageBitmap.h"
6 6
7 #include <memory> 7 #include <memory>
8 #include "core/html/HTMLCanvasElement.h" 8 #include "core/html/HTMLCanvasElement.h"
9 #include "core/html/HTMLVideoElement.h" 9 #include "core/html/HTMLVideoElement.h"
10 #include "core/html/ImageData.h" 10 #include "core/html/ImageData.h"
11 #include "core/offscreencanvas/OffscreenCanvas.h" 11 #include "core/offscreencanvas/OffscreenCanvas.h"
12 #include "platform/graphics/CanvasColorParams.h" 12 #include "platform/graphics/CanvasColorParams.h"
13 #include "platform/graphics/skia/SkiaUtils.h" 13 #include "platform/graphics/skia/SkiaUtils.h"
14 #include "platform/image-decoders/ImageDecoder.h" 14 #include "platform/image-decoders/ImageDecoder.h"
15 #include "platform/wtf/CheckedNumeric.h" 15 #include "platform/wtf/CheckedNumeric.h"
16 #include "platform/wtf/PtrUtil.h" 16 #include "platform/wtf/PtrUtil.h"
17 #include "platform/wtf/RefPtr.h" 17 #include "platform/wtf/RefPtr.h"
18 #include "third_party/skia/include/core/SkCanvas.h" 18 #include "third_party/skia/include/core/SkCanvas.h"
19 #include "third_party/skia/include/core/SkColorSpaceXformCanvas.h"
19 #include "third_party/skia/include/core/SkImageInfo.h" 20 #include "third_party/skia/include/core/SkImageInfo.h"
20 #include "third_party/skia/include/core/SkSurface.h" 21 #include "third_party/skia/include/core/SkSurface.h"
21 22
22 namespace blink { 23 namespace blink {
23 24
24 constexpr const char* kImageOrientationFlipY = "flipY"; 25 constexpr const char* kImageOrientationFlipY = "flipY";
25 constexpr const char* kImageBitmapOptionNone = "none"; 26 constexpr const char* kImageBitmapOptionNone = "none";
26 constexpr const char* kImageBitmapOptionDefault = "default"; 27 constexpr const char* kImageBitmapOptionDefault = "default";
27 constexpr const char* kImageBitmapOptionPremultiply = "premultiply"; 28 constexpr const char* kImageBitmapOptionPremultiply = "premultiply";
28 constexpr const char* kImageBitmapOptionResizeQualityHigh = "high"; 29 constexpr const char* kImageBitmapOptionResizeQualityHigh = "high";
(...skipping 266 matching lines...) Expand 10 before | Expand all | Expand 10 after
295 RefPtr<Uint8Array> dst_pixels = CopySkImageData(input, info); 296 RefPtr<Uint8Array> dst_pixels = CopySkImageData(input, info);
296 if (!dst_pixels) 297 if (!dst_pixels)
297 return nullptr; 298 return nullptr;
298 return NewSkImageFromRaster( 299 return NewSkImageFromRaster(
299 info, std::move(dst_pixels), 300 info, std::move(dst_pixels),
300 static_cast<unsigned>(input->width()) * info.bytesPerPixel()); 301 static_cast<unsigned>(input->width()) * info.bytesPerPixel());
301 } 302 }
302 303
303 static void ApplyColorSpaceConversion(sk_sp<SkImage>& image, 304 static void ApplyColorSpaceConversion(sk_sp<SkImage>& image,
304 ParsedOptions& options) { 305 ParsedOptions& options) {
306 if (options.color_params.UsesOutputSpaceBlending() &&
307 RuntimeEnabledFeatures::ColorCorrectRenderingEnabled()) {
308 image = image->makeColorSpace(options.color_params.GetSkColorSpace(),
309 SkTransferFunctionBehavior::kIgnore);
310 }
311
305 if (!options.color_canvas_extensions_enabled) 312 if (!options.color_canvas_extensions_enabled)
306 return; 313 return;
307 314
308 sk_sp<SkColorSpace> dst_color_space = nullptr; 315 sk_sp<SkColorSpace> dst_color_space = nullptr;
309 SkColorType dst_color_type = kN32_SkColorType; 316 SkColorType dst_color_type = kN32_SkColorType;
310 dst_color_space = options.color_params.GetSkColorSpace(); 317 dst_color_space = options.color_params.GetSkColorSpace();
311 dst_color_type = options.color_params.GetSkColorType(); 318 dst_color_type = options.color_params.GetSkColorType();
312 if (SkColorSpace::Equals(image->colorSpace(), dst_color_space.get())) 319 if (SkColorSpace::Equals(image->colorSpace(), dst_color_space.get()))
313 return; 320 return;
314 321
(...skipping 158 matching lines...) Expand 10 before | Expand all | Expand 10 after
473 return StaticBitmapImage::Create(std::move(cropped_sk_image)); 480 return StaticBitmapImage::Create(std::move(cropped_sk_image));
474 } 481 }
475 482
476 sk_sp<SkSurface> surface = SkSurface::MakeRasterN32Premul( 483 sk_sp<SkSurface> surface = SkSurface::MakeRasterN32Premul(
477 parsed_options.resize_width, parsed_options.resize_height); 484 parsed_options.resize_width, parsed_options.resize_height);
478 if (!surface) 485 if (!surface)
479 return nullptr; 486 return nullptr;
480 if (src_rect.IsEmpty()) 487 if (src_rect.IsEmpty())
481 return StaticBitmapImage::Create(surface->makeImageSnapshot()); 488 return StaticBitmapImage::Create(surface->makeImageSnapshot());
482 489
490 SkCanvas* canvas = surface->getCanvas();
491 std::unique_ptr<SkCanvas> color_transform_canvas;
492 if (parsed_options.color_params.UsesOutputSpaceBlending() &&
493 RuntimeEnabledFeatures::ColorCorrectRenderingEnabled()) {
494 color_transform_canvas = SkCreateColorSpaceXformCanvas(
495 canvas, parsed_options.color_params.GetSkColorSpace());
496 canvas = color_transform_canvas.get();
497 }
498
483 SkScalar dst_left = std::min(0, -parsed_options.crop_rect.X()); 499 SkScalar dst_left = std::min(0, -parsed_options.crop_rect.X());
484 SkScalar dst_top = std::min(0, -parsed_options.crop_rect.Y()); 500 SkScalar dst_top = std::min(0, -parsed_options.crop_rect.Y());
485 if (parsed_options.crop_rect.X() < 0) 501 if (parsed_options.crop_rect.X() < 0)
486 dst_left = -parsed_options.crop_rect.X(); 502 dst_left = -parsed_options.crop_rect.X();
487 if (parsed_options.crop_rect.Y() < 0) 503 if (parsed_options.crop_rect.Y() < 0)
488 dst_top = -parsed_options.crop_rect.Y(); 504 dst_top = -parsed_options.crop_rect.Y();
489 if (parsed_options.flip_y) { 505 if (parsed_options.flip_y) {
490 surface->getCanvas()->translate(0, surface->height()); 506 canvas->translate(0, surface->height());
491 surface->getCanvas()->scale(1, -1); 507 canvas->scale(1, -1);
492 } 508 }
493 if (parsed_options.should_scale_input) { 509 if (parsed_options.should_scale_input) {
494 SkRect draw_src_rect = SkRect::MakeXYWH( 510 SkRect draw_src_rect = SkRect::MakeXYWH(
495 parsed_options.crop_rect.X(), parsed_options.crop_rect.Y(), 511 parsed_options.crop_rect.X(), parsed_options.crop_rect.Y(),
496 parsed_options.crop_rect.Width(), parsed_options.crop_rect.Height()); 512 parsed_options.crop_rect.Width(), parsed_options.crop_rect.Height());
497 SkRect draw_dst_rect = SkRect::MakeXYWH(0, 0, parsed_options.resize_width, 513 SkRect draw_dst_rect = SkRect::MakeXYWH(0, 0, parsed_options.resize_width,
498 parsed_options.resize_height); 514 parsed_options.resize_height);
499 SkPaint paint; 515 SkPaint paint;
500 paint.setFilterQuality(parsed_options.resize_quality); 516 paint.setFilterQuality(parsed_options.resize_quality);
501 surface->getCanvas()->drawImageRect(skia_image, draw_src_rect, 517 canvas->drawImageRect(skia_image, draw_src_rect, draw_dst_rect, &paint);
502 draw_dst_rect, &paint);
503 } else { 518 } else {
504 surface->getCanvas()->drawImage(skia_image, dst_left, dst_top); 519 canvas->drawImage(skia_image, dst_left, dst_top);
505 } 520 }
506 skia_image = surface->makeImageSnapshot(); 521 skia_image = surface->makeImageSnapshot();
507 ApplyColorSpaceConversion(skia_image, parsed_options); 522 ApplyColorSpaceConversion(skia_image, parsed_options);
508 523
509 if (parsed_options.premultiply_alpha) { 524 if (parsed_options.premultiply_alpha) {
510 if (image_format == kDontPremultiplyAlpha) 525 if (image_format == kDontPremultiplyAlpha)
511 return StaticBitmapImage::Create( 526 return StaticBitmapImage::Create(
512 UnPremulSkImageToPremul(skia_image.get())); 527 UnPremulSkImageToPremul(skia_image.get()));
513 return StaticBitmapImage::Create(std::move(skia_image)); 528 return StaticBitmapImage::Create(std::move(skia_image));
514 } 529 }
(...skipping 30 matching lines...) Expand all
545 sk_sp<SkColorSpace> dst_color_space = nullptr; 560 sk_sp<SkColorSpace> dst_color_space = nullptr;
546 SkColorType dst_color_type = kN32_SkColorType; 561 SkColorType dst_color_type = kN32_SkColorType;
547 if (parsed_options.color_canvas_extensions_enabled) { 562 if (parsed_options.color_canvas_extensions_enabled) {
548 dst_color_space = parsed_options.color_params.GetSkColorSpace(); 563 dst_color_space = parsed_options.color_params.GetSkColorSpace();
549 dst_color_type = parsed_options.color_params.GetSkColorType(); 564 dst_color_type = parsed_options.color_params.GetSkColorType();
550 } 565 }
551 SkImageInfo image_info = 566 SkImageInfo image_info =
552 SkImageInfo::Make(sk_image->width(), sk_image->height(), dst_color_type, 567 SkImageInfo::Make(sk_image->width(), sk_image->height(), dst_color_type,
553 kPremul_SkAlphaType, dst_color_space); 568 kPremul_SkAlphaType, dst_color_space);
554 sk_sp<SkSurface> surface = SkSurface::MakeRaster(image_info); 569 sk_sp<SkSurface> surface = SkSurface::MakeRaster(image_info);
555 surface->getCanvas()->drawImage(sk_image, 0, 0); 570 SkCanvas* canvas = surface->getCanvas();
571 std::unique_ptr<SkCanvas> color_transform_canvas;
572 if (parsed_options.color_params.UsesOutputSpaceBlending() &&
573 RuntimeEnabledFeatures::ColorCorrectRenderingEnabled()) {
574 color_transform_canvas = SkCreateColorSpaceXformCanvas(
575 canvas, parsed_options.color_params.GetSkColorSpace());
576 canvas = color_transform_canvas.get();
577 }
578 canvas->drawImage(sk_image, 0, 0);
556 image_ = StaticBitmapImage::Create(surface->makeImageSnapshot()); 579 image_ = StaticBitmapImage::Create(surface->makeImageSnapshot());
557 } 580 }
558 if (!image_) 581 if (!image_)
559 return; 582 return;
560 image_->SetOriginClean( 583 image_->SetOriginClean(
561 !image->WouldTaintOrigin(document->GetSecurityOrigin())); 584 !image->WouldTaintOrigin(document->GetSecurityOrigin()));
562 image_->SetPremultiplied(parsed_options.premultiply_alpha); 585 image_->SetPremultiplied(parsed_options.premultiply_alpha);
563 } 586 }
564 587
565 ImageBitmap::ImageBitmap(HTMLVideoElement* video, 588 ImageBitmap::ImageBitmap(HTMLVideoElement* video,
(...skipping 339 matching lines...) Expand 10 before | Expand all | Expand 10 after
905 if (parsed_options.should_scale_input) { 928 if (parsed_options.should_scale_input) {
906 sk_sp<SkSurface> surface = SkSurface::MakeRaster(SkImageInfo::MakeN32Premul( 929 sk_sp<SkSurface> surface = SkSurface::MakeRaster(SkImageInfo::MakeN32Premul(
907 parsed_options.resize_width, parsed_options.resize_height, 930 parsed_options.resize_width, parsed_options.resize_height,
908 data->GetSkColorSpace())); 931 data->GetSkColorSpace()));
909 if (!surface) 932 if (!surface)
910 return; 933 return;
911 SkPaint paint; 934 SkPaint paint;
912 paint.setFilterQuality(parsed_options.resize_quality); 935 paint.setFilterQuality(parsed_options.resize_quality);
913 SkRect dst_draw_rect = SkRect::MakeWH(parsed_options.resize_width, 936 SkRect dst_draw_rect = SkRect::MakeWH(parsed_options.resize_width,
914 parsed_options.resize_height); 937 parsed_options.resize_height);
915 surface->getCanvas()->drawImageRect(sk_image, dst_draw_rect, &paint); 938 SkCanvas* canvas = surface->getCanvas();
939 std::unique_ptr<SkCanvas> color_transform_canvas;
940 if (parsed_options.color_params.UsesOutputSpaceBlending() &&
941 RuntimeEnabledFeatures::ColorCorrectRenderingEnabled()) {
942 color_transform_canvas = SkCreateColorSpaceXformCanvas(
943 canvas, parsed_options.color_params.GetSkColorSpace());
944 canvas = color_transform_canvas.get();
945 }
946 canvas->drawImageRect(sk_image, dst_draw_rect, &paint);
916 sk_image = surface->makeImageSnapshot(); 947 sk_image = surface->makeImageSnapshot();
917 } 948 }
918 ApplyColorSpaceConversion(sk_image, parsed_options); 949 ApplyColorSpaceConversion(sk_image, parsed_options);
919 image_ = StaticBitmapImage::Create(std::move(sk_image)); 950 image_ = StaticBitmapImage::Create(std::move(sk_image));
920 } 951 }
921 952
922 ImageBitmap::ImageBitmap(ImageBitmap* bitmap, 953 ImageBitmap::ImageBitmap(ImageBitmap* bitmap,
923 Optional<IntRect> crop_rect, 954 Optional<IntRect> crop_rect,
924 const ImageBitmapOptions& options) { 955 const ImageBitmapOptions& options) {
925 RefPtr<Image> input = bitmap->BitmapImage(); 956 RefPtr<Image> input = bitmap->BitmapImage();
(...skipping 189 matching lines...) Expand 10 before | Expand all | Expand 10 after
1115 void ImageBitmap::AdjustDrawRects(FloatRect* src_rect, 1146 void ImageBitmap::AdjustDrawRects(FloatRect* src_rect,
1116 FloatRect* dst_rect) const {} 1147 FloatRect* dst_rect) const {}
1117 1148
1118 FloatSize ImageBitmap::ElementSize(const FloatSize&) const { 1149 FloatSize ImageBitmap::ElementSize(const FloatSize&) const {
1119 return FloatSize(width(), height()); 1150 return FloatSize(width(), height());
1120 } 1151 }
1121 1152
1122 DEFINE_TRACE(ImageBitmap) {} 1153 DEFINE_TRACE(ImageBitmap) {}
1123 1154
1124 } // namespace blink 1155 } // namespace blink
OLDNEW
« no previous file with comments | « third_party/WebKit/LayoutTests/TestExpectations ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698