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 403 of file KoColorConversionSystem.cpp.

404{
405 const Node* srcNode = 0;
406 const Node* dstNode = 0;
407 Q_FOREACH (Node* node, d->graph) {
408 if (node->id() == srcKey) {
409 srcNode = node;
410 }
411 if (node->id() == dstKey) {
412 dstNode = node;
413 }
414 }
415 Path p = findBestPath(srcNode, dstNode);
416 Q_ASSERT(!p.isEmpty());
417 QString dot = "digraph CCS {\n" +
418 QString(" \"%1\" [color=red]\n").arg(srcNode->id()) +
419 QString(" \"%1\" [color=red]\n").arg(dstNode->id());
420 Q_FOREACH (Vertex* oV, d->vertexes) {
421 QString options;
422 if (p.vertexes.contains(oV)) {
423 options = "[color=red]";
424 }
425 dot += vertexToDot(oV, options) ;
426 }
427 dot += "}\n";
428 return dot;
429}
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 223 of file KoColorConversionSystem.cpp.

224{
225 Q_ASSERT(srcColorSpace);
226 Q_ASSERT(dstColorSpace);
227 if (*srcColorSpace == *dstColorSpace) {
228 return new KoCopyColorConversionTransformation(srcColorSpace);
229 }
230 dbgPigmentCCS << srcColorSpace->id() << (srcColorSpace->profile() ? srcColorSpace->profile()->name() : "default");
231 dbgPigmentCCS << dstColorSpace->id() << (dstColorSpace->profile() ? dstColorSpace->profile()->name() : "default");
232 Path path = findBestPath(
233 nodeFor(srcColorSpace),
234 nodeFor(dstColorSpace));
235 Q_ASSERT(path.length() > 0);
236 KoColorConversionTransformation* transfo = createTransformationFromPath(path, srcColorSpace, dstColorSpace, renderingIntent, conversionFlags);
237 Q_ASSERT(transfo);
238 Q_ASSERT(*transfo->srcColorSpace() == *srcColorSpace);
239 Q_ASSERT(*transfo->dstColorSpace() == *dstColorSpace);
240 return transfo;
241}
#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 243 of file KoColorConversionSystem.cpp.

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

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

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 277 of file KoColorConversionSystem.cpp.

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

331{
332 Vertex* v = new Vertex(srcNode, dstNode);
333 srcNode->outputVertexes.append(v);
334 d->vertexes.append(v);
335 return v;
336}
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 163 of file KoColorConversionSystem.cpp.

164{
165 return d->registryInterface->colorSpace(node->modelId, node->depthId, node->profileName);
166}

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 368 of file KoColorConversionSystem.cpp.

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

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 355 of file KoColorConversionSystem.cpp.

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

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 431 of file KoColorConversionSystem.cpp.

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

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

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 380 of file KoColorConversionSystem.cpp.

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

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

◆ insertColorProfile()

void KoColorConversionSystem::insertColorProfile ( const KoColorProfile * _profile)

Definition at line 118 of file KoColorConversionSystem.cpp.

119{
120 dbgPigmentCCS << _profile->name();
121 const QList< const KoColorSpaceFactory* >& factories = d->registryInterface->colorSpacesFor(_profile);
122 Q_FOREACH (const KoColorSpaceFactory* factory, factories) {
123 QString modelId = factory->colorModelId().id();
124 QString depthId = factory->colorDepthId().id();
125 Node* n = nodeFor(modelId, depthId, _profile->name());
126 n->init(factory);
127 if (!factory->colorSpaceEngine().isEmpty()) {
129 Q_ASSERT(engine);
130 Node* engineNode = d->graph[ NodeKey(engine->id(), engine->id(), engine->id())];
131 Q_ASSERT(engineNode);
132
133 if (engine->supportsColorSpace(modelId, depthId, _profile)) {
134 connectToEngine(n, engineNode);
135 }
136 }
138 cctfs.append(factory->colorConversionLinksFromProfile(_profile));
139 Q_FOREACH (KoColorConversionTransformationFactory* cctf, cctfs) {
140 Node* srcNode = nodeFor(cctf->srcColorModelId(), cctf->srcColorDepthId(), cctf->srcProfile());
141 Q_ASSERT(srcNode);
142 Node* dstNode = nodeFor(cctf->dstColorModelId(), cctf->dstColorDepthId(), cctf->dstProfile());
143 Q_ASSERT(dstNode);
144 if (srcNode == n || dstNode == n) {
145 // Check if the two nodes are already connected
146 Vertex* v = vertexBetween(srcNode, dstNode);
147 // If the vertex doesn't already exist, then create it
148 if (!v) {
149 v = createVertex(srcNode, dstNode);
150 }
151 Q_ASSERT(v); // we should have one now
152 if (dstNode->modelId == modelId && dstNode->depthId == depthId) {
153 v->setFactoryFromDst(cctf);
154 }
155 if (srcNode->modelId == modelId && srcNode->depthId == depthId) {
156 v->setFactoryFromSrc(cctf);
157 }
158 }
159 }
160 }
161}
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 QList< KoColorConversionTransformationFactory * > colorConversionLinksFromProfile(const KoColorProfile *profile) const
colorConversionLinksFromProfile Sometimes, we need to generate special color conversion links based o...
virtual QString colorSpaceEngine() const =0

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

References KoColorSpaceFactory::colorConversionLinks(), KoColorSpaceFactory::colorConversionLinksFromProfile(), 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 178 of file KoColorConversionSystem.cpp.

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

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 202 of file KoColorConversionSystem.cpp.

203{
204 QHash<NodeKey, Node*>::ConstIterator it = d->graph.constFind(key);
205 if (it != d->graph.constEnd()) {
206 return it.value();
207 } else {
208 return createNode(key.modelId, key.depthId, key.profileName);
209 }
210}
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 191 of file KoColorConversionSystem.cpp.

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

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 197 of file KoColorConversionSystem.cpp.

198{
199 return nodeFor(NodeKey(_colorModelId, _colorDepthId, _profileName));
200}

References nodeFor().

◆ nodeFor() [5/5]

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

Definition at line 185 of file KoColorConversionSystem.cpp.

186{
187 dbgPigmentCCS << "Look for node: " << _colorModelId << " " << _colorDepthId << " " << _profileName;
188 return nodeFor(NodeKey(_colorModelId, _colorDepthId, _profileName));
189}

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 212 of file KoColorConversionSystem.cpp.

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

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 345 of file KoColorConversionSystem.cpp.

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

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 320 of file KoColorConversionSystem.cpp.

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

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

◆ vertexToDot()

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

Definition at line 340 of file KoColorConversionSystem.cpp.

341{
342 return QString(" \"%1\" -> \"%2\" %3\n").arg(v->srcNode->id()).arg(v->dstNode->id()).arg(options);
343}

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: