FFmpeg coverage


Directory: ../../../ffmpeg/
File: src/libavutil/tests/csp.c
Date: 2026-08-30 18:45:47
Exec Total Coverage
Lines: 62 62 100.0%
Functions: 4 4 100.0%
Branches: 35 52 67.3%

Line Branch Exec Source
1 /*
2 * This file is part of FFmpeg.
3 *
4 * FFmpeg is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
8 *
9 * FFmpeg is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
13 *
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with FFmpeg; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
17 */
18
19 #include <stdio.h>
20
21 #include "libavutil/csp.h"
22 #include "libavutil/pixdesc.h"
23 #include "libavutil/pixfmt.h"
24
25 48 static void print_cie(const char *label, AVCIExy xy)
26 {
27 48 printf(" %s=(%d/%d, %d/%d)\n", label,
28 xy.x.num, xy.x.den, xy.y.num, xy.y.den);
29 48 }
30
31 44 static int cie_eq(AVCIExy a, AVCIExy b)
32 {
33
2/4
✓ Branch 1 taken 44 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 44 times.
✗ Branch 5 not taken.
44 return av_cmp_q(a.x, b.x) == 0 && av_cmp_q(a.y, b.y) == 0;
34 }
35
36 11 static int desc_eq(const AVColorPrimariesDesc *a, const AVColorPrimariesDesc *b)
37 {
38
1/2
✓ Branch 1 taken 11 times.
✗ Branch 2 not taken.
22 return cie_eq(a->wp, b->wp) &&
39
1/2
✓ Branch 1 taken 11 times.
✗ Branch 2 not taken.
22 cie_eq(a->prim.r, b->prim.r) &&
40
2/4
✓ Branch 0 taken 11 times.
✗ Branch 1 not taken.
✓ Branch 3 taken 11 times.
✗ Branch 4 not taken.
33 cie_eq(a->prim.g, b->prim.g) &&
41 11 cie_eq(a->prim.b, b->prim.b);
42 }
43
44 1 int main(void)
45 {
46 /* av_csp_luma_coeffs_from_avcsp: iterate every defined colorspace */
47 1 printf("Testing av_csp_luma_coeffs_from_avcsp()\n");
48
2/2
✓ Branch 0 taken 18 times.
✓ Branch 1 taken 1 times.
19 for (enum AVColorSpace csp = 0; csp < AVCOL_SPC_NB; csp++) {
49 18 const AVLumaCoefficients *c = av_csp_luma_coeffs_from_avcsp(csp);
50 18 const char *name = av_color_space_name(csp);
51
2/2
✓ Branch 0 taken 9 times.
✓ Branch 1 taken 9 times.
18 if (!c) {
52
1/2
✓ Branch 0 taken 9 times.
✗ Branch 1 not taken.
9 printf("csp=%-16s -> NULL\n", name ? name : "?");
53 9 continue;
54 }
55 9 printf("csp=%-16s -> cr=%d/%d cg=%d/%d cb=%d/%d\n",
56 name ? name : "?",
57 9 c->cr.num, c->cr.den,
58 9 c->cg.num, c->cg.den,
59
1/2
✓ Branch 0 taken 9 times.
✗ Branch 1 not taken.
9 c->cb.num, c->cb.den);
60 }
61 /* out-of-range enum */
62
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 printf("csp=AVCOL_SPC_NB -> %s\n",
63 1 av_csp_luma_coeffs_from_avcsp(AVCOL_SPC_NB) ? "FAIL" : "NULL");
64
65 /* av_csp_primaries_desc_from_id + av_csp_primaries_id_from_desc */
66 1 printf("\nTesting av_csp_primaries_desc_from_id() round trip\n");
67
2/2
✓ Branch 0 taken 24 times.
✓ Branch 1 taken 1 times.
25 for (enum AVColorPrimaries prm = 0; prm < AVCOL_PRI_EXT_NB; prm++) {
68 const AVColorPrimariesDesc *d;
69 const AVColorPrimariesDesc *d_back;
70 enum AVColorPrimaries back;
71 const char *name, *back_name, *status;
72
73
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 23 times.
24 if (prm == AVCOL_PRI_NB)
74 1 prm = AVCOL_PRI_EXT_BASE;
75
76 24 d = av_csp_primaries_desc_from_id(prm);
77 24 name = av_color_primaries_name(prm);
78
2/2
✓ Branch 0 taken 12 times.
✓ Branch 1 taken 12 times.
24 if (!d) {
79
2/2
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 9 times.
12 printf("prm=%-16s -> NULL\n", name ? name : "?");
80 12 continue;
81 }
82
1/2
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
12 printf("prm=%-16s ->\n", name ? name : "?");
83 12 print_cie("wp ", d->wp);
84 12 print_cie("r ", d->prim.r);
85 12 print_cie("g ", d->prim.g);
86 12 print_cie("b ", d->prim.b);
87
88 /* For colorspaces with identical primaries (e.g. smpte170m and
89 * smpte240m), the canonical first match may differ from the input
90 * enum, so compare descs not enums. id_from_desc only searches
91 * the base AVCOL_PRI_* range and returns UNSPECIFIED for
92 * extended-range inputs that have no base match. */
93 12 back = av_csp_primaries_id_from_desc(d);
94 12 d_back = av_csp_primaries_desc_from_id(back);
95 12 back_name = av_color_primaries_name(back);
96
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 11 times.
12 if (back == AVCOL_PRI_UNSPECIFIED)
97 1 status = prm >= AVCOL_PRI_EXT_BASE ? "ext-no-base-match"
98
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 : "MISMATCH";
99 else
100
2/4
✓ Branch 0 taken 11 times.
✗ Branch 1 not taken.
✓ Branch 3 taken 11 times.
✗ Branch 4 not taken.
11 status = d_back && desc_eq(d, d_back) ? "OK" : "MISMATCH";
101
1/2
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
12 printf(" round-trip id=%-16s desc=%s\n",
102 back_name ? back_name : "?", status);
103 }
104 /* out-of-range enum */
105
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 printf("prm=AVCOL_PRI_NB -> %s\n",
106 1 av_csp_primaries_desc_from_id(AVCOL_PRI_NB) ? "FAIL" : "NULL");
107
108 /* id_from_desc on a garbage description returns UNSPECIFIED */
109 {
110 1 AVColorPrimariesDesc garbage = {
111 .wp = { { 0, 1 }, { 0, 1 } },
112 .prim = {
113 .r = { { 0, 1 }, { 0, 1 } },
114 .g = { { 0, 1 }, { 0, 1 } },
115 .b = { { 0, 1 }, { 0, 1 } },
116 },
117 };
118 1 enum AVColorPrimaries back = av_csp_primaries_id_from_desc(&garbage);
119
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
2 printf("garbage desc -> %s (expect AVCOL_PRI_UNSPECIFIED)\n",
120 2 av_color_primaries_name(back) ? av_color_primaries_name(back) : "?");
121 }
122
123 /* av_csp_approximate_trc_gamma + av_csp_approximate_eotf_gamma:
124 * both return values from static tables, so output is bitexact. */
125 1 printf("\nTesting av_csp_approximate_{trc,eotf}_gamma()\n");
126
2/2
✓ Branch 0 taken 20 times.
✓ Branch 1 taken 1 times.
21 for (enum AVColorTransferCharacteristic trc = 0; trc < AVCOL_TRC_EXT_NB; trc++) {
127 const char *name;
128 double g_trc, g_eotf;
129
130
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 19 times.
20 if (trc == AVCOL_TRC_NB)
131 1 trc = AVCOL_TRC_EXT_BASE;
132
133 20 name = av_color_transfer_name(trc);
134 20 g_trc = av_csp_approximate_trc_gamma(trc);
135 20 g_eotf = av_csp_approximate_eotf_gamma(trc);
136
1/2
✓ Branch 0 taken 20 times.
✗ Branch 1 not taken.
20 printf("trc=%-16s trc_gamma=%.6f eotf_gamma=%.6f\n",
137 name ? name : "?", g_trc, g_eotf);
138 }
139 /* out-of-range enum: both must return 0.0 */
140 1 printf("trc=AVCOL_TRC_NB trc_gamma=%.6f eotf_gamma=%.6f\n",
141 av_csp_approximate_trc_gamma(AVCOL_TRC_NB),
142 av_csp_approximate_eotf_gamma(AVCOL_TRC_NB));
143
144 1 return 0;
145 }
146