X-Git-Url: https://git.sesse.net/?p=movit;a=blobdiff_plain;f=effect_chain_test.cpp;h=ace160f1a015a11464eb586e1fcd5c44e714f331;hp=5df9270f3b09d48c344bda1569b84895d92478ab;hb=a616ded3842994840ce0cfa365d259f602493779;hpb=898a2140fa78eecb3552f63f021c608b239f969c diff --git a/effect_chain_test.cpp b/effect_chain_test.cpp index 5df9270..ace160f 100644 --- a/effect_chain_test.cpp +++ b/effect_chain_test.cpp @@ -2,12 +2,13 @@ // // Note that this also contains the tests for some of the simpler effects. +#include + #include "effect_chain.h" #include "flat_input.h" #include "gtest/gtest.h" #include "mirror_effect.h" #include "resize_effect.h" -#include "opengl.h" #include "test_util.h" TEST(EffectChainTest, EmptyChain) { @@ -135,6 +136,31 @@ TEST(EffectChainTest, RewritingWorksAndGammaConversionsAreInserted) { expect_equal(expected_data, out_data, 3, 2); } +TEST(EffectChainTest, RewritingWorksAndTexturesAreAskedForsRGB) { + unsigned char data[] = { + 0, 64, + 128, 255, + }; + float expected_data[4] = { + 1.0f, 0.9771f, + 0.8983f, 0.0f, + }; + float out_data[2]; + EffectChainTester tester(NULL, 2, 2); + tester.add_input(data, FORMAT_GRAYSCALE, COLORSPACE_sRGB, GAMMA_sRGB); + RewritingToInvertEffect *effect = new RewritingToInvertEffect(); + tester.get_chain()->add_effect(effect); + tester.run(out_data, GL_RED, COLORSPACE_sRGB, GAMMA_sRGB); + + Node *node = effect->invert_node; + ASSERT_EQ(1, node->incoming_links.size()); + ASSERT_EQ(1, node->outgoing_links.size()); + EXPECT_EQ("FlatInput", node->incoming_links[0]->effect->effect_type_id()); + EXPECT_EQ("GammaCompressionEffect", node->outgoing_links[0]->effect->effect_type_id()); + + expect_equal(expected_data, out_data, 2, 2); +} + TEST(EffectChainTest, RewritingWorksAndColorspaceConversionsAreInserted) { float data[] = { 0.0f, 0.25f, 0.3f, @@ -153,12 +179,67 @@ TEST(EffectChainTest, RewritingWorksAndColorspaceConversionsAreInserted) { Node *node = effect->invert_node; ASSERT_EQ(1, node->incoming_links.size()); ASSERT_EQ(1, node->outgoing_links.size()); - EXPECT_EQ("ColorSpaceConversionEffect", node->incoming_links[0]->effect->effect_type_id()); - EXPECT_EQ("ColorSpaceConversionEffect", node->outgoing_links[0]->effect->effect_type_id()); + EXPECT_EQ("ColorspaceConversionEffect", node->incoming_links[0]->effect->effect_type_id()); + EXPECT_EQ("ColorspaceConversionEffect", node->outgoing_links[0]->effect->effect_type_id()); expect_equal(expected_data, out_data, 3, 2); } +// A fake input that can change its output colorspace and gamma between instantiation +// and finalize. +class UnknownColorspaceInput : public FlatInput { +public: + UnknownColorspaceInput(ImageFormat format, MovitPixelFormat pixel_format, GLenum type, unsigned width, unsigned height) + : FlatInput(format, pixel_format, type, width, height), + overridden_color_space(format.color_space), + overridden_gamma_curve(format.gamma_curve) {} + virtual std::string effect_type_id() const { return "UnknownColorspaceInput"; } + + void set_color_space(Colorspace colorspace) { + overridden_color_space = colorspace; + } + void set_gamma_curve(GammaCurve gamma_curve) { + overridden_gamma_curve = gamma_curve; + } + Colorspace get_color_space() const { return overridden_color_space; } + GammaCurve get_gamma_curve() const { return overridden_gamma_curve; } + +private: + Colorspace overridden_color_space; + GammaCurve overridden_gamma_curve; +}; + +TEST(EffectChainTester, HandlesInputChangingColorspace) { + const int size = 4; + + float data[size] = { + 0.0, + 0.5, + 0.7, + 1.0, + }; + float out_data[size]; + + EffectChainTester tester(NULL, 4, 1, FORMAT_GRAYSCALE); + + // First say that we have sRGB, linear input. + ImageFormat format; + format.color_space = COLORSPACE_sRGB; + format.gamma_curve = GAMMA_LINEAR; + + UnknownColorspaceInput *input = new UnknownColorspaceInput(format, FORMAT_GRAYSCALE, GL_FLOAT, 4, 1); + input->set_pixel_data(data); + tester.get_chain()->add_input(input); + + // Now we change to Rec. 601 input. + input->set_color_space(COLORSPACE_REC_601_625); + input->set_gamma_curve(GAMMA_REC_601); + + // Now ask for Rec. 601 output. Thus, our chain should now be a no-op. + tester.run(out_data, GL_RED, COLORSPACE_REC_601_625, GAMMA_REC_601); + expect_equal(data, out_data, 4, 1); +} + // Like RewritingToInvertEffect, but splicing in a MirrorEffect instead, // which does not need linear light or sRGB primaries. class RewritingToMirrorEffect : public Effect { @@ -239,6 +320,23 @@ TEST(EffectChainTest, IdentityThroughsRGBConversions) { expect_equal(data, out_data, 256, 1); } +// Same, but uses the forward sRGB table from the GPU. +TEST(EffectChainTest, IdentityThroughGPUsRGBConversions) { + unsigned char data[256]; + float expected_data[256]; + for (unsigned i = 0; i < 256; ++i) { + data[i] = i; + expected_data[i] = i / 255.0; + }; + float out_data[256]; + EffectChainTester tester(NULL, 256, 1); + tester.add_input(data, FORMAT_GRAYSCALE, COLORSPACE_sRGB, GAMMA_sRGB); + tester.get_chain()->add_effect(new IdentityEffect()); + tester.run(out_data, GL_RED, COLORSPACE_sRGB, GAMMA_sRGB); + + expect_equal(expected_data, out_data, 256, 1); +} + // Same, for the Rec. 601/709 gamma curve. TEST(EffectChainTest, IdentityThroughRec709) { float data[256];