summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorMarti Maria <info@littlecms.com>2011-04-12 15:48:03 +0200
committerMarti Maria <info@littlecms.com>2011-04-12 15:48:03 +0200
commit97f22bda885166a18e346db8dd24bd66bc4615cd (patch)
treedf399bb7e3db23ae02b8a0b01262fe5041f6c783 /src
parentb735a01cd82f08ef46733c9f19eb08ba1a6623af (diff)
downloadlcms2-97f22bda885166a18e346db8dd24bd66bc4615cd.tar.gz
Added named color functionality
Diffstat (limited to 'src')
-rw-r--r--src/cmscnvrt.c4
-rw-r--r--src/cmserr.c2
-rw-r--r--src/cmsio1.c40
-rw-r--r--src/cmsnamed.c24
-rw-r--r--src/cmspack.c2
-rw-r--r--src/cmsxform.c13
-rw-r--r--src/lcms2_internal.h2
7 files changed, 78 insertions, 9 deletions
diff --git a/src/cmscnvrt.c b/src/cmscnvrt.c
index 7e47d6c..8b5cd72 100644
--- a/src/cmscnvrt.c
+++ b/src/cmscnvrt.c
@@ -476,7 +476,7 @@ cmsPipeline* DefaultICCintents(cmsContext ContextID,
hProfile = hProfiles[i];
ClassSig = cmsGetDeviceClass(hProfile);
lIsDeviceLink = (ClassSig == cmsSigLinkClass || ClassSig == cmsSigAbstractClass );
-
+
// First profile is used as input unless devicelink or abstract
if ((i == 0) && !lIsDeviceLink) {
lIsInput = TRUE;
@@ -508,7 +508,7 @@ cmsPipeline* DefaultICCintents(cmsContext ContextID,
// If devicelink is found, then no custom intent is allowed and we can
// read the LUT to be applied. Settings don't apply here.
- if (lIsDeviceLink) {
+ if (lIsDeviceLink || ((ClassSig == cmsSigNamedColorClass) && (nProfiles == 1))) {
// Get the involved LUT from the profile
Lut = _cmsReadDevicelinkLUT(hProfile, Intent);
diff --git a/src/cmserr.c b/src/cmserr.c
index caa17e5..83d1e4f 100644
--- a/src/cmserr.c
+++ b/src/cmserr.c
@@ -250,7 +250,7 @@ void* CMSEXPORT _cmsDupMem(cmsContext ContextID, const void* Org, cmsUInt32Numbe
// Sub allocation takes care of many pointers of small size. The memory allocated in
// this way have be freed at once. Next function allocates a single chunk for linked list
// I prefer this method over realloc due to the big inpact on xput realloc may have if
-// memory is being swapped to disk. This approach is safer (although thats not true on any platform)
+// memory is being swapped to disk. This approach is safer (although that may not be true on all platforms)
static
_cmsSubAllocator_chunk* _cmsCreateSubAllocChunk(cmsContext ContextID, cmsUInt32Number Initial)
{
diff --git a/src/cmsio1.c b/src/cmsio1.c
index b235333..f746d81 100644
--- a/src/cmsio1.c
+++ b/src/cmsio1.c
@@ -246,6 +246,25 @@ cmsPipeline* _cmsReadInputLUT(cmsHPROFILE hProfile, int Intent)
cmsTagSignature tagFloat = Device2PCSFloat[Intent];
cmsContext ContextID = cmsGetProfileContextID(hProfile);
+ // On named color, take the appropiate tag
+ if (cmsGetDeviceClass(hProfile) == cmsSigNamedColorClass) {
+
+ cmsPipeline* Lut;
+ cmsNAMEDCOLORLIST* nc = (cmsNAMEDCOLORLIST*) cmsReadTag(hProfile, cmsSigNamedColor2Tag);
+
+ if (nc == NULL) return NULL;
+
+ Lut = cmsPipelineAlloc(ContextID, 0, 0);
+ if (Lut == NULL) {
+ cmsFreeNamedColorList(nc);
+ return NULL;
+ }
+
+ cmsPipelineInsertStage(Lut, cmsAT_BEGIN, _cmsStageAllocNamedColor(nc, TRUE));
+ cmsPipelineInsertStage(Lut, cmsAT_END, _cmsStageAllocLabV2ToV4(ContextID));
+ return Lut;
+ }
+
if (cmsIsTag(hProfile, tagFloat)) { // Float tag takes precedence
// Floating point LUT are always V4, so no adjustment is required
@@ -490,6 +509,27 @@ cmsPipeline* _cmsReadDevicelinkLUT(cmsHPROFILE hProfile, int Intent)
cmsTagSignature tagFloat = Device2PCSFloat[Intent];
cmsContext ContextID = cmsGetProfileContextID(hProfile);
+
+ // On named color, take the appropiate tag
+ if (cmsGetDeviceClass(hProfile) == cmsSigNamedColorClass) {
+
+ cmsPipeline* Lut;
+ cmsNAMEDCOLORLIST* nc = (cmsNAMEDCOLORLIST*) cmsReadTag(hProfile, cmsSigNamedColor2Tag);
+
+ if (nc == NULL) return NULL;
+
+ Lut = cmsPipelineAlloc(ContextID, 0, 0);
+ if (Lut == NULL) {
+ cmsFreeNamedColorList(nc);
+ return NULL;
+ }
+
+ cmsPipelineInsertStage(Lut, cmsAT_BEGIN, _cmsStageAllocNamedColor(nc, FALSE));
+ if (cmsGetColorSpace(hProfile) == cmsSigLabData)
+ cmsPipelineInsertStage(Lut, cmsAT_END, _cmsStageAllocLabV2ToV4(ContextID));
+ return Lut;
+ }
+
if (cmsIsTag(hProfile, tagFloat)) { // Float tag takes precedence
// Floating point LUT are always V4, no adjustment is required
diff --git a/src/cmsnamed.c b/src/cmsnamed.c
index d1a86b6..f4f423d 100644
--- a/src/cmsnamed.c
+++ b/src/cmsnamed.c
@@ -619,6 +619,24 @@ void* DupNamedColorList(cmsStage* mpe)
}
static
+void EvalNamedColorPCS(const cmsFloat32Number In[], cmsFloat32Number Out[], const cmsStage *mpe)
+{
+ cmsNAMEDCOLORLIST* NamedColorList = (cmsNAMEDCOLORLIST*) mpe ->Data;
+ cmsUInt16Number index = (cmsUInt16Number) _cmsQuickSaturateWord(In[0] * 65535.0);
+
+ if (index >= NamedColorList-> nColors) {
+ cmsSignalError(NamedColorList ->ContextID, cmsERROR_RANGE, "Color %d out of range; ignored", index);
+ }
+ else {
+
+ // Named color always uses Lab
+ Out[0] = (cmsFloat32Number) (NamedColorList->List[index].PCS[0] / 65535.0);
+ Out[1] = (cmsFloat32Number) (NamedColorList->List[index].PCS[1] / 65535.0);
+ Out[2] = (cmsFloat32Number) (NamedColorList->List[index].PCS[2] / 65535.0);
+ }
+}
+
+static
void EvalNamedColor(const cmsFloat32Number In[], cmsFloat32Number Out[], const cmsStage *mpe)
{
cmsNAMEDCOLORLIST* NamedColorList = (cmsNAMEDCOLORLIST*) mpe ->Data;
@@ -636,12 +654,12 @@ void EvalNamedColor(const cmsFloat32Number In[], cmsFloat32Number Out[], const c
// Named color lookup element
-cmsStage* _cmsStageAllocNamedColor(cmsNAMEDCOLORLIST* NamedColorList)
+cmsStage* _cmsStageAllocNamedColor(cmsNAMEDCOLORLIST* NamedColorList, cmsBool UsePCS)
{
return _cmsStageAllocPlaceholder(NamedColorList ->ContextID,
cmsSigNamedColorElemType,
- 1, 3,
- EvalNamedColor,
+ 1, UsePCS ? 3 : NamedColorList ->ColorantCount,
+ UsePCS ? EvalNamedColorPCS : EvalNamedColor,
DupNamedColorList,
FreeNamedColorList,
cmsDupNamedColorList(NamedColorList));
diff --git a/src/cmspack.c b/src/cmspack.c
index ae8df4f..c49961f 100644
--- a/src/cmspack.c
+++ b/src/cmspack.c
@@ -1873,7 +1873,7 @@ cmsUInt8Number* PackDoubleFrom16(register _cmsTRANSFORM* Info,
cmsFloat64Number* Inks = (cmsFloat64Number*) output;
int nChan = T_CHANNELS(Info -> OutputFormat);
int i;
- cmsFloat64Number maximum = IsInkSpace(Info ->InputFormat) ? 655.35 : 65535.0;
+ cmsFloat64Number maximum = IsInkSpace(Info ->OutputFormat) ? 655.35 : 65535.0;
if (T_PLANAR(Info -> OutputFormat)) {
diff --git a/src/cmsxform.c b/src/cmsxform.c
index 4e13e1a..e7f30c5 100644
--- a/src/cmsxform.c
+++ b/src/cmsxform.c
@@ -433,6 +433,13 @@ cmsBool GetXFormColorSpaces(int nProfiles, cmsHPROFILE hProfiles[], cmsColorSpac
*Input = PostColorSpace = cmsGetColorSpace(hProfiles[0]);
+ // Special handling for named color profiles as devicelinks
+ if (nProfiles == 1 && cmsGetDeviceClass(hProfiles[0]) == cmsSigNamedColorClass) {
+ *Input = cmsSig1colorData;
+ *Output = PostColorSpace;
+ return TRUE;
+ }
+
for (i=0; i < nProfiles; i++) {
cmsHPROFILE hProfile = hProfiles[i];
@@ -440,9 +447,13 @@ cmsBool GetXFormColorSpaces(int nProfiles, cmsHPROFILE hProfiles[], cmsColorSpac
int lIsInput = (PostColorSpace != cmsSigXYZData) &&
(PostColorSpace != cmsSigLabData);
+ int lIsDeviceLink;
+
if (hProfile == NULL) return FALSE;
- if (lIsInput) {
+ lIsDeviceLink = (cmsGetDeviceClass(hProfile) == cmsSigLinkClass);
+
+ if (lIsInput || lIsDeviceLink) {
ColorSpaceIn = cmsGetColorSpace(hProfile);
ColorSpaceOut = cmsGetPCS(hProfile);
diff --git a/src/lcms2_internal.h b/src/lcms2_internal.h
index cdcba71..872272a 100644
--- a/src/lcms2_internal.h
+++ b/src/lcms2_internal.h
@@ -424,7 +424,7 @@ cmsStage* _cmsStageAllocLabPrelin(cmsContext ContextID);
cmsStage* _cmsStageAllocLabV2ToV4(cmsContext ContextID);
cmsStage* _cmsStageAllocLabV2ToV4curves(cmsContext ContextID);
cmsStage* _cmsStageAllocLabV4ToV2(cmsContext ContextID);
-cmsStage* _cmsStageAllocNamedColor(cmsNAMEDCOLORLIST* NamedColorList);
+cmsStage* _cmsStageAllocNamedColor(cmsNAMEDCOLORLIST* NamedColorList, cmsBool UsePCS);
cmsStage* _cmsStageAllocIdentityCurves(cmsContext ContextID, int nChannels);
cmsStage* _cmsStageAllocIdentityCLut(cmsContext ContextID, int nChan);