[gnome-color-manager] trivial: Do not subclass GcmProfile, as realistically we're never going to support using lcms1 _and_
- From: Richard Hughes <rhughes src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-color-manager] trivial: Do not subclass GcmProfile, as realistically we're never going to support using lcms1 _and_
- Date: Thu, 24 Jun 2010 11:06:35 +0000 (UTC)
commit 6646d00938437de62e0a8594ae3ce3d8c388e552
Author: Richard Hughes <richard hughsie com>
Date: Thu Jun 24 09:50:14 2010 +0100
trivial: Do not subclass GcmProfile, as realistically we're never going to support using lcms1 _and_ lcms2
src/Makefile.am | 2 -
src/gcm-device-xrandr.c | 2 +-
src/gcm-device.c | 4 +-
src/gcm-dump-profile.c | 2 +-
src/gcm-import.c | 2 +-
src/gcm-inspect.c | 2 +-
src/gcm-prefs.c | 2 +-
src/gcm-profile-lcms1.c | 999 -----------------------------------------------
src/gcm-profile-lcms1.h | 66 ---
src/gcm-profile-store.c | 2 +-
src/gcm-profile.c | 878 +++++++++++++++++++++++++++++++++++++++--
src/gcm-profile.h | 13 +-
src/gcm-self-test.c | 37 +-
13 files changed, 861 insertions(+), 1150 deletions(-)
---
diff --git a/src/Makefile.am b/src/Makefile.am
index 6b93d6a..abeab99 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -79,8 +79,6 @@ libgcmshared_a_SOURCES = \
gcm-gamma-widget.h \
gcm-profile-store.c \
gcm-profile-store.h \
- gcm-profile-lcms1.c \
- gcm-profile-lcms1.h \
gcm-profile.c \
gcm-profile.h \
gcm-calibrate.c \
diff --git a/src/gcm-device-xrandr.c b/src/gcm-device-xrandr.c
index c40cd42..b17e07a 100644
--- a/src/gcm-device-xrandr.c
+++ b/src/gcm-device-xrandr.c
@@ -549,7 +549,7 @@ gcm_device_xrandr_apply (GcmDevice *device, GError **error)
ret = g_file_test (filename_systemwide, G_FILE_TEST_EXISTS);
if (ret) {
egg_debug ("using systemwide %s as profile", filename_systemwide);
- profile = gcm_profile_default_new ();
+ profile = gcm_profile_new ();
file = g_file_new_for_path (filename_systemwide);
ret = gcm_profile_parse (profile, file, error);
g_object_unref (file);
diff --git a/src/gcm-device.c b/src/gcm-device.c
index 4a2933d..2ee18ea 100644
--- a/src/gcm-device.c
+++ b/src/gcm-device.c
@@ -553,7 +553,7 @@ gcm_device_set_default_profile_filename (GcmDevice *device, const gchar *profile
/* create new list */
array = g_ptr_array_new_with_free_func ((GDestroyNotify) g_object_unref);
- profile = gcm_profile_default_new ();
+ profile = gcm_profile_new ();
/* TODO: parse here? */
file = g_file_new_for_path (profile_filename);
@@ -646,7 +646,7 @@ gcm_device_load (GcmDevice *device, GError **error)
if (profile_filenames != NULL) {
for (i=0; profile_filenames[i] != NULL; i++) {
file_tmp = g_file_new_for_path (profile_filenames[i]);
- profile = gcm_profile_default_new ();
+ profile = gcm_profile_new ();
ret = gcm_profile_parse (profile, file_tmp, &error_local);
if (ret) {
g_ptr_array_add (priv->profiles, g_object_ref (profile));
diff --git a/src/gcm-dump-profile.c b/src/gcm-dump-profile.c
index 8930b7d..43ecc22 100644
--- a/src/gcm-dump-profile.c
+++ b/src/gcm-dump-profile.c
@@ -51,7 +51,7 @@ gcm_dump_profile_filename (const gchar *filename)
GFile *file = NULL;
/* parse profile */
- profile = gcm_profile_default_new ();
+ profile = gcm_profile_new ();
file = g_file_new_for_path (filename);
ret = gcm_profile_parse (profile, file, &error);
if (!ret) {
diff --git a/src/gcm-import.c b/src/gcm-import.c
index 806fa26..f066412 100644
--- a/src/gcm-import.c
+++ b/src/gcm-import.c
@@ -110,7 +110,7 @@ main (int argc, char **argv)
}
/* load profile */
- profile = gcm_profile_default_new ();
+ profile = gcm_profile_new ();
file = g_file_new_for_path (files[0]);
ret = gcm_profile_parse (profile, file, &error);
if (!ret) {
diff --git a/src/gcm-inspect.c b/src/gcm-inspect.c
index d05bedb..8b101a1 100644
--- a/src/gcm-inspect.c
+++ b/src/gcm-inspect.c
@@ -44,7 +44,7 @@ gcm_inspect_print_data_info (const gchar *title, const guint8 *data, gsize lengt
gboolean ret;
/* parse the data */
- profile = gcm_profile_default_new ();
+ profile = gcm_profile_new ();
ret = gcm_profile_parse_data (profile, data, length, &error);
if (!ret) {
egg_warning ("failed to parse data: %s", error->message);
diff --git a/src/gcm-prefs.c b/src/gcm-prefs.c
index 142a94a..51b4852 100644
--- a/src/gcm-prefs.c
+++ b/src/gcm-prefs.c
@@ -2391,7 +2391,7 @@ gcm_prefs_profile_combo_changed_cb (GtkWidget *widget, GcmPrefsData *prefsdata)
/* get an object of the destination */
dest = gcm_utils_get_profile_destination (file);
- profile = gcm_profile_default_new ();
+ profile = gcm_profile_new ();
ret = gcm_profile_parse (profile, dest, &error);
if (!ret) {
/* set to first entry */
diff --git a/src/gcm-profile-store.c b/src/gcm-profile-store.c
index 8815512..aeda5bd 100644
--- a/src/gcm-profile-store.c
+++ b/src/gcm-profile-store.c
@@ -223,7 +223,7 @@ gcm_profile_store_add_profile (GcmProfileStore *profile_store, GFile *file)
goto out;
/* parse the profile name */
- profile = gcm_profile_default_new ();
+ profile = gcm_profile_new ();
ret = gcm_profile_parse (profile, file, &error);
if (!ret) {
egg_warning ("failed to add profile '%s': %s", filename, error->message);
diff --git a/src/gcm-profile.c b/src/gcm-profile.c
index 7088452..4d0467b 100644
--- a/src/gcm-profile.c
+++ b/src/gcm-profile.c
@@ -32,18 +32,57 @@
#include <glib-object.h>
#include <glib/gi18n.h>
#include <gio/gio.h>
+#include <lcms.h>
#include "egg-debug.h"
#include "gcm-profile.h"
#include "gcm-utils.h"
#include "gcm-xyz.h"
-#include "gcm-profile-lcms1.h"
static void gcm_profile_finalize (GObject *object);
#define GCM_PROFILE_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), GCM_TYPE_PROFILE, GcmProfilePrivate))
+#define GCM_NUMTAGS 0x80
+#define GCM_BODY 0x84
+
+#define GCM_TAG_ID 0x00
+#define GCM_TAG_OFFSET 0x04
+#define GCM_TAG_SIZE 0x08
+#define GCM_TAG_WIDTH 0x0c
+
+#define icSigVideoCartGammaTableTag 0x76636774
+#define icSigMachineLookUpTableTag 0x6d4c5554
+
+#define GCM_MLUT_RED 0x000
+#define GCM_MLUT_GREEN 0x200
+#define GCM_MLUT_BLUE 0x400
+
+#define GCM_DESC_RECORD_SIZE 0x08
+#define GCM_DESC_RECORD_TEXT 0x0c
+#define GCM_TEXT_RECORD_TEXT 0x08
+
+#define GCM_VCGT_ID 0x00
+#define GCM_VCGT_DUMMY 0x04
+#define GCM_VCGT_GAMMA_TYPE 0x08
+#define GCM_VCGT_GAMMA_DATA 0x0c
+
+#define GCM_VCGT_FORMULA_GAMMA_RED 0x00
+#define GCM_VCGT_FORMULA_MIN_RED 0x04
+#define GCM_VCGT_FORMULA_MAX_RED 0x08
+#define GCM_VCGT_FORMULA_GAMMA_GREEN 0x0c
+#define GCM_VCGT_FORMULA_MIN_GREEN 0x10
+#define GCM_VCGT_FORMULA_MAX_GREEN 0x14
+#define GCM_VCGT_FORMULA_GAMMA_BLUE 0x18
+#define GCM_VCGT_FORMULA_MIN_BLUE 0x1c
+#define GCM_VCGT_FORMULA_MAX_BLUE 0x20
+
+#define GCM_VCGT_TABLE_NUM_CHANNELS 0x00
+#define GCM_VCGT_TABLE_NUM_ENTRIES 0x02
+#define GCM_VCGT_TABLE_NUM_SIZE 0x04
+#define GCM_VCGT_TABLE_NUM_DATA 0x06
+
/**
* GcmProfilePrivate:
*
@@ -69,6 +108,17 @@ struct _GcmProfilePrivate
GcmXyz *green;
GcmXyz *blue;
GFileMonitor *monitor;
+
+ gboolean loaded;
+ gboolean has_mlut;
+ gboolean has_vcgt_formula;
+ gboolean has_vcgt_table;
+ cmsHPROFILE lcms_profile;
+ GcmClutData *vcgt_data;
+ guint vcgt_data_size;
+ GcmClutData *mlut_data;
+ guint mlut_data_size;
+ gboolean adobe_gamma_workaround;
};
enum {
@@ -98,6 +148,301 @@ G_DEFINE_TYPE (GcmProfile, gcm_profile, G_TYPE_OBJECT)
static void gcm_profile_file_monitor_changed_cb (GFileMonitor *monitor, GFile *file, GFile *other_file, GFileMonitorEvent event_type, GcmProfile *profile);
/**
+ * gcm_parser_decode_32:
+ **/
+static guint
+gcm_parser_decode_32 (const guint8 *data)
+{
+ guint retval;
+ retval = (*(data + 0) << 0) + (*(data + 1) << 8) + (*(data + 2) << 16) + (*(data + 3) << 24);
+ return GUINT32_FROM_BE (retval);
+}
+
+/**
+ * gcm_parser_decode_16:
+ **/
+static guint
+gcm_parser_decode_16 (const guint8 *data)
+{
+ guint retval;
+ retval = (*(data + 0) << 0) + (*(data + 1) << 8);
+ return GUINT16_FROM_BE (retval);
+}
+
+/**
+ * gcm_parser_decode_8:
+ **/
+static guint
+gcm_parser_decode_8 (const guint8 *data)
+{
+ guint retval;
+ retval = (*data << 0);
+ return GUINT16_FROM_BE (retval);
+}
+
+/**
+ * gcm_parser_load_icc_mlut:
+ **/
+static gboolean
+gcm_parser_load_icc_mlut (GcmProfile *profile, const guint8 *data, guint size)
+{
+ gboolean ret = TRUE;
+ guint i;
+ GcmClutData *mlut_data;
+
+ /* just load in data into a fixed size LUT */
+ profile->priv->mlut_data = g_new0 (GcmClutData, 256);
+ mlut_data = profile->priv->mlut_data;
+
+ for (i=0; i<256; i++)
+ mlut_data[i].red = gcm_parser_decode_16 (data + GCM_MLUT_RED + i*2);
+ for (i=0; i<256; i++)
+ mlut_data[i].green = gcm_parser_decode_16 (data + GCM_MLUT_GREEN + i*2);
+ for (i=0; i<256; i++)
+ mlut_data[i].blue = gcm_parser_decode_16 (data + GCM_MLUT_BLUE + i*2);
+
+ /* save datatype */
+ profile->priv->has_mlut = TRUE;
+ return ret;
+}
+
+/**
+ * gcm_parser_load_icc_vcgt_formula:
+ **/
+static gboolean
+gcm_parser_load_icc_vcgt_formula (GcmProfile *profile, const guint8 *data, guint size)
+{
+ gboolean ret = FALSE;
+ GcmClutData *vcgt_data;
+
+ /* just load in data into a temporary array */
+ profile->priv->vcgt_data = g_new0 (GcmClutData, 4);
+ vcgt_data = profile->priv->vcgt_data;
+
+ /* read in block of data */
+ vcgt_data[0].red = gcm_parser_decode_32 (data + GCM_VCGT_FORMULA_GAMMA_RED);
+ vcgt_data[0].green = gcm_parser_decode_32 (data + GCM_VCGT_FORMULA_GAMMA_GREEN);
+ vcgt_data[0].blue = gcm_parser_decode_32 (data + GCM_VCGT_FORMULA_GAMMA_BLUE);
+
+ vcgt_data[1].red = gcm_parser_decode_32 (data + GCM_VCGT_FORMULA_MIN_RED);
+ vcgt_data[1].green = gcm_parser_decode_32 (data + GCM_VCGT_FORMULA_MIN_GREEN);
+ vcgt_data[1].blue = gcm_parser_decode_32 (data + GCM_VCGT_FORMULA_MIN_BLUE);
+
+ vcgt_data[2].red = gcm_parser_decode_32 (data + GCM_VCGT_FORMULA_MAX_RED);
+ vcgt_data[2].green = gcm_parser_decode_32 (data + GCM_VCGT_FORMULA_MAX_GREEN);
+ vcgt_data[2].blue = gcm_parser_decode_32 (data + GCM_VCGT_FORMULA_MAX_BLUE);
+
+ /* check if valid */
+ if (vcgt_data[0].red / 65536.0 > 5.0 || vcgt_data[0].green / 65536.0 > 5.0 || vcgt_data[0].blue / 65536.0 > 5.0) {
+ egg_warning ("Gamma values out of range: [R:%u G:%u B:%u]", vcgt_data[0].red, vcgt_data[0].green, vcgt_data[0].blue);
+ goto out;
+ }
+ if (vcgt_data[1].red / 65536.0 >= 1.0 || vcgt_data[1].green / 65536.0 >= 1.0 || vcgt_data[1].blue / 65536.0 >= 1.0) {
+ egg_warning ("Gamma min limit out of range: [R:%u G:%u B:%u]", vcgt_data[1].red, vcgt_data[1].green, vcgt_data[1].blue);
+ goto out;
+ }
+ if (vcgt_data[2].red / 65536.0 > 1.0 || vcgt_data[2].green / 65536.0 > 1.0 || vcgt_data[2].blue / 65536.0 > 1.0) {
+ egg_warning ("Gamma max limit out of range: [R:%u G:%u B:%u]", vcgt_data[2].red, vcgt_data[2].green, vcgt_data[2].blue);
+ goto out;
+ }
+
+ /* save datatype */
+ profile->priv->has_vcgt_formula = TRUE;
+ profile->priv->vcgt_data_size = 3;
+ ret = TRUE;
+out:
+ return ret;
+}
+
+/**
+ * gcm_parser_load_icc_vcgt_table:
+ **/
+static gboolean
+gcm_parser_load_icc_vcgt_table (GcmProfile *profile, const guint8 *data, guint size)
+{
+ gboolean ret = TRUE;
+ guint num_channels = 0;
+ guint num_entries = 0;
+ guint entry_size = 0;
+ guint i;
+ GcmClutData *vcgt_data;
+
+ num_channels = gcm_parser_decode_16 (data + GCM_VCGT_TABLE_NUM_CHANNELS);
+ num_entries = gcm_parser_decode_16 (data + GCM_VCGT_TABLE_NUM_ENTRIES);
+ entry_size = gcm_parser_decode_16 (data + GCM_VCGT_TABLE_NUM_SIZE);
+
+ /* work-around for AdobeGamma-ProfileLcms1s (taken from xcalib) */
+ if (profile->priv->adobe_gamma_workaround) {
+ egg_debug ("Working around AdobeGamma profile");
+ entry_size = 2;
+ num_entries = 256;
+ num_channels = 3;
+ }
+
+ /* only able to parse RGB data */
+ if (num_channels != 3) {
+ egg_warning ("cannot parse non RGB entries");
+ ret = FALSE;
+ goto out;
+ }
+
+ /* bigger than will fit in 16 bits? */
+ if (entry_size > 2) {
+ egg_warning ("cannot parse large entries");
+ ret = FALSE;
+ goto out;
+ }
+
+ /* allocate ramp, plus one entry for extrapolation */
+ profile->priv->vcgt_data = g_new0 (GcmClutData, num_entries + 1);
+ vcgt_data = profile->priv->vcgt_data;
+
+ if (entry_size == 1) {
+ for (i=0; i<num_entries; i++)
+ vcgt_data[i].red = gcm_parser_decode_8 (data + GCM_VCGT_TABLE_NUM_DATA + (num_entries * 0) + i);
+ for (i=0; i<num_entries; i++)
+ vcgt_data[i].green = gcm_parser_decode_8 (data + GCM_VCGT_TABLE_NUM_DATA + (num_entries * 1) + i);
+ for (i=0; i<num_entries; i++)
+ vcgt_data[i].blue = gcm_parser_decode_8 (data + GCM_VCGT_TABLE_NUM_DATA + (num_entries * 2) + i);
+ } else {
+ for (i=0; i<num_entries; i++)
+ vcgt_data[i].red = gcm_parser_decode_16 (data + GCM_VCGT_TABLE_NUM_DATA + (num_entries * 0) + (i*2));
+ for (i=0; i<num_entries; i++)
+ vcgt_data[i].green = gcm_parser_decode_16 (data + GCM_VCGT_TABLE_NUM_DATA + (num_entries * 2) + (i*2));
+ for (i=0; i<num_entries; i++)
+ vcgt_data[i].blue = gcm_parser_decode_16 (data + GCM_VCGT_TABLE_NUM_DATA + (num_entries * 4) + (i*2));
+ }
+
+ /* save datatype */
+ profile->priv->has_vcgt_table = TRUE;
+ profile->priv->vcgt_data_size = num_entries;
+out:
+ return ret;
+}
+
+/**
+ * gcm_parser_load_icc_vcgt:
+ **/
+static gboolean
+gcm_parser_load_icc_vcgt (GcmProfile *profile, const guint8 *data, guint size)
+{
+ gboolean ret = FALSE;
+ guint tag_id;
+ guint gamma_type;
+
+ /* check we have a VCGT block */
+ tag_id = gcm_parser_decode_32 (data);
+ if (tag_id != icSigVideoCartGammaTableTag) {
+ egg_warning ("invalid content of table vcgt, starting with %x", tag_id);
+ goto out;
+ }
+
+ /* check what type of gamma encoding we have */
+ gamma_type = gcm_parser_decode_32 (data + GCM_VCGT_GAMMA_TYPE);
+ if (gamma_type == 0) {
+ ret = gcm_parser_load_icc_vcgt_table (profile, data + GCM_VCGT_GAMMA_DATA, size);
+ goto out;
+ }
+ if (gamma_type == 1) {
+ ret = gcm_parser_load_icc_vcgt_formula (profile, data + GCM_VCGT_GAMMA_DATA, size);
+ goto out;
+ }
+
+ /* we didn't understand the encoding */
+ egg_warning ("gamma type encoding not recognized");
+out:
+ return ret;
+}
+
+/**
+ * gcm_profile_utf16be_to_locale:
+ *
+ * Convert ICC encoded UTF-16BE into a string the user can understand
+ **/
+static gchar *
+gcm_profile_utf16be_to_locale (const guint8 *text, guint size)
+{
+ gsize items_written;
+ gchar *text_utf8 = NULL;
+ gchar *text_locale = NULL;
+ GError *error = NULL;
+
+ /* convert from ICC text encoding to UTF-8 */
+ text_utf8 = g_convert ((const gchar*)text, size, "UTF-8", "UTF-16BE", NULL, &items_written, &error);
+ if (text_utf8 == NULL) {
+ egg_warning ("failed to convert to UTF-8: %s", error->message);
+ g_error_free (error);
+ goto out;
+ }
+
+ /* convert from UTF-8 to the users locale*/
+ text_locale = g_locale_from_utf8 (text_utf8, items_written, NULL, NULL, &error);
+ if (text_locale == NULL) {
+ egg_warning ("failed to convert to locale: %s", error->message);
+ g_error_free (error);
+ goto out;
+ }
+out:
+ g_free (text_utf8);
+ return text_locale;
+}
+
+/**
+ * gcm_profile_parse_multi_localized_unicode:
+ **/
+static gchar *
+gcm_profile_parse_multi_localized_unicode (GcmProfile *profile, const guint8 *data, guint size)
+{
+ guint i;
+ gchar *text = NULL;
+ guint record_size;
+ guint names_size;
+ guint len;
+ guint offset_name;
+ guint32 type;
+
+ /* get type */
+ type = gcm_parser_decode_32 (data);
+
+ /* check we are not a localized tag */
+ if (type == icSigTextDescriptionType) {
+ record_size = gcm_parser_decode_32 (data + GCM_DESC_RECORD_SIZE);
+ text = g_strndup ((const gchar*)&data[GCM_DESC_RECORD_TEXT], record_size);
+ goto out;
+ }
+
+ /* check we are not a localized tag */
+ if (type == icSigTextType) {
+ text = g_strdup ((const gchar*)&data[GCM_TEXT_RECORD_TEXT]);
+ goto out;
+ }
+
+ /* check we are not a localized tag */
+ if (type == icSigMultiLocalizedUnicodeType) {
+ names_size = gcm_parser_decode_32 (data + 8);
+ if (names_size != 1) {
+ /* there is more than one language encoded */
+ egg_warning ("more than one item of data in MLUC (names size: %i), using first one", names_size);
+ }
+ len = gcm_parser_decode_32 (data + 20);
+ offset_name = gcm_parser_decode_32 (data + 24);
+ text = gcm_profile_utf16be_to_locale (data + offset_name, len);
+ goto out;
+ }
+
+ /* an unrecognized tag */
+ for (i=0x0; i<0x1c; i++) {
+ egg_warning ("unrecognized text tag");
+ if (data[i] >= 'A' && data[i] <= 'z')
+ egg_debug ("%i\t%c (%i)", i, data[i], data[i]);
+ else
+ egg_debug ("%i\t (%i)", i, data[i]);
+ }
+out:
+ return text;
+}
+
+/**
* gcm_profile_get_description:
**/
const gchar *
@@ -128,7 +473,7 @@ gcm_profile_set_description (GcmProfile *profile, const gchar *description)
if (priv->filename != NULL) {
priv->description = g_path_get_basename (priv->filename);
} else {
- /* TRANSLATORS: this is where the ICC profile_lcms1 has no description */
+ /* TRANSLATORS: this is where the ICC profile has no description */
priv->description = g_strdup (_("Missing description"));
}
}
@@ -431,22 +776,283 @@ gcm_profile_parse_data (GcmProfile *profile, const guint8 *data, gsize length, G
{
gboolean ret = FALSE;
gchar *checksum = NULL;
+ guint num_tags;
+ guint i;
+ guint tag_id;
+ guint offset;
+ guint tag_size;
+ guint tag_offset;
+ icProfileClassSignature profile_class;
+ icColorSpaceSignature color_space;
+ GcmColorspace colorspace;
+ GcmProfileKind profile_kind;
+ cmsCIEXYZ cie_xyz;
+ cmsCIEXYZTRIPLE cie_illum;
+ struct tm created;
+ cmsHPROFILE xyz_profile;
+ cmsHTRANSFORM transform;
+ gchar *text;
+ GcmXyz *xyz;
GcmProfilePrivate *priv = profile->priv;
- GcmProfileClass *klass = GCM_PROFILE_GET_CLASS (profile);
+
+ g_return_val_if_fail (GCM_IS_PROFILE (profile), FALSE);
+ g_return_val_if_fail (data != NULL, FALSE);
+ g_return_val_if_fail (priv->loaded == FALSE, FALSE);
/* save the length */
priv->size = length;
+ priv->loaded = TRUE;
- /* do we have support */
- if (klass->parse_data == NULL) {
- g_set_error_literal (error, 1, 0, "no support");
+ /* load profile into lcms */
+ priv->lcms_profile = cmsOpenProfileFromMem ((LPVOID)data, length);
+ if (priv->lcms_profile == NULL) {
+ g_set_error_literal (error, 1, 0, "failed to load: not an ICC profile");
goto out;
}
- /* proxy */
- ret = klass->parse_data (profile, data, length, error);
- if (!ret)
- goto out;
+ /* get white point */
+ ret = cmsTakeMediaWhitePoint (&cie_xyz, priv->lcms_profile);
+ if (ret) {
+ xyz = gcm_xyz_new ();
+ g_object_set (xyz,
+ "cie-x", cie_xyz.X,
+ "cie-y", cie_xyz.Y,
+ "cie-z", cie_xyz.Z,
+ NULL);
+ g_object_set (profile,
+ "white", xyz,
+ NULL);
+ g_object_unref (xyz);
+ } else {
+ egg_warning ("failed to get white point");
+ }
+
+ /* get black point */
+ ret = cmsTakeMediaBlackPoint (&cie_xyz, priv->lcms_profile);
+ if (ret) {
+ xyz = gcm_xyz_new ();
+ g_object_set (xyz,
+ "cie-x", cie_xyz.X,
+ "cie-y", cie_xyz.Y,
+ "cie-z", cie_xyz.Z,
+ NULL);
+ g_object_set (profile,
+ "black", xyz,
+ NULL);
+ g_object_unref (xyz);
+ } else {
+ egg_warning ("failed to get black point");
+ }
+
+ /* get the profile kind */
+ profile_class = cmsGetDeviceClass (priv->lcms_profile);
+ switch (profile_class) {
+ case icSigInputClass:
+ profile_kind = GCM_PROFILE_KIND_INPUT_DEVICE;
+ break;
+ case icSigDisplayClass:
+ profile_kind = GCM_PROFILE_KIND_DISPLAY_DEVICE;
+ break;
+ case icSigOutputClass:
+ profile_kind = GCM_PROFILE_KIND_OUTPUT_DEVICE;
+ break;
+ case icSigLinkClass:
+ profile_kind = GCM_PROFILE_KIND_DEVICELINK;
+ break;
+ case icSigColorSpaceClass:
+ profile_kind = GCM_PROFILE_KIND_COLORSPACE_CONVERSION;
+ break;
+ case icSigAbstractClass:
+ profile_kind = GCM_PROFILE_KIND_ABSTRACT;
+ break;
+ case icSigNamedColorClass:
+ profile_kind = GCM_PROFILE_KIND_NAMED_COLOR;
+ break;
+ default:
+ profile_kind = GCM_PROFILE_KIND_UNKNOWN;
+ }
+ gcm_profile_set_kind (profile, profile_kind);
+
+ /* get colorspace */
+ color_space = cmsGetColorSpace (priv->lcms_profile);
+ switch (color_space) {
+ case icSigXYZData:
+ colorspace = GCM_COLORSPACE_XYZ;
+ break;
+ case icSigLabData:
+ colorspace = GCM_COLORSPACE_LAB;
+ break;
+ case icSigLuvData:
+ colorspace = GCM_COLORSPACE_LUV;
+ break;
+ case icSigYCbCrData:
+ colorspace = GCM_COLORSPACE_YCBCR;
+ break;
+ case icSigYxyData:
+ colorspace = GCM_COLORSPACE_YXY;
+ break;
+ case icSigRgbData:
+ colorspace = GCM_COLORSPACE_RGB;
+ break;
+ case icSigGrayData:
+ colorspace = GCM_COLORSPACE_GRAY;
+ break;
+ case icSigHsvData:
+ colorspace = GCM_COLORSPACE_HSV;
+ break;
+ case icSigCmykData:
+ colorspace = GCM_COLORSPACE_CMYK;
+ break;
+ case icSigCmyData:
+ colorspace = GCM_COLORSPACE_CMY;
+ break;
+ default:
+ colorspace = GCM_COLORSPACE_UNKNOWN;
+ }
+ gcm_profile_set_colorspace (profile, colorspace);
+
+ /* get primary illuminants */
+ ret = cmsTakeColorants (&cie_illum, priv->lcms_profile);
+
+ /* geting the illuminants failed, try running it through the profile */
+ if (!ret && color_space == icSigRgbData) {
+ gdouble rgb_values[3];
+
+ /* create a transform from profile to XYZ */
+ xyz_profile = cmsCreateXYZProfile ();
+ transform = cmsCreateTransform (priv->lcms_profile, TYPE_RGB_DBL, xyz_profile, TYPE_XYZ_DBL, INTENT_PERCEPTUAL, 0);
+ if (transform != NULL) {
+
+ /* red */
+ rgb_values[0] = 1.0;
+ rgb_values[1] = 0.0;
+ rgb_values[2] = 0.0;
+ cmsDoTransform (transform, rgb_values, &cie_illum.Red, 1);
+
+ /* green */
+ rgb_values[0] = 0.0;
+ rgb_values[1] = 1.0;
+ rgb_values[2] = 0.0;
+ cmsDoTransform (transform, rgb_values, &cie_illum.Green, 1);
+
+ /* blue */
+ rgb_values[0] = 0.0;
+ rgb_values[1] = 0.0;
+ rgb_values[2] = 1.0;
+ cmsDoTransform (transform, rgb_values, &cie_illum.Blue, 1);
+
+ /* we're done */
+ cmsDeleteTransform (transform);
+ ret = TRUE;
+ }
+
+ /* no more need for the output profile */
+ cmsCloseProfile (xyz_profile);
+ }
+
+ /* we've got valid values */
+ if (ret) {
+ /* red */
+ xyz = gcm_xyz_new ();
+ g_object_set (xyz,
+ "cie-x", cie_illum.Red.X,
+ "cie-y", cie_illum.Red.Y,
+ "cie-z", cie_illum.Red.Z,
+ NULL);
+ g_object_set (profile,
+ "red", xyz,
+ NULL);
+ g_object_unref (xyz);
+
+ /* green */
+ xyz = gcm_xyz_new ();
+ g_object_set (xyz,
+ "cie-x", cie_illum.Green.X,
+ "cie-y", cie_illum.Green.Y,
+ "cie-z", cie_illum.Green.Z,
+ NULL);
+ g_object_set (profile,
+ "green", xyz,
+ NULL);
+ g_object_unref (xyz);
+
+ /* blue */
+ xyz = gcm_xyz_new ();
+ g_object_set (xyz,
+ "cie-x", cie_illum.Blue.X,
+ "cie-y", cie_illum.Blue.Y,
+ "cie-z", cie_illum.Blue.Z,
+ NULL);
+ g_object_set (profile,
+ "blue", xyz,
+ NULL);
+ g_object_unref (xyz);
+ } else {
+ egg_debug ("failed to get luminance values");
+ }
+
+ /* get the profile created time and date */
+ ret = cmsTakeCreationDateTime (&created, priv->lcms_profile);
+ if (ret) {
+ text = gcm_utils_format_date_time (&created);
+ gcm_profile_set_datetime (profile, text);
+ g_free (text);
+ }
+
+ /* get the number of tags in the file */
+ num_tags = gcm_parser_decode_32 (data + GCM_NUMTAGS);
+ for (i=0; i<num_tags; i++) {
+ offset = GCM_TAG_WIDTH * i;
+ tag_id = gcm_parser_decode_32 (data + GCM_BODY + offset + GCM_TAG_ID);
+ tag_offset = gcm_parser_decode_32 (data + GCM_BODY + offset + GCM_TAG_OFFSET);
+ tag_size = gcm_parser_decode_32 (data + GCM_BODY + offset + GCM_TAG_SIZE);
+
+ /* print tag */
+// egg_debug ("tag %x is present at 0x%x with size %u", tag_id, tag_offset, tag_size);
+
+ if (tag_id == icSigProfileDescriptionTag) {
+ text = gcm_profile_parse_multi_localized_unicode (profile, data + tag_offset, tag_size);
+ gcm_profile_set_description (profile, text);
+ g_free (text);
+ }
+ if (tag_id == icSigCopyrightTag) {
+ text = gcm_profile_parse_multi_localized_unicode (profile, data + tag_offset, tag_size);
+ gcm_profile_set_copyright (profile, text);
+ g_free (text);
+ }
+ if (tag_id == icSigDeviceMfgDescTag) {
+ text = gcm_profile_parse_multi_localized_unicode (profile, data + tag_offset, tag_size);
+ gcm_profile_set_manufacturer (profile, text);
+ g_free (text);
+ }
+ if (tag_id == icSigDeviceModelDescTag) {
+ text = gcm_profile_parse_multi_localized_unicode (profile, data + tag_offset, tag_size);
+ gcm_profile_set_model (profile, text);
+ g_free (text);
+ }
+ if (tag_id == icSigMachineLookUpTableTag) {
+ ret = gcm_parser_load_icc_mlut (profile, data + tag_offset, tag_size);
+ if (!ret) {
+ g_set_error_literal (error, 1, 0, "failed to load mlut");
+ goto out;
+ }
+ }
+ if (tag_id == icSigVideoCartGammaTableTag) {
+ if (tag_size == 1584)
+ priv->adobe_gamma_workaround = TRUE;
+ ret = gcm_parser_load_icc_vcgt (profile, data + tag_offset, tag_size);
+ if (!ret) {
+ g_set_error_literal (error, 1, 0, "failed to load vcgt");
+ goto out;
+ }
+ }
+ }
+
+ /* success */
+ ret = TRUE;
+
+ /* set properties */
+ gcm_profile_set_has_vcgt (profile, priv->has_vcgt_formula || priv->has_vcgt_table);
/* generate and set checksum */
checksum = g_compute_checksum_for_data (G_CHECKSUM_MD5, (const guchar *) data, length);
@@ -511,7 +1117,6 @@ gcm_profile_save (GcmProfile *profile, const gchar *filename, GError **error)
{
gboolean ret = FALSE;
GcmProfilePrivate *priv = profile->priv;
- GcmProfileClass *klass = GCM_PROFILE_GET_CLASS (profile);
/* not loaded */
if (priv->size == 0) {
@@ -519,14 +1124,9 @@ gcm_profile_save (GcmProfile *profile, const gchar *filename, GError **error)
goto out;
}
- /* do we have support */
- if (klass->save == NULL) {
- g_set_error_literal (error, 1, 0, "no support");
- goto out;
- }
-
- /* proxy */
- ret = klass->save (profile, filename, error);
+ /* save, TODO: get error */
+ _cmsSaveProfile (priv->lcms_profile, filename);
+ ret = TRUE;
out:
return ret;
}
@@ -539,16 +1139,122 @@ out:
GcmClut *
gcm_profile_generate_vcgt (GcmProfile *profile, guint size)
{
+ /* proxy */
+ guint i;
+ guint ratio;
+ GcmClutData *tmp;
+ GcmClutData *vcgt_data;
+ GcmClutData *mlut_data;
+ gfloat gamma_red, min_red, max_red;
+ gfloat gamma_green, min_green, max_green;
+ gfloat gamma_blue, min_blue, max_blue;
+ guint num_entries;
GcmClut *clut = NULL;
- GcmProfileClass *klass = GCM_PROFILE_GET_CLASS (profile);
+ GPtrArray *array = NULL;
+ gfloat inverse_ratio;
+ guint idx;
+ gfloat frac;
+
+ g_return_val_if_fail (GCM_IS_PROFILE (profile), NULL);
+ g_return_val_if_fail (size != 0, FALSE);
+
+ /* reduce dereferences */
+ vcgt_data = profile->priv->vcgt_data;
+ mlut_data = profile->priv->mlut_data;
+
+ if (profile->priv->has_vcgt_table) {
+
+ /* create array */
+ array = g_ptr_array_new_with_free_func (g_free);
+
+ /* simply subsample if the LUT is smaller than the number of entries in the file */
+ num_entries = profile->priv->vcgt_data_size;
+ if (num_entries >= size) {
+ ratio = (guint) (num_entries / size);
+ for (i=0; i<size; i++) {
+ /* add a point */
+ tmp = g_new0 (GcmClutData, 1);
+ tmp->red = vcgt_data[ratio*i].red;
+ tmp->green = vcgt_data[ratio*i].green;
+ tmp->blue = vcgt_data[ratio*i].blue;
+ g_ptr_array_add (array, tmp);
+ }
+ goto out;
+ }
- /* do we have support */
- if (klass->generate_vcgt == NULL)
+ /* LUT is bigger than number of entries, so interpolate */
+ inverse_ratio = (gfloat) num_entries / size;
+ vcgt_data[num_entries].red = 0xffff;
+ vcgt_data[num_entries].green = 0xffff;
+ vcgt_data[num_entries].blue = 0xffff;
+
+ /* interpolate */
+ for (i=0; i<size; i++) {
+ idx = floor(i*inverse_ratio);
+ frac = (i*inverse_ratio) - idx;
+ tmp = g_new0 (GcmClutData, 1);
+ tmp->red = vcgt_data[idx].red * (1.0f-frac) + vcgt_data[idx + 1].red * frac;
+ tmp->green = vcgt_data[idx].green * (1.0f-frac) + vcgt_data[idx + 1].green * frac;
+ tmp->blue = vcgt_data[idx].blue * (1.0f-frac) + vcgt_data[idx + 1].blue * frac;
+ g_ptr_array_add (array, tmp);
+ }
goto out;
+ }
- /* proxy */
- clut = klass->generate_vcgt (profile, size);
+ if (profile->priv->has_vcgt_formula) {
+
+ /* create array */
+ array = g_ptr_array_new_with_free_func (g_free);
+
+ gamma_red = (gfloat) vcgt_data[0].red / 65536.0;
+ gamma_green = (gfloat) vcgt_data[0].green / 65536.0;
+ gamma_blue = (gfloat) vcgt_data[0].blue / 65536.0;
+ min_red = (gfloat) vcgt_data[1].red / 65536.0;
+ min_green = (gfloat) vcgt_data[1].green / 65536.0;
+ min_blue = (gfloat) vcgt_data[1].blue / 65536.0;
+ max_red = (gfloat) vcgt_data[2].red / 65536.0;
+ max_green = (gfloat) vcgt_data[2].green / 65536.0;
+ max_blue = (gfloat) vcgt_data[2].blue / 65536.0;
+
+ /* create mapping of desired size */
+ for (i=0; i<size; i++) {
+ /* add a point */
+ tmp = g_new0 (GcmClutData, 1);
+ tmp->red = 65536.0 * ((gdouble) pow ((gdouble) i / (gdouble) size, gamma_red) * (max_red - min_red) + min_red);
+ tmp->green = 65536.0 * ((gdouble) pow ((gdouble) i / (gdouble) size, gamma_green) * (max_green - min_green) + min_green);
+ tmp->blue = 65536.0 * ((gdouble) pow ((gdouble) i / (gdouble) size, gamma_blue) * (max_blue - min_blue) + min_blue);
+ g_ptr_array_add (array, tmp);
+ }
+ goto out;
+ }
+
+ if (profile->priv->has_mlut) {
+
+ /* create array */
+ array = g_ptr_array_new_with_free_func (g_free);
+
+ /* roughly interpolate table */
+ ratio = (guint) (256 / (size));
+ for (i=0; i<size; i++) {
+ /* add a point */
+ tmp = g_new0 (GcmClutData, 1);
+ tmp->red = mlut_data[ratio*i].red;
+ tmp->green = mlut_data[ratio*i].green;
+ tmp->blue = mlut_data[ratio*i].blue;
+ g_ptr_array_add (array, tmp);
+ }
+ goto out;
+ }
+
+ /* bugger */
+ egg_debug ("no LUT to generate");
out:
+ if (array != NULL) {
+ /* create new output array */
+ clut = gcm_clut_new ();
+ gcm_clut_set_source_array (clut, array);
+ g_ptr_array_unref (array);
+ }
return clut;
}
@@ -561,15 +1267,89 @@ GcmClut *
gcm_profile_generate_curve (GcmProfile *profile, guint size)
{
GcmClut *clut = NULL;
- GcmProfileClass *klass = GCM_PROFILE_GET_CLASS (profile);
+ gdouble *values_in = NULL;
+ gdouble *values_out = NULL;
+ guint i;
+ GcmClutData *data;
+ GPtrArray *array = NULL;
+ gfloat divamount;
+ gfloat divadd;
+ guint component_width;
+ cmsHPROFILE srgb_profile = NULL;
+ cmsHTRANSFORM transform = NULL;
+ guint type;
+ GcmColorspace colorspace;
+ GcmProfilePrivate *priv = profile->priv;
- /* do we have support */
- if (klass->generate_curve == NULL)
- goto out;
+ /* run through the profile */
+ colorspace = gcm_profile_get_colorspace (profile);
+ if (colorspace == GCM_COLORSPACE_RGB) {
+
+ /* RGB */
+ component_width = 3;
+ type = TYPE_RGB_DBL;
+
+ /* create input array */
+ values_in = g_new0 (gdouble, size * 3 * component_width);
+ divamount = 1.0f / (gfloat) (size - 1);
+ for (i=0; i<size; i++) {
+ divadd = divamount * (gfloat) i;
+
+ /* red component */
+ values_in[(i * 3 * component_width)+0] = divadd;
+ values_in[(i * 3 * component_width)+1] = 0.0f;
+ values_in[(i * 3 * component_width)+2] = 0.0f;
+
+ /* green component */
+ values_in[(i * 3 * component_width)+3] = 0.0f;
+ values_in[(i * 3 * component_width)+4] = divadd;
+ values_in[(i * 3 * component_width)+5] = 0.0f;
+
+ /* blue component */
+ values_in[(i * 3 * component_width)+6] = 0.0f;
+ values_in[(i * 3 * component_width)+7] = 0.0f;
+ values_in[(i * 3 * component_width)+8] = divadd;
+ }
+ }
+
+ /* do each transform */
+ if (values_in != NULL) {
+ /* create output array */
+ values_out = g_new0 (gdouble, size * 3 * component_width);
+
+ /* create a transform from profile to sRGB */
+ srgb_profile = cmsCreate_sRGBProfile ();
+ transform = cmsCreateTransform (priv->lcms_profile, type, srgb_profile, TYPE_RGB_DBL, INTENT_PERCEPTUAL, 0);
+ if (transform == NULL)
+ goto out;
+
+ /* do transform */
+ cmsDoTransform (transform, values_in, values_out, size * 3);
+
+ /* create output array */
+ array = g_ptr_array_new_with_free_func (g_free);
+
+ for (i=0; i<size; i++) {
+ data = g_new0 (GcmClutData, 1);
+
+ data->red = values_out[(i * 3 * component_width)+0] * (gfloat) 0xffff;
+ data->green = values_out[(i * 3 * component_width)+4] * (gfloat) 0xffff;
+ data->blue = values_out[(i * 3 * component_width)+8] * (gfloat) 0xffff;
+ g_ptr_array_add (array, data);
+ }
+ clut = gcm_clut_new ();
+ gcm_clut_set_source_array (clut, array);
+ }
- /* proxy */
- clut = klass->generate_curve (profile, size);
out:
+ g_free (values_in);
+ g_free (values_out);
+ if (array != NULL)
+ g_ptr_array_unref (array);
+ if (transform != NULL)
+ cmsDeleteTransform (transform);
+ if (srgb_profile != NULL)
+ cmsCloseProfile (srgb_profile);
return clut;
}
@@ -592,6 +1372,17 @@ out:
return;
}
+
+/**
+ * gcm_profile_lcms_error_cb:
+ **/
+static int
+gcm_profile_lcms_error_cb (int ErrorCode, const char *ErrorText)
+{
+ egg_warning ("LCMS error %i: %s", ErrorCode, ErrorText);
+ return LCMS_ERRC_WARNING;
+}
+
/**
* gcm_profile_get_property:
**/
@@ -878,6 +1669,9 @@ static void
gcm_profile_init (GcmProfile *profile)
{
profile->priv = GCM_PROFILE_GET_PRIVATE (profile);
+ profile->priv->vcgt_data = NULL;
+ profile->priv->mlut_data = NULL;
+ profile->priv->adobe_gamma_workaround = FALSE;
profile->priv->can_delete = FALSE;
profile->priv->monitor = NULL;
profile->priv->kind = GCM_PROFILE_KIND_UNKNOWN;
@@ -887,6 +1681,11 @@ gcm_profile_init (GcmProfile *profile)
profile->priv->red = gcm_xyz_new ();
profile->priv->green = gcm_xyz_new ();
profile->priv->blue = gcm_xyz_new ();
+
+ /* setup LCMS */
+ cmsSetErrorHandler (gcm_profile_lcms_error_cb);
+ cmsErrorAction (LCMS_ERROR_SHOW);
+ cmsSetLanguage ("en", "US");
}
/**
@@ -905,6 +1704,8 @@ gcm_profile_finalize (GObject *object)
g_free (priv->model);
g_free (priv->datetime);
g_free (priv->checksum);
+ g_free (priv->vcgt_data);
+ g_free (priv->mlut_data);
g_object_unref (priv->white);
g_object_unref (priv->black);
g_object_unref (priv->red);
@@ -913,6 +1714,9 @@ gcm_profile_finalize (GObject *object)
if (priv->monitor != NULL)
g_object_unref (priv->monitor);
+ if (priv->lcms_profile != NULL)
+ cmsCloseProfile (priv->lcms_profile);
+
G_OBJECT_CLASS (gcm_profile_parent_class)->finalize (object);
}
@@ -928,17 +1732,3 @@ gcm_profile_new (void)
profile = g_object_new (GCM_TYPE_PROFILE, NULL);
return GCM_PROFILE (profile);
}
-
-/**
- * gcm_profile_default_new:
- *
- * Return value: a new GcmProfile object.
- **/
-GcmProfile *
-gcm_profile_default_new (void)
-{
- GcmProfile *profile = NULL;
- profile = GCM_PROFILE (gcm_profile_lcms1_new ());
- return profile;
-}
-
diff --git a/src/gcm-profile.h b/src/gcm-profile.h
index c42299b..dc20acd 100644
--- a/src/gcm-profile.h
+++ b/src/gcm-profile.h
@@ -50,17 +50,6 @@ struct _GcmProfile
struct _GcmProfileClass
{
GObjectClass parent_class;
- gboolean (*parse_data) (GcmProfile *profile,
- const guint8 *data,
- gsize length,
- GError **error);
- gboolean (*save) (GcmProfile *profile,
- const gchar *filename,
- GError **error);
- GcmClut *(*generate_vcgt) (GcmProfile *profile,
- guint size);
- GcmClut *(*generate_curve) (GcmProfile *profile,
- guint size);
/* padding for future expansion */
void (*_gcm_reserved1) (void);
@@ -72,7 +61,7 @@ struct _GcmProfileClass
GType gcm_profile_get_type (void);
GcmProfile *gcm_profile_new (void);
-GcmProfile *gcm_profile_default_new (void);
+GcmProfile *gcm_profile_new (void);
gboolean gcm_profile_parse (GcmProfile *profile,
GFile *file,
GError **error);
diff --git a/src/gcm-self-test.c b/src/gcm-self-test.c
index 24f1ae1..0549ef4 100644
--- a/src/gcm-self-test.c
+++ b/src/gcm-self-test.c
@@ -41,7 +41,6 @@
#include "gcm-print.h"
#include "gcm-profile.h"
#include "gcm-profile-store.h"
-#include "gcm-profile-lcms1.h"
#include "gcm-tables.h"
#include "gcm-trc-widget.h"
#include "gcm-utils.h"
@@ -200,7 +199,7 @@ gcm_test_cie_widget_func (void)
filename_profile = gcm_test_get_data_file ("bluish.icc");
g_assert ((filename_profile != NULL));
- profile = gcm_profile_default_new ();
+ profile = gcm_profile_new ();
file = g_file_new_for_path (filename_profile);
gcm_profile_parse (profile, file, NULL);
g_object_get (profile,
@@ -831,41 +830,41 @@ gcm_test_profile_test_parse_file (const gchar *datafile, GcmProfileTestData *tes
gchar *filename = NULL;
gboolean ret;
GError *error = NULL;
- GcmProfile *profile_lcms1;
+ GcmProfile *profile;
GcmXyz *xyz;
gfloat luminance;
GFile *file;
- profile_lcms1 = GCM_PROFILE(gcm_profile_lcms1_new ());
- g_assert (profile_lcms1 != NULL);
+ profile = GCM_PROFILE(gcm_profile_new ());
+ g_assert (profile != NULL);
filename = gcm_test_get_data_file (datafile);
g_assert ((filename != NULL));
file = g_file_new_for_path (filename);
- ret = gcm_profile_parse (profile_lcms1, file, &error);
+ ret = gcm_profile_parse (profile, file, &error);
g_assert_no_error (error);
g_assert (ret);
g_object_unref (file);
- g_assert_cmpstr (gcm_profile_get_copyright (profile_lcms1), ==, test_data->copyright);
- g_assert_cmpstr (gcm_profile_get_manufacturer (profile_lcms1), ==, test_data->manufacturer);
- g_assert_cmpstr (gcm_profile_get_model (profile_lcms1), ==, test_data->model);
- g_assert_cmpstr (gcm_profile_get_datetime (profile_lcms1), ==, test_data->datetime);
- g_assert_cmpstr (gcm_profile_get_description (profile_lcms1), ==, test_data->description);
- g_assert_cmpstr (gcm_profile_get_checksum (profile_lcms1), ==, test_data->checksum);
- g_assert_cmpint (gcm_profile_get_kind (profile_lcms1), ==, test_data->kind);
- g_assert_cmpint (gcm_profile_get_colorspace (profile_lcms1), ==, test_data->colorspace);
- g_assert_cmpint (gcm_profile_get_has_vcgt (profile_lcms1), ==, test_data->has_vcgt);
-
- g_object_get (profile_lcms1,
+ g_assert_cmpstr (gcm_profile_get_copyright (profile), ==, test_data->copyright);
+ g_assert_cmpstr (gcm_profile_get_manufacturer (profile), ==, test_data->manufacturer);
+ g_assert_cmpstr (gcm_profile_get_model (profile), ==, test_data->model);
+ g_assert_cmpstr (gcm_profile_get_datetime (profile), ==, test_data->datetime);
+ g_assert_cmpstr (gcm_profile_get_description (profile), ==, test_data->description);
+ g_assert_cmpstr (gcm_profile_get_checksum (profile), ==, test_data->checksum);
+ g_assert_cmpint (gcm_profile_get_kind (profile), ==, test_data->kind);
+ g_assert_cmpint (gcm_profile_get_colorspace (profile), ==, test_data->colorspace);
+ g_assert_cmpint (gcm_profile_get_has_vcgt (profile), ==, test_data->has_vcgt);
+
+ g_object_get (profile,
"red", &xyz,
NULL);
luminance = gcm_xyz_get_x (xyz);
g_assert_cmpfloat (fabs (luminance - test_data->luminance), <, 0.001);
g_object_unref (xyz);
- g_object_unref (profile_lcms1);
+ g_object_unref (profile);
g_free (filename);
}
@@ -991,7 +990,7 @@ gcm_test_trc_widget_func (void)
filename_profile = gcm_test_get_data_file ("AdobeGammaTest.icm");
g_assert ((filename_profile != NULL));
- profile = gcm_profile_default_new ();
+ profile = gcm_profile_new ();
file = g_file_new_for_path (filename_profile);
gcm_profile_parse (profile, file, NULL);
clut = gcm_profile_generate_vcgt (profile, 256);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]