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

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"
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after
110 SkBitmap bitmap = frame->bitmap(); 110 SkBitmap bitmap = frame->bitmap();
111 if (!frameIsValid(bitmap)) 111 if (!frameIsValid(bitmap))
112 return nullptr; 112 return nullptr;
113 return fromSkSp(SkImage::MakeFromBitmap(bitmap)); 113 return fromSkSp(SkImage::MakeFromBitmap(bitmap));
114 } 114 }
115 115
116 // The parameter imageFormat indicates whether the first parameter "image" is un premultiplied or not. 116 // The parameter imageFormat indicates whether the first parameter "image" is un premultiplied or not.
117 // imageFormat = PremultiplyAlpha means the image is in premuliplied format 117 // 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 118 // 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. 119 // 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) 120 static PassRefPtr<StaticBitmapImage> cropImage(Image* image, IntRect& cropRect, bool flipY, bool premultiplyAlpha, AlphaDisposition imageFormat = PremultiplyAlp ha, ImageDecoder::GammaAndColorProfileOption colorSpaceOp = ImageDecoder::GammaA ndColorProfileApplied)
121 { 121 {
122 ASSERT(image); 122 ASSERT(image);
123 123
124 IntRect imgRect(IntPoint(), IntSize(image->width(), image->height())); 124 IntRect imgRect(IntPoint(), IntSize(image->width(), image->height()));
125 const IntRect srcRect = intersection(imgRect, cropRect); 125 const IntRect srcRect = intersection(imgRect, cropRect);
126 126
127 // In the case when cropRect doesn't intersect the source image and it requi res a umpremul image 127 // 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() 128 // We immediately return a transparent black image with cropRect.size()
129 if (srcRect.isEmpty() && !premultiplyAlpha) { 129 if (srcRect.isEmpty() && !premultiplyAlpha) {
130 SkImageInfo info = SkImageInfo::Make(cropRect.width(), cropRect.height() , kN32_SkColorType, kUnpremul_SkAlphaType); 130 SkImageInfo info = SkImageInfo::Make(cropRect.width(), cropRect.height() , kN32_SkColorType, kUnpremul_SkAlphaType);
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
176 skiaImage = flipSkImageVertically(skiaImage.get(), PremultiplyAlpha); 176 skiaImage = flipSkImageVertically(skiaImage.get(), PremultiplyAlpha);
177 177
178 if (premultiplyAlpha) { 178 if (premultiplyAlpha) {
179 if (imageFormat == PremultiplyAlpha) 179 if (imageFormat == PremultiplyAlpha)
180 return StaticBitmapImage::create(unPremulSkImageToPremul(skiaImage.g et())); 180 return StaticBitmapImage::create(unPremulSkImageToPremul(skiaImage.g et()));
181 return StaticBitmapImage::create(skiaImage.release()); 181 return StaticBitmapImage::create(skiaImage.release());
182 } 182 }
183 return StaticBitmapImage::create(premulSkImageToUnPremul(skiaImage.get())); 183 return StaticBitmapImage::create(premulSkImageToUnPremul(skiaImage.get()));
184 } 184 }
185 185
186 ImageBitmap::ImageBitmap(HTMLImageElement* image, const IntRect& cropRect, Docum ent* document, const ImageBitmapOptions& options) 186 static PassRefPtr<Image> scaleInputAndCropRect(Image* input, IntRect& cropRect, unsigned resizeWidth, unsigned resizeHeight, SkFilterQuality resizeQuality)
187 { 187 {
188 bool flipY; 188 if (cropRect.x() == 0 && cropRect.y() == 0 && cropRect.width() == input->wid th() && cropRect.height() == input->height()) {
189 bool premultiplyAlpha; 189 cropRect.setWidth(resizeWidth);
jbroman 2016/06/30 18:52:34 Hmm. It seems you're setting parameters to use for
xidachen 2016/07/07 13:48:47 Done. The scale && crop are in cropImage(), and it
190 parseOptions(options, flipY, premultiplyAlpha); 190 cropRect.setHeight(resizeHeight);
191 }
192
193 RefPtr<SkImage> skiaImage = input->imageForCurrentFrame();
194 sk_sp<SkSurface> surface = SkSurface::MakeRasterN32Premul(resizeWidth, resiz eHeight);
195 SkRect srcRect = SkRect::MakeIWH(input->width(), input->height());
196 SkRect dstRect = SkRect::MakeIWH(resizeWidth, resizeHeight);
197 SkPaint paint;
198 paint.setFilterQuality(resizeQuality);
199 surface->getCanvas()->drawImageRect(skiaImage.get(), srcRect, dstRect, &pain t);
jbroman 2016/06/30 18:52:34 You should also clear the canvas to transparent be
xidachen 2016/07/07 13:48:47 This is not needed as SkSurface::MakeRaster() does
200 return StaticBitmapImage::create(fromSkSp(surface->makeImageSnapshot()));
201 }
202
203 ImageBitmap::ImageBitmap(HTMLImageElement* image, IntRect& cropRect, Document* d ocument, const ImageBitmapOptions& options)
204 {
205 RefPtr<Image> input = image->cachedImage()->getImage();
206 ParsedOptions parsedOptions = parseOptions(options, input->width(), input->h eight());
207 if (parsedOptions.shouldScaleInput)
208 input = scaleInputAndCropRect(input.get(), cropRect, parsedOptions.resiz eWidth, parsedOptions.resizeHeight, parsedOptions.resizeQuality);
191 209
192 if (options.colorSpaceConversion() == "none") 210 if (options.colorSpaceConversion() == "none")
193 m_image = cropImage(image->cachedImage()->getImage(), cropRect, flipY, p remultiplyAlpha, PremultiplyAlpha, ImageDecoder::GammaAndColorProfileIgnored); 211 m_image = cropImage(input.get(), cropRect, parsedOptions.flipY, parsedOp tions.premultiplyAlpha, PremultiplyAlpha, ImageDecoder::GammaAndColorProfileIgno red);
194 else 212 else
195 m_image = cropImage(image->cachedImage()->getImage(), cropRect, flipY, p remultiplyAlpha, PremultiplyAlpha, ImageDecoder::GammaAndColorProfileApplied); 213 m_image = cropImage(input.get(), cropRect, parsedOptions.flipY, parsedOp tions.premultiplyAlpha, PremultiplyAlpha, ImageDecoder::GammaAndColorProfileAppl ied);
196 if (!m_image) 214 if (!m_image)
197 return; 215 return;
198 // In the case where the source image is lazy-decoded, m_image may not be in 216 // In the case where the source image is lazy-decoded, m_image may not be in
199 // a decoded state, we trigger it here. 217 // a decoded state, we trigger it here.
200 RefPtr<SkImage> skImage = m_image->imageForCurrentFrame(); 218 RefPtr<SkImage> skImage = m_image->imageForCurrentFrame();
201 SkPixmap pixmap; 219 SkPixmap pixmap;
202 if (!skImage->isTextureBacked() && !skImage->peekPixels(&pixmap)) { 220 if (!skImage->isTextureBacked() && !skImage->peekPixels(&pixmap)) {
203 sk_sp<SkSurface> surface = SkSurface::MakeRasterN32Premul(skImage->width (), skImage->height()); 221 sk_sp<SkSurface> surface = SkSurface::MakeRasterN32Premul(skImage->width (), skImage->height());
204 surface->getCanvas()->drawImage(skImage.get(), 0, 0); 222 surface->getCanvas()->drawImage(skImage.get(), 0, 0);
205 m_image = StaticBitmapImage::create(fromSkSp(surface->makeImageSnapshot( ))); 223 m_image = StaticBitmapImage::create(fromSkSp(surface->makeImageSnapshot( )));
206 } 224 }
207 m_image->setOriginClean(!image->wouldTaintOrigin(document->getSecurityOrigin ())); 225 m_image->setOriginClean(!image->wouldTaintOrigin(document->getSecurityOrigin ()));
208 m_image->setPremultiplied(premultiplyAlpha); 226 m_image->setPremultiplied(parsedOptions.premultiplyAlpha);
209 } 227 }
210 228
211 ImageBitmap::ImageBitmap(HTMLVideoElement* video, const IntRect& cropRect, Docum ent* document, const ImageBitmapOptions& options) 229 ImageBitmap::ImageBitmap(HTMLVideoElement* video, IntRect& cropRect, Document* d ocument, const ImageBitmapOptions& options)
212 { 230 {
213 IntSize playerSize; 231 IntSize playerSize;
214 if (video->webMediaPlayer()) 232 if (video->webMediaPlayer())
215 playerSize = video->webMediaPlayer()->naturalSize(); 233 playerSize = video->webMediaPlayer()->naturalSize();
216 234
217 IntRect videoRect = IntRect(IntPoint(), playerSize); 235 IntRect videoRect = IntRect(IntPoint(), playerSize);
218 IntRect srcRect = intersection(cropRect, videoRect); 236 IntRect srcRect = intersection(cropRect, videoRect);
219 std::unique_ptr<ImageBuffer> buffer = ImageBuffer::create(cropRect.size(), N onOpaque, DoNotInitializeImagePixels); 237 std::unique_ptr<ImageBuffer> buffer = ImageBuffer::create(cropRect.size(), N onOpaque, DoNotInitializeImagePixels);
220 if (!buffer) 238 if (!buffer)
221 return; 239 return;
222 240
223 IntPoint dstPoint = IntPoint(std::max(0, -cropRect.x()), std::max(0, -cropRe ct.y())); 241 IntPoint dstPoint = IntPoint(std::max(0, -cropRect.x()), std::max(0, -cropRe ct.y()));
224 video->paintCurrentFrame(buffer->canvas(), IntRect(dstPoint, srcRect.size()) , nullptr); 242 video->paintCurrentFrame(buffer->canvas(), IntRect(dstPoint, srcRect.size()) , nullptr);
225 243
226 bool flipY; 244 // TODO(xidachen); implement the resize option.
227 bool premultiplyAlpha; 245 ParsedOptions parsedOptions = parseOptions(options, playerSize.width(), play erSize.height());
228 parseOptions(options, flipY, premultiplyAlpha);
229 246
230 if (flipY || !premultiplyAlpha) { 247 if (parsedOptions.flipY || !parsedOptions.premultiplyAlpha) {
231 RefPtr<SkImage> skiaImage = buffer->newSkImageSnapshot(PreferNoAccelerat ion, SnapshotReasonUnknown); 248 RefPtr<SkImage> skiaImage = buffer->newSkImageSnapshot(PreferNoAccelerat ion, SnapshotReasonUnknown);
232 if (flipY) 249 if (parsedOptions.flipY)
233 skiaImage = flipSkImageVertically(skiaImage.get(), PremultiplyAlpha) ; 250 skiaImage = flipSkImageVertically(skiaImage.get(), PremultiplyAlpha) ;
234 if (!premultiplyAlpha) 251 if (!parsedOptions.premultiplyAlpha)
235 skiaImage = premulSkImageToUnPremul(skiaImage.get()); 252 skiaImage = premulSkImageToUnPremul(skiaImage.get());
236 m_image = StaticBitmapImage::create(skiaImage.release()); 253 m_image = StaticBitmapImage::create(skiaImage.release());
237 } else { 254 } else {
238 m_image = StaticBitmapImage::create(buffer->newSkImageSnapshot(PreferNoA cceleration, SnapshotReasonUnknown)); 255 m_image = StaticBitmapImage::create(buffer->newSkImageSnapshot(PreferNoA cceleration, SnapshotReasonUnknown));
239 } 256 }
240 m_image->setOriginClean(!video->wouldTaintOrigin(document->getSecurityOrigin ())); 257 m_image->setOriginClean(!video->wouldTaintOrigin(document->getSecurityOrigin ()));
241 m_image->setPremultiplied(premultiplyAlpha); 258 m_image->setPremultiplied(parsedOptions.premultiplyAlpha);
242 } 259 }
243 260
244 ImageBitmap::ImageBitmap(HTMLCanvasElement* canvas, const IntRect& cropRect, con st ImageBitmapOptions& options) 261 ImageBitmap::ImageBitmap(HTMLCanvasElement* canvas, IntRect& cropRect, const Ima geBitmapOptions& options)
245 { 262 {
246 ASSERT(canvas->isPaintable()); 263 ASSERT(canvas->isPaintable());
247 bool flipY; 264 RefPtr<Image> input = canvas->copiedImage(BackBuffer, PreferAcceleration);
248 bool premultiplyAlpha; 265 ParsedOptions parsedOptions = parseOptions(options, input->width(), input->h eight());
249 parseOptions(options, flipY, premultiplyAlpha); 266 if (parsedOptions.shouldScaleInput)
267 input = scaleInputAndCropRect(input.get(), cropRect, parsedOptions.resiz eWidth, parsedOptions.resizeHeight, parsedOptions.resizeQuality);
250 268
251 // canvas is always premultiplied, so set the last parameter to true and con vert to un-premul later 269 // canvas is always premultiplied, so set the last parameter to true and con vert to un-premul later
252 m_image = cropImage(canvas->copiedImage(BackBuffer, PreferAcceleration).get( ), cropRect, flipY, true); 270 m_image = cropImage(input.get(), cropRect, parsedOptions.flipY, true);
253 if (!m_image) 271 if (!m_image)
254 return; 272 return;
255 if (!premultiplyAlpha) 273 if (!parsedOptions.premultiplyAlpha)
256 m_image = StaticBitmapImage::create(premulSkImageToUnPremul(m_image->ima geForCurrentFrame().get())); 274 m_image = StaticBitmapImage::create(premulSkImageToUnPremul(m_image->ima geForCurrentFrame().get()));
257 m_image->setOriginClean(canvas->originClean()); 275 m_image->setOriginClean(canvas->originClean());
258 m_image->setPremultiplied(premultiplyAlpha); 276 m_image->setPremultiplied(parsedOptions.premultiplyAlpha);
259 } 277 }
260 278
261 // The last two parameters are used for structure-cloning. 279 // The last two parameters are used for structure-cloning.
262 ImageBitmap::ImageBitmap(ImageData* data, const IntRect& cropRect, const ImageBi tmapOptions& options, const bool& isImageDataPremultiplied, const bool& isImageD ataOriginClean) 280 ImageBitmap::ImageBitmap(ImageData* data, IntRect& cropRect, const ImageBitmapOp tions& options, const bool& isImageDataPremultiplied, const bool& isImageDataOri ginClean)
263 { 281 {
264 bool flipY; 282 // TODO(xidachen): implement the resize option
265 bool premultiplyAlpha; 283 ParsedOptions parsedOptions = parseOptions(options, data->width(), data->hei ght());
266 parseOptions(options, flipY, premultiplyAlpha);
267 IntRect srcRect = intersection(cropRect, IntRect(IntPoint(), data->size())); 284 IntRect srcRect = intersection(cropRect, IntRect(IntPoint(), data->size()));
268 285
269 // treat non-premultiplyAlpha as a special case 286 // treat non-premultiplyAlpha as a special case
270 if (!premultiplyAlpha) { 287 if (!parsedOptions.premultiplyAlpha) {
271 unsigned char* srcAddr = data->data()->data(); 288 unsigned char* srcAddr = data->data()->data();
272 int srcHeight = data->size().height(); 289 int srcHeight = data->size().height();
273 int dstHeight = cropRect.height(); 290 int dstHeight = cropRect.height();
274 // TODO (xidachen): skia doesn't support SkImage::NewRasterCopy from a k RGBA color type. 291 // TODO (xidachen): skia doesn't support SkImage::NewRasterCopy from a k RGBA color type.
275 // For now, we swap R and B channel and uses kBGRA color type. 292 // For now, we swap R and B channel and uses kBGRA color type.
276 SkImageInfo info; 293 SkImageInfo info;
277 if (!isImageDataPremultiplied) 294 if (!isImageDataPremultiplied)
278 info = SkImageInfo::Make(cropRect.width(), dstHeight, kBGRA_8888_SkC olorType, kUnpremul_SkAlphaType); 295 info = SkImageInfo::Make(cropRect.width(), dstHeight, kBGRA_8888_SkC olorType, kUnpremul_SkAlphaType);
279 else 296 else
280 info = SkImageInfo::Make(cropRect.width(), dstHeight, kBGRA_8888_SkC olorType, kPremul_SkAlphaType); 297 info = SkImageInfo::Make(cropRect.width(), dstHeight, kBGRA_8888_SkC olorType, kPremul_SkAlphaType);
281 int srcPixelBytesPerRow = info.bytesPerPixel() * data->size().width(); 298 int srcPixelBytesPerRow = info.bytesPerPixel() * data->size().width();
282 int dstPixelBytesPerRow = info.bytesPerPixel() * cropRect.width(); 299 int dstPixelBytesPerRow = info.bytesPerPixel() * cropRect.width();
283 if (cropRect == IntRect(IntPoint(), data->size())) { 300 if (cropRect == IntRect(IntPoint(), data->size())) {
284 swizzleImageData(srcAddr, srcHeight, srcPixelBytesPerRow, flipY); 301 swizzleImageData(srcAddr, srcHeight, srcPixelBytesPerRow, parsedOpti ons.flipY);
285 m_image = StaticBitmapImage::create(fromSkSp(SkImage::MakeRasterCopy (SkPixmap(info, srcAddr, dstPixelBytesPerRow)))); 302 m_image = StaticBitmapImage::create(fromSkSp(SkImage::MakeRasterCopy (SkPixmap(info, srcAddr, dstPixelBytesPerRow))));
286 // restore the original ImageData 303 // restore the original ImageData
287 swizzleImageData(srcAddr, srcHeight, srcPixelBytesPerRow, flipY); 304 swizzleImageData(srcAddr, srcHeight, srcPixelBytesPerRow, parsedOpti ons.flipY);
288 } else { 305 } else {
289 std::unique_ptr<uint8_t[]> copiedDataBuffer = wrapArrayUnique(new ui nt8_t[dstHeight * dstPixelBytesPerRow]()); 306 std::unique_ptr<uint8_t[]> copiedDataBuffer = wrapArrayUnique(new ui nt8_t[dstHeight * dstPixelBytesPerRow]());
290 if (!srcRect.isEmpty()) { 307 if (!srcRect.isEmpty()) {
291 IntPoint srcPoint = IntPoint((cropRect.x() > 0) ? cropRect.x() : 0, (cropRect.y() > 0) ? cropRect.y() : 0); 308 IntPoint srcPoint = IntPoint((cropRect.x() > 0) ? cropRect.x() : 0, (cropRect.y() > 0) ? cropRect.y() : 0);
292 IntPoint dstPoint = IntPoint((cropRect.x() >= 0) ? 0 : -cropRect .x(), (cropRect.y() >= 0) ? 0 : -cropRect.y()); 309 IntPoint dstPoint = IntPoint((cropRect.x() >= 0) ? 0 : -cropRect .x(), (cropRect.y() >= 0) ? 0 : -cropRect.y());
293 int copyHeight = srcHeight - srcPoint.y(); 310 int copyHeight = srcHeight - srcPoint.y();
294 if (cropRect.height() < copyHeight) 311 if (cropRect.height() < copyHeight)
295 copyHeight = cropRect.height(); 312 copyHeight = cropRect.height();
296 int copyWidth = data->size().width() - srcPoint.x(); 313 int copyWidth = data->size().width() - srcPoint.x();
297 if (cropRect.width() < copyWidth) 314 if (cropRect.width() < copyWidth)
298 copyWidth = cropRect.width(); 315 copyWidth = cropRect.width();
299 for (int i = 0; i < copyHeight; i++) { 316 for (int i = 0; i < copyHeight; i++) {
300 int srcStartCopyPosition = (i + srcPoint.y()) * srcPixelByte sPerRow + srcPoint.x() * info.bytesPerPixel(); 317 int srcStartCopyPosition = (i + srcPoint.y()) * srcPixelByte sPerRow + srcPoint.x() * info.bytesPerPixel();
301 int srcEndCopyPosition = srcStartCopyPosition + copyWidth * info.bytesPerPixel(); 318 int srcEndCopyPosition = srcStartCopyPosition + copyWidth * info.bytesPerPixel();
302 int dstStartCopyPosition; 319 int dstStartCopyPosition;
303 if (flipY) 320 if (parsedOptions.flipY)
304 dstStartCopyPosition = (dstHeight -1 - dstPoint.y() - i) * dstPixelBytesPerRow + dstPoint.x() * info.bytesPerPixel(); 321 dstStartCopyPosition = (dstHeight -1 - dstPoint.y() - i) * dstPixelBytesPerRow + dstPoint.x() * info.bytesPerPixel();
305 else 322 else
306 dstStartCopyPosition = (dstPoint.y() + i) * dstPixelByte sPerRow + dstPoint.x() * info.bytesPerPixel(); 323 dstStartCopyPosition = (dstPoint.y() + i) * dstPixelByte sPerRow + dstPoint.x() * info.bytesPerPixel();
307 for (int j = 0; j < srcEndCopyPosition - srcStartCopyPositio n; j++) { 324 for (int j = 0; j < srcEndCopyPosition - srcStartCopyPositio n; j++) {
308 if (j % 4 == 0) 325 if (j % 4 == 0)
309 copiedDataBuffer[dstStartCopyPosition + j] = srcAddr [srcStartCopyPosition + j + 2]; 326 copiedDataBuffer[dstStartCopyPosition + j] = srcAddr [srcStartCopyPosition + j + 2];
310 else if (j % 4 == 2) 327 else if (j % 4 == 2)
311 copiedDataBuffer[dstStartCopyPosition + j] = srcAddr [srcStartCopyPosition + j - 2]; 328 copiedDataBuffer[dstStartCopyPosition + j] = srcAddr [srcStartCopyPosition + j - 2];
312 else 329 else
313 copiedDataBuffer[dstStartCopyPosition + j] = srcAddr [srcStartCopyPosition + j]; 330 copiedDataBuffer[dstStartCopyPosition + j] = srcAddr [srcStartCopyPosition + j];
314 } 331 }
315 } 332 }
316 } 333 }
317 m_image = StaticBitmapImage::create(newSkImageFromRaster(info, std:: move(copiedDataBuffer), dstPixelBytesPerRow)); 334 m_image = StaticBitmapImage::create(newSkImageFromRaster(info, std:: move(copiedDataBuffer), dstPixelBytesPerRow));
318 } 335 }
319 m_image->setPremultiplied(premultiplyAlpha); 336 m_image->setPremultiplied(parsedOptions.premultiplyAlpha);
320 m_image->setOriginClean(isImageDataOriginClean); 337 m_image->setOriginClean(isImageDataOriginClean);
321 return; 338 return;
322 } 339 }
323 340
324 std::unique_ptr<ImageBuffer> buffer = ImageBuffer::create(cropRect.size(), N onOpaque, DoNotInitializeImagePixels); 341 std::unique_ptr<ImageBuffer> buffer = ImageBuffer::create(cropRect.size(), N onOpaque, DoNotInitializeImagePixels);
325 if (!buffer) 342 if (!buffer)
326 return; 343 return;
327 344
328 if (srcRect.isEmpty()) { 345 if (srcRect.isEmpty()) {
329 m_image = StaticBitmapImage::create(buffer->newSkImageSnapshot(PreferNoA cceleration, SnapshotReasonUnknown)); 346 m_image = StaticBitmapImage::create(buffer->newSkImageSnapshot(PreferNoA cceleration, SnapshotReasonUnknown));
330 return; 347 return;
331 } 348 }
332 349
333 IntPoint dstPoint = IntPoint(std::min(0, -cropRect.x()), std::min(0, -cropRe ct.y())); 350 IntPoint dstPoint = IntPoint(std::min(0, -cropRect.x()), std::min(0, -cropRe ct.y()));
334 if (cropRect.x() < 0) 351 if (cropRect.x() < 0)
335 dstPoint.setX(-cropRect.x()); 352 dstPoint.setX(-cropRect.x());
336 if (cropRect.y() < 0) 353 if (cropRect.y() < 0)
337 dstPoint.setY(-cropRect.y()); 354 dstPoint.setY(-cropRect.y());
338 buffer->putByteArray(Unmultiplied, data->data()->data(), data->size(), srcRe ct, dstPoint); 355 buffer->putByteArray(Unmultiplied, data->data()->data(), data->size(), srcRe ct, dstPoint);
339 if (flipY) 356 if (parsedOptions.flipY)
340 m_image = StaticBitmapImage::create(flipSkImageVertically(buffer->newSkI mageSnapshot(PreferNoAcceleration, SnapshotReasonUnknown).get(), PremultiplyAlph a)); 357 m_image = StaticBitmapImage::create(flipSkImageVertically(buffer->newSkI mageSnapshot(PreferNoAcceleration, SnapshotReasonUnknown).get(), PremultiplyAlph a));
341 else 358 else
342 m_image = StaticBitmapImage::create(buffer->newSkImageSnapshot(PreferNoA cceleration, SnapshotReasonUnknown)); 359 m_image = StaticBitmapImage::create(buffer->newSkImageSnapshot(PreferNoA cceleration, SnapshotReasonUnknown));
343 } 360 }
344 361
345 ImageBitmap::ImageBitmap(ImageBitmap* bitmap, const IntRect& cropRect, const Ima geBitmapOptions& options) 362 ImageBitmap::ImageBitmap(ImageBitmap* bitmap, IntRect& cropRect, const ImageBitm apOptions& options)
346 { 363 {
347 bool flipY; 364 RefPtr<Image> input = bitmap->bitmapImage();
348 bool premultiplyAlpha; 365 ParsedOptions parsedOptions = parseOptions(options, input->width(), input->h eight());
349 parseOptions(options, flipY, premultiplyAlpha); 366 if (parsedOptions.shouldScaleInput)
jbroman 2016/06/30 18:52:34 Could the next few lines be bundles into function
xidachen 2016/07/07 13:48:47 Done.
350 m_image = cropImage(bitmap->bitmapImage(), cropRect, flipY, premultiplyAlpha , bitmap->isPremultiplied() ? PremultiplyAlpha : DontPremultiplyAlpha); 367 input = scaleInputAndCropRect(input.get(), cropRect, parsedOptions.resiz eWidth, parsedOptions.resizeHeight, parsedOptions.resizeQuality);
368
369 m_image = cropImage(input.get(), cropRect, parsedOptions.flipY, parsedOption s.premultiplyAlpha, bitmap->isPremultiplied() ? PremultiplyAlpha : DontPremultip lyAlpha);
351 if (!m_image) 370 if (!m_image)
352 return; 371 return;
353 m_image->setOriginClean(bitmap->originClean()); 372 m_image->setOriginClean(bitmap->originClean());
354 m_image->setPremultiplied(premultiplyAlpha); 373 m_image->setPremultiplied(parsedOptions.premultiplyAlpha);
355 } 374 }
356 375
357 ImageBitmap::ImageBitmap(PassRefPtr<StaticBitmapImage> image, const IntRect& cro pRect, const ImageBitmapOptions& options) 376 ImageBitmap::ImageBitmap(PassRefPtr<StaticBitmapImage> image, IntRect& cropRect, const ImageBitmapOptions& options)
358 { 377 {
359 bool flipY; 378 bool originClean = image->originClean();
360 bool premultiplyAlpha; 379 RefPtr<Image> input = image;
361 parseOptions(options, flipY, premultiplyAlpha); 380 ParsedOptions parsedOptions = parseOptions(options, input->width(), input->h eight());
362 m_image = cropImage(image.get(), cropRect, flipY, premultiplyAlpha, DontPrem ultiplyAlpha); 381 if (parsedOptions.shouldScaleInput)
382 input = scaleInputAndCropRect(input.get(), cropRect, parsedOptions.resiz eWidth, parsedOptions.resizeHeight, parsedOptions.resizeQuality);
383
384 m_image = cropImage(input.get(), cropRect, parsedOptions.flipY, parsedOption s.premultiplyAlpha, DontPremultiplyAlpha);
363 if (!m_image) 385 if (!m_image)
364 return; 386 return;
365 m_image->setOriginClean(image->originClean()); 387 m_image->setOriginClean(originClean);
366 m_image->setPremultiplied(premultiplyAlpha); 388 m_image->setPremultiplied(parsedOptions.premultiplyAlpha);
367 } 389 }
368 390
369 ImageBitmap::ImageBitmap(PassRefPtr<StaticBitmapImage> image) 391 ImageBitmap::ImageBitmap(PassRefPtr<StaticBitmapImage> image)
370 { 392 {
371 m_image = image; 393 m_image = image;
372 } 394 }
373 395
374 ImageBitmap::ImageBitmap(WebExternalTextureMailbox& mailbox) 396 ImageBitmap::ImageBitmap(WebExternalTextureMailbox& mailbox)
375 { 397 {
376 m_image = StaticBitmapImage::create(mailbox); 398 m_image = StaticBitmapImage::create(mailbox);
(...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after
485 507
486 ScriptPromise ImageBitmap::createImageBitmap(ScriptState* scriptState, EventTarg et& eventTarget, int sx, int sy, int sw, int sh, const ImageBitmapOptions& optio ns, ExceptionState& exceptionState) 508 ScriptPromise ImageBitmap::createImageBitmap(ScriptState* scriptState, EventTarg et& eventTarget, int sx, int sy, int sw, int sh, const ImageBitmapOptions& optio ns, ExceptionState& exceptionState)
487 { 509 {
488 if (!sw || !sh) { 510 if (!sw || !sh) {
489 exceptionState.throwDOMException(IndexSizeError, String::format("The sou rce %s provided is 0.", sw ? "height" : "width")); 511 exceptionState.throwDOMException(IndexSizeError, String::format("The sou rce %s provided is 0.", sw ? "height" : "width"));
490 return ScriptPromise(); 512 return ScriptPromise();
491 } 513 }
492 return ImageBitmapSource::fulfillImageBitmap(scriptState, create(this, IntRe ct(sx, sy, sw, sh), options)); 514 return ImageBitmapSource::fulfillImageBitmap(scriptState, create(this, IntRe ct(sx, sy, sw, sh), options));
493 } 515 }
494 516
495 void ImageBitmap::parseOptions(const ImageBitmapOptions& options, bool& flipY, b ool& premultiplyAlpha) 517 ParsedOptions ImageBitmap::parseOptions(const ImageBitmapOptions& options, const int width, const int height)
496 { 518 {
519 ParsedOptions parsedOptions;
497 if (options.imageOrientation() == imageOrientationFlipY) { 520 if (options.imageOrientation() == imageOrientationFlipY) {
498 flipY = true; 521 parsedOptions.flipY = true;
499 } else { 522 } else {
500 flipY = false; 523 parsedOptions.flipY = false;
501 ASSERT(options.imageOrientation() == imageBitmapOptionNone); 524 ASSERT(options.imageOrientation() == imageBitmapOptionNone);
502 } 525 }
503 if (options.premultiplyAlpha() == imageBitmapOptionNone) { 526 if (options.premultiplyAlpha() == imageBitmapOptionNone) {
504 premultiplyAlpha = false; 527 parsedOptions.premultiplyAlpha = false;
505 } else { 528 } else {
506 premultiplyAlpha = true; 529 parsedOptions.premultiplyAlpha = true;
507 ASSERT(options.premultiplyAlpha() == "default" || options.premultiplyAlp ha() == "premultiply"); 530 ASSERT(options.premultiplyAlpha() == "default" || options.premultiplyAlp ha() == "premultiply");
508 } 531 }
532
533 parsedOptions.shouldScaleInput = false;
534 if (!options.hasResizeWidth() && !options.hasResizeHeight())
535 return parsedOptions;
536 if (options.hasResizeWidth() && options.hasResizeHeight()) {
537 parsedOptions.resizeWidth = options.resizeWidth();
jbroman 2016/06/30 18:52:34 What happens if one or both of these is specified,
xidachen 2016/07/07 13:48:47 Spec has been changed, now an exception is thrown
538 parsedOptions.resizeHeight = options.resizeHeight();
539 } else if (options.hasResizeWidth() && !options.hasResizeHeight()) {
540 parsedOptions.resizeWidth = options.resizeWidth();
541 parsedOptions.resizeHeight = static_cast<unsigned>(static_cast<float>(op tions.resizeWidth()) / width * height);
jbroman 2016/06/30 18:52:34 What should be happening when the computed size ba
xidachen 2016/07/07 13:48:47 Spec has been changed, so we round up to its neare
542 } else {
543 parsedOptions.resizeHeight = options.resizeHeight();
544 parsedOptions.resizeWidth = static_cast<unsigned>(static_cast<float>(opt ions.resizeHeight()) / height * width);
545 }
546 if (static_cast<int>(parsedOptions.resizeWidth) != width || static_cast<int> (parsedOptions.resizeHeight) != height)
547 parsedOptions.shouldScaleInput = true;
548 else
549 return parsedOptions;
550
551 if (options.resizeQuality() == "high")
552 parsedOptions.resizeQuality = kHigh_SkFilterQuality;
553 else if (options.resizeQuality() == "medium")
554 parsedOptions.resizeQuality = kMedium_SkFilterQuality;
555 else if (options.resizeQuality() == "pixelated")
556 parsedOptions.resizeQuality = kNone_SkFilterQuality;
557 else
558 parsedOptions.resizeQuality = kLow_SkFilterQuality;
559 return parsedOptions;
509 } 560 }
510 561
511 PassRefPtr<Image> ImageBitmap::getSourceImageForCanvas(SourceImageStatus* status , AccelerationHint, SnapshotReason, const FloatSize&) const 562 PassRefPtr<Image> ImageBitmap::getSourceImageForCanvas(SourceImageStatus* status , AccelerationHint, SnapshotReason, const FloatSize&) const
512 { 563 {
513 *status = NormalSourceImageStatus; 564 *status = NormalSourceImageStatus;
514 return m_image ? m_image : nullptr; 565 return m_image ? m_image : nullptr;
515 } 566 }
516 567
517 void ImageBitmap::adjustDrawRects(FloatRect* srcRect, FloatRect* dstRect) const 568 void ImageBitmap::adjustDrawRects(FloatRect* srcRect, FloatRect* dstRect) const
518 { 569 {
519 } 570 }
520 571
521 FloatSize ImageBitmap::elementSize(const FloatSize&) const 572 FloatSize ImageBitmap::elementSize(const FloatSize&) const
522 { 573 {
523 return FloatSize(width(), height()); 574 return FloatSize(width(), height());
524 } 575 }
525 576
526 DEFINE_TRACE(ImageBitmap) 577 DEFINE_TRACE(ImageBitmap)
527 { 578 {
528 } 579 }
529 580
530 } // namespace blink 581 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698