From 3353809906a443aea0d2789842dfd5b8bfb53b21 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Novomesk=C3=BD?= Date: Sun, 11 Jan 2026 15:03:06 +0100 Subject: [PATCH] jxl: fix crash on lossy gray images There was a rare crash during decoding of some lossy gray images. Problem was reported in https://github.com/libjxl/libjxl/issues/4549 This is a workaround which avoids JxlDecoderSetCms call. --- src/imageformats/jxl.cpp | 41 ++++++++++++++++++++++++---------------- 1 file changed, 25 insertions(+), 16 deletions(-) diff --git a/src/imageformats/jxl.cpp b/src/imageformats/jxl.cpp index 3ee13df..efdbe3f 100644 --- a/src/imageformats/jxl.cpp +++ b/src/imageformats/jxl.cpp @@ -258,14 +258,16 @@ bool QJpegXLHandler::countALLFrames() bool is_gray = m_basicinfo.num_color_channels == 1 && m_basicinfo.alpha_bits == 0; JxlColorEncoding color_encoding; if (m_basicinfo.uses_original_profile == JXL_FALSE && m_basicinfo.have_animation == JXL_FALSE) { - const JxlCmsInterface *jxlcms = JxlGetDefaultCms(); - if (jxlcms) { - status = JxlDecoderSetCms(m_decoder, *jxlcms); - if (status != JXL_DEC_SUCCESS) { - qCWarning(LOG_JXLPLUGIN, "JxlDecoderSetCms ERROR"); + if (!is_gray) { + const JxlCmsInterface *jxlcms = JxlGetDefaultCms(); + if (jxlcms) { + status = JxlDecoderSetCms(m_decoder, *jxlcms); + if (status != JXL_DEC_SUCCESS) { + qCWarning(LOG_JXLPLUGIN, "JxlDecoderSetCms ERROR"); + } + } else { + qCWarning(LOG_JXLPLUGIN, "No JPEG XL CMS Interface"); } - } else { - qCWarning(LOG_JXLPLUGIN, "No JPEG XL CMS Interface"); } JxlColorEncodingSetToSRGB(&color_encoding, is_gray ? JXL_TRUE : JXL_FALSE); @@ -853,7 +855,11 @@ bool QJpegXLHandler::write(const QImage &image) size_t pixel_count = size_t(image.width()) * image.height(); if (MAX_IMAGE_PIXELS && pixel_count > MAX_IMAGE_PIXELS) { - qCWarning(LOG_JXLPLUGIN, "Image (%dx%d) will not be saved because it has more than %d megapixels!", image.width(), image.height(), MAX_IMAGE_PIXELS / 1024 / 1024); + qCWarning(LOG_JXLPLUGIN, + "Image (%dx%d) will not be saved because it has more than %d megapixels!", + image.width(), + image.height(), + MAX_IMAGE_PIXELS / 1024 / 1024); return false; } @@ -1838,17 +1844,20 @@ bool QJpegXLHandler::rewind() return false; } - const JxlCmsInterface *jxlcms = JxlGetDefaultCms(); - if (jxlcms) { - status = JxlDecoderSetCms(m_decoder, *jxlcms); - if (status != JXL_DEC_SUCCESS) { - qCWarning(LOG_JXLPLUGIN, "JxlDecoderSetCms ERROR"); + bool is_gray = m_basicinfo.num_color_channels == 1 && m_basicinfo.alpha_bits == 0; + + if (!is_gray) { + const JxlCmsInterface *jxlcms = JxlGetDefaultCms(); + if (jxlcms) { + status = JxlDecoderSetCms(m_decoder, *jxlcms); + if (status != JXL_DEC_SUCCESS) { + qCWarning(LOG_JXLPLUGIN, "JxlDecoderSetCms ERROR"); + } + } else { + qCWarning(LOG_JXLPLUGIN, "No JPEG XL CMS Interface"); } - } else { - qCWarning(LOG_JXLPLUGIN, "No JPEG XL CMS Interface"); } - bool is_gray = m_basicinfo.num_color_channels == 1 && m_basicinfo.alpha_bits == 0; JxlColorEncoding color_encoding; JxlColorEncodingSetToSRGB(&color_encoding, is_gray ? JXL_TRUE : JXL_FALSE); JxlDecoderSetPreferredColorProfile(m_decoder, &color_encoding);