]> git.sesse.net Git - movit/blob - unsharp_mask_effect_test.cpp
Do not bother with unbinding vertex attributes; that is automatically done when we...
[movit] / unsharp_mask_effect_test.cpp
1 // Unit tests for UnsharpMaskEffect.
2
3 #include <epoxy/gl.h>
4 #include <math.h>
5
6 #include "effect_chain.h"
7 #include "gtest/gtest.h"
8 #include "image_format.h"
9 #include "test_util.h"
10 #include "unsharp_mask_effect.h"
11
12 namespace movit {
13
14 TEST(UnsharpMaskEffectTest, NoAmountDoesNothing) {
15         const int size = 4;
16
17         float data[size * size] = {
18                 0.0, 1.0, 0.0, 1.0,
19                 0.0, 1.0, 1.0, 0.0,
20                 0.0, 0.5, 1.0, 0.5,
21                 0.0, 0.0, 0.0, 0.0,
22         };
23         float out_data[size * size];
24
25         EffectChainTester tester(data, size, size, FORMAT_GRAYSCALE, COLORSPACE_sRGB, GAMMA_LINEAR);
26         Effect *unsharp_mask_effect = tester.get_chain()->add_effect(new UnsharpMaskEffect());
27         ASSERT_TRUE(unsharp_mask_effect->set_float("radius", 2.0f));
28         ASSERT_TRUE(unsharp_mask_effect->set_float("amount", 0.0f));
29         tester.run(out_data, GL_RED, COLORSPACE_sRGB, GAMMA_LINEAR);
30
31         expect_equal(data, out_data, size, size);
32 }
33
34 TEST(UnsharpMaskEffectTest, UnblursGaussianBlur) {
35         const int size = 13;
36         const float sigma = 0.5f;
37
38         float data[size * size], out_data[size * size];
39         float expected_data[] = {  // One single dot in the middle.
40                 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 
41                 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 
42                 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 
43                 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 
44                 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 
45                 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 
46                 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 
47                 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 
48                 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 
49                 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 
50                 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 
51                 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 
52                 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 
53         };
54
55         // Create a Gaussian input. (Note that our blur is not Gaussian.)
56         for (int y = 0; y < size; ++y) {
57                 for (int x = 0; x < size; ++x) {
58                         float z = hypot(x - 6, y - 6);
59                         data[y * size + x] = exp(-z*z / (2.0 * sigma * sigma)) / (2.0 * M_PI * sigma * sigma);
60                 }
61         }
62
63         EffectChainTester tester(data, size, size, FORMAT_GRAYSCALE, COLORSPACE_sRGB, GAMMA_LINEAR);
64         Effect *unsharp_mask_effect = tester.get_chain()->add_effect(new UnsharpMaskEffect());
65         ASSERT_TRUE(unsharp_mask_effect->set_float("radius", sigma));
66         tester.run(out_data, GL_RED, COLORSPACE_sRGB, GAMMA_LINEAR);
67
68         // Check the center sample separately; it's bound to be the sample with the largest
69         // single error, and we know we can't get it perfect anyway.
70         int center = size / 2;
71         EXPECT_GT(out_data[center * size + center], 0.45f);
72         out_data[center * size + center] = 1.0f;
73
74         // Add some leeway for the rest; unsharp masking is not expected to be extremely good.
75         expect_equal(expected_data, out_data, size, size, 0.1, 0.001);
76 }
77
78 }  // namespace movit