NativeImagePtr BitmapImage::frameImageAtIndex(size_t index, float presentationScaleHint) { if (index >= frameCount()) return nullptr; SubsamplingLevel subsamplingLevel = m_source.subsamplingLevelForScale(presentationScaleHint); // We may have cached a frame with a higher subsampling level, in which case we need to // re-decode with a lower level. if (index < m_frames.size() && m_frames[index].m_image && subsamplingLevel < m_frames[index].m_subsamplingLevel) { // If the image is already cached, but at too small a size, re-decode a larger version. int sizeChange = -m_frames[index].m_frameBytes; m_frames[index].clear(true); invalidatePlatformData(); m_decodedSize += sizeChange; if (imageObserver()) imageObserver()->decodedSizeChanged(this, sizeChange); } // If we haven't fetched a frame yet, do so. if (index >= m_frames.size() || !m_frames[index].m_image) cacheFrame(index, subsamplingLevel, CacheMetadataAndFrame); return m_frames[index].m_image; }
void BitmapImage::destroyDecodedData(bool incremental) { // Destroy the cached images and release them. if (m_frames.size()) { int sizeChange = 0; int frameSize = m_size.width() * m_size.height() * 4; for (unsigned i = incremental ? m_frames.size() - 1 : 0; i < m_frames.size(); i++) { if (m_frames[i].m_frame) { sizeChange -= frameSize; m_frames[i].clear(); } } // We just always invalidate our platform data, even in the incremental case. // This could be better, but it's not a big deal. m_isSolidColor = false; invalidatePlatformData(); if (sizeChange) { m_decodedSize += sizeChange; if (imageObserver()) imageObserver()->decodedSizeChanged(this, sizeChange); } if (!incremental) { // Reset the image source, since Image I/O has an underlying cache that it uses // while animating that it seems to never clear. m_source.clear(); m_source.setData(m_data.get(), m_allDataReceived); } } }
void BitmapImage::destroyMetadataAndNotify(int framesCleared) { m_isSolidColor = false; invalidatePlatformData(); const int deltaBytes = framesCleared * -frameBytes(m_size); m_decodedSize += deltaBytes; if (deltaBytes && imageObserver()) imageObserver()->decodedSizeChanged(this, deltaBytes); }
void BitmapImage::destroyMetadataAndNotify(unsigned frameBytesCleared) { m_isSolidColor = false; m_checkedForSolidColor = false; invalidatePlatformData(); ASSERT(m_decodedSize >= frameBytesCleared); m_decodedSize -= frameBytesCleared; if (frameBytesCleared > 0) { frameBytesCleared += m_decodedPropertiesSize; m_decodedPropertiesSize = 0; } if (frameBytesCleared && imageObserver()) imageObserver()->decodedSizeChanged(this, -safeCast<int>(frameBytesCleared)); }
void BitmapImage::destroyMetadataAndNotify(int framesCleared) { m_isSolidColor = false; m_checkedForSolidColor = false; invalidatePlatformData(); int deltaBytes = framesCleared * -frameBytes(m_size); m_decodedSize += deltaBytes; if (framesCleared > 0) { deltaBytes -= m_decodedPropertiesSize; m_decodedPropertiesSize = 0; } if (deltaBytes && imageObserver()) imageObserver()->decodedSizeChanged(this, deltaBytes); }
void BitmapImage::destroyMetadataAndNotify(unsigned frameBytesCleared, ClearedSource clearedSource) { m_solidColor = Nullopt; invalidatePlatformData(); ASSERT(m_decodedSize >= frameBytesCleared); m_decodedSize -= frameBytesCleared; // Clearing the ImageSource destroys the extra decoded data used for determining image properties. if (clearedSource == ClearedSource::Yes) { frameBytesCleared += m_decodedPropertiesSize; m_decodedPropertiesSize = 0; } if (frameBytesCleared && imageObserver()) imageObserver()->decodedSizeChanged(this, -safeCast<int>(frameBytesCleared)); }
BitmapImage::~BitmapImage() { invalidatePlatformData(); stopAnimation(); }