From 127c1cacead02de313a33da3ac7ec031d28b4fec Mon Sep 17 00:00:00 2001 From: Dirk Farin Date: Mon, 30 Oct 2023 13:46:27 +0100 Subject: [PATCH 1/4] alternative implementation of PR #1015 --- examples/heif_enc.cc | 6 ++-- libheif/color-conversion/colorconversion.cc | 14 +-------- libheif/context.cc | 32 +++++++++++++++++---- libheif/nclx.cc | 16 +++++++++++ libheif/nclx.h | 2 ++ 5 files changed, 48 insertions(+), 22 deletions(-) diff --git a/examples/heif_enc.cc b/examples/heif_enc.cc index 5760ccecd4..a62f878d18 100644 --- a/examples/heif_enc.cc +++ b/examples/heif_enc.cc @@ -64,9 +64,9 @@ int metadata_compression = 0; const char* encoderId = nullptr; std::string chroma_downsampling; -uint16_t nclx_matrix_coefficients = 6; -uint16_t nclx_colour_primaries = 2; -uint16_t nclx_transfer_characteristic = 2; +uint16_t nclx_matrix_coefficients = 1; +uint16_t nclx_colour_primaries = 1; +uint16_t nclx_transfer_characteristic = 13; int nclx_full_range = true; std::string property_pitm_description; diff --git a/libheif/color-conversion/colorconversion.cc b/libheif/color-conversion/colorconversion.cc index da39dd11e2..3a7b35315b 100644 --- a/libheif/color-conversion/colorconversion.cc +++ b/libheif/color-conversion/colorconversion.cc @@ -520,19 +520,7 @@ std::shared_ptr convert_colorspace(const std::shared_ptrget_color_profile_nclx(); } - // If some input nclx values are unspecified, use values that match sRGB as default. - - if (input_state.nclx_profile.get_matrix_coefficients() == heif_matrix_coefficients_unspecified) { - input_state.nclx_profile.set_matrix_coefficients(heif_matrix_coefficients_ITU_R_BT_709_5); - } - - if (input_state.nclx_profile.get_colour_primaries() == heif_color_primaries_unspecified) { - input_state.nclx_profile.set_colour_primaries(heif_color_primaries_ITU_R_BT_709_5); - } - - if (input_state.nclx_profile.get_transfer_characteristics() == heif_transfer_characteristic_unspecified) { - input_state.nclx_profile.set_transfer_characteristics(heif_transfer_characteristic_IEC_61966_2_1); - } + input_state.nclx_profile.replace_undefined_values_with_defaults(); std::set channels = input->get_channel_set(); assert(!channels.empty()); diff --git a/libheif/context.cc b/libheif/context.cc index 32077bb087..ec850c8e74 100644 --- a/libheif/context.cc +++ b/libheif/context.cc @@ -2429,6 +2429,29 @@ static bool nclx_profile_matches_spec(heif_colorspace colorspace, } +static std::shared_ptr compute_target_nclx_profile(const std::shared_ptr& image, const heif_color_profile_nclx* output_nclx_profile) +{ + auto target_nclx_profile = std::make_shared(); + + // If there is an output NCLX specified, use that. + if (output_nclx_profile) { + target_nclx_profile->set_from_heif_color_profile_nclx(output_nclx_profile); + } + // Otherwise, if there is an input NCLX, keep that. + else if (auto input_nclx = image->get_color_profile_nclx()) { + *target_nclx_profile = *input_nclx; + } + // Otherwise, just use the defaults (set below) + else { + target_nclx_profile->set_undefined(); + } + + target_nclx_profile->replace_undefined_values_with_defaults(); + + return target_nclx_profile; +} + + Error HeifContext::encode_image_as_hevc(const std::shared_ptr& image, struct heif_encoder* encoder, const struct heif_encoding_options& options, @@ -2444,8 +2467,7 @@ Error HeifContext::encode_image_as_hevc(const std::shared_ptr& i heif_colorspace colorspace = image->get_colorspace(); heif_chroma chroma = image->get_chroma_format(); - auto target_nclx_profile = std::make_shared(); - target_nclx_profile->set_from_heif_color_profile_nclx(options.output_nclx_profile); + auto target_nclx_profile = compute_target_nclx_profile(image, options.output_nclx_profile); if (encoder->plugin->plugin_api_version >= 2) { encoder->plugin->query_input_colorspace2(encoder->encoder, &colorspace, &chroma); @@ -2652,8 +2674,7 @@ Error HeifContext::encode_image_as_av1(const std::shared_ptr& im heif_colorspace colorspace = image->get_colorspace(); heif_chroma chroma = image->get_chroma_format(); - auto target_nclx_profile = std::make_shared(); - target_nclx_profile->set_from_heif_color_profile_nclx(options.output_nclx_profile); + auto target_nclx_profile = compute_target_nclx_profile(image, options.output_nclx_profile); if (encoder->plugin->plugin_api_version >= 2) { encoder->plugin->query_input_colorspace2(encoder->encoder, &colorspace, &chroma); @@ -2828,8 +2849,7 @@ Error HeifContext::encode_image_as_jpeg2000(const std::shared_ptr(color_profile); */ - auto target_nclx_profile = std::make_shared(); - target_nclx_profile->set_from_heif_color_profile_nclx(options.output_nclx_profile); + auto target_nclx_profile = compute_target_nclx_profile(image, options.output_nclx_profile); if (encoder->plugin->plugin_api_version >= 2) { encoder->plugin->query_input_colorspace2(encoder->encoder, &colorspace, &chroma); diff --git a/libheif/nclx.cc b/libheif/nclx.cc index 9be6848ac1..7b845700d6 100644 --- a/libheif/nclx.cc +++ b/libheif/nclx.cc @@ -339,6 +339,22 @@ void color_profile_nclx::set_from_heif_color_profile_nclx(const struct heif_colo } +void color_profile_nclx::replace_undefined_values_with_defaults() +{ + if (m_matrix_coefficients == heif_matrix_coefficients_unspecified) { + m_matrix_coefficients = heif_matrix_coefficients_ITU_R_BT_709_5; + } + + if (m_colour_primaries == heif_color_primaries_unspecified) { + m_colour_primaries = heif_color_primaries_ITU_R_BT_709_5; + } + + if (m_transfer_characteristics == heif_color_primaries_unspecified) { + m_transfer_characteristics = heif_transfer_characteristic_IEC_61966_2_1; + } +} + + Error Box_colr::parse(BitstreamRange& range) { StreamReader::grow_status status; diff --git a/libheif/nclx.h b/libheif/nclx.h index 9d6bb666bb..12c0448057 100644 --- a/libheif/nclx.h +++ b/libheif/nclx.h @@ -159,6 +159,8 @@ class color_profile_nclx : public color_profile void set_from_heif_color_profile_nclx(const struct heif_color_profile_nclx* nclx); + void replace_undefined_values_with_defaults(); + private: uint16_t m_colour_primaries = heif_color_primaries_unspecified; uint16_t m_transfer_characteristics = heif_transfer_characteristic_unspecified; From 136cf0173ffb52a92842736fec47c83e69475327 Mon Sep 17 00:00:00 2001 From: Dirk Farin Date: Mon, 30 Oct 2023 13:56:20 +0100 Subject: [PATCH 2/4] turn off macOS_compatibility_workaround_no_nclx_profile by default --- libheif/heif.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libheif/heif.cc b/libheif/heif.cc index 05bf31cc52..6f7f614989 100644 --- a/libheif/heif.cc +++ b/libheif/heif.cc @@ -2606,7 +2606,7 @@ static void set_default_options(heif_encoding_options& options) options.macOS_compatibility_workaround = false; options.save_two_colr_boxes_when_ICC_and_nclx_available = false; options.output_nclx_profile = nullptr; - options.macOS_compatibility_workaround_no_nclx_profile = true; + options.macOS_compatibility_workaround_no_nclx_profile = false; options.image_orientation = heif_orientation_normal; options.color_conversion_options.version = 1; From 36326c5312137396c9b328556d6d1b3d0967586f Mon Sep 17 00:00:00 2001 From: Dirk Farin Date: Mon, 30 Oct 2023 14:10:27 +0100 Subject: [PATCH 3/4] fix heif_transfer_characteristic_unspecified --- libheif/nclx.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libheif/nclx.cc b/libheif/nclx.cc index 7b845700d6..ded33d8fe2 100644 --- a/libheif/nclx.cc +++ b/libheif/nclx.cc @@ -349,7 +349,7 @@ void color_profile_nclx::replace_undefined_values_with_defaults() m_colour_primaries = heif_color_primaries_ITU_R_BT_709_5; } - if (m_transfer_characteristics == heif_color_primaries_unspecified) { + if (m_transfer_characteristics == heif_transfer_characteristic_unspecified) { m_transfer_characteristics = heif_transfer_characteristic_IEC_61966_2_1; } } From 2698eefe9aa24f07e79cb1ae630982e0625ef3f5 Mon Sep 17 00:00:00 2001 From: Dirk Farin Date: Mon, 30 Oct 2023 15:00:16 +0100 Subject: [PATCH 4/4] use matrix_coefficients=5 for sRGB --- examples/heif_enc.cc | 2 +- libheif/color-conversion/colorconversion.cc | 2 +- libheif/context.cc | 2 +- libheif/nclx.cc | 15 +++++++++------ libheif/nclx.h | 2 +- 5 files changed, 13 insertions(+), 10 deletions(-) diff --git a/examples/heif_enc.cc b/examples/heif_enc.cc index a62f878d18..f98a379138 100644 --- a/examples/heif_enc.cc +++ b/examples/heif_enc.cc @@ -64,9 +64,9 @@ int metadata_compression = 0; const char* encoderId = nullptr; std::string chroma_downsampling; -uint16_t nclx_matrix_coefficients = 1; uint16_t nclx_colour_primaries = 1; uint16_t nclx_transfer_characteristic = 13; +uint16_t nclx_matrix_coefficients = 5; int nclx_full_range = true; std::string property_pitm_description; diff --git a/libheif/color-conversion/colorconversion.cc b/libheif/color-conversion/colorconversion.cc index 3a7b35315b..5a0d6b57a4 100644 --- a/libheif/color-conversion/colorconversion.cc +++ b/libheif/color-conversion/colorconversion.cc @@ -520,7 +520,7 @@ std::shared_ptr convert_colorspace(const std::shared_ptrget_color_profile_nclx(); } - input_state.nclx_profile.replace_undefined_values_with_defaults(); + input_state.nclx_profile.replace_undefined_values_with_sRGB_defaults(); std::set channels = input->get_channel_set(); assert(!channels.empty()); diff --git a/libheif/context.cc b/libheif/context.cc index ec850c8e74..c7e49ea538 100644 --- a/libheif/context.cc +++ b/libheif/context.cc @@ -2446,7 +2446,7 @@ static std::shared_ptr compute_target_nclx_profile(const std target_nclx_profile->set_undefined(); } - target_nclx_profile->replace_undefined_values_with_defaults(); + target_nclx_profile->replace_undefined_values_with_sRGB_defaults(); return target_nclx_profile; } diff --git a/libheif/nclx.cc b/libheif/nclx.cc index ded33d8fe2..3be972d7ca 100644 --- a/libheif/nclx.cc +++ b/libheif/nclx.cc @@ -294,9 +294,11 @@ struct heif_color_profile_nclx* color_profile_nclx::alloc_nclx_color_profile() if (profile) { profile->version = 1; - profile->color_primaries = heif_color_primaries_ITU_R_BT_709_5; - profile->transfer_characteristics = heif_transfer_characteristic_IEC_61966_2_1; - profile->matrix_coefficients = heif_matrix_coefficients_ITU_R_BT_709_5; + + // sRGB defaults + profile->color_primaries = heif_color_primaries_ITU_R_BT_709_5; // 1 + profile->transfer_characteristics = heif_transfer_characteristic_IEC_61966_2_1; // 13 + profile->matrix_coefficients = heif_matrix_coefficients_ITU_R_BT_470_6_System_B_G; // 5 profile->full_range_flag = true; } @@ -312,9 +314,10 @@ void color_profile_nclx::free_nclx_color_profile(struct heif_color_profile_nclx* void color_profile_nclx::set_default() { + // sRGB defaults m_colour_primaries = 1; m_transfer_characteristics = 13; - m_matrix_coefficients = 1; + m_matrix_coefficients = 5; m_full_range_flag = true; } @@ -339,10 +342,10 @@ void color_profile_nclx::set_from_heif_color_profile_nclx(const struct heif_colo } -void color_profile_nclx::replace_undefined_values_with_defaults() +void color_profile_nclx::replace_undefined_values_with_sRGB_defaults() { if (m_matrix_coefficients == heif_matrix_coefficients_unspecified) { - m_matrix_coefficients = heif_matrix_coefficients_ITU_R_BT_709_5; + m_matrix_coefficients = heif_matrix_coefficients_ITU_R_BT_470_6_System_B_G; } if (m_colour_primaries == heif_color_primaries_unspecified) { diff --git a/libheif/nclx.h b/libheif/nclx.h index 12c0448057..ad832752dd 100644 --- a/libheif/nclx.h +++ b/libheif/nclx.h @@ -159,7 +159,7 @@ class color_profile_nclx : public color_profile void set_from_heif_color_profile_nclx(const struct heif_color_profile_nclx* nclx); - void replace_undefined_values_with_defaults(); + void replace_undefined_values_with_sRGB_defaults(); private: uint16_t m_colour_primaries = heif_color_primaries_unspecified;