FFmpeg coverage


Directory: ../../../ffmpeg/
File: src/libavfilter/vf_hqx.c
Date: 2022-12-05 20:26:17
Exec Total Coverage
Lines: 324 327 99.1%
Functions: 14 14 100.0%
Branches: 688 700 98.3%

Line Branch Exec Source
1 /*
2 * Copyright (c) 2014 Clément Bœsch
3 *
4 * This file is part of FFmpeg.
5 *
6 * Permission to use, copy, modify, and/or distribute this software for any
7 * purpose with or without fee is hereby granted, provided that the above
8 * copyright notice and this permission notice appear in all copies.
9 *
10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17 */
18
19 /**
20 * @file
21 * hqx magnification filters (hq2x, hq3x, hq4x)
22 *
23 * Originally designed by Maxim Stephin.
24 *
25 * @see http://en.wikipedia.org/wiki/Hqx
26 * @see http://web.archive.org/web/20131114143602/http://www.hiend3d.com/hq3x.html
27 * @see http://blog.pkh.me/p/19-butchering-hqx-scaling-filters.html
28 */
29
30 #include "libavutil/opt.h"
31 #include "libavutil/avassert.h"
32 #include "libavutil/pixdesc.h"
33 #include "internal.h"
34
35 typedef int (*hqxfunc_t)(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs);
36
37 typedef struct HQXContext {
38 const AVClass *class;
39 int n;
40 hqxfunc_t func;
41 uint32_t rgbtoyuv[1<<24];
42 } HQXContext;
43
44 typedef struct ThreadData {
45 AVFrame *in, *out;
46 const uint32_t *rgbtoyuv;
47 } ThreadData;
48
49 #define OFFSET(x) offsetof(HQXContext, x)
50 #define FLAGS AV_OPT_FLAG_FILTERING_PARAM|AV_OPT_FLAG_VIDEO_PARAM
51 static const AVOption hqx_options[] = {
52 { "n", "set scale factor", OFFSET(n), AV_OPT_TYPE_INT, {.i64 = 3}, 2, 4, .flags = FLAGS },
53 { NULL }
54 };
55
56 AVFILTER_DEFINE_CLASS(hqx);
57
58 1564116 static av_always_inline uint32_t rgb2yuv(const uint32_t *r2y, uint32_t c)
59 {
60 1564116 return r2y[c & 0xffffff];
61 }
62
63 1053411 static av_always_inline int yuv_diff(uint32_t yuv1, uint32_t yuv2)
64 {
65 #define YMASK 0xff0000
66 #define UMASK 0x00ff00
67 #define VMASK 0x0000ff
68 #define ABSDIFF(a,b) (abs((int)(a)-(int)(b)))
69
70 1488443 return ABSDIFF(yuv1 & YMASK, yuv2 & YMASK) > (48 << 16) ||
71
4/4
✓ Branch 0 taken 435032 times.
✓ Branch 1 taken 618379 times.
✓ Branch 2 taken 241679 times.
✓ Branch 3 taken 193353 times.
1295090 ABSDIFF(yuv1 & UMASK, yuv2 & UMASK) > ( 7 << 8) ||
72
2/2
✓ Branch 0 taken 30757 times.
✓ Branch 1 taken 210922 times.
241679 ABSDIFF(yuv1 & VMASK, yuv2 & VMASK) > ( 6 << 0);
73 }
74
75 /* (c1*w1 + c2*w2) >> s */
76 1090820 static av_always_inline uint32_t interp_2px(uint32_t c1, int w1, uint32_t c2, int w2, int s)
77 {
78 2181640 return (((((c1 & 0xff00ff00) >> 8) * w1 + ((c2 & 0xff00ff00) >> 8) * w2) << (8 - s)) & 0xff00ff00) |
79 1090820 (((((c1 & 0x00ff00ff) ) * w1 + ((c2 & 0x00ff00ff) ) * w2) >> s ) & 0x00ff00ff);
80 }
81
82 /* (c1*w1 + c2*w2 + c3*w3) >> s */
83 1473284 static av_always_inline uint32_t interp_3px(uint32_t c1, int w1, uint32_t c2, int w2, uint32_t c3, int w3, int s)
84 {
85 2946568 return (((((c1 & 0xff00ff00) >> 8) * w1 + ((c2 & 0xff00ff00) >> 8) * w2 + ((c3 & 0xff00ff00) >> 8) * w3) << (8 - s)) & 0xff00ff00) |
86 1473284 (((((c1 & 0x00ff00ff) ) * w1 + ((c2 & 0x00ff00ff) ) * w2 + ((c3 & 0x00ff00ff) ) * w3) >> s ) & 0x00ff00ff);
87 }
88
89 /* m is the mask of diff with the center pixel that matters in the pattern, and
90 * r is the expected result (bit set to 1 if there is difference with the
91 * center, 0 otherwise) */
92 #define P(m, r) ((k_shuffled & (m)) == (r))
93
94 /* adjust 012345678 to 01235678: the mask doesn't contain the (null) diff
95 * between the center/current pixel and itself */
96 #define DROP4(z) ((z) > 4 ? (z)-1 : (z))
97
98 /* shuffle the input mask: move bit n (4-adjusted) to position stored in p<n> */
99 #define SHF(x, rot, n) (((x) >> ((rot) ? 7-DROP4(n) : DROP4(n)) & 1) << DROP4(p##n))
100
101 /* used to check if there is YUV difference between 2 pixels */
102 #define WDIFF(c1, c2) yuv_diff(rgb2yuv(r2y, c1), rgb2yuv(r2y, c2))
103
104 /* bootstrap template for every interpolation code. It defines the shuffled
105 * masks and surrounding pixels. The rot flag is used to indicate if it's a
106 * rotation; its basic effect is to shuffle k using p8..p0 instead of p0..p8 */
107 #define INTERP_BOOTSTRAP(rot) \
108 const int k_shuffled = SHF(k,rot,0) | SHF(k,rot,1) | SHF(k,rot,2) \
109 | SHF(k,rot,3) | 0 | SHF(k,rot,5) \
110 | SHF(k,rot,6) | SHF(k,rot,7) | SHF(k,rot,8); \
111 \
112 const uint32_t w0 = w[p0], w1 = w[p1], \
113 w3 = w[p3], w4 = w[p4], w5 = w[p5], \
114 w7 = w[p7]
115
116 /* Assuming p0..p8 is mapped to pixels 0..8, this function interpolates the
117 * top-left pixel in the total of the 2x2 pixels to interpolates. The function
118 * is also used for the 3 other pixels */
119 395752 static av_always_inline uint32_t hq2x_interp_1x1(const uint32_t *r2y, int k,
120 const uint32_t *w,
121 int p0, int p1, int p2,
122 int p3, int p4, int p5,
123 int p6, int p7, int p8)
124 {
125
16/16
✓ Branch 0 taken 197876 times.
✓ Branch 1 taken 197876 times.
✓ Branch 2 taken 197876 times.
✓ Branch 3 taken 197876 times.
✓ Branch 4 taken 197876 times.
✓ Branch 5 taken 197876 times.
✓ Branch 6 taken 197876 times.
✓ Branch 7 taken 197876 times.
✓ Branch 8 taken 197876 times.
✓ Branch 9 taken 197876 times.
✓ Branch 10 taken 197876 times.
✓ Branch 11 taken 197876 times.
✓ Branch 12 taken 197876 times.
✓ Branch 13 taken 197876 times.
✓ Branch 14 taken 197876 times.
✓ Branch 15 taken 197876 times.
395752 INTERP_BOOTSTRAP(0);
126
127
6/6
✓ Branch 0 taken 393760 times.
✓ Branch 1 taken 1992 times.
✓ Branch 2 taken 1580 times.
✓ Branch 3 taken 392180 times.
✓ Branch 7 taken 925 times.
✓ Branch 8 taken 2647 times.
395752 if ((P(0xbf,0x37) || P(0xdb,0x13)) && WDIFF(w1, w5))
128 925 return interp_2px(w4, 3, w3, 1, 2);
129
6/6
✓ Branch 0 taken 392527 times.
✓ Branch 1 taken 2300 times.
✓ Branch 2 taken 1743 times.
✓ Branch 3 taken 390784 times.
✓ Branch 7 taken 1196 times.
✓ Branch 8 taken 2847 times.
394827 if ((P(0xdb,0x49) || P(0xef,0x6d)) && WDIFF(w7, w3))
130 1196 return interp_2px(w4, 3, w1, 1, 2);
131
8/8
✓ Branch 0 taken 356872 times.
✓ Branch 1 taken 36759 times.
✓ Branch 2 taken 356750 times.
✓ Branch 3 taken 122 times.
✓ Branch 4 taken 140 times.
✓ Branch 5 taken 356610 times.
✓ Branch 9 taken 15433 times.
✓ Branch 10 taken 21588 times.
393631 if ((P(0x0b,0x0b) || P(0xfe,0x4a) || P(0xfe,0x1a)) && WDIFF(w3, w1))
132 15433 return w4;
133
8/8
✓ Branch 0 taken 377567 times.
✓ Branch 1 taken 631 times.
✓ Branch 2 taken 376292 times.
✓ Branch 3 taken 1275 times.
✓ Branch 4 taken 376069 times.
✓ Branch 5 taken 223 times.
✓ Branch 6 taken 375685 times.
✓ Branch 7 taken 384 times.
378198 if ((P(0x6f,0x2a) || P(0x5b,0x0a) || P(0xbf,0x3a) || P(0xdf,0x5a) ||
134
8/8
✓ Branch 0 taken 375397 times.
✓ Branch 1 taken 288 times.
✓ Branch 2 taken 375349 times.
✓ Branch 3 taken 48 times.
✓ Branch 4 taken 375086 times.
✓ Branch 5 taken 263 times.
✓ Branch 6 taken 374898 times.
✓ Branch 7 taken 188 times.
375685 P(0x9f,0x8a) || P(0xcf,0x8a) || P(0xef,0x4e) || P(0x3f,0x0e) ||
135
5/8
✓ Branch 0 taken 374898 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 374898 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 374675 times.
✓ Branch 5 taken 223 times.
✓ Branch 6 taken 374675 times.
✗ Branch 7 not taken.
374898 P(0xfb,0x5a) || P(0xbb,0x8a) || P(0x7f,0x5a) || P(0xaf,0x8a) ||
136
4/4
✓ Branch 0 taken 289 times.
✓ Branch 1 taken 374386 times.
✓ Branch 5 taken 1364 times.
✓ Branch 6 taken 2448 times.
378198 P(0xeb,0x8a)) && WDIFF(w3, w1))
137 1364 return interp_2px(w4, 3, w0, 1, 2);
138
2/2
✓ Branch 0 taken 13377 times.
✓ Branch 1 taken 363457 times.
376834 if (P(0x0b,0x08))
139 13377 return interp_3px(w4, 2, w0, 1, w1, 1, 2);
140
2/2
✓ Branch 0 taken 13309 times.
✓ Branch 1 taken 350148 times.
363457 if (P(0x0b,0x02))
141 13309 return interp_3px(w4, 2, w0, 1, w3, 1, 2);
142
2/2
✓ Branch 0 taken 6679 times.
✓ Branch 1 taken 343469 times.
350148 if (P(0x2f,0x2f))
143 6679 return interp_3px(w4, 14, w3, 1, w1, 1, 4);
144
4/4
✓ Branch 0 taken 342000 times.
✓ Branch 1 taken 1469 times.
✓ Branch 2 taken 1178 times.
✓ Branch 3 taken 340822 times.
343469 if (P(0xbf,0x37) || P(0xdb,0x13))
145 2647 return interp_3px(w4, 5, w1, 2, w3, 1, 3);
146
4/4
✓ Branch 0 taken 339291 times.
✓ Branch 1 taken 1531 times.
✓ Branch 2 taken 1316 times.
✓ Branch 3 taken 337975 times.
340822 if (P(0xdb,0x49) || P(0xef,0x6d))
147 2847 return interp_3px(w4, 5, w3, 2, w1, 1, 3);
148
8/8
✓ Branch 0 taken 302916 times.
✓ Branch 1 taken 35059 times.
✓ Branch 2 taken 300862 times.
✓ Branch 3 taken 2054 times.
✓ Branch 4 taken 295673 times.
✓ Branch 5 taken 5189 times.
✓ Branch 6 taken 248 times.
✓ Branch 7 taken 295425 times.
337975 if (P(0x1b,0x03) || P(0x4f,0x43) || P(0x8b,0x83) || P(0x6b,0x43))
149 42550 return interp_2px(w4, 3, w3, 1, 2);
150
8/8
✓ Branch 0 taken 259441 times.
✓ Branch 1 taken 35984 times.
✓ Branch 2 taken 251717 times.
✓ Branch 3 taken 7724 times.
✓ Branch 4 taken 251380 times.
✓ Branch 5 taken 337 times.
✓ Branch 6 taken 278 times.
✓ Branch 7 taken 251102 times.
295425 if (P(0x4b,0x09) || P(0x8b,0x89) || P(0x1f,0x19) || P(0x3b,0x19))
151 44323 return interp_2px(w4, 3, w1, 1, 2);
152
8/8
✓ Branch 0 taken 249571 times.
✓ Branch 1 taken 1531 times.
✓ Branch 2 taken 248255 times.
✓ Branch 3 taken 1316 times.
✓ Branch 4 taken 246786 times.
✓ Branch 5 taken 1469 times.
✓ Branch 6 taken 1178 times.
✓ Branch 7 taken 245608 times.
251102 if (P(0x7e,0x2a) || P(0xef,0xab) || P(0xbf,0x8f) || P(0x7e,0x0e))
153 5494 return interp_3px(w4, 2, w3, 3, w1, 3, 3);
154
8/8
✓ Branch 0 taken 245173 times.
✓ Branch 1 taken 435 times.
✓ Branch 2 taken 239438 times.
✓ Branch 3 taken 5735 times.
✓ Branch 4 taken 237436 times.
✓ Branch 5 taken 2002 times.
✓ Branch 6 taken 236958 times.
✓ Branch 7 taken 478 times.
245608 if (P(0xfb,0x6a) || P(0x6f,0x6e) || P(0x3f,0x3e) || P(0xfb,0xfa) ||
155
4/4
✓ Branch 0 taken 236564 times.
✓ Branch 1 taken 394 times.
✓ Branch 2 taken 148 times.
✓ Branch 3 taken 236416 times.
236958 P(0xdf,0xde) || P(0xdf,0x1e))
156 9192 return interp_2px(w4, 3, w0, 1, 2);
157
8/8
✓ Branch 0 taken 11863 times.
✓ Branch 1 taken 224553 times.
✓ Branch 2 taken 7338 times.
✓ Branch 3 taken 4525 times.
✓ Branch 4 taken 7011 times.
✓ Branch 5 taken 327 times.
✓ Branch 6 taken 4407 times.
✓ Branch 7 taken 2604 times.
236416 if (P(0x0a,0x00) || P(0x4f,0x4b) || P(0x9f,0x1b) || P(0x2f,0x0b) ||
158
8/8
✓ Branch 0 taken 3747 times.
✓ Branch 1 taken 660 times.
✓ Branch 2 taken 3634 times.
✓ Branch 3 taken 113 times.
✓ Branch 4 taken 3546 times.
✓ Branch 5 taken 88 times.
✓ Branch 6 taken 3091 times.
✓ Branch 7 taken 455 times.
4407 P(0xbe,0x0a) || P(0xee,0x0a) || P(0x7e,0x0a) || P(0xeb,0x4b) ||
159
2/2
✓ Branch 0 taken 1730 times.
✓ Branch 1 taken 1361 times.
3091 P(0x3b,0x1b))
160 235055 return interp_3px(w4, 2, w3, 1, w1, 1, 2);
161 1361 return interp_3px(w4, 6, w3, 1, w1, 1, 3);
162 }
163
164 /* Assuming p0..p8 is mapped to pixels 0..8, this function interpolates the
165 * top-left and top-center pixel in the total of the 3x3 pixels to
166 * interpolates. The function is also used for the 3 other couples of pixels
167 * defining the outline. The center pixel is not defined through this function,
168 * since it's just the same as the original value. */
169 395752 static av_always_inline void hq3x_interp_2x1(uint32_t *dst, int dst_linesize,
170 const uint32_t *r2y, int k,
171 const uint32_t *w,
172 int pos00, int pos01,
173 int p0, int p1, int p2,
174 int p3, int p4, int p5,
175 int p6, int p7, int p8,
176 int rotate)
177 {
178
32/32
✓ Branch 0 taken 197876 times.
✓ Branch 1 taken 197876 times.
✓ Branch 2 taken 197876 times.
✓ Branch 3 taken 197876 times.
✓ Branch 4 taken 197876 times.
✓ Branch 5 taken 197876 times.
✓ Branch 6 taken 197876 times.
✓ Branch 7 taken 197876 times.
✓ Branch 8 taken 197876 times.
✓ Branch 9 taken 197876 times.
✓ Branch 10 taken 197876 times.
✓ Branch 11 taken 197876 times.
✓ Branch 12 taken 197876 times.
✓ Branch 13 taken 197876 times.
✓ Branch 14 taken 197876 times.
✓ Branch 15 taken 197876 times.
✓ Branch 16 taken 197876 times.
✓ Branch 17 taken 197876 times.
✓ Branch 18 taken 197876 times.
✓ Branch 19 taken 197876 times.
✓ Branch 20 taken 197876 times.
✓ Branch 21 taken 197876 times.
✓ Branch 22 taken 197876 times.
✓ Branch 23 taken 197876 times.
✓ Branch 24 taken 197876 times.
✓ Branch 25 taken 197876 times.
✓ Branch 26 taken 197876 times.
✓ Branch 27 taken 197876 times.
✓ Branch 28 taken 197876 times.
✓ Branch 29 taken 197876 times.
✓ Branch 30 taken 197876 times.
✓ Branch 31 taken 197876 times.
395752 INTERP_BOOTSTRAP(rotate);
179
180 395752 uint32_t *dst00 = &dst[dst_linesize*(pos00>>1) + (pos00&1)];
181 395752 uint32_t *dst01 = &dst[dst_linesize*(pos01>>1) + (pos01&1)];
182
183
6/6
✓ Branch 0 taken 393713 times.
✓ Branch 1 taken 2039 times.
✓ Branch 2 taken 1557 times.
✓ Branch 3 taken 392156 times.
✓ Branch 7 taken 1054 times.
✓ Branch 8 taken 2542 times.
395752 if ((P(0xdb,0x49) || P(0xef,0x6d)) && WDIFF(w7, w3))
184 1054 *dst00 = interp_2px(w4, 3, w1, 1, 2);
185
6/6
✓ Branch 0 taken 392453 times.
✓ Branch 1 taken 2245 times.
✓ Branch 2 taken 1774 times.
✓ Branch 3 taken 390679 times.
✓ Branch 7 taken 1067 times.
✓ Branch 8 taken 2952 times.
394698 else if ((P(0xbf,0x37) || P(0xdb,0x13)) && WDIFF(w1, w5))
186 1067 *dst00 = interp_2px(w4, 3, w3, 1, 2);
187
8/8
✓ Branch 0 taken 356872 times.
✓ Branch 1 taken 36759 times.
✓ Branch 2 taken 356741 times.
✓ Branch 3 taken 131 times.
✓ Branch 4 taken 131 times.
✓ Branch 5 taken 356610 times.
✓ Branch 9 taken 15433 times.
✓ Branch 10 taken 21588 times.
393631 else if ((P(0x0b,0x0b) || P(0xfe,0x4a) || P(0xfe,0x1a)) && WDIFF(w3, w1))
188 15433 *dst00 = w4;
189
8/8
✓ Branch 0 taken 377602 times.
✓ Branch 1 taken 596 times.
✓ Branch 2 taken 376334 times.
✓ Branch 3 taken 1268 times.
✓ Branch 4 taken 376111 times.
✓ Branch 5 taken 223 times.
✓ Branch 6 taken 375727 times.
✓ Branch 7 taken 384 times.
378198 else if ((P(0x6f,0x2a) || P(0x5b,0x0a) || P(0xbf,0x3a) || P(0xdf,0x5a) ||
190
8/8
✓ Branch 0 taken 375427 times.
✓ Branch 1 taken 300 times.
✓ Branch 2 taken 375390 times.
✓ Branch 3 taken 37 times.
✓ Branch 4 taken 375130 times.
✓ Branch 5 taken 260 times.
✓ Branch 6 taken 374897 times.
✓ Branch 7 taken 233 times.
375727 P(0x9f,0x8a) || P(0xcf,0x8a) || P(0xef,0x4e) || P(0x3f,0x0e) ||
191
5/8
✓ Branch 0 taken 374897 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 374897 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 374674 times.
✓ Branch 5 taken 223 times.
✓ Branch 6 taken 374674 times.
✗ Branch 7 not taken.
374897 P(0xfb,0x5a) || P(0xbb,0x8a) || P(0x7f,0x5a) || P(0xaf,0x8a) ||
192
4/4
✓ Branch 0 taken 288 times.
✓ Branch 1 taken 374386 times.
✓ Branch 5 taken 1364 times.
✓ Branch 6 taken 2448 times.
378198 P(0xeb,0x8a)) && WDIFF(w3, w1))
193 1364 *dst00 = interp_2px(w4, 3, w0, 1, 2);
194
8/8
✓ Branch 0 taken 341246 times.
✓ Branch 1 taken 35588 times.
✓ Branch 2 taken 333753 times.
✓ Branch 3 taken 7493 times.
✓ Branch 4 taken 333428 times.
✓ Branch 5 taken 325 times.
✓ Branch 6 taken 233 times.
✓ Branch 7 taken 333195 times.
376834 else if (P(0x4b,0x09) || P(0x8b,0x89) || P(0x1f,0x19) || P(0x3b,0x19))
195 43639 *dst00 = interp_2px(w4, 3, w1, 1, 2);
196
8/8
✓ Branch 0 taken 297740 times.
✓ Branch 1 taken 35455 times.
✓ Branch 2 taken 295652 times.
✓ Branch 3 taken 2088 times.
✓ Branch 4 taken 290210 times.
✓ Branch 5 taken 5442 times.
✓ Branch 6 taken 249 times.
✓ Branch 7 taken 289961 times.
333195 else if (P(0x1b,0x03) || P(0x4f,0x43) || P(0x8b,0x83) || P(0x6b,0x43))
197 43234 *dst00 = interp_2px(w4, 3, w3, 1, 2);
198
8/8
✓ Branch 0 taken 288374 times.
✓ Branch 1 taken 1587 times.
✓ Branch 2 taken 287009 times.
✓ Branch 3 taken 1365 times.
✓ Branch 4 taken 285600 times.
✓ Branch 5 taken 1409 times.
✓ Branch 6 taken 1133 times.
✓ Branch 7 taken 284467 times.
289961 else if (P(0x7e,0x2a) || P(0xef,0xab) || P(0xbf,0x8f) || P(0x7e,0x0e))
199 5494 *dst00 = interp_2px(w3, 1, w1, 1, 1);
200
8/8
✓ Branch 0 taken 279958 times.
✓ Branch 1 taken 4509 times.
✓ Branch 2 taken 279627 times.
✓ Branch 3 taken 331 times.
✓ Branch 4 taken 277034 times.
✓ Branch 5 taken 2593 times.
✓ Branch 6 taken 276369 times.
✓ Branch 7 taken 665 times.
284467 else if (P(0x4f,0x4b) || P(0x9f,0x1b) || P(0x2f,0x0b) || P(0xbe,0x0a) ||
201
8/8
✓ Branch 0 taken 276261 times.
✓ Branch 1 taken 108 times.
✓ Branch 2 taken 276173 times.
✓ Branch 3 taken 88 times.
✓ Branch 4 taken 275726 times.
✓ Branch 5 taken 447 times.
✓ Branch 6 taken 1761 times.
✓ Branch 7 taken 273965 times.
276369 P(0xee,0x0a) || P(0x7e,0x0a) || P(0xeb,0x4b) || P(0x3b,0x1b))
202 10502 *dst00 = interp_3px(w4, 2, w3, 7, w1, 7, 4);
203
8/8
✓ Branch 0 taken 260613 times.
✓ Branch 1 taken 13352 times.
✓ Branch 2 taken 260192 times.
✓ Branch 3 taken 421 times.
✓ Branch 4 taken 259951 times.
✓ Branch 5 taken 241 times.
✓ Branch 6 taken 254030 times.
✓ Branch 7 taken 5921 times.
273965 else if (P(0x0b,0x08) || P(0xf9,0x68) || P(0xf3,0x62) || P(0x6d,0x6c) ||
204
8/8
✓ Branch 0 taken 251900 times.
✓ Branch 1 taken 2130 times.
✓ Branch 2 taken 250096 times.
✓ Branch 3 taken 1804 times.
✓ Branch 4 taken 249152 times.
✓ Branch 5 taken 944 times.
✓ Branch 6 taken 248716 times.
✓ Branch 7 taken 436 times.
254030 P(0x67,0x66) || P(0x3d,0x3c) || P(0x37,0x36) || P(0xf9,0xf8) ||
205
8/8
✓ Branch 0 taken 248280 times.
✓ Branch 1 taken 436 times.
✓ Branch 2 taken 247992 times.
✓ Branch 3 taken 288 times.
✓ Branch 4 taken 247550 times.
✓ Branch 5 taken 442 times.
✓ Branch 6 taken 247376 times.
✓ Branch 7 taken 174 times.
248716 P(0xdd,0xdc) || P(0xf3,0xf2) || P(0xd7,0xd6) || P(0xdd,0x1c) ||
206
4/4
✓ Branch 0 taken 245210 times.
✓ Branch 1 taken 2166 times.
✓ Branch 2 taken 7123 times.
✓ Branch 3 taken 238087 times.
247376 P(0xd7,0x16) || P(0x0b,0x02))
207 35878 *dst00 = interp_2px(w4, 3, w0, 1, 2);
208 else
209 238087 *dst00 = interp_3px(w4, 2, w3, 1, w1, 1, 2);
210
211
8/8
✓ Branch 0 taken 393525 times.
✓ Branch 1 taken 2227 times.
✓ Branch 2 taken 386471 times.
✓ Branch 3 taken 7054 times.
✓ Branch 4 taken 385472 times.
✓ Branch 5 taken 999 times.
✓ Branch 6 taken 375829 times.
✓ Branch 7 taken 9643 times.
395752 if ((P(0xfe,0xde) || P(0x9e,0x16) || P(0xda,0x12) || P(0x17,0x16) ||
212
6/6
✓ Branch 0 taken 375528 times.
✓ Branch 1 taken 301 times.
✓ Branch 2 taken 131 times.
✓ Branch 3 taken 375397 times.
✓ Branch 7 taken 5856 times.
✓ Branch 8 taken 14499 times.
395752 P(0x5b,0x12) || P(0xbb,0x12)) && WDIFF(w1, w5))
213 5856 *dst01 = w4;
214
8/8
✓ Branch 0 taken 376373 times.
✓ Branch 1 taken 13523 times.
✓ Branch 2 taken 375374 times.
✓ Branch 3 taken 999 times.
✓ Branch 4 taken 373583 times.
✓ Branch 5 taken 1791 times.
✓ Branch 6 taken 370000 times.
✓ Branch 7 taken 3583 times.
389896 else if ((P(0x0f,0x0b) || P(0x5e,0x0a) || P(0xfb,0x7b) || P(0x3b,0x0b) ||
215
6/6
✓ Branch 0 taken 369869 times.
✓ Branch 1 taken 131 times.
✓ Branch 2 taken 301 times.
✓ Branch 3 taken 369568 times.
✓ Branch 7 taken 5877 times.
✓ Branch 8 taken 14451 times.
389896 P(0xbe,0x0a) || P(0x7a,0x0a)) && WDIFF(w3, w1))
216 5877 *dst01 = w4;
217
8/8
✓ Branch 0 taken 382610 times.
✓ Branch 1 taken 1409 times.
✓ Branch 2 taken 381477 times.
✓ Branch 3 taken 1133 times.
✓ Branch 4 taken 379779 times.
✓ Branch 5 taken 1698 times.
✓ Branch 6 taken 1254 times.
✓ Branch 7 taken 378525 times.
384019 else if (P(0xbf,0x8f) || P(0x7e,0x0e) || P(0xbf,0x37) || P(0xdb,0x13))
218 5494 *dst01 = interp_2px(w1, 3, w4, 1, 2);
219
8/8
✓ Branch 0 taken 93385 times.
✓ Branch 1 taken 285140 times.
✓ Branch 2 taken 91798 times.
✓ Branch 3 taken 1587 times.
✓ Branch 4 taken 90433 times.
✓ Branch 5 taken 1365 times.
✓ Branch 6 taken 89024 times.
✓ Branch 7 taken 1409 times.
378525 else if (P(0x02,0x00) || P(0x7c,0x28) || P(0xed,0xa9) || P(0xf5,0xb4) ||
220
2/2
✓ Branch 0 taken 1133 times.
✓ Branch 1 taken 87891 times.
89024 P(0xd9,0x90))
221 290634 *dst01 = interp_2px(w4, 3, w1, 1, 2);
222
8/8
✓ Branch 0 taken 83382 times.
✓ Branch 1 taken 4509 times.
✓ Branch 2 taken 82809 times.
✓ Branch 3 taken 573 times.
✓ Branch 4 taken 80792 times.
✓ Branch 5 taken 2017 times.
✓ Branch 6 taken 80461 times.
✓ Branch 7 taken 331 times.
87891 else if (P(0x4f,0x4b) || P(0xfb,0x7b) || P(0xfe,0x7e) || P(0x9f,0x1b) ||
223
8/8
✓ Branch 0 taken 77868 times.
✓ Branch 1 taken 2593 times.
✓ Branch 2 taken 77203 times.
✓ Branch 3 taken 665 times.
✓ Branch 4 taken 77115 times.
✓ Branch 5 taken 88 times.
✓ Branch 6 taken 76917 times.
✓ Branch 7 taken 198 times.
80461 P(0x2f,0x0b) || P(0xbe,0x0a) || P(0x7e,0x0a) || P(0xfb,0x4b) ||
224
8/8
✓ Branch 0 taken 76344 times.
✓ Branch 1 taken 573 times.
✓ Branch 2 taken 76095 times.
✓ Branch 3 taken 249 times.
✓ Branch 4 taken 75764 times.
✓ Branch 5 taken 331 times.
✓ Branch 6 taken 73622 times.
✓ Branch 7 taken 2142 times.
76917 P(0xfb,0xdb) || P(0xfe,0xde) || P(0xfe,0x56) || P(0x57,0x56) ||
225
8/8
✓ Branch 0 taken 70879 times.
✓ Branch 1 taken 2743 times.
✓ Branch 2 taken 70681 times.
✓ Branch 3 taken 198 times.
✓ Branch 4 taken 70037 times.
✓ Branch 5 taken 644 times.
✓ Branch 6 taken 108 times.
✓ Branch 7 taken 69929 times.
73622 P(0x97,0x16) || P(0x3f,0x1e) || P(0xdb,0x12) || P(0xbb,0x12))
226 17962 *dst01 = interp_2px(w4, 7, w1, 1, 3);
227 else
228 69929 *dst01 = w4;
229 395752 }
230
231 /* Assuming p0..p8 is mapped to pixels 0..8, this function interpolates the
232 * top-left block of 2x2 pixels in the total of the 4x4 pixels (or 4 blocks) to
233 * interpolates. The function is also used for the 3 other blocks of 2x2
234 * pixels. */
235 395752 static av_always_inline void hq4x_interp_2x2(uint32_t *dst, int dst_linesize,
236 const uint32_t *r2y, int k,
237 const uint32_t *w,
238 int pos00, int pos01,
239 int pos10, int pos11,
240 int p0, int p1, int p2,
241 int p3, int p4, int p5,
242 int p6, int p7, int p8)
243 {
244
16/16
✓ Branch 0 taken 197876 times.
✓ Branch 1 taken 197876 times.
✓ Branch 2 taken 197876 times.
✓ Branch 3 taken 197876 times.
✓ Branch 4 taken 197876 times.
✓ Branch 5 taken 197876 times.
✓ Branch 6 taken 197876 times.
✓ Branch 7 taken 197876 times.
✓ Branch 8 taken 197876 times.
✓ Branch 9 taken 197876 times.
✓ Branch 10 taken 197876 times.
✓ Branch 11 taken 197876 times.
✓ Branch 12 taken 197876 times.
✓ Branch 13 taken 197876 times.
✓ Branch 14 taken 197876 times.
✓ Branch 15 taken 197876 times.
395752 INTERP_BOOTSTRAP(0);
245
246 395752 uint32_t *dst00 = &dst[dst_linesize*(pos00>>1) + (pos00&1)];
247 395752 uint32_t *dst01 = &dst[dst_linesize*(pos01>>1) + (pos01&1)];
248 395752 uint32_t *dst10 = &dst[dst_linesize*(pos10>>1) + (pos10&1)];
249 395752 uint32_t *dst11 = &dst[dst_linesize*(pos11>>1) + (pos11&1)];
250
251
6/6
✓ Branch 0 taken 393760 times.
✓ Branch 1 taken 1992 times.
✓ Branch 2 taken 1580 times.
✓ Branch 3 taken 392180 times.
✓ Branch 7 taken 925 times.
✓ Branch 8 taken 2647 times.
395752 const int cond00 = (P(0xbf,0x37) || P(0xdb,0x13)) && WDIFF(w1, w5);
252
6/6
✓ Branch 0 taken 393452 times.
✓ Branch 1 taken 2300 times.
✓ Branch 2 taken 1743 times.
✓ Branch 3 taken 391709 times.
✓ Branch 7 taken 1196 times.
✓ Branch 8 taken 2847 times.
395752 const int cond01 = (P(0xdb,0x49) || P(0xef,0x6d)) && WDIFF(w7, w3);
253
4/4
✓ Branch 0 taken 393846 times.
✓ Branch 1 taken 1275 times.
✓ Branch 2 taken 393623 times.
✓ Branch 3 taken 223 times.
395121 const int cond02 = (P(0x6f,0x2a) || P(0x5b,0x0a) || P(0xbf,0x3a) ||
254
6/6
✓ Branch 0 taken 393239 times.
✓ Branch 1 taken 384 times.
✓ Branch 2 taken 392951 times.
✓ Branch 3 taken 288 times.
✓ Branch 4 taken 392903 times.
✓ Branch 5 taken 48 times.
393623 P(0xdf,0x5a) || P(0x9f,0x8a) || P(0xcf,0x8a) ||
255
5/6
✓ Branch 0 taken 392640 times.
✓ Branch 1 taken 263 times.
✓ Branch 2 taken 392452 times.
✓ Branch 3 taken 188 times.
✓ Branch 4 taken 392452 times.
✗ Branch 5 not taken.
392903 P(0xef,0x4e) || P(0x3f,0x0e) || P(0xfb,0x5a) ||
256
4/6
✓ Branch 0 taken 392452 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 392229 times.
✓ Branch 3 taken 223 times.
✓ Branch 4 taken 392229 times.
✗ Branch 5 not taken.
392452 P(0xbb,0x8a) || P(0x7f,0x5a) || P(0xaf,0x8a) ||
257
6/6
✓ Branch 0 taken 395121 times.
✓ Branch 1 taken 631 times.
✓ Branch 2 taken 289 times.
✓ Branch 3 taken 391940 times.
✓ Branch 7 taken 1364 times.
✓ Branch 8 taken 2448 times.
790873 P(0xeb,0x8a)) && WDIFF(w3, w1);
258
4/4
✓ Branch 0 taken 393452 times.
✓ Branch 1 taken 2300 times.
✓ Branch 2 taken 1743 times.
✓ Branch 3 taken 391709 times.
395752 const int cond03 = P(0xdb,0x49) || P(0xef,0x6d);
259
4/4
✓ Branch 0 taken 393760 times.
✓ Branch 1 taken 1992 times.
✓ Branch 2 taken 1580 times.
✓ Branch 3 taken 392180 times.
395752 const int cond04 = P(0xbf,0x37) || P(0xdb,0x13);
260
6/6
✓ Branch 0 taken 360693 times.
✓ Branch 1 taken 35059 times.
✓ Branch 2 taken 358639 times.
✓ Branch 3 taken 2054 times.
✓ Branch 4 taken 353450 times.
✓ Branch 5 taken 5189 times.
749202 const int cond05 = P(0x1b,0x03) || P(0x4f,0x43) || P(0x8b,0x83) ||
261
2/2
✓ Branch 0 taken 248 times.
✓ Branch 1 taken 353202 times.
353450 P(0x6b,0x43);
262
6/6
✓ Branch 0 taken 359768 times.
✓ Branch 1 taken 35984 times.
✓ Branch 2 taken 352044 times.
✓ Branch 3 taken 7724 times.
✓ Branch 4 taken 351707 times.
✓ Branch 5 taken 337 times.
747459 const int cond06 = P(0x4b,0x09) || P(0x8b,0x89) || P(0x1f,0x19) ||
263
2/2
✓ Branch 0 taken 278 times.
✓ Branch 1 taken 351429 times.
351707 P(0x3b,0x19);
264
4/4
✓ Branch 0 taken 381940 times.
✓ Branch 1 taken 435 times.
✓ Branch 2 taken 381703 times.
✓ Branch 3 taken 237 times.
382375 const int cond07 = P(0x0b,0x08) || P(0xf9,0x68) || P(0xf3,0x62) ||
265
6/6
✓ Branch 0 taken 375968 times.
✓ Branch 1 taken 5735 times.
✓ Branch 2 taken 373907 times.
✓ Branch 3 taken 2061 times.
✓ Branch 4 taken 371905 times.
✓ Branch 5 taken 2002 times.
381703 P(0x6d,0x6c) || P(0x67,0x66) || P(0x3d,0x3c) ||
266
6/6
✓ Branch 0 taken 370894 times.
✓ Branch 1 taken 1011 times.
✓ Branch 2 taken 370416 times.
✓ Branch 3 taken 478 times.
✓ Branch 4 taken 370022 times.
✓ Branch 5 taken 394 times.
371905 P(0x37,0x36) || P(0xf9,0xf8) || P(0xdd,0xdc) ||
267
6/6
✓ Branch 0 taken 369774 times.
✓ Branch 1 taken 248 times.
✓ Branch 2 taken 369310 times.
✓ Branch 3 taken 464 times.
✓ Branch 4 taken 369162 times.
✓ Branch 5 taken 148 times.
370022 P(0xf3,0xf2) || P(0xd7,0xd6) || P(0xdd,0x1c) ||
268
6/6
✓ Branch 0 taken 382375 times.
✓ Branch 1 taken 13377 times.
✓ Branch 2 taken 366996 times.
✓ Branch 3 taken 2166 times.
✓ Branch 4 taken 7122 times.
✓ Branch 5 taken 359874 times.
778127 P(0xd7,0x16) || P(0x0b,0x02);
269
4/4
✓ Branch 0 taken 375152 times.
✓ Branch 1 taken 7050 times.
✓ Branch 2 taken 375030 times.
✓ Branch 3 taken 122 times.
382202 const int cond08 = (P(0x0f,0x0b) || P(0x2b,0x0b) || P(0xfe,0x4a) ||
270
6/6
✓ Branch 0 taken 382202 times.
✓ Branch 1 taken 13550 times.
✓ Branch 2 taken 140 times.
✓ Branch 3 taken 374890 times.
✓ Branch 7 taken 5953 times.
✓ Branch 8 taken 14909 times.
777954 P(0xfe,0x1a)) && WDIFF(w3, w1);
271 395752 const int cond09 = P(0x2f,0x2f);
272 395752 const int cond10 = P(0x0a,0x00);
273 395752 const int cond11 = P(0x0b,0x09);
274
4/4
✓ Branch 0 taken 393452 times.
✓ Branch 1 taken 2300 times.
✓ Branch 2 taken 1743 times.
✓ Branch 3 taken 391709 times.
395752 const int cond12 = P(0x7e,0x2a) || P(0xef,0xab);
275
4/4
✓ Branch 0 taken 393760 times.
✓ Branch 1 taken 1992 times.
✓ Branch 2 taken 1580 times.
✓ Branch 3 taken 392180 times.
395752 const int cond13 = P(0xbf,0x8f) || P(0x7e,0x0e);
276
4/4
✓ Branch 0 taken 388876 times.
✓ Branch 1 taken 437 times.
✓ Branch 2 taken 385940 times.
✓ Branch 3 taken 2936 times.
389313 const int cond14 = P(0x4f,0x4b) || P(0x9f,0x1b) || P(0x2f,0x0b) ||
277
6/6
✓ Branch 0 taken 385236 times.
✓ Branch 1 taken 704 times.
✓ Branch 2 taken 385096 times.
✓ Branch 3 taken 140 times.
✓ Branch 4 taken 384991 times.
✓ Branch 5 taken 105 times.
385940 P(0xbe,0x0a) || P(0xee,0x0a) || P(0x7e,0x0a) ||
278
6/6
✓ Branch 0 taken 389313 times.
✓ Branch 1 taken 6439 times.
✓ Branch 2 taken 384265 times.
✓ Branch 3 taken 726 times.
✓ Branch 4 taken 3060 times.
✓ Branch 5 taken 381205 times.
785065 P(0xeb,0x4b) || P(0x3b,0x1b);
279 395752 const int cond15 = P(0x0b,0x03);
280
281
2/2
✓ Branch 0 taken 925 times.
✓ Branch 1 taken 394827 times.
395752 if (cond00)
282 925 *dst00 = interp_2px(w4, 5, w3, 3, 3);
283
2/2
✓ Branch 0 taken 1196 times.
✓ Branch 1 taken 393631 times.
394827 else if (cond01)
284 1196 *dst00 = interp_2px(w4, 5, w1, 3, 3);
285
8/8
✓ Branch 0 taken 356872 times.
✓ Branch 1 taken 36759 times.
✓ Branch 2 taken 356750 times.
✓ Branch 3 taken 122 times.
✓ Branch 4 taken 140 times.
✓ Branch 5 taken 356610 times.
✓ Branch 9 taken 15433 times.
✓ Branch 10 taken 21588 times.
393631 else if ((P(0x0b,0x0b) || P(0xfe,0x4a) || P(0xfe,0x1a)) && WDIFF(w3, w1))
286 15433 *dst00 = w4;
287
2/2
✓ Branch 0 taken 1364 times.
✓ Branch 1 taken 376834 times.
378198 else if (cond02)
288 1364 *dst00 = interp_2px(w4, 5, w0, 3, 3);
289
2/2
✓ Branch 0 taken 2847 times.
✓ Branch 1 taken 373987 times.
376834 else if (cond03)
290 2847 *dst00 = interp_2px(w4, 3, w3, 1, 2);
291
2/2
✓ Branch 0 taken 2647 times.
✓ Branch 1 taken 371340 times.
373987 else if (cond04)
292 2647 *dst00 = interp_2px(w4, 3, w1, 1, 2);
293
2/2
✓ Branch 0 taken 42550 times.
✓ Branch 1 taken 328790 times.
371340 else if (cond05)
294 42550 *dst00 = interp_2px(w4, 5, w3, 3, 3);
295
2/2
✓ Branch 0 taken 44323 times.
✓ Branch 1 taken 284467 times.
328790 else if (cond06)
296 44323 *dst00 = interp_2px(w4, 5, w1, 3, 3);
297
8/8
✓ Branch 0 taken 274377 times.
✓ Branch 1 taken 10090 times.
✓ Branch 2 taken 273520 times.
✓ Branch 3 taken 857 times.
✓ Branch 4 taken 268918 times.
✓ Branch 5 taken 4602 times.
✓ Branch 6 taken 268814 times.
✓ Branch 7 taken 104 times.
284467 else if (P(0x0f,0x0b) || P(0x5e,0x0a) || P(0x2b,0x0b) || P(0xbe,0x0a) ||
298
4/4
✓ Branch 0 taken 268584 times.
✓ Branch 1 taken 230 times.
✓ Branch 2 taken 113 times.
✓ Branch 3 taken 268471 times.
268814 P(0x7a,0x0a) || P(0xee,0x0a))
299 15996 *dst00 = interp_2px(w1, 1, w3, 1, 1);
300
2/2
✓ Branch 0 taken 35878 times.
✓ Branch 1 taken 232593 times.
268471 else if (cond07)
301 35878 *dst00 = interp_2px(w4, 5, w0, 3, 3);
302 else
303 232593 *dst00 = interp_3px(w4, 2, w1, 1, w3, 1, 2);
304
305
2/2
✓ Branch 0 taken 925 times.
✓ Branch 1 taken 394827 times.
395752 if (cond00)
306 925 *dst01 = interp_2px(w4, 7, w3, 1, 3);
307
2/2
✓ Branch 0 taken 5953 times.
✓ Branch 1 taken 388874 times.
394827 else if (cond08)
308 5953 *dst01 = w4;
309
2/2
✓ Branch 0 taken 1364 times.
✓ Branch 1 taken 387510 times.
388874 else if (cond02)
310 1364 *dst01 = interp_2px(w4, 3, w0, 1, 2);
311
2/2
✓ Branch 0 taken 16159 times.
✓ Branch 1 taken 371351 times.
387510 else if (cond09)
312 16159 *dst01 = w4;
313
2/2
✓ Branch 0 taken 224553 times.
✓ Branch 1 taken 146798 times.
371351 else if (cond10)
314 224553 *dst01 = interp_3px(w4, 5, w1, 2, w3, 1, 3);
315
2/2
✓ Branch 0 taken 13377 times.
✓ Branch 1 taken 133421 times.
146798 else if (P(0x0b,0x08))
316 13377 *dst01 = interp_3px(w4, 5, w1, 2, w0, 1, 3);
317
2/2
✓ Branch 0 taken 48366 times.
✓ Branch 1 taken 85055 times.
133421 else if (cond11)
318 48366 *dst01 = interp_2px(w4, 5, w1, 3, 3);
319
2/2
✓ Branch 0 taken 2647 times.
✓ Branch 1 taken 82408 times.
85055 else if (cond04)
320 2647 *dst01 = interp_2px(w1, 3, w4, 1, 2);
321
2/2
✓ Branch 0 taken 2847 times.
✓ Branch 1 taken 79561 times.
82408 else if (cond12)
322 2847 *dst01 = interp_3px(w1, 2, w4, 1, w3, 1, 2);
323
2/2
✓ Branch 0 taken 2647 times.
✓ Branch 1 taken 76914 times.
79561 else if (cond13)
324 2647 *dst01 = interp_2px(w1, 5, w3, 3, 3);
325
2/2
✓ Branch 0 taken 42550 times.
✓ Branch 1 taken 34364 times.
76914 else if (cond05)
326 42550 *dst01 = interp_2px(w4, 7, w3, 1, 3);
327
8/8
✓ Branch 0 taken 33692 times.
✓ Branch 1 taken 672 times.
✓ Branch 2 taken 25896 times.
✓ Branch 3 taken 7796 times.
✓ Branch 4 taken 22883 times.
✓ Branch 5 taken 3013 times.
✓ Branch 6 taken 22157 times.
✓ Branch 7 taken 726 times.
34364 else if (P(0xf3,0x62) || P(0x67,0x66) || P(0x37,0x36) || P(0xf3,0xf2) ||
328
6/6
✓ Branch 0 taken 21299 times.
✓ Branch 1 taken 858 times.
✓ Branch 2 taken 18985 times.
✓ Branch 3 taken 2314 times.
✓ Branch 4 taken 7122 times.
✓ Branch 5 taken 11863 times.
22157 P(0xd7,0xd6) || P(0xd7,0x16) || P(0x0b,0x02))
329 22501 *dst01 = interp_2px(w4, 3, w0, 1, 2);
330
2/2
✓ Branch 0 taken 10502 times.
✓ Branch 1 taken 1361 times.
11863 else if (cond14)
331 10502 *dst01 = interp_2px(w1, 1, w4, 1, 1);
332 else
333 1361 *dst01 = interp_2px(w4, 3, w1, 1, 2);
334
335
2/2
✓ Branch 0 taken 1196 times.
✓ Branch 1 taken 394556 times.
395752 if (cond01)
336 1196 *dst10 = interp_2px(w4, 7, w1, 1, 3);
337
2/2
✓ Branch 0 taken 5953 times.
✓ Branch 1 taken 388603 times.
394556 else if (cond08)
338 5953 *dst10 = w4;
339
2/2
✓ Branch 0 taken 1364 times.
✓ Branch 1 taken 387239 times.
388603 else if (cond02)
340 1364 *dst10 = interp_2px(w4, 3, w0, 1, 2);
341
2/2
✓ Branch 0 taken 16159 times.
✓ Branch 1 taken 371080 times.
387239 else if (cond09)
342 16159 *dst10 = w4;
343
2/2
✓ Branch 0 taken 224553 times.
✓ Branch 1 taken 146527 times.
371080 else if (cond10)
344 224553 *dst10 = interp_3px(w4, 5, w3, 2, w1, 1, 3);
345
2/2
✓ Branch 0 taken 13309 times.
✓ Branch 1 taken 133218 times.
146527 else if (P(0x0b,0x02))
346 13309 *dst10 = interp_3px(w4, 5, w3, 2, w0, 1, 3);
347
2/2
✓ Branch 0 taken 46122 times.
✓ Branch 1 taken 87096 times.
133218 else if (cond15)
348 46122 *dst10 = interp_2px(w4, 5, w3, 3, 3);
349
2/2
✓ Branch 0 taken 2847 times.
✓ Branch 1 taken 84249 times.
87096 else if (cond03)
350 2847 *dst10 = interp_2px(w3, 3, w4, 1, 2);
351
2/2
✓ Branch 0 taken 2647 times.
✓ Branch 1 taken 81602 times.
84249 else if (cond13)
352 2647 *dst10 = interp_3px(w3, 2, w4, 1, w1, 1, 2);
353
2/2
✓ Branch 0 taken 2847 times.
✓ Branch 1 taken 78755 times.
81602 else if (cond12)
354 2847 *dst10 = interp_2px(w3, 5, w1, 3, 3);
355
2/2
✓ Branch 0 taken 44323 times.
✓ Branch 1 taken 34432 times.
78755 else if (cond06)
356 44323 *dst10 = interp_2px(w4, 7, w1, 1, 3);
357
8/8
✓ Branch 0 taken 21055 times.
✓ Branch 1 taken 13377 times.
✓ Branch 2 taken 20620 times.
✓ Branch 3 taken 435 times.
✓ Branch 4 taken 14885 times.
✓ Branch 5 taken 5735 times.
✓ Branch 6 taken 12883 times.
✓ Branch 7 taken 2002 times.
34432 else if (P(0x0b,0x08) || P(0xf9,0x68) || P(0x6d,0x6c) || P(0x3d,0x3c) ||
358
6/6
✓ Branch 0 taken 12405 times.
✓ Branch 1 taken 478 times.
✓ Branch 2 taken 12011 times.
✓ Branch 3 taken 394 times.
✓ Branch 4 taken 148 times.
✓ Branch 5 taken 11863 times.
12883 P(0xf9,0xf8) || P(0xdd,0xdc) || P(0xdd,0x1c))
359 22569 *dst10 = interp_2px(w4, 3, w0, 1, 2);
360
2/2
✓ Branch 0 taken 10502 times.
✓ Branch 1 taken 1361 times.
11863 else if (cond14)
361 10502 *dst10 = interp_2px(w3, 1, w4, 1, 1);
362 else
363 1361 *dst10 = interp_2px(w4, 3, w3, 1, 2);
364
365
10/10
✓ Branch 0 taken 393757 times.
✓ Branch 1 taken 1995 times.
✓ Branch 2 taken 392014 times.
✓ Branch 3 taken 1743 times.
✓ Branch 4 taken 390022 times.
✓ Branch 5 taken 1992 times.
✓ Branch 6 taken 1272 times.
✓ Branch 7 taken 388750 times.
✓ Branch 8 taken 1951 times.
✓ Branch 9 taken 5051 times.
402754 if ((P(0x7f,0x2b) || P(0xef,0xab) || P(0xbf,0x8f) || P(0x7f,0x0f)) &&
366 7002 WDIFF(w3, w1))
367 1951 *dst11 = w4;
368
2/2
✓ Branch 0 taken 1364 times.
✓ Branch 1 taken 392437 times.
393801 else if (cond02)
369 1364 *dst11 = interp_2px(w4, 7, w0, 1, 3);
370
2/2
✓ Branch 0 taken 46122 times.
✓ Branch 1 taken 346315 times.
392437 else if (cond15)
371 46122 *dst11 = interp_2px(w4, 7, w3, 1, 3);
372
2/2
✓ Branch 0 taken 48366 times.
✓ Branch 1 taken 297949 times.
346315 else if (cond11)
373 48366 *dst11 = interp_2px(w4, 7, w1, 1, 3);
374
8/8
✓ Branch 0 taken 73396 times.
✓ Branch 1 taken 224553 times.
✓ Branch 2 taken 71865 times.
✓ Branch 3 taken 1531 times.
✓ Branch 4 taken 70549 times.
✓ Branch 5 taken 1316 times.
✓ Branch 6 taken 69080 times.
✓ Branch 7 taken 1469 times.
297949 else if (P(0x0a,0x00) || P(0x7e,0x2a) || P(0xef,0xab) || P(0xbf,0x8f) ||
375
2/2
✓ Branch 0 taken 1178 times.
✓ Branch 1 taken 67902 times.
69080 P(0x7e,0x0e))
376 230047 *dst11 = interp_3px(w4, 6, w3, 1, w1, 1, 3);
377
2/2
✓ Branch 0 taken 35878 times.
✓ Branch 1 taken 32024 times.
67902 else if (cond07)
378 35878 *dst11 = interp_2px(w4, 7, w0, 1, 3);
379 else
380 32024 *dst11 = w4;
381 395752 }
382
383 54 static av_always_inline void hqx_filter(const ThreadData *td, int jobnr, int nb_jobs, int n)
384 {
385 int x, y;
386 54 AVFrame *in = td->in, *out = td->out;
387 54 const uint32_t *r2y = td->rgbtoyuv;
388 54 const int height = in->height;
389 54 const int width = in->width;
390 54 const int slice_start = (height * jobnr ) / nb_jobs;
391 54 const int slice_end = (height * (jobnr+1)) / nb_jobs;
392 54 const int dst_linesize = out->linesize[0];
393 54 const int src_linesize = in->linesize[0];
394 54 uint8_t *dst = out->data[0] + slice_start * dst_linesize * n;
395 54 const uint8_t *src = in->data[0] + slice_start * src_linesize;
396
397 54 const int dst32_linesize = dst_linesize >> 2;
398 54 const int src32_linesize = src_linesize >> 2;
399
400
2/2
✓ Branch 0 taken 1554 times.
✓ Branch 1 taken 54 times.
1608 for (y = slice_start; y < slice_end; y++) {
401 1554 const uint32_t *src32 = (const uint32_t *)src;
402 1554 uint32_t *dst32 = (uint32_t *)dst;
403
2/2
✓ Branch 0 taken 1548 times.
✓ Branch 1 taken 6 times.
1554 const int prevline = y > 0 ? -src32_linesize : 0;
404
2/2
✓ Branch 0 taken 1548 times.
✓ Branch 1 taken 6 times.
1554 const int nextline = y < height - 1 ? src32_linesize : 0;
405
406
2/2
✓ Branch 0 taken 296814 times.
✓ Branch 1 taken 1554 times.
298368 for (x = 0; x < width; x++) {
407
2/2
✓ Branch 0 taken 295260 times.
✓ Branch 1 taken 1554 times.
296814 const int prevcol = x > 0 ? -1 : 0;
408 296814 const int nextcol = x < width -1 ? 1 : 0;
409 296814 const uint32_t w[3*3] = {
410 296814 src32[prevcol + prevline], src32[prevline], src32[prevline + nextcol],
411 296814 src32[prevcol ], src32[ 0], src32[ nextcol],
412 296814 src32[prevcol + nextline], src32[nextline], src32[nextline + nextcol]
413 };
414 296814 const uint32_t yuv1 = rgb2yuv(r2y, w[4]);
415
2/2
✓ Branch 0 taken 118860 times.
✓ Branch 1 taken 177954 times.
296814 const int pattern = (w[4] != w[0] ? (yuv_diff(yuv1, rgb2yuv(r2y, w[0]))) : 0)
416
2/2
✓ Branch 0 taken 91854 times.
✓ Branch 1 taken 204960 times.
296814 | (w[4] != w[1] ? (yuv_diff(yuv1, rgb2yuv(r2y, w[1]))) : 0) << 1
417
2/2
✓ Branch 0 taken 115710 times.
✓ Branch 1 taken 181104 times.
296814 | (w[4] != w[2] ? (yuv_diff(yuv1, rgb2yuv(r2y, w[2]))) : 0) << 2
418
2/2
✓ Branch 0 taken 93384 times.
✓ Branch 1 taken 203430 times.
296814 | (w[4] != w[3] ? (yuv_diff(yuv1, rgb2yuv(r2y, w[3]))) : 0) << 3
419
2/2
✓ Branch 0 taken 93384 times.
✓ Branch 1 taken 203430 times.
296814 | (w[4] != w[5] ? (yuv_diff(yuv1, rgb2yuv(r2y, w[5]))) : 0) << 4
420
2/2
✓ Branch 0 taken 115674 times.
✓ Branch 1 taken 181140 times.
296814 | (w[4] != w[6] ? (yuv_diff(yuv1, rgb2yuv(r2y, w[6]))) : 0) << 5
421
2/2
✓ Branch 0 taken 91854 times.
✓ Branch 1 taken 204960 times.
296814 | (w[4] != w[7] ? (yuv_diff(yuv1, rgb2yuv(r2y, w[7]))) : 0) << 6
422
2/2
✓ Branch 0 taken 118800 times.
✓ Branch 1 taken 178014 times.
296814 | (w[4] != w[8] ? (yuv_diff(yuv1, rgb2yuv(r2y, w[8]))) : 0) << 7;
423
424
2/2
✓ Branch 0 taken 98938 times.
✓ Branch 1 taken 197876 times.
296814 if (n == 2) {
425 98938 dst32[dst32_linesize*0 + 0] = hq2x_interp_1x1(r2y, pattern, w, 0,1,2,3,4,5,6,7,8); // 00
426 98938 dst32[dst32_linesize*0 + 1] = hq2x_interp_1x1(r2y, pattern, w, 2,1,0,5,4,3,8,7,6); // 01 (vert mirrored)
427 98938 dst32[dst32_linesize*1 + 0] = hq2x_interp_1x1(r2y, pattern, w, 6,7,8,3,4,5,0,1,2); // 10 (horiz mirrored)
428 98938 dst32[dst32_linesize*1 + 1] = hq2x_interp_1x1(r2y, pattern, w, 8,7,6,5,4,3,2,1,0); // 11 (center mirrored)
429
2/2
✓ Branch 0 taken 98938 times.
✓ Branch 1 taken 98938 times.
197876 } else if (n == 3) {
430 98938 hq3x_interp_2x1(dst32, dst32_linesize, r2y, pattern, w, 0,1, 0,1,2,3,4,5,6,7,8, 0); // 00 01
431 98938 hq3x_interp_2x1(dst32 + 1, dst32_linesize, r2y, pattern, w, 1,3, 2,5,8,1,4,7,0,3,6, 1); // 02 12 (rotated to the right)
432 98938 hq3x_interp_2x1(dst32 + 1*dst32_linesize, dst32_linesize, r2y, pattern, w, 2,0, 6,3,0,7,4,1,8,5,2, 1); // 20 10 (rotated to the left)
433 98938 hq3x_interp_2x1(dst32 + 1*dst32_linesize + 1, dst32_linesize, r2y, pattern, w, 3,2, 8,7,6,5,4,3,2,1,0, 0); // 22 21 (center mirrored)
434 98938 dst32[dst32_linesize + 1] = w[4]; // 11
435
1/2
✓ Branch 0 taken 98938 times.
✗ Branch 1 not taken.
98938 } else if (n == 4) {
436 98938 hq4x_interp_2x2(dst32, dst32_linesize, r2y, pattern, w, 0,1,2,3, 0,1,2,3,4,5,6,7,8); // 00 01 10 11
437 98938 hq4x_interp_2x2(dst32 + 2, dst32_linesize, r2y, pattern, w, 1,0,3,2, 2,1,0,5,4,3,8,7,6); // 02 03 12 13 (vert mirrored)
438 98938 hq4x_interp_2x2(dst32 + 2*dst32_linesize, dst32_linesize, r2y, pattern, w, 2,3,0,1, 6,7,8,3,4,5,0,1,2); // 20 21 30 31 (horiz mirrored)
439 98938 hq4x_interp_2x2(dst32 + 2*dst32_linesize + 2, dst32_linesize, r2y, pattern, w, 3,2,1,0, 8,7,6,5,4,3,2,1,0); // 22 23 32 33 (center mirrored)
440 } else {
441 av_assert0(0);
442 }
443
444 296814 src32 += 1;
445 296814 dst32 += n;
446 }
447
448 1554 src += src_linesize;
449 1554 dst += dst_linesize * n;
450 }
451 54 }
452
453 #define HQX_FUNC(size) \
454 static int hq##size##x(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs) \
455 { \
456 hqx_filter(arg, jobnr, nb_jobs, size); \
457 return 0; \
458 }
459
460 18 HQX_FUNC(2)
461 18 HQX_FUNC(3)
462 18 HQX_FUNC(4)
463
464 6 static int config_output(AVFilterLink *outlink)
465 {
466 6 AVFilterContext *ctx = outlink->src;
467 6 HQXContext *hqx = ctx->priv;
468 6 AVFilterLink *inlink = ctx->inputs[0];
469
470 6 outlink->w = inlink->w * hqx->n;
471 6 outlink->h = inlink->h * hqx->n;
472 6 av_log(inlink->dst, AV_LOG_VERBOSE, "fmt:%s size:%dx%d -> size:%dx%d\n",
473 6 av_get_pix_fmt_name(inlink->format),
474 inlink->w, inlink->h, outlink->w, outlink->h);
475 6 return 0;
476 }
477
478 6 static int filter_frame(AVFilterLink *inlink, AVFrame *in)
479 {
480 6 AVFilterContext *ctx = inlink->dst;
481 6 AVFilterLink *outlink = ctx->outputs[0];
482 6 HQXContext *hqx = ctx->priv;
483 ThreadData td;
484 6 AVFrame *out = ff_get_video_buffer(outlink, outlink->w, outlink->h);
485
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6 times.
6 if (!out) {
486 av_frame_free(&in);
487 return AVERROR(ENOMEM);
488 }
489 6 av_frame_copy_props(out, in);
490 6 out->width = outlink->w;
491 6 out->height = outlink->h;
492
493 6 td.in = in;
494 6 td.out = out;
495 6 td.rgbtoyuv = hqx->rgbtoyuv;
496 6 ff_filter_execute(ctx, hqx->func, &td, NULL,
497
1/2
✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
6 FFMIN(inlink->h, ff_filter_get_nb_threads(ctx)));
498
499 6 av_frame_free(&in);
500 6 return ff_filter_frame(outlink, out);
501 }
502
503 6 static av_cold int init(AVFilterContext *ctx)
504 {
505 6 HQXContext *hqx = ctx->priv;
506 static const hqxfunc_t hqxfuncs[] = {hq2x, hq3x, hq4x};
507
508 uint32_t c;
509 int bg, rg, g;
510
511
2/2
✓ Branch 0 taken 3066 times.
✓ Branch 1 taken 6 times.
3072 for (bg=-255; bg<256; bg++) {
512
2/2
✓ Branch 0 taken 1566726 times.
✓ Branch 1 taken 3066 times.
1569792 for (rg=-255; rg<256; rg++) {
513 1566726 const uint32_t u = (uint32_t)((-169*rg + 500*bg)/1000) + 128;
514 1566726 const uint32_t v = (uint32_t)(( 500*rg - 81*bg)/1000) + 128;
515
6/6
✓ Branch 0 taken 781830 times.
✓ Branch 1 taken 784896 times.
✓ Branch 2 taken 1173510 times.
✓ Branch 3 taken 393216 times.
✓ Branch 4 taken 585990 times.
✓ Branch 5 taken 587520 times.
1566726 int startg = FFMAX3(-bg, -rg, 0);
516
6/6
✓ Branch 0 taken 781830 times.
✓ Branch 1 taken 784896 times.
✓ Branch 2 taken 390150 times.
✓ Branch 3 taken 1176576 times.
✓ Branch 4 taken 587520 times.
✓ Branch 5 taken 589056 times.
1566726 int endg = FFMIN3(255-bg, 255-rg, 255);
517 1566726 uint32_t y = (uint32_t)(( 299*rg + 1000*startg + 114*bg)/1000);
518 1566726 c = bg + rg * (1 << 16) + 0x010101 * startg;
519
2/2
✓ Branch 0 taken 100663296 times.
✓ Branch 1 taken 1566726 times.
102230022 for (g = startg; g <= endg; g++) {
520 100663296 hqx->rgbtoyuv[c] = ((y++) << 16) + (u << 8) + v;
521 100663296 c+= 0x010101;
522 }
523 }
524 }
525
526 6 hqx->func = hqxfuncs[hqx->n - 2];
527 6 return 0;
528 }
529
530 static const AVFilterPad hqx_inputs[] = {
531 {
532 .name = "default",
533 .type = AVMEDIA_TYPE_VIDEO,
534 .filter_frame = filter_frame,
535 },
536 };
537
538 static const AVFilterPad hqx_outputs[] = {
539 {
540 .name = "default",
541 .type = AVMEDIA_TYPE_VIDEO,
542 .config_props = config_output,
543 },
544 };
545
546 const AVFilter ff_vf_hqx = {
547 .name = "hqx",
548 .description = NULL_IF_CONFIG_SMALL("Scale the input by 2, 3 or 4 using the hq*x magnification algorithm."),
549 .priv_size = sizeof(HQXContext),
550 .init = init,
551 FILTER_INPUTS(hqx_inputs),
552 FILTER_OUTPUTS(hqx_outputs),
553 FILTER_SINGLE_PIXFMT(AV_PIX_FMT_RGB32),
554 .priv_class = &hqx_class,
555 .flags = AVFILTER_FLAG_SLICE_THREADS,
556 };
557