ImageDecoderSkia.cpp [plain text]
#include "config.h"
#include "ImageDecoder.h"
#include "NotImplemented.h"
#if PLATFORM(CHROMIUM) && OS(DARWIN)
#include "GraphicsContextCG.h"
#include "SkCGUtils.h"
#endif
namespace WebCore {
ImageFrame::ImageFrame()
: m_status(FrameEmpty)
, m_duration(0)
, m_disposalMethod(DisposeNotSpecified)
, m_premultiplyAlpha(true)
{
}
ImageFrame& ImageFrame::operator=(const ImageFrame& other)
{
if (this == &other)
return *this;
m_bitmap = other.m_bitmap;
m_bitmap.bitmap().lockPixels();
setOriginalFrameRect(other.originalFrameRect());
setStatus(other.status());
setDuration(other.duration());
setDisposalMethod(other.disposalMethod());
setPremultiplyAlpha(other.premultiplyAlpha());
return *this;
}
void ImageFrame::clearPixelData()
{
m_bitmap.bitmap().reset();
m_status = FrameEmpty;
}
void ImageFrame::zeroFillPixelData()
{
m_bitmap.bitmap().eraseARGB(0, 0, 0, 0);
}
bool ImageFrame::copyBitmapData(const ImageFrame& other)
{
if (this == &other)
return true;
m_bitmap.bitmap().reset();
const NativeImageSkia& otherBitmap = other.m_bitmap;
return otherBitmap.bitmap().copyTo(&m_bitmap.bitmap(), otherBitmap.bitmap().config());
}
bool ImageFrame::setSize(int newWidth, int newHeight)
{
ASSERT(!width() && !height());
m_bitmap.bitmap().setConfig(SkBitmap::kARGB_8888_Config, newWidth, newHeight);
if (!m_bitmap.bitmap().allocPixels())
return false;
zeroFillPixelData();
return true;
}
NativeImagePtr ImageFrame::asNewNativeImage() const
{
return new NativeImageSkia(m_bitmap);
}
bool ImageFrame::hasAlpha() const
{
return !m_bitmap.bitmap().isOpaque();
}
void ImageFrame::setHasAlpha(bool alpha)
{
m_bitmap.bitmap().setIsOpaque(!alpha);
}
#if PLATFORM(CHROMIUM) && OS(DARWIN)
static void resolveColorSpace(const SkBitmap& bitmap, CGColorSpaceRef colorSpace)
{
int width = bitmap.width();
int height = bitmap.height();
RetainPtr<CGImageRef> srcImage(AdoptCF, SkCreateCGImageRefWithColorspace(bitmap, colorSpace));
SkAutoLockPixels lock(bitmap);
void* pixels = bitmap.getPixels();
RetainPtr<CGContextRef> cgBitmap(AdoptCF, CGBitmapContextCreate(pixels, width, height, 8, width * 4, deviceRGBColorSpaceRef(), kCGBitmapByteOrder32Host | kCGImageAlphaPremultipliedFirst));
if (!cgBitmap)
return;
CGContextSetBlendMode(cgBitmap.get(), kCGBlendModeCopy);
CGRect bounds = { {0, 0}, {width, height} };
CGContextDrawImage(cgBitmap.get(), bounds, srcImage.get());
}
static CGColorSpaceRef createColorSpace(const ColorProfile& colorProfile)
{
RetainPtr<CFDataRef> data(AdoptCF, CFDataCreate(kCFAllocatorDefault, reinterpret_cast<const UInt8*>(colorProfile.data()), colorProfile.size()));
#ifndef TARGETING_LEOPARD
return CGColorSpaceCreateWithICCProfile(data.get());
#else
RetainPtr<CGDataProviderRef> profileDataProvider(AdoptCF, CGDataProviderCreateWithCFData(data.get()));
CGFloat ranges[] = {0.0, 255.0, 0.0, 255.0, 0.0, 255.0};
return CGColorSpaceCreateICCBased(3, ranges, profileDataProvider.get(), deviceRGBColorSpaceRef());
#endif
}
#endif
void ImageFrame::setColorProfile(const ColorProfile& colorProfile)
{
#if PLATFORM(CHROMIUM) && OS(DARWIN)
m_colorProfile = colorProfile;
#else
notImplemented();
#endif
}
void ImageFrame::setStatus(FrameStatus status)
{
m_status = status;
if (m_status == FrameComplete) {
m_bitmap.setDataComplete(); #if PLATFORM(CHROMIUM) && OS(DARWIN)
if (m_colorProfile.isEmpty() || (!m_premultiplyAlpha && hasAlpha()))
return;
RetainPtr<CGColorSpaceRef> cgColorSpace(AdoptCF, createColorSpace(m_colorProfile));
resolveColorSpace(m_bitmap.bitmap(), cgColorSpace.get());
#endif
}
}
int ImageFrame::width() const
{
return m_bitmap.bitmap().width();
}
int ImageFrame::height() const
{
return m_bitmap.bitmap().height();
}
}