7b4847f473a8355422688e00dfa2ecfbb6ad597a
[vuplus_webkit] / Source / WebCore / platform / image-decoders / ImageDecoder.h
1 /*
2  * Copyright (C) 2006 Apple Computer, Inc.  All rights reserved.
3  * Copyright (C) 2008-2009 Torch Mobile, Inc.
4  * Copyright (C) Research In Motion Limited 2009-2010. All rights reserved.
5  * Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies)
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 #ifndef ImageDecoder_h
30 #define ImageDecoder_h
31
32 #include "IntRect.h"
33 #include "ImageSource.h"
34 #include "PlatformString.h"
35 #include "SharedBuffer.h"
36 #include <wtf/Assertions.h>
37 #include <wtf/RefPtr.h>
38 #include <wtf/Vector.h>
39
40 #if USE(SKIA)
41 #include "NativeImageSkia.h"
42 #include "SkColorPriv.h"
43 #elif PLATFORM(QT)
44 #include <QPixmap>
45 #include <QImage>
46 #endif
47
48 namespace WebCore {
49
50     // FIXME: Do we want better encapsulation?
51     typedef Vector<char> ColorProfile;
52
53     // ImageFrame represents the decoded image data.  This buffer is what all
54     // decoders write a single frame into.
55     class ImageFrame {
56     public:
57         enum FrameStatus { FrameEmpty, FramePartial, FrameComplete };
58         enum FrameDisposalMethod {
59             // If you change the numeric values of these, make sure you audit
60             // all users, as some users may cast raw values to/from these
61             // constants.
62             DisposeNotSpecified,      // Leave frame in framebuffer
63             DisposeKeep,              // Leave frame in framebuffer
64             DisposeOverwriteBgcolor,  // Clear frame to transparent
65             DisposeOverwritePrevious  // Clear frame to previous framebuffer
66                                       // contents
67         };
68 #if USE(SKIA) || PLATFORM(QT)
69         typedef uint32_t PixelData;
70 #else
71         typedef unsigned PixelData;
72 #endif
73
74         ImageFrame();
75
76         ImageFrame(const ImageFrame& other) { operator=(other); }
77
78         // For backends which refcount their data, this operator doesn't need to
79         // create a new copy of the image data, only increase the ref count.
80         ImageFrame& operator=(const ImageFrame& other);
81
82         // These do not touch other metadata, only the raw pixel data.
83         void clearPixelData();
84         void zeroFillPixelData();
85
86         // Makes this frame have an independent copy of the provided image's
87         // pixel data, so that modifications in one frame are not reflected in
88         // the other.  Returns whether the copy succeeded.
89         bool copyBitmapData(const ImageFrame&);
90
91         // Makes this frame reference the provided image's pixel data, so that
92         // modifications in one frame are reflected in the other.
93         void copyReferenceToBitmapData(const ImageFrame&);
94
95         // Copies the pixel data at [(startX, startY), (endX, startY)) to the
96         // same X-coordinates on each subsequent row up to but not including
97         // endY.
98         void copyRowNTimes(int startX, int endX, int startY, int endY)
99         {
100             ASSERT(startX < width());
101             ASSERT(endX <= width());
102             ASSERT(startY < height());
103             ASSERT(endY <= height());
104             const int rowBytes = (endX - startX) * sizeof(PixelData);
105             const PixelData* const startAddr = getAddr(startX, startY);
106             for (int destY = startY + 1; destY < endY; ++destY)
107                 memcpy(getAddr(startX, destY), startAddr, rowBytes);
108         }
109
110         // Allocates space for the pixel data.  Must be called before any pixels
111         // are written.  Must only be called once.  Returns whether allocation
112         // succeeded.
113         bool setSize(int newWidth, int newHeight);
114
115         // Returns a caller-owned pointer to the underlying native image data.
116         // (Actual use: This pointer will be owned by BitmapImage and freed in
117         // FrameData::clear()).
118         NativeImagePtr asNewNativeImage() const;
119
120         bool hasAlpha() const;
121         const IntRect& originalFrameRect() const { return m_originalFrameRect; }
122         FrameStatus status() const { return m_status; }
123         unsigned duration() const { return m_duration; }
124         FrameDisposalMethod disposalMethod() const { return m_disposalMethod; }
125         bool premultiplyAlpha() const { return m_premultiplyAlpha; }
126
127         void setHasAlpha(bool alpha);
128         void setColorProfile(const ColorProfile&);
129         void setOriginalFrameRect(const IntRect& r) { m_originalFrameRect = r; }
130         void setStatus(FrameStatus status);
131         void setDuration(unsigned duration) { m_duration = duration; }
132         void setDisposalMethod(FrameDisposalMethod method) { m_disposalMethod = method; }
133         void setPremultiplyAlpha(bool premultiplyAlpha) { m_premultiplyAlpha = premultiplyAlpha; }
134
135         inline void setRGBA(int x, int y, unsigned r, unsigned g, unsigned b, unsigned a)
136         {
137             setRGBA(getAddr(x, y), r, g, b, a);
138         }
139
140 #if PLATFORM(QT)
141         void setPixmap(const QPixmap& pixmap);
142 #endif
143
144     private:
145 #if USE(CG)
146         typedef RetainPtr<CFMutableDataRef> NativeBackingStore;
147 #else
148         typedef Vector<PixelData> NativeBackingStore;
149 #endif
150
151         int width() const;
152         int height() const;
153
154         inline PixelData* getAddr(int x, int y)
155         {
156 #if USE(SKIA)
157             return m_bitmap.bitmap().getAddr32(x, y);
158 #elif PLATFORM(QT)
159             m_image = m_pixmap.toImage();
160             m_pixmap = QPixmap();
161             return reinterpret_cast_ptr<QRgb*>(m_image.scanLine(y)) + x;
162 #else
163             return m_bytes + (y * width()) + x;
164 #endif
165         }
166
167         inline void setRGBA(PixelData* dest, unsigned r, unsigned g, unsigned b, unsigned a)
168         {
169             if (m_premultiplyAlpha && !a)
170                 *dest = 0;
171             else {
172                 if (m_premultiplyAlpha && a < 255) {
173                     float alphaPercent = a / 255.0f;
174                     r = static_cast<unsigned>(r * alphaPercent);
175                     g = static_cast<unsigned>(g * alphaPercent);
176                     b = static_cast<unsigned>(b * alphaPercent);
177                 }
178 #if USE(SKIA)
179                 // we are sure to call the NoCheck version, since we may
180                 // deliberately pass non-premultiplied values, and we don't want
181                 // an assert.
182                 *dest = SkPackARGB32NoCheck(a, r, g, b);
183 #else
184                 *dest = (a << 24 | r << 16 | g << 8 | b);
185 #endif
186             }
187         }
188
189 #if USE(SKIA)
190         NativeImageSkia m_bitmap;
191 #elif PLATFORM(QT)
192         mutable QPixmap m_pixmap;
193         mutable QImage m_image;
194         bool m_hasAlpha;
195         IntSize m_size;
196 #else
197         NativeBackingStore m_backingStore;
198         PixelData* m_bytes; // The memory is backed by m_backingStore.
199         IntSize m_size;
200         bool m_hasAlpha;
201         ColorProfile m_colorProfile;
202 #endif
203         IntRect m_originalFrameRect; // This will always just be the entire
204                                      // buffer except for GIF frames whose
205                                      // original rect was smaller than the
206                                      // overall image size.
207         FrameStatus m_status;
208         unsigned m_duration;
209         FrameDisposalMethod m_disposalMethod;
210         bool m_premultiplyAlpha;
211     };
212
213     // ImageDecoder is a base for all format-specific decoders
214     // (e.g. JPEGImageDecoder).  This base manages the ImageFrame cache.
215     //
216     // ENABLE(IMAGE_DECODER_DOWN_SAMPLING) allows image decoders to downsample
217     // at decode time.  Image decoders will downsample any images larger than
218     // |m_maxNumPixels|.  FIXME: Not yet supported by all decoders.
219     class ImageDecoder {
220         WTF_MAKE_NONCOPYABLE(ImageDecoder); WTF_MAKE_FAST_ALLOCATED;
221     public:
222         ImageDecoder(ImageSource::AlphaOption alphaOption, ImageSource::GammaAndColorProfileOption gammaAndColorProfileOption)
223             : m_scaled(false)
224             , m_premultiplyAlpha(alphaOption == ImageSource::AlphaPremultiplied)
225             , m_ignoreGammaAndColorProfile(gammaAndColorProfileOption == ImageSource::GammaAndColorProfileIgnored)
226             , m_sizeAvailable(false)
227             , m_maxNumPixels(-1)
228             , m_isAllDataReceived(false)
229             , m_failed(false) { }
230
231         virtual ~ImageDecoder() { }
232
233         // Returns a caller-owned decoder of the appropriate type.  Returns 0 if
234         // we can't sniff a supported type from the provided data (possibly
235         // because there isn't enough data yet).
236         static ImageDecoder* create(const SharedBuffer& data, ImageSource::AlphaOption, ImageSource::GammaAndColorProfileOption);
237
238         virtual String filenameExtension() const = 0;
239
240         bool isAllDataReceived() const { return m_isAllDataReceived; }
241
242         virtual void setData(SharedBuffer* data, bool allDataReceived)
243         {
244             if (m_failed)
245                 return;
246             m_data = data;
247             m_isAllDataReceived = allDataReceived;
248         }
249
250         // Lazily-decodes enough of the image to get the size (if possible).
251         // FIXME: Right now that has to be done by each subclass; factor the
252         // decode call out and use it here.
253         virtual bool isSizeAvailable()
254         {
255             return !m_failed && m_sizeAvailable;
256         }
257
258         virtual IntSize size() const { return m_size; }
259
260         IntSize scaledSize() const
261         {
262             return m_scaled ? IntSize(m_scaledColumns.size(), m_scaledRows.size()) : size();
263         }
264
265         // This will only differ from size() for ICO (where each frame is a
266         // different icon) or other formats where different frames are different
267         // sizes.  This does NOT differ from size() for GIF, since decoding GIFs
268         // composites any smaller frames against previous frames to create full-
269         // size frames.
270         virtual IntSize frameSizeAtIndex(size_t) const
271         {
272             return size();
273         }
274
275         // Returns whether the size is legal (i.e. not going to result in
276         // overflow elsewhere).  If not, marks decoding as failed.
277         virtual bool setSize(unsigned width, unsigned height)
278         {
279             if (isOverSize(width, height))
280                 return setFailed();
281             m_size = IntSize(width, height);
282             m_sizeAvailable = true;
283             return true;
284         }
285
286         // Lazily-decodes enough of the image to get the frame count (if
287         // possible), without decoding the individual frames.
288         // FIXME: Right now that has to be done by each subclass; factor the
289         // decode call out and use it here.
290         virtual size_t frameCount() { return 1; }
291
292         virtual int repetitionCount() const { return cAnimationNone; }
293
294         // Decodes as much of the requested frame as possible, and returns an
295         // ImageDecoder-owned pointer.
296         virtual ImageFrame* frameBufferAtIndex(size_t) = 0;
297
298         void setIgnoreGammaAndColorProfile(bool flag) { m_ignoreGammaAndColorProfile = flag; }
299         bool ignoresGammaAndColorProfile() const { return m_ignoreGammaAndColorProfile; }
300
301         // Sets the "decode failure" flag.  For caller convenience (since so
302         // many callers want to return false after calling this), returns false
303         // to enable easy tailcalling.  Subclasses may override this to also
304         // clean up any local data.
305         virtual bool setFailed()
306         {
307             m_failed = true;
308             return false;
309         }
310
311         bool failed() const { return m_failed; }
312
313         // Clears decoded pixel data from before the provided frame unless that
314         // data may be needed to decode future frames (e.g. due to GIF frame
315         // compositing).
316         virtual void clearFrameBufferCache(size_t) { }
317
318 #if ENABLE(IMAGE_DECODER_DOWN_SAMPLING)
319         void setMaxNumPixels(int m) { m_maxNumPixels = m; }
320 #endif
321
322     protected:
323         void prepareScaleDataIfNecessary();
324         int upperBoundScaledX(int origX, int searchStart = 0);
325         int lowerBoundScaledX(int origX, int searchStart = 0);
326         int upperBoundScaledY(int origY, int searchStart = 0);
327         int lowerBoundScaledY(int origY, int searchStart = 0);
328         int scaledY(int origY, int searchStart = 0);
329
330         RefPtr<SharedBuffer> m_data; // The encoded data.
331         Vector<ImageFrame> m_frameBufferCache;
332         ColorProfile m_colorProfile;
333         bool m_scaled;
334         Vector<int> m_scaledColumns;
335         Vector<int> m_scaledRows;
336         bool m_premultiplyAlpha;
337         bool m_ignoreGammaAndColorProfile;
338
339     private:
340         // Some code paths compute the size of the image as "width * height * 4"
341         // and return it as a (signed) int.  Avoid overflow.
342         static bool isOverSize(unsigned width, unsigned height)
343         {
344             unsigned long long total_size = static_cast<unsigned long long>(width)
345                                           * static_cast<unsigned long long>(height);
346             return total_size > ((1 << 29) - 1);
347         }
348
349         IntSize m_size;
350         bool m_sizeAvailable;
351         int m_maxNumPixels;
352         bool m_isAllDataReceived;
353         bool m_failed;
354     };
355
356 } // namespace WebCore
357
358 #endif