Coverage Report

Created: 2026-05-16 06:41

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/work/svt-av1/third_party/fastfeat/nonmax.c
Line
Count
Source
1
// clang-format off
2
#include <stdlib.h>
3
#include "fast.h"
4
5
6
0
#define Compare(X, Y) ((X)>=(Y))
7
8
xy* svt_aom_nonmax_suppression(const xy* corners, const int* scores, int num_corners, int* ret_num_nonmax)
9
0
{
10
0
  int num_nonmax=0;
11
0
  int last_row;
12
0
  int* row_start;
13
0
  int i, j;
14
0
  xy* ret_nonmax;
15
0
  const int sz = (int)num_corners;
16
17
  /*Point above points (roughly) to the pixel above the one of interest, if there
18
    is a feature there.*/
19
0
  int point_above = 0;
20
0
  int point_below = 0;
21
22
23
0
  if(num_corners < 1)
24
0
  {
25
0
    *ret_num_nonmax = 0;
26
0
    return 0;
27
0
  }
28
29
0
  ret_nonmax = (xy*)malloc(num_corners * sizeof(xy));
30
31
  /* Find where each row begins
32
     (the corners are output in raster scan order). A beginning of -1 signifies
33
     that there are no corners on that row. */
34
0
  last_row = corners[num_corners-1].y;
35
0
  row_start = (int*)malloc((last_row+1)*sizeof(int));
36
37
0
  for(i=0; i < last_row+1; i++)
38
0
    row_start[i] = -1;
39
40
0
  {
41
0
    int prev_row = -1;
42
0
    for(i=0; i< num_corners; i++)
43
0
      if(corners[i].y != prev_row)
44
0
      {
45
0
        row_start[corners[i].y] = i;
46
0
        prev_row = corners[i].y;
47
0
      }
48
0
  }
49
50
51
52
0
  for(i=0; i < sz; i++)
53
0
  {
54
0
    int score = scores[i];
55
0
    xy pos = corners[i];
56
57
    /*Check left */
58
0
    if(i > 0)
59
0
      if(corners[i-1].x == pos.x-1 && corners[i-1].y == pos.y && Compare(scores[i-1], score))
60
0
        continue;
61
62
    /*Check right*/
63
0
    if(i < (sz - 1))
64
0
      if(corners[i+1].x == pos.x+1 && corners[i+1].y == pos.y && Compare(scores[i+1], score))
65
0
        continue;
66
67
    /*Check above (if there is a valid row above)*/
68
0
    if(pos.y > 0)
69
0
      if (row_start[pos.y - 1] != -1)
70
0
      {
71
        /*Make sure that current point_above is one
72
          row above.*/
73
0
        if(corners[point_above].y < pos.y - 1)
74
0
          point_above = row_start[pos.y-1];
75
76
        /*Make point_above point to the first of the pixels above the current point,
77
          if it exists.*/
78
0
        for(; corners[point_above].y < pos.y && corners[point_above].x < pos.x - 1; point_above++)
79
0
        {}
80
81
82
0
        for(j=point_above; corners[j].y < pos.y && corners[j].x <= pos.x + 1; j++)
83
0
        {
84
0
          int x = corners[j].x;
85
0
          if( (x == pos.x - 1 || x ==pos.x || x == pos.x+1) && Compare(scores[j], score))
86
0
            goto cont;
87
0
        }
88
89
0
      }
90
91
    /*Check below (if there is anything below)*/
92
0
    if(pos.y >= 0)
93
0
      if (pos.y != last_row && row_start[pos.y + 1] != -1 && point_below < sz) /*Nothing below*/
94
0
      {
95
0
        if(corners[point_below].y < pos.y + 1)
96
0
          point_below = row_start[pos.y+1];
97
98
        /* Make point below point to one of the pixels belowthe current point, if it
99
           exists.*/
100
0
        for(; point_below < sz && corners[point_below].y == pos.y+1 && corners[point_below].x < pos.x - 1; point_below++)
101
0
        {}
102
103
0
        for(j=point_below; j < sz && corners[j].y == pos.y+1 && corners[j].x <= pos.x + 1; j++)
104
0
        {
105
0
          int x = corners[j].x;
106
0
          if( (x == pos.x - 1 || x ==pos.x || x == pos.x+1) && Compare(scores[j],score))
107
0
            goto cont;
108
0
        }
109
0
      }
110
111
0
    ret_nonmax[num_nonmax++] = corners[i];
112
0
cont:
113
0
    ;
114
0
  }
115
116
0
  free(row_start);
117
0
  *ret_num_nonmax = num_nonmax;
118
0
  return ret_nonmax;
119
0
}
120
121
// clang-format on