Bug 1568860 - Part 2: Make getAllFonts fission compatible. r=ochameau
[gecko.git] / image / test / gtest / Common.cpp
blobf36295a8d02a3f96ad10c2e323e9a707d4c5103b
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/. */
6 #include "Common.h"
8 #include <cstdlib>
10 #include "gfxPlatform.h"
12 #include "nsDirectoryServiceDefs.h"
13 #include "nsIDirectoryService.h"
14 #include "nsIFile.h"
15 #include "nsIInputStream.h"
16 #include "nsIProperties.h"
17 #include "nsNetUtil.h"
18 #include "mozilla/RefPtr.h"
19 #include "nsStreamUtils.h"
20 #include "nsString.h"
22 namespace mozilla {
23 namespace image {
25 using namespace gfx;
27 using std::abs;
28 using std::vector;
30 static bool sImageLibInitialized = false;
32 AutoInitializeImageLib::AutoInitializeImageLib() {
33 if (MOZ_LIKELY(sImageLibInitialized)) {
34 return;
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
58 // the main thread.
59 SpinPendingEvents();
62 void ImageBenchmarkBase::SetUp() {
63 nsCOMPtr<nsIInputStream> inputStream = LoadFile(mTestCase.mPath);
64 ASSERT_TRUE(inputStream != nullptr);
66 // Figure out how much data we have.
67 uint64_t length;
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 ///////////////////////////////////////////////////////////////////////////////
82 // General Helpers
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) \
88 EXPECT_TRUE(e); \
89 if (!(e)) { \
90 return rv; \
93 #define ASSERT_EQ_OR_RETURN(a, b, rv) \
94 EXPECT_EQ(a, b); \
95 if ((a) != (b)) { \
96 return rv; \
99 #define ASSERT_GE_OR_RETURN(a, b, rv) \
100 EXPECT_GE(a, b); \
101 if (!((a) >= (b))) { \
102 return rv; \
105 #define ASSERT_LE_OR_RETURN(a, b, rv) \
106 EXPECT_LE(a, b); \
107 if (!((a) <= (b))) { \
108 return rv; \
111 #define ASSERT_LT_OR_RETURN(a, b, rv) \
112 EXPECT_LT(a, b); \
113 if (!((a) < (b))) { \
114 return rv; \
117 void SpinPendingEvents() {
118 nsCOMPtr<nsIThread> mainThread = do_GetMainThread();
119 EXPECT_TRUE(mainThread != nullptr);
121 bool processed;
122 do {
123 processed = false;
124 nsresult rv = mainThread->ProcessNextEvent(false, &processed);
125 EXPECT_TRUE(NS_SUCCEEDED(rv));
126 } while (processed);
129 already_AddRefed<nsIInputStream> LoadFile(const char* aRelativePath) {
130 nsresult rv;
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),
167 aColor, aFuzz);
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();
181 IntRect rect =
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;
200 if (aFuzz != 0) {
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);
205 } else {
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);
214 return true;
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);
245 return true;
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 // +---------------------------+
290 // | A |
291 // +---------+--------+--------+
292 // | B | C | D |
293 // +---------+--------+--------+
294 // | E |
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.
306 // (Region 'B'.)
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.
312 // (Region 'D'.)
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);
349 // Fill the image.
350 int32_t count = 0;
351 auto result = aFilter->WritePixels<uint32_t>([&] {
352 ++count;
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>([&] {
363 ++count;
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 ///////////////////////////////////////////////////////////////////////////////
386 // Test Data
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),
399 TEST_CASE_IS_FUZZY);
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
469 // state machine.
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();
510 return test;
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
517 return test;
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
547 // it's animated.
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
553 // second frame.
554 return ImageTestCase("animated-with-extra-image-sub-blocks.gif", "image/gif",
555 IntSize(100, 100));
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),
564 IntSize(20, 20));
567 ImageTestCase DownscaledGIFTestCase() {
568 return ImageTestCase("downscaled.gif", "image/gif", IntSize(100, 100),
569 IntSize(20, 20));
572 ImageTestCase DownscaledJPGTestCase() {
573 return ImageTestCase("downscaled.jpg", "image/jpeg", IntSize(100, 100),
574 IntSize(20, 20));
577 ImageTestCase DownscaledBMPTestCase() {
578 return ImageTestCase("downscaled.bmp", "image/bmp", IntSize(100, 100),
579 IntSize(20, 20));
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),
594 IntSize(20, 20));
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",
622 IntSize(256, 256));
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));
679 } // namespace image
680 } // namespace mozilla