Changeset 206481 in webkit
- Timestamp:
- Sep 27, 2016 6:06:57 PM (8 years ago)
- Location:
- trunk/Source/WebCore
- Files:
-
- 2 added
- 36 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/WebCore/CMakeLists.txt
r206440 r206481 2222 2222 platform/graphics/ImageBuffer.cpp 2223 2223 platform/graphics/ImageFrame.cpp 2224 platform/graphics/ImageFrameCache.cpp 2224 2225 platform/graphics/ImageOrientation.cpp 2225 2226 platform/graphics/ImageSource.cpp -
trunk/Source/WebCore/ChangeLog
r206480 r206481 1 2016-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 1 257 2016-09-27 Alex Christensen <achristensen@webkit.org> 2 258 -
trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj
r206440 r206481 2272 2272 5576A5641D88A70800CCC04C /* ImageFrame.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5576A5621D88A70800CCC04C /* ImageFrame.cpp */; }; 2273 2273 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, ); }; }; 2274 2276 55A336F71D8209F40022C4C7 /* NativeImage.h in Headers */ = {isa = PBXBuildFile; fileRef = 55A336F61D8209F40022C4C7 /* NativeImage.h */; }; 2275 2277 55A336F91D821E3C0022C4C7 /* ImageBackingStore.h in Headers */ = {isa = PBXBuildFile; fileRef = 55A336F81D821E3C0022C4C7 /* ImageBackingStore.h */; settings = {ATTRIBUTES = (Private, ); }; }; … … 9301 9303 5576A5621D88A70800CCC04C /* ImageFrame.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ImageFrame.cpp; sourceTree = "<group>"; }; 9302 9304 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>"; }; 9303 9307 55A336F61D8209F40022C4C7 /* NativeImage.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = NativeImage.h; sourceTree = "<group>"; }; 9304 9308 55A336F81D821E3C0022C4C7 /* ImageBackingStore.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ImageBackingStore.h; sourceTree = "<group>"; }; … … 20719 20723 5576A5621D88A70800CCC04C /* ImageFrame.cpp */, 20720 20724 5576A5631D88A70800CCC04C /* ImageFrame.h */, 20725 5597F8241D91C3130066BC21 /* ImageFrameCache.cpp */, 20726 5597F8251D91C3130066BC21 /* ImageFrameCache.h */, 20721 20727 BC7F44A70B9E324E00A9D081 /* ImageObserver.h */, 20722 20728 A8748D7412CC3F89001FBA41 /* ImageOrientation.cpp */, … … 24496 24502 B275356B0B053814002CE64F /* FloatRect.h in Headers */, 24497 24503 6E0E569C183BFFE600E0E8D5 /* FloatRoundedRect.h in Headers */, 24504 5597F8271D91C3130066BC21 /* ImageFrameCache.h in Headers */, 24498 24505 B275356D0B053814002CE64F /* FloatSize.h in Headers */, 24499 24506 58CD35CB18EB4C3900B9F3AC /* FloatSizeHash.h in Headers */, … … 27618 27625 E461D65D1BB0C7F000CB5645 /* AuthorStyleSheets.cpp in Sources */, 27619 27626 A5F6E16B132ED46E008EDAE3 /* Autocapitalize.cpp in Sources */, 27627 5597F8261D91C3130066BC21 /* ImageFrameCache.cpp in Sources */, 27620 27628 7C1843FD1C8B7283002EB973 /* Autofill.cpp in Sources */, 27621 27629 7C1E97271A9F9834007BF0FB /* AutoFillButtonElement.cpp in Sources */, -
trunk/Source/WebCore/platform/graphics/BitmapImage.cpp
r206419 r206481 22 22 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 23 23 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 24 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 24 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 25 */ 26 26 … … 49 49 BitmapImage::BitmapImage(ImageObserver* observer) 50 50 : 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) 57 52 { 58 53 } … … 60 55 BitmapImage::BitmapImage(NativeImagePtr&& image, ImageObserver* observer) 61 56 : 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 { 77 59 } 78 60 … … 83 65 } 84 66 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 96 67 void BitmapImage::destroyDecodedData(bool destroyAll) 97 68 { 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(); 113 71 } 114 72 115 73 void BitmapImage::destroyDecodedDataIfNecessary(bool destroyAll) 116 74 { 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); 235 76 } 236 77 237 78 bool BitmapImage::dataChanged(bool allDataReceived) 238 79 { 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 83 NativeImagePtr 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))); 360 87 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 373 93 NativeImagePtr BitmapImage::nativeImage() 374 94 { … … 380 100 return frameImageAtIndex(m_currentFrame); 381 101 } 382 102 383 103 #if USE(CG) 384 104 NativeImagePtr BitmapImage::nativeImageOfSize(const IntSize& size) 385 105 { 386 106 size_t count = frameCount(); 387 107 388 108 for (size_t i = 0; i < count; ++i) { 389 109 auto image = frameImageAtIndex(i); … … 391 111 return image; 392 112 } 393 113 394 114 // Fallback to the first frame image if we can't find the right size 395 115 return frameImageAtIndex(0); 396 116 } 397 117 398 118 Vector<NativeImagePtr> BitmapImage::framesNativeImages() 399 119 { 400 120 Vector<NativeImagePtr> images; 401 121 size_t count = frameCount(); 402 122 403 123 for (size_t i = 0; i < count; ++i) { 404 124 if (auto image = frameImageAtIndex(i)) 405 125 images.append(image); 406 126 } 407 127 408 128 return images; 409 129 } 410 130 #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 }480 131 481 132 #if !ASSERT_DISABLED … … 485 136 } 486 137 #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, the492 // repetition count may not be accurate yet for GIFs; in this case the493 // decoder will default to RepetitionCountOnce, and we'll try and read494 // 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 }501 138 502 139 void BitmapImage::draw(GraphicsContext& context, const FloatRect& destRect, const FloatRect& srcRect, CompositeOperator op, BlendMode mode, ImageOrientationDescription description) … … 517 154 } 518 155 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); 520 161 if (!image) // If it's too early we won't have an image yet. 521 162 return; … … 525 166 orientation = frameOrientationAtIndex(m_currentFrame); 526 167 527 drawNativeImage(image, context, destRect, srcRect, m_size, op, mode, orientation);168 drawNativeImage(image, context, destRect, srcRect, IntSize(size()), op, mode, orientation); 528 169 529 170 if (imageObserver()) 530 171 imageObserver()->didDraw(this); 531 172 } 532 173 533 174 void BitmapImage::drawPattern(GraphicsContext& ctxt, const FloatRect& tileRect, const AffineTransform& transform, const FloatPoint& phase, const FloatSize& spacing, CompositeOperator op, const FloatRect& destRect, BlendMode blendMode) 534 175 { … … 560 201 return; 561 202 } 562 203 563 204 ctxt.setDrawLuminanceMask(false); 564 205 m_cachedImage->drawPattern(ctxt, tileRect, transform, phase, spacing, op, destRect, blendMode); … … 567 208 bool BitmapImage::shouldAnimate() 568 209 { 569 return repetitionCount( false) && !m_animationFinished && imageObserver();210 return repetitionCount() && !m_animationFinished && imageObserver(); 570 211 } 571 212 … … 599 240 // Don't advance the animation to an incomplete frame. 600 241 size_t nextFrame = (m_currentFrame + 1) % frameCount(); 601 if (!m_ allDataReceived&& !frameIsCompleteAtIndex(nextFrame))242 if (!m_source.isAllDataReceived() && !frameIsCompleteAtIndex(nextFrame)) 602 243 return; 603 244 … … 606 247 // in a GIF can potentially come after all the rest of the image data, so 607 248 // 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)) 609 250 return; 610 251 … … 657 298 size_t startCatchupFrameIndex = nextFrame; 658 299 #endif 659 300 660 301 for (size_t frameAfterNext = (nextFrame + 1) % frameCount(); frameIsCompleteAtIndex(frameAfterNext); frameAfterNext = (nextFrame + 1) % frameCount()) { 661 302 // Should we skip the next frame? … … 701 342 return false; 702 343 } 703 344 704 345 ++m_currentFrame; 705 346 bool advancedAnimation = true; … … 711 352 // repetition count before, we should have decoded the whole image by 712 353 // now, so it should now be available. 713 if (repetitionCount( true) != RepetitionCountInfinite && m_repetitionsComplete > m_repetitionCount) {354 if (repetitionCount() != RepetitionCountInfinite && m_repetitionsComplete > repetitionCount()) { 714 355 m_animationFinished = true; 715 356 m_desiredFrameStartTime = 0; … … 753 394 { 754 395 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()) 761 398 ts.dumpProperty("current-frame", m_currentFrame); 762 }763 764 if (m_solidColor)765 ts.dumpProperty("solid-color", m_solidColor.value());766 399 767 400 m_source.dump(ts); -
trunk/Source/WebCore/platform/graphics/BitmapImage.h
r206156 r206481 26 26 */ 27 27 28 #ifndef BitmapImage_h 29 #define BitmapImage_h 28 #pragma once 30 29 31 30 #include "Image.h" … … 68 67 bool hasSingleSecurityOrigin() const override { return true; } 69 68 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 70 78 // 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()); } 89 96 90 97 // Accessors for native image formats. 91 92 98 #if USE(APPKIT) 93 99 NSImage* getNSImage() override; … … 117 123 Vector<NativeImagePtr> framesNativeImages() override; 118 124 #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;135 125 136 126 protected: 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 143 127 WEBCORE_EXPORT BitmapImage(NativeImagePtr&&, ImageObserver* = nullptr); 144 128 WEBCORE_EXPORT BitmapImage(ImageObserver* = nullptr); 145 129 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); 172 131 173 132 // Called to invalidate cached data. When |destroyAll| is true, we wipe out … … 181 140 // If the image is large enough, calls destroyDecodedData() and passes 182 141 // |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 199 149 200 150 // 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; } 202 152 bool shouldAnimate(); 153 bool canAnimate(); 203 154 void startAnimation(CatchUpAnimation = CatchUp) override; 204 155 void advanceAnimation(); … … 212 163 bool internalAdvanceAnimation(AnimationAdvancement = Normal); 213 164 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 214 171 // Handle platform-specific data 215 172 void invalidatePlatformData(); 216 217 Color singlePixelSolidColor() override;218 173 219 174 #if !ASSERT_DISABLED … … 224 179 void clearTimer(); 225 180 void startTimer(double delay); 226 181 bool isBitmapImage() const override { return true; } 227 182 void dump(TextStream&) const override; 228 183 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; 232 185 233 186 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 236 187 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 };239 188 RepetitionCount m_repetitionsComplete { RepetitionCountNone }; // How many repetitions we've finished. 240 189 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 }; 241 192 242 193 #if USE(APPKIT) … … 246 197 mutable RetainPtr<CFDataRef> m_tiffRep; // Cached TIFF rep for frame 0. Only built lazily if someone queries for one. 247 198 #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 invalid250 // color if we have analyzed and decided it’s not a solid color, and a valid color if we have analyzed and decide that the251 // 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 #endif263 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 271 199 RefPtr<Image> m_cachedImage; 272 200 }; … … 275 203 276 204 SPECIALIZE_TYPE_TRAITS_IMAGE(BitmapImage) 277 278 #endif // BitmapImage_h -
trunk/Source/WebCore/platform/graphics/GeneratedImage.h
r204466 r206481 53 53 54 54 // FIXME: Implement this to be less conservative. 55 bool currentFrameKnownToBeOpaque() override { return false; }55 bool currentFrameKnownToBeOpaque() const override { return false; } 56 56 57 57 GeneratedImage() { } -
trunk/Source/WebCore/platform/graphics/Image.h
r205682 r206481 89 89 virtual bool isPDFDocumentImage() const { return false; } 90 90 91 virtual bool currentFrameKnownToBeOpaque() = 0;91 virtual bool currentFrameKnownToBeOpaque() const = 0; 92 92 virtual bool isAnimated() const { return false; } 93 93 … … 141 141 virtual NativeImagePtr nativeImageOfSize(const IntSize&) { return nullptr; } 142 142 virtual NativeImagePtr nativeImageForCurrentFrame() { return nullptr; } 143 virtual ImageOrientation orientationForCurrentFrame() { return ImageOrientation(); }143 virtual ImageOrientation orientationForCurrentFrame() const { return ImageOrientation(); } 144 144 virtual Vector<NativeImagePtr> framesNativeImages() { return { }; } 145 145 … … 193 193 194 194 // Supporting tiled drawing 195 virtual Color singlePixelSolidColor() { return Color(); }195 virtual Color singlePixelSolidColor() const { return Color(); } 196 196 197 197 private: -
trunk/Source/WebCore/platform/graphics/ImageFrame.cpp
r206156 r206481 27 27 #include "ImageFrame.h" 28 28 29 #if USE(CG) 30 #include "ImageDecoderCG.h" 31 #else 32 #include "ImageDecoder.h" 33 #endif 29 #include <wtf/NeverDestroyed.h> 34 30 35 31 namespace WebCore { … … 42 38 { 43 39 clearImage(); 40 } 41 42 const ImageFrame& ImageFrame::defaultFrame() 43 { 44 static NeverDestroyed<ImageFrame> sharedInstance; 45 return sharedInstance; 44 46 } 45 47 … … 69 71 } 70 72 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 84 73 unsigned ImageFrame::clearImage() 85 74 { … … 105 94 *this = ImageFrame(); 106 95 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);126 96 } 127 97 -
trunk/Source/WebCore/platform/graphics/ImageFrame.h
r206156 r206481 35 35 36 36 class Color; 37 class ImageDecoder;38 37 39 38 // There are four subsampling levels: 0 = 1x, 1 = 0.5x, 2 = 0.25x, 3 = 0.125x. … … 65 64 }; 66 65 66 enum class AlphaOption { 67 Premultiplied, 68 NotPremultiplied 69 }; 70 71 enum class GammaAndColorProfileOption { 72 Applied, 73 Ignored 74 }; 75 67 76 class ImageFrame { 77 friend class ImageFrameCache; 68 78 public: 69 79 enum class Caching { Empty, Metadata, MetadataAndImage }; … … 71 81 72 82 ImageFrame(); 73 ImageFrame(NativeImagePtr&&);74 83 ImageFrame(const ImageFrame& other) { operator=(other); } 75 84 76 85 ~ImageFrame(); 86 87 static const ImageFrame& defaultFrame(); 77 88 78 89 ImageFrame& operator=(const ImageFrame& other); … … 81 92 unsigned clear(); 82 93 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 cheap85 // 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&&);88 94 #if !USE(CG) 89 95 bool initialize(const ImageBackingStore&); … … 113 119 ImageOrientation orientation() const { return m_orientation; } 114 120 115 void setDuration( unsignedduration) { m_duration = duration; }121 void setDuration(float duration) { m_duration = duration; } 116 122 float duration() const { return m_duration; } 117 123 118 124 void setHasAlpha(bool hasAlpha) { m_hasAlpha = hasAlpha; } 119 bool hasAlpha() const { return m_hasAlpha; }125 bool hasAlpha() const { return !hasMetadata() || m_hasAlpha; } 120 126 121 127 bool hasNativeImage() const { return m_nativeImage; } … … 131 137 132 138 private: 133 void fillMetadata(ImageDecoder&, size_t, SubsamplingLevel, bool animating);134 135 139 Decoding m_decoding { Decoding::Empty }; 136 140 IntSize m_size; -
trunk/Source/WebCore/platform/graphics/ImageSource.cpp
r206156 r206481 38 38 #include "ImageOrientation.h" 39 39 40 #include <wtf/CurrentTime.h> 41 40 42 namespace WebCore { 41 43 42 ImageSource::ImageSource(const NativeImagePtr&) 44 ImageSource::ImageSource(NativeImagePtr&& nativeImage) 45 : m_frameCache(WTFMove(nativeImage)) 43 46 { 44 47 } 45 48 46 ImageSource::ImageSource(ImageSource::AlphaOption alphaOption, ImageSource::GammaAndColorProfileOption gammaAndColorProfileOption) 47 : m_needsUpdateMetadata(true) 48 , m_maximumSubsamplingLevel(Nullopt) 49 ImageSource::ImageSource(Image* image, AlphaOption alphaOption, GammaAndColorProfileOption gammaAndColorProfileOption) 50 : m_frameCache(image) 49 51 , m_alphaOption(alphaOption) 50 52 , m_gammaAndColorProfileOption(gammaAndColorProfileOption) … … 58 60 void ImageSource::clearFrameBufferCache(size_t clearBeforeFrame) 59 61 { 60 if (!i nitialized())62 if (!isDecoderAvailable()) 61 63 return; 62 64 m_decoder->clearFrameBufferCache(clearBeforeFrame); 63 65 } 64 66 65 void ImageSource::clear(bool destroyAll Frames, size_t clearBeforeFrame, SharedBuffer* data, bool allDataReceived)67 void ImageSource::clear(bool destroyAll, size_t count, SharedBuffer* data) 66 68 { 67 69 // There's no need to throw away the decoder unless we're explicitly asked 68 70 // to destroy all of the frames. 69 if (!destroyAll Frames) {70 clearFrameBufferCache(c learBeforeFrame);71 if (!destroyAll) { 72 clearFrameBufferCache(count); 71 73 return; 72 74 } 73 75 74 76 m_decoder = nullptr; 75 76 if (data) 77 m_frameCache.setDecoder(nullptr); 78 setData(data, isAllDataReceived()); 79 } 80 81 void 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 88 bool 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 102 bool 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 115 void ImageSource::setData(SharedBuffer* data, bool allDataReceived) 116 { 117 if (!data || !ensureDecoderAvailable(data)) 118 return; 119 120 m_decoder->setData(*data, allDataReceived); 121 } 122 123 bool 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) 77 144 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 157 bool ImageSource::isAllDataReceived() 158 { 159 return isDecoderAvailable() ? m_decoder->isAllDataReceived() : m_frameCache.frameCount(); 160 } 161 162 SubsamplingLevel ImageSource::maximumSubsamplingLevel() 163 { 164 if (m_maximumSubsamplingLevel) 165 return m_maximumSubsamplingLevel.value(); 166 167 if (!m_allowSubsampling || !isDecoderAvailable() || !m_decoder->frameAllowSubsamplingAtIndex(0)) 97 168 return SubsamplingLevel::Default; 98 169 99 170 // FIXME: this value was chosen to be appropriate for iOS since the image 100 171 // subsampling is only enabled by default on iOS. Choose a different value 101 172 // if image subsampling is enabled on other platform. 102 173 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) { 105 177 if (frameSizeAtIndex(0, level).area() < maximumImageAreaBeforeSubsampling) 106 return level;178 break; 107 179 } 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 124 185 SubsamplingLevel ImageSource::subsamplingLevelForScale(float scale) 125 186 { … … 127 188 return SubsamplingLevel::Default; 128 189 129 updateMetadata();130 if (!m_maximumSubsamplingLevel)131 return SubsamplingLevel::Default;132 133 190 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 220 194 NativeImagePtr ImageSource::createFrameImageAtIndex(size_t index, SubsamplingLevel subsamplingLevel) 221 195 { 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 199 void 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 230 206 ImageOrientation orientation = frameOrientationAtIndex(0); 231 207 if (orientation != OriginTopLeft) -
trunk/Source/WebCore/platform/graphics/ImageSource.h
r206156 r206481 25 25 */ 26 26 27 #ifndef ImageSource_h 28 #define ImageSource_h 27 #pragma once 29 28 30 29 #include "ImageFrame.h" 30 #include "ImageFrameCache.h" 31 31 #include "ImageOrientation.h" 32 32 #include "IntPoint.h" … … 39 39 namespace WebCore { 40 40 41 class ImageDecoder; 41 42 class ImageOrientation; 42 43 class IntPoint; 43 44 class IntSize; 44 45 class SharedBuffer; 45 class ImageDecoder;46 46 47 47 class ImageSource { … … 49 49 friend class BitmapImage; 50 50 public: 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); 63 53 ~ImageSource(); 64 54 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); 87 57 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(); } 91 60 92 61 void setData(SharedBuffer* data, bool allDataReceived); 93 94 void setNeedsUpdateMetadata() { m_needsUpdateMetadata = true; } 62 bool dataChanged(SharedBuffer* data, bool allDataReceived); 95 63 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(); 96 94 SubsamplingLevel subsamplingLevelForScale(float); 97 95 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); 104 97 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 yet118 // 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 orientation123 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 128 98 private: 129 99 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&); 133 102 103 ImageFrameCache m_frameCache; 134 104 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; 139 107 140 108 // The default value of m_allowSubsampling should be the same as defaultImageSubsamplingEnabled in Settings.cpp … … 145 113 #endif 146 114 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 }; 149 123 }; 150 124 151 125 } 152 153 #endif -
trunk/Source/WebCore/platform/graphics/cairo/GraphicsContext3DCairo.cpp
r203498 r206481 212 212 return false; 213 213 // 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 215 218 if (!m_decoder) 216 219 return false; 220 217 221 ImageSource& decoder = *m_decoder; 218 219 222 m_alphaOp = AlphaDoNothing; 223 220 224 if (m_image->data()) { 221 225 decoder.setData(m_image->data(), true); -
trunk/Source/WebCore/platform/graphics/cg/GraphicsContext3DCG.cpp
r198655 r206481 328 328 bool hasAlpha = !m_image->currentFrameKnownToBeOpaque(); 329 329 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); 332 331 decoder.setData(m_image->data(), true); 333 332 if (!decoder.frameCount()) -
trunk/Source/WebCore/platform/graphics/cg/ImageDecoderCG.cpp
r206156 r206481 119 119 #endif 120 120 121 ImageDecoder::ImageDecoder( )121 ImageDecoder::ImageDecoder(AlphaOption, GammaAndColorProfileOption) 122 122 { 123 123 m_nativeDecoder = adoptCF(CGImageSourceCreateIncremental(nullptr)); … … 153 153 return CFDictionaryContainsKey(image0Properties.get(), kCGImagePropertyPixelWidth) 154 154 && CFDictionaryContainsKey(image0Properties.get(), kCGImagePropertyPixelHeight); 155 }156 157 IntSize ImageDecoder::size() const158 {159 if (m_size.isEmpty())160 m_size = frameSizeAtIndex(0);161 return m_size;162 155 } 163 156 … … 375 368 } 376 369 377 void ImageDecoder::setData(CFDataRef data, bool allDataReceived)378 {379 CGImageSourceUpdateData(m_nativeDecoder.get(), data, allDataReceived);380 }381 382 370 void ImageDecoder::setData(SharedBuffer& data, bool allDataReceived) 383 371 { 372 m_isAllDataReceived = allDataReceived; 373 384 374 #if PLATFORM(COCOA) 385 375 // On Mac the NSData inside the SharedBuffer can be secretly appended to without the SharedBuffer's knowledge. 386 376 // We use SharedBuffer's ability to wrap itself inside CFData to get around this, ensuring that ImageIO is 387 377 // really looking at the SharedBuffer. 388 setData(data.createCFData().get(), allDataReceived);378 CGImageSourceUpdateData(m_nativeDecoder.get(), data.createCFData().get(), allDataReceived); 389 379 #else 390 380 // Create a CGDataProvider to wrap the SharedBuffer. -
trunk/Source/WebCore/platform/graphics/cg/ImageDecoderCG.h
r206156 r206481 24 24 */ 25 25 26 #ifndef ImageDecoderCG_h 27 #define ImageDecoderCG_h 26 #pragma once 28 27 29 28 #include "ImageSourceCG.h" … … 40 39 WTF_MAKE_FAST_ALLOCATED; 41 40 public: 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) 45 44 { 46 return std::make_unique<ImageDecoder>( );45 return std::make_unique<ImageDecoder>(alphaOption, gammaAndColorProfileOption); 47 46 } 48 47 49 48 static size_t bytesDecodedToDetermineProperties(); 50 49 50 bool isSizeAvailable() const; 51 size_t frameCount() const; 52 RepetitionCount repetitionCount() const; 51 53 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; 57 55 58 RepetitionCount repetitionCount() const;59 Optional<IntPoint> hotSpot() const;60 61 56 IntSize frameSizeAtIndex(size_t, SubsamplingLevel = SubsamplingLevel::Default) const; 62 57 bool frameIsCompleteAtIndex(size_t) const; … … 70 65 NativeImagePtr createFrameImageAtIndex(size_t, SubsamplingLevel = SubsamplingLevel::Default) const; 71 66 72 void setData(CFDataRef, bool allDataReceived);73 67 void setData(SharedBuffer&, bool allDataReceived); 74 68 bool isAllDataReceived() const { return m_isAllDataReceived; } 75 69 void clearFrameBufferCache(size_t) { } 76 70 77 71 protected: 78 mutable IntSize m_size;72 bool m_isAllDataReceived { false }; 79 73 RetainPtr<CGImageSourceRef> m_nativeDecoder; 80 74 }; 81 75 82 76 } 83 84 #endif // ImageDecoderCG_h -
trunk/Source/WebCore/platform/graphics/cg/PDFDocumentImage.h
r204983 r206481 76 76 77 77 // FIXME: Implement this to be less conservative. 78 bool currentFrameKnownToBeOpaque() override { return false; }78 bool currentFrameKnownToBeOpaque() const override { return false; } 79 79 80 80 void dump(TextStream&) const override; -
trunk/Source/WebCore/platform/graphics/efl/GraphicsContext3DEfl.cpp
r199819 r206481 250 250 251 251 // 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); 253 255 254 256 if (!m_decoder) -
trunk/Source/WebCore/platform/graphics/mac/ImageMac.mm
r205682 r206481 48 48 void BitmapImage::invalidatePlatformData() 49 49 { 50 if ( m_frames.size() != 1)50 if (frameCount() != 1) 51 51 return; 52 52 -
trunk/Source/WebCore/platform/image-decoders/ImageDecoder.cpp
r206156 r206481 97 97 } 98 98 99 std::unique_ptr<ImageDecoder> ImageDecoder::create(const SharedBuffer& data, ImageSource::AlphaOption alphaOption, ImageSource::GammaAndColorProfileOption gammaAndColorProfileOption)99 std::unique_ptr<ImageDecoder> ImageDecoder::create(const SharedBuffer& data, AlphaOption alphaOption, GammaAndColorProfileOption gammaAndColorProfileOption) 100 100 { 101 101 static const unsigned lengthOfLongestSignature = 14; // To wit: "RIFF????WEBPVP" -
trunk/Source/WebCore/platform/image-decoders/ImageDecoder.h
r206156 r206481 29 29 #pragma once 30 30 31 #include "ImageBackingStore.h" 32 #include "ImageSource.h" 31 #include "ImageFrame.h" 33 32 #include "IntRect.h" 34 33 #include "IntSize.h" … … 43 42 namespace WebCore { 44 43 45 using ColorProfile = Vector<char>;46 47 44 // ImageDecoder is a base for all format-specific decoders 48 45 // (e.g. JPEGImageDecoder). This base manages the ImageFrame cache. … … 54 51 WTF_MAKE_NONCOPYABLE(ImageDecoder); WTF_MAKE_FAST_ALLOCATED; 55 52 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) 59 56 { 60 57 } … … 67 64 // we can't sniff a supported type from the provided data (possibly 68 65 // 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); 70 67 71 68 virtual String filenameExtension() const = 0; … … 123 120 // FIXME: Right now that has to be done by each subclass; factor the 124 121 // decode call out and use it here. 125 virtual size_t frameCount() { return 1; }122 virtual size_t frameCount() const { return 1; } 126 123 127 124 virtual RepetitionCount repetitionCount() const { return RepetitionCountNone; } -
trunk/Source/WebCore/platform/image-decoders/bmp/BMPImageDecoder.cpp
r206156 r206481 41 41 static const size_t sizeOfFileHeader = 14; 42 42 43 BMPImageDecoder::BMPImageDecoder(ImageSource::AlphaOption alphaOption, 44 ImageSource::GammaAndColorProfileOption gammaAndColorProfileOption) 43 BMPImageDecoder::BMPImageDecoder(AlphaOption alphaOption, GammaAndColorProfileOption gammaAndColorProfileOption) 45 44 : ImageDecoder(alphaOption, gammaAndColorProfileOption) 46 45 , m_decodedOffset(0) -
trunk/Source/WebCore/platform/image-decoders/bmp/BMPImageDecoder.h
r202677 r206481 29 29 */ 30 30 31 #ifndef BMPImageDecoder_h 32 #define BMPImageDecoder_h 31 #pragma once 33 32 34 33 #include "BMPImageReader.h" … … 39 38 class BMPImageDecoder final : public ImageDecoder { 40 39 public: 41 BMPImageDecoder( ImageSource::AlphaOption, ImageSource::GammaAndColorProfileOption);40 BMPImageDecoder(AlphaOption, GammaAndColorProfileOption); 42 41 43 42 // ImageDecoder … … 81 80 82 81 } // namespace WebCore 83 84 #endif -
trunk/Source/WebCore/platform/image-decoders/gif/GIFImageDecoder.cpp
r206156 r206481 32 32 namespace WebCore { 33 33 34 GIFImageDecoder::GIFImageDecoder( ImageSource::AlphaOption alphaOption, ImageSource::GammaAndColorProfileOption gammaAndColorProfileOption)34 GIFImageDecoder::GIFImageDecoder(AlphaOption alphaOption, GammaAndColorProfileOption gammaAndColorProfileOption) 35 35 : ImageDecoder(alphaOption, gammaAndColorProfileOption) 36 36 { … … 71 71 } 72 72 73 size_t GIFImageDecoder::frameCount() 74 { 75 decode(std::numeric_limits<unsigned>::max(), GIFFrameCountQuery);73 size_t GIFImageDecoder::frameCount() const 74 { 75 const_cast<GIFImageDecoder*>(this)->decode(std::numeric_limits<unsigned>::max(), GIFFrameCountQuery); 76 76 return m_frameBufferCache.size(); 77 77 } -
trunk/Source/WebCore/platform/image-decoders/gif/GIFImageDecoder.h
r206156 r206481 24 24 */ 25 25 26 #ifndef GIFImageDecoder_h 27 #define GIFImageDecoder_h 26 #pragma once 28 27 29 28 #include "ImageDecoder.h" … … 36 35 class GIFImageDecoder final : public ImageDecoder { 37 36 public: 38 GIFImageDecoder( ImageSource::AlphaOption, ImageSource::GammaAndColorProfileOption);37 GIFImageDecoder(AlphaOption, GammaAndColorProfileOption); 39 38 virtual ~GIFImageDecoder(); 40 39 … … 46 45 bool isSizeAvailable() override; 47 46 bool setSize(const IntSize&) override; 48 size_t frameCount() override;47 size_t frameCount() const override; 49 48 RepetitionCount repetitionCount() const override; 50 49 ImageFrame* frameBufferAtIndex(size_t index) override; … … 78 77 79 78 } // namespace WebCore 80 81 #endif -
trunk/Source/WebCore/platform/image-decoders/gif/GIFImageReader.cpp
r206156 r206481 78 78 #include <string.h> 79 79 #include "GIFImageDecoder.h" 80 #include "ImageSource.h"81 80 82 81 using WebCore::GIFImageDecoder; -
trunk/Source/WebCore/platform/image-decoders/gif/GIFImageReader.h
r206156 r206481 36 36 * ***** END LICENSE BLOCK ***** */ 37 37 38 #ifndef GIFImageReader_h 39 #define GIFImageReader_h 38 #pragma once 40 39 41 40 // Define ourselves as the clientPtr. Mozilla just hacked their C++ callback class into this old C decoder, … … 324 323 bool m_parseCompleted; 325 324 }; 326 327 #endif -
trunk/Source/WebCore/platform/image-decoders/ico/ICOImageDecoder.cpp
r206156 r206481 45 45 static const size_t sizeOfDirEntry = 16; 46 46 47 ICOImageDecoder::ICOImageDecoder(ImageSource::AlphaOption alphaOption, 48 ImageSource::GammaAndColorProfileOption gammaAndColorProfileOption) 47 ICOImageDecoder::ICOImageDecoder(AlphaOption alphaOption, GammaAndColorProfileOption gammaAndColorProfileOption) 49 48 : ImageDecoder(alphaOption, gammaAndColorProfileOption) 50 49 , m_decodedOffset(0) … … 96 95 } 97 96 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. 97 size_t ICOImageDecoder::frameCount() const 98 { 99 const_cast<ICOImageDecoder*>(this)->decode(0, true); 106 100 return m_frameBufferCache.size(); 107 101 } … … 181 175 m_pngDecoders[index] = nullptr; 182 176 } 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. 183 183 } 184 184 … … 218 218 if (!m_pngDecoders[index]) { 219 219 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); 222 222 setDataForPNGDecoderAtIndex(index); 223 223 } -
trunk/Source/WebCore/platform/image-decoders/ico/ICOImageDecoder.h
r205841 r206481 29 29 */ 30 30 31 #ifndef ICOImageDecoder_h 32 #define ICOImageDecoder_h 31 #pragma once 33 32 34 33 #include "BMPImageReader.h" … … 41 40 class ICOImageDecoder final : public ImageDecoder { 42 41 public: 43 ICOImageDecoder( ImageSource::AlphaOption, ImageSource::GammaAndColorProfileOption);42 ICOImageDecoder(AlphaOption, GammaAndColorProfileOption); 44 43 virtual ~ICOImageDecoder(); 45 44 … … 51 50 IntSize frameSizeAtIndex(size_t, SubsamplingLevel) override; 52 51 bool setSize(const IntSize&) override; 53 size_t frameCount() override;52 size_t frameCount() const override; 54 53 ImageFrame* frameBufferAtIndex(size_t) override; 55 54 // CAUTION: setFailed() deletes all readers and decoders. Be careful to … … 152 151 153 152 } // namespace WebCore 154 155 #endif -
trunk/Source/WebCore/platform/image-decoders/jpeg/JPEGImageDecoder.cpp
r206156 r206481 502 502 } 503 503 504 JPEGImageDecoder::JPEGImageDecoder(ImageSource::AlphaOption alphaOption, 505 ImageSource::GammaAndColorProfileOption gammaAndColorProfileOption) 504 JPEGImageDecoder::JPEGImageDecoder(AlphaOption alphaOption, GammaAndColorProfileOption gammaAndColorProfileOption) 506 505 : ImageDecoder(alphaOption, gammaAndColorProfileOption) 507 506 { -
trunk/Source/WebCore/platform/image-decoders/jpeg/JPEGImageDecoder.h
r205841 r206481 25 25 */ 26 26 27 #ifndef JPEGImageDecoder_h 28 #define JPEGImageDecoder_h 27 #pragma once 29 28 30 29 #include "ImageDecoder.h" … … 45 44 class JPEGImageDecoder final : public ImageDecoder { 46 45 public: 47 JPEGImageDecoder( ImageSource::AlphaOption, ImageSource::GammaAndColorProfileOption);46 JPEGImageDecoder(AlphaOption, GammaAndColorProfileOption); 48 47 virtual ~JPEGImageDecoder(); 49 48 … … 85 84 86 85 } // namespace WebCore 87 88 #endif -
trunk/Source/WebCore/platform/image-decoders/png/PNGImageDecoder.cpp
r206156 r206481 194 194 }; 195 195 196 PNGImageDecoder::PNGImageDecoder( ImageSource::AlphaOption alphaOption, ImageSource::GammaAndColorProfileOption gammaAndColorProfileOption)196 PNGImageDecoder::PNGImageDecoder(AlphaOption alphaOption, GammaAndColorProfileOption gammaAndColorProfileOption) 197 197 : ImageDecoder(alphaOption, gammaAndColorProfileOption) 198 198 , m_doNothingOnFailure(false) -
trunk/Source/WebCore/platform/image-decoders/png/PNGImageDecoder.h
r206156 r206481 24 24 */ 25 25 26 #ifndef PNGImageDecoder_h 27 #define PNGImageDecoder_h 26 #pragma once 28 27 29 28 #include "ImageDecoder.h" … … 39 38 class PNGImageDecoder final : public ImageDecoder { 40 39 public: 41 PNGImageDecoder( ImageSource::AlphaOption, ImageSource::GammaAndColorProfileOption);40 PNGImageDecoder(AlphaOption, GammaAndColorProfileOption); 42 41 virtual ~PNGImageDecoder(); 43 42 … … 45 44 String filenameExtension() const override { return "png"; } 46 45 #if ENABLE(APNG) 47 size_t frameCount() override { return m_frameCount; }46 size_t frameCount() const override { return m_frameCount; } 48 47 RepetitionCount repetitionCount() const override { return m_playCount-1; } 49 48 #endif … … 131 130 132 131 } // namespace WebCore 133 134 #endif -
trunk/Source/WebCore/platform/image-decoders/webp/WEBPImageDecoder.cpp
r206156 r206481 46 46 namespace WebCore { 47 47 48 WEBPImageDecoder::WEBPImageDecoder(ImageSource::AlphaOption alphaOption, 49 ImageSource::GammaAndColorProfileOption gammaAndColorProfileOption) 48 WEBPImageDecoder::WEBPImageDecoder(AlphaOption alphaOption, GammaAndColorProfileOption gammaAndColorProfileOption) 50 49 : ImageDecoder(alphaOption, gammaAndColorProfileOption) 51 50 , m_decoder(0) -
trunk/Source/WebCore/platform/image-decoders/webp/WEBPImageDecoder.h
r202677 r206481 27 27 */ 28 28 29 #ifndef WEBPImageDecoder_h 30 #define WEBPImageDecoder_h 29 #pragma once 31 30 32 31 #include "ImageDecoder.h" … … 40 39 class WEBPImageDecoder final : public ImageDecoder { 41 40 public: 42 WEBPImageDecoder( ImageSource::AlphaOption, ImageSource::GammaAndColorProfileOption);41 WEBPImageDecoder(AlphaOption, GammaAndColorProfileOption); 43 42 virtual ~WEBPImageDecoder(); 44 43 … … 60 59 61 60 #endif 62 63 #endif -
trunk/Source/WebCore/svg/graphics/SVGImage.h
r203469 r206481 90 90 91 91 // FIXME: Implement this to be less conservative. 92 bool currentFrameKnownToBeOpaque() final { return false; }92 bool currentFrameKnownToBeOpaque() const final { return false; } 93 93 94 94 void dump(TextStream&) const final; -
trunk/Source/WebCore/svg/graphics/SVGImageForContainer.h
r203469 r206481 62 62 63 63 // FIXME: Implement this to be less conservative. 64 bool currentFrameKnownToBeOpaque() final { return false; }64 bool currentFrameKnownToBeOpaque() const final { return false; } 65 65 66 66 NativeImagePtr nativeImageForCurrentFrame() final;
Note: See TracChangeset
for help on using the changeset viewer.