Add a unit test for MixEffect.
authorSteinar H. Gunderson <sgunderson@bigfoot.com>
Fri, 12 Oct 2012 00:25:34 +0000 (02:25 +0200)
committerSteinar H. Gunderson <sgunderson@bigfoot.com>
Fri, 12 Oct 2012 00:25:34 +0000 (02:25 +0200)
Makefile
mix_effect_test.cpp [new file with mode: 0644]
test_util.cpp
test_util.h

index 0ebb884..69e9ef4 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -7,7 +7,7 @@ LDFLAGS=-lSDL -lSDL_image -lGL -lrt -lpthread
 RANLIB=ranlib
 
 DEMO_OBJS=demo.o
-TESTS=effect_chain_test
+TESTS=effect_chain_test mix_effect_test
 
 # Core.
 LIB_OBJS=util.o widgets.o effect.o effect_chain.o
@@ -48,6 +48,8 @@ gtest_sdl_main.o: gtest_sdl_main.cpp
 # Unit tests.
 effect_chain_test: effect_chain_test.o $(TEST_OBJS) libmovit.a
        $(CXX) -o $@ effect_chain_test.o $(TEST_OBJS) libmovit.a $(LDFLAGS)
+mix_effect_test: mix_effect_test.o $(TEST_OBJS) libmovit.a
+       $(CXX) -o $@ mix_effect_test.o $(TEST_OBJS) libmovit.a $(LDFLAGS)
 
 OBJS=$(DEMO_OBJS) $(LIB_OBJS) $(GDEMO_OBJS)
 
