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 "core/platform/graphics/ImageSource.h" 30 31 #include "core/platform/graphics/ImageOrientation.h" 32 #include "core/platform/graphics/chromium/DeferredImageDecoder.h" 33 #include "core/platform/image-decoders/ImageDecoder.h" 34 #include "wtf/PassOwnPtr.h" 35 #include "wtf/PassRefPtr.h" 36 37 namespace WebCore { 38 39 ImageSource::ImageSource(ImageSource::AlphaOption alphaOption, ImageSource::GammaAndColorProfileOption gammaAndColorProfileOption) 40 : m_alphaOption(alphaOption) 41 , m_gammaAndColorProfileOption(gammaAndColorProfileOption) 42 { 43 } 44 45 ImageSource::~ImageSource() 46 { 47 } 48 49 size_t ImageSource::clearCacheExceptFrame(size_t clearExceptFrame) 50 { 51 return m_decoder ? m_decoder->clearCacheExceptFrame(clearExceptFrame) : 0; 52 } 53 54 bool ImageSource::initialized() const 55 { 56 return m_decoder; 57 } 58 59 void ImageSource::setData(SharedBuffer* data, bool allDataReceived) 60 { 61 // Make the decoder by sniffing the bytes. 62 // This method will examine the data and instantiate an instance of the appropriate decoder plugin. 63 // If insufficient bytes are available to determine the image type, no decoder plugin will be 64 // made. 65 if (!m_decoder) 66 m_decoder = DeferredImageDecoder::create(*data, m_alphaOption, m_gammaAndColorProfileOption); 67 68 if (m_decoder) 69 m_decoder->setData(data, allDataReceived); 70 } 71 72 String ImageSource::filenameExtension() const 73 { 74 return m_decoder ? m_decoder->filenameExtension() : String(); 75 } 76 77 bool ImageSource::isSizeAvailable() 78 { 79 return m_decoder && m_decoder->isSizeAvailable(); 80 } 81 82 IntSize ImageSource::size(RespectImageOrientationEnum shouldRespectOrientation) const 83 { 84 return frameSizeAtIndex(0, shouldRespectOrientation); 85 } 86 87 IntSize ImageSource::frameSizeAtIndex(size_t index, RespectImageOrientationEnum shouldRespectOrientation) const 88 { 89 if (!m_decoder) 90 return IntSize(); 91 92 IntSize size = m_decoder->frameSizeAtIndex(index); 93 if ((shouldRespectOrientation == RespectImageOrientation) && m_decoder->orientation().usesWidthAsHeight()) 94 return IntSize(size.height(), size.width()); 95 96 return size; 97 } 98 99 bool ImageSource::getHotSpot(IntPoint& hotSpot) const 100 { 101 return m_decoder ? m_decoder->hotSpot(hotSpot) : false; 102 } 103 104 size_t ImageSource::bytesDecodedToDetermineProperties() const 105 { 106 return 0; 107 } 108 109 int ImageSource::repetitionCount() 110 { 111 return m_decoder ? m_decoder->repetitionCount() : cAnimationNone; 112 } 113 114 size_t ImageSource::frameCount() const 115 { 116 return m_decoder ? m_decoder->frameCount() : 0; 117 } 118 119 PassRefPtr<NativeImageSkia> ImageSource::createFrameAtIndex(size_t index) 120 { 121 if (!m_decoder) 122 return 0; 123 124 ImageFrame* buffer = m_decoder->frameBufferAtIndex(index); 125 if (!buffer || buffer->status() == ImageFrame::FrameEmpty) 126 return 0; 127 128 // Zero-height images can cause problems for some ports. If we have an 129 // empty image dimension, just bail. 130 if (size().isEmpty()) 131 return 0; 132 133 // Return the buffer contents as a native image. For some ports, the data 134 // is already in a native container, and this just increments its refcount. 135 return buffer->asNewNativeImage(); 136 } 137 138 float ImageSource::frameDurationAtIndex(size_t index) const 139 { 140 if (!m_decoder) 141 return 0; 142 143 // Many annoying ads specify a 0 duration to make an image flash as quickly as possible. 144 // We follow Firefox's behavior and use a duration of 100 ms for any frames that specify 145 // a duration of <= 10 ms. See <rdar://problem/7689300> and <http://webkit.org/b/36082> 146 // for more information. 147 const float duration = m_decoder->frameDurationAtIndex(index) / 1000.0f; 148 if (duration < 0.011f) 149 return 0.100f; 150 return duration; 151 } 152 153 ImageOrientation ImageSource::orientationAtIndex(size_t) const 154 { 155 return m_decoder ? m_decoder->orientation() : DefaultImageOrientation; 156 } 157 158 bool ImageSource::frameHasAlphaAtIndex(size_t index) const 159 { 160 return !m_decoder || m_decoder->frameHasAlphaAtIndex(index); 161 } 162 163 bool ImageSource::frameIsCompleteAtIndex(size_t index) const 164 { 165 return m_decoder && m_decoder->frameIsCompleteAtIndex(index); 166 } 167 168 unsigned ImageSource::frameBytesAtIndex(size_t index) const 169 { 170 if (!m_decoder) 171 return 0; 172 return m_decoder->frameBytesAtIndex(index); 173 } 174 175 } 176