1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* This Source Code Form is subject to the terms of the Mozilla Public
3 * License, v. 2.0. If a copy of the MPL was not distributed with this
4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
10 #include "gfxPlatform.h"
12 #include "nsDirectoryServiceDefs.h"
13 #include "nsIDirectoryService.h"
15 #include "nsIInputStream.h"
16 #include "nsIProperties.h"
17 #include "nsNetUtil.h"
18 #include "mozilla/RefPtr.h"
19 #include "nsStreamUtils.h"
30 static bool sImageLibInitialized
= false;
32 AutoInitializeImageLib::AutoInitializeImageLib() {
33 if (MOZ_LIKELY(sImageLibInitialized
)) {
37 EXPECT_TRUE(NS_IsMainThread());
38 sImageLibInitialized
= true;
40 // Force sRGB to be consistent with reftests.
41 nsresult rv
= Preferences::SetBool("gfx.color_management.force_srgb", true);
42 EXPECT_TRUE(rv
== NS_OK
);
44 // Ensure WebP is enabled to run decoder tests.
45 rv
= Preferences::SetBool("image.webp.enabled", true);
46 EXPECT_TRUE(rv
== NS_OK
);
48 // Ensure that ImageLib services are initialized.
49 nsCOMPtr
<imgITools
> imgTools
=
50 do_CreateInstance("@mozilla.org/image/tools;1");
51 EXPECT_TRUE(imgTools
!= nullptr);
53 // Ensure gfxPlatform is initialized.
54 gfxPlatform::GetPlatform();
56 // Depending on initialization order, it is possible that our pref changes
57 // have not taken effect yet because there are pending gfx-related events on
62 void ImageBenchmarkBase::SetUp() {
63 nsCOMPtr
<nsIInputStream
> inputStream
= LoadFile(mTestCase
.mPath
);
64 ASSERT_TRUE(inputStream
!= nullptr);
66 // Figure out how much data we have.
68 nsresult rv
= inputStream
->Available(&length
);
69 ASSERT_TRUE(NS_SUCCEEDED(rv
));
71 // Write the data into a SourceBuffer.
72 mSourceBuffer
= new SourceBuffer();
73 mSourceBuffer
->ExpectLength(length
);
74 rv
= mSourceBuffer
->AppendFromInputStream(inputStream
, length
);
75 ASSERT_TRUE(NS_SUCCEEDED(rv
));
76 mSourceBuffer
->Complete(NS_OK
);
79 void ImageBenchmarkBase::TearDown() {}
81 ///////////////////////////////////////////////////////////////////////////////
83 ///////////////////////////////////////////////////////////////////////////////
85 // These macros work like gtest's ASSERT_* macros, except that they can be used
86 // in functions that return values.
87 #define ASSERT_TRUE_OR_RETURN(e, rv) \
93 #define ASSERT_EQ_OR_RETURN(a, b, rv) \
99 #define ASSERT_GE_OR_RETURN(a, b, rv) \
101 if (!((a) >= (b))) { \
105 #define ASSERT_LE_OR_RETURN(a, b, rv) \
107 if (!((a) <= (b))) { \
111 #define ASSERT_LT_OR_RETURN(a, b, rv) \
113 if (!((a) < (b))) { \
117 void SpinPendingEvents() {
118 nsCOMPtr
<nsIThread
> mainThread
= do_GetMainThread();
119 EXPECT_TRUE(mainThread
!= nullptr);
124 nsresult rv
= mainThread
->ProcessNextEvent(false, &processed
);
125 EXPECT_TRUE(NS_SUCCEEDED(rv
));
129 already_AddRefed
<nsIInputStream
> LoadFile(const char* aRelativePath
) {
132 nsCOMPtr
<nsIProperties
> dirService
=
133 do_GetService(NS_DIRECTORY_SERVICE_CONTRACTID
);
134 ASSERT_TRUE_OR_RETURN(dirService
!= nullptr, nullptr);
136 // Retrieve the current working directory.
137 nsCOMPtr
<nsIFile
> file
;
138 rv
= dirService
->Get(NS_OS_CURRENT_WORKING_DIR
, NS_GET_IID(nsIFile
),
139 getter_AddRefs(file
));
140 ASSERT_TRUE_OR_RETURN(NS_SUCCEEDED(rv
), nullptr);
142 // Construct the final path by appending the working path to the current
143 // working directory.
144 file
->AppendNative(nsDependentCString(aRelativePath
));
146 // Construct an input stream for the requested file.
147 nsCOMPtr
<nsIInputStream
> inputStream
;
148 rv
= NS_NewLocalFileInputStream(getter_AddRefs(inputStream
), file
);
149 ASSERT_TRUE_OR_RETURN(NS_SUCCEEDED(rv
), nullptr);
151 // Ensure the resulting input stream is buffered.
152 if (!NS_InputStreamIsBuffered(inputStream
)) {
153 nsCOMPtr
<nsIInputStream
> bufStream
;
154 rv
= NS_NewBufferedInputStream(getter_AddRefs(bufStream
),
155 inputStream
.forget(), 1024);
156 ASSERT_TRUE_OR_RETURN(NS_SUCCEEDED(rv
), nullptr);
157 inputStream
= bufStream
;
160 return inputStream
.forget();
163 bool IsSolidColor(SourceSurface
* aSurface
, BGRAColor aColor
,
164 uint8_t aFuzz
/* = 0 */) {
165 IntSize size
= aSurface
->GetSize();
166 return RectIsSolidColor(aSurface
, IntRect(0, 0, size
.width
, size
.height
),
170 bool RowsAreSolidColor(SourceSurface
* aSurface
, int32_t aStartRow
,
171 int32_t aRowCount
, BGRAColor aColor
,
172 uint8_t aFuzz
/* = 0 */) {
173 IntSize size
= aSurface
->GetSize();
174 return RectIsSolidColor(
175 aSurface
, IntRect(0, aStartRow
, size
.width
, aRowCount
), aColor
, aFuzz
);
178 bool RectIsSolidColor(SourceSurface
* aSurface
, const IntRect
& aRect
,
179 BGRAColor aColor
, uint8_t aFuzz
/* = 0 */) {
180 IntSize surfaceSize
= aSurface
->GetSize();
182 aRect
.Intersect(IntRect(0, 0, surfaceSize
.width
, surfaceSize
.height
));
184 RefPtr
<DataSourceSurface
> dataSurface
= aSurface
->GetDataSurface();
185 ASSERT_TRUE_OR_RETURN(dataSurface
!= nullptr, false);
187 DataSourceSurface::ScopedMap
mapping(dataSurface
,
188 DataSourceSurface::MapType::READ
);
189 ASSERT_TRUE_OR_RETURN(mapping
.IsMapped(), false);
190 ASSERT_EQ_OR_RETURN(mapping
.GetStride(), surfaceSize
.width
* 4, false);
192 uint8_t* data
= mapping
.GetData();
193 ASSERT_TRUE_OR_RETURN(data
!= nullptr, false);
195 BGRAColor pmColor
= aColor
.Premultiply();
196 int32_t rowLength
= mapping
.GetStride();
197 for (int32_t row
= rect
.Y(); row
< rect
.YMost(); ++row
) {
198 for (int32_t col
= rect
.X(); col
< rect
.XMost(); ++col
) {
199 int32_t i
= row
* rowLength
+ col
* 4;
201 ASSERT_LE_OR_RETURN(abs(pmColor
.mBlue
- data
[i
+ 0]), aFuzz
, false);
202 ASSERT_LE_OR_RETURN(abs(pmColor
.mGreen
- data
[i
+ 1]), aFuzz
, false);
203 ASSERT_LE_OR_RETURN(abs(pmColor
.mRed
- data
[i
+ 2]), aFuzz
, false);
204 ASSERT_LE_OR_RETURN(abs(pmColor
.mAlpha
- data
[i
+ 3]), aFuzz
, false);
206 ASSERT_EQ_OR_RETURN(pmColor
.mBlue
, data
[i
+ 0], false);
207 ASSERT_EQ_OR_RETURN(pmColor
.mGreen
, data
[i
+ 1], false);
208 ASSERT_EQ_OR_RETURN(pmColor
.mRed
, data
[i
+ 2], false);
209 ASSERT_EQ_OR_RETURN(pmColor
.mAlpha
, data
[i
+ 3], false);
217 bool RowHasPixels(SourceSurface
* aSurface
, int32_t aRow
,
218 const vector
<BGRAColor
>& aPixels
) {
219 ASSERT_GE_OR_RETURN(aRow
, 0, false);
221 IntSize surfaceSize
= aSurface
->GetSize();
222 ASSERT_EQ_OR_RETURN(aPixels
.size(), size_t(surfaceSize
.width
), false);
223 ASSERT_LT_OR_RETURN(aRow
, surfaceSize
.height
, false);
225 RefPtr
<DataSourceSurface
> dataSurface
= aSurface
->GetDataSurface();
226 ASSERT_TRUE_OR_RETURN(dataSurface
, false);
228 DataSourceSurface::ScopedMap
mapping(dataSurface
,
229 DataSourceSurface::MapType::READ
);
230 ASSERT_TRUE_OR_RETURN(mapping
.IsMapped(), false);
231 ASSERT_EQ_OR_RETURN(mapping
.GetStride(), surfaceSize
.width
* 4, false);
233 uint8_t* data
= mapping
.GetData();
234 ASSERT_TRUE_OR_RETURN(data
!= nullptr, false);
236 int32_t rowLength
= mapping
.GetStride();
237 for (int32_t col
= 0; col
< surfaceSize
.width
; ++col
) {
238 int32_t i
= aRow
* rowLength
+ col
* 4;
239 ASSERT_EQ_OR_RETURN(aPixels
[col
].mBlue
, data
[i
+ 0], false);
240 ASSERT_EQ_OR_RETURN(aPixels
[col
].mGreen
, data
[i
+ 1], false);
241 ASSERT_EQ_OR_RETURN(aPixels
[col
].mRed
, data
[i
+ 2], false);
242 ASSERT_EQ_OR_RETURN(aPixels
[col
].mAlpha
, data
[i
+ 3], false);
248 ///////////////////////////////////////////////////////////////////////////////
249 // SurfacePipe Helpers
250 ///////////////////////////////////////////////////////////////////////////////
252 already_AddRefed
<Decoder
> CreateTrivialDecoder() {
253 DecoderType decoderType
= DecoderFactory::GetDecoderType("image/gif");
254 auto sourceBuffer
= MakeNotNull
<RefPtr
<SourceBuffer
>>();
255 RefPtr
<Decoder
> decoder
= DecoderFactory::CreateAnonymousDecoder(
256 decoderType
, sourceBuffer
, Nothing(), DefaultDecoderFlags(),
257 DefaultSurfaceFlags());
258 return decoder
.forget();
261 void AssertCorrectPipelineFinalState(SurfaceFilter
* aFilter
,
262 const gfx::IntRect
& aInputSpaceRect
,
263 const gfx::IntRect
& aOutputSpaceRect
) {
264 EXPECT_TRUE(aFilter
->IsSurfaceFinished());
265 Maybe
<SurfaceInvalidRect
> invalidRect
= aFilter
->TakeInvalidRect();
266 EXPECT_TRUE(invalidRect
.isSome());
267 EXPECT_EQ(aInputSpaceRect
, invalidRect
->mInputSpaceRect
);
268 EXPECT_EQ(aOutputSpaceRect
, invalidRect
->mOutputSpaceRect
);
271 void CheckGeneratedImage(Decoder
* aDecoder
, const IntRect
& aRect
,
272 uint8_t aFuzz
/* = 0 */) {
273 RawAccessFrameRef currentFrame
= aDecoder
->GetCurrentFrameRef();
274 RefPtr
<SourceSurface
> surface
= currentFrame
->GetSourceSurface();
275 CheckGeneratedSurface(surface
, aRect
, BGRAColor::Green(),
276 BGRAColor::Transparent(), aFuzz
);
279 void CheckGeneratedSurface(SourceSurface
* aSurface
, const IntRect
& aRect
,
280 const BGRAColor
& aInnerColor
,
281 const BGRAColor
& aOuterColor
,
282 uint8_t aFuzz
/* = 0 */) {
283 const IntSize surfaceSize
= aSurface
->GetSize();
285 // This diagram shows how the surface is divided into regions that the code
286 // below tests for the correct content. The output rect is the bounds of the
287 // region labeled 'C'.
289 // +---------------------------+
291 // +---------+--------+--------+
293 // +---------+--------+--------+
295 // +---------------------------+
297 // Check that the output rect itself is the inner color. (Region 'C'.)
298 EXPECT_TRUE(RectIsSolidColor(aSurface
, aRect
, aInnerColor
, aFuzz
));
300 // Check that the area above the output rect is the outer color. (Region 'A'.)
301 EXPECT_TRUE(RectIsSolidColor(aSurface
,
302 IntRect(0, 0, surfaceSize
.width
, aRect
.Y()),
303 aOuterColor
, aFuzz
));
305 // Check that the area to the left of the output rect is the outer color.
307 EXPECT_TRUE(RectIsSolidColor(aSurface
,
308 IntRect(0, aRect
.Y(), aRect
.X(), aRect
.YMost()),
309 aOuterColor
, aFuzz
));
311 // Check that the area to the right of the output rect is the outer color.
313 const int32_t widthOnRight
= surfaceSize
.width
- aRect
.XMost();
314 EXPECT_TRUE(RectIsSolidColor(
315 aSurface
, IntRect(aRect
.XMost(), aRect
.Y(), widthOnRight
, aRect
.YMost()),
316 aOuterColor
, aFuzz
));
318 // Check that the area below the output rect is the outer color. (Region 'E'.)
319 const int32_t heightBelow
= surfaceSize
.height
- aRect
.YMost();
320 EXPECT_TRUE(RectIsSolidColor(
321 aSurface
, IntRect(0, aRect
.YMost(), surfaceSize
.width
, heightBelow
),
322 aOuterColor
, aFuzz
));
325 void CheckWritePixels(Decoder
* aDecoder
, SurfaceFilter
* aFilter
,
326 const Maybe
<IntRect
>& aOutputRect
/* = Nothing() */,
327 const Maybe
<IntRect
>& aInputRect
/* = Nothing() */,
328 const Maybe
<IntRect
>& aInputWriteRect
/* = Nothing() */,
329 const Maybe
<IntRect
>& aOutputWriteRect
/* = Nothing() */,
330 uint8_t aFuzz
/* = 0 */) {
331 CheckTransformedWritePixels(aDecoder
, aFilter
, BGRAColor::Green(),
332 BGRAColor::Green(), aOutputRect
, aInputRect
,
333 aInputWriteRect
, aOutputWriteRect
, aFuzz
);
336 void CheckTransformedWritePixels(
337 Decoder
* aDecoder
, SurfaceFilter
* aFilter
, const BGRAColor
& aInputColor
,
338 const BGRAColor
& aOutputColor
,
339 const Maybe
<IntRect
>& aOutputRect
/* = Nothing() */,
340 const Maybe
<IntRect
>& aInputRect
/* = Nothing() */,
341 const Maybe
<IntRect
>& aInputWriteRect
/* = Nothing() */,
342 const Maybe
<IntRect
>& aOutputWriteRect
/* = Nothing() */,
343 uint8_t aFuzz
/* = 0 */) {
344 IntRect outputRect
= aOutputRect
.valueOr(IntRect(0, 0, 100, 100));
345 IntRect inputRect
= aInputRect
.valueOr(IntRect(0, 0, 100, 100));
346 IntRect inputWriteRect
= aInputWriteRect
.valueOr(inputRect
);
347 IntRect outputWriteRect
= aOutputWriteRect
.valueOr(outputRect
);
351 auto result
= aFilter
->WritePixels
<uint32_t>([&] {
353 return AsVariant(aInputColor
.AsPixel());
355 EXPECT_EQ(WriteState::FINISHED
, result
);
356 EXPECT_EQ(inputWriteRect
.Width() * inputWriteRect
.Height(), count
);
358 AssertCorrectPipelineFinalState(aFilter
, inputRect
, outputRect
);
360 // Attempt to write more data and make sure nothing changes.
361 const int32_t oldCount
= count
;
362 result
= aFilter
->WritePixels
<uint32_t>([&] {
364 return AsVariant(aInputColor
.AsPixel());
366 EXPECT_EQ(oldCount
, count
);
367 EXPECT_EQ(WriteState::FINISHED
, result
);
368 EXPECT_TRUE(aFilter
->IsSurfaceFinished());
369 Maybe
<SurfaceInvalidRect
> invalidRect
= aFilter
->TakeInvalidRect();
370 EXPECT_TRUE(invalidRect
.isNothing());
372 // Attempt to advance to the next row and make sure nothing changes.
373 aFilter
->AdvanceRow();
374 EXPECT_TRUE(aFilter
->IsSurfaceFinished());
375 invalidRect
= aFilter
->TakeInvalidRect();
376 EXPECT_TRUE(invalidRect
.isNothing());
378 // Check that the generated image is correct.
379 RawAccessFrameRef currentFrame
= aDecoder
->GetCurrentFrameRef();
380 RefPtr
<SourceSurface
> surface
= currentFrame
->GetSourceSurface();
381 CheckGeneratedSurface(surface
, outputWriteRect
, aOutputColor
,
382 BGRAColor::Transparent(), aFuzz
);
385 ///////////////////////////////////////////////////////////////////////////////
387 ///////////////////////////////////////////////////////////////////////////////
389 ImageTestCase
GreenPNGTestCase() {
390 return ImageTestCase("green.png", "image/png", IntSize(100, 100));
393 ImageTestCase
GreenGIFTestCase() {
394 return ImageTestCase("green.gif", "image/gif", IntSize(100, 100));
397 ImageTestCase
GreenJPGTestCase() {
398 return ImageTestCase("green.jpg", "image/jpeg", IntSize(100, 100),
402 ImageTestCase
GreenBMPTestCase() {
403 return ImageTestCase("green.bmp", "image/bmp", IntSize(100, 100));
406 ImageTestCase
GreenICOTestCase() {
407 // This ICO contains a 32-bit BMP, and we use a BMP's alpha data by default
408 // when the BMP is embedded in an ICO, so it's transparent.
409 return ImageTestCase("green.ico", "image/x-icon", IntSize(100, 100),
410 TEST_CASE_IS_TRANSPARENT
);
413 ImageTestCase
GreenIconTestCase() {
414 return ImageTestCase("green.icon", "image/icon", IntSize(100, 100),
415 TEST_CASE_IS_TRANSPARENT
);
418 ImageTestCase
GreenWebPTestCase() {
419 return ImageTestCase("green.webp", "image/webp", IntSize(100, 100));
422 ImageTestCase
LargeWebPTestCase() {
423 return ImageTestCase("large.webp", "image/webp", IntSize(1200, 660),
424 TEST_CASE_IGNORE_OUTPUT
);
427 ImageTestCase
GreenWebPIccSrgbTestCase() {
428 return ImageTestCase("green.icc_srgb.webp", "image/webp", IntSize(100, 100));
431 ImageTestCase
GreenFirstFrameAnimatedGIFTestCase() {
432 return ImageTestCase("first-frame-green.gif", "image/gif", IntSize(100, 100),
433 TEST_CASE_IS_ANIMATED
);
436 ImageTestCase
GreenFirstFrameAnimatedPNGTestCase() {
437 return ImageTestCase("first-frame-green.png", "image/png", IntSize(100, 100),
438 TEST_CASE_IS_TRANSPARENT
| TEST_CASE_IS_ANIMATED
);
441 ImageTestCase
GreenFirstFrameAnimatedWebPTestCase() {
442 return ImageTestCase("first-frame-green.webp", "image/webp",
443 IntSize(100, 100), TEST_CASE_IS_ANIMATED
);
446 ImageTestCase
BlendAnimatedGIFTestCase() {
447 return ImageTestCase("blend.gif", "image/gif", IntSize(100, 100),
448 TEST_CASE_IS_ANIMATED
);
451 ImageTestCase
BlendAnimatedPNGTestCase() {
452 return ImageTestCase("blend.png", "image/png", IntSize(100, 100),
453 TEST_CASE_IS_TRANSPARENT
| TEST_CASE_IS_ANIMATED
);
456 ImageTestCase
BlendAnimatedWebPTestCase() {
457 return ImageTestCase("blend.webp", "image/webp", IntSize(100, 100),
458 TEST_CASE_IS_TRANSPARENT
| TEST_CASE_IS_ANIMATED
);
461 ImageTestCase
CorruptTestCase() {
462 return ImageTestCase("corrupt.jpg", "image/jpeg", IntSize(100, 100),
463 TEST_CASE_HAS_ERROR
);
466 ImageTestCase
CorruptBMPWithTruncatedHeader() {
467 // This BMP has a header which is truncated right between the BIH and the
468 // bitfields, which is a particularly error-prone place w.r.t. the BMP decoder
470 return ImageTestCase("invalid-truncated-metadata.bmp", "image/bmp",
471 IntSize(100, 100), TEST_CASE_HAS_ERROR
);
474 ImageTestCase
CorruptICOWithBadBMPWidthTestCase() {
475 // This ICO contains a BMP icon which has a width that doesn't match the size
476 // listed in the corresponding ICO directory entry.
477 return ImageTestCase("corrupt-with-bad-bmp-width.ico", "image/x-icon",
478 IntSize(100, 100), TEST_CASE_HAS_ERROR
);
481 ImageTestCase
CorruptICOWithBadBMPHeightTestCase() {
482 // This ICO contains a BMP icon which has a height that doesn't match the size
483 // listed in the corresponding ICO directory entry.
484 return ImageTestCase("corrupt-with-bad-bmp-height.ico", "image/x-icon",
485 IntSize(100, 100), TEST_CASE_HAS_ERROR
);
488 ImageTestCase
CorruptICOWithBadBppTestCase() {
489 // This test case is an ICO with a BPP (15) in the ICO header which differs
490 // from that in the BMP header itself (1). It should ignore the ICO BPP when
491 // the BMP BPP is available and thus correctly decode the image.
492 return ImageTestCase("corrupt-with-bad-ico-bpp.ico", "image/x-icon",
493 IntSize(100, 100), TEST_CASE_IS_TRANSPARENT
);
496 ImageTestCase
TransparentPNGTestCase() {
497 return ImageTestCase("transparent.png", "image/png", IntSize(32, 32),
498 TEST_CASE_IS_TRANSPARENT
);
501 ImageTestCase
TransparentGIFTestCase() {
502 return ImageTestCase("transparent.gif", "image/gif", IntSize(16, 16),
503 TEST_CASE_IS_TRANSPARENT
);
506 ImageTestCase
TransparentWebPTestCase() {
507 ImageTestCase
test("transparent.webp", "image/webp", IntSize(100, 100),
508 TEST_CASE_IS_TRANSPARENT
);
509 test
.mColor
= BGRAColor::Transparent();
513 ImageTestCase
TransparentNoAlphaHeaderWebPTestCase() {
514 ImageTestCase
test("transparent-no-alpha-header.webp", "image/webp",
515 IntSize(100, 100), TEST_CASE_IS_FUZZY
);
516 test
.mColor
= BGRAColor(0x00, 0x00, 0x00, 0xFF); // black
520 ImageTestCase
FirstFramePaddingGIFTestCase() {
521 return ImageTestCase("transparent.gif", "image/gif", IntSize(16, 16),
522 TEST_CASE_IS_TRANSPARENT
);
525 ImageTestCase
TransparentIfWithinICOBMPTestCase(TestCaseFlags aFlags
) {
526 // This is a BMP that is only transparent when decoded as if it is within an
527 // ICO file. (Note: aFlags needs to be set to TEST_CASE_DEFAULT_FLAGS or
528 // TEST_CASE_IS_TRANSPARENT accordingly.)
529 return ImageTestCase("transparent-if-within-ico.bmp", "image/bmp",
530 IntSize(32, 32), aFlags
);
533 ImageTestCase
RLE4BMPTestCase() {
534 return ImageTestCase("rle4.bmp", "image/bmp", IntSize(320, 240),
535 TEST_CASE_IS_TRANSPARENT
);
538 ImageTestCase
RLE8BMPTestCase() {
539 return ImageTestCase("rle8.bmp", "image/bmp", IntSize(32, 32),
540 TEST_CASE_IS_TRANSPARENT
);
543 ImageTestCase
NoFrameDelayGIFTestCase() {
544 // This is an invalid (or at least, questionably valid) GIF that's animated
545 // even though it specifies a frame delay of zero. It's animated, but it's not
546 // marked TEST_CASE_IS_ANIMATED because the metadata decoder can't detect that
548 return ImageTestCase("no-frame-delay.gif", "image/gif", IntSize(100, 100));
551 ImageTestCase
ExtraImageSubBlocksAnimatedGIFTestCase() {
552 // This is a corrupt GIF that has extra image sub blocks between the first and
554 return ImageTestCase("animated-with-extra-image-sub-blocks.gif", "image/gif",
558 ImageTestCase
DownscaledPNGTestCase() {
559 // This testcase (and all the other "downscaled") testcases) consists of 25
560 // lines of green, followed by 25 lines of red, followed by 25 lines of green,
561 // followed by 25 more lines of red. It's intended that tests downscale it
562 // from 100x100 to 20x20, so we specify a 20x20 output size.
563 return ImageTestCase("downscaled.png", "image/png", IntSize(100, 100),
567 ImageTestCase
DownscaledGIFTestCase() {
568 return ImageTestCase("downscaled.gif", "image/gif", IntSize(100, 100),
572 ImageTestCase
DownscaledJPGTestCase() {
573 return ImageTestCase("downscaled.jpg", "image/jpeg", IntSize(100, 100),
577 ImageTestCase
DownscaledBMPTestCase() {
578 return ImageTestCase("downscaled.bmp", "image/bmp", IntSize(100, 100),
582 ImageTestCase
DownscaledICOTestCase() {
583 return ImageTestCase("downscaled.ico", "image/x-icon", IntSize(100, 100),
584 IntSize(20, 20), TEST_CASE_IS_TRANSPARENT
);
587 ImageTestCase
DownscaledIconTestCase() {
588 return ImageTestCase("downscaled.icon", "image/icon", IntSize(100, 100),
589 IntSize(20, 20), TEST_CASE_IS_TRANSPARENT
);
592 ImageTestCase
DownscaledWebPTestCase() {
593 return ImageTestCase("downscaled.webp", "image/webp", IntSize(100, 100),
597 ImageTestCase
DownscaledTransparentICOWithANDMaskTestCase() {
598 // This test case is an ICO with AND mask transparency. We want to ensure that
599 // we can downscale it without crashing or triggering ASAN failures, but its
600 // content isn't simple to verify, so for now we don't check the output.
601 return ImageTestCase("transparent-ico-with-and-mask.ico", "image/x-icon",
602 IntSize(32, 32), IntSize(20, 20),
603 TEST_CASE_IS_TRANSPARENT
| TEST_CASE_IGNORE_OUTPUT
);
606 ImageTestCase
TruncatedSmallGIFTestCase() {
607 return ImageTestCase("green-1x1-truncated.gif", "image/gif", IntSize(1, 1));
610 ImageTestCase
LargeICOWithBMPTestCase() {
611 return ImageTestCase("green-large-bmp.ico", "image/x-icon", IntSize(256, 256),
612 TEST_CASE_IS_TRANSPARENT
);
615 ImageTestCase
LargeICOWithPNGTestCase() {
616 return ImageTestCase("green-large-png.ico", "image/x-icon", IntSize(512, 512),
617 TEST_CASE_IS_TRANSPARENT
);
620 ImageTestCase
GreenMultipleSizesICOTestCase() {
621 return ImageTestCase("green-multiple-sizes.ico", "image/x-icon",
625 ImageTestCase
PerfGrayJPGTestCase() {
626 return ImageTestCase("perf_gray.jpg", "image/jpeg", IntSize(1000, 1000));
629 ImageTestCase
PerfCmykJPGTestCase() {
630 return ImageTestCase("perf_cmyk.jpg", "image/jpeg", IntSize(1000, 1000));
633 ImageTestCase
PerfYCbCrJPGTestCase() {
634 return ImageTestCase("perf_ycbcr.jpg", "image/jpeg", IntSize(1000, 1000));
637 ImageTestCase
PerfRgbPNGTestCase() {
638 return ImageTestCase("perf_srgb.png", "image/png", IntSize(1000, 1000));
641 ImageTestCase
PerfRgbAlphaPNGTestCase() {
642 return ImageTestCase("perf_srgb_alpha.png", "image/png", IntSize(1000, 1000),
643 TEST_CASE_IS_TRANSPARENT
);
646 ImageTestCase
PerfGrayPNGTestCase() {
647 return ImageTestCase("perf_gray.png", "image/png", IntSize(1000, 1000));
650 ImageTestCase
PerfGrayAlphaPNGTestCase() {
651 return ImageTestCase("perf_gray_alpha.png", "image/png", IntSize(1000, 1000),
652 TEST_CASE_IS_TRANSPARENT
);
655 ImageTestCase
PerfRgbLosslessWebPTestCase() {
656 return ImageTestCase("perf_srgb_lossless.webp", "image/webp",
657 IntSize(1000, 1000));
660 ImageTestCase
PerfRgbAlphaLosslessWebPTestCase() {
661 return ImageTestCase("perf_srgb_alpha_lossless.webp", "image/webp",
662 IntSize(1000, 1000), TEST_CASE_IS_TRANSPARENT
);
665 ImageTestCase
PerfRgbLossyWebPTestCase() {
666 return ImageTestCase("perf_srgb_lossy.webp", "image/webp",
667 IntSize(1000, 1000));
670 ImageTestCase
PerfRgbAlphaLossyWebPTestCase() {
671 return ImageTestCase("perf_srgb_alpha_lossy.webp", "image/webp",
672 IntSize(1000, 1000), TEST_CASE_IS_TRANSPARENT
);
675 ImageTestCase
PerfRgbGIFTestCase() {
676 return ImageTestCase("perf_srgb.gif", "image/gif", IntSize(1000, 1000));
680 } // namespace mozilla