mirror of
https://invent.kde.org/frameworks/kimageformats.git
synced 2025-06-03 17:08:08 -04:00
avif: color profiles improvements
With Qt 6.8.x, PQ and HLG transfer functions are supported. Better support for GRAY profiles
This commit is contained in:
parent
a7cf1a87f9
commit
43f3fd05f7
@ -249,11 +249,15 @@ bool QAVIFHandler::decode_one_frame()
|
||||
}
|
||||
|
||||
bool loadalpha;
|
||||
bool loadgray = false;
|
||||
|
||||
if (m_decoder->image->alphaPlane) {
|
||||
loadalpha = true;
|
||||
} else {
|
||||
loadalpha = false;
|
||||
if (m_decoder->image->yuvFormat == AVIF_PIXEL_FORMAT_YUV400) {
|
||||
loadgray = true;
|
||||
}
|
||||
}
|
||||
|
||||
QImage::Format resultformat;
|
||||
@ -285,6 +289,38 @@ bool QAVIFHandler::decode_one_frame()
|
||||
if (!colorspace.isValid()) {
|
||||
qWarning("AVIF image has Qt-unsupported or invalid ICC profile!");
|
||||
}
|
||||
#if (QT_VERSION >= QT_VERSION_CHECK(6, 8, 0))
|
||||
else {
|
||||
if (colorspace.colorModel() == QColorSpace::ColorModel::Cmyk) {
|
||||
qWarning("CMYK ICC profile is not extected for AVIF, discarding the ICCprofile!");
|
||||
colorspace = QColorSpace();
|
||||
} else if (colorspace.colorModel() == QColorSpace::ColorModel::Rgb && loadgray) {
|
||||
// Input is GRAY but ICC is RGB, we will return RGB image
|
||||
loadgray = false;
|
||||
} else if (colorspace.colorModel() == QColorSpace::ColorModel::Gray && !loadgray) {
|
||||
// ICC is GRAY but we must return RGB (image has alpha channel for example)
|
||||
// we create similar RGB profile (same whitepoint and TRC)
|
||||
QPointF gray_whitePoint = colorspace.whitePoint();
|
||||
if (gray_whitePoint.isNull()) {
|
||||
gray_whitePoint = QPointF(0.3127f, 0.329f);
|
||||
}
|
||||
|
||||
const QPointF redP(0.64f, 0.33f);
|
||||
const QPointF greenP(0.3f, 0.6f);
|
||||
const QPointF blueP(0.15f, 0.06f);
|
||||
|
||||
QColorSpace::TransferFunction trc_new = colorspace.transferFunction();
|
||||
float gamma_new = colorspace.gamma();
|
||||
if (trc_new == QColorSpace::TransferFunction::Custom) {
|
||||
trc_new = QColorSpace::TransferFunction::SRgb;
|
||||
}
|
||||
colorspace = QColorSpace(gray_whitePoint, redP, greenP, blueP, trc_new, gamma_new);
|
||||
if (!colorspace.isValid()) {
|
||||
qWarning("AVIF plugin created invalid QColorSpace!");
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
} else {
|
||||
float prim[8] = {0.64f, 0.33f, 0.3f, 0.6f, 0.15f, 0.06f, 0.3127f, 0.329f};
|
||||
// outPrimaries: rX, rY, gX, gY, bX, bY, wX, wY
|
||||
@ -319,6 +355,14 @@ bool QAVIFHandler::decode_one_frame()
|
||||
case 13:
|
||||
q_trc = QColorSpace::TransferFunction::SRgb;
|
||||
break;
|
||||
#if (QT_VERSION >= QT_VERSION_CHECK(6, 8, 0))
|
||||
case 16: /* AVIF_TRANSFER_CHARACTERISTICS_PQ */
|
||||
q_trc = QColorSpace::TransferFunction::St2084;
|
||||
break;
|
||||
case 18: /* AVIF_TRANSFER_CHARACTERISTICS_HLG */
|
||||
q_trc = QColorSpace::TransferFunction::Hlg;
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
qWarning("CICP colorPrimaries: %d, transferCharacteristics: %d\nThe colorspace is unsupported by this plug-in yet.",
|
||||
m_decoder->image->colorPrimaries,
|
||||
@ -328,21 +372,29 @@ bool QAVIFHandler::decode_one_frame()
|
||||
}
|
||||
|
||||
if (q_trc != QColorSpace::TransferFunction::Custom) { // we create new colorspace using Qt
|
||||
switch (m_decoder->image->colorPrimaries) {
|
||||
/* AVIF_COLOR_PRIMARIES_BT709 */
|
||||
case 0:
|
||||
case 1:
|
||||
case 2: /* AVIF_COLOR_PRIMARIES_UNSPECIFIED */
|
||||
colorspace = QColorSpace(QColorSpace::Primaries::SRgb, q_trc, q_trc_gamma);
|
||||
break;
|
||||
/* AVIF_COLOR_PRIMARIES_SMPTE432 */
|
||||
case 12:
|
||||
colorspace = QColorSpace(QColorSpace::Primaries::DciP3D65, q_trc, q_trc_gamma);
|
||||
break;
|
||||
default:
|
||||
colorspace = QColorSpace(whitePoint, redPoint, greenPoint, bluePoint, q_trc, q_trc_gamma);
|
||||
break;
|
||||
#if (QT_VERSION >= QT_VERSION_CHECK(6, 8, 0))
|
||||
if (loadgray) {
|
||||
colorspace = QColorSpace(whitePoint, q_trc, q_trc_gamma);
|
||||
} else {
|
||||
#endif
|
||||
switch (m_decoder->image->colorPrimaries) {
|
||||
/* AVIF_COLOR_PRIMARIES_BT709 */
|
||||
case 0:
|
||||
case 1:
|
||||
case 2: /* AVIF_COLOR_PRIMARIES_UNSPECIFIED */
|
||||
colorspace = QColorSpace(QColorSpace::Primaries::SRgb, q_trc, q_trc_gamma);
|
||||
break;
|
||||
/* AVIF_COLOR_PRIMARIES_SMPTE432 */
|
||||
case 12:
|
||||
colorspace = QColorSpace(QColorSpace::Primaries::DciP3D65, q_trc, q_trc_gamma);
|
||||
break;
|
||||
default:
|
||||
colorspace = QColorSpace(whitePoint, redPoint, greenPoint, bluePoint, q_trc, q_trc_gamma);
|
||||
break;
|
||||
}
|
||||
#if (QT_VERSION >= QT_VERSION_CHECK(6, 8, 0))
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
if (!colorspace.isValid()) {
|
||||
@ -350,8 +402,6 @@ bool QAVIFHandler::decode_one_frame()
|
||||
}
|
||||
}
|
||||
|
||||
result.setColorSpace(colorspace);
|
||||
|
||||
avifRGBImage rgb;
|
||||
avifRGBImageSetDefaults(&rgb, m_decoder->image);
|
||||
|
||||
@ -363,7 +413,7 @@ bool QAVIFHandler::decode_one_frame()
|
||||
rgb.depth = 16;
|
||||
rgb.format = AVIF_RGB_FORMAT_RGBA;
|
||||
|
||||
if (!loadalpha && (m_decoder->image->yuvFormat == AVIF_PIXEL_FORMAT_YUV400)) {
|
||||
if (loadgray) {
|
||||
resultformat = QImage::Format_Grayscale16;
|
||||
}
|
||||
} else {
|
||||
@ -381,7 +431,7 @@ bool QAVIFHandler::decode_one_frame()
|
||||
}
|
||||
#endif
|
||||
|
||||
if (!loadalpha && (m_decoder->image->yuvFormat == AVIF_PIXEL_FORMAT_YUV400)) {
|
||||
if (loadgray) {
|
||||
resultformat = QImage::Format_Grayscale8;
|
||||
}
|
||||
}
|
||||
@ -473,6 +523,8 @@ bool QAVIFHandler::decode_one_frame()
|
||||
m_current_image = result.convertToFormat(resultformat);
|
||||
}
|
||||
|
||||
m_current_image.setColorSpace(colorspace);
|
||||
|
||||
m_estimated_dimensions = m_current_image.size();
|
||||
|
||||
m_must_jump_to_next_image = false;
|
||||
@ -642,6 +694,14 @@ bool QAVIFHandler::write(const QImage &image)
|
||||
/* AVIF_TRANSFER_CHARACTERISTICS_SRGB */
|
||||
avif->transferCharacteristics = (avifTransferCharacteristics)13;
|
||||
break;
|
||||
#if (QT_VERSION >= QT_VERSION_CHECK(6, 8, 0))
|
||||
case QColorSpace::TransferFunction::St2084:
|
||||
avif->transferCharacteristics = (avifTransferCharacteristics)16;
|
||||
break;
|
||||
case QColorSpace::TransferFunction::Hlg:
|
||||
avif->transferCharacteristics = (avifTransferCharacteristics)18;
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
/* AVIF_TRANSFER_CHARACTERISTICS_UNSPECIFIED */
|
||||
break;
|
||||
@ -691,8 +751,14 @@ bool QAVIFHandler::write(const QImage &image)
|
||||
auto cs = image.colorSpace();
|
||||
if (cs.isValid() && cs.colorModel() == QColorSpace::ColorModel::Cmyk && image.format() == QImage::Format_CMYK8888) {
|
||||
tmpcolorimage = image.convertedToColorSpace(QColorSpace(QColorSpace::SRgb), tmpformat);
|
||||
}
|
||||
else {
|
||||
} else if (cs.isValid() && cs.colorModel() == QColorSpace::ColorModel::Gray) {
|
||||
QColorSpace::TransferFunction trc_new = cs.transferFunction();
|
||||
float gamma_new = cs.gamma();
|
||||
if (trc_new == QColorSpace::TransferFunction::Custom) {
|
||||
trc_new = QColorSpace::TransferFunction::SRgb;
|
||||
}
|
||||
tmpcolorimage = image.convertedToColorSpace(QColorSpace(QColorSpace::Primaries::SRgb, trc_new, gamma_new), tmpformat);
|
||||
} else {
|
||||
tmpcolorimage = image.convertToFormat(tmpformat);
|
||||
}
|
||||
#else
|
||||
@ -757,6 +823,14 @@ bool QAVIFHandler::write(const QImage &image)
|
||||
/* AVIF_TRANSFER_CHARACTERISTICS_SRGB */
|
||||
transfer_to_save = (avifTransferCharacteristics)13;
|
||||
break;
|
||||
#if (QT_VERSION >= QT_VERSION_CHECK(6, 8, 0))
|
||||
case QColorSpace::TransferFunction::St2084:
|
||||
transfer_to_save = (avifTransferCharacteristics)16;
|
||||
break;
|
||||
case QColorSpace::TransferFunction::Hlg:
|
||||
transfer_to_save = (avifTransferCharacteristics)18;
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
/* AVIF_TRANSFER_CHARACTERISTICS_UNSPECIFIED */
|
||||
transfer_to_save = (avifTransferCharacteristics)2;
|
||||
@ -792,6 +866,14 @@ bool QAVIFHandler::write(const QImage &image)
|
||||
case 5: // AVIF_TRANSFER_CHARACTERISTICS_BT470BG
|
||||
tmpcolorimage.convertToColorSpace(QColorSpace(QColorSpace::Primaries::SRgb, 2.8f));
|
||||
break;
|
||||
#if (QT_VERSION >= QT_VERSION_CHECK(6, 8, 0))
|
||||
case 16:
|
||||
tmpcolorimage.convertToColorSpace(QColorSpace(QColorSpace::Primaries::SRgb, QColorSpace::TransferFunction::St2084));
|
||||
break;
|
||||
case 18:
|
||||
tmpcolorimage.convertToColorSpace(QColorSpace(QColorSpace::Primaries::SRgb, QColorSpace::TransferFunction::Hlg));
|
||||
break;
|
||||
#endif
|
||||
default: // AVIF_TRANSFER_CHARACTERISTICS_SRGB + any other
|
||||
tmpcolorimage.convertToColorSpace(QColorSpace(QColorSpace::Primaries::SRgb, QColorSpace::TransferFunction::SRgb));
|
||||
transfer_to_save = (avifTransferCharacteristics)13;
|
||||
|
Loading…
x
Reference in New Issue
Block a user