Bug 1262549 - Refuse to allocate huge deinterlacing buffers. r=edwin

This commit is contained in:
Seth Fowler 2016-06-23 11:13:14 -07:00
parent 120cdf42f2
commit f3f1ed4efa
6 changed files with 165 additions and 112 deletions

View File

@ -21,6 +21,7 @@
#include "mozilla/gfx/2D.h"
#include "DownscalingFilter.h"
#include "SurfaceCache.h"
#include "SurfacePipe.h"
namespace mozilla {
@ -91,6 +92,14 @@ public:
outputSize.height *
sizeof(PixelType);
// Use the size of the SurfaceCache as a heuristic to avoid gigantic
// allocations. Even if DownscalingFilter allowed us to allocate space for
// the output image, the deinterlacing buffer may still be too big, and
// fallible allocation won't always save us in the presence of overcommit.
if (!SurfaceCache::CanHold(bufferSize)) {
return NS_ERROR_OUT_OF_MEMORY;
}
// Allocate the buffer, which contains deinterlaced scanlines of the image.
// The buffer is necessary so that we can output rows which have already
// been deinterlaced again on subsequent passes. Since a later stage in the

View File

@ -22,16 +22,6 @@ using namespace mozilla;
using namespace mozilla::gfx;
using namespace mozilla::image;
TEST(ImageDecodeToSurface, ImageModuleAvailable)
{
// We can run into problems if XPCOM modules get initialized in the wrong
// order. It's important that this test run first, both as a sanity check and
// to ensure we get the module initialization order we want.
nsCOMPtr<imgITools> imgTools =
do_CreateInstance("@mozilla.org/image/tools;1");
EXPECT_TRUE(imgTools != nullptr);
}
class DecodeToSurfaceRunnable : public Runnable
{
public:
@ -95,24 +85,35 @@ RunDecodeToSurface(const ImageTestCase& aTestCase)
surface = nullptr;
}
TEST(ImageDecodeToSurface, PNG) { RunDecodeToSurface(GreenPNGTestCase()); }
TEST(ImageDecodeToSurface, GIF) { RunDecodeToSurface(GreenGIFTestCase()); }
TEST(ImageDecodeToSurface, JPG) { RunDecodeToSurface(GreenJPGTestCase()); }
TEST(ImageDecodeToSurface, BMP) { RunDecodeToSurface(GreenBMPTestCase()); }
TEST(ImageDecodeToSurface, ICO) { RunDecodeToSurface(GreenICOTestCase()); }
TEST(ImageDecodeToSurface, Icon) { RunDecodeToSurface(GreenIconTestCase()); }
class ImageDecodeToSurface : public ::testing::Test
{
protected:
static void SetUpTestCase()
{
// Ensure that ImageLib services are initialized.
nsCOMPtr<imgITools> imgTools = do_CreateInstance("@mozilla.org/image/tools;1");
EXPECT_TRUE(imgTools != nullptr);
}
};
TEST(ImageDecodeToSurface, AnimatedGIF)
TEST_F(ImageDecodeToSurface, PNG) { RunDecodeToSurface(GreenPNGTestCase()); }
TEST_F(ImageDecodeToSurface, GIF) { RunDecodeToSurface(GreenGIFTestCase()); }
TEST_F(ImageDecodeToSurface, JPG) { RunDecodeToSurface(GreenJPGTestCase()); }
TEST_F(ImageDecodeToSurface, BMP) { RunDecodeToSurface(GreenBMPTestCase()); }
TEST_F(ImageDecodeToSurface, ICO) { RunDecodeToSurface(GreenICOTestCase()); }
TEST_F(ImageDecodeToSurface, Icon) { RunDecodeToSurface(GreenIconTestCase()); }
TEST_F(ImageDecodeToSurface, AnimatedGIF)
{
RunDecodeToSurface(GreenFirstFrameAnimatedGIFTestCase());
}
TEST(ImageDecodeToSurface, AnimatedPNG)
TEST_F(ImageDecodeToSurface, AnimatedPNG)
{
RunDecodeToSurface(GreenFirstFrameAnimatedPNGTestCase());
}
TEST(ImageDecodeToSurface, Corrupt)
TEST_F(ImageDecodeToSurface, Corrupt)
{
ImageTestCase testCase = CorruptTestCase();

View File

@ -28,16 +28,6 @@ using namespace mozilla;
using namespace mozilla::gfx;
using namespace mozilla::image;
TEST(ImageDecoders, ImageModuleAvailable)
{
// We can run into problems if XPCOM modules get initialized in the wrong
// order. It's important that this test run first, both as a sanity check and
// to ensure we get the module initialization order we want.
nsCOMPtr<imgITools> imgTools =
do_CreateInstance("@mozilla.org/image/tools;1");
EXPECT_TRUE(imgTools != nullptr);
}
static already_AddRefed<SourceSurface>
CheckDecoderState(const ImageTestCase& aTestCase, Decoder* aDecoder)
{
@ -225,152 +215,163 @@ CheckDownscaleDuringDecode(const ImageTestCase& aTestCase)
});
}
TEST(ImageDecoders, PNGSingleChunk)
class ImageDecoders : public ::testing::Test
{
protected:
static void SetUpTestCase()
{
// Ensure that ImageLib services are initialized.
nsCOMPtr<imgITools> imgTools = do_CreateInstance("@mozilla.org/image/tools;1");
EXPECT_TRUE(imgTools != nullptr);
}
};
TEST_F(ImageDecoders, PNGSingleChunk)
{
CheckDecoderSingleChunk(GreenPNGTestCase());
}
TEST(ImageDecoders, PNGMultiChunk)
TEST_F(ImageDecoders, PNGMultiChunk)
{
CheckDecoderMultiChunk(GreenPNGTestCase());
}
TEST(ImageDecoders, PNGDownscaleDuringDecode)
TEST_F(ImageDecoders, PNGDownscaleDuringDecode)
{
CheckDownscaleDuringDecode(DownscaledPNGTestCase());
}
TEST(ImageDecoders, GIFSingleChunk)
TEST_F(ImageDecoders, GIFSingleChunk)
{
CheckDecoderSingleChunk(GreenGIFTestCase());
}
TEST(ImageDecoders, GIFMultiChunk)
TEST_F(ImageDecoders, GIFMultiChunk)
{
CheckDecoderMultiChunk(GreenGIFTestCase());
}
TEST(ImageDecoders, GIFDownscaleDuringDecode)
TEST_F(ImageDecoders, GIFDownscaleDuringDecode)
{
CheckDownscaleDuringDecode(DownscaledGIFTestCase());
}
TEST(ImageDecoders, JPGSingleChunk)
TEST_F(ImageDecoders, JPGSingleChunk)
{
CheckDecoderSingleChunk(GreenJPGTestCase());
}
TEST(ImageDecoders, JPGMultiChunk)
TEST_F(ImageDecoders, JPGMultiChunk)
{
CheckDecoderMultiChunk(GreenJPGTestCase());
}
TEST(ImageDecoders, JPGDownscaleDuringDecode)
TEST_F(ImageDecoders, JPGDownscaleDuringDecode)
{
CheckDownscaleDuringDecode(DownscaledJPGTestCase());
}
TEST(ImageDecoders, BMPSingleChunk)
TEST_F(ImageDecoders, BMPSingleChunk)
{
CheckDecoderSingleChunk(GreenBMPTestCase());
}
TEST(ImageDecoders, BMPMultiChunk)
TEST_F(ImageDecoders, BMPMultiChunk)
{
CheckDecoderMultiChunk(GreenBMPTestCase());
}
TEST(ImageDecoders, BMPDownscaleDuringDecode)
TEST_F(ImageDecoders, BMPDownscaleDuringDecode)
{
CheckDownscaleDuringDecode(DownscaledBMPTestCase());
}
TEST(ImageDecoders, ICOSingleChunk)
TEST_F(ImageDecoders, ICOSingleChunk)
{
CheckDecoderSingleChunk(GreenICOTestCase());
}
TEST(ImageDecoders, ICOMultiChunk)
TEST_F(ImageDecoders, ICOMultiChunk)
{
CheckDecoderMultiChunk(GreenICOTestCase());
}
TEST(ImageDecoders, ICODownscaleDuringDecode)
TEST_F(ImageDecoders, ICODownscaleDuringDecode)
{
CheckDownscaleDuringDecode(DownscaledICOTestCase());
}
TEST(ImageDecoders, ICOWithANDMaskDownscaleDuringDecode)
TEST_F(ImageDecoders, ICOWithANDMaskDownscaleDuringDecode)
{
CheckDownscaleDuringDecode(DownscaledTransparentICOWithANDMaskTestCase());
}
TEST(ImageDecoders, IconSingleChunk)
TEST_F(ImageDecoders, IconSingleChunk)
{
CheckDecoderSingleChunk(GreenIconTestCase());
}
TEST(ImageDecoders, IconMultiChunk)
TEST_F(ImageDecoders, IconMultiChunk)
{
CheckDecoderMultiChunk(GreenIconTestCase());
}
TEST(ImageDecoders, IconDownscaleDuringDecode)
TEST_F(ImageDecoders, IconDownscaleDuringDecode)
{
CheckDownscaleDuringDecode(DownscaledIconTestCase());
}
TEST(ImageDecoders, AnimatedGIFSingleChunk)
TEST_F(ImageDecoders, AnimatedGIFSingleChunk)
{
CheckDecoderSingleChunk(GreenFirstFrameAnimatedGIFTestCase());
}
TEST(ImageDecoders, AnimatedGIFMultiChunk)
TEST_F(ImageDecoders, AnimatedGIFMultiChunk)
{
CheckDecoderMultiChunk(GreenFirstFrameAnimatedGIFTestCase());
}
TEST(ImageDecoders, AnimatedPNGSingleChunk)
TEST_F(ImageDecoders, AnimatedPNGSingleChunk)
{
CheckDecoderSingleChunk(GreenFirstFrameAnimatedPNGTestCase());
}
TEST(ImageDecoders, AnimatedPNGMultiChunk)
TEST_F(ImageDecoders, AnimatedPNGMultiChunk)
{
CheckDecoderMultiChunk(GreenFirstFrameAnimatedPNGTestCase());
}
TEST(ImageDecoders, CorruptSingleChunk)
TEST_F(ImageDecoders, CorruptSingleChunk)
{
CheckDecoderSingleChunk(CorruptTestCase());
}
TEST(ImageDecoders, CorruptMultiChunk)
TEST_F(ImageDecoders, CorruptMultiChunk)
{
CheckDecoderMultiChunk(CorruptTestCase());
}
TEST(ImageDecoders, CorruptICOWithBadBMPWidthSingleChunk)
TEST_F(ImageDecoders, CorruptICOWithBadBMPWidthSingleChunk)
{
CheckDecoderSingleChunk(CorruptICOWithBadBMPWidthTestCase());
}
TEST(ImageDecoders, CorruptICOWithBadBMPWidthMultiChunk)
TEST_F(ImageDecoders, CorruptICOWithBadBMPWidthMultiChunk)
{
CheckDecoderMultiChunk(CorruptICOWithBadBMPWidthTestCase());
}
TEST(ImageDecoders, CorruptICOWithBadBMPHeightSingleChunk)
TEST_F(ImageDecoders, CorruptICOWithBadBMPHeightSingleChunk)
{
CheckDecoderSingleChunk(CorruptICOWithBadBMPHeightTestCase());
}
TEST(ImageDecoders, CorruptICOWithBadBMPHeightMultiChunk)
TEST_F(ImageDecoders, CorruptICOWithBadBMPHeightMultiChunk)
{
CheckDecoderMultiChunk(CorruptICOWithBadBMPHeightTestCase());
}
TEST(ImageDecoders, AnimatedGIFWithExtraImageSubBlocks)
TEST_F(ImageDecoders, AnimatedGIFWithExtraImageSubBlocks)
{
ImageTestCase testCase = ExtraImageSubBlocksAnimatedGIFTestCase();

View File

@ -59,7 +59,18 @@ AssertConfiguringDeinterlacingFilterFails(const IntSize& aSize)
SurfaceFormat::B8G8R8A8, false });
}
TEST(ImageDeinterlacingFilter, WritePixels100_100)
class ImageDeinterlacingFilter : public ::testing::Test
{
protected:
static void SetUpTestCase()
{
// Ensure that ImageLib services are initialized.
nsCOMPtr<imgITools> imgTools = do_CreateInstance("@mozilla.org/image/tools;1");
EXPECT_TRUE(imgTools != nullptr);
}
};
TEST_F(ImageDeinterlacingFilter, WritePixels100_100)
{
WithDeinterlacingFilter(IntSize(100, 100), /* aProgressiveDisplay = */ true,
[](Decoder* aDecoder, SurfaceFilter* aFilter) {
@ -69,7 +80,7 @@ TEST(ImageDeinterlacingFilter, WritePixels100_100)
});
}
TEST(ImageDeinterlacingFilter, WritePixels99_99)
TEST_F(ImageDeinterlacingFilter, WritePixels99_99)
{
WithDeinterlacingFilter(IntSize(99, 99), /* aProgressiveDisplay = */ true,
[](Decoder* aDecoder, SurfaceFilter* aFilter) {
@ -79,7 +90,7 @@ TEST(ImageDeinterlacingFilter, WritePixels99_99)
});
}
TEST(ImageDeinterlacingFilter, WritePixels8_8)
TEST_F(ImageDeinterlacingFilter, WritePixels8_8)
{
WithDeinterlacingFilter(IntSize(8, 8), /* aProgressiveDisplay = */ true,
[](Decoder* aDecoder, SurfaceFilter* aFilter) {
@ -89,7 +100,7 @@ TEST(ImageDeinterlacingFilter, WritePixels8_8)
});
}
TEST(ImageDeinterlacingFilter, WritePixels7_7)
TEST_F(ImageDeinterlacingFilter, WritePixels7_7)
{
WithDeinterlacingFilter(IntSize(7, 7), /* aProgressiveDisplay = */ true,
[](Decoder* aDecoder, SurfaceFilter* aFilter) {
@ -99,7 +110,7 @@ TEST(ImageDeinterlacingFilter, WritePixels7_7)
});
}
TEST(ImageDeinterlacingFilter, WritePixels3_3)
TEST_F(ImageDeinterlacingFilter, WritePixels3_3)
{
WithDeinterlacingFilter(IntSize(3, 3), /* aProgressiveDisplay = */ true,
[](Decoder* aDecoder, SurfaceFilter* aFilter) {
@ -109,7 +120,7 @@ TEST(ImageDeinterlacingFilter, WritePixels3_3)
});
}
TEST(ImageDeinterlacingFilter, WritePixels1_1)
TEST_F(ImageDeinterlacingFilter, WritePixels1_1)
{
WithDeinterlacingFilter(IntSize(1, 1), /* aProgressiveDisplay = */ true,
[](Decoder* aDecoder, SurfaceFilter* aFilter) {
@ -119,7 +130,7 @@ TEST(ImageDeinterlacingFilter, WritePixels1_1)
});
}
TEST(ImageDeinterlacingFilter, PalettedWritePixels)
TEST_F(ImageDeinterlacingFilter, PalettedWritePixels)
{
WithPalettedDeinterlacingFilter(IntSize(100, 100),
[](Decoder* aDecoder, SurfaceFilter* aFilter) {
@ -127,7 +138,7 @@ TEST(ImageDeinterlacingFilter, PalettedWritePixels)
});
}
TEST(ImageDeinterlacingFilter, WritePixelsNonProgressiveOutput51_52)
TEST_F(ImageDeinterlacingFilter, WritePixelsNonProgressiveOutput51_52)
{
WithDeinterlacingFilter(IntSize(51, 52), /* aProgressiveDisplay = */ false,
[](Decoder* aDecoder, SurfaceFilter* aFilter) {
@ -233,7 +244,7 @@ TEST(ImageDeinterlacingFilter, WritePixelsNonProgressiveOutput51_52)
});
}
TEST(ImageDeinterlacingFilter, WritePixelsOutput20_20)
TEST_F(ImageDeinterlacingFilter, WritePixelsOutput20_20)
{
WithDeinterlacingFilter(IntSize(20, 20), /* aProgressiveDisplay = */ true,
[](Decoder* aDecoder, SurfaceFilter* aFilter) {
@ -307,7 +318,7 @@ TEST(ImageDeinterlacingFilter, WritePixelsOutput20_20)
});
}
TEST(ImageDeinterlacingFilter, WritePixelsOutput7_7)
TEST_F(ImageDeinterlacingFilter, WritePixelsOutput7_7)
{
WithDeinterlacingFilter(IntSize(7, 7), /* aProgressiveDisplay = */ true,
[](Decoder* aDecoder, SurfaceFilter* aFilter) {
@ -369,7 +380,7 @@ TEST(ImageDeinterlacingFilter, WritePixelsOutput7_7)
});
}
TEST(ImageDeinterlacingFilter, WritePixelsOutput3_3)
TEST_F(ImageDeinterlacingFilter, WritePixelsOutput3_3)
{
WithDeinterlacingFilter(IntSize(3, 3), /* aProgressiveDisplay = */ true,
[](Decoder* aDecoder, SurfaceFilter* aFilter) {
@ -422,7 +433,7 @@ TEST(ImageDeinterlacingFilter, WritePixelsOutput3_3)
});
}
TEST(ImageDeinterlacingFilter, WritePixelsOutput1_1)
TEST_F(ImageDeinterlacingFilter, WritePixelsOutput1_1)
{
WithDeinterlacingFilter(IntSize(1, 1), /* aProgressiveDisplay = */ true,
[](Decoder* aDecoder, SurfaceFilter* aFilter) {
@ -490,7 +501,7 @@ WriteRowAndCheckInterlacerOutput(Decoder* aDecoder,
}
}
TEST(ImageDeinterlacingFilter, WritePixelsIntermediateOutput7_7)
TEST_F(ImageDeinterlacingFilter, WritePixelsIntermediateOutput7_7)
{
WithDeinterlacingFilter(IntSize(7, 7), /* aProgressiveDisplay = */ true,
[](Decoder* aDecoder, SurfaceFilter* aFilter) {
@ -571,7 +582,7 @@ TEST(ImageDeinterlacingFilter, WritePixelsIntermediateOutput7_7)
});
}
TEST(ImageDeinterlacingFilter, WritePixelsNonProgressiveIntermediateOutput7_7)
TEST_F(ImageDeinterlacingFilter, WritePixelsNonProgressiveIntermediateOutput7_7)
{
WithDeinterlacingFilter(IntSize(7, 7), /* aProgressiveDisplay = */ false,
[](Decoder* aDecoder, SurfaceFilter* aFilter) {
@ -653,13 +664,13 @@ TEST(ImageDeinterlacingFilter, WritePixelsNonProgressiveIntermediateOutput7_7)
}
TEST(ImageDeinterlacingFilter, DeinterlacingFailsFor0_0)
TEST_F(ImageDeinterlacingFilter, DeinterlacingFailsFor0_0)
{
// A 0x0 input size is invalid, so configuration should fail.
AssertConfiguringDeinterlacingFilterFails(IntSize(0, 0));
}
TEST(ImageDeinterlacingFilter, DeinterlacingFailsForMinus1_Minus1)
TEST_F(ImageDeinterlacingFilter, DeinterlacingFailsForMinus1_Minus1)
{
// A negative input size is invalid, so configuration should fail.
AssertConfiguringDeinterlacingFilterFails(IntSize(-1, -1));

View File

@ -28,16 +28,6 @@ using namespace mozilla;
using namespace mozilla::gfx;
using namespace mozilla::image;
TEST(ImageMetadata, ImageModuleAvailable)
{
// We can run into problems if XPCOM modules get initialized in the wrong
// order. It's important that this test run first, both as a sanity check and
// to ensure we get the module initialization order we want.
nsCOMPtr<imgITools> imgTools =
do_CreateInstance("@mozilla.org/image/tools;1");
EXPECT_TRUE(imgTools != nullptr);
}
enum class BMPWithinICO
{
NO,
@ -140,53 +130,64 @@ CheckMetadata(const ImageTestCase& aTestCase,
(fullProgress & FLAG_IS_ANIMATED));
}
TEST(ImageMetadata, PNG) { CheckMetadata(GreenPNGTestCase()); }
TEST(ImageMetadata, TransparentPNG) { CheckMetadata(TransparentPNGTestCase()); }
TEST(ImageMetadata, GIF) { CheckMetadata(GreenGIFTestCase()); }
TEST(ImageMetadata, TransparentGIF) { CheckMetadata(TransparentGIFTestCase()); }
TEST(ImageMetadata, JPG) { CheckMetadata(GreenJPGTestCase()); }
TEST(ImageMetadata, BMP) { CheckMetadata(GreenBMPTestCase()); }
TEST(ImageMetadata, ICO) { CheckMetadata(GreenICOTestCase()); }
TEST(ImageMetadata, Icon) { CheckMetadata(GreenIconTestCase()); }
class ImageDecoderMetadata : public ::testing::Test
{
protected:
static void SetUpTestCase()
{
// Ensure that ImageLib services are initialized.
nsCOMPtr<imgITools> imgTools = do_CreateInstance("@mozilla.org/image/tools;1");
EXPECT_TRUE(imgTools != nullptr);
}
};
TEST(ImageMetadata, AnimatedGIF)
TEST_F(ImageDecoderMetadata, PNG) { CheckMetadata(GreenPNGTestCase()); }
TEST_F(ImageDecoderMetadata, TransparentPNG) { CheckMetadata(TransparentPNGTestCase()); }
TEST_F(ImageDecoderMetadata, GIF) { CheckMetadata(GreenGIFTestCase()); }
TEST_F(ImageDecoderMetadata, TransparentGIF) { CheckMetadata(TransparentGIFTestCase()); }
TEST_F(ImageDecoderMetadata, JPG) { CheckMetadata(GreenJPGTestCase()); }
TEST_F(ImageDecoderMetadata, BMP) { CheckMetadata(GreenBMPTestCase()); }
TEST_F(ImageDecoderMetadata, ICO) { CheckMetadata(GreenICOTestCase()); }
TEST_F(ImageDecoderMetadata, Icon) { CheckMetadata(GreenIconTestCase()); }
TEST_F(ImageDecoderMetadata, AnimatedGIF)
{
CheckMetadata(GreenFirstFrameAnimatedGIFTestCase());
}
TEST(ImageMetadata, AnimatedPNG)
TEST_F(ImageDecoderMetadata, AnimatedPNG)
{
CheckMetadata(GreenFirstFrameAnimatedPNGTestCase());
}
TEST(ImageMetadata, FirstFramePaddingGIF)
TEST_F(ImageDecoderMetadata, FirstFramePaddingGIF)
{
CheckMetadata(FirstFramePaddingGIFTestCase());
}
TEST(ImageMetadata, TransparentIfWithinICOBMPNotWithinICO)
TEST_F(ImageDecoderMetadata, TransparentIfWithinICOBMPNotWithinICO)
{
CheckMetadata(TransparentIfWithinICOBMPTestCase(TEST_CASE_DEFAULT_FLAGS),
BMPWithinICO::NO);
}
TEST(ImageMetadata, TransparentIfWithinICOBMPWithinICO)
TEST_F(ImageDecoderMetadata, TransparentIfWithinICOBMPWithinICO)
{
CheckMetadata(TransparentIfWithinICOBMPTestCase(TEST_CASE_IS_TRANSPARENT),
BMPWithinICO::YES);
}
TEST(ImageMetadata, RLE4BMP) { CheckMetadata(RLE4BMPTestCase()); }
TEST(ImageMetadata, RLE8BMP) { CheckMetadata(RLE8BMPTestCase()); }
TEST_F(ImageDecoderMetadata, RLE4BMP) { CheckMetadata(RLE4BMPTestCase()); }
TEST_F(ImageDecoderMetadata, RLE8BMP) { CheckMetadata(RLE8BMPTestCase()); }
TEST(ImageMetadata, Corrupt) { CheckMetadata(CorruptTestCase()); }
TEST_F(ImageDecoderMetadata, Corrupt) { CheckMetadata(CorruptTestCase()); }
TEST(ImageMetadata, NoFrameDelayGIF)
TEST_F(ImageDecoderMetadata, NoFrameDelayGIF)
{
CheckMetadata(NoFrameDelayGIFTestCase());
}
TEST(ImageMetadata, NoFrameDelayGIFFullDecode)
TEST_F(ImageDecoderMetadata, NoFrameDelayGIFFullDecode)
{
ImageTestCase testCase = NoFrameDelayGIFTestCase();

View File

@ -129,7 +129,18 @@ CheckPalettedSurfacePipeMethodResults(SurfacePipe* aPipe,
EXPECT_TRUE(invalidRect.isNothing());
}
TEST(ImageSurfacePipeIntegration, SurfacePipe)
class ImageSurfacePipeIntegration : public ::testing::Test
{
protected:
static void SetUpTestCase()
{
// Ensure that ImageLib services are initialized.
nsCOMPtr<imgITools> imgTools = do_CreateInstance("@mozilla.org/image/tools;1");
EXPECT_TRUE(imgTools != nullptr);
}
};
TEST_F(ImageSurfacePipeIntegration, SurfacePipe)
{
// Test that SurfacePipe objects can be initialized and move constructed.
SurfacePipe pipe = TestSurfacePipeFactory::SimpleSurfacePipe();
@ -213,7 +224,7 @@ TEST(ImageSurfacePipeIntegration, SurfacePipe)
currentFrame->Finish();
}
TEST(ImageSurfacePipeIntegration, PalettedSurfacePipe)
TEST_F(ImageSurfacePipeIntegration, PalettedSurfacePipe)
{
// Create a SurfacePipe containing a PalettedSurfaceSink.
RefPtr<Decoder> decoder = CreateTrivialDecoder();
@ -293,7 +304,7 @@ TEST(ImageSurfacePipeIntegration, PalettedSurfacePipe)
currentFrame->Finish();
}
TEST(ImageSurfacePipeIntegration, DeinterlaceDownscaleWritePixels)
TEST_F(ImageSurfacePipeIntegration, DeinterlaceDownscaleWritePixels)
{
RefPtr<Decoder> decoder = CreateTrivialDecoder();
ASSERT_TRUE(decoder != nullptr);
@ -311,7 +322,7 @@ TEST(ImageSurfacePipeIntegration, DeinterlaceDownscaleWritePixels)
SurfaceFormat::B8G8R8A8, false });
}
TEST(ImageSurfacePipeIntegration, RemoveFrameRectBottomRightDownscaleWritePixels)
TEST_F(ImageSurfacePipeIntegration, RemoveFrameRectBottomRightDownscaleWritePixels)
{
// This test case uses a frame rect that extends beyond the borders of the
// image to the bottom and to the right. It looks roughly like this (with the
@ -367,7 +378,7 @@ TEST(ImageSurfacePipeIntegration, RemoveFrameRectBottomRightDownscaleWritePixels
SurfaceFormat::B8G8R8A8, false });
}
TEST(ImageSurfacePipeIntegration, RemoveFrameRectTopLeftDownscaleWritePixels)
TEST_F(ImageSurfacePipeIntegration, RemoveFrameRectTopLeftDownscaleWritePixels)
{
// This test case uses a frame rect that extends beyond the borders of the
// image to the top and to the left. It looks roughly like this (with the
@ -401,7 +412,7 @@ TEST(ImageSurfacePipeIntegration, RemoveFrameRectTopLeftDownscaleWritePixels)
SurfaceFormat::B8G8R8A8, false });
}
TEST(ImageSurfacePipeIntegration, DeinterlaceRemoveFrameRectWritePixels)
TEST_F(ImageSurfacePipeIntegration, DeinterlaceRemoveFrameRectWritePixels)
{
RefPtr<Decoder> decoder = CreateTrivialDecoder();
ASSERT_TRUE(decoder != nullptr);
@ -425,7 +436,7 @@ TEST(ImageSurfacePipeIntegration, DeinterlaceRemoveFrameRectWritePixels)
SurfaceFormat::B8G8R8A8, false });
}
TEST(ImageSurfacePipeIntegration, DeinterlaceRemoveFrameRectDownscaleWritePixels)
TEST_F(ImageSurfacePipeIntegration, DeinterlaceRemoveFrameRectDownscaleWritePixels)
{
RefPtr<Decoder> decoder = CreateTrivialDecoder();
ASSERT_TRUE(decoder != nullptr);
@ -448,7 +459,7 @@ TEST(ImageSurfacePipeIntegration, DeinterlaceRemoveFrameRectDownscaleWritePixels
SurfaceFormat::B8G8R8A8, false });
}
TEST(ImageSurfacePipeIntegration, ConfiguringPalettedRemoveFrameRectDownscaleFails)
TEST_F(ImageSurfacePipeIntegration, ConfiguringPalettedRemoveFrameRectDownscaleFails)
{
RefPtr<Decoder> decoder = CreateTrivialDecoder();
ASSERT_TRUE(decoder != nullptr);
@ -465,7 +476,7 @@ TEST(ImageSurfacePipeIntegration, ConfiguringPalettedRemoveFrameRectDownscaleFai
false });
}
TEST(ImageSurfacePipeIntegration, ConfiguringPalettedDeinterlaceDownscaleFails)
TEST_F(ImageSurfacePipeIntegration, ConfiguringPalettedDeinterlaceDownscaleFails)
{
RefPtr<Decoder> decoder = CreateTrivialDecoder();
ASSERT_TRUE(decoder != nullptr);
@ -481,3 +492,22 @@ TEST(ImageSurfacePipeIntegration, ConfiguringPalettedDeinterlaceDownscaleFails)
SurfaceFormat::B8G8R8A8, 8,
false });
}
TEST_F(ImageSurfacePipeIntegration, ConfiguringHugeDeinterlacingBufferFails)
{
RefPtr<Decoder> decoder = CreateTrivialDecoder();
ASSERT_TRUE(decoder != nullptr);
// When DownscalingFilter is used, we may succeed in allocating an output
// surface for huge images, because we only need to store the scaled-down
// version of the image. However, regardless of downscaling,
// DeinterlacingFilter needs to allocate a buffer as large as the size of the
// input. This can cause OOMs on operating systems that allow overcommit. This
// test makes sure that we reject such allocations.
AssertConfiguringPipelineFails(decoder,
DeinterlacingConfig<uint32_t> { /* mProgressiveDisplay = */ true},
DownscalingConfig { IntSize(60000, 60000),
SurfaceFormat::B8G8R8A8 },
SurfaceConfig { decoder, 0, IntSize(600, 600),
SurfaceFormat::B8G8R8A8, false });
}