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 "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 
     50 namespace 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