Coverage Report

Created: 2026-09-14 06:44

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/work/libde265/libde265/scan.cc
Line
Count
Source
1
/*
2
 * H.265 video codec.
3
 * Copyright (c) 2013-2014 struktur AG, Dirk Farin <farin@struktur.de>
4
 *
5
 * This file is part of libde265.
6
 *
7
 * libde265 is free software: you can redistribute it and/or modify
8
 * it under the terms of the GNU Lesser General Public License as
9
 * published by the Free Software Foundation, either version 3 of
10
 * the License, or (at your option) any later version.
11
 *
12
 * libde265 is distributed in the hope that it will be useful,
13
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15
 * GNU Lesser General Public License for more details.
16
 *
17
 * You should have received a copy of the GNU Lesser General Public License
18
 * along with libde265.  If not, see <http://www.gnu.org/licenses/>.
19
 */
20
21
#include "scan.h"
22
23
static position scan0 = { 0,0 };
24
static position scan_h_1[ 2* 2], scan_v_1[ 2* 2], scan_d_1[ 2* 2];
25
static position scan_h_2[ 4* 4], scan_v_2[ 4* 4], scan_d_2[ 4* 4];
26
static position scan_h_3[ 8* 8], scan_v_3[ 8* 8], scan_d_3[ 8* 8];
27
static position scan_h_4[16*16], scan_v_4[16*16], scan_d_4[16*16];
28
static position scan_h_5[32*32], scan_v_5[32*32], scan_d_5[32*32];
29
30
static position* scan_h[7] = { &scan0,scan_h_1,scan_h_2,scan_h_3,scan_h_4,scan_h_5 };
31
static position* scan_v[7] = { &scan0,scan_v_1,scan_v_2,scan_v_3,scan_v_4,scan_v_5 };
32
static position* scan_d[7] = { &scan0,scan_d_1,scan_d_2,scan_d_3,scan_d_4,scan_d_5 };
33
34
static void init_scan_h(position* scan, int blkSize)
35
80
{
36
80
  int i=0;
37
1.07k
  for (int y=0;y<blkSize;y++)
38
22.8k
    for (int x=0;x<blkSize;x++)
39
21.8k
      {
40
21.8k
        scan[i].x = x;
41
21.8k
        scan[i].y = y;
42
21.8k
        i++;
43
21.8k
      }
44
80
}
45
46
static void init_scan_v(position* scan, int blkSize)
47
80
{
48
80
  int i=0;
49
1.07k
  for (int x=0;x<blkSize;x++)
50
22.8k
    for (int y=0;y<blkSize;y++)
51
21.8k
      {
52
21.8k
        scan[i].x = x;
53
21.8k
        scan[i].y = y;
54
21.8k
        i++;
55
21.8k
      }
56
80
}
57
58
static void init_scan_d(position* scan, int blkSize)
59
80
{
60
80
  int i=0;
61
80
  int x=0,y=0;
62
63
1.90k
  do {
64
44.5k
    while (y>=0) {
65
42.6k
      if (x<blkSize && y<blkSize) {
66
21.8k
        scan[i].x = x;
67
21.8k
        scan[i].y = y;
68
21.8k
        i++;
69
21.8k
      }
70
42.6k
      y--;
71
42.6k
      x++;
72
42.6k
    }
73
74
1.90k
    y=x;
75
1.90k
    x=0;
76
1.90k
  } while (i < blkSize*blkSize);
77
80
}
78
79
80
const position* get_scan_order(int log2BlockSize, int scanIdx)
81
83.6M
{
82
83.6M
  switch (scanIdx) {
83
76.7M
  case 0: return scan_d[log2BlockSize];
84
4.47M
  case 1: return scan_h[log2BlockSize];
85
2.62M
  case 2: return scan_v[log2BlockSize];
86
0
  default: return 0; // should never happen
87
83.6M
  }
88
83.6M
}
89
90
91
92
static scan_position scanpos_h_2[ 4* 4], scanpos_v_2[ 4* 4], scanpos_d_2[ 4* 4];
93
static scan_position scanpos_h_3[ 8* 8], scanpos_v_3[ 8* 8], scanpos_d_3[ 8* 8];
94
static scan_position scanpos_h_4[16*16], scanpos_v_4[16*16], scanpos_d_4[16*16];
95
static scan_position scanpos_h_5[32*32], scanpos_v_5[32*32], scanpos_d_5[32*32];
96
97
static scan_position* scanpos[3][6] =
98
  { { 0,0,scanpos_d_2,scanpos_d_3,scanpos_d_4,scanpos_d_5 },
99
    { 0,0,scanpos_h_2,scanpos_h_3,scanpos_h_4,scanpos_h_5 },
100
    { 0,0,scanpos_v_2,scanpos_v_3,scanpos_v_4,scanpos_v_5 } };
101
   
102
103
scan_position get_scan_position(int x,int y, int scanIdx, int log2BlkSize)
104
41.6M
{
105
41.6M
  return scanpos[scanIdx][log2BlkSize][ y*(1<<log2BlkSize) + x ];
106
41.6M
}
107
108
static void fill_scan_pos_table(scan_position* pos, int scanIdx, int log2TrafoSize)
109
192
{
110
192
  int numSubBlocks = (1<<(log2TrafoSize-2)) * (1<<(log2TrafoSize-2));
111
192
  int blkSize = 1 << log2TrafoSize;
112
113
192
  const position* ScanOrderSub = get_scan_order(log2TrafoSize-2, scanIdx);
114
192
  const position* ScanOrderPos = get_scan_order(2, scanIdx);
115
116
4.27k
  for (int sb = 0; sb < numSubBlocks; sb++)
117
4.08k
    {
118
4.08k
      position S = ScanOrderSub[sb];
119
69.3k
      for (int sp = 0; sp < 16; sp++)
120
65.2k
        {
121
65.2k
          int xC = (S.x<<2) + ScanOrderPos[sp].x;
122
65.2k
          int yC = (S.y<<2) + ScanOrderPos[sp].y;
123
65.2k
          pos[yC * blkSize + xC].subBlock = sb;
124
65.2k
          pos[yC * blkSize + xC].scanPos  = sp;
125
65.2k
        }
126
4.08k
    }
127
192
}
128
129
130
void init_scan_orders()
131
16
{
132
96
  for (int log2size=1;log2size<=5;log2size++)
133
80
    {
134
80
      init_scan_h(scan_h[log2size], 1<<log2size);
135
80
      init_scan_v(scan_v[log2size], 1<<log2size);
136
80
      init_scan_d(scan_d[log2size], 1<<log2size);
137
80
    }
138
139
80
  for (int log2size=2;log2size<=5;log2size++)
140
256
    for (int scanIdx=0;scanIdx<3;scanIdx++)
141
192
      fill_scan_pos_table(scanpos[scanIdx][log2size], scanIdx, log2size);
142
16
}