Home | History | Annotate | Download | only in image-decoders
      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 "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"
     41 
     42 #if USE(QCMSLIB)
     43 #include "qcms.h"
     44 #endif
     45 
     46 typedef Vector<char> ColorProfile;
     47 
     48 namespace blink {
     49 
     50 // ImagePlanes can be used to decode color components into provided buffers instead of using an ImageFrame.
     51 class PLATFORM_EXPORT ImagePlanes {
     52 public:
     53     ImagePlanes();
     54     ImagePlanes(void* planes[3], size_t rowBytes[3]);
     55 
     56     void* plane(int);
     57     size_t rowBytes(int) const;
     58 
     59 private:
     60     void* m_planes[3];
     61     size_t m_rowBytes[3];
     62 };
     63 
     64 // ImageDecoder is a base for all format-specific decoders
     65 // (e.g. JPEGImageDecoder). This base manages the ImageFrame cache.
     66 //
     67 class PLATFORM_EXPORT ImageDecoder {
     68     WTF_MAKE_NONCOPYABLE(ImageDecoder); WTF_MAKE_FAST_ALLOCATED;
     69 public:
     70     enum SizeType { ActualSize, SizeForMemoryAllocation };
     71 
     72     static const size_t noDecodedImageByteLimit = blink::Platform::noDecodedImageByteLimit;
     73 
     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)
     80         , m_failed(false) { }
     81 
     82     virtual ~ImageDecoder() { }
     83 
     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);
     89 
     90     // Returns a decoder with custom maxDecodedSize.
     91     static PassOwnPtr<ImageDecoder> create(const SharedBuffer& data, ImageSource::AlphaOption, ImageSource::GammaAndColorProfileOption, size_t maxDecodedSize);
     92 
     93     virtual String filenameExtension() const = 0;
     94 
     95     bool isAllDataReceived() const { return m_isAllDataReceived; }
     96 
     97     virtual void setData(SharedBuffer* data, bool allDataReceived)
     98     {
     99         if (m_failed)
    100             return;
    101         m_data = data;
    102         m_isAllDataReceived = allDataReceived;
    103     }
    104 
    105     virtual bool isSizeAvailable()
    106     {
    107         return !m_failed && m_sizeAvailable;
    108     }
    109 
    110     bool isSizeAvailable() const
    111     {
    112         return !m_failed && m_sizeAvailable;
    113     }
    114 
    115     virtual IntSize size() const { return m_size; }
    116 
    117     // Decoders which downsample images should override this method to
    118     // return the actual decoded size.
    119     virtual IntSize decodedSize() const { return size(); }
    120 
    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(); }
    124 
    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
    131     {
    132         return size();
    133     }
    134 
    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)
    138     {
    139         if (sizeCalculationMayOverflow(width, height))
    140             return setFailed();
    141         m_size = IntSize(width, height);
    142         m_sizeAvailable = true;
    143         return true;
    144     }
    145 
    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; }
    151 
    152     virtual int repetitionCount() const { return cAnimationNone; }
    153 
    154     // Decodes as much of the requested frame as possible, and returns an
    155     // ImageDecoder-owned pointer.
    156     virtual ImageFrame* frameBufferAtIndex(size_t) = 0;
    157 
    158     // Make the best effort guess to check if the requested frame has alpha channel.
    159     virtual bool frameHasAlphaAtIndex(size_t) const;
    160 
    161     // Whether or not the frame is fully received.
    162     virtual bool frameIsCompleteAtIndex(size_t) const;
    163 
    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; }
    166 
    167     // Number of bytes in the decoded frame requested. Return 0 if not yet decoded.
    168     virtual unsigned frameBytesAtIndex(size_t) const;
    169 
    170     ImageOrientation orientation() const { return m_orientation; }
    171 
    172     static bool deferredImageDecodingEnabled();
    173 
    174     void setIgnoreGammaAndColorProfile(bool flag) { m_ignoreGammaAndColorProfile = flag; }
    175     bool ignoresGammaAndColorProfile() const { return m_ignoreGammaAndColorProfile; }
    176 
    177     virtual bool hasColorProfile() const { return false; }
    178 
    179 #if USE(QCMSLIB)
    180     enum { iccColorProfileHeaderLength = 128 };
    181 
    182     static bool rgbColorProfile(const char* profileData, unsigned profileLength)
    183     {
    184         ASSERT_UNUSED(profileLength, profileLength >= iccColorProfileHeaderLength);
    185 
    186         return !memcmp(&profileData[16], "RGB ", 4);
    187     }
    188 
    189     static bool inputDeviceColorProfile(const char* profileData, unsigned profileLength)
    190     {
    191         ASSERT_UNUSED(profileLength, profileLength >= iccColorProfileHeaderLength);
    192 
    193         return !memcmp(&profileData[12], "mntr", 4) || !memcmp(&profileData[12], "scnr", 4);
    194     }
    195 
    196     class OutputDeviceProfile {
    197     public:
    198         OutputDeviceProfile()
    199             : m_outputDeviceProfile(0)
    200         {
    201             ColorProfile profile = screenColorProfile();
    202             if (!profile.isEmpty())
    203                 m_outputDeviceProfile = qcms_profile_from_memory(profile.data(), profile.size());
    204 
    205             if (m_outputDeviceProfile && qcms_profile_is_bogus(m_outputDeviceProfile)) {
    206                 qcms_profile_release(m_outputDeviceProfile);
    207                 m_outputDeviceProfile = 0;
    208             }
    209 
    210             if (!m_outputDeviceProfile)
    211                 m_outputDeviceProfile = qcms_profile_sRGB();
    212             if (m_outputDeviceProfile)
    213                 qcms_profile_precache_output_transform(m_outputDeviceProfile);
    214         }
    215 
    216         qcms_profile* profile() const { return m_outputDeviceProfile; }
    217 
    218     private:
    219         static ColorProfile screenColorProfile()
    220         {
    221             // FIXME: Add optional ICCv4 support and support for multiple monitors.
    222             WebVector<char> profile;
    223             Platform::current()->screenColorProfile(&profile);
    224 
    225             ColorProfile colorProfile;
    226             colorProfile.append(profile.data(), profile.size());
    227             return colorProfile;
    228         }
    229 
    230         qcms_profile* m_outputDeviceProfile;
    231     };
    232 
    233     static qcms_profile* qcmsOutputDeviceProfile()
    234     {
    235         AtomicallyInitializedStatic(OutputDeviceProfile*, outputDeviceProfile = new OutputDeviceProfile());
    236 
    237         return outputDeviceProfile->profile();
    238     }
    239 #endif
    240 
    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()
    246     {
    247         m_failed = true;
    248         return false;
    249     }
    250 
    251     bool failed() const { return m_failed; }
    252 
    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);
    258 
    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; }
    262 
    263     virtual void setMemoryAllocator(SkBitmap::Allocator* allocator)
    264     {
    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));
    270         }
    271         m_frameBufferCache[0].setMemoryAllocator(allocator);
    272     }
    273 
    274     virtual bool canDecodeToYUV() const { return false; }
    275     virtual bool decodeToYUV() { return false; }
    276     virtual void setImagePlanes(PassOwnPtr<ImagePlanes>) { }
    277 
    278 protected:
    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.
    284     //
    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.
    292     //
    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);
    297 
    298     virtual void clearFrameBuffer(size_t frameIndex);
    299 
    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;
    305 
    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-
    310     // memory devices.
    311     size_t m_maxDecodedBytes;
    312 
    313 private:
    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)
    317     {
    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);
    321     }
    322 
    323     IntSize m_size;
    324     bool m_sizeAvailable;
    325     bool m_isAllDataReceived;
    326     bool m_failed;
    327 };
    328 
    329 } // namespace blink
    330 
    331 #endif
    332