Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(244)

Unified Diff: third_party/WebKit/Source/core/frame/ImageBitmap.cpp

Issue 2035113002: Implement ImageBitmapOptions resize (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: address comments Created 4 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: third_party/WebKit/Source/core/frame/ImageBitmap.cpp
diff --git a/third_party/WebKit/Source/core/frame/ImageBitmap.cpp b/third_party/WebKit/Source/core/frame/ImageBitmap.cpp
index bbfdb51187538d9e1064c0f78539065dd981ee6c..70c271251e41b316f7924cd1518d4ef2253c299b 100644
--- a/third_party/WebKit/Source/core/frame/ImageBitmap.cpp
+++ b/third_party/WebKit/Source/core/frame/ImageBitmap.cpp
@@ -20,6 +20,18 @@ namespace blink {
static const char* imageOrientationFlipY = "flipY";
static const char* imageBitmapOptionNone = "none";
+namespace {
+
+struct ParsedOptions {
+ bool flipY = false;
+ bool premultiplyAlpha = true;
+ bool shouldScaleInput = false;
+ unsigned resizeWidth = 0;
+ unsigned resizeHeight = 0;
+ IntRect cropRect;
+ SkFilterQuality resizeQuality = kLow_SkFilterQuality;
+};
+
// The following two functions are helpers used in cropImage
static inline IntRect normalizeRect(const IntRect& rect)
{
@@ -35,6 +47,61 @@ static bool frameIsValid(const SkBitmap& frameBitmap)
return frameBitmap.colorType() == kN32_SkColorType;
}
+ParsedOptions parseOptions(const ImageBitmapOptions& options, Optional<IntRect> cropRect, IntSize sourceSize)
+{
+ ParsedOptions parsedOptions;
+ if (options.imageOrientation() == imageOrientationFlipY) {
+ parsedOptions.flipY = true;
+ } else {
+ parsedOptions.flipY = false;
+ DCHECK(options.imageOrientation() == imageBitmapOptionNone);
+ }
+ if (options.premultiplyAlpha() == imageBitmapOptionNone) {
+ parsedOptions.premultiplyAlpha = false;
+ } else {
+ parsedOptions.premultiplyAlpha = true;
+ DCHECK(options.premultiplyAlpha() == "default" || options.premultiplyAlpha() == "premultiply");
+ }
+
+ int sourceWidth = sourceSize.width();
+ int sourceHeight = sourceSize.height();
+ if (!options.hasResizeWidth() && !options.hasResizeHeight()) {
+ parsedOptions.resizeWidth = sourceWidth;
+ parsedOptions.resizeHeight = sourceHeight;
+ } else if (options.hasResizeWidth() && options.hasResizeHeight()) {
+ parsedOptions.resizeWidth = options.resizeWidth();
+ parsedOptions.resizeHeight = options.resizeHeight();
+ } else if (options.hasResizeWidth() && !options.hasResizeHeight()) {
+ parsedOptions.resizeWidth = options.resizeWidth();
+ parsedOptions.resizeHeight = ceil(static_cast<float>(options.resizeWidth()) / sourceWidth * sourceHeight);
+ } else {
+ parsedOptions.resizeHeight = options.resizeHeight();
+ parsedOptions.resizeWidth = ceil(static_cast<float>(options.resizeHeight()) / sourceHeight * sourceWidth);
+ }
+ if (!cropRect) {
+ parsedOptions.cropRect = IntRect(0, 0, parsedOptions.resizeWidth, parsedOptions.resizeHeight);
+ } else {
+ parsedOptions.cropRect = normalizeRect(*cropRect);
+ }
+ if (static_cast<int>(parsedOptions.resizeWidth) == sourceWidth && static_cast<int>(parsedOptions.resizeHeight) == sourceHeight) {
+ parsedOptions.shouldScaleInput = false;
+ return parsedOptions;
+ }
+ parsedOptions.shouldScaleInput = true;
+
+ if (options.resizeQuality() == "high")
+ parsedOptions.resizeQuality = kHigh_SkFilterQuality;
+ else if (options.resizeQuality() == "medium")
+ parsedOptions.resizeQuality = kMedium_SkFilterQuality;
+ else if (options.resizeQuality() == "pixelated")
+ parsedOptions.resizeQuality = kNone_SkFilterQuality;
+ else
+ parsedOptions.resizeQuality = kLow_SkFilterQuality;
+ return parsedOptions;
+}
+
+} // namespace
+
static std::unique_ptr<uint8_t[]> copySkImageData(SkImage* input, const SkImageInfo& info)
{
std::unique_ptr<uint8_t[]> dstPixels = wrapArrayUnique(new uint8_t[input->width() * input->height() * info.bytesPerPixel()]);
@@ -113,30 +180,48 @@ PassRefPtr<SkImage> ImageBitmap::getSkImageFromDecoder(std::unique_ptr<ImageDeco
return fromSkSp(SkImage::MakeFromBitmap(bitmap));
}
+bool ImageBitmap::isResizeOptionValid(const ImageBitmapOptions& options, ExceptionState& exceptionState)
+{
+ if ((options.hasResizeWidth() && options.resizeWidth() == 0) || (options.hasResizeHeight() && options.resizeHeight() == 0)) {
+ exceptionState.throwDOMException(InvalidStateError, "The resizeWidth or/and resizeHeight is equal to 0.");
+ return false;
+ }
+ return true;
+}
+
+bool ImageBitmap::isSourceSizeValid(int sourceWidth, int sourceHeight, ExceptionState& exceptionState)
+{
+ if (!sourceWidth || !sourceHeight) {
+ exceptionState.throwDOMException(IndexSizeError, String::format("The source %s provided is 0.", sourceWidth ? "height" : "width"));
+ return false;
+ }
+ return true;
+}
+
// The parameter imageFormat indicates whether the first parameter "image" is unpremultiplied or not.
// imageFormat = PremultiplyAlpha means the image is in premuliplied format
// For example, if the image is already in unpremultiplied format and we want the created ImageBitmap
// in the same format, then we don't need to use the ImageDecoder to decode the image.
-static PassRefPtr<StaticBitmapImage> cropImage(Image* image, const IntRect& cropRect, bool flipY, bool premultiplyAlpha, AlphaDisposition imageFormat = PremultiplyAlpha, ImageDecoder::GammaAndColorProfileOption colorSpaceOp = ImageDecoder::GammaAndColorProfileApplied)
+static PassRefPtr<StaticBitmapImage> cropImage(Image* image, const ParsedOptions& parsedOptions, AlphaDisposition imageFormat = PremultiplyAlpha, ImageDecoder::GammaAndColorProfileOption colorSpaceOp = ImageDecoder::GammaAndColorProfileApplied)
{
ASSERT(image);
IntRect imgRect(IntPoint(), IntSize(image->width(), image->height()));
- const IntRect srcRect = intersection(imgRect, cropRect);
+ const IntRect srcRect = intersection(imgRect, parsedOptions.cropRect);
// In the case when cropRect doesn't intersect the source image and it requires a umpremul image
// We immediately return a transparent black image with cropRect.size()
- if (srcRect.isEmpty() && !premultiplyAlpha) {
- SkImageInfo info = SkImageInfo::Make(cropRect.width(), cropRect.height(), kN32_SkColorType, kUnpremul_SkAlphaType);
- std::unique_ptr<uint8_t[]> dstPixels = wrapArrayUnique(new uint8_t[cropRect.width() * cropRect.height() * info.bytesPerPixel()]());
- return StaticBitmapImage::create(newSkImageFromRaster(info, std::move(dstPixels), cropRect.width() * info.bytesPerPixel()));
+ if (srcRect.isEmpty() && !parsedOptions.premultiplyAlpha) {
+ SkImageInfo info = SkImageInfo::Make(parsedOptions.cropRect.width(), parsedOptions.cropRect.height(), kN32_SkColorType, kUnpremul_SkAlphaType);
+ std::unique_ptr<uint8_t[]> dstPixels = wrapArrayUnique(new uint8_t[parsedOptions.cropRect.width() * parsedOptions.cropRect.height() * info.bytesPerPixel()]());
+ return StaticBitmapImage::create(newSkImageFromRaster(info, std::move(dstPixels), parsedOptions.cropRect.width() * info.bytesPerPixel()));
}
RefPtr<SkImage> skiaImage = image->imageForCurrentFrame();
// Attempt to get raw unpremultiplied image data, executed only when skiaImage is premultiplied.
- if ((((!premultiplyAlpha && !skiaImage->isOpaque()) || !skiaImage) && image->data() && imageFormat == PremultiplyAlpha) || colorSpaceOp == ImageDecoder::GammaAndColorProfileIgnored) {
+ if ((((!parsedOptions.premultiplyAlpha && !skiaImage->isOpaque()) || !skiaImage) && image->data() && imageFormat == PremultiplyAlpha) || colorSpaceOp == ImageDecoder::GammaAndColorProfileIgnored) {
std::unique_ptr<ImageDecoder> decoder(ImageDecoder::create(*(image->data()),
- premultiplyAlpha ? ImageDecoder::AlphaPremultiplied : ImageDecoder::AlphaNotPremultiplied,
+ parsedOptions.premultiplyAlpha ? ImageDecoder::AlphaPremultiplied : ImageDecoder::AlphaNotPremultiplied,
colorSpaceOp));
if (!decoder)
return nullptr;
@@ -146,36 +231,43 @@ static PassRefPtr<StaticBitmapImage> cropImage(Image* image, const IntRect& crop
return nullptr;
}
- if (cropRect == srcRect) {
+ if (parsedOptions.cropRect == srcRect) {
RefPtr<SkImage> croppedSkImage = fromSkSp(skiaImage->makeSubset(srcRect));
- if (flipY)
- return StaticBitmapImage::create(flipSkImageVertically(croppedSkImage.get(), premultiplyAlpha ? PremultiplyAlpha : DontPremultiplyAlpha));
+ if (parsedOptions.flipY)
+ return StaticBitmapImage::create(flipSkImageVertically(croppedSkImage.get(), parsedOptions.premultiplyAlpha ? PremultiplyAlpha : DontPremultiplyAlpha));
// Special case: The first parameter image is unpremul but we need to turn it into premul.
- if (premultiplyAlpha && imageFormat == DontPremultiplyAlpha)
+ if (parsedOptions.premultiplyAlpha && imageFormat == DontPremultiplyAlpha)
return StaticBitmapImage::create(unPremulSkImageToPremul(croppedSkImage.get()));
// Call preroll to trigger image decoding.
croppedSkImage->preroll();
return StaticBitmapImage::create(croppedSkImage.release());
}
- sk_sp<SkSurface> surface = SkSurface::MakeRasterN32Premul(cropRect.width(), cropRect.height());
+ sk_sp<SkSurface> surface = SkSurface::MakeRasterN32Premul(parsedOptions.cropRect.width(), parsedOptions.cropRect.height());
if (!surface)
return nullptr;
if (srcRect.isEmpty())
return StaticBitmapImage::create(fromSkSp(surface->makeImageSnapshot()));
- SkScalar dstLeft = std::min(0, -cropRect.x());
- SkScalar dstTop = std::min(0, -cropRect.y());
- if (cropRect.x() < 0)
- dstLeft = -cropRect.x();
- if (cropRect.y() < 0)
- dstTop = -cropRect.y();
- surface->getCanvas()->drawImage(skiaImage.get(), dstLeft, dstTop);
+ SkScalar dstLeft = std::min(0, -parsedOptions.cropRect.x());
+ SkScalar dstTop = std::min(0, -parsedOptions.cropRect.y());
+ if (parsedOptions.cropRect.x() < 0)
+ dstLeft = -parsedOptions.cropRect.x();
+ if (parsedOptions.cropRect.y() < 0)
+ dstTop = -parsedOptions.cropRect.y();
+ if (parsedOptions.shouldScaleInput) {
+ SkRect drawDstRect = SkRect::MakeXYWH(dstLeft, dstTop, parsedOptions.resizeWidth, parsedOptions.resizeHeight);
+ SkPaint paint;
+ paint.setFilterQuality(parsedOptions.resizeQuality);
+ surface->getCanvas()->drawImageRect(skiaImage.get(), drawDstRect, &paint);
+ } else {
+ surface->getCanvas()->drawImage(skiaImage.get(), dstLeft, dstTop);
+ }
skiaImage = fromSkSp(surface->makeImageSnapshot());
- if (flipY)
+ if (parsedOptions.flipY)
skiaImage = flipSkImageVertically(skiaImage.get(), PremultiplyAlpha);
- if (premultiplyAlpha) {
+ if (parsedOptions.premultiplyAlpha) {
if (imageFormat == PremultiplyAlpha)
return StaticBitmapImage::create(unPremulSkImageToPremul(skiaImage.get()));
return StaticBitmapImage::create(skiaImage.release());
@@ -183,16 +275,15 @@ static PassRefPtr<StaticBitmapImage> cropImage(Image* image, const IntRect& crop
return StaticBitmapImage::create(premulSkImageToUnPremul(skiaImage.get()));
}
-ImageBitmap::ImageBitmap(HTMLImageElement* image, const IntRect& cropRect, Document* document, const ImageBitmapOptions& options)
+ImageBitmap::ImageBitmap(HTMLImageElement* image, Optional<IntRect> cropRect, Document* document, const ImageBitmapOptions& options)
{
- bool flipY;
- bool premultiplyAlpha;
- parseOptions(options, flipY, premultiplyAlpha);
+ RefPtr<Image> input = image->cachedImage()->getImage();
+ ParsedOptions parsedOptions = parseOptions(options, cropRect, image->bitmapSourceSize());
if (options.colorSpaceConversion() == "none")
- m_image = cropImage(image->cachedImage()->getImage(), cropRect, flipY, premultiplyAlpha, PremultiplyAlpha, ImageDecoder::GammaAndColorProfileIgnored);
+ m_image = cropImage(input.get(), parsedOptions, PremultiplyAlpha, ImageDecoder::GammaAndColorProfileIgnored);
else
- m_image = cropImage(image->cachedImage()->getImage(), cropRect, flipY, premultiplyAlpha, PremultiplyAlpha, ImageDecoder::GammaAndColorProfileApplied);
+ m_image = cropImage(input.get(), parsedOptions, PremultiplyAlpha, ImageDecoder::GammaAndColorProfileApplied);
if (!m_image)
return;
// In the case where the source image is lazy-decoded, m_image may not be in
@@ -205,57 +296,61 @@ ImageBitmap::ImageBitmap(HTMLImageElement* image, const IntRect& cropRect, Docum
m_image = StaticBitmapImage::create(fromSkSp(surface->makeImageSnapshot()));
}
m_image->setOriginClean(!image->wouldTaintOrigin(document->getSecurityOrigin()));
- m_image->setPremultiplied(premultiplyAlpha);
+ m_image->setPremultiplied(parsedOptions.premultiplyAlpha);
}
-ImageBitmap::ImageBitmap(HTMLVideoElement* video, const IntRect& cropRect, Document* document, const ImageBitmapOptions& options)
+ImageBitmap::ImageBitmap(HTMLVideoElement* video, Optional<IntRect> cropRect, Document* document, const ImageBitmapOptions& options)
{
IntSize playerSize;
if (video->webMediaPlayer())
playerSize = video->webMediaPlayer()->naturalSize();
+ // TODO(xidachen); implement the resize option.
+ ParsedOptions parsedOptions = parseOptions(options, cropRect, video->bitmapSourceSize());
+
IntRect videoRect = IntRect(IntPoint(), playerSize);
- IntRect srcRect = intersection(cropRect, videoRect);
- std::unique_ptr<ImageBuffer> buffer = ImageBuffer::create(cropRect.size(), NonOpaque, DoNotInitializeImagePixels);
+ IntRect srcRect = intersection(parsedOptions.cropRect, videoRect);
+ std::unique_ptr<ImageBuffer> buffer = ImageBuffer::create(parsedOptions.cropRect.size(), NonOpaque, DoNotInitializeImagePixels);
if (!buffer)
return;
- IntPoint dstPoint = IntPoint(std::max(0, -cropRect.x()), std::max(0, -cropRect.y()));
+ IntPoint dstPoint = IntPoint(std::max(0, -parsedOptions.cropRect.x()), std::max(0, -parsedOptions.cropRect.y()));
video->paintCurrentFrame(buffer->canvas(), IntRect(dstPoint, srcRect.size()), nullptr);
- bool flipY;
- bool premultiplyAlpha;
- parseOptions(options, flipY, premultiplyAlpha);
-
- if (flipY || !premultiplyAlpha) {
+ if (parsedOptions.flipY || !parsedOptions.premultiplyAlpha) {
RefPtr<SkImage> skiaImage = buffer->newSkImageSnapshot(PreferNoAcceleration, SnapshotReasonUnknown);
- if (flipY)
+ if (parsedOptions.flipY)
skiaImage = flipSkImageVertically(skiaImage.get(), PremultiplyAlpha);
- if (!premultiplyAlpha)
+ if (!parsedOptions.premultiplyAlpha)
skiaImage = premulSkImageToUnPremul(skiaImage.get());
m_image = StaticBitmapImage::create(skiaImage.release());
} else {
m_image = StaticBitmapImage::create(buffer->newSkImageSnapshot(PreferNoAcceleration, SnapshotReasonUnknown));
}
m_image->setOriginClean(!video->wouldTaintOrigin(document->getSecurityOrigin()));
- m_image->setPremultiplied(premultiplyAlpha);
+ m_image->setPremultiplied(parsedOptions.premultiplyAlpha);
}
-ImageBitmap::ImageBitmap(HTMLCanvasElement* canvas, const IntRect& cropRect, const ImageBitmapOptions& options)
+ImageBitmap::ImageBitmap(HTMLCanvasElement* canvas, Optional<IntRect> cropRect, const ImageBitmapOptions& options)
{
ASSERT(canvas->isPaintable());
- bool flipY;
- bool premultiplyAlpha;
- parseOptions(options, flipY, premultiplyAlpha);
+ RefPtr<Image> input = canvas->copiedImage(BackBuffer, PreferAcceleration);
+ ParsedOptions parsedOptions = parseOptions(options, cropRect, canvas->bitmapSourceSize());
- // canvas is always premultiplied, so set the last parameter to true and convert to un-premul later
- m_image = cropImage(canvas->copiedImage(BackBuffer, PreferAcceleration).get(), cropRect, flipY, true);
+ bool isPremultiplyAlphaReverted = false;
+ if (!parsedOptions.premultiplyAlpha) {
+ parsedOptions.premultiplyAlpha = true;
+ isPremultiplyAlphaReverted = true;
+ }
+ m_image = cropImage(input.get(), parsedOptions);
if (!m_image)
return;
- if (!premultiplyAlpha)
+ if (isPremultiplyAlphaReverted) {
+ parsedOptions.premultiplyAlpha = false;
m_image = StaticBitmapImage::create(premulSkImageToUnPremul(m_image->imageForCurrentFrame().get()));
+ }
m_image->setOriginClean(canvas->originClean());
- m_image->setPremultiplied(premultiplyAlpha);
+ m_image->setPremultiplied(parsedOptions.premultiplyAlpha);
}
ImageBitmap::ImageBitmap(std::unique_ptr<uint8_t[]> data, uint32_t width, uint32_t height, bool isImageBitmapPremultiplied, bool isImageBitmapOriginClean)
@@ -266,44 +361,44 @@ ImageBitmap::ImageBitmap(std::unique_ptr<uint8_t[]> data, uint32_t width, uint32
m_image->setOriginClean(isImageBitmapOriginClean);
}
-ImageBitmap::ImageBitmap(ImageData* data, const IntRect& cropRect, const ImageBitmapOptions& options)
+ImageBitmap::ImageBitmap(ImageData* data, Optional<IntRect> cropRect, const ImageBitmapOptions& options)
{
- bool flipY;
- bool premultiplyAlpha;
- parseOptions(options, flipY, premultiplyAlpha);
- IntRect srcRect = intersection(cropRect, IntRect(IntPoint(), data->size()));
+ // TODO(xidachen): implement the resize option
+ IntRect dataSrcRect = IntRect(IntPoint(), data->size());
+ ParsedOptions parsedOptions = parseOptions(options, cropRect, data->bitmapSourceSize());
+ IntRect srcRect = cropRect ? intersection(parsedOptions.cropRect, dataSrcRect) : dataSrcRect;
// treat non-premultiplyAlpha as a special case
- if (!premultiplyAlpha) {
+ if (!parsedOptions.premultiplyAlpha) {
unsigned char* srcAddr = data->data()->data();
int srcHeight = data->size().height();
- int dstHeight = cropRect.height();
+ int dstHeight = parsedOptions.cropRect.height();
// TODO (xidachen): skia doesn't support SkImage::NewRasterCopy from a kRGBA color type.
// For now, we swap R and B channel and uses kBGRA color type.
- SkImageInfo info = SkImageInfo::Make(cropRect.width(), dstHeight, kBGRA_8888_SkColorType, kUnpremul_SkAlphaType);
+ SkImageInfo info = SkImageInfo::Make(parsedOptions.cropRect.width(), dstHeight, kBGRA_8888_SkColorType, kUnpremul_SkAlphaType);
int srcPixelBytesPerRow = info.bytesPerPixel() * data->size().width();
- int dstPixelBytesPerRow = info.bytesPerPixel() * cropRect.width();
- if (cropRect == IntRect(IntPoint(), data->size())) {
- swizzleImageData(srcAddr, srcHeight, srcPixelBytesPerRow, flipY);
+ int dstPixelBytesPerRow = info.bytesPerPixel() * parsedOptions.cropRect.width();
+ if (parsedOptions.cropRect == IntRect(IntPoint(), data->size())) {
+ swizzleImageData(srcAddr, srcHeight, srcPixelBytesPerRow, parsedOptions.flipY);
m_image = StaticBitmapImage::create(fromSkSp(SkImage::MakeRasterCopy(SkPixmap(info, srcAddr, dstPixelBytesPerRow))));
// restore the original ImageData
- swizzleImageData(srcAddr, srcHeight, srcPixelBytesPerRow, flipY);
+ swizzleImageData(srcAddr, srcHeight, srcPixelBytesPerRow, parsedOptions.flipY);
} else {
std::unique_ptr<uint8_t[]> copiedDataBuffer = wrapArrayUnique(new uint8_t[dstHeight * dstPixelBytesPerRow]());
if (!srcRect.isEmpty()) {
- IntPoint srcPoint = IntPoint((cropRect.x() > 0) ? cropRect.x() : 0, (cropRect.y() > 0) ? cropRect.y() : 0);
- IntPoint dstPoint = IntPoint((cropRect.x() >= 0) ? 0 : -cropRect.x(), (cropRect.y() >= 0) ? 0 : -cropRect.y());
+ IntPoint srcPoint = IntPoint((parsedOptions.cropRect.x() > 0) ? parsedOptions.cropRect.x() : 0, (parsedOptions.cropRect.y() > 0) ? parsedOptions.cropRect.y() : 0);
+ IntPoint dstPoint = IntPoint((parsedOptions.cropRect.x() >= 0) ? 0 : -parsedOptions.cropRect.x(), (parsedOptions.cropRect.y() >= 0) ? 0 : -parsedOptions.cropRect.y());
int copyHeight = srcHeight - srcPoint.y();
- if (cropRect.height() < copyHeight)
- copyHeight = cropRect.height();
+ if (parsedOptions.cropRect.height() < copyHeight)
+ copyHeight = parsedOptions.cropRect.height();
int copyWidth = data->size().width() - srcPoint.x();
- if (cropRect.width() < copyWidth)
- copyWidth = cropRect.width();
+ if (parsedOptions.cropRect.width() < copyWidth)
+ copyWidth = parsedOptions.cropRect.width();
for (int i = 0; i < copyHeight; i++) {
int srcStartCopyPosition = (i + srcPoint.y()) * srcPixelBytesPerRow + srcPoint.x() * info.bytesPerPixel();
int srcEndCopyPosition = srcStartCopyPosition + copyWidth * info.bytesPerPixel();
int dstStartCopyPosition;
- if (flipY)
+ if (parsedOptions.flipY)
dstStartCopyPosition = (dstHeight -1 - dstPoint.y() - i) * dstPixelBytesPerRow + dstPoint.x() * info.bytesPerPixel();
else
dstStartCopyPosition = (dstPoint.y() + i) * dstPixelBytesPerRow + dstPoint.x() * info.bytesPerPixel();
@@ -319,11 +414,11 @@ ImageBitmap::ImageBitmap(ImageData* data, const IntRect& cropRect, const ImageBi
}
m_image = StaticBitmapImage::create(newSkImageFromRaster(info, std::move(copiedDataBuffer), dstPixelBytesPerRow));
}
- m_image->setPremultiplied(premultiplyAlpha);
+ m_image->setPremultiplied(parsedOptions.premultiplyAlpha);
return;
}
- std::unique_ptr<ImageBuffer> buffer = ImageBuffer::create(cropRect.size(), NonOpaque, DoNotInitializeImagePixels);
+ std::unique_ptr<ImageBuffer> buffer = ImageBuffer::create(parsedOptions.cropRect.size(), NonOpaque, DoNotInitializeImagePixels);
if (!buffer)
return;
@@ -332,40 +427,43 @@ ImageBitmap::ImageBitmap(ImageData* data, const IntRect& cropRect, const ImageBi
return;
}
- IntPoint dstPoint = IntPoint(std::min(0, -cropRect.x()), std::min(0, -cropRect.y()));
- if (cropRect.x() < 0)
- dstPoint.setX(-cropRect.x());
- if (cropRect.y() < 0)
- dstPoint.setY(-cropRect.y());
+ IntPoint dstPoint = IntPoint(std::min(0, -parsedOptions.cropRect.x()), std::min(0, -parsedOptions.cropRect.y()));
+ if (parsedOptions.cropRect.x() < 0)
+ dstPoint.setX(-parsedOptions.cropRect.x());
+ if (parsedOptions.cropRect.y() < 0)
+ dstPoint.setY(-parsedOptions.cropRect.y());
buffer->putByteArray(Unmultiplied, data->data()->data(), data->size(), srcRect, dstPoint);
- if (flipY)
+ if (parsedOptions.flipY)
m_image = StaticBitmapImage::create(flipSkImageVertically(buffer->newSkImageSnapshot(PreferNoAcceleration, SnapshotReasonUnknown).get(), PremultiplyAlpha));
else
m_image = StaticBitmapImage::create(buffer->newSkImageSnapshot(PreferNoAcceleration, SnapshotReasonUnknown));
}
-ImageBitmap::ImageBitmap(ImageBitmap* bitmap, const IntRect& cropRect, const ImageBitmapOptions& options)
+ImageBitmap::ImageBitmap(ImageBitmap* bitmap, Optional<IntRect> cropRect, const ImageBitmapOptions& options)
{
- bool flipY;
- bool premultiplyAlpha;
- parseOptions(options, flipY, premultiplyAlpha);
- m_image = cropImage(bitmap->bitmapImage(), cropRect, flipY, premultiplyAlpha, bitmap->isPremultiplied() ? PremultiplyAlpha : DontPremultiplyAlpha);
+ RefPtr<Image> input = bitmap->bitmapImage();
+ if (!input)
+ return;
+ ParsedOptions parsedOptions = parseOptions(options, cropRect, input->size());
+
+ m_image = cropImage(input.get(), parsedOptions, bitmap->isPremultiplied() ? PremultiplyAlpha : DontPremultiplyAlpha);
if (!m_image)
return;
m_image->setOriginClean(bitmap->originClean());
- m_image->setPremultiplied(premultiplyAlpha);
+ m_image->setPremultiplied(parsedOptions.premultiplyAlpha);
}
-ImageBitmap::ImageBitmap(PassRefPtr<StaticBitmapImage> image, const IntRect& cropRect, const ImageBitmapOptions& options)
+ImageBitmap::ImageBitmap(PassRefPtr<StaticBitmapImage> image, Optional<IntRect> cropRect, const ImageBitmapOptions& options)
{
- bool flipY;
- bool premultiplyAlpha;
- parseOptions(options, flipY, premultiplyAlpha);
- m_image = cropImage(image.get(), cropRect, flipY, premultiplyAlpha, DontPremultiplyAlpha);
+ bool originClean = image->originClean();
+ RefPtr<Image> input = image;
+ ParsedOptions parsedOptions = parseOptions(options, cropRect, input->size());
+
+ m_image = cropImage(input.get(), parsedOptions, DontPremultiplyAlpha);
if (!m_image)
return;
- m_image->setOriginClean(image->originClean());
- m_image->setPremultiplied(premultiplyAlpha);
+ m_image->setOriginClean(originClean);
+ m_image->setPremultiplied(parsedOptions.premultiplyAlpha);
}
ImageBitmap::ImageBitmap(PassRefPtr<StaticBitmapImage> image)
@@ -389,40 +487,34 @@ ImageBitmap::~ImageBitmap()
{
}
-ImageBitmap* ImageBitmap::create(HTMLImageElement* image, const IntRect& cropRect, Document* document, const ImageBitmapOptions& options)
+ImageBitmap* ImageBitmap::create(HTMLImageElement* image, Optional<IntRect> cropRect, Document* document, const ImageBitmapOptions& options)
{
- IntRect normalizedCropRect = normalizeRect(cropRect);
- return new ImageBitmap(image, normalizedCropRect, document, options);
+ return new ImageBitmap(image, cropRect, document, options);
}
-ImageBitmap* ImageBitmap::create(HTMLVideoElement* video, const IntRect& cropRect, Document* document, const ImageBitmapOptions& options)
+ImageBitmap* ImageBitmap::create(HTMLVideoElement* video, Optional<IntRect> cropRect, Document* document, const ImageBitmapOptions& options)
{
- IntRect normalizedCropRect = normalizeRect(cropRect);
- return new ImageBitmap(video, normalizedCropRect, document, options);
+ return new ImageBitmap(video, cropRect, document, options);
}
-ImageBitmap* ImageBitmap::create(HTMLCanvasElement* canvas, const IntRect& cropRect, const ImageBitmapOptions& options)
+ImageBitmap* ImageBitmap::create(HTMLCanvasElement* canvas, Optional<IntRect> cropRect, const ImageBitmapOptions& options)
{
- IntRect normalizedCropRect = normalizeRect(cropRect);
- return new ImageBitmap(canvas, normalizedCropRect, options);
+ return new ImageBitmap(canvas, cropRect, options);
}
-ImageBitmap* ImageBitmap::create(ImageData* data, const IntRect& cropRect, const ImageBitmapOptions& options)
+ImageBitmap* ImageBitmap::create(ImageData* data, Optional<IntRect> cropRect, const ImageBitmapOptions& options)
{
- IntRect normalizedCropRect = normalizeRect(cropRect);
- return new ImageBitmap(data, normalizedCropRect, options);
+ return new ImageBitmap(data, cropRect, options);
}
-ImageBitmap* ImageBitmap::create(ImageBitmap* bitmap, const IntRect& cropRect, const ImageBitmapOptions& options)
+ImageBitmap* ImageBitmap::create(ImageBitmap* bitmap, Optional<IntRect> cropRect, const ImageBitmapOptions& options)
{
- IntRect normalizedCropRect = normalizeRect(cropRect);
- return new ImageBitmap(bitmap, normalizedCropRect, options);
+ return new ImageBitmap(bitmap, cropRect, options);
}
-ImageBitmap* ImageBitmap::create(PassRefPtr<StaticBitmapImage> image, const IntRect& cropRect, const ImageBitmapOptions& options)
+ImageBitmap* ImageBitmap::create(PassRefPtr<StaticBitmapImage> image, Optional<IntRect> cropRect, const ImageBitmapOptions& options)
{
- IntRect normalizedCropRect = normalizeRect(cropRect);
- return new ImageBitmap(image, normalizedCropRect, options);
+ return new ImageBitmap(image, cropRect, options);
}
ImageBitmap* ImageBitmap::create(PassRefPtr<StaticBitmapImage> image)
@@ -490,29 +582,14 @@ IntSize ImageBitmap::size() const
return IntSize(m_image->width(), m_image->height());
}
-ScriptPromise ImageBitmap::createImageBitmap(ScriptState* scriptState, EventTarget& eventTarget, int sx, int sy, int sw, int sh, const ImageBitmapOptions& options, ExceptionState& exceptionState)
+ScriptPromise ImageBitmap::createImageBitmap(ScriptState* scriptState, EventTarget& eventTarget, Optional<IntRect> cropRect, const ImageBitmapOptions& options, ExceptionState& exceptionState)
{
- if (!sw || !sh) {
- exceptionState.throwDOMException(IndexSizeError, String::format("The source %s provided is 0.", sw ? "height" : "width"));
+ if ((cropRect && !isSourceSizeValid(cropRect->width(), cropRect->height(), exceptionState))
+ || !isSourceSizeValid(width(), height(), exceptionState))
return ScriptPromise();
- }
- return ImageBitmapSource::fulfillImageBitmap(scriptState, create(this, IntRect(sx, sy, sw, sh), options));
-}
-
-void ImageBitmap::parseOptions(const ImageBitmapOptions& options, bool& flipY, bool& premultiplyAlpha)
-{
- if (options.imageOrientation() == imageOrientationFlipY) {
- flipY = true;
- } else {
- flipY = false;
- ASSERT(options.imageOrientation() == imageBitmapOptionNone);
- }
- if (options.premultiplyAlpha() == imageBitmapOptionNone) {
- premultiplyAlpha = false;
- } else {
- premultiplyAlpha = true;
- ASSERT(options.premultiplyAlpha() == "default" || options.premultiplyAlpha() == "premultiply");
- }
+ if (!isResizeOptionValid(options, exceptionState))
+ return ScriptPromise();
+ return ImageBitmapSource::fulfillImageBitmap(scriptState, create(this, cropRect, options));
}
PassRefPtr<Image> ImageBitmap::getSourceImageForCanvas(SourceImageStatus* status, AccelerationHint, SnapshotReason, const FloatSize&) const
« no previous file with comments | « third_party/WebKit/Source/core/frame/ImageBitmap.h ('k') | third_party/WebKit/Source/core/frame/ImageBitmapTest.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698