FFmpeg coverage


Directory: ../../../ffmpeg/
File: src/libavutil/gain_map.c
Date: 2026-10-01 14:18:39
Exec Total Coverage
Lines: 28 38 73.7%
Functions: 4 5 80.0%
Branches: 25 50 50.0%

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 "gain_map.h"
20 #include "mem.h"
21
22 5 static void gain_map_params_default(AVGainMapParams *p)
23 {
24 5 *p = (AVGainMapParams) {
25 .base_hdr_headroom = { 0, 1 },
26 .alternate_hdr_headroom = { 0, 1 },
27 .nb_channels = 1,
28 };
29
30 /* Pre-fill all three channels as a convenience */
31
2/2
✓ Branch 0 taken 15 times.
✓ Branch 1 taken 5 times.
20 for (int c = 0; c < 3; c++) {
32 15 p->channels[c] = (struct AVGainMapChannel) {
33 .gain_map_min = { 0, 1 },
34 .gain_map_max = { 0, 1 },
35 .gamma = { 1, 1 },
36 .base_offset = { 1, 64 },
37 .alternate_offset = { 1, 64 },
38 };
39 }
40 5 }
41
42 #define CHECK(cond) do { if (!(cond)) return AVERROR_INVALIDDATA; } while (0)
43 #define CHECK_SIGNED(q) CHECK((q).den > 0);
44 #define CHECK_UNSIGNED(q) CHECK((q).num >= 0 && (q).den > 0);
45
46 10 int av_gain_map_params_validate(const AVGainMapParams *p)
47 {
48
2/4
✓ Branch 0 taken 10 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 10 times.
10 CHECK(0 <= p->version && p->version <= AV_ISO21496_VERSION);
49
3/4
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 2 times.
10 CHECK(p->nb_channels == 1 || p->nb_channels == 3);
50
2/4
✓ Branch 0 taken 10 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 10 times.
10 CHECK_UNSIGNED(p->base_hdr_headroom);
51
2/4
✓ Branch 0 taken 10 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 10 times.
10 CHECK_UNSIGNED(p->alternate_hdr_headroom);
52
53
2/2
✓ Branch 0 taken 14 times.
✓ Branch 1 taken 10 times.
24 for (int c = 0; c < p->nb_channels; c++) {
54 14 const struct AVGainMapChannel *const ch = &p->channels[c];
55
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 14 times.
14 CHECK_SIGNED(ch->gain_map_min);
56
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 14 times.
14 CHECK_SIGNED(ch->gain_map_max);
57
2/4
✓ Branch 0 taken 14 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 14 times.
14 CHECK_UNSIGNED(ch->gamma);
58
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 14 times.
14 CHECK(ch->gamma.num != 0);
59 /**
60 * Note: The ISO spec declares these as signed, but a negative value
61 * makes no numeric sense and would result in infinities in the
62 * middle of the valid signal range; so just constrain them to be
63 * unsigned as a safeguard. Note that the Adobe hdrgm spec explicitly
64 * requires them to be nonnegative as well, so this avoids an
65 * inconsistency.
66 */
67
2/4
✓ Branch 0 taken 14 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 14 times.
14 CHECK_UNSIGNED(ch->base_offset);
68
2/4
✓ Branch 0 taken 14 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 14 times.
14 CHECK_UNSIGNED(ch->alternate_offset);
69
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 14 times.
14 CHECK(av_cmp_q(ch->gain_map_min, ch->gain_map_max) <= 0);
70 }
71
72 10 return 0;
73 }
74
75 1 int av_gain_map_channels_identical(const AVGainMapParams *p)
76 {
77 static_assert(sizeof(p->channels[0]) == sizeof(int[2]) * 5,
78 "AVGainMapChannel struct is tightly packed");
79
80
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 return !memcmp(&p->channels[0], &p->channels[1], sizeof(p->channels[0])) &&
81 ✗ !memcmp(&p->channels[0], &p->channels[2], sizeof(p->channels[0]));
82 }
83
84 ✗ AVGainMapParams *av_gain_map_params_alloc(size_t *size)
85 {
86 ✗ AVGainMapParams *p = av_malloc(sizeof(AVGainMapParams));
87 ✗ if (!p)
88 ✗ return NULL;
89
90 ✗ gain_map_params_default(p);
91
92 ✗ if (size)
93 ✗ *size = sizeof(*p);
94
95 ✗ return p;
96 }
97
98 5 AVGainMapParams *av_gain_map_params_create_side_data(AVFrameSideData ***fsd, int *nb_sd)
99 {
100 AVFrameSideData *sd;
101 5 sd = av_frame_side_data_new(fsd, nb_sd, AV_FRAME_DATA_GAIN_MAP_PARAMS,
102 sizeof(AVGainMapParams),
103 AV_FRAME_SIDE_DATA_FLAG_REPLACE);
104
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 5 times.
5 if (!sd)
105 ✗ return NULL;
106
107 5 AVGainMapParams *const p = (AVGainMapParams *) sd->data;
108 5 gain_map_params_default(p);
109 5 return p;
110 }
111