Script 'mail_helper' called by obssrc
Hello community,

here is the log from the commit of package kimageformats for openSUSE:Factory 
checked in at 2021-12-13 20:40:57
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/kimageformats (Old)
 and      /work/SRC/openSUSE:Factory/.kimageformats.new.2520 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "kimageformats"

Mon Dec 13 20:40:57 2021 rev:101 rq:939219 version:5.89.0

Changes:
--------
--- /work/SRC/openSUSE:Factory/kimageformats/kimageformats.changes      
2021-11-15 15:26:37.401827245 +0100
+++ /work/SRC/openSUSE:Factory/.kimageformats.new.2520/kimageformats.changes    
2021-12-13 20:44:20.476484673 +0100
@@ -1,0 +2,12 @@
+Sat Dec  4 22:56:42 UTC 2021 - Christophe Giboudeaux <christo...@krop.fr>
+
+- Update to 5.89.0
+  * New feature release
+  * For more details please see:
+  * https://kde.org/announcements/frameworks/5/5.89.0
+- Changes since 5.88.0:
+  * avif: limit scope of variables
+  * Add JXL to the list of supported formats
+  * Add plugin for JPEG XL (JXL)
+
+-------------------------------------------------------------------

Old:
----
  kimageformats-5.88.0.tar.xz
  kimageformats-5.88.0.tar.xz.sig

New:
----
  kimageformats-5.89.0.tar.xz
  kimageformats-5.89.0.tar.xz.sig

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ kimageformats.spec ++++++
--- /var/tmp/diff_new_pack.ZDz8sY/_old  2021-12-13 20:44:21.268484771 +0100
+++ /var/tmp/diff_new_pack.ZDz8sY/_new  2021-12-13 20:44:21.280484772 +0100
@@ -22,7 +22,7 @@
 %if 0%{?suse_version} > 1500 || (0%{?is_opensuse} && 0%{?sle_version} >= 
150300)
 %define with_heif 1
 %endif
-%define _tar_path 5.88
+%define _tar_path 5.89
 # Full KF5 version (e.g. 5.33.0)
 %{!?_kf5_version: %global _kf5_version %{version}}
 # Last major and minor KF5 version (e.g. 5.33)
@@ -30,7 +30,7 @@
 # Only needed for the package signature condition
 %bcond_without lang
 Name:           kimageformats
-Version:        5.88.0
+Version:        5.89.0
 Release:        0
 Summary:        Image format plugins for Qt
 License:        LGPL-2.1-or-later


++++++ kimageformats-5.88.0.tar.xz -> kimageformats-5.89.0.tar.xz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/kimageformats-5.88.0/CMakeLists.txt 
new/kimageformats-5.89.0/CMakeLists.txt
--- old/kimageformats-5.88.0/CMakeLists.txt     2021-10-07 00:28:35.000000000 
+0200
+++ new/kimageformats-5.89.0/CMakeLists.txt     2021-12-04 18:00:59.000000000 
+0100
@@ -3,7 +3,7 @@
 project(KImageFormats)
 
 include(FeatureSummary)
