Krita Source Code Documentation
Loading...
Searching...
No Matches
KoColorProfileStorage.cpp
Go to the documentation of this file.
1/*
2 * SPDX-FileCopyrightText: 2017 Dmitry Kazakov <dimula73@gmail.com>
3 *
4 * SPDX-License-Identifier: GPL-2.0-or-later
5 */
6
8
9#include <cmath>
10
11#include <QHash>
12#include <QReadWriteLock>
13#include <QString>
14
15#include "DebugPigment.h"
16#include "KoColorSpaceFactory.h"
17#include "KoColorProfile.h"
18#include "kis_assert.h"
19
20
22 QHash<QString, KoColorProfile * > profileMap;
23 QHash<QByteArray, KoColorProfile * > profileUniqueIdMap;
25 QHash<QString, QString> profileAlias;
26 QReadWriteLock lock;
27
29
31 {
32 Q_FOREACH (KoColorProfile *p, profileMap) {
33 profileUniqueIdMap.remove(p->uniqueId());
34 duplicates.removeAll(p);
35 delete p;
36 }
37 profileMap.clear();
38 Q_FOREACH (KoColorProfile *p, profileUniqueIdMap) {
39 duplicates.removeAll(p);
40 delete p;
41 }
42 profileUniqueIdMap.clear();
43 Q_FOREACH(KoColorProfile *p, duplicates) {
44 delete p;
45 }
46 duplicates.clear();
47 }
48};
49
55
59
61{
62 QWriteLocker locker(&d->lock);
63
64 if (profile->valid()) {
65 d->profileMap[profile->name()] = profile;
66 if (d->profileUniqueIdMap.contains(profile->uniqueId())) {
67 //warnPigment << "Duplicated profile" << profile->name() << profile->fileName() << d->profileUniqueIdMap[profile->uniqueId()]->fileName();
68 d->duplicates.append(d->profileUniqueIdMap[profile->uniqueId()]);
69 }
70 d->profileUniqueIdMap.insert(profile->uniqueId(), profile);
71 }
72}
73
75{
76 QWriteLocker locker(&d->lock);
77
78 d->profileMap.remove(profile->name());
79 d->profileUniqueIdMap.remove(profile->uniqueId());
80 d->duplicates.removeAll(profile);
81}
82
84{
85 QReadLocker l(&d->lock);
86 return d->profileMap.contains(profile->name());
87}
88
89void KoColorProfileStorage::addProfileAlias(const QString &name, const QString &to)
90{
91 QWriteLocker l(&d->lock);
92 d->profileAlias[name] = to;
93}
94
95QString KoColorProfileStorage::profileAlias(const QString &name) const
96{
97 QReadLocker l(&d->lock);
98 return d->profileAlias.value(name, name);
99}
100
102{
103 QReadLocker l(&d->lock);
104 return d->profileMap.value(d->profileAlias.value(name, name), 0);
105}
106
108{
109 QWriteLocker l(&lock);
110 profileUniqueIdMap.clear();
111
112 for (auto it = profileMap.constBegin();
113 it != profileMap.constEnd();
114 ++it) {
115
116 KoColorProfile *profile = it.value();
117 QByteArray id = profile->uniqueId();
118
119 if (!id.isEmpty()) {
120 profileUniqueIdMap.insert(id, profile);
121 }
122 }
123}
124
125
127{
128 QReadLocker l(&d->lock);
129 if (d->profileUniqueIdMap.isEmpty()) {
130 l.unlock();
131 d->populateUniqueIdMap();
132 l.relock();
133 }
134 return d->profileUniqueIdMap.value(id, 0);
135
136}
137
139{
141 if (!csf) return profiles;
142
143 QReadLocker l(&d->lock);
144
145 QHash<QString, KoColorProfile * >::ConstIterator it;
146 for (it = d->profileMap.constBegin(); it != d->profileMap.constEnd(); ++it) {
147 KoColorProfile * profile = it.value();
148 if (csf->profileIsCompatible(profile)) {
149 Q_ASSERT(profile);
150 // if (profile->colorSpaceSignature() == csf->colorSpaceSignature()) {
151 profiles.push_back(profile);
152 }
153 }
154 return profiles;
155}
156
158{
160
161 if (colorants.isEmpty() && colorantType == PRIMARIES_UNSPECIFIED && transferType == TRC_UNSPECIFIED) {
162 return profiles;
163 }
164
165 QReadLocker l(&d->lock);
166 for (const KoColorProfile* profile : d->profileMap) {
167 bool colorantMatch = (colorants.isEmpty() || colorantType != PRIMARIES_UNSPECIFIED);
168 bool colorantTypeMatch = (colorantType == PRIMARIES_UNSPECIFIED);
169 bool transferMatch = (transferType == 2);
170 if (colorantType != PRIMARIES_UNSPECIFIED) {
171 if (int(profile->getColorPrimaries()) == colorantType) {
172 colorantTypeMatch = true;
173 }
174 }
175 if (transferType != TRC_UNSPECIFIED) {
176 if (int(profile->getTransferCharacteristics()) == transferType) {
177 transferMatch = true;
178 }
179 }
180
181 if (!colorants.isEmpty() && colorantType == PRIMARIES_UNSPECIFIED) {
182 QVector<qreal> wp = profile->getWhitePointxyY();
183 if (profile->hasColorants() && colorants.size() == 8) {
184 QVector<qreal> col = profile->getColorantsxyY();
185 if (col.size() < 8 || wp.size() < 2) {
186 // too few colorants, skip.
187 continue;
188 }
189 QVector<double> compare = {wp[0], wp[1], col[0], col[1], col[3], col[4], col[6], col[7]};
190
191 for (int i = 0; i < compare.size(); i++) {
192 colorantMatch = std::fabs(compare[i] - colorants[i]) < error;
193 if (!colorantMatch) {
194 break;
195 }
196 }
197 } else {
198 if (wp.size() < 2 || colorants.size() < 2) {
199 // too few colorants, skip.
200 continue;
201 }
202 if (std::fabs(wp[0] - colorants[0]) < error && std::fabs(wp[1] - colorants[1]) < error) {
203 colorantMatch = true;
204 }
205 }
206 }
207
208 if (transferMatch && colorantMatch && colorantTypeMatch) {
209 profiles.push_back(profile);
210 }
211 }
212
213 return profiles;
214}
const Params2D p
ColorPrimaries
The colorPrimaries enum Enum of colorants, follows ITU H.273 for values 0 to 255, and has extra known...
@ PRIMARIES_UNSPECIFIED
TransferCharacteristics
The transferCharacteristics enum Enum of transfer characteristics, follows ITU H.273 for values 0 to ...
const KoColorProfile * profileByName(const QString &name) const
QList< const KoColorProfile * > profilesFor(const KoColorSpaceFactory *csf) const
QString profileAlias(const QString &name) const
void removeProfile(KoColorProfile *profile)
bool containsProfile(const KoColorProfile *profile)
containsProfile shows if a profile is registered in the storage
const KoColorProfile * profileByUniqueId(const QByteArray &id) const
const QScopedPointer< Private > d
void addProfileAlias(const QString &name, const QString &to)
void addProfile(KoColorProfile *profile)
QHash< QByteArray, KoColorProfile * > profileUniqueIdMap
QList< KoColorProfile * > duplicates
QHash< QString, KoColorProfile * > profileMap
QHash< QString, QString > profileAlias
virtual QByteArray uniqueId() const =0
virtual bool valid() const =0
virtual bool profileIsCompatible(const KoColorProfile *profile) const =0