avif: Improved color profiles support

This commit is contained in:
Daniel Novomeský
2026-01-07 23:22:04 +01:00
parent e644ab997f
commit 6b1c52c55c

View File

@ -388,6 +388,9 @@ bool QAVIFHandler::decode_one_frame()
case 2: /* AVIF_COLOR_PRIMARIES_UNSPECIFIED */
colorspace = QColorSpace(QColorSpace::Primaries::SRgb, q_trc, q_trc_gamma);
break;
case 9:
colorspace = QColorSpace(QColorSpace::Primaries::Bt2020, q_trc, q_trc_gamma);
break;
/* AVIF_COLOR_PRIMARIES_SMPTE432 */
case 12:
colorspace = QColorSpace(QColorSpace::Primaries::DciP3D65, q_trc, q_trc_gamma);
@ -740,6 +743,15 @@ bool QAVIFHandler::write(const QImage &image)
/* AVIF_TRANSFER_CHARACTERISTICS_LINEAR */
avif->transferCharacteristics = (avifTransferCharacteristics)8;
break;
case QColorSpace::TransferFunction::Gamma:
if (qAbs(tmpgrayimage.colorSpace().gamma() - 2.2f) < 0.1f) {
/* AVIF_TRANSFER_CHARACTERISTICS_BT470M */
avif->transferCharacteristics = (avifTransferCharacteristics)4;
} else if (qAbs(tmpgrayimage.colorSpace().gamma() - 2.8f) < 0.1f) {
/* AVIF_TRANSFER_CHARACTERISTICS_BT470BG */
avif->transferCharacteristics = (avifTransferCharacteristics)5;
}
break;
case QColorSpace::TransferFunction::SRgb:
/* AVIF_TRANSFER_CHARACTERISTICS_SRGB */
avif->transferCharacteristics = (avifTransferCharacteristics)13;
@ -754,6 +766,42 @@ bool QAVIFHandler::write(const QImage &image)
/* AVIF_TRANSFER_CHARACTERISTICS_UNSPECIFIED */
break;
}
if (avif->transferCharacteristics == 2) { // in case TransferFunction was not identified yet
if (tmpgrayimage.colorSpace().colorModel() == QColorSpace::ColorModel::Gray && lossless) {
avif->colorPrimaries = (avifColorPrimaries)2;
avif->matrixCoefficients = (avifMatrixCoefficients)6;
QByteArray iccprofile_gray = tmpgrayimage.colorSpace().iccProfile();
if (iccprofile_gray.size() > 0) {
#if AVIF_VERSION >= 1000000
res = avifImageSetProfileICC(avif, reinterpret_cast<const uint8_t *>(iccprofile_gray.constData()), iccprofile_gray.size());
if (res != AVIF_RESULT_OK) {
qCWarning(LOG_AVIFPLUGIN, "ERROR in avifImageSetProfileICC: %s", avifResultToString(res));
return false;
}
#else
avifImageSetProfileICC(avif, reinterpret_cast<const uint8_t *>(iccprofile_gray.constData()), iccprofile_gray.size());
#endif
}
} else { // convert to grayscale with SRgb
tmpgrayimage.convertToColorSpace(QColorSpace(QPointF(0.3127f, 0.329f), QColorSpace::TransferFunction::SRgb), QImage::Format_Grayscale16);
switch (tmpgrayimage.format()) {
case QImage::Format_Grayscale8:
save_depth = 8;
break;
case QImage::Format_Grayscale16:
save_depth = 10;
avif->transferCharacteristics = (avifTransferCharacteristics)13;
break;
default:
qCWarning(LOG_AVIFPLUGIN, "Error saving Gray image");
return false;
break;
}
}
}
}
if (save_depth > 8) { // QImage::Format_Grayscale16
@ -838,6 +886,10 @@ bool QAVIFHandler::write(const QImage &image)
/* AVIF_MATRIX_COEFFICIENTS_CHROMA_DERIVED_NCL */
matrix_to_save = (avifMatrixCoefficients)12;
break;
case QColorSpace::Primaries::Bt2020:
primaries_to_save = (avifColorPrimaries)9;
matrix_to_save = (avifMatrixCoefficients)12;
break;
default:
/* AVIF_TRANSFER_CHARACTERISTICS_UNSPECIFIED */
primaries_to_save = (avifColorPrimaries)2;