Changeset 206481 in webkit


Ignore:
Timestamp:
Sep 27, 2016 6:06:57 PM (8 years ago)
Author:
commit-queue@webkit.org
Message:

Move caching the ImageFrame from BitmapImage to ImageSource
https://bugs.webkit.org/show_bug.cgi?id=155498

Patch by Said Abou-Hallawa <sabouhallawa@apple.com> on 2016-09-27
Reviewed by Simon Fraser.

BitmapImage has two modes of operation regarding its image decoding state.
The first mode happens when a remote image is loaded as encoded data and
which requires an ImageDecoder to generate the image metadata and the
the ImageFrames. The second mode happens when a BitmapImage is created
with a NativeImagePtr. In this case, no ImageDecoder is needed.

To remove this burden from the BitmapImage the member 'm_frames' is removed
from BitmapImage. A new member named 'm_frameCache' of type ImageFrameCache
is added to ImageSource. This class handles caching and recaching the image
metadata and the ImageFrames if the image needs decoding. When the BitmapImage
is initialized with a memory image, the ImageFrameCache initializes its
metadata and ImageFrames directly from the NativeImagePtr.

The plan for ImageFrameCache is to be extended for the asynchronous image
decoding and also to be used by the non CG image decoders which cache
other copies of the ImageFrames. This double caching should be removed.

When the BitmapImage is replying to the ImageFrame queries, it will ask the
ImageSource which will pass the query the ImageFrameCache. ImageFrameCache
will ensure the requested ImageFrame is cached and is valid for the requested
SubSamplingLevel before accessing the data members of this ImageFrame.

  • CMakeLists.txt:
  • WebCore.xcodeproj/project.pbxproj:

Add and ImageFrameCache.cpp to the WebCore project.

  • platform/graphics/BitmapImage.cpp:

(WebCore::BitmapImage::BitmapImage): Move initializing the image metadata to
ImageSource. Add initializers for the remaining members in the class declaration.

(WebCore::BitmapImage::destroyDecodedData): Move most of the logic of this
function to ImageFrameCache::destroyDecodedData(). The only part which can't
be moved is the call invalidatePlatformData().

(WebCore::BitmapImage::destroyDecodedDataIfNecessary): Move the logic of this
function to ImageFrameCache::destroyDecodedDataIfNecessary().

(WebCore::BitmapImage::dataChanged): Move the logic of this function to
ImageSource::dataChanged().

(WebCore::BitmapImage::frameImageAtIndex): Move most of the logic of this
function to ImageFrameCache::frameImageAtIndex(). The only part which can't
be moved is the call invalidatePlatformData() if the required subsampling
level is different from the subsampling level for the cached frame image.

(WebCore::BitmapImage::draw): Replace the BitmapImage cached metadata with
the corresponding ImageSource cached metadata.
(WebCore::BitmapImage::drawPattern): Ditto.
(WebCore::BitmapImage::shouldAnimate): Ditto.
(WebCore::BitmapImage::startAnimation): Ditto.
(WebCore::BitmapImage::internalAdvanceAnimation): Ditto.

(WebCore::BitmapImage::dump): Call ImageSource::dump() to dump the image
cached metadata.

(WebCore::BitmapImage::haveFrameImageAtIndex): Deleted.
(WebCore::BitmapImage::destroyMetadataAndNotify): Deleted.
(WebCore::BitmapImage::cacheFrame): Deleted.
(WebCore::BitmapImage::didDecodeProperties): Deleted.
(WebCore::BitmapImage::updateSize): Deleted.
(WebCore::BitmapImage::size): Deleted.
(WebCore::BitmapImage::sizeRespectingOrientation): Deleted.
(WebCore::BitmapImage::hotSpot): Deleted.
(WebCore::BitmapImage::frameCount): Deleted.
(WebCore::BitmapImage::isSizeAvailable): Deleted.
(WebCore::BitmapImage::ensureFrameAtIndexIsCached): Deleted.
(WebCore::BitmapImage::frameIsCompleteAtIndex): Deleted.
(WebCore::BitmapImage::frameDurationAtIndex): Deleted.
(WebCore::BitmapImage::frameHasAlphaAtIndex): Deleted.
(WebCore::BitmapImage::currentFrameKnownToBeOpaque): Deleted.
(WebCore::BitmapImage::frameOrientationAtIndex): Deleted.
(WebCore::BitmapImage::singlePixelSolidColor): Deleted.
(WebCore::BitmapImage::repetitionCount): Deleted.

  • platform/graphics/BitmapImage.h:

Managing the ImageFrames caching is moved to ImageFrameCache. Caching the
image metadata is now moved to the ImageSource.

  • platform/graphics/GeneratedImage.h:
  • platform/graphics/Image.h:

(WebCore::Image::orientationForCurrentFrame):
(WebCore::Image::singlePixelSolidColor):
Change currentFrameKnownToBeOpaque(), orientationForCurrentFrame() and
singlePixelSolidColor() to be const.

  • platform/graphics/ImageFrame.cpp:

(WebCore::ImageFrame::defaultFrame): Returns an empty ImageFrame to get the default ImageFrame metadata.
(WebCore::ImageFrame::fillMetadata): Deleted. Moved to ImageFrameCache.
(WebCore::ImageFrame::initialize): Deleted. Ditto.

  • platform/graphics/ImageFrame.h:

(WebCore::ImageFrame::setDuration): Change the type of the argument to float instead of unsigned.
(WebCore::ImageFrame::hasAlpha): Protect the unset m_hasAlpha by checking hasMetadata() first.

  • platform/graphics/ImageFrameCache.cpp: Added.

(WebCore::ImageFrameCache::ImageFrameCache): Two constructors similar to what we do for ImageSource and BitmapImage.
(WebCore::ImageFrameCache::destroyDecodedData): Moved from BitmapImage.cpp.
(WebCore::ImageFrameCache::destroyDecodedDataIfNecessary): Ditto.
(WebCore::ImageFrameCache::destroyIncompleteDecodedData): Ditto.
(WebCore::ImageFrameCache::decodedSizeChanged): Ditto.
(WebCore::ImageFrameCache::decodedSizeIncremented): Ditto.
(WebCore::ImageFrameCache::decodedSizeDecremented): Ditto.
(WebCore::ImageFrameCache::decodedSizeReset): Ditto.
(WebCore::ImageFrameCache::didDecodeProperties): Ditto.
(WebCore::ImageFrameCache::growFrames): Grows the size of m_frames if necessary.
(WebCore::ImageFrameCache::setNativeImage): Initializes the ImageFrame metadata directly from the NativeImagePtr.
(WebCore::ImageFrameCache::setFrameNativeImage): Initializes the ImageFrame image and the metadata.
(WebCore::ImageFrameCache::setFrameMetadata): Initializes the ImageFrame metadata from the ImageDecoder.
(WebCore::ImageFrameCache::frameAtIndex): Returns an ImageFrame given its index. Cache or recache the requested ImageFrame if necessary.
(WebCore::ImageFrameCache::clearMetadata): Invalidates the cached image metadata.
(WebCore::ImageFrameCache::metadata): A template function which returns an image metadata property.
(WebCore::ImageFrameCache::frameMetadataAtIndex): A template function which returns an ImageFrame metadata property.
(WebCore::ImageFrameCache::isSizeAvailable): An image metadata property.
(WebCore::ImageFrameCache::frameCount): Ditto.
(WebCore::ImageFrameCache::repetitionCount): Ditto.
(WebCore::ImageFrameCache::filenameExtension): Ditto.
(WebCore::ImageFrameCache::hotSpot): Ditto.
(WebCore::ImageFrameCache::size): An image metadata property but we get it from the first ImageFrame.
(WebCore::ImageFrameCache::sizeRespectingOrientation): Ditto.
(WebCore::ImageFrameCache::singlePixelSolidColor): Ditto.
(WebCore::ImageFrameCache::frameIsCompleteAtIndex): An ImageFrame metadata property.
(WebCore::ImageFrameCache::frameHasAlphaAtIndex): Ditto.
(WebCore::ImageFrameCache::frameHasImageAtIndex): Ditto.
(WebCore::ImageFrameCache::frameHasInvalidNativeImageAtIndex): Ditto.
(WebCore::ImageFrameCache::frameSubsamplingLevelAtIndex): Ditto.
(WebCore::ImageFrameCache::frameSizeAtIndex): Ditto.
(WebCore::ImageFrameCache::frameBytesAtIndex): Ditto.
(WebCore::ImageFrameCache::frameDurationAtIndex): Ditto.
(WebCore::ImageFrameCache::frameOrientationAtIndex): Ditto.
(WebCore::ImageFrameCache::frameImageAtIndex): Ditto.

  • platform/graphics/ImageFrameCache.h: Added.

(WebCore::ImageFrameCache::setDecoder): Sets the current ImageDecoder which is owned by the ImageSource.
(WebCore::ImageFrameCache::decodedSize): Returns the size of the cached NativeImages.
(WebCore::ImageFrameCache::isDecoderAvailable): Returns whether an ImageDecoder is available.

  • platform/graphics/ImageSource.cpp:

(WebCore::ImageSource::ImageSource): Initializes the ImageFrameCache based on the image decoding state.
(WebCore::ImageSource::clearFrameBufferCache): Replace initialized() with isDecoderAvailable().
(WebCore::ImageSource::clear): Clears the ImageDecoder of the ImageFrameCache.
(WebCore::ImageSource::destroyDecodedData): Moved from BitmapImage.cpp.
(WebCore::ImageSource::destroyDecodedDataIfNecessary): Ditto.
(WebCore::ImageSource::ensureDecoderAvailable): Creates an ImageDecoder if necessary and sets it in ImageFrameCache.
(WebCore::ImageSource::setData):
(WebCore::ImageSource::dataChanged): Moved from BitmapImage.cpp.
(WebCore::ImageSource::isAllDataReceived):
(WebCore::ImageSource::maximumSubsamplingLevel): Rename calculateMaximumSubsamplingLevel() to maximumSubsamplingLevel().
(WebCore::ImageSource::subsamplingLevelForScale):
(WebCore::ImageSource::createFrameImageAtIndex):
(WebCore::ImageSource::dump):
(WebCore::ImageSource::calculateMaximumSubsamplingLevel): Deleted. Renamed to maximumSubsamplingLevel().
(WebCore::ImageSource::updateMetadata): Deleted. Not needed. Caching the image metadata is the responsibility of ImageFrameCache.
(WebCore::ImageSource::bytesDecodedToDetermineProperties): Deleted. Not needed.
(WebCore::ImageSource::isSizeAvailable): Deleted. Moved to ImageSource.h.
(WebCore::ImageSource::size): Deleted. Ditto.
(WebCore::ImageSource::sizeRespectingOrientation): Deleted. Ditto.
(WebCore::ImageSource::frameCount): Deleted. Ditto.
(WebCore::ImageSource::repetitionCount): Deleted. Ditto.
(WebCore::ImageSource::filenameExtension): Deleted. Ditto.
(WebCore::ImageSource::hotSpot): Deleted. Ditto.
(WebCore::ImageSource::frameIsCompleteAtIndex): Deleted. Ditto.
(WebCore::ImageSource::frameHasAlphaAtIndex): Deleted. Ditto.
(WebCore::ImageSource::frameAllowSubsamplingAtIndex): Deleted. Ditto.
(WebCore::ImageSource::frameSizeAtIndex): Deleted. Ditto.
(WebCore::ImageSource::frameBytesAtIndex): Deleted. Ditto.
(WebCore::ImageSource::frameDurationAtIndex): Deleted. Ditto.
(WebCore::ImageSource::frameOrientationAtIndex): Deleted. Ditto.

  • platform/graphics/ImageSource.h:

(WebCore::ImageSource::isDecoderAvailable): initialized() was renamed to isDecoderAvailable().
(WebCore::ImageSource::decodedSize): Send the query to ImageFrameCache.
(WebCore::ImageSource::isSizeAvailable): Ditto.
(WebCore::ImageSource::frameCount): Ditto.
(WebCore::ImageSource::repetitionCount): Ditto.
(WebCore::ImageSource::filenameExtension): Ditto.
(WebCore::ImageSource::hotSpot): Ditto.
(WebCore::ImageSource::size): Ditto.
(WebCore::ImageSource::sizeRespectingOrientation): Ditto.
(WebCore::ImageSource::singlePixelSolidColor): Ditto.
(WebCore::ImageSource::frameIsCompleteAtIndex): Ditto.
(WebCore::ImageSource::frameHasAlphaAtIndex): Ditto.
(WebCore::ImageSource::frameHasImageAtIndex): Ditto.
(WebCore::ImageSource::frameHasInvalidNativeImageAtIndex): Ditto.
(WebCore::ImageSource::frameSubsamplingLevelAtIndex): Ditto.
(WebCore::ImageSource::frameSizeAtIndex): Ditto.
(WebCore::ImageSource::frameBytesAtIndex): Ditto.
(WebCore::ImageSource::frameDurationAtIndex): Ditto.
(WebCore::ImageSource::frameOrientationAtIndex): Ditto.
(WebCore::ImageSource::frameImageAtIndex): Ditto.
(WebCore::ImageSource::decoder): Deleted. Not needed.
(WebCore::ImageSource::initialized): Deleted. Was renamed to isDecoderAvailable().
(WebCore::ImageSource::setNeedsUpdateMetadata): Deleted. Not needed.

  • platform/graphics/cairo/GraphicsContext3DCairo.cpp:

(WebCore::GraphicsContext3D::ImageExtractor::extractImage): AlphaOption and GammaAndColorProfileOption are moved out of ImageSource.

  • platform/graphics/cg/GraphicsContext3DCG.cpp:

(WebCore::GraphicsContext3D::ImageExtractor::extractImage): Ditto.

  • platform/graphics/cg/ImageDecoderCG.cpp:

(WebCore::ImageDecoder::ImageDecoder): Make the constructor of ImageDecoder be the same for all ports.
(WebCore::ImageDecoder::setData): Removed unused overloaded function.
(WebCore::ImageDecoder::size): Deleted. Removed unused function.

  • platform/graphics/cg/ImageDecoderCG.h:

(WebCore::ImageDecoder::create): Make the constructor of CG ImageDecoder be like the other ports.
(WebCore::ImageDecoder::isAllDataReceived): Make this property owned by ImageDecoder.

  • platform/graphics/cg/PDFDocumentImage.h: Change currentFrameKnownToBeOpaque() to be const.
  • platform/graphics/efl/GraphicsContext3DEfl.cpp:

(WebCore::GraphicsContext3D::ImageExtractor::extractImage): AlphaOption and GammaAndColorProfileOption are moved out of ImageSource.

  • platform/graphics/mac/ImageMac.mm:

(WebCore::BitmapImage::invalidatePlatformData): m_frames is owned by ImageFrameCache. ImageFrameCache::frameCount() has to
be equal to ImageFrame::m_frames.size().

  • platform/image-decoders/ImageDecoder.cpp:

(WebCore::ImageDecoder::create): AlphaOption and GammaAndColorProfileOption are moved out of ImageSource.

  • platform/image-decoders/ImageDecoder.h:

(WebCore::ImageDecoder::ImageDecoder): Ditto.
(WebCore::ImageDecoder::frameCount): Make frameCount const so it can be passed to the template function ImageFrameCache::metadata().

  • platform/image-decoders/bmp/BMPImageDecoder.cpp:

(WebCore::BMPImageDecoder::BMPImageDecoder): AlphaOption and GammaAndColorProfileOption are moved out of ImageSource.

  • platform/image-decoders/bmp/BMPImageDecoder.h:
  • platform/image-decoders/gif/GIFImageDecoder.cpp:

(WebCore::GIFImageDecoder::GIFImageDecoder): AlphaOption and GammaAndColorProfileOption are moved out of ImageSource.
(WebCore::GIFImageDecoder::frameCount): Make frameCount const so it can be passed to the template function ImageFrameCache::metadata().

  • platform/image-decoders/gif/GIFImageDecoder.h:
  • platform/image-decoders/gif/GIFImageReader.cpp:
  • platform/image-decoders/gif/GIFImageReader.h:
  • platform/image-decoders/ico/ICOImageDecoder.cpp:

