Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

set NCLX defaults to match sRGB and change handling of unspecified NCLX values #1017

Merged
merged 4 commits into from
Oct 30, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions examples/heif_enc.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
14 changes: 1 addition & 13 deletions libheif/color-conversion/colorconversion.cc
Original file line number Diff line number Diff line change
Expand Up @@ -520,19 +520,7 @@ std::shared_ptr<HeifPixelImage> convert_colorspace(const std::shared_ptr<HeifPix
input_state.nclx_profile = *input->get_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<enum heif_channel> channels = input->get_channel_set();
assert(!channels.empty());
Expand Down
32 changes: 26 additions & 6 deletions libheif/context.cc
Original file line number Diff line number Diff line change
Expand Up @@ -2429,6 +2429,29 @@ static bool nclx_profile_matches_spec(heif_colorspace colorspace,
}


static std::shared_ptr<color_profile_nclx> compute_target_nclx_profile(const std::shared_ptr<HeifPixelImage>& image, const heif_color_profile_nclx* output_nclx_profile)
{
auto target_nclx_profile = std::make_shared<color_profile_nclx>();

// 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<HeifPixelImage>& image,
struct heif_encoder* encoder,
const struct heif_encoding_options& options,
Expand All @@ -2444,8 +2467,7 @@ Error HeifContext::encode_image_as_hevc(const std::shared_ptr<HeifPixelImage>& i
heif_colorspace colorspace = image->get_colorspace();
heif_chroma chroma = image->get_chroma_format();

auto target_nclx_profile = std::make_shared<color_profile_nclx>();
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);
Expand Down Expand Up @@ -2652,8 +2674,7 @@ Error HeifContext::encode_image_as_av1(const std::shared_ptr<HeifPixelImage>& im
heif_colorspace colorspace = image->get_colorspace();
heif_chroma chroma = image->get_chroma_format();

auto target_nclx_profile = std::make_shared<color_profile_nclx>();
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);
Expand Down Expand Up @@ -2828,8 +2849,7 @@ Error HeifContext::encode_image_as_jpeg2000(const std::shared_ptr<HeifPixelImage
auto nclx_profile = std::dynamic_pointer_cast<const color_profile_nclx>(color_profile);
*/

auto target_nclx_profile = std::make_shared<color_profile_nclx>();
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);
Expand Down
2 changes: 1 addition & 1 deletion libheif/heif.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
27 changes: 23 additions & 4 deletions libheif/nclx.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}

Expand All @@ -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;
}

Expand All @@ -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;
Expand Down
2 changes: 2 additions & 0 deletions libheif/nclx.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
Loading