TEST(AnimatedWebPTests, uniqueGenerationIDs) { std::unique_ptr<ImageDecoder> decoder = createDecoder(); RefPtr<SharedBuffer> data = readFile("/LayoutTests/images/resources/webp-animated.webp"); ASSERT_TRUE(data.get()); decoder->setData(data.get(), true); ImageFrame* frame = decoder->frameBufferAtIndex(0); uint32_t generationID0 = frame->bitmap().getGenerationID(); frame = decoder->frameBufferAtIndex(1); uint32_t generationID1 = frame->bitmap().getGenerationID(); EXPECT_TRUE(generationID0 != generationID1); }
void NotificationImageLoader::didFinishLoading(unsigned long resourceIdentifier, double finishTime) { // If this has been stopped it is not desirable to trigger further work, // there is a shutdown of some sort in progress. if (m_stopped) return; DEFINE_THREAD_SAFE_STATIC_LOCAL( CustomCountHistogram, finishedTimeHistogram, new CustomCountHistogram("Notifications.Icon.LoadFinishTime", 1, 1000 * 60 * 60 /* 1 hour max */, 50 /* buckets */)); finishedTimeHistogram.count(monotonicallyIncreasingTimeMS() - m_startTime); if (m_data) { DEFINE_THREAD_SAFE_STATIC_LOCAL( CustomCountHistogram, fileSizeHistogram, new CustomCountHistogram("Notifications.Icon.FileSize", 1, 10000000 /* ~10mb max */, 50 /* buckets */)); fileSizeHistogram.count(m_data->size()); std::unique_ptr<ImageDecoder> decoder = ImageDecoder::create( m_data, true /* dataComplete */, ImageDecoder::AlphaPremultiplied, ImageDecoder::ColorSpaceApplied); if (decoder) { // The |ImageFrame*| is owned by the decoder. ImageFrame* imageFrame = decoder->frameBufferAtIndex(0); if (imageFrame) { (*m_imageCallback)(imageFrame->bitmap()); return; } } } runCallbackWithEmptyBitmap(); }
bool DeferredImageDecoder::createFrameAtIndex(size_t index, SkBitmap* bitmap) { prepareLazyDecodedFrames(); if (index < m_frameData.size()) { // ImageFrameGenerator has the latest known alpha state. There will // be a performance boost if this frame is opaque. *bitmap = createBitmap(index); if (m_frameGenerator->hasAlpha(index)) { m_frameData[index].m_hasAlpha = true; bitmap->setAlphaType(kPremul_SkAlphaType); } else { m_frameData[index].m_hasAlpha = false; bitmap->setAlphaType(kOpaque_SkAlphaType); } m_frameData[index].m_frameBytes = m_size.area() * sizeof(ImageFrame::PixelData); return true; } if (m_actualDecoder) { ImageFrame* buffer = m_actualDecoder->frameBufferAtIndex(index); if (!buffer || buffer->status() == ImageFrame::FrameEmpty) return false; *bitmap = buffer->bitmap(); return true; } return false; }
sk_sp<SkImage> DeferredImageDecoder::createFrameAtIndex(size_t index) { if (m_frameGenerator && m_frameGenerator->decodeFailed()) return nullptr; prepareLazyDecodedFrames(); if (index < m_frameData.size()) { DeferredFrameData* frameData = &m_frameData[index]; if (m_actualDecoder) frameData->m_frameBytes = m_actualDecoder->frameBytesAtIndex(index); else frameData->m_frameBytes = m_size.area() * sizeof(ImageFrame::PixelData); // ImageFrameGenerator has the latest known alpha state. There will be a // performance boost if this frame is opaque. DCHECK(m_frameGenerator); return createFrameImageAtIndex(index, !m_frameGenerator->hasAlpha(index)); } if (!m_actualDecoder || m_actualDecoder->failed()) return nullptr; ImageFrame* frame = m_actualDecoder->frameBufferAtIndex(index); if (!frame || frame->getStatus() == ImageFrame::FrameEmpty) return nullptr; return (frame->getStatus() == ImageFrame::FrameComplete) ? frame->finalizePixelsAndGetImage() : SkImage::MakeFromBitmap(frame->bitmap()); }
static bool decodeBitmap(const void* data, size_t length, SkBitmap* result) { std::unique_ptr<ImageDecoder> imageDecoder = ImageDecoder::create(static_cast<const char*>(data), length, ImageDecoder::AlphaPremultiplied, ImageDecoder::GammaAndColorProfileIgnored); if (!imageDecoder) return false; // No need to copy the data; this decodes immediately. RefPtr<SegmentReader> segmentReader = SegmentReader::createFromSkData(adoptRef(SkData::NewWithoutCopy(data, length))); imageDecoder->setData(segmentReader.release(), true); ImageFrame* frame = imageDecoder->frameBufferAtIndex(0); if (!frame) return true; *result = frame->bitmap(); return true; }
SkBitmapRef* ImageSource::createFrameAtIndex(size_t index) { #ifdef ANDROID_ANIMATED_GIF if (m_decoder.m_gifDecoder) { ImageFrame* buffer = m_decoder.m_gifDecoder->frameBufferAtIndex(index); if (!buffer || buffer->status() == ImageFrame::FrameEmpty) return 0; SkBitmap& bitmap = buffer->bitmap(); SkPixelRef* pixelRef = bitmap.pixelRef(); if (pixelRef) pixelRef->setURI(m_decoder.m_url); return new SkBitmapRef(bitmap); } #else SkASSERT(index == 0); #endif SkASSERT(m_decoder.m_image != NULL); m_decoder.m_image->ref(); return m_decoder.m_image; }
PassRefPtr<SkImage> DeferredImageDecoder::createFrameAtIndex(size_t index) { prepareLazyDecodedFrames(); if (index < m_frameData.size()) { // ImageFrameGenerator has the latest known alpha state. There will be a // performance boost if this frame is opaque. FrameData* frameData = &m_frameData[index]; frameData->m_hasAlpha = m_frameGenerator->hasAlpha(index); frameData->m_frameBytes = m_size.area() * sizeof(ImageFrame::PixelData); return createImage(index, !frameData->m_hasAlpha); } if (!m_actualDecoder) return nullptr; ImageFrame* buffer = m_actualDecoder->frameBufferAtIndex(index); if (!buffer || buffer->status() == ImageFrame::FrameEmpty) return nullptr; return adoptRef(SkImage::NewFromBitmap(buffer->bitmap())); }