1 /* 2 * Copyright (C) 2006 Apple Computer, Inc. All rights reserved. 3 * Copyright (C) 2008, 2009 Google, Inc. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 14 * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY 15 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 17 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR 18 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 19 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 20 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 21 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY 22 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 23 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 24 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 */ 26 27 #include "config.h" 28 #include "platform/image-decoders/ImageDecoder.h" 29 30 namespace WebCore { 31 32 ImageFrame::ImageFrame() 33 : m_allocator(0) 34 , m_hasAlpha(false) 35 , m_status(FrameEmpty) 36 , m_duration(0) 37 , m_disposalMethod(DisposeNotSpecified) 38 , m_alphaBlendSource(BlendAtopPreviousFrame) 39 , m_premultiplyAlpha(true) 40 , m_pixelsChanged(false) 41 , m_requiredPreviousFrameIndex(kNotFound) 42 #if ASSERT_ENABLED 43 , m_requiredPreviousFrameIndexValid(false) 44 #endif 45 { 46 } 47 48 ImageFrame& ImageFrame::operator=(const ImageFrame& other) 49 { 50 if (this == &other) 51 return *this; 52 53 m_bitmap = other.m_bitmap; 54 // Keep the pixels locked since we will be writing directly into the 55 // bitmap throughout this object's lifetime. 56 m_bitmap.lockPixels(); 57 // Be sure to assign this before calling setStatus(), since setStatus() may 58 // call notifyBitmapIfPixelsChanged(). 59 m_pixelsChanged = other.m_pixelsChanged; 60 setMemoryAllocator(other.allocator()); 61 setOriginalFrameRect(other.originalFrameRect()); 62 setStatus(other.status()); 63 setDuration(other.duration()); 64 setDisposalMethod(other.disposalMethod()); 65 setAlphaBlendSource(other.alphaBlendSource()); 66 setPremultiplyAlpha(other.premultiplyAlpha()); 67 // Be sure that this is called after we've called setStatus(), since we 68 // look at our status to know what to do with the alpha value. 69 setHasAlpha(other.hasAlpha()); 70 // Copy raw fields to avoid ASSERT failure in requiredPreviousFrameIndex(). 71 m_requiredPreviousFrameIndex = other.m_requiredPreviousFrameIndex; 72 #if ASSERT_ENABLED 73 m_requiredPreviousFrameIndexValid = other.m_requiredPreviousFrameIndexValid; 74 #endif 75 return *this; 76 } 77 78 void ImageFrame::clearPixelData() 79 { 80 m_bitmap.reset(); 81 m_status = FrameEmpty; 82 // NOTE: Do not reset other members here; clearFrameBufferCache() 83 // calls this to free the bitmap data, but other functions like 84 // initFrameBuffer() and frameComplete() may still need to read 85 // other metadata out of this frame later. 86 } 87 88 void ImageFrame::zeroFillPixelData() 89 { 90 m_bitmap.eraseARGB(0, 0, 0, 0); 91 m_hasAlpha = true; 92 } 93 94 bool ImageFrame::copyBitmapData(const ImageFrame& other) 95 { 96 if (this == &other) 97 return true; 98 99 m_hasAlpha = other.m_hasAlpha; 100 m_bitmap.reset(); 101 return other.m_bitmap.copyTo(&m_bitmap, other.m_bitmap.colorType()); 102 } 103 104 bool ImageFrame::setSize(int newWidth, int newHeight) 105 { 106 // setSize() should only be called once, it leaks memory otherwise. 107 ASSERT(!width() && !height()); 108 109 m_bitmap.setInfo(SkImageInfo::MakeN32Premul(newWidth, newHeight)); 110 if (!m_bitmap.allocPixels(m_allocator, 0)) 111 return false; 112 113 zeroFillPixelData(); 114 return true; 115 } 116 117 PassRefPtr<NativeImageSkia> ImageFrame::asNewNativeImage() const 118 { 119 return NativeImageSkia::create(m_bitmap); 120 } 121 122 bool ImageFrame::hasAlpha() const 123 { 124 return m_hasAlpha; 125 } 126 127 void ImageFrame::setHasAlpha(bool alpha) 128 { 129 m_hasAlpha = alpha; 130 131 // If the frame is not fully loaded, there will be transparent pixels, 132 // so we can't tell skia we're opaque, even for image types that logically 133 // always are (e.g. jpeg). 134 if (m_status != FrameComplete) 135 alpha = true; 136 m_bitmap.setAlphaType(alpha ? kPremul_SkAlphaType : kOpaque_SkAlphaType); 137 } 138 139 void ImageFrame::setStatus(Status status) 140 { 141 m_status = status; 142 if (m_status == FrameComplete) { 143 m_bitmap.setAlphaType(m_hasAlpha ? kPremul_SkAlphaType : kOpaque_SkAlphaType); 144 // Send pending pixels changed notifications now, because we can't do this after 145 // the bitmap has been marked immutable. 146 notifyBitmapIfPixelsChanged(); 147 m_bitmap.setImmutable(); // Tell the bitmap it's done. 148 } 149 } 150 151 void ImageFrame::zeroFillFrameRect(const IntRect& rect) 152 { 153 if (rect.isEmpty()) 154 return; 155 156 m_bitmap.eraseArea(rect, SkColorSetARGB(0, 0, 0, 0)); 157 setHasAlpha(true); 158 } 159 160 } // namespace WebCore 161