(WebCore::ICOImageDecoder::ICOImageDecoder):
(WebCore::ICOImageDecoder::frameCount): Make frameCount const so it can be passed to the template function ImageFrameCache::metadata().
(WebCore::ICOImageDecoder::decode): Move resizing the m_frameBufferCache from ICOImageDecoder::frameCount() to ICOImageDecoder::decode().
(WebCore::ICOImageDecoder::decodeAtIndex): AlphaOption and GammaAndColorProfileOption are moved out of ImageSource.

  • platform/image-decoders/ico/ICOImageDecoder.h:
  • platform/image-decoders/jpeg/JPEGImageDecoder.cpp:

(WebCore::JPEGImageDecoder::JPEGImageDecoder): AlphaOption and GammaAndColorProfileOption are moved out of ImageSource.

  • platform/image-decoders/jpeg/JPEGImageDecoder.h:
  • platform/image-decoders/png/PNGImageDecoder.cpp:

(WebCore::PNGImageDecoder::PNGImageDecoder): AlphaOption and GammaAndColorProfileOption are moved out of ImageSource.

  • platform/image-decoders/png/PNGImageDecoder.h:

(WebCore::PNGImageDecoder::frameCount): Make frameCount const so it can be passed to the template function ImageFrameCache::metadata().

  • platform/image-decoders/webp/WEBPImageDecoder.cpp:

(WebCore::WEBPImageDecoder::WEBPImageDecoder):

  • platform/image-decoders/webp/WEBPImageDecoder.h:
  • svg/graphics/SVGImage.h: Make currentFrameKnownToBeOpaque() be const.
  • svg/graphics/SVGImageForContainer.h: Ditto.
