summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRichard Hughes <richard@hughsie.com>2011-04-07 22:43:23 +0100
committerRichard Hughes <richard@hughsie.com>2011-04-07 22:43:37 +0100
commit9ae0fba1816cba725306174f5fc1a35a05bd36ef (patch)
tree3328308881fc23d329b587b0d6490959e288c3ea
parent69ea455a4187970ff178dd08818a6147acf8d452 (diff)
downloadcolord-9ae0fba1816cba725306174f5fc1a35a05bd36ef.tar.gz
Use the embedded profile-id if it is available, else fallback to the file MD5
This should speed up startup as we can use the pre-cooked value rather than using g_compute_checksum_for_data on every profile. This speeds up startup by more than 70% if all the system profiles are fixed.
-rw-r--r--doc/device-and-profile-naming-spec.txt14
-rw-r--r--src/cd-profile.c44
2 files changed, 50 insertions, 8 deletions
diff --git a/doc/device-and-profile-naming-spec.txt b/doc/device-and-profile-naming-spec.txt
index d43d67b..8ec13e0 100644
--- a/doc/device-and-profile-naming-spec.txt
+++ b/doc/device-and-profile-naming-spec.txt
@@ -129,10 +129,18 @@ and spaces and does not have to be escaped.
A profile ID is the same for binary identical profiles, even if
duplicated on the filesystem.
-In line with other ICC reccomendations, the complete MD5 file checksum
-is used for the profile ID, e.g.
+In line with other ICC reccomendations, the embedded profile ID (bytes
+84 to 99) is used, after converting it to a hexadecimal encoding.
-Format: icc-{%checksum}
+Format: icc-{%embedded-profile-id}
+Example: icc-3c219b18958837493b586581f8c2a2a4
+
+The ICC do not mandate the embedded profile-id and only recommend it,
+and as such few profiles in the wild use a real value.
+If the embedded profile ID is not set, the complete MD5 file checksum
+should be used instead, e.g.
+
+Format: icc-{%file-checksum}
Example: icc-bd847723f676e2b846daaf6759330624
If a physical profile does not exist (for instance, for embedded printer
diff --git a/src/cd-profile.c b/src/cd-profile.c
index 2b480e4..405b185 100644
--- a/src/cd-profile.c
+++ b/src/cd-profile.c
@@ -635,6 +635,36 @@ out:
}
/**
+ * cd_profile_get_precooked_md5:
+ **/
+static gchar *
+cd_profile_get_precooked_md5 (cmsHPROFILE lcms_profile)
+{
+ cmsUInt8Number profile_id[16];
+ gboolean md5_precooked = FALSE;
+ guint i;
+ gchar *md5 = NULL;
+
+ /* check to see if we have a pre-cooked MD5 */
+ cmsGetHeaderProfileID (lcms_profile, profile_id);
+ for (i=0; i<16; i++) {
+ if (profile_id[i] != 0) {
+ md5_precooked = TRUE;
+ break;
+ }
+ }
+ if (!md5_precooked)
+ goto out;
+
+ /* convert to a hex string */
+ md5 = g_new0 (gchar, 32 + 1);
+ for (i=0; i<16; i++)
+ g_snprintf (md5 + i*2, 3, "%x", profile_id[i]);
+out:
+ return md5;
+}
+
+/**
* cd_profile_set_filename:
**/
gboolean
@@ -771,11 +801,15 @@ cd_profile_set_filename (CdProfile *profile, const gchar *filename, GError **err
g_strdup (fake_md5));
}
- /* generate and set checksum */
- profile->priv->checksum =
- g_compute_checksum_for_data (G_CHECKSUM_MD5,
- (const guchar *) data,
- len);
+ /* use a pre-cooked MD5 if available, else fall back to
+ * calculating it ourselves */
+ profile->priv->checksum = cd_profile_get_precooked_md5 (lcms_profile);
+ if (profile->priv->checksum == NULL) {
+ profile->priv->checksum =
+ g_compute_checksum_for_data (G_CHECKSUM_MD5,
+ (const guchar *) data,
+ len);
+ }
/* success */
g_free (profile->priv->filename);