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

Side by Side 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 unified diff | Download patch
OLDNEW
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
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
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
OLDNEW
« 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