⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 imagesourcecg.cpp

📁 linux下开源浏览器WebKit的源码,市面上的很多商用浏览器都是移植自WebKit
💻 CPP
字号:
/* * Copyright (C) 2004, 2005, 2006, 2008 Apple Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright *    notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright *    notice, this list of conditions and the following disclaimer in the *    documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.  */#include "config.h"#include "ImageSource.h"#if PLATFORM(CG)#include "ImageSourceCG.h"#include "IntSize.h"#include "MIMETypeRegistry.h"#include "SharedBuffer.h"#include <ApplicationServices/ApplicationServices.h>namespace WebCore {static const CFStringRef kCGImageSourceShouldPreferRGB32 = CFSTR("kCGImageSourceShouldPreferRGB32");ImageSource::ImageSource()    : m_decoder(0){}ImageSource::~ImageSource(){    clear(true);}void ImageSource::clear(bool, size_t, SharedBuffer* data, bool allDataReceived){    // We always destroy the decoder, because there is no API to get it to    // selectively release some of the frames it's holding, and if we don't    // release any of them, we use too much memory on large images.    if (m_decoder) {        CFRelease(m_decoder);        m_decoder = 0;    }    if (data)        setData(data, allDataReceived);}static CFDictionaryRef imageSourceOptions(){    static CFDictionaryRef options;        if (!options) {        const void* keys[2] = { kCGImageSourceShouldCache, kCGImageSourceShouldPreferRGB32 };        const void* values[2] = { kCFBooleanTrue, kCFBooleanTrue };        options = CFDictionaryCreate(NULL, keys, values, 2,             &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);    }    return options;}bool ImageSource::initialized() const{    return m_decoder;}void ImageSource::setData(SharedBuffer* data, bool allDataReceived){    if (!m_decoder)        m_decoder = CGImageSourceCreateIncremental(NULL);#if PLATFORM(MAC)    // On Mac the NSData inside the SharedBuffer can be secretly appended to without the SharedBuffer's knowledge.  We use SharedBuffer's ability    // to wrap itself inside CFData to get around this, ensuring that ImageIO is really looking at the SharedBuffer.    CFDataRef cfData = data->createCFData();#else    // If no NSData is available, then we know SharedBuffer will always just be a vector.  That means no secret changes can occur to it behind the    // scenes.  We use CFDataCreateWithBytesNoCopy in that case.    CFDataRef cfData = CFDataCreateWithBytesNoCopy(0, reinterpret_cast<const UInt8*>(data->data()), data->size(), kCFAllocatorNull);#endif    CGImageSourceUpdateData(m_decoder, cfData, allDataReceived);    CFRelease(cfData);}String ImageSource::filenameExtension() const{    if (!m_decoder)        return String();    CFStringRef imageSourceType = CGImageSourceGetType(m_decoder);    return WebCore::preferredExtensionForImageSourceType(imageSourceType);}bool ImageSource::isSizeAvailable(){    bool result = false;    CGImageSourceStatus imageSourceStatus = CGImageSourceGetStatus(m_decoder);    // Ragnaros yells: TOO SOON! You have awakened me TOO SOON, Executus!    if (imageSourceStatus >= kCGImageStatusIncomplete) {        CFDictionaryRef image0Properties = CGImageSourceCopyPropertiesAtIndex(m_decoder, 0, imageSourceOptions());        if (image0Properties) {            CFNumberRef widthNumber = (CFNumberRef)CFDictionaryGetValue(image0Properties, kCGImagePropertyPixelWidth);            CFNumberRef heightNumber = (CFNumberRef)CFDictionaryGetValue(image0Properties, kCGImagePropertyPixelHeight);            result = widthNumber && heightNumber;            CFRelease(image0Properties);        }    }        return result;}IntSize ImageSource::frameSizeAtIndex(size_t index) const{    IntSize result;    CFDictionaryRef properties = CGImageSourceCopyPropertiesAtIndex(m_decoder, index, imageSourceOptions());    if (properties) {        int w = 0, h = 0;        CFNumberRef num = (CFNumberRef)CFDictionaryGetValue(properties, kCGImagePropertyPixelWidth);        if (num)            CFNumberGetValue(num, kCFNumberIntType, &w);        num = (CFNumberRef)CFDictionaryGetValue(properties, kCGImagePropertyPixelHeight);        if (num)            CFNumberGetValue(num, kCFNumberIntType, &h);        result = IntSize(w, h);        CFRelease(properties);    }    return result;}IntSize ImageSource::size() const{    return frameSizeAtIndex(0);}int ImageSource::repetitionCount(){    int result = cAnimationLoopOnce; // No property means loop once.    if (!initialized())        return result;    // A property with value 0 means loop forever.    CFDictionaryRef properties = CGImageSourceCopyProperties(m_decoder, imageSourceOptions());    if (properties) {        CFDictionaryRef gifProperties = (CFDictionaryRef)CFDictionaryGetValue(properties, kCGImagePropertyGIFDictionary);        if (gifProperties) {            CFNumberRef num = (CFNumberRef)CFDictionaryGetValue(gifProperties, kCGImagePropertyGIFLoopCount);            if (num)                CFNumberGetValue(num, kCFNumberIntType, &result);        } else            result = cAnimationNone; // Turns out we're not a GIF after all, so we don't animate.                CFRelease(properties);    }        return result;}size_t ImageSource::frameCount() const{    return m_decoder ? CGImageSourceGetCount(m_decoder) : 0;}CGImageRef ImageSource::createFrameAtIndex(size_t index){    if (!initialized())        return 0;    CGImageRef image = CGImageSourceCreateImageAtIndex(m_decoder, index, imageSourceOptions());    CFStringRef imageUTI = CGImageSourceGetType(m_decoder);    static const CFStringRef xbmUTI = CFSTR("public.xbitmap-image");    if (!imageUTI || !CFEqual(imageUTI, xbmUTI))        return image;        // If it is an xbm image, mask out all the white areas to render them transparent.    const CGFloat maskingColors[6] = {255, 255,  255, 255, 255, 255};    CGImageRef maskedImage = CGImageCreateWithMaskingColors(image, maskingColors);    if (!maskedImage)        return image;            CGImageRelease(image);    return maskedImage; }bool ImageSource::frameIsCompleteAtIndex(size_t index){    return CGImageSourceGetStatusAtIndex(m_decoder, index) == kCGImageStatusComplete;}float ImageSource::frameDurationAtIndex(size_t index){    if (!initialized())        return 0;    float duration = 0;    CFDictionaryRef properties = CGImageSourceCopyPropertiesAtIndex(m_decoder, index, imageSourceOptions());    if (properties) {        CFDictionaryRef typeProperties = (CFDictionaryRef)CFDictionaryGetValue(properties, kCGImagePropertyGIFDictionary);        if (typeProperties) {            CFNumberRef num = (CFNumberRef)CFDictionaryGetValue(typeProperties, kCGImagePropertyGIFDelayTime);            if (num)                CFNumberGetValue(num, kCFNumberFloatType, &duration);        }        CFRelease(properties);    }    // Many annoying ads specify a 0 duration to make an image flash as quickly as possible.    // We follow WinIE's behavior and use a duration of 100 ms for any frames that specify    // a duration of <= 50 ms. See <http://bugs.webkit.org/show_bug.cgi?id=14413> or Radar 4051389 for more.    if (duration < 0.051f)        return 0.100f;    return duration;}bool ImageSource::frameHasAlphaAtIndex(size_t){    // Might be interesting to do this optimization on Mac some day, but for now we're just using this    // for the Cairo source, since it uses our decoders, and our decoders can answer this question.    // FIXME: Could return false for JPEG and other non-transparent image formats.    // FIXME: Could maybe return false for a GIF Frame if we have enough info in the GIF properties dictionary    // to determine whether or not a transparent color was defined.    return true;}}#endif // PLATFORM(CG)

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -