File indexing completed on 2024-05-12 04:44:28

0001 // SPDX-FileCopyrightText: Lukas Sommer <sommerluk@gmail.com>
0002 // SPDX-License-Identifier: BSD-2-Clause OR MIT
0003 
0004 #ifndef ABSOLUTECOLOR_H
0005 #define ABSOLUTECOLOR_H
0006 
0007 #include "genericcolor.h"
0008 #include "helperconversion.h"
0009 #include <array>
0010 #include <optional>
0011 #include <qglobal.h>
0012 #include <qhash.h>
0013 #include <qlist.h>
0014 
0015 #if (QT_VERSION < QT_VERSION_CHECK(6, 0, 0))
0016 #include <qobjectdefs.h>
0017 #include <qstring.h>
0018 #endif
0019 
0020 namespace PerceptualColor
0021 {
0022 
0023 /** @internal
0024  *
0025  * @brief Toolbox for color conversions.
0026  *
0027  * @sa @ref RgbColor */
0028 class AbsoluteColor final
0029 {
0030 public:
0031     AbsoluteColor() = delete;
0032 
0033     [[nodiscard]] static QHash<ColorModel, GenericColor> allConversions(const ColorModel model, const GenericColor &value);
0034     [[nodiscard]] static std::optional<GenericColor> convert(const ColorModel from, const GenericColor &value, const ColorModel to);
0035     static GenericColor fromXyzD50ToXyzD65(const GenericColor &value);
0036     static GenericColor fromXyzD65ToXyzD50(const GenericColor &value);
0037     static GenericColor fromXyzD65ToOklab(const GenericColor &value);
0038     static GenericColor fromOklabToXyzD65(const GenericColor &value);
0039     static GenericColor fromXyzD50ToCielabD50(const GenericColor &value);
0040     static GenericColor fromCielabD50ToXyzD50(const GenericColor &value);
0041     static GenericColor fromPolarToCartesian(const GenericColor &value);
0042     static GenericColor fromCartesianToPolar(const GenericColor &value);
0043 
0044 private:
0045     /** @brief Function pointer type for the conversion functions. */
0046     // NOTE std::function<> has nicer syntax for function pointers, but does
0047     // not allow constexpr.
0048     using ConversionFunction = GenericColor (*)(const GenericColor &);
0049 
0050     /** @brief Gives access to a conversion function. */
0051     struct Conversion {
0052     public:
0053         /** @brief The color space from which the function converts. */
0054         ColorModel from;
0055         /** @brief The color space to which the function converts. */
0056         ColorModel to;
0057         /** @brief The function. */
0058         ConversionFunction conversionFunction;
0059     };
0060 
0061     /** @brief List of all conversion accesses. */
0062     static constexpr std::array<Conversion, 10> conversionList //
0063         {{{ColorModel::XyzD50, ColorModel::XyzD65, fromXyzD50ToXyzD65},
0064           {ColorModel::XyzD65, ColorModel::XyzD50, fromXyzD65ToXyzD50},
0065           {ColorModel::OklabD65, ColorModel::XyzD65, fromOklabToXyzD65},
0066           {ColorModel::XyzD65, ColorModel::OklabD65, fromXyzD65ToOklab},
0067           {ColorModel::XyzD50, ColorModel::CielabD50, fromXyzD50ToCielabD50},
0068           {ColorModel::CielabD50, ColorModel::XyzD50, fromCielabD50ToXyzD50},
0069           {ColorModel::CielchD50, ColorModel::CielabD50, fromPolarToCartesian},
0070           {ColorModel::OklchD65, ColorModel::OklabD65, fromPolarToCartesian},
0071           {ColorModel::CielabD50, ColorModel::CielchD50, fromCartesianToPolar},
0072           {ColorModel::OklabD65, ColorModel::OklchD65, fromCartesianToPolar}}};
0073 
0074     [[nodiscard]] static QList<AbsoluteColor::Conversion> conversionsFrom(const ColorModel model);
0075 
0076     static void addDirectConversionsRecursivly(QHash<ColorModel, GenericColor> *values, const ColorModel model);
0077 };
0078 
0079 } // namespace PerceptualColor
0080 
0081 #endif // ABSOLUTECOLOR_H