43 *
size =
sizeof(*hdr_plus);
88 if (
s->num_windows < 1 ||
s->num_windows > 3) {
95 for (
int w = 1;
w <
s->num_windows;
w++) {
120 s->targeted_system_display_maximum_luminance =
122 s->targeted_system_display_actual_peak_luminance_flag =
get_bits1(gb);
124 if (
s->targeted_system_display_actual_peak_luminance_flag) {
130 if (((rows < 2) || (rows > 25)) || ((cols < 2) || (cols > 25))) {
133 s->num_rows_targeted_system_display_actual_peak_luminance = rows;
134 s->num_cols_targeted_system_display_actual_peak_luminance = cols;
139 for (
int i = 0;
i < rows;
i++) {
140 for (
int j = 0; j < cols; j++) {
141 s->targeted_system_display_actual_peak_luminance[
i][j] =
146 for (
int w = 0;
w <
s->num_windows;
w++) {
151 for (
int i = 0;
i < 3;
i++) {
176 s->mastering_display_actual_peak_luminance_flag =
get_bits1(gb);
177 if (
s->mastering_display_actual_peak_luminance_flag) {
183 if (((rows < 2) || (rows > 25)) || ((cols < 2) || (cols > 25))) {
186 s->num_rows_mastering_display_actual_peak_luminance = rows;
187 s->num_cols_mastering_display_actual_peak_luminance = cols;
192 for (
int i = 0;
i < rows;
i++) {
193 for (
int j = 0; j < cols; j++) {
194 s->mastering_display_actual_peak_luminance[
i][j] =
200 for (
int w = 0;
w <
s->num_windows;
w++) {
242 size_t size_bits, size_bytes;
268 for (
int w = 1;
w <
s->num_windows;
w++)
274 if (
s->targeted_system_display_actual_peak_luminance_flag)
276 s->num_rows_targeted_system_display_actual_peak_luminance *
277 s->num_cols_targeted_system_display_actual_peak_luminance * 4;
279 for (
int w = 0;
w <
s->num_windows;
w++)
280 size_bits += 72 +
s->params[
w].num_distribution_maxrgb_percentiles * 24 + 10;
283 if (
s->mastering_display_actual_peak_luminance_flag)
285 s->num_rows_mastering_display_actual_peak_luminance *
286 s->num_cols_mastering_display_actual_peak_luminance * 4;
288 for (
int w = 0;
w <
s->num_windows;
w++) {
290 if (
s->params[
w].tone_mapping_flag)
291 size_bits += 28 +
s->params[
w].num_bezier_curve_anchors * 10;
294 if (
s->params[
w].color_saturation_mapping_flag)
298 size_bytes = (size_bits + 7) / 8;
306 if (*
size < size_bytes)
323 for (
int w = 1;
w <
s->num_windows;
w++) {
324 put_bits(pb, 16,
s->params[
w].window_upper_left_corner_x.num /
s->params[
w].window_upper_left_corner_x.den);
325 put_bits(pb, 16,
s->params[
w].window_upper_left_corner_y.num /
s->params[
w].window_upper_left_corner_y.den);
326 put_bits(pb, 16,
s->params[
w].window_lower_right_corner_x.num /
s->params[
w].window_lower_right_corner_x.den);
327 put_bits(pb, 16,
s->params[
w].window_lower_right_corner_y.num /
s->params[
w].window_lower_right_corner_y.den);
328 put_bits(pb, 16,
s->params[
w].center_of_ellipse_x);
329 put_bits(pb, 16,
s->params[
w].center_of_ellipse_y);
331 put_bits(pb, 16,
s->params[
w].semimajor_axis_internal_ellipse);
332 put_bits(pb, 16,
s->params[
w].semimajor_axis_external_ellipse);
333 put_bits(pb, 16,
s->params[
w].semiminor_axis_external_ellipse);
334 put_bits(pb, 1,
s->params[
w].overlap_process_option);
338 s->targeted_system_display_maximum_luminance.den);
339 put_bits(pb, 1,
s->targeted_system_display_actual_peak_luminance_flag);
340 if (
s->targeted_system_display_actual_peak_luminance_flag) {
341 put_bits(pb, 5,
s->num_rows_targeted_system_display_actual_peak_luminance);
342 put_bits(pb, 5,
s->num_cols_targeted_system_display_actual_peak_luminance);
343 for (
int i = 0;
i <
s->num_rows_targeted_system_display_actual_peak_luminance;
i++) {
344 for (
int j = 0; j <
s->num_cols_targeted_system_display_actual_peak_luminance; j++)
346 s->targeted_system_display_actual_peak_luminance[
i][j].den);
350 for (
int w = 0;
w <
s->num_windows;
w++) {
351 for (
int i = 0;
i < 3;
i++)
353 put_bits(pb, 17,
s->params[
w].average_maxrgb.num *
rgb_den /
s->params[
w].average_maxrgb.den);
354 put_bits(pb, 4,
s->params[
w].num_distribution_maxrgb_percentiles);
355 for (
int i = 0;
i <
s->params[
w].num_distribution_maxrgb_percentiles;
i++) {
356 put_bits(pb, 7,
s->params[
w].distribution_maxrgb[
i].percentage);
358 s->params[
w].distribution_maxrgb[
i].percentile.den);
361 s->params[
w].fraction_bright_pixels.den);
364 put_bits(pb, 1,
s->mastering_display_actual_peak_luminance_flag);
365 if (
s->mastering_display_actual_peak_luminance_flag) {
366 put_bits(pb, 5,
s->num_rows_mastering_display_actual_peak_luminance);
367 put_bits(pb, 5,
s->num_cols_mastering_display_actual_peak_luminance);
368 for (
int i = 0;
i <
s->num_rows_mastering_display_actual_peak_luminance;
i++) {
369 for (
int j = 0; j <
s->num_cols_mastering_display_actual_peak_luminance; j++)
371 s->mastering_display_actual_peak_luminance[
i][j].den);
375 for (
int w = 0;
w <
s->num_windows;
w++) {
376 put_bits(pb, 1,
s->params[
w].tone_mapping_flag);
377 if (
s->params[
w].tone_mapping_flag) {
380 put_bits(pb, 4,
s->params[
w].num_bezier_curve_anchors);
381 for (
int i = 0;
i <
s->params[
w].num_bezier_curve_anchors;
i++)
383 s->params[
w].bezier_curve_anchors[
i].den);
384 put_bits(pb, 1,
s->params[
w].color_saturation_mapping_flag);
385 if (
s->params[
w].color_saturation_mapping_flag)
387 s->params[
w].color_saturation_weight.den);
406 *
size =
sizeof(*smpte2094_app5);
408 return smpte2094_app5;
424 #define GET_BITS_OR_FAIL(var, n) \
426 if (get_bits_left(gb) < n) { \
427 ret = AVERROR_INVALIDDATA; \
430 var = get_bits(gb, n); \
437 int ret, reserved_zero;
443 uint8_t *padded_data =
av_mallocz(padded_size);
466 if (
s->has_custom_hdr_reference_white_flag)
468 if (!
s->has_adaptive_tone_map_flag) {
476 if (
s->use_reference_white_tone_mapping_flag) {
482 if (
s->num_alternate_images > 4) {
489 if (
s->gain_application_space_chromaticities_flag == 3)
490 for (
int r = 0;
r < 8;
r++)
493 for (
int a = 0;
a <
s->num_alternate_images;
a++) {
497 if (!
a || !
s->has_common_component_mix_params_flag) {
499 if (
s->component_mixing_type[
a] != 3) {
506 for (
int k = 0; k < 6; k++)
508 for (
int k = 0; k < 6; k++) {
509 if (
s->has_component_mixing_coefficient_flag[
a][k]) {
512 s->component_mixing_coefficient[
a][k] = 0;
517 s->component_mixing_type[
a] =
s->component_mixing_type[0];
518 if (
s->component_mixing_type[
a] == 3) {
519 for (
int k = 0; k < 6; k++) {
520 s->has_component_mixing_coefficient_flag[
a][k] =
521 s->has_component_mixing_coefficient_flag[0][k];
522 s->component_mixing_coefficient[
a][k] =
s->component_mixing_coefficient[0][k];
528 if (!
a || !
s->has_common_curve_params_flag) {
530 if (
s->gain_curve_num_control_points_minus_1[
a] > 31) {
540 for (
int c = 0;
c <=
s->gain_curve_num_control_points_minus_1[
a];
c++) {
544 s->gain_curve_num_control_points_minus_1[
a] =
545 s->gain_curve_num_control_points_minus_1[0];
546 s->gain_curve_use_pchip_slope_flag[
a] =
s->gain_curve_use_pchip_slope_flag[0];
547 for (
int c = 0;
c <=
s->gain_curve_num_control_points_minus_1[
a];
c++) {
548 s->gain_curve_control_points_x[
a][
c] =
s->gain_curve_control_points_x[0][
c];
551 for (
int c = 0;
c <=
s->gain_curve_num_control_points_minus_1[
a];
c++)
553 if (!
s->gain_curve_use_pchip_slope_flag[
a]) {
554 for (
int c = 0;
c <=
s->gain_curve_num_control_points_minus_1[
a];
c++)
568 size_t size_bytes, size_bits;
576 if (
s->application_version >= 8 ||
s->minimum_application_version >= 3)
579 size_bits += 3 + 3 + 2;
580 size_bits += 1 + 1 + 6;
581 if (
s->has_custom_hdr_reference_white_flag)
583 if (
s->has_adaptive_tone_map_flag) {
585 if (
s->use_reference_white_tone_mapping_flag) {
588 size_bits += 3 + 2 + 1 + 1;
589 if (
s->gain_application_space_chromaticities_flag == 3)
591 if (
s->num_alternate_images > 4)
593 for (
int a = 0;
a <
s->num_alternate_images;
a++) {
595 if (!
a || !
s->has_common_component_mix_params_flag) {
597 if (
s->component_mixing_type[
a] != 3) {
601 for (
int k = 0; k < 6; k++)
602 if (
s->has_component_mixing_coefficient_flag[
a][k])
606 if (!
a || !
s->has_common_curve_params_flag) {
607 size_bits += 5 + 1 + 2;
608 if (
s->gain_curve_num_control_points_minus_1[
a] > 31)
610 size_bits += 16 * (
s->gain_curve_num_control_points_minus_1[
a] + 1);
612 size_bits += 16 * (
s->gain_curve_num_control_points_minus_1[
a] + 1);
613 if (!
s->gain_curve_use_pchip_slope_flag[
a])
614 size_bits += 16 * (
s->gain_curve_num_control_points_minus_1[
a] + 1);
620 size_bytes = size_bits >> 3;
626 if (*
size < size_bytes)
639 put_bits(pb, 3,
s->minimum_application_version);
643 put_bits(pb, 1,
s->has_custom_hdr_reference_white_flag);
644 put_bits(pb, 1,
s->has_adaptive_tone_map_flag);
647 if (
s->has_custom_hdr_reference_white_flag)
648 put_bits(pb, 16,
s->hdr_reference_white);
650 if (
s->has_adaptive_tone_map_flag) {
652 put_bits(pb, 16,
s->baseline_hdr_headroom);
653 put_bits(pb, 1,
s->use_reference_white_tone_mapping_flag);
654 if (
s->use_reference_white_tone_mapping_flag) {
657 put_bits(pb, 3,
s->num_alternate_images);
658 put_bits(pb, 2,
s->gain_application_space_chromaticities_flag);
659 put_bits(pb, 1,
s->has_common_component_mix_params_flag);
660 put_bits(pb, 1,
s->has_common_curve_params_flag);
662 if (
s->gain_application_space_chromaticities_flag == 3)
663 for (
int r = 0;
r < 8;
r++)
664 put_bits(pb, 16,
s->gain_application_space_chromaticities[
r]);
666 for (
int a = 0;
a <
s->num_alternate_images;
a++) {
667 put_bits(pb, 16,
s->alternate_hdr_headrooms[
a]);
670 if (!
a || !
s->has_common_component_mix_params_flag) {
672 if (
s->component_mixing_type[
a] != 3) {
675 for (
int k = 0; k < 6; k++)
676 put_bits(pb, 1,
s->has_component_mixing_coefficient_flag[
a][k]);
677 for (
int k = 0; k < 6; k++)
678 if (
s->has_component_mixing_coefficient_flag[
a][k])
679 put_bits(pb, 16,
s->component_mixing_coefficient[
a][k]);
684 if (!
a || !
s->has_common_curve_params_flag) {
685 put_bits(pb, 5,
s->gain_curve_num_control_points_minus_1[
a]);
686 put_bits(pb, 1,
s->gain_curve_use_pchip_slope_flag[
a]);
688 for (
int c = 0;
c <=
s->gain_curve_num_control_points_minus_1[
a];
c++)
689 put_bits(pb, 16,
s->gain_curve_control_points_x[
a][
c]);
691 for (
int c = 0;
c <=
s->gain_curve_num_control_points_minus_1[
a];
c++)
692 put_bits(pb, 16,
s->gain_curve_control_points_y[
a][
c]);
693 if (!
s->gain_curve_use_pchip_slope_flag[
a]) {
694 for (
int c = 0;
c <=
s->gain_curve_num_control_points_minus_1[
a];
c++)
695 put_bits(pb, 16,
s->gain_curve_control_points_theta[
a][
c]);