Branch data Line data Source code
1 : : #include "utils.h"
2 : :
3 : : #include <libplacebo/filters.h>
4 : :
5 : 1 : int main()
6 : : {
7 : 1 : pl_log log = pl_test_logger();
8 : :
9 [ + + ]: 30 : for (int i = 0; i < pl_num_filter_functions; i++) {
10 : 29 : const struct pl_filter_function *fun = pl_filter_functions[i];
11 [ + + ]: 29 : if (fun->opaque)
12 : 1 : continue;
13 : :
14 : 28 : printf("Testing filter function '%s'\n", fun->name);
15 : :
16 : 28 : struct pl_filter_ctx ctx = { .radius = fun->radius };
17 : : memcpy(ctx.params, fun->params, sizeof(ctx.params));
18 : :
19 : : // Ensure the kernel is correctly scaled
20 [ - + ]: 28 : REQUIRE_FEQ(fun->weight(&ctx, 0.0), 1.0, 1e-7);
21 : :
22 : : // Only box filters are radius 1, these are unwindowed by design.
23 : : // Gaussian technically never reaches 0 even at its preconfigured radius.
24 [ + + + + ]: 28 : if (fun->radius > 1.0 && fun != &pl_filter_function_gaussian)
25 [ - + ]: 15 : REQUIRE_FEQ(fun->weight(&ctx, fun->radius), 0.0, 1e-7);
26 : : }
27 : :
28 [ + + ]: 30 : for (int c = 0; c < pl_num_filter_configs; c++) {
29 : 29 : const struct pl_filter_config *conf = pl_filter_configs[c];
30 [ + + ]: 29 : if (conf->kernel->opaque)
31 : 1 : continue;
32 : :
33 : 28 : printf("Testing filter config '%s'\n", conf->name);
34 : 28 : pl_filter flt = pl_filter_generate(log, pl_filter_params(
35 : : .config = *conf,
36 : : .lut_entries = 256,
37 : : .cutoff = 1e-3,
38 : : ));
39 [ - + ]: 28 : REQUIRE(flt);
40 [ + + ]: 28 : const float radius = PL_DEF(conf->radius, conf->kernel->radius);
41 [ - + ]: 28 : REQUIRE_CMP(flt->radius, <=, radius, "f");
42 [ - + ]: 28 : REQUIRE_CMP(flt->radius_zero, >, 0.0, "f");
43 [ - + ]: 28 : REQUIRE_CMP(flt->radius_zero, <=, flt->radius, "f");
44 : :
45 [ + + ]: 28 : if (conf->polar) {
46 : :
47 : : // Test LUT accuracy
48 : 9 : const int range = flt->params.lut_entries - 1;
49 : 9 : double scale = flt->weights[0] / pl_filter_sample(conf, 0.0);
50 : : double err = 0.0;
51 [ + + ]: 9018 : for (float k = 0.0; k <= 1.0; k += 1e-3f) {
52 : 9009 : double ref = scale * pl_filter_sample(conf, k * flt->radius);
53 : 9009 : double idx = k * range;
54 : 9009 : int base = floorf(idx);
55 : 9009 : double fpart = idx - base;
56 : 9009 : int next = PL_MIN(base + 1, range);
57 : 9009 : double interp = PL_MIX(flt->weights[base], flt->weights[next], fpart);
58 : 9009 : err = fmaxf(err, fabs(interp - ref));
59 : : }
60 [ - + ]: 9 : REQUIRE_CMP(err, <=, 1e-4, "g");
61 : :
62 : : } else {
63 : :
64 : : // Ensure the weights for each row add up to unity
65 [ + + ]: 4883 : for (int i = 0; i < flt->params.lut_entries; i++) {
66 : 4864 : const float *row = flt->weights + i * flt->row_stride;
67 : : float sum = 0.0;
68 [ - + ]: 4864 : REQUIRE(flt->row_size);
69 [ - + ]: 4864 : REQUIRE_CMP(flt->row_stride, >=, flt->row_size, "d");
70 [ + + ]: 24320 : for (int n = 0; n < flt->row_size; n++)
71 : 19456 : sum += row[n];
72 [ - + ]: 4864 : REQUIRE_FEQ(sum, 1.0, 1e-6);
73 : : }
74 : :
75 : : }
76 : :
77 : 28 : pl_filter_free(&flt);
78 : : }
79 : :
80 : 1 : pl_log_destroy(&log);
81 : : }
|