Bug 1207830 (Part 2) - Add downscale-during-decode GTests for all image formats. r=njn
authorSeth Fowler <mark.seth.fowler@gmail.com>
Fri, 27 May 2016 12:59:19 -0700
changeset 338401 3a61f536f0e6b992ddc587a2d4620e58da3a2fe6
parent 338400 3b02a890b94e4b1879f0bd8e2361444e17de5dc5
child 338402 7856fc2284735fbca3b33f76eb045c9ad3e8b8c9
push id6249
push userjlund@mozilla.com
push dateMon, 01 Aug 2016 13:59:36 +0000
treeherdermozilla-beta@bad9d4f5bf7e [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersnjn
bugs1207830
milestone49.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1207830 (Part 2) - Add downscale-during-decode GTests for all image formats. r=njn
image/test/gtest/Common.cpp
image/test/gtest/Common.h
image/test/gtest/TestDecoders.cpp
image/test/gtest/downscaled.bmp
image/test/gtest/downscaled.gif
image/test/gtest/downscaled.ico
image/test/gtest/downscaled.icon
image/test/gtest/downscaled.jpg
image/test/gtest/downscaled.png
image/test/gtest/moz.build
--- a/image/test/gtest/Common.cpp
+++ b/image/test/gtest/Common.cpp
@@ -505,10 +505,50 @@ ImageTestCase NoFrameDelayGIFTestCase()
 {
   // This is an invalid (or at least, questionably valid) GIF that's animated
   // even though it specifies a frame delay of zero. It's animated, but it's not
   // marked TEST_CASE_IS_ANIMATED because the metadata decoder can't detect that
   // it's animated.
   return ImageTestCase("no-frame-delay.gif", "image/gif", IntSize(100, 100));
 }
 
+ImageTestCase DownscaledPNGTestCase()
+{
+  // This testcase (and all the other "downscaled") testcases) consists of 25
+  // lines of green, followed by 25 lines of red, followed by 25 lines of green,
+  // followed by 25 more lines of red. It's intended that tests downscale it
+  // from 100x100 to 20x20, so we specify a 20x20 output size.
+  return ImageTestCase("downscaled.png", "image/png", IntSize(100, 100),
+                       IntSize(20, 20));
+}
+
+ImageTestCase DownscaledGIFTestCase()
+{
+  return ImageTestCase("downscaled.gif", "image/gif", IntSize(100, 100),
+                       IntSize(20, 20));
+}
+
+ImageTestCase DownscaledJPGTestCase()
+{
+  return ImageTestCase("downscaled.jpg", "image/jpeg", IntSize(100, 100),
+                       IntSize(20, 20));
+}
+
+ImageTestCase DownscaledBMPTestCase()
+{
+  return ImageTestCase("downscaled.bmp", "image/bmp", IntSize(100, 100),
+                       IntSize(20, 20));
+}
+
+ImageTestCase DownscaledICOTestCase()
+{
+  return ImageTestCase("downscaled.ico", "image/x-icon", IntSize(100, 100),
+                       IntSize(20, 20), TEST_CASE_IS_TRANSPARENT);
+}
+
+ImageTestCase DownscaledIconTestCase()
+{
+  return ImageTestCase("downscaled.icon", "image/icon", IntSize(100, 100),
+                       IntSize(20, 20), TEST_CASE_IS_TRANSPARENT);
+}
+
 } // namespace image
 } // namespace mozilla
