diff options
author | Marti Maria <info@littlecms.com> | 2011-04-12 15:48:03 +0200 |
---|---|---|
committer | Marti Maria <info@littlecms.com> | 2011-04-12 15:48:03 +0200 |
commit | 97f22bda885166a18e346db8dd24bd66bc4615cd (patch) | |
tree | df399bb7e3db23ae02b8a0b01262fe5041f6c783 /src | |
parent | b735a01cd82f08ef46733c9f19eb08ba1a6623af (diff) | |
download | lcms2-97f22bda885166a18e346db8dd24bd66bc4615cd.tar.gz |
Added named color functionality
Diffstat (limited to 'src')
-rw-r--r-- | src/cmscnvrt.c | 4 | ||||
-rw-r--r-- | src/cmserr.c | 2 | ||||
-rw-r--r-- | src/cmsio1.c | 40 | ||||
-rw-r--r-- | src/cmsnamed.c | 24 | ||||
-rw-r--r-- | src/cmspack.c | 2 | ||||
-rw-r--r-- | src/cmsxform.c | 13 | ||||
-rw-r--r-- | src/lcms2_internal.h | 2 |
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); |