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

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

Issue 1609763002: Implement ImageBitmap options premultiplyAlpha (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 4 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
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 7f848ba80871b373d307b52d1cd811514cb4c380..29d6a7ce21a51ef707bc0b40214d242ec0a29f7a 100644
--- a/third_party/WebKit/Source/core/frame/ImageBitmap.cpp
+++ b/third_party/WebKit/Source/core/frame/ImageBitmap.cpp
@@ -7,11 +7,13 @@
#include "core/html/HTMLCanvasElement.h"
#include "core/html/HTMLVideoElement.h"
#include "core/html/ImageData.h"
+#include "platform/image-decoders/ImageDecoder.h"
#include "third_party/skia/include/core/SkSurface.h"
#include "wtf/RefPtr.h"
namespace blink {
+// The following two functions are helpers used in cropImage
static inline IntRect normalizeRect(const IntRect& rect)
{
return IntRect(std::min(rect.x(), rect.maxX()),
@@ -20,17 +22,52 @@ static inline IntRect normalizeRect(const IntRect& rect)
std::max(rect.height(), -rect.height()));
}
-static PassRefPtr<StaticBitmapImage> cropImage(Image* image, const IntRect& cropRect)
+static bool frameIsValid(const SkBitmap& frameBitmap)
+{
+ return !frameBitmap.isNull()
+ && !frameBitmap.empty()
+ && frameBitmap.isImmutable()
+ && frameBitmap.colorType() == kN32_SkColorType;
+}
+
+static PassRefPtr<StaticBitmapImage> cropImage(Image* image, const IntRect& cropRect, const ImageBitmapOptions& options)
{
ASSERT(image);
IntRect imgRect(IntPoint(), IntSize(image->width(), image->height()));
const IntRect srcRect = intersection(imgRect, cropRect);
- if (cropRect == srcRect)
- return StaticBitmapImage::create(adoptRef(image->imageForCurrentFrame()->newSubset(srcRect)));
+ RefPtr<SkImage> skiaImage = image->imageForCurrentFrame();
+ // Attempt to get raw unpremultiplied image data.
+ if (((!options.premultiplyAlpha() && !skiaImage->isOpaque()) || !skiaImage) && image->data()) {
+ OwnPtr<ImageDecoder> decoder(ImageDecoder::create(
+ *(image->data()), ImageDecoder::AlphaNotPremultiplied,
+ ImageDecoder::GammaAndColorProfileIgnored));
+ if (!decoder)
+ return nullptr;
+ decoder->setData(image->data(), true);
+ if (!decoder->frameCount())
+ return nullptr;
+ ImageFrame* frame = decoder->frameBufferAtIndex(0);
+ if (!frame || frame->status() != ImageFrame::FrameComplete)
+ return nullptr;
+ SkBitmap bitmap = frame->bitmap();
+ if (!frameIsValid(bitmap))
+ return nullptr;
+ ASSERT(bitmap.isImmutable());
+ skiaImage = adoptRef(SkImage::NewFromBitmap(bitmap));
+ }
- RefPtr<SkSurface> surface = adoptRef(SkSurface::NewRasterN32Premul(cropRect.width(), cropRect.height()));
+ if (cropRect == srcRect)
+ return StaticBitmapImage::create(adoptRef(skiaImage->newSubset(srcRect)));
+
+ RefPtr<SkSurface> surface;
+ if (options.premultiplyAlpha()) {
+ surface = adoptRef(SkSurface::NewRasterN32Premul(cropRect.width(), cropRect.height()));
+ } else {
+ SkImageInfo info = SkImageInfo::MakeN32(cropRect.width(), cropRect.height(), kUnpremul_SkAlphaType);
+ surface = adoptRef(SkSurface::NewRaster(info));
+ }
if (srcRect.isEmpty())
return StaticBitmapImage::create(adoptRef(surface->newImageSnapshot()));
@@ -41,13 +78,14 @@ static PassRefPtr<StaticBitmapImage> cropImage(Image* image, const IntRect& crop
dstLeft = -cropRect.x();
if (cropRect.y() < 0)
dstTop = -cropRect.y();
- surface->getCanvas()->drawImage(image->imageForCurrentFrame().get(), dstLeft, dstTop);
+
+ surface->getCanvas()->drawImage(skiaImage.get(), dstLeft, dstTop);
xidachen 2016/01/20 02:29:07 This program could crash at this point. It is beca
return StaticBitmapImage::create(adoptRef(surface->newImageSnapshot()));
}
ImageBitmap::ImageBitmap(HTMLImageElement* image, const IntRect& cropRect, Document* document, const ImageBitmapOptions& options)
{
- m_image = cropImage(image->cachedImage()->image(), cropRect);
+ m_image = cropImage(image->cachedImage()->image(), cropRect, options);
m_image->setOriginClean(!image->wouldTaintOrigin(document->securityOrigin()));
}
@@ -65,14 +103,17 @@ ImageBitmap::ImageBitmap(HTMLVideoElement* video, const IntRect& cropRect, Docum
IntPoint dstPoint = IntPoint(std::max(0, -cropRect.x()), std::max(0, -cropRect.y()));
video->paintCurrentFrame(buffer->canvas(), IntRect(dstPoint, srcRect.size()), nullptr);
- m_image = StaticBitmapImage::create(buffer->newSkImageSnapshot(PreferNoAcceleration));
+ if (options.premultiplyAlpha())
+ m_image = StaticBitmapImage::create(buffer->newSkImageSnapshot(PreferNoAcceleration));
+ else
+ m_image = cropImage(buffer->newImageSnapshot().get(), IntRect(IntPoint(0, 0), cropRect.size()), options);
m_image->setOriginClean(!video->wouldTaintOrigin(document->securityOrigin()));
}
ImageBitmap::ImageBitmap(HTMLCanvasElement* canvas, const IntRect& cropRect, const ImageBitmapOptions& options)
{
ASSERT(canvas->isPaintable());
- m_image = cropImage(canvas->copiedImage(BackBuffer, PreferAcceleration).get(), cropRect);
+ m_image = cropImage(canvas->copiedImage(BackBuffer, PreferAcceleration).get(), cropRect, options);
m_image->setOriginClean(canvas->originClean());
}
@@ -100,13 +141,13 @@ ImageBitmap::ImageBitmap(ImageData* data, const IntRect& cropRect, const ImageBi
ImageBitmap::ImageBitmap(ImageBitmap* bitmap, const IntRect& cropRect, const ImageBitmapOptions& options)
{
- m_image = cropImage(bitmap->bitmapImage(), cropRect);
+ m_image = cropImage(bitmap->bitmapImage(), cropRect, options);
m_image->setOriginClean(bitmap->originClean());
}
ImageBitmap::ImageBitmap(PassRefPtr<StaticBitmapImage> image, const IntRect& cropRect, const ImageBitmapOptions& options)
{
- m_image = cropImage(image.get(), cropRect);
+ m_image = cropImage(image.get(), cropRect, options);
m_image->setOriginClean(image->originClean());
}

Powered by Google App Engine
This is Rietveld 408576698