Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "core/frame/ImageBitmap.h" | 5 #include "core/frame/ImageBitmap.h" |
| 6 | 6 |
| 7 #include "core/html/HTMLCanvasElement.h" | 7 #include "core/html/HTMLCanvasElement.h" |
| 8 #include "core/html/HTMLVideoElement.h" | 8 #include "core/html/HTMLVideoElement.h" |
| 9 #include "core/html/ImageData.h" | 9 #include "core/html/ImageData.h" |
| 10 #include "platform/graphics/skia/SkiaUtils.h" | 10 #include "platform/graphics/skia/SkiaUtils.h" |
| (...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 |
| OLD | NEW |