Esempio n. 1
0
// Creates a fake NULL profile. This profile return 1 channel as always 0. 
// Is useful only for gamut checking tricks
cmsHPROFILE CMSEXPORT cmsCreateNULLProfileTHR(cmsContext ContextID)
{
    cmsHPROFILE hProfile;        
    cmsPipeline* LUT = NULL;
    cmsStage* PostLin;
    cmsToneCurve* EmptyTab;
    cmsUInt16Number Zero[2] = { 0, 0 };

    hProfile = cmsCreateProfilePlaceholder(ContextID);
    if (!hProfile)                          // can't allocate
        return NULL;

    cmsSetProfileVersion(hProfile, 4.2);

    if (!SetTextTags(hProfile, L"NULL profile built-in")) goto Error;    

    

    cmsSetDeviceClass(hProfile, cmsSigOutputClass);
    cmsSetColorSpace(hProfile,  cmsSigGrayData);
    cmsSetPCS(hProfile,         cmsSigLabData);

    // An empty LUTs is all we need
    LUT = cmsPipelineAlloc(ContextID, 1, 1);
    if (LUT == NULL) goto Error;

    EmptyTab = cmsBuildTabulatedToneCurve16(ContextID, 2, Zero);       
    PostLin = cmsStageAllocToneCurves(ContextID, 1, &EmptyTab);
    cmsFreeToneCurve(EmptyTab);

    cmsPipelineInsertStage(LUT, cmsAT_END, PostLin);

    if (!cmsWriteTag(hProfile, cmsSigBToA0Tag, (void*) LUT)) goto Error;
    if (!cmsWriteTag(hProfile, cmsSigMediaWhitePointTag, cmsD50_XYZ())) goto Error;

    cmsPipelineFree(LUT);       
    return hProfile;

Error:

    if (LUT != NULL)
        cmsPipelineFree(LUT);

    if (hProfile != NULL)
        cmsCloseProfile(hProfile);

    return NULL;
}
Esempio n. 2
0
// 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);

    // 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;
}
Esempio n. 3
0
static
cmsHPROFILE CreateNamedColorDevicelink(cmsHTRANSFORM xform)
{
    _LPcmsTRANSFORM v = (_LPcmsTRANSFORM) xform;
    cmsHPROFILE hICC;
    cmsCIEXYZ WhitePoint;    
    int i, nColors;
    size_t Size;
    LPcmsNAMEDCOLORLIST nc2;


    hICC = _cmsCreateProfilePlaceholder();
    if (hICC == NULL) return NULL;

    cmsSetRenderingIntent(hICC, v -> Intent); 
    cmsSetDeviceClass(hICC, icSigNamedColorClass);
    cmsSetColorSpace(hICC, v ->ExitColorSpace);
    cmsSetPCS(hICC, cmsGetPCS(v ->InputProfile));
    cmsTakeMediaWhitePoint(&WhitePoint, v ->InputProfile);

    cmsAddTag(hICC, icSigMediaWhitePointTag,  &WhitePoint);
    cmsAddTag(hICC, icSigDeviceMfgDescTag,       (LPVOID) "LittleCMS");       
    cmsAddTag(hICC, icSigProfileDescriptionTag,  (LPVOID) "Named color Device link");
    cmsAddTag(hICC, icSigDeviceModelDescTag,     (LPVOID) "Named color Device link");      
    

    nColors = cmsNamedColorCount(xform);
    nc2     = cmsAllocNamedColorList(nColors);

    Size = sizeof(cmsNAMEDCOLORLIST) + (sizeof(cmsNAMEDCOLOR) * (nColors-1));

    CopyMemory(nc2, v->NamedColorList, Size);
    nc2 ->ColorantCount = _cmsChannelsOf(v ->ExitColorSpace);

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

    cmsAddTag(hICC, icSigNamedColor2Tag, (void*) nc2);
    cmsFreeNamedColorList(nc2);

    return hICC;
}
Esempio n. 4
0
cmsHPROFILE LCMSEXPORT cmsCreateLinearizationDeviceLink(icColorSpaceSignature ColorSpace,
                                                        LPGAMMATABLE TransferFunctions[])
{
       cmsHPROFILE hICC;
       LPLUT Lut;
           
        
       hICC = _cmsCreateProfilePlaceholder();
       if (!hICC)                          // can't allocate
            return NULL;


       cmsSetDeviceClass(hICC,      icSigLinkClass);
       cmsSetColorSpace(hICC,       ColorSpace);
       cmsSetPCS(hICC,              ColorSpace);
       cmsSetRenderingIntent(hICC,  INTENT_PERCEPTUAL); 

     
       // Creates a LUT with prelinearization step only
       Lut = cmsAllocLUT();
       if (Lut == NULL) return NULL;

       // Set up channels
       Lut ->InputChan = Lut ->OutputChan = _cmsChannelsOf(ColorSpace);

       // Copy tables to LUT
       cmsAllocLinearTable(Lut, TransferFunctions, 1);

       // Create tags       
       cmsAddTag(hICC, icSigDeviceMfgDescTag,       (LPVOID) "(lcms internal)");
       cmsAddTag(hICC, icSigProfileDescriptionTag,  (LPVOID) "lcms linearization device link");
       cmsAddTag(hICC, icSigDeviceModelDescTag,     (LPVOID) "linearization built-in");      
    
       cmsAddTag(hICC, icSigMediaWhitePointTag, (LPVOID) cmsD50_XYZ());
       cmsAddTag(hICC, icSigAToB0Tag, (LPVOID) Lut);
       
       // LUT is already on virtual profile
       cmsFreeLUT(Lut);

       // Ok, done
       return hICC;
}
Esempio n. 5
0
// Creates a fake Lab identity.
cmsHPROFILE CMSEXPORT cmsCreateLab2ProfileTHR(cmsContext ContextID, const cmsCIExyY* WhitePoint)
{
    cmsHPROFILE hProfile;
    cmsPipeline* LUT = NULL;

    hProfile = cmsCreateRGBProfileTHR(ContextID, WhitePoint == NULL ? cmsD50_xyY() : WhitePoint, NULL, NULL);
    if (hProfile == NULL) return NULL;

    cmsSetProfileVersion(hProfile, 2.1);

    cmsSetDeviceClass(hProfile, cmsSigAbstractClass);
    cmsSetColorSpace(hProfile,  cmsSigLabData);
    cmsSetPCS(hProfile,         cmsSigLabData);

    if (!SetTextTags(hProfile, L"Lab identity built-in")) return NULL;

    // An identity LUT is all we need
    LUT = cmsPipelineAlloc(ContextID, 3, 3);
    if (LUT == NULL) goto Error;

    if (!cmsPipelineInsertStage(LUT, cmsAT_BEGIN, _cmsStageAllocIdentityCLut(ContextID, 3)))
        goto Error;

    if (!cmsWriteTag(hProfile, cmsSigAToB0Tag, LUT)) goto Error;
    cmsPipelineFree(LUT);

    return hProfile;

Error:

    if (LUT != NULL)
        cmsPipelineFree(LUT);

    if (hProfile != NULL)
        cmsCloseProfile(hProfile);

    return NULL;
}
Esempio n. 6
0
// Creates a fake XYZ identity
cmsHPROFILE CMSEXPORT cmsCreateXYZProfileTHR(cmsContext ContextID)
{
    cmsHPROFILE hProfile;
    cmsPipeline* LUT = NULL;

    hProfile = cmsCreateRGBProfileTHR(ContextID, cmsD50_xyY(), NULL, NULL);
    if (hProfile == NULL) return NULL;

    cmsSetProfileVersion(hProfile, 4.3);

    cmsSetDeviceClass(hProfile, cmsSigAbstractClass);
    cmsSetColorSpace(hProfile,  cmsSigXYZData);
    cmsSetPCS(hProfile,         cmsSigXYZData);

    if (!SetTextTags(hProfile, L"XYZ identity built-in")) goto Error;

    // An identity LUT is all we need
    LUT = cmsPipelineAlloc(ContextID, 3, 3);
    if (LUT == NULL) goto Error;

    if (!cmsPipelineInsertStage(LUT, cmsAT_BEGIN, _cmsStageAllocIdentityCurves(ContextID, 3)))
        goto Error;

    if (!cmsWriteTag(hProfile, cmsSigAToB0Tag, LUT)) goto Error;
    cmsPipelineFree(LUT);

    return hProfile;

Error:

    if (LUT != NULL)
        cmsPipelineFree(LUT);

    if (hProfile != NULL)
        cmsCloseProfile(hProfile);

    return NULL;
}
Esempio n. 7
0
int main(int argc, char *argv[])
{
    LPLUT AToB0;
    cmsHPROFILE hProfile;

    fprintf(stderr, "Creating grayer.icm...");

    unlink("grayer.icm");
    hProfile = cmsOpenProfileFromFile("grayer.icm", "w");


    AToB0 = cmsAllocLUT();


    cmsAlloc3DGrid(AToB0, GRID_POINTS, 3, 3);

    cmsSample3DGrid(AToB0, Forward, NULL, 0);

    cmsAddTag(hProfile, icSigAToB0Tag, AToB0);

    cmsSetColorSpace(hProfile, icSigLabData);
    cmsSetPCS(hProfile, icSigLabData);
    cmsSetDeviceClass(hProfile, icSigAbstractClass);

    cmsAddTag(hProfile, icSigProfileDescriptionTag, "Little cms Grayifier");
    cmsAddTag(hProfile, icSigCopyrightTag,          "Copyright (c) Marti Maria 2003. All rights reserved.");
    cmsAddTag(hProfile, icSigDeviceMfgDescTag,      "Little cms");
    cmsAddTag(hProfile, icSigDeviceModelDescTag,    "Grayifier abstract profile");


    cmsCloseProfile(hProfile);

    cmsFreeLUT(AToB0);

    fprintf(stderr, "Done.\n");

    return 0;
}
Esempio n. 8
0
cmsHPROFILE LCMSEXPORT cmsCreateNULLProfile(void)
{
        cmsHPROFILE hProfile;        
        LPLUT Lut;
        LPGAMMATABLE EmptyTab;

        hProfile = _cmsCreateProfilePlaceholder();
        if (!hProfile)                          // can't allocate
                return NULL;
      
        cmsSetDeviceClass(hProfile, icSigOutputClass);
        cmsSetColorSpace(hProfile,  icSigGrayData);
        cmsSetPCS(hProfile,         icSigLabData);
        

       // An empty LUTs is all we need
       Lut = cmsAllocLUT();
       if (Lut == NULL) {
           cmsCloseProfile(hProfile);
           return NULL;
           }

       Lut -> InputChan = 3;
       Lut -> OutputChan = 1;

       EmptyTab = cmsAllocGamma(2);
       EmptyTab ->GammaTable[0] = 0;
       EmptyTab ->GammaTable[1] = 0;

       cmsAllocLinearTable(Lut, &EmptyTab, 2);
        
       cmsAddTag(hProfile, icSigBToA0Tag, (LPVOID) Lut);
    
       cmsFreeLUT(Lut);
       cmsFreeGamma(EmptyTab);
       
       return hProfile;
}
Esempio n. 9
0
// Creates a fake Lab identity.
cmsHPROFILE LCMSEXPORT cmsCreateLab4Profile(LPcmsCIExyY WhitePoint)
{
        cmsHPROFILE hProfile;        
        LPLUT Lut;

        hProfile = cmsCreateRGBProfile(WhitePoint == NULL ? cmsD50_xyY() : WhitePoint, NULL, NULL);
        if (hProfile == NULL) return NULL;

        cmsSetProfileICCversion(hProfile, 0x4000000);

        cmsSetDeviceClass(hProfile, icSigAbstractClass);
        cmsSetColorSpace(hProfile,  icSigLabData);
        cmsSetPCS(hProfile,         icSigLabData);

        cmsAddTag(hProfile, icSigDeviceMfgDescTag,     (LPVOID) "(lcms internal)"); 
        cmsAddTag(hProfile, icSigProfileDescriptionTag, (LPVOID) "lcms Lab identity v4");      
        cmsAddTag(hProfile, icSigDeviceModelDescTag,    (LPVOID) "Lab v4 built-in");      


       // An empty LUTs is all we need
       Lut = Create3x3EmptyLUT();
       if (Lut == NULL) {
           cmsCloseProfile(hProfile);
           return NULL;
           }

       Lut -> wFlags |= LUT_V4_INPUT_EMULATE_V2;
       cmsAddTag(hProfile, icSigAToB0Tag,    (LPVOID) Lut);

       Lut -> wFlags |= LUT_V4_OUTPUT_EMULATE_V2;
       cmsAddTag(hProfile, icSigBToA0Tag,    (LPVOID) Lut);
    
       cmsFreeLUT(Lut);

       return hProfile;
}
Esempio n. 10
0
cmsBool _setHeaderInfo(cmsHPROFILE pf, jbyte* pBuffer, jint bufferSize)
{
  cmsICCHeader pfHeader = { 0 };

  if (pBuffer == NULL || bufferSize < sizeof(cmsICCHeader)) {
    return FALSE;
  }

  memcpy(&pfHeader, pBuffer, sizeof(cmsICCHeader));

  // now set header fields, which we can access using the lcms2 public API
  cmsSetHeaderFlags(pf, pfHeader.flags);
  cmsSetHeaderManufacturer(pf, pfHeader.manufacturer);
  cmsSetHeaderModel(pf, pfHeader.model);
  cmsSetHeaderAttributes(pf, pfHeader.attributes);
  cmsSetHeaderProfileID(pf, (cmsUInt8Number*)&(pfHeader.profileID));
  cmsSetHeaderRenderingIntent(pf, pfHeader.renderingIntent);
  cmsSetPCS(pf, pfHeader.pcs);
  cmsSetColorSpace(pf, pfHeader.colorSpace);
  cmsSetDeviceClass(pf, pfHeader.deviceClass);
  cmsSetEncodedICCversion(pf, pfHeader.version);

  return TRUE;
}
Esempio n. 11
0
cmsHPROFILE CMSEXPORT cmsCreateBCHSWabstractProfileTHR(cmsContext ContextID,
    int nLUTPoints,
    cmsFloat64Number Bright,
    cmsFloat64Number Contrast,
    cmsFloat64Number Hue,
    cmsFloat64Number Saturation,
    int TempSrc,
    int TempDest)
{
    cmsHPROFILE hICC;
    cmsPipeline* Pipeline;
    BCHSWADJUSTS bchsw;
    cmsCIExyY WhitePnt;
    cmsStage* CLUT;
    cmsUInt32Number Dimensions[MAX_INPUT_DIMENSIONS];
    int i;

    bchsw.Brightness = Bright;
    bchsw.Contrast   = Contrast;
    bchsw.Hue        = Hue;
    bchsw.Saturation = Saturation;

    cmsWhitePointFromTemp(&WhitePnt, TempSrc );
    cmsxyY2XYZ(&bchsw.WPsrc, &WhitePnt);

    cmsWhitePointFromTemp(&WhitePnt, TempDest);
    cmsxyY2XYZ(&bchsw.WPdest, &WhitePnt);

    hICC = cmsCreateProfilePlaceholder(ContextID);
    if (!hICC)                          // can't allocate
        return NULL;


    cmsSetDeviceClass(hICC,      cmsSigAbstractClass);
    cmsSetColorSpace(hICC,       cmsSigLabData);
    cmsSetPCS(hICC,              cmsSigLabData);

    cmsSetHeaderRenderingIntent(hICC,  INTENT_PERCEPTUAL);

    // Creates a Pipeline with 3D grid only
    Pipeline = cmsPipelineAlloc(ContextID, 3, 3);
    if (Pipeline == NULL) {
        cmsCloseProfile(hICC);
        return NULL;
    }

    for (i=0; i < MAX_INPUT_DIMENSIONS; i++) Dimensions[i] = nLUTPoints;
    CLUT = cmsStageAllocCLut16bitGranular(ContextID, Dimensions, 3, 3, NULL);
    if (CLUT == NULL) return NULL;


    if (!cmsStageSampleCLut16bit(CLUT, bchswSampler, (void*) &bchsw, 0)) {

        // Shouldn't reach here
        goto Error;
    }

    if (!cmsPipelineInsertStage(Pipeline, cmsAT_END, CLUT)) {
        goto Error;
    }

    // Create tags
    if (!SetTextTags(hICC, L"BCHS built-in")) return NULL;

    cmsWriteTag(hICC, cmsSigMediaWhitePointTag, (void*) cmsD50_XYZ());

    cmsWriteTag(hICC, cmsSigAToB0Tag, (void*) Pipeline);

    // Pipeline is already on virtual profile
    cmsPipelineFree(Pipeline);

    // Ok, done
    return hICC;

Error:
    cmsPipelineFree(Pipeline);
    cmsCloseProfile(hICC);
    return NULL;
}
Esempio n. 12
0
cmsHPROFILE LCMSEXPORT cmsCreateInkLimitingDeviceLink(icColorSpaceSignature ColorSpace,
                                                        double Limit)
{
       cmsHPROFILE hICC;
       LPLUT Lut;
           
       if (ColorSpace != icSigCmykData) {
            cmsSignalError(LCMS_ERRC_ABORTED, "InkLimiting: Only CMYK currently supported");
            return NULL;
       }

       if (Limit < 0.0 || Limit > 400) {

           cmsSignalError(LCMS_ERRC_WARNING, "InkLimiting: Limit should be between 0..400");        
           if (Limit < 0) Limit = 0;
           if (Limit > 400) Limit = 400;
       
       }

      hICC = _cmsCreateProfilePlaceholder();
       if (!hICC)                          // can't allocate
            return NULL;
              

       cmsSetDeviceClass(hICC,      icSigLinkClass);
       cmsSetColorSpace(hICC,       ColorSpace);
       cmsSetPCS(hICC,              ColorSpace);
       cmsSetRenderingIntent(hICC,  INTENT_PERCEPTUAL); 

      
       // Creates a LUT with 3D grid only
       Lut = cmsAllocLUT();
       if (Lut == NULL) {
           cmsCloseProfile(hICC);
           return NULL;
           }


       cmsAlloc3DGrid(Lut, 17, _cmsChannelsOf(ColorSpace), 
                               _cmsChannelsOf(ColorSpace));

       if (!cmsSample3DGrid(Lut, InkLimitingSampler, (LPVOID) &Limit, 0)) {

                // Shouldn't reach here
                cmsFreeLUT(Lut);
                cmsCloseProfile(hICC);
                return NULL;
       }    
       
       // Create tags
        
       cmsAddTag(hICC, icSigDeviceMfgDescTag,      (LPVOID) "(lcms internal)"); 
       cmsAddTag(hICC, icSigProfileDescriptionTag, (LPVOID) "lcms ink limiting device link");  
       cmsAddTag(hICC, icSigDeviceModelDescTag,    (LPVOID) "ink limiting built-in");      
       
       cmsAddTag(hICC, icSigMediaWhitePointTag, (LPVOID) cmsD50_XYZ());

       cmsAddTag(hICC, icSigAToB0Tag, (LPVOID) Lut);
       
       // LUT is already on virtual profile
       cmsFreeLUT(Lut);

       // Ok, done
       return hICC;
}
Esempio n. 13
0
cmsHPROFILE LCMSEXPORT cmsCreateRGBProfile(LPcmsCIExyY WhitePoint,
                                LPcmsCIExyYTRIPLE Primaries,
                                LPGAMMATABLE TransferFunction[3])
{
       cmsHPROFILE hICC;
       cmsCIEXYZ tmp;
       MAT3 MColorants;
       cmsCIEXYZTRIPLE Colorants;
       cmsCIExyY MaxWhite;
      

       hICC = _cmsCreateProfilePlaceholder();
       if (!hICC)                          // can't allocate
            return NULL;
              

       cmsSetDeviceClass(hICC,      icSigDisplayClass);
       cmsSetColorSpace(hICC,       icSigRgbData);
       cmsSetPCS(hICC,              icSigXYZData);
       cmsSetRenderingIntent(hICC,  INTENT_PERCEPTUAL); 
        
      
       // Implement profile using following tags:
       //
       //  1 icSigProfileDescriptionTag
       //  2 icSigMediaWhitePointTag
       //  3 icSigRedColorantTag
       //  4 icSigGreenColorantTag
       //  5 icSigBlueColorantTag
       //  6 icSigRedTRCTag
       //  7 icSigGreenTRCTag
       //  8 icSigBlueTRCTag

       // This conforms a standard RGB DisplayProfile as says ICC, and then I add

       // 9 icSigChromaticityTag

       // As addendum II
      

       // Fill-in the tags

       cmsAddTag(hICC, icSigDeviceMfgDescTag,       (LPVOID) "(lcms internal)");
       cmsAddTag(hICC, icSigProfileDescriptionTag,  (LPVOID) "lcms RGB virtual profile");
       cmsAddTag(hICC, icSigDeviceModelDescTag,     (LPVOID) "rgb built-in");      
          

       if (WhitePoint) {

       cmsxyY2XYZ(&tmp, WhitePoint);
       cmsAddTag(hICC, icSigMediaWhitePointTag, (LPVOID) &tmp);
       }

       if (WhitePoint && Primaries) {

        MaxWhite.x =  WhitePoint -> x;
        MaxWhite.y =  WhitePoint -> y;
        MaxWhite.Y =  1.0;

       if (!cmsBuildRGB2XYZtransferMatrix(&MColorants, &MaxWhite, Primaries))
       {
              cmsCloseProfile(hICC);
              return NULL;
       }  
     
       cmsAdaptMatrixToD50(&MColorants, &MaxWhite);

       Colorants.Red.X = MColorants.v[0].n[0];
       Colorants.Red.Y = MColorants.v[1].n[0];
       Colorants.Red.Z = MColorants.v[2].n[0];

       Colorants.Green.X = MColorants.v[0].n[1];
       Colorants.Green.Y = MColorants.v[1].n[1];
       Colorants.Green.Z = MColorants.v[2].n[1];

       Colorants.Blue.X = MColorants.v[0].n[2];
       Colorants.Blue.Y = MColorants.v[1].n[2];
       Colorants.Blue.Z = MColorants.v[2].n[2];

       cmsAddTag(hICC, icSigRedColorantTag,   (LPVOID) &Colorants.Red);
       cmsAddTag(hICC, icSigBlueColorantTag,  (LPVOID) &Colorants.Blue);
       cmsAddTag(hICC, icSigGreenColorantTag, (LPVOID) &Colorants.Green);
       }


       if (TransferFunction) {

       // In case of gamma, we must dup' the table pointer

        cmsAddTag(hICC, icSigRedTRCTag,   (LPVOID) TransferFunction[0]);
        cmsAddTag(hICC, icSigGreenTRCTag, (LPVOID) TransferFunction[1]);
        cmsAddTag(hICC, icSigBlueTRCTag,  (LPVOID) TransferFunction[2]);
       }

       if (Primaries) {
            cmsAddTag(hICC, icSigChromaticityTag, (LPVOID) Primaries);
       }

       return hICC;
}
Esempio n. 14
0
// This function creates a profile based on White point, primaries and
// transfer functions.
cmsHPROFILE CMSEXPORT cmsCreateRGBProfileTHR(cmsContext ContextID,
                                          const cmsCIExyY* WhitePoint,
                                          const cmsCIExyYTRIPLE* Primaries,
                                          cmsToneCurve* const TransferFunction[3])
{
    cmsHPROFILE hICC;
    cmsMAT3 MColorants;
    cmsCIEXYZTRIPLE Colorants;
    cmsCIExyY MaxWhite;
    cmsMAT3 CHAD;
    cmsCIEXYZ WhitePointXYZ;

    hICC = cmsCreateProfilePlaceholder(ContextID);
    if (!hICC)                          // can't allocate
        return NULL;

    cmsSetProfileVersion(hICC, 4.3);

    cmsSetDeviceClass(hICC,      cmsSigDisplayClass);
    cmsSetColorSpace(hICC,       cmsSigRgbData);
    cmsSetPCS(hICC,              cmsSigXYZData);

    cmsSetHeaderRenderingIntent(hICC,  INTENT_PERCEPTUAL);


    // Implement profile using following tags:
    //
    //  1 cmsSigProfileDescriptionTag
    //  2 cmsSigMediaWhitePointTag
    //  3 cmsSigRedColorantTag
    //  4 cmsSigGreenColorantTag
    //  5 cmsSigBlueColorantTag
    //  6 cmsSigRedTRCTag
    //  7 cmsSigGreenTRCTag
    //  8 cmsSigBlueTRCTag
    //  9 Chromatic adaptation Tag
    // This conforms a standard RGB DisplayProfile as says ICC, and then I add (As per addendum II)
    // 10 cmsSigChromaticityTag


    if (!SetTextTags(hICC, L"RGB built-in")) goto Error;

    if (WhitePoint) {

        if (!cmsWriteTag(hICC, cmsSigMediaWhitePointTag, cmsD50_XYZ())) goto Error;

        cmsxyY2XYZ(&WhitePointXYZ, WhitePoint);
        _cmsAdaptationMatrix(&CHAD, NULL, &WhitePointXYZ, cmsD50_XYZ());

        // This is a V4 tag, but many CMM does read and understand it no matter which version
        if (!cmsWriteTag(hICC, cmsSigChromaticAdaptationTag, (void*) &CHAD)) goto Error;
    }

    if (WhitePoint && Primaries) {

        MaxWhite.x =  WhitePoint -> x;
        MaxWhite.y =  WhitePoint -> y;
        MaxWhite.Y =  1.0;

        if (!_cmsBuildRGB2XYZtransferMatrix(&MColorants, &MaxWhite, Primaries)) goto Error;

        Colorants.Red.X   = MColorants.v[0].n[0];
        Colorants.Red.Y   = MColorants.v[1].n[0];
        Colorants.Red.Z   = MColorants.v[2].n[0];

        Colorants.Green.X = MColorants.v[0].n[1];
        Colorants.Green.Y = MColorants.v[1].n[1];
        Colorants.Green.Z = MColorants.v[2].n[1];

        Colorants.Blue.X  = MColorants.v[0].n[2];
        Colorants.Blue.Y  = MColorants.v[1].n[2];
        Colorants.Blue.Z  = MColorants.v[2].n[2];

        if (!cmsWriteTag(hICC, cmsSigRedColorantTag,   (void*) &Colorants.Red)) goto Error;
        if (!cmsWriteTag(hICC, cmsSigBlueColorantTag,  (void*) &Colorants.Blue)) goto Error;
        if (!cmsWriteTag(hICC, cmsSigGreenColorantTag, (void*) &Colorants.Green)) goto Error;
    }


    if (TransferFunction) {

        // Tries to minimize space. Thanks to Richard Hughes for this nice idea         
        if (!cmsWriteTag(hICC, cmsSigRedTRCTag,   (void*) TransferFunction[0])) goto Error;

        if (TransferFunction[1] == TransferFunction[0]) {

            if (!cmsLinkTag (hICC, cmsSigGreenTRCTag, cmsSigRedTRCTag)) goto Error;

        } else {

            if (!cmsWriteTag(hICC, cmsSigGreenTRCTag, (void*) TransferFunction[1])) goto Error;
        }

        if (TransferFunction[2] == TransferFunction[0]) {

            if (!cmsLinkTag (hICC, cmsSigBlueTRCTag, cmsSigRedTRCTag)) goto Error;

        } else {

            if (!cmsWriteTag(hICC, cmsSigBlueTRCTag, (void*) TransferFunction[2])) goto Error;
        }
    }

    if (Primaries) {
        if (!cmsWriteTag(hICC, cmsSigChromaticityTag, (void*) Primaries)) goto Error;
    }


    return hICC;

Error:
    if (hICC)
        cmsCloseProfile(hICC);
    return NULL;
}
Esempio n. 15
0
cmsHPROFILE CMSEXPORT cmsCreateInkLimitingDeviceLinkTHR(cmsContext ContextID,
                                                     cmsColorSpaceSignature ColorSpace,
                                                     cmsFloat64Number Limit)
{
    cmsHPROFILE hICC;
    cmsPipeline* LUT;
    cmsStage* CLUT;
    int nChannels;

    if (ColorSpace != cmsSigCmykData) {
        cmsSignalError(ContextID, cmsERROR_COLORSPACE_CHECK, "InkLimiting: Only CMYK currently supported");
        return NULL;
    }

    if (Limit < 0.0 || Limit > 400) {

        cmsSignalError(ContextID, cmsERROR_RANGE, "InkLimiting: Limit should be between 0..400");
        if (Limit < 0) Limit = 0;
        if (Limit > 400) Limit = 400;

    }

    hICC = cmsCreateProfilePlaceholder(ContextID);
    if (!hICC)                          // can't allocate
        return NULL;

    cmsSetProfileVersion(hICC, 4.3);

    cmsSetDeviceClass(hICC,      cmsSigLinkClass);
    cmsSetColorSpace(hICC,       ColorSpace);
    cmsSetPCS(hICC,              ColorSpace);

    cmsSetHeaderRenderingIntent(hICC,  INTENT_PERCEPTUAL);


    // Creates a Pipeline with 3D grid only
    LUT = cmsPipelineAlloc(ContextID, 4, 4);
    if (LUT == NULL) goto Error;


    nChannels = cmsChannelsOf(ColorSpace);

    CLUT = cmsStageAllocCLut16bit(ContextID, 17, nChannels, nChannels, NULL);
    if (CLUT == NULL) goto Error;

    if (!cmsStageSampleCLut16bit(CLUT, InkLimitingSampler, (void*) &Limit, 0)) goto Error;

    if (!cmsPipelineInsertStage(LUT, cmsAT_BEGIN, _cmsStageAllocIdentityCurves(ContextID, nChannels)) ||
        !cmsPipelineInsertStage(LUT, cmsAT_END, CLUT) ||
        !cmsPipelineInsertStage(LUT, cmsAT_END, _cmsStageAllocIdentityCurves(ContextID, nChannels)))
        goto Error;

    // Create tags
    if (!SetTextTags(hICC, L"ink-limiting built-in")) goto Error;

    if (!cmsWriteTag(hICC, cmsSigAToB0Tag, (void*) LUT))  goto Error;
    if (!SetSeqDescTag(hICC, "ink-limiting built-in")) goto Error;

    // cmsPipeline is already on virtual profile
    cmsPipelineFree(LUT);

    // Ok, done
    return hICC;

Error:
    if (LUT != NULL)
        cmsPipelineFree(LUT);

    if (hICC != NULL)
        cmsCloseProfile(hICC);

    return NULL;
}
cmsHPROFILE LCMSEXPORT f_cmsCreateBCHSWabstractProfile(int nLUTPoints,
						       double Exposure,
						       double Bright, 
						       double Contrast,
						       double Hue,
						       double Saturation,
						       LPcmsCIExyY current_wp,
						       LPcmsCIExyY destination_wp,
						       LPGAMMATABLE Tables [])
{
	cmsHPROFILE hICC;
	LPLUT Lut;
	BCHSWADJUSTS bchsw;
	cmsCIExyY WhitePnt;
	
	bchsw.Exposure   = Exposure;
	bchsw.Brightness = Bright;
	bchsw.Contrast   = Contrast;
	bchsw.Hue        = Hue;
	bchsw.Saturation = Saturation;
	
	cmsxyY2XYZ(&bchsw.WPsrc, current_wp);
	cmsxyY2XYZ(&bchsw.WPdest, destination_wp);
	
	hICC = _cmsCreateProfilePlaceholder();
	if (!hICC)                          // can't allocate
		return NULL;
	
	cmsSetDeviceClass(hICC,      icSigAbstractClass);
	cmsSetColorSpace(hICC,       icSigLabData);
	cmsSetPCS(hICC,              icSigLabData);
	
	cmsSetRenderingIntent(hICC,  INTENT_PERCEPTUAL); 
	
	// Creates a LUT with 3D grid only
	Lut = cmsAllocLUT();
	
	cmsAlloc3DGrid(Lut, nLUTPoints, 3, 3);
	
	if (Tables != NULL)
	       cmsAllocLinearTable (Lut, Tables, 1);
	
       if (!cmsSample3DGrid(Lut, bchswSampler, (LPVOID) &bchsw, 0)) {
	       
	       // Shouldn't reach here
	       cmsFreeLUT(Lut);
	       cmsCloseProfile(hICC);
	       return NULL;
       }    
       
       // Create tags
       
       cmsAddTag(hICC, icSigDeviceMfgDescTag,      (LPVOID) "(f-spot internal)"); 
       cmsAddTag(hICC, icSigProfileDescriptionTag, (LPVOID) "f-spot BCHSW abstract profile");  
       cmsAddTag(hICC, icSigDeviceModelDescTag,    (LPVOID) "BCHSW built-in");      
       
       cmsAddTag(hICC, icSigMediaWhitePointTag, (LPVOID) cmsD50_XYZ());
       
       cmsAddTag(hICC, icSigAToB0Tag, (LPVOID) Lut);
       
       // LUT is already on virtual profile
       cmsFreeLUT(Lut);

       // Ok, done
       return hICC;
}
Esempio n. 17
0
/**
 * cd_util_create_named_color:
 **/