Location:
trunk/Source/WebCore
Files:
2 added
36 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebCore/CMakeLists.txt

    r206440 r206481  
    22222222    platform/graphics/ImageBuffer.cpp
    22232223    platform/graphics/ImageFrame.cpp
     2224    platform/graphics/ImageFrameCache.cpp
    22242225    platform/graphics/ImageOrientation.cpp
    22252226    platform/graphics/ImageSource.cpp
  • trunk/Source/WebCore/ChangeLog

    r206480 r206481  
     12016-09-27  Said Abou-Hallawa  <sabouhallawa@apple.com>
     2
     3        Move caching the ImageFrame from BitmapImage to ImageSource
     4        https://bugs.webkit.org/show_bug.cgi?id=155498
     5
     6        Reviewed by Simon Fraser.
     7
     8        BitmapImage has two modes of operation regarding its image decoding state.
     9        The first mode happens when a remote image is loaded as encoded data and
     10        which requires an ImageDecoder to generate the image metadata and the
     11        the ImageFrames. The second mode happens when a BitmapImage is created
     12        with a NativeImagePtr. In this case, no ImageDecoder is needed.
     13
     14        To remove this burden from the BitmapImage the member 'm_frames' is removed
     15        from BitmapImage. A new member named 'm_frameCache' of type ImageFrameCache
     16        is added to ImageSource. This class handles caching and recaching the image
     17        metadata and the ImageFrames if the image needs decoding. When the BitmapImage
     18        is initialized with a memory image, the ImageFrameCache initializes its
     19        metadata and ImageFrames directly from the NativeImagePtr.
     20
     21        The plan for ImageFrameCache is to be extended for the asynchronous image
     22        decoding and also to be used by the non CG image decoders which cache
     23        other copies of the ImageFrames. This double caching should be removed.
     24
     25        When the BitmapImage is replying to the ImageFrame queries, it will ask the
     26        ImageSource which will pass the query the ImageFrameCache. ImageFrameCache
     27        will ensure the requested ImageFrame is cached and is valid for the requested
     28        SubSamplingLevel before accessing the data members of this ImageFrame.
     29
     30        * CMakeLists.txt:
     31        * WebCore.xcodeproj/project.pbxproj:
     32        Add and ImageFrameCache.cpp to the WebCore project.
     33
     34        * platform/graphics/BitmapImage.cpp:
     35        (WebCore::BitmapImage::BitmapImage): Move initializing the image metadata to
     36        ImageSource. Add initializers for the remaining members in the class declaration.
     37
     38        (WebCore::BitmapImage::destroyDecodedData): Move most of the logic of this
     39        function to ImageFrameCache::destroyDecodedData(). The only part which can't
     40        be moved is the call invalidatePlatformData().
     41
     42        (WebCore::BitmapImage::destroyDecodedDataIfNecessary): Move the logic of this
     43        function to ImageFrameCache::destroyDecodedDataIfNecessary().
     44
     45        (WebCore::BitmapImage::dataChanged): Move the logic of this function to
     46        ImageSource::dataChanged().
     47
     48        (WebCore::BitmapImage::frameImageAtIndex): Move most of the logic of this
     49        function to ImageFrameCache::frameImageAtIndex(). The only part which can't
     50        be moved is the call invalidatePlatformData() if the required subsampling
     51        level is different from the subsampling level for the cached frame image.
     52
     53        (WebCore::BitmapImage::draw): Replace the BitmapImage  cached metadata with
     54        the corresponding ImageSource cached metadata.
     55        (WebCore::BitmapImage::drawPattern): Ditto.
     56        (WebCore::BitmapImage::shouldAnimate): Ditto.
     57        (WebCore::BitmapImage::startAnimation): Ditto.
     58        (WebCore::BitmapImage::internalAdvanceAnimation): Ditto.
     59
     60        (WebCore::BitmapImage::dump): Call ImageSource::dump() to dump the image
     61        cached metadata.
     62
     63        (WebCore::BitmapImage::haveFrameImageAtIndex): Deleted.
     64        (WebCore::BitmapImage::destroyMetadataAndNotify): Deleted.
     65        (WebCore::BitmapImage::cacheFrame): Deleted.
     66        (WebCore::BitmapImage::didDecodeProperties): Deleted.
     67        (WebCore::BitmapImage::updateSize): Deleted.
     68        (WebCore::BitmapImage::size): Deleted.
     69        (WebCore::BitmapImage::sizeRespectingOrientation): Deleted.
     70        (WebCore::BitmapImage::hotSpot): Deleted.
     71        (WebCore::BitmapImage::frameCount): Deleted.
     72        (WebCore::BitmapImage::isSizeAvailable): Deleted.
     73        (WebCore::BitmapImage::ensureFrameAtIndexIsCached): Deleted.
     74        (WebCore::BitmapImage::frameIsCompleteAtIndex): Deleted.
     75        (WebCore::BitmapImage::frameDurationAtIndex): Deleted.
     76        (WebCore::BitmapImage::frameHasAlphaAtIndex): Deleted.
     77        (WebCore::BitmapImage::currentFrameKnownToBeOpaque): Deleted.
     78        (WebCore::BitmapImage::frameOrientationAtIndex): Deleted.
     79        (WebCore::BitmapImage::singlePixelSolidColor): Deleted.
     80        (WebCore::BitmapImage::repetitionCount): Deleted.
     81        * platform/graphics/BitmapImage.h:
     82        Managing the ImageFrames caching is moved to ImageFrameCache. Caching the
     83        image metadata is now moved to the ImageSource.
     84       
     85        * platform/graphics/GeneratedImage.h:
     86        * platform/graphics/Image.h:
     87        (WebCore::Image::orientationForCurrentFrame):
     88        (WebCore::Image::singlePixelSolidColor):
     89        Change currentFrameKnownToBeOpaque(), orientationForCurrentFrame() and
     90        singlePixelSolidColor() to be const.
     91       
     92        * platform/graphics/ImageFrame.cpp:
     93        (WebCore::ImageFrame::defaultFrame): Returns an empty ImageFrame to get the default ImageFrame metadata.
     94        (WebCore::ImageFrame::fillMetadata): Deleted. Moved to ImageFrameCache.
     95        (WebCore::ImageFrame::initialize): Deleted. Ditto.
     96       
     97        * platform/graphics/ImageFrame.h:
     98        (WebCore::ImageFrame::setDuration): Change the type of the argument to float instead of unsigned.
     99        (WebCore::ImageFrame::hasAlpha): Protect the unset m_hasAlpha by checking hasMetadata() first.
     100
     101        * platform/graphics/ImageFrameCache.cpp: Added.
     102        (WebCore::ImageFrameCache::ImageFrameCache): Two constructors similar to what we do for ImageSource and BitmapImage.
     103        (WebCore::ImageFrameCache::destroyDecodedData): Moved from BitmapImage.cpp.
     104        (WebCore::ImageFrameCache::destroyDecodedDataIfNecessary): Ditto.
     105        (WebCore::ImageFrameCache::destroyIncompleteDecodedData): Ditto.
     106        (WebCore::ImageFrameCache::decodedSizeChanged): Ditto.
     107        (WebCore::ImageFrameCache::decodedSizeIncremented): Ditto.
     108        (WebCore::ImageFrameCache::decodedSizeDecremented): Ditto.
     109        (WebCore::ImageFrameCache::decodedSizeReset): Ditto.
     110        (WebCore::ImageFrameCache::didDecodeProperties): Ditto.
     111        (WebCore::ImageFrameCache::growFrames): Grows the size of m_frames if necessary.
     112        (WebCore::ImageFrameCache::setNativeImage): Initializes the ImageFrame metadata directly from the NativeImagePtr.
     113        (WebCore::ImageFrameCache::setFrameNativeImage): Initializes the ImageFrame image and the metadata.
     114        (WebCore::ImageFrameCache::setFrameMetadata): Initializes the ImageFrame metadata from the ImageDecoder.
     115        (WebCore::ImageFrameCache::frameAtIndex): Returns an ImageFrame given its index. Cache or recache the requested ImageFrame if necessary.
     116        (WebCore::ImageFrameCache::clearMetadata): Invalidates the cached image metadata.
     117        (WebCore::ImageFrameCache::metadata): A template function which returns an image metadata property.
     118        (WebCore::ImageFrameCache::frameMetadataAtIndex): A template function which returns an ImageFrame metadata property.
     119        (WebCore::ImageFrameCache::isSizeAvailable): An image metadata property.
     120        (WebCore::ImageFrameCache::frameCount): Ditto.
     121        (WebCore::ImageFrameCache::repetitionCount): Ditto.
     122        (WebCore::ImageFrameCache::filenameExtension): Ditto.
     123        (WebCore::ImageFrameCache::hotSpot): Ditto.
     124        (WebCore::ImageFrameCache::size): An image metadata property but we get it from the first ImageFrame.
     125        (WebCore::ImageFrameCache::sizeRespectingOrientation): Ditto.
     126        (WebCore::ImageFrameCache::singlePixelSolidColor): Ditto.
     127        (WebCore::ImageFrameCache::frameIsCompleteAtIndex): An ImageFrame metadata property.
     128        (WebCore::ImageFrameCache::frameHasAlphaAtIndex): Ditto.
     129        (WebCore::ImageFrameCache::frameHasImageAtIndex): Ditto.
     130        (WebCore::ImageFrameCache::frameHasInvalidNativeImageAtIndex): Ditto.
     131        (WebCore::ImageFrameCache::frameSubsamplingLevelAtIndex): Ditto.
     132        (WebCore::ImageFrameCache::frameSizeAtIndex): Ditto.
     133        (WebCore::ImageFrameCache::frameBytesAtIndex): Ditto.
     134        (WebCore::ImageFrameCache::frameDurationAtIndex): Ditto.
     135        (WebCore::ImageFrameCache::frameOrientationAtIndex): Ditto.
     136        (WebCore::ImageFrameCache::frameImageAtIndex): Ditto.
     137
     138        * platform/graphics/ImageFrameCache.h: Added.
     139        (WebCore::ImageFrameCache::setDecoder): Sets the current ImageDecoder which is owned by the ImageSource.
     140        (WebCore::ImageFrameCache::decodedSize): Returns the size of the cached NativeImages.
     141        (WebCore::ImageFrameCache::isDecoderAvailable): Returns whether an ImageDecoder is available.
     142
     143        * platform/graphics/ImageSource.cpp:
     144        (WebCore::ImageSource::ImageSource): Initializes the ImageFrameCache based on the image decoding state.
     145        (WebCore::ImageSource::clearFrameBufferCache): Replace initialized() with isDecoderAvailable().
     146        (WebCore::ImageSource::clear): Clears the ImageDecoder of the ImageFrameCache.
     147        (WebCore::ImageSource::destroyDecodedData): Moved from BitmapImage.cpp.
     148        (WebCore::ImageSource::destroyDecodedDataIfNecessary): Ditto.
     149        (WebCore::ImageSource::ensureDecoderAvailable): Creates an ImageDecoder if necessary and sets it in ImageFrameCache.
     150        (WebCore::ImageSource::setData):
     151        (WebCore::ImageSource::dataChanged): Moved from BitmapImage.cpp.
     152        (WebCore::ImageSource::isAllDataReceived):
     153        (WebCore::ImageSource::maximumSubsamplingLevel): Rename calculateMaximumSubsamplingLevel() to maximumSubsamplingLevel().
     154        (WebCore::ImageSource::subsamplingLevelForScale):
     155        (WebCore::ImageSource::createFrameImageAtIndex):
     156        (WebCore::ImageSource::dump):
     157        (WebCore::ImageSource::calculateMaximumSubsamplingLevel): Deleted. Renamed to maximumSubsamplingLevel().
     158        (WebCore::ImageSource::updateMetadata): Deleted. Not needed. Caching the image metadata is the responsibility of ImageFrameCache.
     159        (WebCore::ImageSource::bytesDecodedToDetermineProperties): Deleted. Not needed.
     160        (WebCore::ImageSource::isSizeAvailable): Deleted. Moved to ImageSource.h.
     161        (WebCore::ImageSource::size): Deleted. Ditto.
     162        (WebCore::ImageSource::sizeRespectingOrientation): Deleted. Ditto.
     163        (WebCore::ImageSource::frameCount): Deleted. Ditto.
     164        (WebCore::ImageSource::repetitionCount): Deleted. Ditto.
     165        (WebCore::ImageSource::filenameExtension): Deleted. Ditto.
     166        (WebCore::ImageSource::hotSpot): Deleted. Ditto.
     167        (WebCore::ImageSource::frameIsCompleteAtIndex): Deleted. Ditto.
     168        (WebCore::ImageSource::frameHasAlphaAtIndex): Deleted. Ditto.
     169        (WebCore::ImageSource::frameAllowSubsamplingAtIndex): Deleted. Ditto.
     170        (WebCore::ImageSource::frameSizeAtIndex): Deleted. Ditto.
     171        (WebCore::ImageSource::frameBytesAtIndex): Deleted. Ditto.
     172        (WebCore::ImageSource::frameDurationAtIndex): Deleted. Ditto.
     173        (WebCore::ImageSource::frameOrientationAtIndex): Deleted. Ditto.
     174
     175        * platform/graphics/ImageSource.h:
     176        (WebCore::ImageSource::isDecoderAvailable): initialized() was renamed to isDecoderAvailable().
     177        (WebCore::ImageSource::decodedSize): Send the query to ImageFrameCache.
     178        (WebCore::ImageSource::isSizeAvailable): Ditto.
     179        (WebCore::ImageSource::frameCount): Ditto.
     180        (WebCore::ImageSource::repetitionCount): Ditto.
     181        (WebCore::ImageSource::filenameExtension): Ditto.
     182        (WebCore::ImageSource::hotSpot): Ditto.
     183        (WebCore::ImageSource::size): Ditto.
     184        (WebCore::ImageSource::sizeRespectingOrientation): Ditto.
     185        (WebCore::ImageSource::singlePixelSolidColor): Ditto.
     186        (WebCore::ImageSource::frameIsCompleteAtIndex): Ditto.
     187        (WebCore::ImageSource::frameHasAlphaAtIndex): Ditto.
     188        (WebCore::ImageSource::frameHasImageAtIndex): Ditto.
     189        (WebCore::ImageSource::frameHasInvalidNativeImageAtIndex): Ditto.
     190        (WebCore::ImageSource::frameSubsamplingLevelAtIndex): Ditto.
     191        (WebCore::ImageSource::frameSizeAtIndex): Ditto.
     192        (WebCore::ImageSource::frameBytesAtIndex): Ditto.
     193        (WebCore::ImageSource::frameDurationAtIndex): Ditto.
     194        (WebCore::ImageSource::frameOrientationAtIndex): Ditto.
     195        (WebCore::ImageSource::frameImageAtIndex): Ditto.
     196        (WebCore::ImageSource::decoder): Deleted. Not needed.
     197        (WebCore::ImageSource::initialized): Deleted. Was renamed to isDecoderAvailable().
     198        (WebCore::ImageSource::setNeedsUpdateMetadata): Deleted. Not needed.
     199
     200        * platform/graphics/cairo/GraphicsContext3DCairo.cpp:
     201        (WebCore::GraphicsContext3D::ImageExtractor::extractImage): AlphaOption and GammaAndColorProfileOption are moved out of ImageSource.
     202        * platform/graphics/cg/GraphicsContext3DCG.cpp:
     203        (WebCore::GraphicsContext3D::ImageExtractor::extractImage): Ditto.
     204       
     205        * platform/graphics/cg/ImageDecoderCG.cpp:
     206        (WebCore::ImageDecoder::ImageDecoder): Make the constructor of ImageDecoder be the same for all ports.
     207        (WebCore::ImageDecoder::setData): Removed unused overloaded function.
     208        (WebCore::ImageDecoder::size): Deleted.  Removed unused function.
     209
     210        * platform/graphics/cg/ImageDecoderCG.h:
     211        (WebCore::ImageDecoder::create): Make the constructor of CG ImageDecoder be like the other ports.
     212        (WebCore::ImageDecoder::isAllDataReceived): Make this property owned by ImageDecoder.
     213
     214        * platform/graphics/cg/PDFDocumentImage.h: Change currentFrameKnownToBeOpaque() to be const.
     215
     216        * platform/graphics/efl/GraphicsContext3DEfl.cpp:
     217        (WebCore::GraphicsContext3D::ImageExtractor::extractImage): AlphaOption and GammaAndColorProfileOption are moved out of ImageSource.
     218       
     219        * platform/graphics/mac/ImageMac.mm:
     220        (WebCore::BitmapImage::invalidatePlatformData): m_frames is owned by ImageFrameCache. ImageFrameCache::frameCount() has to
     221        be equal to ImageFrame::m_frames.size().
     222
     223        * platform/image-decoders/ImageDecoder.cpp:
     224        (WebCore::ImageDecoder::create): AlphaOption and GammaAndColorProfileOption are moved out of ImageSource.
     225        * platform/image-decoders/ImageDecoder.h:
     226        (WebCore::ImageDecoder::ImageDecoder): Ditto.
     227        (WebCore::ImageDecoder::frameCount): Make frameCount const so it can be passed to the template function ImageFrameCache::metadata().
     228        * platform/image-decoders/bmp/BMPImageDecoder.cpp:
     229        (WebCore::BMPImageDecoder::BMPImageDecoder): AlphaOption and GammaAndColorProfileOption are moved out of ImageSource.
     230        * platform/image-decoders/bmp/BMPImageDecoder.h:
     231        * platform/image-decoders/gif/GIFImageDecoder.cpp:
     232        (WebCore::GIFImageDecoder::GIFImageDecoder): AlphaOption and GammaAndColorProfileOption are moved out of ImageSource.
     233        (WebCore::GIFImageDecoder::frameCount): Make frameCount const so it can be passed to the template function ImageFrameCache::metadata().
     234        * platform/image-decoders/gif/GIFImageDecoder.h:
     235        * platform/image-decoders/gif/GIFImageReader.cpp:
     236        * platform/image-decoders/gif/GIFImageReader.h:
     237        * platform/image-decoders/ico/ICOImageDecoder.cpp:
     238        (WebCore::ICOImageDecoder::ICOImageDecoder):
     239        (WebCore::ICOImageDecoder::frameCount): Make frameCount const so it can be passed to the template function ImageFrameCache::metadata().
     240        (WebCore::ICOImageDecoder::decode): Move resizing the m_frameBufferCache from ICOImageDecoder::frameCount() to ICOImageDecoder::decode().
     241        (WebCore::ICOImageDecoder::decodeAtIndex): AlphaOption and GammaAndColorProfileOption are moved out of ImageSource.
     242        * platform/image-decoders/ico/ICOImageDecoder.h:
     243        * platform/image-decoders/jpeg/JPEGImageDecoder.cpp:
     244        (WebCore::JPEGImageDecoder::JPEGImageDecoder): AlphaOption and GammaAndColorProfileOption are moved out of ImageSource.
     245        * platform/image-decoders/jpeg/JPEGImageDecoder.h:
     246        * platform/image-decoders/png/PNGImageDecoder.cpp:
     247        (WebCore::PNGImageDecoder::PNGImageDecoder): AlphaOption and GammaAndColorProfileOption are moved out of ImageSource.
     248        * platform/image-decoders/png/PNGImageDecoder.h:
     249        (WebCore::PNGImageDecoder::frameCount): Make frameCount const so it can be passed to the template function ImageFrameCache::metadata().
     250        * platform/image-decoders/webp/WEBPImageDecoder.cpp:
     251        (WebCore::WEBPImageDecoder::WEBPImageDecoder):
     252        * platform/image-decoders/webp/WEBPImageDecoder.h:
     253
     254        * svg/graphics/SVGImage.h: Make currentFrameKnownToBeOpaque() be const.
     255        * svg/graphics/SVGImageForContainer.h: Ditto.
     256
    12572016-09-27  Alex Christensen  <achristensen@webkit.org>
    2258
  • trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj

    r206440 r206481  
    22722272                5576A5641D88A70800CCC04C /* ImageFrame.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5576A5621D88A70800CCC04C /* ImageFrame.cpp */; };
    22732273                5576A5651D88A70800CCC04C /* ImageFrame.h in Headers */ = {isa = PBXBuildFile; fileRef = 5576A5631D88A70800CCC04C /* ImageFrame.h */; settings = {ATTRIBUTES = (Private, ); }; };
     2274                5597F8261D91C3130066BC21 /* ImageFrameCache.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5597F8241D91C3130066BC21 /* ImageFrameCache.cpp */; };
     2275                5597F8271D91C3130066BC21 /* ImageFrameCache.h in Headers */ = {isa = PBXBuildFile; fileRef = 5597F8251D91C3130066BC21 /* ImageFrameCache.h */; settings = {ATTRIBUTES = (Private, ); }; };
    22742276                55A336F71D8209F40022C4C7 /* NativeImage.h in Headers */ = {isa = PBXBuildFile; fileRef = 55A336F61D8209F40022C4C7 /* NativeImage.h */; };
    22752277                55A336F91D821E3C0022C4C7 /* ImageBackingStore.h in Headers */ = {isa = PBXBuildFile; fileRef = 55A336F81D821E3C0022C4C7 /* ImageBackingStore.h */; settings = {ATTRIBUTES = (Private, ); }; };
     
    93019303                5576A5621D88A70800CCC04C /* ImageFrame.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ImageFrame.cpp; sourceTree = "<group>"; };
    93029304                5576A5631D88A70800CCC04C /* ImageFrame.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ImageFrame.h; sourceTree = "<group>"; };
     9305                5597F8241D91C3130066BC21 /* ImageFrameCache.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ImageFrameCache.cpp; sourceTree = "<group>"; };
     9306                5597F8251D91C3130066BC21 /* ImageFrameCache.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ImageFrameCache.h; sourceTree = "<group>"; };
    93039307                55A336F61D8209F40022C4C7 /* NativeImage.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = NativeImage.h; sourceTree = "<group>"; };
    93049308                55A336F81D821E3C0022C4C7 /* ImageBackingStore.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ImageBackingStore.h; sourceTree = "<group>"; };
     
    2071920723                                5576A5621D88A70800CCC04C /* ImageFrame.cpp */,
    2072020724                                5576A5631D88A70800CCC04C /* ImageFrame.h */,
     20725                                5597F8241D91C3130066BC21 /* ImageFrameCache.cpp */,
     20726                                5597F8251D91C3130066BC21 /* ImageFrameCache.h */,
    2072120727                                BC7F44A70B9E324E00A9D081 /* ImageObserver.h */,
    2072220728                                A8748D7412CC3F89001FBA41 /* ImageOrientation.cpp */,
     
    2449624502                                B275356B0B053814002CE64F /* FloatRect.h in Headers */,
    2449724503                                6E0E569C183BFFE600E0E8D5 /* FloatRoundedRect.h in Headers */,
     24504                                5597F8271D91C3130066BC21 /* ImageFrameCache.h in Headers */,
    2449824505                                B275356D0B053814002CE64F /* FloatSize.h in Headers */,
    2449924506                                58CD35CB18EB4C3900B9F3AC /* FloatSizeHash.h in Headers */,
     
    2761827625                                E461D65D1BB0C7F000CB5645 /* AuthorStyleSheets.cpp in Sources */,
    2761927626                                A5F6E16B132ED46E008EDAE3 /* Autocapitalize.cpp in Sources */,
     27627                                5597F8261D91C3130066BC21 /* ImageFrameCache.cpp in Sources */,
    2762027628                                7C1843FD1C8B7283002EB973 /* Autofill.cpp in Sources */,
    2762127629                                7C1E97271A9F9834007BF0FB /* AutoFillButtonElement.cpp in Sources */,
  • trunk/Source/WebCore/platform/graphics/BitmapImage.cpp

    r206419 r206481  
    2222 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
    2323 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
    24  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
     24 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    2525 */
    2626
     
    4949BitmapImage::BitmapImage(ImageObserver* observer)
    5050    : Image(observer)
    51     , m_animationFinished(false)
    52     , m_allDataReceived(false)
    53     , m_haveSize(false)
    54     , m_sizeAvailable(false)
    55     , m_haveFrameCount(false)
    56     , m_animationFinishedWhenCatchingUp(false)
     51    , m_source(this)
    5752{
    5853}
     
    6055BitmapImage::BitmapImage(NativeImagePtr&& image, ImageObserver* observer)
    6156    : Image(observer)
    62     , m_source(image)
    63     , m_frameCount(1)
    64     , m_animationFinished(true)
    65     , m_allDataReceived(true)
    66     , m_haveSize(true)
    67     , m_sizeAvailable(true)
    68     , m_haveFrameCount(true)
    69     , m_animationFinishedWhenCatchingUp(false)
    70 {
    71     m_frames.grow(1);
    72     m_frames[0].initialize(WTFMove(image));
    73 
    74     m_size = m_frames[0].size();
    75     m_sizeRespectingOrientation = m_size;
    76     m_decodedSize = m_size.area() * 4;
     57    , m_source(WTFMove(image))
     58{
    7759}
    7860
     
    8365}
    8466
    85 bool BitmapImage::haveFrameImageAtIndex(size_t index)
    86 {
    87     if (index >= frameCount())
    88         return false;
    89 
    90     if (index >= m_frames.size())
    91         return false;
    92 
    93     return m_frames[index].hasNativeImage();
    94 }
    95 
    9667void BitmapImage::destroyDecodedData(bool destroyAll)
    9768{
    98     unsigned frameBytesCleared = 0;
    99     const size_t clearBeforeFrame = destroyAll ? m_frames.size() : m_currentFrame;
    100 
    101     // Because we can advance frames without always needing to decode the actual
    102     // bitmap data, |m_currentFrame| may be larger than m_frames.size();
    103     // make sure not to walk off the end of the container in this case.
    104     for (size_t i = 0; i <  std::min(clearBeforeFrame, m_frames.size()); ++i) {
    105         // The underlying frame isn't actually changing (we're just trying to
    106         // save the memory for the framebuffer data), so we don't need to clear
    107         // the metadata.
    108         frameBytesCleared += m_frames[i].clearImage();
    109     }
    110 
    111     m_source.clear(destroyAll, clearBeforeFrame, data(), m_allDataReceived);
    112     destroyMetadataAndNotify(frameBytesCleared, ClearedSource::Yes);
     69    m_source.destroyDecodedData(data(), destroyAll, m_currentFrame);
     70    invalidatePlatformData();
    11371}
    11472
    11573void BitmapImage::destroyDecodedDataIfNecessary(bool destroyAll)
    11674{
    117     // Animated images over a certain size are considered large enough that we'll only hang on
    118     // to one frame at a time.
    119 #if PLATFORM(IOS)
    120     const unsigned largeAnimationCutoff = 2097152;
    121 #else
    122     const unsigned largeAnimationCutoff = 5242880;
    123 #endif
    124 
    125     // If we have decoded frames but there is no encoded data, we shouldn't destroy
    126     // the decoded image since we won't be able to reconstruct it later.
    127     if (!data() && m_frames.size())
    128         return;
    129 
    130     unsigned allFrameBytes = 0;
    131     for (auto& frame : m_frames)
    132         allFrameBytes += frame.frameBytes();
    133 
    134     if (allFrameBytes > largeAnimationCutoff) {
    135         LOG(Images, "BitmapImage %p destroyDecodedDataIfNecessary destroyingData: allFrameBytes=%u cutoff=%u", this, allFrameBytes, largeAnimationCutoff);
    136         destroyDecodedData(destroyAll);
    137     }
    138 }
    139 
    140 void BitmapImage::destroyMetadataAndNotify(unsigned frameBytesCleared, ClearedSource clearedSource)
    141 {
    142     m_solidColor = Nullopt;
    143     invalidatePlatformData();
    144 
    145     ASSERT(m_decodedSize >= frameBytesCleared);
    146     m_decodedSize -= frameBytesCleared;
    147 
    148     // Clearing the ImageSource destroys the extra decoded data used for determining image properties.
    149     if (clearedSource == ClearedSource::Yes) {
    150         frameBytesCleared += m_decodedPropertiesSize;
    151         m_decodedPropertiesSize = 0;
    152     }
    153 
    154     if (frameBytesCleared && imageObserver())
    155         imageObserver()->decodedSizeChanged(this, -safeCast<int>(frameBytesCleared));
    156 }
    157 
    158 void BitmapImage::cacheFrame(size_t index, SubsamplingLevel subsamplingLevel, ImageFrame::Caching caching)
    159 {
    160     size_t numFrames = frameCount();
    161     ASSERT(m_decodedSize == 0 || numFrames > 1);
    162    
    163     if (m_frames.size() < numFrames)
    164         m_frames.grow(numFrames);
    165 
    166     if (caching == ImageFrame::Caching::MetadataAndImage) {
    167         NativeImagePtr image = m_source.createFrameImageAtIndex(index, subsamplingLevel);
    168         m_frames[index].initialize(WTFMove(image), *m_source.decoder(), index, subsamplingLevel, repetitionCount(false));
    169     } else
    170         m_frames[index].initialize(nullptr, *m_source.decoder(), index, subsamplingLevel, repetitionCount(false));
    171 
    172     LOG(Images, "BitmapImage %p cacheFrame %lu (%s%u bytes, complete %d)", this, index, caching == ImageFrame::Caching::Metadata ? "metadata only, " : "", m_frames[index].frameBytes(), m_frames[index].isComplete());
    173 
    174     if (m_frames[index].hasNativeImage()) {
    175         int deltaBytes = safeCast<int>(m_frames[index].frameBytes());
    176         m_decodedSize += deltaBytes;
    177         // The fully-decoded frame will subsume the partially decoded data used
    178         // to determine image properties.
    179         deltaBytes -= m_decodedPropertiesSize;
    180         m_decodedPropertiesSize = 0;
    181         if (imageObserver())
    182             imageObserver()->decodedSizeChanged(this, deltaBytes);
    183     }
    184 }
    185 
    186 void BitmapImage::didDecodeProperties() const
    187 {
    188     if (m_decodedSize)
    189         return;
    190 
    191     size_t updatedSize = m_source.bytesDecodedToDetermineProperties();
    192     if (m_decodedPropertiesSize == updatedSize)
    193         return;
    194 
    195     int deltaBytes = updatedSize - m_decodedPropertiesSize;
    196 #if !ASSERT_DISABLED
    197     bool overflow = updatedSize > m_decodedPropertiesSize && deltaBytes < 0;
    198     bool underflow = updatedSize < m_decodedPropertiesSize && deltaBytes > 0;
    199     ASSERT(!overflow && !underflow);
    200 #endif
    201     m_decodedPropertiesSize = updatedSize;
    202     if (imageObserver())
    203         imageObserver()->decodedSizeChanged(this, deltaBytes);
    204 }
    205 
    206 void BitmapImage::updateSize() const
    207 {
    208     if (!m_sizeAvailable || m_haveSize)
    209         return;
    210 
    211     m_size = m_source.size();
    212     m_sizeRespectingOrientation = m_source.sizeRespectingOrientation();
    213 
    214     m_haveSize = true;
    215     didDecodeProperties();
    216 }
    217 
    218 FloatSize BitmapImage::size() const
    219 {
    220     updateSize();
    221     return m_size;
    222 }
    223 
    224 IntSize BitmapImage::sizeRespectingOrientation() const
    225 {
    226     updateSize();
    227     return m_sizeRespectingOrientation;
    228 }
    229 
    230 Optional<IntPoint> BitmapImage::hotSpot() const
    231 {
    232     auto result = m_source.hotSpot();
    233     didDecodeProperties();
    234     return result;
     75    m_source.destroyDecodedDataIfNecessary(data(), destroyAll, m_currentFrame);
    23576}
    23677
    23778bool BitmapImage::dataChanged(bool allDataReceived)
    23879{
    239     // Because we're modifying the current frame, clear its (now possibly
    240     // inaccurate) metadata as well.
    241 #if !PLATFORM(IOS)
    242     // Clear all partially-decoded frames. For most image formats, there is only
    243     // one frame, but at least GIF and ICO can have more. With GIFs, the frames
    244     // come in order and we ask to decode them in order, waiting to request a
    245     // subsequent frame until the prior one is complete. Given that we clear
    246     // incomplete frames here, this means there is at most one incomplete frame
    247     // (even if we use destroyDecodedData() -- since it doesn't reset the
    248     // metadata), and it is after all the complete frames.
    249     //
    250     // With ICOs, on the other hand, we may ask for arbitrary frames at
    251     // different times (e.g. because we're displaying a higher-resolution image
    252     // in the content area and using a lower-resolution one for the favicon),
    253     // and the frames aren't even guaranteed to appear in the file in the same
    254     // order as in the directory, so an arbitrary number of the frames might be
    255     // incomplete (if we ask for frames for which we've not yet reached the
    256     // start of the frame data), and any or none of them might be the particular
    257     // frame affected by appending new data here. Thus we have to clear all the
    258     // incomplete frames to be safe.
    259     unsigned frameBytesCleared = 0;
    260     for (auto& frame : m_frames) {
    261         // NOTE: Don't call frameIsCompleteAtIndex() here, that will try to
    262         // decode any uncached (i.e. never-decoded or
    263         // cleared-on-a-previous-pass) frames!
    264         if (frame.hasMetadata() && !frame.isComplete())
    265             frameBytesCleared += frame.clear();
    266     }
    267     destroyMetadataAndNotify(frameBytesCleared, ClearedSource::No);
    268 #else
    269     // FIXME: why is this different for iOS?
    270     int deltaBytes = 0;
    271     if (!m_frames.isEmpty()) {
    272         if (int bytes = m_frames[m_frames.size() - 1].clear()) {
    273             deltaBytes += bytes;
    274             deltaBytes += m_decodedPropertiesSize;
    275             m_decodedPropertiesSize = 0;
    276         }
    277     }
    278     destroyMetadataAndNotify(deltaBytes, ClearedSource::No);
    279 #endif
    280    
    281     // Feed all the data we've seen so far to the image decoder.
    282     m_allDataReceived = allDataReceived;
    283 #if PLATFORM(IOS)
    284     // FIXME: We should expose a setting to enable/disable progressive loading and make this
    285     // code conditional on it. Then we can remove the PLATFORM(IOS)-guard.
    286     static const double chunkLoadIntervals[] = {0, 1, 3, 6, 15};
    287     double interval = chunkLoadIntervals[std::min(m_progressiveLoadChunkCount, static_cast<uint16_t>(4))];
    288 
    289     bool needsUpdate = false;
    290     if (currentTime() - m_progressiveLoadChunkTime > interval) { // The first time through, the chunk time will be 0 and the image will get an update.
    291         needsUpdate = true;
    292         m_progressiveLoadChunkTime = currentTime();
    293         ASSERT(m_progressiveLoadChunkCount <= std::numeric_limits<uint16_t>::max());
    294         ++m_progressiveLoadChunkCount;
    295     }
    296     if (needsUpdate || allDataReceived)
    297         m_source.setData(data(), allDataReceived);
    298 #else
    299     m_source.setData(data(), allDataReceived);
    300 #endif
    301 
    302     m_haveFrameCount = false;
    303     m_source.setNeedsUpdateMetadata();
    304     return isSizeAvailable();
    305 }
    306 
    307 size_t BitmapImage::frameCount()
    308 {
    309     if (!m_haveFrameCount) {
    310         m_frameCount = m_source.frameCount();
    311         // If decoder is not initialized yet, m_source.frameCount() returns 0.
    312         if (m_frameCount) {
    313             didDecodeProperties();
    314             m_haveFrameCount = true;
    315         }
    316     }
    317     return m_frameCount;
    318 }
    319 
    320 bool BitmapImage::isSizeAvailable()
    321 {
    322     if (m_sizeAvailable)
    323         return true;
    324 
    325     m_sizeAvailable = m_source.isSizeAvailable();
    326     didDecodeProperties();
    327 
    328     return m_sizeAvailable;
    329 }
    330 
    331 bool BitmapImage::ensureFrameAtIndexIsCached(size_t index, ImageFrame::Caching caching)
    332 {
    333     if (index >= frameCount())
    334         return false;
    335 
    336     if (index >= m_frames.size()
    337         || (caching == ImageFrame::Caching::MetadataAndImage && !m_frames[index].hasNativeImage())
    338         || (caching == ImageFrame::Caching::Metadata && !m_frames[index].hasMetadata()))
    339         cacheFrame(index, SubsamplingLevel::Default, caching);
    340 
    341     return true;
    342 }
    343 
    344 NativeImagePtr BitmapImage::frameImageAtIndex(size_t index, float presentationScaleHint)
    345 {
    346     if (index >= frameCount())
    347         return nullptr;
    348 
    349     SubsamplingLevel subsamplingLevel = m_source.subsamplingLevelForScale(presentationScaleHint);
    350    
    351     LOG(Images, "BitmapImage %p frameImageAtIndex - subsamplingLevel %d at scale %.4f", this, static_cast<int>(subsamplingLevel), presentationScaleHint);
    352 
    353     // We may have cached a frame with a higher subsampling level, in which case we need to
    354     // re-decode with a lower level.
    355     if (index < m_frames.size() && m_frames[index].hasInvalidNativeImage(subsamplingLevel)) {
    356         LOG(Images, "  subsamplingLevel was %d, resampling", static_cast<int>(m_frames[index].subsamplingLevel()));
    357 
    358         // If the image is already cached, but at too small a size, re-decode a larger version.
    359         int sizeChange = -m_frames[index].clear();
     80    return m_source.dataChanged(data(), allDataReceived);
     81}
     82
     83NativeImagePtr BitmapImage::frameImageAtIndex(size_t index, SubsamplingLevel subsamplingLevel)
     84{
     85    if (frameHasInvalidNativeImageAtIndex(index, subsamplingLevel)) {
     86        LOG(Images, "BitmapImage %p frameImageAtIndex - subsamplingLevel was %d, resampling", this, static_cast<int>(frameSubsamplingLevelAtIndex(index)));
    36087        invalidatePlatformData();
    361         m_decodedSize += sizeChange;
    362         if (imageObserver())
    363             imageObserver()->decodedSizeChanged(this, sizeChange);
    364     }
    365 
    366     // If we haven't fetched a frame yet, do so.
    367     if (index >= m_frames.size() || !m_frames[index].hasNativeImage())
    368         cacheFrame(index, subsamplingLevel, ImageFrame::Caching::MetadataAndImage);
    369 
    370     return m_frames[index].nativeImage();
    371 }
    372    
     88    }
     89
     90    return m_source.frameImageAtIndex(index, subsamplingLevel);
     91}
     92
    37393NativeImagePtr BitmapImage::nativeImage()
    37494{
     
    380100    return frameImageAtIndex(m_currentFrame);
    381101}
    382    
     102
    383103#if USE(CG)
    384104NativeImagePtr BitmapImage::nativeImageOfSize(const IntSize& size)
    385105{
    386106    size_t count = frameCount();
    387    
     107
    388108    for (size_t i = 0; i < count; ++i) {
    389109        auto image = frameImageAtIndex(i);
     
    391111            return image;
    392112    }
    393    
     113
    394114    // Fallback to the first frame image if we can't find the right size
    395115    return frameImageAtIndex(0);
    396116}
    397    
     117
    398118Vector<NativeImagePtr> BitmapImage::framesNativeImages()
    399119{
    400120    Vector<NativeImagePtr> images;
    401121    size_t count = frameCount();
    402    
     122
    403123    for (size_t i = 0; i < count; ++i) {
    404124        if (auto image = frameImageAtIndex(i))
    405125            images.append(image);
    406126    }
    407    
     127
    408128    return images;
    409129}
    410130#endif
    411 
    412 bool BitmapImage::frameIsCompleteAtIndex(size_t index)
    413 {
    414     if (!ensureFrameAtIndexIsCached(index, ImageFrame::Caching::Metadata))
    415         return false;
    416 
    417     return m_frames[index].isComplete();
    418 }
    419 
    420 float BitmapImage::frameDurationAtIndex(size_t index)
    421 {
    422     if (!ensureFrameAtIndexIsCached(index, ImageFrame::Caching::Metadata))
    423         return 0;
    424 
    425     return m_frames[index].duration();
    426 }
    427 
    428 bool BitmapImage::frameHasAlphaAtIndex(size_t index)
    429 {
    430     if (!ensureFrameAtIndexIsCached(index, ImageFrame::Caching::Metadata))
    431         return true;
    432 
    433     if (m_frames[index].hasMetadata())
    434         return m_frames[index].hasAlpha();
    435 
    436     return m_source.frameHasAlphaAtIndex(index);
    437 }
    438 
    439 bool BitmapImage::currentFrameKnownToBeOpaque()
    440 {
    441     return !frameHasAlphaAtIndex(currentFrame());
    442 }
    443 
    444 ImageOrientation BitmapImage::frameOrientationAtIndex(size_t index)
    445 {
    446     if (!ensureFrameAtIndexIsCached(index, ImageFrame::Caching::Metadata))
    447         return ImageOrientation();
    448 
    449     if (m_frames[index].hasMetadata())
    450         return m_frames[index].orientation();
    451 
    452     return m_source.frameOrientationAtIndex(index);
    453 }
    454 
    455 Color BitmapImage::singlePixelSolidColor()
    456 {
    457     // If the image size is not available yet or if the image will be animating don't use the solid color optimization.
    458     if (frameCount() != 1)
    459         return Color();
    460 
    461     if (m_solidColor)
    462         return m_solidColor.value();
    463 
    464     // If the frame image is not loaded, first use the decoder to get the size of the image.
    465     if (!haveFrameImageAtIndex(0) && m_source.frameSizeAtIndex(0) != IntSize(1, 1)) {
    466         m_solidColor = Color();
    467         return m_solidColor.value();
    468     }
    469 
    470     // Cache the frame image. The size will be calculated from the NativeImagePtr.
    471     if (!ensureFrameAtIndexIsCached(0))
    472         return Color();
    473 
    474     ASSERT(m_frames.size());
    475     m_solidColor = nativeImageSinglePixelSolidColor(m_frames[0].nativeImage());
    476    
    477     ASSERT(m_solidColor);
    478     return m_solidColor.value();
    479 }
    480131
    481132#if !ASSERT_DISABLED
     
    485136}
    486137#endif
    487 
    488 RepetitionCount BitmapImage::repetitionCount(bool imageKnownToBeComplete)
    489 {
    490     if ((m_repetitionCountStatus == Unknown) || ((m_repetitionCountStatus == Uncertain) && imageKnownToBeComplete)) {
    491         // Snag the repetition count. If |imageKnownToBeComplete| is false, the
    492         // repetition count may not be accurate yet for GIFs; in this case the
    493         // decoder will default to RepetitionCountOnce, and we'll try and read
    494         // the count again once the whole image is decoded.
    495         m_repetitionCount = m_source.repetitionCount();
    496         didDecodeProperties();
    497         m_repetitionCountStatus = (imageKnownToBeComplete || m_repetitionCount == RepetitionCountNone) ? Certain : Uncertain;
    498     }
    499     return m_repetitionCount;
    500 }
    501138
    502139void BitmapImage::draw(GraphicsContext& context, const FloatRect& destRect, const FloatRect& srcRect, CompositeOperator op, BlendMode mode, ImageOrientationDescription description)
     
    517154    }
    518155
    519     auto image = frameImageAtIndex(m_currentFrame, subsamplingScale(context, destRect, srcRect));
     156    float scale = subsamplingScale(context, destRect, srcRect);
     157    SubsamplingLevel subsamplingLevel = m_source.subsamplingLevelForScale(scale);
     158    LOG(Images, "BitmapImage %p draw - subsamplingLevel %d at scale %.4f", this, subsamplingLevel, scale);
     159
     160    auto image = frameImageAtIndex(m_currentFrame, subsamplingLevel);
    520161    if (!image) // If it's too early we won't have an image yet.
    521162        return;
     
    525166        orientation = frameOrientationAtIndex(m_currentFrame);
    526167
    527     drawNativeImage(image, context, destRect, srcRect, m_size, op, mode, orientation);
     168    drawNativeImage(image, context, destRect, srcRect, IntSize(size()), op, mode, orientation);
    528169
    529170    if (imageObserver())
    530171        imageObserver()->didDraw(this);
    531172}
    532    
     173
    533174void BitmapImage::drawPattern(GraphicsContext& ctxt, const FloatRect& tileRect, const AffineTransform& transform, const FloatPoint& phase, const FloatSize& spacing, CompositeOperator op, const FloatRect& destRect, BlendMode blendMode)
    534175{
     
    560201            return;
    561202    }
    562    
     203
    563204    ctxt.setDrawLuminanceMask(false);
    564205    m_cachedImage->drawPattern(ctxt, tileRect, transform, phase, spacing, op, destRect, blendMode);
     
    567208bool BitmapImage::shouldAnimate()
    568209{
    569     return repetitionCount(false) && !m_animationFinished && imageObserver();
     210    return repetitionCount() && !m_animationFinished && imageObserver();
    570211}
    571212
     
    599240    // Don't advance the animation to an incomplete frame.
    600241    size_t nextFrame = (m_currentFrame + 1) % frameCount();
    601     if (!m_allDataReceived && !frameIsCompleteAtIndex(nextFrame))
     242    if (!m_source.isAllDataReceived() && !frameIsCompleteAtIndex(nextFrame))
    602243        return;
    603244
     
    606247    // in a GIF can potentially come after all the rest of the image data, so
    607248    // wait on it.
    608     if (!m_allDataReceived && repetitionCount(false) == RepetitionCountOnce && m_currentFrame >= (frameCount() - 1))
     249    if (!m_source.isAllDataReceived() && repetitionCount() == RepetitionCountOnce && m_currentFrame >= (frameCount() - 1))
    609250        return;
    610251
     
    657298    size_t startCatchupFrameIndex = nextFrame;
    658299#endif
    659    
     300
    660301    for (size_t frameAfterNext = (nextFrame + 1) % frameCount(); frameIsCompleteAtIndex(frameAfterNext); frameAfterNext = (nextFrame + 1) % frameCount()) {
    661302        // Should we skip the next frame?
     
    701342        return false;
    702343    }
    703    
     344
    704345    ++m_currentFrame;
    705346    bool advancedAnimation = true;
     
    711352        // repetition count before, we should have decoded the whole image by
    712353        // now, so it should now be available.
    713         if (repetitionCount(true) != RepetitionCountInfinite && m_repetitionsComplete > m_repetitionCount) {
     354        if (repetitionCount() != RepetitionCountInfinite && m_repetitionsComplete > repetitionCount()) {
    714355            m_animationFinished = true;
    715356            m_desiredFrameStartTime = 0;
     
    753394{
    754395    Image::dump(ts);
    755 
    756     ts.dumpProperty("type", m_source.filenameExtension());
    757 
    758     if (isAnimated()) {
    759         ts.dumpProperty("frame-count", m_frameCount);
    760         ts.dumpProperty("repetitions", m_repetitionCount);
     396   
     397    if (isAnimated())
    761398        ts.dumpProperty("current-frame", m_currentFrame);
    762     }
    763    
    764     if (m_solidColor)
    765         ts.dumpProperty("solid-color", m_solidColor.value());
    766399   
    767400    m_source.dump(ts);
  • trunk/Source/WebCore/platform/graphics/BitmapImage.h

    r206156 r206481  
    2626 */
    2727
    28 #ifndef BitmapImage_h
    29 #define BitmapImage_h
     28#pragma once
    3029
    3130#include "Image.h"
     
    6867    bool hasSingleSecurityOrigin() const override { return true; }
    6968
     69    bool dataChanged(bool allDataReceived) override;
     70    unsigned decodedSize() const { return m_source.decodedSize(); }
     71
     72    bool isSizeAvailable() const { return m_source.isSizeAvailable(); }
     73    size_t frameCount() const { return m_source.frameCount(); }
     74    RepetitionCount repetitionCount() const { return m_source.repetitionCount(); }
     75    String filenameExtension() const override { return m_source.filenameExtension(); }
     76    Optional<IntPoint> hotSpot() const override { return m_source.hotSpot(); }
     77
    7078    // FloatSize due to override.
    71     FloatSize size() const override;
    72     IntSize sizeRespectingOrientation() const;
    73 
    74     Optional<IntPoint> hotSpot() const override;
    75 
    76     unsigned decodedSize() const { return m_decodedSize; }
    77 
    78     bool dataChanged(bool allDataReceived) override;
    79     String filenameExtension() const override { return m_source.filenameExtension(); }
    80 
    81     // It may look unusual that there is no start animation call as public API. This is because
    82     // we start and stop animating lazily. Animation begins whenever someone draws the image. It will
    83     // automatically pause once all observers no longer want to render the image anywhere.
    84     void stopAnimation() override;
    85     void resetAnimation() override;
    86 
    87     void drawPattern(GraphicsContext&, const FloatRect& srcRect, const AffineTransform& patternTransform,
    88         const FloatPoint& phase, const FloatSize& spacing, CompositeOperator, const FloatRect& destRect, BlendMode = BlendModeNormal) override;
     79    FloatSize size() const override { return m_source.size(); }
     80    IntSize sizeRespectingOrientation() const { return m_source.sizeRespectingOrientation(); }
     81    Color singlePixelSolidColor() const override { return m_source.singlePixelSolidColor(); }
     82
     83    void setAllowSubsampling(bool allowSubsampling) { m_source.setAllowSubsampling(allowSubsampling); }
     84
     85    bool frameIsCompleteAtIndex(size_t index) const { return m_source.frameIsCompleteAtIndex(index); }
     86    bool frameHasAlphaAtIndex(size_t index) const { return m_source.frameHasAlphaAtIndex(index); }
     87    bool frameHasInvalidNativeImageAtIndex(size_t index, SubsamplingLevel subsamplingLevel) const { return m_source.frameHasInvalidNativeImageAtIndex(index, subsamplingLevel); }
     88    SubsamplingLevel frameSubsamplingLevelAtIndex(size_t index) const { return m_source.frameSubsamplingLevelAtIndex(index); }
     89
     90    float frameDurationAtIndex(size_t index) const { return m_source.frameDurationAtIndex(index); }
     91    ImageOrientation frameOrientationAtIndex(size_t index) const { return m_source.frameOrientationAtIndex(index); }
     92
     93    size_t currentFrame() const { return m_currentFrame; }
     94    bool currentFrameKnownToBeOpaque() const override { return !frameHasAlphaAtIndex(currentFrame()); }
     95    ImageOrientation orientationForCurrentFrame() const override { return frameOrientationAtIndex(currentFrame()); }
    8996
    9097    // Accessors for native image formats.
    91 
    9298#if USE(APPKIT)
    9399    NSImage* getNSImage() override;
     
    117123    Vector<NativeImagePtr> framesNativeImages() override;
    118124#endif
    119     ImageOrientation orientationForCurrentFrame() override { return frameOrientationAtIndex(currentFrame()); }
    120 
    121     bool currentFrameKnownToBeOpaque() override;
    122 
    123     bool isAnimated() const override { return m_frameCount > 1; }
    124    
    125     bool canAnimate();
    126 
    127     void setAllowSubsampling(bool allowSubsampling) { m_source.setAllowSubsampling(allowSubsampling); }
    128 
    129     size_t currentFrame() const { return m_currentFrame; }
    130    
    131 private:
    132     bool isBitmapImage() const override { return true; }
    133 
    134     void updateSize() const;
    135125
    136126protected:
    137     enum RepetitionCountStatus {
    138       Unknown,    // We haven't checked the source's repetition count.
    139       Uncertain,  // We have a repetition count, but it might be wrong (some GIFs have a count after the image data, and will report "loop once" until all data has been decoded).
    140       Certain     // The repetition count is known to be correct.
    141     };
    142 
    143127    WEBCORE_EXPORT BitmapImage(NativeImagePtr&&, ImageObserver* = nullptr);
    144128    WEBCORE_EXPORT BitmapImage(ImageObserver* = nullptr);
    145129
    146 #if PLATFORM(WIN)
    147     void drawFrameMatchingSourceSize(GraphicsContext&, const FloatRect& dstRect, const IntSize& srcSize, CompositeOperator) override;
    148 #endif
    149     void draw(GraphicsContext&, const FloatRect& dstRect, const FloatRect& srcRect, CompositeOperator, BlendMode, ImageOrientationDescription) override;
    150 
    151 #if USE(WINGDI)
    152     virtual void drawPattern(GraphicsContext&, const FloatRect& srcRect, const AffineTransform& patternTransform,
    153         const FloatPoint& phase, const FloatSize& spacing, CompositeOperator, const FloatRect& destRect);
    154 #endif
    155 
    156     size_t frameCount();
    157 
    158     NativeImagePtr frameImageAtIndex(size_t, float presentationScaleHint = 1);
    159 
    160     bool haveFrameImageAtIndex(size_t);
    161 
    162     bool frameIsCompleteAtIndex(size_t);
    163     float frameDurationAtIndex(size_t);
    164     bool frameHasAlphaAtIndex(size_t);
    165     ImageOrientation frameOrientationAtIndex(size_t);
    166 
    167     // Decodes and caches a frame. Never accessed except internally.
    168     void cacheFrame(size_t index, SubsamplingLevel, ImageFrame::Caching = ImageFrame::Caching::MetadataAndImage);
    169 
    170     // Called before accessing m_frames[index] for info without decoding. Returns false on index out of bounds.
    171     bool ensureFrameAtIndexIsCached(size_t index, ImageFrame::Caching = ImageFrame::Caching::MetadataAndImage);
     130    NativeImagePtr frameImageAtIndex(size_t, SubsamplingLevel = SubsamplingLevel::Default);
    172131
    173132    // Called to invalidate cached data. When |destroyAll| is true, we wipe out
     
    181140    // If the image is large enough, calls destroyDecodedData() and passes
    182141    // |destroyAll| along.
    183     void destroyDecodedDataIfNecessary(bool destroyAll);
    184 
    185     // Generally called by destroyDecodedData(), destroys whole-image metadata
    186     // and notifies observers that the memory footprint has (hopefully)
    187     // decreased by |frameBytesCleared|.
    188     enum class ClearedSource { No, Yes };
    189     void destroyMetadataAndNotify(unsigned frameBytesCleared, ClearedSource);
    190 
    191     // Whether or not size is available yet.
    192     bool isSizeAvailable();
    193 
    194     // Called after asking the source for any information that may require
    195     // decoding part of the image (e.g., the image size). We need to report
    196     // the partially decoded data to our observer so it has an accurate
    197     // account of the BitmapImage's memory usage.
    198     void didDecodeProperties() const;
     142    void destroyDecodedDataIfNecessary(bool destroyAll = true);
     143
     144    void draw(GraphicsContext&, const FloatRect& dstRect, const FloatRect& srcRect, CompositeOperator, BlendMode, ImageOrientationDescription) override;
     145    void drawPattern(GraphicsContext&, const FloatRect& srcRect, const AffineTransform& patternTransform, const FloatPoint& phase, const FloatSize& spacing, CompositeOperator, const FloatRect& destRect, BlendMode = BlendModeNormal) override;
     146#if PLATFORM(WIN)
     147    void drawFrameMatchingSourceSize(GraphicsContext&, const FloatRect& dstRect, const IntSize& srcSize, CompositeOperator) override;
     148#endif
    199149
    200150    // Animation.
    201     RepetitionCount repetitionCount(bool imageKnownToBeComplete); // |imageKnownToBeComplete| should be set if the caller knows the entire image has been decoded.
     151    bool isAnimated() const override { return m_source.frameCount() > 1; }
    202152    bool shouldAnimate();
     153    bool canAnimate();
    203154    void startAnimation(CatchUpAnimation = CatchUp) override;
    204155    void advanceAnimation();
     
    212163    bool internalAdvanceAnimation(AnimationAdvancement = Normal);
    213164
     165    // It may look unusual that there is no start animation call as public API. This is because
     166    // we start and stop animating lazily. Animation begins whenever someone draws the image. It will
     167    // automatically pause once all observers no longer want to render the image anywhere.
     168    void stopAnimation() override;
     169    void resetAnimation() override;
     170
    214171    // Handle platform-specific data
    215172    void invalidatePlatformData();
    216 
    217     Color singlePixelSolidColor() override;
    218173
    219174#if !ASSERT_DISABLED
     
    224179    void clearTimer();
    225180    void startTimer(double delay);
    226 
     181    bool isBitmapImage() const override { return true; }
    227182    void dump(TextStream&) const override;
    228183
    229     ImageSource m_source;
    230     mutable IntSize m_size; // The size to use for the overall image (will just be the size of the first image).
    231     mutable IntSize m_sizeRespectingOrientation;
     184    mutable ImageSource m_source;
    232185
    233186    size_t m_currentFrame { 0 }; // The index of the current frame of animation.
    234     Vector<ImageFrame, 1> m_frames; // An array of the cached frames of the animation. We have to ref frames to pin them in the cache.
    235 
    236187    std::unique_ptr<Timer> m_frameTimer;
    237     RepetitionCount m_repetitionCount { RepetitionCountNone }; // How many total animation loops we should do. This will be cAnimationNone if this image type is incapable of animation.
    238     RepetitionCountStatus m_repetitionCountStatus { Unknown };
    239188    RepetitionCount m_repetitionsComplete { RepetitionCountNone }; // How many repetitions we've finished.
    240189    double m_desiredFrameStartTime { 0 }; // The system time at which we hope to see the next call to startAnimation().
     190    bool m_animationFinished { false };
     191    bool m_animationFinishedWhenCatchingUp { false };
    241192
    242193#if USE(APPKIT)
     
    246197    mutable RetainPtr<CFDataRef> m_tiffRep; // Cached TIFF rep for frame 0. Only built lazily if someone queries for one.
    247198#endif
    248 
    249     // The value of this data member is a missing value if we haven’t analyzed to check for a solid color or not, but an invalid
    250     // color if we have analyzed and decided it’s not a solid color, and a valid color if we have analyzed and decide that the
    251     // solid color optimization applies. The analysis, we do, handles only the case of 1x1 solid color images.
    252     Optional<Color> m_solidColor;
    253 
    254     unsigned m_decodedSize { 0 }; // The current size of all decoded frames.
    255     mutable unsigned m_decodedPropertiesSize { 0 }; // The size of data decoded by the source to determine image properties (e.g. size, frame count, etc).
    256     size_t m_frameCount;
    257 
    258 #if PLATFORM(IOS)
    259     // FIXME: We should expose a setting to enable/disable progressive loading remove the PLATFORM(IOS)-guard.
    260     double m_progressiveLoadChunkTime { 0 };
    261     uint16_t m_progressiveLoadChunkCount { 0 };
    262 #endif
    263     bool m_animationFinished : 1; // Whether or not we've completed the entire animation.
    264 
    265     bool m_allDataReceived : 1; // Whether or not we've received all our data.
    266     mutable bool m_haveSize : 1; // Whether or not our |m_size| member variable has the final overall image size yet.
    267     bool m_sizeAvailable : 1; // Whether or not we can obtain the size of the first image frame yet from ImageIO.
    268     mutable bool m_haveFrameCount : 1;
    269     bool m_animationFinishedWhenCatchingUp : 1;
    270 
    271199    RefPtr<Image> m_cachedImage;
    272200};
     
    275203
    276204SPECIALIZE_TYPE_TRAITS_IMAGE(BitmapImage)
    277 
    278 #endif // BitmapImage_h
  • trunk/Source/WebCore/platform/graphics/GeneratedImage.h

    r204466 r206481  
    5353
    5454    // FIXME: Implement this to be less conservative.
    55     bool currentFrameKnownToBeOpaque() override { return false; }
     55    bool currentFrameKnownToBeOpaque() const override { return false; }
    5656
    5757    GeneratedImage() { }
  • trunk/Source/WebCore/platform/graphics/Image.h

    r205682 r206481  
    8989    virtual bool isPDFDocumentImage() const { return false; }
    9090
    91     virtual bool currentFrameKnownToBeOpaque() = 0;
     91    virtual bool currentFrameKnownToBeOpaque() const = 0;
    9292    virtual bool isAnimated() const { return false; }
    9393
     
    141141    virtual NativeImagePtr nativeImageOfSize(const IntSize&) { return nullptr; }
    142142    virtual NativeImagePtr nativeImageForCurrentFrame() { return nullptr; }
    143     virtual ImageOrientation orientationForCurrentFrame() { return ImageOrientation(); }
     143    virtual ImageOrientation orientationForCurrentFrame() const { return ImageOrientation(); }
    144144    virtual Vector<NativeImagePtr> framesNativeImages() { return { }; }
    145145
     
    193193
    194194    // Supporting tiled drawing
    195     virtual Color singlePixelSolidColor() { return Color(); }
     195    virtual Color singlePixelSolidColor() const { return Color(); }
    196196   
    197197private:
  • trunk/Source/WebCore/platform/graphics/ImageFrame.cpp

    r206156 r206481  
    2727#include "ImageFrame.h"
    2828
    29 #if USE(CG)
    30 #include "ImageDecoderCG.h"
    31 #else
    32 #include "ImageDecoder.h"
    33 #endif
     29#include <wtf/NeverDestroyed.h>
    3430
    3531namespace WebCore {
     
    4238{
    4339    clearImage();
     40}
     41
     42const ImageFrame& ImageFrame::defaultFrame()
     43{
     44    static NeverDestroyed<ImageFrame> sharedInstance;
     45    return sharedInstance;
    4446}
    4547
     
    6971}
    7072
    71 void ImageFrame::fillMetadata(ImageDecoder& decoder, size_t index, SubsamplingLevel subsamplingLevel, bool animating)
    72 {
    73     m_decoding = decoder.frameIsCompleteAtIndex(index) ? Decoding::Complete : Decoding::Partial;
    74     m_size = decoder.frameSizeAtIndex(index, subsamplingLevel);
    75 
    76     m_subsamplingLevel = subsamplingLevel;
    77 
    78     m_orientation = decoder.frameOrientationAtIndex(index);
    79     if (animating)
    80         m_duration = decoder.frameDurationAtIndex(index);
    81     m_hasAlpha = decoder.frameHasAlphaAtIndex(index);
    82 }
    83 
    8473unsigned ImageFrame::clearImage()
    8574{
     
    10594    *this = ImageFrame();
    10695    return frameBytes;
    107 }
    108 
    109 void ImageFrame::initialize(NativeImagePtr&& nativeImage, ImageDecoder& decoder, size_t index, SubsamplingLevel subsamplingLevel, bool animating)
    110 {
    111     m_nativeImage = WTFMove(nativeImage);
    112 
    113     if (!hasMetadata())
    114         fillMetadata(decoder, index, subsamplingLevel, animating);
    115     else if (!isComplete())
    116         m_decoding = decoder.frameIsCompleteAtIndex(index) ? Decoding::Complete : Decoding::Partial;
    117 }
    118 
    119 void ImageFrame::initialize(NativeImagePtr&& nativeImage)
    120 {
    121     m_nativeImage = WTFMove(nativeImage);
    122 
    123     m_decoding = Decoding::Complete;
    124     m_size = nativeImageSize(m_nativeImage);
    125     m_hasAlpha = nativeImageHasAlpha(m_nativeImage);
    12696}
    12797
  • trunk/Source/WebCore/platform/graphics/ImageFrame.h

    r206156 r206481  
    3535
    3636class Color;
    37 class ImageDecoder;
    3837
    3938// There are four subsampling levels: 0 = 1x, 1 = 0.5x, 2 = 0.25x, 3 = 0.125x.
     
    6564};
    6665
     66enum class AlphaOption {
     67    Premultiplied,
     68    NotPremultiplied
     69};
     70
     71enum class GammaAndColorProfileOption {
     72    Applied,
     73    Ignored
     74};
     75
    6776class ImageFrame {
     77    friend class ImageFrameCache;
    6878public:
    6979    enum class Caching { Empty, Metadata, MetadataAndImage };
     
    7181
    7282    ImageFrame();
    73     ImageFrame(NativeImagePtr&&);
    7483    ImageFrame(const ImageFrame& other) { operator=(other); }
    7584
    7685    ~ImageFrame();
     86
     87    static const ImageFrame& defaultFrame();
    7788
    7889    ImageFrame& operator=(const ImageFrame& other);
     
    8192    unsigned clear();
    8293
    83     // FIXME: Calling ImageDecoder::repetitionCount() is expensive to be done for every frame.
    84     // Remove the 'animating' flag from this function when calling repetitionCount() is cheap
    85     // because it will be cached by ImageDecoder or a sub-class of it.
    86     void initialize(NativeImagePtr&&, ImageDecoder&, size_t, SubsamplingLevel, bool animating);
    87     void initialize(NativeImagePtr&&);
    8894#if !USE(CG)
    8995    bool initialize(const ImageBackingStore&);
     
    113119    ImageOrientation orientation() const { return m_orientation; }
    114120
    115     void setDuration(unsigned duration) { m_duration = duration; }
     121    void setDuration(float duration) { m_duration = duration; }
    116122    float duration() const { return m_duration; }
    117123
    118124    void setHasAlpha(bool hasAlpha) { m_hasAlpha = hasAlpha; }
    119     bool hasAlpha() const { return m_hasAlpha; }
     125    bool hasAlpha() const { return !hasMetadata() || m_hasAlpha; }
    120126
    121127    bool hasNativeImage() const { return m_nativeImage; }
     
    131137
    132138private:
    133     void fillMetadata(ImageDecoder&, size_t, SubsamplingLevel, bool animating);
    134 
    135139    Decoding m_decoding { Decoding::Empty };
    136140    IntSize m_size;
  • trunk/Source/WebCore/platform/graphics/ImageSource.cpp

    r206156 r206481  
    3838#include "ImageOrientation.h"
    3939
     40#include <wtf/CurrentTime.h>
     41
    4042namespace WebCore {
    4143
    42 ImageSource::ImageSource(const NativeImagePtr&)
     44ImageSource::ImageSource(NativeImagePtr&& nativeImage)
     45    : m_frameCache(WTFMove(nativeImage))
    4346{
    4447}
    4548   
    46 ImageSource::ImageSource(ImageSource::AlphaOption alphaOption, ImageSource::GammaAndColorProfileOption gammaAndColorProfileOption)
    47     : m_needsUpdateMetadata(true)
    48     , m_maximumSubsamplingLevel(Nullopt)
     49ImageSource::ImageSource(Image* image, AlphaOption alphaOption, GammaAndColorProfileOption gammaAndColorProfileOption)
     50    : m_frameCache(image)
    4951    , m_alphaOption(alphaOption)
    5052    , m_gammaAndColorProfileOption(gammaAndColorProfileOption)
     
    5860void ImageSource::clearFrameBufferCache(size_t clearBeforeFrame)
    5961{
    60     if (!initialized())
     62    if (!isDecoderAvailable())
    6163        return;
    6264    m_decoder->clearFrameBufferCache(clearBeforeFrame);
    6365}
    6466
    65 void ImageSource::clear(bool destroyAllFrames, size_t clearBeforeFrame, SharedBuffer* data, bool allDataReceived)
     67void ImageSource::clear(bool destroyAll, size_t count, SharedBuffer* data)
    6668{
    6769    // There's no need to throw away the decoder unless we're explicitly asked
    6870    // to destroy all of the frames.
    69     if (!destroyAllFrames) {
    70         clearFrameBufferCache(clearBeforeFrame);
     71    if (!destroyAll) {
     72        clearFrameBufferCache(count);
    7173        return;
    7274    }
    7375
    7476    m_decoder = nullptr;
    75 
    76     if (data)
     77    m_frameCache.setDecoder(nullptr);
     78    setData(data, isAllDataReceived());
     79}
     80
     81void ImageSource::destroyDecodedData(SharedBuffer* data, bool destroyAll, size_t count)
     82{
     83    ASSERT(isDecoderAvailable());
     84    m_frameCache.destroyDecodedData(destroyAll, count);
     85    clear(destroyAll, count, data);
     86}
     87
     88bool ImageSource::destroyDecodedDataIfNecessary(SharedBuffer* data, bool destroyAll, size_t count)
     89{
     90    // If we have decoded frames but there is no encoded data, we shouldn't destroy
     91    // the decoded image since we won't be able to reconstruct it later.
     92    if (!data && m_frameCache.frameCount())
     93        return false;
     94
     95    if (!m_frameCache.destroyDecodedDataIfNecessary(destroyAll, count))
     96        return false;
     97
     98    clear(destroyAll, count, data);
     99    return true;
     100}
     101
     102bool ImageSource::ensureDecoderAvailable(SharedBuffer* data)
     103{
     104    if (!data || isDecoderAvailable())
     105        return true;
     106
     107    m_decoder = ImageDecoder::create(*data, m_alphaOption, m_gammaAndColorProfileOption);
     108    if (!isDecoderAvailable())
     109        return false;
     110
     111    m_frameCache.setDecoder(m_decoder.get());
     112    return true;
     113}
     114
     115void ImageSource::setData(SharedBuffer* data, bool allDataReceived)
     116{
     117    if (!data || !ensureDecoderAvailable(data))
     118        return;
     119
     120    m_decoder->setData(*data, allDataReceived);
     121}
     122
     123bool ImageSource::dataChanged(SharedBuffer* data, bool allDataReceived)
     124{
     125    m_frameCache.destroyIncompleteDecodedData();
     126
     127#if PLATFORM(IOS)
     128    // FIXME: We should expose a setting to enable/disable progressive loading and make this
     129    // code conditional on it. Then we can remove the PLATFORM(IOS)-guard.
     130    static const double chunkLoadIntervals[] = {0, 1, 3, 6, 15};
     131    double interval = chunkLoadIntervals[std::min(m_progressiveLoadChunkCount, static_cast<uint16_t>(4))];
     132
     133    bool needsUpdate = false;
     134
     135    // The first time through, the chunk time will be 0 and the image will get an update.
     136    if (currentTime() - m_progressiveLoadChunkTime > interval) {
     137        needsUpdate = true;
     138        m_progressiveLoadChunkTime = currentTime();
     139        ASSERT(m_progressiveLoadChunkCount <= std::numeric_limits<uint16_t>::max());
     140        ++m_progressiveLoadChunkCount;
     141    }
     142
     143    if (needsUpdate || allDataReceived)
    77144        setData(data, allDataReceived);
    78 }
    79 
    80 void ImageSource::setData(SharedBuffer* data, bool allDataReceived)
    81 {
    82     if (!data)
    83         return;
    84 
    85     if (!initialized()) {
    86         m_decoder = ImageDecoder::create(*data, m_alphaOption, m_gammaAndColorProfileOption);
    87         if (!m_decoder)
    88             return;
    89     }
    90 
    91     m_decoder->setData(*data, allDataReceived);
    92 }
    93 
    94 SubsamplingLevel ImageSource::calculateMaximumSubsamplingLevel() const
    95 {
    96     if (!m_allowSubsampling || !frameAllowSubsamplingAtIndex(0))
     145#else
     146    setData(data, allDataReceived);
     147#endif
     148
     149    m_frameCache.clearMetadata();
     150    if (!isSizeAvailable())
     151        return false;
     152
     153    m_frameCache.growFrames();
     154    return true;
     155}
     156
     157bool ImageSource::isAllDataReceived()
     158{
     159    return isDecoderAvailable() ? m_decoder->isAllDataReceived() : m_frameCache.frameCount();
     160}
     161
     162SubsamplingLevel ImageSource::maximumSubsamplingLevel()
     163{
     164    if (m_maximumSubsamplingLevel)
     165        return m_maximumSubsamplingLevel.value();
     166
     167    if (!m_allowSubsampling || !isDecoderAvailable() || !m_decoder->frameAllowSubsamplingAtIndex(0))
    97168        return SubsamplingLevel::Default;
    98    
     169
    99170    // FIXME: this value was chosen to be appropriate for iOS since the image
    100171    // subsampling is only enabled by default on iOS. Choose a different value
    101172    // if image subsampling is enabled on other platform.
    102173    const int maximumImageAreaBeforeSubsampling = 5 * 1024 * 1024;
    103 
    104     for (SubsamplingLevel level = SubsamplingLevel::First; level <= SubsamplingLevel::Last; ++level) {
     174    SubsamplingLevel level = SubsamplingLevel::First;
     175
     176    for (; level < SubsamplingLevel::Last; ++level) {
    105177        if (frameSizeAtIndex(0, level).area() < maximumImageAreaBeforeSubsampling)
    106             return level;
     178            break;
    107179    }
    108    
    109     return SubsamplingLevel::Last;
    110 }
    111 
    112 void ImageSource::updateMetadata()
    113 {
    114     if (!(m_needsUpdateMetadata && isSizeAvailable()))
    115         return;
    116 
    117     m_frameCount = m_decoder->frameCount();
    118     if (!m_maximumSubsamplingLevel)
    119         m_maximumSubsamplingLevel = calculateMaximumSubsamplingLevel();
    120 
    121     m_needsUpdateMetadata = false;
    122 }
    123    
     180
     181    m_maximumSubsamplingLevel = level;
     182    return m_maximumSubsamplingLevel.value();
     183}
     184
    124185SubsamplingLevel ImageSource::subsamplingLevelForScale(float scale)
    125186{
     
    127188        return SubsamplingLevel::Default;
    128189
    129     updateMetadata();
    130     if (!m_maximumSubsamplingLevel)
    131         return SubsamplingLevel::Default;
    132 
    133190    int result = std::ceil(std::log2(1 / scale));
    134     return static_cast<SubsamplingLevel>(std::min(result, static_cast<int>(m_maximumSubsamplingLevel.value())));
    135 }
    136 
    137 size_t ImageSource::bytesDecodedToDetermineProperties()
    138 {
    139     return ImageDecoder::bytesDecodedToDetermineProperties();
    140 }
    141 
    142 bool ImageSource::isSizeAvailable() const
    143 {
    144     return initialized() && m_decoder->isSizeAvailable();
    145 }
    146 
    147 IntSize ImageSource::size() const
    148 {
    149     return frameSizeAtIndex(0, SubsamplingLevel::Default);
    150 }
    151 
    152 IntSize ImageSource::sizeRespectingOrientation() const
    153 {
    154     return frameSizeAtIndex(0, SubsamplingLevel::Default, RespectImageOrientation);
    155 }
    156 
    157 size_t ImageSource::frameCount()
    158 {
    159     updateMetadata();
    160     return m_frameCount;
    161 }
    162 
    163 RepetitionCount ImageSource::repetitionCount()
    164 {
    165     return initialized() ? m_decoder->repetitionCount() : RepetitionCountNone;
    166 }
    167 
    168 String ImageSource::filenameExtension() const
    169 {
    170     return initialized() ? m_decoder->filenameExtension() : String();
    171 }
    172 
    173 Optional<IntPoint> ImageSource::hotSpot() const
    174 {
    175     return initialized() ? m_decoder->hotSpot() : Nullopt;
    176 }
    177 
    178 bool ImageSource::frameIsCompleteAtIndex(size_t index)
    179 {
    180     return initialized() && m_decoder->frameIsCompleteAtIndex(index);
    181 }
    182 
    183 bool ImageSource::frameHasAlphaAtIndex(size_t index)
    184 {
    185     return !initialized() || m_decoder->frameHasAlphaAtIndex(index);
    186 }
    187 
    188 bool ImageSource::frameAllowSubsamplingAtIndex(size_t index) const
    189 {
    190     return initialized() && m_decoder->frameAllowSubsamplingAtIndex(index);
    191 }
    192 
    193 IntSize ImageSource::frameSizeAtIndex(size_t index, SubsamplingLevel subsamplingLevel, RespectImageOrientationEnum shouldRespectImageOrientation) const
    194 {
    195     if (!initialized())
    196         return { };
    197 
    198     IntSize size = m_decoder->frameSizeAtIndex(index, subsamplingLevel);
    199     if (shouldRespectImageOrientation != RespectImageOrientation)
    200         return size;
    201 
    202     return frameOrientationAtIndex(index).usesWidthAsHeight() ? size.transposedSize() : size;
    203 }
    204 
    205 unsigned ImageSource::frameBytesAtIndex(size_t index, SubsamplingLevel subsamplingLevel) const
    206 {
    207     return frameSizeAtIndex(index, subsamplingLevel).area() * 4;
    208 }
    209 
    210 float ImageSource::frameDurationAtIndex(size_t index)
    211 {
    212     return initialized() ? m_decoder->frameDurationAtIndex(index) : 0;
    213 }
    214 
    215 ImageOrientation ImageSource::frameOrientationAtIndex(size_t index) const
    216 {
    217     return initialized() ? m_decoder->frameOrientationAtIndex(index) : ImageOrientation();
    218 }
    219    
     191    return static_cast<SubsamplingLevel>(std::min(result, static_cast<int>(maximumSubsamplingLevel())));
     192}
     193
    220194NativeImagePtr ImageSource::createFrameImageAtIndex(size_t index, SubsamplingLevel subsamplingLevel)
    221195{
    222     return initialized() ? m_decoder->createFrameImageAtIndex(index, subsamplingLevel) : nullptr;
    223 }
    224 
    225 void ImageSource::dump(TextStream& ts) const
    226 {
    227     if (m_allowSubsampling)
    228         ts.dumpProperty("allow-subsampling", m_allowSubsampling);
    229    
     196    return isDecoderAvailable() ? m_decoder->createFrameImageAtIndex(index, subsamplingLevel) : nullptr;
     197}
     198
     199void ImageSource::dump(TextStream& ts)
     200{
     201    ts.dumpProperty("type", filenameExtension());
     202    ts.dumpProperty("frame-count", frameCount());
     203    ts.dumpProperty("repetitions", repetitionCount());
     204    ts.dumpProperty("solid-color", singlePixelSolidColor());
     205
    230206    ImageOrientation orientation = frameOrientationAtIndex(0);
    231207    if (orientation != OriginTopLeft)
  • trunk/Source/WebCore/platform/graphics/ImageSource.h

    r206156 r206481  
    2525 */
    2626
    27 #ifndef ImageSource_h
    28 #define ImageSource_h
     27#pragma once
    2928
    3029#include "ImageFrame.h"
     30#include "ImageFrameCache.h"
    3131#include "ImageOrientation.h"
    3232#include "IntPoint.h"
     
    3939namespace WebCore {
    4040
     41class ImageDecoder;
    4142class ImageOrientation;
    4243class IntPoint;
    4344class IntSize;
    4445class SharedBuffer;
    45 class ImageDecoder;
    4646
    4747class ImageSource {
     
    4949    friend class BitmapImage;
    5050public:
    51     enum AlphaOption {
    52         AlphaPremultiplied,
    53         AlphaNotPremultiplied
    54     };
    55 
    56     enum GammaAndColorProfileOption {
    57         GammaAndColorProfileApplied,
    58         GammaAndColorProfileIgnored
    59     };
    60 
    61     ImageSource(const NativeImagePtr&);
    62     ImageSource(AlphaOption = AlphaPremultiplied, GammaAndColorProfileOption = GammaAndColorProfileApplied);
     51    ImageSource(NativeImagePtr&&);
     52    ImageSource(Image*, AlphaOption = AlphaOption::Premultiplied, GammaAndColorProfileOption = GammaAndColorProfileOption::Applied);
    6353    ~ImageSource();
    6454
    65     // Tells the ImageSource that the Image no longer cares about decoded frame
    66     // data -- at all (if |destroyAll| is true), or before frame
    67     // |clearBeforeFrame| (if |destroyAll| is false).  The ImageSource should
    68     // delete cached decoded data for these frames where possible to keep memory
    69     // usage low.  When |destroyAll| is true, the ImageSource should also reset
    70     // any local state so that decoding can begin again.
    71     //
    72     // Implementations that delete less than what's specified above waste
    73     // memory.  Implementations that delete more may burn CPU re-decoding frames
    74     // that could otherwise have been cached, or encounter errors if they're
    75     // asked to decode frames they can't decode due to the loss of previous
    76     // decoded frames.
    77     //
    78     // Callers should not call clear(false, n) and subsequently call
    79     // createFrameImageAtIndex(m) with m < n, unless they first call clear(true).
    80     // This ensures that stateful ImageSources/decoders will work properly.
    81     //
    82     // The |data| and |allDataReceived| parameters should be supplied by callers
    83     // who set |destroyAll| to true if they wish to be able to continue using
    84     // the ImageSource.  This way implementations which choose to destroy their
    85     // decoders in some cases can reconstruct them correctly.
    86     void clear(bool destroyAll, size_t clearBeforeFrame = 0, SharedBuffer* data = nullptr, bool allDataReceived = false);
     55    void destroyDecodedData(SharedBuffer* data, bool destroyAll = true, size_t count = 0);
     56    bool destroyDecodedDataIfNecessary(SharedBuffer* data, bool destroyAll = true, size_t count = 0);
    8757
    88     // FIXME: Remove the decoder() function from this class when caching the ImageFrame is moved outside BitmapImage.
    89     ImageDecoder* decoder() const { return m_decoder.get(); }
    90     bool initialized() const { return m_decoder.get(); }
     58    bool ensureDecoderAvailable(SharedBuffer*);
     59    bool isDecoderAvailable() const { return m_decoder.get(); }
    9160
    9261    void setData(SharedBuffer* data, bool allDataReceived);
    93    
    94     void setNeedsUpdateMetadata() { m_needsUpdateMetadata = true; }
     62    bool dataChanged(SharedBuffer* data, bool allDataReceived);
    9563
     64    unsigned decodedSize() const { return m_frameCache.decodedSize(); }
     65    bool isAllDataReceived();
     66
     67    // Image metadata which is calculated by the decoder or can deduced by the case of the memory NativeImage.
     68    bool isSizeAvailable() { return m_frameCache.isSizeAvailable(); }
     69    size_t frameCount() { return m_frameCache.frameCount(); }
     70    RepetitionCount repetitionCount() { return m_frameCache.repetitionCount(); }
     71    String filenameExtension() { return m_frameCache.filenameExtension(); }
     72    Optional<IntPoint> hotSpot() { return m_frameCache.hotSpot(); }
     73
     74    // Image metadata which is calculated from the first ImageFrame.
     75    IntSize size() { return m_frameCache.size(); }
     76    IntSize sizeRespectingOrientation() { return m_frameCache.sizeRespectingOrientation(); }
     77    Color singlePixelSolidColor() { return m_frameCache.singlePixelSolidColor(); }
     78
     79    // ImageFrame metadata which does not require caching the ImageFrame.
     80    bool frameIsCompleteAtIndex(size_t index) { return m_frameCache.frameIsCompleteAtIndex(index); }
     81    bool frameHasAlphaAtIndex(size_t index) { return m_frameCache.frameHasAlphaAtIndex(index); }
     82    bool frameHasImageAtIndex(size_t index) { return m_frameCache.frameHasImageAtIndex(index); }
     83    bool frameHasInvalidNativeImageAtIndex(size_t index, SubsamplingLevel subsamplingLevel) { return m_frameCache.frameHasInvalidNativeImageAtIndex(index, subsamplingLevel); }
     84    SubsamplingLevel frameSubsamplingLevelAtIndex(size_t index) { return m_frameCache.frameSubsamplingLevelAtIndex(index); }
     85
     86    // ImageFrame metadata which forces caching or re-caching the ImageFrame.
     87    IntSize frameSizeAtIndex(size_t index, SubsamplingLevel subsamplingLevel = SubsamplingLevel::Default) { return m_frameCache.frameSizeAtIndex(index, subsamplingLevel); }
     88    unsigned frameBytesAtIndex(size_t index, SubsamplingLevel subsamplingLevel = SubsamplingLevel::Default) { return m_frameCache.frameBytesAtIndex(index, subsamplingLevel); }
     89    float frameDurationAtIndex(size_t index) { return m_frameCache.frameDurationAtIndex(index); }
     90    ImageOrientation frameOrientationAtIndex(size_t index) { return m_frameCache.frameOrientationAtIndex(index); }
     91    NativeImagePtr frameImageAtIndex(size_t index, SubsamplingLevel subsamplingLevel = SubsamplingLevel::Default) { return m_frameCache.frameImageAtIndex(index, subsamplingLevel); }
     92
     93    SubsamplingLevel maximumSubsamplingLevel();
    9694    SubsamplingLevel subsamplingLevelForScale(float);
    9795    void setAllowSubsampling(bool allowSubsampling) { m_allowSubsampling = allowSubsampling; }
    98     static size_t bytesDecodedToDetermineProperties();
    99    
    100     bool isSizeAvailable() const;
    101     // Always original size, without subsampling.
    102     IntSize size() const;
    103     IntSize sizeRespectingOrientation() const;
     96    NativeImagePtr createFrameImageAtIndex(size_t, SubsamplingLevel = SubsamplingLevel::Default);
    10497
    105     size_t frameCount();
    106     RepetitionCount repetitionCount();
    107     String filenameExtension() const;
    108     Optional<IntPoint> hotSpot() const;
    109 
    110     bool frameIsCompleteAtIndex(size_t); // Whether or not the frame is completely decoded.
    111     bool frameHasAlphaAtIndex(size_t); // Whether or not the frame actually used any alpha.
    112     bool frameAllowSubsamplingAtIndex(size_t) const;
    113    
    114     // Size of optionally subsampled frame.
    115     IntSize frameSizeAtIndex(size_t, SubsamplingLevel = SubsamplingLevel::Default, RespectImageOrientationEnum = DoNotRespectImageOrientation) const;
    116    
    117     // Return the number of bytes in the decoded frame. If the frame is not yet
    118     // decoded then return 0.
    119     unsigned frameBytesAtIndex(size_t, SubsamplingLevel = SubsamplingLevel::Default) const;
    120    
    121     float frameDurationAtIndex(size_t);
    122     ImageOrientation frameOrientationAtIndex(size_t) const; // EXIF image orientation
    123    
    124     // Callers should not call this after calling clear() with a higher index;
    125     // see comments on clear() above.
    126     NativeImagePtr createFrameImageAtIndex(size_t, SubsamplingLevel = SubsamplingLevel::Default);
    127    
    12898private:
    12999    void clearFrameBufferCache(size_t);
    130     SubsamplingLevel calculateMaximumSubsamplingLevel() const;
    131     void updateMetadata();
    132     void dump(TextStream&) const;
     100    void clear(bool destroyAll, size_t count, SharedBuffer* data);
     101    void dump(TextStream&);
    133102   
     103    ImageFrameCache m_frameCache;
    134104    std::unique_ptr<ImageDecoder> m_decoder;
    135    
    136     bool m_needsUpdateMetadata { false };
    137     size_t m_frameCount { 0 };
    138     Optional<SubsamplingLevel> m_maximumSubsamplingLevel { SubsamplingLevel::Default };
     105
     106    Optional<SubsamplingLevel> m_maximumSubsamplingLevel;
    139107
    140108    // The default value of m_allowSubsampling should be the same as defaultImageSubsamplingEnabled in Settings.cpp
     
    145113#endif
    146114
    147     AlphaOption m_alphaOption { AlphaPremultiplied };
    148     GammaAndColorProfileOption m_gammaAndColorProfileOption { GammaAndColorProfileApplied };
     115#if PLATFORM(IOS)
     116    // FIXME: We should expose a setting to enable/disable progressive loading so that we can remove the PLATFORM(IOS)-guard.
     117    double m_progressiveLoadChunkTime { 0 };
     118    uint16_t m_progressiveLoadChunkCount { 0 };
     119#endif
     120
     121    AlphaOption m_alphaOption { AlphaOption::Premultiplied };
     122    GammaAndColorProfileOption m_gammaAndColorProfileOption { GammaAndColorProfileOption::Applied };
    149123};
    150124
    151125}
    152 
    153 #endif
  • trunk/Source/WebCore/platform/graphics/cairo/GraphicsContext3DCairo.cpp

    r203498 r206481  
    212212        return false;
    213213    // We need this to stay in scope because the native image is just a shallow copy of the data.
    214     m_decoder = new ImageSource(premultiplyAlpha ? ImageSource::AlphaPremultiplied : ImageSource::AlphaNotPremultiplied, ignoreGammaAndColorProfile ? ImageSource::GammaAndColorProfileIgnored : ImageSource::GammaAndColorProfileApplied);
     214    AlphaOption alphaOption = premultiplyAlpha ? AlphaOption::Premultiplied : AlphaOption::NotPremultiplied;
     215    GammaAndColorProfileOption gammaAndColorProfileOption = ignoreGammaAndColorProfile ? GammaAndColorProfileOption::Ignored : GammaAndColorProfileOption::Applied;
     216    m_decoder = new ImageSource(nullptr, alphaOption, gammaAndColorProfileOption);
     217   
    215218    if (!m_decoder)
    216219        return false;
     220
    217221    ImageSource& decoder = *m_decoder;
    218 
    219222    m_alphaOp = AlphaDoNothing;
     223
    220224    if (m_image->data()) {
    221225        decoder.setData(m_image->data(), true);
  • trunk/Source/WebCore/platform/graphics/cg/GraphicsContext3DCG.cpp

    r198655 r206481  
    328328    bool hasAlpha = !m_image->currentFrameKnownToBeOpaque();
    329329    if ((ignoreGammaAndColorProfile || (hasAlpha && !premultiplyAlpha)) && m_image->data()) {
    330         ImageSource decoder(ImageSource::AlphaNotPremultiplied,
    331                             ignoreGammaAndColorProfile ? ImageSource::GammaAndColorProfileIgnored : ImageSource::GammaAndColorProfileApplied);
     330        ImageSource decoder(nullptr, AlphaOption::NotPremultiplied, ignoreGammaAndColorProfile ? GammaAndColorProfileOption::Ignored : GammaAndColorProfileOption::Applied);
    332331        decoder.setData(m_image->data(), true);
    333332        if (!decoder.frameCount())
  • trunk/Source/WebCore/platform/graphics/cg/ImageDecoderCG.cpp

    r206156 r206481  
    119119#endif
    120120
    121 ImageDecoder::ImageDecoder()
     121ImageDecoder::ImageDecoder(AlphaOption, GammaAndColorProfileOption)
    122122{
    123123    m_nativeDecoder = adoptCF(CGImageSourceCreateIncremental(nullptr));
     
    153153    return CFDictionaryContainsKey(image0Properties.get(), kCGImagePropertyPixelWidth)
    154154    && CFDictionaryContainsKey(image0Properties.get(), kCGImagePropertyPixelHeight);
    155 }
    156 
    157 IntSize ImageDecoder::size() const
    158 {
    159     if (m_size.isEmpty())
    160         m_size = frameSizeAtIndex(0);
    161     return m_size;
    162155}
    163156
     
    375368}
    376369
    377 void ImageDecoder::setData(CFDataRef data, bool allDataReceived)
    378 {
    379     CGImageSourceUpdateData(m_nativeDecoder.get(), data, allDataReceived);
    380 }
    381 
    382370void ImageDecoder::setData(SharedBuffer& data, bool allDataReceived)
    383371{
     372    m_isAllDataReceived = allDataReceived;
     373
    384374#if PLATFORM(COCOA)
    385375    // On Mac the NSData inside the SharedBuffer can be secretly appended to without the SharedBuffer's knowledge.
    386376    // We use SharedBuffer's ability to wrap itself inside CFData to get around this, ensuring that ImageIO is
    387377    // really looking at the SharedBuffer.
    388     setData(data.createCFData().get(), allDataReceived);
     378    CGImageSourceUpdateData(m_nativeDecoder.get(), data.createCFData().get(), allDataReceived);
    389379#else
    390380    // Create a CGDataProvider to wrap the SharedBuffer.
  • trunk/Source/WebCore/platform/graphics/cg/ImageDecoderCG.h

    r206156 r206481  
    2424 */
    2525
    26 #ifndef ImageDecoderCG_h
    27 #define ImageDecoderCG_h
     26#pragma once
    2827
    2928#include "ImageSourceCG.h"
     
    4039    WTF_MAKE_FAST_ALLOCATED;
    4140public:
    42     ImageDecoder();
    43    
    44     static std::unique_ptr<ImageDecoder> create(const SharedBuffer&, ImageSource::AlphaOption, ImageSource::GammaAndColorProfileOption)
     41    ImageDecoder(AlphaOption, GammaAndColorProfileOption);
     42
     43    static std::unique_ptr<ImageDecoder> create(const SharedBuffer&, AlphaOption alphaOption, GammaAndColorProfileOption gammaAndColorProfileOption)
    4544    {
    46         return std::make_unique<ImageDecoder>();
     45        return std::make_unique<ImageDecoder>(alphaOption, gammaAndColorProfileOption);
    4746    }
    4847   
    4948    static size_t bytesDecodedToDetermineProperties();
    50    
     49
     50    bool isSizeAvailable() const;
     51    size_t frameCount() const;
     52    RepetitionCount repetitionCount() const;
    5153    String filenameExtension() const;
    52     bool isSizeAvailable() const;
    53    
    54     // Always original size, without subsampling.
    55     IntSize size() const;
    56     size_t frameCount() const;
     54    Optional<IntPoint> hotSpot() const;
    5755
    58     RepetitionCount repetitionCount() const;
    59     Optional<IntPoint> hotSpot() const;
    60    
    6156    IntSize frameSizeAtIndex(size_t, SubsamplingLevel = SubsamplingLevel::Default) const;
    6257    bool frameIsCompleteAtIndex(size_t) const;
     
    7065    NativeImagePtr createFrameImageAtIndex(size_t, SubsamplingLevel = SubsamplingLevel::Default) const;
    7166   
    72     void setData(CFDataRef, bool allDataReceived);
    7367    void setData(SharedBuffer&, bool allDataReceived);
    74    
     68    bool isAllDataReceived() const { return m_isAllDataReceived; }
    7569    void clearFrameBufferCache(size_t) { }
    7670   
    7771protected:
    78     mutable IntSize m_size;
     72    bool m_isAllDataReceived { false };
    7973    RetainPtr<CGImageSourceRef> m_nativeDecoder;
    8074};
    8175
    8276}
    83 
    84 #endif // ImageDecoderCG_h
  • trunk/Source/WebCore/platform/graphics/cg/PDFDocumentImage.h

    r204983 r206481  
    7676
    7777    // FIXME: Implement this to be less conservative.
    78     bool currentFrameKnownToBeOpaque() override { return false; }
     78    bool currentFrameKnownToBeOpaque() const override { return false; }
    7979
    8080    void dump(TextStream&) const override;
  • trunk/Source/WebCore/platform/graphics/efl/GraphicsContext3DEfl.cpp

    r199819 r206481  
    250250
    251251    // We need this to stay in scope because the native image is just a shallow copy of the data.
    252     m_decoder = new ImageSource(premultiplyAlpha ? ImageSource::AlphaPremultiplied : ImageSource::AlphaNotPremultiplied, ignoreGammaAndColorProfile ? ImageSource::GammaAndColorProfileIgnored : ImageSource::GammaAndColorProfileApplied);
     252    AlphaOption alphaOption = premultiplyAlpha ? AlphaOption::Premultiplied : AlphaOption::NotPremultiplied;
     253    GammaAndColorProfileOption gammaAndColorProfileOption = ignoreGammaAndColorProfile ? GammaAndColorProfileOption::Ignored : GammaAndColorProfileOption::Applied;
     254    m_decoder = new ImageSource(nullptr, alphaOption, gammaAndColorProfileOption);
    253255
    254256    if (!m_decoder)
  • trunk/Source/WebCore/platform/graphics/mac/ImageMac.mm

    r205682 r206481  
    4848void BitmapImage::invalidatePlatformData()
    4949{
    50     if (m_frames.size() != 1)
     50    if (frameCount() != 1)
    5151        return;
    5252
  • trunk/Source/WebCore/platform/image-decoders/ImageDecoder.cpp

    r206156 r206481  
    9797}
    9898
    99 std::unique_ptr<ImageDecoder> ImageDecoder::create(const SharedBuffer& data, ImageSource::AlphaOption alphaOption, ImageSource::GammaAndColorProfileOption gammaAndColorProfileOption)
     99std::unique_ptr<ImageDecoder> ImageDecoder::create(const SharedBuffer& data, AlphaOption alphaOption, GammaAndColorProfileOption gammaAndColorProfileOption)
    100100{
    101101    static const unsigned lengthOfLongestSignature = 14; // To wit: "RIFF????WEBPVP"
  • trunk/Source/WebCore/platform/image-decoders/ImageDecoder.h

    r206156 r206481  
    2929#pragma once
    3030
    31 #include "ImageBackingStore.h"
    32 #include "ImageSource.h"
     31#include "ImageFrame.h"
    3332#include "IntRect.h"
    3433#include "IntSize.h"
     
    4342namespace WebCore {
    4443
    45 using ColorProfile = Vector<char>;
    46 
    4744    // ImageDecoder is a base for all format-specific decoders
    4845    // (e.g. JPEGImageDecoder).  This base manages the ImageFrame cache.
     
    5451        WTF_MAKE_NONCOPYABLE(ImageDecoder); WTF_MAKE_FAST_ALLOCATED;
    5552    public:
    56         ImageDecoder(ImageSource::AlphaOption alphaOption, ImageSource::GammaAndColorProfileOption gammaAndColorProfileOption)
    57             : m_premultiplyAlpha(alphaOption == ImageSource::AlphaPremultiplied)
    58             , m_ignoreGammaAndColorProfile(gammaAndColorProfileOption == ImageSource::GammaAndColorProfileIgnored)
     53        ImageDecoder(AlphaOption alphaOption, GammaAndColorProfileOption gammaAndColorProfileOption)
     54            : m_premultiplyAlpha(alphaOption == AlphaOption::Premultiplied)
     55            , m_ignoreGammaAndColorProfile(gammaAndColorProfileOption == GammaAndColorProfileOption::Ignored)
    5956        {
    6057        }
     
    6764        // we can't sniff a supported type from the provided data (possibly
    6865        // because there isn't enough data yet).
    69         static std::unique_ptr<ImageDecoder> create(const SharedBuffer& data, ImageSource::AlphaOption, ImageSource::GammaAndColorProfileOption);
     66        static std::unique_ptr<ImageDecoder> create(const SharedBuffer& data, AlphaOption, GammaAndColorProfileOption);
    7067
    7168        virtual String filenameExtension() const = 0;
     
    123120        // FIXME: Right now that has to be done by each subclass; factor the
    124121        // decode call out and use it here.
    125         virtual size_t frameCount() { return 1; }
     122        virtual size_t frameCount() const { return 1; }
    126123
    127124        virtual RepetitionCount repetitionCount() const { return RepetitionCountNone; }
  • trunk/Source/WebCore/platform/image-decoders/bmp/BMPImageDecoder.cpp

    r206156 r206481  
    4141static const size_t sizeOfFileHeader = 14;
    4242
    43 BMPImageDecoder::BMPImageDecoder(ImageSource::AlphaOption alphaOption,
    44                                  ImageSource::GammaAndColorProfileOption gammaAndColorProfileOption)
     43BMPImageDecoder::BMPImageDecoder(AlphaOption alphaOption, GammaAndColorProfileOption gammaAndColorProfileOption)
    4544    : ImageDecoder(alphaOption, gammaAndColorProfileOption)
    4645    , m_decodedOffset(0)
  • trunk/Source/WebCore/platform/image-decoders/bmp/BMPImageDecoder.h

    r202677 r206481  
    2929 */
    3030
    31 #ifndef BMPImageDecoder_h
    32 #define BMPImageDecoder_h
     31#pragma once
    3332
    3433#include "BMPImageReader.h"
     
    3938    class BMPImageDecoder final : public ImageDecoder {
    4039    public:
    41         BMPImageDecoder(ImageSource::AlphaOption, ImageSource::GammaAndColorProfileOption);
     40        BMPImageDecoder(AlphaOption, GammaAndColorProfileOption);
    4241
    4342        // ImageDecoder
     
    8180
    8281} // namespace WebCore
    83 
    84 #endif
  • trunk/Source/WebCore/platform/image-decoders/gif/GIFImageDecoder.cpp

    r206156 r206481  
    3232namespace WebCore {
    3333
    34 GIFImageDecoder::GIFImageDecoder(ImageSource::AlphaOption alphaOption, ImageSource::GammaAndColorProfileOption gammaAndColorProfileOption)
     34GIFImageDecoder::GIFImageDecoder(AlphaOption alphaOption, GammaAndColorProfileOption gammaAndColorProfileOption)
    3535    : ImageDecoder(alphaOption, gammaAndColorProfileOption)
    3636{
     
    7171}
    7272
    73 size_t GIFImageDecoder::frameCount()
    74 {
    75     decode(std::numeric_limits<unsigned>::max(), GIFFrameCountQuery);
     73size_t GIFImageDecoder::frameCount() const
     74{
     75    const_cast<GIFImageDecoder*>(this)->decode(std::numeric_limits<unsigned>::max(), GIFFrameCountQuery);
    7676    return m_frameBufferCache.size();
    7777}
  • trunk/Source/WebCore/platform/image-decoders/gif/GIFImageDecoder.h

    r206156 r206481  
    2424 */
    2525
    26 #ifndef GIFImageDecoder_h
    27 #define GIFImageDecoder_h
     26#pragma once
    2827
    2928#include "ImageDecoder.h"
     
    3635    class GIFImageDecoder final : public ImageDecoder {
    3736    public:
    38         GIFImageDecoder(ImageSource::AlphaOption, ImageSource::GammaAndColorProfileOption);
     37        GIFImageDecoder(AlphaOption, GammaAndColorProfileOption);
    3938        virtual ~GIFImageDecoder();
    4039
     
    4645        bool isSizeAvailable() override;
    4746        bool setSize(const IntSize&) override;
    48         size_t frameCount() override;
     47        size_t frameCount() const override;
    4948        RepetitionCount repetitionCount() const override;
    5049        ImageFrame* frameBufferAtIndex(size_t index) override;
     
    7877
    7978} // namespace WebCore
    80 
    81 #endif
  • trunk/Source/WebCore/platform/image-decoders/gif/GIFImageReader.cpp

    r206156 r206481  
    7878#include <string.h>
    7979#include "GIFImageDecoder.h"
    80 #include "ImageSource.h"
    8180
    8281using WebCore::GIFImageDecoder;
  • trunk/Source/WebCore/platform/image-decoders/gif/GIFImageReader.h

    r206156 r206481  
    3636 * ***** END LICENSE BLOCK ***** */
    3737
    38 #ifndef GIFImageReader_h
    39 #define GIFImageReader_h
     38#pragma once
    4039
    4140// Define ourselves as the clientPtr.  Mozilla just hacked their C++ callback class into this old C decoder,
     
    324323    bool m_parseCompleted;
    325324};
    326 
    327 #endif
  • trunk/Source/WebCore/platform/image-decoders/ico/ICOImageDecoder.cpp

    r206156 r206481  
    4545static const size_t sizeOfDirEntry = 16;
    4646
    47 ICOImageDecoder::ICOImageDecoder(ImageSource::AlphaOption alphaOption,
    48                                  ImageSource::GammaAndColorProfileOption gammaAndColorProfileOption)
     47ICOImageDecoder::ICOImageDecoder(AlphaOption alphaOption, GammaAndColorProfileOption gammaAndColorProfileOption)
    4948    : ImageDecoder(alphaOption, gammaAndColorProfileOption)
    5049    , m_decodedOffset(0)
     
    9695}
    9796
    98 size_t ICOImageDecoder::frameCount()
    99 {
    100     decode(0, true);
    101     if (m_frameBufferCache.isEmpty())
    102         m_frameBufferCache.resize(m_dirEntries.size());
    103     // CAUTION: We must not resize m_frameBufferCache again after this, as
    104     // decodeAtIndex() may give a BMPImageReader a pointer to one of the
    105     // entries.
     97size_t ICOImageDecoder::frameCount() const
     98{
     99    const_cast<ICOImageDecoder*>(this)->decode(0, true);
    106100    return m_frameBufferCache.size();
    107101}
     
    181175        m_pngDecoders[index] = nullptr;
    182176    }
     177   
     178    if (m_frameBufferCache.isEmpty())
     179        m_frameBufferCache.resize(m_dirEntries.size());
     180    // CAUTION: We must not resize m_frameBufferCache again after this, as
     181    // decodeAtIndex() may give a BMPImageReader a pointer to one of the
     182    // entries.
    183183}
    184184
     
    218218    if (!m_pngDecoders[index]) {
    219219        m_pngDecoders[index] = std::make_unique<
    220             PNGImageDecoder>(m_premultiplyAlpha ? ImageSource::AlphaPremultiplied : ImageSource::AlphaNotPremultiplied,
    221                 m_ignoreGammaAndColorProfile ? ImageSource::GammaAndColorProfileIgnored : ImageSource::GammaAndColorProfileApplied);
     220            PNGImageDecoder>(m_premultiplyAlpha ? AlphaOption::Premultiplied : AlphaOption::NotPremultiplied,
     221                m_ignoreGammaAndColorProfile ? GammaAndColorProfileOption::Ignored : GammaAndColorProfileOption::Applied);
    222222        setDataForPNGDecoderAtIndex(index);
    223223    }
  • trunk/Source/WebCore/platform/image-decoders/ico/ICOImageDecoder.h

    r205841 r206481  
    2929 */
    3030
    31 #ifndef ICOImageDecoder_h
    32 #define ICOImageDecoder_h
     31#pragma once
    3332
    3433#include "BMPImageReader.h"
     
    4140    class ICOImageDecoder final : public ImageDecoder {
    4241    public:
    43         ICOImageDecoder(ImageSource::AlphaOption, ImageSource::GammaAndColorProfileOption);
     42        ICOImageDecoder(AlphaOption, GammaAndColorProfileOption);
    4443        virtual ~ICOImageDecoder();
    4544
     
    5150        IntSize frameSizeAtIndex(size_t, SubsamplingLevel) override;
    5251        bool setSize(const IntSize&) override;
    53         size_t frameCount() override;
     52        size_t frameCount() const override;
    5453        ImageFrame* frameBufferAtIndex(size_t) override;
    5554        // CAUTION: setFailed() deletes all readers and decoders.  Be careful to
     
    152151
    153152} // namespace WebCore
    154 
    155 #endif
  • trunk/Source/WebCore/platform/image-decoders/jpeg/JPEGImageDecoder.cpp

    r206156 r206481  
    502502}
    503503
    504 JPEGImageDecoder::JPEGImageDecoder(ImageSource::AlphaOption alphaOption,
    505                                    ImageSource::GammaAndColorProfileOption gammaAndColorProfileOption)
     504JPEGImageDecoder::JPEGImageDecoder(AlphaOption alphaOption, GammaAndColorProfileOption gammaAndColorProfileOption)
    506505    : ImageDecoder(alphaOption, gammaAndColorProfileOption)
    507506{
  • trunk/Source/WebCore/platform/image-decoders/jpeg/JPEGImageDecoder.h

    r205841 r206481  
    2525 */
    2626
    27 #ifndef JPEGImageDecoder_h
    28 #define JPEGImageDecoder_h
     27#pragma once
    2928
    3029#include "ImageDecoder.h"
     
    4544    class JPEGImageDecoder final : public ImageDecoder {
    4645    public:
    47         JPEGImageDecoder(ImageSource::AlphaOption, ImageSource::GammaAndColorProfileOption);
     46        JPEGImageDecoder(AlphaOption, GammaAndColorProfileOption);
    4847        virtual ~JPEGImageDecoder();
    4948
     
    8584
    8685} // namespace WebCore
    87 
    88 #endif
  • trunk/Source/WebCore/platform/image-decoders/png/PNGImageDecoder.cpp

    r206156 r206481  
    194194};
    195195
    196 PNGImageDecoder::PNGImageDecoder(ImageSource::AlphaOption alphaOption, ImageSource::GammaAndColorProfileOption gammaAndColorProfileOption)
     196PNGImageDecoder::PNGImageDecoder(AlphaOption alphaOption, GammaAndColorProfileOption gammaAndColorProfileOption)
    197197    : ImageDecoder(alphaOption, gammaAndColorProfileOption)
    198198    , m_doNothingOnFailure(false)
  • trunk/Source/WebCore/platform/image-decoders/png/PNGImageDecoder.h

    r206156 r206481  
    2424 */
    2525
    26 #ifndef PNGImageDecoder_h
    27 #define PNGImageDecoder_h
     26#pragma once
    2827
    2928#include "ImageDecoder.h"
     
    3938    class PNGImageDecoder final : public ImageDecoder {
    4039    public:
    41         PNGImageDecoder(ImageSource::AlphaOption, ImageSource::GammaAndColorProfileOption);
     40        PNGImageDecoder(AlphaOption, GammaAndColorProfileOption);
    4241        virtual ~PNGImageDecoder();
    4342
     
    4544        String filenameExtension() const override { return "png"; }
    4645#if ENABLE(APNG)
    47         size_t frameCount() override { return m_frameCount; }
     46        size_t frameCount() const override { return m_frameCount; }
    4847        RepetitionCount repetitionCount() const override { return m_playCount-1; }
    4948#endif
     
    131130
    132131} // namespace WebCore
    133 
    134 #endif
  • trunk/Source/WebCore/platform/image-decoders/webp/WEBPImageDecoder.cpp

    r206156 r206481  
    4646namespace WebCore {
    4747
    48 WEBPImageDecoder::WEBPImageDecoder(ImageSource::AlphaOption alphaOption,
    49                                    ImageSource::GammaAndColorProfileOption gammaAndColorProfileOption)
     48WEBPImageDecoder::WEBPImageDecoder(AlphaOption alphaOption, GammaAndColorProfileOption gammaAndColorProfileOption)
    5049    : ImageDecoder(alphaOption, gammaAndColorProfileOption)
    5150    , m_decoder(0)
  • trunk/Source/WebCore/platform/image-decoders/webp/WEBPImageDecoder.h

    r202677 r206481  
    2727 */
    2828
    29 #ifndef WEBPImageDecoder_h
    30 #define WEBPImageDecoder_h
     29#pragma once
    3130
    3231#include "ImageDecoder.h"
     
    4039class WEBPImageDecoder final : public ImageDecoder {
    4140public:
    42     WEBPImageDecoder(ImageSource::AlphaOption, ImageSource::GammaAndColorProfileOption);
     41    WEBPImageDecoder(AlphaOption, GammaAndColorProfileOption);
    4342    virtual ~WEBPImageDecoder();
    4443
     
    6059
    6160#endif
    62 
    63 #endif
  • trunk/Source/WebCore/svg/graphics/SVGImage.h

    r203469 r206481  
    9090
    9191    // FIXME: Implement this to be less conservative.
    92     bool currentFrameKnownToBeOpaque() final { return false; }
     92    bool currentFrameKnownToBeOpaque() const final { return false; }
    9393
    9494    void dump(TextStream&) const final;
  • trunk/Source/WebCore/svg/graphics/SVGImageForContainer.h

    r203469 r206481  
    6262
    6363    // FIXME: Implement this to be less conservative.
    64     bool currentFrameKnownToBeOpaque() final { return false; }
     64    bool currentFrameKnownToBeOpaque() const final { return false; }
    6565
    6666    NativeImagePtr nativeImageForCurrentFrame() final;
Note: See TracChangeset for help on using the changeset viewer.