Krita Source Code Documentation
Loading...
Searching...
No Matches
LcmsEnginePlugin.cpp
Go to the documentation of this file.
1/*
2 * SPDX-FileCopyrightText: 2003 Patrick Julien <freak@codepimps.org>
3 * SPDX-FileCopyrightText: 2004, 2010 Cyrille Berger <cberger@cberger.net>
4 * SPDX-FileCopyrightText: 2011 Srikanth Tiyyagura <srikanth.tulasiram@gmail.com>
5 *
6 * SPDX-License-Identifier: LGPL-2.1-or-later
7*/
8#include "LcmsEnginePlugin.h"
9
10#include <QApplication>
11#include <QDebug>
12#include <QDir>
13#include <QStringList>
14
15#include <klocalizedstring.h>
16#include <kpluginfactory.h>
17
19#include <KoColorSpace.h>
20#include <KoColorSpaceEngine.h>
22#include <KoResourcePaths.h>
23#include <kis_assert.h>
24#include <kis_debug.h>
25
26#include "IccColorSpaceEngine.h"
27#include <KoColorProfileQuery.h>
29
33
37
41
45
49
53
55
56#include <KoConfig.h>
57
58#ifdef HAVE_OPENEXR
59# include <half.h>
60# ifdef HAVE_LCMS24
64# endif
65#endif
66
67#if defined(HAVE_LCMS_FAST_FLOAT_PLUGIN)
68#include <lcms2_fast_float.h>
69#endif
70
71void lcms2LogErrorHandlerFunction(cmsContext /*ContextID*/, cmsUInt32Number ErrorCode, const char *Text)
72{
73 errorPigment << "Lcms2 error: " << ErrorCode << Text;
74}
75
76K_PLUGIN_FACTORY_WITH_JSON(PluginFactory, "kolcmsengine.json", registerPlugin<LcmsEnginePlugin>();)
77
78LcmsEnginePlugin::LcmsEnginePlugin(QObject *parent, const QVariantList &)
79 : QObject(parent)
80{
81 KoResourcePaths::addAssetType("icc_profiles", "data", "/color/icc");
82 KoResourcePaths::addAssetType("icc_profiles", "data", "/profiles/");
83
84 // Set the lmcs error reporting function
85 cmsSetLogErrorHandler(&lcms2LogErrorHandlerFunction);
86
88
89 // Initialise color engine
91
92 QStringList profileFilenames;
93 profileFilenames += KoResourcePaths::findAllAssets("icc_profiles", "*.icm", KoResourcePaths::Recursive);
94 profileFilenames += KoResourcePaths::findAllAssets("icc_profiles", "*.ICM", KoResourcePaths::Recursive);
95 profileFilenames += KoResourcePaths::findAllAssets("icc_profiles", "*.ICC", KoResourcePaths::Recursive);
96 profileFilenames += KoResourcePaths::findAllAssets("icc_profiles", "*.icc", KoResourcePaths::Recursive);
97
98 QStringList iccProfileDirs;
99
100#ifdef Q_OS_MAC
101 iccProfileDirs.append(QDir::homePath() + "/Library/ColorSync/Profiles/");
102 iccProfileDirs.append("/System/Library/ColorSync/Profiles/");
103 iccProfileDirs.append("/Library/ColorSync/Profiles/");
104#endif
105#ifdef Q_OS_WIN
106 QString winPath = QString::fromUtf8(qgetenv("windir"));
107 winPath.replace('\\','/');
108 iccProfileDirs.append(winPath + "/System32/Spool/Drivers/Color/");
109
110#endif
111#ifdef Q_OS_LINUX
112 iccProfileDirs.append(QDir::homePath() + "./share/color/icc");
113#endif
114
115 QStringList blackList = QStringList() << "panhexro.icm"
116 << "ctpctdmed.icc";
117
118
119 Q_FOREACH(const QString &iccProfiledir, iccProfileDirs) {
120 QDir profileDir(iccProfiledir);
121 Q_FOREACH(const QString &entry, profileDir.entryList(QStringList() << "*.icm" << "*.icc" << "*.ICM" << "*.ICC", QDir::NoDotAndDotDot | QDir::Files | QDir::Readable)) {
122 if (blackList.contains(entry.toLower())) continue;
123 profileFilenames << iccProfiledir + "/" + entry;
124 }
125 }
126
127 // Load the profiles
128 if (!profileFilenames.empty()) {
129 for (QStringList::Iterator it = profileFilenames.begin(); it != profileFilenames.end(); ++it) {
130
131 KoColorProfile *profile = new IccColorProfile(*it);
132 Q_CHECK_PTR(profile);
133
134 profile->load();
135 if (profile->valid()) {
136 //qDebug() << "Valid profile : " << profile->fileName() << profile->name();
137 registry->addProfileToMap(profile);
138 } else {
139 qDebug() << "Invalid profile : " << *it;
140 delete profile;
141 }
142 }
143 }
144
145 // ------------------- LAB ---------------------------------
146
147 KoColorProfile *labProfile = LcmsColorProfileContainer::createFromLcmsProfile(cmsCreateLab4Profile(0));
148 registry->addProfile(labProfile);
149
150 registry->add(new LabU8ColorSpaceFactory());
151 registry->add(new LabU16ColorSpaceFactory());
152 registry->add(new LabF32ColorSpaceFactory());
153
156 (KoID("LABAU8HISTO", i18n("L*a*b*/8 Histogram")), LABAColorModelID.id(), Integer8BitsColorDepthID.id()));
157
160 (KoID("LABAU16HISTO", i18n("L*a*b*/16 Histogram")), LABAColorModelID.id(), Integer16BitsColorDepthID.id()));
161
164 (KoID("LABAF32HISTO", i18n("L*a*b*/32 Histogram")), LABAColorModelID.id(), Float32BitsColorDepthID.id()));
165
166 // ------------------- RGB ---------------------------------
167
168 KoColorProfile *rgbProfile = LcmsColorProfileContainer::createFromLcmsProfile(cmsCreate_sRGBProfile());
169 registry->addProfile(rgbProfile);
170
172 registry->addProfile(rec2100pq);
173
181 const QString legacyRec2020PQProfileName = "High Dynamic Range UHDTV Wide Color Gamut Display (Rec. 2020) - SMPTE ST 2084 PQ EOTF";
182 registry->addProfileAlias(legacyRec2020PQProfileName, rec2100pq->name());
183
184 registry->add(new RgbU8ColorSpaceFactory());
185 registry->add(new RgbU16ColorSpaceFactory());
186 #ifdef HAVE_LCMS24
187 #ifdef HAVE_OPENEXR
188 registry->add(new RgbF16ColorSpaceFactory());
189 #endif
190 #endif
191 registry->add(new RgbF32ColorSpaceFactory());
192
195 (KoID("RGBU8HISTO", i18n("RGBA/8 Histogram")), RGBAColorModelID.id(), Integer8BitsColorDepthID.id()));
196
199 (KoID("RGBU16HISTO", i18n("RGBA/16 Histogram")), RGBAColorModelID.id(), Integer16BitsColorDepthID.id()));
200
201#ifdef HAVE_LCMS24
202#ifdef HAVE_OPENEXR
205 (KoID("RGBF16HISTO", i18n("RGBA/F16 Histogram")), RGBAColorModelID.id(), Float16BitsColorDepthID.id()));
206#endif
207#endif
208
211 (KoID("RGF328HISTO", i18n("RGBA/F32 Histogram")), RGBAColorModelID.id(), Float32BitsColorDepthID.id()));
212
213 // ------------------- GRAY ---------------------------------
214
215 cmsToneCurve *Gamma = cmsBuildGamma(0, 2.2);
216 cmsHPROFILE hProfile = cmsCreateGrayProfile(cmsD50_xyY(), Gamma);
217 cmsFreeToneCurve(Gamma);
219 registry->addProfile(defProfile);
220
221 registry->add(new GrayAU8ColorSpaceFactory());
222 registry->add(new GrayAU16ColorSpaceFactory());
223#ifdef HAVE_LCMS24
224#ifdef HAVE_OPENEXR
225 registry->add(new GrayF16ColorSpaceFactory());
226#endif
227#endif
228 registry->add(new GrayF32ColorSpaceFactory());
229
232 (KoID("GRAYA8HISTO", i18n("GRAY/8 Histogram")), GrayAColorModelID.id(), Integer8BitsColorDepthID.id()));
233
236 (KoID("GRAYA16HISTO", i18n("GRAY/16 Histogram")), GrayAColorModelID.id(), Integer16BitsColorDepthID.id()));
237#ifdef HAVE_LCMS24
238#ifdef HAVE_OPENEXR
241 (KoID("GRAYF16HISTO", i18n("GRAYF/F16 Histogram")), GrayAColorModelID.id(), Float16BitsColorDepthID.id()));
242#endif
243#endif
244
247 (KoID("GRAYAF32HISTO", i18n("GRAY/F32 float Histogram")), GrayAColorModelID.id(), Float32BitsColorDepthID.id()));
248
249 // ------------------- CMYK ---------------------------------
250
251 registry->add(new CmykU8ColorSpaceFactory());
252 registry->add(new CmykU16ColorSpaceFactory());
253 registry->add(new CmykF32ColorSpaceFactory());
254
257 (KoID("CMYK8HISTO", i18n("CMYK/8 Histogram")), CMYKAColorModelID.id(), Integer8BitsColorDepthID.id()));
258
261 (KoID("CMYK16HISTO", i18n("CMYK/16 Histogram")), CMYKAColorModelID.id(), Integer16BitsColorDepthID.id()));
262
265 (KoID("CMYKF32HISTO", i18n("CMYK/F32 Histogram")), CMYKAColorModelID.id(), Float32BitsColorDepthID.id()));
266
267 // ------------------- XYZ ---------------------------------
268
269 KoColorProfile *xyzProfile = LcmsColorProfileContainer::createFromLcmsProfile(cmsCreateXYZProfile());
270 registry->addProfile(xyzProfile);
271
272 registry->add(new XyzU8ColorSpaceFactory());
273 registry->add(new XyzU16ColorSpaceFactory());
274#ifdef HAVE_LCMS24
275#ifdef HAVE_OPENEXR
276 registry->add(new XyzF16ColorSpaceFactory());
277#endif
278#endif
279 registry->add(new XyzF32ColorSpaceFactory());
280
283 (KoID("XYZ8HISTO", i18n("XYZ/8 Histogram")), XYZAColorModelID.id(), Integer8BitsColorDepthID.id()));
284
287 (KoID("XYZ16HISTO", i18n("XYZ/16 Histogram")), XYZAColorModelID.id(), Integer16BitsColorDepthID.id()));
288
289#ifdef HAVE_LCMS24
290#ifdef HAVE_OPENEXR
293 (KoID("XYZF16HISTO", i18n("XYZ/F16 Histogram")), XYZAColorModelID.id(), Float16BitsColorDepthID.id()));
294#endif
295#endif
296
299 (KoID("XYZF32HISTO", i18n("XYZF32 Histogram")), XYZAColorModelID.id(), Float32BitsColorDepthID.id()));
300
301 // ------------------- YCBCR ---------------------------------
302
303 // KoColorProfile *yCbCrProfile = LcmsColorProfileContainer::createFromLcmsProfile(cmsCreateYCBCRProfile());
304 // registry->addProfile(yCbCrProfile);
305
306 registry->add(new YCbCrU8ColorSpaceFactory());
307 registry->add(new YCbCrU16ColorSpaceFactory());
308 registry->add(new YCbCrF32ColorSpaceFactory());
309
312 (KoID("YCBCR8HISTO", i18n("YCbCr/8 Histogram")), YCbCrAColorModelID.id(), Integer8BitsColorDepthID.id()));
313
316 (KoID("YCBCR16HISTO", i18n("YCbCr/16 Histogram")), YCbCrAColorModelID.id(), Integer16BitsColorDepthID.id()));
317
320 (KoID("YCBCRF32HISTO", i18n("YCbCr/F32 Histogram")), YCbCrAColorModelID.id(), Float32BitsColorDepthID.id()));
321
322 // Add profile alias for default profile from lcms1
323 registry->addProfileAlias("sRGB built-in - (lcms internal)", "sRGB built-in");
324 registry->addProfileAlias("gray built-in - (lcms internal)", "gray built-in");
325 registry->addProfileAlias("Lab identity built-in - (lcms internal)", "Lab identity built-in");
326 registry->addProfileAlias("XYZ built-in - (lcms internal)", "XYZ identity built-in");
327
328#if defined(HAVE_LCMS_FAST_FLOAT_PLUGIN)
329 cmsPlugin(cmsFastFloatExtensions());
330#endif
331}
332
333#include <LcmsEnginePlugin.moc>
#define errorPigment
QList< QString > QStringList
const KoID Float32BitsColorDepthID("F32", ki18n("32-bit float/channel"))
const KoID YCbCrAColorModelID("YCbCrA", ki18n("YCbCr/Alpha"))
const KoID GrayAColorModelID("GRAYA", ki18n("Grayscale/Alpha"))
const KoID XYZAColorModelID("XYZA", ki18n("XYZ/Alpha"))
const KoID Float16BitsColorDepthID("F16", ki18n("16-bit float/channel"))
const KoID Integer8BitsColorDepthID("U8", ki18n("8-bit integer/channel"))
const KoID Integer16BitsColorDepthID("U16", ki18n("16-bit integer/channel"))
const KoID CMYKAColorModelID("CMYKA", ki18n("CMYK/Alpha"))
const KoID LABAColorModelID("LABA", ki18n("L*a*b*/Alpha"))
const KoID RGBAColorModelID("RGBA", ki18n("RGB/Alpha"))
@ PRIMARIES_ITU_R_BT_2020_2_AND_2100_0
@ TRC_ITU_R_BT_2100_0_PQ
void lcms2LogErrorHandlerFunction(cmsContext, cmsUInt32Number ErrorCode, const char *Text)
static KoColorSpaceEngineRegistry * instance()
static KoHistogramProducerFactoryRegistry * instance()
Definition KoID.h:30
QString id() const
Definition KoID.cpp:63
static void addAssetType(const QString &type, const char *basetype, const QString &relativeName, bool priority=true)
static QStringList findAllAssets(const QString &type, const QString &filter=QString(), SearchOptions options=NoSearchOptions)
static IccColorProfile * createFromLcmsProfile(const cmsHPROFILE profile)
LcmsEnginePlugin(QObject *parent, const QVariantList &)
K_PLUGIN_FACTORY_WITH_JSON(KritaASCCDLFactory, "kritaasccdl.json", registerPlugin< KritaASCCDL >();) KritaASCCDL
The KoColorProfileQuery struct.
virtual bool load()
virtual bool valid() const =0
void addProfileAlias(const QString &name, const QString &to)
static KoColorSpaceRegistry * instance()
void add(KoColorSpaceFactory *item)
void addProfileToMap(KoColorProfile *p)
void addProfile(KoColorProfile *profile)