1/* 2 * Copyright (C) 2006 Apple Computer, Inc. All rights reserved. 3 * Copyright (C) 2007 Alp Toker <alp.toker@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 36namespace WebCore { 37 38ImageSource::ImageSource(ImageSource::AlphaOption alphaOption, ImageSource::GammaAndColorProfileOption gammaAndColorProfileOption) 39 : m_alphaOption(alphaOption) 40 , m_gammaAndColorProfileOption(gammaAndColorProfileOption) 41{ 42} 43 44ImageSource::~ImageSource() 45{ 46} 47 48size_t ImageSource::clearCacheExceptFrame(size_t clearExceptFrame) 49{ 50 return m_decoder ? m_decoder->clearCacheExceptFrame(clearExceptFrame) : 0; 51} 52 53bool ImageSource::initialized() const 54{ 55 return m_decoder; 56} 57 58void 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 71String ImageSource::filenameExtension() const 72{ 73 return m_decoder ? m_decoder->filenameExtension() : String(); 74} 75 76bool ImageSource::isSizeAvailable() 77{ 78 return m_decoder && m_decoder->isSizeAvailable(); 79} 80 81bool ImageSource::hasColorProfile() const 82{ 83 return m_decoder && m_decoder->hasColorProfile(); 84} 85 86IntSize ImageSource::size(RespectImageOrientationEnum shouldRespectOrientation) const 87{ 88 return frameSizeAtIndex(0, shouldRespectOrientation); 89} 90 91IntSize 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 103bool ImageSource::getHotSpot(IntPoint& hotSpot) const 104{ 105 return m_decoder ? m_decoder->hotSpot(hotSpot) : false; 106} 107 108int ImageSource::repetitionCount() 109{ 110 return m_decoder ? m_decoder->repetitionCount() : cAnimationNone; 111} 112 113size_t ImageSource::frameCount() const 114{ 115 return m_decoder ? m_decoder->frameCount() : 0; 116} 117 118PassRefPtr<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 137float 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 152ImageOrientation ImageSource::orientationAtIndex(size_t) const 153{ 154 return m_decoder ? m_decoder->orientation() : DefaultImageOrientation; 155} 156 157bool ImageSource::frameHasAlphaAtIndex(size_t index) const 158{ 159 return !m_decoder || m_decoder->frameHasAlphaAtIndex(index); 160} 161 162bool ImageSource::frameIsCompleteAtIndex(size_t index) const 163{ 164 return m_decoder && m_decoder->frameIsCompleteAtIndex(index); 165} 166 167unsigned ImageSource::frameBytesAtIndex(size_t index) const 168{ 169 if (!m_decoder) 170 return 0; 171 return m_decoder->frameBytesAtIndex(index); 172} 173 174} 175