bool BitmapImage::dataChanged(bool allDataReceived) { destroyDecodedData(true); // Feed all the data we've seen so far to the image decoder. m_allDataReceived = allDataReceived; m_source.setData(m_data.get(), allDataReceived); // Image properties will not be available until the first frame of the file // reaches kCGImageStatusIncomplete. return isSizeAvailable(); }
bool BitmapImage::dataChanged(bool allDataReceived) { // Because we're modifying the current frame, clear its (now possibly // inaccurate) metadata as well. destroyMetadataAndNotify((!m_frames.isEmpty() && m_frames[m_frames.size() - 1].clear(true)) ? 1 : 0); // Feed all the data we've seen so far to the image decoder. m_allDataReceived = allDataReceived; m_source.setData(m_data.get(), allDataReceived); // Clear the frame count. m_haveFrameCount = false; m_hasUniformFrameSize = true; // Image properties will not be available until the first frame of the file // reaches kCGImageStatusIncomplete. return isSizeAvailable(); }
bool Image::setNativeData(NativeBytePtr data, bool allDataReceived) { #if __APPLE__ // FIXME: Will go away when we make PDF a subclass. if (m_isPDF) { if (allDataReceived && !m_PDFDoc) m_PDFDoc = new PDFDocumentImage(data); return m_PDFDoc; } #endif destroyDecodedData(true); // Feed all the data we've seen so far to the image decoder. m_source.setData(data, allDataReceived); // Image properties will not be available until the first frame of the file // reaches kCGImageStatusIncomplete. return isSizeAvailable(); }
bool BitmapImage::dataChanged(bool allDataReceived) { TRACE_EVENT0("blink", "BitmapImage::dataChanged"); // Clear all partially-decoded frames. For most image formats, there is only // one frame, but at least GIF and ICO can have more. With GIFs, the frames // come in order and we ask to decode them in order, waiting to request a // subsequent frame until the prior one is complete. Given that we clear // incomplete frames here, this means there is at most one incomplete frame // (even if we use destroyDecodedData() -- since it doesn't reset the // metadata), and it is after all the complete frames. // // With ICOs, on the other hand, we may ask for arbitrary frames at // different times (e.g. because we're displaying a higher-resolution image // in the content area and using a lower-resolution one for the favicon), // and the frames aren't even guaranteed to appear in the file in the same // order as in the directory, so an arbitrary number of the frames might be // incomplete (if we ask for frames for which we've not yet reached the // start of the frame data), and any or none of them might be the particular // frame affected by appending new data here. Thus we have to clear all the // incomplete frames to be safe. size_t frameBytesCleared = 0; for (size_t i = 0; i < m_frames.size(); ++i) { // NOTE: Don't call frameIsCompleteAtIndex() here, that will try to // decode any uncached (i.e. never-decoded or // cleared-on-a-previous-pass) frames! size_t frameBytes = m_frames[i].m_frameBytes; if (m_frames[i].m_haveMetadata && !m_frames[i].m_isComplete) frameBytesCleared += (m_frames[i].clear(true) ? frameBytes : 0); } destroyMetadataAndNotify(frameBytesCleared); // Feed all the data we've seen so far to the image decoder. m_allDataReceived = allDataReceived; ASSERT(data()); m_source.setData(*data(), allDataReceived); m_haveFrameCount = false; m_hasUniformFrameSize = true; return isSizeAvailable(); }
void ImageFrameCache::growFrames() { ASSERT(isSizeAvailable()); ASSERT(m_frames.size() <= frameCount()); m_frames.grow(frameCount()); }
bool BitmapImage::dataChanged(bool allDataReceived) { // Because we're modifying the current frame, clear its (now possibly // inaccurate) metadata as well. #if !PLATFORM(IOS) // Clear all partially-decoded frames. For most image formats, there is only // one frame, but at least GIF and ICO can have more. With GIFs, the frames // come in order and we ask to decode them in order, waiting to request a // subsequent frame until the prior one is complete. Given that we clear // incomplete frames here, this means there is at most one incomplete frame // (even if we use destroyDecodedData() -- since it doesn't reset the // metadata), and it is after all the complete frames. // // With ICOs, on the other hand, we may ask for arbitrary frames at // different times (e.g. because we're displaying a higher-resolution image // in the content area and using a lower-resolution one for the favicon), // and the frames aren't even guaranteed to appear in the file in the same // order as in the directory, so an arbitrary number of the frames might be // incomplete (if we ask for frames for which we've not yet reached the // start of the frame data), and any or none of them might be the particular // frame affected by appending new data here. Thus we have to clear all the // incomplete frames to be safe. unsigned frameBytesCleared = 0; for (size_t i = 0; i < m_frames.size(); ++i) { // NOTE: Don't call frameIsCompleteAtIndex() here, that will try to // decode any uncached (i.e. never-decoded or // cleared-on-a-previous-pass) frames! unsigned frameBytes = m_frames[i].m_frameBytes; if (m_frames[i].m_haveMetadata && !m_frames[i].m_isComplete) frameBytesCleared += (m_frames[i].clear(true) ? frameBytes : 0); } destroyMetadataAndNotify(frameBytesCleared, ClearedSource::No); #else // FIXME: why is this different for iOS? int deltaBytes = 0; if (!m_frames.isEmpty()) { int bytes = m_frames[m_frames.size() - 1].m_frameBytes; if (m_frames[m_frames.size() - 1].clear(true)) { deltaBytes += bytes; deltaBytes += m_decodedPropertiesSize; m_decodedPropertiesSize = 0; } } destroyMetadataAndNotify(deltaBytes, ClearedSource::No); #endif // Feed all the data we've seen so far to the image decoder. m_allDataReceived = allDataReceived; #if PLATFORM(IOS) // FIXME: We should expose a setting to enable/disable progressive loading and make this // code conditional on it. Then we can remove the PLATFORM(IOS)-guard. static const double chunkLoadIntervals[] = {0, 1, 3, 6, 15}; double interval = chunkLoadIntervals[std::min(m_progressiveLoadChunkCount, static_cast<uint16_t>(4))]; bool needsUpdate = false; if (currentTime() - m_progressiveLoadChunkTime > interval) { // The first time through, the chunk time will be 0 and the image will get an update. needsUpdate = true; m_progressiveLoadChunkTime = currentTime(); ASSERT(m_progressiveLoadChunkCount <= std::numeric_limits<uint16_t>::max()); ++m_progressiveLoadChunkCount; } if (needsUpdate || allDataReceived) m_source.setData(data(), allDataReceived); #else m_source.setData(data(), allDataReceived); #endif m_haveFrameCount = false; m_source.setNeedsUpdateMetadata(); return isSizeAvailable(); }