Krita Source Code Documentation
Loading...
Searching...
No Matches
KoColorConversionSystem Struct Reference

#include <KoColorConversionSystem.h>

+ Inheritance diagram for KoColorConversionSystem:

Classes

struct  Node
 
struct  NodeKey
 
struct  Path
 
struct  RegistryInterface
 
struct  Vertex
 

Public Member Functions

QString bestPathToDot (const QString &srcKey, const QString &dstKey) const
 
KoColorConversionTransformationcreateColorConverter (const KoColorSpace *srcColorSpace, const KoColorSpace *dstColorSpace, KoColorConversionTransformation::Intent renderingIntent, KoColorConversionTransformation::ConversionFlags conversionFlags) const
 
void createColorConverters (const KoColorSpace *colorSpace, const QList< QPair< KoID, KoID > > &possibilities, KoColorConversionTransformation *&fromCS, KoColorConversionTransformation *&toCS) const
 
bool existsGoodPath (const QString &srcModelId, const QString &srcDepthId, const QString &srcProfileName, const QString &dstModelId, const QString &dstDepthId, const QString &dstProfileName) const
 
bool existsPath (const QString &srcModelId, const QString &srcDepthId, const QString &srcProfileName, const QString &dstModelId, const QString &dstDepthId, const QString &dstProfileName) const
 
Path findBestPath (const NodeKey &src, const NodeKey &dst) const
 
Path findBestPath (const QString &srcModelId, const QString &srcDepthId, const QString &srcProfileName, const QString &dstModelId, const QString &dstDepthId, const QString &dstProfileName) const
 
void insertColorProfile (const KoColorProfile *)
 
void insertColorSpace (const KoColorSpaceFactory *)
 
 KoColorConversionSystem (RegistryInterface *registryInterface)
 
 Private (RegistryInterface *_registryInterface)
 
QString toDot () const
 
 ~KoColorConversionSystem ()
 
- Public Member Functions inherited from Private
 Private (KisCanvas2 *c)
 

Public Attributes

QHash< NodeKey, Node * > graph
 
RegistryInterfaceregistryInterface
 
QList< Vertex * > vertexes
 
- Public Attributes inherited from Private
KisCanvas2canvas
 
int displayedFrame
 
int intendedFrame
 

Private Member Functions

void connectToEngine (Node *_node, Node *_engine)
 
NodecreateNode (const QString &_modelId, const QString &_depthId, const QString &_profileName)
 
KoColorConversionTransformationcreateTransformationFromPath (const KoColorConversionSystem::Path &path, const KoColorSpace *srcColorSpace, const KoColorSpace *dstColorSpace, KoColorConversionTransformation::Intent renderingIntent, KoColorConversionTransformation::ConversionFlags conversionFlags) const
 
VertexcreateVertex (Node *srcNode, Node *dstNode)
 
const KoColorSpacedefaultColorSpaceForNode (const Node *node) const
 
void deletePaths (QList< KoColorConversionSystem::Path * > paths) const
 
Path findBestPath (const Node *srcNode, const Node *dstNode) const
 
NodeinsertEngine (const KoColorSpaceEngine *engine)
 
const NodenodeFor (const KoColorSpace *) const
 
NodenodeFor (const NodeKey &key)
 
const NodenodeFor (const NodeKey &key) const
 
NodenodeFor (const QString &colorModelId, const QString &colorDepthId, const QString &_profileName)
 
const NodenodeFor (const QString &colorModelId, const QString &colorDepthId, const QString &_profileName) const
 
QList< Node * > nodesFor (const QString &_modelId, const QString &_depthId)
 
VertexvertexBetween (Node *srcNode, Node *dstNode)
 
QString vertexToDot (Vertex *v, const QString &options) const
 

Private Attributes

Private *const d
 

Friends

uint qHash (const KoColorConversionSystem::NodeKey &key)
 

Detailed Description

This class hold the logic related to pigment's Color Conversion System. It's basically a graph containing all the possible color transformation between the color spaces. The most useful functions are createColorConverter to create a color conversion between two color spaces, and insertColorSpace which is called by KoColorSpaceRegistry each time a new color space is added to the registry.

This class is not part of public API, and can be changed without notice.

Definition at line 32 of file KoColorConversionSystem.h.

Constructor & Destructor Documentation

◆ KoColorConversionSystem()

KoColorConversionSystem::KoColorConversionSystem ( RegistryInterface * registryInterface)

Construct a Color Conversion System, leave to the KoColorSpaceRegistry to create it.

Definition at line 21 of file KoColorConversionSystem.cpp.

◆ ~KoColorConversionSystem()

KoColorConversionSystem::~KoColorConversionSystem ( )

Definition at line 26 of file KoColorConversionSystem.cpp.

27{
28 qDeleteAll(d->graph);
29 qDeleteAll(d->vertexes);
30 delete d;
31}

References d.

Member Function Documentation

◆ bestPathToDot()

QString KoColorConversionSystem::bestPathToDot ( const QString & srcKey,
const QString & dstKey ) const

This function return a text that can be compiled using dot to display the graph of color conversion connection, with a red link to show the path of the best color conversion.

Definition at line 400 of file KoColorConversionSystem.cpp.

