[gnome-color-manager] Make gcm-picker actually read a spot color from a device



commit b7856065bc677bb679c1f4b5e950525560eca776
Author: Richard Hughes <richard hughsie com>
Date:   Tue Apr 27 13:55:20 2010 +0100

    Make gcm-picker actually read a spot color from a device

 src/gcm-calibrate-argyll.c |   86 ++++++++++++++++++++++------
 src/gcm-picker.c           |  133 +++++++++++++++++++++++++++++++++++++++-----
 2 files changed, 185 insertions(+), 34 deletions(-)
---
diff --git a/src/gcm-calibrate-argyll.c b/src/gcm-calibrate-argyll.c
index 8163e19..6fe0149 100644
--- a/src/gcm-calibrate-argyll.c
+++ b/src/gcm-calibrate-argyll.c
@@ -43,6 +43,7 @@
 #include "gcm-utils.h"
 #include "gcm-screen.h"
 #include "gcm-print.h"
+#include "gcm-xyz.h"
 #include "gcm-calibrate-dialog.h"
 
 #include "egg-debug.h"
@@ -80,6 +81,7 @@ struct _GcmCalibrateArgyllPrivate
 	GcmCalibrateArgyllState		 state;
 	GcmPrint			*print;
 	const gchar			*argyllcms_ok;
