X-Git-Url: https://git.sesse.net/?p=movit;a=blobdiff_plain;f=fft_convolution_effect_test.cpp;fp=fft_convolution_effect_test.cpp;h=f0f85278cd1ae045226d165d29c3f380946cd8f8;hp=0000000000000000000000000000000000000000;hb=3ccf5fb197c9a72545affc0b7286349d5603b72e;hpb=74ac64b2e402247edf61271a4862e657da7fe135 diff --git a/fft_convolution_effect_test.cpp b/fft_convolution_effect_test.cpp new file mode 100644 index 0000000..f0f8527 --- /dev/null +++ b/fft_convolution_effect_test.cpp @@ -0,0 +1,211 @@ +// Unit tests for FFTConvolutionEffect. + +#include +#include + +#include "effect_chain.h" +#include "gtest/gtest.h" +#include "image_format.h" +#include "test_util.h" +#include "fft_convolution_effect.h" + +namespace movit { + +TEST(FFTConvolutionEffectTest, Identity) { + const int size = 4; + + float data[size * size] = { + 0.1, 1.1, 2.1, 3.1, + 0.2, 1.2, 2.2, 3.2, + 0.3, 1.3, 2.3, 3.3, + 0.4, 1.4, 2.4, 3.4, + }; + float out_data[size * size]; + + for (int convolve_size = 1; convolve_size < 10; ++convolve_size) { + float kernel[convolve_size * convolve_size]; + for (int i = 0; i < convolve_size * convolve_size; ++i) { + kernel[i] = 0.0f; + } + kernel[0] = 1.0f; + + EffectChainTester tester(NULL, size, size, FORMAT_GRAYSCALE, COLORSPACE_sRGB, GAMMA_LINEAR); + tester.add_input(data, FORMAT_GRAYSCALE, COLORSPACE_sRGB, GAMMA_LINEAR, size, size); + + FFTConvolutionEffect *fft_effect = new FFTConvolutionEffect(size, size, convolve_size, convolve_size); + tester.get_chain()->add_effect(fft_effect); + fft_effect->set_convolution_kernel(kernel); + tester.run(out_data, GL_RED, COLORSPACE_sRGB, GAMMA_LINEAR, OUTPUT_ALPHA_FORMAT_PREMULTIPLIED); + + expect_equal(data, out_data, size, size, 0.02, 0.003); + } +} + +TEST(FFTConvolutionEffectTest, Constant) { + const int size = 4, convolve_size = 17; + const float f = 7.0f; + + float data[size * size] = { + 0.1, 1.1, 2.1, 3.1, + 0.2, 1.2, 2.2, 3.2, + 0.3, 1.3, 2.3, 3.3, + 0.4, 1.4, 2.4, 3.4, + }; + float expected_data[size * size] = { + f * 0.1, f * 1.1, f * 2.1, f * 3.1, + f * 0.2, f * 1.2, f * 2.2, f * 3.2, + f * 0.3, f * 1.3, f * 2.3, f * 3.3, + f * 0.4, f * 1.4, f * 2.4, f * 3.4, + }; + float out_data[size * size]; + float kernel[convolve_size * convolve_size]; + for (int i = 0; i < convolve_size * convolve_size; ++i) { + kernel[i] = 0.0f; + } + kernel[0] = f; + + EffectChainTester tester(NULL, size, size, FORMAT_GRAYSCALE, COLORSPACE_sRGB, GAMMA_LINEAR); + tester.add_input(data, FORMAT_GRAYSCALE, COLORSPACE_sRGB, GAMMA_LINEAR, size, size); + + FFTConvolutionEffect *fft_effect = new FFTConvolutionEffect(size, size, convolve_size, convolve_size); + tester.get_chain()->add_effect(fft_effect); + fft_effect->set_convolution_kernel(kernel); + tester.run(out_data, GL_RED, COLORSPACE_sRGB, GAMMA_LINEAR, OUTPUT_ALPHA_FORMAT_PREMULTIPLIED); + + // Somewhat looser bounds due to the higher magnitude. + expect_equal(expected_data, out_data, size, size, f * 0.03, f * 0.004); +} + +TEST(FFTConvolutionEffectTest, MoveRight) { + const int size = 4, convolve_size = 3; + + float data[size * size] = { + 0.1, 1.1, 2.1, 3.1, + 0.2, 1.2, 2.2, 3.2, + 0.3, 1.3, 2.3, 3.3, + 0.4, 1.4, 2.4, 3.4, + }; + float kernel[convolve_size * convolve_size] = { + 0.0, 1.0, 0.0, + 0.0, 0.0, 0.0, + 0.0, 0.0, 0.0, + }; + float expected_data[size * size] = { + 0.1, 0.1, 1.1, 2.1, + 0.2, 0.2, 1.2, 2.2, + 0.3, 0.3, 1.3, 2.3, + 0.4, 0.4, 1.4, 2.4, + }; + float out_data[size * size]; + + EffectChainTester tester(NULL, size, size, FORMAT_GRAYSCALE, COLORSPACE_sRGB, GAMMA_LINEAR); + tester.add_input(data, FORMAT_GRAYSCALE, COLORSPACE_sRGB, GAMMA_LINEAR, size, size); + + FFTConvolutionEffect *fft_effect = new FFTConvolutionEffect(size, size, convolve_size, convolve_size); + tester.get_chain()->add_effect(fft_effect); + fft_effect->set_convolution_kernel(kernel); + tester.run(out_data, GL_RED, COLORSPACE_sRGB, GAMMA_LINEAR, OUTPUT_ALPHA_FORMAT_PREMULTIPLIED); + + expect_equal(expected_data, out_data, size, size, 0.02, 0.003); +} + +TEST(FFTConvolutionEffectTest, MoveDown) { + const int size = 4, convolve_size = 3; + + float data[size * size] = { + 0.1, 1.1, 2.1, 3.1, + 0.2, 1.2, 2.2, 3.2, + 0.3, 1.3, 2.3, 3.3, + 0.4, 1.4, 2.4, 3.4, + }; + float kernel[convolve_size * convolve_size] = { + 0.0, 0.0, 0.0, + 1.0, 0.0, 0.0, + 0.0, 0.0, 0.0, + }; + float expected_data[size * size] = { + 0.1, 1.1, 2.1, 3.1, + 0.1, 1.1, 2.1, 3.1, + 0.2, 1.2, 2.2, 3.2, + 0.3, 1.3, 2.3, 3.3, + }; + float out_data[size * size]; + + EffectChainTester tester(NULL, size, size, FORMAT_GRAYSCALE, COLORSPACE_sRGB, GAMMA_LINEAR); + tester.add_input(data, FORMAT_GRAYSCALE, COLORSPACE_sRGB, GAMMA_LINEAR, size, size); + + FFTConvolutionEffect *fft_effect = new FFTConvolutionEffect(size, size, convolve_size, convolve_size); + tester.get_chain()->add_effect(fft_effect); + fft_effect->set_convolution_kernel(kernel); + tester.run(out_data, GL_RED, COLORSPACE_sRGB, GAMMA_LINEAR, OUTPUT_ALPHA_FORMAT_PREMULTIPLIED); + + expect_equal(expected_data, out_data, size, size, 0.02, 0.003); +} + +TEST(FFTConvolutionEffectTest, MergeWithLeft) { + const int size = 4, convolve_size = 3; + + float data[size * size] = { + 0.1, 1.1, 2.1, 3.1, + 0.2, 1.2, 2.2, 3.2, + 0.3, 1.3, 2.3, 3.3, + 0.4, 1.4, 2.4, 3.4, + }; + float kernel[convolve_size * convolve_size] = { + 1.0, 1.0, 0.0, + 0.0, 0.0, 0.0, + 0.0, 0.0, 0.0, + }; + float expected_data[size * size] = { + 0.1 + 0.1, 0.1 + 1.1, 1.1 + 2.1, 2.1 + 3.1, + 0.2 + 0.2, 0.2 + 1.2, 1.2 + 2.2, 2.2 + 3.2, + 0.3 + 0.3, 0.3 + 1.3, 1.3 + 2.3, 2.3 + 3.3, + 0.4 + 0.4, 0.4 + 1.4, 1.4 + 2.4, 2.4 + 3.4, + }; + float out_data[size * size]; + + EffectChainTester tester(NULL, size, size, FORMAT_GRAYSCALE, COLORSPACE_sRGB, GAMMA_LINEAR); + tester.add_input(data, FORMAT_GRAYSCALE, COLORSPACE_sRGB, GAMMA_LINEAR, size, size); + + FFTConvolutionEffect *fft_effect = new FFTConvolutionEffect(size, size, convolve_size, convolve_size); + tester.get_chain()->add_effect(fft_effect); + fft_effect->set_convolution_kernel(kernel); + tester.run(out_data, GL_RED, COLORSPACE_sRGB, GAMMA_LINEAR, OUTPUT_ALPHA_FORMAT_PREMULTIPLIED); + + expect_equal(expected_data, out_data, size, size, 0.02, 0.003); +} + +TEST(FFTConvolutionEffectTest, NegativeCoefficients) { + const int size = 4; + const int convolve_width = 3, convolve_height = 2; + + float data[size * size] = { + 0.1, 1.1, 2.1, 3.1, + 0.2, 1.2, 2.2, 3.2, + 0.3, 1.3, 2.3, 3.3, + 0.4, 1.4, 2.4, 3.4, + }; + float kernel[convolve_width * convolve_height] = { + 1.0, 0.0, 0.0, + 0.0, 0.0, -0.5, + }; + float expected_data[size * size] = { + 0.1 - 0.5 * 0.1, 1.1 - 0.5 * 0.1, 2.1 - 0.5 * 0.1, 3.1 - 0.5 * 1.1, + 0.2 - 0.5 * 0.1, 1.2 - 0.5 * 0.1, 2.2 - 0.5 * 0.1, 3.2 - 0.5 * 1.1, + 0.3 - 0.5 * 0.2, 1.3 - 0.5 * 0.2, 2.3 - 0.5 * 0.2, 3.3 - 0.5 * 1.2, + 0.4 - 0.5 * 0.3, 1.4 - 0.5 * 0.3, 2.4 - 0.5 * 0.3, 3.4 - 0.5 * 1.3, + }; + float out_data[size * size]; + + EffectChainTester tester(NULL, size, size, FORMAT_GRAYSCALE, COLORSPACE_sRGB, GAMMA_LINEAR); + tester.add_input(data, FORMAT_GRAYSCALE, COLORSPACE_sRGB, GAMMA_LINEAR, size, size); + + FFTConvolutionEffect *fft_effect = new FFTConvolutionEffect(size, size, convolve_width, convolve_height); + tester.get_chain()->add_effect(fft_effect); + fft_effect->set_convolution_kernel(kernel); + tester.run(out_data, GL_RED, COLORSPACE_sRGB, GAMMA_LINEAR, OUTPUT_ALPHA_FORMAT_PREMULTIPLIED); + + expect_equal(expected_data, out_data, size, size, 0.02, 0.003); +} + +} // namespace movit