Exemplo n.º 1
0
cmsHTRANSFORM CMSEXPORT cmsCreateTransformTHR(cmsContext ContextID,
                                              cmsHPROFILE Input,
                                              cmsUInt32Number InputFormat,
                                              cmsHPROFILE Output,
                                              cmsUInt32Number OutputFormat,
                                              cmsUInt32Number Intent,
                                              cmsUInt32Number dwFlags)
{

    cmsHPROFILE hArray[2];

    hArray[0] = Input;
    hArray[1] = Output;

    return cmsCreateMultiprofileTransformTHR(ContextID, hArray, Output == NULL ? 1 : 2, InputFormat, OutputFormat, Intent, dwFlags);
}
Exemplo n.º 2
0
cmsHTRANSFORM CMSEXPORT cmsCreateMultiprofileTransform(cmsHPROFILE hProfiles[],
                                                  cmsUInt32Number nProfiles,
                                                  cmsUInt32Number InputFormat,
                                                  cmsUInt32Number OutputFormat,
                                                  cmsUInt32Number Intent,
                                                  cmsUInt32Number dwFlags)
{

    if (nProfiles <= 0 || nProfiles > 255) {
         cmsSignalError(NULL, cmsERROR_RANGE, "Wrong number of profiles. 1..255 expected, %d found.", nProfiles);
         return NULL;
    }

    return cmsCreateMultiprofileTransformTHR(cmsGetProfileContextID(hProfiles[0]),
                                                  hProfiles,
                                                  nProfiles,
                                                  InputFormat,
                                                  OutputFormat,
                                                  Intent,
                                                  dwFlags);
}
Exemplo n.º 3
0
static
int WriteOutputLUT(cmsIOHANDLER* m, cmsHPROFILE hProfile, int Intent, cmsUInt32Number dwFlags)
{
    cmsHPROFILE hLab;
    cmsHTRANSFORM xform;
    int i, nChannels;
    cmsUInt32Number OutputFormat;
    _cmsTRANSFORM* v;
    cmsPipeline* DeviceLink;
    cmsHPROFILE Profiles[3];
    cmsCIEXYZ BlackPointAdaptedToD50;
    cmsBool lDoBPC = (dwFlags & cmsFLAGS_BLACKPOINTCOMPENSATION);
    cmsBool lFixWhite = !(dwFlags & cmsFLAGS_NOWHITEONWHITEFIXUP);
	cmsUInt32Number InFrm = TYPE_Lab_16;
	int RelativeEncodingIntent;
	cmsColorSpaceSignature ColorSpace;
    
    
	hLab = cmsCreateLab4ProfileTHR(m ->ContextID, NULL);
	if (hLab == NULL) return 0;

    OutputFormat = cmsFormatterForColorspaceOfProfile(hProfile, 2, FALSE);
	nChannels    = T_CHANNELS(OutputFormat);

	ColorSpace = cmsGetColorSpace(hProfile);

	// For absolute colorimetric, the LUT is encoded as relative in order to preserve precision.

    RelativeEncodingIntent = Intent;
	if (RelativeEncodingIntent == INTENT_ABSOLUTE_COLORIMETRIC)
		RelativeEncodingIntent = INTENT_RELATIVE_COLORIMETRIC;


	// Use V4 Lab always
	Profiles[0] = hLab;
	Profiles[1] = hProfile;

	xform = cmsCreateMultiprofileTransformTHR(m ->ContextID, 
		                                      Profiles, 2, TYPE_Lab_DBL, 
		                                      OutputFormat, RelativeEncodingIntent, 0);
	cmsCloseProfile(hLab);

    if (xform == NULL) {
                        
		cmsSignalError(m ->ContextID, cmsERROR_COLORSPACE_CHECK, "Cannot create transform Lab -> Profile in CRD creation");
        return 0;
    }

    // Get a copy of the internal devicelink
    v = (_cmsTRANSFORM*) xform;
    DeviceLink = cmsPipelineDup(v ->Lut);
	if (DeviceLink == NULL) return 0;
   
  
	// We need a CLUT
	dwFlags |= cmsFLAGS_FORCE_CLUT;
	_cmsOptimizePipeline(&DeviceLink, RelativeEncodingIntent, &InFrm, &OutputFormat, &dwFlags);
  
    _cmsIOPrintf(m, "<<\n");
    _cmsIOPrintf(m, "/ColorRenderingType 1\n");


    cmsDetectBlackPoint(&BlackPointAdaptedToD50, hProfile, Intent, 0);

    // Emit headers, etc.
    EmitWhiteBlackD50(m, &BlackPointAdaptedToD50);
    EmitPQRStage(m, hProfile, lDoBPC, Intent == INTENT_ABSOLUTE_COLORIMETRIC);
    EmitXYZ2Lab(m);
        
   
    // FIXUP: map Lab (100, 0, 0) to perfect white, because the particular encoding for Lab 
    // does map a=b=0 not falling into any specific node. Since range a,b goes -128..127, 
    // zero is slightly moved towards right, so assure next node (in L=100 slice) is mapped to
    // zero. This would sacrifice a bit of highlights, but failure to do so would cause
    // scum dot. Ouch.
    
    if (Intent == INTENT_ABSOLUTE_COLORIMETRIC)
            lFixWhite = FALSE;

    _cmsIOPrintf(m, "/RenderTable ");
    
	
    WriteCLUT(m, cmsPipelineGetPtrToFirstStage(DeviceLink), "<", ">\n", "", "", lFixWhite, ColorSpace);
    
    _cmsIOPrintf(m, " %d {} bind ", nChannels);

    for (i=1; i < nChannels; i++)
            _cmsIOPrintf(m, "dup ");

    _cmsIOPrintf(m, "]\n");

        
    EmitIntent(m, Intent);

    _cmsIOPrintf(m, ">>\n");

    if (!(dwFlags & cmsFLAGS_NODEFAULTRESOURCEDEF)) {

        _cmsIOPrintf(m, "/Current exch /ColorRendering defineresource pop\n");
    }

    cmsPipelineFree(DeviceLink);
    cmsDeleteTransform(xform);
 
    return 1;   
}
Exemplo n.º 4
0
/* Get the link from the CMS, but include proofing and/or a device link
   profile.  Note also, that the source may be a device link profile, in
   which case we will not have a destination profile but could still have
   a proof profile or an additional device link profile */
