File indexing completed on 2024-05-12 15:59:32

0001 /*
0002  *  SPDX-FileCopyrightText: 2007-2008 Cyrille Berger <cberger@cberger.net>
0003  *
0004  * SPDX-License-Identifier: LGPL-2.1-or-later
0005 */
0006 
0007 #ifndef _KO_COLOR_CONVERSION_SYSTEM_H_
0008 #define _KO_COLOR_CONVERSION_SYSTEM_H_
0009 
0010 class KoColorProfile;
0011 class KoColorSpace;
0012 class KoColorSpaceFactory;
0013 class KoColorSpaceEngine;
0014 class KoID;
0015 
0016 #include "KoColorConversionTransformation.h"
0017 
0018 #include <QList>
0019 #include <QPair>
0020 
0021 #include "kritapigment_export.h"
0022 
0023 /**
0024  * This class hold the logic related to pigment's Color Conversion System. It's
0025  * basically a graph containing all the possible color transformation between
0026  * the color spaces. The most useful functions are createColorConverter to create
0027  * a color conversion between two color spaces, and insertColorSpace which is called
0028  * by KoColorSpaceRegistry each time a new color space is added to the registry.
0029  *
0030  * This class is not part of public API, and can be changed without notice.
0031  */
0032 class KRITAPIGMENT_EXPORT KoColorConversionSystem
0033 {
0034 public:
0035     struct RegistryInterface {
0036         virtual ~RegistryInterface() {}
0037 
0038         virtual const KoColorSpace * colorSpace(const QString & colorModelId, const QString & colorDepthId, const QString &profileName) = 0;
0039         virtual const KoColorSpaceFactory* colorSpaceFactory(const QString &colorModelId, const QString &colorDepthId) const = 0;
0040         virtual QList<const KoColorProfile *>  profilesFor(const KoColorSpaceFactory * csf) const = 0;
0041         virtual QList<const KoColorSpaceFactory*> colorSpacesFor(const KoColorProfile* profile) const = 0;
0042     };
0043 
0044 public:
0045     struct Node;
0046     struct Vertex;
0047     struct NodeKey;
0048     friend uint qHash(const KoColorConversionSystem::NodeKey &key);
0049     struct Path;
0050     /**
0051      * Construct a Color Conversion System, leave to the KoColorSpaceRegistry to
0052      * create it.
0053      */
0054     KoColorConversionSystem(RegistryInterface *registryInterface);
0055     ~KoColorConversionSystem();
0056     /**
0057      * This function is called by the KoColorSpaceRegistry to add a new color space
0058      * to the graph of transformation.
0059      */
0060     void insertColorSpace(const KoColorSpaceFactory*);
0061 
0062     void insertColorProfile(const KoColorProfile*);
0063     /**
0064      * This function is called by the color space to create a color conversion
0065      * between two color space. This function search in the graph of transformations
0066      * the best possible path between the two color space.
0067      */
0068     KoColorConversionTransformation* createColorConverter(const KoColorSpace * srcColorSpace, const KoColorSpace * dstColorSpace, KoColorConversionTransformation::Intent renderingIntent, KoColorConversionTransformation::ConversionFlags conversionFlags) const;
0069 
0070     /**
0071      * This function creates two transformations, one from the color space and one to the
0072      * color space. The destination color space is picked from a list of color space, such
0073      * as the conversion between the two color space is of the best quality.
0074      *
0075      * The typical use case of this function is for KoColorTransformationFactory which
0076      * doesn't support all color spaces, so unsupported color space have to find an
0077      * acceptable conversion in order to use that KoColorTransformationFactory.
0078      *
0079      * @param colorSpace the source color space
0080      * @param possibilities a list of color space among which we need to find the best
0081      *                      conversion
0082      * @param fromCS the conversion from the source color space will be affected to this
0083      *               variable
0084      * @param toCS the revert conversion to the source color space will be affected to this
0085      *             variable
0086      */
0087     void createColorConverters(const KoColorSpace* colorSpace, const QList< QPair<KoID, KoID> >& possibilities, KoColorConversionTransformation*& fromCS, KoColorConversionTransformation*& toCS) const;
0088 public:
0089     /**
0090      * This function return a text that can be compiled using dot to display
0091      * the graph of color conversion connection.
0092      */
0093     QString toDot() const;
0094     /**
0095      * This function return a text that can be compiled using dot to display
0096      * the graph of color conversion connection, with a red link to show the
0097      * path of the best color conversion.
0098      */
0099     QString bestPathToDot(const QString& srcKey, const QString& dstKey) const;
0100 public:
0101     /**
0102      * @return true if there is a path between two color spaces
0103      */
0104     bool existsPath(const QString& srcModelId, const QString& srcDepthId, const QString& srcProfileName, const QString& dstModelId, const QString& dstDepthId, const QString& dstProfileName) const;
0105     /**
0106      * @return true if there is a good path between two color spaces
0107      */
0108     bool existsGoodPath(const QString& srcModelId, const QString& srcDepthId, const QString& srcProfileName, const QString& dstModelId, const QString& dstDepthId, const QString& dstProfileName) const;
0109 
0110     /**
0111      * @return the best path for the specified color spaces. Used for
0112      * testing purposes only
0113      */
0114     Path findBestPath(const QString& srcModelId, const QString& srcDepthId, const QString& srcProfileName, const QString& dstModelId, const QString& dstDepthId, const QString& dstProfileName) const;
0115 
0116     /**
0117      * @return the best path for the specified color spaces. Used for
0118      * testing purposes only
0119      */
0120     Path findBestPath(const NodeKey &src, const NodeKey &dst) const;
0121 private:
0122     QString vertexToDot(Vertex* v, const QString &options) const;
0123 private:
0124     /**
0125      * Insert an engine.
0126      */
0127     Node* insertEngine(const KoColorSpaceEngine* engine);
0128     KoColorConversionTransformation* createTransformationFromPath(const KoColorConversionSystem::Path& path, const KoColorSpace* srcColorSpace, const KoColorSpace* dstColorSpace, KoColorConversionTransformation::Intent renderingIntent, KoColorConversionTransformation::ConversionFlags conversionFlags) const;
0129     /**
0130      * Query the registry to get the color space associated with this
0131      * node. (default profile)
0132      */
0133     const KoColorSpace* defaultColorSpaceForNode(const Node* node) const;
0134     /**
0135      * Create a new node
0136      */
0137     Node* createNode(const QString& _modelId, const QString& _depthId, const QString& _profileName);
0138     /**
0139      * Initialise a node for ICC color spaces
0140      */
0141     void connectToEngine(Node* _node, Node* _engine);
0142     const Node* nodeFor(const KoColorSpace*) const;
0143     /**
0144      * @return the node corresponding to that key, or create it if needed
0145      */
0146     Node* nodeFor(const NodeKey& key);
0147     const Node* nodeFor(const NodeKey& key) const;
0148     /**
0149      * @return the list of nodes that correspond to a given model and depth.
0150      */
0151     QList<Node*> nodesFor(const QString& _modelId, const QString& _depthId);
0152     /**
0153      * @return the node associated with that key, and create it if needed
0154      */
0155     Node* nodeFor(const QString& colorModelId, const QString& colorDepthId, const QString& _profileName);
0156     const Node* nodeFor(const QString& colorModelId, const QString& colorDepthId, const QString& _profileName) const;
0157     /**
0158      * @return the vertex between two nodes, or null if the vertex doesn't exist
0159      */
0160     Vertex* vertexBetween(Node* srcNode, Node* dstNode);
0161     /**
0162      * create a vertex between two nodes and return it.
0163      */
0164     Vertex* createVertex(Node* srcNode, Node* dstNode);
0165     /**
0166      * looks for the best path between two nodes
0167      */
0168     Path findBestPath(const Node* srcNode, const Node* dstNode) const;
0169     /**
0170      * Delete all the paths of the list given in argument.
0171      */
0172     void deletePaths(QList<KoColorConversionSystem::Path*> paths) const;
0173 
0174 private:
0175     struct Private;
0176     Private* const d;
0177 };
0178 
0179 #endif