• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 PLATFORM(SKIA)
41 #include "NativeImageSkia.h"
42 #include "SkColorPriv.h"
43 #elif PLATFORM(QT)
44 #include <QImage>
45 #endif
46 
47 namespace WebCore {
48 
49     // The RGBA32Buffer object represents the decoded image data in RGBA32 format.  This buffer is what all
50     // decoders write a single frame into.  Frames are then instantiated for drawing by being handed this buffer.
51     class RGBA32Buffer {
52     public:
53         enum FrameStatus { FrameEmpty, FramePartial, FrameComplete };
54         enum FrameDisposalMethod {
55             // If you change the numeric values of these, make sure you audit all
56             // users, as some users may cast raw values to/from these constants.
57             DisposeNotSpecified,       // Leave frame in framebuffer
58             DisposeKeep,               // Leave frame in framebuffer
59             DisposeOverwriteBgcolor,   // Clear frame to transparent
60             DisposeOverwritePrevious,  // Clear frame to previous framebuffer contents
61         };
62 #if PLATFORM(SKIA) || PLATFORM(QT)
63         typedef uint32_t PixelData;
64 #else
65         typedef unsigned PixelData;
66 #endif
67 
68         RGBA32Buffer();
69 
70         // For backends which refcount their data, this constructor doesn't need
71         // to create a new copy of the image data, only increase the ref count.
72         //
73         // This exists because ImageDecoder keeps a Vector<RGBA32Buffer>, and
74         // Vector requires this constructor.
RGBA32Buffer(const RGBA32Buffer & other)75         RGBA32Buffer(const RGBA32Buffer& other)
76         {
77             operator=(other);
78         }
79 
80         // Deletes the pixel data entirely; used by ImageDecoder to save memory
81         // when we no longer need to display a frame and only need its metadata.
82         void clear();
83 
84         // Zeroes the pixel data in the buffer, setting it to fully-transparent.
85         void zeroFill();
86 
87         // Creates a new copy of the image data in |other|, so the two images
88         // can be modified independently.
89         void copyBitmapData(const RGBA32Buffer& other);
90 
91         // Copies the pixel data at [(startX, startY), (endX, startY)) to the
92         // same X-coordinates on each subsequent row up to but not including
93         // endY.
copyRowNTimes(int startX,int endX,int startY,int endY)94         void copyRowNTimes(int startX, int endX, int startY, int endY)
95         {
96             ASSERT(startX < width());
97             ASSERT(endX <= width());
98             ASSERT(startY < height());
99             ASSERT(endY <= height());
100             const int rowBytes = (endX - startX) * sizeof(PixelData);
101             const PixelData* const startAddr = getAddr(startX, startY);
102             for (int destY = startY + 1; destY < endY; ++destY)
103                 memcpy(getAddr(startX, destY), startAddr, rowBytes);
104         }
105 
106 #if PLATFORM(ANDROID)
bitmap()107         NativeImageSkia& bitmap() { return m_bitmap; }
bitmap()108         const NativeImageSkia& bitmap() const { return m_bitmap; }
109 #endif
110 
111         // Allocates space for the pixel data.  Must be called before any pixels
112         // are written. Will return true on success, false if the memory
113         // allocation fails.  Calling this multiple times is undefined and may
114         // leak memory.
115         bool setSize(int newWidth, int newHeight);
116 
117         // To be used by ImageSource::createFrameAtIndex().  Returns a pointer
118         // to the underlying native image data.  This pointer will be owned by
119         // the BitmapImage and freed in FrameData::clear().
120         NativeImagePtr asNewNativeImage() const;
121 
122         bool hasAlpha() const;
rect()123         const IntRect& rect() const { return m_rect; }
status()124         FrameStatus status() const { return m_status; }
duration()125         unsigned duration() const { return m_duration; }
disposalMethod()126         FrameDisposalMethod disposalMethod() const { return m_disposalMethod; }
127 
128         void setHasAlpha(bool alpha);
setRect(const IntRect & r)129         void setRect(const IntRect& r) { m_rect = r; }
130         void setStatus(FrameStatus status);
setDuration(unsigned duration)131         void setDuration(unsigned duration) { m_duration = duration; }
setDisposalMethod(FrameDisposalMethod method)132         void setDisposalMethod(FrameDisposalMethod method) { m_disposalMethod = method; }
133 
setRGBA(int x,int y,unsigned r,unsigned g,unsigned b,unsigned a)134         inline void setRGBA(int x, int y, unsigned r, unsigned g, unsigned b, unsigned a)
135         {
136             setRGBA(getAddr(x, y), r, g, b, a);
137         }
138 
139 #if PLATFORM(QT)
140         void setDecodedImage(const QImage& image);
decodedImage()141         QImage decodedImage() const { return m_image; }
142 #endif
143 
144     private:
145         RGBA32Buffer& operator=(const RGBA32Buffer& other);
146 
147         int width() const;
148         int height() const;
149 
getAddr(int x,int y)150         inline PixelData* getAddr(int x, int y)
151         {
152 #if PLATFORM(SKIA)
153             return m_bitmap.getAddr32(x, y);
154 #elif PLATFORM(QT)
155             return reinterpret_cast<QRgb*>(m_image.scanLine(y)) + x;
156 #else
157             return m_bytes.data() + (y * width()) + x;
158 #endif
159         }
160 
setRGBA(PixelData * dest,unsigned r,unsigned g,unsigned b,unsigned a)161         inline void setRGBA(PixelData* dest, unsigned r, unsigned g, unsigned b, unsigned a)
162         {
163             // We store this data pre-multiplied.
164             if (a == 0)
165                 *dest = 0;
166             else {
167                 if (a < 255) {
168                     float alphaPercent = a / 255.0f;
169                     r = static_cast<unsigned>(r * alphaPercent);
170                     g = static_cast<unsigned>(g * alphaPercent);
171                     b = static_cast<unsigned>(b * alphaPercent);
172                 }
173 #if PLATFORM(ANDROID)
174                 *dest = SkPackARGB32(a, r, g, b);
175 #else
176                 *dest = (a << 24 | r << 16 | g << 8 | b);
177 #endif
178             }
179         }
180 
181 #if PLATFORM(SKIA)
182         NativeImageSkia m_bitmap;
183 #elif PLATFORM(QT)
184         mutable QImage m_image;
185         bool m_hasAlpha;
186         IntSize m_size;
187 #else
188         Vector<PixelData> m_bytes;
189         IntSize m_size;       // The size of the buffer.  This should be the
190                               // same as ImageDecoder::m_size.
191         bool m_hasAlpha;      // Whether or not any of the pixels in the buffer have transparency.
192 #endif
193         IntRect m_rect;       // The rect of the original specified frame within the overall buffer.
194                               // This will always just be the entire buffer except for GIF frames
195                               // whose original rect was smaller than the overall image size.
196         FrameStatus m_status; // Whether or not this frame is completely finished decoding.
197         unsigned m_duration;  // The animation delay.
198         FrameDisposalMethod m_disposalMethod;
199                               // What to do with this frame's data when initializing the next frame.
200     };
201 
202     // The ImageDecoder class represents a base class for specific image format decoders
203     // (e.g., GIF, JPG, PNG, ICO) to derive from.  All decoders decode into RGBA32 format
204     // and the base class manages the RGBA32 frame cache.
205     class ImageDecoder : public Noncopyable {
206     public:
207         // ENABLE(IMAGE_DECODER_DOWN_SAMPLING) allows image decoders to write directly to
208         // scaled output buffers by down sampling. Call setMaxNumPixels() to specify the
209         // biggest size that decoded images can have. Image decoders will deflate those
210         // images that are bigger than m_maxNumPixels. (Not supported by all image decoders yet)
ImageDecoder()211         ImageDecoder()
212             : m_scaled(false)
213             , m_failed(false)
214             , m_sizeAvailable(false)
215             , m_isAllDataReceived(false)
216             , m_maxNumPixels(-1)
217         {
218         }
219 
~ImageDecoder()220         virtual ~ImageDecoder() {}
221 
222         // Factory function to create an ImageDecoder.  Ports that subclass
223         // ImageDecoder can provide their own implementation of this to avoid
224         // needing to write a dedicated setData() implementation.
225         static ImageDecoder* create(const SharedBuffer& data);
226 
227         // The the filename extension usually associated with an undecoded image of this type.
228         virtual String filenameExtension() const = 0;
229 
230         // All specific decoder plugins must do something with the data they are given.
isAllDataReceived()231         bool isAllDataReceived() const { return m_isAllDataReceived; }
setData(SharedBuffer * data,bool allDataReceived)232         virtual void setData(SharedBuffer* data, bool allDataReceived)
233         {
234             m_data = data;
235             m_isAllDataReceived = allDataReceived;
236         }
237 
238         // Whether or not the size information has been decoded yet. This default
239         // implementation just returns true if the size has been set and we have not
240         // seen a failure. Decoders may want to override this to lazily decode
241         // enough of the image to get the size.
isSizeAvailable()242         virtual bool isSizeAvailable()
243         {
244             return !m_failed && m_sizeAvailable;
245         }
246 
247         // Returns the size of the image.
size()248         virtual IntSize size() const
249         {
250             return m_size;
251         }
252 
scaledSize()253         IntSize scaledSize() const
254         {
255             return m_scaled ? IntSize(m_scaledColumns.size(), m_scaledRows.size()) : size();
256         }
257 
258         // Returns the size of frame |index|.  This will only differ from size()
259         // for formats where different frames are different sizes (namely ICO,
260         // where each frame represents a different icon within the master file).
261         // Notably, this does not return different sizes for different GIF
262         // frames, since while these may be stored as smaller rectangles, during
263         // decoding they are composited to create a full-size frame.
frameSizeAtIndex(size_t)264         virtual IntSize frameSizeAtIndex(size_t) const
265         {
266             return size();
267         }
268 
269         // Called by the image decoders to set their decoded size, this also check
270         // the size for validity. It will return true if the size was set, or false
271         // if there is an error. On error, the m_failed flag will be set and the
272         // caller should immediately stop decoding.
setSize(unsigned width,unsigned height)273         virtual bool setSize(unsigned width, unsigned height)
274         {
275             if (isOverSize(width, height)) {
276                 m_failed = true;
277                 return false;
278             }
279             m_size = IntSize(width, height);
280             m_sizeAvailable = true;
281             return true;
282         }
283 
284         // The total number of frames for the image.  Classes that support multiple frames
285         // will scan the image data for the answer if they need to (without necessarily
286         // decoding all of the individual frames).
frameCount()287         virtual size_t frameCount() { return 1; }
288 
289         // The number of repetitions to perform for an animation loop.
repetitionCount()290         virtual int repetitionCount() const { return cAnimationNone; }
291 
292         // Called to obtain the RGBA32Buffer full of decoded data for rendering.  The
293         // decoder plugin will decode as much of the frame as it can before handing
294         // back the buffer.
295         virtual RGBA32Buffer* frameBufferAtIndex(size_t) = 0;
296 
297         // Whether or not the underlying image format even supports alpha transparency.
supportsAlpha()298         virtual bool supportsAlpha() const { return true; }
299 
failed()300         bool failed() const { return m_failed; }
setFailed()301         void setFailed() { m_failed = true; }
302 
303         // Wipe out frames in the frame buffer cache before |clearBeforeFrame|,
304         // assuming this can be done without breaking decoding.  Different decoders
305         // place different restrictions on what frames are safe to destroy, so this
306         // is left to them to implement.
307         // For convenience's sake, we provide a default (empty) implementation,
308         // since in practice only GIFs will ever use this.
clearFrameBufferCache(size_t clearBeforeFrame)309         virtual void clearFrameBufferCache(size_t clearBeforeFrame) { }
310 
311 #if ENABLE(IMAGE_DECODER_DOWN_SAMPLING)
setMaxNumPixels(int m)312         void setMaxNumPixels(int m) { m_maxNumPixels = m; }
313 #endif
314 
315     protected:
316         void prepareScaleDataIfNecessary();
317         int upperBoundScaledX(int origX, int searchStart = 0);
318         int lowerBoundScaledX(int origX, int searchStart = 0);
319         int upperBoundScaledY(int origY, int searchStart = 0);
320         int lowerBoundScaledY(int origY, int searchStart = 0);
321         int scaledY(int origY, int searchStart = 0);
322 
323         RefPtr<SharedBuffer> m_data; // The encoded data.
324         Vector<int> m_scaledColumns;
325         Vector<int> m_scaledRows;
326         bool m_scaled;
327         Vector<RGBA32Buffer> m_frameBufferCache;
328         bool m_failed;
329 
330     private:
331         // Some code paths compute the size of the image as "width * height * 4"
332         // and return it as a (signed) int.  Avoid overflow.
isOverSize(unsigned width,unsigned height)333         static bool isOverSize(unsigned width, unsigned height)
334         {
335             // width * height must not exceed (2 ^ 29) - 1, so that we don't
336             // overflow when we multiply by 4.
337             unsigned long long total_size = static_cast<unsigned long long>(width)
338                                           * static_cast<unsigned long long>(height);
339             return total_size > ((1 << 29) - 1);
340         }
341 
342         IntSize m_size;
343         bool m_sizeAvailable;
344         bool m_isAllDataReceived;
345         int m_maxNumPixels;
346     };
347 
348 } // namespace WebCore
349 
350 #endif
351