gcmmhlink_t
gscms_get_link_proof_devlink(gcmmhprofile_t lcms_srchandle,
                             gcmmhprofile_t lcms_proofhandle,
                             gcmmhprofile_t lcms_deshandle,
                             gcmmhprofile_t lcms_devlinkhandle,
                             gsicc_rendering_param_t *rendering_params,
                             bool src_dev_link, int cmm_flags,
                             gs_memory_t *memory)
{
    cmsUInt32Number src_data_type,des_data_type;
    cmsColorSpaceSignature src_color_space,des_color_space;
    int src_nChannels,des_nChannels;
    int lcms_src_color_space, lcms_des_color_space;
    cmsHPROFILE hProfiles[5];
    int nProfiles = 0;
    unsigned int flag;

    /* Check if the rendering intent is something other than relative colorimetric
       and  if we have a proofing profile.  In this case we need to create the
       combined profile a bit different.  LCMS does not allow us to use different
       intents in the cmsCreateMultiprofileTransform transform.  Also, don't even
       think about doing this if someone has snuck in a source based device link
       profile into the mix */
    if (lcms_proofhandle != NULL &&
            rendering_params->rendering_intent != gsRELATIVECOLORIMETRIC &&
            !src_dev_link) {
        /* First handle the source to proof profile with its particular intent as
           a device link profile */
        cmsHPROFILE src_to_proof;
        cmsHTRANSFORM temptransform;

        temptransform = gscms_get_link(lcms_srchandle, lcms_proofhandle,
                                       rendering_params, cmm_flags, memory);
        /* Now mash that to a device link profile */
        flag = cmsFLAGS_HIGHRESPRECALC;
        if (rendering_params->black_point_comp == gsBLACKPTCOMP_ON ||
                rendering_params->black_point_comp == gsBLACKPTCOMP_ON_OR) {
            flag = (flag | cmsFLAGS_BLACKPOINTCOMPENSATION);
        }
        src_to_proof = cmsTransform2DeviceLink(temptransform, 3.4, flag);
        /* Free up the link handle */
        cmsDeleteTransform(temptransform);
        src_color_space  = cmsGetColorSpace(src_to_proof);
        lcms_src_color_space = _cmsLCMScolorSpace(src_color_space);
        /* littlecms returns -1 for types it does not (but should) understand */
        if (lcms_src_color_space < 0) lcms_src_color_space = 0;
        src_nChannels = cmsChannelsOf(src_color_space);
        /* For now, just do single byte data, interleaved.  We can change this
          when we use the transformation. */
        src_data_type = (COLORSPACE_SH(lcms_src_color_space)|
                         CHANNELS_SH(src_nChannels)|BYTES_SH(2));
        if (lcms_devlinkhandle == NULL) {
            des_color_space = cmsGetColorSpace(lcms_deshandle);
        } else {
            des_color_space = cmsGetPCS(lcms_devlinkhandle);
        }
        lcms_des_color_space = _cmsLCMScolorSpace(des_color_space);
        if (lcms_des_color_space < 0) lcms_des_color_space = 0;
        des_nChannels = cmsChannelsOf(des_color_space);
        des_data_type = (COLORSPACE_SH(lcms_des_color_space)|
                         CHANNELS_SH(des_nChannels)|BYTES_SH(2));
        /* Now, we need to go back through the proofing profile, to the
           destination and then to the device link profile if there was one. */
        hProfiles[nProfiles++] = src_to_proof;  /* Src to proof with special intent */
        hProfiles[nProfiles++] = lcms_proofhandle; /* Proof to CIELAB */
        if (lcms_deshandle != NULL) {
            hProfiles[nProfiles++] = lcms_deshandle;  /* Our destination */
        }
        /* The output device link profile */
        if (lcms_devlinkhandle != NULL) {
            hProfiles[nProfiles++] = lcms_devlinkhandle;
        }
        flag = cmsFLAGS_HIGHRESPRECALC;
        if (rendering_params->black_point_comp == gsBLACKPTCOMP_ON
                || rendering_params->black_point_comp == gsBLACKPTCOMP_ON_OR) {
            flag = (flag | cmsFLAGS_BLACKPOINTCOMPENSATION);
        }
        /* Use relative colorimetric here */
        temptransform = cmsCreateMultiprofileTransformTHR((cmsContext)memory,
                        hProfiles, nProfiles, src_data_type,
                        des_data_type, gsRELATIVECOLORIMETRIC, flag);
        cmsCloseProfile(src_to_proof);
        return temptransform;
    } else {
        /* First handle all the source stuff */
        src_color_space  = cmsGetColorSpace(lcms_srchandle);
        lcms_src_color_space = _cmsLCMScolorSpace(src_color_space);
        /* littlecms returns -1 for types it does not (but should) understand */
        if (lcms_src_color_space < 0) lcms_src_color_space = 0;
        src_nChannels = cmsChannelsOf(src_color_space);
        /* For now, just do single byte data, interleaved.  We can change this
          when we use the transformation. */
        src_data_type = (COLORSPACE_SH(lcms_src_color_space)|
                         CHANNELS_SH(src_nChannels)|BYTES_SH(2));
        if (lcms_devlinkhandle == NULL) {
            if (src_dev_link) {
                des_color_space = cmsGetPCS(lcms_srchandle);
            } else {
                des_color_space = cmsGetColorSpace(lcms_deshandle);
            }
        } else {
            des_color_space = cmsGetPCS(lcms_devlinkhandle);
        }
        lcms_des_color_space = _cmsLCMScolorSpace(des_color_space);
        if (lcms_des_color_space < 0) lcms_des_color_space = 0;
        des_nChannels = cmsChannelsOf(des_color_space);
        des_data_type = (COLORSPACE_SH(lcms_des_color_space)|
                         CHANNELS_SH(des_nChannels)|BYTES_SH(2));
        /* lcms proofing transform has a clunky API and can't include the device
           link profile if we have both. So use cmsCreateMultiprofileTransform
           instead and round trip the proofing profile. */
        hProfiles[nProfiles++] = lcms_srchandle;
        /* Note if source is device link, we cannot do any proofing */
        if (lcms_proofhandle != NULL && !src_dev_link) {
            hProfiles[nProfiles++] = lcms_proofhandle;
            hProfiles[nProfiles++] = lcms_proofhandle;
        }
        /* This should be NULL if we have a source device link */
        if (lcms_deshandle != NULL) {
            hProfiles[nProfiles++] = lcms_deshandle;
        }
        /* Someone could have a device link at the output, giving us possibly two
           device link profiles to smash together */
        if (lcms_devlinkhandle != NULL) {
            hProfiles[nProfiles++] = lcms_devlinkhandle;
        }
        flag = cmsFLAGS_HIGHRESPRECALC;
        if (rendering_params->black_point_comp == gsBLACKPTCOMP_ON
                || rendering_params->black_point_comp == gsBLACKPTCOMP_ON_OR) {
            flag = (flag | cmsFLAGS_BLACKPOINTCOMPENSATION);
        }
        return cmsCreateMultiprofileTransformTHR((cmsContext)memory,
                hProfiles, nProfiles, src_data_type,
                des_data_type, rendering_params->rendering_intent, flag);
    }
}