Bug 1181863 (Part 3) - Add tests for DecodeToSurface(). r=tn
authorSeth Fowler <mark.seth.fowler@gmail.com>
Fri, 31 Jul 2015 18:10:34 -0700
changeset 287430 4d7cd400d799e73e54c7d81d8379df7c097fb3c4
parent 287429 44dc3228c00b1f809629d7d88c9df7749186d734
child 287431 20d502d64ba5878eee66688076928e0f57c54bd7
push id5067
push userraliiev@mozilla.com
push dateMon, 21 Sep 2015 14:04:52 +0000
treeherdermozilla-beta@14221ffe5b2f [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerstn
bugs1181863
milestone42.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 1181863 (Part 3) - Add tests for DecodeToSurface(). r=tn
image/ImageOps.cpp
image/ImageOps.h
image/moz.build
image/test/gtest/Common.cpp
image/test/gtest/Common.h
image/test/gtest/TestDecodeToSurface.cpp
image/test/gtest/corrupt.jpg
image/test/gtest/first-frame-green.gif
image/test/gtest/first-frame-green.png
image/test/gtest/green.bmp
image/test/gtest/green.gif
image/test/gtest/green.ico
image/test/gtest/green.jpg
image/test/gtest/green.png
image/test/gtest/moz.build
--- a/image/ImageOps.cpp
+++ b/image/ImageOps.cpp
@@ -1,26 +1,25 @@
 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
  *
  * This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "ImageOps.h"
 
-#include "mozilla/gfx/2D.h"
-
 #include "ClippedImage.h"
 #include "DecodePool.h"
 #include "Decoder.h"
 #include "DecoderFactory.h"
 #include "DynamicImage.h"
 #include "FrozenImage.h"
 #include "Image.h"
 #include "imgIContainer.h"
+#include "mozilla/gfx/2D.h"
 #include "nsStreamUtils.h"
 #include "OrientedImage.h"
 #include "SourceBuffer.h"
 
 using namespace mozilla::gfx;
 
 namespace mozilla {
 namespace image {
--- a/image/ImageOps.h
+++ b/image/ImageOps.h
@@ -74,17 +74,17 @@ public:
    * off-main-thread.
    *
    * @param aInputStream An input stream containing an encoded image.
    * @param aMimeType The MIME type of the image.
    * @param aFlags Flags of the imgIContainer::FLAG_DECODE_* variety.
    * @return A SourceSurface containing the first frame of the image at its
    *         intrinsic size, or nullptr if the image cannot be decoded.
    */
-  already_AddRefed<gfx::SourceSurface>
+  static already_AddRefed<gfx::SourceSurface>
   DecodeToSurface(nsIInputStream* aInputStream,
                   const nsACString& aMimeType,
                   uint32_t aFlags);
 
 private:
   // This is a static utility class, so disallow instantiation.
   virtual ~ImageOps() = 0;
 };
--- a/image/moz.build
+++ b/image/moz.build
@@ -1,15 +1,17 @@
 # -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
 # vim: set filetype=python:
 # This Source Code Form is subject to the terms of the Mozilla Public
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
 DIRS += ['build', 'decoders', 'encoders']
+if CONFIG['ENABLE_TESTS']:
+    DIRS += ['test/gtest']
 
 with Files('**'):
     BUG_COMPONENT = ('Core', 'ImageLib')
 
 BROWSER_CHROME_MANIFESTS += ['test/browser/browser.ini']
 
 MOCHITEST_MANIFESTS += ['test/mochitest/mochitest.ini']
 
new file mode 100644
--- /dev/null
+++ b/image/test/gtest/Common.cpp
@@ -0,0 +1,157 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "Common.h"
+
+#include <cstdlib>
+#include "gtest/gtest.h"
+
+#include "nsDirectoryServiceDefs.h"
+#include "nsIDirectoryService.h"
+#include "nsIFile.h"
+#include "nsIInputStream.h"
+#include "nsIProperties.h"
+#include "nsNetUtil.h"
+#include "nsRefPtr.h"
+#include "nsString.h"
+
+namespace mozilla {
+
+using namespace gfx;
+
+using std::abs;
+
+///////////////////////////////////////////////////////////////////////////////
+// Helpers
+///////////////////////////////////////////////////////////////////////////////
+
+// These macros work like gtest's ASSERT_* macros, except that they can be used
+// in functions that return values.
+#define ASSERT_TRUE_OR_RETURN(e, rv) \
+  EXPECT_TRUE(e);                    \
+  if (!(e)) {                        \
+    return rv;                       \
+  }
+
+#define ASSERT_EQ_OR_RETURN(a, b, rv) \
+  EXPECT_EQ(a, b);                    \
+  if ((a) != (b)) {                   \
+    return rv;                        \
+  }
+
+#define ASSERT_LE_OR_RETURN(a, b, rv) \
+  EXPECT_LE(a, b);                    \
+  if (!((a) <= (b))) {                 \
+    return rv;                        \
+  }
+
+already_AddRefed<nsIInputStream>
+LoadFile(const char* aRelativePath)
+{
+  nsresult rv;
+
+  nsCOMPtr<nsIProperties> dirService =
+    do_GetService(NS_DIRECTORY_SERVICE_CONTRACTID);
+  ASSERT_TRUE_OR_RETURN(dirService != nullptr, nullptr);
+
+  // Retrieve the current working directory.
+  nsCOMPtr<nsIFile> file;
+  rv = dirService->Get(NS_OS_CURRENT_WORKING_DIR,
+                       NS_GET_IID(nsIFile), getter_AddRefs(file));
+  ASSERT_TRUE_OR_RETURN(NS_SUCCEEDED(rv), nullptr);
+
+  // Construct the final path by appending the working path to the current
+  // working directory.
+  file->AppendNative(nsAutoCString(aRelativePath));
+
+  // Construct an input stream for the requested file.
+  nsCOMPtr<nsIInputStream> inputStream;
+  rv = NS_NewLocalFileInputStream(getter_AddRefs(inputStream), file);
+  ASSERT_TRUE_OR_RETURN(NS_SUCCEEDED(rv), nullptr);
+
+  return inputStream.forget();
+}
+
+bool
+IsSolidColor(SourceSurface* aSurface, BGRAColor aColor, bool aFuzzy)
+{
+  nsRefPtr<DataSourceSurface> dataSurface = aSurface->GetDataSurface();
+  ASSERT_TRUE_OR_RETURN(dataSurface != nullptr, false);
+
+  ASSERT_EQ_OR_RETURN(dataSurface->Stride(), aSurface->GetSize().width * 4,
+                      false);
+
+  DataSourceSurface::ScopedMap mapping(dataSurface,
+                                       DataSourceSurface::MapType::READ);
+  ASSERT_TRUE_OR_RETURN(mapping.IsMapped(), false);
+
+  uint8_t* data = dataSurface->GetData();
+  ASSERT_TRUE_OR_RETURN(data != nullptr, false);
+
+  int32_t length = dataSurface->Stride() * aSurface->GetSize().height;
+  for (int32_t i = 0 ; i < length ; i += 4) {
+    if (aFuzzy) {
+      ASSERT_LE_OR_RETURN(abs(aColor.mBlue - data[i + 0]), 1, false);
+      ASSERT_LE_OR_RETURN(abs(aColor.mGreen - data[i + 1]), 1, false);
+      ASSERT_LE_OR_RETURN(abs(aColor.mRed - data[i + 2]), 1, false);
+      ASSERT_LE_OR_RETURN(abs(aColor.mAlpha - data[i + 3]), 1, false);
+    } else {
+      ASSERT_EQ_OR_RETURN(aColor.mBlue,  data[i + 0], false);
+      ASSERT_EQ_OR_RETURN(aColor.mGreen, data[i + 1], false);
+      ASSERT_EQ_OR_RETURN(aColor.mRed,   data[i + 2], false);
+      ASSERT_EQ_OR_RETURN(aColor.mAlpha, data[i + 3], false);
+    }
+  }
+
+  return true;
+}
+
+
+///////////////////////////////////////////////////////////////////////////////
+// Test Data
+///////////////////////////////////////////////////////////////////////////////
+
+ImageTestCase GreenPNGTestCase()
+{
+  return ImageTestCase("green.png", "image/png", IntSize(100, 100));
+}
+
+ImageTestCase GreenGIFTestCase()
+{
+  return ImageTestCase("green.gif", "image/gif", IntSize(100, 100));
+}
+
+ImageTestCase GreenJPGTestCase()
+{
+  return ImageTestCase("green.jpg", "image/jpeg", IntSize(100, 100),
+                       /* aFuzzy = */ true);
+}
+
+ImageTestCase GreenBMPTestCase()
+{
+  return ImageTestCase("green.bmp", "image/bmp", IntSize(100, 100));
+}
+
+ImageTestCase GreenICOTestCase()
+{
+  return ImageTestCase("green.ico", "image/x-icon", IntSize(100, 100));
+}
+
+ImageTestCase GreenFirstFrameAnimatedGIFTestCase()
+{
+  return ImageTestCase("first-frame-green.gif", "image/gif", IntSize(100, 100));
+}
+
+ImageTestCase GreenFirstFrameAnimatedPNGTestCase()
+{
+  return ImageTestCase("first-frame-green.png", "image/png", IntSize(100, 100));
+}
+
+ImageTestCase CorruptTestCase()
+{
+  return ImageTestCase("corrupt.jpg", "image/jpeg", IntSize(100, 100));
+}
+
+} // namespace mozilla
new file mode 100644
--- /dev/null
+++ b/image/test/gtest/Common.h
@@ -0,0 +1,91 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#ifndef mozilla_image_test_gtest_Common_h
+#define mozilla_image_test_gtest_Common_h
+
+#include "mozilla/gfx/2D.h"
+#include "nsCOMPtr.h"
+
+class nsIInputStream;
+
+namespace mozilla {
+
+///////////////////////////////////////////////////////////////////////////////
+// Types
+///////////////////////////////////////////////////////////////////////////////
+
+struct ImageTestCase
+{
+  ImageTestCase(const char* aPath,
+                const char* aMimeType,
+                gfx::IntSize aSize,
+                bool aFuzzy = false)
+    : mPath(aPath)
+    , mMimeType(aMimeType)
+    , mSize(aSize)
+    , mFuzzy(aFuzzy)
+  { }
+
+  const char* mPath;
+  const char* mMimeType;
+  gfx::IntSize mSize;
+  bool mFuzzy;
+};
+
+struct BGRAColor
+{
+  BGRAColor(uint8_t aBlue, uint8_t aGreen, uint8_t aRed, uint8_t aAlpha)
+    : mBlue(aBlue)
+    , mGreen(aGreen)
+    , mRed(aRed)
+    , mAlpha(aAlpha)
+  { }
+
+  static BGRAColor Green() { return BGRAColor(0x00, 0xFF, 0x00, 0xFF); }
+
+  uint8_t mBlue;
+  uint8_t mGreen;
+  uint8_t mRed;
+  uint8_t mAlpha;
+};
+
+
+///////////////////////////////////////////////////////////////////////////////
+// Helpers
+///////////////////////////////////////////////////////////////////////////////
+
+/// Loads a file from the current directory. @return an nsIInputStream for it.
+already_AddRefed<nsIInputStream> LoadFile(const char* aRelativePath);
+
+/**
+ * @returns true if every pixel of @aSurface is @aColor.
+ * 
+ * If @aFuzzy is true, a tolerance of 1 is allowed in each color component. This
+ * may be necessary for tests that involve JPEG images.
+ */
+bool IsSolidColor(gfx::SourceSurface* aSurface,
+                  BGRAColor aColor,
+                  bool aFuzzy = false);
+
+
+///////////////////////////////////////////////////////////////////////////////
+// Test Data
+///////////////////////////////////////////////////////////////////////////////
+
+ImageTestCase GreenPNGTestCase();
+ImageTestCase GreenGIFTestCase();
+ImageTestCase GreenJPGTestCase();
+ImageTestCase GreenBMPTestCase();
+ImageTestCase GreenICOTestCase();
+
+ImageTestCase GreenFirstFrameAnimatedGIFTestCase();
+ImageTestCase GreenFirstFrameAnimatedPNGTestCase();
+
+ImageTestCase CorruptTestCase();
+
+} // namespace mozilla
+
+#endif // mozilla_image_test_gtest_Common_h
new file mode 100644
--- /dev/null
+++ b/image/test/gtest/TestDecodeToSurface.cpp
@@ -0,0 +1,119 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "gtest/gtest.h"
+
+#include "Common.h"
+#include "imgIContainer.h"
+#include "imgITools.h"
+#include "ImageOps.h"
+#include "mozilla/gfx/2D.h"
+#include "nsComponentManagerUtils.h"
+#include "nsCOMPtr.h"
+#include "nsIInputStream.h"
+#include "nsIRunnable.h"
+#include "nsIThread.h"
+#include "nsRefPtr.h"
+#include "nsString.h"
+#include "nsThreadUtils.h"
+
+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 nsRunnable
+{
+public:
+  DecodeToSurfaceRunnable(nsIInputStream* aInputStream,
+                          const ImageTestCase& aTestCase)
+    : mInputStream(aInputStream)
+    , mTestCase(aTestCase)
+  { }
+
+  NS_IMETHOD Run()
+  {
+    Go();
+    return NS_OK;
+  }
+
+  void Go()
+  {
+    nsRefPtr<SourceSurface> surface =
+      ImageOps::DecodeToSurface(mInputStream,
+                                nsAutoCString(mTestCase.mMimeType),
+                                imgIContainer::DECODE_FLAGS_DEFAULT);
+    ASSERT_TRUE(surface != nullptr);
+
+    EXPECT_EQ(SurfaceType::DATA, surface->GetType());
+    EXPECT_TRUE(surface->GetFormat() == SurfaceFormat::B8G8R8X8 ||
+                surface->GetFormat() == SurfaceFormat::B8G8R8A8);
+    EXPECT_EQ(mTestCase.mSize, surface->GetSize());
+
+    EXPECT_TRUE(IsSolidColor(surface, BGRAColor::Green(), mTestCase.mFuzzy));
+  }
+
+private:
+  nsCOMPtr<nsIInputStream> mInputStream;
+  ImageTestCase mTestCase;
+};
+
+static void
+RunDecodeToSurface(const ImageTestCase& aTestCase)
+{
+  nsCOMPtr<nsIInputStream> inputStream = LoadFile(aTestCase.mPath);
+  ASSERT_TRUE(inputStream != nullptr);
+
+  nsCOMPtr<nsIThread> thread;
+  nsresult rv = NS_NewThread(getter_AddRefs(thread), nullptr);
+  ASSERT_TRUE(NS_SUCCEEDED(rv));
+
+  // We run the DecodeToSurface tests off-main-thread to ensure that
+  // DecodeToSurface doesn't require any main-thread-only code.
+  nsCOMPtr<nsIRunnable> runnable =
+    new DecodeToSurfaceRunnable(inputStream, aTestCase);
+  thread->Dispatch(runnable, nsIThread::DISPATCH_SYNC);
+
+  thread->Shutdown();
+}
+
+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, AnimatedGIF)
+{
+  RunDecodeToSurface(GreenFirstFrameAnimatedGIFTestCase());
+}
+
+TEST(ImageDecodeToSurface, AnimatedPNG)
+{
+  RunDecodeToSurface(GreenFirstFrameAnimatedPNGTestCase());
+}
+
+TEST(ImageDecodeToSurface, Corrupt)
+{
+  ImageTestCase testCase = CorruptTestCase();
+
+  nsCOMPtr<nsIInputStream> inputStream = LoadFile(testCase.mPath);
+  ASSERT_TRUE(inputStream != nullptr);
+
+  nsRefPtr<SourceSurface> surface =
+    ImageOps::DecodeToSurface(inputStream,
+                              nsAutoCString(testCase.mMimeType),
+                              imgIContainer::DECODE_FLAGS_DEFAULT);
+  EXPECT_TRUE(surface == nullptr);
+}
new file mode 100644
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..555a416d7d8e6c0f835a756994a8efca17c55cd8
GIT binary patch
literal 2477
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
G1pWd#D4b{j
new file mode 100644
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..cd3c7d3db89085bbdbcb41247792bfc5fde9c492
GIT binary patch
literal 317
zc${<hbhEHbOkqf2_`txx@E?d76o0ZXaDnLm+<vYh!Oo5Wu10zW%#1)G9gsXoF#}U^
zOaIE#Z}}I`*>bCU^SwR4`P&|OOncV3?A57l@3@bD^11%4_xZ1L-~aLRaJ3&<^s&Q7
zYx<dGpE-NImS0)*wd-uw_B-pobMti{f3oRkkKgL+Z?^sB?LYne%dWqD=U;#Sv+qB@
kgocGjL`Fr&j1@ah+<5VWBQpZwG`Kq&>g($n2Ff+o0RC>C`Tzg`
new file mode 100644
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..115f035d897859b9ad8e47cb158d252e621096c2
GIT binary patch
literal 364
zc%17D@N?(olHy`uVBq!ia0vp^DIm<j3?$ucQqzDGM`Ch_50GX8VusJXlM8?pXMj(L
zD-#nF!+(bQ`uf)2X6Zmd#*!evU<QY0H$b|i(jdARU`8^)Knn8<28QVe`;~!gTTd6q
zkc@k8&oXi{Fz_%hSX=*ctA)&#hL?>VDngwuN)vHYpX?={8L10C=x=?9WE~@R>v%S$
zeh0E0(^4EmKwd$za^t^+*B=#JU|PnG&o(f1@_)*b|9*-Re#S9CL!?VwBT9nv(@M${
ni&7aJfg!2jSX`W%o0OAUq+qOP5a+5R19E_;tDnm{r-UW|#oJ$m
new file mode 100644
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..f79dd672adfd43be0906e2ce5bb600b215517d27
GIT binary patch
literal 30138
zc%1Fbp$<WD6bImI%!YVplT0uZjVhQTDY78g{{>7FZc!BZHjiPVm+%m>%-zM9EPlUz
zzi`gk&UkuSM|pNxH(8gj7NSPJ?`8M6_UtG3w|p2+W~=0U>n@JXdTV<vj0S@^386Cz
zp?pZw%CLGVw&(l)_lHvSlRE$a000000000000000000000000000000006*$JOE67
B0m1+P
new file mode 100644
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..ef215dfc94751a15cca5909a443632f5468041b1
GIT binary patch
literal 156
zc${<hbhEHbOkqf2_`txx@E?d76o0aSC<Yx60g_>0DsJgtdHOB?;yGJxb#K16=Qn@b
zBadm%I+wjVwe21E@lQV2zx6)<b?*B=ejcv&Ba1$E_-IW(v+Ofxuh;S`tG;%f&Dwrv
z-FI%j?&D83{p|5uef`b0-@N^&pMTl)x9|Mx?|=6F=a<m1@QBE$=$Nr$$B7#+esE+)
IFfdpH0Q_Q3xc~qF
new file mode 100644
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..c5dfa8b5383c534df2f5e633e7d94d32cfd3b76a
GIT binary patch
literal 41662
zc%1FXp$&jg5JbU6BT3Lm%AlBE779fvbOlF9egWutlRL4=P+Cj<CFhaMN!GfWa^>6K
zwmq4~?|L@?0000000000000000000000000000000000000000000000MJR2^rHu<
C>)Sj4
new file mode 100644
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..48c454d27c9c46574597f80fdd64ecd4d254577d
GIT binary patch
literal 361
zc$}S%Jr2S!427SY62(c{IxR3UaS;ZjN^lMi!+jW87&rt!3pWYQNSWZXWLZz|+0M88
zg6zlL2%-urE#xP*Fjb*+qtv!8IBRE?o%igRee9wSZD4Lv({>_BeC&r_2A!oWp^`MU
z)1U+n@-z8@<Z!^j&>B@DlPF)Y&{y$^Re3H`6{;?Yrf$c@oxa@<L_>PVBy4b|?sS}5
I{)F=V4K5EK<NyEw
new file mode 100644
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..7df25f33bdb26cc7f41138501ab399059839137d
GIT binary patch
literal 255
zc%17D@N?(olHy`uVBq!ia0vp^DIm<j1SJ1AFfjuu&H|6fVg?3oVGw3ym^DWND9B#o
z>FdgVmrY2>Os;yW$XlS$JWm(LkcwMxFBmd1FmNz0$ozjU>fm{HrGS|QSGZD6PEz%r
zro*}k!eEMoFdB8hjHM3Kz>FXTZ!kl1f-0CHassR?l5*|8wspoc9#?7J!~=9GgQu&X
J%Q~loCICH_Rq+4-
new file mode 100644
--- /dev/null
+++ b/image/test/gtest/moz.build
@@ -0,0 +1,31 @@
+# -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
+# vim: set filetype=python:
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+Library('imagetest')
+
+FAIL_ON_WARNINGS = True
+
+UNIFIED_SOURCES = [
+    'Common.cpp',
+    'TestDecodeToSurface.cpp',
+]
+
+TEST_HARNESS_FILES.gtest += [
+    'corrupt.jpg',
+    'first-frame-green.gif',
+    'first-frame-green.png',
+    'green.bmp',
+    'green.gif',
+    'green.ico',
+    'green.jpg',
+    'green.png',
+]
+
+LOCAL_INCLUDES += [
+    '/image',
+]
+
+FINAL_LIBRARY = 'xul-gtest'