From f0623d1cdbfdb30ed44c94d6bceb46874e3fac46 Mon Sep 17 00:00:00 2001 From: Christopher James Halse Rogers Date: Fri, 15 Dec 2017 17:21:27 +1100 Subject: libcolord: Add cd_icc_set_created This allows clients to override the creation time of an ICC profile, particularly useful for code that tries to build deterministically. --- lib/colord/cd-icc.c | 62 +++++++++++++++++++++++++++++++++++++++++++++++++++++ lib/colord/cd-icc.h | 2 ++ 2 files changed, 64 insertions(+) diff --git a/lib/colord/cd-icc.c b/lib/colord/cd-icc.c index 5e9441a..e5f436a 100644 --- a/lib/colord/cd-icc.c +++ b/lib/colord/cd-icc.c @@ -29,9 +29,11 @@ #include #include #include +#include #include #include #include +#include #include #include "cd-context-lcms.h" @@ -70,6 +72,7 @@ typedef struct gdouble version; GHashTable *mluc_data[CD_MLUC_LAST]; /* key is 'en_GB' or '' for default */ GHashTable *metadata; + gint64 creation_time; guint32 size; GPtrArray *named_colors; guint temperature; @@ -1673,6 +1676,43 @@ cd_icc_save_data (CdIcc *icc, goto out; } + /* finally, optionally override the created date */ + if (priv->creation_time != -1) { + /* + * LCMS2 maintainer rejects adding API to do this, + * instead suggesting you munge the header directly: + * https://github.com/mm2/Little-CMS/issues/71 + */ + struct tm creation_time; + cmsICCHeader *header; + g_autoptr(GByteArray) mutable_data = NULL; + + data = cd_icc_serialize_profile (icc, error); + if (data == NULL) + goto out; + + mutable_data = g_bytes_unref_to_array (data); + data = NULL; + + if (!gmtime_r (&priv->creation_time, &creation_time)) { + g_set_error (error, + CD_ICC_ERROR, + CD_ICC_ERROR_FAILED_TO_SAVE, + "failed to translate creation time: %s (%i)", + g_strerror (errno), + errno); + goto out; + } + header = (cmsICCHeader*)mutable_data->data; + _cmsEncodeDateTimeNumber (&header->date, &creation_time); + + /* we've changed the creation date, recalculate MD5 */ + cmsCloseProfile (priv->lcms_profile); + priv->lcms_profile = cmsOpenProfileFromMemTHR (priv->context_lcms, + mutable_data->data, + mutable_data->len); + } + /* write profile id */ ret = cmsMD5computeID (priv->lcms_profile); if (!ret) { @@ -2398,6 +2438,10 @@ cd_icc_get_created (CdIcc *icc) g_return_val_if_fail (CD_IS_ICC (icc), NULL); + /* If the creation time has been overridden, return that */ + if (priv->creation_time != (gint64)-1) + return g_date_time_new_from_unix_local (priv->creation_time); + /* get the profile creation time and date */ if (!cmsGetHeaderCreationDateTime (priv->lcms_profile, &created_tm)) return NULL; @@ -2413,6 +2457,23 @@ cd_icc_get_created (CdIcc *icc) return g_date_time_new_from_unix_local (created_t); } +/** + * cd_icc_set_created + * @icc: A valid #CdIcc + * + * Sets the ICC creation date and time. + * + * Since: 1.4.2 + **/ +void +cd_icc_set_created (CdIcc *icc, GDateTime* creation_time) +{ + CdIccPrivate *priv = GET_PRIVATE (icc); + + g_return_if_fail (CD_IS_ICC (icc)); + priv->creation_time = g_date_time_to_unix (creation_time); +} + /** * cd_icc_get_checksum: * @icc: A valid #CdIcc @@ -3945,6 +4006,7 @@ cd_icc_init (CdIcc *icc) g_str_equal, g_free, g_free); + priv->creation_time = -1; for (i = 0; i < CD_MLUC_LAST; i++) { priv->mluc_data[i] = g_hash_table_new_full (g_str_hash, g_str_equal, diff --git a/lib/colord/cd-icc.h b/lib/colord/cd-icc.h index 35c605b..31699eb 100644 --- a/lib/colord/cd-icc.h +++ b/lib/colord/cd-icc.h @@ -195,6 +195,8 @@ void cd_icc_remove_metadata (CdIcc *icc, GPtrArray *cd_icc_get_named_colors (CdIcc *icc); gboolean cd_icc_get_can_delete (CdIcc *icc); GDateTime *cd_icc_get_created (CdIcc *icc); +void cd_icc_set_created (CdIcc *icc, + GDateTime *creation_time); const gchar *cd_icc_get_checksum (CdIcc *icc); const gchar *cd_icc_get_description (CdIcc *icc, const gchar *locale, -- cgit v1.2.1