1/*
2 The high dynamic range EXR format support for QImage.
3
4 SPDX-FileCopyrightText: 2003 Brad Hards <bradh@frogmouth.net>
5 SPDX-FileCopyrightText: 2023 Mirco Miranda <mircomir@outlook.com>
6
7 SPDX-License-Identifier: LGPL-2.0-or-later
8*/
9
10#ifndef KIMG_EXR_P_H
11#define KIMG_EXR_P_H
12
13#include <QImageIOPlugin>
14
15/*!
16 * \brief The EXRHandler class
17 * The handler uses the OpenEXR reference implementation of the EXR file format.
18 *
19 * The purpose of EXR format is to accurately and efficiently represent high-dynamic-range scene-linear
20 * image data and associated metadata.
21 *
22 * Both reading and writing of EXR files is supported. When saving, the image is converted to 16-bit
23 * and sRGB Linear color space (if not already so). If no color space is set in the image, sRGB is assumed.
24 * When the handler is compiled with the default compile options, the loaded image is a 16-bit image
25 * with linear color space.
26 * Multiview images are also supported (read only) via imageCount(), jumpToImage(), etc....
27 *
28 * The following QImageIOHandler options are supported:
29 * - ImageFormat: The image's data format returned by the handler.
30 * - Size: The size of the image.
31 * - CompressionRatio: The compression ratio of the image data (see OpenEXR compression schemes).
32 * - Quality: The quality level of the image (see OpenEXR compression level of lossy codecs).
33 *
34 * The following metadata are set/get via QImage::setText()/QImage::text() in both read/write (if any):
35 * - Latitude, Longitude, Altitude: Geographic coordinates (Float converted to string).
36 * - CreationDate: Date the image was captured/created (QDateTime converted to string using Qt::ISODate).
37 * - Comment: Additional image information in human-readable form, for example a verbal description of the image (QString).
38 * - Owner: Name of the owner of the image (QString).
39 *
40 * In addition, information about image resolution is preserved and the preview is written for images larger
41 * than 1024px.
42 *
43 * The following compile options are supported (defines):
44 * - EXR_MAX_IMAGE_WIDTH: Maximum image width supported (read/write, default: 300000 px).
45 * - EXR_MAX_IMAGE_HEIGHT: Maximum image height supported (read/write, default: 300000 px).
46 * - EXR_LINES_PER_BLOCK: The number of scanlines buffered on both read and write operations.\n
47 * The higher the value, the greater the parallelization but the RAM consumption increases (default: 128)
48 * - EXR_USE_LEGACY_CONVERSIONS: The result image is an 8-bit RGB(A) converted without icc profiles (read, default: undefined).
49 * - EXR_CONVERT_TO_SRGB: The resulting image is convertef in the sRGB color space (read, default: undefined).
50 * - EXR_DISABLE_XMP_ATTRIBUTE: Disable the stores of XMP values in a non-standard attribute named "xmp".\n
51 * The QImage metadata used is "XML:com.adobe.xmp" (write, default: undefined).
52 */
53class EXRHandler : public QImageIOHandler
54{
55public:
56 EXRHandler();
57
58 bool canRead() const override;
59 bool read(QImage *outImage) override;
60 bool write(const QImage &image) override;
61
62 void setOption(ImageOption option, const QVariant &value) override;
63 bool supportsOption(QImageIOHandler::ImageOption option) const override;
64 QVariant option(QImageIOHandler::ImageOption option) const override;
65
66 bool jumpToNextImage() override;
67 bool jumpToImage(int imageNumber) override;
68 int imageCount() const override;
69 int currentImageNumber() const override;
70
71 static bool canRead(QIODevice *device);
72
73private:
74 /*!
75 * \brief m_compressionRatio
76 * Value set by QImageWriter::setCompression().
77 *
78 * The compression scheme is the same as defined by OpenEXR library:
79 * - 0: no compression
80 * - 1: run length encoding
81 * - 2: zlib compression, one scan line at a time
82 * - 3: zlib compression, in blocks of 16 scan lines
83 * - 4: piz-based wavelet compression (default)
84 * - 5: lossy 24-bit float compression
85 * - 6: lossy 4-by-4 pixel block compression, fixed compression rate
86 * - 7: lossy 4-by-4 pixel block compression, fields are compressed more
87 * - 8: lossy DCT based compression, in blocks of 32 scanlines. More efficient for partial buffer access.
88 * - 9: lossy DCT based compression, in blocks of 256 scanlines. More efficient space wise and faster to decode full frames than DWAA_COMPRESSION.
89 */
90 qint32 m_compressionRatio;
91
92 /*!
93 * \brief m_quality
94 * Value set by QImageWriter::setQuality().
95 *
96 * The quality is used on DCT compression schemes only with a
97 * supposed value between 0 and 100 (default: 45).
98 */
99 qint32 m_quality;
100
101 /*!
102 * \brief m_imageNumber
103 * Value set by QImageReader::jumpToImage() or QImageReader::jumpToNextImage().
104 * The number of view selected in a multiview image.
105 */
106 qint32 m_imageNumber;
107
108 /*!
109 * \brief m_imageCount
110 * The total number of views (cache value)
111 */
112 mutable qint32 m_imageCount;
113
114 /*!
115 * \brief m_startPos
116 * The initial device position to allow multi image load (cache value).
117 */
118 qint64 m_startPos;
119};
120
121class EXRPlugin : public QImageIOPlugin
122{
123 Q_OBJECT
124 Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QImageIOHandlerFactoryInterface" FILE "exr.json")
125
126public:
127 Capabilities capabilities(QIODevice *device, const QByteArray &format) const override;
128 QImageIOHandler *create(QIODevice *device, const QByteArray &format = QByteArray()) const override;
129};
130
131#endif // KIMG_EXR_P_H
132

source code of kimageformats/src/imageformats/exr_p.h