Coverage Report

Created: 2026-08-31 06:22

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/work/libde265/libde265/intrapred.h
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
#ifndef DE265_INTRAPRED_H
22
#define DE265_INTRAPRED_H
23
24
#include "libde265/decctx.h"
25
26
extern const int intraPredAngle_table[1+34];
27
28
29
/* Fill the three intra-pred-mode candidates into candModeList.
30
   Block position is (x,y) and you also have to give the PUidx for this
31
   block (which is (x>>Log2MinPUSize) + (y>>Log2MinPUSize)*PicWidthInMinPUs).
32
   availableA/B is the output of check_CTB_available().
33
 */
34
void fillIntraPredModeCandidates(enum IntraPredMode candModeList[3],
35
                                 int x,int y, int PUidx,
36
                                 bool availableA, // left
37
                                 bool availableB, // top
38
                                 const de265_image* img);
39
40
41
inline void fillIntraPredModeCandidates(enum IntraPredMode candModeList[3], int x,int y,
42
                                 bool availableA, // left
43
                                 bool availableB, // top
44
                                 const de265_image* img)
45
0
{
46
0
  int PUidx = img->get_sps().getPUIndexRS(x,y);
47
0
  fillIntraPredModeCandidates(candModeList, x,y, PUidx, availableA,availableB, img);
48
0
}
49
50
void fillIntraPredModeCandidates(enum IntraPredMode candModeList[3],
51
                                 enum IntraPredMode candIntraPredModeA,
52
                                 enum IntraPredMode candIntraPredModeB);
53
54
55
/* Return value >= 0 -> use mpm_idx(return value)
56
   else              -> use rem_intra(-return value-1)
57
58
   This function may modify the candModeList !
59
 */
60
int find_intra_pred_mode(enum IntraPredMode mode,
61
                         enum IntraPredMode candModeList[3]);
62
63
void list_chroma_pred_candidates(enum IntraPredMode chroma_mode[5],
64
                                 enum IntraPredMode luma_mode);
65
66
int get_intra_scan_idx(int log2TrafoSize, enum IntraPredMode intraPredMode, int cIdx,
67
                       const seq_parameter_set* sps);
68
69
int get_intra_scan_idx_luma  (int log2TrafoSize, enum IntraPredMode intraPredMode); // DEPRECATED
70
int get_intra_scan_idx_chroma(int log2TrafoSize, enum IntraPredMode intraPredMode); // DEPRECATED
71
72
enum IntraPredMode lumaPredMode_to_chromaPredMode(enum IntraPredMode luma,
73
                                                  enum IntraChromaPredMode chroma);
74
75
/*
76
void decode_intra_block(decoder_context* ctx,
77
                        thread_context* tctx,
78
                        int cIdx,
79
                        int xB0,int yB0, // position of TU in frame (chroma adapted)
80
                        int x0,int y0,   // position of CU in frame (chroma adapted)
81
                        int log2TrafoSize, int trafoDepth,
82
                        enum IntraPredMode intraPredMode,
83
                        bool transform_skip_flag);
84
*/
85
86
//void fill_border_samples(decoder_context* ctx, int xB,int yB,
87
//                         int nT, int cIdx, uint8_t* out_border);
88
89
void decode_intra_prediction(de265_image* img,
90
                             int xB0,int yB0,
91
                             enum IntraPredMode intraPredMode,
92
                             int nT, int cIdx);
93
94
// TODO: remove this
95
template <class pixel_t> void decode_intra_prediction(de265_image* img,
96
                                                      int xB0,int yB0,
97
                                                      enum IntraPredMode intraPredMode,
98
                                                      pixel_t* dst, int nT, int cIdx);
99
100
101
102
103
// --- internal use only ---
104
105
// Actually, the largest TB block can only be 32, but in some intra-pred-mode algorithms
106
// (e.g. min-residual), we may call intra prediction on the maximum CTB size (64).
107
static const int MAX_INTRA_PRED_BLOCK_SIZE = 64;
108
109
110
template <class pixel_t>
111
class intra_border_computer
112
{
113
 public:
114
  pixel_t* out_border;
115
116
  const de265_image* img;
117
  int nT;
118
  int cIdx;
119
120
  int xB,yB;
121
122
  const seq_parameter_set* sps;
123
  const pic_parameter_set* pps;
124
125
  uint8_t available_data[4*MAX_INTRA_PRED_BLOCK_SIZE + 1];
126
  uint8_t* available;
127
128
  int SubWidth;
129
  int SubHeight;
130
131
  bool availableLeft;    // is CTB at left side available?
132
  bool availableTop;     // is CTB at top side available?
133
  bool availableTopRight; // is CTB at top-right side available?
134
  bool availableTopLeft;  // if CTB at top-left pixel available?
135
136
  int nBottom;
137
  int nRight;
138
  int nAvail;
139
  pixel_t firstValue;
140
141
  void init(pixel_t* _out_border,
142
41.8M
            const de265_image* _img, int _nT, int _cIdx, int _xB, int _yB) {
143
41.8M
    img=_img; nT=_nT; cIdx=_cIdx;
144
41.8M
    out_border=_out_border; xB=_xB; yB=_yB;
145
146
41.8M
    assert(nT <= MAX_INTRA_PRED_BLOCK_SIZE);
147
148
41.8M
    availableLeft=true;
149
41.8M
    availableTop=true;
150
41.8M
    availableTopRight=true;
151
41.8M
    availableTopLeft=true;
152
41.8M
  }
intra_border_computer<unsigned short>::init(unsigned short*, de265_image const*, int, int, int, int)
Line
Count
Source
142
15.2M
            const de265_image* _img, int _nT, int _cIdx, int _xB, int _yB) {
143
15.2M
    img=_img; nT=_nT; cIdx=_cIdx;
144
15.2M
    out_border=_out_border; xB=_xB; yB=_yB;
145
146
15.2M
    assert(nT <= MAX_INTRA_PRED_BLOCK_SIZE);
147
148
15.2M
    availableLeft=true;
149
15.2M
    availableTop=true;
150
15.2M
    availableTopRight=true;
151
15.2M
    availableTopLeft=true;
152
15.2M
  }
intra_border_computer<unsigned char>::init(unsigned char*, de265_image const*, int, int, int, int)
Line
Count
Source
142
26.6M
            const de265_image* _img, int _nT, int _cIdx, int _xB, int _yB) {
143
26.6M
    img=_img; nT=_nT; cIdx=_cIdx;
144
26.6M
    out_border=_out_border; xB=_xB; yB=_yB;
145
146
26.6M
    assert(nT <= MAX_INTRA_PRED_BLOCK_SIZE);
147
148
26.6M
    availableLeft=true;
149
26.6M
    availableTop=true;
150
26.6M
    availableTopRight=true;
151
26.6M
    availableTopLeft=true;
152
26.6M
  }
153
  void preproc();
154
  void fill_from_image();
155
156
  void reference_sample_substitution();
157
};
158
159
160
#ifdef DE265_LOG_TRACE
161
template <class pixel_t>
162
void print_border(pixel_t* data, uint8_t* available, int nT)
163
{
164
  for (int i=-2*nT ; i<=2*nT ; i++) {
165
    if (i==0 || i==1 || i==-nT || i==nT+1) {
166
      logtrace(LogIntraPred,"|");
167
    } else {
168
      logtrace(LogIntraPred," ");
169
    }
170
171
    if (available==nullptr || available[i]) {
172
      logtrace(LogIntraPred,"%02x",data[i]);
173
    }
174
    else {
175
      logtrace(LogIntraPred,"--");
176
    }
177
  }
178
}
179
#else
180
#define print_border(data, available, nT)
181
#endif
182
183
184
// (8.4.4.2.3)
185
template <class pixel_t>
186
void intra_prediction_sample_filtering(const seq_parameter_set& sps,
187
                                       pixel_t* p,
188
                                       int nT, int cIdx,
189
                                       enum IntraPredMode intraPredMode)
