1/*
2 * Copyright (C) 2006 Apple Computer, Inc.  All rights reserved.
3 * Copyright (C) Research In Motion Limited 2009-2010. All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
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.
13 *
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.
25 */
26
27#ifndef ImageDecoder_h
28#define ImageDecoder_h
29
30#include "SkColorPriv.h"
31#include "core/platform/PlatformScreen.h"
32#include "core/platform/SharedBuffer.h"
33#include "core/platform/graphics/ImageSource.h"
34#include "core/platform/graphics/IntRect.h"
35#include "core/platform/graphics/skia/NativeImageSkia.h"
36#include "wtf/Assertions.h"
37#include "wtf/RefPtr.h"
38#include "wtf/text/WTFString.h"
39#include "wtf/Vector.h"
40
41#if USE(QCMSLIB)
42#include "qcms.h"
43#if OS(DARWIN)
44#include <ApplicationServices/ApplicationServices.h>
45#include "core/platform/graphics/cg/GraphicsContextCG.h"
46#include "wtf/RetainPtr.h"
47#endif
48#endif
49
50namespace WebCore {
51
52    // ImageFrame represents the decoded image data.  This buffer is what all
53    // decoders write a single frame into.
54    class ImageFrame {
55    public:
56        enum FrameStatus { FrameEmpty, FramePartial, FrameComplete };
57        enum FrameDisposalMethod {
58            // If you change the numeric values of these, make sure you audit
59            // all users, as some users may cast raw values to/from these
60            // constants.
61            DisposeNotSpecified,      // Leave frame in framebuffer
62            DisposeKeep,              // Leave frame in framebuffer
63            DisposeOverwriteBgcolor,  // Clear frame to transparent
64            DisposeOverwritePrevious  // Clear frame to previous framebuffer
65                                      // contents
66        };
67        typedef uint32_t PixelData;
68
69        ImageFrame();
70
71        ImageFrame(const ImageFrame& other) { operator=(other); }
72
73        // For backends which refcount their data, this operator doesn't need to
74        // create a new copy of the image data, only increase the ref count.
75        ImageFrame& operator=(const ImageFrame& other);
76
77        // These do not touch other metadata, only the raw pixel data.
78        void clearPixelData();
79        void zeroFillPixelData();
80        void zeroFillFrameRect(const IntRect&);
81
82        // Makes this frame have an independent copy of the provided image's
83        // pixel data, so that modifications in one frame are not reflected in
84        // the other.  Returns whether the copy succeeded.
85        bool copyBitmapData(const ImageFrame&);
86
87        // Copies the pixel data at [(startX, startY), (endX, startY)) to the
88        // same X-coordinates on each subsequent row up to but not including
89        // endY.
90        void copyRowNTimes(int startX, int endX, int startY, int endY)
91        {
92            ASSERT(startX < width());
93            ASSERT(endX <= width());
94            ASSERT(startY < height());
95            ASSERT(endY <= height());
96            const int rowBytes = (endX - startX) * sizeof(PixelData);
97            const PixelData* const startAddr = getAddr(startX, startY);
98            for (int destY = startY + 1; destY < endY; ++destY)
99                memcpy(getAddr(startX, destY), startAddr, rowBytes);
100        }
101
102        // Allocates space for the pixel data.  Must be called before any pixels
103        // are written.  Must only be called once.  Returns whether allocation
104        // succeeded.
105        bool setSize(int newWidth, int newHeight);
106
107        // Returns a caller-owned pointer to the underlying native image data.
108        // (Actual use: This pointer will be owned by BitmapImage and freed in
109        // FrameData::clear()).
110        PassRefPtr<NativeImageSkia> asNewNativeImage() const;
111
112        bool hasAlpha() const;
113        const IntRect& originalFrameRect() const { return m_originalFrameRect; }
114        FrameStatus status() const { return m_status; }
115        unsigned duration() const { return m_duration; }
116        FrameDisposalMethod disposalMethod() const { return m_disposalMethod; }
117        bool premultiplyAlpha() const { return m_premultiplyAlpha; }
118        SkBitmap::Allocator* allocator() const { return m_allocator; }
119        const SkBitmap& getSkBitmap() const { return m_bitmap->bitmap(); }
120
121        size_t requiredPreviousFrameIndex() const
122        {
123            ASSERT(m_requiredPreviousFrameIndexValid);
124            return m_requiredPreviousFrameIndex;
125        }
126#if !ASSERT_DISABLED
127        bool requiredPreviousFrameIndexValid() const { return m_requiredPreviousFrameIndexValid; }
128#endif
129        void setHasAlpha(bool alpha);
130        void setOriginalFrameRect(const IntRect& r) { m_originalFrameRect = r; }
131        void setStatus(FrameStatus status);
132        void setDuration(unsigned duration) { m_duration = duration; }
133        void setDisposalMethod(FrameDisposalMethod method) { m_disposalMethod = method; }
134        void setPremultiplyAlpha(bool premultiplyAlpha) { m_premultiplyAlpha = premultiplyAlpha; }
135        void setMemoryAllocator(SkBitmap::Allocator* allocator) { m_allocator = allocator; }
136        void setSkBitmap(const SkBitmap& bitmap) { m_bitmap = NativeImageSkia::create(bitmap); }
137
138        void setRequiredPreviousFrameIndex(size_t previousFrameIndex)
139        {
140            m_requiredPreviousFrameIndex = previousFrameIndex;
141#if !ASSERT_DISABLED
142            m_requiredPreviousFrameIndexValid = true;
143#endif
144        }
145
146        inline PixelData* getAddr(int x, int y)
147        {
148            return m_bitmap->bitmap().getAddr32(x, y);
149        }
150
151        inline void setRGBA(int x, int y, unsigned r, unsigned g, unsigned b, unsigned a)
152        {
153            setRGBA(getAddr(x, y), r, g, b, a);
154        }
155
156        static const unsigned div255 = static_cast<unsigned>(1.0 / 255 * (1 << 24)) + 1;
157
158        inline void setRGBA(PixelData* dest, unsigned r, unsigned g, unsigned b, unsigned a)
159        {
160            if (m_premultiplyAlpha && a < 255) {
161                if (!a) {
162                    *dest = 0;
163                    return;
164                }
165
166                unsigned alpha = a * div255;
167                r = (r * alpha) >> 24;
168                g = (g * alpha) >> 24;
169                b = (b * alpha) >> 24;
170            }
171
172            // Call the "NoCheck" version since we may deliberately pass non-premultiplied
173            // values, and we don't want an assert.
174            *dest = SkPackARGB32NoCheck(a, r, g, b);
175        }
176
177        inline void setRGBARaw(PixelData* dest, unsigned r, unsigned g, unsigned b, unsigned a)
178        {
179            *dest = SkPackARGB32NoCheck(a, r, g, b);
180        }
181
182    private:
183        int width() const
184        {
185            return m_bitmap->bitmap().width();
186        }
187
188        int height() const
189        {
190            return m_bitmap->bitmap().height();
191        }
192
193        RefPtr<NativeImageSkia> m_bitmap;
194        SkBitmap::Allocator* m_allocator;
195        bool m_hasAlpha;
196        // This will always just be the entire buffer except for GIF or WebP
197        // frames whose original rect was smaller than the overall image size.
198        IntRect m_originalFrameRect;
199        FrameStatus m_status;
200        unsigned m_duration;
201        FrameDisposalMethod m_disposalMethod;
202        bool m_premultiplyAlpha;
203
204        // The frame that must be decoded before this frame can be decoded.
205        // WTF::notFound if this frame doesn't require any previous frame.
206        // This is used by ImageDecoder::clearCacheExceptFrame(), and will never
207        // be read for image formats that do not have multiple frames.
208        size_t m_requiredPreviousFrameIndex;
209#if !ASSERT_DISABLED
210        bool m_requiredPreviousFrameIndexValid;
211#endif
212    };
213
214    // ImageDecoder is a base for all format-specific decoders
215    // (e.g. JPEGImageDecoder). This base manages the ImageFrame cache.
216    class ImageDecoder {
217        WTF_MAKE_NONCOPYABLE(ImageDecoder); WTF_MAKE_FAST_ALLOCATED;
218    public:
219        ImageDecoder(ImageSource::AlphaOption alphaOption, ImageSource::GammaAndColorProfileOption gammaAndColorProfileOption)
220            : m_premultiplyAlpha(alphaOption == ImageSource::AlphaPremultiplied)
221            , m_ignoreGammaAndColorProfile(gammaAndColorProfileOption == ImageSource::GammaAndColorProfileIgnored)
222            , m_sizeAvailable(false)
223            , m_isAllDataReceived(false)
224            , m_failed(false) { }
225
226        virtual ~ImageDecoder() { }
227
228        // Returns a caller-owned decoder of the appropriate type.  Returns 0 if
229        // we can't sniff a supported type from the provided data (possibly
230        // because there isn't enough data yet).
231        static PassOwnPtr<ImageDecoder> create(const SharedBuffer& data, ImageSource::AlphaOption, ImageSource::GammaAndColorProfileOption);
232
233        virtual String filenameExtension() const = 0;
234
235        bool isAllDataReceived() const { return m_isAllDataReceived; }
236
237        virtual void setData(SharedBuffer* data, bool allDataReceived)
238        {
239            if (m_failed)
240                return;
241            m_data = data;
242            m_isAllDataReceived = allDataReceived;
243        }
244
245        // Lazily-decodes enough of the image to get the size (if possible).
246        // FIXME: Right now that has to be done by each subclass; factor the
247        // decode call out and use it here.
248        virtual bool isSizeAvailable()
249        {
250            return !m_failed && m_sizeAvailable;
251        }
252
253        virtual IntSize size() const { return m_size; }
254
255        // This will only differ from size() for ICO (where each frame is a
256        // different icon) or other formats where different frames are different
257        // sizes. This does NOT differ from size() for GIF or WebP, since
258        // decoding GIF or WebP composites any smaller frames against previous
259        // frames to create full-size frames.
260        virtual IntSize frameSizeAtIndex(size_t) const
261        {
262            return size();
263        }
264
265        // Returns whether the size is legal (i.e. not going to result in
266        // overflow elsewhere).  If not, marks decoding as failed.
267        virtual bool setSize(unsigned width, unsigned height)
268        {
269            if (isOverSize(width, height))
270                return setFailed();
271            m_size = IntSize(width, height);
272            m_sizeAvailable = true;
273            return true;
274        }
275
276        // Lazily-decodes enough of the image to get the frame count (if
277        // possible), without decoding the individual frames.
278        // FIXME: Right now that has to be done by each subclass; factor the
279        // decode call out and use it here.
280        virtual size_t frameCount() { return 1; }
281
282        virtual int repetitionCount() const { return cAnimationNone; }
283
284        // Decodes as much of the requested frame as possible, and returns an
285        // ImageDecoder-owned pointer.
286        virtual ImageFrame* frameBufferAtIndex(size_t) = 0;
287
288        // Make the best effort guess to check if the requested frame has alpha channel.
289        virtual bool frameHasAlphaAtIndex(size_t) const;
290
291        // Whether or not the frame is fully received.
292        virtual bool frameIsCompleteAtIndex(size_t) const;
293
294        // Duration for displaying a frame in seconds. This method is used by animated images only.
295        virtual float frameDurationAtIndex(size_t) const { return 0; }
296
297        // Number of bytes in the decoded frame requested. Return 0 if not yet decoded.
298        virtual unsigned frameBytesAtIndex(size_t) const;
299
300        void setIgnoreGammaAndColorProfile(bool flag) { m_ignoreGammaAndColorProfile = flag; }
301        bool ignoresGammaAndColorProfile() const { return m_ignoreGammaAndColorProfile; }
302
303        ImageOrientation orientation() const { return m_orientation; }
304
305        enum { iccColorProfileHeaderLength = 128 };
306
307        static bool rgbColorProfile(const char* profileData, unsigned profileLength)
308        {
309            ASSERT_UNUSED(profileLength, profileLength >= iccColorProfileHeaderLength);
310
311            return !memcmp(&profileData[16], "RGB ", 4);
312        }
313
314        static bool inputDeviceColorProfile(const char* profileData, unsigned profileLength)
315        {
316            ASSERT_UNUSED(profileLength, profileLength >= iccColorProfileHeaderLength);
317
318            return !memcmp(&profileData[12], "mntr", 4) || !memcmp(&profileData[12], "scnr", 4);
319        }
320
321#if USE(QCMSLIB)
322        static qcms_profile* qcmsOutputDeviceProfile()
323        {
324            static qcms_profile* outputDeviceProfile = 0;
325
326            static bool qcmsInitialized = false;
327            if (!qcmsInitialized) {
328                qcmsInitialized = true;
329                // FIXME: Add optional ICCv4 support.
330#if OS(DARWIN)
331                RetainPtr<CGColorSpaceRef> monitorColorSpace(AdoptCF, CGDisplayCopyColorSpace(CGMainDisplayID()));
332                CFDataRef iccProfile(CGColorSpaceCopyICCProfile(monitorColorSpace.get()));
333                if (iccProfile) {
334                    size_t length = CFDataGetLength(iccProfile);
335                    const unsigned char* systemProfile = CFDataGetBytePtr(iccProfile);
336                    outputDeviceProfile = qcms_profile_from_memory(systemProfile, length);
337                }
338#else
339                // FIXME: add support for multiple monitors.
340                ColorProfile profile;
341                screenColorProfile(profile);
342                if (!profile.isEmpty())
343                    outputDeviceProfile = qcms_profile_from_memory(profile.data(), profile.size());
344#endif
345                if (outputDeviceProfile && qcms_profile_is_bogus(outputDeviceProfile)) {
346                    qcms_profile_release(outputDeviceProfile);
347                    outputDeviceProfile = 0;
348                }
349                if (!outputDeviceProfile)
350                    outputDeviceProfile = qcms_profile_sRGB();
351                if (outputDeviceProfile)
352                    qcms_profile_precache_output_transform(outputDeviceProfile);
353            }
354            return outputDeviceProfile;
355        }
356#endif
357
358        // Sets the "decode failure" flag.  For caller convenience (since so
359        // many callers want to return false after calling this), returns false
360        // to enable easy tailcalling.  Subclasses may override this to also
361        // clean up any local data.
362        virtual bool setFailed()
363        {
364            m_failed = true;
365            return false;
366        }
367
368        bool failed() const { return m_failed; }
369
370        // Clears decoded pixel data from all frames except the provided frame.
371        // Callers may pass WTF::notFound to clear all frames.
372        // Note: If |m_frameBufferCache| contains only one frame, it won't be cleared.
373        // Returns the number of bytes of frame data actually cleared.
374        virtual size_t clearCacheExceptFrame(size_t);
375
376        // If the image has a cursor hot-spot, stores it in the argument
377        // and returns true. Otherwise returns false.
378        virtual bool hotSpot(IntPoint&) const { return false; }
379
380        virtual void setMemoryAllocator(SkBitmap::Allocator* allocator)
381        {
382            // FIXME: this doesn't work for images with multiple frames.
383            if (m_frameBufferCache.isEmpty()) {
384                m_frameBufferCache.resize(1);
385                m_frameBufferCache[0].setRequiredPreviousFrameIndex(
386                    findRequiredPreviousFrame(0));
387            }
388            m_frameBufferCache[0].setMemoryAllocator(allocator);
389        }
390
391    protected:
392        // Calculates the most recent frame whose image data may be needed in
393        // order to decode frame |frameIndex|, based on frame disposal methods.
394        // If no previous frame's data is required, returns WTF::notFound.
395        //
396        // This function requires that the previous frame's
397        // |m_requiredPreviousFrameIndex| member has been set correctly. The
398        // easiest way to ensure this is for subclasses to call this method and
399        // store the result on the frame via setRequiredPreviousFrameIndex()
400        // as soon as the frame has been created and parsed sufficiently to
401        // determine the disposal method; assuming this happens for all frames
402        // in order, the required invariant will hold.
403        //
404        // Image formats which do not use more than one frame do not need to
405        // worry about this; see comments on
406        // ImageFrame::m_requiredPreviousFrameIndex.
407        size_t findRequiredPreviousFrame(size_t frameIndex);
408
409        virtual void clearFrameBuffer(size_t frameIndex);
410
411        RefPtr<SharedBuffer> m_data; // The encoded data.
412        Vector<ImageFrame, 1> m_frameBufferCache;
413        bool m_premultiplyAlpha;
414        bool m_ignoreGammaAndColorProfile;
415        ImageOrientation m_orientation;
416
417    private:
418        // Some code paths compute the size of the image as "width * height * 4"
419        // and return it as a (signed) int.  Avoid overflow.
420        static bool isOverSize(unsigned width, unsigned height)
421        {
422            unsigned long long total_size = static_cast<unsigned long long>(width)
423                                          * static_cast<unsigned long long>(height);
424            return total_size > ((1 << 29) - 1);
425        }
426
427        IntSize m_size;
428        bool m_sizeAvailable;
429        bool m_isAllDataReceived;
430        bool m_failed;
431    };
432
433} // namespace WebCore
434
435#endif
436