Example #1
0
/* Get the link from the CMS, but include proofing and/or a 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 *mem)
{
    DWORD src_data_type,des_data_type;
    icColorSpaceSignature 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;

   /* 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_deshandle != NULL) {
        des_color_space  = cmsGetColorSpace(lcms_deshandle);
    } else {
        /* We must have a device link profile. */
        des_color_space = cmsGetPCS(lcms_deshandle);
    }
    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;
    if (lcms_proofhandle != NULL) {
        hProfiles[nProfiles++] = lcms_proofhandle;
        hProfiles[nProfiles++] = lcms_proofhandle;
    }
    hProfiles[nProfiles++] = lcms_deshandle;
    if (lcms_devlinkhandle != NULL) {
        hProfiles[nProfiles++] = lcms_devlinkhandle;
    }
    return(cmsCreateMultiprofileTransform(hProfiles, nProfiles, src_data_type, 
                                          des_data_type, rendering_params->rendering_intent, 
                                          (cmm_flags | cmsFLAGS_BLACKPOINTCOMPENSATION | 
                                           cmsFLAGS_HIGHRESPRECALC |
                                           cmsFLAGS_NOTCACHE)));
}
Example #2
0
static
int GetDevicelinkColorSpace(cmsHPROFILE hProfile)
{
    cmsColorSpaceSignature ProfileSpace = cmsGetPCS(hProfile);

	return _cmsLCMScolorSpace(ProfileSpace);
}
Example #3
0
// Equivalence between ICC color spaces and lcms color spaces
static
int GetProfileColorSpace(cmsHPROFILE hProfile)
{
    cmsColorSpaceSignature ProfileSpace = cmsGetColorSpace(hProfile);

	return _cmsLCMScolorSpace(ProfileSpace);
}
Example #4
0
/* Get the link from the CMS. TODO:  Add error checking */
gcmmhlink_t
gscms_get_link(gcmmhprofile_t  lcms_srchandle,
                    gcmmhprofile_t lcms_deshandle,
                    gsicc_rendering_param_t *rendering_params)
{
    DWORD src_data_type,des_data_type;
    icColorSpaceSignature src_color_space,des_color_space;
    int src_nChannels,des_nChannels;
    int lcms_src_color_space, lcms_des_color_space;

    /* Check for case of request for a transfrom from a device link profile
       in that case, the destination profile is NULL */

   /* 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_deshandle != NULL) {
        des_color_space  = cmsGetColorSpace(lcms_deshandle);
    } else {
        /* We must have a device link profile. */
        des_color_space = cmsGetPCS(lcms_deshandle);
    }
    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));
