cmsHPROFILE CMSEXPORT cmsCreateNULLProfile(void) { return cmsCreateNULLProfileTHR(NULL); }
// Virtual profiles are handled here. cmsHPROFILE OpenStockProfile(cmsContext ContextID, const char* File) { if (!File) return cmsCreate_sRGBProfileTHR(ContextID); if (cmsstrcasecmp(File, "*Lab2") == 0) return cmsCreateLab2ProfileTHR(ContextID, NULL); if (cmsstrcasecmp(File, "*Lab4") == 0) return cmsCreateLab4ProfileTHR(ContextID, NULL); if (cmsstrcasecmp(File, "*Lab") == 0) return cmsCreateLab4ProfileTHR(ContextID, NULL); if (cmsstrcasecmp(File, "*LabD65") == 0) { cmsCIExyY D65xyY; cmsWhitePointFromTemp( &D65xyY, 6504); return cmsCreateLab4ProfileTHR(ContextID, &D65xyY); } if (cmsstrcasecmp(File, "*XYZ") == 0) return cmsCreateXYZProfileTHR(ContextID); if (cmsstrcasecmp(File, "*Gray22") == 0) { cmsToneCurve* Curve = cmsBuildGamma(ContextID, 2.2); cmsHPROFILE hProfile = cmsCreateGrayProfileTHR(ContextID, cmsD50_xyY(), Curve); cmsFreeToneCurve(Curve); return hProfile; } if (cmsstrcasecmp(File, "*Gray30") == 0) { cmsToneCurve* Curve = cmsBuildGamma(ContextID, 3.0); cmsHPROFILE hProfile = cmsCreateGrayProfileTHR(ContextID, cmsD50_xyY(), Curve); cmsFreeToneCurve(Curve); return hProfile; } if (cmsstrcasecmp(File, "*srgb") == 0) return cmsCreate_sRGBProfileTHR(ContextID); if (cmsstrcasecmp(File, "*null") == 0) return cmsCreateNULLProfileTHR(ContextID); if (cmsstrcasecmp(File, "*Lin2222") == 0) { cmsToneCurve* Gamma = cmsBuildGamma(0, 2.2); cmsToneCurve* Gamma4[4]; cmsHPROFILE hProfile; Gamma4[0] = Gamma4[1] = Gamma4[2] = Gamma4[3] = Gamma; hProfile = cmsCreateLinearizationDeviceLink(cmsSigCmykData, Gamma4); cmsFreeToneCurve(Gamma); return hProfile; } return cmsOpenProfileFromFileTHR(ContextID, File, "r"); }
/** * 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; }
/** * cd_icc_utils_get_coverage_calc: **/ static gboolean cd_icc_utils_get_coverage_calc (CdIcc *icc, CdIcc *icc_reference, gdouble *coverage, GError **error) { const guint cube_size = 33; cmsHPROFILE profile_null = NULL; cmsHTRANSFORM transform = NULL; cmsUInt32Number dimensions[] = { cube_size, cube_size, cube_size }; CdIccUtilsGamutCheckHelper helper; gboolean ret = TRUE; guint cnt = 0; guint data_len = cube_size * cube_size * cube_size; guint i; g_autofree cmsFloat32Number *data = NULL; g_autofree cmsUInt16Number *alarm_codes = NULL; /* create a proofing transform with gamut check */ profile_null = cmsCreateNULLProfileTHR (cd_icc_get_context (icc)); transform = cmsCreateProofingTransformTHR (cd_icc_get_context (icc), cd_icc_get_handle (icc), TYPE_RGB_FLT, profile_null, TYPE_GRAY_FLT, cd_icc_get_handle (icc_reference), INTENT_ABSOLUTE_COLORIMETRIC, INTENT_ABSOLUTE_COLORIMETRIC, cmsFLAGS_GAMUTCHECK | cmsFLAGS_SOFTPROOFING); if (transform == NULL) { ret = FALSE; g_set_error (error, CD_ICC_ERROR, CD_ICC_ERROR_INVALID_COLORSPACE, "Failed to setup transform for %s->%s", cd_icc_get_filename (icc), cd_icc_get_filename (icc_reference)); goto out; } /* set gamut alarm to 0xffff */ alarm_codes = g_new0 (cmsUInt16Number, cmsMAXCHANNELS); alarm_codes[0] = 0xffff; cmsSetAlarmCodes (alarm_codes); /* slice profile in regular intevals */ data = g_new0 (cmsFloat32Number, data_len * 3); helper.data = data; helper.idx = 0; ret = cmsSliceSpaceFloat (3, dimensions, cd_icc_utils_get_coverage_sample_cb, &helper); if (!ret) { g_set_error_literal (error, CD_ICC_ERROR, CD_ICC_ERROR_INTERNAL, "Failed to slice data"); goto out; } /* transform each one of those nodes across the proofing transform */ cmsDoTransform (transform, helper.data, helper.data, data_len); /* count the nodes that gives you zero and divide by total number */ for (i = 0; i < data_len; i++) { if (helper.data[i] == 0.0) cnt++; } /* success */ if (coverage != NULL) *coverage = (gdouble) cnt / (gdouble) data_len; out: cmsCloseProfile (profile_null); if (transform != NULL) cmsDeleteTransform (transform); return ret; }