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

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

Issue 2522693002: Color correct ImageBitmap(HTMLImageElement*) constructor (Closed)
Patch Set: Created 4 years, 1 month 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
« no previous file with comments | « no previous file | third_party/WebKit/Source/core/frame/ImageBitmapTest.cpp » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 c1cb64a471998ea3f1508f3306a180c6237de77a..87ee6f51f9d6b6496b3bff13891db67346fbffe4 100644
--- a/third_party/WebKit/Source/core/frame/ImageBitmap.cpp
+++ b/third_party/WebKit/Source/core/frame/ImageBitmap.cpp
@@ -11,6 +11,8 @@
#include "platform/image-decoders/ImageDecoder.h"
#include "third_party/skia/include/core/SkCanvas.h"
#include "third_party/skia/include/core/SkSurface.h"
+#include "ui/gfx/icc_profile.h"
+#include "ui/gfx/color_space.h"
#include "wtf/CheckedNumeric.h"
#include "wtf/PtrUtil.h"
#include "wtf/RefPtr.h"
@@ -232,6 +234,73 @@ static sk_sp<SkImage> unPremulSkImageToPremul(SkImage* input) {
static_cast<unsigned>(input->width()) * info.bytesPerPixel());
}
+static sk_sp<SkImage> applyColorSpaceConversion(
+ sk_sp<SkImage> image,
+ bool premultiplyAlpha,
+ const ImageBitmapOptions* options) {
+ // Valid values for colorSpaceConversion are "default", "srgb" and
+ // "linear-rgb" here.
+ if (options->colorSpaceConversion() != "default" &&
+ options->colorSpaceConversion() != "srgb" &&
+ options->colorSpaceConversion() != "linear-rgb") {
+ NOTREACHED() << "Invalid ImageBitmap creation attribute colorConversionSpace: "
+ << options->colorSpaceConversion();
+ return image;
+ }
+
+ bool colorCorrectRendering =
+ RuntimeEnabledFeatures::experimentalCanvasFeaturesEnabled() &&
+ RuntimeEnabledFeatures::colorCorrectRenderingEnabled();
+
+ // If color correct rendering is not set, only "default" is accepted here.
+ if (options->colorSpaceConversion() != "default" &&
+ !colorCorrectRendering) {
+ NOTREACHED() << "Invalid ImageBitmap creation attribute colorConversionSpace in\
+ not-color-corrected mode: "
+ << options->colorSpaceConversion();
+ return image;
+ }
+
+ SkImageInfo imageInfo;
+ // If color space conversion is default and color correct rendering is
+ // not set, color correct the image to display color space.
+ // For now we assume 8 bit per channel for display. This must be fixed
+ // to properly support color space conversion on HDR displays.
+ if (options->colorSpaceConversion() == "default" &&
+ !colorCorrectRendering) {
ccameron 2016/11/21 22:11:36 Ah -- as soon as https://codereview.chromium.org/2
+ gfx::ICCProfile iccProfile = gfx::ICCProfile::FromBestMonitor();
+ gfx::ColorSpace gfxColorSpace = iccProfile.GetColorSpace();
+ sk_sp<SkColorSpace> colorSpace =
+ (gfxColorSpace != gfx::ColorSpace()) ?
+ gfxColorSpace.ToSkColorSpace() :
+ SkColorSpace::MakeNamed(SkColorSpace::kSRGB_Named);
+ imageInfo = SkImageInfo::Make(
+ image->width(), image->height(),
+ SkColorType::kN32_SkColorType,
+ SkAlphaType::kPremul_SkAlphaType,
+ colorSpace);
+
+ // If color space conversion is default and color correct rendering is
+ // set, color correct the image to sRGB.
+ } else if (options->colorSpaceConversion() == "default" ||
+ options->colorSpaceConversion() == "srgb") {
+ imageInfo = SkImageInfo::MakeS32(
+ image->width(), image->height(),
+ SkAlphaType::kPremul_SkAlphaType);
+
+ } else if (options->colorSpaceConversion() == "linear-rgb") {
+ imageInfo = SkImageInfo::Make(
+ image->width(), image->height(),
+ SkColorType::kRGBA_F16_SkColorType,
+ SkAlphaType::kPremul_SkAlphaType,
+ SkColorSpace::MakeNamed(SkColorSpace::kSRGBLinear_Named));
+ }
+
+ sk_sp<SkSurface> surface = SkSurface::MakeRaster(imageInfo);
+ surface->getCanvas()->drawImage(image, 0, 0);
+ return surface->makeImageSnapshot();
+}
+
sk_sp<SkImage> ImageBitmap::getSkImageFromDecoder(
std::unique_ptr<ImageDecoder> decoder) {
if (!decoder->frameCount())
@@ -277,7 +346,9 @@ static PassRefPtr<StaticBitmapImage> cropImage(
const ParsedOptions& parsedOptions,
AlphaDisposition imageFormat = PremultiplyAlpha,
ImageDecoder::ColorSpaceOption colorSpaceOp =
- ImageDecoder::ColorSpaceApplied) {
+ ImageDecoder::ColorSpaceApplied,
+ const ImageBitmapOptions* imageBitmapOptions = nullptr) {
+
ASSERT(image);
IntRect imgRect(IntPoint(), IntSize(image->width(), image->height()));
const IntRect srcRect = intersection(imgRect, parsedOptions.cropRect);
@@ -296,9 +367,10 @@ static PassRefPtr<StaticBitmapImage> cropImage(
return nullptr;
RefPtr<Uint8Array> dstPixels =
Uint8Array::create(dstBuffer, 0, dstBuffer->byteLength());
- return StaticBitmapImage::create(newSkImageFromRaster(
- info, std::move(dstPixels),
- static_cast<unsigned>(info.width()) * info.bytesPerPixel()));
+ sk_sp<SkImage> croppedImage = newSkImageFromRaster(
+ info, std::move(dstPixels),
+ static_cast<size_t>(info.width()) * info.bytesPerPixel());
+ return StaticBitmapImage::create(croppedImage);
}
sk_sp<SkImage> skiaImage = image->imageForCurrentFrame();
@@ -322,6 +394,11 @@ static PassRefPtr<StaticBitmapImage> cropImage(
if (parsedOptions.cropRect == srcRect && !parsedOptions.shouldScaleInput) {
sk_sp<SkImage> croppedSkImage = skiaImage->makeSubset(srcRect);
+ if (colorSpaceOp == ImageDecoder::ColorSpaceApplied)
+ croppedSkImage = applyColorSpaceConversion(
+ croppedSkImage,
+ parsedOptions.premultiplyAlpha,
+ imageBitmapOptions);
if (parsedOptions.flipY)
return StaticBitmapImage::create(flipSkImageVertically(
croppedSkImage.get(), parsedOptions.premultiplyAlpha
@@ -337,6 +414,9 @@ static PassRefPtr<StaticBitmapImage> cropImage(
return StaticBitmapImage::create(std::move(croppedSkImage));
}
+ // Currently ImageDecoder assumes at most 8 bits per channel for the decoded
+ // image. When this is fixed, we should change this code to create the
+ // surface according to the color depth of the decoded image.
sk_sp<SkSurface> surface = SkSurface::MakeRasterN32Premul(
parsedOptions.resizeWidth, parsedOptions.resizeHeight);
if (!surface)
@@ -369,6 +449,11 @@ static PassRefPtr<StaticBitmapImage> cropImage(
}
skiaImage = surface->makeImageSnapshot();
+ if (colorSpaceOp == ImageDecoder::ColorSpaceApplied)
+ skiaImage = applyColorSpaceConversion(skiaImage,
+ parsedOptions.premultiplyAlpha,
+ imageBitmapOptions);
+
if (parsedOptions.premultiplyAlpha) {
if (imageFormat == DontPremultiplyAlpha)
return StaticBitmapImage::create(
@@ -393,7 +478,7 @@ ImageBitmap::ImageBitmap(HTMLImageElement* image,
ImageDecoder::ColorSpaceIgnored);
} else {
m_image = cropImage(input.get(), parsedOptions, PremultiplyAlpha,
- ImageDecoder::ColorSpaceApplied);
+ ImageDecoder::ColorSpaceApplied, &options);
}
if (!m_image)
return;
« no previous file with comments | « no previous file | third_party/WebKit/Source/core/frame/ImageBitmapTest.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698