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 34 namespace blink { 35 36 ImageSource::ImageSource(ImageSource::AlphaOption alphaOption, ImageSource::GammaAndColorProfileOption gammaAndColorProfileOption) 37 : m_alphaOption(alphaOption) 38 , m_gammaAndColorProfileOption(gammaAndColorProfileOption) 39 { 40 } 41 42 ImageSource::~ImageSource() 43 { 44 } 45 46 size_t ImageSource::clearCacheExceptFrame(size_t clearExceptFrame) 47 { 48 return m_decoder ? m_decoder->clearCacheExceptFrame(clearExceptFrame) : 0; 49 } 50 51 bool ImageSource::initialized() const 52 { 53 return m_decoder; 54 } 55 56 void ImageSource::resetDecoder() 57 { 58 m_decoder.clear(); 59 } 60 61 void ImageSource::setData(SharedBuffer& data, bool allDataReceived) 62 { 63 // Create a decoder by sniffing the encoded data. If insufficient data bytes are available to 64 // determine the encoded image type, no decoder is created. 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 bool ImageSource::hasColorProfile() const 83 { 84 return m_decoder && m_decoder->hasColorProfile(); 85 } 86 87 IntSize ImageSource::size(RespectImageOrientationEnum shouldRespectOrientation) const 88 { 89 return frameSizeAtIndex(0, shouldRespectOrientation); 90 } 91 92 IntSize ImageSource::frameSizeAtIndex(size_t index, RespectImageOrientationEnum shouldRespectOrientation) const 93 { 94 if (!m_decoder) 95 return IntSize(); 96 97 IntSize size = m_decoder->frameSizeAtIndex(index); 98 if ((shouldRespectOrientation == RespectImageOrientation) && m_decoder->orientation().usesWidthAsHeight()) 99 return IntSize(size.height(), size.width()); 100 101 return size; 102 } 103 104 bool ImageSource::getHotSpot(IntPoint& hotSpot) const 105 { 106 return m_decoder ? m_decoder->hotSpot(hotSpot) : false; 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 nullptr; 123 124 ImageFrame* buffer = m_decoder->frameBufferAtIndex(index); 125 if (!buffer || buffer->status() == ImageFrame::FrameEmpty) 126 return nullptr; 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 nullptr; 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 return m_decoder ? m_decoder->frameBytesAtIndex(index) : 0; 171 } 172 173 } // namespace blink 174