1643ca7872b450ea4efacab6188849e5aac2ba161Steve Block/* 2643ca7872b450ea4efacab6188849e5aac2ba161Steve Block * Copyright (C) 2009 Google Inc. All rights reserved. 3643ca7872b450ea4efacab6188849e5aac2ba161Steve Block * 4643ca7872b450ea4efacab6188849e5aac2ba161Steve Block * Redistribution and use in source and binary forms, with or without 5643ca7872b450ea4efacab6188849e5aac2ba161Steve Block * modification, are permitted provided that the following conditions are 6643ca7872b450ea4efacab6188849e5aac2ba161Steve Block * met: 7643ca7872b450ea4efacab6188849e5aac2ba161Steve Block * 8643ca7872b450ea4efacab6188849e5aac2ba161Steve Block * * Redistributions of source code must retain the above copyright 9643ca7872b450ea4efacab6188849e5aac2ba161Steve Block * notice, this list of conditions and the following disclaimer. 10643ca7872b450ea4efacab6188849e5aac2ba161Steve Block * * Redistributions in binary form must reproduce the above 11643ca7872b450ea4efacab6188849e5aac2ba161Steve Block * copyright notice, this list of conditions and the following disclaimer 12643ca7872b450ea4efacab6188849e5aac2ba161Steve Block * in the documentation and/or other materials provided with the 13643ca7872b450ea4efacab6188849e5aac2ba161Steve Block * distribution. 14643ca7872b450ea4efacab6188849e5aac2ba161Steve Block * * Neither the name of Google Inc. nor the names of its 15643ca7872b450ea4efacab6188849e5aac2ba161Steve Block * contributors may be used to endorse or promote products derived from 16643ca7872b450ea4efacab6188849e5aac2ba161Steve Block * this software without specific prior written permission. 17643ca7872b450ea4efacab6188849e5aac2ba161Steve Block * 18643ca7872b450ea4efacab6188849e5aac2ba161Steve Block * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19643ca7872b450ea4efacab6188849e5aac2ba161Steve Block * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20643ca7872b450ea4efacab6188849e5aac2ba161Steve Block * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21643ca7872b450ea4efacab6188849e5aac2ba161Steve Block * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 22643ca7872b450ea4efacab6188849e5aac2ba161Steve Block * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23643ca7872b450ea4efacab6188849e5aac2ba161Steve Block * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 24643ca7872b450ea4efacab6188849e5aac2ba161Steve Block * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25643ca7872b450ea4efacab6188849e5aac2ba161Steve Block * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26643ca7872b450ea4efacab6188849e5aac2ba161Steve Block * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27643ca7872b450ea4efacab6188849e5aac2ba161Steve Block * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28643ca7872b450ea4efacab6188849e5aac2ba161Steve Block * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29643ca7872b450ea4efacab6188849e5aac2ba161Steve Block */ 30643ca7872b450ea4efacab6188849e5aac2ba161Steve Block 31643ca7872b450ea4efacab6188849e5aac2ba161Steve Block#include "config.h" 32643ca7872b450ea4efacab6188849e5aac2ba161Steve Block#include "WebImage.h" 33643ca7872b450ea4efacab6188849e5aac2ba161Steve Block 34643ca7872b450ea4efacab6188849e5aac2ba161Steve Block#include "Image.h" 35643ca7872b450ea4efacab6188849e5aac2ba161Steve Block#include "ImageSource.h" 36643ca7872b450ea4efacab6188849e5aac2ba161Steve Block#include "SharedBuffer.h" 37643ca7872b450ea4efacab6188849e5aac2ba161Steve Block 38643ca7872b450ea4efacab6188849e5aac2ba161Steve Block#include "WebData.h" 39643ca7872b450ea4efacab6188849e5aac2ba161Steve Block#include "WebSize.h" 40643ca7872b450ea4efacab6188849e5aac2ba161Steve Block 41643ca7872b450ea4efacab6188849e5aac2ba161Steve Block#include <CoreGraphics/CGImage.h> 42643ca7872b450ea4efacab6188849e5aac2ba161Steve Block 43643ca7872b450ea4efacab6188849e5aac2ba161Steve Block#include <wtf/PassRefPtr.h> 44643ca7872b450ea4efacab6188849e5aac2ba161Steve Block#include <wtf/RetainPtr.h> 45643ca7872b450ea4efacab6188849e5aac2ba161Steve Block 46643ca7872b450ea4efacab6188849e5aac2ba161Steve Blockusing namespace WebCore; 47643ca7872b450ea4efacab6188849e5aac2ba161Steve Block 48643ca7872b450ea4efacab6188849e5aac2ba161Steve Blocknamespace WebKit { 49643ca7872b450ea4efacab6188849e5aac2ba161Steve Block 50643ca7872b450ea4efacab6188849e5aac2ba161Steve BlockWebImage WebImage::fromData(const WebData& data, const WebSize& desiredSize) 51643ca7872b450ea4efacab6188849e5aac2ba161Steve Block{ 52643ca7872b450ea4efacab6188849e5aac2ba161Steve Block ImageSource source; 53643ca7872b450ea4efacab6188849e5aac2ba161Steve Block source.setData(PassRefPtr<SharedBuffer>(data).get(), true); 54643ca7872b450ea4efacab6188849e5aac2ba161Steve Block if (!source.isSizeAvailable()) 55643ca7872b450ea4efacab6188849e5aac2ba161Steve Block return WebImage(); 56643ca7872b450ea4efacab6188849e5aac2ba161Steve Block 572fc2651226baac27029e38c9d6ef883fa32084dbSteve Block // Frames are arranged by decreasing size, then decreasing bit depth. 582fc2651226baac27029e38c9d6ef883fa32084dbSteve Block // Pick the frame closest to |desiredSize|'s area without being smaller, 592fc2651226baac27029e38c9d6ef883fa32084dbSteve Block // which has the highest bit depth. 602fc2651226baac27029e38c9d6ef883fa32084dbSteve Block const size_t frameCount = source.frameCount(); 612fc2651226baac27029e38c9d6ef883fa32084dbSteve Block size_t index = 0; // Default to first frame if none are large enough. 622fc2651226baac27029e38c9d6ef883fa32084dbSteve Block int frameAreaAtIndex = 0; 632fc2651226baac27029e38c9d6ef883fa32084dbSteve Block for (size_t i = 0; i < frameCount; ++i) { 642fc2651226baac27029e38c9d6ef883fa32084dbSteve Block const IntSize frameSize = source.frameSizeAtIndex(i); 652fc2651226baac27029e38c9d6ef883fa32084dbSteve Block if (WebSize(frameSize) == desiredSize) { 662fc2651226baac27029e38c9d6ef883fa32084dbSteve Block index = i; 672fc2651226baac27029e38c9d6ef883fa32084dbSteve Block break; // Perfect match. 682fc2651226baac27029e38c9d6ef883fa32084dbSteve Block } 692fc2651226baac27029e38c9d6ef883fa32084dbSteve Block const int frameArea = frameSize.width() * frameSize.height(); 702fc2651226baac27029e38c9d6ef883fa32084dbSteve Block if (frameArea < (desiredSize.width * desiredSize.height)) 712fc2651226baac27029e38c9d6ef883fa32084dbSteve Block break; // No more frames that are large enough. 722fc2651226baac27029e38c9d6ef883fa32084dbSteve Block 732fc2651226baac27029e38c9d6ef883fa32084dbSteve Block if (!i || (frameArea < frameAreaAtIndex)) { 742fc2651226baac27029e38c9d6ef883fa32084dbSteve Block index = i; // Closer to desired area than previous best match. 752fc2651226baac27029e38c9d6ef883fa32084dbSteve Block frameAreaAtIndex = frameArea; 762fc2651226baac27029e38c9d6ef883fa32084dbSteve Block } 772fc2651226baac27029e38c9d6ef883fa32084dbSteve Block } 782fc2651226baac27029e38c9d6ef883fa32084dbSteve Block 792fc2651226baac27029e38c9d6ef883fa32084dbSteve Block RetainPtr<CGImageRef> frame(AdoptCF, source.createFrameAtIndex(index)); 802fc2651226baac27029e38c9d6ef883fa32084dbSteve Block if (!frame) 81643ca7872b450ea4efacab6188849e5aac2ba161Steve Block return WebImage(); 82643ca7872b450ea4efacab6188849e5aac2ba161Steve Block 832fc2651226baac27029e38c9d6ef883fa32084dbSteve Block return WebImage(frame.get()); 84643ca7872b450ea4efacab6188849e5aac2ba161Steve Block} 85643ca7872b450ea4efacab6188849e5aac2ba161Steve Block 86643ca7872b450ea4efacab6188849e5aac2ba161Steve Blockvoid WebImage::reset() 87643ca7872b450ea4efacab6188849e5aac2ba161Steve Block{ 88643ca7872b450ea4efacab6188849e5aac2ba161Steve Block CGImageRelease(m_imageRef); 89643ca7872b450ea4efacab6188849e5aac2ba161Steve Block m_imageRef = 0; 90643ca7872b450ea4efacab6188849e5aac2ba161Steve Block} 91643ca7872b450ea4efacab6188849e5aac2ba161Steve Block 92643ca7872b450ea4efacab6188849e5aac2ba161Steve Blockvoid WebImage::assign(const WebImage& image) 93643ca7872b450ea4efacab6188849e5aac2ba161Steve Block{ 94643ca7872b450ea4efacab6188849e5aac2ba161Steve Block assign(image.m_imageRef); 95643ca7872b450ea4efacab6188849e5aac2ba161Steve Block} 96643ca7872b450ea4efacab6188849e5aac2ba161Steve Block 97643ca7872b450ea4efacab6188849e5aac2ba161Steve Blockbool WebImage::isNull() const 98643ca7872b450ea4efacab6188849e5aac2ba161Steve Block{ 99643ca7872b450ea4efacab6188849e5aac2ba161Steve Block return !m_imageRef; 100643ca7872b450ea4efacab6188849e5aac2ba161Steve Block} 101643ca7872b450ea4efacab6188849e5aac2ba161Steve Block 102643ca7872b450ea4efacab6188849e5aac2ba161Steve BlockWebSize WebImage::size() const 103643ca7872b450ea4efacab6188849e5aac2ba161Steve Block{ 104643ca7872b450ea4efacab6188849e5aac2ba161Steve Block return WebSize(CGImageGetWidth(m_imageRef), CGImageGetHeight(m_imageRef)); 105643ca7872b450ea4efacab6188849e5aac2ba161Steve Block} 106643ca7872b450ea4efacab6188849e5aac2ba161Steve Block 107643ca7872b450ea4efacab6188849e5aac2ba161Steve BlockWebImage::WebImage(const PassRefPtr<Image>& image) 108643ca7872b450ea4efacab6188849e5aac2ba161Steve Block : m_imageRef(0) 109643ca7872b450ea4efacab6188849e5aac2ba161Steve Block{ 110545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch NativeImagePtr p; 111545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch if (image.get() && (p = image->nativeImageForCurrentFrame())) 112545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch assign(p); 113643ca7872b450ea4efacab6188849e5aac2ba161Steve Block} 114643ca7872b450ea4efacab6188849e5aac2ba161Steve Block 115643ca7872b450ea4efacab6188849e5aac2ba161Steve BlockWebImage& WebImage::operator=(const PassRefPtr<Image>& image) 116643ca7872b450ea4efacab6188849e5aac2ba161Steve Block{ 117545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch NativeImagePtr p; 118545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch if (image.get() && (p = image->nativeImageForCurrentFrame())) 119545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch assign(p); 120643ca7872b450ea4efacab6188849e5aac2ba161Steve Block else 121643ca7872b450ea4efacab6188849e5aac2ba161Steve Block reset(); 122643ca7872b450ea4efacab6188849e5aac2ba161Steve Block return *this; 123643ca7872b450ea4efacab6188849e5aac2ba161Steve Block} 124643ca7872b450ea4efacab6188849e5aac2ba161Steve Block 125643ca7872b450ea4efacab6188849e5aac2ba161Steve Blockvoid WebImage::assign(CGImageRef imageRef) 126643ca7872b450ea4efacab6188849e5aac2ba161Steve Block{ 127643ca7872b450ea4efacab6188849e5aac2ba161Steve Block // Make sure to retain the imageRef first incase m_imageRef == imageRef. 128643ca7872b450ea4efacab6188849e5aac2ba161Steve Block CGImageRetain(imageRef); 129643ca7872b450ea4efacab6188849e5aac2ba161Steve Block CGImageRelease(m_imageRef); 130643ca7872b450ea4efacab6188849e5aac2ba161Steve Block m_imageRef = imageRef; 131643ca7872b450ea4efacab6188849e5aac2ba161Steve Block} 132643ca7872b450ea4efacab6188849e5aac2ba161Steve Block 133643ca7872b450ea4efacab6188849e5aac2ba161Steve Block} // namespace WebKit 134