190
18.9M
{
191
18.9M
  int filterFlag;
192
193
  //printf("filtering, mode: %d\n",intraPredMode);
194
195
18.9M
  if (intraPredMode==INTRA_DC || nT==4) {
196
15.6M
    filterFlag = 0;
197
15.6M
  } else {
198
3.31M
    int minDistVerHor = std::min( std::abs((int)intraPredMode-26),
199
3.31M
                                  std::abs((int)intraPredMode-10) );
200
201
    //printf("mindist: %d\n",minDistVerHor);
202
203
3.31M
    switch (nT) {
204
3.15M
    case 8:  filterFlag = (minDistVerHor>7) ? 1 : 0; break;
205
89.2k
    case 16: filterFlag = (minDistVerHor>1) ? 1 : 0; break;
206
85.0k
    case 32: filterFlag = (minDistVerHor>0) ? 1 : 0; break;
207
      // there is no official 64x64 TB block, but we call this for some intra-pred mode algorithms
208
      // on the whole CB (2Nx2N mode for the whole CTB)
209
0
    case 64: filterFlag = 0; break;
210
0
    default: filterFlag = -1; assert(false); break; // should never happen
211
3.31M
    }
212
3.31M
  }
213
214
215
19.0M
  if (filterFlag) {
216
2.06M
    int biIntFlag = (sps.strong_intra_smoothing_enable_flag &&
217
796k
                     cIdx==0 &&
218
658k
                     nT==32 &&
219
33.6k
                     std::abs(p[0]+p[ 64]-2*p[ 32]) < (1<<(sps.bit_depth_luma-5)) &&
220
31.0k
                     std::abs(p[0]+p[-64]-2*p[-32]) < (1<<(sps.bit_depth_luma-5)))
221
2.06M
      ? 1 : 0;
222
223
2.06M
    pixel_t  pF_mem[4*32+1];
224
2.06M
    pixel_t* pF = &pF_mem[2*32];
225
226
2.06M
    if (biIntFlag) {
227
27.9k
      pF[-2*nT] = p[-2*nT];
228
27.9k
      pF[ 2*nT] = p[ 2*nT];
229
27.9k
      pF[    0] = p[    0];
230
231
1.78M
      for (int i=1;i<=63;i++) {
232
1.75M
        pF[-i] = p[0] + ((i*(p[-64]-p[0])+32)>>6);
233
1.75M
        pF[ i] = p[0] + ((i*(p[ 64]-p[0])+32)>>6);
234
1.75M
      }
235
2.04M
    } else {
236
2.04M
      pF[-2*nT] = p[-2*nT];
237
2.04M
      pF[ 2*nT] = p[ 2*nT];
238
239
71.9M
      for (int i=-(2*nT-1) ; i<=2*nT-1 ; i++)
240
69.8M
        {
241
69.8M
          pF[i] = (p[i+1] + 2*p[i] + p[i-1] + 2) >> 2;
242
69.8M
        }
243
2.04M
    }
244
245
246
    // copy back to original array
247
248
2.06M
    memcpy(p-2*nT, pF-2*nT, (4*nT+1) * sizeof(pixel_t));
249
2.06M
  }
250
16.9M
  else {
251
    // do nothing ?
252
16.9M
  }
253
254
255
19.0M
  logtrace(LogIntraPred,"post filtering: ");
256
19.0M
  print_border(p,nullptr,nT);
257
19.0M
  logtrace(LogIntraPred,"\n");
258
19.0M
}
void intra_prediction_sample_filtering<unsigned short>(seq_parameter_set const&, unsigned short*, int, int, IntraPredMode)
Line
Count
Source
190
6.33M
{
191
6.33M
  int filterFlag;
192
193
  //printf("filtering, mode: %d\n",intraPredMode);
194
195
6.33M
  if (intraPredMode==INTRA_DC || nT==4) {
196
5.09M
    filterFlag = 0;
197
5.09M
  } else {
198
1.23M
    int minDistVerHor = std::min( std::abs((int)intraPredMode-26),
199
1.23M
                                  std::abs((int)intraPredMode-10) );
200
201
    //printf("mindist: %d\n",minDistVerHor);
202
203
1.23M
    switch (nT) {
204
1.17M
    case 8:  filterFlag = (minDistVerHor>7) ? 1 : 0; break;
205
42.5k
    case 16: filterFlag = (minDistVerHor>1) ? 1 : 0; break;
206
22.4k
    case 32: filterFlag = (minDistVerHor>0) ? 1 : 0; break;
207
      // there is no official 64x64 TB block, but we call this for some intra-pred mode algorithms
208
      // on the whole CB (2Nx2N mode for the whole CTB)
209
0
    case 64: filterFlag = 0; break;
210
0
    default: filterFlag = -1; assert(false); break; // should never happen
211
1.23M
    }
212
1.23M
  }
213
214
215
6.33M
  if (filterFlag) {
216
739k
    int biIntFlag = (sps.strong_intra_smoothing_enable_flag &&
217
625k
                     cIdx==0 &&
218
509k
                     nT==32 &&
219
14.5k
                     std::abs(p[0]+p[ 64]-2*p[ 32]) < (1<<(sps.bit_depth_luma-5)) &&
220
13.1k
                     std::abs(p[0]+p[-64]-2*p[-32]) < (1<<(sps.bit_depth_luma-5)))
221
739k
      ? 1 : 0;
222
223
739k
    pixel_t  pF_mem[4*32+1];
224
739k
    pixel_t* pF = &pF_mem[2*32];
225
226
739k
    if (biIntFlag) {
227
11.0k
      pF[-2*nT] = p[-2*nT];
228
11.0k
      pF[ 2*nT] = p[ 2*nT];
229
11.0k
      pF[    0] = p[    0];
230
231
705k
      for (int i=1;i<=63;i++) {
232
694k
        pF[-i] = p[0] + ((i*(p[-64]-p[0])+32)>>6);
233
694k
        pF[ i] = p[0] + ((i*(p[ 64]-p[0])+32)>>6);
234
694k
      }
235
728k
    } else {
236
728k
      pF[-2*nT] = p[-2*nT];
237
728k
      pF[ 2*nT] = p[ 2*nT];
238
239
25.1M
      for (int i=-(2*nT-1) ; i<=2*nT-1 ; i++)
240
24.3M
        {
241
24.3M
          pF[i] = (p[i+1] + 2*p[i] + p[i-1] + 2) >> 2;
242
24.3M
        }
243
728k
    }
244
245
246
    // copy back to original array
247
248
739k
    memcpy(p-2*nT, pF-2*nT, (4*nT+1) * sizeof(pixel_t));
249
739k
  }
250
5.59M
  else {
251
    // do nothing ?
252
5.59M
  }
253
254
255
6.33M
  logtrace(LogIntraPred,"post filtering: ");
256
6.33M
  print_border(p,nullptr,nT);
257
6.33M
  logtrace(LogIntraPred,"\n");
258
6.33M
}
void intra_prediction_sample_filtering<unsigned char>(seq_parameter_set const&, unsigned char*, int, int, IntraPredMode)
Line
Count
Source
190
12.6M
{
191
12.6M
  int filterFlag;
192
193
  //printf("filtering, mode: %d\n",intraPredMode);
194
195
12.6M
  if (intraPredMode==INTRA_DC || nT==4) {
196
10.5M
    filterFlag = 0;
197
10.5M
  } else {
198
2.07M
    int minDistVerHor = std::min( std::abs((int)intraPredMode-26),
199
2.07M
                                  std::abs((int)intraPredMode-10) );
200
201
    //printf("mindist: %d\n",minDistVerHor);
202
203
2.07M
    switch (nT) {
204
1.98M
    case 8:  filterFlag = (minDistVerHor>7) ? 1 : 0; break;
205
46.7k
    case 16: filterFlag = (minDistVerHor>1) ? 1 : 0; break;
206
62.5k
    case 32: filterFlag = (minDistVerHor>0) ? 1 : 0; break;
207
      // there is no official 64x64 TB block, but we call this for some intra-pred mode algorithms
208
      // on the whole CB (2Nx2N mode for the whole CTB)
209
0
    case 64: filterFlag = 0; break;
210
0
    default: filterFlag = -1; assert(false); break; // should never happen
211
2.07M
    }
212
2.07M
  }
213
214
215
12.6M
  if (filterFlag) {
216
1.32M
    int biIntFlag = (sps.strong_intra_smoothing_enable_flag &&
217
171k
                     cIdx==0 &&
218
148k
                     nT==32 &&
219
19.1k
                     std::abs(p[0]+p[ 64]-2*p[ 32]) < (1<<(sps.bit_depth_luma-5)) &&
220
17.9k
                     std::abs(p[0]+p[-64]-2*p[-32]) < (1<<(sps.bit_depth_luma-5)))
221
1.32M
      ? 1 : 0;
222
223
1.32M
    pixel_t  pF_mem[4*32+1];
224
1.32M
    pixel_t* pF = &pF_mem[2*32];
225
226
1.32M
    if (biIntFlag) {
227
16.9k
      pF[-2*nT] = p[-2*nT];
228
16.9k
      pF[ 2*nT] = p[ 2*nT];
229
16.9k
      pF[    0] = p[    0];
230
231
1.07M
      for (int i=1;i<=63;i++) {
232
1.05M
        pF[-i] = p[0] + ((i*(p[-64]-p[0])+32)>>6);
233
1.05M
        pF[ i] = p[0] + ((i*(p[ 64]-p[0])+32)>>6);
234
1.05M
      }
235
1.31M
    } else {
236
1.31M
      pF[-2*nT] = p[-2*nT];
237
1.31M
      pF[ 2*nT] = p[ 2*nT];
238
239
46.8M
      for (int i=-(2*nT-1) ; i<=2*nT-1 ; i++)
240
45.5M
        {
241
45.5M
          pF[i] = (p[i+1] + 2*p[i] + p[i-1] + 2) >> 2;
242
45.5M
        }
243
1.31M
    }
244
245
246
    // copy back to original array
247
248
1.32M
    memcpy(p-2*nT, pF-2*nT, (4*nT+1) * sizeof(pixel_t));
249
1.32M
  }
250
11.3M
  else {
251
    // do nothing ?
252
11.3M
  }
253
254
255
12.6M
  logtrace(LogIntraPred,"post filtering: ");
256
12.6M
  print_border(p,nullptr,nT);
257
12.6M
  logtrace(LogIntraPred,"\n");
258
12.6M
}
259
260
261
template <class pixel_t>
262
void intra_prediction_planar(pixel_t* dst, int dstStride,
263
                             int nT,int cIdx,
264
                             pixel_t* border)