401{
402 const Node* srcNode = 0;
403 const Node* dstNode = 0;
404 Q_FOREACH (Node* node, d->graph) {
405 if (node->id() == srcKey) {
406 srcNode = node;
407 }
408 if (node->id() == dstKey) {
409 dstNode = node;
410 }
411 }
412 Path p = findBestPath(srcNode, dstNode);
413 Q_ASSERT(!p.isEmpty());
414 QString dot = "digraph CCS {\n" +
415 QString(" \"%1\" [color=red]\n").arg(srcNode->id()) +
416 QString(" \"%1\" [color=red]\n").arg(dstNode->id());
417 Q_FOREACH (Vertex* oV, d->vertexes) {
418 QString options;
419 if (p.vertexes.contains(oV)) {
420 options = "[color=red]";
421 }
422 dot += vertexToDot(oV, options) ;
423 }
424 dot += "}\n";
425 return dot;
426}
const Params2D p
Path findBestPath(const QString &srcModelId, const QString &srcDepthId, const QString &srcProfileName, const QString &dstModelId, const QString &dstDepthId, const QString &dstProfileName) const
QString vertexToDot(Vertex *v, const QString &options) const
Definition Node.h:24

References d, findBestPath(), KoColorConversionSystem::Node::id(), p, and vertexToDot().

◆ connectToEngine()

void KoColorConversionSystem::connectToEngine ( Node * _node,
Node * _engine )
private

Initialise a node for ICC color spaces

Definition at line 33 of file KoColorConversionSystem.cpp.

34{
35 Vertex* v1 = createVertex(_node, _engine);
36 Vertex* v2 = createVertex(_engine, _node);
37
38 Q_UNUSED(v1);
39 Q_UNUSED(v2);
40}
Vertex * createVertex(Node *srcNode, Node *dstNode)

References createVertex().

◆ createColorConverter()

KoColorConversionTransformation * KoColorConversionSystem::createColorConverter ( const KoColorSpace * srcColorSpace,
const KoColorSpace * dstColorSpace,
KoColorConversionTransformation::Intent renderingIntent,
KoColorConversionTransformation::ConversionFlags conversionFlags ) const

This function is called by the color space to create a color conversion between two color space. This function search in the graph of transformations the best possible path between the two color space.

Definition at line 220 of file KoColorConversionSystem.cpp.

221{
222 Q_ASSERT(srcColorSpace);
223 Q_ASSERT(dstColorSpace);
224 if (*srcColorSpace == *dstColorSpace) {
225 return new KoCopyColorConversionTransformation(srcColorSpace);
226 }
227 dbgPigmentCCS << srcColorSpace->id() << (srcColorSpace->profile() ? srcColorSpace->profile()->name() : "default");
228 dbgPigmentCCS << dstColorSpace->id() << (dstColorSpace->profile() ? dstColorSpace->profile()->name() : "default");
229 Path path = findBestPath(
230 nodeFor(srcColorSpace),
231 nodeFor(dstColorSpace));
232 Q_ASSERT(path.length() > 0);
233 KoColorConversionTransformation* transfo = createTransformationFromPath(path, srcColorSpace, dstColorSpace, renderingIntent, conversionFlags);
234 Q_ASSERT(transfo);
235 Q_ASSERT(*transfo->srcColorSpace() == *srcColorSpace);
236 Q_ASSERT(*transfo->dstColorSpace() == *dstColorSpace);
237 return transfo;
238}
#define dbgPigmentCCS
KoColorConversionTransformation * createTransformationFromPath(const KoColorConversionSystem::Path &path, const KoColorSpace *srcColorSpace, const KoColorSpace *dstColorSpace, KoColorConversionTransformation::Intent renderingIntent, KoColorConversionTransformation::ConversionFlags conversionFlags) const
const Node * nodeFor(const KoColorSpace *) const
virtual const KoColorProfile * profile() const =0

References createTransformationFromPath(), dbgPigmentCCS, KoColorConversionTransformation::dstColorSpace, findBestPath(), KoColorSpace::id, KoColorProfile::name, nodeFor(), KoColorSpace::profile(), and KoColorConversionTransformation::srcColorSpace.

◆ createColorConverters()

void KoColorConversionSystem::createColorConverters ( const KoColorSpace * colorSpace,
const QList< QPair< KoID, KoID > > & possibilities,
KoColorConversionTransformation *& fromCS,
KoColorConversionTransformation *& toCS ) const

This function creates two transformations, one from the color space and one to the color space. The destination color space is picked from a list of color space, such as the conversion between the two color space is of the best quality.

The typical use case of this function is for KoColorTransformationFactory which doesn't support all color spaces, so unsupported color space have to find an acceptable conversion in order to use that KoColorTransformationFactory.

Parameters
colorSpacethe source color space
possibilitiesa list of color space among which we need to find the best conversion
fromCSthe conversion from the source color space will be affected to this variable
toCSthe revert conversion to the source color space will be affected to this variable

Definition at line 240 of file KoColorConversionSystem.cpp.

