LCOV - code coverage report
Current view: top level - src/tests - filters.c (source / functions) Hit Total Coverage
Test: Code coverage Lines: 43 43 100.0 %
Date: 2025-03-29 09:04:10 Functions: 1 1 100.0 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 32 42 76.2 %

           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                 :            : }

Generated by: LCOV version 1.16