265
6.02M
{
266
6.02M
  int Log2_nT = Log2(nT);
267
268
32.8M
  for (int y=0;y<nT;y++)
269
162M
    for (int x=0;x<nT;x++)
270
135M
      {
271
135M
        dst[x+y*dstStride] = ((nT-1-x)*border[-1-y] + (x+1)*border[ 1+nT] +
272
135M
                              (nT-1-y)*border[ 1+x] + (y+1)*border[-1-nT] + nT) >> (Log2_nT+1);
273
135M
      }
274
275
276
6.02M
  logtrace(LogIntraPred,"result of planar prediction\n");
277
278
32.8M
  for (int y=0;y<nT;y++)
279
26.7M
    {
280
162M
      for (int x=0;x<nT;x++)
281
135M
        logtrace(LogIntraPred,"%02x ", dst[x+y*dstStride]);
282
283
26.7M
      logtrace(LogIntraPred,"\n");
284
26.7M
    }
285
6.02M
}
Unexecuted instantiation: void intra_prediction_planar<unsigned char>(unsigned char*, int, int, int, unsigned char*)
void intra_prediction_planar<unsigned short>(unsigned short*, int, int, int, unsigned short*)
Line
Count
Source
265
6.02M
{
266
6.02M
  int Log2_nT = Log2(nT);
267
268
32.8M
  for (int y=0;y<nT;y++)
269
162M
    for (int x=0;x<nT;x++)
270
135M
      {
271
135M
        dst[x+y*dstStride] = ((nT-1-x)*border[-1-y] + (x+1)*border[ 1+nT] +
272
135M
                              (nT-1-y)*border[ 1+x] + (y+1)*border[-1-nT] + nT) >> (Log2_nT+1);
273
135M
      }
274
275
276
6.02M
  logtrace(LogIntraPred,"result of planar prediction\n");
277
278
32.8M
  for (int y=0;y<nT;y++)
279
26.7M
    {
280
162M
      for (int x=0;x<nT;x++)
281
135M
        logtrace(LogIntraPred,"%02x ", dst[x+y*dstStride]);
282
283
26.7M
      logtrace(LogIntraPred,"\n");
284
26.7M
    }
285
6.02M
}
286
287
288
template <class pixel_t>
289
void intra_prediction_DC(pixel_t* dst, int dstStride,
290
                         int nT,int cIdx,
291
                         pixel_t* border)
292
2.08M
{
293
2.08M
  int Log2_nT = Log2(nT);
294
295
2.08M
  int dcVal = 0;
296
11.1M
  for (int i=0;i<nT;i++)
297
9.03M
    {
298
9.03M
      dcVal += border[ i+1];
299
9.03M
      dcVal += border[-i-1];
300
9.03M
    }
301
302
2.08M
  dcVal += nT;
303
2.08M
  dcVal >>= Log2_nT+1;
304
305
2.08M
  if (cIdx==0 && nT<32) {
306
1.61M
    dst[0] = (border[-1] + 2*dcVal + border[1] +2) >> 2;
307
308
6.79M
    for (int x=1;x<nT;x++) { dst[x]           = (border[ x+1] + 3*dcVal+2)>>2; }
309
6.79M
    for (int y=1;y<nT;y++) { dst[y*dstStride] = (border[-y-1] + 3*dcVal+2)>>2; }
310
6.79M
    for (int y=1;y<nT;y++)
311
23.4M
      for (int x=1;x<nT;x++)
312
18.2M
        {
313
18.2M
          dst[x+y*dstStride] = dcVal;
314
18.2M
        }
315
1.61M
  } else {
316
2.71M
    for (int y=0;y<nT;y++)
317
15.3M
      for (int x=0;x<nT;x++)
318
13.1M
        {
319
13.1M
          dst[x+y*dstStride] = dcVal;
320
13.1M
        }
321
470k
  }
322
2.08M
}
Unexecuted instantiation: void intra_prediction_DC<unsigned char>(unsigned char*, int, int, int, unsigned char*)
void intra_prediction_DC<unsigned short>(unsigned short*, int, int, int, unsigned short*)
Line
Count
Source
292
2.08M
{
293
2.08M
  int Log2_nT = Log2(nT);
294
295
2.08M
  int dcVal = 0;
296
11.1M
  for (int i=0;i<nT;i++)
297
9.03M
    {
298
9.03M
      dcVal += border[ i+1];
299
9.03M
      dcVal += border[-i-1];
300
9.03M
    }
301
302
2.08M
  dcVal += nT;
303
2.08M
  dcVal >>= Log2_nT+1;
304
305
2.08M
  if (cIdx==0 && nT<32) {
306
1.61M
    dst[0] = (border[-1] + 2*dcVal + border[1] +2) >> 2;
307
308
6.79M
    for (int x=1;x<nT;x++) { dst[x]           = (border[ x+1] + 3*dcVal+2)>>2; }
309
6.79M
    for (int y=1;y<nT;y++) { dst[y*dstStride] = (border[-y-1] + 3*dcVal+2)>>2; }
310
6.79M
    for (int y=1;y<nT;y++)
311
23.4M
      for (int x=1;x<nT;x++)
312
18.2M
        {
313
18.2M
          dst[x+y*dstStride] = dcVal;
314
18.2M
        }
315
1.61M
  } else {
316
2.71M
    for (int y=0;y<nT;y++)
317
15.3M
      for (int x=0;x<nT;x++)
318
13.1M
        {
319
13.1M
          dst[x+y*dstStride] = dcVal;
320
13.1M
        }
321
470k
  }
322
2.08M
}
323
324
325
extern const int intraPredAngle_table[1+34];
326
extern const int invAngle_table[25-10];
327
328
329
// (8.4.4.2.6)
330
template <class pixel_t>
331
void intra_prediction_angular(pixel_t* dst, int dstStride,
332
                              int bit_depth, bool disableIntraBoundaryFilter,
333
                              int xB0,int yB0,
334
                              enum IntraPredMode intraPredMode,
335
                              int nT,int cIdx,
336
                              pixel_t* border)
