490c2a8a8c5e32168842e5d18dc4e210d2acb886
[WebKit-https.git] / WebCore / platform / graphics / qt / ImageSourceQt.cpp
1 /*
2  * Copyright (C) 2006 Apple Computer, Inc.  All rights reserved. 
3  * Copyright (C) 2006 Dirk Mueller <mueller@kde.org>
4  * Copyright (C) 2006 Zack Rusin <zack@kde.org>
5  *
6  * All rights reserved.
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions
10  * are met:
11  * 1. Redistributions of source code must retain the above copyright
12  *    notice, this list of conditions and the following disclaimer.
13  * 2. Redistributions in binary form must reproduce the above copyright
14  *    notice, this list of conditions and the following disclaimer in the
15  *    documentation and/or other materials provided with the distribution.
16  *
17  * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
18  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
20  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
21  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
22  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
23  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
24  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
25  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
27  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28  */
29
30 #include "config.h"
31 #include "ImageSource.h"
32
33 #include "GIFImageDecoder.h"
34 #include "JPEGImageDecoder.h"
35 #include "PNGImageDecoder.h"
36 #include "BMPImageDecoder.h"
37 #include "ICOImageDecoder.h"
38 #include "XBMImageDecoder.h"
39
40 #include <QImage>
41
42 namespace WebCore {
43
44 ImageDecoder* createDecoder(const Vector<char>& data)
45 {
46     // We need at least 4 bytes to figure out what kind of image we're dealing with.
47     int length = data.size();
48     if (length < 4)
49         return 0;
50
51     const unsigned char* uContents = (const unsigned char*) data.data();
52     const char* contents = data.data();
53
54     // GIFs begin with GIF8(7 or 9).
55     if (strncmp(contents, "GIF8", 4) == 0)
56         return new GIFImageDecoder();
57
58     // Test for PNG.
59     if (uContents[0] == 0x89 &&
60         uContents[1] == 0x50 &&
61         uContents[2] == 0x4E &&
62         uContents[3] == 0x47)
63         return new PNGImageDecoder();
64
65     // JPEG
66     if (uContents[0] == 0xFF &&
67         uContents[1] == 0xD8 &&
68         uContents[2] == 0xFF)
69         return new JPEGImageDecoder();
70
71     // BMP
72     if (strncmp(contents, "BM", 2) == 0)
73         return new BMPImageDecoder();
74
75     // ICOs always begin with a 2-byte 0 followed by a 2-byte 1.
76     // CURs begin with 2-byte 0 followed by 2-byte 2.
77     if (!memcmp(contents, "\000\000\001\000", 4) ||
78         !memcmp(contents, "\000\000\002\000", 4))
79         return new ICOImageDecoder();
80
81     // XBMs require 8 bytes of info.
82     if (length >= 8 && strncmp(contents, "#define ", 8) == 0)
83         return new XBMImageDecoder();
84
85     // Give up. We don't know what the heck this is.
86     return 0;
87 }
88
89 ImageSource::ImageSource()
90     : m_decoder(0)
91 {
92 }
93
94 ImageSource::~ImageSource()
95 {
96     delete m_decoder;
97 }
98
99 bool ImageSource::initialized() const
100 {
101     return m_decoder;
102 }
103
104 void ImageSource::setData(const Vector<char>* data, bool allDataReceived)
105 {
106     // Make the decoder by sniffing the bytes.
107     // This method will examine the data and instantiate an instance of the appropriate decoder plugin.
108     // If insufficient bytes are available to determine the image type, no decoder plugin will be
109     // made.
110     m_decoder = createDecoder(*data);
111
112     if (!m_decoder)
113         return;
114
115     m_decoder->setData(*data, allDataReceived);
116 }
117
118 bool ImageSource::isSizeAvailable()
119 {
120     if (!m_decoder)
121         return false;
122
123     return m_decoder->isSizeAvailable();
124 }
125
126 IntSize ImageSource::size() const
127 {
128     if (!m_decoder)
129         return IntSize();
130
131     return m_decoder->size();
132 }
133
134 int ImageSource::repetitionCount()
135 {
136     if (!m_decoder)
137         return cAnimationNone;
138
139     return m_decoder->repetitionCount();
140 }
141
142 size_t ImageSource::frameCount() const
143 {
144     if (!m_decoder)
145         return 0;
146
147     return m_decoder->frameCount();
148 }
149
150 NativeImagePtr ImageSource::createFrameAtIndex(size_t index)
151 {
152     if (!m_decoder)
153         return 0;
154
155     RGBA32Buffer* buffer = m_decoder->frameBufferAtIndex(index);
156     if (!buffer || buffer->status() == RGBA32Buffer::FrameEmpty)
157         return 0;
158
159     return new QImage(reinterpret_cast<unsigned char*>(buffer->bytes().data()),
160                       size().width(), buffer->height(),
161                       QImage::Format_ARGB32);
162 }
163
164 float ImageSource::frameDurationAtIndex(size_t index)
165 {
166     if (!m_decoder)
167         return 0;
168
169     RGBA32Buffer* buffer = m_decoder->frameBufferAtIndex(index);
170     if (!buffer || buffer->status() == RGBA32Buffer::FrameEmpty)
171         return 0;
172
173     return buffer->duration() / 1000.0f;
174 }
175
176 bool ImageSource::frameHasAlphaAtIndex(size_t index)
177 {
178     if (!m_decoder || !m_decoder->supportsAlpha())
179         return false;
180
181     RGBA32Buffer* buffer = m_decoder->frameBufferAtIndex(index);
182     if (!buffer || buffer->status() == RGBA32Buffer::FrameEmpty)
183         return false;
184
185     return buffer->hasAlpha();
186 }
187
188 }
189
190 // vim: ts=4 sw=4 et