Chromium Code Reviews| 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 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 58 } | 58 } |
| 59 if (options.premultiplyAlpha() == imageBitmapOptionNone) { | 59 if (options.premultiplyAlpha() == imageBitmapOptionNone) { |
| 60 parsedOptions.premultiplyAlpha = false; | 60 parsedOptions.premultiplyAlpha = false; |
| 61 } else { | 61 } else { |
| 62 parsedOptions.premultiplyAlpha = true; | 62 parsedOptions.premultiplyAlpha = true; |
| 63 DCHECK(options.premultiplyAlpha() == "default" || options.premultiplyAlp ha() == "premultiply"); | 63 DCHECK(options.premultiplyAlpha() == "default" || options.premultiplyAlp ha() == "premultiply"); |
| 64 } | 64 } |
| 65 | 65 |
| 66 int sourceWidth = sourceSize.width(); | 66 int sourceWidth = sourceSize.width(); |
| 67 int sourceHeight = sourceSize.height(); | 67 int sourceHeight = sourceSize.height(); |
| 68 if (!cropRect) { | |
| 69 parsedOptions.cropRect = IntRect(0, 0, sourceWidth, sourceHeight); | |
| 70 } else { | |
| 71 parsedOptions.cropRect = normalizeRect(*cropRect); | |
| 72 } | |
| 68 if (!options.hasResizeWidth() && !options.hasResizeHeight()) { | 73 if (!options.hasResizeWidth() && !options.hasResizeHeight()) { |
| 69 parsedOptions.resizeWidth = sourceWidth; | 74 parsedOptions.resizeWidth = parsedOptions.cropRect.width(); |
| 70 parsedOptions.resizeHeight = sourceHeight; | 75 parsedOptions.resizeHeight = parsedOptions.cropRect.height(); |
| 71 } else if (options.hasResizeWidth() && options.hasResizeHeight()) { | 76 } else if (options.hasResizeWidth() && options.hasResizeHeight()) { |
| 72 parsedOptions.resizeWidth = options.resizeWidth(); | 77 parsedOptions.resizeWidth = options.resizeWidth(); |
| 73 parsedOptions.resizeHeight = options.resizeHeight(); | 78 parsedOptions.resizeHeight = options.resizeHeight(); |
| 74 } else if (options.hasResizeWidth() && !options.hasResizeHeight()) { | 79 } else if (options.hasResizeWidth() && !options.hasResizeHeight()) { |
| 75 parsedOptions.resizeWidth = options.resizeWidth(); | 80 parsedOptions.resizeWidth = options.resizeWidth(); |
| 76 parsedOptions.resizeHeight = ceil(static_cast<float>(options.resizeWidth ()) / sourceWidth * sourceHeight); | 81 parsedOptions.resizeHeight = ceil(static_cast<float>(options.resizeWidth ()) / parsedOptions.cropRect.width() * parsedOptions.cropRect.height()); |
| 77 } else { | 82 } else { |
| 78 parsedOptions.resizeHeight = options.resizeHeight(); | 83 parsedOptions.resizeHeight = options.resizeHeight(); |
| 79 parsedOptions.resizeWidth = ceil(static_cast<float>(options.resizeHeight ()) / sourceHeight * sourceWidth); | 84 parsedOptions.resizeWidth = ceil(static_cast<float>(options.resizeHeight ()) / parsedOptions.cropRect.height() * parsedOptions.cropRect.width()); |
| 80 } | 85 } |
| 81 if (!cropRect) { | 86 if (static_cast<int>(parsedOptions.resizeWidth) == parsedOptions.cropRect.wi dth() && static_cast<int>(parsedOptions.resizeHeight) == parsedOptions.cropRect. height()) { |
| 82 parsedOptions.cropRect = IntRect(0, 0, parsedOptions.resizeWidth, parsed Options.resizeHeight); | |
| 83 } else { | |
| 84 parsedOptions.cropRect = normalizeRect(*cropRect); | |
| 85 } | |
| 86 if (static_cast<int>(parsedOptions.resizeWidth) == sourceWidth && static_cas t<int>(parsedOptions.resizeHeight) == sourceHeight) { | |
| 87 parsedOptions.shouldScaleInput = false; | 87 parsedOptions.shouldScaleInput = false; |
| 88 return parsedOptions; | 88 return parsedOptions; |
| 89 } | 89 } |
| 90 parsedOptions.shouldScaleInput = true; | 90 parsedOptions.shouldScaleInput = true; |
| 91 | 91 |
| 92 if (options.resizeQuality() == "high") | 92 if (options.resizeQuality() == "high") |
| 93 parsedOptions.resizeQuality = kHigh_SkFilterQuality; | 93 parsedOptions.resizeQuality = kHigh_SkFilterQuality; |
| 94 else if (options.resizeQuality() == "medium") | 94 else if (options.resizeQuality() == "medium") |
| 95 parsedOptions.resizeQuality = kMedium_SkFilterQuality; | 95 parsedOptions.resizeQuality = kMedium_SkFilterQuality; |
| 96 else if (options.resizeQuality() == "pixelated") | 96 else if (options.resizeQuality() == "pixelated") |
| (...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 205 static PassRefPtr<StaticBitmapImage> cropImage(Image* image, const ParsedOptions & parsedOptions, AlphaDisposition imageFormat = PremultiplyAlpha, ImageDecoder:: GammaAndColorProfileOption colorSpaceOp = ImageDecoder::GammaAndColorProfileAppl ied) | 205 static PassRefPtr<StaticBitmapImage> cropImage(Image* image, const ParsedOptions & parsedOptions, AlphaDisposition imageFormat = PremultiplyAlpha, ImageDecoder:: GammaAndColorProfileOption colorSpaceOp = ImageDecoder::GammaAndColorProfileAppl ied) |
| 206 { | 206 { |
| 207 ASSERT(image); | 207 ASSERT(image); |
| 208 | 208 |
| 209 IntRect imgRect(IntPoint(), IntSize(image->width(), image->height())); | 209 IntRect imgRect(IntPoint(), IntSize(image->width(), image->height())); |
| 210 const IntRect srcRect = intersection(imgRect, parsedOptions.cropRect); | 210 const IntRect srcRect = intersection(imgRect, parsedOptions.cropRect); |
| 211 | 211 |
| 212 // In the case when cropRect doesn't intersect the source image and it requi res a umpremul image | 212 // In the case when cropRect doesn't intersect the source image and it requi res a umpremul image |
| 213 // We immediately return a transparent black image with cropRect.size() | 213 // We immediately return a transparent black image with cropRect.size() |
| 214 if (srcRect.isEmpty() && !parsedOptions.premultiplyAlpha) { | 214 if (srcRect.isEmpty() && !parsedOptions.premultiplyAlpha) { |
| 215 SkImageInfo info = SkImageInfo::Make(parsedOptions.cropRect.width(), par sedOptions.cropRect.height(), kN32_SkColorType, kUnpremul_SkAlphaType); | 215 SkImageInfo info = SkImageInfo::Make(parsedOptions.shouldScaleInput ? pa rsedOptions.resizeWidth : parsedOptions.cropRect.width(), |
|
Justin Novosad
2016/07/25 18:03:10
This ternary operation is not necessary.
Reason:
xidachen
2016/07/25 19:02:01
Good catch, changes are made. Thanks.
| |
| 216 std::unique_ptr<uint8_t[]> dstPixels = wrapArrayUnique(new uint8_t[parse dOptions.cropRect.width() * parsedOptions.cropRect.height() * info.bytesPerPixel ()]()); | 216 parsedOptions.shouldScaleInput ? parsedOptions.resizeHeight : parsed Options.cropRect.height(), kN32_SkColorType, kUnpremul_SkAlphaType); |
|
Justin Novosad
2016/07/25 18:03:10
same here.
xidachen
2016/07/25 19:02:01
Done.
| |
| 217 return StaticBitmapImage::create(newSkImageFromRaster(info, std::move(ds tPixels), parsedOptions.cropRect.width() * info.bytesPerPixel())); | 217 std::unique_ptr<uint8_t[]> dstPixels = wrapArrayUnique(new uint8_t[info. width() * info.height() * info.bytesPerPixel()]()); |
| 218 return StaticBitmapImage::create(newSkImageFromRaster(info, std::move(ds tPixels), info.width() * info.bytesPerPixel())); | |
| 218 } | 219 } |
| 219 | 220 |
| 220 RefPtr<SkImage> skiaImage = image->imageForCurrentFrame(); | 221 RefPtr<SkImage> skiaImage = image->imageForCurrentFrame(); |
| 221 // Attempt to get raw unpremultiplied image data, executed only when skiaIma ge is premultiplied. | 222 // Attempt to get raw unpremultiplied image data, executed only when skiaIma ge is premultiplied. |
| 222 if ((((!parsedOptions.premultiplyAlpha && !skiaImage->isOpaque()) || !skiaIm age) && image->data() && imageFormat == PremultiplyAlpha) || colorSpaceOp == Ima geDecoder::GammaAndColorProfileIgnored) { | 223 if ((((!parsedOptions.premultiplyAlpha && !skiaImage->isOpaque()) || !skiaIm age) && image->data() && imageFormat == PremultiplyAlpha) || colorSpaceOp == Ima geDecoder::GammaAndColorProfileIgnored) { |
| 223 std::unique_ptr<ImageDecoder> decoder(ImageDecoder::create(*(image->data ()), | 224 std::unique_ptr<ImageDecoder> decoder(ImageDecoder::create(*(image->data ()), |
| 224 parsedOptions.premultiplyAlpha ? ImageDecoder::AlphaPremultiplied : ImageDecoder::AlphaNotPremultiplied, | 225 parsedOptions.premultiplyAlpha ? ImageDecoder::AlphaPremultiplied : ImageDecoder::AlphaNotPremultiplied, |
| 225 colorSpaceOp)); | 226 colorSpaceOp)); |
| 226 if (!decoder) | 227 if (!decoder) |
| 227 return nullptr; | 228 return nullptr; |
| 228 decoder->setData(image->data(), true); | 229 decoder->setData(image->data(), true); |
| 229 skiaImage = ImageBitmap::getSkImageFromDecoder(std::move(decoder)); | 230 skiaImage = ImageBitmap::getSkImageFromDecoder(std::move(decoder)); |
| 230 if (!skiaImage) | 231 if (!skiaImage) |
| 231 return nullptr; | 232 return nullptr; |
| 232 } | 233 } |
| 233 | 234 |
| 234 if (parsedOptions.cropRect == srcRect) { | 235 if (parsedOptions.cropRect == srcRect && !parsedOptions.shouldScaleInput) { |
| 235 RefPtr<SkImage> croppedSkImage = fromSkSp(skiaImage->makeSubset(srcRect) ); | 236 RefPtr<SkImage> croppedSkImage = fromSkSp(skiaImage->makeSubset(srcRect) ); |
| 236 if (parsedOptions.flipY) | 237 if (parsedOptions.flipY) |
| 237 return StaticBitmapImage::create(flipSkImageVertically(croppedSkImag e.get(), parsedOptions.premultiplyAlpha ? PremultiplyAlpha : DontPremultiplyAlph a)); | 238 return StaticBitmapImage::create(flipSkImageVertically(croppedSkImag e.get(), parsedOptions.premultiplyAlpha ? PremultiplyAlpha : DontPremultiplyAlph a)); |
| 238 // Special case: The first parameter image is unpremul but we need to tu rn it into premul. | 239 // Special case: The first parameter image is unpremul but we need to tu rn it into premul. |
| 239 if (parsedOptions.premultiplyAlpha && imageFormat == DontPremultiplyAlph a) | 240 if (parsedOptions.premultiplyAlpha && imageFormat == DontPremultiplyAlph a) |
| 240 return StaticBitmapImage::create(unPremulSkImageToPremul(croppedSkIm age.get())); | 241 return StaticBitmapImage::create(unPremulSkImageToPremul(croppedSkIm age.get())); |
| 241 // Call preroll to trigger image decoding. | 242 // Call preroll to trigger image decoding. |
| 242 croppedSkImage->preroll(); | 243 croppedSkImage->preroll(); |
| 243 return StaticBitmapImage::create(croppedSkImage.release()); | 244 return StaticBitmapImage::create(croppedSkImage.release()); |
| 244 } | 245 } |
| 245 | 246 |
| 246 sk_sp<SkSurface> surface = SkSurface::MakeRasterN32Premul(parsedOptions.crop Rect.width(), parsedOptions.cropRect.height()); | 247 sk_sp<SkSurface> surface = SkSurface::MakeRasterN32Premul(parsedOptions.shou ldScaleInput ? parsedOptions.resizeWidth : parsedOptions.cropRect.width(), |
|
Justin Novosad
2016/07/25 18:03:10
same here.
xidachen
2016/07/25 19:02:01
Done.
| |
| 248 parsedOptions.shouldScaleInput ? parsedOptions.resizeHeight : parsedOpti ons.cropRect.height()); | |
|
Justin Novosad
2016/07/25 18:03:10
same here.
xidachen
2016/07/25 19:02:02
Done.
| |
| 247 if (!surface) | 249 if (!surface) |
| 248 return nullptr; | 250 return nullptr; |
| 249 if (srcRect.isEmpty()) | 251 if (srcRect.isEmpty()) |
| 250 return StaticBitmapImage::create(fromSkSp(surface->makeImageSnapshot())) ; | 252 return StaticBitmapImage::create(fromSkSp(surface->makeImageSnapshot())) ; |
| 251 | 253 |
| 252 SkScalar dstLeft = std::min(0, -parsedOptions.cropRect.x()); | 254 SkScalar dstLeft = std::min(0, -parsedOptions.cropRect.x()); |
| 253 SkScalar dstTop = std::min(0, -parsedOptions.cropRect.y()); | 255 SkScalar dstTop = std::min(0, -parsedOptions.cropRect.y()); |
| 254 if (parsedOptions.cropRect.x() < 0) | 256 if (parsedOptions.cropRect.x() < 0) |
| 255 dstLeft = -parsedOptions.cropRect.x(); | 257 dstLeft = -parsedOptions.cropRect.x(); |
| 256 if (parsedOptions.cropRect.y() < 0) | 258 if (parsedOptions.cropRect.y() < 0) |
| 257 dstTop = -parsedOptions.cropRect.y(); | 259 dstTop = -parsedOptions.cropRect.y(); |
| 258 if (parsedOptions.flipY) { | 260 if (parsedOptions.flipY) { |
| 259 surface->getCanvas()->translate(0, surface->height()); | 261 surface->getCanvas()->translate(0, surface->height()); |
| 260 surface->getCanvas()->scale(1, -1); | 262 surface->getCanvas()->scale(1, -1); |
| 261 } | 263 } |
| 262 if (parsedOptions.shouldScaleInput) { | 264 if (parsedOptions.shouldScaleInput) { |
| 263 SkRect drawDstRect = SkRect::MakeXYWH(dstLeft, dstTop, parsedOptions.res izeWidth, parsedOptions.resizeHeight); | 265 SkRect drawSrcRect = SkRect::MakeXYWH(parsedOptions.cropRect.x(), parsed Options.cropRect.y(), parsedOptions.cropRect.width(), parsedOptions.cropRect.hei ght()); |
| 266 SkRect drawDstRect = SkRect::MakeXYWH(0, 0, parsedOptions.resizeWidth, p arsedOptions.resizeHeight); | |
| 264 SkPaint paint; | 267 SkPaint paint; |
| 265 paint.setFilterQuality(parsedOptions.resizeQuality); | 268 paint.setFilterQuality(parsedOptions.resizeQuality); |
| 266 surface->getCanvas()->drawImageRect(skiaImage.get(), drawDstRect, &paint ); | 269 surface->getCanvas()->drawImageRect(skiaImage.get(), drawSrcRect, drawDs tRect, &paint); |
| 267 } else { | 270 } else { |
| 268 surface->getCanvas()->drawImage(skiaImage.get(), dstLeft, dstTop); | 271 surface->getCanvas()->drawImage(skiaImage.get(), dstLeft, dstTop); |
| 269 } | 272 } |
| 270 skiaImage = fromSkSp(surface->makeImageSnapshot()); | 273 skiaImage = fromSkSp(surface->makeImageSnapshot()); |
| 271 | 274 |
| 272 if (parsedOptions.premultiplyAlpha) { | 275 if (parsedOptions.premultiplyAlpha) { |
| 273 if (imageFormat == PremultiplyAlpha) | 276 if (imageFormat == PremultiplyAlpha) |
| 274 return StaticBitmapImage::create(unPremulSkImageToPremul(skiaImage.g et())); | 277 return StaticBitmapImage::create(unPremulSkImageToPremul(skiaImage.g et())); |
| 275 return StaticBitmapImage::create(skiaImage.release()); | 278 return StaticBitmapImage::create(skiaImage.release()); |
| 276 } | 279 } |
| (...skipping 328 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 605 FloatSize ImageBitmap::elementSize(const FloatSize&) const | 608 FloatSize ImageBitmap::elementSize(const FloatSize&) const |
| 606 { | 609 { |
| 607 return FloatSize(width(), height()); | 610 return FloatSize(width(), height()); |
| 608 } | 611 } |
| 609 | 612 |
| 610 DEFINE_TRACE(ImageBitmap) | 613 DEFINE_TRACE(ImageBitmap) |
| 611 { | 614 { |
| 612 } | 615 } |
| 613 | 616 |
| 614 } // namespace blink | 617 } // namespace blink |
| OLD | NEW |