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 loadalpha;
|
||||||
|
bool loadgray = false;
|
||||||
|
|
||||||
if (m_decoder->image->alphaPlane) {
|
if (m_decoder->image->alphaPlane) {
|
||||||
loadalpha = true;
|
loadalpha = true;
|
||||||
} else {
|
} else {
|
||||||
loadalpha = false;
|
loadalpha = false;
|
||||||
|
if (m_decoder->image->yuvFormat == AVIF_PIXEL_FORMAT_YUV400) {
|
||||||
|
loadgray = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
QImage::Format resultformat;
|
QImage::Format resultformat;
|
||||||
@ -285,6 +289,38 @@ bool QAVIFHandler::decode_one_frame()
|
|||||||
if (!colorspace.isValid()) {
|
if (!colorspace.isValid()) {
|
||||||
qWarning("AVIF image has Qt-unsupported or invalid ICC profile!");
|
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 {
|
} else {
|
||||||
float prim[8] = {0.64f, 0.33f, 0.3f, 0.6f, 0.15f, 0.06f, 0.3127f, 0.329f};
|
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
|
// outPrimaries: rX, rY, gX, gY, bX, bY, wX, wY
|
||||||
@ -319,6 +355,14 @@ bool QAVIFHandler::decode_one_frame()
|
|||||||
case 13:
|
case 13:
|
||||||
q_trc = QColorSpace::TransferFunction::SRgb;
|
q_trc = QColorSpace::TransferFunction::SRgb;
|
||||||
break;
|
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:
|
default:
|
||||||
qWarning("CICP colorPrimaries: %d, transferCharacteristics: %d\nThe colorspace is unsupported by this plug-in yet.",
|
qWarning("CICP colorPrimaries: %d, transferCharacteristics: %d\nThe colorspace is unsupported by this plug-in yet.",
|
||||||
m_decoder->image->colorPrimaries,
|
m_decoder->image->colorPrimaries,
|
||||||
@ -328,6 +372,11 @@ bool QAVIFHandler::decode_one_frame()
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (q_trc != QColorSpace::TransferFunction::Custom) { // we create new colorspace using Qt
|
if (q_trc != QColorSpace::TransferFunction::Custom) { // we create new colorspace using Qt
|
||||||
|
#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) {
|
switch (m_decoder->image->colorPrimaries) {
|
||||||
/* AVIF_COLOR_PRIMARIES_BT709 */
|
/* AVIF_COLOR_PRIMARIES_BT709 */
|
||||||
case 0:
|
case 0:
|
||||||
@ -343,6 +392,9 @@ bool QAVIFHandler::decode_one_frame()
|
|||||||
colorspace = QColorSpace(whitePoint, redPoint, greenPoint, bluePoint, q_trc, q_trc_gamma);
|
colorspace = QColorSpace(whitePoint, redPoint, greenPoint, bluePoint, q_trc, q_trc_gamma);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
#if (QT_VERSION >= QT_VERSION_CHECK(6, 8, 0))
|
||||||
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!colorspace.isValid()) {
|
if (!colorspace.isValid()) {
|
||||||
@ -350,8 +402,6 @@ bool QAVIFHandler::decode_one_frame()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
result.setColorSpace(colorspace);
|
|
||||||
|
|
||||||
avifRGBImage rgb;
|
avifRGBImage rgb;
|
||||||
avifRGBImageSetDefaults(&rgb, m_decoder->image);
|
avifRGBImageSetDefaults(&rgb, m_decoder->image);
|
||||||
|
|
||||||
@ -363,7 +413,7 @@ bool QAVIFHandler::decode_one_frame()
|
|||||||
rgb.depth = 16;
|
rgb.depth = 16;
|
||||||
rgb.format = AVIF_RGB_FORMAT_RGBA;
|
rgb.format = AVIF_RGB_FORMAT_RGBA;
|
||||||
|
|
||||||
if (!loadalpha && (m_decoder->image->yuvFormat == AVIF_PIXEL_FORMAT_YUV400)) {
|
if (loadgray) {
|
||||||
resultformat = QImage::Format_Grayscale16;
|
resultformat = QImage::Format_Grayscale16;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@ -381,7 +431,7 @@ bool QAVIFHandler::decode_one_frame()
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (!loadalpha && (m_decoder->image->yuvFormat == AVIF_PIXEL_FORMAT_YUV400)) {
|
if (loadgray) {
|
||||||
resultformat = QImage::Format_Grayscale8;
|
resultformat = QImage::Format_Grayscale8;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -473,6 +523,8 @@ bool QAVIFHandler::decode_one_frame()
|
|||||||
m_current_image = result.convertToFormat(resultformat);
|
m_current_image = result.convertToFormat(resultformat);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
m_current_image.setColorSpace(colorspace);
|
||||||
|
|
||||||
m_estimated_dimensions = m_current_image.size();
|
m_estimated_dimensions = m_current_image.size();
|
||||||
|
|
||||||
m_must_jump_to_next_image = false;
|
m_must_jump_to_next_image = false;
|
||||||
@ -642,6 +694,14 @@ bool QAVIFHandler::write(const QImage &image)
|
|||||||
/* AVIF_TRANSFER_CHARACTERISTICS_SRGB */
|
/* AVIF_TRANSFER_CHARACTERISTICS_SRGB */
|
||||||
avif->transferCharacteristics = (avifTransferCharacteristics)13;
|
avif->transferCharacteristics = (avifTransferCharacteristics)13;
|
||||||
break;
|
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:
|
default:
|
||||||
/* AVIF_TRANSFER_CHARACTERISTICS_UNSPECIFIED */
|
/* AVIF_TRANSFER_CHARACTERISTICS_UNSPECIFIED */
|
||||||
break;
|
break;
|
||||||
@ -691,8 +751,14 @@ bool QAVIFHandler::write(const QImage &image)
|
|||||||
auto cs = image.colorSpace();
|
auto cs = image.colorSpace();
|
||||||
if (cs.isValid() && cs.colorModel() == QColorSpace::ColorModel::Cmyk && image.format() == QImage::Format_CMYK8888) {
|
if (cs.isValid() && cs.colorModel() == QColorSpace::ColorModel::Cmyk && image.format() == QImage::Format_CMYK8888) {
|
||||||
tmpcolorimage = image.convertedToColorSpace(QColorSpace(QColorSpace::SRgb), tmpformat);
|
tmpcolorimage = image.convertedToColorSpace(QColorSpace(QColorSpace::SRgb), tmpformat);
|
||||||
|
} 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;
|
||||||
}
|
}
|
||||||
else {
|
tmpcolorimage = image.convertedToColorSpace(QColorSpace(QColorSpace::Primaries::SRgb, trc_new, gamma_new), tmpformat);
|
||||||
|
} else {
|
||||||
tmpcolorimage = image.convertToFormat(tmpformat);
|
tmpcolorimage = image.convertToFormat(tmpformat);
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
@ -757,6 +823,14 @@ bool QAVIFHandler::write(const QImage &image)
|
|||||||
/* AVIF_TRANSFER_CHARACTERISTICS_SRGB */
|
/* AVIF_TRANSFER_CHARACTERISTICS_SRGB */
|
||||||
transfer_to_save = (avifTransferCharacteristics)13;
|
transfer_to_save = (avifTransferCharacteristics)13;
|
||||||
break;
|
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:
|
default:
|
||||||
/* AVIF_TRANSFER_CHARACTERISTICS_UNSPECIFIED */
|
/* AVIF_TRANSFER_CHARACTERISTICS_UNSPECIFIED */
|
||||||
transfer_to_save = (avifTransferCharacteristics)2;
|
transfer_to_save = (avifTransferCharacteristics)2;
|
||||||
@ -792,6 +866,14 @@ bool QAVIFHandler::write(const QImage &image)
|
|||||||
case 5: // AVIF_TRANSFER_CHARACTERISTICS_BT470BG
|
case 5: // AVIF_TRANSFER_CHARACTERISTICS_BT470BG
|
||||||
tmpcolorimage.convertToColorSpace(QColorSpace(QColorSpace::Primaries::SRgb, 2.8f));
|
tmpcolorimage.convertToColorSpace(QColorSpace(QColorSpace::Primaries::SRgb, 2.8f));
|
||||||
break;
|
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
|
default: // AVIF_TRANSFER_CHARACTERISTICS_SRGB + any other
|
||||||
tmpcolorimage.convertToColorSpace(QColorSpace(QColorSpace::Primaries::SRgb, QColorSpace::TransferFunction::SRgb));
|
tmpcolorimage.convertToColorSpace(QColorSpace(QColorSpace::Primaries::SRgb, QColorSpace::TransferFunction::SRgb));
|
||||||
transfer_to_save = (avifTransferCharacteristics)13;
|
transfer_to_save = (avifTransferCharacteristics)13;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user