diff --git a/mix_effect_test.cpp b/mix_effect_test.cpp
new file mode 100644 (file)
index 0000000..cae4b28
--- /dev/null
@@ -0,0 +1,105 @@
+// Unit tests for MixEffect.
+
+#include "test_util.h"
+#include "gtest/gtest.h"
+#include "mix_effect.h"
+
+TEST(MixEffectTest, FiftyFiftyMix) {
+       float data_a[] = {
+               0.0f, 0.25f,
+               0.75f, 1.0f,
+       };
+       float data_b[] = {
+               1.0f, 0.5f,
+               0.75f, 0.6f,
+       };
+       float expected_data[] = {
+               0.5f, 0.375f,
+               0.75f, 0.8f,
+       };
+       float out_data[4];
+       EffectChainTester tester(data_a, 2, 2, COLORSPACE_sRGB, GAMMA_LINEAR);
+       Effect *input1 = tester.get_chain()->last_added_effect();
+       Effect *input2 = tester.add_input(data_b, COLORSPACE_sRGB, GAMMA_LINEAR);
+
+       Effect *mix_effect = tester.get_chain()->add_effect(new MixEffect(), input1, input2);
+       ASSERT_TRUE(mix_effect->set_float("strength_first", 0.5f));
+       ASSERT_TRUE(mix_effect->set_float("strength_second", 0.5f));
+       tester.run(out_data, COLORSPACE_sRGB, GAMMA_LINEAR);
+
+       expect_equal(expected_data, out_data, 2, 2);
+}
+
+TEST(MixEffectTest, OnlyA) {
+       float data_a[] = {
+               0.0f, 0.25f,
+               0.75f, 1.0f,
+       };
+       float data_b[] = {
+               1.0f, 0.5f,
+               0.75f, 0.6f,
+       };
+       float out_data[4];
+       EffectChainTester tester(data_a, 2, 2, COLORSPACE_sRGB, GAMMA_LINEAR);
+       Effect *input1 = tester.get_chain()->last_added_effect();
+       Effect *input2 = tester.add_input(data_b, COLORSPACE_sRGB, GAMMA_LINEAR);
+
+       Effect *mix_effect = tester.get_chain()->add_effect(new MixEffect(), input1, input2);
+       ASSERT_TRUE(mix_effect->set_float("strength_first", 1.0f));
+       ASSERT_TRUE(mix_effect->set_float("strength_second", 0.0f));
+       tester.run(out_data, COLORSPACE_sRGB, GAMMA_LINEAR);
+
+       expect_equal(data_a, out_data, 2, 2);
+}
+
+TEST(MixEffectTest, DoesNotSumToOne) {
+       float data_a[] = {
+               1.0f, 0.5f,
+               0.75f, 1.0f,
+       };
+       float data_b[] = {
+               1.0f, 0.25f,
+               0.15f, 0.6f,
+       };
+       float expected_data[] = {
+               0.0f, 0.25f,
+               0.6f, 0.4f,
+       };
+       float out_data[4];
+       EffectChainTester tester(data_a, 2, 2, COLORSPACE_sRGB, GAMMA_LINEAR);
+       Effect *input1 = tester.get_chain()->last_added_effect();
+       Effect *input2 = tester.add_input(data_b, COLORSPACE_sRGB, GAMMA_LINEAR);
+
+       Effect *mix_effect = tester.get_chain()->add_effect(new MixEffect(), input1, input2);
+       ASSERT_TRUE(mix_effect->set_float("strength_first", 1.0f));
+       ASSERT_TRUE(mix_effect->set_float("strength_second", -1.0f));
+       tester.run(out_data, COLORSPACE_sRGB, GAMMA_LINEAR);
+
+       expect_equal(expected_data, out_data, 2, 2);
+}
+
+TEST(MixEffectTest, MixesLinearlyDespitesRGBInputsAndOutputs) {
+       float data_a[] = {
+               0.0f, 0.25f,
+               0.75f, 1.0f,
+       };
+       float data_b[] = {
+               0.0f, 0.0f,
+               0.0f, 0.0f,
+       };
+       float expected_data[] = {  // sRGB(0.5 * inv_sRGB(a)).
+               0.00000f, 0.17349f,
+               0.54807f, 0.73536f,
+       };
+       float out_data[4];
+       EffectChainTester tester(data_a, 2, 2, COLORSPACE_sRGB, GAMMA_sRGB);
+       Effect *input1 = tester.get_chain()->last_added_effect();
+       Effect *input2 = tester.add_input(data_b, COLORSPACE_sRGB, GAMMA_sRGB);
+
+       Effect *mix_effect = tester.get_chain()->add_effect(new MixEffect(), input1, input2);
+       ASSERT_TRUE(mix_effect->set_float("strength_first", 0.5f));
+       ASSERT_TRUE(mix_effect->set_float("strength_second", 0.5f));
+       tester.run(out_data, COLORSPACE_sRGB, GAMMA_sRGB);
+
+       expect_equal(expected_data, out_data, 2, 2);
+}
index a52eb79..8fa6714 100644 (file)
@@ -9,6 +9,11 @@
 
 EffectChainTester::EffectChainTester(const float *data, unsigned width, unsigned height, ColorSpace color_space, GammaCurve gamma_curve)
        : chain(width, height), width(width), height(height)
+{
+       add_input(data, color_space, gamma_curve);
+}
+
+Input *EffectChainTester::add_input(const float *data, ColorSpace color_space, GammaCurve gamma_curve)
 {
        ImageFormat format;
        format.color_space = color_space;
@@ -17,6 +22,7 @@ EffectChainTester::EffectChainTester(const float *data, unsigned width, unsigned
        FlatInput *input = new FlatInput(format, FORMAT_GRAYSCALE, GL_FLOAT, width, height);
        input->set_pixel_data(data);
        chain.add_input(input);
+       return input;
 }
 
 void EffectChainTester::run(float *out_data, ColorSpace color_space, GammaCurve gamma_curve)
index ed0275e..0c2e7b9 100644 (file)
@@ -7,6 +7,7 @@ class EffectChainTester {
 public:
        EffectChainTester(const float *data, unsigned width, unsigned height, ColorSpace color_space, GammaCurve gamma_curve);
        EffectChain *get_chain() { return &chain; }
+       Input *add_input(const float *data, ColorSpace color_space, GammaCurve gamma_curve);
        void run(float *out_data, ColorSpace color_space, GammaCurve gamma_curve);
 
 private: