summaryrefslogtreecommitdiff
path: root/src/graphics/testgraphics.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/graphics/testgraphics.cpp')
-rw-r--r--src/graphics/testgraphics.cpp1057
1 files changed, 1057 insertions, 0 deletions
diff --git a/src/graphics/testgraphics.cpp b/src/graphics/testgraphics.cpp
new file mode 100644
index 0000000..f6874b6
--- /dev/null
+++ b/src/graphics/testgraphics.cpp
@@ -0,0 +1,1057 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#include "GraphicsTest.h"
+#include "Bitmap.h"
+#include "BitmapLoader.h"
+#include "Pixel32.h"
+#include "Pixel24.h"
+#include "Pixel16.h"
+#include "Filtercolorize.h"
+#include "Filtergrayscale.h"
+#include "Filterfill.h"
+#include "Filterflip.h"
+#include "Filterfliprgb.h"
+#include "Filterflipuv.h"
+#include "Filter3x3.h"
+#include "FilterConvol.h"
+#include "HistoryPreProcessor.h"
+#include "FilterHighpass.h"
+#include "FilterFastBandpass.h"
+#include "FilterGauss.h"
+#include "FilterBlur.h"
+#include "FilterBandpass.h"
+#include "FilterFastDownscale.h"
+#include "FilterMask.h"
+#include "FilterThreshold.h"
+#include "FilterFloodfill.h"
+#include "FilterDilation.h"
+#include "FilterErosion.h"
+#include "FilterGetAlpha.h"
+#include "FilterResizeBilinear.h"
+#include "FilterUnmultiplyAlpha.h"
+
+#include "../base/TestSuite.h"
+#include "../base/Exception.h"
+#include "../base/MathHelper.h"
+
+#ifdef _WIN32
+#pragma warning(push)
+#pragma warning(disable: 4251)
+#endif
+#ifdef _WIN32
+#pragma warning(pop)
+#endif
+
+#include <cstring>
+#include <iostream>
+#include <stdio.h>
+#include <stdlib.h>
+
+#include <glib-object.h>
+
+using namespace avg;
+using namespace std;
+
+BitmapPtr initBmp(PixelFormat pf)
+{
+ int height;
+ if (pf == YCbCr422) {
+ height = 10;
+ } else {
+ height = 7;
+
+ }
+ BitmapPtr pBmp(new Bitmap(IntPoint(4, height), pf));
+ int bpp = pBmp->getBytesPerPixel();
+ for (int y = 0; y < height; ++y) {
+ for (int x = 0; x < 4; ++x) {
+ unsigned char * pPixel =
+ pBmp->getPixels()+y*pBmp->getStride()+x*pBmp->getBytesPerPixel();
+ *(pPixel) = x;
+ if (bpp > 1) {
+ *(pPixel+1) = 0;
+ }
+ if (bpp > 2) {
+ *(pPixel+2) = x;
+ *(pPixel) = 16*y;
+ }
+ if (bpp > 3) {
+ *(pPixel+3) = 0x80;
+ }
+ }
+ }
+ return pBmp;
+}
+
+// TODO: This is very incomplete!
+class PixelTest: public GraphicsTest {
+public:
+ PixelTest()
+ : GraphicsTest("PixelTest", 2)
+ {
+ }
+
+ void runTests()
+ {
+ float h, s, l;
+ Pixel32(255, 0, 0).toHSL(h, s, l);
+ TEST(h == 0 && almostEqual(s, 1.0f) && almostEqual(l, 0.5f));
+ Pixel32(0, 255, 0).toHSL(h, s, l);
+ TEST(h == 120 && almostEqual(s, 1.0f) && almostEqual(l, 0.5f));
+ Pixel32(0, 0, 255).toHSL(h, s, l);
+ TEST(h == 240 && almostEqual(s, 1.0f) && almostEqual(l, 0.5f));
+ Pixel32(255, 255, 0).toHSL(h, s, l);
+ TEST(h == 60 && almostEqual(s, 1.0f) && almostEqual(l, 0.5f));
+ Pixel32(255, 0, 255).toHSL(h, s, l);
+ TEST(h == 300 && almostEqual(s, 1.0f) && almostEqual(l, 0.5f));
+ Pixel32(0, 255, 255).toHSL(h, s, l);
+ TEST(h == 180 && almostEqual(s, 1.0f) && almostEqual(l, 0.5f));
+ Pixel32(0, 0, 0).toHSL(h, s, l);
+ TEST(s == 0.0f && l == 0.0f);
+ Pixel32(255, 255, 255).toHSL(h, s, l);
+ TEST(s == 0.0f && l == 1.0f);
+ Pixel32(128, 128, 128).toHSL(h, s, l);
+ TEST(s == 0.0f && almostEqual(l, 0.5f, 0.02f));
+ }
+};
+
+class BitmapTest: public GraphicsTest {
+public:
+ BitmapTest()
+ : GraphicsTest("BitmapTest", 2)
+ {
+ }
+
+ void runTests()
+ {
+ runPFTests(B8G8R8A8);
+ runPFTests(R8G8B8A8);
+ runPFTests(R8G8B8X8);
+ runPFTests(R8G8B8);
+ runPFTests(I8);
+ runPFTests(I16);
+ runPFTests(YCbCr422);
+ runLineTest(B8G8R8A8, Pixel32(0,0,255,255));
+ runLineTest(B8G8R8, Pixel24(0,0,255));
+ runLineTest(I8, Pixel8(255));
+
+ cerr << " Testing OwnsBits." << endl;
+ unsigned char pData[4*7*3];
+ for (int i = 0; i < 4*7*3; ++i) {
+ pData[i] = i;
+ }
+ Bitmap Bmp1 = Bitmap(IntPoint(4,7), R8G8B8, pData, 12, true, "");
+ Bitmap Bmp2 = Bitmap(IntPoint(4,7), R8G8B8, pData, 12, false, "");
+ testEqual(Bmp1, Bmp2, "BmpOwnsBits");
+ {
+ cerr << " Testing copyPixels - R8G8B8X8->R8G8B8->R8G8B8X8." << endl;
+ BitmapPtr pBmp = initBmp(R8G8B8X8);
+ Bitmap Bmp1(IntPoint(4,7), R8G8B8);
+ Bmp1.copyPixels(*pBmp);
+ Bitmap Bmp2(IntPoint(4,7), R8G8B8X8);
+ Bmp2.copyPixels(Bmp1);
+ for(int y = 0; y < 7; ++y) {
+ for (int x = 0; x < 4; ++x) {
+ *(Bmp2.getPixels()+y*Bmp2.getStride()+x
+ *Bmp2.getBytesPerPixel()+3) = 0x80;
+ }
+ }
+ testEqual(Bmp2, *pBmp, "BmpCopyPixels_1");
+ }
+ {
+ cerr << " Testing copyPixels - R8G8B8A8->R8G8B8->R8G8B8A8." << endl;
+ BitmapPtr pBmp = initBmp(R8G8B8A8);
+ BitmapPtr pBaselineBmp = initBmp(R8G8B8A8);
+ BitmapPtr pCopyBmp = BitmapPtr(new Bitmap(IntPoint(4,7), R8G8B8));
+ pCopyBmp->copyPixels(*pBmp);
+ pBmp->copyPixels(*pCopyBmp);
+ for(int y = 0; y < 7; ++y) {
+ for (int x = 0; x < 4; ++x) {
+ *(pBmp->getPixels()+y*pBmp->getStride()+x
+ *pBmp->getBytesPerPixel()+3) = 0x80;
+ }
+ }
+ testEqual(*pBmp, *pBaselineBmp, "BmpCopyPixels_2");
+ }
+ {
+ cerr << " Testing copyPixels - I8->I16->I8." << endl;
+ BitmapPtr pBmp = initBmp(I8);
+ BitmapPtr pBaselineBmp = initBmp(I8);
+ BitmapPtr pCopyBmp = BitmapPtr(new Bitmap(IntPoint(4,7), I16));
+ pCopyBmp->copyPixels(*pBmp);
+ pBmp->copyPixels(*pCopyBmp);
+ testEqual(*pBmp, *pBaselineBmp, "BmpCopyPixels_3");
+ }
+ {
+ cerr << " Testing copyPixels - R8G8B8A8->R32G32B32A32F->R8G8B8A8." << endl;
+ BitmapPtr pBmp = initBmp(R8G8B8A8);
+ BitmapPtr pBaselineBmp = initBmp(R8G8B8A8);
+ BitmapPtr pCopyBmp = BitmapPtr(new Bitmap(IntPoint(4,7), R32G32B32A32F));
+ pCopyBmp->copyPixels(*pBmp);
+ pBmp->copyPixels(*pCopyBmp);
+ testEqual(*pBmp, *pBaselineBmp, "BmpCopyPixels_3");
+ }
+ {
+ cerr << " Testing copyPixels - B5G6R5->B8G8R8->B5G6R5." << endl;
+ BitmapPtr pBmp = initBmp(B5G6R5);
+ BitmapPtr pBaselineBmp = initBmp(B5G6R5);
+ BitmapPtr pCopyBmp = BitmapPtr(new Bitmap(IntPoint(4,7), B8G8R8));
+ pCopyBmp->copyPixels(*pBmp);
+ pBmp->copyPixels(*pCopyBmp);
+ testEqual(*pBmp, *pBaselineBmp, "BmpCopyPixels_4");
+ }
+ testCopyToGreyscale(R8G8B8X8);
+ testCopyToGreyscale(B8G8R8X8);
+ testSubtract();
+ {
+ cerr << " Testing statistics." << endl;
+ cerr << " I8" << endl;
+ testStatistics(I8, Pixel8(0), Pixel8(0), Pixel8(2), Pixel8(2));
+ cerr << " R8G8B8A8" << endl;
+ testStatistics(R8G8B8A8, Pixel32(0,0,0,0), Pixel32(0,0,0,0),
+ Pixel32(255,255,255,255), Pixel32(255,255,255,255), 127.5, 90.1561);
+ cerr << " R8G8B8X8" << endl;
+ testStatistics(R8G8B8X8, Pixel32(0,0,0,255), Pixel32(0,0,0,255),
+ Pixel32(2,2,2,255), Pixel32(2,2,2,255));
+ cerr << " R8G8B8" << endl;
+ testStatistics(R8G8B8, Pixel24(0,0,0), Pixel24(0,0,0),
+ Pixel24(2,2,2), Pixel24(2,2,2));
+ cerr << " ChannelAvg" << endl;
+ testChannelAvg();
+ }
+ {
+ cerr << " Testing YUV->RGB conversion." << endl;
+ testYUV2RGB();
+ }
+ runSaveTest(B8G8R8A8);
+ runSaveTest(B8G8R8X8);
+ }
+
+private:
+ void runPFTests(PixelFormat pf)
+ {
+ cerr << " Testing " << pf << endl;
+ BitmapPtr pBmp = initBmp(pf);
+ {
+ cerr << " Testing size." <<endl;
+ if (pf == YCbCr422) {
+ TEST(pBmp->getSize() == IntPoint(4,10));
+ } else {
+ TEST(pBmp->getSize() == IntPoint(4,7));
+ }
+ }
+ {
+ cerr << " Testing copy constructor." << endl;
+ Bitmap bmpCopy1(*pBmp);
+ testEqual(bmpCopy1, *pBmp, "BmpCopyConstructor");
+ }
+ {
+ cerr << " Testing assignment operator." << endl;
+ Bitmap bmpCopy2 = *pBmp;
+ testEqual(bmpCopy2, *pBmp, "BmpAssignment");
+ }
+ {
+ cerr << " Testing sub-bitmap constructor." << endl;
+ Bitmap bmpCopy3 (*pBmp, IntRect(IntPoint(0,0), pBmp->getSize()));
+ testEqual(bmpCopy3, *pBmp, "BmpSubBmpCtor");
+ }
+ if (pf == I8) {
+ cerr << " Testing getHistogram." << endl;
+ HistogramPtr pHist = pBmp->getHistogram();
+ TEST((*pHist)[0] == 7);
+ TEST((*pHist)[1] == 7);
+ TEST((*pHist)[2] == 7);
+ TEST((*pHist)[3] == 7);
+ bool bOk = true;
+ for (int i = 4; i < 256; ++i) {
+ if (bOk) {
+ bOk = ((*pHist)[i] == 0);
+ }
+ }
+ TEST(bOk);
+ }
+ }
+
+ void runSaveTest(PixelFormat pf)
+ {
+ cerr << " Testing save for " << pf << endl;
+ BitmapPtr pBmp = initBmp(pf);
+ pBmp->save("test.png");
+ BitmapPtr pLoadedBmp = loadBitmap("test.png");
+ ::remove("test.png");
+ testEqual(*pLoadedBmp, *pBmp, "BmpSave");
+ }
+
+ template<class PIXEL>
+ void runLineTest(PixelFormat pf, PIXEL color)
+ {
+ cerr << " Testing line drawing for " << pf << endl;
+ Bitmap bmp(IntPoint(15, 15), pf);
+ memset(bmp.getPixels(), 0, bmp.getStride()*15);
+ bmp.drawLine(IntPoint(7,7), IntPoint( 0, 2), color);
+ bmp.drawLine(IntPoint(7,7), IntPoint( 0,12), color);
+ bmp.drawLine(IntPoint(7,7), IntPoint( 2, 0), color);
+ bmp.drawLine(IntPoint(7,7), IntPoint( 2,14), color);
+ bmp.drawLine(IntPoint(7,7), IntPoint(12, 0), color);
+ bmp.drawLine(IntPoint(7,7), IntPoint(12,14), color);
+ bmp.drawLine(IntPoint(7,7), IntPoint(14, 2), color);
+ bmp.drawLine(IntPoint(7,7), IntPoint(14,12), color);
+ string sFName = getSrcDirName() + "baseline/LineResult" + getPixelFormatString(pf)
+ + ".png";
+ BitmapPtr pBaselineBmp = loadBitmap(sFName, pf);
+ testEqual(bmp, *pBaselineBmp, "BmpLineDraw");
+ }
+
+ void testCopyToGreyscale(PixelFormat pf)
+ {
+ cerr << " Testing copyPixels - " << pf << "->I8." << endl;
+ BitmapPtr pBmp(new Bitmap(IntPoint(4,4), pf));
+ for (int y=0; y<4; ++y) {
+ for (int x=0; x<4; ++x) {
+ unsigned char * pPixel =
+ pBmp->getPixels()+y*pBmp->getStride()+x*pBmp->getBytesPerPixel();
+ pPixel[0] = x*64;
+ pPixel[1] = 128;
+ pPixel[2] = y*64;
+ pPixel[3] = 255;
+ }
+ }
+ BitmapPtr pCopyBmp = BitmapPtr(new Bitmap(IntPoint(4,4), I8));
+ pCopyBmp->copyPixels(*pBmp);
+ testEqual(*pCopyBmp, string("copyPixels_")+getPixelFormatString(pf)+"_I8",
+ I8, 0.5, 0.5);
+ }
+
+ void testSubtract()
+ {
+ BitmapPtr pBmp1(new Bitmap(IntPoint(4,1), I8));
+ BitmapPtr pBmp2(new Bitmap(IntPoint(4,1), I8));
+ for (int x=0; x<4; ++x) {
+ pBmp1->getPixels()[x] = x;
+ pBmp2->getPixels()[x] = 0;
+ }
+ BitmapPtr pDiffBmp = pBmp1->subtract(*pBmp2);
+ testEqual(*pDiffBmp, *pBmp1, "BmpSubtract1");
+ pDiffBmp = pBmp2->subtract(*pBmp1);
+ testEqual(*pDiffBmp, *pBmp1, "BmpSubtract2");
+ }
+
+ template<class PIXEL>
+ void testStatistics(PixelFormat pf, const PIXEL& p00, const PIXEL& p01,
+ const PIXEL& p10, const PIXEL& p11, float avg=1, float stdDev=1)
+ {
+ BitmapPtr pBmp = BitmapPtr(new Bitmap(IntPoint(2,2), pf));
+ pBmp->setPixel(IntPoint(0,0), p00);
+ pBmp->setPixel(IntPoint(0,1), p01);
+ pBmp->setPixel(IntPoint(1,0), p10);
+ pBmp->setPixel(IntPoint(1,1), p11);
+ TEST(almostEqual(pBmp->getAvg(), avg, 0.001));
+ TEST(almostEqual(pBmp->getStdDev(), stdDev, 0.001));
+ }
+
+ void testChannelAvg()
+ {
+ BitmapPtr pBmp = BitmapPtr(new Bitmap(IntPoint(2,2), R8G8B8));
+ pBmp->setPixel(IntPoint(0,0), Pixel24(0,0,0));
+ pBmp->setPixel(IntPoint(0,1), Pixel24(128,0,0));
+ pBmp->setPixel(IntPoint(1,0), Pixel24(128,128,0));
+ pBmp->setPixel(IntPoint(1,1), Pixel24(128,128,128));
+ TEST(almostEqual(pBmp->getChannelAvg(0), 96));
+ TEST(almostEqual(pBmp->getChannelAvg(1), 64));
+ TEST(almostEqual(pBmp->getChannelAvg(2), 32));
+ }
+
+ void testYUV2RGB()
+ {
+ BitmapPtr pYBmp = BitmapPtr(new Bitmap(IntPoint(16, 16), I8));
+ for (int x=0; x<16; ++x) {
+ FilterFillRect<Pixel8>(IntRect(x, 0, x+1, 16), 255-x*16).applyInPlace(pYBmp);
+ }
+ BitmapPtr pUBmp = BitmapPtr(new Bitmap(IntPoint(8, 8), I8));
+ BitmapPtr pVBmp = BitmapPtr(new Bitmap(IntPoint(8, 8), I8));
+ FilterFillRect<Pixel8>(IntRect(0, 0, 8, 4), 128).applyInPlace(pUBmp);
+ FilterFillRect<Pixel8>(IntRect(0, 0, 8, 4), 128).applyInPlace(pVBmp);
+ for (int y=4; y<8; ++y) {
+ FilterFillRect<Pixel8>(IntRect(0, y, 8, y+1), y*64).applyInPlace(pUBmp);
+ FilterFillRect<Pixel8>(IntRect(0, y, 8, y+1), 255-y*64).applyInPlace(pVBmp);
+ }
+ BitmapPtr pRGBBmp = BitmapPtr(new Bitmap(IntPoint(16, 16), B8G8R8X8));
+ FilterFill<Pixel32>(Pixel32(255,0,0,255)).applyInPlace(pRGBBmp);
+ pRGBBmp->copyYUVPixels(*pYBmp, *pUBmp, *pVBmp, false);
+ testEqual(*pRGBBmp, "YUV2RGBResult1", B8G8R8X8, 0.5, 0.5);
+ }
+
+};
+
+class FilterColorizeTest: public GraphicsTest {
+public:
+ FilterColorizeTest()
+ : GraphicsTest("FilterColorizeTest", 2)
+ {
+ }
+
+ void runTests()
+ {
+ runPFTests(R8G8B8A8);
+ runPFTests(R8G8B8);
+ }
+
+private:
+ void runPFTests(PixelFormat pf) {
+ BitmapPtr pBmp = initBmp(pf);
+ FilterColorize(15, 0).applyInPlace(pBmp);
+ FilterColorize(100, 50).applyInPlace(pBmp);
+ FilterColorize(50, 100).applyInPlace(pBmp);
+ }
+};
+
+class FilterGrayscaleTest: public GraphicsTest {
+public:
+ FilterGrayscaleTest()
+ : GraphicsTest("FilterGrayscaleTest", 2)
+ {
+ }
+
+ void runTests()
+ {
+ runPFTests(R8G8B8A8);
+ runPFTests(R8G8B8);
+ runPFTests(I8);
+ }
+
+private:
+ void runPFTests(PixelFormat pf) {
+ BitmapPtr pBmp = initBmp(pf);
+ FilterGrayscale().applyInPlace(pBmp);
+ }
+};
+
+class FilterFillTest: public GraphicsTest {
+public:
+ FilterFillTest()
+ : GraphicsTest("FilterFillTest", 2)
+ {
+ }
+
+ void runTests()
+ {
+ runPFTests<Pixel32>(R8G8B8A8, Pixel32(255,80,0,255));
+ runPFTests<Pixel24>(R8G8B8, Pixel24(255,80,0));
+ }
+
+private:
+ template<class PixelC>
+ void runPFTests(PixelFormat pf, PixelC color) {
+ BitmapPtr pBmp = initBmp(pf);
+ FilterFill<PixelC>(color).applyInPlace(pBmp);
+ }
+};
+
+class FilterFlipTest: public GraphicsTest {
+public:
+ FilterFlipTest()
+ : GraphicsTest("FilterFlipTest", 2)
+ {
+ }
+
+ void runTests()
+ {
+ runPFTests(R8G8B8A8);
+ runPFTests(B8G8R8X8);
+ runPFTests(R8G8B8);
+ runPFTests(I8);
+ }
+
+private:
+ void runPFTests(PixelFormat pf) {
+ BitmapPtr pBmp = initBmp(pf);
+ {
+ BitmapPtr pBmp1 = FilterFlip().apply(pBmp);
+ BitmapPtr pBmp2 = FilterFlip().apply(pBmp1);
+ TEST(*pBmp == *pBmp2);
+ }
+ pBmp = initBmp(pf);
+ {
+ Bitmap baselineBmp = *pBmp;
+ FilterFlip().applyInPlace(pBmp);
+ FilterFlip().applyInPlace(pBmp);
+ TEST(*pBmp == baselineBmp);
+ }
+ }
+};
+
+class FilterFlipRGBTest: public GraphicsTest {
+public:
+ FilterFlipRGBTest()
+ : GraphicsTest("FilterFlipRGBTest", 2)
+ {
+ }
+
+ void runTests()
+ {
+ runPFTests(B8G8R8A8);
+ runPFTests(R8G8B8A8);
+ runPFTests(R8G8B8);
+ }
+
+private:
+ void runPFTests(PixelFormat pf) {
+ BitmapPtr pBmp = initBmp(pf);
+ {
+ BitmapPtr pBmp1 = FilterFlipRGB().apply(pBmp);
+ BitmapPtr pBmp2 = FilterFlipRGB().apply(pBmp1);
+ TEST(*pBmp == *pBmp2);
+ }
+ {
+ Bitmap baselineBmp = *pBmp;
+ FilterFlipRGB().applyInPlace(pBmp);
+ FilterFlipRGB().applyInPlace(pBmp);
+ TEST(*pBmp == baselineBmp);
+ }
+ }
+};
+
+class FilterFlipUVTest: public GraphicsTest {
+public:
+ FilterFlipUVTest()
+ : GraphicsTest("FilterFlipUVTest", 2)
+ {
+ }
+
+ void runTests()
+ {
+ BitmapPtr pBmp = initBmp(YCbCr422);
+ {
+ BitmapPtr pBmp1 = FilterFlipUV().apply(pBmp);
+ BitmapPtr pBmp2 = FilterFlipUV().apply(pBmp1);
+ TEST(*pBmp == *pBmp2);
+ }
+ {
+ Bitmap baselineBmp = *pBmp;
+ FilterFlipUV().applyInPlace(pBmp);
+ FilterFlipUV().applyInPlace(pBmp);
+ TEST(*pBmp == baselineBmp);
+ }
+ }
+};
+
+class FilterComboTest: public GraphicsTest {
+public:
+ FilterComboTest()
+ : GraphicsTest("FilterComboTest", 2)
+ {
+ }
+
+ void runTests()
+ {
+ try {
+ char * pSrcDir = getenv("srcdir");
+ string sFilename;
+ if (pSrcDir) {
+ sFilename = (string)pSrcDir+"/";
+ }
+ sFilename += "../test/media/rgb24-64x64.png";
+ BitmapPtr pBmp = loadBitmap(sFilename, R8G8B8);
+ FilterColorize(15, 50).applyInPlace(pBmp);
+ FilterFlipRGB().applyInPlace(pBmp);
+ } catch (Exception & ex) {
+ cerr << ex.getStr() << endl;
+ setFailed();
+ }
+ }
+
+private:
+ BitmapPtr createBmp(const IntPoint& size, PixelFormat pf)
+ {
+ BitmapPtr pBmp;
+ pBmp = BitmapPtr(new Bitmap(size, pf));
+ return pBmp;
+ }
+};
+
+class FilterConvolTest: public GraphicsTest {
+public:
+ FilterConvolTest()
+ : GraphicsTest("FilterConvolTest", 2)
+ {
+ }
+
+ void runTests()
+ {
+ runPFTests<Pixel24>(R8G8B8);
+ runPFTests<Pixel32>(R8G8B8X8);
+ //FIXME runPFTests<Pixel8>(I8);
+ }
+
+private:
+ template<class PIXEL>
+ void runPFTests(PixelFormat pf)
+ {
+ BitmapPtr pBmp(new Bitmap(IntPoint(4, 4), pf));
+ initBmp<PIXEL>(pBmp);
+ float mat[9] =
+ {1,0,2,
+ 0,1,0,
+ 3,0,4};
+ BitmapPtr pNewBmp = FilterConvol<PIXEL>(&(mat[0]),3,3).apply(pBmp);
+ TEST(pNewBmp->getSize() == IntPoint(2,2));
+ unsigned char * pLine0 = pNewBmp->getPixels();
+ TEST(*(PIXEL*)pLine0 == PIXEL(1,0,0));
+ TEST(*(((PIXEL*)pLine0)+1) == PIXEL(4,0,0));
+ unsigned char * pLine1 = pNewBmp->getPixels()+pNewBmp->getStride();
+ TEST(*(PIXEL*)(pLine1) == PIXEL(0,0,9));
+ TEST(*((PIXEL*)(pLine1)+1) == PIXEL(0,0,16));
+
+ }
+
+ template<class PIXEL>
+ void initBmp(BitmapPtr pBmp)
+ {
+ PIXEL * pPixels = (PIXEL *)(pBmp->getPixels());
+ PIXEL color = PIXEL(0,0,0);
+ FilterFill<PIXEL>(color).applyInPlace(pBmp);
+ pPixels[0] = PIXEL(1,0,0);
+ pPixels[3] = PIXEL(2,0,0);
+ pPixels = (PIXEL*)((char *)pPixels+3*pBmp->getStride());
+ pPixels[0] = PIXEL(0,0,3);
+ pPixels[3] = PIXEL(0,0,4);
+ }
+};
+
+class Filter3x3Test: public GraphicsTest {
+public:
+ Filter3x3Test()
+ : GraphicsTest("Filter3x3Test", 2)
+ {
+ }
+
+ void runTests()
+ {
+ runPFTests<Pixel24>(R8G8B8);
+ runPFTests<Pixel32>(R8G8B8X8);
+ }
+
+private:
+ template<class PIXEL>
+ void runPFTests(PixelFormat pf)
+ {
+ BitmapPtr pBmp(new Bitmap(IntPoint(4, 4), pf));
+ initBmp<PIXEL>(pBmp);
+ float mat[3][3] =
+ {{1,0,2},
+ {0,1,0},
+ {3,0,4}};
+ BitmapPtr pNewBmp = Filter3x3(mat).apply(pBmp);
+ TEST(pNewBmp->getSize() == IntPoint(2,2));
+ unsigned char * pLine0 = pNewBmp->getPixels();
+ TEST(*(PIXEL*)pLine0 == PIXEL(1,0,0));
+ TEST(*(((PIXEL*)pLine0)+1) == PIXEL(4,0,0));
+ unsigned char * pLine1 = pNewBmp->getPixels()+pNewBmp->getStride();
+ TEST(*(PIXEL*)(pLine1) == PIXEL(0,0,9));
+ TEST(*((PIXEL*)(pLine1)+1) == PIXEL(0,0,16));
+
+ }
+
+ template<class PIXEL>
+ void initBmp(BitmapPtr pBmp)
+ {
+ PIXEL * pPixels = (PIXEL *)(pBmp->getPixels());
+ PIXEL color = PIXEL(0,0,0);
+ FilterFill<PIXEL>(color).applyInPlace(pBmp);
+ pPixels[0] = PIXEL(1,0,0);
+ pPixels[3] = PIXEL(2,0,0);
+ pPixels = (PIXEL*)((char *)pPixels+3*pBmp->getStride());
+ pPixels[0] = PIXEL(0,0,3);
+ pPixels[3] = PIXEL(0,0,4);
+ }
+};
+
+class HistoryPreProcessorTest: public GraphicsTest {
+public:
+ HistoryPreProcessorTest()
+ : GraphicsTest("HistoryPreProcessor", 2)
+ {
+ }
+
+ void runTests()
+ {
+ BitmapPtr pBaseBmp = initBmp(I8);
+ BitmapPtr pBmp = BitmapPtr(new Bitmap(*pBaseBmp));
+ BitmapPtr nullBmp = FilterFill<Pixel8>(0).apply(pBmp);
+ pBmp->copyPixels(*pBaseBmp);
+ HistoryPreProcessor filt(pBaseBmp->getSize(), 1, true);
+ pBmp = filt.apply(pBaseBmp);
+ testEqual(*pBmp, *nullBmp, "HistoryPreprocessor1");
+ for(int i=0;i<1;i++){
+ pBmp = filt.apply(pBaseBmp);
+ testEqual(*pBmp, *nullBmp, "HistoryPreprocessor2");
+ }
+ }
+
+};
+
+class FilterFastBandpassTest: public GraphicsTest {
+public:
+ FilterFastBandpassTest()
+ : GraphicsTest("FilterFastBandpassTest", 2)
+ {
+ }
+
+ void runTests()
+ {
+ BitmapPtr pBmp = BitmapPtr(new Bitmap(IntPoint(16,16), I8));
+ FilterFill<Pixel8>(0).applyInPlace(pBmp);
+ *(pBmp->getPixels()+pBmp->getStride()*7+7) = 255;
+ BitmapPtr pDestBmp = FilterFastBandpass().apply(pBmp);
+ testEqual(*pDestBmp, "FastBandpassResult", I8);
+ }
+};
+
+
+class FilterHighpassTest: public GraphicsTest {
+public:
+ FilterHighpassTest()
+ : GraphicsTest("FilterHighpassTest", 2)
+ {
+ }
+
+ void runTests()
+ {
+ BitmapPtr pBmp = BitmapPtr(new Bitmap(IntPoint(16,16), I8));
+ FilterFill<Pixel8>(0).applyInPlace(pBmp);
+ *(pBmp->getPixels()+pBmp->getStride()*7+7) = 255;
+ BitmapPtr pDestBmp = FilterHighpass().apply(pBmp);
+ testEqual(*pDestBmp, "HighpassResult", I8);
+ }
+};
+
+
+class FilterGaussTest: public GraphicsTest {
+public:
+ FilterGaussTest()
+ : GraphicsTest("FilterGaussTest", 2)
+ {
+ }
+
+ void runTests()
+ {
+ BitmapPtr pBmp = BitmapPtr(new Bitmap(IntPoint(16,16), I8));
+ FilterFill<Pixel8>(0).applyInPlace(pBmp);
+ *(pBmp->getPixels()+pBmp->getStride()*7+7) = 255;
+ BitmapPtr pDestBmp = FilterGauss(3).apply(pBmp);
+ testEqual(*pDestBmp, "Gauss3Result", I8);
+ pDestBmp = FilterGauss(1).apply(pBmp);
+ testEqual(*pDestBmp, "Gauss1Result", I8);
+ pDestBmp = FilterGauss(1.5).apply(pBmp);
+ testEqual(*pDestBmp, "Gauss15Result", I8);
+ pDestBmp = FilterGauss(5).apply(pBmp);
+ testEqual(*pDestBmp, "Gauss5Result", I8);
+ }
+};
+
+
+class FilterBlurTest: public GraphicsTest {
+public:
+ FilterBlurTest()
+ : GraphicsTest("FilterBlurTest", 2)
+ {
+ }
+
+ void runTests()
+ {
+ BitmapPtr pBmp = BitmapPtr(new Bitmap(IntPoint(16,16), I8));
+ FilterFill<Pixel8>(0).applyInPlace(pBmp);
+ *(pBmp->getPixels()+pBmp->getStride()*7+7) = 255;
+ BitmapPtr pDestBmp = FilterBlur().apply(pBmp);
+ testEqual(*pDestBmp, "BlurResult", I8);
+ }
+};
+
+
+class FilterBandpassTest: public GraphicsTest {
+public:
+ FilterBandpassTest()
+ : GraphicsTest("FilterBandpassTest", 2)
+ {
+ }
+
+ void runTests()
+ {
+ BitmapPtr pBmp = BitmapPtr(new Bitmap(IntPoint(16,16), I8));
+ FilterFill<Pixel8>(0).applyInPlace(pBmp);
+ *(pBmp->getPixels()+pBmp->getStride()*7+7) = 255;
+
+ BitmapPtr pDestBmp = FilterBandpass(1.9,3).apply(pBmp);
+ testEqual(*pDestBmp, "BandpassResult", I8);
+ }
+};
+
+class FilterFastDownscaleTest: public GraphicsTest {
+public:
+ FilterFastDownscaleTest()
+ : GraphicsTest("FilterFastDownscaleTest", 2)
+ {
+ }
+
+ void runTests()
+ {
+ BitmapPtr pBmp = BitmapPtr(new Bitmap(IntPoint(4,4), I8));
+ FilterFill<Pixel8>(0).applyInPlace(pBmp);
+ *(pBmp->getPixels()+pBmp->getStride()*3+3) = 252;
+
+ BitmapPtr pDestBmp = FilterFastDownscale(2).apply(pBmp);
+ testEqual(*pDestBmp, "FastDownscaleResult", I8);
+ }
+};
+
+class FilterMaskTest: public GraphicsTest {
+public:
+ FilterMaskTest()
+ : GraphicsTest("FilterMaskTest", 2)
+ {
+ }
+
+ void runTests()
+ {
+ runTestsWithBmp(initBmp(I8), "I8");
+ runTestsWithBmp(initBmp(B8G8R8), "B8G8R8");
+ runTestsWithBmp(initBmp(B8G8R8X8), "B8G8R8X8");
+ }
+
+private:
+ void runTestsWithBmp(BitmapPtr pBmp, const string& sName)
+ {
+ BitmapPtr pMaskBmp = BitmapPtr(new Bitmap(pBmp->getSize(), I8));
+ FilterFill<Pixel8>(0).applyInPlace(pMaskBmp);
+ for (int y = 0; y < pBmp->getSize().y; y++) {
+ pMaskBmp->setPixel(IntPoint(1, y), Pixel8(128));
+ pMaskBmp->setPixel(IntPoint(2, y), Pixel8(255));
+ pMaskBmp->setPixel(IntPoint(3, y), Pixel8(255));
+ }
+
+ BitmapPtr pDestBmp = FilterMask(pMaskBmp).apply(pBmp);
+ string sFName = string("baseline/MaskResult")+sName+".png";
+// pDestBmp->save(sFName);
+ sFName = getSrcDirName()+sFName;
+ BitmapPtr pBaselineBmp = loadBitmap(sFName, pBmp->getPixelFormat());
+ TEST(*pDestBmp == *pBaselineBmp);
+ }
+};
+
+class FilterThresholdTest: public GraphicsTest {
+public:
+ FilterThresholdTest()
+ : GraphicsTest("FilterThresholdTest", 2)
+ {
+ }
+
+ void runTests()
+ {
+ BitmapPtr pBmp(initBmp(I8));
+ BitmapPtr pDestBmp = FilterThreshold(1).apply(pBmp);
+ string sFName = "baseline/ThresholdResult.png";
+// pDestBmp->save(sFName);
+ sFName = getSrcDirName()+sFName;
+ BitmapPtr pBaselineBmp = loadBitmap(sFName, pBmp->getPixelFormat());
+ TEST(*pDestBmp == *pBaselineBmp);
+ }
+};
+
+class FilterFloodfillTest: public GraphicsTest {
+public:
+ FilterFloodfillTest()
+ : GraphicsTest("FilterFloodfillTest", 2)
+ {
+ }
+
+ void runTests()
+ {
+ BitmapPtr pBmp = loadTestBmp("floodfill");
+ BitmapPtr pDestBmp = FilterFloodfill<ColorTester>(
+ ColorTester(Pixel32(255,255,255,255)), IntPoint(4,3)).apply(pBmp);
+ testEqual(*pDestBmp, "FloodfillResult", B8G8R8A8, 0, 0);
+ }
+
+};
+
+class FilterDilationTest: public GraphicsTest {
+public:
+ FilterDilationTest()
+ : GraphicsTest("FilterDilationTest", 2)
+ {
+ }
+
+ void runTests()
+ {
+ BitmapPtr pBmp = loadTestBmp("dilation", I8);
+ BitmapPtr pDestBmp = FilterDilation().apply(pBmp);
+ testEqual(*pDestBmp, "DilationResult", I8, 0, 0);
+ }
+
+};
+
+class FilterErosionTest: public GraphicsTest {
+public:
+ FilterErosionTest()
+ : GraphicsTest("FilterErosionTest", 2)
+ {
+ }
+
+ void runTests()
+ {
+ BitmapPtr pBmp = loadTestBmp("erosion", I8);
+ BitmapPtr pDestBmp = FilterErosion().apply(pBmp);
+ testEqual(*pDestBmp, "ErosionResult", I8, 0, 0);
+ }
+
+};
+
+class FilterAlphaTest: public GraphicsTest {
+public:
+ FilterAlphaTest()
+ : GraphicsTest("FilterAlphaTest", 2)
+ {
+ }
+
+ void runTests()
+ {
+ BitmapPtr pBmp = loadTestBmp("rgb24alpha-64x64", R8G8B8A8);
+ BitmapPtr pAlphaBmp = FilterGetAlpha().apply(pBmp);
+ testEqual(*pAlphaBmp, "GetAlphaResult", I8, 0, 0);
+ BitmapPtr pDestBmp(new Bitmap(*pBmp));
+ pDestBmp->setAlpha(*pAlphaBmp);
+ testEqual(*pDestBmp, *pBmp, "SetAlphaResult", 0, 0);
+ }
+
+};
+
+class FilterResizeBilinearTest: public GraphicsTest {
+public:
+ FilterResizeBilinearTest()
+ : GraphicsTest("FilterResizeBilinearTest", 2)
+ {
+ }
+
+ void runTests()
+ {
+ BitmapPtr pBmp = loadTestBmp("rgb24alpha-64x64", B8G8R8A8);
+ runTestWithBitmap(pBmp);
+ pBmp = loadTestBmp("rgb24-64x64", B8G8R8X8);
+ runTestWithBitmap(pBmp);
+ pBmp = loadTestBmp("rgb24-65x65", B8G8R8);
+ runTestWithBitmap(pBmp);
+ }
+
+private:
+ void runTestWithBitmap(BitmapPtr pBmp)
+ {
+ BitmapPtr pDestBmp = FilterResizeBilinear(IntPoint(32,32)).apply(pBmp);
+ string sName = string("ResizeBilinearResult")
+ +getPixelFormatString(pBmp->getPixelFormat());
+ testEqual(*pDestBmp, sName, pBmp->getPixelFormat());
+ }
+
+};
+
+class FilterUnmultiplyAlphaTest: public GraphicsTest {
+public:
+ FilterUnmultiplyAlphaTest()
+ : GraphicsTest("FilterUnmultiplyAlphaTest", 2)
+ {
+ }
+
+ void runTests()
+ {
+ BitmapPtr pBmp(new Bitmap(IntPoint(16, 1), B8G8R8A8));
+ for (int x = 0; x < 16; ++x) {
+ unsigned char * pPixel = pBmp->getPixels()+x*4;
+ unsigned char val = 17*x;
+ *(pPixel+REDPOS) = val;
+ *(pPixel+GREENPOS) = val;
+ *(pPixel+BLUEPOS) = val;
+ *(pPixel+ALPHAPOS) = val;
+ }
+ FilterUnmultiplyAlpha().applyInPlace(pBmp);
+ QUIET_TEST(*(pBmp->getPixels()+ALPHAPOS) == 0);
+ for (int x = 1; x < 16; ++x) {
+ unsigned char * pPixel = pBmp->getPixels()+x*4;
+ QUIET_TEST(*(pPixel+REDPOS) == 255);
+ QUIET_TEST(*(pPixel+GREENPOS) == 255);
+ QUIET_TEST(*(pPixel+BLUEPOS) == 255);
+ QUIET_TEST(*(pPixel+ALPHAPOS) == 17*x);
+ }
+ }
+
+private:
+
+};
+
+class GraphicsTestSuite: public TestSuite {
+public:
+ GraphicsTestSuite()
+ : TestSuite("GraphicsTestSuite")
+ {
+ addTest(TestPtr(new PixelTest));
+ addTest(TestPtr(new BitmapTest));
+ addTest(TestPtr(new Filter3x3Test));
+ addTest(TestPtr(new FilterConvolTest));
+ addTest(TestPtr(new FilterColorizeTest));
+ addTest(TestPtr(new FilterGrayscaleTest));
+ addTest(TestPtr(new FilterFillTest));
+ addTest(TestPtr(new FilterFlipTest));
+ addTest(TestPtr(new FilterFlipRGBTest));
+ addTest(TestPtr(new FilterFlipUVTest));
+ addTest(TestPtr(new FilterComboTest));
+ addTest(TestPtr(new HistoryPreProcessorTest));
+ addTest(TestPtr(new FilterHighpassTest));
+ addTest(TestPtr(new FilterGaussTest));
+ addTest(TestPtr(new FilterBlurTest));
+ addTest(TestPtr(new FilterBandpassTest));
+ addTest(TestPtr(new FilterFastBandpassTest));
+ addTest(TestPtr(new FilterFastDownscaleTest));
+ addTest(TestPtr(new FilterMaskTest));
+ addTest(TestPtr(new FilterThresholdTest));
+ addTest(TestPtr(new FilterFloodfillTest));
+ addTest(TestPtr(new FilterDilationTest));
+ addTest(TestPtr(new FilterErosionTest));
+ addTest(TestPtr(new FilterAlphaTest));
+ addTest(TestPtr(new FilterResizeBilinearTest));
+ addTest(TestPtr(new FilterUnmultiplyAlphaTest));
+ }
+};
+
+
+int main(int nargs, char** args)
+{
+ BitmapLoader::init(true);
+ GraphicsTest::createResultImgDir();
+ GraphicsTestSuite suite;
+ suite.runTests();
+ bool bOK = suite.isOk();
+
+ if (bOK) {
+ return 0;
+ } else {
+ return 1;
+ }
+}
+