/* Create the link */
    return(cmsCreateTransform(lcms_srchandle, src_data_type, lcms_deshandle,
                        des_data_type, rendering_params->rendering_intent,
               (cmsFLAGS_BLACKPOINTCOMPENSATION | cmsFLAGS_HIGHRESPRECALC)));
    /* cmsFLAGS_HIGHRESPRECALC)  cmsFLAGS_NOTPRECALC  cmsFLAGS_LOWRESPRECALC*/
}
Example #5
0
// Check colorspace
static
cmsBool  IsProperColorSpace(cmsColorSpaceSignature Check, cmsUInt32Number dwFormat)
{
    int Space1 = T_COLORSPACE(dwFormat);
    int Space2 = _cmsLCMScolorSpace(Check);

    if (Space1 == PT_ANY) return TRUE;
    if (Space1 == Space2) return TRUE;

    if (Space1 == PT_LabV2 && Space2 == PT_Lab) return TRUE;
    if (Space1 == PT_Lab   && Space2 == PT_LabV2) return TRUE;

    return FALSE;
}
void IccColorProfile::calculateFloatUIMinMax(void)
{
    QVector<KoChannelInfo::DoubleRange> &ret = d->shared->uiMinMaxes;

    cmsHPROFILE cprofile = d->shared->lcmsProfile->lcmsProfile();
    Q_ASSERT(cprofile);

    cmsColorSpaceSignature color_space_sig = cmsGetColorSpace(cprofile);
    unsigned int num_channels = cmsChannelsOf(color_space_sig);
    unsigned int color_space_mask = _cmsLCMScolorSpace(color_space_sig);

    Q_ASSERT(num_channels>=1 && num_channels <=4);  // num_channels==1 is for grayscale, we need to handle it
    Q_ASSERT(color_space_mask);

    // to try to find the max range of float/doubles for this profile,
    // pass in min/max int and make the profile convert that
    // this is far from perfect, we need a better way, if possible to get the "bounds" of a profile

    uint16_t in_min_pixel[4] = {0,0,0,0};
    uint16_t in_max_pixel[4] = {0xFFFF,0xFFFF,0xFFFF,0xFFFF};
    double out_min_pixel[4] = {0,0,0,0};
    double out_max_pixel[4] = {0,0,0,0};

    cmsHTRANSFORM trans = cmsCreateTransform(
        cprofile,
        (COLORSPACE_SH(color_space_mask)|CHANNELS_SH(num_channels)|BYTES_SH(2)),
        cprofile,
        (COLORSPACE_SH(color_space_mask)|FLOAT_SH(1)|CHANNELS_SH(num_channels)|BYTES_SH(0)), //NOTE THAT 'BYTES' FIELD IS SET TO ZERO ON DLB because 8 bytes overflows the bitfield
        INTENT_PERCEPTUAL, 0);      // does the intent matter in this case?

    if (trans) {
        cmsDoTransform(trans, in_min_pixel, out_min_pixel, 1);
        cmsDoTransform(trans, in_max_pixel, out_max_pixel, 1);
        cmsDeleteTransform(trans);
    }//else, we'll just default to [0..1] below

    ret.resize(num_channels);
    for (unsigned int i=0; i<num_channels; ++i) {
        if (out_min_pixel[i] < out_max_pixel[i]) {
            ret[i].minVal = out_min_pixel[i];
            ret[i].maxVal = out_max_pixel[i];
        } else {
            // aparently we can't even guarentee that converted_to_double(0x0000) < converted_to_double(0xFFFF)
            // assume [0..1] in such cases
            // we need to find a really solid way of determining the bounds of a profile, if possible
            ret[i].minVal = 0;
            ret[i].maxVal = 1;
        }
    }
}
// This function creates a named color profile dumping all the contents of transform to a single profile
// In this way, LittleCMS may be used to "group" several named color databases into a single profile.
// It has, however, several minor limitations. PCS is always Lab, which is not very critic since this
// is the normal PCS for named color profiles.
static
cmsHPROFILE CreateNamedColorDevicelink(cmsHTRANSFORM xform)
{
    _cmsTRANSFORM* v = (_cmsTRANSFORM*) xform;
    cmsHPROFILE hICC = NULL;
    int i, nColors;
    cmsNAMEDCOLORLIST *nc2 = NULL, *Original = NULL;

    // Create an empty placeholder
    hICC = cmsCreateProfilePlaceholder(v->ContextID);
    if (hICC == NULL) return NULL;

    // Critical information
    cmsSetDeviceClass(hICC, cmsSigNamedColorClass);
    cmsSetColorSpace(hICC, v ->ExitColorSpace);
    cmsSetPCS(hICC, cmsSigLabData);

    // Tag profile with information
    if (!SetTextTags(hICC, L"Named color devicelink")) goto Error;

    Original = cmsGetNamedColorList(xform);
    if (Original == NULL) goto Error;

    nColors = cmsNamedColorCount(Original);
    nc2     = cmsDupNamedColorList(Original);
    if (nc2 == NULL) goto Error;

    // Colorant count now depends on the output space
    nc2 ->ColorantCount = cmsPipelineOutputChannels(v ->Lut);

    // Make sure we have proper formatters
    cmsChangeBuffersFormat(xform, TYPE_NAMED_COLOR_INDEX,
        FLOAT_SH(0) | COLORSPACE_SH(_cmsLCMScolorSpace(v ->ExitColorSpace))
        | BYTES_SH(2) | CHANNELS_SH(cmsChannelsOf(v ->ExitColorSpace)));

    // Apply the transfor to colorants.
    for (i=0; i < nColors; i++) {
        cmsDoTransform(xform, &i, nc2 ->List[i].DeviceColorant, 1);
    }

    if (!cmsWriteTag(hICC, cmsSigNamedColor2Tag, (void*) nc2)) goto Error;
    cmsFreeNamedColorList(nc2);

    return hICC;

Error:
    if (hICC != NULL) cmsCloseProfile(hICC);
    return NULL;
}
Example #8
0
static
int TransformImage(TIFF* in, TIFF* out, const char *cDefInpProf, const char *cOutProf)
{
       cmsHPROFILE hIn, hOut, hProof, hInkLimit = NULL;
       cmsHTRANSFORM xform;
       DWORD wInput, wOutput;
       int OutputColorSpace;
       int bps = (Width16 ? 2 : 1);
       DWORD dwFlags = 0;        
       int nPlanes;

    // Observer adaptation state (only meaningful on absolute colorimetric intent)

       cmsSetAdaptationState(ObserverAdaptationState);

       if (EmbedProfile && cOutProf) 
           DoEmbedProfile(out, cOutProf);


       
       if (BlackWhiteCompensation) 
            dwFlags |= cmsFLAGS_WHITEBLACKCOMPENSATION;           
       

       if (PreserveBlack) {
			dwFlags |= cmsFLAGS_PRESERVEBLACK;
			if (PrecalcMode == 0) PrecalcMode = 1;
	   }

       switch (PrecalcMode) {
           
       case 0: dwFlags |= cmsFLAGS_NOTPRECALC; break;
       case 2: dwFlags |= cmsFLAGS_HIGHRESPRECALC; break;
       case 3: dwFlags |= cmsFLAGS_LOWRESPRECALC; break;
       case 1: break;

       default: FatalError("Unknown precalculation mode '%d'", PrecalcMode);
       }
        

       if (GamutCheck)
            dwFlags |= cmsFLAGS_GAMUTCHECK;
        

       hProof = NULL;
       hOut = NULL;

       if (lIsDeviceLink) {

            hIn = cmsOpenProfileFromFile(cDefInpProf, "r");                  
       }
       else {

               hIn =  GetTIFFProfile(in);

               if (hIn == NULL)                    
                       hIn = OpenStockProfile(cDefInpProf);               
               
               hOut = OpenStockProfile(cOutProf);
                 
               if (cProofing != NULL) {

                   hProof = OpenStockProfile(cProofing);
                   dwFlags |= cmsFLAGS_SOFTPROOFING;
               }
       }

       // Take input color space

       wInput = GetInputPixelType(in);

       // Assure both, input profile and input TIFF are on same colorspace

       if (_cmsLCMScolorSpace(cmsGetColorSpace(hIn)) != (int) T_COLORSPACE(wInput))
              FatalError("Input profile is not operating in proper color space");

      
       if (!lIsDeviceLink) 
                OutputColorSpace = _cmsLCMScolorSpace(cmsGetColorSpace(hOut));
       else 
                OutputColorSpace = _cmsLCMScolorSpace(cmsGetPCS(hIn));
                
       wOutput      = ComputeOutputFormatDescriptor(wInput, OutputColorSpace, bps);

       WriteOutputTags(out, OutputColorSpace, bps);
       CopyOtherTags(in, out);

       // Ink limit
       if (InkLimit != 400.0 && 
                (OutputColorSpace == PT_CMYK || OutputColorSpace == PT_CMY)) {

           cmsHPROFILE hProfiles[10];
           int nProfiles = 0;


           hInkLimit = cmsCreateInkLimitingDeviceLink(cmsGetColorSpace(hOut), InkLimit);

           hProfiles[nProfiles++] = hIn;
           if (hProof) {
                hProfiles[nProfiles++] = hProof;
                hProfiles[nProfiles++] = hProof;
           }

           hProfiles[nProfiles++] = hOut;
           hProfiles[nProfiles++] = hInkLimit;
                   
           xform = cmsCreateMultiprofileTransform(hProfiles, nProfiles, 
                                                wInput, wOutput, Intent, dwFlags);
           
       }
       else {

		   xform = cmsCreateProofingTransform(hIn, wInput, 
											  hOut, wOutput, 
											  hProof, Intent, 
											  ProofingIntent, 
											  dwFlags);
       }

      

       // Planar stuff

       if (T_PLANAR(wInput)) 
            nPlanes = T_CHANNELS(wInput) + T_EXTRA(wInput);
       else
            nPlanes = 1;


	   // TIFF Lab of 8 bits need special handling

		if (wInput == TYPE_Lab_8 && 
			   !InputLabUsingICC &&
			   cInpProf != NULL  &&
			   stricmp(cInpProf, "*Lab") == 0) {

					cmsSetUserFormatters(xform, TYPE_Lab_8, UnrollTIFFLab8, TYPE_Lab_8, NULL); 
		}


		if (wOutput == TYPE_Lab_8 && 			   
			   cOutProf != NULL  &&
			   stricmp(cOutProf, "*Lab") == 0) {

					cmsSetUserFormatters(xform, TYPE_Lab_8, NULL, TYPE_Lab_8, PackTIFFLab8); 
		}

	   
       // Handle tile by tile or strip by strip

       if (TIFFIsTiled(in)) {

                TileBasedXform(xform, in, out, nPlanes);
       }
       else {

                StripBasedXform(xform, in, out, nPlanes);
       }


       cmsDeleteTransform(xform);
       cmsCloseProfile(hIn);
       cmsCloseProfile(hOut);
       if (hInkLimit) 
           cmsCloseProfile(hInkLimit);
       if (hProof) 
           cmsCloseProfile(hProof);


       TIFFWriteDirectory(out);

       return 1;
}
// Does convert a transform into a device link profile
cmsHPROFILE CMSEXPORT cmsTransform2DeviceLink(cmsHTRANSFORM hTransform, cmsFloat64Number Version, cmsUInt32Number dwFlags)
{
    cmsHPROFILE hProfile = NULL;
    cmsUInt32Number FrmIn, FrmOut, ChansIn, ChansOut;
    cmsUInt32Number ColorSpaceBitsIn, ColorSpaceBitsOut;
    _cmsTRANSFORM* xform = (_cmsTRANSFORM*) hTransform;
    cmsPipeline* LUT = NULL;
    cmsStage* mpe;
    cmsContext ContextID = cmsGetTransformContextID(hTransform);
    const cmsAllowedLUT* AllowedLUT;
    cmsTagSignature DestinationTag;
    cmsProfileClassSignature deviceClass; 

    _cmsAssert(hTransform != NULL);

    // Get the first mpe to check for named color
    mpe = cmsPipelineGetPtrToFirstStage(xform ->Lut);

    // Check if is a named color transform
    if (mpe != NULL) {

        if (cmsStageType(mpe) == cmsSigNamedColorElemType) {
            return CreateNamedColorDevicelink(hTransform);
        }
    }

    // First thing to do is to get a copy of the transformation
    LUT = cmsPipelineDup(xform ->Lut);
    if (LUT == NULL) return NULL;

    // Time to fix the Lab2/Lab4 issue.
    if ((xform ->EntryColorSpace == cmsSigLabData) && (Version < 4.0)) {

        if (!cmsPipelineInsertStage(LUT, cmsAT_BEGIN, _cmsStageAllocLabV2ToV4curves(ContextID)))
            goto Error;
    }

    // On the output side too
    if ((xform ->ExitColorSpace) == cmsSigLabData && (Version < 4.0)) {

        if (!cmsPipelineInsertStage(LUT, cmsAT_END, _cmsStageAllocLabV4ToV2(ContextID)))
            goto Error;
    }


    hProfile = cmsCreateProfilePlaceholder(ContextID);
    if (!hProfile) goto Error;                    // can't allocate

    cmsSetProfileVersion(hProfile, Version);

    FixColorSpaces(hProfile, xform -> EntryColorSpace, xform -> ExitColorSpace, dwFlags);

    // Optimize the LUT and precalculate a devicelink

    ChansIn  = cmsChannelsOf(xform -> EntryColorSpace);
    ChansOut = cmsChannelsOf(xform -> ExitColorSpace);

    ColorSpaceBitsIn  = _cmsLCMScolorSpace(xform -> EntryColorSpace);
    ColorSpaceBitsOut = _cmsLCMScolorSpace(xform -> ExitColorSpace);

    FrmIn  = COLORSPACE_SH(ColorSpaceBitsIn) | CHANNELS_SH(ChansIn)|BYTES_SH(2);
    FrmOut = COLORSPACE_SH(ColorSpaceBitsOut) | CHANNELS_SH(ChansOut)|BYTES_SH(2);

    deviceClass = cmsGetDeviceClass(hProfile);

     if (deviceClass == cmsSigOutputClass)
         DestinationTag = cmsSigBToA0Tag;
     else
         DestinationTag = cmsSigAToB0Tag;

    // Check if the profile/version can store the result
    if (dwFlags & cmsFLAGS_FORCE_CLUT)
        AllowedLUT = NULL;
    else
        AllowedLUT = FindCombination(LUT, Version >= 4.0, DestinationTag);

    if (AllowedLUT == NULL) {

        // Try to optimize
        _cmsOptimizePipeline(ContextID, &LUT, xform ->RenderingIntent, &FrmIn, &FrmOut, &dwFlags);
        AllowedLUT = FindCombination(LUT, Version >= 4.0, DestinationTag);

    }

    // If no way, then force CLUT that for sure can be written
    if (AllowedLUT == NULL) {

        dwFlags |= cmsFLAGS_FORCE_CLUT;
        _cmsOptimizePipeline(ContextID, &LUT, xform ->RenderingIntent, &FrmIn, &FrmOut, &dwFlags);

        // Put identity curves if needed
        if (cmsPipelineGetPtrToFirstStage(LUT) ->Type != cmsSigCurveSetElemType)
             if (!cmsPipelineInsertStage(LUT, cmsAT_BEGIN, _cmsStageAllocIdentityCurves(ContextID, ChansIn)))
                 goto Error;

        if (cmsPipelineGetPtrToLastStage(LUT) ->Type != cmsSigCurveSetElemType)
             if (!cmsPipelineInsertStage(LUT, cmsAT_END,   _cmsStageAllocIdentityCurves(ContextID, ChansOut)))
                 goto Error;

        AllowedLUT = FindCombination(LUT, Version >= 4.0, DestinationTag);
    }

    // Somethings is wrong...
    if (AllowedLUT == NULL) {
        goto Error;
    }


    if (dwFlags & cmsFLAGS_8BITS_DEVICELINK)
                     cmsPipelineSetSaveAs8bitsFlag(LUT, TRUE);

    // Tag profile with information
    if (!SetTextTags(hProfile, L"devicelink")) goto Error;

    // Store result
    if (!cmsWriteTag(hProfile, DestinationTag, LUT)) goto Error;


    if (xform -> InputColorant != NULL) {
           if (!cmsWriteTag(hProfile, cmsSigColorantTableTag, xform->InputColorant)) goto Error;
    }

    if (xform -> OutputColorant != NULL) {
           if (!cmsWriteTag(hProfile, cmsSigColorantTableOutTag, xform->OutputColorant)) goto Error;
    }

    if ((deviceClass == cmsSigLinkClass) && (xform ->Sequence != NULL)) {
        if (!_cmsWriteProfileSequence(hProfile, xform ->Sequence)) goto Error;
    }

    // Set the white point
    if (deviceClass == cmsSigInputClass) {
        if (!cmsWriteTag(hProfile, cmsSigMediaWhitePointTag, &xform ->EntryWhitePoint)) goto Error;
    }
    else {
         if (!cmsWriteTag(hProfile, cmsSigMediaWhitePointTag, &xform ->ExitWhitePoint)) goto Error;
    }

  
    // Per 7.2.15 in spec 4.3
    cmsSetHeaderRenderingIntent(hProfile, xform ->RenderingIntent);

    cmsPipelineFree(LUT);
    return hProfile;

Error:
    if (LUT != NULL) cmsPipelineFree(LUT);
    cmsCloseProfile(hProfile);
    return NULL;
}
Example #10
0
int dt_apply_printer_profile(int imgid, void **in, uint32_t width, uint32_t height, int bpp,
                             cmsHPROFILE hOutProfile, int intent, gboolean black_point_compensation)
{
  cmsHPROFILE hInProfile;
  cmsHTRANSFORM hTransform;
  cmsUInt32Number wInput, wOutput;
  int OutputColorSpace;

  if(!hOutProfile)
    return 1;

  const dt_colorspaces_color_profile_t *in_profile = dt_colorspaces_get_output_profile(imgid);
  if(!in_profile || !in_profile->profile)
  {
    fprintf(stderr, "error getting output profile for image %d\n", imgid);
    return 1;
  }
  hInProfile = in_profile->profile;

  wInput = ComputeFormatDescriptor (PT_RGB, (bpp==8?1:2));

  OutputColorSpace = _cmsLCMScolorSpace(cmsGetColorSpace(hOutProfile));
  wOutput = ComputeOutputFormatDescriptor(wInput, OutputColorSpace, 1);

  hTransform = cmsCreateTransform
    (hInProfile,  wInput,
     hOutProfile, wOutput,
     intent,
     black_point_compensation ? cmsFLAGS_BLACKPOINTCOMPENSATION : 0);

  void *out = (void *)malloc(width*height*3);

  if (bpp == 8)
  {
    const uint8_t *ptr_in = (uint8_t *)*in;
    uint8_t *ptr_out = (uint8_t *)out;

#ifdef _OPENMP
#pragma omp parallel for schedule(static) default(none) shared(ptr_in, ptr_out, hTransform, height, width)
#endif
    for (int k=0; k<height; k++)
      cmsDoTransform(hTransform, (const void *)&ptr_in[k*width*3], (void *)&ptr_out[k*width*3], width);
  }
  else
  {
    const uint16_t *ptr_in = (uint16_t *)*in;
    uint8_t *ptr_out = (uint8_t *)out;

#ifdef _OPENMP
#pragma omp parallel for schedule(static) default(none) shared(ptr_in, ptr_out, hTransform, height, width)
#endif
    for (int k=0; k<height; k++)
      cmsDoTransform(hTransform, (const void *)&ptr_in[k*width*3], (void *)&ptr_out[k*width*3], width);
  }

  cmsDeleteTransform(hTransform);

  free(*in);
  *in = out;

  return 0;
}
Example #11
0
void Color::LoadICCProfiles()
{
	if(m_iccSearchPaths!= NULL){
		delete m_iccSearchPaths;
	}
    
    const Int32 NUMSEARCHPATHS = 4;
    
	m_iccSearchPaths = new String[NUMSEARCHPATHS];
	

	Filename cmykDir = GeGetPluginPath();
	cmykDir += Filename(String("cmyk"));

	m_iccSearchPaths[0] = cmykDir.GetString();
    m_iccSearchPaths[1] = "/Library/ColorSync/Profiles/";
    m_iccSearchPaths[2] = "/Users/vidarn/Library/ColorSync";
	m_iccSearchPaths[3] = "C:\\Windows\\System32\\Spool\\Drivers\\Color\\";

	Logger::AddLine("Creating LAB profile",1);
	m_LABProfile = cmsCreateLab4Profile(NULL);

	Logger::AddLine("Creating default sRGB profile",1);
	m_displayProfile = cmsCreate_sRGBProfile();
	m_RGBProfiles.Insert(vnColorProfile("sRGB",m_displayProfile),0);

    for(Int32 i=0;i<NUMSEARCHPATHS;++i){
        BrowseFiles* bf = BrowseFiles::Alloc();
        Filename dir(m_iccSearchPaths[i]);
        bf->Init(dir,FALSE);
        int RGBPos  = m_RGBProfiles.GetCount();
        int CMYKPos = m_CMYKProfiles.GetCount();
        int spotPos = m_spotProfiles.GetCount();

        if (bf)
        {
            while (bf->GetNext())
            {
                Filename fileName = bf->GetFilename();
                fileName.SetDirectory(dir);
                String str = fileName.GetString();
                Char *buffer = new Char[str.GetCStringLen()+1];
                str.GetCString(buffer,str.GetCStringLen()+1);
				Logger::AddLine(buffer,1);
                cmsHPROFILE profile = cmsOpenProfileFromFile(buffer, "r");
                if(profile != NULL){
                    cmsColorSpaceSignature sig = cmsGetColorSpace(profile);
                    Int32 length = cmsGetProfileInfoASCII(profile,cmsInfoDescription,"en","US",NULL,0);
                    Char *buffer2 = new Char[length];
                    cmsGetProfileInfoASCII(profile,cmsInfoDescription,"en","US",buffer2,length);
                    String info(buffer2);
                    int pt = _cmsLCMScolorSpace(sig);
                    if(PT_RGB == pt){
						Logger::AddLine("RGB profile",1);
                        m_RGBProfiles.Insert(vnColorProfile(info,profile),RGBPos);
                        RGBPos++;
                    }
                    if(PT_CMYK == pt){
                        cmsHTRANSFORM xform = cmsCreateTransform(profile,TYPE_NAMED_COLOR_INDEX,m_displayProfile,TYPE_RGB_DBL,INTENT_PERCEPTUAL,0);
                        if(xform != NULL){
                            cmsNAMEDCOLORLIST* colorList = cmsGetNamedColorList(xform);
                            if(colorList != NULL){
                                m_spotProfiles.Insert(vnColorProfile(info,profile),spotPos);
                                spotPos++;
                            }
                            else{
								Logger::AddLine("CMYK profile",1);
                                m_CMYKProfiles.Insert(vnColorProfile(info,profile),CMYKPos);
                                CMYKPos++;
                            }
							cmsDeleteTransform(xform);
                        }
                    }
                    delete buffer2;
                } else {
					Logger::AddLine("Invalid",1);
				}
                delete buffer;
            }
        }
        BrowseFiles::Free(bf);
    }
}
Example #12
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);
    }
}
Example #13
0
/* Get the link from the CMS. TODO:  Add error checking */
gcmmhlink_t
gscms_get_link(gcmmhprofile_t  lcms_srchandle,
               gcmmhprofile_t lcms_deshandle,
               gsicc_rendering_param_t *rendering_params, 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;
    unsigned int flag;

    /* Check for case of request for a transfrom from a device link profile
       in that case, the destination profile is NULL */

    /* 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 0
    src_data_type = src_data_type | ENDIAN16_SH(1);
#endif
    if (lcms_deshandle != NULL) {
        des_color_space  = cmsGetColorSpace(lcms_deshandle);
    } else {
        /* We must have a device link profile. */
        des_color_space = cmsGetPCS(lcms_deshandle);
    }
    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));
    /* endian */
