Home | History | Annotate | Download | only in image-decoders
      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 "core/platform/image-decoders/ImageDecoder.h"
     29 
     30 #include "core/platform/graphics/skia/NativeImageSkia.h"
     31 #include "wtf/PassRefPtr.h"
     32 
     33 namespace WebCore {
     34 
     35 ImageFrame::ImageFrame()
     36     : m_bitmap(NativeImageSkia::create())
     37     , m_allocator(0)
     38     , m_hasAlpha(false)
     39     , m_status(FrameEmpty)
     40     , m_duration(0)
     41     , m_disposalMethod(DisposeNotSpecified)
     42     , m_premultiplyAlpha(true)
     43     , m_requiredPreviousFrameIndex(notFound)
     44 #if !ASSERT_DISABLED
     45     , m_requiredPreviousFrameIndexValid(false)
     46 #endif
     47 {
     48 }
     49 
     50 ImageFrame& ImageFrame::operator=(const ImageFrame& other)
     51 {
     52     if (this == &other)
     53         return *this;
     54 
     55     m_bitmap = other.m_bitmap->clone();
     56     // Keep the pixels locked since we will be writing directly into the
     57     // bitmap throughout this object's lifetime.
     58     m_bitmap->bitmap().lockPixels();
     59     setMemoryAllocator(other.allocator());
     60     setOriginalFrameRect(other.originalFrameRect());
     61     setStatus(other.status());
     62     setDuration(other.duration());
     63     setDisposalMethod(other.disposalMethod());
     64     setPremultiplyAlpha(other.premultiplyAlpha());
     65     // Be sure that this is called after we've called setStatus(), since we
     66     // look at our status to know what to do with the alpha value.
     67     setHasAlpha(other.hasAlpha());
     68     // Copy raw fields to avoid ASSERT failure in requiredPreviousFrameIndex().
     69     m_requiredPreviousFrameIndex = other.m_requiredPreviousFrameIndex;
     70 #if !ASSERT_DISABLED
     71     m_requiredPreviousFrameIndexValid = other.m_requiredPreviousFrameIndexValid;
     72 #endif
     73     return *this;
     74 }
     75 
     76 void ImageFrame::clearPixelData()
     77 {
     78     m_bitmap->bitmap().reset();
     79     m_status = FrameEmpty;
     80     // NOTE: Do not reset other members here; clearFrameBufferCache()
     81     // calls this to free the bitmap data, but other functions like
     82     // initFrameBuffer() and frameComplete() may still need to read
     83     // other metadata out of this frame later.
     84 }
     85 
     86 void ImageFrame::zeroFillPixelData()
     87 {
     88     m_bitmap->bitmap().eraseARGB(0, 0, 0, 0);
     89     m_hasAlpha = true;
     90 }
     91 
     92 bool ImageFrame::copyBitmapData(const ImageFrame& other)
     93 {
     94     if (this == &other)
     95         return true;
     96 
     97     m_hasAlpha = other.m_hasAlpha;
     98     m_bitmap->bitmap().reset();
     99     const NativeImageSkia* otherBitmap = other.m_bitmap.get();
    100     return otherBitmap->bitmap().copyTo(&m_bitmap->bitmap(), otherBitmap->bitmap().config());
    101 }
    102 
    103 bool ImageFrame::setSize(int newWidth, int newHeight)
    104 {
    105     // setSize() should only be called once, it leaks memory otherwise.
    106     ASSERT(!width() && !height());
    107 
    108     m_bitmap->bitmap().setConfig(SkBitmap::kARGB_8888_Config, newWidth, newHeight);
    109     if (!m_bitmap->bitmap().allocPixels(m_allocator, 0))
    110         return false;
    111 
    112     zeroFillPixelData();
    113     return true;
    114 }
    115 
    116 PassRefPtr<NativeImageSkia> ImageFrame::asNewNativeImage() const
    117 {
    118     return m_bitmap->clone();
    119 }
    120 
    121 bool ImageFrame::hasAlpha() const
    122 {
    123     return m_hasAlpha;
    124 }
    125 
    126 void ImageFrame::setHasAlpha(bool alpha)
    127 {
    128     m_hasAlpha = alpha;
    129 
    130     // If the frame is not fully loaded, there will be transparent pixels,
    131     // so we can't tell skia we're opaque, even for image types that logically
    132     // always are (e.g. jpeg).
    133     bool isOpaque = !m_hasAlpha;
    134     if (m_status != FrameComplete)
    135         isOpaque = false;
    136     m_bitmap->bitmap().setIsOpaque(isOpaque);
    137 }
    138 
    139 void ImageFrame::setStatus(FrameStatus status)
    140 {
    141     m_status = status;
    142     if (m_status == FrameComplete) {
    143         m_bitmap->bitmap().setIsOpaque(!m_hasAlpha);
    144         m_bitmap->setDataComplete(); // Tell the bitmap it's done.
    145     }
    146 }
    147 
    148 void ImageFrame::zeroFillFrameRect(const IntRect& rect)
    149 {
    150     if (rect.isEmpty())
    151         return;
    152 
    153     m_bitmap->bitmap().eraseArea(rect, SkColorSetARGB(0, 0, 0, 0));
    154     setHasAlpha(true);
    155 }
    156 
    157 } // namespace WebCore
    158