r15127 by jghali - add lcms2 color management classes
scribus-commit
scribus-commit at lists.scribus.net
Fri May 28 18:30:47 CEST 2010
Revision: 15127
Author: jghali
Date: 2010-05-28T16:25:44.997861Z
Commit message: add lcms2 color management classes
Changeset:
A /trunk/Scribus/scribus/colormgmt/sclcms2colormgmtengineimpl.h
A /trunk/Scribus/scribus/colormgmt/sclcms2colorprofileimpl.cpp
A /trunk/Scribus/scribus/colormgmt/sclcms2colortransformimpl.h
A /trunk/Scribus/scribus/colormgmt/sclcms2colorprofileimpl.h
A /trunk/Scribus/scribus/colormgmt/sclcms2colormgmtengineimpl.cpp
A /trunk/Scribus/scribus/colormgmt/sclcms2colortransformimpl.cpp
Diffs:
Index: scribus/colormgmt/sclcms2colormgmtengineimpl.cpp
===================================================================
--- scribus/colormgmt/sclcms2colormgmtengineimpl.cpp (revision 0)
+++ scribus/colormgmt/sclcms2colormgmtengineimpl.cpp (revision 15127)
@@ -0,0 +1,518 @@
+/*
+For general Scribus (>=1.3.2) copyright and licensing information please refer
+to the COPYING file provided with the program. Following this notice may exist
+a copyright and/or license notice that predates the release of Scribus 1.3.2
+for which a new license (GPL+exception) is in place.
+*/
+
+#include <iostream>
+#include <string>
+#include <QDir>
+#include <QFile>
+
+#include "sclcms2colormgmtengineimpl.h"
+#include "sclcms2colorprofileimpl.h"
+#include "sclcms2colortransformimpl.h"
+
+#ifndef cmsFLAGS_PRESERVEBLACK
+#define cmsFLAGS_PRESERVEBLACK 0x8000
+#endif
+
+QSharedPointer<ScColorProfileCache> ScLcms2ColorMgmtEngineImpl::m_profileCache;
+QSharedPointer<ScColorTransformPool> ScLcms2ColorMgmtEngineImpl::m_transformPool;
+
+ScLcms2ColorMgmtEngineImpl::ScLcms2ColorMgmtEngineImpl()
+ : ScColorMgmtEngineData("Littlecms v2", 1)
+{
+ if (!m_profileCache)
+ m_profileCache = QSharedPointer<ScColorProfileCache>(new ScColorProfileCache());
+ if (!m_transformPool)
+ m_transformPool = QSharedPointer<ScColorTransformPool>(new ScColorTransformPool(0));
+ cmsUInt16Number alarmCodes[cmsMAXCHANNELS] = { 0 };
+ alarmCodes[1] = 0xFFFF;
+ cmsSetAlarmCodes(alarmCodes);
+ cmsSetLogErrorHandler(&cmsErrorHandler);
+}
+
+void ScLcms2ColorMgmtEngineImpl::setStrategy(const ScColorMgmtStrategy& strategy)
+{
+ m_strategy = strategy;
+}
+
+QList<ScColorProfileInfo> ScLcms2ColorMgmtEngineImpl::getAvailableProfileInfo(const QString& directory, bool recursive)
+{
+ QList<ScColorProfileInfo> profileInfos;
+
+ QDir d(directory, "*", QDir::Name, QDir::Files | QDir::Readable | QDir::Dirs | QDir::NoSymLinks);
+ if ((!d.exists()) || (d.count() == 0))
+ return profileInfos;
+
+ QString nam = "";
+ cmsHPROFILE hIn = NULL;
+
+ for (uint dc = 0; dc < d.count(); ++dc)
+ {
+ QString file = d[dc];
+ if (file == "." || file == "..")
+ continue;
+ QFileInfo fi(directory + "/" + file);
+ if (fi.isDir() && !recursive)
+ continue;
+ else if (fi.isDir() && !file.startsWith('.'))
+ {
+ QList<ScColorProfileInfo> profileInfos2 = getAvailableProfileInfo(fi.filePath()+"/", true);
+ profileInfos.append(profileInfos2);
+ continue;
+ }
+
+ ScColorProfileInfo profileInfo;
+ profileInfo.file = fi.filePath();
+
+ QFile f(fi.filePath());
+ QByteArray bb(40, ' ');
+ if (!f.open(QIODevice::ReadOnly)) {
+ profileInfo.debug = QString("couldn't open %1 as color profile").arg(fi.filePath());
+ profileInfos.append(profileInfo);
+ continue;
+ }
+ int len = f.read(bb.data(), 40);
+ f.close();
+ if (len == 40 && bb[36] == 'a' && bb[37] == 'c' && bb[38] == 's' && bb[39] == 'p')
+ {
+ const QByteArray profilePath( QString(directory + "/" + file).toLocal8Bit() );
+ hIn = cmsOpenProfileFromFile(profilePath.data(), "r");
+ if (hIn == NULL)
+ continue;
+ cmsUInt32Number descSize = cmsGetProfileInfo(hIn, cmsInfoDescription, "en", "US", NULL, 0);
+ if (descSize > 0)
+ {
+ wchar_t* descData = (wchar_t*) malloc(descSize + sizeof(wchar_t));
+ descSize = cmsGetProfileInfo(hIn, cmsInfoDescription, "en", "US", descData, descSize);
+ if (descSize > 0)
+ {
+ if (sizeof(wchar_t) == sizeof(QChar)) {
+ profileInfo.description = QString::fromUtf16((ushort *) descData, descSize / sizeof(wchar_t));
+ } else {
+ profileInfo.description = QString::fromUcs4((uint *) descData, descSize / sizeof(wchar_t));
+ }
+ free(descData);
+ }
+ }
+ if (profileInfo.description.isEmpty())
+ {
+ cmsCloseProfile(hIn);
+ profileInfo.debug = QString("Color profile %1 is broken : no valid description").arg(fi.filePath());
+ profileInfos.append(profileInfo);
+ continue;
+ }
+ profileInfo.colorSpace = translateLcmsColorSpaceType( cmsGetColorSpace(hIn) );
+ profileInfo.deviceClass = translateLcmsProfileClass( cmsGetDeviceClass(hIn) );
+ profileInfos.append(profileInfo);
+ cmsCloseProfile(hIn);
+ hIn = NULL;
+ }
+ }
+
+ return profileInfos;
+}
+
+ScColorProfile ScLcms2ColorMgmtEngineImpl::openProfileFromFile(ScColorMgmtEngine& engine, const QString& filePath)
+{
+ // Search profile in profile cache first
+ ScColorProfile profile = m_profileCache->profile(filePath);
+ if (!profile.isNull())
+ return profile;
+ cmsHPROFILE lcmsProf = NULL;
+ QFile file(filePath);
+ if (file.open(QFile::ReadOnly))
+ {
+ // We do not use lcms cmsOpenProfileFromFile() to avoid limitations
+ // of I/O on 8bit filenames on Windows
+ QByteArray data = file.readAll();
+ if (!data.isEmpty())
+ {
+ lcmsProf = cmsOpenProfileFromMem(data.data(), data.size());
+ if (lcmsProf)
+ {
+ ScLcms2ColorProfileImpl* profData = new ScLcms2ColorProfileImpl(engine, lcmsProf);
+ profData->m_profileData = data;
+ profData->m_profilePath = filePath;
+ profile = ScColorProfile(dynamic_cast<ScColorProfileData*>(profData));
+ m_profileCache->addProfile(profile);
+ }
+ if (profile.isNull() && lcmsProf)
+ {
+ cmsCloseProfile(lcmsProf);
+ lcmsProf = NULL;
+ }
+ }
+ file.close();
+ }
+ return profile;
+}
+
+ScColorProfile ScLcms2ColorMgmtEngineImpl::openProfileFromMem(ScColorMgmtEngine& engine, const QByteArray& data)
+{
+ ScColorProfile profile;
+ cmsHPROFILE lcmsProf = cmsOpenProfileFromMem((const void *) data.data(), data.size());
+ if (lcmsProf)
+ {
+ ScLcms2ColorProfileImpl* profData = new ScLcms2ColorProfileImpl(engine, lcmsProf);
+ QString desc = profData->productDescription();
+ if (!desc.isEmpty())
+ profData->m_profilePath = QString("memprofile://%1").arg(desc);
+ profData->m_profileData = data;
+ profile = ScColorProfile(dynamic_cast<ScColorProfileData*>(profData));
+ }
+ if (profile.isNull() && lcmsProf)
+ {
+ cmsCloseProfile(lcmsProf);
+ lcmsProf = NULL;
+ }
+ return profile;
+}
+
+ScColorProfile ScLcms2ColorMgmtEngineImpl::createProfile_sRGB(ScColorMgmtEngine& engine)
+{
+ QString internalProfilePath("memprofile://Internal sRGB profile");
+ ScColorProfile profile = m_profileCache->profile(internalProfilePath);
+ if (!profile.isNull())
+ return profile;
+
+ cmsHPROFILE lcmsProf = cmsCreate_sRGBProfile();
+ if (lcmsProf)
+ {
+ ScLcms2ColorProfileImpl* profData = new ScLcms2ColorProfileImpl(engine, lcmsProf);
+ profData->m_profilePath = internalProfilePath;
+ profile = ScColorProfile(dynamic_cast<ScColorProfileData*>(profData));
+ m_profileCache->addProfile(profile);
+ }
+ if (profile.isNull() && lcmsProf)
+ {
+ cmsCloseProfile(lcmsProf);
+ lcmsProf = NULL;
+ }
+ return profile;
+}
+
+ScColorProfile ScLcms2ColorMgmtEngineImpl::createProfile_Lab(ScColorMgmtEngine& engine)
+{
+ QString internalProfilePath("memprofile://Internal Lab profile");
+ ScColorProfile profile = m_profileCache->profile(internalProfilePath);
+ if (!profile.isNull())
+ return profile;
+
+ cmsHPROFILE lcmsProf = cmsCreateLab2Profile(NULL);
+ if (lcmsProf)
+ {
+ ScLcms2ColorProfileImpl* profData = new ScLcms2ColorProfileImpl(engine, lcmsProf);
+ profData->m_profilePath = internalProfilePath;
+ profile = ScColorProfile(dynamic_cast<ScColorProfileData*>(profData));
+ m_profileCache->addProfile(profile);
+ }
+ if (profile.isNull() && lcmsProf)
+ {
+ cmsCloseProfile(lcmsProf);
+ lcmsProf = NULL;
+ }
+ return profile;
+}
+
+ScColorTransform ScLcms2ColorMgmtEngineImpl::createTransform(ScColorMgmtEngine& engine,
+ const ScColorProfile& inputProfile , eColorFormat inputFormat,
+ const ScColorProfile& outputProfile, eColorFormat outputFormat,
+ eRenderIntent renderIntent, long transformFlags)
+{
+ ScColorTransform transform(NULL);
+ if (inputProfile.isNull() || outputProfile.isNull())
+ return transform;
+ int inputProfEngineID = inputProfile.engine().engineID();
+ int outputProfEngineID = outputProfile.engine().engineID();
+ if ((engine.engineID() != m_engineID) || (inputProfEngineID != m_engineID) || (outputProfEngineID != m_engineID))
+ return transform;
+ const ScLcms2ColorProfileImpl* lcmsInputProf = dynamic_cast<const ScLcms2ColorProfileImpl*>(inputProfile.data());
+ const ScLcms2ColorProfileImpl* lcmsOutputProf = dynamic_cast<const ScLcms2ColorProfileImpl*>(outputProfile.data());
+ if (!lcmsInputProf || !lcmsOutputProf)
+ return transform;
+
+ transformFlags &= (~Ctf_Softproofing);
+ transformFlags &= (~Ctf_GamutCheck);
+ long strategyFlags = 0;
+ if (m_strategy.useBlackPointCompensation)
+ strategyFlags |= Ctf_BlackPointCompensation;
+ if (m_strategy.useBlackPreservation)
+ strategyFlags |= Ctf_BlackPreservation;
+
+ ScColorTransformInfo transInfo;
+ transInfo.inputProfile = inputProfile.productDescription();
+ transInfo.outputProfile = outputProfile.productDescription();
+ transInfo.proofingProfile = QString();
+ transInfo.inputFormat = inputFormat;
+ transInfo.outputFormat = outputFormat;
+ transInfo.renderIntent = renderIntent;
+ transInfo.proofingIntent = (eRenderIntent) 0;
+ transInfo.flags = transformFlags | strategyFlags;
+
+ bool nullTransform = false;
+ if (transInfo.inputProfile == transInfo.outputProfile)
+ {
+ // This is a null transform
+ transInfo.inputProfile = QString();
+ transInfo.outputProfile = QString();
+ transInfo.proofingProfile = QString();
+ transInfo.renderIntent = (eRenderIntent) 0;
+ transInfo.proofingIntent = (eRenderIntent) 0;
+ transInfo.flags = 0;
+ nullTransform = true;
+ }
+
+ transform = m_transformPool->findTransform(transInfo);
+ if (transform.isNull())
+ {
+ cmsUInt32Number lcmsFlags = translateFlagsToLcmsFlags(transformFlags | strategyFlags);
+ cmsUInt32Number lcmsInputFmt = translateFormatToLcmsFormat(inputFormat);
+ cmsUInt32Number lcmsOutputFmt = translateFormatToLcmsFormat(outputFormat);
+ int lcmsIntent = translateIntentToLcmsIntent(renderIntent);
+ if (nullTransform)
+ lcmsFlags |= cmsFLAGS_NULLTRANSFORM;
+ cmsHTRANSFORM hTransform = NULL;
+ hTransform = cmsCreateTransform(lcmsInputProf->m_profileHandle , lcmsInputFmt,
+ lcmsOutputProf->m_profileHandle, lcmsOutputFmt,
+ lcmsIntent, lcmsFlags | cmsFLAGS_LOWRESPRECALC);
+ if (hTransform)
+ {
+ ScLcms2ColorTransformImpl* newTrans = new ScLcms2ColorTransformImpl(engine, hTransform);
+ newTrans->setTransformInfo(transInfo);
+ transform = ScColorTransform(dynamic_cast<ScColorTransformData*>(newTrans));
+ m_transformPool->addTransform(transform, true);
+ }
+ }
+ return transform;
+}
+
+ScColorTransform ScLcms2ColorMgmtEngineImpl::createProofingTransform(ScColorMgmtEngine& engine,
+ const ScColorProfile& inputProfile , eColorFormat inputFormat,
+ const ScColorProfile& outputProfile, eColorFormat outputFormat,
+ const ScColorProfile& proofProfile , eRenderIntent renderIntent,
+ eRenderIntent proofingIntent, long transformFlags)
+{
+ ScColorTransform transform(NULL);
+ if (inputProfile.isNull() || outputProfile.isNull())
+ return transform;
+ int inputProfEngineID = inputProfile.engine().engineID();
+ int outputProfEngineID = outputProfile.engine().engineID();
+ int proofProfEngineID = proofProfile.engine().engineID();
+ if ((engine.engineID() != m_engineID) || (inputProfEngineID != m_engineID) ||
+ (outputProfEngineID != m_engineID) || (proofProfEngineID != m_engineID))
+ return transform;
+ const ScLcms2ColorProfileImpl* lcmsInputProf = dynamic_cast<const ScLcms2ColorProfileImpl*>(inputProfile.data());
+ const ScLcms2ColorProfileImpl* lcmsOutputProf = dynamic_cast<const ScLcms2ColorProfileImpl*>(outputProfile.data());
+ const ScLcms2ColorProfileImpl* lcmsProofingProf = dynamic_cast<const ScLcms2ColorProfileImpl*>(proofProfile.data());
+ if (!lcmsInputProf || !lcmsOutputProf || !lcmsProofingProf)
+ return transform;
+
+ long strategyFlags = 0;
+ if (m_strategy.useBlackPointCompensation)
+ strategyFlags |= Ctf_BlackPointCompensation;
+ if (m_strategy.useBlackPreservation)
+ strategyFlags |= Ctf_BlackPreservation;
+
+ ScColorTransformInfo transInfo;
+ transInfo.inputProfile = inputProfile.productDescription();
+ transInfo.outputProfile = outputProfile.productDescription();
+ transInfo.proofingProfile = proofProfile.productDescription();
+ transInfo.inputFormat = inputFormat;
+ transInfo.outputFormat = outputFormat;
+ transInfo.renderIntent = renderIntent;
+ transInfo.proofingIntent = proofingIntent;
+ transInfo.flags = transformFlags | strategyFlags;
+
+ cmsUInt32Number lcmsFlags = translateFlagsToLcmsFlags(transformFlags | strategyFlags);
+ cmsUInt32Number lcmsInputFmt = translateFormatToLcmsFormat(inputFormat);
+ cmsUInt32Number lcmsOutputFmt = translateFormatToLcmsFormat(outputFormat);
+ int lcmsIntent = translateIntentToLcmsIntent(renderIntent);
+ int lcmsPrfIntent = translateIntentToLcmsIntent(proofingIntent);
+
+ if (transInfo.inputProfile != transInfo.proofingProfile)
+ {
+ if (transInfo.proofingProfile == transInfo.outputProfile)
+ {
+ transInfo.proofingIntent = Intent_Relative_Colorimetric;
+ lcmsPrfIntent = translateIntentToLcmsIntent(Intent_Relative_Colorimetric);
+ }
+ transform = m_transformPool->findTransform(transInfo);
+ if (transform.isNull())
+ {
+ cmsHTRANSFORM hTransform = NULL;
+ hTransform = cmsCreateProofingTransform(lcmsInputProf->m_profileHandle , lcmsInputFmt,
+ lcmsOutputProf->m_profileHandle, lcmsOutputFmt,
+ lcmsProofingProf->m_profileHandle, lcmsIntent,
+ lcmsPrfIntent, lcmsFlags | cmsFLAGS_SOFTPROOFING);
+ if (hTransform)
+ {
+ ScLcms2ColorTransformImpl* newTrans = new ScLcms2ColorTransformImpl(engine, hTransform);
+ newTrans->setTransformInfo(transInfo);
+ transform = ScColorTransform(dynamic_cast<ScColorTransformData*>(newTrans));
+ m_transformPool->addTransform(transform, true);
+ }
+ }
+ }
+ else
+ {
+ transformFlags &= (~Ctf_Softproofing);
+ transformFlags &= (~Ctf_GamutCheck);
+ lcmsFlags = translateFlagsToLcmsFlags(transformFlags | strategyFlags);
+ transInfo.flags = transformFlags | strategyFlags;
+ transInfo.renderIntent = proofingIntent;
+ transInfo.proofingIntent = (eRenderIntent) 0;
+ if (transInfo.inputProfile == transInfo.outputProfile)
+ {
+ lcmsFlags |= cmsFLAGS_NULLTRANSFORM;
+ transInfo.inputProfile = QString();
+ transInfo.outputProfile = QString();
+ transInfo.proofingProfile = QString();
+ transInfo.renderIntent = (eRenderIntent) 0;
+ transInfo.proofingIntent = (eRenderIntent) 0;
+ transInfo.flags = 0;
+ }
+ transform = m_transformPool->findTransform(transInfo);
+ if (transform.isNull())
+ {
+ cmsHTRANSFORM hTransform = NULL;
+ hTransform = cmsCreateTransform(lcmsInputProf->m_profileHandle , lcmsInputFmt,
+ lcmsOutputProf->m_profileHandle, lcmsOutputFmt,
+ lcmsPrfIntent, lcmsFlags | cmsFLAGS_LOWRESPRECALC);
+ if (hTransform)
+ {
+ ScLcms2ColorTransformImpl* newTrans = new ScLcms2ColorTransformImpl(engine, hTransform);
+ newTrans->setTransformInfo(transInfo);
+ transform = ScColorTransform(dynamic_cast<ScColorTransformData*>(newTrans));
+ m_transformPool->addTransform(transform, true);
+ }
+ }
+ }
+ return transform;
+}
+
+cmsUInt32Number ScLcms2ColorMgmtEngineImpl::translateFlagsToLcmsFlags(long flags)
+{
+ cmsUInt32Number lFlags = 0;
+ if (flags & Ctf_BlackPointCompensation)
+ lFlags |= cmsFLAGS_BLACKPOINTCOMPENSATION;
+ if (flags & Ctf_BlackPreservation)
+ lFlags |= cmsFLAGS_PRESERVEBLACK;
+ if (flags & Ctf_Softproofing)
+ lFlags |= cmsFLAGS_SOFTPROOFING;
+ if (flags & Ctf_GamutCheck)
+ lFlags |= cmsFLAGS_GAMUTCHECK;
+ return lFlags;
+}
+
+cmsUInt32Number ScLcms2ColorMgmtEngineImpl::translateFormatToLcmsFormat(eColorFormat format)
+{
+ cmsUInt32Number lFormat = 0;
+ if (format == Format_RGB_8)
+ lFormat = TYPE_RGB_8;
+ if (format == Format_RGB_16)
+ lFormat = TYPE_RGB_16;
+ if (format == Format_RGBA_8)
+ lFormat = TYPE_RGBA_8;
+ if (format == Format_RGBA_16)
+ lFormat = TYPE_RGBA_16;
+ if (format == Format_ARGB_8)
+ lFormat = TYPE_ARGB_8;
+ if (format == Format_ARGB_16)
+ lFormat = TYPE_ARGB_16;
+ if (format == Format_BGRA_8)
+ lFormat = TYPE_BGRA_8;
+ if (format == Format_BGRA_16)
+ lFormat = TYPE_BGRA_16;
+ if (format == Format_CMYK_8)
+ lFormat = TYPE_CMYK_8;
+ if (format == Format_CMYK_16)
+ lFormat = TYPE_CMYK_16;
+ if (format == Format_CMYKA_8)
+ lFormat = (COLORSPACE_SH(PT_CMYK)|EXTRA_SH(1)|CHANNELS_SH(4)|BYTES_SH(1));
+ if (format == Format_CMYKA_16)
+ lFormat = (COLORSPACE_SH(PT_CMYK)|EXTRA_SH(1)|CHANNELS_SH(4)|BYTES_SH(2));
+ if (format == Format_YMCK_8)
+ lFormat = (COLORSPACE_SH(PT_CMYK)|CHANNELS_SH(4)|BYTES_SH(1)|DOSWAP_SH(1)|SWAPFIRST_SH(1));
+ if (format == Format_YMCK_16)
+ lFormat = (COLORSPACE_SH(PT_CMYK)|CHANNELS_SH(4)|BYTES_SH(2)|DOSWAP_SH(1)|SWAPFIRST_SH(1));
+ if (format == Format_GRAY_8)
+ lFormat = TYPE_GRAY_8;
+ if (format == Format_GRAY_16)
+ lFormat = TYPE_GRAY_16;
+ if (format == Format_LabA_8)
+ lFormat = COLORSPACE_SH(PT_Lab)|CHANNELS_SH(3)|BYTES_SH(1)|EXTRA_SH(1);
+ return lFormat;
+}
+
+int ScLcms2ColorMgmtEngineImpl::translateIntentToLcmsIntent(eRenderIntent intent, eRenderIntent defIntent)
+{
+ int lIntent = defIntent;
+ if (intent == Intent_Perceptual)
+ lIntent = INTENT_PERCEPTUAL;
+ if (intent == Intent_Relative_Colorimetric)
+ lIntent = INTENT_RELATIVE_COLORIMETRIC;
+ if (intent == Intent_Saturation)
+ lIntent = INTENT_SATURATION;
+ if (intent == Intent_Absolute_Colorimetric)
+ lIntent = INTENT_ABSOLUTE_COLORIMETRIC;
+ return lIntent;
+}
+
+eColorSpaceType ScLcms2ColorMgmtEngineImpl::translateLcmsColorSpaceType(cmsColorSpaceSignature signature)
+{
+ eColorSpaceType colorSpaceType = ColorSpace_Unknown;
+ if (signature == cmsSigXYZData)
+ colorSpaceType = ColorSpace_XYZ;
+ if (signature == cmsSigLabData)
+ colorSpaceType = ColorSpace_Lab;
+ if (signature == cmsSigLuvData)
+ colorSpaceType = ColorSpace_Luv;
+ if (signature == cmsSigYCbCrData)
+ colorSpaceType = ColorSpace_YCbCr;
+ if (signature == cmsSigYxyData)
+ colorSpaceType = ColorSpace_Yxy;
+ if (signature == cmsSigRgbData)
+ colorSpaceType = ColorSpace_Rgb;
+ if (signature == cmsSigGrayData)
+ colorSpaceType = ColorSpace_Gray;
+ if (signature == cmsSigHsvData)
+ colorSpaceType = ColorSpace_Hsv;
+ if (signature == cmsSigHlsData)
+ colorSpaceType = ColorSpace_Hls;
+ if (signature == cmsSigCmykData)
+ colorSpaceType = ColorSpace_Cmyk;
+ if (signature == cmsSigCmyData)
+ colorSpaceType = ColorSpace_Cmy;
+ return colorSpaceType;
+}
+
+eProfileClass ScLcms2ColorMgmtEngineImpl::translateLcmsProfileClass(cmsProfileClassSignature signature)
+{
+ eProfileClass profileClass = Class_Unknown;
+ if (signature == cmsSigInputClass)
+ profileClass = Class_Input;
+ if (signature == cmsSigDisplayClass)
+ profileClass = Class_Display;
+ if (signature == cmsSigOutputClass)
+ profileClass = Class_Output;
+ if (signature == cmsSigLinkClass)
+ profileClass = Class_Link;
+ if (signature == cmsSigAbstractClass)
+ profileClass = Class_Abstract;
+ if (signature == cmsSigColorSpaceClass)
+ profileClass = Class_ColorSpace;
+ if (signature == cmsSigNamedColorClass)
+ profileClass = Class_NamedColor;
+ return profileClass;
+}
+
+void ScLcms2ColorMgmtEngineImpl::cmsErrorHandler(cmsContext contextID, cmsUInt32Number /*ErrorCode*/,
+ const char *ErrorText)
+{
+ std::string msg = std::string("Littlecms : ") + ErrorText;
+ std::cerr << ErrorText << std::endl;
+}
Index: scribus/colormgmt/sclcms2colorprofileimpl.cpp
===================================================================
--- scribus/colormgmt/sclcms2colorprofileimpl.cpp (revision 0)
+++ scribus/colormgmt/sclcms2colorprofileimpl.cpp (revision 15127)
@@ -0,0 +1,74 @@
+/*
+For general Scribus (>=1.3.2) copyright and licensing information please refer
+to the COPYING file provided with the program. Following this notice may exist
+a copyright and/or license notice that predates the release of Scribus 1.3.2
+for which a new license (GPL+exception) is in place.
+*/
+
+#include "sclcms2colorprofileimpl.h"
+#include "sclcms2colormgmtengineimpl.h"
+
+ScLcms2ColorProfileImpl::ScLcms2ColorProfileImpl(ScColorMgmtEngine& engine, cmsHPROFILE lcmsProfile)
+ : ScColorProfileImplBase(engine), m_profileHandle(lcmsProfile)
+{
+
+}
+
+ScLcms2ColorProfileImpl::~ScLcms2ColorProfileImpl()
+{
+ closeProfile();
+}
+
+bool ScLcms2ColorProfileImpl::isNull() const
+{
+ return (m_profileHandle == NULL);
+}
+
+eColorSpaceType ScLcms2ColorProfileImpl::colorSpace() const
+{
+ if (m_profileHandle)
+ return ScLcms2ColorMgmtEngineImpl::translateLcmsColorSpaceType( cmsGetColorSpace(m_profileHandle) );
+ return ColorSpace_Unknown;
+}
+
+eProfileClass ScLcms2ColorProfileImpl::deviceClass() const
+{
+ if (m_profileHandle)
+ return ScLcms2ColorMgmtEngineImpl::translateLcmsProfileClass( cmsGetDeviceClass(m_profileHandle) );
+ return Class_Unknown;
+}
+
+QString ScLcms2ColorProfileImpl::productDescription() const
+{
+ if (m_productDescription.isEmpty())
+ {
+ if (m_profileHandle)
+ {
+ cmsUInt32Number descSize = cmsGetProfileInfo(m_profileHandle, cmsInfoDescription, "en", "US", NULL, 0);
+ if (descSize > 0)
+ {
+ wchar_t* descData = (wchar_t*) malloc(descSize + sizeof(wchar_t));
+ descSize = cmsGetProfileInfo(m_profileHandle, cmsInfoDescription, "en", "US", descData, descSize);
+ if (descSize > 0)
+ {
+ if (sizeof(wchar_t) == sizeof(QChar)) {
+ m_productDescription = QString::fromUtf16((ushort *) descData, descSize / sizeof(wchar_t));
+ } else {
+ m_productDescription = QString::fromUcs4((uint *) descData, descSize / sizeof(wchar_t));
+ }
+ free(descData);
+ }
+ }
+ }
+ }
+ return m_productDescription;
+}
+
+void ScLcms2ColorProfileImpl::closeProfile(void)
+{
+ if (m_profileHandle)
+ {
+ cmsCloseProfile(m_profileHandle);
+ m_profileHandle = NULL;
+ }
+}
\ No newline at end of file
Index: scribus/colormgmt/sclcms2colortransformimpl.h
===================================================================
--- scribus/colormgmt/sclcms2colortransformimpl.h (revision 0)
+++ scribus/colormgmt/sclcms2colortransformimpl.h (revision 15127)
@@ -0,0 +1,34 @@
+/*
+For general Scribus (>=1.3.2) copyright and licensing information please refer
+to the COPYING file provided with the program. Following this notice may exist
+a copyright and/or license notice that predates the release of Scribus 1.3.2
+for which a new license (GPL+exception) is in place.
+*/
+
+#ifndef SCLCMS2COLORTRANSFORMIMPL_H
+#define SCLCMS2COLORTRANSFORMIMPL_H
+
+#include "lcms2.h"
+#include "sccolormgmtimplelem.h"
+#include "sccolortransformdata.h"
+
+class ScLcms2ColorTransformImpl : public ScColorTransformImplBase
+{
+ friend class ScLcms2ColorMgmtEngineImpl;
+
+public:
+ ScLcms2ColorTransformImpl(ScColorMgmtEngine& engine, cmsHTRANSFORM lcmsTransform);
+ virtual ~ScLcms2ColorTransformImpl();
+
+ virtual bool isNull() const;
+
+ virtual bool apply(void* input, void* output, uint numElem);
+ virtual bool apply(QByteArray& input, QByteArray& output, uint numElem);
+
+protected:
+ cmsHTRANSFORM m_transformHandle;
+
+ void deleteTransform(void);
+};
+
+#endif
Index: scribus/colormgmt/sclcms2colormgmtengineimpl.h
===================================================================
--- scribus/colormgmt/sclcms2colormgmtengineimpl.h (revision 0)
+++ scribus/colormgmt/sclcms2colormgmtengineimpl.h (revision 15127)
@@ -0,0 +1,79 @@
+/*
+For general Scribus (>=1.3.2) copyright and licensing information please refer
+to the COPYING file provided with the program. Following this notice may exist
+a copyright and/or license notice that predates the release of Scribus 1.3.2
+for which a new license (GPL+exception) is in place.
+*/
+
+#ifndef SCLCMS2COLORMGMTENGINEIMPL_H
+#define SCLCMS2COLORMGMTENGINEIMPL_H
+
+#include <stdexcept>
+
+#include "lcms2.h"
+#include "sccolormgmtenginedata.h"
+#include "sccolorprofilecache.h"
+
+class ScLcms2ColorMgmtEngineImpl : public ScColorMgmtEngineData
+{
+ friend class ScLcms2ColorProfileImpl;
+ friend class ScLcms2ColorTransformImpl;
+
+public:
+ ScLcms2ColorMgmtEngineImpl();
+
+ // Setter, only for color management strategy
+ virtual void setStrategy(const ScColorMgmtStrategy& strategy);
+
+ // function for getting available profile in a directory
+ virtual QList<ScColorProfileInfo> getAvailableProfileInfo(const QString& directory, bool recursive);
+
+ // functions for opening icc profiles
+ virtual ScColorProfile openProfileFromFile(ScColorMgmtEngine& engine, const QString& filePath);
+ virtual ScColorProfile openProfileFromMem (ScColorMgmtEngine& engine, const QByteArray& array);
+
+ // functions for creating profiles
+ virtual ScColorProfile createProfile_sRGB(ScColorMgmtEngine& engine);
+ virtual ScColorProfile createProfile_Lab (ScColorMgmtEngine& engine);
+
+ // functions for creating transforms
+ virtual ScColorTransform createTransform(ScColorMgmtEngine& colorManagementEngine,
+ const ScColorProfile& inputProfile , eColorFormat inputFormat,
+ const ScColorProfile& outputProfile, eColorFormat outputFormat,
+ eRenderIntent renderIntent, long transformFlags);
+ virtual ScColorTransform createProofingTransform(ScColorMgmtEngine& colorManagementEngine,
+ const ScColorProfile& inputProfile , eColorFormat inputFormat,
+ const ScColorProfile& outputProfile, eColorFormat outputFormat,
+ const ScColorProfile& proofing, eRenderIntent renderIntent,
+ eRenderIntent proofingIntent, long transformFlags);
+
+protected:
+
+ // Color profile cache
+ static QSharedPointer<ScColorProfileCache> m_profileCache;
+
+ // Color transform cache
+ static QSharedPointer<ScColorTransformPool> m_transformPool;
+
+ static cmsUInt32Number translateFlagsToLcmsFlags(long flags);
+ static cmsUInt32Number translateFormatToLcmsFormat(eColorFormat format);
+ static int translateIntentToLcmsIntent(eRenderIntent intent, eRenderIntent defaut = Intent_Relative_Colorimetric);
+ static eColorSpaceType translateLcmsColorSpaceType(cmsColorSpaceSignature);
+ static eProfileClass translateLcmsProfileClass(cmsProfileClassSignature);
+
+ // Exception class thrown by cmsErrorHandler
+ class lcmsException : public std::runtime_error
+ {
+ public :
+ lcmsException(const char* msg) : std::runtime_error(msg) {}
+ };
+
+ /*!
+ \brief Simple error handler for use in conjunction with littlecms
+ \param ErrorCode error code issued by little cms
+ \param ErrorText error message corresponding to the error code
+ */
+ static void cmsErrorHandler(cmsContext contextID, cmsUInt32Number ErrorCode, const char *ErrorText);
+};
+
+#endif
Index: scribus/colormgmt/sclcms2colorprofileimpl.h
===================================================================
--- scribus/colormgmt/sclcms2colorprofileimpl.h (revision 0)
+++ scribus/colormgmt/sclcms2colorprofileimpl.h (revision 15127)
@@ -0,0 +1,38 @@
+/*
+For general Scribus (>=1.3.2) copyright and licensing information please refer
+to the COPYING file provided with the program. Following this notice may exist
+a copyright and/or license notice that predates the release of Scribus 1.3.2
+for which a new license (GPL+exception) is in place.
+*/
+
+#ifndef SCLCMS2COLORPROFILEIMPL_H
+#define SCLCMS2COLORPROFILEIMPL_H
+
+#include <QString>
+
+#include "lcms2.h"
+#include "sccolormgmtimplelem.h"
+#include "sccolorprofiledata.h"
+
+class ScLcms2ColorProfileImpl : public ScColorProfileImplBase
+{
+ friend class ScLcms2ColorMgmtEngineImpl;
+
+public:
+ ScLcms2ColorProfileImpl(ScColorMgmtEngine& engine, cmsHPROFILE lcmsProfile);
+ virtual ~ScLcms2ColorProfileImpl();
+
+ virtual bool isNull() const;
+
+ virtual eColorSpaceType colorSpace() const;
+ virtual eProfileClass deviceClass() const;
+ virtual QString productDescription() const;
+
+protected:
+ cmsHPROFILE m_profileHandle;
+ mutable QString m_productDescription;
+
+ void closeProfile(void);
+};
+
+#endif
Index: scribus/colormgmt/sclcms2colortransformimpl.cpp
===================================================================
--- scribus/colormgmt/sclcms2colortransformimpl.cpp (revision 0)
+++ scribus/colormgmt/sclcms2colortransformimpl.cpp (revision 15127)
@@ -0,0 +1,55 @@
+/*
+For general Scribus (>=1.3.2) copyright and licensing information please refer
+to the COPYING file provided with the program. Following this notice may exist
+a copyright and/or license notice that predates the release of Scribus 1.3.2
+for which a new license (GPL+exception) is in place.
+*/
+
+#include "sclcms2colortransformimpl.h"
+#include "sclcms2colormgmtengineimpl.h"
+
+ScLcms2ColorTransformImpl::ScLcms2ColorTransformImpl(ScColorMgmtEngine& engine, cmsHTRANSFORM lcmsTransform)
+ : ScColorTransformImplBase(engine), m_transformHandle(lcmsTransform)
+{
+
+}
+
+ScLcms2ColorTransformImpl::~ScLcms2ColorTransformImpl()
+{
+ deleteTransform();
+}
+
+bool ScLcms2ColorTransformImpl::isNull() const
+{
+ return (m_transformHandle == NULL);
+}
+
+bool ScLcms2ColorTransformImpl::apply(void* input, void* output, uint numElem)
+{
+ if (m_transformHandle)
+ {
+ cmsDoTransform(m_transformHandle, input, output, numElem);
+ return true;
+ }
+ return false;
+}
+
+bool ScLcms2ColorTransformImpl::apply(QByteArray& input, QByteArray& output, uint numElem)
+{
+ if (m_transformHandle)
+ {
+ cmsDoTransform(m_transformHandle, input.data(), output.data(), numElem);
+ return true;
+ }
+ return false;
+}
+
+void ScLcms2ColorTransformImpl::deleteTransform(void)
+{
+ if (m_transformHandle)
+ {
+ cmsDeleteTransform(m_transformHandle);
+ m_transformHandle = NULL;
+ }
+}
+
More information about the scribus-commit
mailing list