< prev index next >

src/java.desktop/share/native/liblcms/cmscnvrt.c

Print this page

 246     s.n[VX] = cmsD50_XYZ() -> X;
 247     s.n[VY] = cmsD50_XYZ() -> Y;
 248     s.n[VZ] = cmsD50_XYZ() -> Z;
 249 
 250     _cmsMAT3eval(&d, &m2, &s);
 251 
 252     Dest.X = d.n[VX];
 253     Dest.Y = d.n[VY];
 254     Dest.Z = d.n[VZ];
 255 
 256     cmsXYZ2xyY(&DestChromaticity, &Dest);
 257 
 258     if (!cmsTempFromWhitePoint(&TempK, &DestChromaticity))
 259         return -1.0;
 260 
 261     return TempK;
 262 }
 263 
 264 // Compute a CHAD based on a given temperature
 265 static
 266     void Temp2CHAD(cmsMAT3* Chad, cmsFloat64Number Temp)
 267 {
 268     cmsCIEXYZ White;
 269     cmsCIExyY ChromaticityOfWhite;
 270 
 271     cmsWhitePointFromTemp(&ChromaticityOfWhite, Temp);
 272     cmsxyY2XYZ(&White, &ChromaticityOfWhite);
 273     _cmsAdaptationMatrix(Chad, NULL, &White, cmsD50_XYZ());
 274 }
 275 
 276 // Join scalings to obtain relative input to absolute and then to relative output.
 277 // Result is stored in a 3x3 matrix
 278 static
 279 cmsBool  ComputeAbsoluteIntent(cmsFloat64Number AdaptationState,
 280                                const cmsCIEXYZ* WhitePointIn,
 281                                const cmsMAT3* ChromaticAdaptationMatrixIn,
 282                                const cmsCIEXYZ* WhitePointOut,
 283                                const cmsMAT3* ChromaticAdaptationMatrixOut,
 284                                cmsMAT3* m)
 285 {
 286     cmsMAT3 Scale, m1, m2, m3, m4;

 727 // Preserve black only if that is the only ink used
 728 static
 729 int BlackPreservingGrayOnlySampler(CMSREGISTER const cmsUInt16Number In[], CMSREGISTER cmsUInt16Number Out[], CMSREGISTER void* Cargo)
 730 {
 731     GrayOnlyParams* bp = (GrayOnlyParams*) Cargo;
 732 
 733     // If going across black only, keep black only
 734     if (In[0] == 0 && In[1] == 0 && In[2] == 0) {
 735 
 736         // TAC does not apply because it is black ink!
 737         Out[0] = Out[1] = Out[2] = 0;
 738         Out[3] = cmsEvalToneCurve16(bp->KTone, In[3]);
 739         return TRUE;
 740     }
 741 
 742     // Keep normal transform for other colors
 743     bp ->cmyk2cmyk ->Eval16Fn(In, Out, bp ->cmyk2cmyk->Data);
 744     return TRUE;
 745 }
 746 










 747 // This is the entry for black-preserving K-only intents, which are non-ICC
 748 static
 749 cmsPipeline*  BlackPreservingKOnlyIntents(cmsContext     ContextID,
 750                                           cmsUInt32Number nProfiles,
 751                                           cmsUInt32Number TheIntents[],
 752                                           cmsHPROFILE     hProfiles[],
 753                                           cmsBool         BPC[],
 754                                           cmsFloat64Number AdaptationStates[],
 755                                           cmsUInt32Number dwFlags)
 756 {
 757     GrayOnlyParams  bp;
 758     cmsPipeline*    Result;
 759     cmsUInt32Number ICCIntents[256];
 760     cmsStage*         CLUT;
 761     cmsUInt32Number i, nGridPoints;
 762     cmsUInt32Number lastProfilePos;
 763     cmsUInt32Number preservationProfilesCount;
 764     cmsHPROFILE hLastProfile;
 765 
 766 
 767     // Sanity check
 768     if (nProfiles < 1 || nProfiles > 255) return NULL;
 769 
 770     // Translate black-preserving intents to ICC ones
 771     for (i=0; i < nProfiles; i++)
 772         ICCIntents[i] = TranslateNonICCIntents(TheIntents[i]);
 773 
 774 
 775     // Trim all CMYK devicelinks at the end
 776     lastProfilePos = nProfiles - 1;
 777     hLastProfile = hProfiles[lastProfilePos];
 778 
 779     while (lastProfilePos > 1)

 780     {
 781         hLastProfile = hProfiles[--lastProfilePos];
 782         if (cmsGetColorSpace(hLastProfile) != cmsSigCmykData ||
 783             cmsGetDeviceClass(hLastProfile) != cmsSigLinkClass)
 784             break;


 785     }
 786 

 787     preservationProfilesCount = lastProfilePos + 1;
 788 
 789     // Check for non-cmyk profiles
 790     if (cmsGetColorSpace(hProfiles[0]) != cmsSigCmykData ||
 791         !(cmsGetColorSpace(hLastProfile) == cmsSigCmykData ||
 792         cmsGetDeviceClass(hLastProfile) == cmsSigOutputClass))
 793            return DefaultICCintents(ContextID, nProfiles, ICCIntents, hProfiles, BPC, AdaptationStates, dwFlags);
 794 
 795     // Allocate an empty LUT for holding the result
 796     Result = cmsPipelineAlloc(ContextID, 4, 4);
 797     if (Result == NULL) return NULL;
 798 
 799     memset(&bp, 0, sizeof(bp));
 800 
 801     // Create a LUT holding normal ICC transform
 802     bp.cmyk2cmyk = DefaultICCintents(ContextID,
 803                                      preservationProfilesCount,
 804         ICCIntents,
 805         hProfiles,
 806         BPC,
 807         AdaptationStates,
 808         dwFlags);
 809 
 810     if (bp.cmyk2cmyk == NULL) goto Error;
 811 
 812     // Now, compute the tone curve
 813     bp.KTone = _cmsBuildKToneCurve(ContextID,
 814         4096,
 815                                     preservationProfilesCount,
 816         ICCIntents,
 817         hProfiles,
 818         BPC,
 819         AdaptationStates,
 820         dwFlags);
 821 
 822     if (bp.KTone == NULL) goto Error;
 823 
 824 
 825     // How many gridpoints are we going to use?
 826     nGridPoints = _cmsReasonableGridpointsByColorspace(cmsSigCmykData, dwFlags);
 827 
 828     // Create the CLUT. 16 bits
 829     CLUT = cmsStageAllocCLut16bit(ContextID, nGridPoints, 4, 4, NULL);
 830     if (CLUT == NULL) goto Error;
 831 
 832     // This is the one and only MPE in this LUT
 833     if (!cmsPipelineInsertStage(Result, cmsAT_BEGIN, CLUT))
 834         goto Error;
 835 

 985     cmsPipeline*    Result = NULL;
 986     cmsUInt32Number ICCIntents[256];
 987     cmsStage*         CLUT;
 988     cmsUInt32Number i, nGridPoints;
 989     cmsUInt32Number lastProfilePos;
 990     cmsUInt32Number preservationProfilesCount;
 991     cmsHPROFILE hLastProfile;
 992     cmsHPROFILE hLab;
 993 
 994     // Sanity check
 995     if (nProfiles < 1 || nProfiles > 255) return NULL;
 996 
 997     // Translate black-preserving intents to ICC ones
 998     for (i=0; i < nProfiles; i++)
 999         ICCIntents[i] = TranslateNonICCIntents(TheIntents[i]);
1000 
1001     // Trim all CMYK devicelinks at the end
1002     lastProfilePos = nProfiles - 1;
1003     hLastProfile = hProfiles[lastProfilePos];
1004 
1005     while (lastProfilePos > 1)

1006     {
1007         hLastProfile = hProfiles[--lastProfilePos];
1008         if (cmsGetColorSpace(hLastProfile) != cmsSigCmykData ||
1009             cmsGetDeviceClass(hLastProfile) != cmsSigLinkClass)
1010             break;


1011     }
1012 
1013     preservationProfilesCount = lastProfilePos + 1;
1014 
1015     // Check for non-cmyk profiles
1016     if (cmsGetColorSpace(hProfiles[0]) != cmsSigCmykData ||
1017         !(cmsGetColorSpace(hLastProfile) == cmsSigCmykData ||
1018         cmsGetDeviceClass(hLastProfile) == cmsSigOutputClass))
1019            return  DefaultICCintents(ContextID, nProfiles, ICCIntents, hProfiles, BPC, AdaptationStates, dwFlags);
1020 
1021     // Allocate an empty LUT for holding the result
1022     Result = cmsPipelineAlloc(ContextID, 4, 4);
1023     if (Result == NULL) return NULL;
1024 
1025     memset(&bp, 0, sizeof(bp));
1026 
1027     // We need the input LUT of the last profile, assuming this one is responsible of
1028     // black generation. This LUT will be searched in inverse order.
1029     bp.LabK2cmyk = _cmsReadInputLUT(hLastProfile, INTENT_RELATIVE_COLORIMETRIC);
1030     if (bp.LabK2cmyk == NULL) goto Cleanup;

1160     if (Intent == NULL) {
1161         cmsSignalError(ContextID, cmsERROR_UNKNOWN_EXTENSION, "Unsupported intent '%d'", TheIntents[0]);
1162         return NULL;
1163     }
1164 
1165     // Call the handler
1166     return Intent ->Link(ContextID, nProfiles, TheIntents, hProfiles, BPC, AdaptationStates, dwFlags);
1167 }
1168 
1169 // -------------------------------------------------------------------------------------------------
1170 
1171 // Get information about available intents. nMax is the maximum space for the supplied "Codes"
1172 // and "Descriptions" the function returns the total number of intents, which may be greater
1173 // than nMax, although the matrices are not populated beyond this level.
1174 cmsUInt32Number CMSEXPORT cmsGetSupportedIntentsTHR(cmsContext ContextID, cmsUInt32Number nMax, cmsUInt32Number* Codes, char** Descriptions)
1175 {
1176     _cmsIntentsPluginChunkType* ctx = ( _cmsIntentsPluginChunkType*) _cmsContextGetClientChunk(ContextID, IntentPlugin);
1177     cmsIntentsList* pt;
1178     cmsUInt32Number nIntents;
1179 
1180 
1181     for (nIntents=0, pt = ctx->Intents; pt != NULL; pt = pt -> Next)
1182     {
1183         if (nIntents < nMax) {
1184             if (Codes != NULL)
1185                 Codes[nIntents] = pt ->Intent;
1186 
1187             if (Descriptions != NULL)
1188                 Descriptions[nIntents] = pt ->Description;
1189         }
1190 
1191         nIntents++;
1192     }
1193 
1194     for (nIntents=0, pt = DefaultIntents; pt != NULL; pt = pt -> Next)
1195     {
1196         if (nIntents < nMax) {
1197             if (Codes != NULL)
1198                 Codes[nIntents] = pt ->Intent;
1199 
1200             if (Descriptions != NULL)
1201                 Descriptions[nIntents] = pt ->Description;
1202         }
1203 
1204         nIntents++;
1205     }

1206     return nIntents;
1207 }
1208 
1209 cmsUInt32Number CMSEXPORT cmsGetSupportedIntents(cmsUInt32Number nMax, cmsUInt32Number* Codes, char** Descriptions)
1210 {
1211     return cmsGetSupportedIntentsTHR(NULL, nMax, Codes, Descriptions);
1212 }
1213 
1214 // The plug-in registration. User can add new intents or override default routines
1215 cmsBool  _cmsRegisterRenderingIntentPlugin(cmsContext id, cmsPluginBase* Data)
1216 {
1217     _cmsIntentsPluginChunkType* ctx = ( _cmsIntentsPluginChunkType*) _cmsContextGetClientChunk(id, IntentPlugin);
1218     cmsPluginRenderingIntent* Plugin = (cmsPluginRenderingIntent*) Data;
1219     cmsIntentsList* fl;
1220 
1221     // Do we have to reset the custom intents?
1222     if (Data == NULL) {
1223 
1224         ctx->Intents = NULL;
1225         return TRUE;

 246     s.n[VX] = cmsD50_XYZ() -> X;
 247     s.n[VY] = cmsD50_XYZ() -> Y;
 248     s.n[VZ] = cmsD50_XYZ() -> Z;
 249 
 250     _cmsMAT3eval(&d, &m2, &s);
 251 
 252     Dest.X = d.n[VX];
 253     Dest.Y = d.n[VY];
 254     Dest.Z = d.n[VZ];
 255 
 256     cmsXYZ2xyY(&DestChromaticity, &Dest);
 257 
 258     if (!cmsTempFromWhitePoint(&TempK, &DestChromaticity))
 259         return -1.0;
 260 
 261     return TempK;
 262 }
 263 
 264 // Compute a CHAD based on a given temperature
 265 static
 266 void Temp2CHAD(cmsMAT3* Chad, cmsFloat64Number Temp)
 267 {
 268     cmsCIEXYZ White;
 269     cmsCIExyY ChromaticityOfWhite;
 270 
 271     cmsWhitePointFromTemp(&ChromaticityOfWhite, Temp);
 272     cmsxyY2XYZ(&White, &ChromaticityOfWhite);
 273     _cmsAdaptationMatrix(Chad, NULL, &White, cmsD50_XYZ());
 274 }
 275 
 276 // Join scalings to obtain relative input to absolute and then to relative output.
 277 // Result is stored in a 3x3 matrix
 278 static
 279 cmsBool  ComputeAbsoluteIntent(cmsFloat64Number AdaptationState,
 280                                const cmsCIEXYZ* WhitePointIn,
 281                                const cmsMAT3* ChromaticAdaptationMatrixIn,
 282                                const cmsCIEXYZ* WhitePointOut,
 283                                const cmsMAT3* ChromaticAdaptationMatrixOut,
 284                                cmsMAT3* m)
 285 {
 286     cmsMAT3 Scale, m1, m2, m3, m4;

 727 // Preserve black only if that is the only ink used
 728 static
 729 int BlackPreservingGrayOnlySampler(CMSREGISTER const cmsUInt16Number In[], CMSREGISTER cmsUInt16Number Out[], CMSREGISTER void* Cargo)
 730 {
 731     GrayOnlyParams* bp = (GrayOnlyParams*) Cargo;
 732 
 733     // If going across black only, keep black only
 734     if (In[0] == 0 && In[1] == 0 && In[2] == 0) {
 735 
 736         // TAC does not apply because it is black ink!
 737         Out[0] = Out[1] = Out[2] = 0;
 738         Out[3] = cmsEvalToneCurve16(bp->KTone, In[3]);
 739         return TRUE;
 740     }
 741 
 742     // Keep normal transform for other colors
 743     bp ->cmyk2cmyk ->Eval16Fn(In, Out, bp ->cmyk2cmyk->Data);
 744     return TRUE;
 745 }
 746 
 747 
 748 // Check whatever the profile is a CMYK->CMYK devicelink
 749 static
 750 cmsBool is_cmyk_devicelink(cmsHPROFILE hProfile)
 751 {
 752     return cmsGetDeviceClass(hProfile) == cmsSigLinkClass &&
 753             cmsGetColorSpace(hProfile) == cmsSigCmykData &&
 754             cmsGetColorSpace(hProfile) == cmsSigCmykData;
 755 }
 756 
 757 // This is the entry for black-preserving K-only intents, which are non-ICC
 758 static
 759 cmsPipeline*  BlackPreservingKOnlyIntents(cmsContext     ContextID,
 760                                           cmsUInt32Number nProfiles,
 761                                           cmsUInt32Number TheIntents[],
 762                                           cmsHPROFILE     hProfiles[],
 763                                           cmsBool         BPC[],
 764                                           cmsFloat64Number AdaptationStates[],
 765                                           cmsUInt32Number dwFlags)
 766 {
 767     GrayOnlyParams  bp;
 768     cmsPipeline*    Result;
 769     cmsUInt32Number ICCIntents[256];
 770     cmsStage*         CLUT;
 771     cmsUInt32Number i, nGridPoints;
 772     cmsUInt32Number lastProfilePos;
 773     cmsUInt32Number preservationProfilesCount;
 774     cmsHPROFILE hLastProfile;
 775 
 776 
 777     // Sanity check
 778     if (nProfiles < 1 || nProfiles > 255) return NULL;
 779 
 780     // Translate black-preserving intents to ICC ones
 781     for (i=0; i < nProfiles; i++)
 782         ICCIntents[i] = TranslateNonICCIntents(TheIntents[i]);
 783 
 784 
 785     // Trim all CMYK devicelinks at the end
 786     lastProfilePos = nProfiles - 1;
 787     hLastProfile = hProfiles[lastProfilePos];
 788 
 789     // Skip CMYK->CMYK devicelinks on ending
 790     while (is_cmyk_devicelink(hLastProfile))
 791     {
 792         if (lastProfilePos < 2)


 793             break;
 794 
 795         hLastProfile = hProfiles[--lastProfilePos];
 796     }
 797 
 798 
 799     preservationProfilesCount = lastProfilePos + 1;
 800 
 801     // Check for non-cmyk profiles
 802     if (cmsGetColorSpace(hProfiles[0]) != cmsSigCmykData ||
 803         !(cmsGetColorSpace(hLastProfile) == cmsSigCmykData ||
 804         cmsGetDeviceClass(hLastProfile) == cmsSigOutputClass))
 805            return DefaultICCintents(ContextID, nProfiles, ICCIntents, hProfiles, BPC, AdaptationStates, dwFlags);
 806 
 807     // Allocate an empty LUT for holding the result
 808     Result = cmsPipelineAlloc(ContextID, 4, 4);
 809     if (Result == NULL) return NULL;
 810 
 811     memset(&bp, 0, sizeof(bp));
 812 
 813     // Create a LUT holding normal ICC transform
 814     bp.cmyk2cmyk = DefaultICCintents(ContextID,
 815         preservationProfilesCount,
 816         ICCIntents,
 817         hProfiles,
 818         BPC,
 819         AdaptationStates,
 820         dwFlags);
 821 
 822     if (bp.cmyk2cmyk == NULL) goto Error;
 823 
 824     // Now, compute the tone curve
 825     bp.KTone = _cmsBuildKToneCurve(ContextID,
 826         4096,
 827         preservationProfilesCount,
 828         ICCIntents,
 829         hProfiles,
 830         BPC,
 831         AdaptationStates,
 832         dwFlags);
 833 
 834     if (bp.KTone == NULL) goto Error;
 835 
 836 
 837     // How many gridpoints are we going to use?
 838     nGridPoints = _cmsReasonableGridpointsByColorspace(cmsSigCmykData, dwFlags);
 839 
 840     // Create the CLUT. 16 bits
 841     CLUT = cmsStageAllocCLut16bit(ContextID, nGridPoints, 4, 4, NULL);
 842     if (CLUT == NULL) goto Error;
 843 
 844     // This is the one and only MPE in this LUT
 845     if (!cmsPipelineInsertStage(Result, cmsAT_BEGIN, CLUT))
 846         goto Error;
 847 

 997     cmsPipeline*    Result = NULL;
 998     cmsUInt32Number ICCIntents[256];
 999     cmsStage*         CLUT;
1000     cmsUInt32Number i, nGridPoints;
1001     cmsUInt32Number lastProfilePos;
1002     cmsUInt32Number preservationProfilesCount;
1003     cmsHPROFILE hLastProfile;
1004     cmsHPROFILE hLab;
1005 
1006     // Sanity check
1007     if (nProfiles < 1 || nProfiles > 255) return NULL;
1008 
1009     // Translate black-preserving intents to ICC ones
1010     for (i=0; i < nProfiles; i++)
1011         ICCIntents[i] = TranslateNonICCIntents(TheIntents[i]);
1012 
1013     // Trim all CMYK devicelinks at the end
1014     lastProfilePos = nProfiles - 1;
1015     hLastProfile = hProfiles[lastProfilePos];
1016 
1017     // Skip CMYK->CMYK devicelinks on ending
1018     while (is_cmyk_devicelink(hLastProfile))
1019     {
1020         if (lastProfilePos < 2)


1021             break;
1022 
1023         hLastProfile = hProfiles[--lastProfilePos];
1024     }
1025 
1026     preservationProfilesCount = lastProfilePos + 1;
1027 
1028     // Check for non-cmyk profiles
1029     if (cmsGetColorSpace(hProfiles[0]) != cmsSigCmykData ||
1030         !(cmsGetColorSpace(hLastProfile) == cmsSigCmykData ||
1031         cmsGetDeviceClass(hLastProfile) == cmsSigOutputClass))
1032            return  DefaultICCintents(ContextID, nProfiles, ICCIntents, hProfiles, BPC, AdaptationStates, dwFlags);
1033 
1034     // Allocate an empty LUT for holding the result
1035     Result = cmsPipelineAlloc(ContextID, 4, 4);
1036     if (Result == NULL) return NULL;
1037 
1038     memset(&bp, 0, sizeof(bp));
1039 
1040     // We need the input LUT of the last profile, assuming this one is responsible of
1041     // black generation. This LUT will be searched in inverse order.
1042     bp.LabK2cmyk = _cmsReadInputLUT(hLastProfile, INTENT_RELATIVE_COLORIMETRIC);
1043     if (bp.LabK2cmyk == NULL) goto Cleanup;

1173     if (Intent == NULL) {
1174         cmsSignalError(ContextID, cmsERROR_UNKNOWN_EXTENSION, "Unsupported intent '%d'", TheIntents[0]);
1175         return NULL;
1176     }
1177 
1178     // Call the handler
1179     return Intent ->Link(ContextID, nProfiles, TheIntents, hProfiles, BPC, AdaptationStates, dwFlags);
1180 }
1181 
1182 // -------------------------------------------------------------------------------------------------
1183 
1184 // Get information about available intents. nMax is the maximum space for the supplied "Codes"
1185 // and "Descriptions" the function returns the total number of intents, which may be greater
1186 // than nMax, although the matrices are not populated beyond this level.
1187 cmsUInt32Number CMSEXPORT cmsGetSupportedIntentsTHR(cmsContext ContextID, cmsUInt32Number nMax, cmsUInt32Number* Codes, char** Descriptions)
1188 {
1189     _cmsIntentsPluginChunkType* ctx = ( _cmsIntentsPluginChunkType*) _cmsContextGetClientChunk(ContextID, IntentPlugin);
1190     cmsIntentsList* pt;
1191     cmsUInt32Number nIntents;
1192 
1193     for (nIntents=0, pt = DefaultIntents; pt != NULL; pt = pt -> Next)

1194     {
1195         if (nIntents < nMax) {
1196             if (Codes != NULL)
1197                 Codes[nIntents] = pt ->Intent;
1198 
1199             if (Descriptions != NULL)
1200                 Descriptions[nIntents] = pt ->Description;
1201         }
1202 
1203         nIntents++;
1204     }
1205 
1206     for (pt = ctx->Intents; pt != NULL; pt = pt -> Next)
1207     {
1208         if (nIntents < nMax) {
1209             if (Codes != NULL)
1210                 Codes[nIntents] = pt ->Intent;
1211 
1212             if (Descriptions != NULL)
1213                 Descriptions[nIntents] = pt ->Description;
1214         }
1215 
1216         nIntents++;
1217     }
1218 
1219     return nIntents;
1220 }
1221 
1222 cmsUInt32Number CMSEXPORT cmsGetSupportedIntents(cmsUInt32Number nMax, cmsUInt32Number* Codes, char** Descriptions)
1223 {
1224     return cmsGetSupportedIntentsTHR(NULL, nMax, Codes, Descriptions);
1225 }
1226 
1227 // The plug-in registration. User can add new intents or override default routines
1228 cmsBool  _cmsRegisterRenderingIntentPlugin(cmsContext id, cmsPluginBase* Data)
1229 {
1230     _cmsIntentsPluginChunkType* ctx = ( _cmsIntentsPluginChunkType*) _cmsContextGetClientChunk(id, IntentPlugin);
1231     cmsPluginRenderingIntent* Plugin = (cmsPluginRenderingIntent*) Data;
1232     cmsIntentsList* fl;
1233 
1234     // Do we have to reset the custom intents?
1235     if (Data == NULL) {
1236 
1237         ctx->Intents = NULL;
1238         return TRUE;
< prev index next >