File indexing completed on 2024-05-19 04:26:43

0001 /*
0002  * KDE. Krita Project.
0003  *
0004  * SPDX-FileCopyrightText: 2021 Deif Lou <ginoba@gmail.com>
0005  *
0006  * SPDX-License-Identifier: GPL-2.0-or-later
0007  */
0008 
0009 #ifndef KIS_LEVELS_CURVE_H
0010 #define KIS_LEVELS_CURVE_H
0011 
0012 #include <QtGlobal>
0013 #include <QVector>
0014 
0015 #include "kritaimage_export.h"
0016 
0017 /**
0018  * @brief This class holds the parameters for a levels adjustment. It is modeled
0019  * after KisCubicCurve and has similar interface and functionality
0020  */
0021 class KRITAIMAGE_EXPORT KisLevelsCurve
0022 {
0023 public:
0024     /**
0025      * @brief Default value for the input black point
0026      */
0027     static constexpr qreal defaultInputBlackPoint() { return 0.0; }
0028     /**
0029      * @brief Default value for the input white point
0030      */
0031     static constexpr qreal defaultInputWhitePoint() { return 1.0; }
0032     /**
0033      * @brief Default value for the input gamma
0034      */
0035     static constexpr qreal defaultInputGamma() { return 1.0; }
0036     /**
0037      * @brief Default value for the output black point
0038      */
0039     static constexpr qreal defaultOutputBlackPoint() { return 0.0; }
0040     /**
0041      * @brief Default value for the output white point
0042      */
0043     static constexpr qreal defaultOutputWhitePoint() { return 1.0; }
0044 
0045     KisLevelsCurve();
0046     KisLevelsCurve(qreal inputBlackPoint, qreal inputWhitePoint, qreal inputGamma,
0047                    qreal outputBlackPoint, qreal outputWhitePoint);
0048     /**
0049      * @see toString()
0050      * @see fromString() 
0051      */
0052     KisLevelsCurve(const QString &text);
0053     KisLevelsCurve(const KisLevelsCurve &rhs) = default;
0054     KisLevelsCurve& operator=(const KisLevelsCurve &rhs) = default;
0055     bool operator==(const KisLevelsCurve& rhs) const;
0056 
0057     /**
0058      * @brief Evaluates the function formed by the levels parameters for a
0059      * given x. The input and output values are normalized
0060      */
0061     qreal value(qreal x) const;
0062     
0063     /**
0064      * @brief Get the input black point
0065      */
0066     qreal inputBlackPoint() const;
0067     /**
0068      * @brief Get the input white point
0069      */
0070     qreal inputWhitePoint() const;
0071     /**
0072      * @brief Get the gamma value
0073      */
0074     qreal inputGamma() const;
0075     /**
0076      * @brief Get the output black point
0077      */
0078     qreal outputBlackPoint() const;
0079     /**
0080      * @brief Get the output white point
0081      */
0082     qreal outputWhitePoint() const;
0083 
0084     /**
0085      * @brief Set the input black point
0086      */
0087     void setInputBlackPoint(qreal newInputBlackPoint);
0088     /**
0089      * @brief Set the input white point
0090      */
0091     void setInputWhitePoint(qreal newInputWhitePoint);
0092     /**
0093      * @brief Set the gamma value
0094      */
0095     void setInputGamma(qreal newInputGamma);
0096     /**
0097      * @brief Set the output black point
0098      */
0099     void setOutputBlackPoint(qreal newOutputBlackPoint);
0100     /**
0101      * @brief Set the output white point
0102      */
0103     void setOutputWhitePoint(qreal newOutputWhitePoint);
0104 
0105     /**
0106      * @brief Resets the input and output levels (and gamma)
0107      */
0108     void resetAll();
0109     /**
0110      * @brief Resets the input levels only (and gamma)
0111      */
0112     void resetInputLevels();
0113     /**
0114      * @brief Resets the output levels only
0115      */
0116     void resetOutputLevels();
0117 
0118     /**
0119      * @brief Check whether the level info maps all values to themselves.
0120      */
0121     bool isIdentity() const;
0122 
0123     /**
0124      * @brief Get the name associated with this levels info object
0125      */
0126     const QString& name() const;
0127     /**
0128      * @brief Set the name associated with this levels info object. This allows
0129      * us to carry around a display name for the level info internally. It could
0130      * potentially be useful anywhere level info are used in the UI
0131      */
0132     void setName(const QString &newName);
0133 
0134     /**
0135      * @brief Returns a vector of size @param size with values obtained by
0136      * evaluating the function formed by the levels parameters from 0.0 to 1.0.
0137      * The resulting values are scaled to the range [0, 0xFF]
0138      * @param size The size of the returned vector
0139      * @return const QVector<quint16>& The vector with the values
0140      * @see value()
0141      * @see floatTransfer()
0142      */
0143     const QVector<quint16>& uint16Transfer(int size = 256) const;
0144     /**
0145      * @brief Returns a vector of size @param size with values obtained by
0146      * evaluating the function formed by the levels parameters from 0.0 to 1.0.
0147      * The resulting values are in the range [0, 1]
0148      * @param size The size of the returned vector
0149      * @return const QVector<qreal>& The vector with the values
0150      * @see value()
0151      * @see uint16Transfer()
0152      */
0153     const QVector<qreal>& floatTransfer(int size = 256) const;
0154 
0155     /**
0156      * @brief Get a text representation of the parameters. The format is:
0157      * "input_black_point;input_white_point;input_gamma;output_black_point;output_white_point".
0158      * For example: "0;1;0.6;0;1", "0.2;0.8;1.2;0.25;0.75"
0159      * @see fromString()
0160      */
0161     QString toString() const;
0162     /**
0163      * @brief Parses the parameters from a given text
0164      * @see toString
0165      */
0166     void fromString(const QString &text, bool *ok = nullptr);
0167 
0168 private:
0169     qreal m_inputBlackPoint, m_inputWhitePoint, m_inputGamma;
0170     qreal m_outputBlackPoint, m_outputWhitePoint;
0171     qreal m_inputLevelsDelta, m_inverseInputGamma, m_outputLevelsDelta;
0172     QString m_name;
0173     mutable QVector<quint16> m_u16Transfer;
0174     mutable QVector<qreal> m_fTransfer;
0175     mutable bool m_mustRecomputeU16Transfer;
0176     mutable bool m_mustRecomputeFTransfer;
0177 
0178     void invalidate();
0179 };
0180 
0181 #endif