static gboolean
cd_util_create_named_color (CdUtilPrivate *priv,
			    CdDom *dom,
			    const GNode *root,
			    GError **error)
{
	CdColorLab lab;
	cmsNAMEDCOLORLIST *nc2 = NULL;
	cmsUInt16Number pcs[3];
	const GNode *name;
	const GNode *named;
	const GNode *prefix;
	const GNode *suffix;
	const GNode *tmp;
	gboolean ret = TRUE;

	priv->lcms_profile = cmsCreateNULLProfileTHR (cd_icc_get_context (priv->icc));
	if (priv->lcms_profile == NULL) {
		ret = FALSE;
		g_set_error_literal (error, 1, 0,
				     "failed to create NULL profile");
		goto out;
	}

	cmsSetDeviceClass(priv->lcms_profile, cmsSigNamedColorClass);
	cmsSetPCS (priv->lcms_profile, cmsSigLabData);
	cmsSetColorSpace (priv->lcms_profile, cmsSigLabData);

	/* create a named color structure */
	prefix = cd_dom_get_node (dom, root, "prefix");
	suffix = cd_dom_get_node (dom, root, "suffix");
	nc2 = cmsAllocNamedColorList (NULL, 1, /* will realloc more as required */
				      3,
				      prefix != NULL ? cd_dom_get_node_data (prefix) : "",
				      suffix != NULL ? cd_dom_get_node_data (suffix) : "");

	named = cd_dom_get_node (dom, root, "named");
	if (named == NULL) {
		ret = FALSE;
		g_set_error_literal (error, 1, 0,
				     "XML error: missing named");
		goto out;
	}
	for (tmp = named->children; tmp != NULL; tmp = tmp->next) {
		name = cd_dom_get_node (dom, tmp, "name");
		if (name == NULL) {
			ret = FALSE;
			g_set_error_literal (error, 1, 0,
					     "XML error: missing name");
			goto out;
		}
		ret = cd_dom_get_node_lab (tmp, &lab);
		if (!ret) {
			ret = FALSE;
			g_set_error (error, 1, 0,
				     "XML error: missing Lab for %s",
				     cd_dom_get_node_data (name));
			goto out;
		}

		/* PCS = colours in PCS colour space CIE*Lab
		 * colorant = colours in device colour space */
		cmsFloat2LabEncoded (pcs, (cmsCIELab *) &lab);
		ret = cmsAppendNamedColor (nc2, cd_dom_get_node_data (name), pcs, pcs);
		g_assert (ret);
	}
	cmsWriteTag (priv->lcms_profile, cmsSigNamedColor2Tag, nc2);
out:
	if (nc2 != NULL)
		cmsFreeNamedColorList (nc2);
	return ret;
}
Esempio n. 18
0
static GimpColorProfile *
gimp_color_profile_new_from_color_profile (GimpColorProfile *profile,
                                           gboolean          linear)
{
  GimpColorProfile *new_profile;
  cmsHPROFILE       target_profile;
  GimpMatrix3       matrix = { 0, };
  cmsCIEXYZ        *whitepoint;
  cmsToneCurve     *curve;
  const gchar      *model;
  gchar            *new_model;

  g_return_val_if_fail (GIMP_IS_COLOR_PROFILE (profile), NULL);

  if (gimp_color_profile_is_rgb (profile))
    {
      if (! gimp_color_profile_get_rgb_matrix_colorants (profile, &matrix))
        return NULL;
    }
  else if (! gimp_color_profile_is_gray (profile))
    {
      return NULL;
    }

  whitepoint = cmsReadTag (profile->priv->lcms_profile,
                           cmsSigMediaWhitePointTag);

  target_profile = cmsCreateProfilePlaceholder (0);

  cmsSetProfileVersion (target_profile, 4.3);
  cmsSetDeviceClass (target_profile, cmsSigDisplayClass);
  cmsSetPCS (target_profile, cmsSigXYZData);

  cmsWriteTag (target_profile, cmsSigMediaWhitePointTag, whitepoint);

  if (linear)
    {
      /* linear light */
      curve = cmsBuildGamma (NULL, 1.00);

      gimp_color_profile_set_tag (target_profile, cmsSigProfileDescriptionTag,
                                  "linear TRC variant generated by GIMP");
    }
  else
    {
      cmsFloat64Number srgb_parameters[5] =
        { 2.4, 1.0 / 1.055,  0.055 / 1.055, 1.0 / 12.92, 0.04045 };

      /* sRGB curve */
      curve = cmsBuildParametricToneCurve (NULL, 4, srgb_parameters);

      gimp_color_profile_set_tag (target_profile, cmsSigProfileDescriptionTag,
                                  "sRGB TRC variant generated by GIMP");
    }

  if (gimp_color_profile_is_rgb (profile))
    {
      cmsCIEXYZ red;
      cmsCIEXYZ green;
      cmsCIEXYZ blue;

      cmsSetColorSpace (target_profile, cmsSigRgbData);

      red.X = matrix.coeff[0][0];
      red.Y = matrix.coeff[0][1];
      red.Z = matrix.coeff[0][2];

      green.X = matrix.coeff[1][0];
      green.Y = matrix.coeff[1][1];
      green.Z = matrix.coeff[1][2];

      blue.X = matrix.coeff[2][0];
      blue.Y = matrix.coeff[2][1];
      blue.Z = matrix.coeff[2][2];

      cmsWriteTag (target_profile, cmsSigRedColorantTag,   &red);
      cmsWriteTag (target_profile, cmsSigGreenColorantTag, &green);
      cmsWriteTag (target_profile, cmsSigBlueColorantTag,  &blue);

      cmsWriteTag (target_profile, cmsSigRedTRCTag,   curve);
      cmsWriteTag (target_profile, cmsSigGreenTRCTag, curve);
      cmsWriteTag (target_profile, cmsSigBlueTRCTag,  curve);
    }
  else
    {
      cmsSetColorSpace (target_profile, cmsSigGrayData);

      cmsWriteTag (target_profile, cmsSigGrayTRCTag, curve);
    }

  cmsFreeToneCurve (curve);

  model = gimp_color_profile_get_model (profile);

  if (model && g_str_has_prefix (model, "Generated from '"))
    {
      /* don't add multiple "Generated from 'foo'" */
      new_model = g_strdup (model);
    }
  else
    {
      new_model = g_strdup_printf ("Generated from '%s'",
                                   gimp_color_profile_get_description (profile));
    }

  gimp_color_profile_set_tag (target_profile, cmsSigDeviceMfgDescTag,
                              "GIMP");
  gimp_color_profile_set_tag (target_profile, cmsSigDeviceModelDescTag,
                              new_model);
  gimp_color_profile_set_tag (target_profile, cmsSigCopyrightTag,
                              "Public Domain");

  g_free (new_model);

  new_profile = gimp_color_profile_new_from_lcms_profile (target_profile, NULL);

  cmsCloseProfile (target_profile);

  return new_profile;
}
Esempio n. 19
0
bool ProfileUtils::createIccProfile(bool isLaptop, const Edid &edid, const QString &filename)
{
    cmsCIExyYTRIPLE chroma;
    cmsCIExyY white_point;
    cmsHPROFILE lcms_profile = NULL;
    cmsToneCurve *transfer_curve[3] = { NULL, NULL, NULL };
    bool ret = false;
    cmsHANDLE dict = NULL;

    /* ensure the per-user directory exists */
    // Create dir path if not available
    // check if the file doesn't already exist
    QFileInfo fileInfo(filename);
    if (fileInfo.exists()) {
        qCWarning(COLORD) << "EDID ICC Profile already exists" << filename;
        if (*transfer_curve != NULL)
            cmsFreeToneCurve(*transfer_curve);
        return false;
    }

    // copy color data from our structures
    // Red
    chroma.Red.x = edid.red().x();
    chroma.Red.y = edid.red().y();
    // Green
    chroma.Green.x = edid.green().x();
    chroma.Green.y = edid.green().y();
    // Blue
    chroma.Blue.x = edid.blue().x();
    chroma.Blue.y = edid.blue().y();
    // White
    white_point.x = edid.white().x();
    white_point.y = edid.white().y();
    white_point.Y = 1.0;

    // estimate the transfer function for the gamma
    transfer_curve[0] = transfer_curve[1] = transfer_curve[2] = cmsBuildGamma(NULL, edid.gamma());

    // create our generated profile
    lcms_profile = cmsCreateRGBProfile(&white_point, &chroma, transfer_curve);
    if (lcms_profile == NULL) {
        qCWarning(COLORD) << "Failed to create ICC profile on cmsCreateRGBProfile";
        if (*transfer_curve != NULL)
            cmsFreeToneCurve(*transfer_curve);
        return false;
    }

    cmsSetColorSpace(lcms_profile, cmsSigRgbData);
    cmsSetPCS(lcms_profile, cmsSigXYZData);
    cmsSetHeaderRenderingIntent(lcms_profile, INTENT_RELATIVE_COLORIMETRIC);
    cmsSetDeviceClass(lcms_profile, cmsSigDisplayClass);

    // copyright
    ret = cmsWriteTagTextAscii(lcms_profile,
                               cmsSigCopyrightTag,
                               "No copyright");
    if (!ret) {
        qCWarning(COLORD) << "Failed to write copyright";
        if (*transfer_curve != NULL)
            cmsFreeToneCurve(*transfer_curve);
        return false;
    }

    // set model
    QString model;
    if (isLaptop) {
        model = DmiUtils::deviceModel();
    } else {
        model = edid.name();
    }

    if (model.isEmpty()) {
        model = QStringLiteral("Unknown monitor");
    }
    ret = cmsWriteTagTextAscii(lcms_profile,
                               cmsSigDeviceModelDescTag,
                               model);
    if (!ret) {
        qCWarning(COLORD) << "Failed to write model";
        if (*transfer_curve != NULL) {
            cmsFreeToneCurve(*transfer_curve);
        }
        return false;
    }

    // write title
    ret = cmsWriteTagTextAscii(lcms_profile,
                               cmsSigProfileDescriptionTag,
                               model);
    if (!ret) {
        qCWarning(COLORD) << "Failed to write description";
        if (*transfer_curve != NULL)
            cmsFreeToneCurve(*transfer_curve);
        return false;
    }

    // get manufacturer
    QString vendor;
    if (isLaptop) {
        vendor = DmiUtils::deviceVendor();
    } else {
        vendor = edid.vendor();
    }

    if (vendor.isEmpty()) {
        vendor = QStringLiteral("Unknown vendor");
    }
    ret = cmsWriteTagTextAscii(lcms_profile,
                               cmsSigDeviceMfgDescTag,
                               vendor);
    if (!ret) {
        qCWarning(COLORD) << "Failed to write manufacturer";
        if (*transfer_curve != NULL)
            cmsFreeToneCurve(*transfer_curve);
        return false;
    }

    // just create a new dict
    dict = cmsDictAlloc(NULL);

    // set the framework creator metadata
    cmsDictAddEntryAscii(dict,
                         CD_PROFILE_METADATA_CMF_PRODUCT,
                         PACKAGE_NAME);
    cmsDictAddEntryAscii(dict,
                         CD_PROFILE_METADATA_CMF_BINARY,
                         PACKAGE_NAME);
    cmsDictAddEntryAscii(dict,
                         CD_PROFILE_METADATA_CMF_VERSION,
                         PACKAGE_VERSION);

    /* set the data source so we don't ever prompt the user to
         * recalibrate (as the EDID data won't have changed) */
    cmsDictAddEntryAscii(dict,
                         CD_PROFILE_METADATA_DATA_SOURCE,
                         CD_PROFILE_METADATA_DATA_SOURCE_EDID);

    // set 'ICC meta Tag for Monitor Profiles' data
    cmsDictAddEntryAscii(dict, "EDID_md5", edid.hash());

    if (!model.isEmpty())
        cmsDictAddEntryAscii(dict, "EDID_model", model);

    if (!edid.serial().isEmpty()) {
        cmsDictAddEntryAscii(dict, "EDID_serial", edid.serial());
    }

    if (!edid.pnpId().isEmpty()) {
        cmsDictAddEntryAscii(dict, "EDID_mnft", edid.pnpId());
    }

    if (!vendor.isEmpty()) {
        cmsDictAddEntryAscii(dict, "EDID_manufacturer", vendor);
    }

    /* write new tag */
    ret = cmsWriteTag(lcms_profile, cmsSigMetaTag, dict);
    if (!ret) {
        qCWarning(COLORD) << "Failed to write profile metadata";
        if (*transfer_curve != NULL)
            cmsFreeToneCurve(*transfer_curve);
        return false;
    }

    /* write profile id */
    ret = cmsMD5computeID(lcms_profile);
    if (!ret) {
        qCWarning(COLORD) << "Failed to write profile id";
        if (dict != NULL)
            cmsDictFree (dict);
        if (*transfer_curve != NULL)
            cmsFreeToneCurve(*transfer_curve);
        return false;
    }

    /* save, TODO: get error */
    ret = cmsSaveProfileToFile(lcms_profile, filename.toUtf8());

    if (dict != NULL) {
        cmsDictFree (dict);
    }
    if (*transfer_curve != NULL) {
        cmsFreeToneCurve (*transfer_curve);
    }

    return ret;
}
Esempio n. 20
0
BOOL cmsxMonitorProfilerDo(LPMONITORPROFILERDATA sys)
{

    cmsCIExyY White;
    LPLUT AToB0, BToA0;

        AToB0 = BToA0 = NULL;

        if (!*sys -> hdr.OutputProfileFile)
                return false;


        if (sys->hdr.ReferenceSheet[0] || sys->hdr.MeasurementSheet[0]) {

                if (sys->hdr.printf) {

                    sys->hdr.printf("Loading sheets...");

                    if (sys->hdr.ReferenceSheet[0])
                        sys->hdr.printf("Reference sheet: %s", sys->hdr.ReferenceSheet);
                    if (sys->hdr.MeasurementSheet[0])
                        sys->hdr.printf("Measurement sheet: %s", sys->hdr.MeasurementSheet);
                }


                if (!cmsxComputeMatrixShaper(sys -> hdr.ReferenceSheet,
                                             sys -> hdr.MeasurementSheet,
                                             MEDIUM_TRANSMISSIVE,
                                             sys -> Prelinearization,
                                             &sys -> hdr.WhitePoint,
                                             &sys -> hdr.BlackPoint,
                                             &sys -> hdr.Primaries)) return false;

                if (sys->hdr.printf) {

                    char Buffer[1024];
                    _cmsIdentifyWhitePoint(Buffer, &sys ->hdr.WhitePoint);
                    sys->hdr.printf("%s", Buffer);

                    sys->hdr.printf("Primaries: R:%1.2g, %1.2g  G:%1.2g, %1.2g  B:%1.2g, %1.2g",
                            sys->hdr.Primaries.Red.x,sys->hdr.Primaries.Red.y,
                            sys->hdr.Primaries.Green.x, sys->hdr.Primaries.Green.y,
                            sys->hdr.Primaries.Blue.x, sys->hdr.Primaries.Blue.y);
                }

        }


        CreatePrimaryMatrices(sys);


        cmsXYZ2xyY(&White, &sys->hdr.WhitePoint);

        sys->hdr.hProfile = cmsCreateRGBProfile(&White,
                                                &sys-> hdr.Primaries,
                                                sys -> Prelinearization);

        cmsSetDeviceClass(sys->hdr.hProfile, sys->hdr.DeviceClass);

        if (sys -> hdr.lUseCIECAM97s)
            sys->hdr.PCSType = PT_Lab;
        else
            sys->hdr.PCSType = PT_XYZ;

        cmsSetPCS(sys->hdr.hProfile,  _cmsICCcolorSpace(sys->hdr.PCSType));

        if (sys -> hdr.lUseCIECAM97s)
                        CreateLUTS(sys, &AToB0, &BToA0);


        cmsxEmbedTextualInfo(&sys ->hdr);

        cmsAddTag(sys->hdr.hProfile, icSigMediaWhitePointTag,  &sys->hdr.WhitePoint);
        cmsAddTag(sys->hdr.hProfile, icSigMediaBlackPointTag, &sys->hdr.BlackPoint);


        if (sys->hdr.ProfileVerbosityLevel >= 2) {

            cmsxEmbedCharTarget(&sys ->hdr);
        }


        _cmsSaveProfile(sys->hdr.hProfile, sys->hdr.OutputProfileFile);
        cmsCloseProfile(sys->hdr.hProfile);
        sys->hdr.hProfile = NULL;


        if (AToB0) cmsFreeLUT(AToB0);
        if (BToA0) cmsFreeLUT(BToA0);

        if (sys ->Prelinearization[0])
            cmsFreeGammaTriple(sys -> Prelinearization);

    return true;
}