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()); |
} |