Index: third_party/WebKit/Source/platform/image-decoders/ImageFrame.cpp |
diff --git a/third_party/WebKit/Source/platform/image-decoders/ImageFrame.cpp b/third_party/WebKit/Source/platform/image-decoders/ImageFrame.cpp |
index 152d0506ce717645e0cc5f4300a14f5d194740b3..3bb6a3eeb043fd889b0d85e678e2388964f883a4 100644 |
--- a/third_party/WebKit/Source/platform/image-decoders/ImageFrame.cpp |
+++ b/third_party/WebKit/Source/platform/image-decoders/ImageFrame.cpp |
@@ -170,6 +170,49 @@ void ImageFrame::zeroFillFrameRect(const IntRect& rect) { |
setHasAlpha(true); |
} |
+static uint8_t blendChannel(uint8_t src, |
+ uint8_t srcA, |
+ uint8_t dst, |
+ uint8_t dstA, |
+ unsigned scale) { |
+ unsigned blendUnscaled = src * srcA + dst * dstA; |
+ DCHECK(blendUnscaled < (1ULL << 32) / scale); |
+ return (blendUnscaled * scale) >> 24; |
+} |
+ |
+static uint32_t blendSrcOverDstNonPremultiplied(uint32_t src, uint32_t dst) { |
+ uint8_t srcA = SkGetPackedA32(src); |
+ if (srcA == 0) |
+ return dst; |
+ |
+ uint8_t dstA = SkGetPackedA32(dst); |
+ uint8_t dstFactorA = (dstA * SkAlpha255To256(255 - srcA)) >> 8; |
+ DCHECK(srcA + dstFactorA < (1U << 8)); |
+ uint8_t blendA = srcA + dstFactorA; |
+ unsigned scale = (1UL << 24) / blendA; |
+ |
+ uint8_t blendR = blendChannel(SkGetPackedR32(src), srcA, SkGetPackedR32(dst), |
+ dstFactorA, scale); |
+ uint8_t blendG = blendChannel(SkGetPackedG32(src), srcA, SkGetPackedG32(dst), |
+ dstFactorA, scale); |
+ uint8_t blendB = blendChannel(SkGetPackedB32(src), srcA, SkGetPackedB32(dst), |
+ dstFactorA, scale); |
+ |
+ return SkPackARGB32NoCheck(blendA, blendR, blendG, blendB); |
+} |
+ |
+void ImageFrame::blendRGBARaw(PixelData* dest, |
+ unsigned r, |
+ unsigned g, |
+ unsigned b, |
+ unsigned a) { |
+ *dest = blendSrcOverDstNonPremultiplied(SkPackARGB32NoCheck(a, r, g, b), *dest); |
+} |
+ |
+void ImageFrame::blendSrcOverDstRaw(PixelData* src, PixelData dst) { |
+ *src = blendSrcOverDstNonPremultiplied(*src, dst); |
+} |
+ |
SkAlphaType ImageFrame::computeAlphaType() const { |
// If the frame is not fully loaded, there will be transparent pixels, |
// so we can't tell skia we're opaque, even for image types that logically |