diff --git a/examples/heif_enc.cc b/examples/heif_enc.cc index 5760ccecd4..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 = 6; -uint16_t nclx_colour_primaries = 2; -uint16_t nclx_transfer_characteristic = 2; +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 da39dd11e2..5a0d6b57a4 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_sRGB_defaults(); std::set channels = input->get_channel_set(); assert(!channels.empty()); diff --git a/libheif/context.cc b/libheif/context.cc index 32077bb087..c7e49ea538 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_sRGB_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/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; diff --git a/libheif/nclx.cc b/libheif/nclx.cc index 9be6848ac1..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,6 +342,22 @@ void color_profile_nclx::set_from_heif_color_profile_nclx(const struct heif_colo } +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_470_6_System_B_G; + } + + if (m_colour_primaries == heif_color_primaries_unspecified) { + m_colour_primaries = heif_color_primaries_ITU_R_BT_709_5; + } + + if (m_transfer_characteristics == heif_transfer_characteristic_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..ad832752dd 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_sRGB_defaults(); + private: uint16_t m_colour_primaries = heif_color_primaries_unspecified; uint16_t m_transfer_characteristics = heif_transfer_characteristic_unspecified;