241{
242 // TODO This function currently only select the best conversion only based on the transformation
243 // from colorSpace to one of the color spaces in the list, but not the other way around
244 // it might be worth to look also the return path.
245 const Node* csNode = nodeFor(colorSpace);
246 PathQualityChecker pQC(csNode->referenceDepth);
247 // Look for a color conversion
248 Path bestPath;
249 typedef QPair<KoID, KoID> KoID2KoID;
250 Q_FOREACH (const KoID2KoID & possibility, possibilities) {
251 const KoColorSpaceFactory* csf = d->registryInterface->colorSpaceFactory(possibility.first.id(), possibility.second.id());
252 if (csf) {
253 Path path = findBestPath(csNode, nodeFor(csf->colorModelId().id(), csf->colorDepthId().id(), csf->defaultProfile()));
254 Q_ASSERT(path.length() > 0);
255 path.isGood = pQC.isGoodPath(path);
256
257 if (bestPath.isEmpty()) {
258 bestPath = path;
259 } else if ((!bestPath.isGood && path.isGood) || pQC.lessWorseThan(path, bestPath)) {
260 bestPath = path;
261 }
262 }
263 }
264 Q_ASSERT(!bestPath.isEmpty());
265 const KoColorSpace* endColorSpace = defaultColorSpaceForNode(bestPath.endNode());
267 Path returnPath = findBestPath(bestPath.endNode(), csNode);
268 Q_ASSERT(!returnPath.isEmpty());
270 Q_ASSERT(*toCS->dstColorSpace() == *fromCS->srcColorSpace());
271 Q_ASSERT(*fromCS->dstColorSpace() == *toCS->srcColorSpace());
272}
const KoColorSpace * defaultColorSpaceForNode(const Node *node) const
QString id() const
Definition KoID.cpp:63
virtual KoID colorDepthId() const =0
virtual QString defaultProfile() const =0
virtual KoID colorModelId() const =0

References KoColorSpaceFactory::colorDepthId(), KoColorSpaceFactory::colorModelId(), createTransformationFromPath(), d, defaultColorSpaceForNode(), KoColorSpaceFactory::defaultProfile(), KoColorConversionTransformation::dstColorSpace, KoColorConversionSystem::Path::endNode(), findBestPath(), KoID::id(), KoColorConversionTransformation::internalConversionFlags(), KoColorConversionTransformation::internalRenderingIntent(), KoColorConversionSystem::Path::isEmpty(), KoColorConversionSystem::Path::isGood, PathQualityChecker::isGoodPath(), PathQualityChecker::lessWorseThan(), nodeFor(), KoColorConversionSystem::Node::referenceDepth, and KoColorConversionTransformation::srcColorSpace.

◆ createNode()

KoColorConversionSystem::Node * KoColorConversionSystem::createNode ( const QString & _modelId,
const QString & _depthId,
const QString & _profileName )
private

Create a new node

Definition at line 165 of file KoColorConversionSystem.cpp.

166{
167 Node* n = new Node;
168 n->modelId = _modelId;
169 n->depthId = _depthId;
170 n->profileName = _profileName;
171 d->graph.insert(NodeKey(_modelId, _depthId, _profileName), n);
172 return n;
173}

References d, KoColorConversionSystem::Node::depthId, KoColorConversionSystem::Node::modelId, and KoColorConversionSystem::Node::profileName.

◆ createTransformationFromPath()

KoColorConversionTransformation * KoColorConversionSystem::createTransformationFromPath ( const KoColorConversionSystem::Path & path,
const KoColorSpace * srcColorSpace,
const KoColorSpace * dstColorSpace,
KoColorConversionTransformation::Intent renderingIntent,
KoColorConversionTransformation::ConversionFlags conversionFlags ) const
private

Definition at line 274 of file KoColorConversionSystem.cpp.

275{
276 Q_ASSERT(srcColorSpace->colorModelId().id() == path.startNode()->modelId);
277 Q_ASSERT(srcColorSpace->colorDepthId().id() == path.startNode()->depthId);
278 Q_ASSERT(dstColorSpace->colorModelId().id() == path.endNode()->modelId);
279 Q_ASSERT(dstColorSpace->colorDepthId().id() == path.endNode()->depthId);
280
282
283 const QList< Path::node2factory > pathOfNode = path.compressedPath();
284
285 if (pathOfNode.size() == 2) { // Direct connection
286 transfo = pathOfNode[1].second->createColorTransformation(srcColorSpace, dstColorSpace, renderingIntent, conversionFlags);
287 }
288 else {
289
290 KoMultipleColorConversionTransformation* mccTransfo = new KoMultipleColorConversionTransformation(srcColorSpace, dstColorSpace, renderingIntent, conversionFlags);
291
292 transfo = mccTransfo;
293
294 // Get the first intermediary color space
295 dbgPigmentCCS << pathOfNode[ 0 ].first->id() << " to " << pathOfNode[ 1 ].first->id();
296
297 const KoColorSpace* intermCS =
298 defaultColorSpaceForNode(pathOfNode[1].first);
299
300 mccTransfo->appendTransfo(pathOfNode[1].second->createColorTransformation(srcColorSpace, intermCS, renderingIntent, conversionFlags));
301
302 for (int i = 2; i < pathOfNode.size() - 1; i++) {
303 dbgPigmentCCS << pathOfNode[ i - 1 ].first->id() << " to " << pathOfNode[ i ].first->id();
304 const KoColorSpace* intermCS2 = defaultColorSpaceForNode(pathOfNode[i].first);
305 Q_ASSERT(intermCS2);
306 mccTransfo->appendTransfo(pathOfNode[i].second->createColorTransformation(intermCS, intermCS2, renderingIntent, conversionFlags));
307 intermCS = intermCS2;
308 }
309
310 dbgPigmentCCS << pathOfNode[ pathOfNode.size() - 2 ].first->id() << " to " << pathOfNode[ pathOfNode.size() - 1 ].first->id();
311 mccTransfo->appendTransfo(pathOfNode.last().second->createColorTransformation(intermCS, dstColorSpace, renderingIntent, conversionFlags));
312 }
313 return transfo;
314}
virtual KoID colorModelId() const =0
virtual KoID colorDepthId() const =0
void appendTransfo(KoColorConversionTransformation *transfo)

