1 /*
2     JPEG XL (JXL) support for QImage.
3 
4     SPDX-FileCopyrightText: 2021 Daniel Novomesky <dnovomesky@gmail.com>
5 
6     SPDX-License-Identifier: BSD-2-Clause
7 */
8 
9 #ifndef KIMG_JXL_P_H
10 #define KIMG_JXL_P_H
11 
12 #include <QByteArray>
13 #include <QColorSpace>
14 #include <QImage>
15 #include <QImageIOHandler>
16 #include <QImageIOPlugin>
17 #include <QVariant>
18 #include <QVector>
19 
20 #include <jxl/decode.h>
21 
22 class QJpegXLHandler : public QImageIOHandler
23 {
24 public:
25     QJpegXLHandler();
26     ~QJpegXLHandler();
27 
28     bool canRead() const override;
29     bool read(QImage *image) override;
30     bool write(const QImage &image) override;
31 
32     static bool canRead(QIODevice *device);
33 
34     QVariant option(ImageOption option) const override;
35     void setOption(ImageOption option, const QVariant &value) override;
36     bool supportsOption(ImageOption option) const override;
37 
38     int imageCount() const override;
39     int currentImageNumber() const override;
40     bool jumpToNextImage() override;
41     bool jumpToImage(int imageNumber) override;
42 
43     int nextImageDelay() const override;
44 
45     int loopCount() const override;
46 
47 private:
48     bool ensureParsed() const;
49     bool ensureALLCounted() const;
50     bool ensureDecoder();
51     bool countALLFrames();
52     bool decode_one_frame();
53     bool rewind();
54 
55     enum ParseJpegXLState {
56         ParseJpegXLError = -1,
57         ParseJpegXLNotParsed = 0,
58         ParseJpegXLSuccess = 1,
59         ParseJpegXLBasicInfoParsed = 2,
60     };
61 
62     ParseJpegXLState m_parseState;
63     int m_quality;
64     int m_currentimage_index;
65     int m_previousimage_index;
66 
67     QByteArray m_rawData;
68 
69     JxlDecoder *m_decoder;
70     void *m_runner;
71     JxlBasicInfo m_basicinfo;
72 
73     QVector<int> m_framedelays;
74     int m_next_image_delay;
75 
76     QImage m_current_image;
77     QColorSpace m_colorspace;
78 
79     QImage::Format m_input_image_format;
80     QImage::Format m_target_image_format;
81 
82     JxlPixelFormat m_input_pixel_format;
83     size_t m_buffer_size;
84 };
85 
86 class QJpegXLPlugin : public QImageIOPlugin
87 {
88     Q_OBJECT
89     Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QImageIOHandlerFactoryInterface" FILE "jxl.json")
90 
91 public:
92     Capabilities capabilities(QIODevice *device, const QByteArray &format) const override;
93     QImageIOHandler *create(QIODevice *device, const QByteArray &format = QByteArray()) const override;
94 };
95 
96 #endif // KIMG_JXL_P_H
97