WebKit Bugzilla
New
Browse
Search+
Log In
×
Sign in with GitHub
or
Remember my login
Create Account
·
Forgot Password
Forgotten password account recovery
[patch]
Patch
bug-155444-20160314103752.patch (text/plain), 120.44 KB, created by
Said Abou-Hallawa
on 2016-03-14 10:38:04 PDT
(
hide
)
Description:
Patch
Filename:
MIME Type:
Creator:
Said Abou-Hallawa
Created:
2016-03-14 10:38:04 PDT
Size:
120.44 KB
patch
obsolete
>Subversion Revision: 198066 >diff --git a/Source/WebCore/ChangeLog b/Source/WebCore/ChangeLog >index cac98fc61fb8fe1e01a691cc7849346e5a907250..a591e54015679a66efed8e85850fcb2d37190dfc 100644 >--- a/Source/WebCore/ChangeLog >+++ b/Source/WebCore/ChangeLog >@@ -1,3 +1,334 @@ >+2016-03-14 Said Abou-Hallawa <sabouhallawa@apple,com> >+ >+ Rename FrameData to ImageFrameData and move it to a separate file >+ https://bugs.webkit.org/show_bug.cgi?id=155444 >+ >+ Reviewed by NOBODY (OOPS!). >+ >+ This patch is not for review. It is only for EWS. It contains the fix of >+ webkit bugs 155412, 155422 and155444. A separate patch will be posted for >+ review once this combined patch passes the EWS. >+ >+ * PlatformAppleWin.cmake: >+ * PlatformMac.cmake: >+ * WebCore.xcodeproj/project.pbxproj: >+ * loader/cache/CachedImage.cpp: >+ (WebCore::CachedImage::imageSizeForRenderer): >+ * loader/cache/MemoryCache.cpp: >+ (WebCore::MemoryCache::addImageToCache): Deleted. >+ * platform/graphics/BitmapImage.cpp: >+ (WebCore::BitmapImage::haveFrameImageAtIndex): >+ (WebCore::BitmapImage::destroyDecodedData): >+ (WebCore::BitmapImage::destroyMetadataAndNotify): >+ (WebCore::BitmapImage::cacheFrame): >+ (WebCore::BitmapImage::updateSize): >+ (WebCore::BitmapImage::sizeRespectingOrientation): >+ (WebCore::BitmapImage::dataChanged): >+ (WebCore::BitmapImage::ensureFrameIsCached): >+ (WebCore::BitmapImage::frameImageAtIndex): >+ (WebCore::BitmapImage::frameIsCompleteAtIndex): >+ (WebCore::BitmapImage::frameDurationAtIndex): >+ (WebCore::BitmapImage::nativeImageForCurrentFrame): >+ (WebCore::BitmapImage::frameHasAlphaAtIndex): >+ (WebCore::BitmapImage::frameOrientationAtIndex): >+ (WebCore::BitmapImage::checkForSolidColor): >+ (WebCore::BitmapImage::isSolidColor): >+ (WebCore::BitmapImage::mayFillWithSolidColor): >+ (WebCore::BitmapImage::solidColor): >+ (WebCore::BitmapImage::dump): >+ (WebCore::BitmapImage::BitmapImage): Deleted. >+ (WebCore::BitmapImage::haveFrameAtIndex): Deleted. >+ (WebCore::BitmapImage::frameAtIndex): Deleted. >+ * platform/graphics/BitmapImage.h: >+ (WebCore::FrameData::FrameData): Deleted. >+ (WebCore::FrameData::~FrameData): Deleted. >+ * platform/graphics/Icon.h: >+ * platform/graphics/Image.h: >+ (WebCore::Image::solidColor): >+ * platform/graphics/ImageFrameData.cpp: Added. >+ (WebCore::ImageFrameData::ImageFrameData): >+ (WebCore::ImageFrameData::~ImageFrameData): >+ (WebCore::ImageFrameData::status): >+ * platform/graphics/ImageFrameData.h: Added. >+ * platform/graphics/ImageSource.cpp: >+ (WebCore::ImageSource::subsamplingLevelForScale): >+ (WebCore::ImageSource::size): >+ (WebCore::ImageSource::sizeRespectingOrientation): >+ (WebCore::ImageSource::frameSizeAtIndex): >+ (WebCore::ImageSource::createFrameImageAtIndex): >+ (WebCore::ImageSource::initialized): Deleted. >+ (WebCore::ImageSource::createFrameAtIndex): Deleted. >+ * platform/graphics/ImageSource.h: >+ (WebCore::ImageSource::initialized): >+ * platform/graphics/NativeImagePtr.h: >+ * platform/graphics/ca/GraphicsLayerCA.cpp: >+ (WebCore::GraphicsLayerCA::setContentsToImage): >+ * platform/graphics/cairo/BitmapImageCairo.cpp: >+ (WebCore::BitmapImage::BitmapImage): >+ (WebCore::BitmapImage::draw): >+ (WebCore::BitmapImage::determineMinimumSubsamplingLevel): >+ (WebCore::ImageFrameData::ImageFrameData): >+ (WebCore::ImageFrameData::clear): >+ (WebCore::ImageFrameData::solidColor): >+ (WebCore::BitmapImage::checkForSolidColor): Deleted. >+ (WebCore::FrameData::clear): Deleted. >+ * platform/graphics/cairo/GraphicsContext3DCairo.cpp: >+ (WebCore::GraphicsContext3D::ImageExtractor::extractImage): >+ * platform/graphics/cg/BitmapImageCG.cpp: >+ (WebCore::ImageFrameData::ImageFrameData): >+ (WebCore::ImageFrameData::clear): >+ (WebCore::ImageFrameData::solidColor): >+ (WebCore::BitmapImage::BitmapImage): >+ (WebCore::BitmapImage::determineMinimumSubsamplingLevel): >+ (WebCore::BitmapImage::getCGImageRef): >+ (WebCore::BitmapImage::getFirstCGImageRefOfSize): >+ (WebCore::BitmapImage::getCGImageArray): >+ (WebCore::BitmapImage::draw): >+ (WebCore::BitmapImage::copyUnscaledFrameImageAtIndex): >+ (WebCore::FrameData::clear): Deleted. >+ (WebCore::BitmapImage::checkForSolidColor): Deleted. >+ (WebCore::BitmapImage::copyUnscaledFrameAtIndex): Deleted. >+ * platform/graphics/cg/GraphicsContext3DCG.cpp: >+ (WebCore::GraphicsContext3D::ImageExtractor::extractImage): >+ (WebCore::GraphicsContext3D::paintToCanvas): >+ * platform/graphics/cg/GraphicsContextCG.cpp: >+ (WebCore::GraphicsContext::drawPattern): >+ * platform/graphics/cg/ImageDecoder.cpp: Copied from Source/WebCore/platform/graphics/cg/ImageSourceCG.cpp. >+ (WebCore::createImageSourceOptions): >+ (WebCore::imageSourceOptions): >+ (WebCore::orientationFromProperties): >+ (WebCore::sharedBufferGetBytesAtPosition): >+ (WebCore::sharedBufferRelease): >+ (WebCore::ImageDecoder::ImageDecoder): >+ (WebCore::ImageDecoder::subsamplingLevelForScale): >+ (WebCore::ImageDecoder::bytesDecodedToDetermineProperties): >+ (WebCore::ImageDecoder::filenameExtension): >+ (WebCore::ImageDecoder::isSizeAvailable): >+ (WebCore::ImageDecoder::size): >+ (WebCore::ImageDecoder::frameCount): >+ (WebCore::ImageDecoder::repetitionCount): >+ (WebCore::ImageDecoder::getHotSpot): >+ (WebCore::ImageDecoder::frameSizeAtIndex): >+ (WebCore::ImageDecoder::frameIsCompleteAtIndex): >+ (WebCore::ImageDecoder::orientationAtIndex): >+ (WebCore::ImageDecoder::frameDurationAtIndex): >+ (WebCore::ImageDecoder::allowSubsamplingOfFrameAtIndex): >+ (WebCore::ImageDecoder::frameHasAlphaAtIndex): >+ (WebCore::ImageDecoder::frameBytesAtIndex): >+ (WebCore::ImageDecoder::createFrameImageAtIndex): >+ (WebCore::ImageDecoder::setData): >+ * platform/graphics/cg/ImageDecoder.h: Added. >+ (WebCore::ImageDecoder::~ImageDecoder): >+ * platform/graphics/cg/ImageSourceCG.cpp: >+ (WebCore::ImageSource::clear): >+ (WebCore::ImageSource::ensureDecoderIsCreated): >+ (WebCore::ImageSource::setData): >+ (WebCore::ImageSource::filenameExtension): >+ (WebCore::ImageSource::subsamplingLevelForScale): >+ (WebCore::ImageSource::bytesDecodedToDetermineProperties): >+ (WebCore::ImageSource::isSizeAvailable): >+ (WebCore::ImageSource::allowSubsamplingOfFrameAtIndex): >+ (WebCore::ImageSource::frameSizeAtIndex): >+ (WebCore::ImageSource::orientationAtIndex): >+ (WebCore::ImageSource::size): >+ (WebCore::ImageSource::sizeRespectingOrientation): >+ (WebCore::ImageSource::getHotSpot): >+ (WebCore::ImageSource::repetitionCount): >+ (WebCore::ImageSource::frameCount): >+ (WebCore::ImageSource::createFrameImageAtIndex): >+ (WebCore::ImageSource::frameIsCompleteAtIndex): >+ (WebCore::ImageSource::frameDurationAtIndex): >+ (WebCore::ImageSource::frameHasAlphaAtIndex): >+ (WebCore::ImageSource::frameBytesAtIndex): >+ (WebCore::sharedBufferGetBytesAtPosition): Deleted. >+ (WebCore::sharedBufferRelease): Deleted. >+ (WebCore::ImageSource::ImageSource): Deleted. >+ (WebCore::createImageSourceOptions): Deleted. >+ (WebCore::imageSourceOptions): Deleted. >+ (WebCore::ImageSource::initialized): Deleted. >+ (WebCore::orientationFromProperties): Deleted. >+ (WebCore::ImageSource::createFrameAtIndex): Deleted. >+ * platform/graphics/efl/GraphicsContext3DEfl.cpp: >+ (WebCore::GraphicsContext3D::ImageExtractor::extractImage): >+ * platform/graphics/ios/IconIOS.mm: >+ (WebCore::Icon::Icon): >+ * platform/graphics/mac/ImageMac.mm: >+ (WebCore::BitmapImage::getTIFFRepresentation): >+ * platform/graphics/win/ImageCGWin.cpp: >+ (WebCore::BitmapImage::drawFrameMatchingSourceSize): >+ * platform/graphics/win/ImageCairoWin.cpp: >+ (WebCore::BitmapImage::drawFrameMatchingSourceSize): >+ * platform/mac/DragImageMac.mm: >+ (WebCore::createDragImageFromImage): >+ >+2016-03-13 Said Abou-Hallawa <sabouhallawa@apple,com> >+ >+ Create a CG ImageDecoder class instead of defining it as CGImageSourceRef >+ https://bugs.webkit.org/show_bug.cgi?id=155422 >+ >+ Reviewed by NOBODY (OOPS!). >+ >+ Move the image decoding code from ImageSourceCG.cpp out to a new class named >+ ImageDecoder. The purpose of this split is to have the CG ImageSource similar >+ to the none CG ImageSource where there is a separate class for decoding. The >+ plan is to merge the ImageSource.cpp and ImageSourceCG.cpp in one file so >+ deciding whether the decoding should happen synchronously or asynchronously >+ can happen in one place and the caching of the frames can be handled by the >+ ImageSource as well. >+ >+ * PlatformAppleWin.cmake: >+ * PlatformMac.cmake: >+ * WebCore.xcodeproj/project.pbxproj: >+ * loader/cache/CachedImage.cpp: >+ (WebCore::CachedImage::imageSizeForRenderer): >+ * platform/graphics/BitmapImage.cpp: >+ (WebCore::BitmapImage::updateSize): >+ (WebCore::BitmapImage::sizeRespectingOrientation): >+ (WebCore::BitmapImage::frameImageAtIndex): >+ (WebCore::BitmapImage::dump): Deleted. >+ * platform/graphics/BitmapImage.h: >+ * platform/graphics/ImageSource.cpp: >+ (WebCore::ImageSource::size): >+ (WebCore::ImageSource::sizeRespectingOrientation): >+ (WebCore::ImageSource::frameSizeAtIndex): >+ * platform/graphics/ImageSource.h: >+ (WebCore::ImageSource::initialized): >+ * platform/graphics/cg/BitmapImageCG.cpp: >+ (WebCore::BitmapImage::BitmapImage): >+ * platform/graphics/cg/ImageDecoder.cpp: Copied from Source/WebCore/platform/graphics/cg/ImageSourceCG.cpp. >+ (WebCore::createImageSourceOptions): >+ (WebCore::imageSourceOptions): >+ (WebCore::sharedBufferGetBytesAtPosition); >+ (WebCore::sharedBufferRelease); >+ (WebCore::orientationFromProperties): >+ (WebCore::ImageDecoder::ImageDecoder): >+ (WebCore::ImageDecoder::subsamplingLevelForScale): >+ (WebCore::ImageDecoder::bytesDecodedToDetermineProperties): >+ (WebCore::ImageDecoder::filenameExtension): >+ (WebCore::ImageDecoder::isSizeAvailable): >+ (WebCore::ImageDecoder::size): >+ (WebCore::ImageDecoder::frameCount): >+ (WebCore::ImageDecoder::repetitionCount): >+ (WebCore::ImageDecoder::getHotSpot): >+ (WebCore::ImageDecoder::frameSizeAtIndex): >+ (WebCore::ImageDecoder::frameIsCompleteAtIndex): >+ (WebCore::ImageDecoder::orientationAtIndex): >+ (WebCore::ImageDecoder::frameDurationAtIndex): >+ (WebCore::ImageDecoder::allowSubsamplingOfFrameAtIndex): >+ (WebCore::ImageDecoder::frameHasAlphaAtIndex): >+ (WebCore::ImageDecoder::frameBytesAtIndex): >+ (WebCore::ImageDecoder::createFrameImageAtIndex): >+ (WebCore::ImageDecoder::setData): >+ * platform/graphics/cg/ImageDecoder.h: Added. >+ (WebCore::ImageDecoder::~ImageDecoder): >+ * platform/graphics/cg/ImageSourceCG.cpp: >+ (WebCore::ImageSource::clear): >+ (WebCore::ImageSource::ensureDecoderIsCreated): >+ (WebCore::ImageSource::setData): >+ (WebCore::ImageSource::filenameExtension): >+ (WebCore::ImageSource::subsamplingLevelForScale): >+ (WebCore::ImageSource::bytesDecodedToDetermineProperties): >+ (WebCore::ImageSource::isSizeAvailable): >+ (WebCore::ImageSource::allowSubsamplingOfFrameAtIndex): >+ (WebCore::ImageSource::frameSizeAtIndex): >+ (WebCore::ImageSource::orientationAtIndex): >+ (WebCore::ImageSource::size): >+ (WebCore::ImageSource::sizeRespectingOrientation): >+ (WebCore::ImageSource::getHotSpot): >+ (WebCore::ImageSource::repetitionCount): >+ (WebCore::ImageSource::frameCount): >+ (WebCore::ImageSource::createFrameImageAtIndex): >+ (WebCore::ImageSource::frameIsCompleteAtIndex): >+ (WebCore::ImageSource::frameDurationAtIndex): >+ (WebCore::ImageSource::frameHasAlphaAtIndex): >+ (WebCore::ImageSource::frameBytesAtIndex): >+ (WebCore::sharedBufferGetBytesAtPosition): Deleted. >+ (WebCore::sharedBufferRelease): Deleted. >+ (WebCore::ImageSource::ImageSource): Deleted. >+ (WebCore::createImageSourceOptions): Deleted. >+ (WebCore::imageSourceOptions): Deleted. >+ (WebCore::ImageSource::initialized): Deleted. >+ (WebCore::orientationFromProperties): Deleted. >+ (WebCore::ImageSource::createFrameAtIndex): Deleted. >+ * platform/mac/DragImageMac.mm: >+ (WebCore::createDragImageFromImage): >+ * platform/graphics/cairo/BitmapImageCairo.cpp: >+ (WebCore::BitmapImage::determineMinimumSubsamplingLevel): >+ >+2016-03-13 Said Abou-Hallawa <sabouhallawa@apple,com> >+ >+ Change NativeImagePtr for CG to be RetainPtr<CGImageRef> >+ https://bugs.webkit.org/show_bug.cgi?id=155412 >+ >+ Reviewed by NOBODY (OOPS!). >+ >+ Having NativeImagePtr as a raw pointer makes managing the life cycle of >+ the CGImageRef hard. A lot of works was done to make sure the CG pointer >+ is maintained correctly. It was also not possible to move a FrameData since >+ calling the destructor was releasing the CGImageRef. >+ >+ I am going to follow this naming convention: >+ 1. An Image object can have one or more FrameData. A FrameData can be named >+ for shortness as "frame", "m_frames", etc. >+ 2. A FrameData can have zero or one NativeImagePtr. A NativeImagePtr can >+ be named as "image", "m_image", etc. >+ >+ * loader/cache/MemoryCache.cpp: >+ (WebCore::MemoryCache::addImageToCache): >+ * platform/graphics/BitmapImage.cpp: >+ (WebCore::BitmapImage::haveFrameImageAtIndex): >+ (WebCore::BitmapImage::cacheFrame): >+ (WebCore::BitmapImage::ensureFrameIsCached): >+ (WebCore::BitmapImage::frameImageAtIndex): >+ (WebCore::BitmapImage::nativeImageForCurrentFrame): >+ (WebCore::BitmapImage::haveFrameAtIndex): Deleted. >+ (WebCore::BitmapImage::frameAtIndex): Deleted. >+ * platform/graphics/BitmapImage.h: >+ (WebCore::FrameData::FrameData): Deleted. >+ * platform/graphics/Icon.h: >+ * platform/graphics/ImageSource.cpp: >+ (WebCore::ImageSource::createFrameImageAtIndex): >+ (WebCore::ImageSource::createFrameAtIndex): Deleted. >+ * platform/graphics/ImageSource.h: >+ * platform/graphics/NativeImagePtr.h: >+ * platform/graphics/ca/GraphicsLayerCA.cpp: >+ (WebCore::GraphicsLayerCA::setContentsToImage): >+ * platform/graphics/cairo/BitmapImageCairo.cpp: >+ (WebCore::BitmapImage::BitmapImage): >+ (WebCore::BitmapImage::draw): >+ (WebCore::BitmapImage::checkForSolidColor): >+ (WebCore::FrameData::clear): >+ * platform/graphics/cairo/GraphicsContext3DCairo.cpp: >+ (WebCore::GraphicsContext3D::ImageExtractor::extractImage): >+ * platform/graphics/cg/BitmapImageCG.cpp: >+ (WebCore::FrameData::clear): >+ (WebCore::BitmapImage::BitmapImage): >+ (WebCore::BitmapImage::checkForSolidColor): >+ (WebCore::BitmapImage::getCGImageRef): >+ (WebCore::BitmapImage::getFirstCGImageRefOfSize): >+ (WebCore::BitmapImage::getCGImageArray): >+ (WebCore::BitmapImage::draw): >+ (WebCore::BitmapImage::copyUnscaledFrameImageAtIndex): >+ (WebCore::BitmapImage::copyUnscaledFrameAtIndex): Deleted. >+ * platform/graphics/cg/GraphicsContext3DCG.cpp: >+ (WebCore::GraphicsContext3D::ImageExtractor::extractImage): >+ (WebCore::GraphicsContext3D::paintToCanvas): >+ * platform/graphics/cg/GraphicsContextCG.cpp: >+ (WebCore::GraphicsContext::drawPattern): >+ * platform/graphics/cg/ImageSourceCG.cpp: >+ (WebCore::ImageSource::createFrameImageAtIndex): >+ (WebCore::ImageSource::createFrameAtIndex): Deleted. >+ * platform/graphics/efl/GraphicsContext3DEfl.cpp: >+ (WebCore::GraphicsContext3D::ImageExtractor::extractImage): >+ * platform/graphics/ios/IconIOS.mm: >+ (WebCore::Icon::Icon): >+ * platform/graphics/mac/ImageMac.mm: >+ (WebCore::BitmapImage::getTIFFRepresentation): >+ * platform/graphics/win/ImageCGWin.cpp: >+ (WebCore::BitmapImage::drawFrameMatchingSourceSize): >+ * platform/graphics/win/ImageCairoWin.cpp: >+ (WebCore::BitmapImage::drawFrameMatchingSourceSize): >+ > 2016-03-12 Zalan Bujtas <zalan@apple.com> > > [Forms: focus] focus rings around text fields do not follow contour (border-radius) >diff --git a/Source/WebCore/PlatformAppleWin.cmake b/Source/WebCore/PlatformAppleWin.cmake >index e5209cb20cf03387a252643df4e0b215149204f7..7b367a73ac9e15bd95c89c97a36a0f025f728078 100644 >--- a/Source/WebCore/PlatformAppleWin.cmake >+++ b/Source/WebCore/PlatformAppleWin.cmake >@@ -71,6 +71,7 @@ list(APPEND WebCore_SOURCES > platform/graphics/cg/ImageBufferCG.cpp > platform/graphics/cg/ImageBufferDataCG.cpp > platform/graphics/cg/ImageCG.cpp >+ platform/graphics/cg/ImageDecoder.cpp > platform/graphics/cg/ImageSourceCG.cpp > platform/graphics/cg/ImageSourceCGWin.cpp > platform/graphics/cg/IntPointCG.cpp >diff --git a/Source/WebCore/PlatformMac.cmake b/Source/WebCore/PlatformMac.cmake >index 835b9aa224aa9eaaee04623397e99016e9f7eebf..dacda5691a65c6656063a4c0706c10a0efb6214f 100644 >--- a/Source/WebCore/PlatformMac.cmake >+++ b/Source/WebCore/PlatformMac.cmake >@@ -400,6 +400,7 @@ list(APPEND WebCore_SOURCES > platform/graphics/cg/ImageBufferCG.cpp > platform/graphics/cg/ImageBufferDataCG.cpp > platform/graphics/cg/ImageCG.cpp >+ platform/graphics/cg/ImageDecoder.cpp > platform/graphics/cg/ImageSourceCG.cpp > platform/graphics/cg/ImageSourceCGMac.mm > platform/graphics/cg/IntPointCG.cpp >diff --git a/Source/WebCore/WebCore.xcodeproj/project.pbxproj b/Source/WebCore/WebCore.xcodeproj/project.pbxproj >index 0307ba38ff0f3a4c471b9d429146162a959ee766..d13e9b8390a1bd0b217c4238843ce4bd4cd0be0d 100644 >--- a/Source/WebCore/WebCore.xcodeproj/project.pbxproj >+++ b/Source/WebCore/WebCore.xcodeproj/project.pbxproj >@@ -2291,6 +2291,10 @@ > 53EF766C16531994004CBE49 /* SettingsMacros.h in Copy Generated Headers */ = {isa = PBXBuildFile; fileRef = 53EF766A16530A61004CBE49 /* SettingsMacros.h */; }; > 550A0BC9085F6039007353D6 /* QualifiedName.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 550A0BC7085F6039007353D6 /* QualifiedName.cpp */; }; > 550A0BCA085F6039007353D6 /* QualifiedName.h in Headers */ = {isa = PBXBuildFile; fileRef = 550A0BC8085F6039007353D6 /* QualifiedName.h */; settings = {ATTRIBUTES = (Private, ); }; }; >+ 559BB8791C964658002413CD /* ImageDecoder.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 559BB8771C964658002413CD /* ImageDecoder.cpp */; }; >+ 559BB87A1C964658002413CD /* ImageDecoder.h in Headers */ = {isa = PBXBuildFile; fileRef = 559BB8781C964658002413CD /* ImageDecoder.h */; }; >+ 559BB87D1C96B2C8002413CD /* ImageFrameData.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 559BB87B1C96B2C8002413CD /* ImageFrameData.cpp */; }; >+ 559BB87E1C96B2C9002413CD /* ImageFrameData.h in Headers */ = {isa = PBXBuildFile; fileRef = 559BB87C1C96B2C8002413CD /* ImageFrameData.h */; settings = {ATTRIBUTES = (Private, ); }; }; > 572A7F211C6E5719009C6149 /* SimulatedClick.h in Headers */ = {isa = PBXBuildFile; fileRef = 572A7F201C6E5719009C6149 /* SimulatedClick.h */; }; > 572A7F231C6E5A66009C6149 /* SimulatedClick.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 572A7F221C6E5A66009C6149 /* SimulatedClick.cpp */; }; > 580371611A66F00A00BAF519 /* ClipRect.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5803715F1A66F00A00BAF519 /* ClipRect.cpp */; }; >@@ -9875,6 +9879,10 @@ > 53EF766A16530A61004CBE49 /* SettingsMacros.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SettingsMacros.h; sourceTree = "<group>"; }; > 550A0BC7085F6039007353D6 /* QualifiedName.cpp */ = {isa = PBXFileReference; fileEncoding = 30; indentWidth = 4; lastKnownFileType = sourcecode.cpp.cpp; path = QualifiedName.cpp; sourceTree = "<group>"; tabWidth = 8; usesTabs = 0; }; > 550A0BC8085F6039007353D6 /* QualifiedName.h */ = {isa = PBXFileReference; fileEncoding = 30; indentWidth = 4; lastKnownFileType = sourcecode.c.h; path = QualifiedName.h; sourceTree = "<group>"; tabWidth = 8; usesTabs = 0; }; >+ 559BB8771C964658002413CD /* ImageDecoder.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ImageDecoder.cpp; sourceTree = "<group>"; }; >+ 559BB8781C964658002413CD /* ImageDecoder.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ImageDecoder.h; sourceTree = "<group>"; }; >+ 559BB87B1C96B2C8002413CD /* ImageFrameData.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ImageFrameData.cpp; sourceTree = "<group>"; }; >+ 559BB87C1C96B2C8002413CD /* ImageFrameData.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ImageFrameData.h; sourceTree = "<group>"; }; > 55D408F71A7C631800C78450 /* SVGImageClients.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SVGImageClients.h; sourceTree = "<group>"; }; > 572A7F201C6E5719009C6149 /* SimulatedClick.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SimulatedClick.h; sourceTree = "<group>"; }; > 572A7F221C6E5A66009C6149 /* SimulatedClick.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SimulatedClick.cpp; sourceTree = "<group>"; }; >@@ -21833,6 +21841,8 @@ > 2292B27B1356669400CF11EF /* ImageBufferDataCG.cpp */, > 22BD9F80135364FE009BD102 /* ImageBufferDataCG.h */, > B27535300B053814002CE64F /* ImageCG.cpp */, >+ 559BB8771C964658002413CD /* ImageDecoder.cpp */, >+ 559BB8781C964658002413CD /* ImageDecoder.h */, > B27535310B053814002CE64F /* ImageSourceCG.cpp */, > 4B3480920EEF50D400AC1B41 /* ImageSourceCG.h */, > 4B3480910EEF50D400AC1B41 /* ImageSourceCGMac.mm */, >@@ -21995,6 +22005,8 @@ > 43D2597613C816F400608559 /* ImageBuffer.cpp */, > B2A10B910B3818BD00099AA4 /* ImageBuffer.h */, > 22BD9F7D1353625C009BD102 /* ImageBufferData.h */, >+ 559BB87B1C96B2C8002413CD /* ImageFrameData.cpp */, >+ 559BB87C1C96B2C8002413CD /* ImageFrameData.h */, > BC7F44A70B9E324E00A9D081 /* ImageObserver.h */, > A8748D7412CC3F89001FBA41 /* ImageOrientation.cpp */, > A8748D6612CC3763001FBA41 /* ImageOrientation.h */, >@@ -25475,6 +25487,7 @@ > 97BC6A241505F081001B74AC /* DatabaseAuthorizer.h in Headers */, > FE3371A2167C11D400EDB752 /* DatabaseBasicTypes.h in Headers */, > 97BC6A251505F081001B74AC /* DatabaseCallback.h in Headers */, >+ 559BB87E1C96B2C9002413CD /* ImageFrameData.h in Headers */, > 97BC6A281505F081001B74AC /* DatabaseContext.h in Headers */, > 97BC6A291505F081001B74AC /* DatabaseDetails.h in Headers */, > FE09DB49169E2D6E00622557 /* DatabaseError.h in Headers */, >@@ -26812,6 +26825,7 @@ > FDA15ECE12B03F61003A583A /* JSScriptProcessorNode.h in Headers */, > 9FA37EFB1172FDA600C4CD55 /* JSScriptProfile.h in Headers */, > 9FA37EFD1172FDA600C4CD55 /* JSScriptProfileNode.h in Headers */, >+ 559BB87A1C964658002413CD /* ImageDecoder.h in Headers */, > CED06AD11C77754800FDFAF1 /* JSSecurityPolicyViolationEvent.h in Headers */, > 9BDA64D81B975CF2009C4387 /* JSShadowRoot.h in Headers */, > CD9DE17B17AAC75B00EA386D /* JSSourceBuffer.h in Headers */, >@@ -29203,6 +29217,7 @@ > B27535660B053814002CE64F /* Color.cpp in Sources */, > 0FCF33240F2B9715004B6795 /* ColorCG.cpp in Sources */, > 1ABA76C911D20E47004C201C /* ColorData.cpp in Sources */, >+ 559BB8791C964658002413CD /* ImageDecoder.cpp in Sources */, > BC29935D17A1DD5800BCE880 /* ColorInputType.cpp in Sources */, > B27535770B053814002CE64F /* ColorMac.mm in Sources */, > 43EDD67E1B485DBF00640E75 /* CombinedFiltersAlphabet.cpp in Sources */, >@@ -29598,6 +29613,7 @@ > 853BF4DC0ABB6B55008647BB /* DOMNode.mm in Sources */, > 85526C380AB0A17E000302EA /* DOMNodeIterator.mm in Sources */, > 85ACAA8E0A9B759C00671E90 /* DOMNodeList.mm in Sources */, >+ 559BB87D1C96B2C8002413CD /* ImageFrameData.cpp in Sources */, > 856C8AE50A912649005C687B /* DOMObject.mm in Sources */, > 85C7F5D10AAFB8D9004014DD /* DOMOverflowEvent.mm in Sources */, > E1284BD51044A01E00EAEB52 /* DOMPageTransitionEvent.mm in Sources */, >diff --git a/Source/WebCore/loader/cache/CachedImage.cpp b/Source/WebCore/loader/cache/CachedImage.cpp >index f3787521ddfff682bd88e6472caf0625e3f04544..9a147578837fcde1310d1ad10622b7bb70684adb 100644 >--- a/Source/WebCore/loader/cache/CachedImage.cpp >+++ b/Source/WebCore/loader/cache/CachedImage.cpp >@@ -278,7 +278,7 @@ LayoutSize CachedImage::imageSizeForRenderer(const RenderObject* renderer, float > if (renderer && is<BitmapImage>(*m_image)) { > ImageOrientationDescription orientationDescription(renderer->shouldRespectImageOrientation(), renderer->style().imageOrientation()); > if (orientationDescription.respectImageOrientation() == RespectImageOrientation) >- imageSize = LayoutSize(downcast<BitmapImage>(*m_image).sizeRespectingOrientation(orientationDescription)); >+ imageSize = LayoutSize(downcast<BitmapImage>(*m_image).sizeRespectingOrientation()); > } > #else > if (is<BitmapImage>(*m_image) && (renderer && renderer->shouldRespectImageOrientation() == RespectImageOrientation)) >diff --git a/Source/WebCore/loader/cache/MemoryCache.cpp b/Source/WebCore/loader/cache/MemoryCache.cpp >index 999465ea390697cbe00fe6fa8838c138e5447a17..846c0dc9384e75dba0820c280fb641ce8a08f160 100644 >--- a/Source/WebCore/loader/cache/MemoryCache.cpp >+++ b/Source/WebCore/loader/cache/MemoryCache.cpp >@@ -225,8 +225,6 @@ bool MemoryCache::addImageToCache(NativeImagePtr image, const URL& url, const St > > std::unique_ptr<CachedImage> cachedImage = std::make_unique<CachedImage>(url, bitmapImage.get(), CachedImage::ManuallyCached, sessionID); > >- // Actual release of the CGImageRef is done in BitmapImage. >- CFRetain(image); > cachedImage->addClient(&dummyCachedImageClient()); > cachedImage->setDecodedSize(bitmapImage->decodedSize()); > #if ENABLE(CACHE_PARTITIONING) >diff --git a/Source/WebCore/platform/graphics/BitmapImage.cpp b/Source/WebCore/platform/graphics/BitmapImage.cpp >index faf0f86962c3fb6577745bfaf75b4c84d80cc060..6e43c7714b0a05ecccc60c13b25781b8ec9cb3b4 100644 >--- a/Source/WebCore/platform/graphics/BitmapImage.cpp >+++ b/Source/WebCore/platform/graphics/BitmapImage.cpp >@@ -47,9 +47,6 @@ namespace WebCore { > > BitmapImage::BitmapImage(ImageObserver* observer) > : Image(observer) >- , m_minimumSubsamplingLevel(0) >- , m_imageOrientation(OriginTopLeft) >- , m_shouldRespectImageOrientation(false) > , m_currentFrame(0) > , m_repetitionCount(cAnimationNone) > , m_repetitionCountStatus(Unknown) >@@ -66,13 +63,10 @@ BitmapImage::BitmapImage(ImageObserver* observer) > #else > , m_allowSubsampling(false) > #endif >- , m_isSolidColor(false) >- , m_checkedForSolidColor(false) > , m_animationFinished(false) > , m_allDataReceived(false) > , m_haveSize(false) > , m_sizeAvailable(false) >- , m_hasUniformFrameSize(true) > , m_haveFrameCount(false) > , m_animationFinishedWhenCatchingUp(false) > { >@@ -96,7 +90,7 @@ void BitmapImage::startTimer(double delay) > m_frameTimer->startOneShot(delay); > } > >-bool BitmapImage::haveFrameAtIndex(size_t index) >+bool BitmapImage::haveFrameImageAtIndex(size_t index) > { > if (index >= frameCount()) > return false; >@@ -104,7 +98,7 @@ bool BitmapImage::haveFrameAtIndex(size_t index) > if (index >= m_frames.size()) > return false; > >- return m_frames[index].m_frame; >+ return m_frames[index].m_image; > } > > bool BitmapImage::hasSingleSecurityOrigin() const >@@ -125,7 +119,7 @@ void BitmapImage::destroyDecodedData(bool destroyAll) > // save the memory for the framebuffer data), so we don't need to clear > // the metadata. > unsigned frameBytes = m_frames[i].m_frameBytes; >- if (m_frames[i].clear(false)) >+ if (m_frames[i].clear(ImageFrameCaching::CacheMetadata)) > frameBytesCleared += frameBytes; > } > >@@ -158,8 +152,7 @@ void BitmapImage::destroyDecodedDataIfNecessary(bool destroyAll) > > void BitmapImage::destroyMetadataAndNotify(unsigned frameBytesCleared, ClearedSource clearedSource) > { >- m_isSolidColor = false; >- m_checkedForSolidColor = false; >+ m_solidColorValue = TriState::Unchecked; > invalidatePlatformData(); > > ASSERT(m_decodedSize >= frameBytesCleared); >@@ -183,11 +176,9 @@ void BitmapImage::cacheFrame(size_t index, SubsamplingLevel subsamplingLevel, Im > if (m_frames.size() < numFrames) > m_frames.grow(numFrames); > >- if (frameCaching == CacheMetadataAndFrame) { >- m_frames[index].m_frame = m_source.createFrameAtIndex(index, subsamplingLevel); >+ if (frameCaching == ImageFrameCaching::CacheMetadataAndFrame) { >+ m_frames[index].m_image = m_source.createFrameImageAtIndex(index, subsamplingLevel); > m_frames[index].m_subsamplingLevel = subsamplingLevel; >- if (numFrames == 1 && m_frames[index].m_frame) >- checkForSolidColor(); > } > > m_frames[index].m_orientation = m_source.orientationAtIndex(index); >@@ -200,11 +191,7 @@ void BitmapImage::cacheFrame(size_t index, SubsamplingLevel subsamplingLevel, Im > m_frames[index].m_hasAlpha = m_source.frameHasAlphaAtIndex(index); > m_frames[index].m_frameBytes = m_source.frameBytesAtIndex(index, subsamplingLevel); > >- const IntSize frameSize(index ? m_source.frameSizeAtIndex(index, subsamplingLevel) : m_size); >- if (!subsamplingLevel && frameSize != m_size) >- m_hasUniformFrameSize = false; >- >- if (m_frames[index].m_frame) { >+ if (m_frames[index].m_image) { > int deltaBytes = safeCast<int>(m_frames[index].m_frameBytes); > m_decodedSize += deltaBytes; > // The fully-decoded frame will subsume the partially decoded data used >@@ -236,16 +223,13 @@ void BitmapImage::didDecodeProperties() const > imageObserver()->decodedSizeChanged(this, deltaBytes); > } > >-void BitmapImage::updateSize(ImageOrientationDescription description) const >+void BitmapImage::updateSize() const > { > if (!m_sizeAvailable || m_haveSize) > return; > >- m_size = m_source.size(description); >- m_sizeRespectingOrientation = m_source.size(ImageOrientationDescription(RespectImageOrientation, description.imageOrientation())); >- >- m_imageOrientation = static_cast<unsigned>(description.imageOrientation()); >- m_shouldRespectImageOrientation = static_cast<unsigned>(description.respectImageOrientation()); >+ m_size = m_source.size(); >+ m_sizeRespectingOrientation = m_source.sizeRespectingOrientation(); > > m_haveSize = true; > >@@ -259,9 +243,9 @@ FloatSize BitmapImage::size() const > return m_size; > } > >-IntSize BitmapImage::sizeRespectingOrientation(ImageOrientationDescription description) const >+IntSize BitmapImage::sizeRespectingOrientation() const > { >- updateSize(description); >+ updateSize(); > return m_sizeRespectingOrientation; > } > >@@ -301,7 +285,7 @@ bool BitmapImage::dataChanged(bool allDataReceived) > // cleared-on-a-previous-pass) frames! > unsigned frameBytes = m_frames[i].m_frameBytes; > if (m_frames[i].m_haveMetadata && !m_frames[i].m_isComplete) >- frameBytesCleared += (m_frames[i].clear(true) ? frameBytes : 0); >+ frameBytesCleared += (m_frames[i].clear(ImageFrameCaching::CacheNone) ? frameBytes : 0); > } > destroyMetadataAndNotify(frameBytesCleared, ClearedSource::No); > #else >@@ -340,7 +324,6 @@ bool BitmapImage::dataChanged(bool allDataReceived) > #endif > > m_haveFrameCount = false; >- m_hasUniformFrameSize = true; > return isSizeAvailable(); > } > >@@ -379,26 +362,26 @@ bool BitmapImage::ensureFrameIsCached(size_t index, ImageFrameCaching frameCachi > return false; > > if (index >= m_frames.size() >- || (frameCaching == CacheMetadataAndFrame && !m_frames[index].m_frame) >- || (frameCaching == CacheMetadataOnly && !m_frames[index].m_haveMetadata)) >+ || (frameCaching == ImageFrameCaching::CacheMetadataAndFrame && !m_frames[index].m_image) >+ || (frameCaching == ImageFrameCaching::CacheMetadata && !m_frames[index].m_haveMetadata)) > cacheFrame(index, 0, frameCaching); > > return true; > } > >-PassNativeImagePtr BitmapImage::frameAtIndex(size_t index, float presentationScaleHint) >+PassNativeImagePtr BitmapImage::frameImageAtIndex(size_t index, float presentationScaleHint) > { > if (index >= frameCount()) > return nullptr; > >- SubsamplingLevel subsamplingLevel = std::min(m_source.subsamplingLevelForScale(presentationScaleHint), m_minimumSubsamplingLevel); >+ SubsamplingLevel subsamplingLevel = m_source.subsamplingLevelForScale(presentationScaleHint, m_maximumSubsamplingLevel); > > // We may have cached a frame with a higher subsampling level, in which case we need to > // re-decode with a lower level. >- if (index < m_frames.size() && m_frames[index].m_frame && subsamplingLevel < m_frames[index].m_subsamplingLevel) { >+ if (index < m_frames.size() && m_frames[index].m_image && subsamplingLevel < m_frames[index].m_subsamplingLevel) { > // If the image is already cached, but at too small a size, re-decode a larger version. > int sizeChange = -m_frames[index].m_frameBytes; >- m_frames[index].clear(true); >+ m_frames[index].clear(ImageFrameCaching::CacheNone); > invalidatePlatformData(); > m_decodedSize += sizeChange; > if (imageObserver()) >@@ -406,15 +389,15 @@ PassNativeImagePtr BitmapImage::frameAtIndex(size_t index, float presentationSca > } > > // If we haven't fetched a frame yet, do so. >- if (index >= m_frames.size() || !m_frames[index].m_frame) >- cacheFrame(index, subsamplingLevel, CacheMetadataAndFrame); >+ if (index >= m_frames.size() || !m_frames[index].m_image) >+ cacheFrame(index, subsamplingLevel, ImageFrameCaching::CacheMetadataAndFrame); > >- return m_frames[index].m_frame; >+ return m_frames[index].m_image; > } > > bool BitmapImage::frameIsCompleteAtIndex(size_t index) > { >- if (!ensureFrameIsCached(index, CacheMetadataOnly)) >+ if (!ensureFrameIsCached(index, ImageFrameCaching::CacheMetadata)) > return false; > > return m_frames[index].m_isComplete; >@@ -422,7 +405,7 @@ bool BitmapImage::frameIsCompleteAtIndex(size_t index) > > float BitmapImage::frameDurationAtIndex(size_t index) > { >- if (!ensureFrameIsCached(index, CacheMetadataOnly)) >+ if (!ensureFrameIsCached(index, ImageFrameCaching::CacheMetadata)) > return 0; > > return m_frames[index].m_duration; >@@ -430,12 +413,12 @@ float BitmapImage::frameDurationAtIndex(size_t index) > > PassNativeImagePtr BitmapImage::nativeImageForCurrentFrame() > { >- return frameAtIndex(currentFrame()); >+ return frameImageAtIndex(currentFrame()); > } > > bool BitmapImage::frameHasAlphaAtIndex(size_t index) > { >- if (!ensureFrameIsCached(index, CacheMetadataOnly)) >+ if (!ensureFrameIsCached(index, ImageFrameCaching::CacheMetadata)) > return true; > > if (m_frames[index].m_haveMetadata) >@@ -451,7 +434,7 @@ bool BitmapImage::currentFrameKnownToBeOpaque() > > ImageOrientation BitmapImage::frameOrientationAtIndex(size_t index) > { >- if (!ensureFrameIsCached(index, CacheMetadataOnly)) >+ if (!ensureFrameIsCached(index, ImageFrameCaching::CacheMetadata)) > return DefaultImageOrientation; > > if (m_frames[index].m_haveMetadata) >@@ -678,19 +661,49 @@ bool BitmapImage::internalAdvanceAnimation(AnimationAdvancement advancement) > > return advancedAnimation; > } >+ >+void BitmapImage::checkForSolidColor() >+{ >+ m_solidColorValue = TriState::No; >+ >+ if (frameCount() > 1) >+ return; >+ >+ if (!haveFrameImageAtIndex(0)) { >+ IntSize size = m_source.frameSizeAtIndex(0, 0); >+ if (size.width() != 1 || size.height() != 1) >+ return; >+ >+ if (!ensureFrameIsCached(0)) >+ return; >+ } >+ >+ if (!m_frames.size()) >+ return; >+ >+ if (Optional<Color> color = m_frames[0].solidColor()) { >+ m_solidColor = color.value(); >+ m_solidColorValue = TriState::Yes; >+ } >+} > >-bool BitmapImage::mayFillWithSolidColor() >+bool BitmapImage::isSolidColor() > { >- if (!m_checkedForSolidColor && frameCount() > 0) { >+ if (m_solidColorValue == TriState::Unchecked && frameCount() > 0) { > checkForSolidColor(); >- ASSERT(m_checkedForSolidColor); >+ ASSERT(m_solidColorValue != TriState::Unchecked); > } >- return m_isSolidColor && !m_currentFrame; >+ return m_solidColorValue == TriState::Yes; > } >- >-Color BitmapImage::solidColor() const >+ >+bool BitmapImage::mayFillWithSolidColor() >+{ >+ return isSolidColor() && !m_currentFrame; >+} >+ >+Color BitmapImage::solidColor() > { >- return m_solidColor; >+ return isSolidColor() ? m_solidColor : Color(); > } > > bool BitmapImage::canAnimate() >@@ -712,11 +725,8 @@ void BitmapImage::dump(TextStream& ts) const > > if (allowSubsampling()) > ts.dumpProperty("allow-subsampling", allowSubsampling()); >- if (m_isSolidColor) >- ts.dumpProperty("solid-color", m_isSolidColor); >- >- if (m_imageOrientation != OriginTopLeft) >- ts.dumpProperty("orientation", m_imageOrientation); >+ if (m_solidColorValue == TriState::Yes) >+ ts.dumpProperty("solid-color", m_solidColor); > } > > } >diff --git a/Source/WebCore/platform/graphics/BitmapImage.h b/Source/WebCore/platform/graphics/BitmapImage.h >index 7493c6a4bfb863d97637c49c464cc37ae78e0a04..d997edd52e263b55fc2d0819a6c73216823b9256 100644 >--- a/Source/WebCore/platform/graphics/BitmapImage.h >+++ b/Source/WebCore/platform/graphics/BitmapImage.h >@@ -30,6 +30,7 @@ > > #include "Image.h" > #include "Color.h" >+#include "ImageFrameData.h" > #include "ImageOrientation.h" > #include "ImageSource.h" > #include "IntSize.h" >@@ -47,61 +48,9 @@ typedef struct HBITMAP__ *HBITMAP; > #endif > > namespace WebCore { >- struct FrameData; >-} >- >-namespace WTF { >- template<> struct VectorTraits<WebCore::FrameData> : public SimpleClassVectorTraits { >- static const bool canInitializeWithMemset = false; // Not all FrameData members initialize to 0. >- }; >-} >- >-namespace WebCore { > > class Timer; > >-// ================================================ >-// FrameData Class >-// ================================================ >- >-struct FrameData { >- WTF_MAKE_NONCOPYABLE(FrameData); >-public: >- FrameData() >- : m_frame(0) >- , m_orientation(DefaultImageOrientation) >- , m_subsamplingLevel(0) >- , m_duration(0) >- , m_haveMetadata(false) >- , m_isComplete(false) >- , m_hasAlpha(true) >- , m_frameBytes(0) >- { >- } >- >- ~FrameData() >- { >- clear(true); >- } >- >- // Clear the cached image data on the frame, and (optionally) the metadata. >- // Returns whether there was cached image data to clear. >- bool clear(bool clearMetadata); >- >- NativeImagePtr m_frame; >- ImageOrientation m_orientation; >- SubsamplingLevel m_subsamplingLevel; >- float m_duration; >- bool m_haveMetadata : 1; >- bool m_isComplete : 1; >- bool m_hasAlpha : 1; >- unsigned m_frameBytes; >-}; >- >-// ================================================= >-// BitmapImage Class >-// ================================================= >- > class BitmapImage final : public Image { > friend class GeneratedImage; > friend class CrossfadeGeneratedImage; >@@ -125,7 +74,7 @@ public: > > // FloatSize due to override. > FloatSize size() const override; >- IntSize sizeRespectingOrientation(ImageOrientationDescription = ImageOrientationDescription()) const; >+ IntSize sizeRespectingOrientation() const; > > bool getHotSpot(IntPoint&) const override; > >@@ -189,7 +138,7 @@ public: > private: > bool isBitmapImage() const override { return true; } > >- void updateSize(ImageOrientationDescription = ImageOrientationDescription()) const; >+ void updateSize() const; > void determineMinimumSubsamplingLevel() const; > > protected: >@@ -214,10 +163,10 @@ protected: > > size_t frameCount(); > >- PassNativeImagePtr frameAtIndex(size_t, float presentationScaleHint = 1); >- PassNativeImagePtr copyUnscaledFrameAtIndex(size_t); >+ PassNativeImagePtr frameImageAtIndex(size_t, float presentationScaleHint = 1); >+ PassNativeImagePtr copyUnscaledFrameImageAtIndex(size_t); > >- bool haveFrameAtIndex(size_t); >+ bool haveFrameImageAtIndex(size_t); > > bool frameIsCompleteAtIndex(size_t); > float frameDurationAtIndex(size_t); >@@ -225,11 +174,10 @@ protected: > ImageOrientation frameOrientationAtIndex(size_t); > > // Decodes and caches a frame. Never accessed except internally. >- enum ImageFrameCaching { CacheMetadataOnly, CacheMetadataAndFrame }; >- void cacheFrame(size_t index, SubsamplingLevel, ImageFrameCaching = CacheMetadataAndFrame); >+ void cacheFrame(size_t index, SubsamplingLevel, ImageFrameCaching = ImageFrameCaching::CacheMetadataAndFrame); > > // Called before accessing m_frames[index] for info without decoding. Returns false on index out of bounds. >- bool ensureFrameIsCached(size_t index, ImageFrameCaching = CacheMetadataAndFrame); >+ bool ensureFrameIsCached(size_t index, ImageFrameCaching = ImageFrameCaching::CacheMetadataAndFrame); > > // Called to invalidate cached data. When |destroyAll| is true, we wipe out > // the entire frame buffer cache and tell the image source to destroy >@@ -280,8 +228,9 @@ protected: > // changed. > void checkForSolidColor(); > >+ bool isSolidColor(); > bool mayFillWithSolidColor() override; >- Color solidColor() const override; >+ Color solidColor() override; > > #if !ASSERT_DISABLED > bool notSolidColor() override; >@@ -297,13 +246,10 @@ private: > mutable IntSize m_size; // The size to use for the overall image (will just be the size of the first image). > mutable IntSize m_sizeRespectingOrientation; > >- mutable SubsamplingLevel m_minimumSubsamplingLevel; >- >- mutable unsigned m_imageOrientation : 4; // ImageOrientationEnum >- mutable unsigned m_shouldRespectImageOrientation : 1; // RespectImageOrientationEnum >+ mutable SubsamplingLevel m_maximumSubsamplingLevel { 0 }; > > size_t m_currentFrame; // The index of the current frame of animation. >- Vector<FrameData, 1> m_frames; // An array of the cached frames of the animation. We have to ref frames to pin them in the cache. >+ Vector<ImageFrameData, 1> m_frames; // An array of the cached frames of the animation. We have to ref frames to pin them in the cache. > > std::unique_ptr<Timer> m_frameTimer; > int m_repetitionCount; // How many total animation loops we should do. This will be cAnimationNone if this image type is incapable of animation. >@@ -330,16 +276,15 @@ private: > uint16_t m_progressiveLoadChunkCount; > #endif > >+ enum class TriState { Unchecked, No, Yes }; >+ TriState m_solidColorValue { TriState::Unchecked }; >+ > bool m_allowSubsampling : 1; // Whether we should attempt subsampling if this image is very large. >- bool m_isSolidColor : 1; // Whether or not we are a 1x1 solid image. >- bool m_checkedForSolidColor : 1; // Whether we've checked the frame for solid color. >- > bool m_animationFinished : 1; // Whether or not we've completed the entire animation. > > bool m_allDataReceived : 1; // Whether or not we've received all our data. > mutable bool m_haveSize : 1; // Whether or not our |m_size| member variable has the final overall image size yet. > bool m_sizeAvailable : 1; // Whether or not we can obtain the size of the first image frame yet from ImageIO. >- mutable bool m_hasUniformFrameSize : 1; > mutable bool m_haveFrameCount : 1; > bool m_animationFinishedWhenCatchingUp : 1; > >diff --git a/Source/WebCore/platform/graphics/Icon.h b/Source/WebCore/platform/graphics/Icon.h >index d95e7deb810fc24f7f61b1b23a4b9aef3f3c17b7..28c137d29b118a9cf1b6161ede4de491d0488308 100644 >--- a/Source/WebCore/platform/graphics/Icon.h >+++ b/Source/WebCore/platform/graphics/Icon.h >@@ -68,8 +68,8 @@ public: > > private: > #if PLATFORM(IOS) >- Icon(CGImageRef); >- RetainPtr<CGImageRef> m_cgImage; >+ Icon(NativeImagePtr); >+ NativeImagePtr m_cgImage; > #elif PLATFORM(MAC) > Icon(NSImage*); > RetainPtr<NSImage> m_nsImage; >diff --git a/Source/WebCore/platform/graphics/Image.h b/Source/WebCore/platform/graphics/Image.h >index 41fef2a2b03170e3b03fd6c52a2fdf283e562758..b12c0c1ee2ff814145dad0a346d1c7a774b6a78c 100644 >--- a/Source/WebCore/platform/graphics/Image.h >+++ b/Source/WebCore/platform/graphics/Image.h >@@ -194,7 +194,7 @@ protected: > > // Supporting tiled drawing > virtual bool mayFillWithSolidColor() { return false; } >- virtual Color solidColor() const { return Color(); } >+ virtual Color solidColor() { return Color(); } > > private: > RefPtr<SharedBuffer> m_encodedImageData; >diff --git a/Source/WebCore/platform/graphics/ImageFrameData.cpp b/Source/WebCore/platform/graphics/ImageFrameData.cpp >new file mode 100644 >index 0000000000000000000000000000000000000000..3af682087a36f5da296b0d8f4aca03cb8f627189 >--- /dev/null >+++ b/Source/WebCore/platform/graphics/ImageFrameData.cpp >@@ -0,0 +1,84 @@ >+/* >+ * Copyright (C) 2016 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 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 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 "ImageFrameData.h" >+ >+#include "ImageDecoder.h" >+ >+namespace WebCore { >+ >+ImageFrameData::ImageFrameData() >+{ >+} >+ >+ImageFrameData::ImageFrameData(ImageDecoder& decoder, size_t index, SubsamplingLevel subsamplingLevel, const NativeImagePtr& image) >+ : m_image(image) >+ , m_subsamplingLevel(subsamplingLevel) >+ , m_haveMetadata(true) >+{ >+#if USE(CG) >+ m_orientation = decoder.orientationAtIndex(index); >+ m_hasAlpha = decoder.frameHasAlphaAtIndex(index); >+ m_frameBytes = decoder.frameBytesAtIndex(index, subsamplingLevel); >+ >+ m_allowSubsampling = decoder.allowSubsamplingOfFrameAtIndex(index); >+ >+ m_isComplete = decoder.frameIsCompleteAtIndex(index); >+ if (decoder.repetitionCount() != cAnimationNone) >+ m_duration = decoder.frameDurationAtIndex(index); >+#else >+ m_orientation = decoder.orientation(); >+ m_hasAlpha = decoder.frameHasAlphaAtIndex(index); >+ m_frameBytes = decoder.frameBytesAtIndex(index); >+ >+ ImageFrame* buffer = decoder.frameBufferAtIndex(index); >+ if (buffer && buffer->status() != ImageFrame::FrameEmpty) { >+ m_isComplete = buffer->status() == ImageFrame::FrameComplete; >+ if (decoder.repetitionCount() != cAnimationNone) { >+ // Many annoying ads specify a 0 duration to make an image flash as quickly as possible. >+ // We follow Firefox's behavior and use a duration of 100 ms for any frames that specify >+ // a duration of <= 10 ms. See <rdar://problem/7689300> and <http://webkit.org/b/36082> >+ // for more information. >+ m_duration = std::max(buffer->duration() / 1000.0f, 0.100f); >+ } >+ } >+#endif >+} >+ >+ImageFrameData::~ImageFrameData() >+{ >+ clear(ImageFrameCaching::CacheNone); >+} >+ >+ImageFrameStatus ImageFrameData::status() const >+{ >+ if (!m_image) >+ return ImageFrameStatus::DecodeNone; >+ >+ return m_isComplete ? ImageFrameStatus::DecodeComplete : ImageFrameStatus::DecodePartial; >+} >+ >+} >diff --git a/Source/WebCore/platform/graphics/ImageFrameData.h b/Source/WebCore/platform/graphics/ImageFrameData.h >new file mode 100644 >index 0000000000000000000000000000000000000000..14aff864228879ffd5fdd35073ad5897b560633a >--- /dev/null >+++ b/Source/WebCore/platform/graphics/ImageFrameData.h >@@ -0,0 +1,92 @@ >+/* >+ * Copyright (C) 2016 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 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 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. >+ */ >+ >+#ifndef ImageFrameData_h >+#define ImageFrameData_h >+ >+#include "Color.h" >+#include "ImageOrientation.h" >+#include "IntSize.h" >+#include "NativeImagePtr.h" >+ >+#include <wtf/Optional.h> >+#include <wtf/Vector.h> >+ >+namespace WebCore { >+ >+// SubsamplingLevel. 0 is no subsampling, 1 is half dimensions on each axis etc. >+typedef short SubsamplingLevel; >+typedef size_t ImageFrameIndex; >+ >+static const ImageFrameIndex MaxImageFrameIndex = std::numeric_limits<ImageFrameIndex>::max(); >+ >+enum class ImageFrameCaching { >+ CacheNone, >+ CacheMetadata, >+ CacheFrame, >+ CacheMetadataAndFrame >+}; >+ >+enum class ImageFrameStatus { >+ DecodeNone, >+ DecodePartial, >+ DecodeComplete >+}; >+ >+class ImageDecoder; >+ >+struct ImageFrameData { >+public: >+ ImageFrameData(); >+ ImageFrameData(const NativeImagePtr&); >+ ImageFrameData(ImageDecoder&, ImageFrameIndex, SubsamplingLevel, const NativeImagePtr& = nullptr); >+ ~ImageFrameData(); >+ >+ ImageFrameStatus status() const; >+ >+ bool clear(ImageFrameCaching); >+ Optional<Color> solidColor() const; >+ >+ NativeImagePtr m_image { nullptr }; >+ ImageOrientation m_orientation { DefaultImageOrientation }; >+ SubsamplingLevel m_subsamplingLevel { 0 }; >+ float m_duration { 0 }; >+ >+ union { >+ struct { >+ bool m_haveMetadata : 1; >+ bool m_isComplete : 1; >+ bool m_hasAlpha : 1; >+ bool m_allowSubsampling : 1; >+ }; >+ uint8_t m_flags[sizeof(bool)] { 0 }; >+ }; >+ unsigned m_frameBytes { 0 }; >+ IntSize m_size; >+}; >+ >+} // namespace WebCore >+ >+#endif // ImageFrameData_h >diff --git a/Source/WebCore/platform/graphics/ImageSource.cpp b/Source/WebCore/platform/graphics/ImageSource.cpp >index 74ef053a333ff5fc578e81800cc6fc9755efbab8..2ffa40e4384e0bb9aac5ea7792d3de6b123b24c2 100644 >--- a/Source/WebCore/platform/graphics/ImageSource.cpp >+++ b/Source/WebCore/platform/graphics/ImageSource.cpp >@@ -68,11 +68,6 @@ void ImageSource::clear(bool destroyAll, size_t clearBeforeFrame, SharedBuffer* > setData(data, allDataReceived); > } > >-bool ImageSource::initialized() const >-{ >- return m_decoder; >-} >- > void ImageSource::setData(SharedBuffer* data, bool allDataReceived) > { > // Make the decoder by sniffing the bytes. >@@ -96,7 +91,7 @@ String ImageSource::filenameExtension() const > return m_decoder ? m_decoder->filenameExtension() : String(); > } > >-SubsamplingLevel ImageSource::subsamplingLevelForScale(float) const >+SubsamplingLevel ImageSource::subsamplingLevelForScale(float, SubsamplingLevel) const > { > return 0; > } >@@ -111,21 +106,25 @@ bool ImageSource::isSizeAvailable() > return m_decoder && m_decoder->isSizeAvailable(); > } > >-IntSize ImageSource::size(ImageOrientationDescription description) const >+IntSize ImageSource::size() const > { >- return frameSizeAtIndex(0, 0, description); >+ return frameSizeAtIndex(0, 0); >+} >+ >+IntSize ImageSource::sizeRespectingOrientation() const >+{ >+ return frameSizeAtIndex(0, 0, RespectImageOrientation); > } > >-IntSize ImageSource::frameSizeAtIndex(size_t index, SubsamplingLevel, ImageOrientationDescription description) const >+IntSize ImageSource::frameSizeAtIndex(size_t index, SubsamplingLevel, RespectImageOrientationEnum shouldRespectImageOrientation) const > { >- if (!m_decoder) >+ if (!initialized()) > return IntSize(); > > IntSize size = m_decoder->frameSizeAtIndex(index); >- if ((description.respectImageOrientation() == RespectImageOrientation) && m_decoder->orientation().usesWidthAsHeight()) >- return IntSize(size.height(), size.width()); >+ ImageOrientation orientation = m_decoder->orientation(); > >- return size; >+ return shouldRespectImageOrientation == RespectImageOrientation && orientation.usesWidthAsHeight() ? size.transposedSize() : size; > } > > bool ImageSource::getHotSpot(IntPoint& hotSpot) const >@@ -148,7 +147,7 @@ size_t ImageSource::frameCount() const > return m_decoder ? m_decoder->frameCount() : 0; > } > >-PassNativeImagePtr ImageSource::createFrameAtIndex(size_t index, SubsamplingLevel) >+PassNativeImagePtr ImageSource::createFrameImageAtIndex(size_t index, SubsamplingLevel) > { > if (!m_decoder) > return 0; >diff --git a/Source/WebCore/platform/graphics/ImageSource.h b/Source/WebCore/platform/graphics/ImageSource.h >index acdd1ce4ce300de81c9e062eee7607bf472a70af..cc72ff47a541440d652f650ea5d60f513cecb1b1 100644 >--- a/Source/WebCore/platform/graphics/ImageSource.h >+++ b/Source/WebCore/platform/graphics/ImageSource.h >@@ -1,5 +1,5 @@ > /* >- * Copyright (C) 2004, 2005, 2006 Apple Inc. All rights reserved. >+ * Copyright (C) 2004, 2005, 2006, 2016 Apple Inc. All rights reserved. > * Copyright (C) 2007-2008 Torch Mobile, Inc. > * > * Redistribution and use in source and binary forms, with or without >@@ -46,18 +46,9 @@ class IntPoint; > class IntSize; > class SharedBuffer; > >-#if USE(CG) >-typedef CGImageSourceRef NativeImageDecoderPtr; >-#else > class ImageDecoder; > typedef ImageDecoder* NativeImageDecoderPtr; >-#endif >- >-#if USE(CG) >-#define NativeImageDecoder ImageDecoder >-#else > typedef ImageDecoder NativeImageDecoder; >-#endif > > // Right now GIFs are the only recognized image format that supports animation. > // The animation system and the constants below are designed with this in mind. >@@ -110,7 +101,7 @@ public: > // decoded frames. > // > // Callers should not call clear(false, n) and subsequently call >- // createFrameAtIndex(m) with m < n, unless they first call clear(true). >+ // createFrameImageAtIndex(m) with m < n, unless they first call clear(true). > // This ensures that stateful ImageSources/decoders will work properly. > // > // The |data| and |allDataReceived| parameters should be supplied by callers >@@ -122,19 +113,20 @@ public: > SharedBuffer* data = NULL, > bool allDataReceived = false); > >- bool initialized() const; >+ bool initialized() const { return m_decoder; } > > void setData(SharedBuffer* data, bool allDataReceived); > String filenameExtension() const; > >- SubsamplingLevel subsamplingLevelForScale(float) const; >+ SubsamplingLevel subsamplingLevelForScale(float, SubsamplingLevel) const; > bool allowSubsamplingOfFrameAtIndex(size_t) const; > > bool isSizeAvailable(); > // Always original size, without subsampling. >- IntSize size(ImageOrientationDescription = ImageOrientationDescription()) const; >+ IntSize size() const; >+ IntSize sizeRespectingOrientation() const; > // Size of optionally subsampled frame. >- IntSize frameSizeAtIndex(size_t, SubsamplingLevel = 0, ImageOrientationDescription = ImageOrientationDescription()) const; >+ IntSize frameSizeAtIndex(size_t, SubsamplingLevel = 0, RespectImageOrientationEnum = DoNotRespectImageOrientation) const; > > bool getHotSpot(IntPoint&) const; > >@@ -146,7 +138,7 @@ public: > > // Callers should not call this after calling clear() with a higher index; > // see comments on clear() above. >- PassNativeImagePtr createFrameAtIndex(size_t, SubsamplingLevel = 0); >+ PassNativeImagePtr createFrameImageAtIndex(size_t, SubsamplingLevel = 0); > > float frameDurationAtIndex(size_t); > bool frameHasAlphaAtIndex(size_t); // Whether or not the frame actually used any alpha. >@@ -163,7 +155,9 @@ public: > #endif > > private: >- NativeImageDecoderPtr m_decoder; >+ void ensureDecoderIsCreated(SharedBuffer*); >+ >+ NativeImageDecoderPtr m_decoder { nullptr }; > > #if !USE(CG) > AlphaOption m_alphaOption; >diff --git a/Source/WebCore/platform/graphics/NativeImagePtr.h b/Source/WebCore/platform/graphics/NativeImagePtr.h >index df941a566a9e46927727ba1ec6848f216803a45b..eca1b92c41ee1828e310d5bedbb2b5aca595f543 100644 >--- a/Source/WebCore/platform/graphics/NativeImagePtr.h >+++ b/Source/WebCore/platform/graphics/NativeImagePtr.h >@@ -29,6 +29,7 @@ > #define NativeImagePtr_h > > #if USE(CG) >+#include <wtf/RetainPtr.h> > typedef struct CGImage* CGImageRef; > #elif USE(CAIRO) > #include "RefPtrCairo.h" >@@ -41,7 +42,7 @@ namespace WebCore { > // FIXME: NativeImagePtr and PassNativeImagePtr should be smart > // pointers (see SVGImage::nativeImageForCurrentFrame()). > #if USE(CG) >-typedef CGImageRef NativeImagePtr; >+typedef RetainPtr<CGImageRef> NativeImagePtr; > #elif USE(CAIRO) > typedef RefPtr<cairo_surface_t> NativeImagePtr; > typedef PassRefPtr<cairo_surface_t> PassNativeImagePtr; >diff --git a/Source/WebCore/platform/graphics/ca/GraphicsLayerCA.cpp b/Source/WebCore/platform/graphics/ca/GraphicsLayerCA.cpp >index 63dcf0a253e2340f67f1c81d85fc270dd230e86d..a4c65bdff32a92f9c1df26d4bf53080f05ab9614 100644 >--- a/Source/WebCore/platform/graphics/ca/GraphicsLayerCA.cpp >+++ b/Source/WebCore/platform/graphics/ca/GraphicsLayerCA.cpp >@@ -1037,7 +1037,7 @@ void GraphicsLayerCA::setContentsToSolidColor(const Color& color) > void GraphicsLayerCA::setContentsToImage(Image* image) > { > if (image) { >- CGImageRef newImage = image->nativeImageForCurrentFrame(); >+ CGImageRef newImage = image->nativeImageForCurrentFrame().get(); > if (!newImage) > return; > >diff --git a/Source/WebCore/platform/graphics/cairo/BitmapImageCairo.cpp b/Source/WebCore/platform/graphics/cairo/BitmapImageCairo.cpp >index cd57ee485ea80c6cf347ab3bd9737d5999e10282..13d43968255a180d96dbba408fc8279c0f031f37 100644 >--- a/Source/WebCore/platform/graphics/cairo/BitmapImageCairo.cpp >+++ b/Source/WebCore/platform/graphics/cairo/BitmapImageCairo.cpp >@@ -40,16 +40,11 @@ namespace WebCore { > > BitmapImage::BitmapImage(PassRefPtr<cairo_surface_t> nativeImage, ImageObserver* observer) > : Image(observer) >- , m_size(cairoSurfaceSize(nativeImage.get())) >- , m_minimumSubsamplingLevel(0) > , m_currentFrame(0) > , m_repetitionCount(cAnimationNone) > , m_repetitionCountStatus(Unknown) > , m_repetitionsComplete(0) >- , m_decodedSize(m_size.width() * m_size.height() * 4) > , m_frameCount(1) >- , m_isSolidColor(false) >- , m_checkedForSolidColor(false) > , m_animationFinished(true) > , m_allDataReceived(true) > , m_haveSize(true) >@@ -57,11 +52,9 @@ BitmapImage::BitmapImage(PassRefPtr<cairo_surface_t> nativeImage, ImageObserver* > , m_haveFrameCount(true) > { > m_frames.grow(1); >- m_frames[0].m_hasAlpha = cairo_surface_get_content(nativeImage.get()) != CAIRO_CONTENT_COLOR; >- m_frames[0].m_frame = nativeImage; >- m_frames[0].m_haveMetadata = true; >- >- checkForSolidColor(); >+ m_frames[0] = ImageFrameData(nativeImage); >+ m_size = m_frames[0].m_size; >+ m_decodedSize = m_size.width() * m_size.height() * 4; > } > > void BitmapImage::draw(GraphicsContext& context, const FloatRect& dst, const FloatRect& src, CompositeOperator op, >@@ -72,7 +65,7 @@ void BitmapImage::draw(GraphicsContext& context, const FloatRect& dst, const Flo > > startAnimation(); > >- RefPtr<cairo_surface_t> surface = frameAtIndex(m_currentFrame); >+ RefPtr<cairo_surface_t> surface = frameImageAtIndex(m_currentFrame); > if (!surface) // If it's too early we won't have an image yet. > return; > >@@ -124,47 +117,51 @@ void BitmapImage::draw(GraphicsContext& context, const FloatRect& dst, const Flo > > void BitmapImage::determineMinimumSubsamplingLevel() const > { >- m_minimumSubsamplingLevel = 0; >+ m_maximumSubsamplingLevel = 0; > } > >-void BitmapImage::checkForSolidColor() >+ImageFrameData::ImageFrameData(const NativeImagePtr& image) >+ : m_image(image) >+ , m_haveMetadata(true) >+ , m_isComplete(true) > { >- m_isSolidColor = false; >- m_checkedForSolidColor = true; >- >- if (frameCount() > 1) >- return; >- >- RefPtr<cairo_surface_t> surface = frameAtIndex(m_currentFrame); >- if (!surface) // If it's too early we won't have an image yet. >- return; >- >- if (cairo_surface_get_type(surface.get()) != CAIRO_SURFACE_TYPE_IMAGE) >- return; >- >- IntSize size = cairoSurfaceSize(surface.get()); >- >- if (size.width() != 1 || size.height() != 1) >- return; >- >- unsigned* pixelColor = reinterpret_cast_ptr<unsigned*>(cairo_image_surface_get_data(surface.get())); >- m_solidColor = colorFromPremultipliedARGB(*pixelColor); >- >- m_isSolidColor = true; >+ ASSERT(m_image); >+ m_size = cairoSurfaceSize(m_image.get()); >+ m_frameBytes = m_size.width() * m_size.height() * 4; >+ m_hasAlpha = cairo_surface_get_content(m_image.get()) != CAIRO_CONTENT_COLOR; > } > >-bool FrameData::clear(bool clearMetadata) >+ >+bool ImageFrameData::clear(bool clearMetadata) > { > if (clearMetadata) > m_haveMetadata = false; > >- if (m_frame) { >- m_frame = nullptr; >+ if (m_image) { >+ m_image = nullptr; > return true; > } > return false; > } > >+Optional<Color> ImageFrameData::solidColor() const >+{ >+ if (!m_image) >+ return Nullopt; >+ >+ if (cairo_surface_get_type(m_image.get()) != CAIRO_SURFACE_TYPE_IMAGE) >+ return Nullopt; >+ >+ IntSize size = cairoSurfaceSize(m_image.get()); >+ >+ if (size.width() != 1 || size.height() != 1) >+ return Nullopt; >+ >+ unsigned* pixelColor = reinterpret_cast_ptr<unsigned*>(cairo_image_surface_get_data(m_image.get())); >+ return colorFromPremultipliedARGB(*pixelColor); >+} >+ >+ > } // namespace WebCore > > #endif // USE(CAIRO) >diff --git a/Source/WebCore/platform/graphics/cairo/GraphicsContext3DCairo.cpp b/Source/WebCore/platform/graphics/cairo/GraphicsContext3DCairo.cpp >index cc7046147ae81f1fadaa6d841624980c6fdfcbf1..8c4186d71e53a1907e92d73a2b01647ffd66b1c3 100644 >--- a/Source/WebCore/platform/graphics/cairo/GraphicsContext3DCairo.cpp >+++ b/Source/WebCore/platform/graphics/cairo/GraphicsContext3DCairo.cpp >@@ -215,7 +215,7 @@ bool GraphicsContext3D::ImageExtractor::extractImage(bool premultiplyAlpha, bool > decoder.setData(m_image->data(), true); > if (!decoder.frameCount() || !decoder.frameIsCompleteAtIndex(0)) > return false; >- m_imageSurface = decoder.createFrameAtIndex(0); >+ m_imageSurface = decoder.createFrameImageAtIndex(0); > } else { > m_imageSurface = m_image->nativeImageForCurrentFrame(); > // 1. For texImage2D with HTMLVideoElment input, assume no PremultiplyAlpha had been applied and the alpha value is 0xFF for each pixel, >diff --git a/Source/WebCore/platform/graphics/cg/BitmapImageCG.cpp b/Source/WebCore/platform/graphics/cg/BitmapImageCG.cpp >index 01b7d692cdbd7ab4d22bbc1399c10328f57e5e47..5ac336d2afc26fb124319fdf6465f52c5cd814b2 100644 >--- a/Source/WebCore/platform/graphics/cg/BitmapImageCG.cpp >+++ b/Source/WebCore/platform/graphics/cg/BitmapImageCG.cpp >@@ -49,31 +49,63 @@ > #endif > > namespace WebCore { >+ >+ImageFrameData::ImageFrameData(const NativeImagePtr& image) >+ : m_image(image) >+ , m_haveMetadata(true) >+ , m_isComplete(true) >+ , m_hasAlpha(true) >+{ >+ ASSERT(m_image); >+ CGFloat width = CGImageGetWidth(m_image.get()); >+ CGFloat height = CGImageGetHeight(m_image.get()); >+ m_frameBytes = width * height * 4; >+ m_size = IntSize(width, height); >+} > >-bool FrameData::clear(bool clearMetadata) >+bool ImageFrameData::clear(ImageFrameCaching frameCaching) > { >- if (clearMetadata) >+ if (frameCaching == ImageFrameCaching::CacheNone) > m_haveMetadata = false; > > m_orientation = DefaultImageOrientation; > m_subsamplingLevel = 0; > >- if (m_frame) { >+ if (m_image) { > #if CACHE_SUBIMAGES >- subimageCache().clearImage(m_frame); >+ subimageCache().clearImage(m_image.get()); > #endif >- CGImageRelease(m_frame); >- m_frame = 0; >+ m_image = nullptr; > return true; > } > return false; > } >+ >+Optional<Color> ImageFrameData::solidColor() const >+{ >+ if (!m_image) >+ return Nullopt; >+ >+ // Currently we only check for solid color in the important special case of a 1x1 image. >+ if (CGImageGetWidth(m_image.get()) != 1 || CGImageGetHeight(m_image.get()) != 1) >+ return Nullopt; >+ >+ unsigned char pixel[4]; // RGBA >+ RetainPtr<CGContextRef> bitmapContext = adoptCF(CGBitmapContextCreate(pixel, 1, 1, 8, sizeof(pixel), sRGBColorSpaceRef(), kCGImageAlphaPremultipliedLast | kCGBitmapByteOrder32Big)); >+ if (!bitmapContext) >+ return Nullopt; >+ >+ GraphicsContext(bitmapContext.get()).setCompositeOperation(CompositeCopy); >+ CGRect destinationRect = CGRectMake(0, 0, 1, 1); >+ CGContextDrawImage(bitmapContext.get(), destinationRect, m_image.get()); >+ if (!pixel[3]) >+ return Color(0, 0, 0, 0); >+ >+ return Color(pixel[0] * 255 / pixel[3], pixel[1] * 255 / pixel[3], pixel[2] * 255 / pixel[3], pixel[3]); >+} > >-BitmapImage::BitmapImage(CGImageRef cgImage, ImageObserver* observer) >+BitmapImage::BitmapImage(NativeImagePtr image, ImageObserver* observer) > : Image(observer) >- , m_minimumSubsamplingLevel(0) >- , m_imageOrientation(OriginTopLeft) >- , m_shouldRespectImageOrientation(false) > , m_currentFrame(0) > , m_repetitionCount(cAnimationNone) > , m_repetitionCountStatus(Unknown) >@@ -81,16 +113,14 @@ BitmapImage::BitmapImage(CGImageRef cgImage, ImageObserver* observer) > , m_decodedSize(0) > , m_decodedPropertiesSize(0) > , m_frameCount(1) >- , m_isSolidColor(false) >- , m_checkedForSolidColor(false) > , m_animationFinished(true) > , m_allDataReceived(true) > , m_haveSize(true) > , m_sizeAvailable(true) > , m_haveFrameCount(true) > { >- CGFloat width = CGImageGetWidth(cgImage); >- CGFloat height = CGImageGetHeight(cgImage); >+ CGFloat width = CGImageGetWidth(image.get()); >+ CGFloat height = CGImageGetHeight(image.get()); > m_decodedSize = width * height * 4; > m_size = IntSize(width, height); > >@@ -99,11 +129,7 @@ BitmapImage::BitmapImage(CGImageRef cgImage, ImageObserver* observer) > m_sizeRespectingOrientation = m_size; > > m_frames.grow(1); >- m_frames[0].m_frame = CGImageRetain(cgImage); >- m_frames[0].m_hasAlpha = true; >- m_frames[0].m_haveMetadata = true; >- >- checkForSolidColor(); >+ m_frames[0] = ImageFrameData(image); > } > > void BitmapImage::determineMinimumSubsamplingLevel() const >@@ -125,64 +151,21 @@ void BitmapImage::determineMinimumSubsamplingLevel() const > break; > } > >- m_minimumSubsamplingLevel = currentLevel; >-} >- >-void BitmapImage::checkForSolidColor() >-{ >- m_checkedForSolidColor = true; >- m_isSolidColor = false; >- >- if (frameCount() > 1) >- return; >- >- if (!haveFrameAtIndex(0)) { >- IntSize size = m_source.frameSizeAtIndex(0, 0); >- if (size.width() != 1 || size.height() != 1) >- return; >- >- if (!ensureFrameIsCached(0)) >- return; >- } >- >- CGImageRef image = nullptr; >- if (m_frames.size()) >- image = m_frames[0].m_frame; >- >- if (!image) >- return; >- >- // Currently we only check for solid color in the important special case of a 1x1 image. >- if (CGImageGetWidth(image) == 1 && CGImageGetHeight(image) == 1) { >- unsigned char pixel[4]; // RGBA >- RetainPtr<CGContextRef> bitmapContext = adoptCF(CGBitmapContextCreate(pixel, 1, 1, 8, sizeof(pixel), sRGBColorSpaceRef(), >- kCGImageAlphaPremultipliedLast | kCGBitmapByteOrder32Big)); >- if (!bitmapContext) >- return; >- GraphicsContext(bitmapContext.get()).setCompositeOperation(CompositeCopy); >- CGRect destinationRect = CGRectMake(0, 0, 1, 1); >- CGContextDrawImage(bitmapContext.get(), destinationRect, image); >- if (!pixel[3]) >- m_solidColor = Color(0, 0, 0, 0); >- else >- m_solidColor = Color(pixel[0] * 255 / pixel[3], pixel[1] * 255 / pixel[3], pixel[2] * 255 / pixel[3], pixel[3]); >- >- m_isSolidColor = true; >- } >+ m_maximumSubsamplingLevel = currentLevel; > } > > CGImageRef BitmapImage::getCGImageRef() > { >- return frameAtIndex(0); >+ return frameImageAtIndex(0).get(); > } > > CGImageRef BitmapImage::getFirstCGImageRefOfSize(const IntSize& size) > { > size_t count = frameCount(); > for (size_t i = 0; i < count; ++i) { >- CGImageRef cgImage = frameAtIndex(i); >- if (cgImage && IntSize(CGImageGetWidth(cgImage), CGImageGetHeight(cgImage)) == size) >- return cgImage; >+ PassNativeImagePtr image = frameImageAtIndex(i); >+ if (image && IntSize(CGImageGetWidth(image.get()), CGImageGetHeight(image.get())) == size) >+ return image.get(); > } > > // Fallback to the default CGImageRef if we can't find the right size >@@ -197,8 +180,8 @@ RetainPtr<CFArrayRef> BitmapImage::getCGImageArray() > > CFMutableArrayRef array = CFArrayCreateMutable(NULL, count, &kCFTypeArrayCallBacks); > for (size_t i = 0; i < count; ++i) { >- if (CGImageRef currFrame = frameAtIndex(i)) >- CFArrayAppendValue(array, currFrame); >+ if (NativeImagePtr currFrame = frameImageAtIndex(i)) >+ CFArrayAppendValue(array, currFrame.get()); > } > return adoptCF(array); > } >@@ -211,15 +194,15 @@ void BitmapImage::draw(GraphicsContext& ctxt, const FloatRect& destRect, const F > startAnimation(); > #endif > >- RetainPtr<CGImageRef> image; >+ NativeImagePtr image; > // Never use subsampled images for drawing into PDF contexts. > if (wkCGContextIsPDFContext(ctxt.platformContext())) >- image = adoptCF(copyUnscaledFrameAtIndex(m_currentFrame)); >+ image = copyUnscaledFrameImageAtIndex(m_currentFrame); > else { > CGRect transformedDestinationRect = CGRectApplyAffineTransform(destRect, CGContextGetCTM(ctxt.platformContext())); > float subsamplingScale = std::min<float>(1, std::max(transformedDestinationRect.size.width / srcRect.width(), transformedDestinationRect.size.height / srcRect.height())); > >- image = frameAtIndex(m_currentFrame, subsamplingScale); >+ image = frameImageAtIndex(m_currentFrame, subsamplingScale); > } > > if (!image) // If it's too early we won't have an image yet. >@@ -251,18 +234,18 @@ void BitmapImage::draw(GraphicsContext& ctxt, const FloatRect& destRect, const F > imageObserver()->didDraw(this); > } > >-PassNativeImagePtr BitmapImage::copyUnscaledFrameAtIndex(size_t index) >+PassNativeImagePtr BitmapImage::copyUnscaledFrameImageAtIndex(size_t index) > { > if (index >= frameCount()) > return nullptr; > >- if (index >= m_frames.size() || !m_frames[index].m_frame) >+ if (index >= m_frames.size() || !m_frames[index].m_image) > cacheFrame(index, 0); > > if (!m_frames[index].m_subsamplingLevel) >- return CGImageRetain(m_frames[index].m_frame); >+ return m_frames[index].m_image; > >- return m_source.createFrameAtIndex(index); >+ return m_source.createFrameImageAtIndex(index); > } > > } >diff --git a/Source/WebCore/platform/graphics/cg/GraphicsContext3DCG.cpp b/Source/WebCore/platform/graphics/cg/GraphicsContext3DCG.cpp >index 6c03a2cef84606561ea07eb928f1cf295f9f5e36..7a13bb5846708d37e02bd3dd6723c27a495176c0 100644 >--- a/Source/WebCore/platform/graphics/cg/GraphicsContext3DCG.cpp >+++ b/Source/WebCore/platform/graphics/cg/GraphicsContext3DCG.cpp >@@ -333,10 +333,10 @@ bool GraphicsContext3D::ImageExtractor::extractImage(bool premultiplyAlpha, bool > if (!decoder.frameCount()) > return false; > >- m_decodedImage = adoptCF(decoder.createFrameAtIndex(0)); >+ m_decodedImage = decoder.createFrameImageAtIndex(0); > m_cgImage = m_decodedImage.get(); > } else >- m_cgImage = m_image->nativeImageForCurrentFrame(); >+ m_cgImage = m_image->nativeImageForCurrentFrame().get(); > if (!m_cgImage) > return false; > >@@ -536,7 +536,7 @@ void GraphicsContext3D::paintToCanvas(const unsigned char* imagePixels, int imag > context.scale(FloatSize(1, -1)); > context.translate(0, -imageHeight); > context.setImageInterpolationQuality(InterpolationNone); >- context.drawNativeImage(cgImage.get(), imageSize, canvasRect, FloatRect(FloatPoint(), imageSize), CompositeCopy); >+ context.drawNativeImage(cgImage, imageSize, canvasRect, FloatRect(FloatPoint(), imageSize), CompositeCopy); > } > > } // namespace WebCore >diff --git a/Source/WebCore/platform/graphics/cg/GraphicsContextCG.cpp b/Source/WebCore/platform/graphics/cg/GraphicsContextCG.cpp >index a449654046ae8f10abad16415e6460adbbbb8e88..16209af534481db4cddd8b423ce7bf2a40b0dbef 100644 >--- a/Source/WebCore/platform/graphics/cg/GraphicsContextCG.cpp >+++ b/Source/WebCore/platform/graphics/cg/GraphicsContextCG.cpp >@@ -311,8 +311,8 @@ void GraphicsContext::drawPattern(Image& image, const FloatRect& tileRect, const > float adjustedX = phase.x() - destRect.x() + tileRect.x() * narrowPrecisionToFloat(patternTransform.a()); // We translated the context so that destRect.x() is the origin, so subtract it out. > float adjustedY = destRect.height() - (phase.y() - destRect.y() + tileRect.y() * narrowPrecisionToFloat(patternTransform.d()) + scaledTileHeight); > >- CGImageRef tileImage = image.nativeImageForCurrentFrame(); >- float h = CGImageGetHeight(tileImage); >+ RetainPtr<CGImageRef> tileImage = image.nativeImageForCurrentFrame(); >+ float h = CGImageGetHeight(tileImage.get()); > > RetainPtr<CGImageRef> subImage; > #if PLATFORM(IOS) >@@ -326,13 +326,13 @@ void GraphicsContext::drawPattern(Image& image, const FloatRect& tileRect, const > // Copying a sub-image out of a partially-decoded image stops the decoding of the original image. It should never happen > // because sub-images are only used for border-image, which only renders when the image is fully decoded. > ASSERT(h == image.height()); >- subImage = adoptCF(CGImageCreateWithImageInRect(tileImage, tileRect)); >+ subImage = adoptCF(CGImageCreateWithImageInRect(tileImage.get(), tileRect)); > } > > // If we need to paint gaps between tiles because we have a partially loaded image or non-zero spacing, > // fall back to the less efficient CGPattern-based mechanism. > float scaledTileWidth = tileRect.width() * narrowPrecisionToFloat(patternTransform.a()); >- float w = CGImageGetWidth(tileImage); >+ float w = CGImageGetWidth(tileImage.get()); > if (w == image.size().width() && h == image.size().height() && !spacing.width() && !spacing.height()) { > // FIXME: CG seems to snap the images to integral sizes. When we care (e.g. with border-image-repeat: round), > // we should tile all but the last, and stetch the last image to fit. >diff --git a/Source/WebCore/platform/graphics/cg/ImageDecoder.cpp b/Source/WebCore/platform/graphics/cg/ImageDecoder.cpp >new file mode 100644 >index 0000000000000000000000000000000000000000..525ac4af1301e4b5b1c7226a559f2f393ed8b498 >--- /dev/null >+++ b/Source/WebCore/platform/graphics/cg/ImageDecoder.cpp >@@ -0,0 +1,413 @@ >+/* >+ * Copyright (C) 2016 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 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 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 "ImageDecoder.h" >+ >+#if USE(CG) >+ >+#include "CoreGraphicsSPI.h" >+#include "ImageOrientation.h" >+#include "IntPoint.h" >+#include "IntSize.h" >+#include "MIMETypeRegistry.h" >+#include "SharedBuffer.h" >+#include <wtf/NeverDestroyed.h> >+ >+#if !PLATFORM(IOS) >+#include <ApplicationServices/ApplicationServices.h> >+#else >+#include <ImageIO/ImageIO.h> >+#include <wtf/RetainPtr.h> >+#endif >+ >+#if USE(APPLE_INTERNAL_SDK) >+#import <ImageIO/CGImageSourcePrivate.h> >+#else >+const CFStringRef kCGImageSourceSubsampleFactor = CFSTR("kCGImageSourceSubsampleFactor"); >+const CFStringRef kCGImageSourceShouldCacheImmediately = CFSTR("kCGImageSourceShouldCacheImmediately"); >+#endif >+ >+namespace WebCore { >+ >+const CFStringRef WebCoreCGImagePropertyAPNGUnclampedDelayTime = CFSTR("UnclampedDelayTime"); >+const CFStringRef WebCoreCGImagePropertyAPNGDelayTime = CFSTR("DelayTime"); >+const CFStringRef WebCoreCGImagePropertyAPNGLoopCount = CFSTR("LoopCount"); >+ >+const CFStringRef kCGImageSourceShouldPreferRGB32 = CFSTR("kCGImageSourceShouldPreferRGB32"); >+const CFStringRef kCGImageSourceSkipMetadata = CFSTR("kCGImageSourceSkipMetadata"); >+ >+static RetainPtr<CFDictionaryRef> createImageSourceOptions(SubsamplingLevel subsamplingLevel, DecodeMode decodeMode) >+{ >+ const CFIndex basicOptions = 3; >+ const void* keys[basicOptions + 2] = { kCGImageSourceShouldCache, kCGImageSourceShouldPreferRGB32, kCGImageSourceSkipMetadata }; >+ const void* values[basicOptions + 2] = { kCFBooleanTrue, kCFBooleanTrue, kCFBooleanTrue }; >+ CFIndex numOptions = basicOptions; >+ >+ if (subsamplingLevel > 0) { >+ short constrainedSubsamplingLevel = std::min<short>(3, std::max<short>(0, subsamplingLevel)); >+ int subsampleInt = 1 << constrainedSubsamplingLevel; // [0..3] => [1, 2, 4, 8] >+ RetainPtr<CFNumberRef> subsampleNumber = adoptCF(CFNumberCreate(nullptr, kCFNumberIntType, &subsampleInt)); >+ >+ keys[numOptions] = kCGImageSourceSubsampleFactor; >+ values[numOptions++] = kCGImageSourceSubsampleFactor; >+ } >+ >+ if (decodeMode == DecodeMode::Immediate) { >+ keys[numOptions] = kCGImageSourceShouldCacheImmediately; >+ values[numOptions++] = kCFBooleanTrue; >+ } >+ >+ return adoptCF(CFDictionaryCreate(nullptr, keys, values, numOptions, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks)); >+} >+ >+static RetainPtr<CFDictionaryRef> imageSourceOptions(SubsamplingLevel subsamplingLevel = 0, DecodeMode decodeMode = DecodeMode::Lazy) >+{ >+ if (subsamplingLevel || decodeMode == DecodeMode::Immediate) >+ return createImageSourceOptions(subsamplingLevel, decodeMode); >+ >+ static NeverDestroyed<RetainPtr<CFDictionaryRef>> options = createImageSourceOptions(0, DecodeMode::Lazy); >+ return options; >+} >+ >+static ImageOrientation orientationFromProperties(CFDictionaryRef imageProperties) >+{ >+ ASSERT(imageProperties); >+ CFNumberRef orientationProperty = (CFNumberRef)CFDictionaryGetValue(imageProperties, kCGImagePropertyOrientation); >+ if (!orientationProperty) >+ return DefaultImageOrientation; >+ >+ int exifValue; >+ CFNumberGetValue(orientationProperty, kCFNumberIntType, &exifValue); >+ return ImageOrientation::fromEXIFValue(exifValue); >+} >+ >+#if !PLATFORM(COCOA) >+size_t sharedBufferGetBytesAtPosition(void* info, void* buffer, off_t position, size_t count) >+{ >+ SharedBuffer* sharedBuffer = static_cast<SharedBuffer*>(info); >+ size_t sourceSize = sharedBuffer->size(); >+ if (position >= sourceSize) >+ return 0; >+ >+ const char* source = sharedBuffer->data() + position; >+ size_t amount = std::min<size_t>(count, sourceSize - position); >+ memcpy(buffer, source, amount); >+ return amount; >+} >+ >+void sharedBufferRelease(void* info) >+{ >+ SharedBuffer* sharedBuffer = static_cast<SharedBuffer*>(info); >+ sharedBuffer->deref(); >+} >+#endif >+ >+ImageDecoder::ImageDecoder() >+{ >+ m_nativeDecoder = CGImageSourceCreateIncremental(0); >+} >+ >+SubsamplingLevel ImageDecoder::subsamplingLevelForScale(float scale, SubsamplingLevel maximumSubsamplingLevel) >+{ >+ // There are four subsampling levels: 0 = 1x, 1 = 0.5x, 2 = 0.25x, 3 = 0.125x. >+ float clampedScale = std::max<float>(0.125, std::min<float>(1, scale)); >+ SubsamplingLevel result = ceilf(log2f(1 / clampedScale)); >+ ASSERT(result >=0 && result <= 3); >+ return std::min(result, maximumSubsamplingLevel); >+} >+ >+size_t ImageDecoder::bytesDecodedToDetermineProperties() >+{ >+ // Measured by tracing malloc/calloc calls on Mac OS 10.6.6, x86_64. >+ // A non-zero value ensures cached images with no decoded frames still enter >+ // the live decoded resources list when the CGImageSource decodes image >+ // properties, allowing the cache to prune the partially decoded image. >+ // This value is likely to be inaccurate on other platforms, but the overall >+ // behavior is unchanged. >+ return 13088; >+} >+ >+String ImageDecoder::filenameExtension() const >+{ >+ CFStringRef imageSourceType = CGImageSourceGetType(m_nativeDecoder); >+ return WebCore::preferredExtensionForImageSourceType(imageSourceType); >+} >+ >+bool ImageDecoder::isSizeAvailable() const >+{ >+ // Ragnaros yells: TOO SOON! You have awakened me TOO SOON, Executus! >+ if (CGImageSourceGetStatus(m_nativeDecoder) < kCGImageStatusIncomplete) >+ return false; >+ >+ RetainPtr<CFDictionaryRef> image0Properties = adoptCF(CGImageSourceCopyPropertiesAtIndex(m_nativeDecoder, 0, imageSourceOptions().get())); >+ if (!image0Properties) >+ return false; >+ >+ return CFDictionaryContainsKey(image0Properties.get(), kCGImagePropertyPixelWidth) >+ && CFDictionaryContainsKey(image0Properties.get(), kCGImagePropertyPixelHeight); >+} >+ >+IntSize ImageDecoder::size() const >+{ >+ if (m_size.isEmpty()) >+ m_size = frameSizeAtIndex(0, 0); >+ return m_size; >+} >+ >+size_t ImageDecoder::frameCount() const >+{ >+ return CGImageSourceGetCount(m_nativeDecoder); >+} >+ >+int ImageDecoder::repetitionCount() const >+{ >+ RetainPtr<CFDictionaryRef> properties = adoptCF(CGImageSourceCopyProperties(m_nativeDecoder, imageSourceOptions().get())); >+ if (!properties) >+ return cAnimationLoopOnce; >+ >+ CFDictionaryRef gifProperties = (CFDictionaryRef)CFDictionaryGetValue(properties.get(), kCGImagePropertyGIFDictionary); >+ if (gifProperties) { >+ CFNumberRef num = (CFNumberRef)CFDictionaryGetValue(gifProperties, kCGImagePropertyGIFLoopCount); >+ >+ // No property means loop once. >+ if (!num) >+ return cAnimationLoopOnce; >+ >+ int loopCount; >+ CFNumberGetValue(num, kCFNumberIntType, &loopCount); >+ >+ // A property with value 0 means loop forever. >+ return loopCount ? loopCount : cAnimationLoopInfinite; >+ } >+ >+ CFDictionaryRef pngProperties = (CFDictionaryRef)CFDictionaryGetValue(properties.get(), kCGImagePropertyPNGDictionary); >+ if (pngProperties) { >+ CFNumberRef num = (CFNumberRef)CFDictionaryGetValue(pngProperties, WebCoreCGImagePropertyAPNGLoopCount); >+ if (!num) >+ return cAnimationLoopOnce; >+ >+ int loopCount; >+ CFNumberGetValue(num, kCFNumberIntType, &loopCount); >+ return loopCount ? loopCount : cAnimationLoopInfinite; >+ } >+ >+ // Turns out we're not an animated image after all, so we don't animate. >+ return cAnimationNone; >+} >+ >+bool ImageDecoder::getHotSpot(IntPoint& hotSpot) const >+{ >+ RetainPtr<CFDictionaryRef> properties = adoptCF(CGImageSourceCopyPropertiesAtIndex(m_nativeDecoder, 0, imageSourceOptions().get())); >+ if (!properties) >+ return false; >+ >+ int x = -1, y = -1; >+ CFNumberRef num = (CFNumberRef)CFDictionaryGetValue(properties.get(), CFSTR("hotspotX")); >+ if (!num || !CFNumberGetValue(num, kCFNumberIntType, &x)) >+ return false; >+ >+ num = (CFNumberRef)CFDictionaryGetValue(properties.get(), CFSTR("hotspotY")); >+ if (!num || !CFNumberGetValue(num, kCFNumberIntType, &y)) >+ return false; >+ >+ if (x < 0 || y < 0) >+ return false; >+ >+ hotSpot = IntPoint(x, y); >+ return true; >+} >+ >+IntSize ImageDecoder::frameSizeAtIndex(size_t index, SubsamplingLevel subsamplingLevel) const >+{ >+ RetainPtr<CFDictionaryRef> properties = adoptCF(CGImageSourceCopyPropertiesAtIndex(m_nativeDecoder, index, imageSourceOptions(subsamplingLevel).get())); >+ >+ if (!properties) >+ return { }; >+ >+ int width = 0; >+ int height = 0; >+ CFNumberRef num = (CFNumberRef)CFDictionaryGetValue(properties.get(), kCGImagePropertyPixelWidth); >+ if (num) >+ CFNumberGetValue(num, kCFNumberIntType, &width); >+ >+ num = (CFNumberRef)CFDictionaryGetValue(properties.get(), kCGImagePropertyPixelHeight); >+ if (num) >+ CFNumberGetValue(num, kCFNumberIntType, &height); >+ >+ return IntSize(width, height); >+} >+ >+bool ImageDecoder::frameIsCompleteAtIndex(size_t index) const >+{ >+ ASSERT(frameCount()); >+ return CGImageSourceGetStatusAtIndex(m_nativeDecoder, index) == kCGImageStatusComplete; >+} >+ >+ImageOrientation ImageDecoder::orientationAtIndex(size_t index) const >+{ >+ RetainPtr<CFDictionaryRef> properties = adoptCF(CGImageSourceCopyPropertiesAtIndex(m_nativeDecoder, index, imageSourceOptions().get())); >+ if (!properties) >+ return DefaultImageOrientation; >+ >+ return orientationFromProperties(properties.get()); >+} >+ >+float ImageDecoder::frameDurationAtIndex(size_t index) const >+{ >+ float duration = 0; >+ RetainPtr<CFDictionaryRef> properties = adoptCF(CGImageSourceCopyPropertiesAtIndex(m_nativeDecoder, index, imageSourceOptions().get())); >+ if (properties) { >+ CFDictionaryRef gifProperties = (CFDictionaryRef)CFDictionaryGetValue(properties.get(), kCGImagePropertyGIFDictionary); >+ if (gifProperties) { >+ if (CFNumberRef num = (CFNumberRef)CFDictionaryGetValue(gifProperties, kCGImagePropertyGIFUnclampedDelayTime)) { >+ // Use the unclamped frame delay if it exists. >+ CFNumberGetValue(num, kCFNumberFloatType, &duration); >+ } else if (CFNumberRef num = (CFNumberRef)CFDictionaryGetValue(gifProperties, kCGImagePropertyGIFDelayTime)) { >+ // Fall back to the clamped frame delay if the unclamped frame delay does not exist. >+ CFNumberGetValue(num, kCFNumberFloatType, &duration); >+ } >+ } >+ >+ CFDictionaryRef pngProperties = (CFDictionaryRef)CFDictionaryGetValue(properties.get(), kCGImagePropertyPNGDictionary); >+ if (pngProperties) { >+ if (CFNumberRef num = (CFNumberRef)CFDictionaryGetValue(pngProperties, WebCoreCGImagePropertyAPNGUnclampedDelayTime)) >+ CFNumberGetValue(num, kCFNumberFloatType, &duration); >+ else if (CFNumberRef num = (CFNumberRef)CFDictionaryGetValue(pngProperties, WebCoreCGImagePropertyAPNGDelayTime)) >+ CFNumberGetValue(num, kCFNumberFloatType, &duration); >+ } >+ } >+ >+ // Many annoying ads specify a 0 duration to make an image flash as quickly as possible. >+ // We follow Firefox's behavior and use a duration of 100 ms for any frames that specify >+ // a duration of <= 10 ms. See <rdar://problem/7689300> and <http://webkit.org/b/36082> >+ // for more information. >+ if (duration < 0.011f) >+ return 0.1f; >+ return duration; >+} >+ >+bool ImageDecoder::allowSubsamplingOfFrameAtIndex(size_t) const >+{ >+ RetainPtr<CFDictionaryRef> properties = adoptCF(CGImageSourceCopyPropertiesAtIndex(m_nativeDecoder, 0, imageSourceOptions().get())); >+ if (!properties) >+ return false; >+ >+ CFDictionaryRef jfifProperties = static_cast<CFDictionaryRef>(CFDictionaryGetValue(properties.get(), kCGImagePropertyJFIFDictionary)); >+ if (jfifProperties) { >+ CFBooleanRef isProgCFBool = static_cast<CFBooleanRef>(CFDictionaryGetValue(jfifProperties, kCGImagePropertyJFIFIsProgressive)); >+ if (isProgCFBool) { >+ bool isProgressive = CFBooleanGetValue(isProgCFBool); >+ // Workaround for <rdar://problem/5184655> - Hang rendering very large progressive JPEG. Decoding progressive >+ // images hangs for a very long time right now. Until this is fixed, don't sub-sample progressive images. This >+ // will cause them to fail our large image check and they won't be decoded. >+ // FIXME: Remove once underlying issue is fixed (<rdar://problem/5191418>) >+ return !isProgressive; >+ } >+ } >+ >+ return true; >+} >+ >+bool ImageDecoder::frameHasAlphaAtIndex(size_t index) const >+{ >+ if (!frameIsCompleteAtIndex(index)) >+ return true; >+ >+ CFStringRef imageType = CGImageSourceGetType(m_nativeDecoder); >+ >+ // Return false if there is no image type or the image type is JPEG, because >+ // JPEG does not support alpha transparency. >+ if (!imageType || CFEqual(imageType, CFSTR("public.jpeg"))) >+ return false; >+ >+ // FIXME: Could return false for 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; >+} >+ >+unsigned ImageDecoder::frameBytesAtIndex(size_t index, SubsamplingLevel subsamplingLevel) const >+{ >+ IntSize frameSize = frameSizeAtIndex(index, subsamplingLevel); >+ return frameSize.width() * frameSize.height() * 4; >+} >+ >+PassNativeImagePtr ImageDecoder::createFrameImageAtIndex(size_t index, SubsamplingLevel subsamplingLevel, DecodeMode decodeMode) const >+{ >+ RetainPtr<CGImageRef> image = adoptCF(CGImageSourceCreateImageAtIndex(m_nativeDecoder, index, imageSourceOptions(subsamplingLevel, decodeMode).get())); >+ >+#if PLATFORM(IOS) >+ // <rdar://problem/7371198> - CoreGraphics changed the default caching behaviour in iOS 4.0 to kCGImageCachingTransient >+ // which caused a performance regression for us since the images had to be resampled/recreated every time we called >+ // CGContextDrawImage. We now tell CG to cache the drawn images. See also <rdar://problem/14366755> - >+ // CoreGraphics needs to un-deprecate kCGImageCachingTemporary since it's still not the default. >+#if COMPILER(CLANG) >+#pragma clang diagnostic push >+#pragma clang diagnostic ignored "-Wdeprecated-declarations" >+#endif >+ CGImageSetCachingFlags(image.get(), kCGImageCachingTemporary); >+#if COMPILER(CLANG) >+#pragma clang diagnostic pop >+#endif >+#endif // PLATFORM(IOS) >+ >+ CFStringRef imageUTI = CGImageSourceGetType(m_nativeDecoder); >+ static const CFStringRef xbmUTI = CFSTR("public.xbitmap-image"); >+ >+ if (!imageUTI) >+ return image; >+ >+ if (!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}; >+ RetainPtr<CGImageRef> maskedImage = adoptCF(CGImageCreateWithMaskingColors(image.get(), maskingColors)); >+ return maskedImage ? maskedImage : image; >+} >+ >+void ImageDecoder::setData(SharedBuffer* data, bool allDataReceived) >+{ >+#if PLATFORM(COCOA) >+ // 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. >+ CGImageSourceUpdateData(m_nativeDecoder, data->createCFData().get(), allDataReceived); >+#else >+ // Create a CGDataProvider to wrap the SharedBuffer. >+ data->ref(); >+ // We use the GetBytesAtPosition callback rather than the GetBytePointer one because SharedBuffer >+ // does not provide a way to lock down the byte pointer and guarantee that it won't move, which >+ // is a requirement for using the GetBytePointer callback. >+ CGDataProviderDirectCallbacks providerCallbacks = { 0, 0, 0, sharedBufferGetBytesAtPosition, sharedBufferRelease }; >+ RetainPtr<CGDataProviderRef> dataProvider = adoptCF(CGDataProviderCreateDirect(data, data->size(), &providerCallbacks)); >+ CGImageSourceUpdateDataProvider(m_nativeDecoder, dataProvider.get(), allDataReceived); >+#endif >+} >+ >+} >+ >+#endif // USE(CG) >diff --git a/Source/WebCore/platform/graphics/cg/ImageDecoder.h b/Source/WebCore/platform/graphics/cg/ImageDecoder.h >new file mode 100644 >index 0000000000000000000000000000000000000000..1561ab9e1779172bf3ed27fa040a0e4191ba166d >--- /dev/null >+++ b/Source/WebCore/platform/graphics/cg/ImageDecoder.h >@@ -0,0 +1,75 @@ >+/* >+ * Copyright (C) 2016 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 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 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. >+ */ >+ >+#ifndef ImageDecoder_h >+#define ImageDecoder_h >+ >+#include "ImageSource.h" >+#include "IntSize.h" >+ >+namespace WebCore { >+ >+String preferredExtensionForImageSourceType(const String& type); >+ >+enum class DecodeMode { Immediate, Lazy }; >+ >+class SharedBuffer; >+ >+class ImageDecoder { >+public: >+ ImageDecoder(); >+ virtual ~ImageDecoder() { } >+ >+ static size_t bytesDecodedToDetermineProperties(); >+ static SubsamplingLevel subsamplingLevelForScale(float scale, SubsamplingLevel maximumSubsamplingLevel); >+ >+ String filenameExtension() const; >+ bool isSizeAvailable() const; >+ IntSize size() const; >+ size_t frameCount() const; >+ int repetitionCount() const; >+ bool getHotSpot(IntPoint& hotSpot) const; >+ >+ IntSize frameSizeAtIndex(size_t, SubsamplingLevel) const; >+ bool frameIsCompleteAtIndex(size_t) const; >+ ImageOrientation orientationAtIndex(size_t) const; >+ >+ float frameDurationAtIndex(size_t) const; >+ bool frameHasAlphaAtIndex(size_t) const; >+ bool allowSubsamplingOfFrameAtIndex(size_t) const; >+ unsigned frameBytesAtIndex(size_t, SubsamplingLevel = 0) const; >+ >+ PassNativeImagePtr createFrameImageAtIndex(size_t, SubsamplingLevel, DecodeMode = DecodeMode::Lazy) const; >+ >+ void setData(SharedBuffer*, bool allDataReceived); >+ >+protected: >+ mutable IntSize m_size; >+ CGImageSourceRef m_nativeDecoder; >+}; >+ >+} >+ >+#endif // ImageDecoder_h >diff --git a/Source/WebCore/platform/graphics/cg/ImageSourceCG.cpp b/Source/WebCore/platform/graphics/cg/ImageSourceCG.cpp >index d4a012b6f57bf5393064777b6c109366b24c445c..dcf79a72a15e9f7940fada6d6195b8cd435433b3 100644 >--- a/Source/WebCore/platform/graphics/cg/ImageSourceCG.cpp >+++ b/Source/WebCore/platform/graphics/cg/ImageSourceCG.cpp >@@ -30,6 +30,7 @@ > #include "ImageSourceCG.h" > > #include "CoreGraphicsSPI.h" >+#include "ImageDecoder.h" > #include "ImageOrientation.h" > #include "IntPoint.h" > #include "IntSize.h" >@@ -44,44 +45,9 @@ > #include <wtf/RetainPtr.h> > #endif > >-#if USE(APPLE_INTERNAL_SDK) >-#import <ImageIO/CGImageSourcePrivate.h> >-#else >-const CFStringRef kCGImageSourceSubsampleFactor = CFSTR("kCGImageSourceSubsampleFactor"); >-#endif >- > namespace WebCore { > >-const CFStringRef WebCoreCGImagePropertyAPNGUnclampedDelayTime = CFSTR("UnclampedDelayTime"); >-const CFStringRef WebCoreCGImagePropertyAPNGDelayTime = CFSTR("DelayTime"); >-const CFStringRef WebCoreCGImagePropertyAPNGLoopCount = CFSTR("LoopCount"); >- >-const CFStringRef kCGImageSourceShouldPreferRGB32 = CFSTR("kCGImageSourceShouldPreferRGB32"); >-const CFStringRef kCGImageSourceSkipMetadata = CFSTR("kCGImageSourceSkipMetadata"); >- >-#if !PLATFORM(COCOA) >-size_t sharedBufferGetBytesAtPosition(void* info, void* buffer, off_t position, size_t count) >-{ >- SharedBuffer* sharedBuffer = static_cast<SharedBuffer*>(info); >- size_t sourceSize = sharedBuffer->size(); >- if (position >= sourceSize) >- return 0; >- >- const char* source = sharedBuffer->data() + position; >- size_t amount = std::min<size_t>(count, sourceSize - position); >- memcpy(buffer, source, amount); >- return amount; >-} >- >-void sharedBufferRelease(void* info) >-{ >- SharedBuffer* sharedBuffer = static_cast<SharedBuffer*>(info); >- sharedBuffer->deref(); >-} >-#endif >- > ImageSource::ImageSource(ImageSource::AlphaOption, ImageSource::GammaAndColorProfileOption) >- : m_decoder(0) > { > // FIXME: AlphaOption and GammaAndColorProfileOption are ignored. > } >@@ -100,354 +66,129 @@ void ImageSource::clear(bool destroyAllFrames, size_t, SharedBuffer* data, bool > return; > > if (m_decoder) { >- CFRelease(m_decoder); >+ delete m_decoder; > m_decoder = 0; > } >+ > if (data) > setData(data, allDataReceived); > } >- >-static RetainPtr<CFDictionaryRef> createImageSourceOptions(SubsamplingLevel subsamplingLevel) >+ >+void ImageSource::ensureDecoderIsCreated(SharedBuffer* data) > { >- if (!subsamplingLevel) { >- const unsigned numOptions = 3; >- const void* keys[numOptions] = { kCGImageSourceShouldCache, kCGImageSourceShouldPreferRGB32, kCGImageSourceSkipMetadata }; >- const void* values[numOptions] = { kCFBooleanTrue, kCFBooleanTrue, kCFBooleanTrue }; >- return CFDictionaryCreate(nullptr, keys, values, numOptions, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); >- } >- >- short constrainedSubsamplingLevel = std::min<short>(3, std::max<short>(0, subsamplingLevel)); >- int subsampleInt = 1 << constrainedSubsamplingLevel; // [0..3] => [1, 2, 4, 8] >- >- RetainPtr<CFNumberRef> subsampleNumber = adoptCF(CFNumberCreate(nullptr, kCFNumberIntType, &subsampleInt)); >- const CFIndex numOptions = 4; >- const void* keys[numOptions] = { kCGImageSourceShouldCache, kCGImageSourceShouldPreferRGB32, kCGImageSourceSkipMetadata, kCGImageSourceSubsampleFactor }; >- const void* values[numOptions] = { kCFBooleanTrue, kCFBooleanTrue, kCFBooleanTrue, subsampleNumber.get() }; >- return adoptCF(CFDictionaryCreate(nullptr, keys, values, numOptions, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks)); >+ UNUSED_PARAM(data); >+ >+ if (m_decoder) >+ return; >+ >+ m_decoder = new ImageDecoder(); > } >- >-static RetainPtr<CFDictionaryRef> imageSourceOptions(SubsamplingLevel subsamplingLevel = 0) >+ >+void ImageSource::setData(SharedBuffer* data, bool allDataReceived) > { >- if (subsamplingLevel) >- return createImageSourceOptions(subsamplingLevel); >+ if (!data) >+ return; > >- static NeverDestroyed<RetainPtr<CFDictionaryRef>> options = createImageSourceOptions(0); >- return options; >-} >+ ensureDecoderIsCreated(data); >+ if (!m_decoder) { >+ ASSERT_NOT_REACHED(); >+ return; >+ } > >-bool ImageSource::initialized() const >-{ >- return m_decoder; >+ m_decoder->setData(data, allDataReceived); > } > >-void ImageSource::setData(SharedBuffer* data, bool allDataReceived) >+String ImageSource::filenameExtension() const > { >-#if PLATFORM(COCOA) >- if (!m_decoder) >- m_decoder = CGImageSourceCreateIncremental(0); >- // 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. >- CGImageSourceUpdateData(m_decoder, data->createCFData().get(), allDataReceived); >-#else >- if (!m_decoder) >- m_decoder = CGImageSourceCreateIncremental(0); >- // Create a CGDataProvider to wrap the SharedBuffer. >- data->ref(); >- // We use the GetBytesAtPosition callback rather than the GetBytePointer one because SharedBuffer >- // does not provide a way to lock down the byte pointer and guarantee that it won't move, which >- // is a requirement for using the GetBytePointer callback. >- CGDataProviderDirectCallbacks providerCallbacks = { 0, 0, 0, sharedBufferGetBytesAtPosition, sharedBufferRelease }; >- RetainPtr<CGDataProviderRef> dataProvider = adoptCF(CGDataProviderCreateDirect(data, data->size(), &providerCallbacks)); >- CGImageSourceUpdateDataProvider(m_decoder, dataProvider.get(), allDataReceived); >-#endif >+ return initialized() ? m_decoder->filenameExtension() : String(); > } > >-String ImageSource::filenameExtension() const >+SubsamplingLevel ImageSource::subsamplingLevelForScale(float scale, SubsamplingLevel maximumSubsamplingLevel) const > { >- if (!m_decoder) >- return String(); >- CFStringRef imageSourceType = CGImageSourceGetType(m_decoder); >- return WebCore::preferredExtensionForImageSourceType(imageSourceType); >+ return ImageDecoder::subsamplingLevelForScale(scale, maximumSubsamplingLevel); > } >+ > >-SubsamplingLevel ImageSource::subsamplingLevelForScale(float scale) const >+size_t ImageSource::bytesDecodedToDetermineProperties() const > { >- // There are four subsampling levels: 0 = 1x, 1 = 0.5x, 2 = 0.25x, 3 = 0.125x. >- float clampedScale = std::max<float>(0.125, std::min<float>(1, scale)); >- int result = ceilf(log2f(1 / clampedScale)); >- ASSERT(result >=0 && result <= 3); >- return result; >+ return ImageDecoder::bytesDecodedToDetermineProperties(); > } >- >+ > bool ImageSource::isSizeAvailable() > { >- // Ragnaros yells: TOO SOON! You have awakened me TOO SOON, Executus! >- if (CGImageSourceGetStatus(m_decoder) < kCGImageStatusIncomplete) >- return false; >- >- RetainPtr<CFDictionaryRef> image0Properties = adoptCF(CGImageSourceCopyPropertiesAtIndex(m_decoder, 0, imageSourceOptions().get())); >- if (!image0Properties) >- return false; >- >- return CFDictionaryContainsKey(image0Properties.get(), kCGImagePropertyPixelWidth) >- && CFDictionaryContainsKey(image0Properties.get(), kCGImagePropertyPixelHeight); >+ return m_decoder && m_decoder->isSizeAvailable(); > } > >-static ImageOrientation orientationFromProperties(CFDictionaryRef imageProperties) >+bool ImageSource::allowSubsamplingOfFrameAtIndex(size_t index) const > { >- ASSERT(imageProperties); >- CFNumberRef orientationProperty = (CFNumberRef)CFDictionaryGetValue(imageProperties, kCGImagePropertyOrientation); >- if (!orientationProperty) >- return DefaultImageOrientation; >- >- int exifValue; >- CFNumberGetValue(orientationProperty, kCFNumberIntType, &exifValue); >- return ImageOrientation::fromEXIFValue(exifValue); >+ return initialized() && m_decoder->allowSubsamplingOfFrameAtIndex(index); > } > >-bool ImageSource::allowSubsamplingOfFrameAtIndex(size_t) const >+IntSize ImageSource::frameSizeAtIndex(size_t index, SubsamplingLevel subsamplingLevel, RespectImageOrientationEnum shouldRespectImageOrientation) const > { >- RetainPtr<CFDictionaryRef> properties = adoptCF(CGImageSourceCopyPropertiesAtIndex(m_decoder, 0, imageSourceOptions().get())); >- if (!properties) >- return false; >- >- CFDictionaryRef jfifProperties = static_cast<CFDictionaryRef>(CFDictionaryGetValue(properties.get(), kCGImagePropertyJFIFDictionary)); >- if (jfifProperties) { >- CFBooleanRef isProgCFBool = static_cast<CFBooleanRef>(CFDictionaryGetValue(jfifProperties, kCGImagePropertyJFIFIsProgressive)); >- if (isProgCFBool) { >- bool isProgressive = CFBooleanGetValue(isProgCFBool); >- // Workaround for <rdar://problem/5184655> - Hang rendering very large progressive JPEG. Decoding progressive >- // images hangs for a very long time right now. Until this is fixed, don't sub-sample progressive images. This >- // will cause them to fail our large image check and they won't be decoded. >- // FIXME: Remove once underlying issue is fixed (<rdar://problem/5191418>) >- return !isProgressive; >- } >- } >- >- return true; >-} >- >-IntSize ImageSource::frameSizeAtIndex(size_t index, SubsamplingLevel subsamplingLevel, ImageOrientationDescription description) const >-{ >- RetainPtr<CFDictionaryRef> properties = adoptCF(CGImageSourceCopyPropertiesAtIndex(m_decoder, index, imageSourceOptions(subsamplingLevel).get())); >- >- if (!properties) >+ if (!initialized()) > return IntSize(); > >- int width = 0; >- int height = 0; >- CFNumberRef num = (CFNumberRef)CFDictionaryGetValue(properties.get(), kCGImagePropertyPixelWidth); >- if (num) >- CFNumberGetValue(num, kCFNumberIntType, &width); >- num = (CFNumberRef)CFDictionaryGetValue(properties.get(), kCGImagePropertyPixelHeight); >- if (num) >- CFNumberGetValue(num, kCFNumberIntType, &height); >- >- if ((description.respectImageOrientation() == RespectImageOrientation) && orientationFromProperties(properties.get()).usesWidthAsHeight()) >- return IntSize(height, width); >+ IntSize size = m_decoder->frameSizeAtIndex(index, subsamplingLevel); >+ ImageOrientation orientation = m_decoder->orientationAtIndex(index); > >- return IntSize(width, height); >+ return shouldRespectImageOrientation == RespectImageOrientation && orientation.usesWidthAsHeight() ? size.transposedSize() : size; > } > > ImageOrientation ImageSource::orientationAtIndex(size_t index) const > { >- RetainPtr<CFDictionaryRef> properties = adoptCF(CGImageSourceCopyPropertiesAtIndex(m_decoder, index, imageSourceOptions().get())); >- if (!properties) >- return DefaultImageOrientation; >- >- return orientationFromProperties(properties.get()); >+ return initialized() ? m_decoder->orientationAtIndex(index) : DefaultImageOrientation; > } > >-IntSize ImageSource::size(ImageOrientationDescription description) const >+IntSize ImageSource::size() const > { >- return frameSizeAtIndex(0, 0, description); >+ return frameSizeAtIndex(0, 0); > } > >-bool ImageSource::getHotSpot(IntPoint& hotSpot) const >+IntSize ImageSource::sizeRespectingOrientation() const > { >- RetainPtr<CFDictionaryRef> properties = adoptCF(CGImageSourceCopyPropertiesAtIndex(m_decoder, 0, imageSourceOptions().get())); >- if (!properties) >- return false; >- >- int x = -1, y = -1; >- CFNumberRef num = (CFNumberRef)CFDictionaryGetValue(properties.get(), CFSTR("hotspotX")); >- if (!num || !CFNumberGetValue(num, kCFNumberIntType, &x)) >- return false; >- >- num = (CFNumberRef)CFDictionaryGetValue(properties.get(), CFSTR("hotspotY")); >- if (!num || !CFNumberGetValue(num, kCFNumberIntType, &y)) >- return false; >- >- if (x < 0 || y < 0) >- return false; >- >- hotSpot = IntPoint(x, y); >- return true; >+ return frameSizeAtIndex(0, 0, RespectImageOrientation); > } > >-size_t ImageSource::bytesDecodedToDetermineProperties() const >+bool ImageSource::getHotSpot(IntPoint& hotSpot) const > { >- // Measured by tracing malloc/calloc calls on Mac OS 10.6.6, x86_64. >- // A non-zero value ensures cached images with no decoded frames still enter >- // the live decoded resources list when the CGImageSource decodes image >- // properties, allowing the cache to prune the partially decoded image. >- // This value is likely to be inaccurate on other platforms, but the overall >- // behavior is unchanged. >- return 13088; >+ return m_decoder && m_decoder->getHotSpot(hotSpot); > } >- >+ > int ImageSource::repetitionCount() > { >- if (!initialized()) >- return cAnimationLoopOnce; >- >- RetainPtr<CFDictionaryRef> properties = adoptCF(CGImageSourceCopyProperties(m_decoder, imageSourceOptions().get())); >- if (!properties) >- return cAnimationLoopOnce; >- >- CFDictionaryRef gifProperties = (CFDictionaryRef)CFDictionaryGetValue(properties.get(), kCGImagePropertyGIFDictionary); >- if (gifProperties) { >- CFNumberRef num = (CFNumberRef)CFDictionaryGetValue(gifProperties, kCGImagePropertyGIFLoopCount); >- >- // No property means loop once. >- if (!num) >- return cAnimationLoopOnce; >- >- int loopCount; >- CFNumberGetValue(num, kCFNumberIntType, &loopCount); >- >- // A property with value 0 means loop forever. >- return loopCount ? loopCount : cAnimationLoopInfinite; >- } >- >- CFDictionaryRef pngProperties = (CFDictionaryRef)CFDictionaryGetValue(properties.get(), kCGImagePropertyPNGDictionary); >- if (pngProperties) { >- CFNumberRef num = (CFNumberRef)CFDictionaryGetValue(pngProperties, WebCoreCGImagePropertyAPNGLoopCount); >- if (!num) >- return cAnimationLoopOnce; >- >- int loopCount; >- CFNumberGetValue(num, kCFNumberIntType, &loopCount); >- return loopCount ? loopCount : cAnimationLoopInfinite; >- } >- >- // Turns out we're not an animated image after all, so we don't animate. >- return cAnimationNone; >+ return initialized() ? m_decoder->repetitionCount() : cAnimationLoopOnce; > } > > size_t ImageSource::frameCount() const > { >- return m_decoder ? CGImageSourceGetCount(m_decoder) : 0; >+ return m_decoder ? m_decoder->frameCount() : 0; > } > >-CGImageRef ImageSource::createFrameAtIndex(size_t index, SubsamplingLevel subsamplingLevel) >+PassNativeImagePtr ImageSource::createFrameImageAtIndex(size_t index, SubsamplingLevel subsamplingLevel) > { >- if (!initialized()) >- return nullptr; >- >- RetainPtr<CGImageRef> image = adoptCF(CGImageSourceCreateImageAtIndex(m_decoder, index, imageSourceOptions(subsamplingLevel).get())); >- >-#if PLATFORM(IOS) >- // <rdar://problem/7371198> - CoreGraphics changed the default caching behaviour in iOS 4.0 to kCGImageCachingTransient >- // which caused a performance regression for us since the images had to be resampled/recreated every time we called >- // CGContextDrawImage. We now tell CG to cache the drawn images. See also <rdar://problem/14366755> - >- // CoreGraphics needs to un-deprecate kCGImageCachingTemporary since it's still not the default. >-#if COMPILER(CLANG) >-#pragma clang diagnostic push >-#pragma clang diagnostic ignored "-Wdeprecated-declarations" >-#endif >- CGImageSetCachingFlags(image.get(), kCGImageCachingTemporary); >-#if COMPILER(CLANG) >-#pragma clang diagnostic pop >-#endif >-#endif // PLATFORM(IOS) >- >- CFStringRef imageUTI = CGImageSourceGetType(m_decoder); >- static const CFStringRef xbmUTI = CFSTR("public.xbitmap-image"); >- >- if (!imageUTI) >- return image.leakRef(); >- >- if (!CFEqual(imageUTI, xbmUTI)) >- return image.leakRef(); >- >- // 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}; >- RetainPtr<CGImageRef> maskedImage = adoptCF(CGImageCreateWithMaskingColors(image.get(), maskingColors)); >- if (!maskedImage) >- return image.leakRef(); >- >- return maskedImage.leakRef(); >+ return initialized() ? m_decoder->createFrameImageAtIndex(index, subsamplingLevel) : nullptr; > } > > bool ImageSource::frameIsCompleteAtIndex(size_t index) > { > ASSERT(frameCount()); >- return CGImageSourceGetStatusAtIndex(m_decoder, index) == kCGImageStatusComplete; >+ return initialized() && m_decoder->frameIsCompleteAtIndex(index); > } > > float ImageSource::frameDurationAtIndex(size_t index) > { >- if (!initialized()) >- return 0; >- >- float duration = 0; >- RetainPtr<CFDictionaryRef> properties = adoptCF(CGImageSourceCopyPropertiesAtIndex(m_decoder, index, imageSourceOptions().get())); >- if (properties) { >- CFDictionaryRef gifProperties = (CFDictionaryRef)CFDictionaryGetValue(properties.get(), kCGImagePropertyGIFDictionary); >- if (gifProperties) { >- if (CFNumberRef num = (CFNumberRef)CFDictionaryGetValue(gifProperties, kCGImagePropertyGIFUnclampedDelayTime)) { >- // Use the unclamped frame delay if it exists. >- CFNumberGetValue(num, kCFNumberFloatType, &duration); >- } else if (CFNumberRef num = (CFNumberRef)CFDictionaryGetValue(gifProperties, kCGImagePropertyGIFDelayTime)) { >- // Fall back to the clamped frame delay if the unclamped frame delay does not exist. >- CFNumberGetValue(num, kCFNumberFloatType, &duration); >- } >- } >- >- CFDictionaryRef pngProperties = (CFDictionaryRef)CFDictionaryGetValue(properties.get(), kCGImagePropertyPNGDictionary); >- if (pngProperties) { >- if (CFNumberRef num = (CFNumberRef)CFDictionaryGetValue(pngProperties, WebCoreCGImagePropertyAPNGUnclampedDelayTime)) >- CFNumberGetValue(num, kCFNumberFloatType, &duration); >- else if (CFNumberRef num = (CFNumberRef)CFDictionaryGetValue(pngProperties, WebCoreCGImagePropertyAPNGDelayTime)) >- CFNumberGetValue(num, kCFNumberFloatType, &duration); >- } >- } >- >- // Many annoying ads specify a 0 duration to make an image flash as quickly as possible. >- // We follow Firefox's behavior and use a duration of 100 ms for any frames that specify >- // a duration of <= 10 ms. See <rdar://problem/7689300> and <http://webkit.org/b/36082> >- // for more information. >- if (duration < 0.011f) >- return 0.1f; >- return duration; >+ return initialized() ? m_decoder->frameDurationAtIndex(index) : 0; > } > > bool ImageSource::frameHasAlphaAtIndex(size_t index) > { >- if (!m_decoder) >- return false; // FIXME: why doesn't this return true? >- >- if (!frameIsCompleteAtIndex(index)) >- return true; >- >- CFStringRef imageType = CGImageSourceGetType(m_decoder); >- >- // Return false if there is no image type or the image type is JPEG, because >- // JPEG does not support alpha transparency. >- if (!imageType || CFEqual(imageType, CFSTR("public.jpeg"))) >- return false; >- >- // FIXME: Could return false for 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; >+ return initialized() && m_decoder->frameHasAlphaAtIndex(index); > } > > unsigned ImageSource::frameBytesAtIndex(size_t index, SubsamplingLevel subsamplingLevel) const > { >- IntSize frameSize = frameSizeAtIndex(index, subsamplingLevel, ImageOrientationDescription(RespectImageOrientation)); >- return frameSize.width() * frameSize.height() * 4; >+ return initialized() ? m_decoder->frameBytesAtIndex(index, subsamplingLevel) : 0; > } > > } >diff --git a/Source/WebCore/platform/graphics/efl/GraphicsContext3DEfl.cpp b/Source/WebCore/platform/graphics/efl/GraphicsContext3DEfl.cpp >index ba41597aa1101db629023d273b200e781d33aac9..59cc2c9be8b3ffe11186a685d2e8cf594c1d3931 100644 >--- a/Source/WebCore/platform/graphics/efl/GraphicsContext3DEfl.cpp >+++ b/Source/WebCore/platform/graphics/efl/GraphicsContext3DEfl.cpp >@@ -263,7 +263,7 @@ bool GraphicsContext3D::ImageExtractor::extractImage(bool premultiplyAlpha, bool > if (!decoder.frameCount() || !decoder.frameIsCompleteAtIndex(0)) > return false; > >- m_imageSurface = decoder.createFrameAtIndex(0); >+ m_imageSurface = decoder.createFrameImageAtIndex(0); > } else { > m_imageSurface = m_image->nativeImageForCurrentFrame(); > // 1. For texImage2D with HTMLVideoElment input, assume no PremultiplyAlpha had been applied and the alpha value is 0xFF for each pixel, >diff --git a/Source/WebCore/platform/graphics/ios/IconIOS.mm b/Source/WebCore/platform/graphics/ios/IconIOS.mm >index 215915f28a192172396d46f086d2249b81d9d76a..e1833d19830b107663664b612844597f83fc0a88 100644 >--- a/Source/WebCore/platform/graphics/ios/IconIOS.mm >+++ b/Source/WebCore/platform/graphics/ios/IconIOS.mm >@@ -33,7 +33,7 @@ > > namespace WebCore { > >-Icon::Icon(CGImageRef image) >+Icon::Icon(NativeImagePtr image) > : m_cgImage(image) > { > } >diff --git a/Source/WebCore/platform/graphics/mac/ImageMac.mm b/Source/WebCore/platform/graphics/mac/ImageMac.mm >index ff07131a61fced04586b372d9ba2079a9873c38b..fa011aa881630300094498ebc0ffca9fb9c3034b 100644 >--- a/Source/WebCore/platform/graphics/mac/ImageMac.mm >+++ b/Source/WebCore/platform/graphics/mac/ImageMac.mm >@@ -95,7 +95,7 @@ CFDataRef BitmapImage::getTIFFRepresentation() > > Vector<CGImageRef> images; > for (unsigned i = 0; i < numFrames; ++i ) { >- CGImageRef cgImage = frameAtIndex(i); >+ CGImageRef cgImage = frameImageAtIndex(i).get(); > if (cgImage) > images.append(cgImage); > } >diff --git a/Source/WebCore/platform/graphics/win/ImageCGWin.cpp b/Source/WebCore/platform/graphics/win/ImageCGWin.cpp >index 835ecf3f4feeeb8a0dfa8d36973128f3b807b926..47073c0ed690e044ffb3a94e586f260279d1c4c7 100644 >--- a/Source/WebCore/platform/graphics/win/ImageCGWin.cpp >+++ b/Source/WebCore/platform/graphics/win/ImageCGWin.cpp >@@ -90,7 +90,7 @@ void BitmapImage::drawFrameMatchingSourceSize(GraphicsContext& ctxt, const Float > { > size_t frames = frameCount(); > for (size_t i = 0; i < frames; ++i) { >- CGImageRef image = frameAtIndex(i); >+ CGImageRef image = frameImageAtIndex(i).get(); > if (image && CGImageGetHeight(image) == static_cast<size_t>(srcSize.height()) && CGImageGetWidth(image) == static_cast<size_t>(srcSize.width())) { > size_t currentFrame = m_currentFrame; > m_currentFrame = i; >diff --git a/Source/WebCore/platform/graphics/win/ImageCairoWin.cpp b/Source/WebCore/platform/graphics/win/ImageCairoWin.cpp >index 29a2023db63a91434c3948eaa5523bb61fe81075..97ed097935c51fc20a845c958e15698d2000db85 100644 >--- a/Source/WebCore/platform/graphics/win/ImageCairoWin.cpp >+++ b/Source/WebCore/platform/graphics/win/ImageCairoWin.cpp >@@ -93,7 +93,7 @@ void BitmapImage::drawFrameMatchingSourceSize(GraphicsContext& ctxt, const Float > { > size_t frames = frameCount(); > for (size_t i = 0; i < frames; ++i) { >- RefPtr<cairo_surface_t> surface = frameAtIndex(i); >+ RefPtr<cairo_surface_t> surface = frameImageAtIndex(i); > if (!surface) > continue; > >diff --git a/Source/WebCore/platform/mac/DragImageMac.mm b/Source/WebCore/platform/mac/DragImageMac.mm >index bbae91fa8e3c066447c464d6e31200de248ce83f..91c92e912cc21892f659e67a959571fbdd0027b8 100644 >--- a/Source/WebCore/platform/mac/DragImageMac.mm >+++ b/Source/WebCore/platform/mac/DragImageMac.mm >@@ -91,7 +91,7 @@ RetainPtr<NSImage> createDragImageFromImage(Image* image, ImageOrientationDescri > if (is<BitmapImage>(*image)) { > ImageOrientation orientation; > BitmapImage& bitmapImage = downcast<BitmapImage>(*image); >- IntSize sizeRespectingOrientation = bitmapImage.sizeRespectingOrientation(description); >+ IntSize sizeRespectingOrientation = bitmapImage.sizeRespectingOrientation(); > > if (description.respectImageOrientation() == RespectImageOrientation) > orientation = bitmapImage.orientationForCurrentFrame();
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Formatted Diff
|
Diff
Attachments on
bug 155444
:
273988
|
273990
|
273992
|
273995
|
276545
|
276549
|
276550
|
276551
|
276621
|
280332
|
280334
|
281796
|
282736
|
282737
|
282738
|
282741