1/* 2 * Copyright (C) 2010, 2011 Apple Inc. All rights reserved. 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions 6 * are met: 7 * 1. Redistributions of source code must retain the above copyright 8 * notice, this list of conditions and the following disclaimer. 9 * 2. Redistributions in binary form must reproduce the above copyright 10 * notice, this list of conditions and the following disclaimer in the 11 * documentation and/or other materials provided with the distribution. 12 * 13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' 14 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 15 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS 17 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 18 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 19 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 20 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 21 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 22 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 23 * THE POSSIBILITY OF SUCH DAMAGE. 24 */ 25 26#include "config.h" 27#include "ShareableBitmap.h" 28 29#include <WebCore/BitmapImage.h> 30#include <WebCore/GraphicsContext.h> 31#include <wtf/RetainPtr.h> 32#include "CGUtilities.h" 33 34using namespace WebCore; 35 36namespace WebKit { 37 38static CGBitmapInfo bitmapInfo(ShareableBitmap::Flags flags) 39{ 40 CGBitmapInfo info = kCGBitmapByteOrder32Host; 41 if (flags & ShareableBitmap::SupportsAlpha) 42 info |= kCGImageAlphaPremultipliedFirst; 43 else 44 info |= kCGImageAlphaNoneSkipFirst; 45 46 return info; 47} 48 49std::unique_ptr<GraphicsContext> ShareableBitmap::createGraphicsContext() 50{ 51 RetainPtr<CGColorSpaceRef> colorSpace = adoptCF(CGColorSpaceCreateDeviceRGB()); 52 53 ref(); // Balanced by deref in releaseBitmapContextData. 54 RetainPtr<CGContextRef> bitmapContext = adoptCF(CGBitmapContextCreateWithData(data(), 55 m_size.width(), m_size.height(), 8, m_size.width() * 4, colorSpace.get(), 56 bitmapInfo(m_flags), releaseBitmapContextData, this)); 57 58 // We want the origin to be in the top left corner so we flip the backing store context. 59 CGContextTranslateCTM(bitmapContext.get(), 0, m_size.height()); 60 CGContextScaleCTM(bitmapContext.get(), 1, -1); 61 62 return std::make_unique<GraphicsContext>(bitmapContext.get()); 63} 64 65void ShareableBitmap::paint(WebCore::GraphicsContext& context, const IntPoint& destination, const IntRect& source) 66{ 67 paintImage(context.platformContext(), makeCGImageCopy().get(), 1, destination, source); 68} 69 70void ShareableBitmap::paint(WebCore::GraphicsContext& context, float scaleFactor, const IntPoint& destination, const IntRect& source) 71{ 72 paintImage(context.platformContext(), makeCGImageCopy().get(), scaleFactor, destination, source); 73} 74 75RetainPtr<CGImageRef> ShareableBitmap::makeCGImageCopy() 76{ 77 auto graphicsContext = createGraphicsContext(); 78 RetainPtr<CGImageRef> image = adoptCF(CGBitmapContextCreateImage(graphicsContext->platformContext())); 79 return image; 80} 81 82RetainPtr<CGImageRef> ShareableBitmap::makeCGImage() 83{ 84 ref(); // Balanced by deref in releaseDataProviderData. 85 RetainPtr<CGDataProvider> dataProvider = adoptCF(CGDataProviderCreateWithData(this, data(), sizeInBytes(), releaseDataProviderData)); 86 return createCGImage(dataProvider.get()); 87} 88 89RetainPtr<CGImageRef> ShareableBitmap::createCGImage(CGDataProviderRef dataProvider) const 90{ 91 ASSERT_ARG(dataProvider, dataProvider); 92 93 RetainPtr<CGColorSpaceRef> colorSpace = adoptCF(CGColorSpaceCreateDeviceRGB()); 94 RetainPtr<CGImageRef> image = adoptCF(CGImageCreate(m_size.width(), m_size.height(), 8, 32, m_size.width() * 4, colorSpace.get(), bitmapInfo(m_flags), dataProvider, 0, false, kCGRenderingIntentDefault)); 95 return image; 96} 97 98void ShareableBitmap::releaseBitmapContextData(void* typelessBitmap, void* typelessData) 99{ 100 ShareableBitmap* bitmap = static_cast<ShareableBitmap*>(typelessBitmap); 101 ASSERT_UNUSED(typelessData, bitmap->data() == typelessData); 102 bitmap->deref(); // Balanced by ref in createGraphicsContext. 103} 104 105void ShareableBitmap::releaseDataProviderData(void* typelessBitmap, const void* typelessData, size_t) 106{ 107 ShareableBitmap* bitmap = static_cast<ShareableBitmap*>(typelessBitmap); 108 ASSERT_UNUSED(typelessData, bitmap->data() == typelessData); 109 bitmap->deref(); // Balanced by ref in createCGImage. 110} 111 112PassRefPtr<Image> ShareableBitmap::createImage() 113{ 114 RetainPtr<CGImageRef> platformImage = makeCGImage(); 115 if (!platformImage) 116 return nullptr; 117 118 return BitmapImage::create(platformImage.get()); 119} 120 121} // namespace WebKit 122