File indexing completed on 2024-05-12 15:59:33

0001 /*
0002  *  SPDX-FileCopyrightText: 2017 Dmitry Kazakov <dimula73@gmail.com>
0003  *
0004  *  SPDX-License-Identifier: GPL-2.0-or-later
0005  */
0006 
0007 #ifndef KOCOLORPROFILESTORAGE_H
0008 #define KOCOLORPROFILESTORAGE_H
0009 
0010 #include <QScopedPointer>
0011 #include "KoColorProfileConstants.h"
0012 
0013 class QByteArray;
0014 class QString;
0015 class KoColorProfile;
0016 class KoColorSpaceFactory;
0017 
0018 /**
0019  * @brief The KoColorProfileStorage class is a "composite subclass" of
0020  * KoColorSpaceRegistry that ensures that the access to profiles is guarded
0021  * by a separate lock and the hierarchy of locks is always followed (which
0022  * avoid deadlocks).
0023  *
0024  * Registry locking hierarchy is basically the following:
0025  *
0026  * 1) KoColorSpaceRegistry::Private::registrylock
0027  * 2) KoColorProfileStorage::Private::lock
0028  *
0029  * It means that we can take any single lock if we need it separately, but
0030  * if we need to take both of them, we should always take them is a specified
0031  * order.
0032  *
0033  * Encapsulation of the profile accesses inside a separate class lets us
0034  * follow this rule without even thinking of it. KoColorProfileStorage just
0035  * *never* calls any method of the registry, therefore lock order inversion is
0036  * not possible,
0037  */
0038 class KoColorProfileStorage
0039 {
0040 public:
0041     KoColorProfileStorage();
0042     ~KoColorProfileStorage();
0043 
0044     /**
0045      * Register the profile in the storage
0046      * @param profile the new profile to be registered
0047      */
0048     void addProfile(KoColorProfile* profile);
0049 
0050     /**
0051      * Removes the profile from the storage.
0052      * Please note that the caller should delete the profile object himself!
0053      *
0054      * @param profile the profile to be removed
0055      */
0056     void removeProfile(KoColorProfile* profile);
0057 
0058     /**
0059      * @brief containsProfile shows if a profile is registered in the storage
0060      */
0061     bool containsProfile(const KoColorProfile *profile);
0062 
0063     /**
0064      * Create an alias to a profile with a different name. Then @ref profileByName
0065      * will return the profile @p to when passed @p name as a parameter.
0066      */
0067     void addProfileAlias(const QString& name, const QString& to);
0068 
0069     /**
0070      * @return the profile alias, or name if not aliased
0071      */
0072     QString profileAlias(const QString& name) const;
0073 
0074     /**
0075      * Return a profile by its given name, or 0 if none registered.
0076      * @return a profile by its given name, or 0 if none registered.
0077      * @param name the product name as set on the profile.
0078      * @see addProfile()
0079      * @see KoColorProfile::productName()
0080      */
0081     const KoColorProfile * profileByName(const QString & name) const ;
0082 
0083 
0084     /**
0085      * Returns a profile by its unique id stored/calculated in the header.
0086      * The first call to this function might take long, because the map is
0087      * created on the first use only (atm used by SVG only)
0088      * @param id unique ProfileID of the profile (MD5 sum of its header)
0089      * @return the profile or 0 if not found
0090      */
0091     const KoColorProfile *profileByUniqueId(const QByteArray &id) const;
0092 
0093     /**
0094      * Return the list of profiles for a colorspace represented by its factory.
0095      * Profiles will not work with any color space, you can query which profiles
0096      * that are registered with this registry can be used in combination with the
0097      * argument factory.
0098      * @param csf is a factory for the requested color space
0099      * @return a list of profiles for the factory
0100      */
0101     QList<const KoColorProfile *>  profilesFor(const KoColorSpaceFactory * csf) const;
0102     /**
0103      * @brief profilesFor
0104      * Return the list of profiles for a colorspace represented by it's colorants and type.
0105      * @param colorants list of at the least 2 values representing the whitePoint xyY, or 8
0106      * representing whitePoint, red, green and blue x and y xyY values. If the colorant type
0107      * is set, the colorants will not be used.
0108      * @param colorantType the named colorantType, if 2, it's undefined and the colorants will be used.
0109      * @param transferType the name transfer type, if 2 it's undefined.
0110      * @param error the margin of error with which the colorants get compared.
0111      * @return list of available profiles.
0112      */
0113     QList<const KoColorProfile *> profilesFor(const QVector<double>& colorants,
0114                                               ColorPrimaries colorantType,
0115                                               TransferCharacteristics transferType,
0116                                               double error = 0.00001);
0117 
0118 private:
0119     struct Private;
0120     const QScopedPointer<Private> d;
0121 };
0122 
0123 #endif // KOCOLORPROFILESTORAGE_H