337
7.09M
{
338
7.09M
  pixel_t  ref_mem[4*MAX_INTRA_PRED_BLOCK_SIZE+1]; // TODO: what is the required range here ?
339
7.09M
  pixel_t* ref=&ref_mem[2*MAX_INTRA_PRED_BLOCK_SIZE];
340
341
7.09M
  assert(intraPredMode<35);
342
7.09M
  assert(intraPredMode>=2);
343
344
7.09M
  int intraPredAngle = intraPredAngle_table[intraPredMode];
345
346
7.09M
  if (intraPredMode >= 18) {
347
348
14.9M
    for (int x=0;x<=nT;x++)
349
12.7M
      { ref[x] = border[x]; }
350
351
2.19M
    if (intraPredAngle<0) {
352
741k
      int invAngle = invAngle_table[intraPredMode-11];
353
354
741k
      if ((nT*intraPredAngle)>>5 < -1) {
355
2.42M
        for (int x=(nT*intraPredAngle)>>5; x<=-1; x++) {
356
1.88M
          ref[x] = border[0-((x*invAngle+128)>>8)];
357
1.88M
        }
358
547k
      }
359
1.45M
    } else {
360
8.55M
      for (int x=nT+1; x<=2*nT;x++) {
361
7.09M
        ref[x] = border[x];
362
7.09M
      }
363
1.45M
    }
364
365
12.7M
    for (int y=0;y<nT;y++)
366
76.6M
      for (int x=0;x<nT;x++)
367
66.0M
        {
368
66.0M
          int iIdx = ((y+1)*intraPredAngle)>>5;
369
66.0M
          int iFact= ((y+1)*intraPredAngle)&31;
370
371
66.0M
          if (iFact != 0) {
372
32.9M
            dst[x+y*dstStride] = ((32-iFact)*ref[x+iIdx+1] + iFact*ref[x+iIdx+2] + 16)>>5;
373
33.0M
          } else {
374
33.0M
            dst[x+y*dstStride] = ref[x+iIdx+1];
375
33.0M
          }
376
66.0M
        }
377
378
2.19M
    if (intraPredMode==26 && cIdx==0 && nT<32 && !disableIntraBoundaryFilter) {
379
1.34M
      for (int y=0;y<nT;y++) {
380
1.10M
        dst[0+y*dstStride] = Clip_BitDepth(border[1] + ((border[-1-y] - border[0])>>1), bit_depth);
381
1.10M
      }
382
237k
    }
383
2.19M
  }
384
4.89M
  else { // intraPredAngle < 18
385
386
31.8M
    for (int x=0;x<=nT;x++)
387
26.9M
      { ref[x] = border[-x]; }  // DIFF (neg)
388
389
4.89M
    if (intraPredAngle<0) {
390
673k
      int invAngle = invAngle_table[intraPredMode-11];
391
392
673k
      if ((nT*intraPredAngle)>>5 < -1) {
393
2.10M
        for (int x=(nT*intraPredAngle)>>5; x<=-1; x++) {
394
1.58M
          ref[x] = border[((x*invAngle+128)>>8)]; // DIFF (neg)
395
1.58M
        }
396
513k
      }
397
4.22M
    } else {
398
23.0M
      for (int x=nT+1; x<=2*nT;x++) {
399
18.8M
        ref[x] = border[-x]; // DIFF (neg)
400
18.8M
      }
401
4.22M
    }
402
403
26.9M
    for (int y=0;y<nT;y++)
404
138M
      for (int x=0;x<nT;x++)
405
116M
        {
406
116M
          int iIdx = ((x+1)*intraPredAngle)>>5;  // DIFF (x<->y)
407
116M
          int iFact= ((x+1)*intraPredAngle)&31;  // DIFF (x<->y)
408
409
116M
          if (iFact != 0) {
410
55.2M
            dst[x+y*dstStride] = ((32-iFact)*ref[y+iIdx+1] + iFact*ref[y+iIdx+2] + 16)>>5; // DIFF (x<->y)
411
61.7M
          } else {
412
61.7M
            dst[x+y*dstStride] = ref[y+iIdx+1]; // DIFF (x<->y)
413
61.7M
          }
414
116M
        }
415
416
4.89M
    if (intraPredMode==10 && cIdx==0 && nT<32 && !disableIntraBoundaryFilter) {  // DIFF 26->10
417
440k
      for (int x=0;x<nT;x++) { // DIFF (x<->y)
418
364k
        dst[x] = Clip_BitDepth(border[-1] + ((border[1+x] - border[0])>>1), bit_depth); // DIFF (x<->y && neg)
419
364k
      }
420
76.3k
    }
421
4.89M
  }
422
423
424
7.09M
  logtrace(LogIntraPred,"result of angular intra prediction (mode=%d):\n",intraPredMode);
425
426
39.6M
  for (int y=0;y<nT;y++)
427
32.5M
    {
428
215M
      for (int x=0;x<nT;x++)
429
183M
        logtrace(LogIntraPred,"%02x ", dst[x+y*dstStride]);
430
431
32.5M
      logtrace(LogIntraPred,"\n");
432
32.5M
    }
433
7.09M
}
Unexecuted instantiation: void intra_prediction_angular<unsigned char>(unsigned char*, int, int, bool, int, int, IntraPredMode, int, int, unsigned char*)
void intra_prediction_angular<unsigned short>(unsigned short*, int, int, bool, int, int, IntraPredMode, int, int, unsigned short*)
Line
Count
Source
337
7.09M
{
338
7.09M
  pixel_t  ref_mem[4*MAX_INTRA_PRED_BLOCK_SIZE+1]; // TODO: what is the required range here ?
339
7.09M
  pixel_t* ref=&ref_mem[2*MAX_INTRA_PRED_BLOCK_SIZE];
340
341
7.09M
  assert(intraPredMode<35);
342
7.09M
  assert(intraPredMode>=2);
343
344
7.09M
  int intraPredAngle = intraPredAngle_table[intraPredMode];
345
346
7.09M
  if (intraPredMode >= 18) {
347
348
14.9M
    for (int x=0;x<=nT;x++)
349
12.7M
      { ref[x] = border[x]; }
350
351
2.19M
    if (intraPredAngle<0) {
352
741k
      int invAngle = invAngle_table[intraPredMode-11];
353
354
741k
      if ((nT*intraPredAngle)>>5 < -1) {
355
2.42M
        for (int x=(nT*intraPredAngle)>>5; x<=-1; x++) {
356
1.88M
          ref[x] = border[0-((x*invAngle+128)>>8)];
357
1.88M
        }
358
547k
      }
359
1.45M
    } else {
360
8.55M
      for (int x=nT+1; x<=2*nT;x++) {
361
7.09M
        ref[x] = border[x];
362
7.09M
      }
363
1.45M
    }
364
365
12.7M
    for (int y=0;y<nT;y++)
366
76.6M
      for (int x=0;x<nT;x++)
367
66.0M
        {
368
66.0M
          int iIdx = ((y+1)*intraPredAngle)>>5;
369
66.0M
          int iFact= ((y+1)*intraPredAngle)&31;
370
371
66.0M
          if (iFact != 0) {
372
32.9M
            dst[x+y*dstStride] = ((32-iFact)*ref[x+iIdx+1] + iFact*ref[x+iIdx+2] + 16)>>5;
373
33.0M
          } else {
374
33.0M
            dst[x+y*dstStride] = ref[x+iIdx+1];
375
33.0M
          }
376
66.0M
        }
377
378
2.19M
    if (intraPredMode==26 && cIdx==0 && nT<32 && !disableIntraBoundaryFilter) {
379
1.34M
      for (int y=0;y<nT;y++) {
380
1.10M
        dst[0+y*dstStride] = Clip_BitDepth(border[1] + ((border[-1-y] - border[0])>>1), bit_depth);
381
1.10M
      }
382
237k
    }
383
2.19M
  }
384
4.89M
  else { // intraPredAngle < 18
385
386
31.8M
    for (int x=0;x<=nT;x++)
387
26.9M
      { ref[x] = border[-x]; }  // DIFF (neg)
388
389
4.89M
    if (intraPredAngle<0) {
390
673k
      int invAngle = invAngle_table[intraPredMode-11];
391
392
673k
      if ((nT*intraPredAngle)>>5 < -1) {
393
2.10M
        for (int x=(nT*intraPredAngle)>>5; x<=-1; x++) {
394
1.58M
          ref[x] = border[((x*invAngle+128)>>8)]; // DIFF (neg)
395
1.58M
        }
396
513k
      }
397
4.22M
    } else {
398
23.0M
      for (int x=nT+1; x<=2*nT;x++) {
399
18.8M
        ref[x] = border[-x]; // DIFF (neg)
400
18.8M
      }
401
4.22M
    }
402
403
26.9M
    for (int y=0;y<nT;y++)
404
138M
      for (int x=0;x<nT;x++)
405
116M
        {
406
116M
          int iIdx = ((x+1)*intraPredAngle)>>5;  // DIFF (x<->y)
407
116M
          int iFact= ((x+1)*intraPredAngle)&31;  // DIFF (x<->y)
408
409
116M
          if (iFact != 0) {
410
55.2M
            dst[x+y*dstStride] = ((32-iFact)*ref[y+iIdx+1] + iFact*ref[y+iIdx+2] + 16)>>5; // DIFF (x<->y)
411
61.7M
          } else {
412
61.7M
            dst[x+y*dstStride] = ref[y+iIdx+1]; // DIFF (x<->y)
413
61.7M
          }
414
116M
        }
415
416
4.89M
    if (intraPredMode==10 && cIdx==0 && nT<32 && !disableIntraBoundaryFilter) {  // DIFF 26->10
417
440k
      for (int x=0;x<nT;x++) { // DIFF (x<->y)
418
364k
        dst[x] = Clip_BitDepth(border[-1] + ((border[1+x] - border[0])>>1), bit_depth); // DIFF (x<->y && neg)
419
364k
      }
420
76.3k
    }
421
4.89M
  }
422
423
424
7.09M
  logtrace(LogIntraPred,"result of angular intra prediction (mode=%d):\n",intraPredMode);
425
426
39.6M
  for (int y=0;y<nT;y++)
427
32.5M
    {
428
215M
      for (int x=0;x<nT;x++)
429
183M
        logtrace(LogIntraPred,"%02x ", dst[x+y*dstStride]);
430
431
32.5M
      logtrace(LogIntraPred,"\n");
432
32.5M
    }
433
7.09M
}
434
435
436
template <class pixel_t>
437
void intra_border_computer<pixel_t>::preproc()
438
41.8M
{
439
41.8M
  sps = &img->get_sps();
440
41.8M
  pps = &img->get_pps();
441
442
41.8M
  SubWidth  = (cIdx==0) ? 1 : sps->SubWidthC;
443
41.8M
  SubHeight = (cIdx==0) ? 1 : sps->SubHeightC;
444
445
  // --- check for CTB boundaries ---
446
447
41.8M
  int xBLuma = xB * SubWidth;
448
41.8M
  int yBLuma = yB * SubHeight;
449
450
41.8M
  int log2CtbSize = sps->Log2CtbSizeY;
451
41.8M
  int picWidthInCtbs = sps->PicWidthInCtbsY;
452
453
454
  //printf("xB/yB: %d %d\n",xB,yB);
455
456
  // are we at left image border
457
458
41.8M
  if (xBLuma == 0) {
459
341k
    availableLeft = false;
460
341k
    availableTopLeft = false;
461
341k
    xBLuma = 0; // fake value, available flags are already set to false
462
341k
  }
463
464
465
  // are we at top image border
466
467
41.8M
  if (yBLuma == 0) {
468
2.58M
    availableTop = false;
469
2.58M
    availableTopLeft = false;
470
2.58M
    availableTopRight = false;
471
2.58M
    yBLuma = 0; // fake value, available flags are already set to false
472
2.58M
  }
473
474
41.8M
  if (xBLuma+nT*SubWidth >= sps->pic_width_in_luma_samples) {
475
439k
    availableTopRight=false;
476
439k
  }
477
478
  // check for tile and slice boundaries
479
480
41.8M
  int xCurrCtb = xBLuma >> log2CtbSize;
481
41.8M
  int yCurrCtb = yBLuma >> log2CtbSize;
482
41.8M
  int xLeftCtb = (xBLuma-1) >> log2CtbSize;
483
41.8M
  int xRightCtb = (xBLuma+nT*SubWidth) >> log2CtbSize;
484
41.8M
  int yTopCtb   = (yBLuma-1) >> log2CtbSize;
485
486
41.8M
  int currCTBSlice = img->get_SliceAddrRS(xCurrCtb,yCurrCtb);
487
41.8M
  int leftCTBSlice = availableLeft ? img->get_SliceAddrRS(xLeftCtb, yCurrCtb) : -1;
488
41.8M
  int topCTBSlice  = availableTop ? img->get_SliceAddrRS(xCurrCtb, yTopCtb) : -1;
489
41.8M
  int toprightCTBSlice = availableTopRight ? img->get_SliceAddrRS(xRightCtb, yTopCtb) : -1;
490
41.8M
  int topleftCTBSlice  = availableTopLeft  ? img->get_SliceAddrRS(xLeftCtb, yTopCtb) : -1;
491
492
  /*
493
  printf("size: %d\n",pps->scan->TileIdRS.size());
494
  printf("curr: %d left: %d top: %d\n",
495
         xCurrCtb+yCurrCtb*picWidthInCtbs,
496
         availableLeft ? xLeftCtb+yCurrCtb*picWidthInCtbs : 9999,
497
         availableTop  ? xCurrCtb+yTopCtb*picWidthInCtbs  : 9999);
498
  */
499
41.8M
  uint32_t currCTBTileID = pps->scan->TileIdRS[xCurrCtb+yCurrCtb*picWidthInCtbs];
500
41.8M
  uint32_t leftCTBTileID = availableLeft ? pps->scan->TileIdRS[xLeftCtb+yCurrCtb*picWidthInCtbs] : UINT32_MAX;
501
41.8M
  uint32_t topCTBTileID  = availableTop ? pps->scan->TileIdRS[xCurrCtb+yTopCtb*picWidthInCtbs] : UINT32_MAX;
502
41.8M
  uint32_t topleftCTBTileID = availableTopLeft ? pps->scan->TileIdRS[xLeftCtb+yTopCtb*picWidthInCtbs] : UINT32_MAX;
503
41.8M
  uint32_t toprightCTBTileID= availableTopRight? pps->scan->TileIdRS[xRightCtb+yTopCtb*picWidthInCtbs] : UINT32_MAX;
504
505
41.8M
  if (leftCTBSlice != currCTBSlice  || leftCTBTileID != currCTBTileID ) availableLeft    = false;
506
41.8M
  if (topCTBSlice  != currCTBSlice  || topCTBTileID  != currCTBTileID ) availableTop     = false;
507
41.8M
  if (topleftCTBSlice !=currCTBSlice||topleftCTBTileID!=currCTBTileID ) availableTopLeft = false;
508
41.8M
  if (toprightCTBSlice!=currCTBSlice||toprightCTBTileID!=currCTBTileID) availableTopRight= false;
509
510
511
  // number of pixels that are in the valid image area to the right and to the bottom
512
513
41.8M
  nBottom = sps->pic_height_in_luma_samples - yB*SubHeight;
514
41.8M
  nBottom=(nBottom+SubHeight-1)/SubHeight;
515
41.8M
  if (nBottom>2*nT) nBottom=2*nT;
516
517
41.8M
  nRight  = sps->pic_width_in_luma_samples  - xB*SubWidth;
518
41.8M
  nRight =(nRight +SubWidth-1)/SubWidth;
519
41.8M
  if (nRight >2*nT) nRight=2*nT;
520
521
41.8M
  nAvail=0;
522
523
41.8M
  available = &available_data[2*MAX_INTRA_PRED_BLOCK_SIZE];
524
525
41.8M
  memset(available-2*nT, 0, 4*nT+1);
526
41.8M
}
intra_border_computer<unsigned short>::preproc()
Line
Count
Source
438
15.2M
{
439
15.2M
  sps = &img->get_sps();
440
15.2M
  pps = &img->get_pps();
441
442
15.2M
  SubWidth  = (cIdx==0) ? 1 : sps->SubWidthC;
443
15.2M
  SubHeight = (cIdx==0) ? 1 : sps->SubHeightC;
444
445
  // --- check for CTB boundaries ---
446
447
15.2M
  int xBLuma = xB * SubWidth;
448
15.2M
  int yBLuma = yB * SubHeight;
449
450
15.2M
  int log2CtbSize = sps->Log2CtbSizeY;
451
15.2M
  int picWidthInCtbs = sps->PicWidthInCtbsY;
452
453
454
  //printf("xB/yB: %d %d\n",xB,yB);
455
456
  // are we at left image border
457
458
15.2M
  if (xBLuma == 0) {
459
108k
    availableLeft = false;
460
108k
    availableTopLeft = false;
461
108k
    xBLuma = 0; // fake value, available flags are already set to false
462
108k
  }
463
464
465
  // are we at top image border
466
467
15.2M
  if (yBLuma == 0) {
468
1.17M
    availableTop = false;
469
1.17M
    availableTopLeft = false;
470
1.17M
    availableTopRight = false;
471
1.17M
    yBLuma = 0; // fake value, available flags are already set to false
472
1.17M
  }
473
474
15.2M
  if (xBLuma+nT*SubWidth >= sps->pic_width_in_luma_samples) {
475
135k
    availableTopRight=false;
476
135k
  }
477
478
  // check for tile and slice boundaries
479
480
15.2M
  int xCurrCtb = xBLuma >> log2CtbSize;
481
15.2M
  int yCurrCtb = yBLuma >> log2CtbSize;
482
15.2M
  int xLeftCtb = (xBLuma-1) >> log2CtbSize;
483
15.2M
  int xRightCtb = (xBLuma+nT*SubWidth) >> log2CtbSize;
484
15.2M
  int yTopCtb   = (yBLuma-1) >> log2CtbSize;
485
486
15.2M
  int currCTBSlice = img->get_SliceAddrRS(xCurrCtb,yCurrCtb);
487
15.2M
  int leftCTBSlice = availableLeft ? img->get_SliceAddrRS(xLeftCtb, yCurrCtb) : -1;
488
15.2M
  int topCTBSlice  = availableTop ? img->get_SliceAddrRS(xCurrCtb, yTopCtb) : -1;
489
15.2M
  int toprightCTBSlice = availableTopRight ? img->get_SliceAddrRS(xRightCtb, yTopCtb) : -1;
490
15.2M
  int topleftCTBSlice  = availableTopLeft  ? img->get_SliceAddrRS(xLeftCtb, yTopCtb) : -1;
491
492
  /*
493
  printf("size: %d\n",pps->scan->TileIdRS.size());
494
  printf("curr: %d left: %d top: %d\n",
495
         xCurrCtb+yCurrCtb*picWidthInCtbs,
496
         availableLeft ? xLeftCtb+yCurrCtb*picWidthInCtbs : 9999,
497
         availableTop  ? xCurrCtb+yTopCtb*picWidthInCtbs  : 9999);
498
  */
499
15.2M
  uint32_t currCTBTileID = pps->scan->TileIdRS[xCurrCtb+yCurrCtb*picWidthInCtbs];
500
15.2M
  uint32_t leftCTBTileID = availableLeft ? pps->scan->TileIdRS[xLeftCtb+yCurrCtb*picWidthInCtbs] : UINT32_MAX;
501
15.2M
  uint32_t topCTBTileID  = availableTop ? pps->scan->TileIdRS[xCurrCtb+yTopCtb*picWidthInCtbs] : UINT32_MAX;
502
15.2M
  uint32_t topleftCTBTileID = availableTopLeft ? pps->scan->TileIdRS[xLeftCtb+yTopCtb*picWidthInCtbs] : UINT32_MAX;
503
15.2M
  uint32_t toprightCTBTileID= availableTopRight? pps->scan->TileIdRS[xRightCtb+yTopCtb*picWidthInCtbs] : UINT32_MAX;
504
505
15.2M
  if (leftCTBSlice != currCTBSlice  || leftCTBTileID != currCTBTileID ) availableLeft    = false;
506
15.2M
  if (topCTBSlice  != currCTBSlice  || topCTBTileID  != currCTBTileID ) availableTop     = false;
507
15.2M
  if (topleftCTBSlice !=currCTBSlice||topleftCTBTileID!=currCTBTileID ) availableTopLeft = false;
508
15.2M
  if (toprightCTBSlice!=currCTBSlice||toprightCTBTileID!=currCTBTileID) availableTopRight= false;
509
510
511
  // number of pixels that are in the valid image area to the right and to the bottom
512
513
15.2M
  nBottom = sps->pic_height_in_luma_samples - yB*SubHeight;
514
15.2M
  nBottom=(nBottom+SubHeight-1)/SubHeight;
515
15.2M
  if (nBottom>2*nT) nBottom=2*nT;
516
517
15.2M
  nRight  = sps->pic_width_in_luma_samples  - xB*SubWidth;
518
15.2M
  nRight =(nRight +SubWidth-1)/SubWidth;
519
15.2M
  if (nRight >2*nT) nRight=2*nT;
520
521
15.2M
  nAvail=0;
522
523
15.2M
  available = &available_data[2*MAX_INTRA_PRED_BLOCK_SIZE];
524
525
15.2M
  memset(available-2*nT, 0, 4*nT+1);
526
15.2M
}
intra_border_computer<unsigned char>::preproc()
Line
Count
Source
438
26.6M
{
439
26.6M
  sps = &img->get_sps();
440
26.6M
  pps = &img->get_pps();
441
442
26.6M
  SubWidth  = (cIdx==0) ? 1 : sps->SubWidthC;
443
26.6M
  SubHeight = (cIdx==0) ? 1 : sps->SubHeightC;
444
445
  // --- check for CTB boundaries ---
446
447
26.6M
  int xBLuma = xB * SubWidth;
448
26.6M
  int yBLuma = yB * SubHeight;
449
450
26.6M
  int log2CtbSize = sps->Log2CtbSizeY;
451
26.6M
  int picWidthInCtbs = sps->PicWidthInCtbsY;
452
453
454
  //printf("xB/yB: %d %d\n",xB,yB);
455
456
  // are we at left image border
457
458
26.6M
  if (xBLuma == 0) {
459
232k
    availableLeft = false;
460
232k
    availableTopLeft = false;
461
232k
    xBLuma = 0; // fake value, available flags are already set to false
462
232k
  }
463
464
465
  // are we at top image border
466
467
26.6M
  if (yBLuma == 0) {
468
1.41M
    availableTop = false;
469
1.41M
    availableTopLeft = false;
470
1.41M
    availableTopRight = false;
471
1.41M
    yBLuma = 0; // fake value, available flags are already set to false
472
1.41M
  }
473
474
26.6M
  if (xBLuma+nT*SubWidth >= sps->pic_width_in_luma_samples) {
475
304k
    availableTopRight=false;
476
304k
  }
477
478
  // check for tile and slice boundaries
479
480
26.6M
  int xCurrCtb = xBLuma >> log2CtbSize;
481
26.6M
  int yCurrCtb = yBLuma >> log2CtbSize;
482
26.6M
  int xLeftCtb = (xBLuma-1) >> log2CtbSize;
483
26.6M
  int xRightCtb = (xBLuma+nT*SubWidth) >> log2CtbSize;
484
26.6M
  int yTopCtb   = (yBLuma-1) >> log2CtbSize;
485
486
26.6M
  int currCTBSlice = img->get_SliceAddrRS(xCurrCtb,yCurrCtb);
487
26.6M
  int leftCTBSlice = availableLeft ? img->get_SliceAddrRS(xLeftCtb, yCurrCtb) : -1;
488
26.6M
  int topCTBSlice  = availableTop ? img->get_SliceAddrRS(xCurrCtb, yTopCtb) : -1;
489
26.6M
  int toprightCTBSlice = availableTopRight ? img->get_SliceAddrRS(xRightCtb, yTopCtb) : -1;
490
26.6M
  int topleftCTBSlice  = availableTopLeft  ? img->get_SliceAddrRS(xLeftCtb, yTopCtb) : -1;
491
492
  /*
493
  printf("size: %d\n",pps->scan->TileIdRS.size());
494
  printf("curr: %d left: %d top: %d\n",
495
         xCurrCtb+yCurrCtb*picWidthInCtbs,
496
         availableLeft ? xLeftCtb+yCurrCtb*picWidthInCtbs : 9999,
497
         availableTop  ? xCurrCtb+yTopCtb*picWidthInCtbs  : 9999);
498
  */
499
26.6M
  uint32_t currCTBTileID = pps->scan->TileIdRS[xCurrCtb+yCurrCtb*picWidthInCtbs];
500
26.6M
  uint32_t leftCTBTileID = availableLeft ? pps->scan->TileIdRS[xLeftCtb+yCurrCtb*picWidthInCtbs] : UINT32_MAX;
501
26.6M
  uint32_t topCTBTileID  = availableTop ? pps->scan->TileIdRS[xCurrCtb+yTopCtb*picWidthInCtbs] : UINT32_MAX;
502
26.6M
  uint32_t topleftCTBTileID = availableTopLeft ? pps->scan->TileIdRS[xLeftCtb+yTopCtb*picWidthInCtbs] : UINT32_MAX;
503
26.6M
  uint32_t toprightCTBTileID= availableTopRight? pps->scan->TileIdRS[xRightCtb+yTopCtb*picWidthInCtbs] : UINT32_MAX;
504
505
26.6M
  if (leftCTBSlice != currCTBSlice  || leftCTBTileID != currCTBTileID ) availableLeft    = false;
506
26.6M
  if (topCTBSlice  != currCTBSlice  || topCTBTileID  != currCTBTileID ) availableTop     = false;
507
26.6M
  if (topleftCTBSlice !=currCTBSlice||topleftCTBTileID!=currCTBTileID ) availableTopLeft = false;
508
26.6M
  if (toprightCTBSlice!=currCTBSlice||toprightCTBTileID!=currCTBTileID) availableTopRight= false;
509
510
511
  // number of pixels that are in the valid image area to the right and to the bottom
512
513
26.6M
  nBottom = sps->pic_height_in_luma_samples - yB*SubHeight;
514
26.6M
  nBottom=(nBottom+SubHeight-1)/SubHeight;
515
26.6M
  if (nBottom>2*nT) nBottom=2*nT;
516
517
26.6M
  nRight  = sps->pic_width_in_luma_samples  - xB*SubWidth;
518
26.6M
  nRight =(nRight +SubWidth-1)/SubWidth;
519
26.6M
  if (nRight >2*nT) nRight=2*nT;
520
521
26.6M
  nAvail=0;
522
523
26.6M
  available = &available_data[2*MAX_INTRA_PRED_BLOCK_SIZE];
524
525
26.6M
  memset(available-2*nT, 0, 4*nT+1);
526
26.6M
}
527
528
529
template <class pixel_t>
530
void intra_border_computer<pixel_t>::fill_from_image()
531
41.6M
{
532
41.6M
  assert(nT<=32);
533
534
41.6M
  pixel_t* image;
535
41.6M
  ptrdiff_t stride;
536
41.6M
  image  = (pixel_t*)img->get_image_plane(cIdx);
537
41.6M
  stride = img->get_image_stride(cIdx);
538
539
41.6M
  int xBLuma = xB * SubWidth;
540
41.6M
  int yBLuma = yB * SubHeight;
541
542
41.6M
  int currBlockAddr = pps->scan->MinTbAddrZS[ (xBLuma>>sps->Log2MinTrafoSize) +
543
41.6M
                                        (yBLuma>>sps->Log2MinTrafoSize) * sps->PicWidthInTbsY ];
544
545
546
  // copy pixels at left column
547
548
132M
  for (int y=nBottom-1 ; y>=0 ; y-=4)
549
90.7M
    if (availableLeft)
550
89.6M
      {
551
89.6M
        int NBlockAddr = pps->scan->MinTbAddrZS[ (((xB-1)*SubWidth )>>sps->Log2MinTrafoSize) +
552
89.6M
                                           (((yB+y)*SubHeight)>>sps->Log2MinTrafoSize)
553
89.6M
                                           * sps->PicWidthInTbsY ];
554
555
89.6M
        bool availableN = NBlockAddr <= currBlockAddr;
556
557
89.6M
        if (pps->constrained_intra_pred_flag) {
558
31.9M
          if (img->get_pred_mode((xB-1)*SubWidth,(yB+y)*SubHeight)!=MODE_INTRA)
559
128k
            availableN = false;
560
31.9M
        }
561
562
89.6M
        if (availableN) {
563
61.2M
          if (!nAvail) firstValue = image[xB-1 + (yB+y)*stride];
564
565
306M
          for (int i=0;i<4;i++) {
566
245M
            available[-y+i-1] = availableN;
567
245M
            out_border[-y+i-1] = image[xB-1 + (yB+y-i)*stride];
568
245M
          }
569
570
61.2M
          nAvail+=4;
571
61.2M
        }
572
89.6M
      }
573
574
  // copy pixel at top-left position
575
576
41.6M
  if (availableTopLeft)
577
38.8M
    {
578
38.8M
      int NBlockAddr = pps->scan->MinTbAddrZS[ (((xB-1)*SubWidth )>>sps->Log2MinTrafoSize) +
579
38.8M
                                         (((yB-1)*SubHeight)>>sps->Log2MinTrafoSize)
580
38.8M
                                         * sps->PicWidthInTbsY ];
581
582
38.8M
      bool availableN = NBlockAddr <= currBlockAddr;
583
584
38.8M
      if (pps->constrained_intra_pred_flag) {
585
13.6M
        if (img->get_pred_mode((xB-1)*SubWidth,(yB-1)*SubHeight)!=MODE_INTRA) {
586
78.2k
          availableN = false;
587
78.2k
        }
588
13.6M
      }
589
590
38.8M
      if (availableN) {
591
38.7M
        if (!nAvail) firstValue = image[xB-1 + (yB-1)*stride];
592
593
38.7M
        out_border[0] = image[xB-1 + (yB-1)*stride];
594
38.7M
        available[0] = availableN;
595
38.7M
        nAvail++;
596
38.7M
      }
597
38.8M
    }
598
599
  // copy pixels at top row
600
601
135M
  for (int x=0 ; x<nRight ; x+=4) {
602
93.5M
    bool borderAvailable;
603
93.5M
    if (x<nT) borderAvailable=availableTop;
604
46.3M
    else      borderAvailable=availableTopRight;
605
606
93.5M
    if (borderAvailable)
607
86.6M
      {
608
86.6M
        int NBlockAddr = pps->scan->MinTbAddrZS[ (((xB+x)*SubWidth )>>sps->Log2MinTrafoSize) +
609
86.6M
                                           (((yB-1)*SubHeight)>>sps->Log2MinTrafoSize)
610
86.6M
                                           * sps->PicWidthInTbsY ];
611
612
86.6M
        bool availableN = NBlockAddr <= currBlockAddr;
613
614
86.6M
        if (pps->constrained_intra_pred_flag) {
615
31.1M
          if (img->get_pred_mode((xB+x)*SubWidth,(yB-1)*SubHeight)!=MODE_INTRA) {
616
111k
            availableN = false;
617
111k
          }
618
31.1M
        }
619
620
621
86.6M
        if (availableN) {
622
71.8M
          if (!nAvail) firstValue = image[xB+x + (yB-1)*stride];
623
624
359M
          for (int i=0;i<4;i++) {
625
287M
            out_border[x+i+1] = image[xB+x+i + (yB-1)*stride];
626
287M
            available[x+i+1] = availableN;
627
287M
          }
628
629
71.8M
          nAvail+=4;
630
71.8M
        }
631
86.6M
      }
632
93.5M
  }
633
41.6M
}
intra_border_computer<unsigned short>::fill_from_image()
Line
Count
Source
531
15.2M
{
532
15.2M
  assert(nT<=32);
533
534
15.2M
  pixel_t* image;
535
15.2M
  ptrdiff_t stride;
536
15.2M
  image  = (pixel_t*)img->get_image_plane(cIdx);
537
15.2M
  stride = img->get_image_stride(cIdx);
538
539
15.2M
  int xBLuma = xB * SubWidth;
540
15.2M
  int yBLuma = yB * SubHeight;
541
542
15.2M
  int currBlockAddr = pps->scan->MinTbAddrZS[ (xBLuma>>sps->Log2MinTrafoSize) +
543
15.2M
                                        (yBLuma>>sps->Log2MinTrafoSize) * sps->PicWidthInTbsY ];
544
545
546
  // copy pixels at left column
547
548
47.8M
  for (int y=nBottom-1 ; y>=0 ; y-=4)
549
32.5M
    if (availableLeft)
550
32.2M
      {
551
32.2M
        int NBlockAddr = pps->scan->MinTbAddrZS[ (((xB-1)*SubWidth )>>sps->Log2MinTrafoSize) +
552
32.2M
                                           (((yB+y)*SubHeight)>>sps->Log2MinTrafoSize)
553
32.2M
                                           * sps->PicWidthInTbsY ];
554
555
32.2M
        bool availableN = NBlockAddr <= currBlockAddr;
556
557
32.2M
        if (pps->constrained_intra_pred_flag) {
558
8.70M
          if (img->get_pred_mode((xB-1)*SubWidth,(yB+y)*SubHeight)!=MODE_INTRA)
559
22.3k
            availableN = false;
560
8.70M
        }
561
562
32.2M
        if (availableN) {
563
22.4M
          if (!nAvail) firstValue = image[xB-1 + (yB+y)*stride];
564
565
112M
          for (int i=0;i<4;i++) {
566
89.6M
            available[-y+i-1] = availableN;
567
89.6M
            out_border[-y+i-1] = image[xB-1 + (yB+y-i)*stride];
568
89.6M
          }
569
570
22.4M
          nAvail+=4;
571
22.4M
        }
572
32.2M
      }
573
574
  // copy pixel at top-left position
575
576
15.2M
  if (availableTopLeft)
577
13.9M
    {
578
13.9M
      int NBlockAddr = pps->scan->MinTbAddrZS[ (((xB-1)*SubWidth )>>sps->Log2MinTrafoSize) +
579
13.9M
                                         (((yB-1)*SubHeight)>>sps->Log2MinTrafoSize)
580
13.9M
                                         * sps->PicWidthInTbsY ];
581
582
13.9M
      bool availableN = NBlockAddr <= currBlockAddr;
583
584
13.9M
      if (pps->constrained_intra_pred_flag) {
585
4.11M
        if (img->get_pred_mode((xB-1)*SubWidth,(yB-1)*SubHeight)!=MODE_INTRA) {
586
10.9k
          availableN = false;
587
10.9k
        }
588
4.11M
      }
589
590
13.9M
      if (availableN) {
591
13.9M
        if (!nAvail) firstValue = image[xB-1 + (yB-1)*stride];
592
593
13.9M
        out_border[0] = image[xB-1 + (yB-1)*stride];
594
13.9M
        available[0] = availableN;
595
13.9M
        nAvail++;
596
13.9M
      }
597
13.9M
    }
598
599
  // copy pixels at top row
600
601
49.2M
  for (int x=0 ; x<nRight ; x+=4) {
602
34.0M
    bool borderAvailable;
603
34.0M
    if (x<nT) borderAvailable=availableTop;
604
16.9M
    else      borderAvailable=availableTopRight;
605
606
34.0M
    if (borderAvailable)
607
30.7M
      {
608
30.7M
        int NBlockAddr = pps->scan->MinTbAddrZS[ (((xB+x)*SubWidth )>>sps->Log2MinTrafoSize) +
609
30.7M
                                           (((yB-1)*SubHeight)>>sps->Log2MinTrafoSize)
610
30.7M
                                           * sps->PicWidthInTbsY ];
611
612
30.7M
        bool availableN = NBlockAddr <= currBlockAddr;
613
614
30.7M
        if (pps->constrained_intra_pred_flag) {
615
8.32M
          if (img->get_pred_mode((xB+x)*SubWidth,(yB-1)*SubHeight)!=MODE_INTRA) {
616
12.0k
            availableN = false;
617
12.0k
          }
618
8.32M
        }
619
620
621
30.7M
        if (availableN) {
622
25.2M
          if (!nAvail) firstValue = image[xB+x + (yB-1)*stride];
623
624
126M
          for (int i=0;i<4;i++) {
625
101M
            out_border[x+i+1] = image[xB+x+i + (yB-1)*stride];
626
101M
            available[x+i+1] = availableN;
627
101M
          }
628
629
25.2M
          nAvail+=4;
630
25.2M
        }
631
30.7M
      }
632
34.0M
  }
633
15.2M
}
intra_border_computer<unsigned char>::fill_from_image()
Line
Count
Source
531
26.4M
{
532
26.4M
  assert(nT<=32);
533
534
26.4M
  pixel_t* image;
535
26.4M
  ptrdiff_t stride;
536
26.4M
  image  = (pixel_t*)img->get_image_plane(cIdx);
537
26.4M
  stride = img->get_image_stride(cIdx);
538
539
26.4M
  int xBLuma = xB * SubWidth;
540
26.4M
  int yBLuma = yB * SubHeight;
541
542
26.4M
  int currBlockAddr = pps->scan->MinTbAddrZS[ (xBLuma>>sps->Log2MinTrafoSize) +
543
26.4M
                                        (yBLuma>>sps->Log2MinTrafoSize) * sps->PicWidthInTbsY ];
544
545
546
  // copy pixels at left column
547
548
84.6M
  for (int y=nBottom-1 ; y>=0 ; y-=4)
549
58.2M
    if (availableLeft)
550
57.4M
      {
551
57.4M
        int NBlockAddr = pps->scan->MinTbAddrZS[ (((xB-1)*SubWidth )>>sps->Log2MinTrafoSize) +
552
57.4M
                                           (((yB+y)*SubHeight)>>sps->Log2MinTrafoSize)
553
57.4M
                                           * sps->PicWidthInTbsY ];
554
555
57.4M
        bool availableN = NBlockAddr <= currBlockAddr;
556
557
57.4M
        if (pps->constrained_intra_pred_flag) {
558
23.2M
          if (img->get_pred_mode((xB-1)*SubWidth,(yB+y)*SubHeight)!=MODE_INTRA)
559
106k
            availableN = false;
560
23.2M
        }
561
562
57.4M
        if (availableN) {
563
38.8M
          if (!nAvail) firstValue = image[xB-1 + (yB+y)*stride];
564
565
194M
          for (int i=0;i<4;i++) {
566
155M
            available[-y+i-1] = availableN;
567
155M
            out_border[-y+i-1] = image[xB-1 + (yB+y-i)*stride];
568
155M
          }
569
570
38.8M
          nAvail+=4;
571
38.8M
        }
572
57.4M
      }
573
574
  // copy pixel at top-left position
575
576
26.4M
  if (availableTopLeft)
577
24.9M
    {
578
24.9M
      int NBlockAddr = pps->scan->MinTbAddrZS[ (((xB-1)*SubWidth )>>sps->Log2MinTrafoSize) +
579
24.9M
                                         (((yB-1)*SubHeight)>>sps->Log2MinTrafoSize)
580
24.9M
                                         * sps->PicWidthInTbsY ];
581
582
24.9M
      bool availableN = NBlockAddr <= currBlockAddr;
583
584
24.9M
      if (pps->constrained_intra_pred_flag) {
585
9.55M
        if (img->get_pred_mode((xB-1)*SubWidth,(yB-1)*SubHeight)!=MODE_INTRA) {
586
67.3k
          availableN = false;
587
67.3k
        }
588
9.55M
      }
589
590
24.9M
      if (availableN) {
591
24.8M
        if (!nAvail) firstValue = image[xB-1 + (yB-1)*stride];
592
593
24.8M
        out_border[0] = image[xB-1 + (yB-1)*stride];
594
24.8M
        available[0] = availableN;
595
24.8M
        nAvail++;
596
24.8M
      }
597
24.9M
    }
598
599
  // copy pixels at top row
600
601
85.9M
  for (int x=0 ; x<nRight ; x+=4) {
602
59.5M
    bool borderAvailable;
603
59.5M
    if (x<nT) borderAvailable=availableTop;
604
29.4M
    else      borderAvailable=availableTopRight;
605
606
59.5M
    if (borderAvailable)
607
55.9M
      {
608
55.9M
        int NBlockAddr = pps->scan->MinTbAddrZS[ (((xB+x)*SubWidth )>>sps->Log2MinTrafoSize) +
609
55.9M
                                           (((yB-1)*SubHeight)>>sps->Log2MinTrafoSize)
610
55.9M
                                           * sps->PicWidthInTbsY ];
611
612
55.9M
        bool availableN = NBlockAddr <= currBlockAddr;
613
614
55.9M
        if (pps->constrained_intra_pred_flag) {
615
22.8M
          if (img->get_pred_mode((xB+x)*SubWidth,(yB-1)*SubHeight)!=MODE_INTRA) {
616
99.3k
            availableN = false;
617
99.3k
          }
618
22.8M
        }
619
620
621
55.9M
        if (availableN) {
622
46.5M
          if (!nAvail) firstValue = image[xB+x + (yB-1)*stride];
623
624
232M
          for (int i=0;i<4;i++) {
625
186M
            out_border[x+i+1] = image[xB+x+i + (yB-1)*stride];
626
186M
            available[x+i+1] = availableN;
627
186M
          }
628
629
46.5M
          nAvail+=4;
630
46.5M
        }
631
55.9M
      }
632
59.5M
  }
633
26.4M
}
634
635
636
637
template <class pixel_t>
638
void intra_border_computer<pixel_t>::reference_sample_substitution()
639
41.7M
{
640
  // reference sample substitution
641
642
41.7M
  const int bit_depth = img->get_bit_depth(cIdx);
643
644
41.7M
  if (nAvail!=4*nT+1) {
645
30.1M
    if (nAvail==0) {
646
54.6k
      if (sizeof(pixel_t)==1) {
647
38.1k
        memset(out_border-2*nT, 1<<(bit_depth-1), 4*nT+1);
648
38.1k
      }
649
16.4k
      else {
650
697k
        for (int i = -2*nT; i <= 2*nT ; i++) {
651
680k
          out_border[i] = 1<<(bit_depth-1);
652
680k
        }
653
16.4k
      }
654
54.6k
    }
655
30.1M
    else {
656
30.1M
      if (!available[-2*nT]) {
657
28.1M
        out_border[-2*nT] = firstValue;
658
28.1M
      }
659
660
580M
      for (int i=-2*nT+1; i<=2*nT; i++)
661
550M
        if (!available[i]) {
662
194M
          out_border[i]=out_border[i-1];
663
194M
        }
664
30.1M
    }
665
30.1M
  }
666
667
41.7M
  logtrace(LogIntraPred,"availableN: ");
668
41.7M
  print_border(available,nullptr,nT);
669
41.7M
  logtrace(LogIntraPred,"\n");
670
671
41.7M
  logtrace(LogIntraPred,"output:     ");
672
41.7M
  print_border(out_border,nullptr,nT);
673
41.7M
  logtrace(LogIntraPred,"\n");
674
41.7M
}
intra_border_computer<unsigned short>::reference_sample_substitution()
Line
Count
Source
639
15.2M
{
640
  // reference sample substitution
641
642
15.2M
  const int bit_depth = img->get_bit_depth(cIdx);
643
644
15.2M
  if (nAvail!=4*nT+1) {
645
11.0M
    if (nAvail==0) {
646
16.4k
      if (sizeof(pixel_t)==1) {
647
0
        memset(out_border-2*nT, 1<<(bit_depth-1), 4*nT+1);
648
0
      }
649
16.4k
      else {
650
697k
        for (int i = -2*nT; i <= 2*nT ; i++) {
651
680k
          out_border[i] = 1<<(bit_depth-1);
652
680k
        }
653
16.4k
      }
654
16.4k
    }
655
11.0M
    else {
656
11.0M
      if (!available[-2*nT]) {
657
10.1M
        out_border[-2*nT] = firstValue;
658
10.1M
      }
659
660
211M
      for (int i=-2*nT+1; i<=2*nT; i++)
661
200M
        if (!available[i]) {
662
73.2M
          out_border[i]=out_border[i-1];
663
73.2M
        }
664
11.0M
    }
665
11.0M
  }
666
667
15.2M
  logtrace(LogIntraPred,"availableN: ");
668
15.2M
  print_border(available,nullptr,nT);
669
15.2M
  logtrace(LogIntraPred,"\n");
670
671
15.2M
  logtrace(LogIntraPred,"output:     ");
672
15.2M
  print_border(out_border,nullptr,nT);
673
15.2M
  logtrace(LogIntraPred,"\n");
674
15.2M
}
intra_border_computer<unsigned char>::reference_sample_substitution()
Line
Count
Source
639
26.5M
{
640
  // reference sample substitution
641
642
26.5M
  const int bit_depth = img->get_bit_depth(cIdx);
643
644
26.5M
  if (nAvail!=4*nT+1) {
645
19.1M
    if (nAvail==0) {
646
38.1k
      if (sizeof(pixel_t)==1) {
647
38.1k
        memset(out_border-2*nT, 1<<(bit_depth-1), 4*nT+1);
648
38.1k
      }
649
0
      else {
650
0
        for (int i = -2*nT; i <= 2*nT ; i++) {
651
0
          out_border[i] = 1<<(bit_depth-1);
652
0
        }
653
0
      }
654
38.1k
    }
655
19.1M
    else {
656
19.1M
      if (!available[-2*nT]) {
657
17.9M
        out_border[-2*nT] = firstValue;
658
17.9M
      }
659
660
368M
      for (int i=-2*nT+1; i<=2*nT; i++)
661
349M
        if (!available[i]) {
662
121M
          out_border[i]=out_border[i-1];
663
121M
        }
664
19.1M
    }
665
19.1M
  }
666
667
26.5M
  logtrace(LogIntraPred,"availableN: ");
668
26.5M
  print_border(available,nullptr,nT);
669
26.5M
  logtrace(LogIntraPred,"\n");
670
671
26.5M
  logtrace(LogIntraPred,"output:     ");
672
26.5M
  print_border(out_border,nullptr,nT);
673
26.5M
  logtrace(LogIntraPred,"\n");
674
26.5M
}
675
676
677
#endif