TEST(ImageResourceTest, DecodedDataRemainsWhileHasClients)
{
    ResourcePtr<ImageResource> cachedImage = new ImageResource(ResourceRequest(), nullptr);
    cachedImage->setLoading(true);

    MockImageResourceClient client(cachedImage);

    // Send the image response.
    cachedImage->responseReceived(ResourceResponse(KURL(), "multipart/x-mixed-replace", 0, nullAtom, String()), nullptr);

    Vector<unsigned char> jpeg = jpegImage();
    cachedImage->responseReceived(ResourceResponse(KURL(), "image/jpeg", jpeg.size(), nullAtom, String()), nullptr);
    cachedImage->appendData(reinterpret_cast<const char*>(jpeg.data()), jpeg.size());
    cachedImage->finish();
    ASSERT_FALSE(cachedImage->errorOccurred());
    ASSERT_TRUE(cachedImage->hasImage());
    ASSERT_FALSE(cachedImage->image()->isNull());
    ASSERT_TRUE(client.notifyFinishedCalled());

    // The prune comes when the ImageResource still has clients. The image should not be deleted.
    cachedImage->prune();
    ASSERT_TRUE(cachedImage->hasClients());
    ASSERT_TRUE(cachedImage->hasImage());
    ASSERT_FALSE(cachedImage->image()->isNull());

    // The ImageResource no longer has clients. The image should be deleted by prune.
    client.removeAsClient();
    cachedImage->prune();
    ASSERT_FALSE(cachedImage->hasClients());
    ASSERT_FALSE(cachedImage->hasImage());
    ASSERT_TRUE(cachedImage->image()->isNull());
}
// Verifies that ImageBitmaps constructed from HTMLImageElements hold a reference to the original Image if the HTMLImageElement src is changed.
TEST_F(ImageBitmapTest, ImageBitmapSourceChanged)
{
    RefPtrWillBeRawPtr<HTMLImageElement> image = HTMLImageElement::create(*Document::create().get());
    ResourcePtr<ImageResource> originalImageResource = new ImageResource(
        StaticBitmapImage::create(m_image).get());
    image->setImageResource(originalImageResource.get());

    RefPtrWillBeRawPtr<ImageBitmap> imageBitmap = ImageBitmap::create(image.get(),
        IntRect(0, 0, m_image->width(), m_image->height()));
    ASSERT_EQ(imageBitmap->bitmapImage().get(), originalImageResource->image());

    ResourcePtr<ImageResource> newImageResource = new ImageResource(
        StaticBitmapImage::create(m_image2).get());
    image->setImageResource(newImageResource.get());

    // The ImageBitmap should contain the same data as the original cached image but should no longer hold a reference.
    {
        ASSERT_NE(imageBitmap->bitmapImage().get(), originalImageResource->image());
        RefPtr<SkImage> image1 = imageBitmap->bitmapImage()->imageForCurrentFrame();
        ASSERT_NE(image1, nullptr);
        RefPtr<SkImage> image2 = originalImageResource->image()->imageForCurrentFrame();
        ASSERT_NE(image2, nullptr);
        ASSERT_EQ(image1, image2);
    }

    {
        ASSERT_NE(imageBitmap->bitmapImage().get(), newImageResource->image());
        RefPtr<SkImage> image1 = imageBitmap->bitmapImage()->imageForCurrentFrame();
        ASSERT_NE(image1, nullptr);
        RefPtr<SkImage> image2 = newImageResource->image()->imageForCurrentFrame();
        ASSERT_NE(image2, nullptr);
        ASSERT_NE(image1, image2);
    }
}
TEST(ImageResourceTest, MultipartImage)
{
    ResourceFetcher* fetcher = ResourceFetcher::create(nullptr);
    KURL testURL(ParsedURLString, "http://www.test.com/cancelTest.html");
    URLTestHelpers::registerMockedURLLoad(testURL, "cancelTest.html", "text/html");

    // Emulate starting a real load, but don't expect any "real" WebURLLoaderClient callbacks.
    ResourcePtr<ImageResource> cachedImage = new ImageResource(ResourceRequest(testURL), nullptr);
    cachedImage->setIdentifier(createUniqueIdentifier());
    cachedImage->load(fetcher, ResourceLoaderOptions());
    Platform::current()->unitTestSupport()->unregisterMockedURL(testURL);

    MockImageResourceClient client(cachedImage);
    EXPECT_EQ(Resource::Pending, cachedImage->status());

    // Send the multipart response. No image or data buffer is created.
    // Note that the response must be routed through ResourceLoader to
    // ensure the load is flagged as multipart.
    ResourceResponse multipartResponse(KURL(), "multipart/x-mixed-replace", 0, nullAtom, String());
    cachedImage->loader()->didReceiveResponse(nullptr, WrappedResourceResponse(multipartResponse), nullptr);
    ASSERT_FALSE(cachedImage->resourceBuffer());
    ASSERT_FALSE(cachedImage->hasImage());
    ASSERT_EQ(client.imageChangedCount(), 0);
    ASSERT_FALSE(client.notifyFinishedCalled());

    // Send the response for the first real part. No image or data buffer is created.
    const char* svgData = "<svg xmlns='http://www.w3.org/2000/svg' width='1' height='1'><rect width='1' height='1' fill='green'/></svg>";
    unsigned svgDataLength = strlen(svgData);
    ResourceResponse payloadResponse(KURL(), "image/svg+xml", svgDataLength, nullAtom, String());
    cachedImage->loader()->didReceiveResponse(nullptr, WrappedResourceResponse(payloadResponse), nullptr);
    ASSERT_FALSE(cachedImage->resourceBuffer());
    ASSERT_FALSE(cachedImage->hasImage());
    ASSERT_EQ(client.imageChangedCount(), 0);
    ASSERT_FALSE(client.notifyFinishedCalled());

    // The first bytes arrive. The data buffer is created, but no image is created.
    cachedImage->appendData(svgData, svgDataLength);
    ASSERT_TRUE(cachedImage->resourceBuffer());
    ASSERT_EQ(cachedImage->resourceBuffer()->size(), svgDataLength);
    ASSERT_FALSE(cachedImage->hasImage());
    ASSERT_EQ(client.imageChangedCount(), 0);
    ASSERT_FALSE(client.notifyFinishedCalled());

    // This part finishes. The image is created, callbacks are sent, and the data buffer is cleared.
    cachedImage->finish();
    ASSERT_FALSE(cachedImage->resourceBuffer());
    ASSERT_FALSE(cachedImage->errorOccurred());
    ASSERT_TRUE(cachedImage->hasImage());
    ASSERT_FALSE(cachedImage->image()->isNull());
    ASSERT_EQ(cachedImage->image()->width(), 1);
    ASSERT_EQ(cachedImage->image()->height(), 1);
    ASSERT_EQ(client.imageChangedCount(), 2);
    ASSERT_TRUE(client.notifyFinishedCalled());
}
TEST(ImageResourceTest, UpdateBitmapImages)
{
    ResourcePtr<ImageResource> cachedImage = new ImageResource(ResourceRequest(), nullptr);
    cachedImage->setLoading(true);

    MockImageResourceClient client(cachedImage);

    // Send the image response.
    Vector<unsigned char> jpeg = jpegImage();
    cachedImage->responseReceived(ResourceResponse(KURL(), "image/jpeg", jpeg.size(), nullAtom, String()), nullptr);
    cachedImage->appendData(reinterpret_cast<const char*>(jpeg.data()), jpeg.size());
    cachedImage->finish();
    ASSERT_FALSE(cachedImage->errorOccurred());
    ASSERT_TRUE(cachedImage->hasImage());
    ASSERT_FALSE(cachedImage->image()->isNull());
    ASSERT_EQ(client.imageChangedCount(), 2);
    ASSERT_TRUE(client.notifyFinishedCalled());
    ASSERT_TRUE(cachedImage->image()->isBitmapImage());
}
예제 #5
0
// Verifies that ImageBitmaps constructed from HTMLImageElements hold a reference to the original Image if the HTMLImageElement src is changed.
TEST_F(ImageBitmapTest, ImageBitmapSourceChanged)
{
    RefPtr<HTMLImageElement> image = HTMLImageElement::create(*Document::create().get());
    ResourcePtr<ImageResource> originalImageResource = new ImageResource(BitmapImage::create(NativeImageSkia::create(m_bitmap)).get());
    image->setImageResource(originalImageResource.get());

    RefPtrWillBeRawPtr<ImageBitmap> imageBitmap = ImageBitmap::create(image.get(), IntRect(0, 0, m_bitmap.width(), m_bitmap.height()));
    ASSERT_EQ(imageBitmap->bitmapImage().get(), originalImageResource->image());

    ResourcePtr<ImageResource> newImageResource = new ImageResource(BitmapImage::create(NativeImageSkia::create(m_bitmap2)).get());
    image->setImageResource(newImageResource.get());

    // The ImageBitmap should contain the same data as the original cached image but should no longer hold a reference.
    ASSERT_NE(imageBitmap->bitmapImage().get(), originalImageResource->image());
    ASSERT_EQ(imageBitmap->bitmapImage()->nativeImageForCurrentFrame()->bitmap().pixelRef()->pixels(),
        originalImageResource->image()->nativeImageForCurrentFrame()->bitmap().pixelRef()->pixels());

    ASSERT_NE(imageBitmap->bitmapImage().get(), newImageResource->image());
    ASSERT_NE(imageBitmap->bitmapImage()->nativeImageForCurrentFrame()->bitmap().pixelRef()->pixels(),
        newImageResource->image()->nativeImageForCurrentFrame()->bitmap().pixelRef()->pixels());
}