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" |
11 #include "platform/image-decoders/ImageDecoder.h" | 11 #include "platform/image-decoders/ImageDecoder.h" |
12 #include "third_party/skia/include/core/SkCanvas.h" | 12 #include "third_party/skia/include/core/SkCanvas.h" |
13 #include "third_party/skia/include/core/SkSurface.h" | 13 #include "third_party/skia/include/core/SkSurface.h" |
14 #include "wtf/CheckedNumeric.h" | |
14 #include "wtf/PtrUtil.h" | 15 #include "wtf/PtrUtil.h" |
15 #include "wtf/RefPtr.h" | 16 #include "wtf/RefPtr.h" |
16 #include <memory> | 17 #include <memory> |
17 | 18 |
18 namespace blink { | 19 namespace blink { |
19 | 20 |
20 static const char* imageOrientationFlipY = "flipY"; | 21 static const char* imageOrientationFlipY = "flipY"; |
21 static const char* imageBitmapOptionNone = "none"; | 22 static const char* imageBitmapOptionNone = "none"; |
22 | 23 |
23 namespace { | 24 namespace { |
24 | 25 |
25 struct ParsedOptions { | 26 struct ParsedOptions { |
26 bool flipY = false; | 27 bool flipY = false; |
27 bool premultiplyAlpha = true; | 28 bool premultiplyAlpha = true; |
28 bool shouldScaleInput = false; | 29 bool shouldScaleInput = false; |
29 unsigned resizeWidth = 0; | 30 unsigned resizeWidth = 0; |
30 unsigned resizeHeight = 0; | 31 unsigned resizeHeight = 0; |
31 IntRect cropRect; | 32 IntRect cropRect; |
32 SkFilterQuality resizeQuality = kLow_SkFilterQuality; | 33 SkFilterQuality resizeQuality = kLow_SkFilterQuality; |
34 // This value should be changed in the future when we support createImageBit map with higher | |
35 // bit depth, in the parseOptions() function. For now, it is always 4. | |
36 int bytesPerPixel = 4; | |
33 }; | 37 }; |
34 | 38 |
35 // The following two functions are helpers used in cropImage | 39 // The following two functions are helpers used in cropImage |
36 static inline IntRect normalizeRect(const IntRect& rect) | 40 static inline IntRect normalizeRect(const IntRect& rect) |
37 { | 41 { |
38 return IntRect(std::min(rect.x(), rect.maxX()), | 42 return IntRect(std::min(rect.x(), rect.maxX()), |
39 std::min(rect.y(), rect.maxY()), | 43 std::min(rect.y(), rect.maxY()), |
40 std::max(rect.width(), -rect.width()), | 44 std::max(rect.width(), -rect.width()), |
41 std::max(rect.height(), -rect.height())); | 45 std::max(rect.height(), -rect.height())); |
42 } | 46 } |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
93 parsedOptions.resizeQuality = kHigh_SkFilterQuality; | 97 parsedOptions.resizeQuality = kHigh_SkFilterQuality; |
94 else if (options.resizeQuality() == "medium") | 98 else if (options.resizeQuality() == "medium") |
95 parsedOptions.resizeQuality = kMedium_SkFilterQuality; | 99 parsedOptions.resizeQuality = kMedium_SkFilterQuality; |
96 else if (options.resizeQuality() == "pixelated") | 100 else if (options.resizeQuality() == "pixelated") |
97 parsedOptions.resizeQuality = kNone_SkFilterQuality; | 101 parsedOptions.resizeQuality = kNone_SkFilterQuality; |
98 else | 102 else |
99 parsedOptions.resizeQuality = kLow_SkFilterQuality; | 103 parsedOptions.resizeQuality = kLow_SkFilterQuality; |
100 return parsedOptions; | 104 return parsedOptions; |
101 } | 105 } |
102 | 106 |
107 bool dstBufferSizeHasOverflow(ParsedOptions options) | |
108 { | |
109 CheckedNumeric<size_t> totalBytes = options.cropRect.width(); | |
110 totalBytes *= options.cropRect.height(); | |
111 totalBytes *= options.bytesPerPixel; | |
112 if (!totalBytes.IsValid()) | |
113 return true; | |
114 | |
115 if (!options.shouldScaleInput) | |
116 return false; | |
117 totalBytes = options.resizeWidth; | |
118 totalBytes *= options.resizeHeight; | |
119 totalBytes *= options.bytesPerPixel; | |
120 if (!totalBytes.IsValid()) | |
121 return true; | |
122 | |
123 return false; | |
124 } | |
125 | |
103 } // namespace | 126 } // namespace |
104 | 127 |
105 static std::unique_ptr<uint8_t[]> copySkImageData(SkImage* input, const SkImageI nfo& info) | 128 static PassRefPtr<Uint8Array> copySkImageData(SkImage* input, const SkImageInfo& info) |
106 { | 129 { |
107 std::unique_ptr<uint8_t[]> dstPixels = wrapArrayUnique(new uint8_t[input->wi dth() * input->height() * info.bytesPerPixel()]); | 130 // The function dstBufferSizeHasOverflow() is being called at the beginning of each |
108 input->readPixels(info, dstPixels.get(), input->width() * info.bytesPerPixel (), 0, 0); | 131 // ImageBitmap() constructor, which makes sure that doing width * height * b ytesPerPixel |
132 // will never overflow size_t. | |
133 size_t width = static_cast<size_t>(input->width()); | |
134 RefPtr<ArrayBuffer> dstBuffer = ArrayBuffer::createOrNull(width * input->hei ght(), info.bytesPerPixel()); | |
135 if (!dstBuffer) | |
136 return nullptr; | |
137 RefPtr<Uint8Array> dstPixels = Uint8Array::create(dstBuffer, 0, dstBuffer->b yteLength()); | |
138 input->readPixels(info, dstPixels->data(), width * info.bytesPerPixel(), 0, 0); | |
109 return dstPixels; | 139 return dstPixels; |
110 } | 140 } |
111 | 141 |
112 static PassRefPtr<SkImage> newSkImageFromRaster(const SkImageInfo& info, std::un ique_ptr<uint8_t[]> imagePixels, int imageRowBytes) | 142 static PassRefPtr<SkImage> newSkImageFromRaster(const SkImageInfo& info, PassRef Ptr<Uint8Array> imagePixels, size_t imageRowBytes) |
Justin Novosad
2016/08/24 14:49:12
PassRefPtr is deprecated. RefPtr, with std::move a
| |
113 { | 143 { |
114 return fromSkSp(SkImage::MakeFromRaster(SkPixmap(info, imagePixels.release() , imageRowBytes), | 144 return fromSkSp(SkImage::MakeFromRaster(SkPixmap(info, imagePixels->data(), imageRowBytes), |
115 [](const void* pixels, void*) | 145 [](const void*, void* pixels) |
116 { | 146 { |
117 delete[] static_cast<const uint8_t*>(pixels); | 147 static_cast<Uint8Array*>(pixels)->deref(); |
118 }, nullptr)); | 148 }, imagePixels.leakRef())); |
119 } | 149 } |
120 | 150 |
121 static void swizzleImageData(unsigned char* srcAddr, int height, int bytesPerRow , bool flipY) | 151 static void swizzleImageData(unsigned char* srcAddr, size_t height, size_t bytes PerRow, bool flipY) |
122 { | 152 { |
123 if (flipY) { | 153 if (flipY) { |
124 for (int i = 0; i < height / 2; i++) { | 154 for (size_t i = 0; i < height / 2; i++) { |
125 int topRowStartPosition = i * bytesPerRow; | 155 size_t topRowStartPosition = i * bytesPerRow; |
126 int bottomRowStartPosition = (height - 1 - i) * bytesPerRow; | 156 size_t bottomRowStartPosition = (height - 1 - i) * bytesPerRow; |
127 if (kN32_SkColorType == kBGRA_8888_SkColorType) { // needs to swizzl e | 157 if (kN32_SkColorType == kBGRA_8888_SkColorType) { // needs to swizzl e |
128 for (int j = 0; j < bytesPerRow; j += 4) { | 158 for (size_t j = 0; j < bytesPerRow; j += 4) { |
129 std::swap(srcAddr[topRowStartPosition + j], srcAddr[bottomRo wStartPosition + j + 2]); | 159 std::swap(srcAddr[topRowStartPosition + j], srcAddr[bottomRo wStartPosition + j + 2]); |
130 std::swap(srcAddr[topRowStartPosition + j + 1], srcAddr[bott omRowStartPosition + j + 1]); | 160 std::swap(srcAddr[topRowStartPosition + j + 1], srcAddr[bott omRowStartPosition + j + 1]); |
131 std::swap(srcAddr[topRowStartPosition + j + 2], srcAddr[bott omRowStartPosition + j]); | 161 std::swap(srcAddr[topRowStartPosition + j + 2], srcAddr[bott omRowStartPosition + j]); |
132 std::swap(srcAddr[topRowStartPosition + j + 3], srcAddr[bott omRowStartPosition + j + 3]); | 162 std::swap(srcAddr[topRowStartPosition + j + 3], srcAddr[bott omRowStartPosition + j + 3]); |
133 } | 163 } |
134 } else { | 164 } else { |
135 std::swap_ranges(srcAddr + topRowStartPosition, srcAddr + topRow StartPosition + bytesPerRow, srcAddr + bottomRowStartPosition); | 165 std::swap_ranges(srcAddr + topRowStartPosition, srcAddr + topRow StartPosition + bytesPerRow, srcAddr + bottomRowStartPosition); |
136 } | 166 } |
137 } | 167 } |
138 } else { | 168 } else { |
139 if (kN32_SkColorType == kBGRA_8888_SkColorType) // needs to swizzle | 169 if (kN32_SkColorType == kBGRA_8888_SkColorType) // needs to swizzle |
140 for (int i = 0; i < height * bytesPerRow; i += 4) | 170 for (size_t i = 0; i < height * bytesPerRow; i += 4) |
141 std::swap(srcAddr[i], srcAddr[i + 2]); | 171 std::swap(srcAddr[i], srcAddr[i + 2]); |
142 } | 172 } |
143 } | 173 } |
144 | 174 |
145 static PassRefPtr<SkImage> flipSkImageVertically(SkImage* input, AlphaDispositio n alphaOp) | 175 static PassRefPtr<SkImage> flipSkImageVertically(SkImage* input, AlphaDispositio n alphaOp) |
146 { | 176 { |
147 int width = input->width(); | 177 size_t width = static_cast<size_t>(input->width()); |
148 int height = input->height(); | 178 size_t height = static_cast<size_t>(input->height()); |
149 SkImageInfo info = SkImageInfo::MakeN32(width, height, (alphaOp == Premultip lyAlpha) ? kPremul_SkAlphaType : kUnpremul_SkAlphaType); | 179 SkImageInfo info = SkImageInfo::MakeN32(input->width(), input->height(), (al phaOp == PremultiplyAlpha) ? kPremul_SkAlphaType : kUnpremul_SkAlphaType); |
150 int imageRowBytes = width * info.bytesPerPixel(); | 180 size_t imageRowBytes = width * info.bytesPerPixel(); |
151 std::unique_ptr<uint8_t[]> imagePixels = copySkImageData(input, info); | 181 RefPtr<Uint8Array> imagePixels = copySkImageData(input, info); |
152 for (int i = 0; i < height / 2; i++) { | 182 if (!imagePixels) |
153 int topFirstElement = i * imageRowBytes; | 183 return nullptr; |
154 int topLastElement = (i + 1) * imageRowBytes; | 184 for (size_t i = 0; i < height / 2; i++) { |
155 int bottomFirstElement = (height - 1 - i) * imageRowBytes; | 185 size_t topFirstElement = i * imageRowBytes; |
156 std::swap_ranges(imagePixels.get() + topFirstElement, imagePixels.get() + topLastElement, imagePixels.get() + bottomFirstElement); | 186 size_t topLastElement = (i + 1) * imageRowBytes; |
187 size_t bottomFirstElement = (height - 1 - i) * imageRowBytes; | |
188 std::swap_ranges(imagePixels->data() + topFirstElement, imagePixels->dat a() + topLastElement, imagePixels->data() + bottomFirstElement); | |
157 } | 189 } |
158 return newSkImageFromRaster(info, std::move(imagePixels), imageRowBytes); | 190 return newSkImageFromRaster(info, imagePixels, imageRowBytes); |
159 } | 191 } |
160 | 192 |
161 static PassRefPtr<SkImage> premulSkImageToUnPremul(SkImage* input) | 193 static PassRefPtr<SkImage> premulSkImageToUnPremul(SkImage* input) |
162 { | 194 { |
163 SkImageInfo info = SkImageInfo::Make(input->width(), input->height(), kN32_S kColorType, kUnpremul_SkAlphaType); | 195 SkImageInfo info = SkImageInfo::Make(input->width(), input->height(), kN32_S kColorType, kUnpremul_SkAlphaType); |
164 std::unique_ptr<uint8_t[]> dstPixels = copySkImageData(input, info); | 196 RefPtr<Uint8Array> dstPixels = copySkImageData(input, info); |
165 return newSkImageFromRaster(info, std::move(dstPixels), input->width() * inf o.bytesPerPixel()); | 197 if (!dstPixels) |
198 return nullptr; | |
199 return newSkImageFromRaster(info, dstPixels, static_cast<size_t>(input->widt h()) * info.bytesPerPixel()); | |
166 } | 200 } |
167 | 201 |
168 static PassRefPtr<SkImage> unPremulSkImageToPremul(SkImage* input) | 202 static PassRefPtr<SkImage> unPremulSkImageToPremul(SkImage* input) |
169 { | 203 { |
170 SkImageInfo info = SkImageInfo::Make(input->width(), input->height(), kN32_S kColorType, kPremul_SkAlphaType); | 204 SkImageInfo info = SkImageInfo::Make(input->width(), input->height(), kN32_S kColorType, kPremul_SkAlphaType); |
171 std::unique_ptr<uint8_t[]> dstPixels = copySkImageData(input, info); | 205 RefPtr<Uint8Array> dstPixels = copySkImageData(input, info); |
172 return newSkImageFromRaster(info, std::move(dstPixels), input->width() * inf o.bytesPerPixel()); | 206 if (!dstPixels) |
207 return nullptr; | |
208 return newSkImageFromRaster(info, dstPixels, static_cast<size_t>(input->widt h()) * info.bytesPerPixel()); | |
173 } | 209 } |
174 | 210 |
175 PassRefPtr<SkImage> ImageBitmap::getSkImageFromDecoder(std::unique_ptr<ImageDeco der> decoder) | 211 PassRefPtr<SkImage> ImageBitmap::getSkImageFromDecoder(std::unique_ptr<ImageDeco der> decoder) |
176 { | 212 { |
177 if (!decoder->frameCount()) | 213 if (!decoder->frameCount()) |
178 return nullptr; | 214 return nullptr; |
179 ImageFrame* frame = decoder->frameBufferAtIndex(0); | 215 ImageFrame* frame = decoder->frameBufferAtIndex(0); |
180 if (!frame || frame->getStatus() != ImageFrame::FrameComplete) | 216 if (!frame || frame->getStatus() != ImageFrame::FrameComplete) |
181 return nullptr; | 217 return nullptr; |
182 SkBitmap bitmap = frame->bitmap(); | 218 SkBitmap bitmap = frame->bitmap(); |
(...skipping 28 matching lines...) Expand all Loading... | |
211 { | 247 { |
212 ASSERT(image); | 248 ASSERT(image); |
213 | 249 |
214 IntRect imgRect(IntPoint(), IntSize(image->width(), image->height())); | 250 IntRect imgRect(IntPoint(), IntSize(image->width(), image->height())); |
215 const IntRect srcRect = intersection(imgRect, parsedOptions.cropRect); | 251 const IntRect srcRect = intersection(imgRect, parsedOptions.cropRect); |
216 | 252 |
217 // In the case when cropRect doesn't intersect the source image and it requi res a umpremul image | 253 // In the case when cropRect doesn't intersect the source image and it requi res a umpremul image |
218 // We immediately return a transparent black image with cropRect.size() | 254 // We immediately return a transparent black image with cropRect.size() |
219 if (srcRect.isEmpty() && !parsedOptions.premultiplyAlpha) { | 255 if (srcRect.isEmpty() && !parsedOptions.premultiplyAlpha) { |
220 SkImageInfo info = SkImageInfo::Make(parsedOptions.resizeWidth, parsedOp tions.resizeHeight, kN32_SkColorType, kUnpremul_SkAlphaType); | 256 SkImageInfo info = SkImageInfo::Make(parsedOptions.resizeWidth, parsedOp tions.resizeHeight, kN32_SkColorType, kUnpremul_SkAlphaType); |
221 std::unique_ptr<uint8_t[]> dstPixels = wrapArrayUnique(new uint8_t[info. width() * info.height() * info.bytesPerPixel()]()); | 257 RefPtr<ArrayBuffer> dstBuffer = ArrayBuffer::createOrNull(static_cast<si ze_t>(info.width()) * info.height(), info.bytesPerPixel()); |
222 return StaticBitmapImage::create(newSkImageFromRaster(info, std::move(ds tPixels), info.width() * info.bytesPerPixel())); | 258 if (!dstBuffer) |
259 return nullptr; | |
260 RefPtr<Uint8Array> dstPixels = Uint8Array::create(dstBuffer, 0, dstBuffe r->byteLength()); | |
261 return StaticBitmapImage::create(newSkImageFromRaster(info, dstPixels, s tatic_cast<size_t>(info.width()) * info.bytesPerPixel())); | |
223 } | 262 } |
224 | 263 |
225 RefPtr<SkImage> skiaImage = image->imageForCurrentFrame(); | 264 RefPtr<SkImage> skiaImage = image->imageForCurrentFrame(); |
226 // Attempt to get raw unpremultiplied image data, executed only when skiaIma ge is premultiplied. | 265 // Attempt to get raw unpremultiplied image data, executed only when skiaIma ge is premultiplied. |
227 if ((((!parsedOptions.premultiplyAlpha && !skiaImage->isOpaque()) || !skiaIm age) && image->data() && imageFormat == PremultiplyAlpha) || colorSpaceOp == Ima geDecoder::GammaAndColorProfileIgnored) { | 266 if ((((!parsedOptions.premultiplyAlpha && !skiaImage->isOpaque()) || !skiaIm age) && image->data() && imageFormat == PremultiplyAlpha) || colorSpaceOp == Ima geDecoder::GammaAndColorProfileIgnored) { |
228 std::unique_ptr<ImageDecoder> decoder(ImageDecoder::create( | 267 std::unique_ptr<ImageDecoder> decoder(ImageDecoder::create( |
229 ImageDecoder::determineImageType(*(image->data())), | 268 ImageDecoder::determineImageType(*(image->data())), |
230 parsedOptions.premultiplyAlpha ? ImageDecoder::AlphaPremultiplied : ImageDecoder::AlphaNotPremultiplied, | 269 parsedOptions.premultiplyAlpha ? ImageDecoder::AlphaPremultiplied : ImageDecoder::AlphaNotPremultiplied, |
231 colorSpaceOp)); | 270 colorSpaceOp)); |
232 if (!decoder) | 271 if (!decoder) |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
270 SkRect drawDstRect = SkRect::MakeXYWH(0, 0, parsedOptions.resizeWidth, p arsedOptions.resizeHeight); | 309 SkRect drawDstRect = SkRect::MakeXYWH(0, 0, parsedOptions.resizeWidth, p arsedOptions.resizeHeight); |
271 SkPaint paint; | 310 SkPaint paint; |
272 paint.setFilterQuality(parsedOptions.resizeQuality); | 311 paint.setFilterQuality(parsedOptions.resizeQuality); |
273 surface->getCanvas()->drawImageRect(skiaImage.get(), drawSrcRect, drawDs tRect, &paint); | 312 surface->getCanvas()->drawImageRect(skiaImage.get(), drawSrcRect, drawDs tRect, &paint); |
274 } else { | 313 } else { |
275 surface->getCanvas()->drawImage(skiaImage.get(), dstLeft, dstTop); | 314 surface->getCanvas()->drawImage(skiaImage.get(), dstLeft, dstTop); |
276 } | 315 } |
277 skiaImage = fromSkSp(surface->makeImageSnapshot()); | 316 skiaImage = fromSkSp(surface->makeImageSnapshot()); |
278 | 317 |
279 if (parsedOptions.premultiplyAlpha) { | 318 if (parsedOptions.premultiplyAlpha) { |
280 if (imageFormat == PremultiplyAlpha) | 319 if (imageFormat == DontPremultiplyAlpha) |
281 return StaticBitmapImage::create(unPremulSkImageToPremul(skiaImage.g et())); | 320 return StaticBitmapImage::create(unPremulSkImageToPremul(skiaImage.g et())); |
282 return StaticBitmapImage::create(skiaImage.release()); | 321 return StaticBitmapImage::create(skiaImage.release()); |
283 } | 322 } |
284 return StaticBitmapImage::create(premulSkImageToUnPremul(skiaImage.get())); | 323 return StaticBitmapImage::create(premulSkImageToUnPremul(skiaImage.get())); |
285 } | 324 } |
286 | 325 |
287 ImageBitmap::ImageBitmap(HTMLImageElement* image, Optional<IntRect> cropRect, Do cument* document, const ImageBitmapOptions& options) | 326 ImageBitmap::ImageBitmap(HTMLImageElement* image, Optional<IntRect> cropRect, Do cument* document, const ImageBitmapOptions& options) |
288 { | 327 { |
289 RefPtr<Image> input = image->cachedImage()->getImage(); | 328 RefPtr<Image> input = image->cachedImage()->getImage(); |
290 ParsedOptions parsedOptions = parseOptions(options, cropRect, image->bitmapS ourceSize()); | 329 ParsedOptions parsedOptions = parseOptions(options, cropRect, image->bitmapS ourceSize()); |
330 if (dstBufferSizeHasOverflow(parsedOptions)) | |
331 return; | |
291 | 332 |
292 if (options.colorSpaceConversion() == "none") | 333 if (options.colorSpaceConversion() == "none") |
293 m_image = cropImage(input.get(), parsedOptions, PremultiplyAlpha, ImageD ecoder::GammaAndColorProfileIgnored); | 334 m_image = cropImage(input.get(), parsedOptions, PremultiplyAlpha, ImageD ecoder::GammaAndColorProfileIgnored); |
294 else | 335 else |
295 m_image = cropImage(input.get(), parsedOptions, PremultiplyAlpha, ImageD ecoder::GammaAndColorProfileApplied); | 336 m_image = cropImage(input.get(), parsedOptions, PremultiplyAlpha, ImageD ecoder::GammaAndColorProfileApplied); |
296 if (!m_image) | 337 if (!m_image) |
297 return; | 338 return; |
298 // In the case where the source image is lazy-decoded, m_image may not be in | 339 // In the case where the source image is lazy-decoded, m_image may not be in |
299 // a decoded state, we trigger it here. | 340 // a decoded state, we trigger it here. |
300 RefPtr<SkImage> skImage = m_image->imageForCurrentFrame(); | 341 RefPtr<SkImage> skImage = m_image->imageForCurrentFrame(); |
301 SkPixmap pixmap; | 342 SkPixmap pixmap; |
302 if (!skImage->isTextureBacked() && !skImage->peekPixels(&pixmap)) { | 343 if (!skImage->isTextureBacked() && !skImage->peekPixels(&pixmap)) { |
303 sk_sp<SkSurface> surface = SkSurface::MakeRasterN32Premul(skImage->width (), skImage->height()); | 344 sk_sp<SkSurface> surface = SkSurface::MakeRasterN32Premul(skImage->width (), skImage->height()); |
304 surface->getCanvas()->drawImage(skImage.get(), 0, 0); | 345 surface->getCanvas()->drawImage(skImage.get(), 0, 0); |
305 m_image = StaticBitmapImage::create(fromSkSp(surface->makeImageSnapshot( ))); | 346 m_image = StaticBitmapImage::create(fromSkSp(surface->makeImageSnapshot( ))); |
306 } | 347 } |
348 if (!m_image) | |
349 return; | |
307 m_image->setOriginClean(!image->wouldTaintOrigin(document->getSecurityOrigin ())); | 350 m_image->setOriginClean(!image->wouldTaintOrigin(document->getSecurityOrigin ())); |
308 m_image->setPremultiplied(parsedOptions.premultiplyAlpha); | 351 m_image->setPremultiplied(parsedOptions.premultiplyAlpha); |
309 } | 352 } |
310 | 353 |
311 ImageBitmap::ImageBitmap(HTMLVideoElement* video, Optional<IntRect> cropRect, Do cument* document, const ImageBitmapOptions& options) | 354 ImageBitmap::ImageBitmap(HTMLVideoElement* video, Optional<IntRect> cropRect, Do cument* document, const ImageBitmapOptions& options) |
312 { | 355 { |
313 IntSize playerSize; | 356 IntSize playerSize; |
314 if (video->webMediaPlayer()) | 357 if (video->webMediaPlayer()) |
315 playerSize = video->webMediaPlayer()->naturalSize(); | 358 playerSize = video->webMediaPlayer()->naturalSize(); |
316 ParsedOptions parsedOptions = parseOptions(options, cropRect, video->bitmapS ourceSize()); | 359 ParsedOptions parsedOptions = parseOptions(options, cropRect, video->bitmapS ourceSize()); |
360 if (dstBufferSizeHasOverflow(parsedOptions)) | |
361 return; | |
317 | 362 |
318 IntRect videoRect = IntRect(IntPoint(), playerSize); | 363 IntRect videoRect = IntRect(IntPoint(), playerSize); |
319 IntRect srcRect = intersection(parsedOptions.cropRect, videoRect); | 364 IntRect srcRect = intersection(parsedOptions.cropRect, videoRect); |
320 std::unique_ptr<ImageBuffer> buffer = ImageBuffer::create(IntSize(parsedOpti ons.resizeWidth, parsedOptions.resizeHeight), NonOpaque, DoNotInitializeImagePix els); | 365 std::unique_ptr<ImageBuffer> buffer = ImageBuffer::create(IntSize(parsedOpti ons.resizeWidth, parsedOptions.resizeHeight), NonOpaque, DoNotInitializeImagePix els); |
321 if (!buffer) | 366 if (!buffer) |
322 return; | 367 return; |
323 | 368 |
324 if (parsedOptions.flipY) { | 369 if (parsedOptions.flipY) { |
325 buffer->canvas()->translate(0, buffer->size().height()); | 370 buffer->canvas()->translate(0, buffer->size().height()); |
326 buffer->canvas()->scale(1, -1); | 371 buffer->canvas()->scale(1, -1); |
327 } | 372 } |
328 IntPoint dstPoint = IntPoint(std::max(0, -parsedOptions.cropRect.x()), std:: max(0, -parsedOptions.cropRect.y())); | 373 IntPoint dstPoint = IntPoint(std::max(0, -parsedOptions.cropRect.x()), std:: max(0, -parsedOptions.cropRect.y())); |
329 IntSize dstSize = srcRect.size(); | 374 IntSize dstSize = srcRect.size(); |
330 SkPaint paint; | 375 SkPaint paint; |
331 if (parsedOptions.shouldScaleInput) { | 376 if (parsedOptions.shouldScaleInput) { |
332 float scaleRatioX = static_cast<float>(parsedOptions.resizeWidth) / pars edOptions.cropRect.width(); | 377 float scaleRatioX = static_cast<float>(parsedOptions.resizeWidth) / pars edOptions.cropRect.width(); |
333 float scaleRatioY = static_cast<float>(parsedOptions.resizeHeight) / par sedOptions.cropRect.height(); | 378 float scaleRatioY = static_cast<float>(parsedOptions.resizeHeight) / par sedOptions.cropRect.height(); |
334 dstPoint.scale(scaleRatioX, scaleRatioY); | 379 dstPoint.scale(scaleRatioX, scaleRatioY); |
335 paint.setFilterQuality(parsedOptions.resizeQuality); | 380 paint.setFilterQuality(parsedOptions.resizeQuality); |
336 dstSize.scale(scaleRatioX, scaleRatioY); | 381 dstSize.scale(scaleRatioX, scaleRatioY); |
337 } | 382 } |
338 video->paintCurrentFrame(buffer->canvas(), IntRect(dstPoint, dstSize), parse dOptions.shouldScaleInput ? &paint : nullptr); | 383 video->paintCurrentFrame(buffer->canvas(), IntRect(dstPoint, dstSize), parse dOptions.shouldScaleInput ? &paint : nullptr); |
339 | 384 |
340 RefPtr<SkImage> skiaImage = buffer->newSkImageSnapshot(PreferNoAcceleration, SnapshotReasonUnknown); | 385 RefPtr<SkImage> skiaImage = buffer->newSkImageSnapshot(PreferNoAcceleration, SnapshotReasonUnknown); |
341 if (!parsedOptions.premultiplyAlpha) | 386 if (!parsedOptions.premultiplyAlpha) |
342 skiaImage = premulSkImageToUnPremul(skiaImage.get()); | 387 skiaImage = premulSkImageToUnPremul(skiaImage.get()); |
388 if (!skiaImage) | |
389 return; | |
343 m_image = StaticBitmapImage::create(skiaImage.release()); | 390 m_image = StaticBitmapImage::create(skiaImage.release()); |
344 m_image->setOriginClean(!video->wouldTaintOrigin(document->getSecurityOrigin ())); | 391 m_image->setOriginClean(!video->wouldTaintOrigin(document->getSecurityOrigin ())); |
345 m_image->setPremultiplied(parsedOptions.premultiplyAlpha); | 392 m_image->setPremultiplied(parsedOptions.premultiplyAlpha); |
346 } | 393 } |
347 | 394 |
348 ImageBitmap::ImageBitmap(HTMLCanvasElement* canvas, Optional<IntRect> cropRect, const ImageBitmapOptions& options) | 395 ImageBitmap::ImageBitmap(HTMLCanvasElement* canvas, Optional<IntRect> cropRect, const ImageBitmapOptions& options) |
349 { | 396 { |
350 ASSERT(canvas->isPaintable()); | 397 ASSERT(canvas->isPaintable()); |
351 RefPtr<Image> input = canvas->copiedImage(BackBuffer, PreferAcceleration); | 398 RefPtr<Image> input = canvas->copiedImage(BackBuffer, PreferAcceleration); |
352 ParsedOptions parsedOptions = parseOptions(options, cropRect, canvas->bitmap SourceSize()); | 399 ParsedOptions parsedOptions = parseOptions(options, cropRect, canvas->bitmap SourceSize()); |
400 if (dstBufferSizeHasOverflow(parsedOptions)) | |
401 return; | |
353 | 402 |
354 bool isPremultiplyAlphaReverted = false; | 403 bool isPremultiplyAlphaReverted = false; |
355 if (!parsedOptions.premultiplyAlpha) { | 404 if (!parsedOptions.premultiplyAlpha) { |
356 parsedOptions.premultiplyAlpha = true; | 405 parsedOptions.premultiplyAlpha = true; |
357 isPremultiplyAlphaReverted = true; | 406 isPremultiplyAlphaReverted = true; |
358 } | 407 } |
359 m_image = cropImage(input.get(), parsedOptions); | 408 m_image = cropImage(input.get(), parsedOptions); |
360 if (!m_image) | 409 if (!m_image) |
361 return; | 410 return; |
362 if (isPremultiplyAlphaReverted) { | 411 if (isPremultiplyAlphaReverted) { |
363 parsedOptions.premultiplyAlpha = false; | 412 parsedOptions.premultiplyAlpha = false; |
364 m_image = StaticBitmapImage::create(premulSkImageToUnPremul(m_image->ima geForCurrentFrame().get())); | 413 m_image = StaticBitmapImage::create(premulSkImageToUnPremul(m_image->ima geForCurrentFrame().get())); |
365 } | 414 } |
415 if (!m_image) | |
416 return; | |
366 m_image->setOriginClean(canvas->originClean()); | 417 m_image->setOriginClean(canvas->originClean()); |
367 m_image->setPremultiplied(parsedOptions.premultiplyAlpha); | 418 m_image->setPremultiplied(parsedOptions.premultiplyAlpha); |
368 } | 419 } |
369 | 420 |
370 ImageBitmap::ImageBitmap(std::unique_ptr<uint8_t[]> data, uint32_t width, uint32 _t height, bool isImageBitmapPremultiplied, bool isImageBitmapOriginClean) | 421 ImageBitmap::ImageBitmap(std::unique_ptr<uint8_t[]> data, uint32_t width, uint32 _t height, bool isImageBitmapPremultiplied, bool isImageBitmapOriginClean) |
371 { | 422 { |
372 SkImageInfo info = SkImageInfo::MakeN32(width, height, isImageBitmapPremulti plied ? kPremul_SkAlphaType : kUnpremul_SkAlphaType); | 423 SkImageInfo info = SkImageInfo::MakeN32(width, height, isImageBitmapPremulti plied ? kPremul_SkAlphaType : kUnpremul_SkAlphaType); |
373 m_image = StaticBitmapImage::create(fromSkSp(SkImage::MakeRasterCopy(SkPixma p(info, data.get(), info.bytesPerPixel() * width)))); | 424 m_image = StaticBitmapImage::create(fromSkSp(SkImage::MakeRasterCopy(SkPixma p(info, data.get(), info.bytesPerPixel() * width)))); |
425 if (!m_image) | |
426 return; | |
374 m_image->setPremultiplied(isImageBitmapPremultiplied); | 427 m_image->setPremultiplied(isImageBitmapPremultiplied); |
375 m_image->setOriginClean(isImageBitmapOriginClean); | 428 m_image->setOriginClean(isImageBitmapOriginClean); |
376 } | 429 } |
377 | 430 |
378 static PassRefPtr<SkImage> scaleSkImage(PassRefPtr<SkImage> skImage, unsigned re sizeWidth, unsigned resizeHeight, SkFilterQuality resizeQuality) | 431 static PassRefPtr<SkImage> scaleSkImage(PassRefPtr<SkImage> skImage, unsigned re sizeWidth, unsigned resizeHeight, SkFilterQuality resizeQuality) |
379 { | 432 { |
380 SkImageInfo resizedInfo = SkImageInfo::Make(resizeWidth, resizeHeight, kN32_ SkColorType, kUnpremul_SkAlphaType); | 433 SkImageInfo resizedInfo = SkImageInfo::Make(resizeWidth, resizeHeight, kN32_ SkColorType, kUnpremul_SkAlphaType); |
381 std::unique_ptr<uint8_t[]> resizedPixels = wrapArrayUnique(new uint8_t[resiz eWidth * resizeHeight * resizedInfo.bytesPerPixel()]); | 434 RefPtr<ArrayBuffer> dstBuffer = ArrayBuffer::createOrNull(resizeWidth * resi zeHeight, resizedInfo.bytesPerPixel()); |
382 SkPixmap pixmap(resizedInfo, resizedPixels.release(), resizeWidth * resizedI nfo.bytesPerPixel()); | 435 if (!dstBuffer) |
436 return nullptr; | |
437 RefPtr<Uint8Array> resizedPixels = Uint8Array::create(dstBuffer, 0, dstBuffe r->byteLength()); | |
438 SkPixmap pixmap(resizedInfo, resizedPixels->data(), static_cast<size_t>(resi zeWidth) * resizedInfo.bytesPerPixel()); | |
383 skImage->scalePixels(pixmap, resizeQuality); | 439 skImage->scalePixels(pixmap, resizeQuality); |
384 return fromSkSp(SkImage::MakeFromRaster(pixmap, [](const void* pixels, void* ) | 440 return fromSkSp(SkImage::MakeFromRaster(pixmap, [](const void*, void* pixels ) |
385 { | 441 { |
386 delete[] static_cast<const uint8_t*>(pixels); | 442 static_cast<Uint8Array*>(pixels)->deref(); |
387 }, nullptr)); | 443 }, resizedPixels.get())); |
388 } | 444 } |
389 | 445 |
390 ImageBitmap::ImageBitmap(ImageData* data, Optional<IntRect> cropRect, const Imag eBitmapOptions& options) | 446 ImageBitmap::ImageBitmap(ImageData* data, Optional<IntRect> cropRect, const Imag eBitmapOptions& options) |
391 { | 447 { |
392 // TODO(xidachen): implement the resize option | 448 // TODO(xidachen): implement the resize option |
393 IntRect dataSrcRect = IntRect(IntPoint(), data->size()); | 449 IntRect dataSrcRect = IntRect(IntPoint(), data->size()); |
394 ParsedOptions parsedOptions = parseOptions(options, cropRect, data->bitmapSo urceSize()); | 450 ParsedOptions parsedOptions = parseOptions(options, cropRect, data->bitmapSo urceSize()); |
451 if (dstBufferSizeHasOverflow(parsedOptions)) | |
452 return; | |
395 IntRect srcRect = cropRect ? intersection(parsedOptions.cropRect, dataSrcRec t) : dataSrcRect; | 453 IntRect srcRect = cropRect ? intersection(parsedOptions.cropRect, dataSrcRec t) : dataSrcRect; |
396 | 454 |
397 // treat non-premultiplyAlpha as a special case | 455 // treat non-premultiplyAlpha as a special case |
398 if (!parsedOptions.premultiplyAlpha) { | 456 if (!parsedOptions.premultiplyAlpha) { |
399 unsigned char* srcAddr = data->data()->data(); | 457 unsigned char* srcAddr = data->data()->data(); |
400 int srcHeight = data->size().height(); | |
401 int dstHeight = parsedOptions.cropRect.height(); | |
402 | 458 |
403 // Using kN32 type, swizzle input if necessary. | 459 // Using kN32 type, swizzle input if necessary. |
404 SkImageInfo info = SkImageInfo::Make(parsedOptions.cropRect.width(), dst Height, kN32_SkColorType, kUnpremul_SkAlphaType); | 460 SkImageInfo info = SkImageInfo::Make(parsedOptions.cropRect.width(), par sedOptions.cropRect.height(), kN32_SkColorType, kUnpremul_SkAlphaType); |
405 int srcPixelBytesPerRow = info.bytesPerPixel() * data->size().width(); | 461 size_t bytesPerPixel = static_cast<size_t>(info.bytesPerPixel()); |
406 int dstPixelBytesPerRow = info.bytesPerPixel() * parsedOptions.cropRect. width(); | 462 size_t srcPixelBytesPerRow = bytesPerPixel * data->size().width(); |
463 size_t dstPixelBytesPerRow = bytesPerPixel * parsedOptions.cropRect.widt h(); | |
407 RefPtr<SkImage> skImage; | 464 RefPtr<SkImage> skImage; |
408 if (parsedOptions.cropRect == IntRect(IntPoint(), data->size())) { | 465 if (parsedOptions.cropRect == IntRect(IntPoint(), data->size())) { |
409 swizzleImageData(srcAddr, srcHeight, srcPixelBytesPerRow, parsedOpti ons.flipY); | 466 swizzleImageData(srcAddr, data->size().height(), srcPixelBytesPerRow , parsedOptions.flipY); |
410 skImage = fromSkSp(SkImage::MakeRasterCopy(SkPixmap(info, srcAddr, d stPixelBytesPerRow))); | 467 skImage = fromSkSp(SkImage::MakeRasterCopy(SkPixmap(info, srcAddr, d stPixelBytesPerRow))); |
411 // restore the original ImageData | 468 // restore the original ImageData |
412 swizzleImageData(srcAddr, srcHeight, srcPixelBytesPerRow, parsedOpti ons.flipY); | 469 swizzleImageData(srcAddr, data->size().height(), srcPixelBytesPerRow , parsedOptions.flipY); |
413 } else { | 470 } else { |
414 std::unique_ptr<uint8_t[]> copiedDataBuffer = wrapArrayUnique(new ui nt8_t[dstHeight * dstPixelBytesPerRow]()); | 471 RefPtr<ArrayBuffer> dstBuffer = ArrayBuffer::createOrNull(static_cas t<size_t>(parsedOptions.cropRect.height()) * parsedOptions.cropRect.width(), byt esPerPixel); |
472 if (!dstBuffer) | |
473 return; | |
474 RefPtr<Uint8Array> copiedDataBuffer = Uint8Array::create(dstBuffer, 0, dstBuffer->byteLength()); | |
415 if (!srcRect.isEmpty()) { | 475 if (!srcRect.isEmpty()) { |
416 IntPoint srcPoint = IntPoint((parsedOptions.cropRect.x() > 0) ? parsedOptions.cropRect.x() : 0, (parsedOptions.cropRect.y() > 0) ? parsedOptions .cropRect.y() : 0); | 476 IntPoint srcPoint = IntPoint((parsedOptions.cropRect.x() > 0) ? parsedOptions.cropRect.x() : 0, (parsedOptions.cropRect.y() > 0) ? parsedOptions .cropRect.y() : 0); |
417 IntPoint dstPoint = IntPoint((parsedOptions.cropRect.x() >= 0) ? 0 : -parsedOptions.cropRect.x(), (parsedOptions.cropRect.y() >= 0) ? 0 : -parse dOptions.cropRect.y()); | 477 IntPoint dstPoint = IntPoint((parsedOptions.cropRect.x() >= 0) ? 0 : -parsedOptions.cropRect.x(), (parsedOptions.cropRect.y() >= 0) ? 0 : -parse dOptions.cropRect.y()); |
418 int copyHeight = srcHeight - srcPoint.y(); | 478 int copyHeight = data->size().height() - srcPoint.y(); |
419 if (parsedOptions.cropRect.height() < copyHeight) | 479 if (parsedOptions.cropRect.height() < copyHeight) |
420 copyHeight = parsedOptions.cropRect.height(); | 480 copyHeight = parsedOptions.cropRect.height(); |
421 int copyWidth = data->size().width() - srcPoint.x(); | 481 int copyWidth = data->size().width() - srcPoint.x(); |
422 if (parsedOptions.cropRect.width() < copyWidth) | 482 if (parsedOptions.cropRect.width() < copyWidth) |
423 copyWidth = parsedOptions.cropRect.width(); | 483 copyWidth = parsedOptions.cropRect.width(); |
424 for (int i = 0; i < copyHeight; i++) { | 484 for (int i = 0; i < copyHeight; i++) { |
425 int srcStartCopyPosition = (i + srcPoint.y()) * srcPixelByte sPerRow + srcPoint.x() * info.bytesPerPixel(); | 485 size_t srcStartCopyPosition = (i + srcPoint.y()) * srcPixelB ytesPerRow + srcPoint.x() * bytesPerPixel; |
426 int srcEndCopyPosition = srcStartCopyPosition + copyWidth * info.bytesPerPixel(); | 486 size_t srcEndCopyPosition = srcStartCopyPosition + copyWidth * bytesPerPixel; |
427 int dstStartCopyPosition; | 487 size_t dstStartCopyPosition; |
428 if (parsedOptions.flipY) | 488 if (parsedOptions.flipY) |
429 dstStartCopyPosition = (dstHeight -1 - dstPoint.y() - i) * dstPixelBytesPerRow + dstPoint.x() * info.bytesPerPixel(); | 489 dstStartCopyPosition = (parsedOptions.cropRect.height() -1 - dstPoint.y() - i) * dstPixelBytesPerRow + dstPoint.x() * bytesPerPixel; |
430 else | 490 else |
431 dstStartCopyPosition = (dstPoint.y() + i) * dstPixelByte sPerRow + dstPoint.x() * info.bytesPerPixel(); | 491 dstStartCopyPosition = (dstPoint.y() + i) * dstPixelByte sPerRow + dstPoint.x() * bytesPerPixel; |
432 for (int j = 0; j < srcEndCopyPosition - srcStartCopyPositio n; j++) { | 492 for (size_t j = 0; j < srcEndCopyPosition - srcStartCopyPosi tion; j++) { |
433 // swizzle when necessary | 493 // swizzle when necessary |
434 if (kN32_SkColorType == kBGRA_8888_SkColorType) { | 494 if (kN32_SkColorType == kBGRA_8888_SkColorType) { |
435 if (j % 4 == 0) | 495 if (j % 4 == 0) |
436 copiedDataBuffer[dstStartCopyPosition + j] = src Addr[srcStartCopyPosition + j + 2]; | 496 copiedDataBuffer->data()[dstStartCopyPosition + j] = srcAddr[srcStartCopyPosition + j + 2]; |
437 else if (j % 4 == 2) | 497 else if (j % 4 == 2) |
438 copiedDataBuffer[dstStartCopyPosition + j] = src Addr[srcStartCopyPosition + j - 2]; | 498 copiedDataBuffer->data()[dstStartCopyPosition + j] = srcAddr[srcStartCopyPosition + j - 2]; |
439 else | 499 else |
440 copiedDataBuffer[dstStartCopyPosition + j] = src Addr[srcStartCopyPosition + j]; | 500 copiedDataBuffer->data()[dstStartCopyPosition + j] = srcAddr[srcStartCopyPosition + j]; |
441 } else { | 501 } else { |
442 copiedDataBuffer[dstStartCopyPosition + j] = srcAddr [srcStartCopyPosition + j]; | 502 copiedDataBuffer->data()[dstStartCopyPosition + j] = srcAddr[srcStartCopyPosition + j]; |
443 } | 503 } |
444 } | 504 } |
445 } | 505 } |
446 } | 506 } |
447 skImage = newSkImageFromRaster(info, std::move(copiedDataBuffer), ds tPixelBytesPerRow); | 507 skImage = newSkImageFromRaster(info, copiedDataBuffer, dstPixelBytes PerRow); |
448 } | 508 } |
509 if (!skImage) | |
510 return; | |
449 if (parsedOptions.shouldScaleInput) | 511 if (parsedOptions.shouldScaleInput) |
450 m_image = StaticBitmapImage::create(scaleSkImage(skImage, parsedOpti ons.resizeWidth, parsedOptions.resizeHeight, parsedOptions.resizeQuality)); | 512 m_image = StaticBitmapImage::create(scaleSkImage(skImage, parsedOpti ons.resizeWidth, parsedOptions.resizeHeight, parsedOptions.resizeQuality)); |
451 else | 513 else |
452 m_image = StaticBitmapImage::create(skImage); | 514 m_image = StaticBitmapImage::create(skImage); |
515 if (!m_image) | |
516 return; | |
453 m_image->setPremultiplied(parsedOptions.premultiplyAlpha); | 517 m_image->setPremultiplied(parsedOptions.premultiplyAlpha); |
454 return; | 518 return; |
455 } | 519 } |
456 | 520 |
457 std::unique_ptr<ImageBuffer> buffer = ImageBuffer::create(parsedOptions.crop Rect.size(), NonOpaque, DoNotInitializeImagePixels); | 521 std::unique_ptr<ImageBuffer> buffer = ImageBuffer::create(parsedOptions.crop Rect.size(), NonOpaque, DoNotInitializeImagePixels); |
458 if (!buffer) | 522 if (!buffer) |
459 return; | 523 return; |
460 | 524 |
461 if (srcRect.isEmpty()) { | 525 if (srcRect.isEmpty()) { |
462 m_image = StaticBitmapImage::create(buffer->newSkImageSnapshot(PreferNoA cceleration, SnapshotReasonUnknown)); | 526 m_image = StaticBitmapImage::create(buffer->newSkImageSnapshot(PreferNoA cceleration, SnapshotReasonUnknown)); |
463 return; | 527 return; |
464 } | 528 } |
465 | 529 |
466 IntPoint dstPoint = IntPoint(std::min(0, -parsedOptions.cropRect.x()), std:: min(0, -parsedOptions.cropRect.y())); | 530 IntPoint dstPoint = IntPoint(std::min(0, -parsedOptions.cropRect.x()), std:: min(0, -parsedOptions.cropRect.y())); |
467 if (parsedOptions.cropRect.x() < 0) | 531 if (parsedOptions.cropRect.x() < 0) |
468 dstPoint.setX(-parsedOptions.cropRect.x()); | 532 dstPoint.setX(-parsedOptions.cropRect.x()); |
469 if (parsedOptions.cropRect.y() < 0) | 533 if (parsedOptions.cropRect.y() < 0) |
470 dstPoint.setY(-parsedOptions.cropRect.y()); | 534 dstPoint.setY(-parsedOptions.cropRect.y()); |
471 buffer->putByteArray(Unmultiplied, data->data()->data(), data->size(), srcRe ct, dstPoint); | 535 buffer->putByteArray(Unmultiplied, data->data()->data(), data->size(), srcRe ct, dstPoint); |
472 RefPtr<SkImage> skImage = buffer->newSkImageSnapshot(PreferNoAcceleration, S napshotReasonUnknown); | 536 RefPtr<SkImage> skImage = buffer->newSkImageSnapshot(PreferNoAcceleration, S napshotReasonUnknown); |
473 if (parsedOptions.flipY) | 537 if (parsedOptions.flipY) |
474 skImage = flipSkImageVertically(skImage.get(), PremultiplyAlpha); | 538 skImage = flipSkImageVertically(skImage.get(), PremultiplyAlpha); |
539 if (!skImage) | |
540 return; | |
475 if (parsedOptions.shouldScaleInput) { | 541 if (parsedOptions.shouldScaleInput) { |
476 sk_sp<SkSurface> surface = SkSurface::MakeRasterN32Premul(parsedOptions. resizeWidth, parsedOptions.resizeHeight); | 542 sk_sp<SkSurface> surface = SkSurface::MakeRasterN32Premul(parsedOptions. resizeWidth, parsedOptions.resizeHeight); |
477 if (!surface) | 543 if (!surface) |
478 return; | 544 return; |
479 SkPaint paint; | 545 SkPaint paint; |
480 paint.setFilterQuality(parsedOptions.resizeQuality); | 546 paint.setFilterQuality(parsedOptions.resizeQuality); |
481 SkRect dstDrawRect = SkRect::MakeWH(parsedOptions.resizeWidth, parsedOpt ions.resizeHeight); | 547 SkRect dstDrawRect = SkRect::MakeWH(parsedOptions.resizeWidth, parsedOpt ions.resizeHeight); |
482 surface->getCanvas()->drawImageRect(skImage.get(), dstDrawRect, &paint); | 548 surface->getCanvas()->drawImageRect(skImage.get(), dstDrawRect, &paint); |
483 skImage = fromSkSp(surface->makeImageSnapshot()); | 549 skImage = fromSkSp(surface->makeImageSnapshot()); |
484 } | 550 } |
485 m_image = StaticBitmapImage::create(skImage); | 551 m_image = StaticBitmapImage::create(skImage); |
486 } | 552 } |
487 | 553 |
488 ImageBitmap::ImageBitmap(ImageBitmap* bitmap, Optional<IntRect> cropRect, const ImageBitmapOptions& options) | 554 ImageBitmap::ImageBitmap(ImageBitmap* bitmap, Optional<IntRect> cropRect, const ImageBitmapOptions& options) |
489 { | 555 { |
490 RefPtr<Image> input = bitmap->bitmapImage(); | 556 RefPtr<Image> input = bitmap->bitmapImage(); |
491 if (!input) | 557 if (!input) |
492 return; | 558 return; |
493 ParsedOptions parsedOptions = parseOptions(options, cropRect, input->size()) ; | 559 ParsedOptions parsedOptions = parseOptions(options, cropRect, input->size()) ; |
560 if (dstBufferSizeHasOverflow(parsedOptions)) | |
561 return; | |
494 | 562 |
495 m_image = cropImage(input.get(), parsedOptions, bitmap->isPremultiplied() ? PremultiplyAlpha : DontPremultiplyAlpha); | 563 m_image = cropImage(input.get(), parsedOptions, bitmap->isPremultiplied() ? PremultiplyAlpha : DontPremultiplyAlpha); |
496 if (!m_image) | 564 if (!m_image) |
497 return; | 565 return; |
498 m_image->setOriginClean(bitmap->originClean()); | 566 m_image->setOriginClean(bitmap->originClean()); |
499 m_image->setPremultiplied(parsedOptions.premultiplyAlpha); | 567 m_image->setPremultiplied(parsedOptions.premultiplyAlpha); |
500 } | 568 } |
501 | 569 |
502 ImageBitmap::ImageBitmap(PassRefPtr<StaticBitmapImage> image, Optional<IntRect> cropRect, const ImageBitmapOptions& options) | 570 ImageBitmap::ImageBitmap(PassRefPtr<StaticBitmapImage> image, Optional<IntRect> cropRect, const ImageBitmapOptions& options) |
503 { | 571 { |
504 bool originClean = image->originClean(); | 572 bool originClean = image->originClean(); |
505 RefPtr<Image> input = image; | 573 RefPtr<Image> input = image; |
506 ParsedOptions parsedOptions = parseOptions(options, cropRect, input->size()) ; | 574 ParsedOptions parsedOptions = parseOptions(options, cropRect, input->size()) ; |
575 if (dstBufferSizeHasOverflow(parsedOptions)) | |
576 return; | |
507 | 577 |
508 m_image = cropImage(input.get(), parsedOptions, DontPremultiplyAlpha); | 578 m_image = cropImage(input.get(), parsedOptions, DontPremultiplyAlpha); |
509 if (!m_image) | 579 if (!m_image) |
510 return; | 580 return; |
511 m_image->setOriginClean(originClean); | 581 m_image->setOriginClean(originClean); |
512 m_image->setPremultiplied(parsedOptions.premultiplyAlpha); | 582 m_image->setPremultiplied(parsedOptions.premultiplyAlpha); |
513 } | 583 } |
514 | 584 |
515 ImageBitmap::ImageBitmap(PassRefPtr<StaticBitmapImage> image) | 585 ImageBitmap::ImageBitmap(PassRefPtr<StaticBitmapImage> image) |
516 { | 586 { |
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
575 m_image.clear(); | 645 m_image.clear(); |
576 m_isNeutered = true; | 646 m_isNeutered = true; |
577 } | 647 } |
578 | 648 |
579 // static | 649 // static |
580 ImageBitmap* ImageBitmap::take(ScriptPromiseResolver*, sk_sp<SkImage> image) | 650 ImageBitmap* ImageBitmap::take(ScriptPromiseResolver*, sk_sp<SkImage> image) |
581 { | 651 { |
582 return ImageBitmap::create(StaticBitmapImage::create(fromSkSp(image))); | 652 return ImageBitmap::create(StaticBitmapImage::create(fromSkSp(image))); |
583 } | 653 } |
584 | 654 |
585 std::unique_ptr<uint8_t[]> ImageBitmap::copyBitmapData(AlphaDisposition alphaOp, DataColorFormat format) | 655 PassRefPtr<Uint8Array> ImageBitmap::copyBitmapData(AlphaDisposition alphaOp, Dat aColorFormat format) |
586 { | 656 { |
587 SkImageInfo info = SkImageInfo::Make(width(), height(), (format == RGBAColor Type) ? kRGBA_8888_SkColorType : kN32_SkColorType, (alphaOp == PremultiplyAlpha) ? kPremul_SkAlphaType : kUnpremul_SkAlphaType); | 657 SkImageInfo info = SkImageInfo::Make(width(), height(), (format == RGBAColor Type) ? kRGBA_8888_SkColorType : kN32_SkColorType, (alphaOp == PremultiplyAlpha) ? kPremul_SkAlphaType : kUnpremul_SkAlphaType); |
588 std::unique_ptr<uint8_t[]> dstPixels = copySkImageData(m_image->imageForCurr entFrame().get(), info); | 658 RefPtr<Uint8Array> dstPixels = copySkImageData(m_image->imageForCurrentFrame ().get(), info); |
589 return dstPixels; | 659 return dstPixels; |
590 } | 660 } |
591 | 661 |
592 unsigned long ImageBitmap::width() const | 662 unsigned long ImageBitmap::width() const |
593 { | 663 { |
594 if (!m_image) | 664 if (!m_image) |
595 return 0; | 665 return 0; |
596 ASSERT(m_image->width() > 0); | 666 ASSERT(m_image->width() > 0); |
597 return m_image->width(); | 667 return m_image->width(); |
598 } | 668 } |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
641 FloatSize ImageBitmap::elementSize(const FloatSize&) const | 711 FloatSize ImageBitmap::elementSize(const FloatSize&) const |
642 { | 712 { |
643 return FloatSize(width(), height()); | 713 return FloatSize(width(), height()); |
644 } | 714 } |
645 | 715 |
646 DEFINE_TRACE(ImageBitmap) | 716 DEFINE_TRACE(ImageBitmap) |
647 { | 717 { |
648 } | 718 } |
649 | 719 |
650 } // namespace blink | 720 } // namespace blink |
OLD | NEW |