+	gboolean			 done_spot_read;
 };
 
 enum {
@@ -1407,16 +1409,19 @@ gcm_calibrate_argyll_spotread_read_chart (GcmCalibrateArgyll *calibrate_argyll,
 		goto out;
 	}
 
-	/* TRANSLATORS: title, patches are specific colours used in calibration */
-	title = _("Reading the patches");
+	/* TRANSLATORS: title, setting up the photospectromiter */
+	title = _("Setting up device");
 	/* TRANSLATORS: dialog message */
-	message = _("Reading the patches using the color measuring instrument.");
+	message = _("Setting up the device to read a spot colorâ?¦");
 
 	/* push new messages into the UI */
 	gcm_calibrate_dialog_show (priv->calibrate_dialog, GCM_CALIBRATE_DIALOG_TAB_GENERIC, title, message);
 	gcm_calibrate_dialog_set_show_button_ok (priv->calibrate_dialog, FALSE);
 	gcm_calibrate_dialog_set_show_expander (priv->calibrate_dialog, TRUE);
 
+	/* reset flag so we exit after the single spotread */
+	priv->done_spot_read = FALSE;
+
 	/* argument array */
 	array = g_ptr_array_new_with_free_func (g_free);
 
@@ -1475,24 +1480,11 @@ gcm_calibrate_argyll_spotread (GcmCalibrate *calibrate, GtkWindow *window, GErro
 	GcmCalibrateArgyll *calibrate_argyll = GCM_CALIBRATE_ARGYLL(calibrate);
 	GcmCalibrateArgyllPrivate *priv = calibrate_argyll->priv;
 	gboolean ret;
-	const gchar *title;
-	const gchar *message;
 
 	/* set modal windows up correctly */
-	gcm_calibrate_dialog_set_move_window (priv->calibrate_dialog, TRUE);
+	gcm_calibrate_dialog_set_move_window (priv->calibrate_dialog, FALSE);
 	gcm_calibrate_dialog_set_window (priv->calibrate_dialog, window);
 
-	/* TRANSLATORS: title, color spot is the color we are trying to measure */
-	title = _("Sampling the color spot");
-
-	/* TRANSLATORS: dialog message */
-	message = _("Setting up display device for useâ?¦");
-
-	/* push new messages into the UI */
-	gcm_calibrate_dialog_show (priv->calibrate_dialog, GCM_CALIBRATE_DIALOG_TAB_GENERIC, title, message);
-	gcm_calibrate_dialog_set_show_button_ok (priv->calibrate_dialog, FALSE);
-	gcm_calibrate_dialog_set_show_expander (priv->calibrate_dialog, FALSE);
-
 	/* step 3 */
 	ret = gcm_calibrate_argyll_spotread_read_chart (calibrate_argyll, error);
 	if (!ret)
@@ -2346,10 +2338,10 @@ gcm_calibrate_argyll_interaction_surface (GcmCalibrateArgyll *calibrate_argyll)
 
 	if (filename != NULL) {
 		/* TRANSLATORS: this is when the user has to change a setting on the sensor, and we're showing a picture */
-		message = _("Please set the measuring instrument to screen mode like the image below, and ensure it is attached to the screen.");
+		message = _("Please set the measuring instrument to screen mode like the image below.");
 	} else {
 		/* TRANSLATORS: this is when the user has to change a setting on the sensor */
-		message = _("Please set the measuring instrument to screen mode, and ensure it is attached to the screen.");
+		message = _("Please set the measuring instrument to screen mode.");
 	}
 
 	/* push new messages into the UI */
@@ -2463,6 +2455,27 @@ gcm_calibrate_argyll_process_output_cmd (GcmCalibrateArgyll *calibrate_argyll, c
 		goto out;
 	}
 
+	/* spot read result */
+	found = g_strstr_len (line, -1, "Result is XYZ");
+	if (found != NULL) {
+		GcmXyz *xyz;
+		egg_warning ("line=%s", line);
+		split = g_strsplit (line, " ", -1);
+		xyz = gcm_xyz_new ();
+		g_object_set (xyz,
+			      "cie-x", g_ascii_strtod (split[4], NULL),
+			      "cie-y", g_ascii_strtod (split[5], NULL),
+			      "cie-z", g_ascii_strtod (split[6], NULL),
+			      NULL);
+		g_object_set (calibrate_argyll,
+			      "xyz", xyz,
+			      NULL);
+		priv->done_spot_read = TRUE;
+		gcm_calibrate_dialog_response (priv->calibrate_dialog, GTK_RESPONSE_CANCEL);
+		g_object_unref (xyz);
+		goto out;
+	}
+
 	/* error */
 	found = g_strstr_len (line, -1, "Error - ");
 	if (found != NULL) {
@@ -2582,6 +2595,38 @@ gcm_calibrate_argyll_process_output_cmd (GcmCalibrateArgyll *calibrate_argyll, c
 		goto out;
 	}
 
+	/* reading spot */
+	if (g_str_has_prefix (line, "Place instrument on spot to be measured")) {
+		if (!priv->done_spot_read)
+			vte_terminal_feed_child (VTE_TERMINAL(priv->terminal), " ", 1);
+		gcm_calibrate_dialog_hide (priv->calibrate_dialog);
+		goto out;
+	}
+
+
+	/* reading strip */
+	if (g_str_has_prefix (line, "Spot read failed due to misread")) {
+
+		/* TRANSLATORS: title, the calibration failed */
+		title = _("Device Error");
+
+		/* TRANSLATORS: message, the sample was not read correctly */
+		message = _("The device could not measure the color spot correctly.");
+
+		/* push new messages into the UI */
+		gcm_calibrate_dialog_show (priv->calibrate_dialog, GCM_CALIBRATE_DIALOG_TAB_GENERIC, title, message);
+		gcm_calibrate_dialog_set_show_button_ok (priv->calibrate_dialog, TRUE);
+		gcm_calibrate_dialog_set_show_expander (priv->calibrate_dialog, TRUE);
+
+		/* TRANSLATORS: button */
+		gcm_calibrate_dialog_set_button_ok_id (priv->calibrate_dialog, _("Retry"));
+
+		/* set state */
+		priv->argyllcms_ok = " ";
+		priv->state = GCM_CALIBRATE_ARGYLL_STATE_WAITING_FOR_STDIN;
+		goto out;
+	}
+
 	/* reading strip */
 	if (g_str_has_prefix (line, "Ready to read strip pass ")) {
 
@@ -2721,6 +2766,9 @@ gcm_calibrate_argyll_response_cb (GtkWidget *widget, GtkResponseType response, G
 			priv->state = GCM_CALIBRATE_ARGYLL_STATE_RUNNING;
 		}
 
+		/* hide the window */
+		gcm_calibrate_dialog_hide (priv->calibrate_dialog);
+
 		/* stop loop */
 		if (g_main_loop_is_running (priv->loop))
 			g_main_loop_quit (priv->loop);
diff --git a/src/gcm-picker.c b/src/gcm-picker.c
index 4d5771f..4c056f8 100644
--- a/src/gcm-picker.c
+++ b/src/gcm-picker.c
@@ -29,15 +29,19 @@
 #include <locale.h>
 #include <gtk/gtk.h>
 #include <unique/unique.h>
+#include <lcms.h>
 
 #include "egg-debug.h"
 
 #include "gcm-colorimeter.h"
+#include "gcm-calibrate-argyll.h"
 #include "gcm-utils.h"
+#include "gcm-xyz.h"
 
 static GtkBuilder *builder = NULL;
 static GtkWidget *info_bar_hardware = NULL;
 static GtkWidget *info_bar_hardware_label = NULL;
+static GcmCalibrate *calibrate = NULL;
 
 /**
  * gcm_picker_set_pixbuf_color:
@@ -62,7 +66,6 @@ gcm_picker_set_pixbuf_color (GdkPixbuf *pixbuf, gchar red, gchar green, gchar bl
 			p[0] = red;
 			p[1] = green;
 			p[2] = blue;
-//			p[3] = alpha;
 		}
 	}
 }
@@ -73,34 +76,113 @@ gcm_picker_set_pixbuf_color (GdkPixbuf *pixbuf, gchar red, gchar green, gchar bl
 static void
 gcm_picker_measure_cb (GtkWidget *widget, gpointer data)
 {
+	GtkWindow *window;
+	gboolean ret;
+	GError *error = NULL;
+
+	/* get value */
+	window = GTK_WINDOW (gtk_builder_get_object (builder, "dialog_picker"));
+	ret = gcm_calibrate_spotread (calibrate, window, &error);
+	if (!ret) {
+		egg_warning ("failed to get spot color: %s", error->message);
+		g_error_free (error);
+	}
+}
+
+#define TYPE_XYZ_DBL2        (COLORSPACE_SH(PT_XYZ)|CHANNELS_SH(3)|BYTES_SH(sizeof(gdouble)))
+
+/**
+ * gpk_update_viewer_notify_network_state_cb:
+ **/
+static void
+gcm_picker_xyz_notify_cb (GcmCalibrate *calibrate_, GParamSpec *pspec, gpointer user_data)
+{
+	GcmXyz *xyz = NULL;
 	GtkImage *image;
 	GtkLabel *label;
-	GdkPixbuf *pixbuf;
+	GdkPixbuf *pixbuf = NULL;
+	GtkWidget *widget;
+	gdouble color_xyz[3];
+	guint8 color_rgb[3];
+	gdouble color_lab[3];
+	gchar *text_xyz = NULL;
+	gchar *text_lab = NULL;
+	gchar *text_rgb = NULL;
+	cmsHPROFILE profile_xyz;
+	cmsHPROFILE profile_rgb;
+	cmsHPROFILE profile_lab;
+	cmsHTRANSFORM transform_rgb;
+	cmsHTRANSFORM transform_lab;
+
+	/* get new value */
+	g_object_get (calibrate, "xyz", &xyz, NULL);
+
+	/* create new pixbuf of the right size */
 	image = GTK_IMAGE (gtk_builder_get_object (builder, "image_preview"));
-	pixbuf = gtk_image_get_pixbuf (image);
-	if (pixbuf == NULL) {
-		pixbuf = gdk_pixbuf_new (GDK_COLORSPACE_RGB, FALSE, 8, 200, 200);
-		gtk_image_set_from_pixbuf (image, pixbuf);
-	}
+	pixbuf = gdk_pixbuf_new (GDK_COLORSPACE_RGB, FALSE, 8, 200, 200);
+
+	/* get values */
+	g_object_get (xyz,
+		      "cie-x", &color_xyz[0],
+		      "cie-y", &color_xyz[1],
+		      "cie-z", &color_xyz[2],
+		      NULL);
+
+	/* lcms scales these for some reason */
+	color_xyz[0] /= 100.0f;
+	color_xyz[1] /= 100.0f;
+	color_xyz[2] /= 100.0f;
+
+	/* get profiles */
+	profile_xyz = cmsCreateXYZProfile ();
+	profile_rgb = cmsCreate_sRGBProfile ();
+	profile_lab = cmsCreateLabProfile (cmsD50_xyY ());
+
+	/* create transform_rgb */
+	transform_rgb = cmsCreateTransform (profile_xyz, TYPE_XYZ_DBL2, profile_rgb, TYPE_RGB_8, INTENT_PERCEPTUAL, 0);
+	transform_lab = cmsCreateTransform (profile_xyz, TYPE_XYZ_DBL2, profile_lab, TYPE_Lab_DBL, INTENT_PERCEPTUAL, 0);
+
+	cmsDoTransform (transform_rgb, color_xyz, color_rgb, 1);
+	cmsDoTransform (transform_lab, color_xyz, color_lab, 1);
+
+	/* destroy lcms state */
+	cmsDeleteTransform (transform_rgb);
+	cmsDeleteTransform (transform_lab);
+	cmsCloseProfile (profile_xyz);
+	cmsCloseProfile (profile_rgb);
+	cmsCloseProfile (profile_lab);
 
-	gcm_picker_set_pixbuf_color (pixbuf, 254, 128, 0);
+	/* set XYZ */
+	label = GTK_LABEL (gtk_builder_get_object (builder, "label_xyz"));
+	text_xyz = g_strdup_printf ("%.3f, %.3f, %.3f", color_xyz[0], color_xyz[1], color_xyz[2]);
+	gtk_label_set_label (label, text_xyz);
 
 	/* set LAB */
 	label = GTK_LABEL (gtk_builder_get_object (builder, "label_lab"));
-	gtk_label_set_label (label, "1, 2, 3");
-
-	/* set XYZ */
-	label = GTK_LABEL (gtk_builder_get_object (builder, "label_xyz"));
-	gtk_label_set_label (label, "1, 2, 3");
+	text_lab = g_strdup_printf ("%.3f, %.3f, %.3f", color_lab[0], color_lab[1], color_lab[2]);
+	gtk_label_set_label (label, text_lab);
 
 	/* set RGB */
 	label = GTK_LABEL (gtk_builder_get_object (builder, "label_rgb"));
-	gtk_label_set_label (label, "1, 2, 3");
+	text_rgb = g_strdup_printf ("%i, %i, %i", color_rgb[0], color_rgb[1], color_rgb[2]);
+	gtk_label_set_label (label, text_rgb);
+	gcm_picker_set_pixbuf_color (pixbuf, color_rgb[0], color_rgb[1], color_rgb[2]);
 
 	/* set XYZ */
 	widget = GTK_WIDGET (gtk_builder_get_object (builder, "expander_results"));
 	gtk_expander_set_expanded (GTK_EXPANDER (widget), TRUE);
 
+	/* set image */
+	image = GTK_IMAGE (gtk_builder_get_object (builder, "image_preview"));
+	gtk_image_set_from_pixbuf (image, pixbuf);
+
+	g_free (text_xyz);
+	g_free (text_lab);
+	g_free (text_rgb);
+	if (xyz != NULL)
+		g_object_unref (xyz);
+	if (pixbuf != NULL)
+		g_object_unref (pixbuf);
 }
 
 /**
@@ -206,6 +288,16 @@ gcm_window_set_parent_xid (GtkWindow *window, guint32 xid)
 	gdk_window_set_transient_for (our_window, parent_window);
 }
 
+/*
+ * gcm_picker_lcms_error_cb:
+ */
+static gint
+gcm_picker_lcms_error_cb (gint error_code, const gchar *error_text)
+{
+	egg_warning ("LCMS error %i: %s", error_code, error_text);
+	return LCMS_ERRC_WARNING;
+}
+
 /**
  * main:
  **/
@@ -215,7 +307,6 @@ main (int argc, char *argv[])
 	GOptionContext *context;
 	guint retval = 0;
 	GError *error = NULL;
-//	gboolean ret = FALSE;
 	GMainLoop *loop;
 	GtkWidget *main_window;
 	GtkWidget *widget;
@@ -239,6 +330,11 @@ main (int argc, char *argv[])
 	/* setup type system */
 	g_type_init ();
 
+	/* setup LCMS */
+	cmsSetErrorHandler (gcm_picker_lcms_error_cb);
+	cmsErrorAction (LCMS_ERROR_SHOW);
+	cmsSetLanguage ("en", "US");
+
 	context = g_option_context_new (NULL);
 	/* TRANSLATORS: tool that is used to pick colors */
 	g_option_context_set_summary (context, _("GNOME Color Manager Color Picker"));
@@ -305,6 +401,11 @@ main (int argc, char *argv[])
 		gcm_window_set_parent_xid (GTK_WINDOW (main_window), xid);
 	}
 
+	/* use argyll */
+	calibrate = GCM_CALIBRATE (gcm_calibrate_argyll_new ());
+	g_signal_connect (calibrate, "notify::xyz",
+			  G_CALLBACK (gcm_picker_xyz_notify_cb), NULL);
+
 	/* use an info bar if there is no device, or the wrong device */
 	info_bar_hardware = gtk_info_bar_new ();
 	info_bar_hardware_label = gtk_label_new (NULL);
@@ -328,6 +429,8 @@ out:
 	g_object_unref (unique_app);
 	if (colorimeter != NULL)
 		g_object_unref (colorimeter);
+	if (calibrate != NULL)
+		g_object_unref (calibrate);
 	if (builder != NULL)
 		g_object_unref (builder);
 	g_main_loop_unref (loop);



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]