Home | History | Annotate | Download | only in image-decoders
      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 #if PLATFORM(ANDROID)
    111         NativeImageSkia& bitmap() { return m_bitmap; }
    112         const NativeImageSkia& bitmap() const { return m_bitmap; }
    113 #endif
    114 
    115         // Allocates space for the pixel data.  Must be called before any pixels
    116         // are written.  Must only be called once.  Returns whether allocation
    117         // succeeded.
    118         bool setSize(int newWidth, int newHeight);
    119 
    120         // Returns a caller-owned pointer to the underlying native image data.
    121         // (Actual use: This pointer will be owned by BitmapImage and freed in
    122         // FrameData::clear()).
    123         NativeImagePtr asNewNativeImage() const;
    124 
    125         bool hasAlpha() const;
    126         const IntRect& originalFrameRect() const { return m_originalFrameRect; }
    127         FrameStatus status() const { return m_status; }
    128         unsigned duration() const { return m_duration; }
    129         FrameDisposalMethod disposalMethod() const { return m_disposalMethod; }
    130         bool premultiplyAlpha() const { return m_premultiplyAlpha; }
    131 
    132         void setHasAlpha(bool alpha);
    133         void setColorProfile(const ColorProfile&);
    134         void setOriginalFrameRect(const IntRect& r) { m_originalFrameRect = r; }
    135         void setStatus(FrameStatus status);
    136         void setDuration(unsigned duration) { m_duration = duration; }
    137         void setDisposalMethod(FrameDisposalMethod method) { m_disposalMethod = method; }
    138         void setPremultiplyAlpha(bool premultiplyAlpha) { m_premultiplyAlpha = premultiplyAlpha; }
    139 
    140         inline void setRGBA(int x, int y, unsigned r, unsigned g, unsigned b, unsigned a)
    141         {
    142             setRGBA(getAddr(x, y), r, g, b, a);
    143         }
    144 
    145 #if PLATFORM(QT)
    146         void setPixmap(const QPixmap& pixmap);
    147 #endif
    148 
    149     private:
    150 #if USE(CG)
    151         typedef RetainPtr<CFMutableDataRef> NativeBackingStore;
    152 #else
    153         typedef Vector<PixelData> NativeBackingStore;
    154 #endif
    155 
    156         int width() const;
    157         int height() const;
    158 
    159         inline PixelData* getAddr(int x, int y)
    160         {
    161 #if USE(SKIA)
    162             return m_bitmap.getAddr32(x, y);
    163 #elif PLATFORM(QT)
    164             m_image = m_pixmap.toImage();
    165             m_pixmap = QPixmap();
    166             return reinterpret_cast_ptr<QRgb*>(m_image.scanLine(y)) + x;
    167 #else
    168             return m_bytes + (y * width()) + x;
    169 #endif
    170         }
    171 
    172         inline void setRGBA(PixelData* dest, unsigned r, unsigned g, unsigned b, unsigned a)
    173         {
    174             if (m_premultiplyAlpha && !a)
    175                 *dest = 0;
    176             else {
    177                 if (m_premultiplyAlpha && a < 255) {
    178                     float alphaPercent = a / 255.0f;
    179                     r = static_cast<unsigned>(r * alphaPercent);
    180                     g = static_cast<unsigned>(g * alphaPercent);
    181                     b = static_cast<unsigned>(b * alphaPercent);
    182                 }
    183 #if USE(SKIA)
    184                 // we are sure to call the NoCheck version, since we may
    185                 // deliberately pass non-premultiplied values, and we don't want
    186                 // an assert.
    187                 *dest = SkPackARGB32NoCheck(a, r, g, b);
    188 #else
    189                 *dest = (a << 24 | r << 16 | g << 8 | b);
    190 #endif
    191             }
    192         }
    193 
    194 #if USE(SKIA)
    195         NativeImageSkia m_bitmap;
    196 #elif PLATFORM(QT)
    197         mutable QPixmap m_pixmap;
    198         mutable QImage m_image;
    199         bool m_hasAlpha;
    200         IntSize m_size;
    201 #else
    202         NativeBackingStore m_backingStore;
    203         PixelData* m_bytes; // The memory is backed by m_backingStore.
    204         IntSize m_size;
    205         bool m_hasAlpha;
    206         ColorProfile m_colorProfile;
    207 #endif
    208         IntRect m_originalFrameRect; // This will always just be the entire
    209                                      // buffer except for GIF frames whose
    210                                      // original rect was smaller than the
    211                                      // overall image size.
    212         FrameStatus m_status;
    213         unsigned m_duration;
    214         FrameDisposalMethod m_disposalMethod;
    215         bool m_premultiplyAlpha;
    216     };
    217 
    218     // ImageDecoder is a base for all format-specific decoders
    219     // (e.g. JPEGImageDecoder).  This base manages the ImageFrame cache.
    220     //
    221     // ENABLE(IMAGE_DECODER_DOWN_SAMPLING) allows image decoders to downsample
    222     // at decode time.  Image decoders will downsample any images larger than
    223     // |m_maxNumPixels|.  FIXME: Not yet supported by all decoders.
    224     class ImageDecoder {
    225         WTF_MAKE_NONCOPYABLE(ImageDecoder); WTF_MAKE_FAST_ALLOCATED;
    226     public:
    227         ImageDecoder(ImageSource::AlphaOption alphaOption, ImageSource::GammaAndColorProfileOption gammaAndColorProfileOption)
    228             : m_scaled(false)
    229             , m_premultiplyAlpha(alphaOption == ImageSource::AlphaPremultiplied)
    230             , m_ignoreGammaAndColorProfile(gammaAndColorProfileOption == ImageSource::GammaAndColorProfileIgnored)
    231             , m_sizeAvailable(false)
    232             , m_maxNumPixels(-1)
    233             , m_isAllDataReceived(false)
    234             , m_failed(false) { }
    235 
    236         virtual ~ImageDecoder() { }
    237 
    238         // Returns a caller-owned decoder of the appropriate type.  Returns 0 if
    239         // we can't sniff a supported type from the provided data (possibly
    240         // because there isn't enough data yet).
    241         static ImageDecoder* create(const SharedBuffer& data, ImageSource::AlphaOption, ImageSource::GammaAndColorProfileOption);
    242 
    243         virtual String filenameExtension() const = 0;
    244 
    245         bool isAllDataReceived() const { return m_isAllDataReceived; }
    246 
    247         virtual void setData(SharedBuffer* data, bool allDataReceived)
    248         {
    249             if (m_failed)
    250                 return;
    251             m_data = data;
    252             m_isAllDataReceived = allDataReceived;
    253         }
    254 
    255         // Lazily-decodes enough of the image to get the size (if possible).
    256         // FIXME: Right now that has to be done by each subclass; factor the
    257         // decode call out and use it here.
    258         virtual bool isSizeAvailable()
    259         {
    260             return !m_failed && m_sizeAvailable;
    261         }
    262 
    263         virtual IntSize size() const { return m_size; }
    264 
    265         IntSize scaledSize() const
    266         {
    267             return m_scaled ? IntSize(m_scaledColumns.size(), m_scaledRows.size()) : size();
    268         }
    269 
    270         // This will only differ from size() for ICO (where each frame is a
    271         // different icon) or other formats where different frames are different
    272         // sizes.  This does NOT differ from size() for GIF, since decoding GIFs
    273         // composites any smaller frames against previous frames to create full-
    274         // size frames.
    275         virtual IntSize frameSizeAtIndex(size_t) const
    276         {
    277             return size();
    278         }
    279 
    280         // Returns whether the size is legal (i.e. not going to result in
    281         // overflow elsewhere).  If not, marks decoding as failed.
    282         virtual bool setSize(unsigned width, unsigned height)
    283         {
    284             if (isOverSize(width, height))
    285                 return setFailed();
    286             m_size = IntSize(width, height);
    287             m_sizeAvailable = true;
    288             return true;
    289         }
    290 
    291         // Lazily-decodes enough of the image to get the frame count (if
    292         // possible), without decoding the individual frames.
    293         // FIXME: Right now that has to be done by each subclass; factor the
    294         // decode call out and use it here.
    295         virtual size_t frameCount() { return 1; }
    296 
    297         virtual int repetitionCount() const { return cAnimationNone; }
    298 
    299         // Decodes as much of the requested frame as possible, and returns an
    300         // ImageDecoder-owned pointer.
    301         virtual ImageFrame* frameBufferAtIndex(size_t) = 0;
    302 
    303         void setIgnoreGammaAndColorProfile(bool flag) { m_ignoreGammaAndColorProfile = flag; }
    304         bool ignoresGammaAndColorProfile() const { return m_ignoreGammaAndColorProfile; }
    305 
    306         // Sets the "decode failure" flag.  For caller convenience (since so
    307         // many callers want to return false after calling this), returns false
    308         // to enable easy tailcalling.  Subclasses may override this to also
    309         // clean up any local data.
    310         virtual bool setFailed()
    311         {
    312             m_failed = true;
    313             return false;
    314         }
    315 
    316         bool failed() const { return m_failed; }
    317 
    318         // Clears decoded pixel data from before the provided frame unless that
    319         // data may be needed to decode future frames (e.g. due to GIF frame
    320         // compositing).
    321         virtual void clearFrameBufferCache(size_t) { }
    322 
    323 #if ENABLE(IMAGE_DECODER_DOWN_SAMPLING)
    324         void setMaxNumPixels(int m) { m_maxNumPixels = m; }
    325 #endif
    326 
    327     protected:
    328         void prepareScaleDataIfNecessary();
    329         int upperBoundScaledX(int origX, int searchStart = 0);
    330         int lowerBoundScaledX(int origX, int searchStart = 0);
    331         int upperBoundScaledY(int origY, int searchStart = 0);
    332         int lowerBoundScaledY(int origY, int searchStart = 0);
    333         int scaledY(int origY, int searchStart = 0);
    334 
    335         RefPtr<SharedBuffer> m_data; // The encoded data.
    336         Vector<ImageFrame> m_frameBufferCache;
    337         ColorProfile m_colorProfile;
    338         bool m_scaled;
    339         Vector<int> m_scaledColumns;
    340         Vector<int> m_scaledRows;
    341         bool m_premultiplyAlpha;
    342         bool m_ignoreGammaAndColorProfile;
    343 
    344     private:
    345         // Some code paths compute the size of the image as "width * height * 4"
    346         // and return it as a (signed) int.  Avoid overflow.
    347         static bool isOverSize(unsigned width, unsigned height)
    348         {
    349             unsigned long long total_size = static_cast<unsigned long long>(width)
    350                                           * static_cast<unsigned long long>(height);
    351             return total_size > ((1 << 29) - 1);
    352         }
    353 
    354         IntSize m_size;
    355         bool m_sizeAvailable;
    356         int m_maxNumPixels;
    357         bool m_isAllDataReceived;
    358         bool m_failed;
    359     };
    360 
    361 } // namespace WebCore
    362 
    363 #endif
    364