File indexing completed on 2024-04-28 03:54:41

0001 /*
0002     The high dynamic range EXR format support for QImage.
0003 
0004     SPDX-FileCopyrightText: 2003 Brad Hards <bradh@frogmouth.net>
0005     SPDX-FileCopyrightText: 2023 Mirco Miranda <mircomir@outlook.com>
0006 
0007     SPDX-License-Identifier: LGPL-2.0-or-later
0008 */
0009 
0010 #ifndef KIMG_EXR_P_H
0011 #define KIMG_EXR_P_H
0012 
0013 #include <QImageIOPlugin>
0014 
0015 /*!
0016  * \brief The EXRHandler class
0017  * The handler uses the OpenEXR reference implementation of the EXR file format.
0018  *
0019  * The purpose of EXR format is to accurately and efficiently represent high-dynamic-range scene-linear
0020  * image data and associated metadata.
0021  *
0022  * Both reading and writing of EXR files is supported. When saving, the image is converted to 16-bit
0023  * and sRGB Linear color space (if not already so). If no color space is set in the image, sRGB is assumed.
0024  * When the handler is compiled with the default compile options, the loaded image is a 16-bit image
0025  * with linear color space.
0026  * Multiview images are also supported (read only) via imageCount(), jumpToImage(), etc....
0027  *
0028  * The following QImageIOHandler options are supported:
0029  * - ImageFormat: The image's data format returned by the handler.
0030  * - Size: The size of the image.
0031  * - CompressionRatio: The compression ratio of the image data (see OpenEXR compression schemes).
0032  * - Quality: The quality level of the image (see OpenEXR compression level of lossy codecs).
0033  *
0034  * The following metadata are set/get via QImage::setText()/QImage::text() in both read/write (if any):
0035  * - Latitude, Longitude, Altitude: Geographic coordinates (Float converted to string).
0036  * - CreationDate: Date the image was captured/created (QDateTime converted to string using Qt::ISODate).
0037  * - Comment: Additional image information in human-readable form, for example a verbal description of the image (QString).
0038  * - Owner: Name of the owner of the image (QString).
0039  *
0040  * In addition, information about image resolution is preserved and the preview is written for images larger
0041  * than 1024px.
0042  *
0043  * The following compile options are supported (defines):
0044  * - EXR_MAX_IMAGE_WIDTH: Maximum image width supported (read/write, default: 300000 px).
0045  * - EXR_MAX_IMAGE_HEIGHT: Maximum image height supported (read/write, default: 300000 px).
0046  * - EXR_LINES_PER_BLOCK: The number of scanlines buffered on both read and write operations.\n
0047  *                        The higher the value, the greater the parallelization but the RAM consumption increases (default: 128)
0048  * - EXR_USE_LEGACY_CONVERSIONS: The result image is an 8-bit RGB(A) converted without icc profiles (read, default: undefined).
0049  * - EXR_CONVERT_TO_SRGB: The resulting image is convertef in the sRGB color space (read, default: undefined).
0050  * - EXR_DISABLE_XMP_ATTRIBUTE: Disable the stores of XMP values in a non-standard attribute named "xmp".\n
0051  *                              The QImage metadata used is "XML:com.adobe.xmp" (write, default: undefined).
0052  */
0053 class EXRHandler : public QImageIOHandler
0054 {
0055 public:
0056     EXRHandler();
0057 
0058     bool canRead() const override;
0059     bool read(QImage *outImage) override;
0060     bool write(const QImage &image) override;
0061 
0062     void setOption(ImageOption option, const QVariant &value) override;
0063     bool supportsOption(QImageIOHandler::ImageOption option) const override;
0064     QVariant option(QImageIOHandler::ImageOption option) const override;
0065 
0066     bool jumpToNextImage() override;
0067     bool jumpToImage(int imageNumber) override;
0068     int imageCount() const override;
0069     int currentImageNumber() const override;
0070 
0071     static bool canRead(QIODevice *device);
0072 
0073 private:
0074     /*!
0075      * \brief m_compressionRatio
0076      * Value set by QImageWriter::setCompression().
0077      *
0078      * The compression scheme is the same as defined by OpenEXR library:
0079      * - 0: no compression
0080      * - 1: run length encoding
0081      * - 2: zlib compression, one scan line at a time
0082      * - 3: zlib compression, in blocks of 16 scan lines
0083      * - 4: piz-based wavelet compression (default)
0084      * - 5: lossy 24-bit float compression
0085      * - 6: lossy 4-by-4 pixel block compression, fixed compression rate
0086      * - 7: lossy 4-by-4 pixel block compression, fields are compressed more
0087      * - 8: lossy DCT based compression, in blocks of 32 scanlines. More efficient for partial buffer access.
0088      * - 9: lossy DCT based compression, in blocks of 256 scanlines. More efficient space wise and faster to decode full frames than DWAA_COMPRESSION.
0089      */
0090     qint32 m_compressionRatio;
0091 
0092     /*!
0093      * \brief m_quality
0094      * Value set by QImageWriter::setQuality().
0095      *
0096      * The quality is used on DCT compression schemes only with a
0097      * supposed value between 0 and 100 (default: 45).
0098      */
0099     qint32 m_quality;
0100 
0101     /*!
0102      * \brief m_imageNumber
0103      * Value set by QImageReader::jumpToImage() or QImageReader::jumpToNextImage().
0104      * The number of view selected in a multiview image.
0105      */
0106     qint32 m_imageNumber;
0107 
0108     /*!
0109      * \brief m_imageCount
0110      * The total number of views (cache value)
0111      */
0112     mutable qint32 m_imageCount;
0113 
0114     /*!
0115      * \brief m_startPos
0116      * The initial device position to allow multi image load (cache value).
0117      */
0118     qint64 m_startPos;
0119 };
0120 
0121 class EXRPlugin : public QImageIOPlugin
0122 {
0123     Q_OBJECT
0124     Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QImageIOHandlerFactoryInterface" FILE "exr.json")
0125 
0126 public:
0127     Capabilities capabilities(QIODevice *device, const QByteArray &format) const override;
0128     QImageIOHandler *create(QIODevice *device, const QByteArray &format = QByteArray()) const override;
0129 };
0130 
0131 #endif // KIMG_EXR_P_H