| 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 121 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 132 // will never overflow size_t. | 132 // will never overflow size_t. |
| 133 size_t width = static_cast<size_t>(input->width()); | 133 size_t width = static_cast<size_t>(input->width()); |
| 134 RefPtr<ArrayBuffer> dstBuffer = ArrayBuffer::createOrNull(width * input->hei
ght(), info.bytesPerPixel()); | 134 RefPtr<ArrayBuffer> dstBuffer = ArrayBuffer::createOrNull(width * input->hei
ght(), info.bytesPerPixel()); |
| 135 if (!dstBuffer) | 135 if (!dstBuffer) |
| 136 return nullptr; | 136 return nullptr; |
| 137 RefPtr<Uint8Array> dstPixels = Uint8Array::create(dstBuffer, 0, dstBuffer->b
yteLength()); | 137 RefPtr<Uint8Array> dstPixels = Uint8Array::create(dstBuffer, 0, dstBuffer->b
yteLength()); |
| 138 input->readPixels(info, dstPixels->data(), width * info.bytesPerPixel(), 0,
0); | 138 input->readPixels(info, dstPixels->data(), width * info.bytesPerPixel(), 0,
0); |
| 139 return dstPixels; | 139 return dstPixels; |
| 140 } | 140 } |
| 141 | 141 |
| 142 static PassRefPtr<SkImage> newSkImageFromRaster(const SkImageInfo& info, PassRef
Ptr<Uint8Array> imagePixels, size_t imageRowBytes) | 142 static sk_sp<SkImage> newSkImageFromRaster(const SkImageInfo& info, PassRefPtr<U
int8Array> imagePixels, size_t imageRowBytes) |
| 143 { | 143 { |
| 144 SkPixmap pixmap(info, imagePixels->data(), imageRowBytes); | 144 SkPixmap pixmap(info, imagePixels->data(), imageRowBytes); |
| 145 return fromSkSp(SkImage::MakeFromRaster(pixmap, [](const void*, void* pixels
) | 145 return SkImage::MakeFromRaster(pixmap, [](const void*, void* pixels) |
| 146 { | 146 { |
| 147 static_cast<Uint8Array*>(pixels)->deref(); | 147 static_cast<Uint8Array*>(pixels)->deref(); |
| 148 }, imagePixels.leakRef())); | 148 }, imagePixels.leakRef()); |
| 149 } | 149 } |
| 150 | 150 |
| 151 static void swizzleImageData(unsigned char* srcAddr, size_t height, size_t bytes
PerRow, bool flipY) | 151 static void swizzleImageData(unsigned char* srcAddr, size_t height, size_t bytes
PerRow, bool flipY) |
| 152 { | 152 { |
| 153 if (flipY) { | 153 if (flipY) { |
| 154 for (size_t i = 0; i < height / 2; i++) { | 154 for (size_t i = 0; i < height / 2; i++) { |
| 155 size_t topRowStartPosition = i * bytesPerRow; | 155 size_t topRowStartPosition = i * bytesPerRow; |
| 156 size_t bottomRowStartPosition = (height - 1 - i) * bytesPerRow; | 156 size_t bottomRowStartPosition = (height - 1 - i) * bytesPerRow; |
| 157 if (kN32_SkColorType == kBGRA_8888_SkColorType) { // needs to swizzl
e | 157 if (kN32_SkColorType == kBGRA_8888_SkColorType) { // needs to swizzl
e |
| 158 for (size_t j = 0; j < bytesPerRow; j += 4) { | 158 for (size_t j = 0; j < bytesPerRow; j += 4) { |
| 159 std::swap(srcAddr[topRowStartPosition + j], srcAddr[bottomRo
wStartPosition + j + 2]); | 159 std::swap(srcAddr[topRowStartPosition + j], srcAddr[bottomRo
wStartPosition + j + 2]); |
| 160 std::swap(srcAddr[topRowStartPosition + j + 1], srcAddr[bott
omRowStartPosition + j + 1]); | 160 std::swap(srcAddr[topRowStartPosition + j + 1], srcAddr[bott
omRowStartPosition + j + 1]); |
| 161 std::swap(srcAddr[topRowStartPosition + j + 2], srcAddr[bott
omRowStartPosition + j]); | 161 std::swap(srcAddr[topRowStartPosition + j + 2], srcAddr[bott
omRowStartPosition + j]); |
| 162 std::swap(srcAddr[topRowStartPosition + j + 3], srcAddr[bott
omRowStartPosition + j + 3]); | 162 std::swap(srcAddr[topRowStartPosition + j + 3], srcAddr[bott
omRowStartPosition + j + 3]); |
| 163 } | 163 } |
| 164 } else { | 164 } else { |
| 165 std::swap_ranges(srcAddr + topRowStartPosition, srcAddr + topRow
StartPosition + bytesPerRow, srcAddr + bottomRowStartPosition); | 165 std::swap_ranges(srcAddr + topRowStartPosition, srcAddr + topRow
StartPosition + bytesPerRow, srcAddr + bottomRowStartPosition); |
| 166 } | 166 } |
| 167 } | 167 } |
| 168 } else { | 168 } else { |
| 169 if (kN32_SkColorType == kBGRA_8888_SkColorType) // needs to swizzle | 169 if (kN32_SkColorType == kBGRA_8888_SkColorType) // needs to swizzle |
| 170 for (size_t i = 0; i < height * bytesPerRow; i += 4) | 170 for (size_t i = 0; i < height * bytesPerRow; i += 4) |
| 171 std::swap(srcAddr[i], srcAddr[i + 2]); | 171 std::swap(srcAddr[i], srcAddr[i + 2]); |
| 172 } | 172 } |
| 173 } | 173 } |
| 174 | 174 |
| 175 static PassRefPtr<SkImage> flipSkImageVertically(SkImage* input, AlphaDispositio
n alphaOp) | 175 static sk_sp<SkImage> flipSkImageVertically(SkImage* input, AlphaDisposition alp
haOp) |
| 176 { | 176 { |
| 177 size_t width = static_cast<size_t>(input->width()); | 177 size_t width = static_cast<size_t>(input->width()); |
| 178 size_t height = static_cast<size_t>(input->height()); | 178 size_t height = static_cast<size_t>(input->height()); |
| 179 SkImageInfo info = SkImageInfo::MakeN32(input->width(), input->height(), (al
phaOp == PremultiplyAlpha) ? kPremul_SkAlphaType : kUnpremul_SkAlphaType); | 179 SkImageInfo info = SkImageInfo::MakeN32(input->width(), input->height(), (al
phaOp == PremultiplyAlpha) ? kPremul_SkAlphaType : kUnpremul_SkAlphaType); |
| 180 size_t imageRowBytes = width * info.bytesPerPixel(); | 180 size_t imageRowBytes = width * info.bytesPerPixel(); |
| 181 RefPtr<Uint8Array> imagePixels = copySkImageData(input, info); | 181 RefPtr<Uint8Array> imagePixels = copySkImageData(input, info); |
| 182 if (!imagePixels) | 182 if (!imagePixels) |
| 183 return nullptr; | 183 return nullptr; |
| 184 for (size_t i = 0; i < height / 2; i++) { | 184 for (size_t i = 0; i < height / 2; i++) { |
| 185 size_t topFirstElement = i * imageRowBytes; | 185 size_t topFirstElement = i * imageRowBytes; |
| 186 size_t topLastElement = (i + 1) * imageRowBytes; | 186 size_t topLastElement = (i + 1) * imageRowBytes; |
| 187 size_t bottomFirstElement = (height - 1 - i) * imageRowBytes; | 187 size_t bottomFirstElement = (height - 1 - i) * imageRowBytes; |
| 188 std::swap_ranges(imagePixels->data() + topFirstElement, imagePixels->dat
a() + topLastElement, imagePixels->data() + bottomFirstElement); | 188 std::swap_ranges(imagePixels->data() + topFirstElement, imagePixels->dat
a() + topLastElement, imagePixels->data() + bottomFirstElement); |
| 189 } | 189 } |
| 190 return newSkImageFromRaster(info, std::move(imagePixels), imageRowBytes); | 190 return newSkImageFromRaster(info, std::move(imagePixels), imageRowBytes); |
| 191 } | 191 } |
| 192 | 192 |
| 193 static PassRefPtr<SkImage> premulSkImageToUnPremul(SkImage* input) | 193 static sk_sp<SkImage> premulSkImageToUnPremul(SkImage* input) |
| 194 { | 194 { |
| 195 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); |
| 196 RefPtr<Uint8Array> dstPixels = copySkImageData(input, info); | 196 RefPtr<Uint8Array> dstPixels = copySkImageData(input, info); |
| 197 if (!dstPixels) | 197 if (!dstPixels) |
| 198 return nullptr; | 198 return nullptr; |
| 199 return newSkImageFromRaster(info, std::move(dstPixels), static_cast<size_t>(
input->width()) * info.bytesPerPixel()); | 199 return newSkImageFromRaster(info, std::move(dstPixels), static_cast<size_t>(
input->width()) * info.bytesPerPixel()); |
| 200 } | 200 } |
| 201 | 201 |
| 202 static PassRefPtr<SkImage> unPremulSkImageToPremul(SkImage* input) | 202 static sk_sp<SkImage> unPremulSkImageToPremul(SkImage* input) |
| 203 { | 203 { |
| 204 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); |
| 205 RefPtr<Uint8Array> dstPixels = copySkImageData(input, info); | 205 RefPtr<Uint8Array> dstPixels = copySkImageData(input, info); |
| 206 if (!dstPixels) | 206 if (!dstPixels) |
| 207 return nullptr; | 207 return nullptr; |
| 208 return newSkImageFromRaster(info, std::move(dstPixels), static_cast<size_t>(
input->width()) * info.bytesPerPixel()); | 208 return newSkImageFromRaster(info, std::move(dstPixels), static_cast<size_t>(
input->width()) * info.bytesPerPixel()); |
| 209 } | 209 } |
| 210 | 210 |
| 211 PassRefPtr<SkImage> ImageBitmap::getSkImageFromDecoder(std::unique_ptr<ImageDeco
der> decoder) | 211 sk_sp<SkImage> ImageBitmap::getSkImageFromDecoder(std::unique_ptr<ImageDecoder>
decoder) |
| 212 { | 212 { |
| 213 if (!decoder->frameCount()) | 213 if (!decoder->frameCount()) |
| 214 return nullptr; | 214 return nullptr; |
| 215 ImageFrame* frame = decoder->frameBufferAtIndex(0); | 215 ImageFrame* frame = decoder->frameBufferAtIndex(0); |
| 216 if (!frame || frame->getStatus() != ImageFrame::FrameComplete) | 216 if (!frame || frame->getStatus() != ImageFrame::FrameComplete) |
| 217 return nullptr; | 217 return nullptr; |
| 218 SkBitmap bitmap = frame->bitmap(); | 218 SkBitmap bitmap = frame->bitmap(); |
| 219 if (!frameIsValid(bitmap)) | 219 if (!frameIsValid(bitmap)) |
| 220 return nullptr; | 220 return nullptr; |
| 221 return fromSkSp(SkImage::MakeFromBitmap(bitmap)); | 221 return SkImage::MakeFromBitmap(bitmap); |
| 222 } | 222 } |
| 223 | 223 |
| 224 bool ImageBitmap::isResizeOptionValid(const ImageBitmapOptions& options, Excepti
onState& exceptionState) | 224 bool ImageBitmap::isResizeOptionValid(const ImageBitmapOptions& options, Excepti
onState& exceptionState) |
| 225 { | 225 { |
| 226 if ((options.hasResizeWidth() && options.resizeWidth() == 0) || (options.has
ResizeHeight() && options.resizeHeight() == 0)) { | 226 if ((options.hasResizeWidth() && options.resizeWidth() == 0) || (options.has
ResizeHeight() && options.resizeHeight() == 0)) { |
| 227 exceptionState.throwDOMException(InvalidStateError, "The resizeWidth or/
and resizeHeight is equal to 0."); | 227 exceptionState.throwDOMException(InvalidStateError, "The resizeWidth or/
and resizeHeight is equal to 0."); |
| 228 return false; | 228 return false; |
| 229 } | 229 } |
| 230 return true; | 230 return true; |
| 231 } | 231 } |
| (...skipping 21 matching lines...) Expand all Loading... |
| 253 // We immediately return a transparent black image with cropRect.size() | 253 // We immediately return a transparent black image with cropRect.size() |
| 254 if (srcRect.isEmpty() && !parsedOptions.premultiplyAlpha) { | 254 if (srcRect.isEmpty() && !parsedOptions.premultiplyAlpha) { |
| 255 SkImageInfo info = SkImageInfo::Make(parsedOptions.resizeWidth, parsedOp
tions.resizeHeight, kN32_SkColorType, kUnpremul_SkAlphaType); | 255 SkImageInfo info = SkImageInfo::Make(parsedOptions.resizeWidth, parsedOp
tions.resizeHeight, kN32_SkColorType, kUnpremul_SkAlphaType); |
| 256 RefPtr<ArrayBuffer> dstBuffer = ArrayBuffer::createOrNull(static_cast<si
ze_t>(info.width()) * info.height(), info.bytesPerPixel()); | 256 RefPtr<ArrayBuffer> dstBuffer = ArrayBuffer::createOrNull(static_cast<si
ze_t>(info.width()) * info.height(), info.bytesPerPixel()); |
| 257 if (!dstBuffer) | 257 if (!dstBuffer) |
| 258 return nullptr; | 258 return nullptr; |
| 259 RefPtr<Uint8Array> dstPixels = Uint8Array::create(dstBuffer, 0, dstBuffe
r->byteLength()); | 259 RefPtr<Uint8Array> dstPixels = Uint8Array::create(dstBuffer, 0, dstBuffe
r->byteLength()); |
| 260 return StaticBitmapImage::create(newSkImageFromRaster(info, std::move(ds
tPixels), static_cast<size_t>(info.width()) * info.bytesPerPixel())); | 260 return StaticBitmapImage::create(newSkImageFromRaster(info, std::move(ds
tPixels), static_cast<size_t>(info.width()) * info.bytesPerPixel())); |
| 261 } | 261 } |
| 262 | 262 |
| 263 RefPtr<SkImage> skiaImage = image->imageForCurrentFrame(); | 263 sk_sp<SkImage> skiaImage = image->imageForCurrentFrame(); |
| 264 // Attempt to get raw unpremultiplied image data, executed only when skiaIma
ge is premultiplied. | 264 // Attempt to get raw unpremultiplied image data, executed only when skiaIma
ge is premultiplied. |
| 265 if ((((!parsedOptions.premultiplyAlpha && !skiaImage->isOpaque()) || !skiaIm
age) && image->data() && imageFormat == PremultiplyAlpha) || colorSpaceOp == Ima
geDecoder::GammaAndColorProfileIgnored) { | 265 if ((((!parsedOptions.premultiplyAlpha && !skiaImage->isOpaque()) || !skiaIm
age) && image->data() && imageFormat == PremultiplyAlpha) || colorSpaceOp == Ima
geDecoder::GammaAndColorProfileIgnored) { |
| 266 std::unique_ptr<ImageDecoder> decoder(ImageDecoder::create( | 266 std::unique_ptr<ImageDecoder> decoder(ImageDecoder::create( |
| 267 image->data(), true, | 267 image->data(), true, |
| 268 parsedOptions.premultiplyAlpha ? ImageDecoder::AlphaPremultiplied :
ImageDecoder::AlphaNotPremultiplied, | 268 parsedOptions.premultiplyAlpha ? ImageDecoder::AlphaPremultiplied :
ImageDecoder::AlphaNotPremultiplied, |
| 269 colorSpaceOp)); | 269 colorSpaceOp)); |
| 270 if (!decoder) | 270 if (!decoder) |
| 271 return nullptr; | 271 return nullptr; |
| 272 skiaImage = ImageBitmap::getSkImageFromDecoder(std::move(decoder)); | 272 skiaImage = ImageBitmap::getSkImageFromDecoder(std::move(decoder)); |
| 273 if (!skiaImage) | 273 if (!skiaImage) |
| 274 return nullptr; | 274 return nullptr; |
| 275 } | 275 } |
| 276 | 276 |
| 277 if (parsedOptions.cropRect == srcRect && !parsedOptions.shouldScaleInput) { | 277 if (parsedOptions.cropRect == srcRect && !parsedOptions.shouldScaleInput) { |
| 278 RefPtr<SkImage> croppedSkImage = fromSkSp(skiaImage->makeSubset(srcRect)
); | 278 sk_sp<SkImage> croppedSkImage = skiaImage->makeSubset(srcRect); |
| 279 if (parsedOptions.flipY) | 279 if (parsedOptions.flipY) |
| 280 return StaticBitmapImage::create(flipSkImageVertically(croppedSkImag
e.get(), parsedOptions.premultiplyAlpha ? PremultiplyAlpha : DontPremultiplyAlph
a)); | 280 return StaticBitmapImage::create(flipSkImageVertically(croppedSkImag
e.get(), parsedOptions.premultiplyAlpha ? PremultiplyAlpha : DontPremultiplyAlph
a)); |
| 281 // Special case: The first parameter image is unpremul but we need to tu
rn it into premul. | 281 // Special case: The first parameter image is unpremul but we need to tu
rn it into premul. |
| 282 if (parsedOptions.premultiplyAlpha && imageFormat == DontPremultiplyAlph
a) | 282 if (parsedOptions.premultiplyAlpha && imageFormat == DontPremultiplyAlph
a) |
| 283 return StaticBitmapImage::create(unPremulSkImageToPremul(croppedSkIm
age.get())); | 283 return StaticBitmapImage::create(unPremulSkImageToPremul(croppedSkIm
age.get())); |
| 284 // Call preroll to trigger image decoding. | 284 // Call preroll to trigger image decoding. |
| 285 croppedSkImage->preroll(); | 285 croppedSkImage->preroll(); |
| 286 return StaticBitmapImage::create(croppedSkImage.release()); | 286 return StaticBitmapImage::create(std::move(croppedSkImage)); |
| 287 } | 287 } |
| 288 | 288 |
| 289 sk_sp<SkSurface> surface = SkSurface::MakeRasterN32Premul(parsedOptions.resi
zeWidth, parsedOptions.resizeHeight); | 289 sk_sp<SkSurface> surface = SkSurface::MakeRasterN32Premul(parsedOptions.resi
zeWidth, parsedOptions.resizeHeight); |
| 290 if (!surface) | 290 if (!surface) |
| 291 return nullptr; | 291 return nullptr; |
| 292 if (srcRect.isEmpty()) | 292 if (srcRect.isEmpty()) |
| 293 return StaticBitmapImage::create(fromSkSp(surface->makeImageSnapshot()))
; | 293 return StaticBitmapImage::create(surface->makeImageSnapshot()); |
| 294 | 294 |
| 295 SkScalar dstLeft = std::min(0, -parsedOptions.cropRect.x()); | 295 SkScalar dstLeft = std::min(0, -parsedOptions.cropRect.x()); |
| 296 SkScalar dstTop = std::min(0, -parsedOptions.cropRect.y()); | 296 SkScalar dstTop = std::min(0, -parsedOptions.cropRect.y()); |
| 297 if (parsedOptions.cropRect.x() < 0) | 297 if (parsedOptions.cropRect.x() < 0) |
| 298 dstLeft = -parsedOptions.cropRect.x(); | 298 dstLeft = -parsedOptions.cropRect.x(); |
| 299 if (parsedOptions.cropRect.y() < 0) | 299 if (parsedOptions.cropRect.y() < 0) |
| 300 dstTop = -parsedOptions.cropRect.y(); | 300 dstTop = -parsedOptions.cropRect.y(); |
| 301 if (parsedOptions.flipY) { | 301 if (parsedOptions.flipY) { |
| 302 surface->getCanvas()->translate(0, surface->height()); | 302 surface->getCanvas()->translate(0, surface->height()); |
| 303 surface->getCanvas()->scale(1, -1); | 303 surface->getCanvas()->scale(1, -1); |
| 304 } | 304 } |
| 305 if (parsedOptions.shouldScaleInput) { | 305 if (parsedOptions.shouldScaleInput) { |
| 306 SkRect drawSrcRect = SkRect::MakeXYWH(parsedOptions.cropRect.x(), parsed
Options.cropRect.y(), parsedOptions.cropRect.width(), parsedOptions.cropRect.hei
ght()); | 306 SkRect drawSrcRect = SkRect::MakeXYWH(parsedOptions.cropRect.x(), parsed
Options.cropRect.y(), parsedOptions.cropRect.width(), parsedOptions.cropRect.hei
ght()); |
| 307 SkRect drawDstRect = SkRect::MakeXYWH(0, 0, parsedOptions.resizeWidth, p
arsedOptions.resizeHeight); | 307 SkRect drawDstRect = SkRect::MakeXYWH(0, 0, parsedOptions.resizeWidth, p
arsedOptions.resizeHeight); |
| 308 SkPaint paint; | 308 SkPaint paint; |
| 309 paint.setFilterQuality(parsedOptions.resizeQuality); | 309 paint.setFilterQuality(parsedOptions.resizeQuality); |
| 310 surface->getCanvas()->drawImageRect(skiaImage.get(), drawSrcRect, drawDs
tRect, &paint); | 310 surface->getCanvas()->drawImageRect(skiaImage, drawSrcRect, drawDstRect,
&paint); |
| 311 } else { | 311 } else { |
| 312 surface->getCanvas()->drawImage(skiaImage.get(), dstLeft, dstTop); | 312 surface->getCanvas()->drawImage(skiaImage, dstLeft, dstTop); |
| 313 } | 313 } |
| 314 skiaImage = fromSkSp(surface->makeImageSnapshot()); | 314 skiaImage = surface->makeImageSnapshot(); |
| 315 | 315 |
| 316 if (parsedOptions.premultiplyAlpha) { | 316 if (parsedOptions.premultiplyAlpha) { |
| 317 if (imageFormat == DontPremultiplyAlpha) | 317 if (imageFormat == DontPremultiplyAlpha) |
| 318 return StaticBitmapImage::create(unPremulSkImageToPremul(skiaImage.g
et())); | 318 return StaticBitmapImage::create(unPremulSkImageToPremul(skiaImage.g
et())); |
| 319 return StaticBitmapImage::create(skiaImage.release()); | 319 return StaticBitmapImage::create(std::move(skiaImage)); |
| 320 } | 320 } |
| 321 return StaticBitmapImage::create(premulSkImageToUnPremul(skiaImage.get())); | 321 return StaticBitmapImage::create(premulSkImageToUnPremul(skiaImage.get())); |
| 322 } | 322 } |
| 323 | 323 |
| 324 ImageBitmap::ImageBitmap(HTMLImageElement* image, Optional<IntRect> cropRect, Do
cument* document, const ImageBitmapOptions& options) | 324 ImageBitmap::ImageBitmap(HTMLImageElement* image, Optional<IntRect> cropRect, Do
cument* document, const ImageBitmapOptions& options) |
| 325 { | 325 { |
| 326 RefPtr<Image> input = image->cachedImage()->getImage(); | 326 RefPtr<Image> input = image->cachedImage()->getImage(); |
| 327 ParsedOptions parsedOptions = parseOptions(options, cropRect, image->bitmapS
ourceSize()); | 327 ParsedOptions parsedOptions = parseOptions(options, cropRect, image->bitmapS
ourceSize()); |
| 328 if (dstBufferSizeHasOverflow(parsedOptions)) | 328 if (dstBufferSizeHasOverflow(parsedOptions)) |
| 329 return; | 329 return; |
| 330 | 330 |
| 331 if (options.colorSpaceConversion() == "none") | 331 if (options.colorSpaceConversion() == "none") |
| 332 m_image = cropImage(input.get(), parsedOptions, PremultiplyAlpha, ImageD
ecoder::GammaAndColorProfileIgnored); | 332 m_image = cropImage(input.get(), parsedOptions, PremultiplyAlpha, ImageD
ecoder::GammaAndColorProfileIgnored); |
| 333 else | 333 else |
| 334 m_image = cropImage(input.get(), parsedOptions, PremultiplyAlpha, ImageD
ecoder::GammaAndColorProfileApplied); | 334 m_image = cropImage(input.get(), parsedOptions, PremultiplyAlpha, ImageD
ecoder::GammaAndColorProfileApplied); |
| 335 if (!m_image) | 335 if (!m_image) |
| 336 return; | 336 return; |
| 337 // In the case where the source image is lazy-decoded, m_image may not be in | 337 // In the case where the source image is lazy-decoded, m_image may not be in |
| 338 // a decoded state, we trigger it here. | 338 // a decoded state, we trigger it here. |
| 339 RefPtr<SkImage> skImage = m_image->imageForCurrentFrame(); | 339 sk_sp<SkImage> skImage = m_image->imageForCurrentFrame(); |
| 340 SkPixmap pixmap; | 340 SkPixmap pixmap; |
| 341 if (!skImage->isTextureBacked() && !skImage->peekPixels(&pixmap)) { | 341 if (!skImage->isTextureBacked() && !skImage->peekPixels(&pixmap)) { |
| 342 sk_sp<SkSurface> surface = SkSurface::MakeRasterN32Premul(skImage->width
(), skImage->height()); | 342 sk_sp<SkSurface> surface = SkSurface::MakeRasterN32Premul(skImage->width
(), skImage->height()); |
| 343 surface->getCanvas()->drawImage(skImage.get(), 0, 0); | 343 surface->getCanvas()->drawImage(skImage, 0, 0); |
| 344 m_image = StaticBitmapImage::create(fromSkSp(surface->makeImageSnapshot(
))); | 344 m_image = StaticBitmapImage::create(surface->makeImageSnapshot()); |
| 345 } | 345 } |
| 346 if (!m_image) | 346 if (!m_image) |
| 347 return; | 347 return; |
| 348 m_image->setOriginClean(!image->wouldTaintOrigin(document->getSecurityOrigin
())); | 348 m_image->setOriginClean(!image->wouldTaintOrigin(document->getSecurityOrigin
())); |
| 349 m_image->setPremultiplied(parsedOptions.premultiplyAlpha); | 349 m_image->setPremultiplied(parsedOptions.premultiplyAlpha); |
| 350 } | 350 } |
| 351 | 351 |
| 352 ImageBitmap::ImageBitmap(HTMLVideoElement* video, Optional<IntRect> cropRect, Do
cument* document, const ImageBitmapOptions& options) | 352 ImageBitmap::ImageBitmap(HTMLVideoElement* video, Optional<IntRect> cropRect, Do
cument* document, const ImageBitmapOptions& options) |
| 353 { | 353 { |
| 354 IntSize playerSize; | 354 IntSize playerSize; |
| (...skipping 18 matching lines...) Expand all Loading... |
| 373 SkPaint paint; | 373 SkPaint paint; |
| 374 if (parsedOptions.shouldScaleInput) { | 374 if (parsedOptions.shouldScaleInput) { |
| 375 float scaleRatioX = static_cast<float>(parsedOptions.resizeWidth) / pars
edOptions.cropRect.width(); | 375 float scaleRatioX = static_cast<float>(parsedOptions.resizeWidth) / pars
edOptions.cropRect.width(); |
| 376 float scaleRatioY = static_cast<float>(parsedOptions.resizeHeight) / par
sedOptions.cropRect.height(); | 376 float scaleRatioY = static_cast<float>(parsedOptions.resizeHeight) / par
sedOptions.cropRect.height(); |
| 377 dstPoint.scale(scaleRatioX, scaleRatioY); | 377 dstPoint.scale(scaleRatioX, scaleRatioY); |
| 378 paint.setFilterQuality(parsedOptions.resizeQuality); | 378 paint.setFilterQuality(parsedOptions.resizeQuality); |
| 379 dstSize.scale(scaleRatioX, scaleRatioY); | 379 dstSize.scale(scaleRatioX, scaleRatioY); |
| 380 } | 380 } |
| 381 video->paintCurrentFrame(buffer->canvas(), IntRect(dstPoint, dstSize), parse
dOptions.shouldScaleInput ? &paint : nullptr); | 381 video->paintCurrentFrame(buffer->canvas(), IntRect(dstPoint, dstSize), parse
dOptions.shouldScaleInput ? &paint : nullptr); |
| 382 | 382 |
| 383 RefPtr<SkImage> skiaImage = buffer->newSkImageSnapshot(PreferNoAcceleration,
SnapshotReasonUnknown); | 383 sk_sp<SkImage> skiaImage = buffer->newSkImageSnapshot(PreferNoAcceleration,
SnapshotReasonUnknown); |
| 384 if (!parsedOptions.premultiplyAlpha) | 384 if (!parsedOptions.premultiplyAlpha) |
| 385 skiaImage = premulSkImageToUnPremul(skiaImage.get()); | 385 skiaImage = premulSkImageToUnPremul(skiaImage.get()); |
| 386 if (!skiaImage) | 386 if (!skiaImage) |
| 387 return; | 387 return; |
| 388 m_image = StaticBitmapImage::create(skiaImage.release()); | 388 m_image = StaticBitmapImage::create(std::move(skiaImage)); |
| 389 m_image->setOriginClean(!video->wouldTaintOrigin(document->getSecurityOrigin
())); | 389 m_image->setOriginClean(!video->wouldTaintOrigin(document->getSecurityOrigin
())); |
| 390 m_image->setPremultiplied(parsedOptions.premultiplyAlpha); | 390 m_image->setPremultiplied(parsedOptions.premultiplyAlpha); |
| 391 } | 391 } |
| 392 | 392 |
| 393 ImageBitmap::ImageBitmap(HTMLCanvasElement* canvas, Optional<IntRect> cropRect,
const ImageBitmapOptions& options) | 393 ImageBitmap::ImageBitmap(HTMLCanvasElement* canvas, Optional<IntRect> cropRect,
const ImageBitmapOptions& options) |
| 394 { | 394 { |
| 395 ASSERT(canvas->isPaintable()); | 395 ASSERT(canvas->isPaintable()); |
| 396 RefPtr<Image> input = canvas->copiedImage(BackBuffer, PreferAcceleration); | 396 RefPtr<Image> input = canvas->copiedImage(BackBuffer, PreferAcceleration); |
| 397 ParsedOptions parsedOptions = parseOptions(options, cropRect, canvas->bitmap
SourceSize()); | 397 ParsedOptions parsedOptions = parseOptions(options, cropRect, canvas->bitmap
SourceSize()); |
| 398 if (dstBufferSizeHasOverflow(parsedOptions)) | 398 if (dstBufferSizeHasOverflow(parsedOptions)) |
| (...skipping 13 matching lines...) Expand all Loading... |
| 412 } | 412 } |
| 413 if (!m_image) | 413 if (!m_image) |
| 414 return; | 414 return; |
| 415 m_image->setOriginClean(canvas->originClean()); | 415 m_image->setOriginClean(canvas->originClean()); |
| 416 m_image->setPremultiplied(parsedOptions.premultiplyAlpha); | 416 m_image->setPremultiplied(parsedOptions.premultiplyAlpha); |
| 417 } | 417 } |
| 418 | 418 |
| 419 ImageBitmap::ImageBitmap(std::unique_ptr<uint8_t[]> data, uint32_t width, uint32
_t height, bool isImageBitmapPremultiplied, bool isImageBitmapOriginClean) | 419 ImageBitmap::ImageBitmap(std::unique_ptr<uint8_t[]> data, uint32_t width, uint32
_t height, bool isImageBitmapPremultiplied, bool isImageBitmapOriginClean) |
| 420 { | 420 { |
| 421 SkImageInfo info = SkImageInfo::MakeN32(width, height, isImageBitmapPremulti
plied ? kPremul_SkAlphaType : kUnpremul_SkAlphaType); | 421 SkImageInfo info = SkImageInfo::MakeN32(width, height, isImageBitmapPremulti
plied ? kPremul_SkAlphaType : kUnpremul_SkAlphaType); |
| 422 m_image = StaticBitmapImage::create(fromSkSp(SkImage::MakeRasterCopy(SkPixma
p(info, data.get(), info.bytesPerPixel() * width)))); | 422 m_image = StaticBitmapImage::create(SkImage::MakeRasterCopy(SkPixmap(info, d
ata.get(), info.bytesPerPixel() * width))); |
| 423 if (!m_image) | 423 if (!m_image) |
| 424 return; | 424 return; |
| 425 m_image->setPremultiplied(isImageBitmapPremultiplied); | 425 m_image->setPremultiplied(isImageBitmapPremultiplied); |
| 426 m_image->setOriginClean(isImageBitmapOriginClean); | 426 m_image->setOriginClean(isImageBitmapOriginClean); |
| 427 } | 427 } |
| 428 | 428 |
| 429 static PassRefPtr<SkImage> scaleSkImage(PassRefPtr<SkImage> skImage, unsigned re
sizeWidth, unsigned resizeHeight, SkFilterQuality resizeQuality) | 429 static sk_sp<SkImage> scaleSkImage(sk_sp<SkImage> skImage, unsigned resizeWidth,
unsigned resizeHeight, SkFilterQuality resizeQuality) |
| 430 { | 430 { |
| 431 SkImageInfo resizedInfo = SkImageInfo::Make(resizeWidth, resizeHeight, kN32_
SkColorType, kUnpremul_SkAlphaType); | 431 SkImageInfo resizedInfo = SkImageInfo::Make(resizeWidth, resizeHeight, kN32_
SkColorType, kUnpremul_SkAlphaType); |
| 432 RefPtr<ArrayBuffer> dstBuffer = ArrayBuffer::createOrNull(resizeWidth * resi
zeHeight, resizedInfo.bytesPerPixel()); | 432 RefPtr<ArrayBuffer> dstBuffer = ArrayBuffer::createOrNull(resizeWidth * resi
zeHeight, resizedInfo.bytesPerPixel()); |
| 433 if (!dstBuffer) | 433 if (!dstBuffer) |
| 434 return nullptr; | 434 return nullptr; |
| 435 RefPtr<Uint8Array> resizedPixels = Uint8Array::create(dstBuffer, 0, dstBuffe
r->byteLength()); | 435 RefPtr<Uint8Array> resizedPixels = Uint8Array::create(dstBuffer, 0, dstBuffe
r->byteLength()); |
| 436 SkPixmap pixmap(resizedInfo, resizedPixels->data(), static_cast<size_t>(resi
zeWidth) * resizedInfo.bytesPerPixel()); | 436 SkPixmap pixmap(resizedInfo, resizedPixels->data(), static_cast<size_t>(resi
zeWidth) * resizedInfo.bytesPerPixel()); |
| 437 skImage->scalePixels(pixmap, resizeQuality); | 437 skImage->scalePixels(pixmap, resizeQuality); |
| 438 return fromSkSp(SkImage::MakeFromRaster(pixmap, [](const void*, void* pixels
) | 438 return SkImage::MakeFromRaster(pixmap, [](const void*, void* pixels) |
| 439 { | 439 { |
| 440 static_cast<Uint8Array*>(pixels)->deref(); | 440 static_cast<Uint8Array*>(pixels)->deref(); |
| 441 }, resizedPixels.release().leakRef())); | 441 }, resizedPixels.release().leakRef()); |
| 442 } | 442 } |
| 443 | 443 |
| 444 ImageBitmap::ImageBitmap(ImageData* data, Optional<IntRect> cropRect, const Imag
eBitmapOptions& options) | 444 ImageBitmap::ImageBitmap(ImageData* data, Optional<IntRect> cropRect, const Imag
eBitmapOptions& options) |
| 445 { | 445 { |
| 446 // TODO(xidachen): implement the resize option | 446 // TODO(xidachen): implement the resize option |
| 447 IntRect dataSrcRect = IntRect(IntPoint(), data->size()); | 447 IntRect dataSrcRect = IntRect(IntPoint(), data->size()); |
| 448 ParsedOptions parsedOptions = parseOptions(options, cropRect, data->bitmapSo
urceSize()); | 448 ParsedOptions parsedOptions = parseOptions(options, cropRect, data->bitmapSo
urceSize()); |
| 449 if (dstBufferSizeHasOverflow(parsedOptions)) | 449 if (dstBufferSizeHasOverflow(parsedOptions)) |
| 450 return; | 450 return; |
| 451 IntRect srcRect = cropRect ? intersection(parsedOptions.cropRect, dataSrcRec
t) : dataSrcRect; | 451 IntRect srcRect = cropRect ? intersection(parsedOptions.cropRect, dataSrcRec
t) : dataSrcRect; |
| 452 | 452 |
| 453 // treat non-premultiplyAlpha as a special case | 453 // treat non-premultiplyAlpha as a special case |
| 454 if (!parsedOptions.premultiplyAlpha) { | 454 if (!parsedOptions.premultiplyAlpha) { |
| 455 unsigned char* srcAddr = data->data()->data(); | 455 unsigned char* srcAddr = data->data()->data(); |
| 456 | 456 |
| 457 // Using kN32 type, swizzle input if necessary. | 457 // Using kN32 type, swizzle input if necessary. |
| 458 SkImageInfo info = SkImageInfo::Make(parsedOptions.cropRect.width(), par
sedOptions.cropRect.height(), kN32_SkColorType, kUnpremul_SkAlphaType); | 458 SkImageInfo info = SkImageInfo::Make(parsedOptions.cropRect.width(), par
sedOptions.cropRect.height(), kN32_SkColorType, kUnpremul_SkAlphaType); |
| 459 size_t bytesPerPixel = static_cast<size_t>(info.bytesPerPixel()); | 459 size_t bytesPerPixel = static_cast<size_t>(info.bytesPerPixel()); |
| 460 size_t srcPixelBytesPerRow = bytesPerPixel * data->size().width(); | 460 size_t srcPixelBytesPerRow = bytesPerPixel * data->size().width(); |
| 461 size_t dstPixelBytesPerRow = bytesPerPixel * parsedOptions.cropRect.widt
h(); | 461 size_t dstPixelBytesPerRow = bytesPerPixel * parsedOptions.cropRect.widt
h(); |
| 462 RefPtr<SkImage> skImage; | 462 sk_sp<SkImage> skImage; |
| 463 if (parsedOptions.cropRect == IntRect(IntPoint(), data->size())) { | 463 if (parsedOptions.cropRect == IntRect(IntPoint(), data->size())) { |
| 464 swizzleImageData(srcAddr, data->size().height(), srcPixelBytesPerRow
, parsedOptions.flipY); | 464 swizzleImageData(srcAddr, data->size().height(), srcPixelBytesPerRow
, parsedOptions.flipY); |
| 465 skImage = fromSkSp(SkImage::MakeRasterCopy(SkPixmap(info, srcAddr, d
stPixelBytesPerRow))); | 465 skImage = SkImage::MakeRasterCopy(SkPixmap(info, srcAddr, dstPixelBy
tesPerRow)); |
| 466 // restore the original ImageData | 466 // restore the original ImageData |
| 467 swizzleImageData(srcAddr, data->size().height(), srcPixelBytesPerRow
, parsedOptions.flipY); | 467 swizzleImageData(srcAddr, data->size().height(), srcPixelBytesPerRow
, parsedOptions.flipY); |
| 468 } else { | 468 } else { |
| 469 RefPtr<ArrayBuffer> dstBuffer = ArrayBuffer::createOrNull(static_cas
t<size_t>(parsedOptions.cropRect.height()) * parsedOptions.cropRect.width(), byt
esPerPixel); | 469 RefPtr<ArrayBuffer> dstBuffer = ArrayBuffer::createOrNull(static_cas
t<size_t>(parsedOptions.cropRect.height()) * parsedOptions.cropRect.width(), byt
esPerPixel); |
| 470 if (!dstBuffer) | 470 if (!dstBuffer) |
| 471 return; | 471 return; |
| 472 RefPtr<Uint8Array> copiedDataBuffer = Uint8Array::create(dstBuffer,
0, dstBuffer->byteLength()); | 472 RefPtr<Uint8Array> copiedDataBuffer = Uint8Array::create(dstBuffer,
0, dstBuffer->byteLength()); |
| 473 if (!srcRect.isEmpty()) { | 473 if (!srcRect.isEmpty()) { |
| 474 IntPoint srcPoint = IntPoint((parsedOptions.cropRect.x() > 0) ?
parsedOptions.cropRect.x() : 0, (parsedOptions.cropRect.y() > 0) ? parsedOptions
.cropRect.y() : 0); | 474 IntPoint srcPoint = IntPoint((parsedOptions.cropRect.x() > 0) ?
parsedOptions.cropRect.x() : 0, (parsedOptions.cropRect.y() > 0) ? parsedOptions
.cropRect.y() : 0); |
| 475 IntPoint dstPoint = IntPoint((parsedOptions.cropRect.x() >= 0) ?
0 : -parsedOptions.cropRect.x(), (parsedOptions.cropRect.y() >= 0) ? 0 : -parse
dOptions.cropRect.y()); | 475 IntPoint dstPoint = IntPoint((parsedOptions.cropRect.x() >= 0) ?
0 : -parsedOptions.cropRect.x(), (parsedOptions.cropRect.y() >= 0) ? 0 : -parse
dOptions.cropRect.y()); |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 524 m_image = StaticBitmapImage::create(buffer->newSkImageSnapshot(PreferNoA
cceleration, SnapshotReasonUnknown)); | 524 m_image = StaticBitmapImage::create(buffer->newSkImageSnapshot(PreferNoA
cceleration, SnapshotReasonUnknown)); |
| 525 return; | 525 return; |
| 526 } | 526 } |
| 527 | 527 |
| 528 IntPoint dstPoint = IntPoint(std::min(0, -parsedOptions.cropRect.x()), std::
min(0, -parsedOptions.cropRect.y())); | 528 IntPoint dstPoint = IntPoint(std::min(0, -parsedOptions.cropRect.x()), std::
min(0, -parsedOptions.cropRect.y())); |
| 529 if (parsedOptions.cropRect.x() < 0) | 529 if (parsedOptions.cropRect.x() < 0) |
| 530 dstPoint.setX(-parsedOptions.cropRect.x()); | 530 dstPoint.setX(-parsedOptions.cropRect.x()); |
| 531 if (parsedOptions.cropRect.y() < 0) | 531 if (parsedOptions.cropRect.y() < 0) |
| 532 dstPoint.setY(-parsedOptions.cropRect.y()); | 532 dstPoint.setY(-parsedOptions.cropRect.y()); |
| 533 buffer->putByteArray(Unmultiplied, data->data()->data(), data->size(), srcRe
ct, dstPoint); | 533 buffer->putByteArray(Unmultiplied, data->data()->data(), data->size(), srcRe
ct, dstPoint); |
| 534 RefPtr<SkImage> skImage = buffer->newSkImageSnapshot(PreferNoAcceleration, S
napshotReasonUnknown); | 534 sk_sp<SkImage> skImage = buffer->newSkImageSnapshot(PreferNoAcceleration, Sn
apshotReasonUnknown); |
| 535 if (parsedOptions.flipY) | 535 if (parsedOptions.flipY) |
| 536 skImage = flipSkImageVertically(skImage.get(), PremultiplyAlpha); | 536 skImage = flipSkImageVertically(skImage.get(), PremultiplyAlpha); |
| 537 if (!skImage) | 537 if (!skImage) |
| 538 return; | 538 return; |
| 539 if (parsedOptions.shouldScaleInput) { | 539 if (parsedOptions.shouldScaleInput) { |
| 540 sk_sp<SkSurface> surface = SkSurface::MakeRasterN32Premul(parsedOptions.
resizeWidth, parsedOptions.resizeHeight); | 540 sk_sp<SkSurface> surface = SkSurface::MakeRasterN32Premul(parsedOptions.
resizeWidth, parsedOptions.resizeHeight); |
| 541 if (!surface) | 541 if (!surface) |
| 542 return; | 542 return; |
| 543 SkPaint paint; | 543 SkPaint paint; |
| 544 paint.setFilterQuality(parsedOptions.resizeQuality); | 544 paint.setFilterQuality(parsedOptions.resizeQuality); |
| 545 SkRect dstDrawRect = SkRect::MakeWH(parsedOptions.resizeWidth, parsedOpt
ions.resizeHeight); | 545 SkRect dstDrawRect = SkRect::MakeWH(parsedOptions.resizeWidth, parsedOpt
ions.resizeHeight); |
| 546 surface->getCanvas()->drawImageRect(skImage.get(), dstDrawRect, &paint); | 546 surface->getCanvas()->drawImageRect(skImage, dstDrawRect, &paint); |
| 547 skImage = fromSkSp(surface->makeImageSnapshot()); | 547 skImage = surface->makeImageSnapshot(); |
| 548 } | 548 } |
| 549 m_image = StaticBitmapImage::create(skImage); | 549 m_image = StaticBitmapImage::create(std::move(skImage)); |
| 550 } | 550 } |
| 551 | 551 |
| 552 ImageBitmap::ImageBitmap(ImageBitmap* bitmap, Optional<IntRect> cropRect, const
ImageBitmapOptions& options) | 552 ImageBitmap::ImageBitmap(ImageBitmap* bitmap, Optional<IntRect> cropRect, const
ImageBitmapOptions& options) |
| 553 { | 553 { |
| 554 RefPtr<Image> input = bitmap->bitmapImage(); | 554 RefPtr<Image> input = bitmap->bitmapImage(); |
| 555 if (!input) | 555 if (!input) |
| 556 return; | 556 return; |
| 557 ParsedOptions parsedOptions = parseOptions(options, cropRect, input->size())
; | 557 ParsedOptions parsedOptions = parseOptions(options, cropRect, input->size())
; |
| 558 if (dstBufferSizeHasOverflow(parsedOptions)) | 558 if (dstBufferSizeHasOverflow(parsedOptions)) |
| 559 return; | 559 return; |
| (...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 641 { | 641 { |
| 642 if (!m_image || m_isNeutered) | 642 if (!m_image || m_isNeutered) |
| 643 return; | 643 return; |
| 644 m_image.clear(); | 644 m_image.clear(); |
| 645 m_isNeutered = true; | 645 m_isNeutered = true; |
| 646 } | 646 } |
| 647 | 647 |
| 648 // static | 648 // static |
| 649 ImageBitmap* ImageBitmap::take(ScriptPromiseResolver*, sk_sp<SkImage> image) | 649 ImageBitmap* ImageBitmap::take(ScriptPromiseResolver*, sk_sp<SkImage> image) |
| 650 { | 650 { |
| 651 return ImageBitmap::create(StaticBitmapImage::create(fromSkSp(image))); | 651 return ImageBitmap::create(StaticBitmapImage::create(std::move(image))); |
| 652 } | 652 } |
| 653 | 653 |
| 654 PassRefPtr<Uint8Array> ImageBitmap::copyBitmapData(AlphaDisposition alphaOp, Dat
aColorFormat format) | 654 PassRefPtr<Uint8Array> ImageBitmap::copyBitmapData(AlphaDisposition alphaOp, Dat
aColorFormat format) |
| 655 { | 655 { |
| 656 SkImageInfo info = SkImageInfo::Make(width(), height(), (format == RGBAColor
Type) ? kRGBA_8888_SkColorType : kN32_SkColorType, (alphaOp == PremultiplyAlpha)
? kPremul_SkAlphaType : kUnpremul_SkAlphaType); | 656 SkImageInfo info = SkImageInfo::Make(width(), height(), (format == RGBAColor
Type) ? kRGBA_8888_SkColorType : kN32_SkColorType, (alphaOp == PremultiplyAlpha)
? kPremul_SkAlphaType : kUnpremul_SkAlphaType); |
| 657 RefPtr<Uint8Array> dstPixels = copySkImageData(m_image->imageForCurrentFrame
().get(), info); | 657 RefPtr<Uint8Array> dstPixels = copySkImageData(m_image->imageForCurrentFrame
().get(), info); |
| 658 return dstPixels.release(); | 658 return dstPixels.release(); |
| 659 } | 659 } |
| 660 | 660 |
| 661 unsigned long ImageBitmap::width() const | 661 unsigned long ImageBitmap::width() const |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 710 FloatSize ImageBitmap::elementSize(const FloatSize&) const | 710 FloatSize ImageBitmap::elementSize(const FloatSize&) const |
| 711 { | 711 { |
| 712 return FloatSize(width(), height()); | 712 return FloatSize(width(), height()); |
| 713 } | 713 } |
| 714 | 714 |
| 715 DEFINE_TRACE(ImageBitmap) | 715 DEFINE_TRACE(ImageBitmap) |
| 716 { | 716 { |
| 717 } | 717 } |
| 718 | 718 |
| 719 } // namespace blink | 719 } // namespace blink |
| OLD | NEW |