22
22
struct KoColorConversionSystem::Node {
27
, isInitialized(false)
31
, colorSpaceFactory(0)
35
void init( const KoColorSpaceFactory* _colorSpaceFactory)
27
, isInitialized(false)
31
, colorSpaceFactory(0)
35
void init(const KoColorSpaceFactory* _colorSpaceFactory) {
37
36
dbgPigment << "Initialise " << modelId << " " << depthId << " " << profileName;
38
Q_ASSERT(not isInitialized);
39
dbgPigment << "Re-initializing node. Old factory" << colorSpaceFactory << "new factory" << _colorSpaceFactory;
39
41
isInitialized = true;
41
if(_colorSpaceFactory)
43
if (_colorSpaceFactory) {
43
44
isIcc = _colorSpaceFactory->colorSpaceEngine() == "icc";
44
45
isHdr = _colorSpaceFactory->isHdr();
45
46
colorSpaceFactory = _colorSpaceFactory;
46
47
referenceDepth = _colorSpaceFactory->referenceDepth();
47
isGray = ( _colorSpaceFactory->colorModelId() == GrayAColorModelID
48
or _colorSpaceFactory->colorModelId() == GrayColorModelID );
48
isGray = (_colorSpaceFactory->colorModelId() == GrayAColorModelID
49
|| _colorSpaceFactory->colorModelId() == GrayColorModelID);
52
void init( const KoColorSpaceEngine* _engine)
54
Q_ASSERT(not isInitialized);
53
void init(const KoColorSpaceEngine* _engine) {
54
Q_ASSERT(!isInitialized);
56
56
isInitialized = true;
60
60
QString id() const {
61
61
return modelId + " " + depthId + " " + profileName;
66
66
QString profileName;
79
79
struct KoColorConversionSystem::Vertex {
81
Vertex(Node* _srcNode, Node* _dstNode)
81
Vertex(Node* _srcNode, Node* _dstNode)
91
89
if (factoryFromSrc == factoryFromDst) {
92
90
delete factoryFromSrc;
95
92
delete factoryFromSrc;
96
93
delete factoryFromDst;
100
void setFactoryFromSrc(KoColorConversionTransformationFactory* factory)
97
void setFactoryFromSrc(KoColorConversionTransformationFactory* factory) {
102
98
factoryFromSrc = factory;
103
99
initParameter(factoryFromSrc);
106
void setFactoryFromDst(KoColorConversionTransformationFactory* factory)
102
void setFactoryFromDst(KoColorConversionTransformationFactory* factory) {
108
103
factoryFromDst = factory;
109
104
if (!factoryFromSrc) initParameter(factoryFromDst);
112
void initParameter(KoColorConversionTransformationFactory* transfo)
107
void initParameter(KoColorConversionTransformationFactory* transfo) {
114
108
conserveColorInformation = transfo->conserveColorInformation();
115
109
conserveDynamicRange = transfo->conserveDynamicRange();
118
KoColorConversionTransformationFactory* factory()
112
KoColorConversionTransformationFactory* factory() {
120
113
if (factoryFromSrc) return factoryFromSrc;
121
114
return factoryFromDst;
137
130
struct KoColorConversionSystem::NodeKey {
139
132
NodeKey(QString _modelId, QString _depthId, QString _profileName)
142
, profileName(_profileName)
135
, profileName(_profileName) {}
145
bool operator==(const KoColorConversionSystem::NodeKey& rhs) const
147
return modelId == rhs.modelId and depthId == rhs.depthId and profileName == rhs.profileName;
137
bool operator==(const KoColorConversionSystem::NodeKey& rhs) const {
138
return modelId == rhs.modelId && depthId == rhs.depthId && profileName == rhs.profileName;
181
171
void appendVertex(Vertex* v) {
172
if (vertexes.empty()) {
184
173
referenceDepth = v->srcNode->referenceDepth;
186
175
vertexes.append(v);
187
if(not v->conserveColorInformation) respectColorCorrectness = false;
188
if(not v->conserveDynamicRange) keepDynamicRange = false;
189
referenceDepth = qMin( referenceDepth, v->dstNode->referenceDepth);
176
if (!v->conserveColorInformation) respectColorCorrectness = false;
177
if (!v->conserveDynamicRange) keepDynamicRange = false;
178
referenceDepth = qMin(referenceDepth, v->dstNode->referenceDepth);
190
179
cost += v->dstNode->crossingCost;
193
182
// Compress path to hide the Engine node and correctly select the factory
194
183
typedef QPair<Node*, const KoColorConversionTransformationAbstractFactory* > node2factory;
195
QList< node2factory > compressedPath() const
184
QList< node2factory > compressedPath() const {
197
185
QList< node2factory > nodes;
198
nodes.push_back( node2factory( vertexes.first()->srcNode , vertexes.first()->factory() ) );
186
nodes.push_back(node2factory(vertexes.first()->srcNode , vertexes.first()->factory()));
199
187
const KoColorConversionTransformationAbstractFactory* previousFactory = 0;
200
foreach( Vertex* vertex, vertexes)
201
{ // Unless the node is the icc node, add it to the path
188
foreach(Vertex* vertex, vertexes) { // Unless the node is the icc node, add it to the path
202
189
Node* n = vertex->dstNode;
205
191
previousFactory = n->engine;
209
previousFactory ? previousFactory : vertex->factory() ) );
195
previousFactory ? previousFactory : vertex->factory()));
210
196
previousFactory = 0;
218
203
return vertexes.size();
221
bool contains(Node* n) const
223
foreach(Vertex* v, vertexes)
225
if(v->srcNode == n or v->dstNode == n)
206
bool contains(Node* n) const {
207
foreach(Vertex* v, vertexes) {
208
if (v->srcNode == n || v->dstNode == n) {
259
243
#define CHECK_ONE_AND_NOT_THE_OTHER(name) \
260
if(path1-> name and not path2-> name) \
264
if(not path1-> name and path2-> name) \
244
if(path1-> name && !path2-> name) \
248
if(!path1-> name && path2-> name) \
269
253
struct PathQualityChecker {
270
254
PathQualityChecker(int _referenceDepth, bool _ignoreHdr, bool _ignoreColorCorrectness) : referenceDepth(_referenceDepth), ignoreHdr(_ignoreHdr), ignoreColorCorrectness(_ignoreColorCorrectness) {}
271
255
/// @return true if the path maximize all the criterions (except length)
272
inline bool isGoodPath(KoColorConversionSystem::Path* path)
274
return ( path->respectColorCorrectness or ignoreColorCorrectness ) and
275
( path->referenceDepth >= referenceDepth) and
276
( path->keepDynamicRange or ignoreHdr );
256
inline bool isGoodPath(KoColorConversionSystem::Path* path) {
257
return (path->respectColorCorrectness || ignoreColorCorrectness) &&
258
(path->referenceDepth >= referenceDepth) &&
259
(path->keepDynamicRange || ignoreHdr);
279
* Compare two pathes.
281
inline bool lessWorseThan(KoColorConversionSystem::Path* path1, KoColorConversionSystem::Path* path2)
283
// There is no point in comparing two pathes which doesn't start from the same node or doesn't end at the same node
264
inline bool lessWorseThan(KoColorConversionSystem::Path* path1, KoColorConversionSystem::Path* path2) {
265
// There is no point in comparing two paths which doesn't start from the same node or doesn't end at the same node
286
267
CHECK_ONE_AND_NOT_THE_OTHER(keepDynamicRange)
288
if(not ignoreColorCorrectness)
269
if (!ignoreColorCorrectness) {
290
270
CHECK_ONE_AND_NOT_THE_OTHER(respectColorCorrectness)
292
if( path1->referenceDepth == path2->referenceDepth)
272
if (path1->referenceDepth == path2->referenceDepth) {
294
273
return path1->cost < path2->cost; // if they have the same cost, well anyway you have to choose one, and there is no point in keeping one and not the other
296
275
return path1->referenceDepth > path2->referenceDepth;