References KoMultipleColorConversionTransformation::appendTransfo(), KoColorSpace::colorDepthId(), KoColorSpace::colorModelId(), dbgPigmentCCS, defaultColorSpaceForNode(), and KoID::id().

◆ createVertex()

KoColorConversionSystem::Vertex * KoColorConversionSystem::createVertex ( Node * srcNode,
Node * dstNode )
private

create a vertex between two nodes and return it.

Definition at line 327 of file KoColorConversionSystem.cpp.

328{
329 Vertex* v = new Vertex(srcNode, dstNode);
330 srcNode->outputVertexes.append(v);
331 d->vertexes.append(v);
332 return v;
333}
qreal v

References d, KoColorConversionSystem::Node::outputVertexes, and v.

◆ defaultColorSpaceForNode()

const KoColorSpace * KoColorConversionSystem::defaultColorSpaceForNode ( const Node * node) const
private

Query the registry to get the color space associated with this node. (default profile)

Definition at line 160 of file KoColorConversionSystem.cpp.

161{
162 return d->registryInterface->colorSpace(node->modelId, node->depthId, node->profileName);
163}

References d, KoColorConversionSystem::Node::depthId, KoColorConversionSystem::Node::modelId, and KoColorConversionSystem::Node::profileName.

◆ deletePaths()

void KoColorConversionSystem::deletePaths ( QList< KoColorConversionSystem::Path * > paths) const
private

Delete all the paths of the list given in argument.

◆ existsGoodPath()

bool KoColorConversionSystem::existsGoodPath ( const QString & srcModelId,
const QString & srcDepthId,
const QString & srcProfileName,
const QString & dstModelId,
const QString & dstDepthId,
const QString & dstProfileName ) const
Returns
true if there is a good path between two color spaces

Definition at line 365 of file KoColorConversionSystem.cpp.

366{
367 const Node* srcNode = nodeFor(srcModelId, srcDepthId, srcProfileName);
368 const Node* dstNode = nodeFor(dstModelId, dstDepthId, dstProfileName);
369 if (srcNode == dstNode) return true;
370 if (!srcNode) return false;
371 if (!dstNode) return false;
372 Path path = findBestPath(srcNode, dstNode);
373 bool existAndGood = path.isGood;
374 return existAndGood;
375}

References findBestPath(), and nodeFor().

◆ existsPath()

bool KoColorConversionSystem::existsPath ( const QString & srcModelId,
const QString & srcDepthId,
const QString & srcProfileName,
const QString & dstModelId,
const QString & dstDepthId,
const QString & dstProfileName ) const
Returns
true if there is a path between two color spaces

Definition at line 352 of file KoColorConversionSystem.cpp.

353{
354 dbgPigmentCCS << "srcModelId = " << srcModelId << " srcDepthId = " << srcDepthId << " srcProfileName = " << srcProfileName << " dstModelId = " << dstModelId << " dstDepthId = " << dstDepthId << " dstProfileName = " << dstProfileName;
355 const Node* srcNode = nodeFor(srcModelId, srcDepthId, srcProfileName);
356 const Node* dstNode = nodeFor(dstModelId, dstDepthId, dstProfileName);
357 if (srcNode == dstNode) return true;
358 if (!srcNode) return false;
359 if (!dstNode) return false;
360 Path path = findBestPath(srcNode, dstNode);
361 bool exist = !path.isEmpty();
362 return exist;
363}

References dbgPigmentCCS, findBestPath(), and nodeFor().

◆ findBestPath() [1/3]

KoColorConversionSystem::Path KoColorConversionSystem::findBestPath ( const Node * srcNode,
const Node * dstNode ) const
private

looks for the best path between two nodes

Definition at line 428 of file KoColorConversionSystem.cpp.

