KoColorSpaceRegistry.h 16.2 KB
Newer Older
1 2
/*
 *  Copyright (c) 2003 Patrick Julien  <freak@codepimps.org>
3
 *  Copyright (c) 2004,2010 Cyrille Berger <cberger@cberger.net>
4
 *
5
 * This library is free software; you can redistribute it and/or
6
 * modify it under the terms of the GNU Lesser General Public
7
 * License as published by the Free Software Foundation; either
8
 * version 2.1 of the License, or (at your option) any later version.
9
 *
10 11 12
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13
 * Lesser General Public License for more details.
14
 *
15
 * You should have received a copy of the GNU Lesser General Public License
16 17 18 19
 * along with this library; see the file COPYING.LIB.  If not, write to
 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
 * Boston, MA 02110-1301, USA.
*/
20

21 22
#ifndef KOCOLORSPACEREGISTRY_H
#define KOCOLORSPACEREGISTRY_H
23

24 25 26
#include <QObject>
#include <QList>
#include <QString>
27
#include "kritapigment_export.h"
28

29
#include <KoGenericRegistry.h>
Adrian Page's avatar
Adrian Page committed
30
#include <KoColorSpace.h>
Boudewijn Rempt's avatar
Boudewijn Rempt committed
31
#include <KoColorSpaceFactory.h>
Yuri Chornoivan's avatar
Yuri Chornoivan committed
32
#include <KoConfig.h>
33

Cyrille Berger's avatar
Cyrille Berger committed
34
class KoColorProfile;
35
class KoColorConversionSystem;
36
class KoColorConversionCache;
37
class KoColorConversionTransformation;
38

39
/**
40
 * The registry for colorspaces and profiles.
41
 * This class contains:
Casper Boemann's avatar
Casper Boemann committed
42 43
 *      - a registry of colorspace instantiated with specific profiles.
 *      - a registry of singleton colorspace factories.
44
 *      - a registry of icc profiles
45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61
 *
 * Locking policy details:
 *
 * Basically, we have two levels of locks in the registry:
 * 1) (outer level) is Private::registrylock, which controls the structures
 *     of the color space registry itself
 * 2) (inner level) is KoColorProfileStorage::Private::lock controls
 *    the structures related to profiles.
 *
 * The locks can be taken individually, but if you are going to take both
 * of them, you should always follow the order 1) registry; 2) profiles.
 * Otherwise you'll get a deadlock.
 *
 * To avoid recursive deadlocks, all the dependent classes
 * (KoColorConversionSystem and KoColorSpaceFactory) now do not use the direct
 * links to the registry. Instead, they use special private interfaces that
 * skip recursive locking and ensure we take a lock twice.
62
 */
