Fix for <rdar://problem/5585334>
[WebKit-https.git] / WebCore / platform / graphics / cg / ImageBufferCG.cpp
1 /*
2  * Copyright (C) 2006 Nikolas Zimmermann <zimmermann@kde.org>
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 COMPUTER, INC. ``AS IS'' AND ANY
14  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
17  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
24  */
25
26 #include "config.h"
27 #include "ImageBuffer.h"
28
29 #include "GraphicsContext.h"
30
31 #include <ApplicationServices/ApplicationServices.h>
32 #include <wtf/Assertions.h>
33
34 using namespace std;
35
36 namespace WebCore {
37
38 auto_ptr<ImageBuffer> ImageBuffer::create(const IntSize& size, bool grayScale)
39 {
40     if (size.width() <= 0 || size.height() <= 0)
41         return auto_ptr<ImageBuffer>();        
42     unsigned int bytesPerRow = size.width();
43     if (!grayScale) {
44         // Protect against overflow
45         if (bytesPerRow > 0x3FFFFFFF)
46             return auto_ptr<ImageBuffer>();            
47         bytesPerRow *= 4;
48     }
49
50     void* imageBuffer = fastCalloc(size.height(), bytesPerRow);
51     if (!imageBuffer)
52         return auto_ptr<ImageBuffer>();
53     
54     CGColorSpaceRef colorSpace = grayScale ? CGColorSpaceCreateDeviceGray() : CGColorSpaceCreateDeviceRGB();
55     CGContextRef cgContext = CGBitmapContextCreate(imageBuffer, size.width(), size.height(), 8, bytesPerRow,
56         colorSpace, grayScale ? kCGImageAlphaNone : kCGImageAlphaPremultipliedLast);
57     CGColorSpaceRelease(colorSpace);
58     if (!cgContext) {
59         fastFree(imageBuffer);
60         return auto_ptr<ImageBuffer>();
61     }
62
63     auto_ptr<GraphicsContext> context(new GraphicsContext(cgContext));
64     CGContextRelease(cgContext);
65     
66     return auto_ptr<ImageBuffer>(new ImageBuffer(imageBuffer, size, context));
67 }
68
69
70 ImageBuffer::ImageBuffer(void* imageData, const IntSize& size, auto_ptr<GraphicsContext> context)
71     : m_data(imageData)
72     , m_size(size)
73     , m_context(context.release())
74     , m_cgImage(0)
75 {
76 }
77
78 ImageBuffer::~ImageBuffer()
79 {
80     fastFree(m_data);
81     CGImageRelease(m_cgImage);
82 }
83
84 GraphicsContext* ImageBuffer::context() const
85 {
86     return m_context.get();
87 }
88
89 CGImageRef ImageBuffer::cgImage() const
90 {
91     // It's assumed that if cgImage() is called, the actual rendering to the
92     // contained GraphicsContext must be done, as we create the CGImageRef here.
93     if (!m_cgImage) {
94         ASSERT(context());
95         m_cgImage = CGBitmapContextCreateImage(context()->platformContext());
96     }
97
98     return m_cgImage;
99 }
100
101 }