File indexing completed on 2024-05-12 15:59:35
0001 /* 0002 * SPDX-FileCopyrightText: 2003 Patrick Julien <freak@codepimps.org> 0003 * SPDX-FileCopyrightText: 2004, 2010 Cyrille Berger <cberger@cberger.net> 0004 * 0005 * SPDX-License-Identifier: LGPL-2.1-or-later 0006 */ 0007 0008 #ifndef KOCOLORSPACEREGISTRY_H 0009 #define KOCOLORSPACEREGISTRY_H 0010 0011 #include <QObject> 0012 #include <QList> 0013 #include <QString> 0014 #include "kritapigment_export.h" 0015 0016 #include <KoGenericRegistry.h> 0017 #include <KoColorSpace.h> 0018 #include <KoColorSpaceFactory.h> 0019 #include <KoConfig.h> 0020 #include <KoColorProfileConstants.h> 0021 0022 class KoColorProfile; 0023 class KoColorConversionSystem; 0024 class KoColorConversionCache; 0025 class KoColorConversionTransformation; 0026 0027 /** 0028 * The registry for colorspaces and profiles. 0029 * This class contains: 0030 * - a registry of colorspace instantiated with specific profiles. 0031 * - a registry of singleton colorspace factories. 0032 * - a registry of icc profiles 0033 * 0034 * Locking policy details: 0035 * 0036 * Basically, we have two levels of locks in the registry: 0037 * 1) (outer level) is Private::registrylock, which controls the structures 0038 * of the color space registry itself 0039 * 2) (inner level) is KoColorProfileStorage::Private::lock controls 0040 * the structures related to profiles. 0041 * 0042 * The locks can be taken individually, but if you are going to take both 0043 * of them, you should always follow the order 1) registry; 2) profiles. 0044 * Otherwise you'll get a deadlock. 0045 * 0046 * To avoid recursive deadlocks, all the dependent classes 0047 * (KoColorConversionSystem and KoColorSpaceFactory) now do not use the direct 0048 * links to the registry. Instead, they use special private interfaces that 0049 * skip recursive locking and ensure we take a lock twice. 0050 */ 0051 class KRITAPIGMENT_EXPORT KoColorSpaceRegistry 0052 { 0053 public: 0054 KoColorSpaceRegistry(); 0055 0056 enum ColorSpaceListVisibility { 0057 OnlyUserVisible = 1, ///< Only user visible color space 0058 AllColorSpaces = 4 ///< All color space even those not visible to the user 0059 }; 0060 enum ColorSpaceListProfilesSelection { 0061 OnlyDefaultProfile = 1, ///< Only add the default profile 0062 AllProfiles = 4 ///< Add all profiles 0063 }; 0064 0065 /** 0066 * Return an instance of the KoColorSpaceRegistry 0067 * Creates an instance if that has never happened before and returns the singleton instance. 0068 */ 0069 static KoColorSpaceRegistry * instance(); 0070 0071 virtual ~KoColorSpaceRegistry(); 0072 0073 public: 0074 /** 0075 * add a color space to the registry 0076 * @param item the color space factory to add 0077 */ 0078 void add(KoColorSpaceFactory* item); 0079 0080 /** 0081 * Remove a color space factory from the registry. Note that it is the 0082 * responsibility of the caller to ensure that the colorspaces are not 0083 * used anymore. 0084 */ 0085 void remove(KoColorSpaceFactory* item); 0086 0087 /** 0088 * Add a profile to the profile map but do not add it to the 0089 * color conversion system yet. 0090 * @param profile the new profile to be registered. 0091 */ 0092 void addProfileToMap(KoColorProfile *p); 0093 0094 /** 0095 * register the profile with the color space registry 0096 * @param profile the new profile to be registered so it can be combined with 0097 * colorspaces. 0098 */ 0099 void addProfile(KoColorProfile* profile); 0100 void addProfile(const KoColorProfile* profile); // TODO why ? 0101 void removeProfile(KoColorProfile* profile); 0102 0103 /** 0104 * Create an alias to a profile with a different name. Then @ref profileByName 0105 * will return the profile @p to when passed @p name as a parameter. 0106 */ 0107 void addProfileAlias(const QString& name, const QString& to); 0108 0109 /** 0110 * @return the profile alias, or name if not aliased 0111 */ 0112 QString profileAlias(const QString& name) const; 0113 0114 /** 0115 * create a profile of the specified type. 0116 */ 0117 const KoColorProfile *createColorProfile(const QString & colorModelId, const QString & colorDepthId, const QByteArray& rawData); 0118 0119 /** 0120 * Return a profile by its given name, or 0 if none registered. 0121 * @return a profile by its given name, or 0 if none registered. 0122 * @param name the product name as set on the profile. 0123 * @see addProfile() 0124 * @see KoColorProfile::productName() 0125 */ 0126 const KoColorProfile * profileByName(const QString & name) const ; 0127 0128 0129 /** 0130 * Returns a profile by its unique id stored/calculated in the header. 0131 * The first call to this function might take long, because the map is 0132 * created on the first use only (atm used by SVG only) 0133 * @param id unique ProfileID of the profile (MD5 sum of its header) 0134 * @return the profile or 0 if not found 0135 */ 0136 const KoColorProfile *profileByUniqueId(const QByteArray &id) const; 0137 0138 bool profileIsCompatible(const KoColorProfile* profile, const QString &colorSpaceId); 0139 0140 /** 0141 * Return the list of profiles for a colorspace with the argument id. 0142 * Profiles will not work with any color space, you can query which profiles 0143 * that are registered with this registry can be used in combination with the 0144 * argument factory. 0145 * @param colorSpaceId the colorspace-id with which all the returned profiles will work. 0146 * @return a list of profiles for the factory 0147 */ 0148 QList<const KoColorProfile *> profilesFor(const QString& csID) const; 0149 QString defaultProfileForColorSpace(const QString &colorSpaceId) const; 0150 0151 /** 0152 * This function is called by the color space to create a color conversion 0153 * between two color space. This function search in the graph of transformations 0154 * the best possible path between the two color space. 0155 */ 0156 KoColorConversionTransformation* createColorConverter(const KoColorSpace * srcColorSpace, const KoColorSpace * dstColorSpace, KoColorConversionTransformation::Intent renderingIntent, KoColorConversionTransformation::ConversionFlags conversionFlags) const; 0157 0158 /** 0159 * This function creates two transformations, one from the color space and one to the 0160 * color space. The destination color space is picked from a list of color space, such 0161 * as the conversion between the two color space is of the best quality. 0162 * 0163 * The typical use case of this function is for KoColorTransformationFactory which 0164 * doesn't support all color spaces, so unsupported color space have to find an 0165 * acceptable conversion in order to use that KoColorTransformationFactory. 0166 * 0167 * @param colorSpace the source color space 0168 * @param possibilities a list of color space among which we need to find the best 0169 * conversion 0170 * @param fromCS the conversion from the source color space will be affected to this 0171 * variable 0172 * @param toCS the revert conversion to the source color space will be affected to this 0173 * variable 0174 */ 0175 void createColorConverters(const KoColorSpace* colorSpace, const QList< QPair<KoID, KoID> >& possibilities, KoColorConversionTransformation*& fromCS, KoColorConversionTransformation*& toCS) const; 0176 0177 /** 0178 * Return a colorspace that works with the parameter profile. 0179 * @param colorSpaceId the ID string of the colorspace that you want to have returned 0180 * @param profile the profile be combined with the colorspace 0181 * @return the wanted colorspace, or 0 when the cs and profile can not be combined. 0182 */ 0183 const KoColorSpace * colorSpace(const QString & colorModelId, const QString & colorDepthId, const KoColorProfile *profile); 0184 0185 /** 0186 * Return a colorspace that works with the parameter profile. 0187 * @param profileName the name of the KoColorProfile to be combined with the colorspace 0188 * @return the wanted colorspace, or 0 when the cs and profile can not be combined. 0189 */ 0190 const KoColorSpace * colorSpace(const QString & colorModelId, const QString & colorDepthId, const QString &profileName); 0191 0192 const KoColorSpace * colorSpace(const QString & colorModelId, const QString & colorDepthId); 0193 0194 /** 0195 * Return the id of the colorspace that have the defined colorModelId with colorDepthId. 0196 * @param colorModelId id of the color model 0197 * @param colorDepthId id of the color depth 0198 * @return the id of the wanted colorspace, or "" if no colorspace correspond to those ids 0199 */ 0200 QString colorSpaceId(const QString & colorModelId, const QString & colorDepthId) const; 0201 /** 0202 * It's a convenient function that behave like the above. 0203 * Return the id of the colorspace that have the defined colorModelId with colorDepthId. 0204 * @param colorModelId id of the color model 0205 * @param colorDepthId id of the color depth 0206 * @return the id of the wanted colorspace, or "" if no colorspace correspond to those ids 0207 */ 0208 QString colorSpaceId(const KoID& colorModelId, const KoID& colorDepthId) const; 0209 0210 /** 0211 * @return the identifier of the color model for the given color space id. 0212 * 0213 * This function is a compatibility function used to get the color space from 0214 * all kra files. 0215 */ 0216 KoID colorSpaceColorModelId(const QString & _colorSpaceId) const; 0217 0218 /** 0219 * @return the identifier of the color depth for the given color space id. 0220 * 0221 * This function is a compatibility function used to get the color space from 0222 * all kra files. 0223 */ 0224 KoID colorSpaceColorDepthId(const QString & _colorSpaceId) const; 0225 0226 /** 0227 * Convenience methods to get the often used alpha colorspaces 0228 */ 0229 const KoColorSpace *alpha8(); 0230 const KoColorSpace *alpha16(); 0231 #ifdef HAVE_OPENEXR 0232 const KoColorSpace *alpha16f(); 0233 #endif 0234 const KoColorSpace *alpha32f(); 0235 0236 /** 0237 * Convenience method to get a GRAYA 8 bit colorspace. If a profile is not specified, 0238 * the default profile defined in the GRAY colorspace will be used 0239 * @param profile the profile name 0240 * @return an 8 bit graya colorspace with the default profile or 0. 0241 */ 0242 const KoColorSpace *graya8(const QString &profile = QString()); 0243 0244 /** 0245 * Convenience method to get a GRAYA 8 bit colorspace. If a profile is not specified, 0246 * the default profile defined in the GRAY colorspace will be used 0247 * @param profile the profile 0248 * @return an 8 bit graya colorspace with the default profile or 0. 0249 */ 0250 const KoColorSpace *graya8(const KoColorProfile *profile); 0251 0252 /** 0253 * Convenience method to get a GRAYA 16 bit colorspace. If a profile is not specified, 0254 * the default profile defined in the GRAY colorspace will be used 0255 * @param the profile 0256 * @return an 8 bit graya colorspace with the default profile or 0. 0257 */ 0258 const KoColorSpace *graya16(const QString &profile = QString()); 0259 0260 /** 0261 * Convenience method to get a GRAYA 16 bit colorspace. If a profile is not specified, 0262 * the default profile defined in the GRAY colorspace will be used 0263 * @param the profile 0264 * @return an 8 bit graya colorspace with the default profile or 0. 0265 */ 0266 const KoColorSpace *graya16(const KoColorProfile *profile); 0267 0268 0269 /** 0270 * Convenience method to get an RGBA 8bit colorspace. If a profile is not specified, 0271 * an sRGB profile will be used. 0272 * @param profileName the name of an RGB color profile 0273 * @return the wanted colorspace, or 0 if the color space and profile can not be combined. 0274 */ 0275 const KoColorSpace * rgb8(const QString &profileName = QString()); 0276 0277 /** 0278 * Convenience method to get an RGBA 8bit colorspace with the given profile. 0279 * @param profile an RGB profile 0280 * @return the wanted colorspace, or 0 if the color space and profile can not be combined. 0281 */ 0282 const KoColorSpace * rgb8(const KoColorProfile * profile); 0283 0284 /** 0285 * Convenience method to get an RGBA 16bit colorspace. If a profile is not specified, 0286 * an sRGB profile will be used. 0287 * @param profileName the name of an RGB color profile 0288 * @return the wanted colorspace, or 0 if the color space and profile can not be combined. 0289 */ 0290 const KoColorSpace * rgb16(const QString &profileName = QString()); 0291 0292 /** 0293 * Convenience method to get an RGBA 16bit colorspace with the given profile. 0294 * @param profile an RGB profile 0295 * @return the wanted colorspace, or 0 if the color space and profile can not be combined. 0296 */ 0297 const KoColorSpace * rgb16(const KoColorProfile * profile); 0298 0299 /** 0300 * Convenience method to get an Lab 16bit colorspace. If a profile is not specified, 0301 * an Lab profile with a D50 whitepoint will be used. 0302 * @param profileName the name of an Lab color profile 0303 * @return the wanted colorspace, or 0 if the color space and profile can not be combined. 0304 */ 0305 const KoColorSpace * lab16(const QString &profileName = QString()); 0306 0307 /** 0308 * Convenience method to get an Lab 16bit colorspace with the given profile. 0309 * @param profile an Lab profile 0310 * @return the wanted colorspace, or 0 if the color space and profile can not be combined. 0311 */ 0312 const KoColorSpace * lab16(const KoColorProfile * profile); 0313 0314 /** 0315 * Convenience method to get a standard profile for Rec.2020 linear light 0316 * color space 0317 */ 0318 const KoColorProfile *p2020G10Profile() const; 0319 0320 /** 0321 * Convenience method to get a standard profile for Rec.2020 PQ color space 0322 */ 0323 const KoColorProfile *p2020PQProfile() const; 0324 0325 /** 0326 * Convenience method to get a standard profile for Rec. 709 linear light 0327 * color space 0328 */ 0329 const KoColorProfile *p709G10Profile() const; 0330 0331 /** 0332 * Convenience method to get a standard profile for Rec. 709 sRGB-tone- 0333 * response-curve profile 0334 */ 0335 const KoColorProfile *p709SRGBProfile() const; 0336 0337 /** 0338 * @brief profileFor tries to find the profile that matches these characteristics, if no 0339 * such profile is found, it attempts to generate one. 0340 * @param colorants a double of xy (for xyY) values, this expects the first two as the white point, 0341 * then the red, green and blue. If there's only a whitepoint and primaries type is undefined, 0342 * a grayscale profile will be returned. 0343 * @param colorPrimaries the color primaries type as defined in KoColorProfile. 0344 * @param transferFunction the transfer function, as defined in KoColorProfile. 0345 * @return a profile that matches these characteristics. 0346 */ 0347 const KoColorProfile *profileFor(const QVector<double> &colorants, ColorPrimaries colorPrimaries, TransferCharacteristics transferFunction) const; 0348 0349 /** 0350 * @return the list of available color models 0351 */ 0352 QList<KoID> colorModelsList(ColorSpaceListVisibility option) const; 0353 0354 /** 0355 * @return the list of available color models for the given colorModelId 0356 */ 0357 QList<KoID> colorDepthList(const KoID& colorModelId, ColorSpaceListVisibility option) const; 0358 0359 /** 0360 * @return the list of available color models for the given colorModelId 0361 */ 0362 QList<KoID> colorDepthList(const QString & colorModelId, ColorSpaceListVisibility option) const; 0363 0364 /** 0365 * @return the cache of color conversion transformation to be use by KoColorSpace 0366 */ 0367 KoColorConversionCache* colorConversionCache() const; 0368 0369 /** 0370 * @return a permanent colorspace owned by the registry, of the same type and profile 0371 * as the one given in argument 0372 */ 0373 const KoColorSpace* permanentColorspace(const KoColorSpace* _colorSpace); 0374 0375 /** 0376 * This function return a list of all the keys in KoID format by using the name() method 0377 * on the objects stored in the registry. 0378 */ 0379 QList<KoID> listKeys() const; 0380 0381 private: 0382 0383 friend class KisCsConversionTest; 0384 friend class KisIteratorTest; 0385 friend class KisIteratorNGTest; 0386 friend class KisPainterTest; 0387 friend class KisCrashFilterTest; 0388 friend class KoColorSpacesBenchmark; 0389 friend class TestKoColorSpaceSanity; 0390 friend class TestColorConversionSystem; 0391 friend struct FriendOfColorSpaceRegistry; 0392 0393 /** 0394 * @return a list with an instance of all color space with their default profile. 0395 */ 0396 QList<const KoColorSpace*> allColorSpaces(ColorSpaceListVisibility visibility, ColorSpaceListProfilesSelection pSelection); 0397 0398 /** 0399 * @return the color conversion system use by the registry and the color 0400 * spaces to create color conversion transformation. 0401 * 0402 * WARNING: conversion system is guarded by the registry locks, don't 0403 * use it anywhere other than unittests! 0404 */ 0405 const KoColorConversionSystem* colorConversionSystem() const; 0406 0407 private: 0408 KoColorSpaceRegistry(const KoColorSpaceRegistry&); 0409 KoColorSpaceRegistry operator=(const KoColorSpaceRegistry&); 0410 void init(); 0411 0412 private: 0413 struct Private; 0414 Private * const d; 0415 }; 0416 0417 #endif // KOCOLORSPACEREGISTRY_H