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 |