Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "core/frame/ImageBitmap.h" | 5 #include "core/frame/ImageBitmap.h" |
| 6 | 6 |
| 7 #include "core/html/HTMLCanvasElement.h" | 7 #include "core/html/HTMLCanvasElement.h" |
| 8 #include "core/html/HTMLVideoElement.h" | 8 #include "core/html/HTMLVideoElement.h" |
| 9 #include "core/html/ImageData.h" | 9 #include "core/html/ImageData.h" |
| 10 #include "platform/graphics/skia/SkiaUtils.h" | 10 #include "platform/graphics/skia/SkiaUtils.h" |
| (...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 118 return false; | 118 return false; |
| 119 totalBytes = options.resizeWidth; | 119 totalBytes = options.resizeWidth; |
| 120 totalBytes *= options.resizeHeight; | 120 totalBytes *= options.resizeHeight; |
| 121 totalBytes *= options.bytesPerPixel; | 121 totalBytes *= options.bytesPerPixel; |
| 122 if (!totalBytes.IsValid()) | 122 if (!totalBytes.IsValid()) |
| 123 return true; | 123 return true; |
| 124 | 124 |
| 125 return false; | 125 return false; |
| 126 } | 126 } |
| 127 | 127 |
| 128 bool arrayBufferCreationHasOverflow(unsigned width, unsigned height) { | |
| 129 CheckedNumeric<unsigned> numElement = width; | |
| 130 numElement *= height; | |
|
Justin Novosad
2016/11/11 14:40:29
It'a a bit wasteful that this product is always re
| |
| 131 if (!numElement.IsValid()) | |
| 132 return true; | |
| 133 return false; | |
| 134 } | |
| 135 | |
| 128 } // namespace | 136 } // namespace |
| 129 | 137 |
| 130 static PassRefPtr<Uint8Array> copySkImageData(SkImage* input, | 138 static PassRefPtr<Uint8Array> copySkImageData(SkImage* input, |
| 131 const SkImageInfo& info) { | 139 const SkImageInfo& info) { |
| 140 if (arrayBufferCreationHasOverflow(static_cast<unsigned>(input->width()), | |
| 141 static_cast<unsigned>(input->height()))) | |
| 142 return nullptr; | |
| 132 // The function dstBufferSizeHasOverflow() is being called at the beginning of | 143 // The function dstBufferSizeHasOverflow() is being called at the beginning of |
| 133 // each ImageBitmap() constructor, which makes sure that doing | 144 // each ImageBitmap() constructor, which makes sure that doing |
| 134 // width * height * bytesPerPixel will never overflow size_t. | 145 // width * height * bytesPerPixel will never overflow size_t. |
| 135 size_t width = static_cast<size_t>(input->width()); | 146 size_t width = static_cast<size_t>(input->width()); |
|
Justin Novosad
2016/11/11 14:40:29
Here width is size_t, but the check was done using
| |
| 136 RefPtr<ArrayBuffer> dstBuffer = | 147 RefPtr<ArrayBuffer> dstBuffer = |
| 137 ArrayBuffer::createOrNull(width * input->height(), info.bytesPerPixel()); | 148 ArrayBuffer::createOrNull(width * input->height(), info.bytesPerPixel()); |
| 138 if (!dstBuffer) | 149 if (!dstBuffer) |
| 139 return nullptr; | 150 return nullptr; |
| 140 RefPtr<Uint8Array> dstPixels = | 151 RefPtr<Uint8Array> dstPixels = |
| 141 Uint8Array::create(dstBuffer, 0, dstBuffer->byteLength()); | 152 Uint8Array::create(dstBuffer, 0, dstBuffer->byteLength()); |
| 142 input->readPixels(info, dstPixels->data(), width * info.bytesPerPixel(), 0, | 153 input->readPixels(info, dstPixels->data(), width * info.bytesPerPixel(), 0, |
| 143 0); | 154 0); |
| 144 return dstPixels; | 155 return dstPixels; |
| 145 } | 156 } |
| (...skipping 133 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 279 ImageDecoder::ColorSpaceOption colorSpaceOp = | 290 ImageDecoder::ColorSpaceOption colorSpaceOp = |
| 280 ImageDecoder::ColorSpaceApplied) { | 291 ImageDecoder::ColorSpaceApplied) { |
| 281 ASSERT(image); | 292 ASSERT(image); |
| 282 IntRect imgRect(IntPoint(), IntSize(image->width(), image->height())); | 293 IntRect imgRect(IntPoint(), IntSize(image->width(), image->height())); |
| 283 const IntRect srcRect = intersection(imgRect, parsedOptions.cropRect); | 294 const IntRect srcRect = intersection(imgRect, parsedOptions.cropRect); |
| 284 | 295 |
| 285 // In the case when cropRect doesn't intersect the source image and it | 296 // In the case when cropRect doesn't intersect the source image and it |
| 286 // requires a umpremul image We immediately return a transparent black image | 297 // requires a umpremul image We immediately return a transparent black image |
| 287 // with cropRect.size() | 298 // with cropRect.size() |
| 288 if (srcRect.isEmpty() && !parsedOptions.premultiplyAlpha) { | 299 if (srcRect.isEmpty() && !parsedOptions.premultiplyAlpha) { |
| 300 if (arrayBufferCreationHasOverflow(parsedOptions.resizeWidth, | |
| 301 parsedOptions.resizeHeight)) | |
| 302 return nullptr; | |
| 289 SkImageInfo info = | 303 SkImageInfo info = |
| 290 SkImageInfo::Make(parsedOptions.resizeWidth, parsedOptions.resizeHeight, | 304 SkImageInfo::Make(parsedOptions.resizeWidth, parsedOptions.resizeHeight, |
| 291 kN32_SkColorType, kUnpremul_SkAlphaType); | 305 kN32_SkColorType, kUnpremul_SkAlphaType); |
| 292 RefPtr<ArrayBuffer> dstBuffer = ArrayBuffer::createOrNull( | 306 RefPtr<ArrayBuffer> dstBuffer = ArrayBuffer::createOrNull( |
| 293 static_cast<size_t>(info.width()) * info.height(), | 307 static_cast<size_t>(info.width()) * info.height(), |
| 294 info.bytesPerPixel()); | 308 info.bytesPerPixel()); |
| 295 if (!dstBuffer) | 309 if (!dstBuffer) |
| 296 return nullptr; | 310 return nullptr; |
| 297 RefPtr<Uint8Array> dstPixels = | 311 RefPtr<Uint8Array> dstPixels = |
| 298 Uint8Array::create(dstBuffer, 0, dstBuffer->byteLength()); | 312 Uint8Array::create(dstBuffer, 0, dstBuffer->byteLength()); |
| (...skipping 208 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 507 if (!m_image) | 521 if (!m_image) |
| 508 return; | 522 return; |
| 509 m_image->setPremultiplied(isImageBitmapPremultiplied); | 523 m_image->setPremultiplied(isImageBitmapPremultiplied); |
| 510 m_image->setOriginClean(isImageBitmapOriginClean); | 524 m_image->setOriginClean(isImageBitmapOriginClean); |
| 511 } | 525 } |
| 512 | 526 |
| 513 static sk_sp<SkImage> scaleSkImage(sk_sp<SkImage> skImage, | 527 static sk_sp<SkImage> scaleSkImage(sk_sp<SkImage> skImage, |
| 514 unsigned resizeWidth, | 528 unsigned resizeWidth, |
| 515 unsigned resizeHeight, | 529 unsigned resizeHeight, |
| 516 SkFilterQuality resizeQuality) { | 530 SkFilterQuality resizeQuality) { |
| 531 if (arrayBufferCreationHasOverflow(resizeWidth, resizeHeight)) | |
| 532 return nullptr; | |
| 517 SkImageInfo resizedInfo = SkImageInfo::Make( | 533 SkImageInfo resizedInfo = SkImageInfo::Make( |
| 518 resizeWidth, resizeHeight, kN32_SkColorType, kUnpremul_SkAlphaType); | 534 resizeWidth, resizeHeight, kN32_SkColorType, kUnpremul_SkAlphaType); |
| 519 RefPtr<ArrayBuffer> dstBuffer = ArrayBuffer::createOrNull( | 535 RefPtr<ArrayBuffer> dstBuffer = ArrayBuffer::createOrNull( |
| 520 resizeWidth * resizeHeight, resizedInfo.bytesPerPixel()); | 536 resizeWidth * resizeHeight, resizedInfo.bytesPerPixel()); |
| 521 if (!dstBuffer) | 537 if (!dstBuffer) |
| 522 return nullptr; | 538 return nullptr; |
| 523 RefPtr<Uint8Array> resizedPixels = | 539 RefPtr<Uint8Array> resizedPixels = |
| 524 Uint8Array::create(dstBuffer, 0, dstBuffer->byteLength()); | 540 Uint8Array::create(dstBuffer, 0, dstBuffer->byteLength()); |
| 525 SkPixmap pixmap( | 541 SkPixmap pixmap( |
| 526 resizedInfo, resizedPixels->data(), | 542 resizedInfo, resizedPixels->data(), |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 559 sk_sp<SkImage> skImage; | 575 sk_sp<SkImage> skImage; |
| 560 if (parsedOptions.cropRect == IntRect(IntPoint(), data->size())) { | 576 if (parsedOptions.cropRect == IntRect(IntPoint(), data->size())) { |
| 561 swizzleImageData(srcAddr, data->size().height(), srcPixelBytesPerRow, | 577 swizzleImageData(srcAddr, data->size().height(), srcPixelBytesPerRow, |
| 562 parsedOptions.flipY); | 578 parsedOptions.flipY); |
| 563 skImage = | 579 skImage = |
| 564 SkImage::MakeRasterCopy(SkPixmap(info, srcAddr, dstPixelBytesPerRow)); | 580 SkImage::MakeRasterCopy(SkPixmap(info, srcAddr, dstPixelBytesPerRow)); |
| 565 // restore the original ImageData | 581 // restore the original ImageData |
| 566 swizzleImageData(srcAddr, data->size().height(), srcPixelBytesPerRow, | 582 swizzleImageData(srcAddr, data->size().height(), srcPixelBytesPerRow, |
| 567 parsedOptions.flipY); | 583 parsedOptions.flipY); |
| 568 } else { | 584 } else { |
| 585 if (arrayBufferCreationHasOverflow( | |
| 586 static_cast<unsigned>(parsedOptions.cropRect.width()), | |
| 587 static_cast<unsigned>(parsedOptions.cropRect.height()))) | |
| 588 return; | |
| 569 RefPtr<ArrayBuffer> dstBuffer = ArrayBuffer::createOrNull( | 589 RefPtr<ArrayBuffer> dstBuffer = ArrayBuffer::createOrNull( |
| 570 static_cast<size_t>(parsedOptions.cropRect.height()) * | 590 static_cast<size_t>(parsedOptions.cropRect.height()) * |
| 571 parsedOptions.cropRect.width(), | 591 parsedOptions.cropRect.width(), |
| 572 bytesPerPixel); | 592 bytesPerPixel); |
| 573 if (!dstBuffer) | 593 if (!dstBuffer) |
| 574 return; | 594 return; |
| 575 RefPtr<Uint8Array> copiedDataBuffer = | 595 RefPtr<Uint8Array> copiedDataBuffer = |
| 576 Uint8Array::create(dstBuffer, 0, dstBuffer->byteLength()); | 596 Uint8Array::create(dstBuffer, 0, dstBuffer->byteLength()); |
| 577 if (!srcRect.isEmpty()) { | 597 if (!srcRect.isEmpty()) { |
| 578 IntPoint srcPoint = IntPoint( | 598 IntPoint srcPoint = IntPoint( |
| (...skipping 278 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 857 void ImageBitmap::adjustDrawRects(FloatRect* srcRect, | 877 void ImageBitmap::adjustDrawRects(FloatRect* srcRect, |
| 858 FloatRect* dstRect) const {} | 878 FloatRect* dstRect) const {} |
| 859 | 879 |
| 860 FloatSize ImageBitmap::elementSize(const FloatSize&) const { | 880 FloatSize ImageBitmap::elementSize(const FloatSize&) const { |
| 861 return FloatSize(width(), height()); | 881 return FloatSize(width(), height()); |
| 862 } | 882 } |
| 863 | 883 |
| 864 DEFINE_TRACE(ImageBitmap) {} | 884 DEFINE_TRACE(ImageBitmap) {} |
| 865 | 885 |
| 866 } // namespace blink | 886 } // namespace blink |
| OLD | NEW |