| 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" |
| 11 #include "platform/image-decoders/ImageDecoder.h" | 11 #include "platform/image-decoders/ImageDecoder.h" |
| 12 #include "third_party/skia/include/core/SkCanvas.h" | 12 #include "third_party/skia/include/core/SkCanvas.h" |
| 13 #include "third_party/skia/include/core/SkSurface.h" | 13 #include "third_party/skia/include/core/SkSurface.h" |
| 14 #include "wtf/PtrUtil.h" | 14 #include "wtf/PtrUtil.h" |
| 15 #include "wtf/RefPtr.h" | 15 #include "wtf/RefPtr.h" |
| 16 #include <memory> | 16 #include <memory> |
| 17 | 17 |
| 18 namespace blink { | 18 namespace blink { |
| 19 | 19 |
| 20 static const char* imageOrientationFlipY = "flipY"; | 20 static const char* imageOrientationFlipY = "flipY"; |
| 21 static const char* imageBitmapOptionNone = "none"; | 21 static const char* imageBitmapOptionNone = "none"; |
| 22 | 22 |
| 23 namespace { |
| 24 |
| 25 struct ParsedOptions { |
| 26 bool flipY = false; |
| 27 bool premultiplyAlpha = true; |
| 28 bool shouldScaleInput = false; |
| 29 unsigned resizeWidth = 0; |
| 30 unsigned resizeHeight = 0; |
| 31 IntRect cropRect; |
| 32 SkFilterQuality resizeQuality = kLow_SkFilterQuality; |
| 33 }; |
| 34 |
| 23 // The following two functions are helpers used in cropImage | 35 // The following two functions are helpers used in cropImage |
| 24 static inline IntRect normalizeRect(const IntRect& rect) | 36 static inline IntRect normalizeRect(const IntRect& rect) |
| 25 { | 37 { |
| 26 return IntRect(std::min(rect.x(), rect.maxX()), | 38 return IntRect(std::min(rect.x(), rect.maxX()), |
| 27 std::min(rect.y(), rect.maxY()), | 39 std::min(rect.y(), rect.maxY()), |
| 28 std::max(rect.width(), -rect.width()), | 40 std::max(rect.width(), -rect.width()), |
| 29 std::max(rect.height(), -rect.height())); | 41 std::max(rect.height(), -rect.height())); |
| 30 } | 42 } |
| 31 | 43 |
| 32 static bool frameIsValid(const SkBitmap& frameBitmap) | 44 static bool frameIsValid(const SkBitmap& frameBitmap) |
| 33 { | 45 { |
| 34 ASSERT(!frameBitmap.isNull() && !frameBitmap.empty() && frameBitmap.isImmuta
ble()); | 46 ASSERT(!frameBitmap.isNull() && !frameBitmap.empty() && frameBitmap.isImmuta
ble()); |
| 35 return frameBitmap.colorType() == kN32_SkColorType; | 47 return frameBitmap.colorType() == kN32_SkColorType; |
| 36 } | 48 } |
| 37 | 49 |
| 50 ParsedOptions parseOptions(const ImageBitmapOptions& options, Optional<IntRect>
cropRect, IntSize sourceSize) |
| 51 { |
| 52 ParsedOptions parsedOptions; |
| 53 if (options.imageOrientation() == imageOrientationFlipY) { |
| 54 parsedOptions.flipY = true; |
| 55 } else { |
| 56 parsedOptions.flipY = false; |
| 57 DCHECK(options.imageOrientation() == imageBitmapOptionNone); |
| 58 } |
| 59 if (options.premultiplyAlpha() == imageBitmapOptionNone) { |
| 60 parsedOptions.premultiplyAlpha = false; |
| 61 } else { |
| 62 parsedOptions.premultiplyAlpha = true; |
| 63 DCHECK(options.premultiplyAlpha() == "default" || options.premultiplyAlp
ha() == "premultiply"); |
| 64 } |
| 65 |
| 66 int sourceWidth = sourceSize.width(); |
| 67 int sourceHeight = sourceSize.height(); |
| 68 if (!options.hasResizeWidth() && !options.hasResizeHeight()) { |
| 69 parsedOptions.resizeWidth = sourceWidth; |
| 70 parsedOptions.resizeHeight = sourceHeight; |
| 71 } else if (options.hasResizeWidth() && options.hasResizeHeight()) { |
| 72 parsedOptions.resizeWidth = options.resizeWidth(); |
| 73 parsedOptions.resizeHeight = options.resizeHeight(); |
| 74 } else if (options.hasResizeWidth() && !options.hasResizeHeight()) { |
| 75 parsedOptions.resizeWidth = options.resizeWidth(); |
| 76 parsedOptions.resizeHeight = ceil(static_cast<float>(options.resizeWidth
()) / sourceWidth * sourceHeight); |
| 77 } else { |
| 78 parsedOptions.resizeHeight = options.resizeHeight(); |
| 79 parsedOptions.resizeWidth = ceil(static_cast<float>(options.resizeHeight
()) / sourceHeight * sourceWidth); |
| 80 } |
| 81 if (!cropRect) { |
| 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; |
| 88 return parsedOptions; |
| 89 } |
| 90 parsedOptions.shouldScaleInput = true; |
| 91 |
| 92 if (options.resizeQuality() == "high") |
| 93 parsedOptions.resizeQuality = kHigh_SkFilterQuality; |
| 94 else if (options.resizeQuality() == "medium") |
| 95 parsedOptions.resizeQuality = kMedium_SkFilterQuality; |
| 96 else if (options.resizeQuality() == "pixelated") |
| 97 parsedOptions.resizeQuality = kNone_SkFilterQuality; |
| 98 else |
| 99 parsedOptions.resizeQuality = kLow_SkFilterQuality; |
| 100 return parsedOptions; |
| 101 } |
| 102 |
| 103 } // namespace |
| 104 |
| 38 static std::unique_ptr<uint8_t[]> copySkImageData(SkImage* input, const SkImageI
nfo& info) | 105 static std::unique_ptr<uint8_t[]> copySkImageData(SkImage* input, const SkImageI
nfo& info) |
| 39 { | 106 { |
| 40 std::unique_ptr<uint8_t[]> dstPixels = wrapArrayUnique(new uint8_t[input->wi
dth() * input->height() * info.bytesPerPixel()]); | 107 std::unique_ptr<uint8_t[]> dstPixels = wrapArrayUnique(new uint8_t[input->wi
dth() * input->height() * info.bytesPerPixel()]); |
| 41 input->readPixels(info, dstPixels.get(), input->width() * info.bytesPerPixel
(), 0, 0); | 108 input->readPixels(info, dstPixels.get(), input->width() * info.bytesPerPixel
(), 0, 0); |
| 42 return dstPixels; | 109 return dstPixels; |
| 43 } | 110 } |
| 44 | 111 |
| 45 static PassRefPtr<SkImage> newSkImageFromRaster(const SkImageInfo& info, std::un
ique_ptr<uint8_t[]> imagePixels, int imageRowBytes) | 112 static PassRefPtr<SkImage> newSkImageFromRaster(const SkImageInfo& info, std::un
ique_ptr<uint8_t[]> imagePixels, int imageRowBytes) |
| 46 { | 113 { |
| 47 return fromSkSp(SkImage::MakeFromRaster(SkPixmap(info, imagePixels.release()
, imageRowBytes), | 114 return fromSkSp(SkImage::MakeFromRaster(SkPixmap(info, imagePixels.release()
, imageRowBytes), |
| (...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 106 return nullptr; | 173 return nullptr; |
| 107 ImageFrame* frame = decoder->frameBufferAtIndex(0); | 174 ImageFrame* frame = decoder->frameBufferAtIndex(0); |
| 108 if (!frame || frame->getStatus() != ImageFrame::FrameComplete) | 175 if (!frame || frame->getStatus() != ImageFrame::FrameComplete) |
| 109 return nullptr; | 176 return nullptr; |
| 110 SkBitmap bitmap = frame->bitmap(); | 177 SkBitmap bitmap = frame->bitmap(); |
| 111 if (!frameIsValid(bitmap)) | 178 if (!frameIsValid(bitmap)) |
| 112 return nullptr; | 179 return nullptr; |
| 113 return fromSkSp(SkImage::MakeFromBitmap(bitmap)); | 180 return fromSkSp(SkImage::MakeFromBitmap(bitmap)); |
| 114 } | 181 } |
| 115 | 182 |
| 183 bool ImageBitmap::isResizeOptionValid(const ImageBitmapOptions& options, Excepti
onState& exceptionState) |
| 184 { |
| 185 if ((options.hasResizeWidth() && options.resizeWidth() == 0) || (options.has
ResizeHeight() && options.resizeHeight() == 0)) { |
| 186 exceptionState.throwDOMException(InvalidStateError, "The resizeWidth or/
and resizeHeight is equal to 0."); |
| 187 return false; |
| 188 } |
| 189 return true; |
| 190 } |
| 191 |
| 192 bool ImageBitmap::isSourceSizeValid(int sourceWidth, int sourceHeight, Exception
State& exceptionState) |
| 193 { |
| 194 if (!sourceWidth || !sourceHeight) { |
| 195 exceptionState.throwDOMException(IndexSizeError, String::format("The sou
rce %s provided is 0.", sourceWidth ? "height" : "width")); |
| 196 return false; |
| 197 } |
| 198 return true; |
| 199 } |
| 200 |
| 116 // The parameter imageFormat indicates whether the first parameter "image" is un
premultiplied or not. | 201 // The parameter imageFormat indicates whether the first parameter "image" is un
premultiplied or not. |
| 117 // imageFormat = PremultiplyAlpha means the image is in premuliplied format | 202 // imageFormat = PremultiplyAlpha means the image is in premuliplied format |
| 118 // For example, if the image is already in unpremultiplied format and we want th
e created ImageBitmap | 203 // For example, if the image is already in unpremultiplied format and we want th
e created ImageBitmap |
| 119 // in the same format, then we don't need to use the ImageDecoder to decode the
image. | 204 // in the same format, then we don't need to use the ImageDecoder to decode the
image. |
| 120 static PassRefPtr<StaticBitmapImage> cropImage(Image* image, const IntRect& crop
Rect, bool flipY, bool premultiplyAlpha, AlphaDisposition imageFormat = Premulti
plyAlpha, ImageDecoder::GammaAndColorProfileOption colorSpaceOp = ImageDecoder::
GammaAndColorProfileApplied) | 205 static PassRefPtr<StaticBitmapImage> cropImage(Image* image, const ParsedOptions
& parsedOptions, AlphaDisposition imageFormat = PremultiplyAlpha, ImageDecoder::
GammaAndColorProfileOption colorSpaceOp = ImageDecoder::GammaAndColorProfileAppl
ied) |
| 121 { | 206 { |
| 122 ASSERT(image); | 207 ASSERT(image); |
| 123 | 208 |
| 124 IntRect imgRect(IntPoint(), IntSize(image->width(), image->height())); | 209 IntRect imgRect(IntPoint(), IntSize(image->width(), image->height())); |
| 125 const IntRect srcRect = intersection(imgRect, cropRect); | 210 const IntRect srcRect = intersection(imgRect, parsedOptions.cropRect); |
| 126 | 211 |
| 127 // 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 |
| 128 // We immediately return a transparent black image with cropRect.size() | 213 // We immediately return a transparent black image with cropRect.size() |
| 129 if (srcRect.isEmpty() && !premultiplyAlpha) { | 214 if (srcRect.isEmpty() && !parsedOptions.premultiplyAlpha) { |
| 130 SkImageInfo info = SkImageInfo::Make(cropRect.width(), cropRect.height()
, kN32_SkColorType, kUnpremul_SkAlphaType); | 215 SkImageInfo info = SkImageInfo::Make(parsedOptions.cropRect.width(), par
sedOptions.cropRect.height(), kN32_SkColorType, kUnpremul_SkAlphaType); |
| 131 std::unique_ptr<uint8_t[]> dstPixels = wrapArrayUnique(new uint8_t[cropR
ect.width() * cropRect.height() * info.bytesPerPixel()]()); | 216 std::unique_ptr<uint8_t[]> dstPixels = wrapArrayUnique(new uint8_t[parse
dOptions.cropRect.width() * parsedOptions.cropRect.height() * info.bytesPerPixel
()]()); |
| 132 return StaticBitmapImage::create(newSkImageFromRaster(info, std::move(ds
tPixels), cropRect.width() * info.bytesPerPixel())); | 217 return StaticBitmapImage::create(newSkImageFromRaster(info, std::move(ds
tPixels), parsedOptions.cropRect.width() * info.bytesPerPixel())); |
| 133 } | 218 } |
| 134 | 219 |
| 135 RefPtr<SkImage> skiaImage = image->imageForCurrentFrame(); | 220 RefPtr<SkImage> skiaImage = image->imageForCurrentFrame(); |
| 136 // Attempt to get raw unpremultiplied image data, executed only when skiaIma
ge is premultiplied. | 221 // Attempt to get raw unpremultiplied image data, executed only when skiaIma
ge is premultiplied. |
| 137 if ((((!premultiplyAlpha && !skiaImage->isOpaque()) || !skiaImage) && image-
>data() && imageFormat == PremultiplyAlpha) || colorSpaceOp == ImageDecoder::Gam
maAndColorProfileIgnored) { | 222 if ((((!parsedOptions.premultiplyAlpha && !skiaImage->isOpaque()) || !skiaIm
age) && image->data() && imageFormat == PremultiplyAlpha) || colorSpaceOp == Ima
geDecoder::GammaAndColorProfileIgnored) { |
| 138 std::unique_ptr<ImageDecoder> decoder(ImageDecoder::create(*(image->data
()), | 223 std::unique_ptr<ImageDecoder> decoder(ImageDecoder::create(*(image->data
()), |
| 139 premultiplyAlpha ? ImageDecoder::AlphaPremultiplied : ImageDecoder::
AlphaNotPremultiplied, | 224 parsedOptions.premultiplyAlpha ? ImageDecoder::AlphaPremultiplied :
ImageDecoder::AlphaNotPremultiplied, |
| 140 colorSpaceOp)); | 225 colorSpaceOp)); |
| 141 if (!decoder) | 226 if (!decoder) |
| 142 return nullptr; | 227 return nullptr; |
| 143 decoder->setData(image->data(), true); | 228 decoder->setData(image->data(), true); |
| 144 skiaImage = ImageBitmap::getSkImageFromDecoder(std::move(decoder)); | 229 skiaImage = ImageBitmap::getSkImageFromDecoder(std::move(decoder)); |
| 145 if (!skiaImage) | 230 if (!skiaImage) |
| 146 return nullptr; | 231 return nullptr; |
| 147 } | 232 } |
| 148 | 233 |
| 149 if (cropRect == srcRect) { | 234 if (parsedOptions.cropRect == srcRect) { |
| 150 RefPtr<SkImage> croppedSkImage = fromSkSp(skiaImage->makeSubset(srcRect)
); | 235 RefPtr<SkImage> croppedSkImage = fromSkSp(skiaImage->makeSubset(srcRect)
); |
| 151 if (flipY) | 236 if (parsedOptions.flipY) |
| 152 return StaticBitmapImage::create(flipSkImageVertically(croppedSkImag
e.get(), premultiplyAlpha ? PremultiplyAlpha : DontPremultiplyAlpha)); | 237 return StaticBitmapImage::create(flipSkImageVertically(croppedSkImag
e.get(), parsedOptions.premultiplyAlpha ? PremultiplyAlpha : DontPremultiplyAlph
a)); |
| 153 // Special case: The first parameter image is unpremul but we need to tu
rn it into premul. | 238 // Special case: The first parameter image is unpremul but we need to tu
rn it into premul. |
| 154 if (premultiplyAlpha && imageFormat == DontPremultiplyAlpha) | 239 if (parsedOptions.premultiplyAlpha && imageFormat == DontPremultiplyAlph
a) |
| 155 return StaticBitmapImage::create(unPremulSkImageToPremul(croppedSkIm
age.get())); | 240 return StaticBitmapImage::create(unPremulSkImageToPremul(croppedSkIm
age.get())); |
| 156 // Call preroll to trigger image decoding. | 241 // Call preroll to trigger image decoding. |
| 157 croppedSkImage->preroll(); | 242 croppedSkImage->preroll(); |
| 158 return StaticBitmapImage::create(croppedSkImage.release()); | 243 return StaticBitmapImage::create(croppedSkImage.release()); |
| 159 } | 244 } |
| 160 | 245 |
| 161 sk_sp<SkSurface> surface = SkSurface::MakeRasterN32Premul(cropRect.width(),
cropRect.height()); | 246 sk_sp<SkSurface> surface = SkSurface::MakeRasterN32Premul(parsedOptions.crop
Rect.width(), parsedOptions.cropRect.height()); |
| 162 if (!surface) | 247 if (!surface) |
| 163 return nullptr; | 248 return nullptr; |
| 164 if (srcRect.isEmpty()) | 249 if (srcRect.isEmpty()) |
| 165 return StaticBitmapImage::create(fromSkSp(surface->makeImageSnapshot()))
; | 250 return StaticBitmapImage::create(fromSkSp(surface->makeImageSnapshot()))
; |
| 166 | 251 |
| 167 SkScalar dstLeft = std::min(0, -cropRect.x()); | 252 SkScalar dstLeft = std::min(0, -parsedOptions.cropRect.x()); |
| 168 SkScalar dstTop = std::min(0, -cropRect.y()); | 253 SkScalar dstTop = std::min(0, -parsedOptions.cropRect.y()); |
| 169 if (cropRect.x() < 0) | 254 if (parsedOptions.cropRect.x() < 0) |
| 170 dstLeft = -cropRect.x(); | 255 dstLeft = -parsedOptions.cropRect.x(); |
| 171 if (cropRect.y() < 0) | 256 if (parsedOptions.cropRect.y() < 0) |
| 172 dstTop = -cropRect.y(); | 257 dstTop = -parsedOptions.cropRect.y(); |
| 173 surface->getCanvas()->drawImage(skiaImage.get(), dstLeft, dstTop); | 258 if (parsedOptions.shouldScaleInput) { |
| 259 SkRect drawDstRect = SkRect::MakeXYWH(dstLeft, dstTop, parsedOptions.res
izeWidth, parsedOptions.resizeHeight); |
| 260 SkPaint paint; |
| 261 paint.setFilterQuality(parsedOptions.resizeQuality); |
| 262 surface->getCanvas()->drawImageRect(skiaImage.get(), drawDstRect, &paint
); |
| 263 } else { |
| 264 surface->getCanvas()->drawImage(skiaImage.get(), dstLeft, dstTop); |
| 265 } |
| 174 skiaImage = fromSkSp(surface->makeImageSnapshot()); | 266 skiaImage = fromSkSp(surface->makeImageSnapshot()); |
| 175 if (flipY) | 267 if (parsedOptions.flipY) |
| 176 skiaImage = flipSkImageVertically(skiaImage.get(), PremultiplyAlpha); | 268 skiaImage = flipSkImageVertically(skiaImage.get(), PremultiplyAlpha); |
| 177 | 269 |
| 178 if (premultiplyAlpha) { | 270 if (parsedOptions.premultiplyAlpha) { |
| 179 if (imageFormat == PremultiplyAlpha) | 271 if (imageFormat == PremultiplyAlpha) |
| 180 return StaticBitmapImage::create(unPremulSkImageToPremul(skiaImage.g
et())); | 272 return StaticBitmapImage::create(unPremulSkImageToPremul(skiaImage.g
et())); |
| 181 return StaticBitmapImage::create(skiaImage.release()); | 273 return StaticBitmapImage::create(skiaImage.release()); |
| 182 } | 274 } |
| 183 return StaticBitmapImage::create(premulSkImageToUnPremul(skiaImage.get())); | 275 return StaticBitmapImage::create(premulSkImageToUnPremul(skiaImage.get())); |
| 184 } | 276 } |
| 185 | 277 |
| 186 ImageBitmap::ImageBitmap(HTMLImageElement* image, const IntRect& cropRect, Docum
ent* document, const ImageBitmapOptions& options) | 278 ImageBitmap::ImageBitmap(HTMLImageElement* image, Optional<IntRect> cropRect, Do
cument* document, const ImageBitmapOptions& options) |
| 187 { | 279 { |
| 188 bool flipY; | 280 RefPtr<Image> input = image->cachedImage()->getImage(); |
| 189 bool premultiplyAlpha; | 281 ParsedOptions parsedOptions = parseOptions(options, cropRect, image->bitmapS
ourceSize()); |
| 190 parseOptions(options, flipY, premultiplyAlpha); | |
| 191 | 282 |
| 192 if (options.colorSpaceConversion() == "none") | 283 if (options.colorSpaceConversion() == "none") |
| 193 m_image = cropImage(image->cachedImage()->getImage(), cropRect, flipY, p
remultiplyAlpha, PremultiplyAlpha, ImageDecoder::GammaAndColorProfileIgnored); | 284 m_image = cropImage(input.get(), parsedOptions, PremultiplyAlpha, ImageD
ecoder::GammaAndColorProfileIgnored); |
| 194 else | 285 else |
| 195 m_image = cropImage(image->cachedImage()->getImage(), cropRect, flipY, p
remultiplyAlpha, PremultiplyAlpha, ImageDecoder::GammaAndColorProfileApplied); | 286 m_image = cropImage(input.get(), parsedOptions, PremultiplyAlpha, ImageD
ecoder::GammaAndColorProfileApplied); |
| 196 if (!m_image) | 287 if (!m_image) |
| 197 return; | 288 return; |
| 198 // In the case where the source image is lazy-decoded, m_image may not be in | 289 // In the case where the source image is lazy-decoded, m_image may not be in |
| 199 // a decoded state, we trigger it here. | 290 // a decoded state, we trigger it here. |
| 200 RefPtr<SkImage> skImage = m_image->imageForCurrentFrame(); | 291 RefPtr<SkImage> skImage = m_image->imageForCurrentFrame(); |
| 201 SkPixmap pixmap; | 292 SkPixmap pixmap; |
| 202 if (!skImage->isTextureBacked() && !skImage->peekPixels(&pixmap)) { | 293 if (!skImage->isTextureBacked() && !skImage->peekPixels(&pixmap)) { |
| 203 sk_sp<SkSurface> surface = SkSurface::MakeRasterN32Premul(skImage->width
(), skImage->height()); | 294 sk_sp<SkSurface> surface = SkSurface::MakeRasterN32Premul(skImage->width
(), skImage->height()); |
| 204 surface->getCanvas()->drawImage(skImage.get(), 0, 0); | 295 surface->getCanvas()->drawImage(skImage.get(), 0, 0); |
| 205 m_image = StaticBitmapImage::create(fromSkSp(surface->makeImageSnapshot(
))); | 296 m_image = StaticBitmapImage::create(fromSkSp(surface->makeImageSnapshot(
))); |
| 206 } | 297 } |
| 207 m_image->setOriginClean(!image->wouldTaintOrigin(document->getSecurityOrigin
())); | 298 m_image->setOriginClean(!image->wouldTaintOrigin(document->getSecurityOrigin
())); |
| 208 m_image->setPremultiplied(premultiplyAlpha); | 299 m_image->setPremultiplied(parsedOptions.premultiplyAlpha); |
| 209 } | 300 } |
| 210 | 301 |
| 211 ImageBitmap::ImageBitmap(HTMLVideoElement* video, const IntRect& cropRect, Docum
ent* document, const ImageBitmapOptions& options) | 302 ImageBitmap::ImageBitmap(HTMLVideoElement* video, Optional<IntRect> cropRect, Do
cument* document, const ImageBitmapOptions& options) |
| 212 { | 303 { |
| 213 IntSize playerSize; | 304 IntSize playerSize; |
| 214 if (video->webMediaPlayer()) | 305 if (video->webMediaPlayer()) |
| 215 playerSize = video->webMediaPlayer()->naturalSize(); | 306 playerSize = video->webMediaPlayer()->naturalSize(); |
| 216 | 307 |
| 308 // TODO(xidachen); implement the resize option. |
| 309 ParsedOptions parsedOptions = parseOptions(options, cropRect, video->bitmapS
ourceSize()); |
| 310 |
| 217 IntRect videoRect = IntRect(IntPoint(), playerSize); | 311 IntRect videoRect = IntRect(IntPoint(), playerSize); |
| 218 IntRect srcRect = intersection(cropRect, videoRect); | 312 IntRect srcRect = intersection(parsedOptions.cropRect, videoRect); |
| 219 std::unique_ptr<ImageBuffer> buffer = ImageBuffer::create(cropRect.size(), N
onOpaque, DoNotInitializeImagePixels); | 313 std::unique_ptr<ImageBuffer> buffer = ImageBuffer::create(parsedOptions.crop
Rect.size(), NonOpaque, DoNotInitializeImagePixels); |
| 220 if (!buffer) | 314 if (!buffer) |
| 221 return; | 315 return; |
| 222 | 316 |
| 223 IntPoint dstPoint = IntPoint(std::max(0, -cropRect.x()), std::max(0, -cropRe
ct.y())); | 317 IntPoint dstPoint = IntPoint(std::max(0, -parsedOptions.cropRect.x()), std::
max(0, -parsedOptions.cropRect.y())); |
| 224 video->paintCurrentFrame(buffer->canvas(), IntRect(dstPoint, srcRect.size())
, nullptr); | 318 video->paintCurrentFrame(buffer->canvas(), IntRect(dstPoint, srcRect.size())
, nullptr); |
| 225 | 319 |
| 226 bool flipY; | 320 if (parsedOptions.flipY || !parsedOptions.premultiplyAlpha) { |
| 227 bool premultiplyAlpha; | |
| 228 parseOptions(options, flipY, premultiplyAlpha); | |
| 229 | |
| 230 if (flipY || !premultiplyAlpha) { | |
| 231 RefPtr<SkImage> skiaImage = buffer->newSkImageSnapshot(PreferNoAccelerat
ion, SnapshotReasonUnknown); | 321 RefPtr<SkImage> skiaImage = buffer->newSkImageSnapshot(PreferNoAccelerat
ion, SnapshotReasonUnknown); |
| 232 if (flipY) | 322 if (parsedOptions.flipY) |
| 233 skiaImage = flipSkImageVertically(skiaImage.get(), PremultiplyAlpha)
; | 323 skiaImage = flipSkImageVertically(skiaImage.get(), PremultiplyAlpha)
; |
| 234 if (!premultiplyAlpha) | 324 if (!parsedOptions.premultiplyAlpha) |
| 235 skiaImage = premulSkImageToUnPremul(skiaImage.get()); | 325 skiaImage = premulSkImageToUnPremul(skiaImage.get()); |
| 236 m_image = StaticBitmapImage::create(skiaImage.release()); | 326 m_image = StaticBitmapImage::create(skiaImage.release()); |
| 237 } else { | 327 } else { |
| 238 m_image = StaticBitmapImage::create(buffer->newSkImageSnapshot(PreferNoA
cceleration, SnapshotReasonUnknown)); | 328 m_image = StaticBitmapImage::create(buffer->newSkImageSnapshot(PreferNoA
cceleration, SnapshotReasonUnknown)); |
| 239 } | 329 } |
| 240 m_image->setOriginClean(!video->wouldTaintOrigin(document->getSecurityOrigin
())); | 330 m_image->setOriginClean(!video->wouldTaintOrigin(document->getSecurityOrigin
())); |
| 241 m_image->setPremultiplied(premultiplyAlpha); | 331 m_image->setPremultiplied(parsedOptions.premultiplyAlpha); |
| 242 } | 332 } |
| 243 | 333 |
| 244 ImageBitmap::ImageBitmap(HTMLCanvasElement* canvas, const IntRect& cropRect, con
st ImageBitmapOptions& options) | 334 ImageBitmap::ImageBitmap(HTMLCanvasElement* canvas, Optional<IntRect> cropRect,
const ImageBitmapOptions& options) |
| 245 { | 335 { |
| 246 ASSERT(canvas->isPaintable()); | 336 ASSERT(canvas->isPaintable()); |
| 247 bool flipY; | 337 RefPtr<Image> input = canvas->copiedImage(BackBuffer, PreferAcceleration); |
| 248 bool premultiplyAlpha; | 338 ParsedOptions parsedOptions = parseOptions(options, cropRect, canvas->bitmap
SourceSize()); |
| 249 parseOptions(options, flipY, premultiplyAlpha); | |
| 250 | 339 |
| 251 // canvas is always premultiplied, so set the last parameter to true and con
vert to un-premul later | 340 bool isPremultiplyAlphaReverted = false; |
| 252 m_image = cropImage(canvas->copiedImage(BackBuffer, PreferAcceleration).get(
), cropRect, flipY, true); | 341 if (!parsedOptions.premultiplyAlpha) { |
| 342 parsedOptions.premultiplyAlpha = true; |
| 343 isPremultiplyAlphaReverted = true; |
| 344 } |
| 345 m_image = cropImage(input.get(), parsedOptions); |
| 253 if (!m_image) | 346 if (!m_image) |
| 254 return; | 347 return; |
| 255 if (!premultiplyAlpha) | 348 if (isPremultiplyAlphaReverted) { |
| 349 parsedOptions.premultiplyAlpha = false; |
| 256 m_image = StaticBitmapImage::create(premulSkImageToUnPremul(m_image->ima
geForCurrentFrame().get())); | 350 m_image = StaticBitmapImage::create(premulSkImageToUnPremul(m_image->ima
geForCurrentFrame().get())); |
| 351 } |
| 257 m_image->setOriginClean(canvas->originClean()); | 352 m_image->setOriginClean(canvas->originClean()); |
| 258 m_image->setPremultiplied(premultiplyAlpha); | 353 m_image->setPremultiplied(parsedOptions.premultiplyAlpha); |
| 259 } | 354 } |
| 260 | 355 |
| 261 ImageBitmap::ImageBitmap(std::unique_ptr<uint8_t[]> data, uint32_t width, uint32
_t height, bool isImageBitmapPremultiplied, bool isImageBitmapOriginClean) | 356 ImageBitmap::ImageBitmap(std::unique_ptr<uint8_t[]> data, uint32_t width, uint32
_t height, bool isImageBitmapPremultiplied, bool isImageBitmapOriginClean) |
| 262 { | 357 { |
| 263 SkImageInfo info = SkImageInfo::MakeN32(width, height, isImageBitmapPremulti
plied ? kPremul_SkAlphaType : kUnpremul_SkAlphaType); | 358 SkImageInfo info = SkImageInfo::MakeN32(width, height, isImageBitmapPremulti
plied ? kPremul_SkAlphaType : kUnpremul_SkAlphaType); |
| 264 m_image = StaticBitmapImage::create(fromSkSp(SkImage::MakeRasterCopy(SkPixma
p(info, data.get(), info.bytesPerPixel() * width)))); | 359 m_image = StaticBitmapImage::create(fromSkSp(SkImage::MakeRasterCopy(SkPixma
p(info, data.get(), info.bytesPerPixel() * width)))); |
| 265 m_image->setPremultiplied(isImageBitmapPremultiplied); | 360 m_image->setPremultiplied(isImageBitmapPremultiplied); |
| 266 m_image->setOriginClean(isImageBitmapOriginClean); | 361 m_image->setOriginClean(isImageBitmapOriginClean); |
| 267 } | 362 } |
| 268 | 363 |
| 269 ImageBitmap::ImageBitmap(ImageData* data, const IntRect& cropRect, const ImageBi
tmapOptions& options) | 364 ImageBitmap::ImageBitmap(ImageData* data, Optional<IntRect> cropRect, const Imag
eBitmapOptions& options) |
| 270 { | 365 { |
| 271 bool flipY; | 366 // TODO(xidachen): implement the resize option |
| 272 bool premultiplyAlpha; | 367 IntRect dataSrcRect = IntRect(IntPoint(), data->size()); |
| 273 parseOptions(options, flipY, premultiplyAlpha); | 368 ParsedOptions parsedOptions = parseOptions(options, cropRect, data->bitmapSo
urceSize()); |
| 274 IntRect srcRect = intersection(cropRect, IntRect(IntPoint(), data->size())); | 369 IntRect srcRect = cropRect ? intersection(parsedOptions.cropRect, dataSrcRec
t) : dataSrcRect; |
| 275 | 370 |
| 276 // treat non-premultiplyAlpha as a special case | 371 // treat non-premultiplyAlpha as a special case |
| 277 if (!premultiplyAlpha) { | 372 if (!parsedOptions.premultiplyAlpha) { |
| 278 unsigned char* srcAddr = data->data()->data(); | 373 unsigned char* srcAddr = data->data()->data(); |
| 279 int srcHeight = data->size().height(); | 374 int srcHeight = data->size().height(); |
| 280 int dstHeight = cropRect.height(); | 375 int dstHeight = parsedOptions.cropRect.height(); |
| 281 // TODO (xidachen): skia doesn't support SkImage::NewRasterCopy from a k
RGBA color type. | 376 // TODO (xidachen): skia doesn't support SkImage::NewRasterCopy from a k
RGBA color type. |
| 282 // For now, we swap R and B channel and uses kBGRA color type. | 377 // For now, we swap R and B channel and uses kBGRA color type. |
| 283 SkImageInfo info = SkImageInfo::Make(cropRect.width(), dstHeight, kBGRA_
8888_SkColorType, kUnpremul_SkAlphaType); | 378 SkImageInfo info = SkImageInfo::Make(parsedOptions.cropRect.width(), dst
Height, kBGRA_8888_SkColorType, kUnpremul_SkAlphaType); |
| 284 int srcPixelBytesPerRow = info.bytesPerPixel() * data->size().width(); | 379 int srcPixelBytesPerRow = info.bytesPerPixel() * data->size().width(); |
| 285 int dstPixelBytesPerRow = info.bytesPerPixel() * cropRect.width(); | 380 int dstPixelBytesPerRow = info.bytesPerPixel() * parsedOptions.cropRect.
width(); |
| 286 if (cropRect == IntRect(IntPoint(), data->size())) { | 381 if (parsedOptions.cropRect == IntRect(IntPoint(), data->size())) { |
| 287 swizzleImageData(srcAddr, srcHeight, srcPixelBytesPerRow, flipY); | 382 swizzleImageData(srcAddr, srcHeight, srcPixelBytesPerRow, parsedOpti
ons.flipY); |
| 288 m_image = StaticBitmapImage::create(fromSkSp(SkImage::MakeRasterCopy
(SkPixmap(info, srcAddr, dstPixelBytesPerRow)))); | 383 m_image = StaticBitmapImage::create(fromSkSp(SkImage::MakeRasterCopy
(SkPixmap(info, srcAddr, dstPixelBytesPerRow)))); |
| 289 // restore the original ImageData | 384 // restore the original ImageData |
| 290 swizzleImageData(srcAddr, srcHeight, srcPixelBytesPerRow, flipY); | 385 swizzleImageData(srcAddr, srcHeight, srcPixelBytesPerRow, parsedOpti
ons.flipY); |
| 291 } else { | 386 } else { |
| 292 std::unique_ptr<uint8_t[]> copiedDataBuffer = wrapArrayUnique(new ui
nt8_t[dstHeight * dstPixelBytesPerRow]()); | 387 std::unique_ptr<uint8_t[]> copiedDataBuffer = wrapArrayUnique(new ui
nt8_t[dstHeight * dstPixelBytesPerRow]()); |
| 293 if (!srcRect.isEmpty()) { | 388 if (!srcRect.isEmpty()) { |
| 294 IntPoint srcPoint = IntPoint((cropRect.x() > 0) ? cropRect.x() :
0, (cropRect.y() > 0) ? cropRect.y() : 0); | 389 IntPoint srcPoint = IntPoint((parsedOptions.cropRect.x() > 0) ?
parsedOptions.cropRect.x() : 0, (parsedOptions.cropRect.y() > 0) ? parsedOptions
.cropRect.y() : 0); |
| 295 IntPoint dstPoint = IntPoint((cropRect.x() >= 0) ? 0 : -cropRect
.x(), (cropRect.y() >= 0) ? 0 : -cropRect.y()); | 390 IntPoint dstPoint = IntPoint((parsedOptions.cropRect.x() >= 0) ?
0 : -parsedOptions.cropRect.x(), (parsedOptions.cropRect.y() >= 0) ? 0 : -parse
dOptions.cropRect.y()); |
| 296 int copyHeight = srcHeight - srcPoint.y(); | 391 int copyHeight = srcHeight - srcPoint.y(); |
| 297 if (cropRect.height() < copyHeight) | 392 if (parsedOptions.cropRect.height() < copyHeight) |
| 298 copyHeight = cropRect.height(); | 393 copyHeight = parsedOptions.cropRect.height(); |
| 299 int copyWidth = data->size().width() - srcPoint.x(); | 394 int copyWidth = data->size().width() - srcPoint.x(); |
| 300 if (cropRect.width() < copyWidth) | 395 if (parsedOptions.cropRect.width() < copyWidth) |
| 301 copyWidth = cropRect.width(); | 396 copyWidth = parsedOptions.cropRect.width(); |
| 302 for (int i = 0; i < copyHeight; i++) { | 397 for (int i = 0; i < copyHeight; i++) { |
| 303 int srcStartCopyPosition = (i + srcPoint.y()) * srcPixelByte
sPerRow + srcPoint.x() * info.bytesPerPixel(); | 398 int srcStartCopyPosition = (i + srcPoint.y()) * srcPixelByte
sPerRow + srcPoint.x() * info.bytesPerPixel(); |
| 304 int srcEndCopyPosition = srcStartCopyPosition + copyWidth *
info.bytesPerPixel(); | 399 int srcEndCopyPosition = srcStartCopyPosition + copyWidth *
info.bytesPerPixel(); |
| 305 int dstStartCopyPosition; | 400 int dstStartCopyPosition; |
| 306 if (flipY) | 401 if (parsedOptions.flipY) |
| 307 dstStartCopyPosition = (dstHeight -1 - dstPoint.y() - i)
* dstPixelBytesPerRow + dstPoint.x() * info.bytesPerPixel(); | 402 dstStartCopyPosition = (dstHeight -1 - dstPoint.y() - i)
* dstPixelBytesPerRow + dstPoint.x() * info.bytesPerPixel(); |
| 308 else | 403 else |
| 309 dstStartCopyPosition = (dstPoint.y() + i) * dstPixelByte
sPerRow + dstPoint.x() * info.bytesPerPixel(); | 404 dstStartCopyPosition = (dstPoint.y() + i) * dstPixelByte
sPerRow + dstPoint.x() * info.bytesPerPixel(); |
| 310 for (int j = 0; j < srcEndCopyPosition - srcStartCopyPositio
n; j++) { | 405 for (int j = 0; j < srcEndCopyPosition - srcStartCopyPositio
n; j++) { |
| 311 if (j % 4 == 0) | 406 if (j % 4 == 0) |
| 312 copiedDataBuffer[dstStartCopyPosition + j] = srcAddr
[srcStartCopyPosition + j + 2]; | 407 copiedDataBuffer[dstStartCopyPosition + j] = srcAddr
[srcStartCopyPosition + j + 2]; |
| 313 else if (j % 4 == 2) | 408 else if (j % 4 == 2) |
| 314 copiedDataBuffer[dstStartCopyPosition + j] = srcAddr
[srcStartCopyPosition + j - 2]; | 409 copiedDataBuffer[dstStartCopyPosition + j] = srcAddr
[srcStartCopyPosition + j - 2]; |
| 315 else | 410 else |
| 316 copiedDataBuffer[dstStartCopyPosition + j] = srcAddr
[srcStartCopyPosition + j]; | 411 copiedDataBuffer[dstStartCopyPosition + j] = srcAddr
[srcStartCopyPosition + j]; |
| 317 } | 412 } |
| 318 } | 413 } |
| 319 } | 414 } |
| 320 m_image = StaticBitmapImage::create(newSkImageFromRaster(info, std::
move(copiedDataBuffer), dstPixelBytesPerRow)); | 415 m_image = StaticBitmapImage::create(newSkImageFromRaster(info, std::
move(copiedDataBuffer), dstPixelBytesPerRow)); |
| 321 } | 416 } |
| 322 m_image->setPremultiplied(premultiplyAlpha); | 417 m_image->setPremultiplied(parsedOptions.premultiplyAlpha); |
| 323 return; | 418 return; |
| 324 } | 419 } |
| 325 | 420 |
| 326 std::unique_ptr<ImageBuffer> buffer = ImageBuffer::create(cropRect.size(), N
onOpaque, DoNotInitializeImagePixels); | 421 std::unique_ptr<ImageBuffer> buffer = ImageBuffer::create(parsedOptions.crop
Rect.size(), NonOpaque, DoNotInitializeImagePixels); |
| 327 if (!buffer) | 422 if (!buffer) |
| 328 return; | 423 return; |
| 329 | 424 |
| 330 if (srcRect.isEmpty()) { | 425 if (srcRect.isEmpty()) { |
| 331 m_image = StaticBitmapImage::create(buffer->newSkImageSnapshot(PreferNoA
cceleration, SnapshotReasonUnknown)); | 426 m_image = StaticBitmapImage::create(buffer->newSkImageSnapshot(PreferNoA
cceleration, SnapshotReasonUnknown)); |
| 332 return; | 427 return; |
| 333 } | 428 } |
| 334 | 429 |
| 335 IntPoint dstPoint = IntPoint(std::min(0, -cropRect.x()), std::min(0, -cropRe
ct.y())); | 430 IntPoint dstPoint = IntPoint(std::min(0, -parsedOptions.cropRect.x()), std::
min(0, -parsedOptions.cropRect.y())); |
| 336 if (cropRect.x() < 0) | 431 if (parsedOptions.cropRect.x() < 0) |
| 337 dstPoint.setX(-cropRect.x()); | 432 dstPoint.setX(-parsedOptions.cropRect.x()); |
| 338 if (cropRect.y() < 0) | 433 if (parsedOptions.cropRect.y() < 0) |
| 339 dstPoint.setY(-cropRect.y()); | 434 dstPoint.setY(-parsedOptions.cropRect.y()); |
| 340 buffer->putByteArray(Unmultiplied, data->data()->data(), data->size(), srcRe
ct, dstPoint); | 435 buffer->putByteArray(Unmultiplied, data->data()->data(), data->size(), srcRe
ct, dstPoint); |
| 341 if (flipY) | 436 if (parsedOptions.flipY) |
| 342 m_image = StaticBitmapImage::create(flipSkImageVertically(buffer->newSkI
mageSnapshot(PreferNoAcceleration, SnapshotReasonUnknown).get(), PremultiplyAlph
a)); | 437 m_image = StaticBitmapImage::create(flipSkImageVertically(buffer->newSkI
mageSnapshot(PreferNoAcceleration, SnapshotReasonUnknown).get(), PremultiplyAlph
a)); |
| 343 else | 438 else |
| 344 m_image = StaticBitmapImage::create(buffer->newSkImageSnapshot(PreferNoA
cceleration, SnapshotReasonUnknown)); | 439 m_image = StaticBitmapImage::create(buffer->newSkImageSnapshot(PreferNoA
cceleration, SnapshotReasonUnknown)); |
| 345 } | 440 } |
| 346 | 441 |
| 347 ImageBitmap::ImageBitmap(ImageBitmap* bitmap, const IntRect& cropRect, const Ima
geBitmapOptions& options) | 442 ImageBitmap::ImageBitmap(ImageBitmap* bitmap, Optional<IntRect> cropRect, const
ImageBitmapOptions& options) |
| 348 { | 443 { |
| 349 bool flipY; | 444 RefPtr<Image> input = bitmap->bitmapImage(); |
| 350 bool premultiplyAlpha; | 445 if (!input) |
| 351 parseOptions(options, flipY, premultiplyAlpha); | 446 return; |
| 352 m_image = cropImage(bitmap->bitmapImage(), cropRect, flipY, premultiplyAlpha
, bitmap->isPremultiplied() ? PremultiplyAlpha : DontPremultiplyAlpha); | 447 ParsedOptions parsedOptions = parseOptions(options, cropRect, input->size())
; |
| 448 |
| 449 m_image = cropImage(input.get(), parsedOptions, bitmap->isPremultiplied() ?
PremultiplyAlpha : DontPremultiplyAlpha); |
| 353 if (!m_image) | 450 if (!m_image) |
| 354 return; | 451 return; |
| 355 m_image->setOriginClean(bitmap->originClean()); | 452 m_image->setOriginClean(bitmap->originClean()); |
| 356 m_image->setPremultiplied(premultiplyAlpha); | 453 m_image->setPremultiplied(parsedOptions.premultiplyAlpha); |
| 357 } | 454 } |
| 358 | 455 |
| 359 ImageBitmap::ImageBitmap(PassRefPtr<StaticBitmapImage> image, const IntRect& cro
pRect, const ImageBitmapOptions& options) | 456 ImageBitmap::ImageBitmap(PassRefPtr<StaticBitmapImage> image, Optional<IntRect>
cropRect, const ImageBitmapOptions& options) |
| 360 { | 457 { |
| 361 bool flipY; | 458 bool originClean = image->originClean(); |
| 362 bool premultiplyAlpha; | 459 RefPtr<Image> input = image; |
| 363 parseOptions(options, flipY, premultiplyAlpha); | 460 ParsedOptions parsedOptions = parseOptions(options, cropRect, input->size())
; |
| 364 m_image = cropImage(image.get(), cropRect, flipY, premultiplyAlpha, DontPrem
ultiplyAlpha); | 461 |
| 462 m_image = cropImage(input.get(), parsedOptions, DontPremultiplyAlpha); |
| 365 if (!m_image) | 463 if (!m_image) |
| 366 return; | 464 return; |
| 367 m_image->setOriginClean(image->originClean()); | 465 m_image->setOriginClean(originClean); |
| 368 m_image->setPremultiplied(premultiplyAlpha); | 466 m_image->setPremultiplied(parsedOptions.premultiplyAlpha); |
| 369 } | 467 } |
| 370 | 468 |
| 371 ImageBitmap::ImageBitmap(PassRefPtr<StaticBitmapImage> image) | 469 ImageBitmap::ImageBitmap(PassRefPtr<StaticBitmapImage> image) |
| 372 { | 470 { |
| 373 m_image = image; | 471 m_image = image; |
| 374 } | 472 } |
| 375 | 473 |
| 376 ImageBitmap::ImageBitmap(WebExternalTextureMailbox& mailbox) | 474 ImageBitmap::ImageBitmap(WebExternalTextureMailbox& mailbox) |
| 377 { | 475 { |
| 378 m_image = StaticBitmapImage::create(mailbox); | 476 m_image = StaticBitmapImage::create(mailbox); |
| 379 } | 477 } |
| 380 | 478 |
| 381 PassRefPtr<StaticBitmapImage> ImageBitmap::transfer() | 479 PassRefPtr<StaticBitmapImage> ImageBitmap::transfer() |
| 382 { | 480 { |
| 383 ASSERT(!isNeutered()); | 481 ASSERT(!isNeutered()); |
| 384 m_isNeutered = true; | 482 m_isNeutered = true; |
| 385 return m_image.release(); | 483 return m_image.release(); |
| 386 } | 484 } |
| 387 | 485 |
| 388 ImageBitmap::~ImageBitmap() | 486 ImageBitmap::~ImageBitmap() |
| 389 { | 487 { |
| 390 } | 488 } |
| 391 | 489 |
| 392 ImageBitmap* ImageBitmap::create(HTMLImageElement* image, const IntRect& cropRec
t, Document* document, const ImageBitmapOptions& options) | 490 ImageBitmap* ImageBitmap::create(HTMLImageElement* image, Optional<IntRect> crop
Rect, Document* document, const ImageBitmapOptions& options) |
| 393 { | 491 { |
| 394 IntRect normalizedCropRect = normalizeRect(cropRect); | 492 return new ImageBitmap(image, cropRect, document, options); |
| 395 return new ImageBitmap(image, normalizedCropRect, document, options); | |
| 396 } | 493 } |
| 397 | 494 |
| 398 ImageBitmap* ImageBitmap::create(HTMLVideoElement* video, const IntRect& cropRec
t, Document* document, const ImageBitmapOptions& options) | 495 ImageBitmap* ImageBitmap::create(HTMLVideoElement* video, Optional<IntRect> crop
Rect, Document* document, const ImageBitmapOptions& options) |
| 399 { | 496 { |
| 400 IntRect normalizedCropRect = normalizeRect(cropRect); | 497 return new ImageBitmap(video, cropRect, document, options); |
| 401 return new ImageBitmap(video, normalizedCropRect, document, options); | |
| 402 } | 498 } |
| 403 | 499 |
| 404 ImageBitmap* ImageBitmap::create(HTMLCanvasElement* canvas, const IntRect& cropR
ect, const ImageBitmapOptions& options) | 500 ImageBitmap* ImageBitmap::create(HTMLCanvasElement* canvas, Optional<IntRect> cr
opRect, const ImageBitmapOptions& options) |
| 405 { | 501 { |
| 406 IntRect normalizedCropRect = normalizeRect(cropRect); | 502 return new ImageBitmap(canvas, cropRect, options); |
| 407 return new ImageBitmap(canvas, normalizedCropRect, options); | |
| 408 } | 503 } |
| 409 | 504 |
| 410 ImageBitmap* ImageBitmap::create(ImageData* data, const IntRect& cropRect, const
ImageBitmapOptions& options) | 505 ImageBitmap* ImageBitmap::create(ImageData* data, Optional<IntRect> cropRect, co
nst ImageBitmapOptions& options) |
| 411 { | 506 { |
| 412 IntRect normalizedCropRect = normalizeRect(cropRect); | 507 return new ImageBitmap(data, cropRect, options); |
| 413 return new ImageBitmap(data, normalizedCropRect, options); | |
| 414 } | 508 } |
| 415 | 509 |
| 416 ImageBitmap* ImageBitmap::create(ImageBitmap* bitmap, const IntRect& cropRect, c
onst ImageBitmapOptions& options) | 510 ImageBitmap* ImageBitmap::create(ImageBitmap* bitmap, Optional<IntRect> cropRect
, const ImageBitmapOptions& options) |
| 417 { | 511 { |
| 418 IntRect normalizedCropRect = normalizeRect(cropRect); | 512 return new ImageBitmap(bitmap, cropRect, options); |
| 419 return new ImageBitmap(bitmap, normalizedCropRect, options); | |
| 420 } | 513 } |
| 421 | 514 |
| 422 ImageBitmap* ImageBitmap::create(PassRefPtr<StaticBitmapImage> image, const IntR
ect& cropRect, const ImageBitmapOptions& options) | 515 ImageBitmap* ImageBitmap::create(PassRefPtr<StaticBitmapImage> image, Optional<I
ntRect> cropRect, const ImageBitmapOptions& options) |
| 423 { | 516 { |
| 424 IntRect normalizedCropRect = normalizeRect(cropRect); | 517 return new ImageBitmap(image, cropRect, options); |
| 425 return new ImageBitmap(image, normalizedCropRect, options); | |
| 426 } | 518 } |
| 427 | 519 |
| 428 ImageBitmap* ImageBitmap::create(PassRefPtr<StaticBitmapImage> image) | 520 ImageBitmap* ImageBitmap::create(PassRefPtr<StaticBitmapImage> image) |
| 429 { | 521 { |
| 430 return new ImageBitmap(image); | 522 return new ImageBitmap(image); |
| 431 } | 523 } |
| 432 | 524 |
| 433 ImageBitmap* ImageBitmap::create(WebExternalTextureMailbox& mailbox) | 525 ImageBitmap* ImageBitmap::create(WebExternalTextureMailbox& mailbox) |
| 434 { | 526 { |
| 435 return new ImageBitmap(mailbox); | 527 return new ImageBitmap(mailbox); |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 483 } | 575 } |
| 484 | 576 |
| 485 IntSize ImageBitmap::size() const | 577 IntSize ImageBitmap::size() const |
| 486 { | 578 { |
| 487 if (!m_image) | 579 if (!m_image) |
| 488 return IntSize(); | 580 return IntSize(); |
| 489 ASSERT(m_image->width() > 0 && m_image->height() > 0); | 581 ASSERT(m_image->width() > 0 && m_image->height() > 0); |
| 490 return IntSize(m_image->width(), m_image->height()); | 582 return IntSize(m_image->width(), m_image->height()); |
| 491 } | 583 } |
| 492 | 584 |
| 493 ScriptPromise ImageBitmap::createImageBitmap(ScriptState* scriptState, EventTarg
et& eventTarget, int sx, int sy, int sw, int sh, const ImageBitmapOptions& optio
ns, ExceptionState& exceptionState) | 585 ScriptPromise ImageBitmap::createImageBitmap(ScriptState* scriptState, EventTarg
et& eventTarget, Optional<IntRect> cropRect, const ImageBitmapOptions& options,
ExceptionState& exceptionState) |
| 494 { | 586 { |
| 495 if (!sw || !sh) { | 587 if ((cropRect && !isSourceSizeValid(cropRect->width(), cropRect->height(), e
xceptionState)) |
| 496 exceptionState.throwDOMException(IndexSizeError, String::format("The sou
rce %s provided is 0.", sw ? "height" : "width")); | 588 || !isSourceSizeValid(width(), height(), exceptionState)) |
| 497 return ScriptPromise(); | 589 return ScriptPromise(); |
| 498 } | 590 if (!isResizeOptionValid(options, exceptionState)) |
| 499 return ImageBitmapSource::fulfillImageBitmap(scriptState, create(this, IntRe
ct(sx, sy, sw, sh), options)); | 591 return ScriptPromise(); |
| 500 } | 592 return ImageBitmapSource::fulfillImageBitmap(scriptState, create(this, cropR
ect, options)); |
| 501 | |
| 502 void ImageBitmap::parseOptions(const ImageBitmapOptions& options, bool& flipY, b
ool& premultiplyAlpha) | |
| 503 { | |
| 504 if (options.imageOrientation() == imageOrientationFlipY) { | |
| 505 flipY = true; | |
| 506 } else { | |
| 507 flipY = false; | |
| 508 ASSERT(options.imageOrientation() == imageBitmapOptionNone); | |
| 509 } | |
| 510 if (options.premultiplyAlpha() == imageBitmapOptionNone) { | |
| 511 premultiplyAlpha = false; | |
| 512 } else { | |
| 513 premultiplyAlpha = true; | |
| 514 ASSERT(options.premultiplyAlpha() == "default" || options.premultiplyAlp
ha() == "premultiply"); | |
| 515 } | |
| 516 } | 593 } |
| 517 | 594 |
| 518 PassRefPtr<Image> ImageBitmap::getSourceImageForCanvas(SourceImageStatus* status
, AccelerationHint, SnapshotReason, const FloatSize&) const | 595 PassRefPtr<Image> ImageBitmap::getSourceImageForCanvas(SourceImageStatus* status
, AccelerationHint, SnapshotReason, const FloatSize&) const |
| 519 { | 596 { |
| 520 *status = NormalSourceImageStatus; | 597 *status = NormalSourceImageStatus; |
| 521 return m_image ? m_image : nullptr; | 598 return m_image ? m_image : nullptr; |
| 522 } | 599 } |
| 523 | 600 |
| 524 void ImageBitmap::adjustDrawRects(FloatRect* srcRect, FloatRect* dstRect) const | 601 void ImageBitmap::adjustDrawRects(FloatRect* srcRect, FloatRect* dstRect) const |
| 525 { | 602 { |
| 526 } | 603 } |
| 527 | 604 |
| 528 FloatSize ImageBitmap::elementSize(const FloatSize&) const | 605 FloatSize ImageBitmap::elementSize(const FloatSize&) const |
| 529 { | 606 { |
| 530 return FloatSize(width(), height()); | 607 return FloatSize(width(), height()); |
| 531 } | 608 } |
| 532 | 609 |
| 533 DEFINE_TRACE(ImageBitmap) | 610 DEFINE_TRACE(ImageBitmap) |
| 534 { | 611 { |
| 535 } | 612 } |
| 536 | 613 |
| 537 } // namespace blink | 614 } // namespace blink |
| OLD | NEW |