--- a/image/test/gtest/Common.h
+++ b/image/test/gtest/Common.h
@@ -39,22 +39,36 @@ struct ImageTestCase
 {
   ImageTestCase(const char* aPath,
                 const char* aMimeType,
                 gfx::IntSize aSize,
                 uint32_t aFlags = TEST_CASE_DEFAULT_FLAGS)
     : mPath(aPath)
     , mMimeType(aMimeType)
     , mSize(aSize)
+    , mOutputSize(aSize)
+    , mFlags(aFlags)
+  { }
+
+  ImageTestCase(const char* aPath,
+                const char* aMimeType,
+                gfx::IntSize aSize,
+                gfx::IntSize aOutputSize,
+                uint32_t aFlags = TEST_CASE_DEFAULT_FLAGS)
+    : mPath(aPath)
+    , mMimeType(aMimeType)
+    , mSize(aSize)
+    , mOutputSize(aOutputSize)
     , mFlags(aFlags)
   { }
 
   const char* mPath;
   const char* mMimeType;
   gfx::IntSize mSize;
+  gfx::IntSize mOutputSize;
   uint32_t mFlags;
 };
 
 struct BGRAColor
 {
   BGRAColor(uint8_t aBlue, uint8_t aGreen, uint8_t aRed, uint8_t aAlpha)
     : mBlue(aBlue)
     , mGreen(aGreen)
@@ -307,12 +321,19 @@ ImageTestCase TransparentPNGTestCase();
 ImageTestCase TransparentGIFTestCase();
 ImageTestCase FirstFramePaddingGIFTestCase();
 ImageTestCase NoFrameDelayGIFTestCase();
 
 ImageTestCase TransparentBMPWhenBMPAlphaEnabledTestCase();
 ImageTestCase RLE4BMPTestCase();
 ImageTestCase RLE8BMPTestCase();
 
+ImageTestCase DownscaledPNGTestCase();
+ImageTestCase DownscaledGIFTestCase();
+ImageTestCase DownscaledJPGTestCase();
+ImageTestCase DownscaledBMPTestCase();
+ImageTestCase DownscaledICOTestCase();
+ImageTestCase DownscaledIconTestCase();
+
 } // namespace image
 } // namespace mozilla
 
 #endif // mozilla_image_test_gtest_Common_h
