tagging audio streams and changing audio sink to pulseaudio
[profile/ivi/webkit-efl.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 #elif ENABLE(TIZEN_JPEG_IMAGE_SCALE_DECODING)
42 unsigned ImageSource::s_maxPixelsPerDecodedImage = 2 * 1024 * 1024; // This threshold value can be modified according to your system.
43 #endif
44
45 #if ENABLE(TIZEN_JPEGIMAGE_DECODING_THREAD)
46 static const double cSemaphoreWaitTime = std::numeric_limits<double>::max();
47 #endif
48
49 ImageSource::ImageSource(ImageSource::AlphaOption alphaOption, ImageSource::GammaAndColorProfileOption gammaAndColorProfileOption)
50     : m_decoder(0)
51     , m_alphaOption(alphaOption)
52     , m_gammaAndColorProfileOption(gammaAndColorProfileOption)
53 {
54 }
55
56 ImageSource::~ImageSource()
57 {
58     clear(true);
59 }
60
61 void ImageSource::clear(bool destroyAll, size_t clearBeforeFrame, SharedBuffer* data, bool allDataReceived)
62 {
63 #if ENABLE(TIZEN_JPEGIMAGE_DECODING_THREAD)
64     BinarySemaphore* semaphore = 0;
65
66     if (m_decoder)
67         semaphore = m_decoder->imageSemaphore();
68
69     if (semaphore)
70         semaphore->wait(cSemaphoreWaitTime);
71 #endif
72
73     if (!destroyAll) {
74         if (m_decoder)
75             m_decoder->clearFrameBufferCache(clearBeforeFrame);
76 #if ENABLE(TIZEN_JPEGIMAGE_DECODING_THREAD)
77         semaphore->signal();
78 #endif
79         return;
80     }
81
82     delete m_decoder;
83     m_decoder = 0;
84     if (data)
85         setData(data, allDataReceived);
86 }
87
88 bool ImageSource::initialized() const
89 {
90     return m_decoder;
91 }
92
93 void ImageSource::setData(SharedBuffer* data, bool allDataReceived)
94 {
95     // Make the decoder by sniffing the bytes.
96     // This method will examine the data and instantiate an instance of the appropriate decoder plugin.
97     // If insufficient bytes are available to determine the image type, no decoder plugin will be
98     // made.
99     if (!m_decoder) {
100         m_decoder = static_cast<NativeImageSourcePtr>(ImageDecoder::create(*data, m_alphaOption, m_gammaAndColorProfileOption));
101 #if ENABLE(IMAGE_DECODER_DOWN_SAMPLING) || ENABLE(TIZEN_JPEG_IMAGE_SCALE_DECODING)
102         if (m_decoder && s_maxPixelsPerDecodedImage)
103             m_decoder->setMaxNumPixels(s_maxPixelsPerDecodedImage);
104 #endif
105     }
106
107     if (m_decoder)
108         m_decoder->setData(data, allDataReceived);
109 }
110
111 String ImageSource::filenameExtension() const
112 {
113     return m_decoder ? m_decoder->filenameExtension() : String();
114 }
115
116 bool ImageSource::isSizeAvailable()
117 {
118     return m_decoder && m_decoder->isSizeAvailable();
119 }
120
121 IntSize ImageSource::size(RespectImageOrientationEnum shouldRespectOrientation) const
122 {
123     // The JPEG and TIFF decoders need to be taught how to read EXIF, XMP, or IPTC data.
124     if (shouldRespectOrientation == RespectImageOrientation)
125         notImplemented();
126
127     return m_decoder ? m_decoder->size() : IntSize();
128 }
129
130 IntSize ImageSource::frameSizeAtIndex(size_t index, RespectImageOrientationEnum shouldRespectOrientation) const
131 {
132     // The JPEG and TIFF decoders need to be taught how to read EXIF, XMP, or IPTC data.
133     if (shouldRespectOrientation == RespectImageOrientation)
134         notImplemented();
135
136     return m_decoder ? m_decoder->frameSizeAtIndex(index) : IntSize();
137 }
138
139 bool ImageSource::getHotSpot(IntPoint&) const
140 {
141     return false;
142 }
143
144 size_t ImageSource::bytesDecodedToDetermineProperties() const
145 {
146     return 0;
147 }
148
149 int ImageSource::repetitionCount()
150 {
151     return m_decoder ? m_decoder->repetitionCount() : cAnimationNone;
152 }
153
154 size_t ImageSource::frameCount() const
155 {
156     return m_decoder ? m_decoder->frameCount() : 0;
157 }
158
159 NativeImagePtr ImageSource::createFrameAtIndex(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     // Zero-height images can cause problems for some ports.  If we have an
169     // empty image dimension, just bail.
170     if (size().isEmpty())
171         return 0;
172
173     // Return the buffer contents as a native image.  For some ports, the data
174     // is already in a native container, and this just increments its refcount.
175     return buffer->asNewNativeImage();
176 }
177
178 float ImageSource::frameDurationAtIndex(size_t index)
179 {
180     if (!m_decoder)
181         return 0;
182
183     ImageFrame* buffer = m_decoder->frameBufferAtIndex(index);
184     if (!buffer || buffer->status() == ImageFrame::FrameEmpty)
185         return 0;
186
187     // Many annoying ads specify a 0 duration to make an image flash as quickly as possible.
188     // We follow Firefox's behavior and use a duration of 100 ms for any frames that specify
189     // a duration of <= 10 ms. See <rdar://problem/7689300> and <http://webkit.org/b/36082>
190     // for more information.
191     const float duration = buffer->duration() / 1000.0f;
192     if (duration < 0.011f)
193         return 0.100f;
194     return duration;
195 }
196
197 ImageOrientation ImageSource::orientationAtIndex(size_t index) const
198 {
199     // The JPEG and TIFF decoders need to be taught how to read EXIF, XMP, or IPTC data.
200     notImplemented();
201     return DefaultImageOrientation;
202 }
203
204 bool ImageSource::frameHasAlphaAtIndex(size_t index)
205 {
206     // When a frame has not finished decoding, always mark it as having alpha.
207     // Ports that check the result of this function to determine their
208     // compositing op need this in order to not draw the undecoded portion as
209     // black.
210     // TODO: Perhaps we should ensure that each individual decoder returns true
211     // in this case.
212     return !frameIsCompleteAtIndex(index)
213         || m_decoder->frameBufferAtIndex(index)->hasAlpha();
214 }
215
216 bool ImageSource::frameIsCompleteAtIndex(size_t index)
217 {
218     if (!m_decoder)
219         return false;
220
221     ImageFrame* buffer = m_decoder->frameBufferAtIndex(index);
222     return buffer && buffer->status() == ImageFrame::FrameComplete;
223 }
224
225 }