Color BitmapImage::singlePixelSolidColor() { // If the image size is not available yet or if the image will be animating don't use the solid color optimization. if (frameCount() != 1) return Color(); if (m_solidColor) return m_solidColor.value(); // If the frame image is not loaded, first use the decoder to get the size of the image. if (!haveFrameImageAtIndex(0) && m_source.frameSizeAtIndex(0, 0) != IntSize(1, 1)) { m_solidColor = Color(); return m_solidColor.value(); } // Cache the frame image. The size will be calculated from the NativeImagePtr. if (!ensureFrameIsCached(0)) return Color(); ASSERT(m_frames.size()); m_solidColor = NativeImage::singlePixelSolidColor(m_frames[0].m_image.get()); ASSERT(m_solidColor); return m_solidColor.value(); }
void BitmapImage::checkForSolidColor() { m_checkedForSolidColor = true; m_isSolidColor = false; if (frameCount() > 1) return; if (!haveFrameImageAtIndex(0)) { IntSize size = m_source.frameSizeAtIndex(0, 0); if (size.width() != 1 || size.height() != 1) return; if (!ensureFrameIsCached(0)) return; } CGImageRef image = nullptr; if (m_frames.size()) image = m_frames[0].m_image.get(); if (!image) return; // Currently we only check for solid color in the important special case of a 1x1 image. if (CGImageGetWidth(image) == 1 && CGImageGetHeight(image) == 1) { unsigned char pixel[4]; // RGBA RetainPtr<CGContextRef> bitmapContext = adoptCF(CGBitmapContextCreate(pixel, 1, 1, 8, sizeof(pixel), sRGBColorSpaceRef(), kCGImageAlphaPremultipliedLast | kCGBitmapByteOrder32Big)); if (!bitmapContext) return; GraphicsContext(bitmapContext.get()).setCompositeOperation(CompositeCopy); CGRect destinationRect = CGRectMake(0, 0, 1, 1); CGContextDrawImage(bitmapContext.get(), destinationRect, image); if (!pixel[3]) m_solidColor = Color(0, 0, 0, 0); else m_solidColor = Color(pixel[0] * 255 / pixel[3], pixel[1] * 255 / pixel[3], pixel[2] * 255 / pixel[3], pixel[3]); m_isSolidColor = true; } }