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

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

Issue 2249853008: Reject createImageBitmap promise when the cropRect or resize is too big (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: size_t + Uint8Array + null check (lots) Created 4 years, 4 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 057f80573a1ad10ae9884a0662d1337093a6dbb2..2dc57a0c6b062c6a1c7bc4c4da7ebeded18c5e01 100644
--- a/third_party/WebKit/Source/core/frame/ImageBitmap.cpp
+++ b/third_party/WebKit/Source/core/frame/ImageBitmap.cpp
@@ -11,6 +11,7 @@
#include "platform/image-decoders/ImageDecoder.h"
#include "third_party/skia/include/core/SkCanvas.h"
#include "third_party/skia/include/core/SkSurface.h"
+#include "wtf/CheckedNumeric.h"
#include "wtf/PtrUtil.h"
#include "wtf/RefPtr.h"
#include <memory>
@@ -30,6 +31,9 @@ struct ParsedOptions {
unsigned resizeHeight = 0;
IntRect cropRect;
SkFilterQuality resizeQuality = kLow_SkFilterQuality;
+ // This value should be changed in the future when we support createImageBitmap with higher
+ // bit depth, in the parseOptions() function. For now, it is always 4.
+ int bytesPerPixel = 4;
};
// The following two functions are helpers used in cropImage
@@ -100,32 +104,58 @@ ParsedOptions parseOptions(const ImageBitmapOptions& options, Optional<IntRect>
return parsedOptions;
}
+bool dstBufferSizeHasOverflow(ParsedOptions options)
+{
+ CheckedNumeric<size_t> totalBytes = options.cropRect.width();
+ totalBytes *= options.cropRect.height();
+ totalBytes *= options.bytesPerPixel;
+ if (!totalBytes.IsValid())
+ return true;
+
+ if (!options.shouldScaleInput)
+ return false;
+ totalBytes = options.resizeWidth;
+ totalBytes *= options.resizeHeight;
+ totalBytes *= options.bytesPerPixel;
+ if (!totalBytes.IsValid())
+ return true;
+
+ return false;
+}
+
} // namespace
-static std::unique_ptr<uint8_t[]> copySkImageData(SkImage* input, const SkImageInfo& info)
+static PassRefPtr<Uint8Array> copySkImageData(SkImage* input, const SkImageInfo& info)
{
- std::unique_ptr<uint8_t[]> dstPixels = wrapArrayUnique(new uint8_t[input->width() * input->height() * info.bytesPerPixel()]);
- input->readPixels(info, dstPixels.get(), input->width() * info.bytesPerPixel(), 0, 0);
+ // The function dstBufferSizeHasOverflow() is being called at the beginning of each
+ // ImageBitmap() constructor, which makes sure that doing width * height * bytesPerPixel
+ // will never overflow size_t.
+ size_t width = static_cast<size_t>(input->width());
+ RefPtr<ArrayBuffer> dstBuffer = ArrayBuffer::createOrNull(width * input->height(), info.bytesPerPixel());
+ if (!dstBuffer)
+ return nullptr;
+ RefPtr<Uint8Array> dstPixels = Uint8Array::create(dstBuffer, 0, dstBuffer->byteLength());
+ input->readPixels(info, dstPixels->data(), width * info.bytesPerPixel(), 0, 0);
return dstPixels;
}
-static PassRefPtr<SkImage> newSkImageFromRaster(const SkImageInfo& info, std::unique_ptr<uint8_t[]> imagePixels, int imageRowBytes)
+static PassRefPtr<SkImage> newSkImageFromRaster(const SkImageInfo& info, PassRefPtr<Uint8Array> imagePixels, size_t imageRowBytes)
Justin Novosad 2016/08/24 14:49:12 PassRefPtr is deprecated. RefPtr, with std::move a
{
- return fromSkSp(SkImage::MakeFromRaster(SkPixmap(info, imagePixels.release(), imageRowBytes),
- [](const void* pixels, void*)
+ return fromSkSp(SkImage::MakeFromRaster(SkPixmap(info, imagePixels->data(), imageRowBytes),
+ [](const void*, void* pixels)
{
- delete[] static_cast<const uint8_t*>(pixels);
- }, nullptr));
+ static_cast<Uint8Array*>(pixels)->deref();
+ }, imagePixels.leakRef()));
}
-static void swizzleImageData(unsigned char* srcAddr, int height, int bytesPerRow, bool flipY)
+static void swizzleImageData(unsigned char* srcAddr, size_t height, size_t bytesPerRow, bool flipY)
{
if (flipY) {
- for (int i = 0; i < height / 2; i++) {
- int topRowStartPosition = i * bytesPerRow;
- int bottomRowStartPosition = (height - 1 - i) * bytesPerRow;
+ for (size_t i = 0; i < height / 2; i++) {
+ size_t topRowStartPosition = i * bytesPerRow;
+ size_t bottomRowStartPosition = (height - 1 - i) * bytesPerRow;
if (kN32_SkColorType == kBGRA_8888_SkColorType) { // needs to swizzle
- for (int j = 0; j < bytesPerRow; j += 4) {
+ for (size_t j = 0; j < bytesPerRow; j += 4) {
std::swap(srcAddr[topRowStartPosition + j], srcAddr[bottomRowStartPosition + j + 2]);
std::swap(srcAddr[topRowStartPosition + j + 1], srcAddr[bottomRowStartPosition + j + 1]);
std::swap(srcAddr[topRowStartPosition + j + 2], srcAddr[bottomRowStartPosition + j]);
@@ -137,39 +167,45 @@ static void swizzleImageData(unsigned char* srcAddr, int height, int bytesPerRow
}
} else {
if (kN32_SkColorType == kBGRA_8888_SkColorType) // needs to swizzle
- for (int i = 0; i < height * bytesPerRow; i += 4)
+ for (size_t i = 0; i < height * bytesPerRow; i += 4)
std::swap(srcAddr[i], srcAddr[i + 2]);
}
}
static PassRefPtr<SkImage> flipSkImageVertically(SkImage* input, AlphaDisposition alphaOp)
{
- int width = input->width();
- int height = input->height();
- SkImageInfo info = SkImageInfo::MakeN32(width, height, (alphaOp == PremultiplyAlpha) ? kPremul_SkAlphaType : kUnpremul_SkAlphaType);
- int imageRowBytes = width * info.bytesPerPixel();
- std::unique_ptr<uint8_t[]> imagePixels = copySkImageData(input, info);
- for (int i = 0; i < height / 2; i++) {
- int topFirstElement = i * imageRowBytes;
- int topLastElement = (i + 1) * imageRowBytes;
- int bottomFirstElement = (height - 1 - i) * imageRowBytes;
- std::swap_ranges(imagePixels.get() + topFirstElement, imagePixels.get() + topLastElement, imagePixels.get() + bottomFirstElement);
+ size_t width = static_cast<size_t>(input->width());
+ size_t height = static_cast<size_t>(input->height());
+ SkImageInfo info = SkImageInfo::MakeN32(input->width(), input->height(), (alphaOp == PremultiplyAlpha) ? kPremul_SkAlphaType : kUnpremul_SkAlphaType);
+ size_t imageRowBytes = width * info.bytesPerPixel();
+ RefPtr<Uint8Array> imagePixels = copySkImageData(input, info);
+ if (!imagePixels)
+ return nullptr;
+ for (size_t i = 0; i < height / 2; i++) {
+ size_t topFirstElement = i * imageRowBytes;
+ size_t topLastElement = (i + 1) * imageRowBytes;
+ size_t bottomFirstElement = (height - 1 - i) * imageRowBytes;
+ std::swap_ranges(imagePixels->data() + topFirstElement, imagePixels->data() + topLastElement, imagePixels->data() + bottomFirstElement);
}
- return newSkImageFromRaster(info, std::move(imagePixels), imageRowBytes);
+ return newSkImageFromRaster(info, imagePixels, imageRowBytes);
}
static PassRefPtr<SkImage> premulSkImageToUnPremul(SkImage* input)
{
SkImageInfo info = SkImageInfo::Make(input->width(), input->height(), kN32_SkColorType, kUnpremul_SkAlphaType);
- std::unique_ptr<uint8_t[]> dstPixels = copySkImageData(input, info);
- return newSkImageFromRaster(info, std::move(dstPixels), input->width() * info.bytesPerPixel());
+ RefPtr<Uint8Array> dstPixels = copySkImageData(input, info);
+ if (!dstPixels)
+ return nullptr;
+ return newSkImageFromRaster(info, dstPixels, static_cast<size_t>(input->width()) * info.bytesPerPixel());
}
static PassRefPtr<SkImage> unPremulSkImageToPremul(SkImage* input)
{
SkImageInfo info = SkImageInfo::Make(input->width(), input->height(), kN32_SkColorType, kPremul_SkAlphaType);
- std::unique_ptr<uint8_t[]> dstPixels = copySkImageData(input, info);
- return newSkImageFromRaster(info, std::move(dstPixels), input->width() * info.bytesPerPixel());
+ RefPtr<Uint8Array> dstPixels = copySkImageData(input, info);
+ if (!dstPixels)
+ return nullptr;
+ return newSkImageFromRaster(info, dstPixels, static_cast<size_t>(input->width()) * info.bytesPerPixel());
}
PassRefPtr<SkImage> ImageBitmap::getSkImageFromDecoder(std::unique_ptr<ImageDecoder> decoder)
@@ -218,8 +254,11 @@ static PassRefPtr<StaticBitmapImage> cropImage(Image* image, const ParsedOptions
// We immediately return a transparent black image with cropRect.size()
if (srcRect.isEmpty() && !parsedOptions.premultiplyAlpha) {
SkImageInfo info = SkImageInfo::Make(parsedOptions.resizeWidth, parsedOptions.resizeHeight, kN32_SkColorType, kUnpremul_SkAlphaType);
- std::unique_ptr<uint8_t[]> dstPixels = wrapArrayUnique(new uint8_t[info.width() * info.height() * info.bytesPerPixel()]());
- return StaticBitmapImage::create(newSkImageFromRaster(info, std::move(dstPixels), info.width() * info.bytesPerPixel()));
+ RefPtr<ArrayBuffer> dstBuffer = ArrayBuffer::createOrNull(static_cast<size_t>(info.width()) * info.height(), info.bytesPerPixel());
+ if (!dstBuffer)
+ return nullptr;
+ RefPtr<Uint8Array> dstPixels = Uint8Array::create(dstBuffer, 0, dstBuffer->byteLength());
+ return StaticBitmapImage::create(newSkImageFromRaster(info, dstPixels, static_cast<size_t>(info.width()) * info.bytesPerPixel()));
}
RefPtr<SkImage> skiaImage = image->imageForCurrentFrame();
@@ -277,7 +316,7 @@ static PassRefPtr<StaticBitmapImage> cropImage(Image* image, const ParsedOptions
skiaImage = fromSkSp(surface->makeImageSnapshot());
if (parsedOptions.premultiplyAlpha) {
- if (imageFormat == PremultiplyAlpha)
+ if (imageFormat == DontPremultiplyAlpha)
return StaticBitmapImage::create(unPremulSkImageToPremul(skiaImage.get()));
return StaticBitmapImage::create(skiaImage.release());
}
@@ -288,6 +327,8 @@ ImageBitmap::ImageBitmap(HTMLImageElement* image, Optional<IntRect> cropRect, Do
{
RefPtr<Image> input = image->cachedImage()->getImage();
ParsedOptions parsedOptions = parseOptions(options, cropRect, image->bitmapSourceSize());
+ if (dstBufferSizeHasOverflow(parsedOptions))
+ return;
if (options.colorSpaceConversion() == "none")
m_image = cropImage(input.get(), parsedOptions, PremultiplyAlpha, ImageDecoder::GammaAndColorProfileIgnored);
@@ -304,6 +345,8 @@ ImageBitmap::ImageBitmap(HTMLImageElement* image, Optional<IntRect> cropRect, Do
surface->getCanvas()->drawImage(skImage.get(), 0, 0);
m_image = StaticBitmapImage::create(fromSkSp(surface->makeImageSnapshot()));
}
+ if (!m_image)
+ return;
m_image->setOriginClean(!image->wouldTaintOrigin(document->getSecurityOrigin()));
m_image->setPremultiplied(parsedOptions.premultiplyAlpha);
}
@@ -314,6 +357,8 @@ ImageBitmap::ImageBitmap(HTMLVideoElement* video, Optional<IntRect> cropRect, Do
if (video->webMediaPlayer())
playerSize = video->webMediaPlayer()->naturalSize();
ParsedOptions parsedOptions = parseOptions(options, cropRect, video->bitmapSourceSize());
+ if (dstBufferSizeHasOverflow(parsedOptions))
+ return;
IntRect videoRect = IntRect(IntPoint(), playerSize);
IntRect srcRect = intersection(parsedOptions.cropRect, videoRect);
@@ -340,6 +385,8 @@ ImageBitmap::ImageBitmap(HTMLVideoElement* video, Optional<IntRect> cropRect, Do
RefPtr<SkImage> skiaImage = buffer->newSkImageSnapshot(PreferNoAcceleration, SnapshotReasonUnknown);
if (!parsedOptions.premultiplyAlpha)
skiaImage = premulSkImageToUnPremul(skiaImage.get());
+ if (!skiaImage)
+ return;
m_image = StaticBitmapImage::create(skiaImage.release());
m_image->setOriginClean(!video->wouldTaintOrigin(document->getSecurityOrigin()));
m_image->setPremultiplied(parsedOptions.premultiplyAlpha);
@@ -350,6 +397,8 @@ ImageBitmap::ImageBitmap(HTMLCanvasElement* canvas, Optional<IntRect> cropRect,
ASSERT(canvas->isPaintable());
RefPtr<Image> input = canvas->copiedImage(BackBuffer, PreferAcceleration);
ParsedOptions parsedOptions = parseOptions(options, cropRect, canvas->bitmapSourceSize());
+ if (dstBufferSizeHasOverflow(parsedOptions))
+ return;
bool isPremultiplyAlphaReverted = false;
if (!parsedOptions.premultiplyAlpha) {
@@ -363,6 +412,8 @@ ImageBitmap::ImageBitmap(HTMLCanvasElement* canvas, Optional<IntRect> cropRect,
parsedOptions.premultiplyAlpha = false;
m_image = StaticBitmapImage::create(premulSkImageToUnPremul(m_image->imageForCurrentFrame().get()));
}
+ if (!m_image)
+ return;
m_image->setOriginClean(canvas->originClean());
m_image->setPremultiplied(parsedOptions.premultiplyAlpha);
}
@@ -371,6 +422,8 @@ ImageBitmap::ImageBitmap(std::unique_ptr<uint8_t[]> data, uint32_t width, uint32
{
SkImageInfo info = SkImageInfo::MakeN32(width, height, isImageBitmapPremultiplied ? kPremul_SkAlphaType : kUnpremul_SkAlphaType);
m_image = StaticBitmapImage::create(fromSkSp(SkImage::MakeRasterCopy(SkPixmap(info, data.get(), info.bytesPerPixel() * width))));
+ if (!m_image)
+ return;
m_image->setPremultiplied(isImageBitmapPremultiplied);
m_image->setOriginClean(isImageBitmapOriginClean);
}
@@ -378,13 +431,16 @@ ImageBitmap::ImageBitmap(std::unique_ptr<uint8_t[]> data, uint32_t width, uint32
static PassRefPtr<SkImage> scaleSkImage(PassRefPtr<SkImage> skImage, unsigned resizeWidth, unsigned resizeHeight, SkFilterQuality resizeQuality)
{
SkImageInfo resizedInfo = SkImageInfo::Make(resizeWidth, resizeHeight, kN32_SkColorType, kUnpremul_SkAlphaType);
- std::unique_ptr<uint8_t[]> resizedPixels = wrapArrayUnique(new uint8_t[resizeWidth * resizeHeight * resizedInfo.bytesPerPixel()]);
- SkPixmap pixmap(resizedInfo, resizedPixels.release(), resizeWidth * resizedInfo.bytesPerPixel());
+ RefPtr<ArrayBuffer> dstBuffer = ArrayBuffer::createOrNull(resizeWidth * resizeHeight, resizedInfo.bytesPerPixel());
+ if (!dstBuffer)
+ return nullptr;
+ RefPtr<Uint8Array> resizedPixels = Uint8Array::create(dstBuffer, 0, dstBuffer->byteLength());
+ SkPixmap pixmap(resizedInfo, resizedPixels->data(), static_cast<size_t>(resizeWidth) * resizedInfo.bytesPerPixel());
skImage->scalePixels(pixmap, resizeQuality);
- return fromSkSp(SkImage::MakeFromRaster(pixmap, [](const void* pixels, void*)
+ return fromSkSp(SkImage::MakeFromRaster(pixmap, [](const void*, void* pixels)
{
- delete[] static_cast<const uint8_t*>(pixels);
- }, nullptr));
+ static_cast<Uint8Array*>(pixels)->deref();
+ }, resizedPixels.get()));
}
ImageBitmap::ImageBitmap(ImageData* data, Optional<IntRect> cropRect, const ImageBitmapOptions& options)
@@ -392,64 +448,72 @@ ImageBitmap::ImageBitmap(ImageData* data, Optional<IntRect> cropRect, const Imag
// TODO(xidachen): implement the resize option
IntRect dataSrcRect = IntRect(IntPoint(), data->size());
ParsedOptions parsedOptions = parseOptions(options, cropRect, data->bitmapSourceSize());
+ if (dstBufferSizeHasOverflow(parsedOptions))
+ return;
IntRect srcRect = cropRect ? intersection(parsedOptions.cropRect, dataSrcRect) : dataSrcRect;
// treat non-premultiplyAlpha as a special case
if (!parsedOptions.premultiplyAlpha) {
unsigned char* srcAddr = data->data()->data();
- int srcHeight = data->size().height();
- int dstHeight = parsedOptions.cropRect.height();
// Using kN32 type, swizzle input if necessary.
- SkImageInfo info = SkImageInfo::Make(parsedOptions.cropRect.width(), dstHeight, kN32_SkColorType, kUnpremul_SkAlphaType);
- int srcPixelBytesPerRow = info.bytesPerPixel() * data->size().width();
- int dstPixelBytesPerRow = info.bytesPerPixel() * parsedOptions.cropRect.width();
+ SkImageInfo info = SkImageInfo::Make(parsedOptions.cropRect.width(), parsedOptions.cropRect.height(), kN32_SkColorType, kUnpremul_SkAlphaType);
+ size_t bytesPerPixel = static_cast<size_t>(info.bytesPerPixel());
+ size_t srcPixelBytesPerRow = bytesPerPixel * data->size().width();
+ size_t dstPixelBytesPerRow = bytesPerPixel * parsedOptions.cropRect.width();
RefPtr<SkImage> skImage;
if (parsedOptions.cropRect == IntRect(IntPoint(), data->size())) {
- swizzleImageData(srcAddr, srcHeight, srcPixelBytesPerRow, parsedOptions.flipY);
+ swizzleImageData(srcAddr, data->size().height(), srcPixelBytesPerRow, parsedOptions.flipY);
skImage = fromSkSp(SkImage::MakeRasterCopy(SkPixmap(info, srcAddr, dstPixelBytesPerRow)));
// restore the original ImageData
- swizzleImageData(srcAddr, srcHeight, srcPixelBytesPerRow, parsedOptions.flipY);
+ swizzleImageData(srcAddr, data->size().height(), srcPixelBytesPerRow, parsedOptions.flipY);
} else {
- std::unique_ptr<uint8_t[]> copiedDataBuffer = wrapArrayUnique(new uint8_t[dstHeight * dstPixelBytesPerRow]());
+ RefPtr<ArrayBuffer> dstBuffer = ArrayBuffer::createOrNull(static_cast<size_t>(parsedOptions.cropRect.height()) * parsedOptions.cropRect.width(), bytesPerPixel);
+ if (!dstBuffer)
+ return;
+ RefPtr<Uint8Array> copiedDataBuffer = Uint8Array::create(dstBuffer, 0, dstBuffer->byteLength());
if (!srcRect.isEmpty()) {
IntPoint srcPoint = IntPoint((parsedOptions.cropRect.x() > 0) ? parsedOptions.cropRect.x() : 0, (parsedOptions.cropRect.y() > 0) ? parsedOptions.cropRect.y() : 0);
IntPoint dstPoint = IntPoint((parsedOptions.cropRect.x() >= 0) ? 0 : -parsedOptions.cropRect.x(), (parsedOptions.cropRect.y() >= 0) ? 0 : -parsedOptions.cropRect.y());
- int copyHeight = srcHeight - srcPoint.y();
+ int copyHeight = data->size().height() - srcPoint.y();
if (parsedOptions.cropRect.height() < copyHeight)
copyHeight = parsedOptions.cropRect.height();
int copyWidth = data->size().width() - srcPoint.x();
if (parsedOptions.cropRect.width() < copyWidth)
copyWidth = parsedOptions.cropRect.width();
for (int i = 0; i < copyHeight; i++) {
- int srcStartCopyPosition = (i + srcPoint.y()) * srcPixelBytesPerRow + srcPoint.x() * info.bytesPerPixel();
- int srcEndCopyPosition = srcStartCopyPosition + copyWidth * info.bytesPerPixel();
- int dstStartCopyPosition;
+ size_t srcStartCopyPosition = (i + srcPoint.y()) * srcPixelBytesPerRow + srcPoint.x() * bytesPerPixel;
+ size_t srcEndCopyPosition = srcStartCopyPosition + copyWidth * bytesPerPixel;
+ size_t dstStartCopyPosition;
if (parsedOptions.flipY)
- dstStartCopyPosition = (dstHeight -1 - dstPoint.y() - i) * dstPixelBytesPerRow + dstPoint.x() * info.bytesPerPixel();
+ dstStartCopyPosition = (parsedOptions.cropRect.height() -1 - dstPoint.y() - i) * dstPixelBytesPerRow + dstPoint.x() * bytesPerPixel;
else
- dstStartCopyPosition = (dstPoint.y() + i) * dstPixelBytesPerRow + dstPoint.x() * info.bytesPerPixel();
- for (int j = 0; j < srcEndCopyPosition - srcStartCopyPosition; j++) {
+ dstStartCopyPosition = (dstPoint.y() + i) * dstPixelBytesPerRow + dstPoint.x() * bytesPerPixel;
+ for (size_t j = 0; j < srcEndCopyPosition - srcStartCopyPosition; j++) {
// swizzle when necessary
if (kN32_SkColorType == kBGRA_8888_SkColorType) {
if (j % 4 == 0)
- copiedDataBuffer[dstStartCopyPosition + j] = srcAddr[srcStartCopyPosition + j + 2];
+ copiedDataBuffer->data()[dstStartCopyPosition + j] = srcAddr[srcStartCopyPosition + j + 2];
else if (j % 4 == 2)
- copiedDataBuffer[dstStartCopyPosition + j] = srcAddr[srcStartCopyPosition + j - 2];
+ copiedDataBuffer->data()[dstStartCopyPosition + j] = srcAddr[srcStartCopyPosition + j - 2];
else
- copiedDataBuffer[dstStartCopyPosition + j] = srcAddr[srcStartCopyPosition + j];
+ copiedDataBuffer->data()[dstStartCopyPosition + j] = srcAddr[srcStartCopyPosition + j];
} else {
- copiedDataBuffer[dstStartCopyPosition + j] = srcAddr[srcStartCopyPosition + j];
+ copiedDataBuffer->data()[dstStartCopyPosition + j] = srcAddr[srcStartCopyPosition + j];
}
}
}
}
- skImage = newSkImageFromRaster(info, std::move(copiedDataBuffer), dstPixelBytesPerRow);
+ skImage = newSkImageFromRaster(info, copiedDataBuffer, dstPixelBytesPerRow);
}
+ if (!skImage)
+ return;
if (parsedOptions.shouldScaleInput)
m_image = StaticBitmapImage::create(scaleSkImage(skImage, parsedOptions.resizeWidth, parsedOptions.resizeHeight, parsedOptions.resizeQuality));
else
m_image = StaticBitmapImage::create(skImage);
+ if (!m_image)
+ return;
m_image->setPremultiplied(parsedOptions.premultiplyAlpha);
return;
}
@@ -472,6 +536,8 @@ ImageBitmap::ImageBitmap(ImageData* data, Optional<IntRect> cropRect, const Imag
RefPtr<SkImage> skImage = buffer->newSkImageSnapshot(PreferNoAcceleration, SnapshotReasonUnknown);
if (parsedOptions.flipY)
skImage = flipSkImageVertically(skImage.get(), PremultiplyAlpha);
+ if (!skImage)
+ return;
if (parsedOptions.shouldScaleInput) {
sk_sp<SkSurface> surface = SkSurface::MakeRasterN32Premul(parsedOptions.resizeWidth, parsedOptions.resizeHeight);
if (!surface)
@@ -491,6 +557,8 @@ ImageBitmap::ImageBitmap(ImageBitmap* bitmap, Optional<IntRect> cropRect, const
if (!input)
return;
ParsedOptions parsedOptions = parseOptions(options, cropRect, input->size());
+ if (dstBufferSizeHasOverflow(parsedOptions))
+ return;
m_image = cropImage(input.get(), parsedOptions, bitmap->isPremultiplied() ? PremultiplyAlpha : DontPremultiplyAlpha);
if (!m_image)
@@ -504,6 +572,8 @@ ImageBitmap::ImageBitmap(PassRefPtr<StaticBitmapImage> image, Optional<IntRect>
bool originClean = image->originClean();
RefPtr<Image> input = image;
ParsedOptions parsedOptions = parseOptions(options, cropRect, input->size());
+ if (dstBufferSizeHasOverflow(parsedOptions))
+ return;
m_image = cropImage(input.get(), parsedOptions, DontPremultiplyAlpha);
if (!m_image)
@@ -582,10 +652,10 @@ ImageBitmap* ImageBitmap::take(ScriptPromiseResolver*, sk_sp<SkImage> image)
return ImageBitmap::create(StaticBitmapImage::create(fromSkSp(image)));
}
-std::unique_ptr<uint8_t[]> ImageBitmap::copyBitmapData(AlphaDisposition alphaOp, DataColorFormat format)
+PassRefPtr<Uint8Array> ImageBitmap::copyBitmapData(AlphaDisposition alphaOp, DataColorFormat format)
{
SkImageInfo info = SkImageInfo::Make(width(), height(), (format == RGBAColorType) ? kRGBA_8888_SkColorType : kN32_SkColorType, (alphaOp == PremultiplyAlpha) ? kPremul_SkAlphaType : kUnpremul_SkAlphaType);
- std::unique_ptr<uint8_t[]> dstPixels = copySkImageData(m_image->imageForCurrentFrame().get(), info);
+ RefPtr<Uint8Array> dstPixels = copySkImageData(m_image->imageForCurrentFrame().get(), info);
return dstPixels;
}

Powered by Google App Engine
This is Rietveld 408576698