63
class KRITAPIGMENT_EXPORT KoColorSpaceRegistry
64
{
65
public:
66 67
    KoColorSpaceRegistry();

68 69 70 71
    enum ColorSpaceListVisibility {
        OnlyUserVisible = 1, ///< Only user visible color space
        AllColorSpaces = 4 ///< All color space even those not visible to the user
    };
72 73 74 75
    enum ColorSpaceListProfilesSelection {
        OnlyDefaultProfile = 1, ///< Only add the default profile
        AllProfiles = 4 ///< Add all profiles
    };
76

77
    /**
78
     * Return an instance of the KoColorSpaceRegistry
79
     * Creates an instance if that has never happened before and returns the singleton instance.
80
     */
81
    static KoColorSpaceRegistry * instance();
82

83
    virtual ~KoColorSpaceRegistry();
84

85
public:
86 87 88 89
    /**
      * add a color space to the registry
      * @param item the color space factory to add
      */
90 91 92
    void add(KoColorSpaceFactory* item);

    /**
93
     * Remove a color space factory from the registry. Note that it is the
Jan Hambrecht's avatar
Jan Hambrecht committed
94
     * responsibility of the caller to ensure that the colorspaces are not
95
     * used anymore.
96
     */
97
    void remove(KoColorSpaceFactory* item);
98

99 100 101 102 103 104 105
    /**
     * Add a profile to the profile map but do not add it to the
     * color conversion system yet.
     * @param profile the new profile to be registered.
     */
    void addProfileToMap(KoColorProfile *p);

106
    /**
107
     * register the profile with the color space registry
108
     * @param profile the new profile to be registered so it can be combined with
109
     *  colorspaces.
110
     */
111
    void addProfile(KoColorProfile* profile);
112 113
    void addProfile(const KoColorProfile* profile); // TODO why ?
    void removeProfile(KoColorProfile* profile);
114

115 116 117 118 119
    /**
     * Create an alias to a profile with a different name. Then @ref profileByName
     * will return the profile @p to when passed @p name as a parameter.
     */
    void addProfileAlias(const QString& name, const QString& to);
120

121 122 123 124
    /**
     * @return the profile alias, or name if not aliased
     */
    QString profileAlias(const QString& name) const;
125

126 127 128
    /**
     * create a profile of the specified type.
     */
129
    const KoColorProfile *createColorProfile(const QString & colorModelId, const QString & colorDepthId, const QByteArray& rawData);
130

131
    /**
132 133
     * Return a profile by its given name, or 0 if none registered.
     * @return a profile by its given name, or 0 if none registered.
134 135 136
     * @param name the product name as set on the profile.
     * @see addProfile()
     * @see KoColorProfile::productName()
137
     */
138
    const KoColorProfile * profileByName(const QString & name) const ;
139

140 141 142 143 144 145 146 147 148 149

    /**
     * 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)
     * @param id unique ProfileID of the profile (MD5 sum of its header)
     * @return the profile or 0 if not found
     */
    const KoColorProfile *profileByUniqueId(const QByteArray &id) const;

150
    bool profileIsCompatible(const KoColorProfile* profile, const QString &colorSpaceId);
151

152 153 154
    /**
     * Return the list of profiles for a colorspace with the argument id.
     * Profiles will not work with any color space, you can query which profiles
155
     * that are registered with this registry can be used in combination with the
156
     * argument factory.
Thomas Zander's avatar
Thomas Zander committed
157
     * @param colorSpaceId the colorspace-id with which all the returned profiles will work.
158 159
     * @return a list of profiles for the factory
     */
160 161
    QList<const KoColorProfile *>  profilesFor(const QString& csID) const;
    QString defaultProfileForColorSpace(const QString &colorSpaceId) const;
Cyrille Berger's avatar
Cyrille Berger committed
162

163
    /**
164 165 166
     * This function is called by the color space to create a color conversion
     * between two color space. This function search in the graph of transformations
     * the best possible path between the two color space.
167
     */
168
    KoColorConversionTransformation* createColorConverter(const KoColorSpace * srcColorSpace, const KoColorSpace * dstColorSpace, KoColorConversionTransformation::Intent renderingIntent, KoColorConversionTransformation::ConversionFlags conversionFlags) const;
169

170
    /**
171 172 173 174 175 176 177 178 179 180 181 182 183 184 185
     * This function creates two transformations, one from the color space and one to the
     * color space. The destination color space is picked from a list of color space, such
     * as the conversion between the two color space is of the best quality.
     *
     * The typical use case of this function is for KoColorTransformationFactory which
     * doesn't support all color spaces, so unsupported color space have to find an
     * acceptable conversion in order to use that KoColorTransformationFactory.
     *
     * @param colorSpace the source color space
     * @param possibilities a list of color space among which we need to find the best
     *                      conversion
     * @param fromCS the conversion from the source color space will be affected to this
     *               variable
     * @param toCS the revert conversion to the source color space will be affected to this
     *             variable
186
     */
187
    void createColorConverters(const KoColorSpace* colorSpace, const QList< QPair<KoID, KoID> >& possibilities, KoColorConversionTransformation*& fromCS, KoColorConversionTransformation*& toCS) const;
188

189 190 191 192 193 194 195 196 197 198 199 200 201 202 203
    /**
     * Return a colorspace that works with the parameter profile.
     * @param colorSpaceId the ID string of the colorspace that you want to have returned
     * @param profile the profile be combined with the colorspace
     * @return the wanted colorspace, or 0 when the cs and profile can not be combined.
     */
    const KoColorSpace * colorSpace(const QString & colorModelId, const QString & colorDepthId, const KoColorProfile *profile);

    /**
     * Return a colorspace that works with the parameter profile.
     * @param profileName the name of the KoColorProfile to be combined with the colorspace
     * @return the wanted colorspace, or 0 when the cs and profile can not be combined.
     */
    const KoColorSpace * colorSpace(const QString & colorModelId, const QString & colorDepthId, const QString &profileName);

204 205
    const KoColorSpace * colorSpace(const QString & colorModelId, const QString & colorDepthId);

206 207 208 209 210 211
    /**
     * Return the id of the colorspace that have the defined colorModelId with colorDepthId.
     * @param colorModelId id of the color model
     * @param colorDepthId id of the color depth
     * @return the id of the wanted colorspace, or "" if no colorspace correspond to those ids
     */
212
    QString colorSpaceId(const QString & colorModelId, const QString & colorDepthId) const;
213 214 215 216 217 218 219
    /**
     * It's a convenient function that behave like the above.
     * Return the id of the colorspace that have the defined colorModelId with colorDepthId.
     * @param colorModelId id of the color model
     * @param colorDepthId id of the color depth
     * @return the id of the wanted colorspace, or "" if no colorspace correspond to those ids
     */
220 221 222
    QString colorSpaceId(const KoID& colorModelId, const KoID& colorDepthId) const;

    /**
Yuri Chornoivan's avatar
Yuri Chornoivan committed
223
     * @return the identifier of the color model for the given color space id.
224 225 226 227 228 229 230
     *
     * This function is a compatibility function used to get the color space from
     * all kra files.
     */
    KoID colorSpaceColorModelId(const QString & _colorSpaceId) const;

    /**
Yuri Chornoivan's avatar
Yuri Chornoivan committed
231
     * @return the identifier of the color depth for the given color space id.
232 233 234 235 236
     *
     * This function is a compatibility function used to get the color space from
     * all kra files.
     */
    KoID colorSpaceColorDepthId(const QString & _colorSpaceId) const;
237

238
    /**
239
     * Convenience methods to get the often used alpha colorspaces
240
     */
241 242 243 244 245 246
    const KoColorSpace *alpha8();
    const KoColorSpace *alpha16();
#ifdef HAVE_OPENEXR
    const KoColorSpace *alpha16f();
#endif
    const KoColorSpace *alpha32f();
247

248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280
    /**
     * Convenience method to get a GRAYA 8 bit colorspace. If a profile is not specified,
     * the default profile defined in the GRAY colorspace will be used
     * @param profile the profile name
     * @return an 8 bit graya colorspace with the default profile or 0.
     */
    const KoColorSpace *graya8(const QString &profile = QString());

    /**
     * Convenience method to get a GRAYA 8 bit colorspace. If a profile is not specified,
     * the default profile defined in the GRAY colorspace will be used
     * @param profile the profile
     * @return an 8 bit graya colorspace with the default profile or 0.
     */
    const KoColorSpace *graya8(const KoColorProfile *profile);

    /**
     * Convenience method to get a GRAYA 16 bit colorspace. If a profile is not specified,
     * the default profile defined in the GRAY colorspace will be used
     * @param the profile
     * @return an 8 bit graya colorspace with the default profile or 0.
     */
    const KoColorSpace *graya16(const QString &profile = QString());

    /**
     * Convenience method to get a GRAYA 16 bit colorspace. If a profile is not specified,
     * the default profile defined in the GRAY colorspace will be used
     * @param the profile
     * @return an 8 bit graya colorspace with the default profile or 0.
     */
    const KoColorSpace *graya16(const KoColorProfile *profile);


281
    /**
282
     * Convenience method to get an RGBA 8bit colorspace. If a profile is not specified,
283 284 285
     * an sRGB profile will be used.
     * @param profileName the name of an RGB color profile
     * @return the wanted colorspace, or 0 if the color space and profile can not be combined.
286
     */
287
    const KoColorSpace * rgb8(const QString &profileName = QString());
288

289
    /**
290
     * Convenience method to get an RGBA 8bit colorspace with the given profile.
291 292
     * @param profile an RGB profile
     * @return the wanted colorspace, or 0 if the color space and profile can not be combined.
293
     */
294
    const KoColorSpace * rgb8(const KoColorProfile * profile);
295

296
    /**
297
     * Convenience method to get an RGBA 16bit colorspace. If a profile is not specified,
298 299 300 301
     * an sRGB profile will be used.
     * @param profileName the name of an RGB color profile
     * @return the wanted colorspace, or 0 if the color space and profile can not be combined.
     */
302
    const KoColorSpace * rgb16(const QString &profileName = QString());
303 304

    /**
305
     * Convenience method to get an RGBA 16bit colorspace with the given profile.
306 307 308
     * @param profile an RGB profile
     * @return the wanted colorspace, or 0 if the color space and profile can not be combined.
     */
309
    const KoColorSpace * rgb16(const KoColorProfile * profile);
310 311 312 313 314 315 316

    /**
     * Convenience method to get an Lab 16bit colorspace. If a profile is not specified,
     * an Lab profile with a D50 whitepoint will be used.
     * @param profileName the name of an Lab color profile
     * @return the wanted colorspace, or 0 if the color space and profile can not be combined.
     */
317
    const KoColorSpace * lab16(const QString &profileName = QString());
318 319

    /**
320 321 322
     * Convenience method to get an Lab 16bit colorspace with the given profile.
     * @param profile an Lab profile
     * @return the wanted colorspace, or 0 if the color space and profile can not be combined.
323
     */
324
    const KoColorSpace * lab16(const KoColorProfile * profile);
325

326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342
    /**
     * Convenience method to get a standard profile for Rec.2020 linear light
     * color space
     */
    const KoColorProfile *p2020G10Profile() const;

    /**
     * Convenience method to get a standard profile for Rec.2020 PQ color space
     */
    const KoColorProfile *p2020PQProfile() const;

    /**
     * Convenience method to get a standard profile for Rec. 709 linear light
     * color space
     */
    const KoColorProfile *p709G10Profile() const;

343 344 345 346 347 348
    /**
     * Convenience method to get a standard profile for Rec. 709 sRGB-tone-
     * response-curve profile
     */
    const KoColorProfile *p709SRGBProfile() const;

349 350 351
    /**
     * @return the list of available color models
     */
352
    QList<KoID> colorModelsList(ColorSpaceListVisibility option) const;
353

354 355 356
    /**
     * @return the list of available color models for the given colorModelId
     */
357
    QList<KoID> colorDepthList(const KoID& colorModelId, ColorSpaceListVisibility option) const;
358

359 360 361
    /**
     * @return the list of available color models for the given colorModelId
     */
362 363
    QList<KoID> colorDepthList(const QString & colorModelId, ColorSpaceListVisibility option) const;

364 365 366 367
    /**
     * @return the cache of color conversion transformation to be use by KoColorSpace
     */
    KoColorConversionCache* colorConversionCache() const;
368

369 370 371 372
    /**
     * @return a permanent colorspace owned by the registry, of the same type and profile
     *         as the one given in argument
     */
373
    const KoColorSpace* permanentColorspace(const KoColorSpace* _colorSpace);
374 375 376 377 378 379 380

    /**
     * This function return a list of all the keys in KoID format by using the name() method
     * on the objects stored in the registry.
     */
    QList<KoID> listKeys() const;

381 382 383 384
private:

    friend class KisCsConversionTest;
    friend class KisIteratorTest;
385
    friend class KisIteratorNGTest;
386 387 388 389
    friend class KisPainterTest;
    friend class KisCrashFilterTest;
    friend class KoColorSpacesBenchmark;
    friend class TestKoColorSpaceSanity;
390
    friend class TestColorConversionSystem;
391
    friend struct FriendOfColorSpaceRegistry;
392

393
    /**
394
     * @return a list with an instance of all color space with their default profile.
395
     */
Cyrille Berger's avatar
Cyrille Berger committed
396
    QList<const KoColorSpace*> allColorSpaces(ColorSpaceListVisibility visibility, ColorSpaceListProfilesSelection pSelection);
397

398
    /**
399 400 401
     * @return the color conversion system use by the registry and the color
     * spaces to create color conversion transformation.
     *
Yuri Chornoivan's avatar
Yuri Chornoivan committed
402 403
     * WARNING: conversion system is guarded by the registry locks, don't
     *          use it anywhere other than unittests!
404
     */
405
    const KoColorConversionSystem* colorConversionSystem() const;
406

407
private:
408 409
    KoColorSpaceRegistry(const KoColorSpaceRegistry&);
    KoColorSpaceRegistry operator=(const KoColorSpaceRegistry&);
410
    void init();
411 412

private:
Jarosław Staniek's avatar
Jarosław Staniek committed
413
    struct Private;
Stefan Nikolaus's avatar
Stefan Nikolaus committed
414
    Private * const d;
415 416
};

417
#endif // KOCOLORSPACEREGISTRY_H