Chromium Code Reviews| 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; |
| } |