2 * Copyright (C) 2006 Apple Computer, Inc. All rights reserved.
3 * Copyright (C) Research In Motion Limited 2009-2010. All rights reserved.
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
14 * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
15 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
17 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
18 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
19 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
20 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
21 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
22 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
24 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 #ifndef ImageDecoder_h
28 #define ImageDecoder_h
30 #include "SkColorPriv.h"
31 #include "platform/PlatformExport.h"
32 #include "platform/PlatformScreen.h"
33 #include "platform/SharedBuffer.h"
34 #include "platform/graphics/ImageSource.h"
35 #include "platform/image-decoders/ImageFrame.h"
36 #include "public/platform/Platform.h"
37 #include "wtf/Assertions.h"
38 #include "wtf/RefPtr.h"
39 #include "wtf/Vector.h"
40 #include "wtf/text/WTFString.h"
46 typedef Vector<char> ColorProfile;
50 // ImagePlanes can be used to decode color components into provided buffers instead of using an ImageFrame.
51 class PLATFORM_EXPORT ImagePlanes {
54 ImagePlanes(void* planes[3], size_t rowBytes[3]);
57 size_t rowBytes(int) const;
64 // ImageDecoder is a base for all format-specific decoders
65 // (e.g. JPEGImageDecoder). This base manages the ImageFrame cache.
67 class PLATFORM_EXPORT ImageDecoder {
68 WTF_MAKE_NONCOPYABLE(ImageDecoder); WTF_MAKE_FAST_ALLOCATED;
70 enum SizeType { ActualSize, SizeForMemoryAllocation };
72 static const size_t noDecodedImageByteLimit = Platform::noDecodedImageByteLimit;
74 ImageDecoder(ImageSource::AlphaOption alphaOption, ImageSource::GammaAndColorProfileOption gammaAndColorProfileOption, size_t maxDecodedBytes)
75 : m_premultiplyAlpha(alphaOption == ImageSource::AlphaPremultiplied)
76 , m_ignoreGammaAndColorProfile(gammaAndColorProfileOption == ImageSource::GammaAndColorProfileIgnored)
77 , m_maxDecodedBytes(maxDecodedBytes)
78 , m_sizeAvailable(false)
79 , m_isAllDataReceived(false)
82 virtual ~ImageDecoder() { }
84 // Returns a caller-owned decoder of the appropriate type. Returns 0 if
85 // we can't sniff a supported type from the provided data (possibly
86 // because there isn't enough data yet).
87 // Sets m_maxDecodedBytes to Platform::maxImageDecodedBytes().
88 static PassOwnPtr<ImageDecoder> create(const SharedBuffer& data, ImageSource::AlphaOption, ImageSource::GammaAndColorProfileOption);
90 // Returns a decoder with custom maxDecodedSize.
91 static PassOwnPtr<ImageDecoder> create(const SharedBuffer& data, ImageSource::AlphaOption, ImageSource::GammaAndColorProfileOption, size_t maxDecodedSize);
93 virtual String filenameExtension() const = 0;
95 bool isAllDataReceived() const { return m_isAllDataReceived; }
97 virtual void setData(SharedBuffer* data, bool allDataReceived)
102 m_isAllDataReceived = allDataReceived;
105 virtual bool isSizeAvailable()
107 return !m_failed && m_sizeAvailable;
110 bool isSizeAvailable() const
112 return !m_failed && m_sizeAvailable;
115 virtual IntSize size() const { return m_size; }
117 // Decoders which downsample images should override this method to
118 // return the actual decoded size.
119 virtual IntSize decodedSize() const { return size(); }
121 // Decoders which support YUV decoding can override this to
122 // give potentially different sizes per component.
123 virtual IntSize decodedYUVSize(int component, SizeType) const { return decodedSize(); }
125 // This will only differ from size() for ICO (where each frame is a
126 // different icon) or other formats where different frames are different
127 // sizes. This does NOT differ from size() for GIF or WebP, since
128 // decoding GIF or WebP composites any smaller frames against previous
129 // frames to create full-size frames.
130 virtual IntSize frameSizeAtIndex(size_t) const
135 // Returns whether the size is legal (i.e. not going to result in
136 // overflow elsewhere). If not, marks decoding as failed.
137 virtual bool setSize(unsigned width, unsigned height)
139 if (sizeCalculationMayOverflow(width, height))
141 m_size = IntSize(width, height);
142 m_sizeAvailable = true;
146 // Lazily-decodes enough of the image to get the frame count (if
147 // possible), without decoding the individual frames.
148 // FIXME: Right now that has to be done by each subclass; factor the
149 // decode call out and use it here.
150 virtual size_t frameCount() { return 1; }
152 virtual int repetitionCount() const { return cAnimationNone; }
154 // Decodes as much of the requested frame as possible, and returns an
155 // ImageDecoder-owned pointer.
156 virtual ImageFrame* frameBufferAtIndex(size_t) = 0;
158 // Make the best effort guess to check if the requested frame has alpha channel.
159 virtual bool frameHasAlphaAtIndex(size_t) const;
161 // Whether or not the frame is fully received.
162 virtual bool frameIsCompleteAtIndex(size_t) const;
164 // Duration for displaying a frame in seconds. This method is used by animated images only.
165 virtual float frameDurationAtIndex(size_t) const { return 0; }
167 // Number of bytes in the decoded frame requested. Return 0 if not yet decoded.
168 virtual unsigned frameBytesAtIndex(size_t) const;
170 ImageOrientation orientation() const { return m_orientation; }
172 static bool deferredImageDecodingEnabled();
174 void setIgnoreGammaAndColorProfile(bool flag) { m_ignoreGammaAndColorProfile = flag; }
175 bool ignoresGammaAndColorProfile() const { return m_ignoreGammaAndColorProfile; }
177 virtual bool hasColorProfile() const { return false; }
180 enum { iccColorProfileHeaderLength = 128 };
182 static bool rgbColorProfile(const char* profileData, unsigned profileLength)
184 ASSERT_UNUSED(profileLength, profileLength >= iccColorProfileHeaderLength);
186 return !memcmp(&profileData[16], "RGB ", 4);
189 static bool inputDeviceColorProfile(const char* profileData, unsigned profileLength)
191 ASSERT_UNUSED(profileLength, profileLength >= iccColorProfileHeaderLength);
193 return !memcmp(&profileData[12], "mntr", 4) || !memcmp(&profileData[12], "scnr", 4);
196 class OutputDeviceProfile {
198 OutputDeviceProfile()
199 : m_outputDeviceProfile(0)
201 ColorProfile profile = screenColorProfile();
202 if (!profile.isEmpty())
203 m_outputDeviceProfile = qcms_profile_from_memory(profile.data(), profile.size());
205 if (m_outputDeviceProfile && qcms_profile_is_bogus(m_outputDeviceProfile)) {
206 qcms_profile_release(m_outputDeviceProfile);
207 m_outputDeviceProfile = 0;
210 if (!m_outputDeviceProfile)
211 m_outputDeviceProfile = qcms_profile_sRGB();
212 if (m_outputDeviceProfile)
213 qcms_profile_precache_output_transform(m_outputDeviceProfile);
216 qcms_profile* profile() const { return m_outputDeviceProfile; }
219 static ColorProfile screenColorProfile()
221 // FIXME: Add optional ICCv4 support and support for multiple monitors.
222 WebVector<char> profile;
223 Platform::current()->screenColorProfile(&profile);
225 ColorProfile colorProfile;
226 colorProfile.append(profile.data(), profile.size());
230 qcms_profile* m_outputDeviceProfile;
233 static qcms_profile* qcmsOutputDeviceProfile()
235 AtomicallyInitializedStatic(OutputDeviceProfile*, outputDeviceProfile = new OutputDeviceProfile());
237 return outputDeviceProfile->profile();
241 // Sets the "decode failure" flag. For caller convenience (since so
242 // many callers want to return false after calling this), returns false
243 // to enable easy tailcalling. Subclasses may override this to also
244 // clean up any local data.
245 virtual bool setFailed()
251 bool failed() const { return m_failed; }
253 // Clears decoded pixel data from all frames except the provided frame.
254 // Callers may pass WTF::kNotFound to clear all frames.
255 // Note: If |m_frameBufferCache| contains only one frame, it won't be cleared.
256 // Returns the number of bytes of frame data actually cleared.
257 virtual size_t clearCacheExceptFrame(size_t);
259 // If the image has a cursor hot-spot, stores it in the argument
260 // and returns true. Otherwise returns false.
261 virtual bool hotSpot(IntPoint&) const { return false; }
263 virtual void setMemoryAllocator(SkBitmap::Allocator* allocator)
265 // FIXME: this doesn't work for images with multiple frames.
266 if (m_frameBufferCache.isEmpty()) {
267 m_frameBufferCache.resize(1);
268 m_frameBufferCache[0].setRequiredPreviousFrameIndex(
269 findRequiredPreviousFrame(0, false));
271 m_frameBufferCache[0].setMemoryAllocator(allocator);
274 virtual bool canDecodeToYUV() const { return false; }
275 virtual bool decodeToYUV() { return false; }
276 virtual void setImagePlanes(PassOwnPtr<ImagePlanes>) { }
279 // Calculates the most recent frame whose image data may be needed in
280 // order to decode frame |frameIndex|, based on frame disposal methods
281 // and |frameRectIsOpaque|, where |frameRectIsOpaque| signifies whether
282 // the rectangle of frame at |frameIndex| is known to be opaque.
283 // If no previous frame's data is required, returns WTF::kNotFound.
285 // This function requires that the previous frame's
286 // |m_requiredPreviousFrameIndex| member has been set correctly. The
287 // easiest way to ensure this is for subclasses to call this method and
288 // store the result on the frame via setRequiredPreviousFrameIndex()
289 // as soon as the frame has been created and parsed sufficiently to
290 // determine the disposal method; assuming this happens for all frames
291 // in order, the required invariant will hold.
293 // Image formats which do not use more than one frame do not need to
294 // worry about this; see comments on
295 // ImageFrame::m_requiredPreviousFrameIndex.
296 size_t findRequiredPreviousFrame(size_t frameIndex, bool frameRectIsOpaque);
298 virtual void clearFrameBuffer(size_t frameIndex);
300 RefPtr<SharedBuffer> m_data; // The encoded data.
301 Vector<ImageFrame, 1> m_frameBufferCache;
302 bool m_premultiplyAlpha;
303 bool m_ignoreGammaAndColorProfile;
304 ImageOrientation m_orientation;
306 // The maximum amount of memory a decoded image should require. Ideally,
307 // image decoders should downsample large images to fit under this limit
308 // (and then return the downsampled size from decodedSize()). Ignoring
309 // this limit can cause excessive memory use or even crashes on low-
311 size_t m_maxDecodedBytes;
314 // Some code paths compute the size of the image as "width * height * 4"
315 // and return it as a (signed) int. Avoid overflow.
316 static bool sizeCalculationMayOverflow(unsigned width, unsigned height)
318 unsigned long long total_size = static_cast<unsigned long long>(width)
319 * static_cast<unsigned long long>(height);
320 return total_size > ((1 << 29) - 1);
324 bool m_sizeAvailable;
325 bool m_isAllDataReceived;