gboolean gimp_lcms_profile_is_equal (GimpColorProfile profile1, GimpColorProfile profile2) { cmsUInt8Number digest1[GIMP_LCMS_MD5_DIGEST_LENGTH]; cmsUInt8Number digest2[GIMP_LCMS_MD5_DIGEST_LENGTH]; g_return_val_if_fail (profile1 != NULL, FALSE); g_return_val_if_fail (profile2 != NULL, FALSE); if (! cmsMD5computeID (profile1) || ! cmsMD5computeID (profile2)) { return FALSE; } cmsGetHeaderProfileID (profile1, digest1); cmsGetHeaderProfileID (profile2, digest2); return (memcmp (digest1, digest2, GIMP_LCMS_MD5_DIGEST_LENGTH) == 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; }