[Qt] Set WebCore imagedecoders as default and add fallback to QImageDecoder
[WebKit-https.git] / Source / WebCore / platform / graphics / ImageSource.cpp
1 /*
2  * Copyright (C) 2006 Apple Computer, Inc.  All rights reserved.
3  * Copyright (C) 2007 Alp Toker <alp.toker@collabora.co.uk>
4  * Copyright (C) 2008, Google Inc. All rights reserved.
5  * Copyright (C) 2007-2009 Torch Mobile, Inc
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  * 1. Redistributions of source code must retain the above copyright
11  *    notice, this list of conditions and the following disclaimer.
12  * 2. Redistributions in binary form must reproduce the above copyright
13  *    notice, this list of conditions and the following disclaimer in the
14  *    documentation and/or other materials provided with the distribution.
15  *
16  * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
17  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
19  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
20  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
21  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
22  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
23  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
24  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27  */
28
29 #include "config.h"
30 #include "ImageSource.h"
31
32 #include "ImageDecoder.h"
33
34 #include "ImageOrientation.h"
35 #include "NotImplemented.h"
36
37 namespace WebCore {
38
39 #if ENABLE(IMAGE_DECODER_DOWN_SAMPLING)
40 unsigned ImageSource::s_maxPixelsPerDecodedImage = 1024 * 1024;
41 #endif
42
43 ImageSource::ImageSource(ImageSource::AlphaOption alphaOption, ImageSource::GammaAndColorProfileOption gammaAndColorProfileOption)
44     : m_decoder(0)
45     , m_alphaOption(alphaOption)
46     , m_gammaAndColorProfileOption(gammaAndColorProfileOption)
47 {
48 }
49
50 ImageSource::~ImageSource()
51 {
52     clear(true);
53 }
54
55 void ImageSource::clear(bool destroyAll, size_t clearBeforeFrame, SharedBuffer* data, bool allDataReceived)
56 {
57     if (!destroyAll) {
58         if (m_decoder)
59             m_decoder->clearFrameBufferCache(clearBeforeFrame);
60         return;
61     }
62
63     delete m_decoder;
64     m_decoder = 0;
65     if (data)
66         setData(data, allDataReceived);
67 }
68
69 bool ImageSource::initialized() const
70 {
71     return m_decoder;
72 }
73
74 void ImageSource::setData(SharedBuffer* data, bool allDataReceived)
75 {
76     // Make the decoder by sniffing the bytes.
77     // This method will examine the data and instantiate an instance of the appropriate decoder plugin.
78     // If insufficient bytes are available to determine the image type, no decoder plugin will be
79     // made.
80     if (!m_decoder) {
81         m_decoder = static_cast<NativeImageSourcePtr>(ImageDecoder::create(*data, m_alphaOption, m_gammaAndColorProfileOption));
82 #if ENABLE(IMAGE_DECODER_DOWN_SAMPLING)
83         if (m_decoder && s_maxPixelsPerDecodedImage)
84             m_decoder->setMaxNumPixels(s_maxPixelsPerDecodedImage);
85 #endif
86     }
87
88     if (m_decoder)
89         m_decoder->setData(data, allDataReceived);
90 }
91
92 String ImageSource::filenameExtension() const
93 {
94     return m_decoder ? m_decoder->filenameExtension() : String();
95 }
96
97 bool ImageSource::isSizeAvailable()
98 {
99     return m_decoder && m_decoder->isSizeAvailable();
100 }
101
102 IntSize ImageSource::size(RespectImageOrientationEnum shouldRespectOrientation) const
103 {
104     // The JPEG and TIFF decoders need to be taught how to read EXIF, XMP, or IPTC data.
105     if (shouldRespectOrientation == RespectImageOrientation)
106         notImplemented();
107
108     return m_decoder ? m_decoder->size() : IntSize();
109 }
110
111 IntSize ImageSource::frameSizeAtIndex(size_t index, RespectImageOrientationEnum shouldRespectOrientation) const
112 {
113     // The JPEG and TIFF decoders need to be taught how to read EXIF, XMP, or IPTC data.
114     if (shouldRespectOrientation == RespectImageOrientation)
115         notImplemented();
116
117     return m_decoder ? m_decoder->frameSizeAtIndex(index) : IntSize();
118 }
119
120 bool ImageSource::getHotSpot(IntPoint&) const
121 {
122     return false;
123 }
124
125 size_t ImageSource::bytesDecodedToDetermineProperties() const
126 {
127     return 0;
128 }
129
130 int ImageSource::repetitionCount()
131 {
132     return m_decoder ? m_decoder->repetitionCount() : cAnimationNone;
133 }
134
135 size_t ImageSource::frameCount() const
136 {
137     return m_decoder ? m_decoder->frameCount() : 0;
138 }
139
140 NativeImagePtr ImageSource::createFrameAtIndex(size_t index)
141 {
142     if (!m_decoder)
143         return 0;
144
145     ImageFrame* buffer = m_decoder->frameBufferAtIndex(index);
146     if (!buffer || buffer->status() == ImageFrame::FrameEmpty)
147         return 0;
148
149     // Zero-height images can cause problems for some ports.  If we have an
150     // empty image dimension, just bail.
151     if (size().isEmpty())
152         return 0;
153
154     // Return the buffer contents as a native image.  For some ports, the data
155     // is already in a native container, and this just increments its refcount.
156     return buffer->asNewNativeImage();
157 }
158
159 float ImageSource::frameDurationAtIndex(size_t index)
160 {
161     if (!m_decoder)
162         return 0;
163
164     ImageFrame* buffer = m_decoder->frameBufferAtIndex(index);
165     if (!buffer || buffer->status() == ImageFrame::FrameEmpty)
166         return 0;
167
168     // Many annoying ads specify a 0 duration to make an image flash as quickly as possible.
169     // We follow Firefox's behavior and use a duration of 100 ms for any frames that specify
170     // a duration of <= 10 ms. See <rdar://problem/7689300> and <http://webkit.org/b/36082>
171     // for more information.
172     const float duration = buffer->duration() / 1000.0f;
173     if (duration < 0.011f)
174         return 0.100f;
175     return duration;
176 }
177
178 ImageOrientation ImageSource::orientationAtIndex(size_t index) const
179 {
180     // The JPEG and TIFF decoders need to be taught how to read EXIF, XMP, or IPTC data.
181     notImplemented();
182     return DefaultImageOrientation;
183 }
184
185 bool ImageSource::frameHasAlphaAtIndex(size_t index)
186 {
187     // When a frame has not finished decoding, always mark it as having alpha.
188     // Ports that check the result of this function to determine their
189     // compositing op need this in order to not draw the undecoded portion as
190     // black.
191     // TODO: Perhaps we should ensure that each individual decoder returns true
192     // in this case.
193     return !frameIsCompleteAtIndex(index)
194         || m_decoder->frameBufferAtIndex(index)->hasAlpha();
195 }
196
197 bool ImageSource::frameIsCompleteAtIndex(size_t index)
198 {
199     if (!m_decoder)
200         return false;
201
202     ImageFrame* buffer = m_decoder->frameBufferAtIndex(index);
203     return buffer && buffer->status() == ImageFrame::FrameComplete;
204 }
205
206 }