Krita Source Code Documentation
Loading...
Searching...
No Matches
KoColorProfileStorage Class Reference

The KoColorProfileStorage class is a "composite subclass" of KoColorSpaceRegistry that ensures that the access to profiles is guarded by a separate lock and the hierarchy of locks is always followed (which avoid deadlocks). More...

#include <KoColorProfileStorage.h>

Classes

struct  Private
 

Public Member Functions

void addProfile (KoColorProfile *profile)
 
void addProfileAlias (const QString &name, const QString &to)
 
bool containsProfile (const KoColorProfile *profile)
 containsProfile shows if a profile is registered in the storage
 
 KoColorProfileStorage ()
 
QString profileAlias (const QString &name) const
 
const KoColorProfileprofileByName (const QString &name) const
 
const KoColorProfileprofileByUniqueId (const QByteArray &id) const
 
QList< const KoColorProfile * > profilesFor (const KoColorSpaceFactory *csf) const
 
QList< const KoColorProfile * > profilesFor (const QVector< double > &colorants, ColorPrimaries colorantType, TransferCharacteristics transferType, double error=0.00001)
 profilesFor Return the list of profiles for a colorspace represented by it's colorants and type.
 
void removeProfile (KoColorProfile *profile)
 
 ~KoColorProfileStorage ()
 

Private Attributes

const QScopedPointer< Privated
 

Detailed Description

The KoColorProfileStorage class is a "composite subclass" of KoColorSpaceRegistry that ensures that the access to profiles is guarded by a separate lock and the hierarchy of locks is always followed (which avoid deadlocks).

Registry locking hierarchy is basically the following:

1) KoColorSpaceRegistry::Private::registrylock 2) KoColorProfileStorage::Private::lock

It means that we can take any single lock if we need it separately, but if we need to take both of them, we should always take them is a specified order.

Encapsulation of the profile accesses inside a separate class lets us follow this rule without even thinking of it. KoColorProfileStorage just never calls any method of the registry, therefore lock order inversion is not possible,

Definition at line 38 of file KoColorProfileStorage.h.

Constructor & Destructor Documentation

◆ KoColorProfileStorage()

KoColorProfileStorage::KoColorProfileStorage ( )

Definition at line 50 of file KoColorProfileStorage.cpp.

51 : d(new Private)
52{
53
54}
const QScopedPointer< Private > d

◆ ~KoColorProfileStorage()

KoColorProfileStorage::~KoColorProfileStorage ( )

Definition at line 56 of file KoColorProfileStorage.cpp.

57{
58}

Member Function Documentation

◆ addProfile()

void KoColorProfileStorage::addProfile ( KoColorProfile * profile)

Register the profile in the storage

Parameters
profilethe new profile to be registered

Definition at line 60 of file KoColorProfileStorage.cpp.

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}
virtual QByteArray uniqueId() const =0
virtual bool valid() const =0

References d, KoColorProfile::name, KoColorProfile::uniqueId(), and KoColorProfile::valid().

◆ addProfileAlias()

void KoColorProfileStorage::addProfileAlias ( const QString & name,
const QString & to )

Create an alias to a profile with a different name. Then profileByName will return the profile to when passed name as a parameter.

Definition at line 89 of file KoColorProfileStorage.cpp.

90{
91 QWriteLocker l(&d->lock);
92 d->profileAlias[name] = to;
93}
const char * name(StandardAction id)

References d.

◆ containsProfile()

bool KoColorProfileStorage::containsProfile ( const KoColorProfile * profile)

containsProfile shows if a profile is registered in the storage

Definition at line 83 of file KoColorProfileStorage.cpp.

84{
85 QReadLocker l(&d->lock);
86 return d->profileMap.contains(profile->name());
87}

References d, and KoColorProfile::name.

◆ profileAlias()

QString KoColorProfileStorage::profileAlias ( const QString & name) const
Returns
the profile alias, or name if not aliased

Definition at line 95 of file KoColorProfileStorage.cpp.

96{
97 QReadLocker l(&d->lock);
98 return d->profileAlias.value(name, name);
99}

References d.

◆ profileByName()

const KoColorProfile * KoColorProfileStorage::profileByName ( const QString & name) const

Return a profile by its given name, or 0 if none registered.

Returns
a profile by its given name, or 0 if none registered.
Parameters
namethe product name as set on the profile.
See also
addProfile()
KoColorProfile::productName()

Definition at line 101 of file KoColorProfileStorage.cpp.

102{
103 QReadLocker l(&d->lock);
104 return d->profileMap.value(d->profileAlias.value(name, name), 0);
105}

References d.

◆ profileByUniqueId()

const KoColorProfile * KoColorProfileStorage::profileByUniqueId ( const QByteArray & id) const

Returns a profile by its unique id stored/calculated in the header. The first call to this function might take long, because the map is created on the first use only (atm used by SVG only)

Parameters
idunique ProfileID of the profile (MD5 sum of its header)
Returns
the profile or 0 if not found

Definition at line 126 of file KoColorProfileStorage.cpp.

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}

References d.

◆ profilesFor() [1/2]

QList< const KoColorProfile * > KoColorProfileStorage::profilesFor ( const KoColorSpaceFactory * csf) const

Return the list of profiles for a colorspace represented by its factory. Profiles will not work with any color space, you can query which profiles that are registered with this registry can be used in combination with the argument factory.

Parameters
csfis a factory for the requested color space
Returns
a list of profiles for the factory

Definition at line 138 of file KoColorProfileStorage.cpp.

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}
virtual bool profileIsCompatible(const KoColorProfile *profile) const =0

References d, and KoColorSpaceFactory::profileIsCompatible().

◆ profilesFor() [2/2]

QList< const KoColorProfile * > KoColorProfileStorage::profilesFor ( const QVector< double > & colorants,
ColorPrimaries colorantType,
TransferCharacteristics transferType,
double error = 0.00001 )

profilesFor Return the list of profiles for a colorspace represented by it's colorants and type.

Parameters
colorantslist of at the least 2 values representing the whitePoint xyY, or 8 representing whitePoint, red, green and blue x and y xyY values. If the colorant type is set, the colorants will not be used.
colorantTypethe named colorantType, if 2, it's undefined and the colorants will be used.
transferTypethe name transfer type, if 2 it's undefined.
errorthe margin of error with which the colorants get compared.
Returns
list of available profiles.

Definition at line 157 of file KoColorProfileStorage.cpp.

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}
@ PRIMARIES_UNSPECIFIED

References d, PRIMARIES_UNSPECIFIED, and TRC_UNSPECIFIED.

◆ removeProfile()

void KoColorProfileStorage::removeProfile ( KoColorProfile * profile)

Removes the profile from the storage. Please note that the caller should delete the profile object himself!

Parameters
profilethe profile to be removed

Definition at line 74 of file KoColorProfileStorage.cpp.

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}

References d, KoColorProfile::name, and KoColorProfile::uniqueId().

Member Data Documentation

◆ d

const QScopedPointer<Private> KoColorProfileStorage::d
private

Definition at line 120 of file KoColorProfileStorage.h.


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