429{
430 KIS_ASSERT(srcNode);
431 KIS_ASSERT(dstNode);
432
433 dbgPigmentCCS << "Find best path between " << srcNode->id() << " and " << dstNode->id();
434
435 PathQualityChecker pQC(qMin(srcNode->referenceDepth, dstNode->referenceDepth));
436 Node2PathHash node2path; // current best path to reach a given node
437 QList<Path> possiblePaths; // list of all paths
438 // Generate the initial list of paths
439 Q_FOREACH (Vertex* v, srcNode->outputVertexes) {
440 if (v->dstNode->isInitialized) {
441 Path p;
442 p.appendVertex(v);
443 Node* endNode = v->dstNode;
444 if (endNode == dstNode) {
445 Q_ASSERT(pQC.isGoodPath(p)); // <- it's a direct link, it has to be a good path
446 p.isGood = true;
447 return p;
448 } else {
449 //Q_ASSERT(!node2path.contains(endNode)); // That would be a total fuck up if there are two vertices between two nodes
450 node2path.insert(endNode, p);
451 possiblePaths.append(p);
452 }
453 }
454 }
455
456 Path currentBestPath;
457 // Continue while there are any possibilities remaining
458 while (possiblePaths.size() > 0) {
459
460 // Loop through all paths and explore one step further
461 const QList<Path> currentPaths = possiblePaths;
462 for (const Path &p : currentPaths) {
463 const Node* endNode = p.endNode();
464 for (Vertex* v : endNode->outputVertexes) {
465 if (v->dstNode->isInitialized && !p.contains(v->dstNode)) {
466 Path newP = p; // Candidate
467 newP.appendVertex(v);
468 Node* newEndNode = v->dstNode;
469 if (newEndNode == dstNode) {
470 if (pQC.isGoodPath(newP)) { // Victory
471 newP.isGood = true;
472 return newP;
473 } else if (pQC.lessWorseThan(newP, currentBestPath)) {
474 if (newP.startNode() && newP.endNode() && currentBestPath.startNode() && currentBestPath.endNode()) {
475 Q_ASSERT(newP.startNode()->id() == currentBestPath.startNode()->id());
476 Q_ASSERT(newP.endNode()->id() == currentBestPath.endNode()->id());
477 // Can we do better than dumping memory values???
478 // warnPigment << pQC.lessWorseThan(newP, currentBestPath) << " " << newP << " " << currentBestPath;
479 currentBestPath = newP;
480 }
481 }
482 } else {
483 // This is an incomplete path. Check if there's a better way to get to its endpoint.
484 Node2PathHash::Iterator it = node2path.find(newEndNode);
485 if (it != node2path.end()) {
486 Path &p2 = it.value();
487 if (pQC.lessWorseThan(newP, p2)) {
488 p2 = newP;
489 possiblePaths.append(newP);
490 }
491 } else {
492 node2path.insert(newEndNode, newP);
493 possiblePaths.append(newP);
494 }
495 }
496 }
497 }
498 possiblePaths.removeAll(p); // Remove from list of remaining paths
499 }
500 }
501
502 if (!currentBestPath.isEmpty()) {
503 warnPigment << "No good path from " << srcNode->id() << " to " << dstNode->id() << " found : length = " << currentBestPath.length() << " cost = " << currentBestPath.cost << " referenceDepth = " << currentBestPath.referenceDepth << " respectColorCorrectness = " << " isGood = " << currentBestPath.isGood ;
504 return currentBestPath;
505 }
506 errorPigment << "No path from " << srcNode->id() << " to " << dstNode->id() << " found not ";
507 return currentBestPath;
508}
#define warnPigment
#define errorPigment
QPointF p2
QHash< KoColorConversionSystem::Node *, KoColorConversionSystem::Path > Node2PathHash
#define KIS_ASSERT(cond)
Definition kis_assert.h:33

References KoColorConversionSystem::Path::appendVertex(), KoColorConversionSystem::Path::cost, dbgPigmentCCS, KoColorConversionSystem::Path::endNode(), errorPigment, KoColorConversionSystem::Node::id(), KoColorConversionSystem::Path::isEmpty(), KoColorConversionSystem::Path::isGood, PathQualityChecker::isGoodPath(), KIS_ASSERT, KoColorConversionSystem::Path::length(), PathQualityChecker::lessWorseThan(), KoColorConversionSystem::Node::outputVertexes, p, p2, KoColorConversionSystem::Node::referenceDepth, KoColorConversionSystem::Path::referenceDepth, KoColorConversionSystem::Path::startNode(), v, and warnPigment.

◆ findBestPath() [2/3]

KoColorConversionSystem::Path KoColorConversionSystem::findBestPath ( const NodeKey & src,
const NodeKey & dst ) const
Returns
the best path for the specified color spaces. Used for testing purposes only

Definition at line 388 of file KoColorConversionSystem.cpp.

389{
390 const Node *srcNode = nodeFor(src);
391 const Node *dstNode = nodeFor(dst);
392
393 KIS_ASSERT(srcNode);
394 KIS_ASSERT(dstNode);
395
396 return findBestPath(srcNode, dstNode);
397}

References findBestPath(), KIS_ASSERT, and nodeFor().

◆ findBestPath() [3/3]

KoColorConversionSystem::Path KoColorConversionSystem::findBestPath ( const QString & srcModelId,
const QString & srcDepthId,
const QString & srcProfileName,
const QString & dstModelId,
const QString & dstDepthId,
const QString & dstProfileName ) const
Returns
the best path for the specified color spaces. Used for testing purposes only

Definition at line 377 of file KoColorConversionSystem.cpp.

