56
#include "lcms2_internal.h"
298
_cmsStageCLutData* Pipeline;
311
cmsColorSpaceSignature ColorSpace;
316
static int _cmsPSActualColumn = 0;
321
cmsUInt8Number Word2Byte(cmsUInt16Number w)
323
return (cmsUInt8Number) floor((cmsFloat64Number) w / 257.0 + 0.5);
329
void WriteByte(cmsIOHANDLER* m, cmsUInt8Number b)
331
_cmsIOPrintf(m, "%02x", b);
332
_cmsPSActualColumn += 2;
334
if (_cmsPSActualColumn > MAXPSCOLS) {
336
_cmsIOPrintf(m, "\n");
337
_cmsPSActualColumn = 0;
347
char* RemoveCR(const char* txt)
349
static char Buffer[2048];
352
strncpy(Buffer, txt, 2047);
354
for (pt = Buffer; *pt; pt++)
355
if (*pt == '\n' || *pt == '\r') *pt = ' ';
362
void EmitHeader(cmsIOHANDLER* m, const char* Title, cmsHPROFILE hProfile)
365
cmsMLU *Description, *Copyright;
366
char DescASCII[256], CopyrightASCII[256];
370
Description = (cmsMLU*) cmsReadTag(hProfile, cmsSigProfileDescriptionTag);
371
Copyright = (cmsMLU*) cmsReadTag(hProfile, cmsSigCopyrightTag);
373
DescASCII[0] = DescASCII[255] = 0;
374
CopyrightASCII[0] = CopyrightASCII[255] = 0;
376
if (Description != NULL) cmsMLUgetASCII(Description, cmsNoLanguage, cmsNoCountry, DescASCII, 255);
377
if (Copyright != NULL) cmsMLUgetASCII(Copyright, cmsNoLanguage, cmsNoCountry, CopyrightASCII, 255);
379
_cmsIOPrintf(m, "%%!PS-Adobe-3.0\n");
380
_cmsIOPrintf(m, "%%\n");
381
_cmsIOPrintf(m, "%% %s\n", Title);
382
_cmsIOPrintf(m, "%% Source: %s\n", RemoveCR(DescASCII));
383
_cmsIOPrintf(m, "%% %s\n", RemoveCR(CopyrightASCII));
384
_cmsIOPrintf(m, "%% Created: %s", ctime(&timer));
385
_cmsIOPrintf(m, "%%\n");
386
_cmsIOPrintf(m, "%%%%BeginResource\n");
395
void EmitWhiteBlackD50(cmsIOHANDLER* m, cmsCIEXYZ* BlackPoint)
398
_cmsIOPrintf(m, "/BlackPoint [%f %f %f]\n", BlackPoint -> X,
402
_cmsIOPrintf(m, "/WhitePoint [%f %f %f]\n", cmsD50_XYZ()->X,
409
void EmitRangeCheck(cmsIOHANDLER* m)
411
_cmsIOPrintf(m, "dup 0.0 lt { pop 0.0 } if "
412
"dup 1.0 gt { pop 1.0 } if ");
419
void EmitIntent(cmsIOHANDLER* m, cmsUInt32Number RenderingIntent)
423
switch (RenderingIntent) {
425
case INTENT_PERCEPTUAL: intent = "Perceptual"; break;
426
case INTENT_RELATIVE_COLORIMETRIC: intent = "RelativeColorimetric"; break;
427
case INTENT_ABSOLUTE_COLORIMETRIC: intent = "AbsoluteColorimetric"; break;
428
case INTENT_SATURATION: intent = "Saturation"; break;
430
default: intent = "Undefined"; break;
433
_cmsIOPrintf(m, "/RenderingIntent (%s)\n", intent );
446
void EmitLab2XYZ(cmsIOHANDLER* m)
448
_cmsIOPrintf(m, "/RangeABC [ 0 1 0 1 0 1]\n");
449
_cmsIOPrintf(m, "/DecodeABC [\n");
450
_cmsIOPrintf(m, "{100 mul 16 add 116 div } bind\n");
451
_cmsIOPrintf(m, "{255 mul 128 sub 500 div } bind\n");
452
_cmsIOPrintf(m, "{255 mul 128 sub 200 div } bind\n");
453
_cmsIOPrintf(m, "]\n");
454
_cmsIOPrintf(m, "/MatrixABC [ 1 1 1 1 0 0 0 0 -1]\n");
455
_cmsIOPrintf(m, "/RangeLMN [ -0.236 1.254 0 1 -0.635 1.640 ]\n");
456
_cmsIOPrintf(m, "/DecodeLMN [\n");
457
_cmsIOPrintf(m, "{dup 6 29 div ge {dup dup mul mul} {4 29 div sub 108 841 div mul} ifelse 0.964200 mul} bind\n");
458
_cmsIOPrintf(m, "{dup 6 29 div ge {dup dup mul mul} {4 29 div sub 108 841 div mul} ifelse } bind\n");
459
_cmsIOPrintf(m, "{dup 6 29 div ge {dup dup mul mul} {4 29 div sub 108 841 div mul} ifelse 0.824900 mul} bind\n");
460
_cmsIOPrintf(m, "]\n");
468
void Emit1Gamma(cmsIOHANDLER* m, cmsToneCurve* Table)
471
cmsFloat64Number gamma;
477
Table->nEntries <= 0 ||
478
cmsIsToneCurveLinear(Table)) {
480
_cmsIOPrintf(m, "{ 1 } bind ");
486
gamma = cmsEstimateGamma(Table, 0.001);
488
_cmsIOPrintf(m, "{ %g exp } bind ", gamma);
492
_cmsIOPrintf(m, "{ ");
502
_cmsIOPrintf(m, " [");
504
for (i=0; i < Table->nEntries; i++) {
506
_cmsIOPrintf(m, "\n ");
507
_cmsIOPrintf(m, "%d ", Table->Table16[i]);
510
_cmsIOPrintf(m, "] ");
512
_cmsIOPrintf(m, "dup ");
513
_cmsIOPrintf(m, "length 1 sub ");
514
_cmsIOPrintf(m, "3 -1 roll ");
515
_cmsIOPrintf(m, "mul ");
516
_cmsIOPrintf(m, "dup ");
517
_cmsIOPrintf(m, "dup ");
518
_cmsIOPrintf(m, "floor cvi ");
519
_cmsIOPrintf(m, "exch ");
520
_cmsIOPrintf(m, "ceiling cvi ");
521
_cmsIOPrintf(m, "3 index ");
522
_cmsIOPrintf(m, "exch ");
523
_cmsIOPrintf(m, "get\n ");
524
_cmsIOPrintf(m, "4 -1 roll ");
525
_cmsIOPrintf(m, "3 -1 roll ");
526
_cmsIOPrintf(m, "get ");
527
_cmsIOPrintf(m, "dup ");
528
_cmsIOPrintf(m, "3 1 roll ");
529
_cmsIOPrintf(m, "sub ");
530
_cmsIOPrintf(m, "3 -1 roll ");
531
_cmsIOPrintf(m, "dup ");
532
_cmsIOPrintf(m, "floor cvi ");
533
_cmsIOPrintf(m, "sub ");
534
_cmsIOPrintf(m, "mul ");
535
_cmsIOPrintf(m, "add ");
536
_cmsIOPrintf(m, "65535 div\n");
538
_cmsIOPrintf(m, " } bind ");
545
cmsBool GammaTableEquals(cmsUInt16Number* g1, cmsUInt16Number* g2, cmsUInt32Number nG1, cmsUInt32Number nG2)
547
if (nG1 != nG2) return FALSE;
548
return memcmp(g1, g2, nG1 * sizeof(cmsUInt16Number)) == 0;
555
void EmitNGamma(cmsIOHANDLER* m, cmsUInt32Number n, cmsToneCurve* g[])
560
for( i=0; i < n; i++ )
562
if (g[i] == NULL) return;
564
if (i > 0 && GammaTableEquals(g[i-1]->Table16, g[i]->Table16, g[i-1]->nEntries, g[i]->nEntries)) {
566
_cmsIOPrintf(m, "dup ");
592
int OutputValueSampler(CMSREGISTER const cmsUInt16Number In[], CMSREGISTER cmsUInt16Number Out[], CMSREGISTER void* Cargo)
594
cmsPsSamplerCargo* sc = (cmsPsSamplerCargo*) Cargo;
598
if (sc -> FixWhite) {
600
if (In[0] == 0xFFFF) {
602
if ((In[1] >= 0x7800 && In[1] <= 0x8800) &&
603
(In[2] >= 0x7800 && In[2] <= 0x8800)) {
605
cmsUInt16Number* Black;
606
cmsUInt16Number* White;
607
cmsUInt32Number nOutputs;
609
if (!_cmsEndPointsBySpace(sc ->ColorSpace, &White, &Black, &nOutputs))
612
for (i=0; i < nOutputs; i++)
623
if (In[0] != sc ->FirstComponent) {
625
if (sc ->FirstComponent != -1) {
627
_cmsIOPrintf(sc ->m, sc ->PostMin);
628
sc ->SecondComponent = -1;
629
_cmsIOPrintf(sc ->m, sc ->PostMaj);
633
_cmsPSActualColumn = 0;
635
_cmsIOPrintf(sc ->m, sc ->PreMaj);
636
sc ->FirstComponent = In[0];
640
if (In[1] != sc ->SecondComponent) {
642
if (sc ->SecondComponent != -1) {
644
_cmsIOPrintf(sc ->m, sc ->PostMin);
647
_cmsIOPrintf(sc ->m, sc ->PreMin);
648
sc ->SecondComponent = In[1];
653
for (i=0; i < sc -> Pipeline ->Params->nOutputs; i++) {
655
cmsUInt16Number wWordOut = Out[i];
656
cmsUInt8Number wByteOut;
661
wByteOut = Word2Byte(wWordOut);
662
WriteByte(sc -> m, wByteOut);
671
void WriteCLUT(cmsIOHANDLER* m, cmsStage* mpe, const char* PreMaj,
676
cmsColorSpaceSignature ColorSpace)
679
cmsPsSamplerCargo sc;
681
sc.FirstComponent = -1;
682
sc.SecondComponent = -1;
683
sc.Pipeline = (_cmsStageCLutData *) mpe ->Data;
689
sc.PostMin = PostMin;
690
sc.FixWhite = FixWhite;
691
sc.ColorSpace = ColorSpace;
693
if (sc.Pipeline != NULL && sc.Pipeline->Params != NULL) {
695
_cmsIOPrintf(m, "[");
697
for (i = 0; i < sc.Pipeline->Params->nInputs; i++)
698
_cmsIOPrintf(m, " %d ", sc.Pipeline->Params->nSamples[i]);
700
_cmsIOPrintf(m, " [\n");
702
cmsStageSampleCLut16bit(mpe, OutputValueSampler, (void*)&sc, SAMPLER_INSPECT);
704
_cmsIOPrintf(m, PostMin);
705
_cmsIOPrintf(m, PostMaj);
706
_cmsIOPrintf(m, "] ");
715
int EmitCIEBasedA(cmsIOHANDLER* m, cmsToneCurve* Curve, cmsCIEXYZ* BlackPoint)
718
_cmsIOPrintf(m, "[ /CIEBasedA\n");
719
_cmsIOPrintf(m, " <<\n");
721
_cmsIOPrintf(m, "/DecodeA ");
723
Emit1Gamma(m, Curve);
725
_cmsIOPrintf(m, " \n");
727
_cmsIOPrintf(m, "/MatrixA [ 0.9642 1.0000 0.8249 ]\n");
728
_cmsIOPrintf(m, "/RangeLMN [ 0.0 0.9642 0.0 1.0000 0.0 0.8249 ]\n");
730
EmitWhiteBlackD50(m, BlackPoint);
731
EmitIntent(m, INTENT_PERCEPTUAL);
733
_cmsIOPrintf(m, ">>\n");
734
_cmsIOPrintf(m, "]\n");
743
int EmitCIEBasedABC(cmsIOHANDLER* m, cmsFloat64Number* Matrix, cmsToneCurve** CurveSet, cmsCIEXYZ* BlackPoint)
747
_cmsIOPrintf(m, "[ /CIEBasedABC\n");
748
_cmsIOPrintf(m, "<<\n");
749
_cmsIOPrintf(m, "/DecodeABC [ ");
751
EmitNGamma(m, 3, CurveSet);
753
_cmsIOPrintf(m, "]\n");
755
_cmsIOPrintf(m, "/MatrixABC [ " );
757
for( i=0; i < 3; i++ ) {
759
_cmsIOPrintf(m, "%.6f %.6f %.6f ", Matrix[i + 3*0],
765
_cmsIOPrintf(m, "]\n");
767
_cmsIOPrintf(m, "/RangeLMN [ 0.0 0.9642 0.0 1.0000 0.0 0.8249 ]\n");
769
EmitWhiteBlackD50(m, BlackPoint);
770
EmitIntent(m, INTENT_PERCEPTUAL);
772
_cmsIOPrintf(m, ">>\n");
773
_cmsIOPrintf(m, "]\n");
781
int EmitCIEBasedDEF(cmsIOHANDLER* m, cmsPipeline* Pipeline, cmsUInt32Number Intent, cmsCIEXYZ* BlackPoint)
785
const char* PreMin, *PostMin;
788
mpe = Pipeline->Elements;
790
switch (cmsStageInputChannels(mpe)) {
792
_cmsIOPrintf(m, "[ /CIEBasedDEF\n");
795
PreMin = PostMin = "";
799
_cmsIOPrintf(m, "[ /CIEBasedDEFG\n");
811
_cmsIOPrintf(m, "<<\n");
813
if (cmsStageType(mpe) == cmsSigCurveSetElemType) {
815
_cmsIOPrintf(m, "/DecodeDEF [ ");
816
EmitNGamma(m, cmsStageOutputChannels(mpe), _cmsStageGetPtrToCurveSet(mpe));
817
_cmsIOPrintf(m, "]\n");
822
if (cmsStageType(mpe) == cmsSigCLutElemType) {
824
_cmsIOPrintf(m, "/Table ");
825
WriteCLUT(m, mpe, PreMaj, PostMaj, PreMin, PostMin, FALSE, (cmsColorSpaceSignature) 0);
826
_cmsIOPrintf(m, "]\n");
830
EmitWhiteBlackD50(m, BlackPoint);
831
EmitIntent(m, Intent);
833
_cmsIOPrintf(m, " >>\n");
834
_cmsIOPrintf(m, "]\n");
842
cmsToneCurve* ExtractGray2Y(cmsContext ContextID, cmsHPROFILE hProfile, cmsUInt32Number Intent)
844
cmsToneCurve* Out = cmsBuildTabulatedToneCurve16(ContextID, 256, NULL);
845
cmsHPROFILE hXYZ = cmsCreateXYZProfile();
846
cmsHTRANSFORM xform = cmsCreateTransformTHR(ContextID, hProfile, TYPE_GRAY_8, hXYZ, TYPE_XYZ_DBL, Intent, cmsFLAGS_NOOPTIMIZE);
849
if (Out != NULL && xform != NULL) {
850
for (i=0; i < 256; i++) {
852
cmsUInt8Number Gray = (cmsUInt8Number) i;
855
cmsDoTransform(xform, &Gray, &XYZ, 1);
857
Out ->Table16[i] =_cmsQuickSaturateWord(XYZ.Y * 65535.0);
861
if (xform) cmsDeleteTransform(xform);
862
if (hXYZ) cmsCloseProfile(hXYZ);
872
int WriteInputLUT(cmsIOHANDLER* m, cmsHPROFILE hProfile, cmsUInt32Number Intent, cmsUInt32Number dwFlags)
876
cmsUInt32Number nChannels;
877
cmsUInt32Number InputFormat;
879
cmsHPROFILE Profiles[2];
880
cmsCIEXYZ BlackPointAdaptedToD50;
885
InputFormat = cmsFormatterForColorspaceOfProfile(hProfile, 2, FALSE);
886
nChannels = T_CHANNELS(InputFormat);
889
cmsDetectBlackPoint(&BlackPointAdaptedToD50, hProfile, Intent, 0);
892
hLab = cmsCreateLab4ProfileTHR(m ->ContextID, NULL);
894
Profiles[0] = hProfile;
897
xform = cmsCreateMultiprofileTransform(Profiles, 2, InputFormat, TYPE_Lab_DBL, Intent, 0);
898
cmsCloseProfile(hLab);
902
cmsSignalError(m ->ContextID, cmsERROR_COLORSPACE_CHECK, "Cannot create transform Profile -> Lab");
911
cmsToneCurve* Gray2Y = ExtractGray2Y(m ->ContextID, hProfile, Intent);
912
EmitCIEBasedA(m, Gray2Y, &BlackPointAdaptedToD50);
913
cmsFreeToneCurve(Gray2Y);
919
cmsUInt32Number OutFrm = TYPE_Lab_16;
920
cmsPipeline* DeviceLink;
921
_cmsTRANSFORM* v = (_cmsTRANSFORM*) xform;
923
DeviceLink = cmsPipelineDup(v ->Lut);
924
if (DeviceLink == NULL) return 0;
926
dwFlags |= cmsFLAGS_FORCE_CLUT;
927
_cmsOptimizePipeline(m->ContextID, &DeviceLink, Intent, &InputFormat, &OutFrm, &dwFlags);
929
rc = EmitCIEBasedDEF(m, DeviceLink, Intent, &BlackPointAdaptedToD50);
930
cmsPipelineFree(DeviceLink);
931
if (rc == 0) return 0;
937
cmsSignalError(m ->ContextID, cmsERROR_COLORSPACE_CHECK, "Only 3, 4 channels are supported for CSA. This profile has %d channels.", nChannels);
942
cmsDeleteTransform(xform);
948
cmsFloat64Number* GetPtrToMatrix(const cmsStage* mpe)
950
_cmsStageMatrixData* Data = (_cmsStageMatrixData*) mpe ->Data;
952
return Data -> Double;
958
int WriteInputMatrixShaper(cmsIOHANDLER* m, cmsHPROFILE hProfile, cmsStage* Matrix, cmsStage* Shaper)
960
cmsColorSpaceSignature ColorSpace;
962
cmsCIEXYZ BlackPointAdaptedToD50;
964
ColorSpace = cmsGetColorSpace(hProfile);
966
cmsDetectBlackPoint(&BlackPointAdaptedToD50, hProfile, INTENT_RELATIVE_COLORIMETRIC, 0);
968
if (ColorSpace == cmsSigGrayData) {
970
cmsToneCurve** ShaperCurve = _cmsStageGetPtrToCurveSet(Shaper);
971
rc = EmitCIEBasedA(m, ShaperCurve[0], &BlackPointAdaptedToD50);
975
if (ColorSpace == cmsSigRgbData) {
980
memmove(&Mat, GetPtrToMatrix(Matrix), sizeof(Mat));
982
for (i = 0; i < 3; i++)
983
for (j = 0; j < 3; j++)
984
Mat.v[i].n[j] *= MAX_ENCODEABLE_XYZ;
986
rc = EmitCIEBasedABC(m, (cmsFloat64Number *) &Mat,
987
_cmsStageGetPtrToCurveSet(Shaper),
988
&BlackPointAdaptedToD50);
992
cmsSignalError(m->ContextID, cmsERROR_COLORSPACE_CHECK, "Profile is not suitable for CSA. Unsupported colorspace.");
1005
int WriteNamedColorCSA(cmsIOHANDLER* m, cmsHPROFILE hNamedColor, cmsUInt32Number Intent)
1007
cmsHTRANSFORM xform;
1009
cmsUInt32Number i, nColors;
1010
char ColorName[cmsMAX_PATH];
1011
cmsNAMEDCOLORLIST* NamedColorList;
1013
hLab = cmsCreateLab4ProfileTHR(m ->ContextID, NULL);
1014
xform = cmsCreateTransform(hNamedColor, TYPE_NAMED_COLOR_INDEX, hLab, TYPE_Lab_DBL, Intent, 0);
1015
cmsCloseProfile(hLab);
1017
if (xform == NULL) return 0;
1019
NamedColorList = cmsGetNamedColorList(xform);
1020
if (NamedColorList == NULL) {
1021
cmsDeleteTransform(xform);
1025
_cmsIOPrintf(m, "<<\n");
1026
_cmsIOPrintf(m, "(colorlistcomment) (%s)\n", "Named color CSA");
1027
_cmsIOPrintf(m, "(Prefix) [ (Pantone ) (PANTONE ) ]\n");
1028
_cmsIOPrintf(m, "(Suffix) [ ( CV) ( CVC) ( C) ]\n");
1030
nColors = cmsNamedColorCount(NamedColorList);
1032
for (i=0; i < nColors; i++) {
1034
cmsUInt16Number In[1];
1037
In[0] = (cmsUInt16Number) i;
1039
if (!cmsNamedColorInfo(NamedColorList, i, ColorName, NULL, NULL, NULL, NULL))
1042
cmsDoTransform(xform, In, &Lab, 1);
1043
_cmsIOPrintf(m, " (%s) [ %.3f %.3f %.3f ]\n", ColorName, Lab.L, Lab.a, Lab.b);
1046
_cmsIOPrintf(m, ">>\n");
1048
cmsDeleteTransform(xform);
1055
cmsUInt32Number GenerateCSA(cmsContext ContextID,
1056
cmsHPROFILE hProfile,
1057
cmsUInt32Number Intent,
1058
cmsUInt32Number dwFlags,
1061
cmsUInt32Number dwBytesUsed;
1062
cmsPipeline* lut = NULL;
1063
cmsStage* Matrix, *Shaper;
1067
if (cmsGetDeviceClass(hProfile) == cmsSigNamedColorClass) {
1069
if (!WriteNamedColorCSA(mem, hProfile, Intent)) goto Error;
1076
cmsColorSpaceSignature ColorSpace = cmsGetPCS(hProfile);
1078
if (ColorSpace != cmsSigXYZData &&
1079
ColorSpace != cmsSigLabData) {
1081
cmsSignalError(ContextID, cmsERROR_COLORSPACE_CHECK, "Invalid output color space");
1087
lut = _cmsReadInputLUT(hProfile, Intent);
1088
if (lut == NULL) goto Error;
1092
if (cmsPipelineCheckAndRetreiveStages(lut, 2, cmsSigCurveSetElemType, cmsSigMatrixElemType, &Shaper, &Matrix)) {
1094
if (!WriteInputMatrixShaper(mem, hProfile, Matrix, Shaper)) goto Error;
1099
if (!WriteInputLUT(mem, hProfile, Intent, dwFlags)) goto Error;
1105
dwBytesUsed = mem ->UsedSpace;
1108
if (lut != NULL) cmsPipelineFree(lut);
1114
if (lut != NULL) cmsPipelineFree(lut);
1185
void EmitPQRStage(cmsIOHANDLER* m, cmsHPROFILE hProfile, int DoBPC, int lIsAbsolute)
1198
_cmsReadMediaWhitePoint(&White, hProfile);
1200
_cmsIOPrintf(m,"/MatrixPQR [1 0 0 0 1 0 0 0 1 ]\n");
1201
_cmsIOPrintf(m,"/RangePQR [ -0.5 2 -0.5 2 -0.5 2 ]\n");
1203
_cmsIOPrintf(m, "%% Absolute colorimetric -- encode to relative to maximize LUT usage\n"
1205
"{0.9642 mul %g div exch pop exch pop exch pop exch pop} bind\n"
1206
"{1.0000 mul %g div exch pop exch pop exch pop exch pop} bind\n"
1207
"{0.8249 mul %g div exch pop exch pop exch pop exch pop} bind\n]\n",
1208
White.X, White.Y, White.Z);
1213
_cmsIOPrintf(m,"%% Bradford Cone Space\n"
1214
"/MatrixPQR [0.8951 -0.7502 0.0389 0.2664 1.7135 -0.0685 -0.1614 0.0367 1.0296 ] \n");
1216
_cmsIOPrintf(m, "/RangePQR [ -0.5 2 -0.5 2 -0.5 2 ]\n");
1223
_cmsIOPrintf(m, "%% VonKries-like transform in Bradford Cone Space\n"
1225
"{exch pop exch 3 get mul exch pop exch 3 get div} bind\n"
1226
"{exch pop exch 4 get mul exch pop exch 4 get div} bind\n"
1227
"{exch pop exch 5 get mul exch pop exch 5 get div} bind\n]\n");
1232
_cmsIOPrintf(m, "%% VonKries-like transform in Bradford Cone Space plus BPC\n"
1233
"/TransformPQR [\n");
1235
_cmsIOPrintf(m, "{4 index 3 get div 2 index 3 get mul "
1236
"2 index 3 get 2 index 3 get sub mul "
1237
"2 index 3 get 4 index 3 get 3 index 3 get sub mul sub "
1238
"3 index 3 get 3 index 3 get exch sub div "
1239
"exch pop exch pop exch pop exch pop } bind\n");
1241
_cmsIOPrintf(m, "{4 index 4 get div 2 index 4 get mul "
1242
"2 index 4 get 2 index 4 get sub mul "
1243
"2 index 4 get 4 index 4 get 3 index 4 get sub mul sub "
1244
"3 index 4 get 3 index 4 get exch sub div "
1245
"exch pop exch pop exch pop exch pop } bind\n");
1247
_cmsIOPrintf(m, "{4 index 5 get div 2 index 5 get mul "
1248
"2 index 5 get 2 index 5 get sub mul "
1249
"2 index 5 get 4 index 5 get 3 index 5 get sub mul sub "
1250
"3 index 5 get 3 index 5 get exch sub div "
1251
"exch pop exch pop exch pop exch pop } bind\n]\n");
1258
void EmitXYZ2Lab(cmsIOHANDLER* m)
1260
_cmsIOPrintf(m, "/RangeLMN [ -0.635 2.0 0 2 -0.635 2.0 ]\n");
1261
_cmsIOPrintf(m, "/EncodeLMN [\n");
1262
_cmsIOPrintf(m, "{ 0.964200 div dup 0.008856 le {7.787 mul 16 116 div add}{1 3 div exp} ifelse } bind\n");
1263
_cmsIOPrintf(m, "{ 1.000000 div dup 0.008856 le {7.787 mul 16 116 div add}{1 3 div exp} ifelse } bind\n");
1264
_cmsIOPrintf(m, "{ 0.824900 div dup 0.008856 le {7.787 mul 16 116 div add}{1 3 div exp} ifelse } bind\n");
1265
_cmsIOPrintf(m, "]\n");
1266
_cmsIOPrintf(m, "/MatrixABC [ 0 1 0 1 -1 1 0 0 -1 ]\n");
1267
_cmsIOPrintf(m, "/EncodeABC [\n");
1270
_cmsIOPrintf(m, "{ 116 mul 16 sub 100 div } bind\n");
1271
_cmsIOPrintf(m, "{ 500 mul 128 add 256 div } bind\n");
1272
_cmsIOPrintf(m, "{ 200 mul 128 add 256 div } bind\n");
1275
_cmsIOPrintf(m, "]\n");
1287
int WriteOutputLUT(cmsIOHANDLER* m, cmsHPROFILE hProfile, cmsUInt32Number Intent, cmsUInt32Number dwFlags)
1290
cmsHTRANSFORM xform;
1291
cmsUInt32Number i, nChannels;
1292
cmsUInt32Number OutputFormat;
1294
cmsPipeline* DeviceLink;
1295
cmsHPROFILE Profiles[3];
1296
cmsCIEXYZ BlackPointAdaptedToD50;
1297
cmsBool lDoBPC = (cmsBool) (dwFlags & cmsFLAGS_BLACKPOINTCOMPENSATION);
1298
cmsBool lFixWhite = (cmsBool) !(dwFlags & cmsFLAGS_NOWHITEONWHITEFIXUP);
1299
cmsUInt32Number InFrm = TYPE_Lab_16;
1300
cmsUInt32Number RelativeEncodingIntent;
1301
cmsColorSpaceSignature ColorSpace;
1304
hLab = cmsCreateLab4ProfileTHR(m ->ContextID, NULL);
1305
if (hLab == NULL) return 0;
1307
OutputFormat = cmsFormatterForColorspaceOfProfile(hProfile, 2, FALSE);
1308
nChannels = T_CHANNELS(OutputFormat);
1310
ColorSpace = cmsGetColorSpace(hProfile);
1314
RelativeEncodingIntent = Intent;
1315
if (RelativeEncodingIntent == INTENT_ABSOLUTE_COLORIMETRIC)
1316
RelativeEncodingIntent = INTENT_RELATIVE_COLORIMETRIC;
1321
Profiles[1] = hProfile;
1323
xform = cmsCreateMultiprofileTransformTHR(m ->ContextID,
1324
Profiles, 2, TYPE_Lab_DBL,
1325
OutputFormat, RelativeEncodingIntent, 0);
1326
cmsCloseProfile(hLab);
1328
if (xform == NULL) {
1329
cmsSignalError(m ->ContextID, cmsERROR_COLORSPACE_CHECK, "Cannot create transform Lab -> Profile in CRD creation");
1334
v = (_cmsTRANSFORM*) xform;
1335
DeviceLink = cmsPipelineDup(v ->Lut);
1336
if (DeviceLink == NULL) {
1337
cmsDeleteTransform(xform);
1342
dwFlags |= cmsFLAGS_FORCE_CLUT;
1343
_cmsOptimizePipeline(m->ContextID, &DeviceLink, RelativeEncodingIntent, &InFrm, &OutputFormat, &dwFlags);
1345
_cmsIOPrintf(m, "<<\n");
1346
_cmsIOPrintf(m, "/ColorRenderingType 1\n");
1349
cmsDetectBlackPoint(&BlackPointAdaptedToD50, hProfile, Intent, 0);
1352
EmitWhiteBlackD50(m, &BlackPointAdaptedToD50);
1353
EmitPQRStage(m, hProfile, lDoBPC, Intent == INTENT_ABSOLUTE_COLORIMETRIC);
1363
if (Intent == INTENT_ABSOLUTE_COLORIMETRIC)
1366
_cmsIOPrintf(m, "/RenderTable ");
1368
first = cmsPipelineGetPtrToFirstStage(DeviceLink);
1369
if (first != NULL) {
1370
WriteCLUT(m, first, "<", ">\n", "", "", lFixWhite, ColorSpace);
1373
_cmsIOPrintf(m, " %d {} bind ", nChannels);
1375
for (i=1; i < nChannels; i++)
1376
_cmsIOPrintf(m, "dup ");
1378
_cmsIOPrintf(m, "]\n");
1380
EmitIntent(m, Intent);
1382
_cmsIOPrintf(m, ">>\n");
1384
if (!(dwFlags & cmsFLAGS_NODEFAULTRESOURCEDEF)) {
1386
_cmsIOPrintf(m, "/Current exch /ColorRendering defineresource pop\n");
1389
cmsPipelineFree(DeviceLink);
1390
cmsDeleteTransform(xform);
1398
void BuildColorantList(char *Colorant, cmsUInt32Number nColorant, cmsUInt16Number Out[])
1404
if (nColorant > cmsMAXCHANNELS)
1405
nColorant = cmsMAXCHANNELS;
1407
for (j = 0; j < nColorant; j++) {
1409
snprintf(Buff, 31, "%.3f", Out[j] / 65535.0);
1411
strcat(Colorant, Buff);
1412
if (j < nColorant - 1)
1413
strcat(Colorant, " ");
1423
int WriteNamedColorCRD(cmsIOHANDLER* m, cmsHPROFILE hNamedColor, cmsUInt32Number Intent, cmsUInt32Number dwFlags)
1425
cmsHTRANSFORM xform;
1426
cmsUInt32Number i, nColors, nColorant;
1427
cmsUInt32Number OutputFormat;
1428
char ColorName[cmsMAX_PATH];
1430
cmsNAMEDCOLORLIST* NamedColorList;
1433
OutputFormat = cmsFormatterForColorspaceOfProfile(hNamedColor, 2, FALSE);
1434
nColorant = T_CHANNELS(OutputFormat);
1437
xform = cmsCreateTransform(hNamedColor, TYPE_NAMED_COLOR_INDEX, NULL, OutputFormat, Intent, dwFlags);
1438
if (xform == NULL) return 0;
1441
NamedColorList = cmsGetNamedColorList(xform);
1442
if (NamedColorList == NULL) {
1443
cmsDeleteTransform(xform);
1447
_cmsIOPrintf(m, "<<\n");
1448
_cmsIOPrintf(m, "(colorlistcomment) (%s) \n", "Named profile");
1449
_cmsIOPrintf(m, "(Prefix) [ (Pantone ) (PANTONE ) ]\n");
1450
_cmsIOPrintf(m, "(Suffix) [ ( CV) ( CVC) ( C) ]\n");
1452
nColors = cmsNamedColorCount(NamedColorList);
1454
for (i=0; i < nColors; i++) {
1456
cmsUInt16Number In[1];
1457
cmsUInt16Number Out[cmsMAXCHANNELS];
1459
In[0] = (cmsUInt16Number) i;
1461
if (!cmsNamedColorInfo(NamedColorList, i, ColorName, NULL, NULL, NULL, NULL))
1464
cmsDoTransform(xform, In, Out, 1);
1465
BuildColorantList(Colorant, nColorant, Out);
1466
_cmsIOPrintf(m, " (%s) [ %s ]\n", ColorName, Colorant);
1469
_cmsIOPrintf(m, " >>");
1471
if (!(dwFlags & cmsFLAGS_NODEFAULTRESOURCEDEF)) {
1473
_cmsIOPrintf(m, " /Current exch /HPSpotTable defineresource pop\n");
1476
cmsDeleteTransform(xform);
1487
cmsUInt32Number GenerateCRD(cmsContext ContextID,
1488
cmsHPROFILE hProfile,
1489
cmsUInt32Number Intent, cmsUInt32Number dwFlags,
1492
cmsUInt32Number dwBytesUsed;
1494
if (!(dwFlags & cmsFLAGS_NODEFAULTRESOURCEDEF)) {
1496
EmitHeader(mem, "Color Rendering Dictionary (CRD)", hProfile);
1501
if (cmsGetDeviceClass(hProfile) == cmsSigNamedColorClass) {
1503
if (!WriteNamedColorCRD(mem, hProfile, Intent, dwFlags)) {
1511
if (!WriteOutputLUT(mem, hProfile, Intent, dwFlags)) {
1516
if (!(dwFlags & cmsFLAGS_NODEFAULTRESOURCEDEF)) {
1518
_cmsIOPrintf(mem, "%%%%EndResource\n");
1519
_cmsIOPrintf(mem, "\n%% CRD End\n");
1523
dwBytesUsed = mem ->UsedSpace;
1528
cmsUNUSED_PARAMETER(ContextID);
1534
cmsUInt32Number CMSEXPORT cmsGetPostScriptColorResource(cmsContext ContextID,
1535
cmsPSResourceType Type,
1536
cmsHPROFILE hProfile,
1537
cmsUInt32Number Intent,
1538
cmsUInt32Number dwFlags,
1546
case cmsPS_RESOURCE_CSA:
1547
rc = GenerateCSA(ContextID, hProfile, Intent, dwFlags, io);
1551
case cmsPS_RESOURCE_CRD:
1552
rc = GenerateCRD(ContextID, hProfile, Intent, dwFlags, io);
1561
cmsUInt32Number CMSEXPORT cmsGetPostScriptCRD(cmsContext ContextID,
1562
cmsHPROFILE hProfile,
1563
cmsUInt32Number Intent, cmsUInt32Number dwFlags,
1564
void* Buffer, cmsUInt32Number dwBufferLen)
1567
cmsUInt32Number dwBytesUsed;
1571
mem = cmsOpenIOhandlerFromNULL(ContextID);
1573
mem = cmsOpenIOhandlerFromMem(ContextID, Buffer, dwBufferLen, "w");
1577
dwBytesUsed = cmsGetPostScriptColorResource(ContextID, cmsPS_RESOURCE_CRD, hProfile, Intent, dwFlags, mem);
1580
cmsCloseIOhandler(mem);
1588
cmsUInt32Number CMSEXPORT cmsGetPostScriptCSA(cmsContext ContextID,
1589
cmsHPROFILE hProfile,
1590
cmsUInt32Number Intent,
1591
cmsUInt32Number dwFlags,
1593
cmsUInt32Number dwBufferLen)
1596
cmsUInt32Number dwBytesUsed;
1599
mem = cmsOpenIOhandlerFromNULL(ContextID);
1601
mem = cmsOpenIOhandlerFromMem(ContextID, Buffer, dwBufferLen, "w");
1605
dwBytesUsed = cmsGetPostScriptColorResource(ContextID, cmsPS_RESOURCE_CSA, hProfile, Intent, dwFlags, mem);
1608
cmsCloseIOhandler(mem);