Coverage Report

Created: 2024-09-06 07:53

/src/ffmpeg/libavcodec/dynamic_hdr_vivid.c
Line
Count
Source (jump to first uncovered line)
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 "dynamic_hdr_vivid.h"
20
#include "get_bits.h"
21
22
static const int32_t maxrgb_den = 4095;
23
static const int32_t color_saturation_gain_den = 128;
24
static const int32_t maximum_luminance_den = 4095;
25
static const int32_t base_param_m_p_den = 16383;
26
static const int32_t base_param_m_m_den = 10;
27
static const int32_t base_param_m_a_den = 1023;
28
static const int32_t base_param_m_b_den = 1023;
29
static const int32_t base_param_m_n_den = 10;
30
static const int32_t base_param_Delta_den = 127;
31
32
int ff_parse_itu_t_t35_to_dynamic_hdr_vivid(AVDynamicHDRVivid *s, const uint8_t *data,
33
                                             int size)
34
5.52k
{
35
5.52k
    GetBitContext gbc, *gb = &gbc;
36
5.52k
    int ret;
37
38
5.52k
    if (!s)
39
0
        return AVERROR(ENOMEM);
40
41
5.52k
    ret = init_get_bits8(gb, data, size);
42
5.52k
    if (ret < 0)
43
0
        return ret;
44
45
5.52k
    if (get_bits_left(gb) < 8)
46
3
        return AVERROR_INVALIDDATA;
47
48
5.52k
    s->system_start_code = get_bits(gb, 8);
49
    // T/UWA 005.1-2022, table 11
50
5.52k
    if (s->system_start_code >= 0x01 && s->system_start_code <= 0x07) {
51
4.84k
        s->num_windows = 1;
52
53
4.84k
        if (get_bits_left(gb) < 12 * 4 * s->num_windows)
54
6
            return AVERROR_INVALIDDATA;
55
9.66k
        for (int w = 0; w < s->num_windows; w++) {
56
4.83k
            AVHDRVividColorTransformParams *params = &s->params[w];
57
58
4.83k
            params->minimum_maxrgb  = (AVRational){get_bits(gb, 12), maxrgb_den};
59
4.83k
            params->average_maxrgb  = (AVRational){get_bits(gb, 12), maxrgb_den};
60
4.83k
            params->variance_maxrgb = (AVRational){get_bits(gb, 12), maxrgb_den};
61
4.83k
            params->maximum_maxrgb  = (AVRational){get_bits(gb, 12), maxrgb_den};
62
4.83k
        }
63
64
4.83k
        if (get_bits_left(gb) < 2 * s->num_windows)
65
45
            return AVERROR_INVALIDDATA;
66
6.63k
        for (int w = 0; w < s->num_windows; w++) {
67
4.78k
            AVHDRVividColorTransformParams *params = &s->params[w];
68
69
4.78k
            params->tone_mapping_mode_flag = get_bits(gb, 1);
70
4.78k
            if (params->tone_mapping_mode_flag) {
71
4.08k
                if (get_bits_left(gb) < 1 )
72
0
                    return AVERROR_INVALIDDATA;
73
4.08k
                params->tone_mapping_param_num = get_bits(gb, 1) + 1;
74
10.1k
                for (int i = 0; i < params->tone_mapping_param_num; i++) {
75
7.25k
                    AVHDRVividColorToneMappingParams *tm_params = &params->tm_params[i];
76
77
7.25k
                    if (get_bits_left(gb) < 13)
78
61
                        return AVERROR_INVALIDDATA;
79
7.19k
                    tm_params->targeted_system_display_maximum_luminance = (AVRational){get_bits(gb, 12), maximum_luminance_den};
80
7.19k
                    tm_params->base_enable_flag = get_bits(gb, 1);
81
7.19k
                    if (tm_params->base_enable_flag) {
82
2.91k
                        if (get_bits_left(gb) < (14 + 6 + 10 + 10 + 6 + 8 + 10))
83
698
                            return AVERROR_INVALIDDATA;
84
2.21k
                        tm_params->base_param_m_p = (AVRational){get_bits(gb, 14), base_param_m_p_den};
85
2.21k
                        tm_params->base_param_m_m = (AVRational){get_bits(gb,  6), base_param_m_m_den};
86
2.21k
                        tm_params->base_param_m_a = (AVRational){get_bits(gb, 10), base_param_m_a_den};
87
2.21k
                        tm_params->base_param_m_b = (AVRational){get_bits(gb, 10), base_param_m_b_den};
88
2.21k
                        tm_params->base_param_m_n = (AVRational){get_bits(gb,  6), base_param_m_n_den};
89
2.21k
                        tm_params->base_param_k1 = get_bits(gb, 2);
90
2.21k
                        tm_params->base_param_k2 = get_bits(gb, 2);
91
2.21k
                        tm_params->base_param_k3 = get_bits(gb, 4);
92
2.21k
                        tm_params->base_param_Delta_enable_mode = get_bits(gb, 3);
93
2.21k
                        tm_params->base_param_Delta = (AVRational){get_bits(gb, 7), base_param_Delta_den};
94
2.21k
                    }
95
6.49k
                    if (get_bits_left(gb) < 1)
96
310
                        return AVERROR_INVALIDDATA;
97
6.18k
                    tm_params->three_Spline_enable_flag = get_bits(gb, 1);
98
6.18k
                    if (tm_params->three_Spline_enable_flag) {
99
4.97k
                        AVHDRVivid3SplineParams *three_spline;
100
101
4.97k
                        if (get_bits_left(gb) < 1 + tm_params->three_Spline_num * (2 + 12 + 28 + 1))
102
7
                            return AVERROR_INVALIDDATA;
103
4.97k
                        tm_params->three_Spline_num = get_bits(gb, 1) + 1;
104
4.97k
                        if (tm_params->three_Spline_num > FF_ARRAY_ELEMS(tm_params->three_spline))
105
0
                            return AVERROR_INVALIDDATA;
106
13.5k
                        for (int j = 0; j < tm_params->three_Spline_num; j++) {
107
8.69k
                            three_spline = &tm_params->three_spline[j];
108
8.69k
                            three_spline->th_mode = get_bits(gb, 2);
109
8.69k
                            if (three_spline->th_mode == 0 || three_spline->th_mode == 2) {
110
2.88k
                                if (get_bits_left(gb) < 8)
111
79
                                    return AVERROR_INVALIDDATA;
112
2.80k
                                three_spline->th_enable_mb = (AVRational){get_bits(gb, 8),  255};
113
2.80k
                            }
114
8.61k
                            three_spline->th_enable = (AVRational){get_bits(gb, 12),  4095};
115
8.61k
                            three_spline->th_delta1 = (AVRational){get_bits(gb, 10),  1023};
116
8.61k
                            three_spline->th_delta2 = (AVRational){get_bits(gb, 10),  1023};
117
8.61k
                            three_spline->enable_strength = (AVRational){get_bits(gb,  8),  255};
118
8.61k
                        }
119
4.89k
#if FF_API_HDR_VIVID_THREE_SPLINE
120
4.89k
                        three_spline = &tm_params->three_spline[0];
121
4.89k
FF_DISABLE_DEPRECATION_WARNINGS
122
4.89k
                        tm_params->three_Spline_TH_mode = three_spline->th_mode;
123
4.89k
                        tm_params->three_Spline_TH_enable_MB = three_spline->th_enable_mb;
124
4.89k
                        tm_params->three_Spline_TH_enable = three_spline->th_enable;
125
4.89k
                        tm_params->three_Spline_TH_Delta1 = three_spline->th_delta1;
126
4.89k
                        tm_params->three_Spline_TH_Delta2 = three_spline->th_delta2;
127
4.89k
                        tm_params->three_Spline_enable_Strength = three_spline->enable_strength;
128
4.89k
FF_ENABLE_DEPRECATION_WARNINGS
129
4.89k
#endif
130
4.89k
                    }
131
6.18k
                }
132
4.08k
            }
133
134
3.63k
            params->color_saturation_mapping_flag = get_bits(gb, 1);
135
3.63k
            if (params->color_saturation_mapping_flag) {
136
3.39k
                if (get_bits_left(gb) < 3 + params->color_saturation_num * 8)
137
1.79k
                    return AVERROR_INVALIDDATA;
138
139
1.59k
                params->color_saturation_num = get_bits(gb, 3);
140
8.45k
                for (int i = 0; i < params->color_saturation_num; i++) {
141
6.85k
                    params->color_saturation_gain[i] = (AVRational){get_bits(gb, 8), color_saturation_gain_den};
142
6.85k
                }
143
1.59k
            }
144
3.63k
        }
145
4.78k
    }
146
147
2.52k
    return 0;
148
5.52k
}