378{
379 const Node *srcNode = nodeFor(srcModelId, srcDepthId, srcProfileName);
380 const Node *dstNode = nodeFor(dstModelId, dstDepthId, dstProfileName);
381
382 KIS_ASSERT(srcNode);
383 KIS_ASSERT(dstNode);
384
385 return findBestPath(srcNode, dstNode);
386}

References findBestPath(), KIS_ASSERT, and nodeFor().

◆ insertColorProfile()

void KoColorConversionSystem::insertColorProfile ( const KoColorProfile * _profile)

Definition at line 116 of file KoColorConversionSystem.cpp.

117{
118 dbgPigmentCCS << _profile->name();
119 const QList< const KoColorSpaceFactory* >& factories = d->registryInterface->colorSpacesFor(_profile);
120 Q_FOREACH (const KoColorSpaceFactory* factory, factories) {
121 QString modelId = factory->colorModelId().id();
122 QString depthId = factory->colorDepthId().id();
123 Node* n = nodeFor(modelId, depthId, _profile->name());
124 n->init(factory);
125 if (!factory->colorSpaceEngine().isEmpty()) {
127 Q_ASSERT(engine);
128 Node* engineNode = d->graph[ NodeKey(engine->id(), engine->id(), engine->id())];
129 Q_ASSERT(engineNode);
130
131 if (engine->supportsColorSpace(modelId, depthId, _profile)) {
132 connectToEngine(n, engineNode);
133 }
134 }
136 Q_FOREACH (KoColorConversionTransformationFactory* cctf, cctfs) {
137 Node* srcNode = nodeFor(cctf->srcColorModelId(), cctf->srcColorDepthId(), cctf->srcProfile());
138 Q_ASSERT(srcNode);
139 Node* dstNode = nodeFor(cctf->dstColorModelId(), cctf->dstColorDepthId(), cctf->dstProfile());
140 Q_ASSERT(dstNode);
141 if (srcNode == n || dstNode == n) {
142 // Check if the two nodes are already connected
143 Vertex* v = vertexBetween(srcNode, dstNode);
144 // If the vertex doesn't already exist, then create it
145 if (!v) {
146 v = createVertex(srcNode, dstNode);
147 }
148 Q_ASSERT(v); // we should have one now
149 if (dstNode->modelId == modelId && dstNode->depthId == depthId) {
150 v->setFactoryFromDst(cctf);
151 }
152 if (srcNode->modelId == modelId && srcNode->depthId == depthId) {
153 v->setFactoryFromSrc(cctf);
154 }
155 }
156 }
157 }
158}
void connectToEngine(Node *_node, Node *_engine)
Vertex * vertexBetween(Node *srcNode, Node *dstNode)
static KoColorSpaceEngineRegistry * instance()
T get(const QString &id) const
virtual bool supportsColorSpace(const QString &colorModelId, const QString &colorDepthId, const KoColorProfile *profile) const
virtual QList< KoColorConversionTransformationFactory * > colorConversionLinks() const =0
virtual QString colorSpaceEngine() const =0

References KoColorSpaceFactory::colorConversionLinks(), KoColorSpaceFactory::colorDepthId(), KoColorSpaceFactory::colorModelId(), KoColorSpaceFactory::colorSpaceEngine(), connectToEngine(), createVertex(), d, dbgPigmentCCS, KoColorConversionSystem::Node::depthId, KoColorConversionTransformationFactory::dstColorDepthId(), KoColorConversionTransformationFactory::dstColorModelId(), KoColorConversionTransformationFactory::dstProfile, KoGenericRegistry< T >::get(), KoID::id(), KoColorSpaceEngine::id, KoColorConversionSystem::Node::init(), KoColorSpaceEngineRegistry::instance(), KoColorConversionSystem::Node::modelId, KoColorProfile::name, nodeFor(), KoColorConversionTransformationFactory::srcColorDepthId(), KoColorConversionTransformationFactory::srcColorModelId(), KoColorConversionTransformationFactory::srcProfile, KoColorSpaceEngine::supportsColorSpace(), v, and vertexBetween().

◆ insertColorSpace()

void KoColorConversionSystem::insertColorSpace ( const KoColorSpaceFactory * csf)

This function is called by the KoColorSpaceRegistry to add a new color space to the graph of transformation.

Definition at line 56 of file KoColorConversionSystem.cpp.

