cmsHPROFILE dt_colorspaces_create_xyz_profile(void) { cmsHPROFILE hXYZ = cmsCreateXYZProfile(); // revert some settings which prevent us from using XYZ as output profile: cmsSetDeviceClass(hXYZ, cmsSigDisplayClass); cmsSetColorSpace(hXYZ, cmsSigRgbData); cmsSetPCS(hXYZ, cmsSigXYZData); cmsSetHeaderRenderingIntent(hXYZ, INTENT_PERCEPTUAL); if (hXYZ == NULL) return NULL; cmsSetProfileVersion(hXYZ, 2.1); cmsMLU *mlu0 = cmsMLUalloc(NULL, 1); cmsMLUsetASCII(mlu0, "en", "US", "(dt internal)"); cmsMLU *mlu1 = cmsMLUalloc(NULL, 1); cmsMLUsetASCII(mlu1, "en", "US", "linear XYZ"); cmsMLU *mlu2 = cmsMLUalloc(NULL, 1); cmsMLUsetASCII(mlu2, "en", "US", "Darktable linear XYZ"); cmsWriteTag(hXYZ, cmsSigDeviceMfgDescTag, mlu0); cmsWriteTag(hXYZ, cmsSigDeviceModelDescTag, mlu1); // this will only be displayed when the embedded profile is read by for example GIMP cmsWriteTag(hXYZ, cmsSigProfileDescriptionTag, mlu2); cmsMLUfree(mlu0); cmsMLUfree(mlu1); cmsMLUfree(mlu2); return hXYZ; }
static cmsBool SetSeqDescTag(cmsHPROFILE hProfile, const char* Model) { cmsBool rc = FALSE; cmsContext ContextID = cmsGetProfileContextID(hProfile); cmsSEQ* Seq = cmsAllocProfileSequenceDescription(ContextID, 1); if (Seq == NULL) return FALSE; Seq->seq[0].deviceMfg = (cmsSignature) 0; Seq->seq[0].deviceModel = (cmsSignature) 0; #ifdef CMS_DONT_USE_INT64 Seq->seq[0].attributes[0] = 0; Seq->seq[0].attributes[1] = 0; #else Seq->seq[0].attributes = 0; #endif Seq->seq[0].technology = (cmsTechnologySignature) 0; cmsMLUsetASCII( Seq->seq[0].Manufacturer, cmsNoLanguage, cmsNoCountry, "Little CMS"); cmsMLUsetASCII( Seq->seq[0].Model, cmsNoLanguage, cmsNoCountry, Model); if (!_cmsWriteProfileSequence(hProfile, Seq)) goto Error; rc = TRUE; Error: if (Seq) cmsFreeProfileSequenceDescription(Seq); return rc; }
// Set the copyright and description static cmsBool SetTextTags(cmsHPROFILE hProfile) { cmsMLU *DescriptionMLU, *CopyrightMLU; cmsBool rc = FALSE; cmsContext ContextID = cmsGetProfileContextID(hProfile); DescriptionMLU = cmsMLUalloc(ContextID, 1); CopyrightMLU = cmsMLUalloc(ContextID, 1); if (DescriptionMLU == NULL || CopyrightMLU == NULL) goto Error; if (!cmsMLUsetASCII(DescriptionMLU, "en", "US", Description)) goto Error; if (!cmsMLUsetASCII(CopyrightMLU, "en", "US", Copyright)) goto Error; if (!cmsWriteTag(hProfile, cmsSigProfileDescriptionTag, DescriptionMLU)) goto Error; if (!cmsWriteTag(hProfile, cmsSigCopyrightTag, CopyrightMLU)) goto Error; rc = TRUE; Error: if (DescriptionMLU) cmsMLUfree(DescriptionMLU); if (CopyrightMLU) cmsMLUfree(CopyrightMLU); return rc; }
// Create the ICC virtual profile for adobe rgb space cmsHPROFILE dt_colorspaces_create_adobergb_profile(void) { cmsHPROFILE hAdobeRGB; cmsCIEXYZTRIPLE Colorants = { {0.609741, 0.311111, 0.019470}, {0.205276, 0.625671, 0.060867}, {0.149185, 0.063217, 0.744568} }; cmsCIEXYZ black = { 0, 0, 0 }; cmsCIEXYZ D65 = { 0.95045, 1, 1.08905 }; cmsToneCurve* transferFunction; transferFunction = cmsBuildGamma(NULL, 2.2); hAdobeRGB = cmsCreateProfilePlaceholder(0); cmsSetProfileVersion(hAdobeRGB, 2.1); cmsMLU *mlu0 = cmsMLUalloc(NULL, 1); cmsMLUsetASCII(mlu0, "en", "US", "Public Domain"); cmsMLU *mlu1 = cmsMLUalloc(NULL, 1); cmsMLUsetASCII(mlu1, "en", "US", "AdobeRGB"); cmsMLU *mlu2 = cmsMLUalloc(NULL, 1); cmsMLUsetASCII(mlu2, "en", "US", "Darktable"); cmsMLU *mlu3 = cmsMLUalloc(NULL, 1); cmsMLUsetASCII(mlu3, "en", "US", "AdobeRGB"); // this will only be displayed when the embedded profile is read by for example GIMP cmsWriteTag(hAdobeRGB, cmsSigCopyrightTag, mlu0); cmsWriteTag(hAdobeRGB, cmsSigProfileDescriptionTag, mlu1); cmsWriteTag(hAdobeRGB, cmsSigDeviceMfgDescTag, mlu2); cmsWriteTag(hAdobeRGB, cmsSigDeviceModelDescTag, mlu3); cmsMLUfree(mlu0); cmsMLUfree(mlu1); cmsMLUfree(mlu2); cmsMLUfree(mlu3); cmsSetDeviceClass(hAdobeRGB, cmsSigDisplayClass); cmsSetColorSpace(hAdobeRGB, cmsSigRgbData); cmsSetPCS(hAdobeRGB, cmsSigXYZData); cmsWriteTag(hAdobeRGB, cmsSigMediaWhitePointTag, &D65); cmsWriteTag(hAdobeRGB, cmsSigMediaBlackPointTag, &black); cmsWriteTag(hAdobeRGB, cmsSigRedColorantTag, (void*) &Colorants.Red); cmsWriteTag(hAdobeRGB, cmsSigGreenColorantTag, (void*) &Colorants.Green); cmsWriteTag(hAdobeRGB, cmsSigBlueColorantTag, (void*) &Colorants.Blue); cmsWriteTag(hAdobeRGB, cmsSigRedTRCTag, (void*) transferFunction); cmsLinkTag(hAdobeRGB, cmsSigGreenTRCTag, cmsSigRedTRCTag ); cmsLinkTag(hAdobeRGB, cmsSigBlueTRCTag, cmsSigRedTRCTag ); return hAdobeRGB; }
cmsHPROFILE dt_colorspaces_create_srgb_profile() { cmsHPROFILE hsRGB; cmsCIEXYZTRIPLE Colorants = { {0.436066, 0.222488, 0.013916}, {0.385147, 0.716873, 0.097076}, {0.143066, 0.060608, 0.714096} }; cmsCIEXYZ black = { 0, 0, 0 }; cmsCIEXYZ D65 = { 0.95045, 1, 1.08905 }; cmsToneCurve* transferFunction; transferFunction = cmsBuildTabulatedToneCurve16(NULL, dt_srgb_tone_curve_values_n, dt_srgb_tone_curve_values); hsRGB = cmsCreateProfilePlaceholder(0); cmsSetProfileVersion(hsRGB, 2.1); cmsMLU *mlu0 = cmsMLUalloc(NULL, 1); cmsMLUsetASCII(mlu0, "en", "US", "Public Domain"); cmsMLU *mlu1 = cmsMLUalloc(NULL, 1); cmsMLUsetASCII(mlu1, "en", "US", "sRGB"); cmsMLU *mlu2 = cmsMLUalloc(NULL, 1); cmsMLUsetASCII(mlu2, "en", "US", "Darktable"); cmsMLU *mlu3 = cmsMLUalloc(NULL, 1); cmsMLUsetASCII(mlu3, "en", "US", "sRGB"); // this will only be displayed when the embedded profile is read by for example GIMP cmsWriteTag(hsRGB, cmsSigCopyrightTag, mlu0); cmsWriteTag(hsRGB, cmsSigProfileDescriptionTag, mlu1); cmsWriteTag(hsRGB, cmsSigDeviceMfgDescTag, mlu2); cmsWriteTag(hsRGB, cmsSigDeviceModelDescTag, mlu3); cmsMLUfree(mlu0); cmsMLUfree(mlu1); cmsMLUfree(mlu2); cmsMLUfree(mlu3); cmsSetDeviceClass(hsRGB, cmsSigDisplayClass); cmsSetColorSpace(hsRGB, cmsSigRgbData); cmsSetPCS(hsRGB, cmsSigXYZData); cmsWriteTag(hsRGB, cmsSigMediaWhitePointTag, &D65); cmsWriteTag(hsRGB, cmsSigMediaBlackPointTag, &black); cmsWriteTag(hsRGB, cmsSigRedColorantTag, (void*) &Colorants.Red); cmsWriteTag(hsRGB, cmsSigGreenColorantTag, (void*) &Colorants.Green); cmsWriteTag(hsRGB, cmsSigBlueColorantTag, (void*) &Colorants.Blue); cmsWriteTag(hsRGB, cmsSigRedTRCTag, (void*) transferFunction); cmsLinkTag(hsRGB, cmsSigGreenTRCTag, cmsSigRedTRCTag ); cmsLinkTag(hsRGB, cmsSigBlueTRCTag, cmsSigRedTRCTag ); return hsRGB; }
cmsHPROFILE dt_colorspaces_create_darktable_profile(const char *makermodel) { dt_profiled_colormatrix_t *preset = NULL; for(int k=0; k<dt_profiled_colormatrix_cnt; k++) { if(!strcasecmp(makermodel, dt_profiled_colormatrices[k].makermodel)) { preset = dt_profiled_colormatrices + k; break; } } if(!preset) return NULL; const float wxyz = preset->white[0]+preset->white[1]+preset->white[2]; const float rxyz = preset->rXYZ[0] +preset->rXYZ[1] +preset->rXYZ[2]; const float gxyz = preset->gXYZ[0] +preset->gXYZ[1] +preset->gXYZ[2]; const float bxyz = preset->bXYZ[0] +preset->bXYZ[1] +preset->bXYZ[2]; cmsCIExyY WP = {preset->white[0]/wxyz, preset->white[1]/wxyz, 1.0}; cmsCIExyYTRIPLE XYZPrimaries = { {preset->rXYZ[0]/rxyz, preset->rXYZ[1]/rxyz, 1.0}, {preset->gXYZ[0]/gxyz, preset->gXYZ[1]/gxyz, 1.0}, {preset->bXYZ[0]/bxyz, preset->bXYZ[1]/bxyz, 1.0} }; cmsToneCurve *Gamma[3]; cmsHPROFILE hp; Gamma[0] = Gamma[1] = Gamma[2] = build_linear_gamma(); hp = cmsCreateRGBProfile(&WP, &XYZPrimaries, Gamma); cmsFreeToneCurve(Gamma[0]); if (hp == NULL) return NULL; char name[512]; snprintf(name, 512, "Darktable profiled %s", makermodel); cmsSetProfileVersion(hp, 2.1); cmsMLU *mlu0 = cmsMLUalloc(NULL, 1); cmsMLUsetASCII(mlu0, "en", "US", "(dt internal)"); cmsMLU *mlu1 = cmsMLUalloc(NULL, 1); cmsMLUsetASCII(mlu1, "en", "US", name); cmsMLU *mlu2 = cmsMLUalloc(NULL, 1); cmsMLUsetASCII(mlu2, "en", "US", name); cmsWriteTag(hp, cmsSigDeviceMfgDescTag, mlu0); cmsWriteTag(hp, cmsSigDeviceModelDescTag, mlu1); // this will only be displayed when the embedded profile is read by for example GIMP cmsWriteTag(hp, cmsSigProfileDescriptionTag, mlu2); cmsMLUfree(mlu0); cmsMLUfree(mlu1); cmsMLUfree(mlu2); return hp; }
cmsHPROFILE dt_colorspaces_create_xyzmatrix_profile(float mat[3][3]) { // mat: cam -> xyz cmsCIExyY D65; float x[3], y[3]; for(int k=0; k<3; k++) { const float norm = mat[0][k] + mat[1][k] + mat[2][k]; x[k] = mat[0][k] / norm; y[k] = mat[1][k] / norm; } cmsCIExyYTRIPLE CameraPrimaries = { {x[0], y[0], 1.0}, {x[1], y[1], 1.0}, {x[2], y[2], 1.0} }; cmsHPROFILE cmat; cmsWhitePointFromTemp(&D65, 6504.0); cmsToneCurve *Gamma[3]; Gamma[0] = Gamma[1] = Gamma[2] = build_linear_gamma(); cmat = cmsCreateRGBProfile(&D65, &CameraPrimaries, Gamma); if (cmat == NULL) return NULL; cmsFreeToneCurve(Gamma[0]); cmsSetProfileVersion(cmat, 2.1); cmsMLU *mlu0 = cmsMLUalloc(NULL, 1); cmsMLUsetASCII(mlu0, "en", "US", "(dt internal)"); cmsMLU *mlu1 = cmsMLUalloc(NULL, 1); cmsMLUsetASCII(mlu1, "en", "US", "color matrix built-in"); cmsMLU *mlu2 = cmsMLUalloc(NULL, 1); cmsMLUsetASCII(mlu2, "en", "US", "color matrix built-in"); cmsWriteTag(cmat, cmsSigDeviceMfgDescTag, mlu0); cmsWriteTag(cmat, cmsSigDeviceModelDescTag, mlu1); // this will only be displayed when the embedded profile is read by for example GIMP cmsWriteTag(cmat, cmsSigProfileDescriptionTag, mlu2); cmsMLUfree(mlu0); cmsMLUfree(mlu1); cmsMLUfree(mlu2); return cmat; }
cmsBool ProfileUtils::cmsWriteTagTextAscii(cmsHPROFILE lcms_profile, cmsTagSignature sig, const QString &text) { cmsBool ret; cmsMLU *mlu = cmsMLUalloc(0, 1); cmsMLUsetASCII(mlu, "EN", "us", text.toLatin1().constData()); ret = cmsWriteTag(lcms_profile, sig, mlu); cmsMLUfree(mlu); return ret; }
static void gimp_lcms_profile_set_tag (cmsHPROFILE profile, cmsTagSignature sig, const gchar *tag) { cmsMLU *mlu; mlu = cmsMLUalloc (NULL, 1); cmsMLUsetASCII (mlu, "en", "US", tag); cmsWriteTag (profile, sig, mlu); cmsMLUfree (mlu); }
cmsHPROFILE dt_colorspaces_create_linear_infrared_profile(void) { // linear rgb with r and b swapped: cmsCIExyY D65; cmsCIExyYTRIPLE Rec709Primaries = { {0.1500, 0.0600, 1.0}, {0.3000, 0.6000, 1.0}, {0.6400, 0.3300, 1.0} }; cmsToneCurve *Gamma[3]; cmsHPROFILE hsRGB; cmsWhitePointFromTemp(&D65, 6504.0); Gamma[0] = Gamma[1] = Gamma[2] = build_linear_gamma(); hsRGB = cmsCreateRGBProfile(&D65, &Rec709Primaries, Gamma); cmsFreeToneCurve(Gamma[0]); if (hsRGB == NULL) return NULL; cmsSetProfileVersion(hsRGB, 2.1); cmsMLU *mlu0 = cmsMLUalloc(NULL, 1); cmsMLUsetASCII(mlu0, "en", "US", "(dt internal)"); cmsMLU *mlu1 = cmsMLUalloc(NULL, 1); cmsMLUsetASCII(mlu1, "en", "US", "linear infrared bgr"); cmsMLU *mlu2 = cmsMLUalloc(NULL, 1); cmsMLUsetASCII(mlu2, "en", "US", "Darktable Linear Infrared RGB"); cmsWriteTag(hsRGB, cmsSigDeviceMfgDescTag, mlu0); cmsWriteTag(hsRGB, cmsSigDeviceModelDescTag, mlu1); // this will only be displayed when the embedded profile is read by for example GIMP cmsWriteTag(hsRGB, cmsSigProfileDescriptionTag, mlu2); cmsMLUfree(mlu0); cmsMLUfree(mlu1); cmsMLUfree(mlu2); return hsRGB; }
// Create the ICC virtual profile for adobe rgb space cmsHPROFILE dt_colorspaces_create_adobergb_profile(void) { cmsCIExyY D65; cmsCIExyYTRIPLE AdobePrimaries = { {0.6400, 0.3300, 1.0}, {0.2100, 0.7100, 1.0}, {0.1500, 0.0600, 1.0} }; cmsToneCurve *Gamma22[3]; cmsHPROFILE hAdobeRGB; cmsWhitePointFromTemp(&D65, 6504.0); Gamma22[0] = Gamma22[1] = Gamma22[2] = build_adobergb_gamma(); hAdobeRGB = cmsCreateRGBProfile(&D65, &AdobePrimaries, Gamma22); cmsFreeToneCurve(Gamma22[0]); if (hAdobeRGB == NULL) return NULL; cmsSetProfileVersion(hAdobeRGB, 2.1); cmsMLU *mlu0 = cmsMLUalloc(NULL, 1); cmsMLUsetASCII(mlu0, "en", "US", "(dt internal)"); cmsMLU *mlu1 = cmsMLUalloc(NULL, 1); cmsMLUsetASCII(mlu1, "en", "US", "AdobeRGB"); cmsMLU *mlu2 = cmsMLUalloc(NULL, 1); cmsMLUsetASCII(mlu2, "en", "US", "Darktable AdobeRGB"); cmsWriteTag(hAdobeRGB, cmsSigDeviceMfgDescTag, mlu0); cmsWriteTag(hAdobeRGB, cmsSigDeviceModelDescTag, mlu1); // this will only be displayed when the embedded profile is read by for example GIMP cmsWriteTag(hAdobeRGB, cmsSigProfileDescriptionTag, mlu2); cmsMLUfree(mlu0); cmsMLUfree(mlu1); cmsMLUfree(mlu2); return hAdobeRGB; }