1 /*
2 For general Scribus (>=1.3.2) copyright and licensing information please refer
3 to the COPYING file provided with the program. Following this notice may exist
4 a copyright and/or license notice that predates the release of Scribus 1.3.2
5 for which a new license (GPL+exception) is in place.
6 */
7
8 #include <iostream>
9 #include <string>
10 #include <QDir>
11 #include <QFile>
12
13 #include "sclcmscolormgmtengineimpl.h"
14 #include "sclcmscolorprofileimpl.h"
15 #include "sclcmscolortransformimpl.h"
16
17 #ifndef cmsFLAGS_PRESERVEBLACK
18 #define cmsFLAGS_PRESERVEBLACK 0x8000
19 #endif
20
21 QSharedPointer<ScColorProfileCache> ScLcmsColorMgmtEngineImpl::m_profileCache;
22 QSharedPointer<ScColorTransformPool> ScLcmsColorMgmtEngineImpl::m_transformPool;
23
ScLcmsColorMgmtEngineImpl()24 ScLcmsColorMgmtEngineImpl::ScLcmsColorMgmtEngineImpl()
25 : ScColorMgmtEngineData("Littlecms v1", 0)
26 {
27 if (!m_profileCache)
28 m_profileCache = QSharedPointer<ScColorProfileCache>(new ScColorProfileCache());
29 if (!m_transformPool)
30 m_transformPool = QSharedPointer<ScColorTransformPool>(new ScColorTransformPool(0));
31 cmsSetAlarmCodes(0, 255, 0);
32 }
33
setStrategy(const ScColorMgmtStrategy & strategy)34 void ScLcmsColorMgmtEngineImpl::setStrategy(const ScColorMgmtStrategy& strategy)
35 {
36 m_strategy = strategy;
37 }
38
getAvailableProfileInfo(const QString & directory,bool recursive)39 QList<ScColorProfileInfo> ScLcmsColorMgmtEngineImpl::getAvailableProfileInfo(const QString& directory, bool recursive)
40 {
41 QList<ScColorProfileInfo> profileInfos;
42
43 QDir d(directory, "*", QDir::Name, QDir::Files | QDir::Readable | QDir::Dirs | QDir::NoSymLinks);
44 if ((!d.exists()) || (d.count() == 0))
45 return profileInfos;
46
47 QString nam = "";
48 cmsHPROFILE hIn = nullptr;
49
50 for (uint dc = 0; dc < d.count(); ++dc)
51 {
52 QString file = d[dc];
53 if (file == "." || file == "..")
54 continue;
55 QFileInfo fi(directory + "/" + file);
56 if (fi.isDir() && !recursive)
57 continue;
58 else if (fi.isDir() && !file.startsWith('.'))
59 {
60 QList<ScColorProfileInfo> profileInfos2 = getAvailableProfileInfo(fi.filePath()+"/", true);
61 profileInfos.append(profileInfos2);
62 continue;
63 }
64
65 ScColorProfileInfo profileInfo;
66 profileInfo.file = fi.filePath();
67
68 QFile f(fi.filePath());
69 QByteArray bb(40, ' ');
70 if (!f.open(QIODevice::ReadOnly)) {
71 profileInfo.debug = QString("couldn't open %1 as color profile").arg(fi.filePath());
72 profileInfos.append(profileInfo);
73 continue;
74 }
75 int len = f.read(bb.data(), 40);
76 f.close();
77 if (len == 40 && bb[36] == 'a' && bb[37] == 'c' && bb[38] == 's' && bb[39] == 'p')
78 {
79 const QByteArray profilePath( QString(directory + "/" + file).toLocal8Bit() );
80 cmsSetErrorHandler(&cmsErrorHandler);
81 try
82 {
83 hIn = cmsOpenProfileFromFile(profilePath.data(), "r");
84 if (hIn == nullptr)
85 continue;
86 const char* profileDescriptor = cmsTakeProductDesc(hIn);
87 profileInfo.description = QString(profileDescriptor);
88 if (profileInfo.description.isEmpty())
89 {
90 cmsCloseProfile(hIn);
91 profileInfo.debug = QString("Color profile %1 is broken : no valid description").arg(fi.filePath());
92 profileInfos.append(profileInfo);
93 continue;
94 }
95 profileInfo.colorSpace = translateLcmsColorSpaceType( cmsGetColorSpace(hIn) );
96 profileInfo.deviceClass = translateLcmsProfileClass( cmsGetDeviceClass(hIn) );
97 profileInfos.append(profileInfo);
98 cmsCloseProfile(hIn);
99 hIn = nullptr;
100 }
101 catch (lcmsException&)
102 {
103 // Profile is broken
104 if (hIn)
105 {
106 cmsCloseProfile(hIn);
107 hIn = nullptr;
108 }
109 profileInfo.debug = QString("Color profile %1 is broken").arg(fi.filePath());
110 profileInfos.append(profileInfo);
111 }
112 cmsSetErrorHandler(nullptr);
113 }
114 }
115 cmsSetErrorHandler(nullptr);
116
117 return profileInfos;
118 }
119
openProfileFromFile(ScColorMgmtEngine & engine,const QString & filePath)120 ScColorProfile ScLcmsColorMgmtEngineImpl::openProfileFromFile(ScColorMgmtEngine& engine, const QString& filePath)
121 {
122 // Search profile in profile cache first
123 ScColorProfile profile = m_profileCache->profile(filePath);
124 if (!profile.isNull())
125 return profile;
126 cmsHPROFILE lcmsProf = nullptr;
127 cmsSetErrorHandler(&cmsErrorHandler);
128 try
129 {
130 QFile file(filePath);
131 if (file.open(QFile::ReadOnly))
132 {
133 // We do not use lcms cmsOpenProfileFromFile() to avoid limitations
134 // of I/O on 8bit filenames on Windows
135 QByteArray data = file.readAll();
136 if (!data.isEmpty())
137 {
138 lcmsProf = cmsOpenProfileFromMem(data.data(), data.size());
139 if (lcmsProf)
140 {
141 ScLcmsColorProfileImpl* profData = new ScLcmsColorProfileImpl(engine, lcmsProf);
142 profData->m_profileData = data;
143 profData->m_profilePath = filePath;
144 profile = ScColorProfile(dynamic_cast<ScColorProfileData*>(profData));
145 m_profileCache->addProfile(profile);
146 }
147 if (profile.isNull() && lcmsProf)
148 {
149 cmsCloseProfile(lcmsProf);
150 lcmsProf = nullptr;
151 }
152 }
153 file.close();
154 }
155 }
156 catch (lcmsException& e)
157 {
158 std::cerr << e.what() << std::endl;
159 if (profile.isNull() && lcmsProf)
160 cmsCloseProfile(lcmsProf);
161 profile = ScColorProfile();
162 }
163 cmsSetErrorHandler(nullptr);
164 return profile;
165 }
166
openProfileFromMem(ScColorMgmtEngine & engine,const QByteArray & data)167 ScColorProfile ScLcmsColorMgmtEngineImpl::openProfileFromMem(ScColorMgmtEngine& engine, const QByteArray& data)
168 {
169 ScColorProfile profile;
170 cmsHPROFILE lcmsProf = nullptr;
171 cmsSetErrorHandler(&cmsErrorHandler);
172 try
173 {
174 lcmsProf = cmsOpenProfileFromMem((LPVOID) data.data(), data.size());
175 if (lcmsProf)
176 {
177 ScLcmsColorProfileImpl* profData = new ScLcmsColorProfileImpl(engine, lcmsProf);
178 QString desc = profData->productDescription();
179 if (!desc.isEmpty())
180 profData->m_profilePath = QString("memprofile://%1").arg(desc);
181 profData->m_profileData = data;
182 profile = ScColorProfile(dynamic_cast<ScColorProfileData*>(profData));
183 }
184 if (profile.isNull() && lcmsProf)
185 {
186 cmsCloseProfile(lcmsProf);
187 lcmsProf = nullptr;
188 }
189 }
190 catch (lcmsException& e)
191 {
192 std::cerr << e.what() << std::endl;
193 if (profile.isNull() && lcmsProf)
194 cmsCloseProfile(lcmsProf);
195 profile = ScColorProfile();
196 }
197 cmsSetErrorHandler(nullptr);
198 return profile;
199 }
200
createProfile_sRGB(ScColorMgmtEngine & engine)201 ScColorProfile ScLcmsColorMgmtEngineImpl::createProfile_sRGB(ScColorMgmtEngine& engine)
202 {
203 QString internalProfilePath("memprofile://Internal sRGB profile");
204 ScColorProfile profile = m_profileCache->profile(internalProfilePath);
205 if (!profile.isNull())
206 return profile;
207
208 cmsHPROFILE lcmsProf = nullptr;
209 cmsSetErrorHandler(&cmsErrorHandler);
210 try
211 {
212 lcmsProf = cmsCreate_sRGBProfile();
213 if (lcmsProf)
214 {
215 ScLcmsColorProfileImpl* profData = new ScLcmsColorProfileImpl(engine, lcmsProf);
216 profData->m_profilePath = internalProfilePath;
217 profile = ScColorProfile(dynamic_cast<ScColorProfileData*>(profData));
218 m_profileCache->addProfile(profile);
219 }
220 if (profile.isNull() && lcmsProf)
221 {
222 cmsCloseProfile(lcmsProf);
223 lcmsProf = nullptr;
224 }
225 }
226 catch (lcmsException& e)
227 {
228 std::cerr << e.what() << std::endl;
229 if (profile.isNull() && lcmsProf)
230 cmsCloseProfile(lcmsProf);
231 profile = ScColorProfile();
232 }
233 cmsSetErrorHandler(nullptr);
234 return profile;
235 }
236
createProfile_Lab(ScColorMgmtEngine & engine)237 ScColorProfile ScLcmsColorMgmtEngineImpl::createProfile_Lab(ScColorMgmtEngine& engine)
238 {
239 QString internalProfilePath("memprofile://Internal Lab profile");
240 ScColorProfile profile = m_profileCache->profile(internalProfilePath);
241 if (!profile.isNull())
242 return profile;
243
244 cmsHPROFILE lcmsProf = nullptr;
245 cmsSetErrorHandler(&cmsErrorHandler);
246 try
247 {
248 lcmsProf = cmsCreateLabProfile(nullptr);
249 if (lcmsProf)
250 {
251 ScLcmsColorProfileImpl* profData = new ScLcmsColorProfileImpl(engine, lcmsProf);
252 profData->m_profilePath = internalProfilePath;
253 profile = ScColorProfile(dynamic_cast<ScColorProfileData*>(profData));
254 m_profileCache->addProfile(profile);
255 }
256 if (profile.isNull() && lcmsProf)
257 {
258 cmsCloseProfile(lcmsProf);
259 lcmsProf = nullptr;
260 }
261 }
262 catch (lcmsException& e)
263 {
264 std::cerr << e.what() << std::endl;
265 if (profile.isNull() && lcmsProf)
266 cmsCloseProfile(lcmsProf);
267 profile = ScColorProfile();
268 }
269 cmsSetErrorHandler(nullptr);
270 return profile;
271 }
272
createTransform(ScColorMgmtEngine & engine,const ScColorProfile & inputProfile,eColorFormat inputFormat,const ScColorProfile & outputProfile,eColorFormat outputFormat,eRenderIntent renderIntent,long transformFlags)273 ScColorTransform ScLcmsColorMgmtEngineImpl::createTransform(ScColorMgmtEngine& engine,
274 const ScColorProfile& inputProfile , eColorFormat inputFormat,
275 const ScColorProfile& outputProfile, eColorFormat outputFormat,
276 eRenderIntent renderIntent, long transformFlags)
277 {
278 ScColorTransform transform(nullptr);
279 if (inputProfile.isNull() || outputProfile.isNull())
280 return transform;
281 int inputProfEngineID = inputProfile.engine().engineID();
282 int outputProfEngineID = outputProfile.engine().engineID();
283 if ((engine.engineID() != m_engineID) || (inputProfEngineID != m_engineID) || (outputProfEngineID != m_engineID))
284 return transform;
285 const ScLcmsColorProfileImpl* lcmsInputProf = dynamic_cast<const ScLcmsColorProfileImpl*>(inputProfile.data());
286 const ScLcmsColorProfileImpl* lcmsOutputProf = dynamic_cast<const ScLcmsColorProfileImpl*>(outputProfile.data());
287 if (!lcmsInputProf || !lcmsOutputProf)
288 return transform;
289
290 transformFlags &= (~Ctf_Softproofing);
291 transformFlags &= (~Ctf_GamutCheck);
292 long strategyFlags = 0;
293 if (m_strategy.useBlackPointCompensation)
294 strategyFlags |= Ctf_BlackPointCompensation;
295 if (m_strategy.useBlackPreservation)
296 strategyFlags |= Ctf_BlackPreservation;
297
298 ScColorTransformInfo transInfo;
299 transInfo.inputProfile = inputProfile.productDescription();
300 transInfo.outputProfile = outputProfile.productDescription();
301 transInfo.proofingProfile.clear();
302 transInfo.inputFormat = inputFormat;
303 transInfo.outputFormat = outputFormat;
304 transInfo.renderIntent = renderIntent;
305 transInfo.proofingIntent = (eRenderIntent) 0;
306 transInfo.flags = transformFlags | strategyFlags;
307
308 bool nullTransform = false;
309 if (transInfo.inputProfile == transInfo.outputProfile)
310 {
311 // This is a null transform
312 transInfo.inputProfile.clear();
313 transInfo.outputProfile.clear();
314 transInfo.proofingProfile.clear();
315 transInfo.renderIntent = (eRenderIntent) 0;
316 transInfo.proofingIntent = (eRenderIntent) 0;
317 transInfo.flags = 0;
318 nullTransform = true;
319 }
320
321 transform = m_transformPool->findTransform(transInfo);
322 if (transform.isNull())
323 {
324 DWORD lcmsFlags = translateFlagsToLcmsFlags(transformFlags | strategyFlags);
325 DWORD lcmsInputFmt = translateFormatToLcmsFormat(inputFormat);
326 DWORD lcmsOutputFmt = translateFormatToLcmsFormat(outputFormat);
327 int lcmsIntent = translateIntentToLcmsIntent(renderIntent);
328 if (nullTransform)
329 lcmsFlags |= cmsFLAGS_NULLTRANSFORM;
330 cmsHTRANSFORM hTransform = nullptr;
331 cmsSetErrorHandler(&cmsErrorHandler);
332 try
333 {
334 hTransform = cmsCreateTransform(lcmsInputProf->m_profileHandle , lcmsInputFmt,
335 lcmsOutputProf->m_profileHandle, lcmsOutputFmt,
336 lcmsIntent, lcmsFlags | cmsFLAGS_LOWRESPRECALC);
337 if (hTransform)
338 {
339 ScLcmsColorTransformImpl* newTrans = new ScLcmsColorTransformImpl(engine, hTransform);
340 newTrans->setTransformInfo(transInfo);
341 transform = ScColorTransform(dynamic_cast<ScColorTransformData*>(newTrans));
342 m_transformPool->addTransform(transform, true);
343 }
344 }
345 catch (lcmsException& e)
346 {
347 std::cerr << e.what() << std::endl;
348 // #9922 : no idea why that crash in release mode
349 /*if (transform.isNull() && hTransform)
350 cmsDeleteTransform(hTransform);*/
351 transform = ScColorTransform();
352 }
353 cmsSetErrorHandler(nullptr);
354 }
355 return transform;
356 }
357
createProofingTransform(ScColorMgmtEngine & engine,const ScColorProfile & inputProfile,eColorFormat inputFormat,const ScColorProfile & outputProfile,eColorFormat outputFormat,const ScColorProfile & proofProfile,eRenderIntent renderIntent,eRenderIntent proofingIntent,long transformFlags)358 ScColorTransform ScLcmsColorMgmtEngineImpl::createProofingTransform(ScColorMgmtEngine& engine,
359 const ScColorProfile& inputProfile , eColorFormat inputFormat,
360 const ScColorProfile& outputProfile, eColorFormat outputFormat,
361 const ScColorProfile& proofProfile , eRenderIntent renderIntent,
362 eRenderIntent proofingIntent, long transformFlags)
363 {
364 ScColorTransform transform(nullptr);
365 if (inputProfile.isNull() || outputProfile.isNull())
366 return transform;
367 int inputProfEngineID = inputProfile.engine().engineID();
368 int outputProfEngineID = outputProfile.engine().engineID();
369 int proofProfEngineID = proofProfile.engine().engineID();
370 if ((engine.engineID() != m_engineID) || (inputProfEngineID != m_engineID) ||
371 (outputProfEngineID != m_engineID) || (proofProfEngineID != m_engineID))
372 return transform;
373 const ScLcmsColorProfileImpl* lcmsInputProf = dynamic_cast<const ScLcmsColorProfileImpl*>(inputProfile.data());
374 const ScLcmsColorProfileImpl* lcmsOutputProf = dynamic_cast<const ScLcmsColorProfileImpl*>(outputProfile.data());
375 const ScLcmsColorProfileImpl* lcmsProofingProf = dynamic_cast<const ScLcmsColorProfileImpl*>(proofProfile.data());
376 if (!lcmsInputProf || !lcmsOutputProf || !lcmsProofingProf)
377 return transform;
378
379 long strategyFlags = 0;
380 if (m_strategy.useBlackPointCompensation)
381 strategyFlags |= Ctf_BlackPointCompensation;
382 if (m_strategy.useBlackPreservation)
383 strategyFlags |= Ctf_BlackPreservation;
384
385 ScColorTransformInfo transInfo;
386 transInfo.inputProfile = inputProfile.productDescription();
387 transInfo.outputProfile = outputProfile.productDescription();
388 transInfo.proofingProfile = proofProfile.productDescription();
389 transInfo.inputFormat = inputFormat;
390 transInfo.outputFormat = outputFormat;
391 transInfo.renderIntent = renderIntent;
392 transInfo.proofingIntent = proofingIntent;
393 transInfo.flags = transformFlags | strategyFlags;
394
395 DWORD lcmsFlags = translateFlagsToLcmsFlags(transformFlags | strategyFlags);
396 DWORD lcmsInputFmt = translateFormatToLcmsFormat(inputFormat);
397 DWORD lcmsOutputFmt = translateFormatToLcmsFormat(outputFormat);
398 int lcmsIntent = translateIntentToLcmsIntent(renderIntent);
399 int lcmsPrfIntent = translateIntentToLcmsIntent(proofingIntent);
400
401 if (transInfo.inputProfile != transInfo.proofingProfile)
402 {
403 if (transInfo.proofingProfile == transInfo.outputProfile)
404 {
405 transInfo.proofingIntent = Intent_Relative_Colorimetric;
406 lcmsPrfIntent = translateIntentToLcmsIntent(Intent_Relative_Colorimetric);
407 }
408 transform = m_transformPool->findTransform(transInfo);
409 if (transform.isNull())
410 {
411 cmsSetErrorHandler(&cmsErrorHandler);
412 cmsHTRANSFORM hTransform = nullptr;
413 try
414 {
415 hTransform = cmsCreateProofingTransform(lcmsInputProf->m_profileHandle , lcmsInputFmt,
416 lcmsOutputProf->m_profileHandle, lcmsOutputFmt,
417 lcmsProofingProf->m_profileHandle, lcmsIntent,
418 lcmsPrfIntent, lcmsFlags | cmsFLAGS_SOFTPROOFING);
419 if (hTransform)
420 {
421 ScLcmsColorTransformImpl* newTrans = new ScLcmsColorTransformImpl(engine, hTransform);
422 newTrans->setTransformInfo(transInfo);
423 transform = ScColorTransform(dynamic_cast<ScColorTransformData*>(newTrans));
424 m_transformPool->addTransform(transform, true);
425 }
426 }
427 catch (lcmsException& e)
428 {
429 std::cerr << e.what() << std::endl;
430 // #9922 : no idea why that crash in release mode
431 /*if (transform.isNull() && hTransform)
432 cmsDeleteTransform(hTransform);*/
433 transform = ScColorTransform();
434 }
435 cmsSetErrorHandler(nullptr);
436 }
437 }
438 else
439 {
440 transformFlags &= (~Ctf_Softproofing);
441 transformFlags &= (~Ctf_GamutCheck);
442 lcmsFlags = translateFlagsToLcmsFlags(transformFlags | strategyFlags);
443 transInfo.flags = transformFlags | strategyFlags;
444 transInfo.renderIntent = proofingIntent;
445 transInfo.proofingIntent = (eRenderIntent) 0;
446 if (transInfo.inputProfile == transInfo.outputProfile)
447 {
448 lcmsFlags |= cmsFLAGS_NULLTRANSFORM;
449 transInfo.inputProfile.clear();
450 transInfo.outputProfile.clear();
451 transInfo.proofingProfile.clear();
452 transInfo.renderIntent = (eRenderIntent) 0;
453 transInfo.proofingIntent = (eRenderIntent) 0;
454 transInfo.flags = 0;
455 }
456 transform = m_transformPool->findTransform(transInfo);
457 if (transform.isNull())
458 {
459 cmsSetErrorHandler(&cmsErrorHandler);
460 cmsHTRANSFORM hTransform = nullptr;
461 try
462 {
463 hTransform = cmsCreateTransform(lcmsInputProf->m_profileHandle , lcmsInputFmt,
464 lcmsOutputProf->m_profileHandle, lcmsOutputFmt,
465 lcmsPrfIntent, lcmsFlags | cmsFLAGS_LOWRESPRECALC);
466 if (hTransform)
467 {
468 ScLcmsColorTransformImpl* newTrans = new ScLcmsColorTransformImpl(engine, hTransform);
469 newTrans->setTransformInfo(transInfo);
470 transform = ScColorTransform(dynamic_cast<ScColorTransformData*>(newTrans));
471 m_transformPool->addTransform(transform, true);
472 }
473 }
474 catch (lcmsException& e)
475 {
476 std::cerr << e.what() << std::endl;
477 // #9922 : no idea why that crash in release mode
478 /*if (transform.isNull() && hTransform)
479 cmsDeleteTransform(hTransform);*/
480 transform = ScColorTransform();
481 }
482 cmsSetErrorHandler(nullptr);
483 }
484 }
485 return transform;
486 }
487
translateFlagsToLcmsFlags(long flags)488 DWORD ScLcmsColorMgmtEngineImpl::translateFlagsToLcmsFlags(long flags)
489 {
490 DWORD lFlags = 0;
491 if (flags & Ctf_BlackPointCompensation)
492 lFlags |= cmsFLAGS_BLACKPOINTCOMPENSATION;
493 if (flags & Ctf_BlackPreservation)
494 lFlags |= cmsFLAGS_PRESERVEBLACK;
495 if (flags & Ctf_Softproofing)
496 lFlags |= cmsFLAGS_SOFTPROOFING;
497 if (flags & Ctf_GamutCheck)
498 lFlags |= cmsFLAGS_GAMUTCHECK;
499 return lFlags;
500 }
501
translateFormatToLcmsFormat(eColorFormat format)502 DWORD ScLcmsColorMgmtEngineImpl::translateFormatToLcmsFormat(eColorFormat format)
503 {
504 DWORD lFormat = 0;
505 if (format == Format_RGB_8)
506 lFormat = TYPE_RGB_8;
507 if (format == Format_RGB_16)
508 lFormat = TYPE_RGB_16;
509 if (format == Format_RGBA_8)
510 lFormat = TYPE_RGBA_8;
511 if (format == Format_RGBA_16)
512 lFormat = TYPE_RGBA_16;
513 if (format == Format_ARGB_8)
514 lFormat = TYPE_ARGB_8;
515 if (format == Format_ARGB_16)
516 lFormat = TYPE_ARGB_16;
517 if (format == Format_BGRA_8)
518 lFormat = TYPE_BGRA_8;
519 if (format == Format_BGRA_16)
520 lFormat = TYPE_BGRA_16;
521 if (format == Format_CMYK_8)
522 lFormat = TYPE_CMYK_8;
523 if (format == Format_CMYK_16)
524 lFormat = TYPE_CMYK_16;
525 if (format == Format_CMYKA_8)
526 lFormat = (COLORSPACE_SH(PT_CMYK)|EXTRA_SH(1)|CHANNELS_SH(4)|BYTES_SH(1));
527 if (format == Format_CMYKA_16)
528 lFormat = (COLORSPACE_SH(PT_CMYK)|EXTRA_SH(1)|CHANNELS_SH(4)|BYTES_SH(2));
529 if (format == Format_YMCK_8)
530 lFormat = (COLORSPACE_SH(PT_CMYK)|CHANNELS_SH(4)|BYTES_SH(1)|DOSWAP_SH(1)|SWAPFIRST_SH(1));
531 if (format == Format_YMCK_16)
532 lFormat = (COLORSPACE_SH(PT_CMYK)|CHANNELS_SH(4)|BYTES_SH(2)|DOSWAP_SH(1)|SWAPFIRST_SH(1));
533 if (format == Format_GRAY_8)
534 lFormat = TYPE_GRAY_8;
535 if (format == Format_GRAY_16)
536 lFormat = TYPE_GRAY_16;
537 if (format == Format_LabA_8)
538 lFormat = COLORSPACE_SH(PT_Lab)|CHANNELS_SH(3)|BYTES_SH(1)|EXTRA_SH(1);
539 return lFormat;
540 }
541
translateIntentToLcmsIntent(eRenderIntent intent,eRenderIntent defIntent)542 int ScLcmsColorMgmtEngineImpl::translateIntentToLcmsIntent(eRenderIntent intent, eRenderIntent defIntent)
543 {
544 int lIntent = defIntent;
545 if (intent == Intent_Perceptual)
546 lIntent = INTENT_PERCEPTUAL;
547 if (intent == Intent_Relative_Colorimetric)
548 lIntent = INTENT_RELATIVE_COLORIMETRIC;
549 if (intent == Intent_Saturation)
550 lIntent = INTENT_SATURATION;
551 if (intent == Intent_Absolute_Colorimetric)
552 lIntent = INTENT_ABSOLUTE_COLORIMETRIC;
553 return lIntent;
554 }
555
translateLcmsColorSpaceType(icColorSpaceSignature signature)556 eColorSpaceType ScLcmsColorMgmtEngineImpl::translateLcmsColorSpaceType(icColorSpaceSignature signature)
557 {
558 eColorSpaceType colorSpaceType = ColorSpace_Unknown;
559 if (signature == icSigXYZData)
560 colorSpaceType = ColorSpace_XYZ;
561 if (signature == icSigLabData)
562 colorSpaceType = ColorSpace_Lab;
563 if (signature == icSigLuvData)
564 colorSpaceType = ColorSpace_Luv;
565 if (signature == icSigYCbCrData)
566 colorSpaceType = ColorSpace_YCbCr;
567 if (signature == icSigYxyData)
568 colorSpaceType = ColorSpace_Yxy;
569 if (signature == icSigRgbData)
570 colorSpaceType = ColorSpace_Rgb;
571 if (signature == icSigGrayData)
572 colorSpaceType = ColorSpace_Gray;
573 if (signature == icSigHsvData)
574 colorSpaceType = ColorSpace_Hsv;
575 if (signature == icSigHlsData)
576 colorSpaceType = ColorSpace_Hls;
577 if (signature == icSigCmykData)
578 colorSpaceType = ColorSpace_Cmyk;
579 if (signature == icSigCmyData)
580 colorSpaceType = ColorSpace_Cmy;
581 return colorSpaceType;
582 }
583
translateLcmsProfileClass(icProfileClassSignature signature)584 eProfileClass ScLcmsColorMgmtEngineImpl::translateLcmsProfileClass(icProfileClassSignature signature)
585 {
586 eProfileClass profileClass = Class_Unknown;
587 if (signature == icSigInputClass)
588 profileClass = Class_Input;
589 if (signature == icSigDisplayClass)
590 profileClass = Class_Display;
591 if (signature == icSigOutputClass)
592 profileClass = Class_Output;
593 if (signature == icSigLinkClass)
594 profileClass = Class_Link;
595 if (signature == icSigAbstractClass)
596 profileClass = Class_Abstract;
597 if (signature == icSigColorSpaceClass)
598 profileClass = Class_ColorSpace;
599 if (signature == icSigNamedColorClass)
600 profileClass = Class_NamedColor;
601 return profileClass;
602 }
603
cmsErrorHandler(int,const char * ErrorText)604 int ScLcmsColorMgmtEngineImpl::cmsErrorHandler(int /*ErrorCode*/, const char *ErrorText)
605 {
606 std::string msg = std::string("Littlecms : ") + ErrorText;
607 throw lcmsException(msg.c_str());
608 return 1;
609 }
610