File indexing completed on 2024-05-12 05:31:20

0001 /*
0002     SPDX-FileCopyrightText: 2023 Xaver Hugl <xaver.hugl@gmail.com>
0003 
0004     SPDX-License-Identifier: GPL-2.0-or-later
0005 */
0006 #pragma once
0007 #include <optional>
0008 
0009 #include <QMatrix4x4>
0010 #include <QVector2D>
0011 
0012 #include "kwin_export.h"
0013 
0014 namespace KWin
0015 {
0016 
0017 enum class NamedColorimetry {
0018     BT709,
0019     BT2020,
0020 };
0021 
0022 /**
0023  * Describes the definition of colors in a color space.
0024  * Red, green and blue define the chromaticities ("absolute colors") of the red, green and blue LEDs on a display in xy coordinates
0025  * White defines the the chromaticity of the reference white in xy coordinates
0026  */
0027 class KWIN_EXPORT Colorimetry
0028 {
0029 public:
0030     static const Colorimetry &fromName(NamedColorimetry name);
0031     /**
0032      * @returns the XYZ representation of the xyY color passed in. Y is assumed to be one
0033      */
0034     static QVector3D xyToXYZ(QVector2D xy);
0035     /**
0036      * @returns the xyY representation of the XYZ color passed in. Y is normalized to be one
0037      */
0038     static QVector2D xyzToXY(QVector3D xyz);
0039     /**
0040      * @returns a matrix adapting XYZ values from the source whitepoint to the destination whitepoint with the Bradford transform
0041      */
0042     static QMatrix4x4 chromaticAdaptationMatrix(QVector2D sourceWhitepoint, QVector2D destinationWhitepoint);
0043 
0044     static QMatrix4x4 calculateToXYZMatrix(QVector3D red, QVector3D green, QVector3D blue, QVector3D white);
0045 
0046     explicit Colorimetry(QVector2D red, QVector2D green, QVector2D blue, QVector2D white);
0047     explicit Colorimetry(QVector3D red, QVector3D green, QVector3D blue, QVector3D white);
0048 
0049     /**
0050      * @returns a matrix that transforms from the linear RGB representation of colors in this colorimetry to the XYZ representation
0051      */
0052     const QMatrix4x4 &toXYZ() const;
0053     /**
0054      * @returns a matrix that transforms from the XYZ representation to the linear RGB representation of colors in this colorimetry
0055      */
0056     const QMatrix4x4 &fromXYZ() const;
0057     /**
0058      * @returns a matrix that transforms from linear RGB in this colorimetry to linear RGB in the other colorimetry
0059      * the rendering intent is relative colorimetric
0060      */
0061     QMatrix4x4 toOther(const Colorimetry &colorimetry) const;
0062     bool operator==(const Colorimetry &other) const;
0063     bool operator==(NamedColorimetry name) const;
0064     /**
0065      * @returns this colorimetry, adapted to the new whitepoint using the Bradford transform
0066      */
0067     Colorimetry adaptedTo(QVector2D newWhitepoint) const;
0068     /**
0069      * interpolates the primaries depending on the passed factor. The whitepoint stays unchanged
0070      */
0071     Colorimetry interpolateGamutTo(const Colorimetry &one, double factor) const;
0072 
0073     const QVector2D &red() const;
0074     const QVector2D &green() const;
0075     const QVector2D &blue() const;
0076     const QVector2D &white() const;
0077 
0078 private:
0079     QVector2D m_red;
0080     QVector2D m_green;
0081     QVector2D m_blue;
0082     QVector2D m_white;
0083     QMatrix4x4 m_toXYZ;
0084     QMatrix4x4 m_fromXYZ;
0085 };
0086 
0087 /**
0088  * Describes an EOTF, that is, how encoded brightness values are converted to light
0089  */
0090 enum class NamedTransferFunction {
0091     sRGB = 0,
0092     linear = 1,
0093     PerceptualQuantizer = 2,
0094     scRGB = 3,
0095     gamma22 = 4,
0096 };
0097 
0098 /**
0099  * Describes the meaning of encoded color values, with additional metadata for how to convert between different encodings
0100  * Note that not all properties of this description are relevant in all contexts
0101  */
0102 class KWIN_EXPORT ColorDescription
0103 {
0104 public:
0105     /**
0106      * @param colorimety the colorimety of this description
0107      * @param tf the transfer function of this description
0108      * @param sdrBrightness the brightness of SDR content
0109      * @param minHdrBrightness the minimum brightness of HDR content
0110      * @param maxFrameAverageBrightness the maximum brightness of HDR content, if the whole screen is white
0111      * @param maxHdrHighlightBrightness the maximum brightness of HDR content, for a small part of the screen only
0112      * @param sdrColorimetry
0113      */
0114     explicit ColorDescription(const Colorimetry &colorimety, NamedTransferFunction tf, double sdrBrightness, double minHdrBrightness, double maxFrameAverageBrightness, double maxHdrHighlightBrightness, const Colorimetry &sdrColorimetry = Colorimetry::fromName(NamedColorimetry::BT709));
0115     explicit ColorDescription(NamedColorimetry colorimetry, NamedTransferFunction tf, double sdrBrightness, double minHdrBrightness, double maxFrameAverageBrightness, double maxHdrHighlightBrightness, const Colorimetry &sdrColorimetry = Colorimetry::fromName(NamedColorimetry::BT709));
0116 
0117     const Colorimetry &colorimetry() const;
0118     const Colorimetry &sdrColorimetry() const;
0119     NamedTransferFunction transferFunction() const;
0120     double sdrBrightness() const;
0121     double minHdrBrightness() const;
0122     double maxFrameAverageBrightness() const;
0123     double maxHdrHighlightBrightness() const;
0124 
0125     bool operator==(const ColorDescription &other) const;
0126 
0127     QVector3D mapTo(QVector3D rgb, const ColorDescription &other) const;
0128 
0129     /**
0130      * This color description describes display-referred sRGB, with a gamma22 transfer function
0131      */
0132     static const ColorDescription sRGB;
0133     static QVector3D encodedToNits(const QVector3D &nits, NamedTransferFunction tf, double sdrBrightness);
0134     static QVector3D nitsToEncoded(const QVector3D &rgb, NamedTransferFunction tf, double sdrBrightness);
0135 
0136 private:
0137     Colorimetry m_colorimetry;
0138     NamedTransferFunction m_transferFunction;
0139     Colorimetry m_sdrColorimetry;
0140     double m_sdrGamutWideness;
0141     double m_sdrBrightness;
0142     double m_minHdrBrightness;
0143     double m_maxFrameAverageBrightness;
0144     double m_maxHdrHighlightBrightness;
0145 };
0146 }