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

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

Issue 2630563003: Fix ImageBitmap constructor from ImageData to consider the color space tags (Closed)
Patch Set: Rebaseline Created 3 years, 11 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
« 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 d5f6e8af1790a049ad772ed2c5e34db56f804efc..732f02b5b774e722bfc0a87d4847942fb8cf1259 100644
--- a/third_party/WebKit/Source/core/frame/ImageBitmap.cpp
+++ b/third_party/WebKit/Source/core/frame/ImageBitmap.cpp
@@ -70,7 +70,7 @@ ParsedOptions parseOptions(const ImageBitmapOptions& options,
options.premultiplyAlpha() == "premultiply");
}
- if (options.colorSpaceConversion() != "none") {
+ if (options.colorSpaceConversion() != imageBitmapOptionNone) {
if (!RuntimeEnabledFeatures::experimentalCanvasFeaturesEnabled() ||
!RuntimeEnabledFeatures::colorCorrectRenderingEnabled()) {
DCHECK_EQ(options.colorSpaceConversion(), "default");
@@ -312,7 +312,6 @@ static inline void updateLatestColorInformation(ParsedOptions& options) {
// TODO (zakrinasab). Rewrite this when SkImage::readPixels() respectes the
// color space of the passed SkImageInfo (crbug.com/skia/6021) and SkImage
// exposes SkColorSpace and SkColorType (crbug.com/skia/6022).
-
static void applyColorSpaceConversion(sk_sp<SkImage>& image,
ParsedOptions& options) {
if (!options.dstColorSpace)
@@ -329,39 +328,39 @@ static void applyColorSpaceConversion(sk_sp<SkImage>& image,
image->width(), image->height(), options.latestColorType,
image->alphaType(), options.latestColorSpace);
size_t size = image->width() * image->height() * info.bytesPerPixel();
- std::unique_ptr<uint8_t[]> srcPixels(new uint8_t[size]());
- if (!image->readPixels(info, &srcPixels,
+ sk_sp<SkData> srcData = SkData::MakeUninitialized(size);
+ if (srcData->size() != size)
+ return;
+ if (!image->readPixels(info, srcData->writable_data(),
image->width() * info.bytesPerPixel(), 0, 0)) {
return;
}
-
- // For in-place color correction, bytes per pixel must be equal for source
- // and destination color spaces.
- std::unique_ptr<uint8_t[]> dstPixels = nullptr;
+ // Proceed with in-place color correction, if possible.
+ sk_sp<SkData> dstData = srcData;
if (SkColorTypeBytesPerPixel(options.dstColorType) !=
SkColorTypeBytesPerPixel(options.latestColorType)) {
size = image->width() * image->height() *
- SkColorTypeBytesPerPixel(options.latestColorType);
- dstPixels = std::unique_ptr<uint8_t[]>(new uint8_t[size]());
+ SkColorTypeBytesPerPixel(options.dstColorType);
+ dstData = SkData::MakeUninitialized(size);
+ if (dstData->size() != size)
+ return;
}
-
- std::unique_ptr<SkColorSpaceXform> xform = SkColorSpaceXform::New(
- options.latestColorSpace.get(), options.dstColorSpace.get());
- xform->apply(getXformFormat(options.dstColorType),
- dstPixels ? &dstPixels : &srcPixels,
- getXformFormat(options.latestColorType), &srcPixels,
- image->width() * image->height(), kUnpremul_SkAlphaType);
-
SkImageInfo dstInfo =
SkImageInfo::Make(image->width(), image->height(), options.dstColorType,
image->alphaType(), options.dstColorSpace);
- sk_sp<SkData> data(SkData::MakeWithoutCopy(&dstPixels, size));
- sk_sp<SkImage> coloredImage = SkImage::MakeRasterData(
- dstInfo, data, image->width() * dstInfo.bytesPerPixel());
- if (coloredImage) {
- updateLatestColorInformation(options);
- image = coloredImage;
- return;
+ std::unique_ptr<SkColorSpaceXform> xform = SkColorSpaceXform::New(
+ options.latestColorSpace.get(), options.dstColorSpace.get());
+ if (xform->apply(getXformFormat(options.dstColorType),
+ dstData->writable_data(),
+ getXformFormat(options.latestColorType), srcData->data(),
+ image->width() * image->height(), kUnpremul_SkAlphaType)) {
+ sk_sp<SkImage> coloredImage = SkImage::MakeRasterData(
+ dstInfo, dstData, image->width() * dstInfo.bytesPerPixel());
+ if (coloredImage) {
+ updateLatestColorInformation(options);
+ image = coloredImage;
+ return;
+ }
}
return;
}
@@ -559,7 +558,7 @@ ImageBitmap::ImageBitmap(HTMLImageElement* image,
if (dstBufferSizeHasOverflow(parsedOptions))
return;
- if (options.colorSpaceConversion() == "none") {
+ if (options.colorSpaceConversion() == imageBitmapOptionNone) {
m_image = cropImageAndApplyColorSpaceConversion(
input.get(), parsedOptions, PremultiplyAlpha, ColorBehavior::ignore());
} else {
@@ -738,28 +737,43 @@ ImageBitmap::ImageBitmap(const void* pixelData,
static sk_sp<SkImage> scaleSkImage(sk_sp<SkImage> skImage,
unsigned resizeWidth,
unsigned resizeHeight,
- SkFilterQuality resizeQuality) {
+ SkFilterQuality resizeQuality,
+ SkColorType colorType = kN32_SkColorType,
+ sk_sp<SkColorSpace> colorSpace = nullptr) {
SkImageInfo resizedInfo = SkImageInfo::Make(
- resizeWidth, resizeHeight, kN32_SkColorType, kUnpremul_SkAlphaType);
+ resizeWidth, resizeHeight, colorType, kUnpremul_SkAlphaType, colorSpace);
RefPtr<ArrayBuffer> dstBuffer = ArrayBuffer::createOrNull(
resizeWidth * resizeHeight, resizedInfo.bytesPerPixel());
if (!dstBuffer)
return nullptr;
- RefPtr<Uint8Array> resizedPixels =
- Uint8Array::create(dstBuffer, 0, dstBuffer->byteLength());
+
+ if (colorType == kN32_SkColorType) {
+ RefPtr<Uint8Array> resizedPixels =
+ Uint8Array::create(dstBuffer, 0, dstBuffer->byteLength());
+ SkPixmap pixmap(
+ resizedInfo, resizedPixels->data(),
+ static_cast<unsigned>(resizeWidth) * resizedInfo.bytesPerPixel());
+ skImage->scalePixels(pixmap, resizeQuality);
+ return SkImage::MakeFromRaster(pixmap,
+ [](const void*, void* pixels) {
+ static_cast<Uint8Array*>(pixels)->deref();
+ },
+ resizedPixels.release().leakRef());
+ }
+
+ RefPtr<Float32Array> resizedPixels =
+ Float32Array::create(dstBuffer, 0, dstBuffer->byteLength());
SkPixmap pixmap(
resizedInfo, resizedPixels->data(),
static_cast<unsigned>(resizeWidth) * resizedInfo.bytesPerPixel());
skImage->scalePixels(pixmap, resizeQuality);
return SkImage::MakeFromRaster(pixmap,
[](const void*, void* pixels) {
- static_cast<Uint8Array*>(pixels)->deref();
+ static_cast<Float32Array*>(pixels)->deref();
},
resizedPixels.release().leakRef());
}
-// TODO(zakerinasab): Fix this and the constructor from Float32ImageData
-// when the CL for Float32ImageData landed.
ImageBitmap::ImageBitmap(ImageData* data,
Optional<IntRect> cropRect,
const ImageBitmapOptions& options) {
@@ -779,7 +793,7 @@ ImageBitmap::ImageBitmap(ImageData* data,
// Using kN32 type, swizzle input if necessary.
SkImageInfo info = SkImageInfo::Make(
parsedOptions.cropRect.width(), parsedOptions.cropRect.height(),
- kN32_SkColorType, kUnpremul_SkAlphaType);
+ kN32_SkColorType, kUnpremul_SkAlphaType, data->getSkColorSpace());
unsigned bytesPerPixel = static_cast<unsigned>(info.bytesPerPixel());
unsigned srcPixelBytesPerRow = bytesPerPixel * data->size().width();
unsigned dstPixelBytesPerRow =
@@ -856,20 +870,27 @@ ImageBitmap::ImageBitmap(ImageData* data,
}
if (!skImage)
return;
- if (parsedOptions.shouldScaleInput)
- m_image = StaticBitmapImage::create(scaleSkImage(
- skImage, parsedOptions.resizeWidth, parsedOptions.resizeHeight,
- parsedOptions.resizeQuality));
- else
+ if (data->getSkColorSpace()) {
+ parsedOptions.latestColorSpace = data->getSkColorSpace();
+ applyColorSpaceConversion(skImage, parsedOptions);
+ }
+ if (parsedOptions.shouldScaleInput) {
+ m_image = StaticBitmapImage::create(
+ scaleSkImage(skImage, parsedOptions.resizeWidth,
+ parsedOptions.resizeHeight, parsedOptions.resizeQuality,
+ parsedOptions.latestColorType, data->getSkColorSpace()));
+ } else {
m_image = StaticBitmapImage::create(skImage);
+ }
if (!m_image)
return;
m_image->setPremultiplied(parsedOptions.premultiplyAlpha);
return;
}
- std::unique_ptr<ImageBuffer> buffer = ImageBuffer::create(
- parsedOptions.cropRect.size(), NonOpaque, DoNotInitializeImagePixels);
+ std::unique_ptr<ImageBuffer> buffer =
+ ImageBuffer::create(parsedOptions.cropRect.size(), NonOpaque,
+ DoNotInitializeImagePixels, data->getSkColorSpace());
if (!buffer)
return;
@@ -885,6 +906,7 @@ ImageBitmap::ImageBitmap(ImageData* data,
dstPoint.setX(-parsedOptions.cropRect.x());
if (parsedOptions.cropRect.y() < 0)
dstPoint.setY(-parsedOptions.cropRect.y());
+
buffer->putByteArray(Unmultiplied, data->data()->data(), data->size(),
srcRect, dstPoint);
sk_sp<SkImage> skImage =
@@ -894,8 +916,9 @@ ImageBitmap::ImageBitmap(ImageData* data,
if (!skImage)
return;
if (parsedOptions.shouldScaleInput) {
- sk_sp<SkSurface> surface = SkSurface::MakeRasterN32Premul(
- parsedOptions.resizeWidth, parsedOptions.resizeHeight);
+ sk_sp<SkSurface> surface = SkSurface::MakeRaster(SkImageInfo::MakeN32Premul(
+ parsedOptions.resizeWidth, parsedOptions.resizeHeight,
+ data->getSkColorSpace()));
if (!surface)
return;
SkPaint paint;
@@ -905,9 +928,14 @@ ImageBitmap::ImageBitmap(ImageData* data,
surface->getCanvas()->drawImageRect(skImage, dstDrawRect, &paint);
skImage = surface->makeImageSnapshot();
}
+ if (data->getSkColorSpace()) {
+ parsedOptions.latestColorSpace = data->getSkColorSpace();
+ applyColorSpaceConversion(skImage, parsedOptions);
+ }
m_image = StaticBitmapImage::create(std::move(skImage));
}
+// TODO(zakerinasab): Fix the constructor from Float32ImageData.
ImageBitmap::ImageBitmap(Float32ImageData* data,
Optional<IntRect> cropRect,
const ImageBitmapOptions& options) {}
« 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