| 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 19 matching lines...) Expand all Loading... |
| 30 static bool frameIsValid(const SkBitmap& frameBitmap) | 30 static bool frameIsValid(const SkBitmap& frameBitmap) |
| 31 { | 31 { |
| 32 ASSERT(!frameBitmap.isNull() && !frameBitmap.empty() && frameBitmap.isImmuta
ble()); | 32 ASSERT(!frameBitmap.isNull() && !frameBitmap.empty() && frameBitmap.isImmuta
ble()); |
| 33 return frameBitmap.colorType() == kN32_SkColorType; | 33 return frameBitmap.colorType() == kN32_SkColorType; |
| 34 } | 34 } |
| 35 | 35 |
| 36 static PassOwnPtr<uint8_t[]> copySkImageData(SkImage* input, SkImageInfo info) | 36 static PassOwnPtr<uint8_t[]> copySkImageData(SkImage* input, SkImageInfo info) |
| 37 { | 37 { |
| 38 OwnPtr<uint8_t[]> dstPixels = adoptArrayPtr(new uint8_t[input->width() * inp
ut->height() * info.bytesPerPixel()]); | 38 OwnPtr<uint8_t[]> dstPixels = adoptArrayPtr(new uint8_t[input->width() * inp
ut->height() * info.bytesPerPixel()]); |
| 39 input->readPixels(info, dstPixels.get(), input->width() * info.bytesPerPixel
(), 0, 0); | 39 input->readPixels(info, dstPixels.get(), input->width() * info.bytesPerPixel
(), 0, 0); |
| 40 return dstPixels.release(); | 40 return dstPixels; |
| 41 } | 41 } |
| 42 | 42 |
| 43 static PassRefPtr<SkImage> newSkImageFromRaster(SkImageInfo info, PassOwnPtr<uin
t8_t[]> imagePixels, int imageRowBytes) | 43 static PassRefPtr<SkImage> newSkImageFromRaster(SkImageInfo info, PassOwnPtr<uin
t8_t[]> imagePixels, int imageRowBytes) |
| 44 { | 44 { |
| 45 return adoptRef(SkImage::NewFromRaster(info, imagePixels.leakPtr(), imageRow
Bytes, | 45 return adoptRef(SkImage::NewFromRaster(info, imagePixels.leakPtr(), imageRow
Bytes, |
| 46 [](const void* pixels, void*) | 46 [](const void* pixels, void*) |
| 47 { | 47 { |
| 48 delete[] static_cast<const uint8_t*>(pixels); | 48 delete[] static_cast<const uint8_t*>(pixels); |
| 49 }, nullptr)); | 49 }, nullptr)); |
| 50 } | 50 } |
| (...skipping 23 matching lines...) Expand all Loading... |
| 74 int height = input->height(); | 74 int height = input->height(); |
| 75 SkImageInfo info = SkImageInfo::MakeN32(width, height, (alphaOp == Premultip
lyAlpha) ? kPremul_SkAlphaType : kUnpremul_SkAlphaType); | 75 SkImageInfo info = SkImageInfo::MakeN32(width, height, (alphaOp == Premultip
lyAlpha) ? kPremul_SkAlphaType : kUnpremul_SkAlphaType); |
| 76 int imageRowBytes = width * info.bytesPerPixel(); | 76 int imageRowBytes = width * info.bytesPerPixel(); |
| 77 OwnPtr<uint8_t[]> imagePixels = copySkImageData(input, info); | 77 OwnPtr<uint8_t[]> imagePixels = copySkImageData(input, info); |
| 78 for (int i = 0; i < height / 2; i++) { | 78 for (int i = 0; i < height / 2; i++) { |
| 79 int topFirstElement = i * imageRowBytes; | 79 int topFirstElement = i * imageRowBytes; |
| 80 int topLastElement = (i + 1) * imageRowBytes; | 80 int topLastElement = (i + 1) * imageRowBytes; |
| 81 int bottomFirstElement = (height - 1 - i) * imageRowBytes; | 81 int bottomFirstElement = (height - 1 - i) * imageRowBytes; |
| 82 std::swap_ranges(imagePixels.get() + topFirstElement, imagePixels.get()
+ topLastElement, imagePixels.get() + bottomFirstElement); | 82 std::swap_ranges(imagePixels.get() + topFirstElement, imagePixels.get()
+ topLastElement, imagePixels.get() + bottomFirstElement); |
| 83 } | 83 } |
| 84 return newSkImageFromRaster(info, imagePixels.release(), imageRowBytes); | 84 return newSkImageFromRaster(info, std::move(imagePixels), imageRowBytes); |
| 85 } | 85 } |
| 86 | 86 |
| 87 static PassRefPtr<SkImage> premulSkImageToUnPremul(SkImage* input) | 87 static PassRefPtr<SkImage> premulSkImageToUnPremul(SkImage* input) |
| 88 { | 88 { |
| 89 SkImageInfo info = SkImageInfo::Make(input->width(), input->height(), kN32_S
kColorType, kUnpremul_SkAlphaType); | 89 SkImageInfo info = SkImageInfo::Make(input->width(), input->height(), kN32_S
kColorType, kUnpremul_SkAlphaType); |
| 90 OwnPtr<uint8_t[]> dstPixels = copySkImageData(input, info); | 90 OwnPtr<uint8_t[]> dstPixels = copySkImageData(input, info); |
| 91 return newSkImageFromRaster(info, dstPixels.release(), input->width() * info
.bytesPerPixel()); | 91 return newSkImageFromRaster(info, std::move(dstPixels), input->width() * inf
o.bytesPerPixel()); |
| 92 } | 92 } |
| 93 | 93 |
| 94 PassRefPtr<SkImage> ImageBitmap::getSkImageFromDecoder(PassOwnPtr<ImageDecoder>
decoder) | 94 PassRefPtr<SkImage> ImageBitmap::getSkImageFromDecoder(PassOwnPtr<ImageDecoder>
decoder) |
| 95 { | 95 { |
| 96 if (!decoder->frameCount()) | 96 if (!decoder->frameCount()) |
| 97 return nullptr; | 97 return nullptr; |
| 98 ImageFrame* frame = decoder->frameBufferAtIndex(0); | 98 ImageFrame* frame = decoder->frameBufferAtIndex(0); |
| 99 if (!frame || frame->getStatus() != ImageFrame::FrameComplete) | 99 if (!frame || frame->getStatus() != ImageFrame::FrameComplete) |
| 100 return nullptr; | 100 return nullptr; |
| 101 SkBitmap bitmap = frame->bitmap(); | 101 SkBitmap bitmap = frame->bitmap(); |
| (...skipping 10 matching lines...) Expand all Loading... |
| 112 ASSERT(image); | 112 ASSERT(image); |
| 113 | 113 |
| 114 IntRect imgRect(IntPoint(), IntSize(image->width(), image->height())); | 114 IntRect imgRect(IntPoint(), IntSize(image->width(), image->height())); |
| 115 const IntRect srcRect = intersection(imgRect, cropRect); | 115 const IntRect srcRect = intersection(imgRect, cropRect); |
| 116 | 116 |
| 117 // In the case when cropRect doesn't intersect the source image and it requi
res a umpremul image | 117 // In the case when cropRect doesn't intersect the source image and it requi
res a umpremul image |
| 118 // We immediately return a transparent black image with cropRect.size() | 118 // We immediately return a transparent black image with cropRect.size() |
| 119 if (srcRect.isEmpty() && !premultiplyAlpha) { | 119 if (srcRect.isEmpty() && !premultiplyAlpha) { |
| 120 SkImageInfo info = SkImageInfo::Make(cropRect.width(), cropRect.height()
, kN32_SkColorType, kUnpremul_SkAlphaType); | 120 SkImageInfo info = SkImageInfo::Make(cropRect.width(), cropRect.height()
, kN32_SkColorType, kUnpremul_SkAlphaType); |
| 121 OwnPtr<uint8_t[]> dstPixels = adoptArrayPtr(new uint8_t[cropRect.width()
* cropRect.height() * info.bytesPerPixel()]()); | 121 OwnPtr<uint8_t[]> dstPixels = adoptArrayPtr(new uint8_t[cropRect.width()
* cropRect.height() * info.bytesPerPixel()]()); |
| 122 return StaticBitmapImage::create(newSkImageFromRaster(info, dstPixels.re
lease(), cropRect.width() * info.bytesPerPixel())); | 122 return StaticBitmapImage::create(newSkImageFromRaster(info, std::move(ds
tPixels), cropRect.width() * info.bytesPerPixel())); |
| 123 } | 123 } |
| 124 | 124 |
| 125 RefPtr<SkImage> skiaImage = image->imageForCurrentFrame(); | 125 RefPtr<SkImage> skiaImage = image->imageForCurrentFrame(); |
| 126 // Attempt to get raw unpremultiplied image data, executed only when skiaIma
ge is premultiplied. | 126 // Attempt to get raw unpremultiplied image data, executed only when skiaIma
ge is premultiplied. |
| 127 if ((((!premultiplyAlpha && !skiaImage->isOpaque()) || !skiaImage) && image-
>data() && imageFormat == DontPremultiplyAlpha) || colorSpaceOp == ImageDecoder:
:GammaAndColorProfileIgnored) { | 127 if ((((!premultiplyAlpha && !skiaImage->isOpaque()) || !skiaImage) && image-
>data() && imageFormat == DontPremultiplyAlpha) || colorSpaceOp == ImageDecoder:
:GammaAndColorProfileIgnored) { |
| 128 OwnPtr<ImageDecoder> decoder(ImageDecoder::create(*(image->data()), | 128 OwnPtr<ImageDecoder> decoder(ImageDecoder::create(*(image->data()), |
| 129 premultiplyAlpha ? ImageDecoder::AlphaPremultiplied : ImageDecoder::
AlphaNotPremultiplied, | 129 premultiplyAlpha ? ImageDecoder::AlphaPremultiplied : ImageDecoder::
AlphaNotPremultiplied, |
| 130 colorSpaceOp)); | 130 colorSpaceOp)); |
| 131 if (!decoder) | 131 if (!decoder) |
| 132 return nullptr; | 132 return nullptr; |
| 133 decoder->setData(image->data(), true); | 133 decoder->setData(image->data(), true); |
| 134 skiaImage = ImageBitmap::getSkImageFromDecoder(decoder.release()); | 134 skiaImage = ImageBitmap::getSkImageFromDecoder(std::move(decoder)); |
| 135 if (!skiaImage) | 135 if (!skiaImage) |
| 136 return nullptr; | 136 return nullptr; |
| 137 } | 137 } |
| 138 | 138 |
| 139 if (cropRect == srcRect) { | 139 if (cropRect == srcRect) { |
| 140 if (flipY) | 140 if (flipY) |
| 141 return StaticBitmapImage::create(flipSkImageVertically(skiaImage->ne
wSubset(srcRect), premultiplyAlpha ? PremultiplyAlpha : DontPremultiplyAlpha)); | 141 return StaticBitmapImage::create(flipSkImageVertically(skiaImage->ne
wSubset(srcRect), premultiplyAlpha ? PremultiplyAlpha : DontPremultiplyAlpha)); |
| 142 SkImage* croppedSkImage = skiaImage->newSubset(srcRect); | 142 SkImage* croppedSkImage = skiaImage->newSubset(srcRect); |
| 143 // Call preroll to trigger image decoding. | 143 // Call preroll to trigger image decoding. |
| 144 croppedSkImage->preroll(); | 144 croppedSkImage->preroll(); |
| (...skipping 136 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 281 for (int j = 0; j < srcEndCopyPosition - srcStartCopyPositio
n; j++) { | 281 for (int j = 0; j < srcEndCopyPosition - srcStartCopyPositio
n; j++) { |
| 282 if (j % 4 == 0) | 282 if (j % 4 == 0) |
| 283 copiedDataBuffer[dstStartCopyPosition + j] = srcAddr
[srcStartCopyPosition + j + 2]; | 283 copiedDataBuffer[dstStartCopyPosition + j] = srcAddr
[srcStartCopyPosition + j + 2]; |
| 284 else if (j % 4 == 2) | 284 else if (j % 4 == 2) |
| 285 copiedDataBuffer[dstStartCopyPosition + j] = srcAddr
[srcStartCopyPosition + j - 2]; | 285 copiedDataBuffer[dstStartCopyPosition + j] = srcAddr
[srcStartCopyPosition + j - 2]; |
| 286 else | 286 else |
| 287 copiedDataBuffer[dstStartCopyPosition + j] = srcAddr
[srcStartCopyPosition + j]; | 287 copiedDataBuffer[dstStartCopyPosition + j] = srcAddr
[srcStartCopyPosition + j]; |
| 288 } | 288 } |
| 289 } | 289 } |
| 290 } | 290 } |
| 291 m_image = StaticBitmapImage::create(newSkImageFromRaster(info, copie
dDataBuffer.release(), dstPixelBytesPerRow)); | 291 m_image = StaticBitmapImage::create(newSkImageFromRaster(info, std::
move(copiedDataBuffer), dstPixelBytesPerRow)); |
| 292 } | 292 } |
| 293 m_image->setPremultiplied(premultiplyAlpha); | 293 m_image->setPremultiplied(premultiplyAlpha); |
| 294 return; | 294 return; |
| 295 } | 295 } |
| 296 | 296 |
| 297 OwnPtr<ImageBuffer> buffer = ImageBuffer::create(cropRect.size(), NonOpaque,
DoNotInitializeImagePixels); | 297 OwnPtr<ImageBuffer> buffer = ImageBuffer::create(cropRect.size(), NonOpaque,
DoNotInitializeImagePixels); |
| 298 if (!buffer) | 298 if (!buffer) |
| 299 return; | 299 return; |
| 300 | 300 |
| 301 if (srcRect.isEmpty()) { | 301 if (srcRect.isEmpty()) { |
| (...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 407 // static | 407 // static |
| 408 ImageBitmap* ImageBitmap::take(ScriptPromiseResolver*, sk_sp<SkImage> image) | 408 ImageBitmap* ImageBitmap::take(ScriptPromiseResolver*, sk_sp<SkImage> image) |
| 409 { | 409 { |
| 410 return ImageBitmap::create(StaticBitmapImage::create(fromSkSp(image))); | 410 return ImageBitmap::create(StaticBitmapImage::create(fromSkSp(image))); |
| 411 } | 411 } |
| 412 | 412 |
| 413 PassOwnPtr<uint8_t[]> ImageBitmap::copyBitmapData(AlphaDisposition alphaOp) | 413 PassOwnPtr<uint8_t[]> ImageBitmap::copyBitmapData(AlphaDisposition alphaOp) |
| 414 { | 414 { |
| 415 SkImageInfo info = SkImageInfo::Make(width(), height(), kRGBA_8888_SkColorTy
pe, (alphaOp == PremultiplyAlpha) ? kPremul_SkAlphaType : kUnpremul_SkAlphaType)
; | 415 SkImageInfo info = SkImageInfo::Make(width(), height(), kRGBA_8888_SkColorTy
pe, (alphaOp == PremultiplyAlpha) ? kPremul_SkAlphaType : kUnpremul_SkAlphaType)
; |
| 416 OwnPtr<uint8_t[]> dstPixels = copySkImageData(m_image->imageForCurrentFrame(
).get(), info); | 416 OwnPtr<uint8_t[]> dstPixels = copySkImageData(m_image->imageForCurrentFrame(
).get(), info); |
| 417 return dstPixels.release(); | 417 return dstPixels; |
| 418 } | 418 } |
| 419 | 419 |
| 420 unsigned long ImageBitmap::width() const | 420 unsigned long ImageBitmap::width() const |
| 421 { | 421 { |
| 422 if (!m_image) | 422 if (!m_image) |
| 423 return 0; | 423 return 0; |
| 424 ASSERT(m_image->width() > 0); | 424 ASSERT(m_image->width() > 0); |
| 425 return m_image->width(); | 425 return m_image->width(); |
| 426 } | 426 } |
| 427 | 427 |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 479 FloatSize ImageBitmap::elementSize(const FloatSize&) const | 479 FloatSize ImageBitmap::elementSize(const FloatSize&) const |
| 480 { | 480 { |
| 481 return FloatSize(width(), height()); | 481 return FloatSize(width(), height()); |
| 482 } | 482 } |
| 483 | 483 |
| 484 DEFINE_TRACE(ImageBitmap) | 484 DEFINE_TRACE(ImageBitmap) |
| 485 { | 485 { |
| 486 } | 486 } |
| 487 | 487 |
| 488 } // namespace blink | 488 } // namespace blink |
| OLD | NEW |