--- a/image/test/gtest/TestDecoders.cpp
+++ b/image/test/gtest/TestDecoders.cpp
@@ -33,31 +33,31 @@ 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 void
-CheckDecoderResults(const ImageTestCase& aTestCase, Decoder* aDecoder)
+static already_AddRefed<SourceSurface>
+CheckDecoderState(const ImageTestCase& aTestCase, Decoder* aDecoder)
 {
   EXPECT_TRUE(aDecoder->GetDecodeDone());
   EXPECT_EQ(bool(aTestCase.mFlags & TEST_CASE_HAS_ERROR),
             aDecoder->HasError());
   EXPECT_TRUE(!aDecoder->WasAborted());
 
   // Verify that the decoder made the expected progress.
   Progress progress = aDecoder->TakeProgress();
   EXPECT_EQ(bool(aTestCase.mFlags & TEST_CASE_HAS_ERROR),
             bool(progress & FLAG_HAS_ERROR));
 
   if (aTestCase.mFlags & TEST_CASE_HAS_ERROR) {
-    return;  // That's all we can check for bad images.
+    return nullptr;  // That's all we can check for bad images.
   }
 
   EXPECT_TRUE(bool(progress & FLAG_SIZE_AVAILABLE));
   EXPECT_TRUE(bool(progress & FLAG_DECODE_COMPLETE));
   EXPECT_TRUE(bool(progress & FLAG_FRAME_COMPLETE));
   EXPECT_EQ(bool(aTestCase.mFlags & TEST_CASE_IS_TRANSPARENT),
             bool(progress & FLAG_HAS_TRANSPARENCY));
   EXPECT_EQ(bool(aTestCase.mFlags & TEST_CASE_IS_ANIMATED),
@@ -72,23 +72,38 @@ CheckDecoderResults(const ImageTestCase&
   // because CreateAnonymousDecoder() forces a first-frame-only decode.
   RawAccessFrameRef currentFrame = aDecoder->GetCurrentFrameRef();
   RefPtr<SourceSurface> surface = currentFrame->GetSurface();
 
   // Verify that the resulting surfaces matches our expectations.
   EXPECT_EQ(SurfaceType::DATA, surface->GetType());
   EXPECT_TRUE(surface->GetFormat() == SurfaceFormat::B8G8R8X8 ||
               surface->GetFormat() == SurfaceFormat::B8G8R8A8);
-  EXPECT_EQ(aTestCase.mSize, surface->GetSize());
+  EXPECT_EQ(aTestCase.mOutputSize, surface->GetSize());
+
+  return surface.forget();
+}
+
+static void
+CheckDecoderResults(const ImageTestCase& aTestCase, Decoder* aDecoder)
+{
+  RefPtr<SourceSurface> surface = CheckDecoderState(aTestCase, aDecoder);
+  if (!surface) {
+    return;
+  }
+
+  // Check the output.
   EXPECT_TRUE(IsSolidColor(surface, BGRAColor::Green(),
                            aTestCase.mFlags & TEST_CASE_IS_FUZZY ? 1 : 0));
 }
 
-static void
-CheckDecoderSingleChunk(const ImageTestCase& aTestCase)
+template <typename Func>
+void WithSingleChunkDecode(const ImageTestCase& aTestCase,
+                           const Maybe<IntSize>& aOutputSize,
+                           Func aResultChecker)
 {
   nsCOMPtr<nsIInputStream> inputStream = LoadFile(aTestCase.mPath);
   ASSERT_TRUE(inputStream != nullptr);
 
   // Figure out how much data we have.
   uint64_t length;
   nsresult rv = inputStream->Available(&length);
   ASSERT_TRUE(NS_SUCCEEDED(rv));
@@ -99,24 +114,33 @@ CheckDecoderSingleChunk(const ImageTestC
   rv = sourceBuffer->AppendFromInputStream(inputStream, length);
   ASSERT_TRUE(NS_SUCCEEDED(rv));
   sourceBuffer->Complete(NS_OK);
 
   // Create a decoder.
   DecoderType decoderType =
     DecoderFactory::GetDecoderType(aTestCase.mMimeType);
   RefPtr<Decoder> decoder =
-    DecoderFactory::CreateAnonymousDecoder(decoderType, sourceBuffer, Nothing(),
+    DecoderFactory::CreateAnonymousDecoder(decoderType, sourceBuffer, aOutputSize,
                                            DefaultSurfaceFlags());
   ASSERT_TRUE(decoder != nullptr);
 
   // Run the full decoder synchronously.
   decoder->Decode();
-  
-  CheckDecoderResults(aTestCase, decoder);
+
+  // Call the lambda to verify the expected results.
+  aResultChecker(decoder);
+}
+
+static void
+CheckDecoderSingleChunk(const ImageTestCase& aTestCase)
+{
+  WithSingleChunkDecode(aTestCase, Nothing(), [&](Decoder* aDecoder) {
+    CheckDecoderResults(aTestCase, aDecoder);
+  });
 }
 
 class NoResume : public IResumable
 {
 public:
   NS_INLINE_DECL_REFCOUNTING(NoResume, override)
   virtual void Resume() override { }
 
@@ -162,76 +186,132 @@ CheckDecoderMultiChunk(const ImageTestCa
   }
 
   sourceBuffer->Complete(NS_OK);
   decoder->Decode(noResume);
   
   CheckDecoderResults(aTestCase, decoder);
 }
 
+static void
+CheckDownscaleDuringDecode(const ImageTestCase& aTestCase)
+{
+  // This function expects that |aTestCase| consists of 25 lines of green,
+  // followed by 25 lines of red, followed by 25 lines of green, followed by 25
+  // more lines of red. We'll downscale it from 100x100 to 20x20.
+  IntSize outputSize(20, 20);
+
+  WithSingleChunkDecode(aTestCase, Some(outputSize), [&](Decoder* aDecoder) {
+    RefPtr<SourceSurface> surface = CheckDecoderState(aTestCase, aDecoder);
+
+    // There are no downscale-during-decode tests that have TEST_CASE_HAS_ERROR
+    // set, so we expect to always get a surface here.
+    EXPECT_TRUE(surface != nullptr);
+
+    // Check that the downscaled image is correct. Note that we skip rows near
+    // the transitions between colors, since the downscaler does not produce a
+    // sharp boundary at these points. Even some of the rows we test need a
+    // small amount of fuzz; this is just the nature of Lanczos downscaling.
+    EXPECT_TRUE(RowsAreSolidColor(surface, 0, 4, BGRAColor::Green(), /* aFuzz = */ 4));
+    EXPECT_TRUE(RowsAreSolidColor(surface, 6, 3, BGRAColor::Red(), /* aFuzz = */ 4));
+    EXPECT_TRUE(RowsAreSolidColor(surface, 11, 3, BGRAColor::Green(), /* aFuzz = */ 4));
+    EXPECT_TRUE(RowsAreSolidColor(surface, 16, 4, BGRAColor::Red(), /* aFuzz = */ 3));
+  });
+}
+
 TEST(ImageDecoders, PNGSingleChunk)
 {
   CheckDecoderSingleChunk(GreenPNGTestCase());
 }
 
 TEST(ImageDecoders, PNGMultiChunk)
 {
   CheckDecoderMultiChunk(GreenPNGTestCase());
 }
 
+TEST(ImageDecoders, PNGDownscaleDuringDecode)
+{
+  CheckDownscaleDuringDecode(DownscaledPNGTestCase());
+}
+
 TEST(ImageDecoders, GIFSingleChunk)
 {
   CheckDecoderSingleChunk(GreenGIFTestCase());
 }
 
 TEST(ImageDecoders, GIFMultiChunk)
 {
   CheckDecoderMultiChunk(GreenGIFTestCase());
 }
 
+TEST(ImageDecoders, GIFDownscaleDuringDecode)
+{
+  CheckDownscaleDuringDecode(DownscaledGIFTestCase());
+}
+
 TEST(ImageDecoders, JPGSingleChunk)
 {
   CheckDecoderSingleChunk(GreenJPGTestCase());
 }
 
 TEST(ImageDecoders, JPGMultiChunk)
 {
   CheckDecoderMultiChunk(GreenJPGTestCase());
 }
 
+TEST(ImageDecoders, JPGDownscaleDuringDecode)
+{
+  CheckDownscaleDuringDecode(DownscaledJPGTestCase());
+}
+
 TEST(ImageDecoders, BMPSingleChunk)
 {
   CheckDecoderSingleChunk(GreenBMPTestCase());
 }
 
 TEST(ImageDecoders, BMPMultiChunk)
 {
   CheckDecoderMultiChunk(GreenBMPTestCase());
 }
 
+TEST(ImageDecoders, BMPDownscaleDuringDecode)
+{
+  CheckDownscaleDuringDecode(DownscaledBMPTestCase());
+}
+
 TEST(ImageDecoders, ICOSingleChunk)
 {
   CheckDecoderSingleChunk(GreenICOTestCase());
 }
 
 TEST(ImageDecoders, ICOMultiChunk)
 {
   CheckDecoderMultiChunk(GreenICOTestCase());
 }
 
+TEST(ImageDecoders, ICODownscaleDuringDecode)
+{
+  CheckDownscaleDuringDecode(DownscaledICOTestCase());
+}
+
 TEST(ImageDecoders, IconSingleChunk)
 {
   CheckDecoderSingleChunk(GreenIconTestCase());
 }
 
 TEST(ImageDecoders, IconMultiChunk)
 {
   CheckDecoderMultiChunk(GreenIconTestCase());
 }
 
+TEST(ImageDecoders, IconDownscaleDuringDecode)
+{
+  CheckDownscaleDuringDecode(DownscaledIconTestCase());
+}
+
 TEST(ImageDecoders, AnimatedGIFSingleChunk)
 {
   CheckDecoderSingleChunk(GreenFirstFrameAnimatedGIFTestCase());
 }
 
 TEST(ImageDecoders, AnimatedGIFMultiChunk)
 {
   CheckDecoderMultiChunk(GreenFirstFrameAnimatedGIFTestCase());
new file mode 100644
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..9e6a29e62ba6cae31498a7cc039d4ef1deaeb44b
GIT binary patch
literal 30138
zc%1Fdp$<V|7zW^D%!YVolT0uZ&8dPZk|GO&of|MsP!vVhT!x8m!bQk3X9r_$;GFQh
zd*1N<|Mq|XXmVZ!X?981Nf+-Hf<}7YOYXzktKU36(qS~7E;pBZcYbQtTiaV<7)9YG
zjyuCRE*}qv%Ak5JwrBhP?+c~iKMw!^000000RCmY9{>OV0000WkFx&(00000002P#
PWW65%0000003e5+*4hEW
new file mode 100644
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..ff9a20bcdb44edf3ea04eea3654fcffe3a51f3ba
GIT binary patch
literal 223
zc$@*>03iQINk%w1VPpVg0Pz3-{{R30{{SXM$tFd~A^8LV00000EC2ui0Av7U00088
zjE||y?GK}zwAzca-n{z{hT=$;=82~2%C_zc$MQ_q_KoNI&iDQg3<`(DqVb4KDkp%Z
z^9hYgr_`$Tip^@b+^+Wv4vWX+viXcotJmzd`wfrF=k&V$j?e4&{J#GW7$`VMSZH{N
zn5ekO*y#8O8L72IS!sERnW?$S+3EQS8Y((UT55WVnyR|W+UojxA}KpdTWfoZo2$Fa
Z+w1!a94tIcTx@)doUFXe-0W5W06UaCazg+B
new file mode 100644
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..ee112af0a9a77a74f5931f8e5bda019e6cac9d39
GIT binary patch
literal 41662
zc%1Fpp$&jA6h+a;5@;l2Figinp%{g&N(mN4NC@P-n^W;;XwtPxNqdK^OVTG9n|8{U
z^L}iabFo?h0000000000;PWI&k|arzBuSDaNs=T<`a^I3#{&QW00000004j|NRlK;
Vk|arzBuSDaNs{!3%*@PgYzG+X+W-In
new file mode 100644
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..19785f5dcb84a0a3f1fd541f0de8ef9f3e8b4076
GIT binary patch
literal 40003
zc%1FpK?wjr2mnFfm(%_gyb^*a!!j*4GfI*qNs=T<k|arzBuSE_14RJ<000000002M
jev%|fk|arzBuSDaNs=U8X!^$k0000000000fClda<TTed
new file mode 100644
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..5a4b3cd03608e26d06ca58a46c0fb4ca82903e54
GIT binary patch
literal 6035
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
new file mode 100644
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..b71b4652d5288450d91a28c1d8da4a51f16cfb85
GIT binary patch
literal 1015
zc%17D@N?(olHy`uVBq!ia0vp^DIm<j1SJ1AFflVQFiK~JM3hAM`dB6B=jtV<<R_)-
zRpb^hfPjsCML}Y6c4~=2Qfhi;o~_dR-TRdkGE;1o!cBb*d<&dYGcrA@ic*8C{6dne
zvXd=Sl<e)eY$~jP2IQueBq~(o=HwMyRoE(l&9wruLBje<3ScEA*|tg%z5xo(`9-M;
zrh2A&21<5Z3N}S4X;wilZcxoYo~=?wNlAf~zJ7Umxn8-kUVc%!zM-Y1rM`iYzLAkG
zP=#)BWnM{Qg>GK4GRO#s87`^C$wiq3C7Jno3Lt)BQhsTPt&);H$P#_1EkNh$!`%zy
zz<r#W2lQqU&_7aMt6u?wsV&plIiNVm-ATdI)!EF@(#%ZPNY9XgL1SX+#Qok*fg;E4
zGxuvKYqYnqwP$qnZ0cCFv}c2p${L5&uJi49x5&NM6zt_)%ggt7!P1Ut&u%TMSKw&M
z>RMnb#TBI#_dIKX%e>QjzZdWSKBxG-t+>p@o@raNek<;tW_*}&zq(NDCli}scj>Pd
zlHHlp3=Pf2m#nJ27rgkH_4-qxci+cn`>E*iW=XXkH$8lY)1SNDtf=jgZQ}N6eX1?z
zTdRF{F8Hwc(qq-S&^cP0oS&A==6>jzxP60q=)sR%*Dj@nRe0>so_#WV|Mx)sLe=YH
z&!_6`749}*{8KR_vCFefG9lzx;+`KbCX0qXsy+Hc;I+`|lNlR2Pikpidh$ZlRR88=
zqt}bnm!=+Z_W678{;jBA3)Yu3WsALv%lW;SU5f8v_3>@{`*MH(W|<Q-{k4;2-ChRe
z{6+7lZC$6Faks5|^(Ha<*3+>sDvXlS)@WERwJwppcYc8?*W2wEw#2Nu{oYQUf5QgW
zgVHzb8}dHp$NpseRg`YJZsjIDVCv*7@Q5sCVBi)8VMc~ob0mO*A3R+gLn`LHy?v1L
zfB_GSqxRqLbG9s~oq52AHErkoi*vqj_;RQ2!2AwTQecn$HQUo%M@WLlRA0|aWlbUp
e>P0e>YK>jb3zmaY3+7gU@~fw-pUXO@geCygWQ7<2
--- a/image/test/gtest/moz.build
+++ b/image/test/gtest/moz.build
@@ -26,16 +26,22 @@ if CONFIG['MOZ_ENABLE_SKIA']:
 
 SOURCES += [
     # Can't be unified because it manipulates the preprocessor environment.
     'TestDownscalingFilterNoSkia.cpp',
 ]
 
 TEST_HARNESS_FILES.gtest += [
     'corrupt.jpg',
+    'downscaled.bmp',
+    'downscaled.gif',
+    'downscaled.ico',
+    'downscaled.icon',
+    'downscaled.jpg',
+    'downscaled.png',
     'first-frame-green.gif',
     'first-frame-green.png',
     'first-frame-padding.gif',
     'green.bmp',
     'green.gif',
     'green.ico',
     'green.icon',
     'green.jpg',