| 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 345 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 356 } | 356 } |
| 357 | 357 |
| 358 ImageBitmap::ImageBitmap(std::unique_ptr<uint8_t[]> data, uint32_t width, uint32
_t height, bool isImageBitmapPremultiplied, bool isImageBitmapOriginClean) | 358 ImageBitmap::ImageBitmap(std::unique_ptr<uint8_t[]> data, uint32_t width, uint32
_t height, bool isImageBitmapPremultiplied, bool isImageBitmapOriginClean) |
| 359 { | 359 { |
| 360 SkImageInfo info = SkImageInfo::MakeN32(width, height, isImageBitmapPremulti
plied ? kPremul_SkAlphaType : kUnpremul_SkAlphaType); | 360 SkImageInfo info = SkImageInfo::MakeN32(width, height, isImageBitmapPremulti
plied ? kPremul_SkAlphaType : kUnpremul_SkAlphaType); |
| 361 m_image = StaticBitmapImage::create(fromSkSp(SkImage::MakeRasterCopy(SkPixma
p(info, data.get(), info.bytesPerPixel() * width)))); | 361 m_image = StaticBitmapImage::create(fromSkSp(SkImage::MakeRasterCopy(SkPixma
p(info, data.get(), info.bytesPerPixel() * width)))); |
| 362 m_image->setPremultiplied(isImageBitmapPremultiplied); | 362 m_image->setPremultiplied(isImageBitmapPremultiplied); |
| 363 m_image->setOriginClean(isImageBitmapOriginClean); | 363 m_image->setOriginClean(isImageBitmapOriginClean); |
| 364 } | 364 } |
| 365 | 365 |
| 366 static PassRefPtr<SkImage> scaleSkImage(PassRefPtr<SkImage> skImage, unsigned re
sizeWidth, unsigned resizeHeight, SkFilterQuality resizeQuality) |
| 367 { |
| 368 SkImageInfo resizedInfo = SkImageInfo::Make(resizeWidth, resizeHeight, kN32_
SkColorType, kUnpremul_SkAlphaType); |
| 369 std::unique_ptr<uint8_t[]> resizedPixels = wrapArrayUnique(new uint8_t[resiz
eWidth * resizeHeight * resizedInfo.bytesPerPixel()]); |
| 370 SkPixmap pixmap(resizedInfo, resizedPixels.release(), resizeWidth * resizedI
nfo.bytesPerPixel()); |
| 371 skImage->scalePixels(pixmap, resizeQuality); |
| 372 return fromSkSp(SkImage::MakeFromRaster(pixmap, [](const void* pixels, void*
) |
| 373 { |
| 374 delete[] static_cast<const uint8_t*>(pixels); |
| 375 }, nullptr)); |
| 376 } |
| 377 |
| 366 ImageBitmap::ImageBitmap(ImageData* data, Optional<IntRect> cropRect, const Imag
eBitmapOptions& options) | 378 ImageBitmap::ImageBitmap(ImageData* data, Optional<IntRect> cropRect, const Imag
eBitmapOptions& options) |
| 367 { | 379 { |
| 368 // TODO(xidachen): implement the resize option | 380 // TODO(xidachen): implement the resize option |
| 369 IntRect dataSrcRect = IntRect(IntPoint(), data->size()); | 381 IntRect dataSrcRect = IntRect(IntPoint(), data->size()); |
| 370 ParsedOptions parsedOptions = parseOptions(options, cropRect, data->bitmapSo
urceSize()); | 382 ParsedOptions parsedOptions = parseOptions(options, cropRect, data->bitmapSo
urceSize()); |
| 371 IntRect srcRect = cropRect ? intersection(parsedOptions.cropRect, dataSrcRec
t) : dataSrcRect; | 383 IntRect srcRect = cropRect ? intersection(parsedOptions.cropRect, dataSrcRec
t) : dataSrcRect; |
| 372 | 384 |
| 373 // treat non-premultiplyAlpha as a special case | 385 // treat non-premultiplyAlpha as a special case |
| 374 if (!parsedOptions.premultiplyAlpha) { | 386 if (!parsedOptions.premultiplyAlpha) { |
| 375 unsigned char* srcAddr = data->data()->data(); | 387 unsigned char* srcAddr = data->data()->data(); |
| 376 int srcHeight = data->size().height(); | 388 int srcHeight = data->size().height(); |
| 377 int dstHeight = parsedOptions.cropRect.height(); | 389 int dstHeight = parsedOptions.cropRect.height(); |
| 378 // TODO (xidachen): skia doesn't support SkImage::NewRasterCopy from a k
RGBA color type. | 390 |
| 379 // For now, we swap R and B channel and uses kBGRA color type. | 391 // Using kN32 type, swizzle input if necessary. |
| 380 SkImageInfo info = SkImageInfo::Make(parsedOptions.cropRect.width(), dst
Height, kBGRA_8888_SkColorType, kUnpremul_SkAlphaType); | 392 SkImageInfo info = SkImageInfo::Make(parsedOptions.cropRect.width(), dst
Height, kN32_SkColorType, kUnpremul_SkAlphaType); |
| 381 int srcPixelBytesPerRow = info.bytesPerPixel() * data->size().width(); | 393 int srcPixelBytesPerRow = info.bytesPerPixel() * data->size().width(); |
| 382 int dstPixelBytesPerRow = info.bytesPerPixel() * parsedOptions.cropRect.
width(); | 394 int dstPixelBytesPerRow = info.bytesPerPixel() * parsedOptions.cropRect.
width(); |
| 395 RefPtr<SkImage> skImage; |
| 383 if (parsedOptions.cropRect == IntRect(IntPoint(), data->size())) { | 396 if (parsedOptions.cropRect == IntRect(IntPoint(), data->size())) { |
| 384 swizzleImageData(srcAddr, srcHeight, srcPixelBytesPerRow, parsedOpti
ons.flipY); | 397 if (kN32_SkColorType == kBGRA_8888_SkColorType) |
| 385 m_image = StaticBitmapImage::create(fromSkSp(SkImage::MakeRasterCopy
(SkPixmap(info, srcAddr, dstPixelBytesPerRow)))); | 398 swizzleImageData(srcAddr, srcHeight, srcPixelBytesPerRow, parsed
Options.flipY); |
| 399 skImage = fromSkSp(SkImage::MakeRasterCopy(SkPixmap(info, srcAddr, d
stPixelBytesPerRow))); |
| 386 // restore the original ImageData | 400 // restore the original ImageData |
| 387 swizzleImageData(srcAddr, srcHeight, srcPixelBytesPerRow, parsedOpti
ons.flipY); | 401 if (kN32_SkColorType == kBGRA_8888_SkColorType) |
| 402 swizzleImageData(srcAddr, srcHeight, srcPixelBytesPerRow, parsed
Options.flipY); |
| 388 } else { | 403 } else { |
| 389 std::unique_ptr<uint8_t[]> copiedDataBuffer = wrapArrayUnique(new ui
nt8_t[dstHeight * dstPixelBytesPerRow]()); | 404 std::unique_ptr<uint8_t[]> copiedDataBuffer = wrapArrayUnique(new ui
nt8_t[dstHeight * dstPixelBytesPerRow]()); |
| 390 if (!srcRect.isEmpty()) { | 405 if (!srcRect.isEmpty()) { |
| 391 IntPoint srcPoint = IntPoint((parsedOptions.cropRect.x() > 0) ?
parsedOptions.cropRect.x() : 0, (parsedOptions.cropRect.y() > 0) ? parsedOptions
.cropRect.y() : 0); | 406 IntPoint srcPoint = IntPoint((parsedOptions.cropRect.x() > 0) ?
parsedOptions.cropRect.x() : 0, (parsedOptions.cropRect.y() > 0) ? parsedOptions
.cropRect.y() : 0); |
| 392 IntPoint dstPoint = IntPoint((parsedOptions.cropRect.x() >= 0) ?
0 : -parsedOptions.cropRect.x(), (parsedOptions.cropRect.y() >= 0) ? 0 : -parse
dOptions.cropRect.y()); | 407 IntPoint dstPoint = IntPoint((parsedOptions.cropRect.x() >= 0) ?
0 : -parsedOptions.cropRect.x(), (parsedOptions.cropRect.y() >= 0) ? 0 : -parse
dOptions.cropRect.y()); |
| 393 int copyHeight = srcHeight - srcPoint.y(); | 408 int copyHeight = srcHeight - srcPoint.y(); |
| 394 if (parsedOptions.cropRect.height() < copyHeight) | 409 if (parsedOptions.cropRect.height() < copyHeight) |
| 395 copyHeight = parsedOptions.cropRect.height(); | 410 copyHeight = parsedOptions.cropRect.height(); |
| 396 int copyWidth = data->size().width() - srcPoint.x(); | 411 int copyWidth = data->size().width() - srcPoint.x(); |
| 397 if (parsedOptions.cropRect.width() < copyWidth) | 412 if (parsedOptions.cropRect.width() < copyWidth) |
| 398 copyWidth = parsedOptions.cropRect.width(); | 413 copyWidth = parsedOptions.cropRect.width(); |
| 399 for (int i = 0; i < copyHeight; i++) { | 414 for (int i = 0; i < copyHeight; i++) { |
| 400 int srcStartCopyPosition = (i + srcPoint.y()) * srcPixelByte
sPerRow + srcPoint.x() * info.bytesPerPixel(); | 415 int srcStartCopyPosition = (i + srcPoint.y()) * srcPixelByte
sPerRow + srcPoint.x() * info.bytesPerPixel(); |
| 401 int srcEndCopyPosition = srcStartCopyPosition + copyWidth *
info.bytesPerPixel(); | 416 int srcEndCopyPosition = srcStartCopyPosition + copyWidth *
info.bytesPerPixel(); |
| 402 int dstStartCopyPosition; | 417 int dstStartCopyPosition; |
| 403 if (parsedOptions.flipY) | 418 if (parsedOptions.flipY) |
| 404 dstStartCopyPosition = (dstHeight -1 - dstPoint.y() - i)
* dstPixelBytesPerRow + dstPoint.x() * info.bytesPerPixel(); | 419 dstStartCopyPosition = (dstHeight -1 - dstPoint.y() - i)
* dstPixelBytesPerRow + dstPoint.x() * info.bytesPerPixel(); |
| 405 else | 420 else |
| 406 dstStartCopyPosition = (dstPoint.y() + i) * dstPixelByte
sPerRow + dstPoint.x() * info.bytesPerPixel(); | 421 dstStartCopyPosition = (dstPoint.y() + i) * dstPixelByte
sPerRow + dstPoint.x() * info.bytesPerPixel(); |
| 407 for (int j = 0; j < srcEndCopyPosition - srcStartCopyPositio
n; j++) { | 422 for (int j = 0; j < srcEndCopyPosition - srcStartCopyPositio
n; j++) { |
| 408 if (j % 4 == 0) | 423 // swizzle when necessary |
| 409 copiedDataBuffer[dstStartCopyPosition + j] = srcAddr
[srcStartCopyPosition + j + 2]; | 424 if (kN32_SkColorType == kBGRA_8888_SkColorType) { |
| 410 else if (j % 4 == 2) | 425 if (j % 4 == 0) |
| 411 copiedDataBuffer[dstStartCopyPosition + j] = srcAddr
[srcStartCopyPosition + j - 2]; | 426 copiedDataBuffer[dstStartCopyPosition + j] = src
Addr[srcStartCopyPosition + j + 2]; |
| 412 else | 427 else if (j % 4 == 2) |
| 428 copiedDataBuffer[dstStartCopyPosition + j] = src
Addr[srcStartCopyPosition + j - 2]; |
| 429 else |
| 430 copiedDataBuffer[dstStartCopyPosition + j] = src
Addr[srcStartCopyPosition + j]; |
| 431 } else { |
| 413 copiedDataBuffer[dstStartCopyPosition + j] = srcAddr
[srcStartCopyPosition + j]; | 432 copiedDataBuffer[dstStartCopyPosition + j] = srcAddr
[srcStartCopyPosition + j]; |
| 433 } |
| 414 } | 434 } |
| 415 } | 435 } |
| 416 } | 436 } |
| 417 m_image = StaticBitmapImage::create(newSkImageFromRaster(info, std::
move(copiedDataBuffer), dstPixelBytesPerRow)); | 437 skImage = newSkImageFromRaster(info, std::move(copiedDataBuffer), ds
tPixelBytesPerRow); |
| 418 } | 438 } |
| 439 if (parsedOptions.shouldScaleInput) |
| 440 m_image = StaticBitmapImage::create(scaleSkImage(skImage, parsedOpti
ons.resizeWidth, parsedOptions.resizeHeight, parsedOptions.resizeQuality)); |
| 441 else |
| 442 m_image = StaticBitmapImage::create(skImage); |
| 419 m_image->setPremultiplied(parsedOptions.premultiplyAlpha); | 443 m_image->setPremultiplied(parsedOptions.premultiplyAlpha); |
| 420 return; | 444 return; |
| 421 } | 445 } |
| 422 | 446 |
| 423 std::unique_ptr<ImageBuffer> buffer = ImageBuffer::create(parsedOptions.crop
Rect.size(), NonOpaque, DoNotInitializeImagePixels); | 447 std::unique_ptr<ImageBuffer> buffer = ImageBuffer::create(parsedOptions.crop
Rect.size(), NonOpaque, DoNotInitializeImagePixels); |
| 424 if (!buffer) | 448 if (!buffer) |
| 425 return; | 449 return; |
| 426 | 450 |
| 427 if (srcRect.isEmpty()) { | 451 if (srcRect.isEmpty()) { |
| 428 m_image = StaticBitmapImage::create(buffer->newSkImageSnapshot(PreferNoA
cceleration, SnapshotReasonUnknown)); | 452 m_image = StaticBitmapImage::create(buffer->newSkImageSnapshot(PreferNoA
cceleration, SnapshotReasonUnknown)); |
| 429 return; | 453 return; |
| 430 } | 454 } |
| 431 | 455 |
| 432 IntPoint dstPoint = IntPoint(std::min(0, -parsedOptions.cropRect.x()), std::
min(0, -parsedOptions.cropRect.y())); | 456 IntPoint dstPoint = IntPoint(std::min(0, -parsedOptions.cropRect.x()), std::
min(0, -parsedOptions.cropRect.y())); |
| 433 if (parsedOptions.cropRect.x() < 0) | 457 if (parsedOptions.cropRect.x() < 0) |
| 434 dstPoint.setX(-parsedOptions.cropRect.x()); | 458 dstPoint.setX(-parsedOptions.cropRect.x()); |
| 435 if (parsedOptions.cropRect.y() < 0) | 459 if (parsedOptions.cropRect.y() < 0) |
| 436 dstPoint.setY(-parsedOptions.cropRect.y()); | 460 dstPoint.setY(-parsedOptions.cropRect.y()); |
| 437 buffer->putByteArray(Unmultiplied, data->data()->data(), data->size(), srcRe
ct, dstPoint); | 461 buffer->putByteArray(Unmultiplied, data->data()->data(), data->size(), srcRe
ct, dstPoint); |
| 462 RefPtr<SkImage> skImage = buffer->newSkImageSnapshot(PreferNoAcceleration, S
napshotReasonUnknown); |
| 438 if (parsedOptions.flipY) | 463 if (parsedOptions.flipY) |
| 439 m_image = StaticBitmapImage::create(flipSkImageVertically(buffer->newSkI
mageSnapshot(PreferNoAcceleration, SnapshotReasonUnknown).get(), PremultiplyAlph
a)); | 464 skImage = flipSkImageVertically(skImage.get(), PremultiplyAlpha); |
| 440 else | 465 if (parsedOptions.shouldScaleInput) { |
| 441 m_image = StaticBitmapImage::create(buffer->newSkImageSnapshot(PreferNoA
cceleration, SnapshotReasonUnknown)); | 466 sk_sp<SkSurface> surface = SkSurface::MakeRasterN32Premul(parsedOptions.
resizeWidth, parsedOptions.resizeHeight); |
| 467 if (!surface) |
| 468 return; |
| 469 SkPaint paint; |
| 470 paint.setFilterQuality(parsedOptions.resizeQuality); |
| 471 SkRect dstDrawRect = SkRect::MakeWH(parsedOptions.resizeWidth, parsedOpt
ions.resizeHeight); |
| 472 surface->getCanvas()->drawImageRect(skImage.get(), dstDrawRect, &paint); |
| 473 skImage = fromSkSp(surface->makeImageSnapshot()); |
| 474 } |
| 475 m_image = StaticBitmapImage::create(skImage); |
| 442 } | 476 } |
| 443 | 477 |
| 444 ImageBitmap::ImageBitmap(ImageBitmap* bitmap, Optional<IntRect> cropRect, const
ImageBitmapOptions& options) | 478 ImageBitmap::ImageBitmap(ImageBitmap* bitmap, Optional<IntRect> cropRect, const
ImageBitmapOptions& options) |
| 445 { | 479 { |
| 446 RefPtr<Image> input = bitmap->bitmapImage(); | 480 RefPtr<Image> input = bitmap->bitmapImage(); |
| 447 if (!input) | 481 if (!input) |
| 448 return; | 482 return; |
| 449 ParsedOptions parsedOptions = parseOptions(options, cropRect, input->size())
; | 483 ParsedOptions parsedOptions = parseOptions(options, cropRect, input->size())
; |
| 450 | 484 |
| 451 m_image = cropImage(input.get(), parsedOptions, bitmap->isPremultiplied() ?
PremultiplyAlpha : DontPremultiplyAlpha); | 485 m_image = cropImage(input.get(), parsedOptions, bitmap->isPremultiplied() ?
PremultiplyAlpha : DontPremultiplyAlpha); |
| (...skipping 155 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 607 FloatSize ImageBitmap::elementSize(const FloatSize&) const | 641 FloatSize ImageBitmap::elementSize(const FloatSize&) const |
| 608 { | 642 { |
| 609 return FloatSize(width(), height()); | 643 return FloatSize(width(), height()); |
| 610 } | 644 } |
| 611 | 645 |
| 612 DEFINE_TRACE(ImageBitmap) | 646 DEFINE_TRACE(ImageBitmap) |
| 613 { | 647 { |
| 614 } | 648 } |
| 615 | 649 |
| 616 } // namespace blink | 650 } // namespace blink |
| OLD | NEW |