File indexing completed on 2024-05-26 04:32:15
0001 /* 0002 * SPDX-FileCopyrightText: 2003 Patrick Julien <freak@codepimps.org> 0003 * SPDX-FileCopyrightText: 2004, 2010 Cyrille Berger <cberger@cberger.net> 0004 * SPDX-FileCopyrightText: 2011 Srikanth Tiyyagura <srikanth.tulasiram@gmail.com> 0005 * 0006 * SPDX-License-Identifier: LGPL-2.1-or-later 0007 */ 0008 #include "LcmsEnginePlugin.h" 0009 0010 #include <QApplication> 0011 #include <QDebug> 0012 #include <QDir> 0013 #include <QHash> 0014 #include <QStringList> 0015 0016 #include <klocalizedstring.h> 0017 #include <kpluginfactory.h> 0018 0019 #include <KoBasicHistogramProducers.h> 0020 #include <KoColorSpace.h> 0021 #include <KoColorSpaceEngine.h> 0022 #include <KoColorSpaceRegistry.h> 0023 #include <KoResourcePaths.h> 0024 #include <kis_assert.h> 0025 #include <kis_debug.h> 0026 0027 #include "IccColorSpaceEngine.h" 0028 #include "colorprofiles/LcmsColorProfileContainer.h" 0029 0030 #include "colorspaces/cmyk_u8/CmykU8ColorSpace.h" 0031 #include "colorspaces/cmyk_u16/CmykU16ColorSpace.h" 0032 #include "colorspaces/cmyk_f32/CmykF32ColorSpace.h" 0033 0034 #include "colorspaces/gray_u8/GrayU8ColorSpace.h" 0035 #include "colorspaces/gray_u16/GrayU16ColorSpace.h" 0036 #include "colorspaces/gray_f32/GrayF32ColorSpace.h" 0037 0038 #include "colorspaces/lab_u8/LabU8ColorSpace.h" 0039 #include "colorspaces/lab_u16/LabColorSpace.h" 0040 #include "colorspaces/lab_f32/LabF32ColorSpace.h" 0041 0042 #include "colorspaces/xyz_u8/XyzU8ColorSpace.h" 0043 #include "colorspaces/xyz_u16/XyzU16ColorSpace.h" 0044 #include "colorspaces/xyz_f32/XyzF32ColorSpace.h" 0045 0046 #include "colorspaces/rgb_u8/RgbU8ColorSpace.h" 0047 #include "colorspaces/rgb_u16/RgbU16ColorSpace.h" 0048 #include "colorspaces/rgb_f32/RgbF32ColorSpace.h" 0049 0050 #include "colorspaces/ycbcr_u8/YCbCrU8ColorSpace.h" 0051 #include "colorspaces/ycbcr_u16/YCbCrU16ColorSpace.h" 0052 #include "colorspaces/ycbcr_f32/YCbCrF32ColorSpace.h" 0053 0054 #include "LcmsRGBP2020PQColorSpace.h" 0055 0056 #include <KoConfig.h> 0057 0058 #ifdef HAVE_OPENEXR 0059 # include <half.h> 0060 # ifdef HAVE_LCMS24 0061 # include "colorspaces/gray_f16/GrayF16ColorSpace.h" 0062 # include "colorspaces/xyz_f16/XyzF16ColorSpace.h" 0063 # include "colorspaces/rgb_f16/RgbF16ColorSpace.h" 0064 # endif 0065 #endif 0066 0067 #if defined(HAVE_LCMS_FAST_FLOAT_PLUGIN) 0068 #include <lcms2_fast_float.h> 0069 #endif 0070 0071 void lcms2LogErrorHandlerFunction(cmsContext /*ContextID*/, cmsUInt32Number ErrorCode, const char *Text) 0072 { 0073 errorPigment << "Lcms2 error: " << ErrorCode << Text; 0074 } 0075 0076 K_PLUGIN_FACTORY_WITH_JSON(PluginFactory, "kolcmsengine.json", registerPlugin<LcmsEnginePlugin>();) 0077 0078 LcmsEnginePlugin::LcmsEnginePlugin(QObject *parent, const QVariantList &) 0079 : QObject(parent) 0080 { 0081 KoResourcePaths::addAssetType("icc_profiles", "data", "/color/icc"); 0082 KoResourcePaths::addAssetType("icc_profiles", "data", "/profiles/"); 0083 0084 // Set the lmcs error reporting function 0085 cmsSetLogErrorHandler(&lcms2LogErrorHandlerFunction); 0086 0087 KoColorSpaceRegistry *registry = KoColorSpaceRegistry::instance(); 0088 0089 // Initialise color engine 0090 KoColorSpaceEngineRegistry::instance()->add(new IccColorSpaceEngine); 0091 0092 QStringList profileFilenames; 0093 profileFilenames += KoResourcePaths::findAllAssets("icc_profiles", "*.icm", KoResourcePaths::Recursive); 0094 profileFilenames += KoResourcePaths::findAllAssets("icc_profiles", "*.ICM", KoResourcePaths::Recursive); 0095 profileFilenames += KoResourcePaths::findAllAssets("icc_profiles", "*.ICC", KoResourcePaths::Recursive); 0096 profileFilenames += KoResourcePaths::findAllAssets("icc_profiles", "*.icc", KoResourcePaths::Recursive); 0097 0098 QStringList iccProfileDirs; 0099 0100 #ifdef Q_OS_MAC 0101 iccProfileDirs.append(QDir::homePath() + "/Library/ColorSync/Profiles/"); 0102 iccProfileDirs.append("/System/Library/ColorSync/Profiles/"); 0103 iccProfileDirs.append("/Library/ColorSync/Profiles/"); 0104 #endif 0105 #ifdef Q_OS_WIN 0106 QString winPath = QString::fromUtf8(qgetenv("windir")); 0107 winPath.replace('\\','/'); 0108 iccProfileDirs.append(winPath + "/System32/Spool/Drivers/Color/"); 0109 0110 #endif 0111 #ifdef Q_OS_LINUX 0112 iccProfileDirs.append(QDir::homePath() + "./share/color/icc"); 0113 #endif 0114 0115 QStringList blackList = QStringList() << "panhexro.icm" 0116 << "ctpctdmed.icc"; 0117 0118 0119 Q_FOREACH(const QString &iccProfiledir, iccProfileDirs) { 0120 QDir profileDir(iccProfiledir); 0121 Q_FOREACH(const QString &entry, profileDir.entryList(QStringList() << "*.icm" << "*.icc" << "*.ICM" << "*.ICC", QDir::NoDotAndDotDot | QDir::Files | QDir::Readable)) { 0122 if (blackList.contains(entry.toLower())) continue; 0123 profileFilenames << iccProfiledir + "/" + entry; 0124 } 0125 } 0126 0127 // Load the profiles 0128 if (!profileFilenames.empty()) { 0129 for (QStringList::Iterator it = profileFilenames.begin(); it != profileFilenames.end(); ++it) { 0130 0131 KoColorProfile *profile = new IccColorProfile(*it); 0132 Q_CHECK_PTR(profile); 0133 0134 profile->load(); 0135 if (profile->valid()) { 0136 //qDebug() << "Valid profile : " << profile->fileName() << profile->name(); 0137 registry->addProfileToMap(profile); 0138 } else { 0139 qDebug() << "Invalid profile : " << *it; 0140 delete profile; 0141 } 0142 } 0143 } 0144 0145 // ------------------- LAB --------------------------------- 0146 0147 KoColorProfile *labProfile = LcmsColorProfileContainer::createFromLcmsProfile(cmsCreateLab4Profile(0)); 0148 registry->addProfile(labProfile); 0149 0150 registry->add(new LabU8ColorSpaceFactory()); 0151 registry->add(new LabU16ColorSpaceFactory()); 0152 registry->add(new LabF32ColorSpaceFactory()); 0153 0154 KoHistogramProducerFactoryRegistry::instance()->add( 0155 new KoBasicHistogramProducerFactory<KoBasicU8HistogramProducer> 0156 (KoID("LABAU8HISTO", i18n("L*a*b*/8 Histogram")), LABAColorModelID.id(), Integer8BitsColorDepthID.id())); 0157 0158 KoHistogramProducerFactoryRegistry::instance()->add( 0159 new KoBasicHistogramProducerFactory<KoBasicU16HistogramProducer> 0160 (KoID("LABAU16HISTO", i18n("L*a*b*/16 Histogram")), LABAColorModelID.id(), Integer16BitsColorDepthID.id())); 0161 0162 KoHistogramProducerFactoryRegistry::instance()->add( 0163 new KoBasicHistogramProducerFactory<KoBasicF32HistogramProducer> 0164 (KoID("LABAF32HISTO", i18n("L*a*b*/32 Histogram")), LABAColorModelID.id(), Float32BitsColorDepthID.id())); 0165 0166 // ------------------- RGB --------------------------------- 0167 0168 KoColorProfile *rgbProfile = LcmsColorProfileContainer::createFromLcmsProfile(cmsCreate_sRGBProfile()); 0169 registry->addProfile(rgbProfile); 0170 0171 registry->add(new LcmsRGBP2020PQColorSpaceFactoryWrapper<RgbU8ColorSpaceFactory>()); 0172 registry->add(new LcmsRGBP2020PQColorSpaceFactoryWrapper<RgbU16ColorSpaceFactory>()); 0173 #ifdef HAVE_LCMS24 0174 #ifdef HAVE_OPENEXR 0175 registry->add(new LcmsRGBP2020PQColorSpaceFactoryWrapper<RgbF16ColorSpaceFactory>()); 0176 #endif 0177 #endif 0178 registry->add(new LcmsRGBP2020PQColorSpaceFactoryWrapper<RgbF32ColorSpaceFactory>()); 0179 0180 KoHistogramProducerFactoryRegistry::instance()->add( 0181 new KoBasicHistogramProducerFactory<KoBasicU8HistogramProducer> 0182 (KoID("RGBU8HISTO", i18n("RGBA/8 Histogram")), RGBAColorModelID.id(), Integer8BitsColorDepthID.id())); 0183 0184 KoHistogramProducerFactoryRegistry::instance()->add( 0185 new KoBasicHistogramProducerFactory<KoBasicU16HistogramProducer> 0186 (KoID("RGBU16HISTO", i18n("RGBA/16 Histogram")), RGBAColorModelID.id(), Integer16BitsColorDepthID.id())); 0187 0188 #ifdef HAVE_LCMS24 0189 #ifdef HAVE_OPENEXR 0190 KoHistogramProducerFactoryRegistry::instance()->add( 0191 new KoBasicHistogramProducerFactory<KoBasicF16HalfHistogramProducer> 0192 (KoID("RGBF16HISTO", i18n("RGBA/F16 Histogram")), RGBAColorModelID.id(), Float16BitsColorDepthID.id())); 0193 #endif 0194 #endif 0195 0196 KoHistogramProducerFactoryRegistry::instance()->add( 0197 new KoBasicHistogramProducerFactory<KoBasicF32HistogramProducer> 0198 (KoID("RGF328HISTO", i18n("RGBA/F32 Histogram")), RGBAColorModelID.id(), Float32BitsColorDepthID.id())); 0199 0200 // ------------------- GRAY --------------------------------- 0201 0202 cmsToneCurve *Gamma = cmsBuildGamma(0, 2.2); 0203 cmsHPROFILE hProfile = cmsCreateGrayProfile(cmsD50_xyY(), Gamma); 0204 cmsFreeToneCurve(Gamma); 0205 KoColorProfile *defProfile = LcmsColorProfileContainer::createFromLcmsProfile(hProfile); 0206 registry->addProfile(defProfile); 0207 0208 registry->add(new GrayAU8ColorSpaceFactory()); 0209 registry->add(new GrayAU16ColorSpaceFactory()); 0210 #ifdef HAVE_LCMS24 0211 #ifdef HAVE_OPENEXR 0212 registry->add(new GrayF16ColorSpaceFactory()); 0213 #endif 0214 #endif 0215 registry->add(new GrayF32ColorSpaceFactory()); 0216 0217 KoHistogramProducerFactoryRegistry::instance()->add( 0218 new KoBasicHistogramProducerFactory<KoBasicU8HistogramProducer> 0219 (KoID("GRAYA8HISTO", i18n("GRAY/8 Histogram")), GrayAColorModelID.id(), Integer8BitsColorDepthID.id())); 0220 0221 KoHistogramProducerFactoryRegistry::instance()->add( 0222 new KoBasicHistogramProducerFactory<KoBasicU16HistogramProducer> 0223 (KoID("GRAYA16HISTO", i18n("GRAY/16 Histogram")), GrayAColorModelID.id(), Integer16BitsColorDepthID.id())); 0224 #ifdef HAVE_LCMS24 0225 #ifdef HAVE_OPENEXR 0226 KoHistogramProducerFactoryRegistry::instance()->add( 0227 new KoBasicHistogramProducerFactory<KoBasicF16HalfHistogramProducer> 0228 (KoID("GRAYF16HISTO", i18n("GRAYF/F16 Histogram")), GrayAColorModelID.id(), Float16BitsColorDepthID.id())); 0229 #endif 0230 #endif 0231 0232 KoHistogramProducerFactoryRegistry::instance()->add( 0233 new KoBasicHistogramProducerFactory<KoBasicF32HistogramProducer> 0234 (KoID("GRAYAF32HISTO", i18n("GRAY/F32 float Histogram")), GrayAColorModelID.id(), Float32BitsColorDepthID.id())); 0235 0236 // ------------------- CMYK --------------------------------- 0237 0238 registry->add(new CmykU8ColorSpaceFactory()); 0239 registry->add(new CmykU16ColorSpaceFactory()); 0240 registry->add(new CmykF32ColorSpaceFactory()); 0241 0242 KoHistogramProducerFactoryRegistry::instance()->add( 0243 new KoBasicHistogramProducerFactory<KoBasicU8HistogramProducer> 0244 (KoID("CMYK8HISTO", i18n("CMYK/8 Histogram")), CMYKAColorModelID.id(), Integer8BitsColorDepthID.id())); 0245 0246 KoHistogramProducerFactoryRegistry::instance()->add( 0247 new KoBasicHistogramProducerFactory<KoBasicU16HistogramProducer> 0248 (KoID("CMYK16HISTO", i18n("CMYK/16 Histogram")), CMYKAColorModelID.id(), Integer16BitsColorDepthID.id())); 0249 0250 KoHistogramProducerFactoryRegistry::instance()->add( 0251 new KoBasicHistogramProducerFactory<KoBasicF32HistogramProducer> 0252 (KoID("CMYKF32HISTO", i18n("CMYK/F32 Histogram")), CMYKAColorModelID.id(), Float32BitsColorDepthID.id())); 0253 0254 // ------------------- XYZ --------------------------------- 0255 0256 KoColorProfile *xyzProfile = LcmsColorProfileContainer::createFromLcmsProfile(cmsCreateXYZProfile()); 0257 registry->addProfile(xyzProfile); 0258 0259 registry->add(new XyzU8ColorSpaceFactory()); 0260 registry->add(new XyzU16ColorSpaceFactory()); 0261 #ifdef HAVE_LCMS24 0262 #ifdef HAVE_OPENEXR 0263 registry->add(new XyzF16ColorSpaceFactory()); 0264 #endif 0265 #endif 0266 registry->add(new XyzF32ColorSpaceFactory()); 0267 0268 KoHistogramProducerFactoryRegistry::instance()->add( 0269 new KoBasicHistogramProducerFactory<KoBasicU8HistogramProducer> 0270 (KoID("XYZ8HISTO", i18n("XYZ/8 Histogram")), XYZAColorModelID.id(), Integer8BitsColorDepthID.id())); 0271 0272 KoHistogramProducerFactoryRegistry::instance()->add( 0273 new KoBasicHistogramProducerFactory<KoBasicU16HistogramProducer> 0274 (KoID("XYZ16HISTO", i18n("XYZ/16 Histogram")), XYZAColorModelID.id(), Integer16BitsColorDepthID.id())); 0275 0276 #ifdef HAVE_LCMS24 0277 #ifdef HAVE_OPENEXR 0278 KoHistogramProducerFactoryRegistry::instance()->add( 0279 new KoBasicHistogramProducerFactory<KoBasicF32HistogramProducer> 0280 (KoID("XYZF16HISTO", i18n("XYZ/F16 Histogram")), XYZAColorModelID.id(), Float16BitsColorDepthID.id())); 0281 #endif 0282 #endif 0283 0284 KoHistogramProducerFactoryRegistry::instance()->add( 0285 new KoBasicHistogramProducerFactory<KoBasicF32HistogramProducer> 0286 (KoID("XYZF32HISTO", i18n("XYZF32 Histogram")), XYZAColorModelID.id(), Float32BitsColorDepthID.id())); 0287 0288 // ------------------- YCBCR --------------------------------- 0289 0290 // KoColorProfile *yCbCrProfile = LcmsColorProfileContainer::createFromLcmsProfile(cmsCreateYCBCRProfile()); 0291 // registry->addProfile(yCbCrProfile); 0292 0293 registry->add(new YCbCrU8ColorSpaceFactory()); 0294 registry->add(new YCbCrU16ColorSpaceFactory()); 0295 registry->add(new YCbCrF32ColorSpaceFactory()); 0296 0297 KoHistogramProducerFactoryRegistry::instance()->add( 0298 new KoBasicHistogramProducerFactory<KoBasicU8HistogramProducer> 0299 (KoID("YCBCR8HISTO", i18n("YCbCr/8 Histogram")), YCbCrAColorModelID.id(), Integer8BitsColorDepthID.id())); 0300 0301 KoHistogramProducerFactoryRegistry::instance()->add( 0302 new KoBasicHistogramProducerFactory<KoBasicU16HistogramProducer> 0303 (KoID("YCBCR16HISTO", i18n("YCbCr/16 Histogram")), YCbCrAColorModelID.id(), Integer16BitsColorDepthID.id())); 0304 0305 KoHistogramProducerFactoryRegistry::instance()->add( 0306 new KoBasicHistogramProducerFactory<KoBasicF32HistogramProducer> 0307 (KoID("YCBCRF32HISTO", i18n("YCbCr/F32 Histogram")), YCbCrAColorModelID.id(), Float32BitsColorDepthID.id())); 0308 0309 // Add profile alias for default profile from lcms1 0310 registry->addProfileAlias("sRGB built-in - (lcms internal)", "sRGB built-in"); 0311 registry->addProfileAlias("gray built-in - (lcms internal)", "gray built-in"); 0312 registry->addProfileAlias("Lab identity built-in - (lcms internal)", "Lab identity built-in"); 0313 registry->addProfileAlias("XYZ built-in - (lcms internal)", "XYZ identity built-in"); 0314 0315 #if defined(HAVE_LCMS_FAST_FLOAT_PLUGIN) 0316 cmsPlugin(cmsFastFloatExtensions()); 0317 #endif 0318 } 0319 0320 #include <LcmsEnginePlugin.moc>