23 : d(new
Private(registryInterface))
30 qDeleteAll(
d->vertexes);
51 d->graph.insert(key, n);
67 std::copy_if(profileQueries.begin(),
69 std::back_inserter(uniqueProfileQueries),
71 return !uniqueProfileQueries.contains(query);
74 return uniqueProfileQueries;
84 if (profiles.isEmpty()) {
90 dbgPigment <<
"Cannot add node for " << csf->
name() <<
", since there are no profiles available";
102 Node* engineNode = 0;
103 QHash<NodeKey, Node*>::ConstIterator it =
d->graph.constFind(engineKey);
104 if (it !=
d->graph.constEnd()) {
105 engineNode = it.value();
131 v->setFactoryFromDst(cctf);
134 v->setFactoryFromSrc(cctf);
150 std::copy_if(profileQueries.begin(),
151 profileQueries.end(),
152 std::back_inserter(uniqueProfileQueries),
154 return !uniqueProfileQueries.contains(query);
157 return uniqueProfileQueries;
173 Q_ASSERT(engineNode);
186 if (srcNode == n || dstNode == n) {
195 v->setFactoryFromDst(cctf);
198 v->setFactoryFromSrc(cctf);
216 d->graph.insert(
NodeKey(_modelId, _depthId, _profileName), n);
224 profile ? profile->
name() :
"default");
229 dbgPigmentCCS <<
"Look for node: " << _colorModelId <<
" " << _colorDepthId <<
" " << _profileName;
230 return nodeFor(
NodeKey(_colorModelId, _colorDepthId, _profileName));
236 return d->graph.value(key);
241 return nodeFor(
NodeKey(_colorModelId, _colorDepthId, _profileName));
246 QHash<NodeKey, Node*>::ConstIterator it =
d->graph.constFind(key);
247 if (it !=
d->graph.constEnd()) {
257 Q_FOREACH (
Node* node,
d->graph) {
267 Q_ASSERT(srcColorSpace);
268 Q_ASSERT(dstColorSpace);
269 if (*srcColorSpace == *dstColorSpace) {
277 Q_ASSERT(path.length() > 0);
294 typedef QPair<KoID, KoID> KoID2KoID;
295 Q_FOREACH (
const KoID2KoID & possibility, possibilities) {
296 const KoColorSpaceFactory* csf =
d->registryInterface->colorSpaceFactory(possibility.first.id(), possibility.second.id());
299 Q_ASSERT(path.length() > 0);
313 Q_ASSERT(!returnPath.
isEmpty());
321 Q_ASSERT(srcColorSpace->
colorModelId().
id() == path.startNode()->modelId);
322 Q_ASSERT(srcColorSpace->
colorDepthId().
id() == path.startNode()->depthId);
323 Q_ASSERT(dstColorSpace->
colorModelId().
id() == path.endNode()->modelId);
324 Q_ASSERT(dstColorSpace->
colorDepthId().
id() == path.endNode()->depthId);
330 if (pathOfNode.size() == 2) {
331 transfo = pathOfNode[1].second->createColorTransformation(srcColorSpace, dstColorSpace, renderingIntent, conversionFlags);
337 transfo = mccTransfo;
340 dbgPigmentCCS << pathOfNode[ 0 ].first->id() <<
" to " << pathOfNode[ 1 ].first->id();
345 mccTransfo->
appendTransfo(pathOfNode[1].second->createColorTransformation(srcColorSpace, intermCS, renderingIntent, conversionFlags));
347 for (
int i = 2; i < pathOfNode.size() - 1; i++) {
348 dbgPigmentCCS << pathOfNode[ i - 1 ].first->id() <<
" to " << pathOfNode[ i ].first->id();
351 mccTransfo->
appendTransfo(pathOfNode[i].second->createColorTransformation(intermCS, intermCS2, renderingIntent, conversionFlags));
352 intermCS = intermCS2;
355 dbgPigmentCCS << pathOfNode[ pathOfNode.size() - 2 ].first->id() <<
" to " << pathOfNode[ pathOfNode.size() - 1 ].first->id();
356 mccTransfo->
appendTransfo(pathOfNode.last().second->createColorTransformation(intermCS, dstColorSpace, renderingIntent, conversionFlags));
376 d->vertexes.append(
v);
384 return QString(
" \"%1\" -> \"%2\" %3\n").arg(
v->srcNode->id()).arg(
v->dstNode->id()).arg(options);
389 QString dot =
"digraph CCS {\n";
390 Q_FOREACH (
Vertex* oV,
d->vertexes) {
397bool KoColorConversionSystem::existsPath(
const QString& srcModelId,
const QString& srcDepthId,
const QString& srcProfileName,
const QString& dstModelId,
const QString& dstDepthId,
const QString& dstProfileName)
const
399 dbgPigmentCCS <<
"srcModelId = " << srcModelId <<
" srcDepthId = " << srcDepthId <<
" srcProfileName = " << srcProfileName <<
" dstModelId = " << dstModelId <<
" dstDepthId = " << dstDepthId <<
" dstProfileName = " << dstProfileName;
400 const Node* srcNode =
nodeFor(srcModelId, srcDepthId, srcProfileName);
401 const Node* dstNode =
nodeFor(dstModelId, dstDepthId, dstProfileName);
402 if (srcNode == dstNode)
return true;
403 if (!srcNode)
return false;
404 if (!dstNode)
return false;
406 bool exist = !path.isEmpty();
410bool KoColorConversionSystem::existsGoodPath(
const QString& srcModelId,
const QString& srcDepthId,
const QString& srcProfileName,
const QString& dstModelId,
const QString& dstDepthId,
const QString& dstProfileName)
const
412 const Node* srcNode =
nodeFor(srcModelId, srcDepthId, srcProfileName);
413 const Node* dstNode =
nodeFor(dstModelId, dstDepthId, dstProfileName);
414 if (srcNode == dstNode)
return true;
415 if (!srcNode)
return false;
416 if (!dstNode)
return false;
418 bool existAndGood = path.isGood;
424 const Node *srcNode =
nodeFor(srcModelId, srcDepthId, srcProfileName);
425 const Node *dstNode =
nodeFor(dstModelId, dstDepthId, dstProfileName);
447 const Node* srcNode = 0;
448 const Node* dstNode = 0;
449 Q_FOREACH (
Node* node,
d->graph) {
450 if (node->
id() == srcKey) {
453 if (node->
id() == dstKey) {
458 Q_ASSERT(!
p.isEmpty());
459 QString dot =
"digraph CCS {\n" +
460 QString(
" \"%1\" [color=red]\n").arg(srcNode->
id()) +
461 QString(
" \"%1\" [color=red]\n").arg(dstNode->
id());
462 Q_FOREACH (
Vertex* oV,
d->vertexes) {
464 if (
p.vertexes.contains(oV)) {
465 options =
"[color=red]";
478 dbgPigmentCCS <<
"Find best path between " << srcNode->
id() <<
" and " << dstNode->
id();
485 if (
v->dstNode->isInitialized) {
488 Node* endNode =
v->dstNode;
489 if (endNode == dstNode) {
495 node2path.insert(endNode,
p);
496 possiblePaths.append(
p);
501 Path currentBestPath;
503 while (possiblePaths.size() > 0) {
507 for (
const Path &
p : currentPaths) {
508 const Node* endNode =
p.endNode();
510 if (
v->dstNode->isInitialized && !
p.contains(
v->dstNode)) {
513 Node* newEndNode =
v->dstNode;
514 if (newEndNode == dstNode) {
524 currentBestPath = newP;
529 Node2PathHash::Iterator it = node2path.find(newEndNode);
530 if (it != node2path.end()) {
534 possiblePaths.append(newP);
537 node2path.insert(newEndNode, newP);
538 possiblePaths.append(newP);
543 possiblePaths.removeAll(
p);
547 if (!currentBestPath.
isEmpty()) {
548 warnPigment <<
"No good path from " << srcNode->
id() <<
" to " << dstNode->
id() <<
" found : length = " << currentBestPath.
length() <<
" cost = " << currentBestPath.
cost <<
" referenceDepth = " << currentBestPath.
referenceDepth <<
" respectColorCorrectness = " <<
" isGood = " << currentBestPath.
isGood ;
549 return currentBestPath;
551 errorPigment <<
"No path from " << srcNode->
id() <<
" to " << dstNode->
id() <<
" found not ";
552 return currentBestPath;
QHash< KoColorConversionSystem::Node *, KoColorConversionSystem::Path > Node2PathHash
KoColorConversionTransformation * createTransformationFromPath(const KoColorConversionSystem::Path &path, const KoColorSpace *srcColorSpace, const KoColorSpace *dstColorSpace, KoColorConversionTransformation::Intent renderingIntent, KoColorConversionTransformation::ConversionFlags conversionFlags) const
Vertex * createVertex(Node *srcNode, Node *dstNode)
Node * insertEngine(const KoColorSpaceEngine *engine)
QList< Node * > nodesFor(const QString &_modelId, const QString &_depthId)
void connectToEngine(Node *_node, Node *_engine)
void insertColorSpace(const KoColorSpaceFactory *csf)
bool existsGoodPath(const QString &srcModelId, const QString &srcDepthId, const QString &srcProfileName, const QString &dstModelId, const QString &dstDepthId, const QString &dstProfileName) const
KoColorConversionTransformation * createColorConverter(const KoColorSpace *srcColorSpace, const KoColorSpace *dstColorSpace, KoColorConversionTransformation::Intent renderingIntent, KoColorConversionTransformation::ConversionFlags conversionFlags) const
KoColorConversionSystem(RegistryInterface *registryInterface)
Path findBestPath(const QString &srcModelId, const QString &srcDepthId, const QString &srcProfileName, const QString &dstModelId, const QString &dstDepthId, const QString &dstProfileName) const
const KoColorSpace * defaultColorSpaceForNode(const Node *node) const
Vertex * vertexBetween(Node *srcNode, Node *dstNode)
QList< KoColorProfileQuery > requiredConnectionProfilesFor(const KoColorSpaceFactory *csf)
void insertColorProfile(const KoColorProfile *profile)
Node * createNode(const QString &_modelId, const QString &_depthId, const QString &_profileName)
bool existsPath(const QString &srcModelId, const QString &srcDepthId, const QString &srcProfileName, const QString &dstModelId, const QString &dstDepthId, const QString &dstProfileName) const
const Node * nodeFor(const KoColorSpace *) const
~KoColorConversionSystem()
QString bestPathToDot(const QString &srcKey, const QString &dstKey) const
QString vertexToDot(Vertex *v, const QString &options) const
void createColorConverters(const KoColorSpace *colorSpace, const QList< QPair< KoID, KoID > > &possibilities, KoColorConversionTransformation *&fromCS, KoColorConversionTransformation *&toCS) const
static KoColorSpaceEngineRegistry * instance()
virtual KoID colorModelId() const =0
virtual KoID colorDepthId() const =0
virtual const KoColorProfile * profile() const =0
T get(const QString &id) const
void init(const KoColorSpaceFactory *_colorSpaceFactory)
QList< Vertex * > outputVertexes
void appendVertex(Vertex *v)
The KoColorProfileQuery struct.
virtual bool supportsColorSpace(const QString &colorModelId, const QString &colorDepthId, const KoColorProfile *profile) const
virtual KoID colorDepthId() const =0
virtual QString name() const =0
virtual QString defaultProfile() const =0
virtual KoID colorModelId() const =0
virtual QString id() const =0
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
virtual QList< KoColorProfileQuery > requiredConnectionProfiles(const KoColorProfile *profile) const
bool lessWorseThan(const KoColorConversionSystem::Path &path1, const KoColorConversionSystem::Path &path2) const
bool isGoodPath(const KoColorConversionSystem::Path &path) const