Esempio n. 1
0
// Tests for a crash that used to happen for a specific file with specific
// sequence of method calls.
TEST(AnimatedWebPTests, reproCrash) {
  std::unique_ptr<ImageDecoder> decoder = createDecoder();

  RefPtr<SharedBuffer> fullData =
      readFile("/LayoutTests/images/resources/invalid_vp8_vp8x.webp");
  ASSERT_TRUE(fullData.get());

  // Parse partial data up to which error in bitstream is not detected.
  const size_t partialSize = 32768;
  ASSERT_GT(fullData->size(), partialSize);
  RefPtr<SharedBuffer> data =
      SharedBuffer::create(fullData->data(), partialSize);
  decoder->setData(data.get(), false);
  EXPECT_EQ(1u, decoder->frameCount());
  ImageFrame* frame = decoder->frameBufferAtIndex(0);
  ASSERT_TRUE(frame);
  EXPECT_EQ(ImageFrame::FramePartial, frame->getStatus());
  EXPECT_FALSE(decoder->failed());

  // Parse full data now. The error in bitstream should now be detected.
  decoder->setData(fullData.get(), true);
  EXPECT_EQ(1u, decoder->frameCount());
  frame = decoder->frameBufferAtIndex(0);
  ASSERT_TRUE(frame);
  EXPECT_EQ(ImageFrame::FramePartial, frame->getStatus());
  EXPECT_EQ(cAnimationLoopOnce, decoder->repetitionCount());
  EXPECT_TRUE(decoder->failed());
}
Esempio n. 2
0
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());
}
Esempio n. 3
0
TEST(AnimatedWebPTests, truncatedInBetweenFrame) {
  std::unique_ptr<ImageDecoder> decoder = createDecoder();

  RefPtr<SharedBuffer> fullData =
      readFile("/LayoutTests/images/resources/invalid-animated-webp4.webp");
  ASSERT_TRUE(fullData.get());
  RefPtr<SharedBuffer> data =
      SharedBuffer::create(fullData->data(), fullData->size() - 1);
  decoder->setData(data.get(), false);

  ImageFrame* frame = decoder->frameBufferAtIndex(1);
  ASSERT_TRUE(frame);
  EXPECT_EQ(ImageFrame::FrameComplete, frame->getStatus());
  frame = decoder->frameBufferAtIndex(2);
  ASSERT_TRUE(frame);
  EXPECT_EQ(ImageFrame::FramePartial, frame->getStatus());
  EXPECT_TRUE(decoder->failed());
}
Esempio n. 4
0
TEST(AnimatedWebPTests, truncatedLastFrame) {
  std::unique_ptr<ImageDecoder> decoder = createDecoder();

  RefPtr<SharedBuffer> data =
      readFile("/LayoutTests/images/resources/invalid-animated-webp2.webp");
  ASSERT_TRUE(data.get());
  decoder->setData(data.get(), true);

  size_t frameCount = 8;
  EXPECT_EQ(frameCount, decoder->frameCount());
  ImageFrame* frame = decoder->frameBufferAtIndex(0);
  ASSERT_TRUE(frame);
  EXPECT_EQ(ImageFrame::FrameComplete, frame->getStatus());
  EXPECT_FALSE(decoder->failed());
  frame = decoder->frameBufferAtIndex(frameCount - 1);
  ASSERT_TRUE(frame);
  EXPECT_EQ(ImageFrame::FramePartial, frame->getStatus());
  EXPECT_TRUE(decoder->failed());
  frame = decoder->frameBufferAtIndex(0);
  ASSERT_TRUE(frame);
  EXPECT_EQ(ImageFrame::FrameComplete, frame->getStatus());
}
Esempio n. 5
0
ImageFrame* ImageDecoder::frameBufferAtIndex(size_t index) {
  if (index >= frameCount())
    return 0;

  ImageFrame* frame = &m_frameBufferCache[index];
  if (frame->getStatus() != ImageFrame::FrameComplete) {
    PlatformInstrumentation::willDecodeImage(filenameExtension());
    decode(index);
    PlatformInstrumentation::didDecodeImage();
  }

  if (!m_hasHistogrammedColorSpace) {
    BitmapImageMetrics::countImageGamma(m_embeddedColorSpace.get());
    m_hasHistogrammedColorSpace = true;
  }

  frame->notifyBitmapIfPixelsChanged();
  return frame;
}