-find_package(ECM 5.87.0  NO_MODULE)
+find_package(ECM 5.89.0  NO_MODULE)
 set_package_properties(ECM PROPERTIES TYPE REQUIRED DESCRIPTION "Extra CMake 
Modules." URL "https://commits.kde.org/extra-cmake-modules";)
 feature_summary(WHAT REQUIRED_PACKAGES_NOT_FOUND 
FATAL_ON_MISSING_REQUIRED_PACKAGES)
 
@@ -17,6 +17,7 @@
 
 
 include(CheckIncludeFiles)
+include(FindPkgConfig)
 
 set(REQUIRED_QT_VERSION 5.15.2)
 find_package(Qt5Gui ${REQUIRED_QT_VERSION} REQUIRED NO_MODULE)
@@ -58,11 +59,17 @@
 
 option(KIMAGEFORMATS_HEIF "Enable plugin for HEIF format" OFF)
 if(KIMAGEFORMATS_HEIF)
-    include(FindPkgConfig)
     pkg_check_modules(LibHeif IMPORTED_TARGET libheif>=1.10.0)
 endif()
 add_feature_info(LibHeif LibHeif_FOUND "required for the QImage plugin for 
HEIF/HEIC images")
 
+option(KIMAGEFORMATS_JXL "Enable plugin for JPEG XL format" ON)
+if(KIMAGEFORMATS_JXL)
+    pkg_check_modules(LibJXL IMPORTED_TARGET libjxl>=0.6.1)
+    pkg_check_modules(LibJXLThreads IMPORTED_TARGET libjxl_threads>=0.6.1)
+endif()
+add_feature_info(LibJXL LibJXL_FOUND "required for the QImage plugin for JPEG 
XL images")
+
 # 050d00 (5.13) triggers a BIC in qimageiohandler.h, in Qt 5.13, so do not 
enable that until we can require 5.14
 # https://codereview.qt-project.org/c/qt/qtbase/+/279215
 add_definitions(-DQT_DISABLE_DEPRECATED_BEFORE=0x050f02)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/kimageformats-5.88.0/LICENSES/CC0-1.0.txt 
new/kimageformats-5.89.0/LICENSES/CC0-1.0.txt
--- old/kimageformats-5.88.0/LICENSES/CC0-1.0.txt       1970-01-01 
01:00:00.000000000 +0100
+++ new/kimageformats-5.89.0/LICENSES/CC0-1.0.txt       2021-12-04 
18:00:59.000000000 +0100
@@ -0,0 +1,121 @@
+Creative Commons Legal Code
+
+CC0 1.0 Universal
+
+    CREATIVE COMMONS CORPORATION IS NOT A LAW FIRM AND DOES NOT PROVIDE
+    LEGAL SERVICES. DISTRIBUTION OF THIS DOCUMENT DOES NOT CREATE AN
+    ATTORNEY-CLIENT RELATIONSHIP. CREATIVE COMMONS PROVIDES THIS
+    INFORMATION ON AN "AS-IS" BASIS. CREATIVE COMMONS MAKES NO WARRANTIES
+    REGARDING THE USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS
+    PROVIDED HEREUNDER, AND DISCLAIMS LIABILITY FOR DAMAGES RESULTING FROM
+    THE USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS PROVIDED
+    HEREUNDER.
+
+Statement of Purpose
+
+The laws of most jurisdictions throughout the world automatically confer
+exclusive Copyright and Related Rights (defined below) upon the creator
+and subsequent owner(s) (each and all, an "owner") of an original work of
+authorship and/or a database (each, a "Work").
+
+Certain owners wish to permanently relinquish those rights to a Work for
+the purpose of contributing to a commons of creative, cultural and
+scientific works ("Commons") that the public can reliably and without fear
+of later claims of infringement build upon, modify, incorporate in other
+works, reuse and redistribute as freely as possible in any form whatsoever
+and for any purposes, including without limitation commercial purposes.
+These owners may contribute to the Commons to promote the ideal of a free
+culture and the further production of creative, cultural and scientific
+works, or to gain reputation or greater distribution for their Work in
+part through the use and efforts of others.
+
+For these and/or other purposes and motivations, and without any
+expectation of additional consideration or compensation, the person
+associating CC0 with a Work (the "Affirmer"), to the extent that he or she
+is an owner of Copyright and Related Rights in the Work, voluntarily
+elects to apply CC0 to the Work and publicly distribute the Work under its
+terms, with knowledge of his or her Copyright and Related Rights in the
+Work and the meaning and intended legal effect of CC0 on those rights.
+
+1. Copyright and Related Rights. A Work made available under CC0 may be
+protected by copyright and related or neighboring rights ("Copyright and
+Related Rights"). Copyright and Related Rights include, but are not
+limited to, the following:
+
+  i. the right to reproduce, adapt, distribute, perform, display,
+     communicate, and translate a Work;
+ ii. moral rights retained by the original author(s) and/or performer(s);
+iii. publicity and privacy rights pertaining to a person's image or
+     likeness depicted in a Work;
+ iv. rights protecting against unfair competition in regards to a Work,
+     subject to the limitations in paragraph 4(a), below;
+  v. rights protecting the extraction, dissemination, use and reuse of data
+     in a Work;
+ vi. database rights (such as those arising under Directive 96/9/EC of the
+     European Parliament and of the Council of 11 March 1996 on the legal
+     protection of databases, and under any national implementation
+     thereof, including any amended or successor version of such
+     directive); and
+vii. other similar, equivalent or corresponding rights throughout the
+     world based on applicable law or treaty, and any national
+     implementations thereof.
+
+2. Waiver. To the greatest extent permitted by, but not in contravention
+of, applicable law, Affirmer hereby overtly, fully, permanently,
+irrevocably and unconditionally waives, abandons, and surrenders all of
+Affirmer's Copyright and Related Rights and associated claims and causes
+of action, whether now known or unknown (including existing as well as
+future claims and causes of action), in the Work (i) in all territories
+worldwide, (ii) for the maximum duration provided by applicable law or
+treaty (including future time extensions), (iii) in any current or future
+medium and for any number of copies, and (iv) for any purpose whatsoever,
+including without limitation commercial, advertising or promotional
+purposes (the "Waiver"). Affirmer makes the Waiver for the benefit of each
+member of the public at large and to the detriment of Affirmer's heirs and
+successors, fully intending that such Waiver shall not be subject to
+revocation, rescission, cancellation, termination, or any other legal or
+equitable action to disrupt the quiet enjoyment of the Work by the public
+as contemplated by Affirmer's express Statement of Purpose.
+
+3. Public License Fallback. Should any part of the Waiver for any reason
+be judged legally invalid or ineffective under applicable law, then the
+Waiver shall be preserved to the maximum extent permitted taking into
+account Affirmer's express Statement of Purpose. In addition, to the
+extent the Waiver is so judged Affirmer hereby grants to each affected
+person a royalty-free, non transferable, non sublicensable, non exclusive,
+irrevocable and unconditional license to exercise Affirmer's Copyright and
+Related Rights in the Work (i) in all territories worldwide, (ii) for the
+maximum duration provided by applicable law or treaty (including future
+time extensions), (iii) in any current or future medium and for any number
+of copies, and (iv) for any purpose whatsoever, including without
+limitation commercial, advertising or promotional purposes (the
+"License"). The License shall be deemed effective as of the date CC0 was
+applied by Affirmer to the Work. Should any part of the License for any
+reason be judged legally invalid or ineffective under applicable law, such
+partial invalidity or ineffectiveness shall not invalidate the remainder
+of the License, and in such case Affirmer hereby affirms that he or she
+will not (i) exercise any of his or her remaining Copyright and Related
+Rights in the Work or (ii) assert any associated claims and causes of
+action with respect to the Work, in either case contrary to Affirmer's
+express Statement of Purpose.
+
+4. Limitations and Disclaimers.
+
+ a. No trademark or patent rights held by Affirmer are waived, abandoned,
+    surrendered, licensed or otherwise affected by this document.
+ b. Affirmer offers the Work as-is and makes no representations or
+    warranties of any kind concerning the Work, express, implied,
+    statutory or otherwise, including without limitation warranties of
+    title, merchantability, fitness for a particular purpose, non
+    infringement, or the absence of latent or other defects, accuracy, or
+    the present or absence of errors, whether or not discoverable, all to
+    the greatest extent permissible under applicable law.
+ c. Affirmer disclaims responsibility for clearing rights of other persons
+    that may apply to the Work or any use thereof, including without
+    limitation any person's Copyright and Related Rights in the Work.
+    Further, Affirmer disclaims responsibility for obtaining any necessary
+    consents, permissions or other rights required for any use of the
+    Work.
+ d. Affirmer understands and acknowledges that Creative Commons is not a
+    party to this document and has no duty or obligation with respect to
+    this CC0 or use of the Work.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/kimageformats-5.88.0/README.md 
new/kimageformats-5.89.0/README.md
--- old/kimageformats-5.88.0/README.md  2021-10-07 00:28:35.000000000 +0200
+++ new/kimageformats-5.89.0/README.md  2021-12-04 18:00:59.000000000 +0100
@@ -23,6 +23,7 @@
 
 - AV1 Image File Format (AVIF)
 - Encapsulated PostScript (eps)
+- JPEG XL (jxl)
 - Personal Computer Exchange (pcx)
 - SGI images (rgb, rgba, sgi, bw)
 - Softimage PIC (pic)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/kimageformats-5.88.0/autotests/CMakeLists.txt 
new/kimageformats-5.89.0/autotests/CMakeLists.txt
--- old/kimageformats-5.88.0/autotests/CMakeLists.txt   2021-10-07 
00:28:35.000000000 +0200
+++ new/kimageformats-5.89.0/autotests/CMakeLists.txt   2021-12-04 
18:00:59.000000000 +0100
@@ -82,6 +82,12 @@
     )
 endif()
 
+if (LibJXL_FOUND AND LibJXLThreads_FOUND)
+    kimageformats_read_tests(
+        jxl
+    )
+endif()
+
 # Allow some fuzziness when reading this formats, to allow for
 # rounding errors (eg: in alpha blending).
 kimageformats_read_tests(FUZZ 1
Binary files old/kimageformats-5.88.0/autotests/read/jxl/rgb.jxl and 
new/kimageformats-5.89.0/autotests/read/jxl/rgb.jxl differ
Binary files old/kimageformats-5.88.0/autotests/read/jxl/rgb.png and 
new/kimageformats-5.89.0/autotests/read/jxl/rgb.png differ
Binary files old/kimageformats-5.88.0/autotests/read/jxl/rgba.jxl and 
new/kimageformats-5.89.0/autotests/read/jxl/rgba.jxl differ
Binary files old/kimageformats-5.88.0/autotests/read/jxl/rgba.png and 
new/kimageformats-5.89.0/autotests/read/jxl/rgba.png differ
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/kimageformats-5.88.0/src/imageformats/CMakeLists.txt 
new/kimageformats-5.89.0/src/imageformats/CMakeLists.txt
--- old/kimageformats-5.88.0/src/imageformats/CMakeLists.txt    2021-10-07 
00:28:35.000000000 +0200
+++ new/kimageformats-5.89.0/src/imageformats/CMakeLists.txt    2021-12-04 
18:00:59.000000000 +0100
@@ -83,6 +83,14 @@
 
 ##################################
 
+if (LibJXL_FOUND AND LibJXLThreads_FOUND)
+    kimageformats_add_plugin(kimg_jxl SOURCES jxl.cpp)
+    target_link_libraries(kimg_jxl PkgConfig::LibJXL PkgConfig::LibJXLThreads)
+    install(FILES jxl.desktop DESTINATION 
${KDE_INSTALL_KSERVICES5DIR}/qimageioplugins/)
+endif()
+
+##################################
+
 kimageformats_add_plugin(kimg_pcx SOURCES pcx.cpp)
 install(FILES pcx.desktop DESTINATION 
${KDE_INSTALL_KSERVICES5DIR}/qimageioplugins/)
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/kimageformats-5.88.0/src/imageformats/avif.cpp 
new/kimageformats-5.89.0/src/imageformats/avif.cpp
--- old/kimageformats-5.88.0/src/imageformats/avif.cpp  2021-10-07 
00:28:35.000000000 +0200
+++ new/kimageformats-5.89.0/src/imageformats/avif.cpp  2021-12-04 
18:00:59.000000000 +0100
@@ -318,27 +318,27 @@
     if (m_decoder->image->transformFlags & AVIF_TRANSFORM_CLAP) {
         if ((m_decoder->image->clap.widthD > 0) && 
(m_decoder->image->clap.heightD > 0) && (m_decoder->image->clap.horizOffD > 0)
             && (m_decoder->image->clap.vertOffD > 0)) {
-            int new_width, new_height, offx, offy;
-
-            new_width = (int)((double)(m_decoder->image->clap.widthN) / 
(m_decoder->image->clap.widthD) + 0.5);
+            int new_width = (int)((double)(m_decoder->image->clap.widthN) / 
(m_decoder->image->clap.widthD) + 0.5);
             if (new_width > result.width()) {
                 new_width = result.width();
             }
 
-            new_height = (int)((double)(m_decoder->image->clap.heightN) / 
(m_decoder->image->clap.heightD) + 0.5);
+            int new_height = (int)((double)(m_decoder->image->clap.heightN) / 
(m_decoder->image->clap.heightD) + 0.5);
             if (new_height > result.height()) {
                 new_height = result.height();
             }
 
             if (new_width > 0 && new_height > 0) {
-                offx = ((double)((int32_t)m_decoder->image->clap.horizOffN)) / 
(m_decoder->image->clap.horizOffD) + (result.width() - new_width) / 2.0 + 0.5;
+                int offx =
+                    ((double)((int32_t)m_decoder->image->clap.horizOffN)) / 
(m_decoder->image->clap.horizOffD) + (result.width() - new_width) / 2.0 + 0.5;
                 if (offx < 0) {
                     offx = 0;
                 } else if (offx > (result.width() - new_width)) {
                     offx = result.width() - new_width;
                 }
 
-                offy = ((double)((int32_t)m_decoder->image->clap.vertOffN)) / 
(m_decoder->image->clap.vertOffD) + (result.height() - new_height) / 2.0 + 0.5;
+                int offy =
+                    ((double)((int32_t)m_decoder->image->clap.vertOffN)) / 
(m_decoder->image->clap.vertOffD) + (result.height() - new_height) / 2.0 + 0.5;
                 if (offy < 0) {
                     offy = 0;
                 } else if (offy > (result.height() - new_height)) {
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/kimageformats-5.88.0/src/imageformats/jxl.cpp 
new/kimageformats-5.89.0/src/imageformats/jxl.cpp
--- old/kimageformats-5.88.0/src/imageformats/jxl.cpp   1970-01-01 
01:00:00.000000000 +0100
+++ new/kimageformats-5.89.0/src/imageformats/jxl.cpp   2021-12-04 
18:00:59.000000000 +0100
@@ -0,0 +1,876 @@
+/*
+    JPEG XL (JXL) support for QImage.
+
+    SPDX-FileCopyrightText: 2021 Daniel Novomesky <dnovome...@gmail.com>
+
+    SPDX-License-Identifier: BSD-2-Clause
+*/
+
+#include <QThread>
+#include <QtGlobal>
+
+#include "jxl_p.h"
+#include <jxl/encode.h>
+#include <jxl/thread_parallel_runner.h>
+
+QJpegXLHandler::QJpegXLHandler()
+    : m_parseState(ParseJpegXLNotParsed)
+    , m_quality(90)
+    , m_currentimage_index(0)
+    , m_previousimage_index(-1)
+    , m_decoder(nullptr)
+    , m_runner(nullptr)
+    , m_next_image_delay(0)
+    , m_input_image_format(QImage::Format_Invalid)
+    , m_target_image_format(QImage::Format_Invalid)
+    , m_buffer_size(0)
+{
+}
+
+QJpegXLHandler::~QJpegXLHandler()
+{
+    if (m_runner) {
+        JxlThreadParallelRunnerDestroy(m_runner);
+    }
+    if (m_decoder) {
+        JxlDecoderDestroy(m_decoder);
+    }
+}
+
+bool QJpegXLHandler::canRead() const
+{
+    if (m_parseState == ParseJpegXLNotParsed && !canRead(device())) {
+        return false;
+    }
+
+    if (m_parseState != ParseJpegXLError) {
+        setFormat("jxl");
+        return true;
+    }
+    return false;
+}
+
+bool QJpegXLHandler::canRead(QIODevice *device)
+{
+    if (!device) {
+        return false;
+    }
+    QByteArray header = device->peek(32);
+    if (header.size() < 12) {
+        return false;
+    }
+
+    JxlSignature signature = JxlSignatureCheck((const uint8_t 
*)header.constData(), header.size());
+    if (signature == JXL_SIG_CODESTREAM || signature == JXL_SIG_CONTAINER) {
+        return true;
+    }
+    return false;
+}
+
+bool QJpegXLHandler::ensureParsed() const
+{
+    if (m_parseState == ParseJpegXLSuccess || m_parseState == 
ParseJpegXLBasicInfoParsed) {
+        return true;
+    }
+    if (m_parseState == ParseJpegXLError) {
+        return false;
+    }
+
+    QJpegXLHandler *that = const_cast<QJpegXLHandler *>(this);
+
+    return that->ensureDecoder();
+}
+
+bool QJpegXLHandler::ensureALLCounted() const
+{
+    if (!ensureParsed()) {
+        return false;
+    }
+
+    if (m_parseState == ParseJpegXLSuccess) {
+        return true;
+    }
+
+    QJpegXLHandler *that = const_cast<QJpegXLHandler *>(this);
+
+    return that->countALLFrames();
+}
+
+bool QJpegXLHandler::ensureDecoder()
+{
+    if (m_decoder) {
+        return true;
+    }
+
+    m_rawData = device()->readAll();
+
+    if (m_rawData.isEmpty()) {
+        return false;
+    }
+
+    JxlSignature signature = JxlSignatureCheck((const uint8_t 
*)m_rawData.constData(), m_rawData.size());
+    if (signature != JXL_SIG_CODESTREAM && signature != JXL_SIG_CONTAINER) {
+        m_parseState = ParseJpegXLError;
+        return false;
+    }
+
+    m_decoder = JxlDecoderCreate(nullptr);
+    if (!m_decoder) {
+        qWarning("ERROR: JxlDecoderCreate failed");
+        m_parseState = ParseJpegXLError;
+        return false;
+    }
+
+    int num_worker_threads = QThread::idealThreadCount();
+    if (!m_runner && num_worker_threads >= 4) {
+        /* use half of the threads because plug-in is usually used in 
environment
+         * where application performs another tasks in backround (pre-load 
other images) */
+        num_worker_threads = num_worker_threads / 2;
+        num_worker_threads = qBound(2, num_worker_threads, 64);
+        m_runner = JxlThreadParallelRunnerCreate(nullptr, num_worker_threads);
+
+        if (JxlDecoderSetParallelRunner(m_decoder, JxlThreadParallelRunner, 
m_runner) != JXL_DEC_SUCCESS) {
+            qWarning("ERROR: JxlDecoderSetParallelRunner failed");
+            m_parseState = ParseJpegXLError;
+            return false;
+        }
+    }
+
+    if (JxlDecoderSetInput(m_decoder, (const uint8_t *)m_rawData.constData(), 
m_rawData.size()) != JXL_DEC_SUCCESS) {
+        qWarning("ERROR: JxlDecoderSetInput failed");
+        m_parseState = ParseJpegXLError;
+        return false;
+    }
+
+    JxlDecoderStatus status = JxlDecoderSubscribeEvents(m_decoder, 
JXL_DEC_BASIC_INFO | JXL_DEC_COLOR_ENCODING | JXL_DEC_FRAME);
+    if (status == JXL_DEC_ERROR) {
+        qWarning("ERROR: JxlDecoderSubscribeEvents failed");
+        m_parseState = ParseJpegXLError;
+        return false;
+    }
+
+    status = JxlDecoderProcessInput(m_decoder);
+    if (status == JXL_DEC_ERROR) {
+        qWarning("ERROR: JXL decoding failed");
+        m_parseState = ParseJpegXLError;
+        return false;
+    }
+    if (status == JXL_DEC_NEED_MORE_INPUT) {
+        qWarning("ERROR: JXL data incomplete");
+        m_parseState = ParseJpegXLError;
+        return false;
+    }
+
+    status = JxlDecoderGetBasicInfo(m_decoder, &m_basicinfo);
+    if (status != JXL_DEC_SUCCESS) {
+        qWarning("ERROR: JXL basic info not available");
+        m_parseState = ParseJpegXLError;
+        return false;
+    }
+
+    if (m_basicinfo.xsize == 0 || m_basicinfo.ysize == 0) {
+        qWarning("ERROR: JXL image has zero dimensions");
+        m_parseState = ParseJpegXLError;
+        return false;
+    }
+
+    if (m_basicinfo.xsize > 32768 || m_basicinfo.ysize > 32768) {
+        qWarning("JXL image (%dx%d) is too large", m_basicinfo.xsize, 
m_basicinfo.ysize);
+        m_parseState = ParseJpegXLError;
+        return false;
+    } else if (sizeof(void *) <= 4) {
+        /* On 32bit systems, there is limited address space.
+         * We skip imagess bigger than 8192 x 8192 pixels.
+         * If we don't do it, abort() in libjxl may close whole application */
+        if ((m_basicinfo.xsize * m_basicinfo.ysize) > 67108864) {
+            qWarning("JXL image (%dx%d) is too large for 32bit build of the 
plug-in", m_basicinfo.xsize, m_basicinfo.ysize);
+            m_parseState = ParseJpegXLError;
+            return false;
+        }
+    }
+
+    m_parseState = ParseJpegXLBasicInfoParsed;
+    return true;
+}
+
+bool QJpegXLHandler::countALLFrames()
+{
+    if (m_parseState != ParseJpegXLBasicInfoParsed) {
+        return false;
+    }
+
+    JxlDecoderStatus status = JxlDecoderProcessInput(m_decoder);
+    if (status != JXL_DEC_COLOR_ENCODING) {
+        qWarning("Unexpected event %d instead of JXL_DEC_COLOR_ENCODING", 
status);
+        m_parseState = ParseJpegXLError;
+        return false;
+    }
+
+    JxlColorEncoding color_encoding;
+    if (m_basicinfo.uses_original_profile == JXL_FALSE) {
+        JxlColorEncodingSetToSRGB(&color_encoding, JXL_FALSE);
+        JxlDecoderSetPreferredColorProfile(m_decoder, &color_encoding);
+    }
+
+    bool loadalpha;
+
+    if (m_basicinfo.alpha_bits > 0) {
+        loadalpha = true;
+    } else {
+        loadalpha = false;
+    }
+
+    m_input_pixel_format.endianness = JXL_NATIVE_ENDIAN;
+    m_input_pixel_format.align = 0;
+    m_input_pixel_format.num_channels = 4;
+
+    if (m_basicinfo.bits_per_sample > 8) { // high bit depth
+        m_input_pixel_format.data_type = JXL_TYPE_UINT16;
+        m_buffer_size = 8 * (size_t)m_basicinfo.xsize * 
(size_t)m_basicinfo.ysize;
+        m_input_image_format = QImage::Format_RGBA64;
+
+        if (loadalpha) {
+            m_target_image_format = QImage::Format_RGBA64;
+        } else {
+            m_target_image_format = QImage::Format_RGBX64;
+        }
+    } else { // 8bit depth
+        m_input_pixel_format.data_type = JXL_TYPE_UINT8;
+        m_buffer_size = 4 * (size_t)m_basicinfo.xsize * 
(size_t)m_basicinfo.ysize;
+        m_input_image_format = QImage::Format_RGBA8888;
+
+        if (loadalpha) {
+            m_target_image_format = QImage::Format_ARGB32;
+        } else {
+            m_target_image_format = QImage::Format_RGB32;
+        }
+    }
+
+    status = JxlDecoderGetColorAsEncodedProfile(m_decoder, 
&m_input_pixel_format, JXL_COLOR_PROFILE_TARGET_DATA, &color_encoding);
+
+    if (status == JXL_DEC_SUCCESS && color_encoding.color_space == 
JXL_COLOR_SPACE_RGB && color_encoding.white_point == JXL_WHITE_POINT_D65
+        && color_encoding.primaries == JXL_PRIMARIES_SRGB && 
color_encoding.transfer_function == JXL_TRANSFER_FUNCTION_SRGB) {
+        m_colorspace = QColorSpace(QColorSpace::SRgb);
+    } else {
+        size_t icc_size = 0;
+        if (JxlDecoderGetICCProfileSize(m_decoder, &m_input_pixel_format, 
JXL_COLOR_PROFILE_TARGET_DATA, &icc_size) == JXL_DEC_SUCCESS) {
+            if (icc_size > 0) {
+                QByteArray icc_data((int)icc_size, 0);
+                if (JxlDecoderGetColorAsICCProfile(m_decoder, 
&m_input_pixel_format, JXL_COLOR_PROFILE_TARGET_DATA, (uint8_t 
*)icc_data.data(), icc_data.size())
+                    == JXL_DEC_SUCCESS) {
+                    m_colorspace = QColorSpace::fromIccProfile(icc_data);
+
+                    if (!m_colorspace.isValid()) {
+                        qWarning("JXL image has Qt-unsupported or invalid ICC 
profile!");
+                    }
+                } else {
+                    qWarning("Failed to obtain data from JPEG XL decoder");
+                }
+            } else {
+                qWarning("Empty ICC data");
+            }
+        } else {
+            qWarning("no ICC, other color profile");
+        }
+    }
+
+    if (m_basicinfo.have_animation) { // count all frames
+        JxlFrameHeader frame_header;
+        int delay;
+
+        for (status = JxlDecoderProcessInput(m_decoder); status != 
JXL_DEC_SUCCESS; status = JxlDecoderProcessInput(m_decoder)) {
+            if (status != JXL_DEC_FRAME) {
+                switch (status) {
+                case JXL_DEC_ERROR:
+                    qWarning("ERROR: JXL decoding failed");
+                    break;
+                case JXL_DEC_NEED_MORE_INPUT:
+                    qWarning("ERROR: JXL data incomplete");
+                    break;
+                default:
+                    qWarning("Unexpected event %d instead of JXL_DEC_FRAME", 
status);
+                    break;
+                }
+                m_parseState = ParseJpegXLError;
+                return false;
+            }
+
+            if (JxlDecoderGetFrameHeader(m_decoder, &frame_header) != 
JXL_DEC_SUCCESS) {
+                qWarning("ERROR: JxlDecoderGetFrameHeader failed");
+                m_parseState = ParseJpegXLError;
+                return false;
+            }
+
+            if (m_basicinfo.animation.tps_denominator > 0 && 
m_basicinfo.animation.tps_numerator > 0) {
+                delay = (int)(0.5 + 1000.0 * frame_header.duration * 
m_basicinfo.animation.tps_denominator / m_basicinfo.animation.tps_numerator);
+            } else {
+                delay = 0;
+            }
+
+            m_framedelays.append(delay);
+        }
+
+        if (m_framedelays.isEmpty()) {
+            qWarning("no frames loaded by the JXL plug-in");
+            m_parseState = ParseJpegXLError;
+            return false;
+        }
+
+        if (m_framedelays.count() == 1) {
+            qWarning("JXL file was marked as animation but it has only one 
frame.");
+            m_basicinfo.have_animation = JXL_FALSE;
+        }
+    } else { // static picture
+        m_framedelays.resize(1);
+        m_framedelays[0] = 0;
+    }
+
+    if (!rewind()) {
+        return false;
+    }
+
+    m_next_image_delay = m_framedelays[0];
+    m_parseState = ParseJpegXLSuccess;
+    return true;
+}
+
+bool QJpegXLHandler::decode_one_frame()
+{
+    JxlDecoderStatus status = JxlDecoderProcessInput(m_decoder);
+    if (status != JXL_DEC_NEED_IMAGE_OUT_BUFFER) {
+        qWarning("Unexpected event %d instead of 
JXL_DEC_NEED_IMAGE_OUT_BUFFER", status);
+        m_parseState = ParseJpegXLError;
+        return false;
+    }
+
+    m_current_image = QImage(m_basicinfo.xsize, m_basicinfo.ysize, 
m_input_image_format);
+    if (m_current_image.isNull()) {
+        qWarning("Memory cannot be allocated");
+        m_parseState = ParseJpegXLError;
+        return false;
+    }
+
+    m_current_image.setColorSpace(m_colorspace);
+
+    if (JxlDecoderSetImageOutBuffer(m_decoder, &m_input_pixel_format, 
m_current_image.bits(), m_buffer_size) != JXL_DEC_SUCCESS) {
+        qWarning("ERROR: JxlDecoderSetImageOutBuffer failed");
+        m_parseState = ParseJpegXLError;
+        return false;
+    }
+
+    status = JxlDecoderProcessInput(m_decoder);
+    if (status != JXL_DEC_FULL_IMAGE) {
+        qWarning("Unexpected event %d instead of JXL_DEC_FULL_IMAGE", status);
+        m_parseState = ParseJpegXLError;
+        return false;
+    }
+
+    if (m_target_image_format != m_input_image_format) {
+        m_current_image.convertTo(m_target_image_format);
+    }
+
+    m_next_image_delay = m_framedelays[m_currentimage_index];
+    m_previousimage_index = m_currentimage_index;
+
+    if (m_framedelays.count() > 1) {
+        m_currentimage_index++;
+
+        if (m_currentimage_index >= m_framedelays.count()) {
+            if (!rewind()) {
+                return false;
+            }
+        }
+    }
+
+    return true;
+}
+
+bool QJpegXLHandler::read(QImage *image)
+{
+    if (!ensureALLCounted()) {
+        return false;
+    }
+
+    if (m_currentimage_index == m_previousimage_index) {
+        *image = m_current_image;
+        return jumpToNextImage();
+    }
+
+    if (decode_one_frame()) {
+        *image = m_current_image;
+        return true;
+    } else {
+        return false;
+    }
+}
+
+bool QJpegXLHandler::write(const QImage &image)
+{
+    if (image.format() == QImage::Format_Invalid) {
+        qWarning("No image data to save");
+        return false;
+    }
+
+    if ((image.width() > 32768) || (image.height() > 32768)) {
+        qWarning("Image is too large");
+        return false;
+    }
+
+    JxlEncoder *encoder = JxlEncoderCreate(nullptr);
+    if (!encoder) {
+        qWarning("Failed to create Jxl encoder");
+        return false;
+    }
+
+    void *runner = nullptr;
+    int num_worker_threads = qBound(1, QThread::idealThreadCount(), 64);
+
+    if (num_worker_threads > 1) {
+        runner = JxlThreadParallelRunnerCreate(nullptr, num_worker_threads);
+        if (JxlEncoderSetParallelRunner(encoder, JxlThreadParallelRunner, 
runner) != JXL_ENC_SUCCESS) {
+            qWarning("JxlEncoderSetParallelRunner failed");
+            JxlThreadParallelRunnerDestroy(runner);
+            JxlEncoderDestroy(encoder);
+            return false;
+        }
+    }
+
+    JxlEncoderOptions *encoder_options = JxlEncoderOptionsCreate(encoder, 
nullptr);
+
+    if (m_quality > 100) {
+        m_quality = 100;
+    } else if (m_quality < 0) {
+        m_quality = 90;
+    }
+
+    JxlEncoderOptionsSetDistance(encoder_options, (100.0f - m_quality) / 
10.0f);
+
+    JxlEncoderOptionsSetLossless(encoder_options, (m_quality == 100) ? 
JXL_TRUE : JXL_FALSE);
+
+    JxlBasicInfo output_info;
+    JxlEncoderInitBasicInfo(&output_info);
+
+    JxlColorEncoding color_profile;
+    JxlColorEncodingSetToSRGB(&color_profile, JXL_FALSE);
+
+    bool convert_color_profile;
+    QByteArray iccprofile;
+
+    if (image.colorSpace().isValid()) {
+        if (image.colorSpace().primaries() != QColorSpace::Primaries::SRgb || 
image.colorSpace().transferFunction() != QColorSpace::TransferFunction::SRgb) {
+            convert_color_profile = true;
+        } else {
+            convert_color_profile = false;
+        }
+    } else { // no profile or Qt-unsupported ICC profile
+        convert_color_profile = false;
+        iccprofile = image.colorSpace().iccProfile();
+        if (iccprofile.size() > 0) {
+            output_info.uses_original_profile = 1;
+        }
+    }
+
+    JxlPixelFormat pixel_format;
+    QImage::Format tmpformat;
+    JxlEncoderStatus status;
+
+    pixel_format.data_type = JXL_TYPE_UINT16;
+    pixel_format.endianness = JXL_NATIVE_ENDIAN;
+    pixel_format.align = 0;
+
+    if (image.hasAlphaChannel()) {
+        tmpformat = QImage::Format_RGBA64;
+        pixel_format.num_channels = 4;
+        output_info.alpha_bits = 16;
+        output_info.num_extra_channels = 1;
+    } else {
+        tmpformat = QImage::Format_RGBX64;
+        pixel_format.num_channels = 3;
+        output_info.alpha_bits = 0;
+    }
+
+    const QImage tmpimage =
+        convert_color_profile ? 
image.convertToFormat(tmpformat).convertedToColorSpace(QColorSpace(QColorSpace::SRgb))
 : image.convertToFormat(tmpformat);
+
+    const size_t xsize = tmpimage.width();
+    const size_t ysize = tmpimage.height();
+    const size_t buffer_size = 2 * pixel_format.num_channels * xsize * ysize;
+
+    if (xsize == 0 || ysize == 0 || tmpimage.isNull()) {
+        qWarning("Unable to allocate memory for output image");
+        if (runner) {
+            JxlThreadParallelRunnerDestroy(runner);
+        }
+        JxlEncoderDestroy(encoder);
+        return false;
+    }
+
+    output_info.xsize = tmpimage.width();
+    output_info.ysize = tmpimage.height();
+    output_info.bits_per_sample = 16;
+    output_info.intensity_target = 255.0f;
+    output_info.orientation = JXL_ORIENT_IDENTITY;
+    output_info.num_color_channels = 3;
+    output_info.animation.tps_numerator = 10;
+    output_info.animation.tps_denominator = 1;
+
+    status = JxlEncoderSetBasicInfo(encoder, &output_info);
+    if (status != JXL_ENC_SUCCESS) {
+        qWarning("JxlEncoderSetBasicInfo failed!");
+        if (runner) {
+            JxlThreadParallelRunnerDestroy(runner);
+        }
+        JxlEncoderDestroy(encoder);
+        return false;
+    }
+
+    if (!convert_color_profile && iccprofile.size() > 0) {
+        status = JxlEncoderSetICCProfile(encoder, (const uint8_t 
*)iccprofile.constData(), iccprofile.size());
+        if (status != JXL_ENC_SUCCESS) {
+            qWarning("JxlEncoderSetICCProfile failed!");
+            if (runner) {
+                JxlThreadParallelRunnerDestroy(runner);
+            }
+            JxlEncoderDestroy(encoder);
+            return false;
+        }
+    } else {
+        status = JxlEncoderSetColorEncoding(encoder, &color_profile);
+        if (status != JXL_ENC_SUCCESS) {
+            qWarning("JxlEncoderSetColorEncoding failed!");
+            if (runner) {
+                JxlThreadParallelRunnerDestroy(runner);
+            }
+            JxlEncoderDestroy(encoder);
+            return false;
+        }
+    }
+
+    if (image.hasAlphaChannel()) {
+        status = JxlEncoderAddImageFrame(encoder_options, &pixel_format, (void 
*)tmpimage.constBits(), buffer_size);
+    } else {
+        uint16_t *tmp_buffer = new (std::nothrow) uint16_t[3 * xsize * ysize];
+        if (!tmp_buffer) {
+            qWarning("Memory allocation error");
+            if (runner) {
+                JxlThreadParallelRunnerDestroy(runner);
+            }
+            JxlEncoderDestroy(encoder);
+            return false;
+        }
+
+        uint16_t *dest_pixels = tmp_buffer;
+        for (int y = 0; y < tmpimage.height(); y++) {
+            const uint16_t *src_pixels = reinterpret_cast<const uint16_t 
*>(tmpimage.constScanLine(y));
+            for (int x = 0; x < tmpimage.width(); x++) {
+                // R
+                *dest_pixels = *src_pixels;
+                dest_pixels++;
+                src_pixels++;
+                // G
+                *dest_pixels = *src_pixels;
+                dest_pixels++;
+                src_pixels++;
+                // B
+                *dest_pixels = *src_pixels;
+                dest_pixels++;
+                src_pixels += 2; // skipalpha
+            }
+        }
+        status = JxlEncoderAddImageFrame(encoder_options, &pixel_format, (void 
*)tmp_buffer, buffer_size);
+        delete[] tmp_buffer;
+    }
+
+    if (status == JXL_ENC_ERROR) {
+        qWarning("JxlEncoderAddImageFrame failed!");
+        if (runner) {
+            JxlThreadParallelRunnerDestroy(runner);
+        }
+        JxlEncoderDestroy(encoder);
+        return false;
+    }
+
+    JxlEncoderCloseInput(encoder);
+
+    std::vector<uint8_t> compressed;
+    compressed.resize(4096);
+    size_t offset = 0;
+    uint8_t *next_out;
+    size_t avail_out;
+    do {
+        next_out = compressed.data() + offset;
+        avail_out = compressed.size() - offset;
+        status = JxlEncoderProcessOutput(encoder, &next_out, &avail_out);
+
+        if (status == JXL_ENC_NEED_MORE_OUTPUT) {
+            offset = next_out - compressed.data();
+            compressed.resize(compressed.size() * 2);
+        } else if (status == JXL_ENC_ERROR) {
+            qWarning("JxlEncoderProcessOutput failed!");
+            if (runner) {
+                JxlThreadParallelRunnerDestroy(runner);
+            }
+            JxlEncoderDestroy(encoder);
+            return false;
+        }
+    } while (status != JXL_ENC_SUCCESS);
+
+    if (runner) {
+        JxlThreadParallelRunnerDestroy(runner);
+    }
+    JxlEncoderDestroy(encoder);
+
+    compressed.resize(next_out - compressed.data());
+
+    if (compressed.size() > 0) {
+        qint64 write_status = device()->write((const char *)compressed.data(), 
compressed.size());
+
+        if (write_status > 0) {
+            return true;
+        } else if (write_status == -1) {
+            qWarning("Write error: %s\n", 
qUtf8Printable(device()->errorString()));
+        }
+    }
+
+    return false;
+}
+
+QVariant QJpegXLHandler::option(ImageOption option) const
+{
+    if (option == Quality) {
+        return m_quality;
+    }
+
+    if (!supportsOption(option) || !ensureParsed()) {
+        return QVariant();
+    }
+
+    switch (option) {
+    case Size:
+        return QSize(m_basicinfo.xsize, m_basicinfo.ysize);
+    case Animation:
+        if (m_basicinfo.have_animation) {
+            return true;
+        } else {
+            return false;
+        }
+    default:
+        return QVariant();
+    }
+}
+
+void QJpegXLHandler::setOption(ImageOption option, const QVariant &value)
+{
+    switch (option) {
+    case Quality:
+        m_quality = value.toInt();
+        if (m_quality > 100) {
+            m_quality = 100;
+        } else if (m_quality < 0) {
+            m_quality = 90;
+        }
+        return;
+    default:
+        break;
+    }
+    QImageIOHandler::setOption(option, value);
+}
+
+bool QJpegXLHandler::supportsOption(ImageOption option) const
+{
+    return option == Quality || option == Size || option == Animation;
+}
+
+int QJpegXLHandler::imageCount() const
+{
+    if (!ensureParsed()) {
+        return 0;
+    }
+
+    if (m_parseState == ParseJpegXLBasicInfoParsed) {
+        if (!m_basicinfo.have_animation) {
+            return 1;
+        }
+
+        if (!ensureALLCounted()) {
+            return 0;
+        }
+    }
+
+    if (!m_framedelays.isEmpty()) {
+        return m_framedelays.count();
+    }
+    return 0;
+}
+
+int QJpegXLHandler::currentImageNumber() const
+{
+    if (m_parseState == ParseJpegXLNotParsed) {
+        return -1;
+    }
+
+    if (m_parseState == ParseJpegXLError || m_parseState == 
ParseJpegXLBasicInfoParsed || !m_decoder) {
+        return 0;
+    }
+
+    return m_currentimage_index;
+}
+
+bool QJpegXLHandler::jumpToNextImage()
+{
+    if (!ensureALLCounted()) {
+        return false;
+    }
+
+    if (m_framedelays.count() > 1) {
+        m_currentimage_index++;
+
+        if (m_currentimage_index >= m_framedelays.count()) {
+            if (!rewind()) {
+                return false;
+            }
+        } else {
+            JxlDecoderSkipFrames(m_decoder, 1);
+        }
+    }
+
+    return true;
+}
+
+bool QJpegXLHandler::jumpToImage(int imageNumber)
+{
+    if (!ensureALLCounted()) {
+        return false;
+    }
+
+    if (imageNumber < 0 || imageNumber >= m_framedelays.count()) {
+        return false;
+    }
+
+    if (imageNumber == m_currentimage_index) {
+        return true;
+    }
+
+    if (imageNumber > m_currentimage_index) {
+        JxlDecoderSkipFrames(m_decoder, imageNumber - m_currentimage_index);
+        m_currentimage_index = imageNumber;
+        return true;
+    }
+
+    if (!rewind()) {
+        return false;
+    }
+
+    if (imageNumber > 0) {
+        JxlDecoderSkipFrames(m_decoder, imageNumber);
+    }
+    m_currentimage_index = imageNumber;
+    return true;
+}
+
+int QJpegXLHandler::nextImageDelay() const
+{
+    if (!ensureALLCounted()) {
+        return 0;
+    }
+
+    if (m_framedelays.count() < 2) {
+        return 0;
+    }
+
+    return m_next_image_delay;
+}
+
+int QJpegXLHandler::loopCount() const
+{
+    if (!ensureParsed()) {
+        return 0;
+    }
+
+    if (m_basicinfo.have_animation) {
+        return 1;
+    } else {
+        return 0;
+    }
+}
+
+bool QJpegXLHandler::rewind()
+{
+    m_currentimage_index = 0;
+
+    JxlDecoderReleaseInput(m_decoder);
+    JxlDecoderRewind(m_decoder);
+    if (m_runner) {
+        if (JxlDecoderSetParallelRunner(m_decoder, JxlThreadParallelRunner, 
m_runner) != JXL_DEC_SUCCESS) {
+            qWarning("ERROR: JxlDecoderSetParallelRunner failed");
+            m_parseState = ParseJpegXLError;
+            return false;
+        }
+    }
+
+    if (JxlDecoderSetInput(m_decoder, (const uint8_t *)m_rawData.constData(), 
m_rawData.size()) != JXL_DEC_SUCCESS) {
+        qWarning("ERROR: JxlDecoderSetInput failed");
+        m_parseState = ParseJpegXLError;
+        return false;
+    }
+
+    if (m_basicinfo.uses_original_profile) {
+        if (JxlDecoderSubscribeEvents(m_decoder, JXL_DEC_FULL_IMAGE) != 
JXL_DEC_SUCCESS) {
+            qWarning("ERROR: JxlDecoderSubscribeEvents failed");
+            m_parseState = ParseJpegXLError;
+            return false;
+        }
+    } else {
+        if (JxlDecoderSubscribeEvents(m_decoder, JXL_DEC_COLOR_ENCODING | 
JXL_DEC_FULL_IMAGE) != JXL_DEC_SUCCESS) {
+            qWarning("ERROR: JxlDecoderSubscribeEvents failed");
+            m_parseState = ParseJpegXLError;
+            return false;
+        }
+
+        JxlDecoderStatus status = JxlDecoderProcessInput(m_decoder);
+        if (status != JXL_DEC_COLOR_ENCODING) {
+            qWarning("Unexpected event %d instead of JXL_DEC_COLOR_ENCODING", 
status);
+            m_parseState = ParseJpegXLError;
+            return false;
+        }
+
+        JxlColorEncoding color_encoding;
+        JxlColorEncodingSetToSRGB(&color_encoding, JXL_FALSE);
+        JxlDecoderSetPreferredColorProfile(m_decoder, &color_encoding);
+    }
+
+    return true;
+}
+
+QImageIOPlugin::Capabilities QJpegXLPlugin::capabilities(QIODevice *device, 
const QByteArray &format) const
+{
+    if (format == "jxl") {
+        return Capabilities(CanRead | CanWrite);
+    }
+
+    if (!format.isEmpty()) {
+        return {};
+    }
+    if (!device->isOpen()) {
+        return {};
+    }
+
+    Capabilities cap;
+    if (device->isReadable() && QJpegXLHandler::canRead(device)) {
+        cap |= CanRead;
+    }
+
+    if (device->isWritable()) {
+        cap |= CanWrite;
+    }
+
+    return cap;
+}
+
+QImageIOHandler *QJpegXLPlugin::create(QIODevice *device, const QByteArray 
&format) const
+{
+    QImageIOHandler *handler = new QJpegXLHandler;
+    handler->setDevice(device);
+    handler->setFormat(format);
+    return handler;
+}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/kimageformats-5.88.0/src/imageformats/jxl.desktop 
new/kimageformats-5.89.0/src/imageformats/jxl.desktop
--- old/kimageformats-5.88.0/src/imageformats/jxl.desktop       1970-01-01 
01:00:00.000000000 +0100
+++ new/kimageformats-5.89.0/src/imageformats/jxl.desktop       2021-12-04 
18:00:59.000000000 +0100
@@ -0,0 +1,7 @@
+[Desktop Entry]
+Type=Service
+X-KDE-ServiceTypes=QImageIOPlugins
+X-KDE-ImageFormat=jxl
+X-KDE-MimeType=image/jxl
+X-KDE-Read=true
+X-KDE-Write=true
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/kimageformats-5.88.0/src/imageformats/jxl.json 
new/kimageformats-5.89.0/src/imageformats/jxl.json
--- old/kimageformats-5.88.0/src/imageformats/jxl.json  1970-01-01 
01:00:00.000000000 +0100
+++ new/kimageformats-5.89.0/src/imageformats/jxl.json  2021-12-04 
18:00:59.000000000 +0100
@@ -0,0 +1,4 @@
+{
+    "Keys": [ "jxl" ],
+    "MimeTypes": [ "image/jxl" ]
+}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/kimageformats-5.88.0/src/imageformats/jxl_p.h 
new/kimageformats-5.89.0/src/imageformats/jxl_p.h
--- old/kimageformats-5.88.0/src/imageformats/jxl_p.h   1970-01-01 
01:00:00.000000000 +0100
+++ new/kimageformats-5.89.0/src/imageformats/jxl_p.h   2021-12-04 
18:00:59.000000000 +0100
@@ -0,0 +1,96 @@
+/*
+    JPEG XL (JXL) support for QImage.
+
+    SPDX-FileCopyrightText: 2021 Daniel Novomesky <dnovome...@gmail.com>
+
+    SPDX-License-Identifier: BSD-2-Clause
+*/
+
+#ifndef KIMG_JXL_P_H
+#define KIMG_JXL_P_H
+
+#include <QByteArray>
+#include <QColorSpace>
+#include <QImage>
+#include <QImageIOHandler>
+#include <QImageIOPlugin>
+#include <QVariant>
+#include <QVector>
+
+#include <jxl/decode.h>
+
+class QJpegXLHandler : public QImageIOHandler
+{
+public:
+    QJpegXLHandler();
+    ~QJpegXLHandler();
+
+    bool canRead() const override;
+    bool read(QImage *image) override;
+    bool write(const QImage &image) override;
+
+    static bool canRead(QIODevice *device);
+
+    QVariant option(ImageOption option) const override;
+    void setOption(ImageOption option, const QVariant &value) override;
+    bool supportsOption(ImageOption option) const override;
+
+    int imageCount() const override;
+    int currentImageNumber() const override;
+    bool jumpToNextImage() override;
+    bool jumpToImage(int imageNumber) override;
+
+    int nextImageDelay() const override;
+
+    int loopCount() const override;
+
+private:
+    bool ensureParsed() const;
+    bool ensureALLCounted() const;
+    bool ensureDecoder();
+    bool countALLFrames();
+    bool decode_one_frame();
+    bool rewind();
+
+    enum ParseJpegXLState {
+        ParseJpegXLError = -1,
+        ParseJpegXLNotParsed = 0,
+        ParseJpegXLSuccess = 1,
+        ParseJpegXLBasicInfoParsed = 2,
+    };
+
+    ParseJpegXLState m_parseState;
+    int m_quality;
+    int m_currentimage_index;
+    int m_previousimage_index;
+
+    QByteArray m_rawData;
+
+    JxlDecoder *m_decoder;
+    void *m_runner;
+    JxlBasicInfo m_basicinfo;
+
+    QVector<int> m_framedelays;
+    int m_next_image_delay;
+
+    QImage m_current_image;
+    QColorSpace m_colorspace;
+
+    QImage::Format m_input_image_format;
+    QImage::Format m_target_image_format;
+
+    JxlPixelFormat m_input_pixel_format;
+    size_t m_buffer_size;
+};
+
+class QJpegXLPlugin : public QImageIOPlugin
+{
+    Q_OBJECT
+    Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QImageIOHandlerFactoryInterface" 
FILE "jxl.json")
+
+public:
+    Capabilities capabilities(QIODevice *device, const QByteArray &format) 
const override;
+    QImageIOHandler *create(QIODevice *device, const QByteArray &format = 
QByteArray()) const override;
+};
+
+#endif // KIMG_JXL_P_H

Reply via email to