#if 0
    des_data_type = des_data_type | ENDIAN16_SH(1);
#endif
    /* Set up the flags */
    flag = cmsFLAGS_HIGHRESPRECALC;
    if (rendering_params->black_point_comp == gsBLACKPTCOMP_ON
            || rendering_params->black_point_comp == gsBLACKPTCOMP_ON_OR) {
        flag = (flag | cmsFLAGS_BLACKPOINTCOMPENSATION);
    }
    if (rendering_params->preserve_black == gsBLACKPRESERVE_KONLY) {
        switch (rendering_params->rendering_intent) {
        case INTENT_PERCEPTUAL:
            rendering_params->rendering_intent = INTENT_PRESERVE_K_ONLY_PERCEPTUAL;
            break;
        case INTENT_RELATIVE_COLORIMETRIC:
            rendering_params->rendering_intent = INTENT_PRESERVE_K_ONLY_RELATIVE_COLORIMETRIC;
            break;
        case INTENT_SATURATION:
            rendering_params->rendering_intent = INTENT_PRESERVE_K_ONLY_SATURATION;
            break;
        default:
            break;
        }
    }
    if (rendering_params->preserve_black == gsBLACKPRESERVE_KPLANE) {
        switch (rendering_params->rendering_intent) {
        case INTENT_PERCEPTUAL:
            rendering_params->rendering_intent = INTENT_PRESERVE_K_PLANE_PERCEPTUAL;
            break;
        case INTENT_RELATIVE_COLORIMETRIC:
            rendering_params->rendering_intent = INTENT_PRESERVE_K_PLANE_RELATIVE_COLORIMETRIC;
            break;
        case INTENT_SATURATION:
            rendering_params->rendering_intent = INTENT_PRESERVE_K_PLANE_SATURATION;
            break;
        default:
            break;
        }
    }
    /* Create the link */
    return cmsCreateTransformTHR((cmsContext)memory,
                                 lcms_srchandle, src_data_type,
                                 lcms_deshandle, des_data_type,
                                 rendering_params->rendering_intent, flag | cmm_flags);
    /* cmsFLAGS_HIGHRESPRECALC)  cmsFLAGS_NOTPRECALC  cmsFLAGS_LOWRESPRECALC*/
}