Home | History | Annotate | Download | only in graphics
      1 /*
      2  * Copyright (C) 2006 Apple Computer, Inc.  All rights reserved.
      3  * Copyright (C) 2007 Alp Toker <alp.toker (at) collabora.co.uk>
      4  * Copyright (C) 2008, Google Inc. All rights reserved.
      5  * Copyright (C) 2007-2009 Torch Mobile, Inc
      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 #include "config.h"
     30 #include "ImageSource.h"
     31 
     32 #if PLATFORM(QT)
     33 #include "ImageDecoderQt.h"
     34 #else
     35 #include "ImageDecoder.h"
     36 #endif
     37 
     38 namespace WebCore {
     39 
     40 ImageSource::ImageSource()
     41     : m_decoder(0)
     42 {
     43 }
     44 
     45 ImageSource::~ImageSource()
     46 {
     47     clear(true);
     48 }
     49 
     50 void ImageSource::clear(bool destroyAll, size_t clearBeforeFrame, SharedBuffer* data, bool allDataReceived)
     51 {
     52     if (!destroyAll) {
     53         if (m_decoder)
     54             m_decoder->clearFrameBufferCache(clearBeforeFrame);
     55         return;
     56     }
     57 
     58     delete m_decoder;
     59     m_decoder = 0;
     60     if (data)
     61         setData(data, allDataReceived);
     62 }
     63 
     64 bool ImageSource::initialized() const
     65 {
     66     return m_decoder;
     67 }
     68 
     69 void ImageSource::setData(SharedBuffer* data, bool allDataReceived)
     70 {
     71     // Make the decoder by sniffing the bytes.
     72     // This method will examine the data and instantiate an instance of the appropriate decoder plugin.
     73     // If insufficient bytes are available to determine the image type, no decoder plugin will be
     74     // made.
     75     if (!m_decoder) {
     76         m_decoder = static_cast<NativeImageSourcePtr>(ImageDecoder::create(*data));
     77 #if ENABLE(IMAGE_DECODER_DOWN_SAMPLING)
     78 #ifndef IMAGE_DECODER_DOWN_SAMPLING_MAX_NUMBER_OF_PIXELS
     79 #define IMAGE_DECODER_DOWN_SAMPLING_MAX_NUMBER_OF_PIXELS (1024 * 1024)
     80 #endif
     81         if (m_decoder)
     82             m_decoder->setMaxNumPixels(IMAGE_DECODER_DOWN_SAMPLING_MAX_NUMBER_OF_PIXELS);
     83 #endif
     84     }
     85 
     86     if (m_decoder)
     87         m_decoder->setData(data, allDataReceived);
     88 }
     89 
     90 String ImageSource::filenameExtension() const
     91 {
     92     return m_decoder ? m_decoder->filenameExtension() : String();
     93 }
     94 
     95 bool ImageSource::isSizeAvailable()
     96 {
     97     return m_decoder && m_decoder->isSizeAvailable();
     98 }
     99 
    100 IntSize ImageSource::size() const
    101 {
    102     return m_decoder ? m_decoder->size() : IntSize();
    103 }
    104 
    105 IntSize ImageSource::frameSizeAtIndex(size_t index) const
    106 {
    107     return m_decoder ? m_decoder->frameSizeAtIndex(index) : IntSize();
    108 }
    109 
    110 int ImageSource::repetitionCount()
    111 {
    112     return m_decoder ? m_decoder->repetitionCount() : cAnimationNone;
    113 }
    114 
    115 size_t ImageSource::frameCount() const
    116 {
    117     return m_decoder ? m_decoder->frameCount() : 0;
    118 }
    119 
    120 NativeImagePtr ImageSource::createFrameAtIndex(size_t index)
    121 {
    122     if (!m_decoder)
    123         return 0;
    124 
    125     RGBA32Buffer* buffer = m_decoder->frameBufferAtIndex(index);
    126     if (!buffer || buffer->status() == RGBA32Buffer::FrameEmpty)
    127         return 0;
    128 
    129     // Zero-height images can cause problems for some ports.  If we have an
    130     // empty image dimension, just bail.
    131     if (size().isEmpty())
    132         return 0;
    133 
    134     // Return the buffer contents as a native image.  For some ports, the data
    135     // is already in a native container, and this just increments its refcount.
    136     return buffer->asNewNativeImage();
    137 }
    138 
    139 float ImageSource::frameDurationAtIndex(size_t index)
    140 {
    141     if (!m_decoder)
    142         return 0;
    143 
    144     RGBA32Buffer* buffer = m_decoder->frameBufferAtIndex(index);
    145     if (!buffer || buffer->status() == RGBA32Buffer::FrameEmpty)
    146         return 0;
    147 
    148     // Many annoying ads specify a 0 duration to make an image flash as quickly
    149     // as possible.  We follow WinIE's behavior and use a duration of 100 ms
    150     // for any frames that specify a duration of <= 50 ms.  See
    151     // <http://bugs.webkit.org/show_bug.cgi?id=14413> or Radar 4051389 for
    152     // more.
    153     const float duration = buffer->duration() / 1000.0f;
    154     return (duration < 0.051f) ? 0.100f : duration;
    155 }
    156 
    157 bool ImageSource::frameHasAlphaAtIndex(size_t index)
    158 {
    159     // When a frame has not finished decoding, always mark it as having alpha.
    160     // Ports that check the result of this function to determine their
    161     // compositing op need this in order to not draw the undecoded portion as
    162     // black.
    163     // TODO: Perhaps we should ensure that each individual decoder returns true
    164     // in this case.
    165     return !frameIsCompleteAtIndex(index)
    166         || m_decoder->frameBufferAtIndex(index)->hasAlpha();
    167 }
    168 
    169 bool ImageSource::frameIsCompleteAtIndex(size_t index)
    170 {
    171     if (!m_decoder)
    172         return false;
    173 
    174     RGBA32Buffer* buffer = m_decoder->frameBufferAtIndex(index);
    175     return buffer && buffer->status() == RGBA32Buffer::FrameComplete;
    176 }
    177 
    178 }
    179