57{
58 dbgPigment << "Inserting color space " << csf->name() << " (" << csf->id() << ") Model: " << csf->colorModelId() << " Depth: " << csf->colorDepthId() << " into the CCS";
59 const QList<const KoColorProfile*> profiles = d->registryInterface->profilesFor(csf);
60 QString modelId = csf->colorModelId().id();
61 QString depthId = csf->colorDepthId().id();
62 if (profiles.isEmpty()) { // There is no profile for this CS, create a node without profile name if the color engine isn't icc-based
63 if (csf->colorSpaceEngine() != "icc") {
64 Node* n = nodeFor(modelId, depthId, "default");
65 n->init(csf);
66 }
67 else {
68 dbgPigment << "Cannot add node for " << csf->name() << ", since there are no profiles available";
69 }
70 } else {
71 // Initialise the nodes
72 Q_FOREACH (const KoColorProfile* profile, profiles) {
73 Node* n = nodeFor(modelId, depthId, profile->name());
74 n->init(csf);
75 if (!csf->colorSpaceEngine().isEmpty()) {
77 Q_ASSERT(engine);
78 NodeKey engineKey(engine->id(), engine->id(), engine->id());
79 Node* engineNode = 0;
80 QHash<NodeKey, Node*>::ConstIterator it = d->graph.constFind(engineKey);
81 if (it != d->graph.constEnd()) {
82 engineNode = it.value();
83 } else {
84 engineNode = insertEngine(engine);
85 }
86
87 if (engine->supportsColorSpace(modelId, depthId, profile)) {
88 connectToEngine(n, engineNode);
89 }
90 }
91 }
92 }
93 // Construct a link for "custom" transformation
95 Q_FOREACH (KoColorConversionTransformationFactory* cctf, cctfs) {
96 Node* srcNode = nodeFor(cctf->srcColorModelId(), cctf->srcColorDepthId(), cctf->srcProfile());
97 Q_ASSERT(srcNode);
98 Node* dstNode = nodeFor(cctf->dstColorModelId(), cctf->dstColorDepthId(), cctf->dstProfile());
99 Q_ASSERT(dstNode);
100 // Check if the two nodes are already connected
101 Vertex* v = vertexBetween(srcNode, dstNode);
102 // If the vertex doesn't already exist, then create it
103 if (!v) {
104 v = createVertex(srcNode, dstNode);
105 }
106 Q_ASSERT(v); // we should have one now
107 if (dstNode->modelId == modelId && dstNode->depthId == depthId) {
108 v->setFactoryFromDst(cctf);
109 }
110 if (srcNode->modelId == modelId && srcNode->depthId == depthId) {
111 v->setFactoryFromSrc(cctf);
112 }
113 }
114}
#define dbgPigment
Node * insertEngine(const KoColorSpaceEngine *engine)
virtual QString name() const =0
virtual QString id() const =0

References KoColorSpaceFactory::colorConversionLinks(), KoColorSpaceFactory::colorDepthId(), KoColorSpaceFactory::colorModelId(), KoColorSpaceFactory::colorSpaceEngine(), connectToEngine(), createVertex(), d, dbgPigment, KoColorConversionSystem::Node::depthId, KoColorConversionTransformationFactory::dstColorDepthId(), KoColorConversionTransformationFactory::dstColorModelId(), KoColorConversionTransformationFactory::dstProfile, KoGenericRegistry< T >::get(), KoID::id(), KoColorSpaceEngine::id, KoColorSpaceFactory::id(), KoColorConversionSystem::Node::init(), insertEngine(), KoColorSpaceEngineRegistry::instance(), KoColorConversionSystem::Node::modelId, KoColorProfile::name, KoColorSpaceFactory::name(), nodeFor(), KoColorConversionTransformationFactory::srcColorDepthId(), KoColorConversionTransformationFactory::srcColorModelId(), KoColorConversionTransformationFactory::srcProfile, KoColorSpaceEngine::supportsColorSpace(), v, and vertexBetween().

◆ insertEngine()

KoColorConversionSystem::Node * KoColorConversionSystem::insertEngine ( const KoColorSpaceEngine * engine)
private

Insert an engine.

Definition at line 42 of file KoColorConversionSystem.cpp.

43{
44 NodeKey key(engine->id(), engine->id(), engine->id());
45 Node* n = new Node;
46 n->modelId = engine->id();
47 n->depthId = engine->id();
48 n->profileName = engine->id();
49 n->referenceDepth = 64; // engine don't have reference depth,
50 d->graph.insert(key, n);
51 n->init(engine);
52 return n;
53}

References d, KoColorConversionSystem::Node::depthId, KoColorSpaceEngine::id, KoColorConversionSystem::Node::init(), KoColorConversionSystem::Node::modelId, KoColorConversionSystem::Node::profileName, and KoColorConversionSystem::Node::referenceDepth.

◆ nodeFor() [1/5]

const KoColorConversionSystem::Node * KoColorConversionSystem::nodeFor ( const KoColorSpace * _colorSpace) const
private

Definition at line 175 of file KoColorConversionSystem.cpp.

176{
177 const KoColorProfile* profile = _colorSpace->profile();
178 return nodeFor(_colorSpace->colorModelId().id(), _colorSpace->colorDepthId().id(),
179 profile ? profile->name() : "default");
180}

References KoColorSpace::colorDepthId(), KoColorSpace::colorModelId(), KoID::id(), KoColorProfile::name, nodeFor(), and KoColorSpace::profile().

◆ nodeFor() [2/5]

KoColorConversionSystem::Node * KoColorConversionSystem::nodeFor ( const NodeKey & key)
private
Returns
the node corresponding to that key, or create it if needed

Definition at line 199 of file KoColorConversionSystem.cpp.

200{
201 QHash<NodeKey, Node*>::ConstIterator it = d->graph.constFind(key);
202 if (it != d->graph.constEnd()) {
203 return it.value();
204 } else {
205 return createNode(key.modelId, key.depthId, key.profileName);
206 }
207}
Node * createNode(const QString &_modelId, const QString &_depthId, const QString &_profileName)

