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  *
      6  * Redistribution and use in source and binary forms, with or without
      7  * modification, are permitted provided that the following conditions
      8  * are met:
      9  * 1. Redistributions of source code must retain the above copyright
     10  *    notice, this list of conditions and the following disclaimer.
     11  * 2. Redistributions in binary form must reproduce the above copyright
     12  *    notice, this list of conditions and the following disclaimer in the
     13  *    documentation and/or other materials provided with the distribution.
     14  *
     15  * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
     16  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     17  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     18  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
     19  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
     20  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
     21  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
     22  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
     23  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     24  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
     25  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     26  */
     27 
     28 #include "config.h"
     29 #include "platform/graphics/ImageSource.h"
     30 
     31 #include "platform/graphics/DeferredImageDecoder.h"
     32 #include "platform/image-decoders/ImageDecoder.h"
     33 #include "wtf/PassOwnPtr.h"
     34 #include "wtf/PassRefPtr.h"
     35 
     36 namespace WebCore {
     37 
     38 ImageSource::ImageSource(ImageSource::AlphaOption alphaOption, ImageSource::GammaAndColorProfileOption gammaAndColorProfileOption)
     39     : m_alphaOption(alphaOption)
     40     , m_gammaAndColorProfileOption(gammaAndColorProfileOption)
     41 {
     42 }
     43 
     44 ImageSource::~ImageSource()
     45 {
     46 }
     47 
     48 size_t ImageSource::clearCacheExceptFrame(size_t clearExceptFrame)
     49 {
     50     return m_decoder ? m_decoder->clearCacheExceptFrame(clearExceptFrame) : 0;
     51 }
     52 
     53 bool ImageSource::initialized() const
     54 {
     55     return m_decoder;
     56 }
     57 
     58 void ImageSource::setData(SharedBuffer& data, bool allDataReceived)
     59 {
     60     // Make the decoder by sniffing the bytes.
     61     // This method will examine the data and instantiate an instance of the appropriate decoder plugin.
     62     // If insufficient bytes are available to determine the image type, no decoder plugin will be
     63     // made.
     64     if (!m_decoder)
     65         m_decoder = DeferredImageDecoder::create(data, m_alphaOption, m_gammaAndColorProfileOption);
     66 
     67     if (m_decoder)
     68         m_decoder->setData(data, allDataReceived);
     69 }
     70 
     71 String ImageSource::filenameExtension() const
     72 {
     73     return m_decoder ? m_decoder->filenameExtension() : String();
     74 }
     75 
     76 bool ImageSource::isSizeAvailable()
     77 {
     78     return m_decoder && m_decoder->isSizeAvailable();
     79 }
     80 
     81 bool ImageSource::hasColorProfile() const
     82 {
     83     return m_decoder && m_decoder->hasColorProfile();
     84 }
     85 
     86 IntSize ImageSource::size(RespectImageOrientationEnum shouldRespectOrientation) const
     87 {
     88     return frameSizeAtIndex(0, shouldRespectOrientation);
     89 }
     90 
     91 IntSize ImageSource::frameSizeAtIndex(size_t index, RespectImageOrientationEnum shouldRespectOrientation) const
     92 {
     93     if (!m_decoder)
     94         return IntSize();
     95 
     96     IntSize size = m_decoder->frameSizeAtIndex(index);
     97     if ((shouldRespectOrientation == RespectImageOrientation) && m_decoder->orientation().usesWidthAsHeight())
     98         return IntSize(size.height(), size.width());
     99 
    100     return size;
    101 }
    102 
    103 bool ImageSource::getHotSpot(IntPoint& hotSpot) const
    104 {
    105     return m_decoder ? m_decoder->hotSpot(hotSpot) : false;
    106 }
    107 
    108 int ImageSource::repetitionCount()
    109 {
    110     return m_decoder ? m_decoder->repetitionCount() : cAnimationNone;
    111 }
    112 
    113 size_t ImageSource::frameCount() const
    114 {
    115     return m_decoder ? m_decoder->frameCount() : 0;
    116 }
    117 
    118 PassRefPtr<NativeImageSkia> ImageSource::createFrameAtIndex(size_t index)
    119 {
    120     if (!m_decoder)
    121         return nullptr;
    122 
    123     ImageFrame* buffer = m_decoder->frameBufferAtIndex(index);
    124     if (!buffer || buffer->status() == ImageFrame::FrameEmpty)
    125         return nullptr;
    126 
    127     // Zero-height images can cause problems for some ports.  If we have an
    128     // empty image dimension, just bail.
    129     if (size().isEmpty())
    130         return nullptr;
    131 
    132     // Return the buffer contents as a native image.  For some ports, the data
    133     // is already in a native container, and this just increments its refcount.
    134     return buffer->asNewNativeImage();
    135 }
    136 
    137 float ImageSource::frameDurationAtIndex(size_t index) const
    138 {
    139     if (!m_decoder)
    140         return 0;
    141 
    142     // Many annoying ads specify a 0 duration to make an image flash as quickly as possible.
    143     // We follow Firefox's behavior and use a duration of 100 ms for any frames that specify
    144     // a duration of <= 10 ms. See <rdar://problem/7689300> and <http://webkit.org/b/36082>
    145     // for more information.
    146     const float duration = m_decoder->frameDurationAtIndex(index) / 1000.0f;
    147     if (duration < 0.011f)
    148         return 0.100f;
    149     return duration;
    150 }
    151 
    152 ImageOrientation ImageSource::orientationAtIndex(size_t) const
    153 {
    154     return m_decoder ? m_decoder->orientation() : DefaultImageOrientation;
    155 }
    156 
    157 bool ImageSource::frameHasAlphaAtIndex(size_t index) const
    158 {
    159     return !m_decoder || m_decoder->frameHasAlphaAtIndex(index);
    160 }
    161 
    162 bool ImageSource::frameIsCompleteAtIndex(size_t index) const
    163 {
    164     return m_decoder && m_decoder->frameIsCompleteAtIndex(index);
    165 }
    166 
    167 unsigned ImageSource::frameBytesAtIndex(size_t index) const
    168 {
    169     if (!m_decoder)
    170         return 0;
    171     return m_decoder->frameBytesAtIndex(index);
    172 }
    173 
    174 }
    175