From 53c47b339a5aaebb361eb5b1253f9ee84b888042 Mon Sep 17 00:00:00 2001 From: Nicholas Hayes <0xC0000054@users.noreply.github.com> Date: Thu, 3 Nov 2022 18:35:14 -0600 Subject: [PATCH] Use the MAIF defaults if the NCLX box is null ISO/IEC 23000-22:2019 Amendment 2 specifies the default values that should be used if the image does not have a NCLX color box. These values will only be used if both the AVIF container and AV1 bitstream do not provide the NCLX (a.k.a. CICP) color information. --- src/common/ColorProfileGeneration.cpp | 63 +++++++++++++++++---------- 1 file changed, 41 insertions(+), 22 deletions(-) diff --git a/src/common/ColorProfileGeneration.cpp b/src/common/ColorProfileGeneration.cpp index 2142320..6a0d4e3 100644 --- a/src/common/ColorProfileGeneration.cpp +++ b/src/common/ColorProfileGeneration.cpp @@ -272,29 +272,48 @@ namespace void SetIccProfileFromNclx(FormatRecord* formatRecord, const heif_color_profile_nclx* nclx) { - if (nclx == nullptr) + // (As of ISO/IEC 23000-22:2019 Amendment 2) + // MIAF Section 7.3.6.4 "Colour information property": + // + // If a coded image has no associated colour property, the default property is defined as having + // colour_type equal to 'nclx' with properties as follows: + // – colour_primaries equal to 1, + // – transfer_characteristics equal to 13, + // – matrix_coefficients equal to 5 or 6 (which are functionally identical), and + // – full_range_flag equal to 1. + // Only if the colour information property of the image matches these default values, the colour + // property may be omitted; all other images shall have an explicitly declared colour space via + // association with a property of this type. + // + // See here for the discussion: https://github.com/AOMediaCodec/av1-avif/issues/77#issuecomment-676526097 + + heif_color_primaries primaries = heif_color_primaries_ITU_R_BT_709_5; + heif_transfer_characteristics transferCharacteristics = heif_transfer_characteristic_IEC_61966_2_1; + heif_matrix_coefficients matrixCoefficients = heif_matrix_coefficients_ITU_R_BT_601_6; + bool fullRange = true; + // Default to the Rec. 709 white point values, D65. + float whitepointX = 0.3127; + float whitepointY = 0.3290; + + if (nclx != nullptr) { - return; - } - - heif_color_primaries primaries = nclx->color_primaries; - heif_transfer_characteristics transferCharacteristics = nclx->transfer_characteristics; - heif_matrix_coefficients matrixCoefficients = nclx->matrix_coefficients; - const bool fullRange = nclx->full_range_flag != 0; - - if (primaries == heif_color_primaries_unspecified) - { - primaries = heif_color_primaries_ITU_R_BT_709_5; - } + if (nclx->color_primaries != heif_color_primaries_unspecified) + { + primaries = nclx->color_primaries; + whitepointX = nclx->color_primary_white_x; + whitepointY = nclx->color_primary_white_y; + } - if (transferCharacteristics == heif_transfer_characteristic_unspecified) - { - transferCharacteristics = heif_transfer_characteristic_IEC_61966_2_1; - } + if (nclx->transfer_characteristics != heif_transfer_characteristic_unspecified) + { + transferCharacteristics = nclx->transfer_characteristics; + } - if (matrixCoefficients == heif_matrix_coefficients_unspecified) - { - matrixCoefficients = heif_matrix_coefficients_ITU_R_BT_601_6; + if (nclx->matrix_coefficients != heif_matrix_coefficients_unspecified) + { + matrixCoefficients = nclx->matrix_coefficients; + } + fullRange = nclx->full_range_flag != 0; } // The 32-bits-per-channel image modes always operate in linear color. @@ -347,8 +366,8 @@ void SetIccProfileFromNclx(FormatRecord* formatRecord, const heif_color_profile_ { ScopedLcmsProfile profile = BuildGrayProfile( context.get(), - nclx->color_primary_white_x, - nclx->color_primary_white_y, + whitepointX, + whitepointY, toneCurve.get(), description);