References createNode(), d, KoColorConversionSystem::NodeKey::depthId, KoColorConversionSystem::NodeKey::modelId, and KoColorConversionSystem::NodeKey::profileName.

◆ nodeFor() [3/5]

const KoColorConversionSystem::Node * KoColorConversionSystem::nodeFor ( const NodeKey & key) const
private

Definition at line 188 of file KoColorConversionSystem.cpp.

189{
190 dbgPigmentCCS << "Look for node: " << key.modelId << " " << key.depthId << " " << key.profileName << " " << d->graph.value(key);
191 return d->graph.value(key);
192}

References d, dbgPigmentCCS, KoColorConversionSystem::NodeKey::depthId, KoColorConversionSystem::NodeKey::modelId, and KoColorConversionSystem::NodeKey::profileName.

◆ nodeFor() [4/5]

KoColorConversionSystem::Node * KoColorConversionSystem::nodeFor ( const QString & colorModelId,
const QString & colorDepthId,
const QString & _profileName )
private
Returns
the node associated with that key, and create it if needed

Definition at line 194 of file KoColorConversionSystem.cpp.

195{
196 return nodeFor(NodeKey(_colorModelId, _colorDepthId, _profileName));
197}

References nodeFor().

◆ nodeFor() [5/5]

const KoColorConversionSystem::Node * KoColorConversionSystem::nodeFor ( const QString & colorModelId,
const QString & colorDepthId,
const QString & _profileName ) const
private

Definition at line 182 of file KoColorConversionSystem.cpp.

183{
184 dbgPigmentCCS << "Look for node: " << _colorModelId << " " << _colorDepthId << " " << _profileName;
185 return nodeFor(NodeKey(_colorModelId, _colorDepthId, _profileName));
186}

References dbgPigmentCCS, and nodeFor().

◆ nodesFor()

QList< KoColorConversionSystem::Node * > KoColorConversionSystem::nodesFor ( const QString & _modelId,
const QString & _depthId )
private
Returns
the list of nodes that correspond to a given model and depth.

Definition at line 209 of file KoColorConversionSystem.cpp.

210{
211 QList<Node*> nodes;
212 Q_FOREACH (Node* node, d->graph) {
213 if (node->modelId == _modelId && node->depthId == _depthId) {
214 nodes << node;
215 }
216 }
217 return nodes;
218}

References d, KoColorConversionSystem::Node::depthId, and KoColorConversionSystem::Node::modelId.

◆ Private()

KoColorConversionSystem::Private ( RegistryInterface * _registryInterface)
inline

Definition at line 326 of file KoColorConversionSystem_p.h.

326: registryInterface(_registryInterface) {}

◆ toDot()

QString KoColorConversionSystem::toDot ( ) const

This function return a text that can be compiled using dot to display the graph of color conversion connection.

Definition at line 342 of file KoColorConversionSystem.cpp.

343{
344 QString dot = "digraph CCS {\n";
345 Q_FOREACH (Vertex* oV, d->vertexes) {
346 dot += vertexToDot(oV, "default") ;
347 }
348 dot += "}\n";
349 return dot;
350}

References d, and vertexToDot().

◆ vertexBetween()

KoColorConversionSystem::Vertex * KoColorConversionSystem::vertexBetween ( KoColorConversionSystem::Node * srcNode,
KoColorConversionSystem::Node * dstNode )
private
Returns
the vertex between two nodes, or null if the vertex doesn't exist

Definition at line 317 of file KoColorConversionSystem.cpp.

318{
319 Q_FOREACH (Vertex* oV, srcNode->outputVertexes) {
320 if (oV->dstNode == dstNode) {
321 return oV;
322 }
323 }
324 return 0;
325}

References KoColorConversionSystem::Vertex::dstNode, and KoColorConversionSystem::Node::outputVertexes.

◆ vertexToDot()

QString KoColorConversionSystem::vertexToDot ( KoColorConversionSystem::Vertex * v,
const QString & options ) const
private

Definition at line 337 of file KoColorConversionSystem.cpp.

338{
339 return QString(" \"%1\" -> \"%2\" %3\n").arg(v->srcNode->id()).arg(v->dstNode->id()).arg(options);
340}

References v.

Friends And Related Symbol Documentation

◆ qHash

uint qHash ( const KoColorConversionSystem::NodeKey & key)
friend

Definition at line 319 of file KoColorConversionSystem_p.h.

320{
321 return qHash(key.modelId) + qHash(key.depthId);
322}
friend uint qHash(const KoColorConversionSystem::NodeKey &key)

Member Data Documentation

◆ d

Private* const KoColorConversionSystem::d
private

Definition at line 176 of file KoColorConversionSystem.h.

◆ graph

QHash<NodeKey, Node*> KoColorConversionSystem::graph

Definition at line 328 of file KoColorConversionSystem_p.h.

◆ registryInterface

RegistryInterface* KoColorConversionSystem::registryInterface

Definition at line 330 of file KoColorConversionSystem_p.h.

◆ vertexes

QList<Vertex*> KoColorConversionSystem::vertexes

Definition at line 329 of file KoColorConversionSystem_p.h.


The documentation for this struct was generated from the following files: