[gnome-color-manager] Add gcm_profile_guess_and_add_vcgt() to emulate a VCGT from an ICC profile



commit 05f4c8a0b98411cf4cc30977c81f454de7b9d75e
Author: Richard Hughes <richard hughsie com>
Date:   Wed Oct 13 16:26:00 2010 +0100

    Add gcm_profile_guess_and_add_vcgt() to emulate a VCGT from an ICC profile

 libcolor-glib/gcm-profile.c   |   85 +++++++++++++++++++++++++++++++++++++++++
 libcolor-glib/gcm-profile.h   |    2 +
 libcolor-glib/gcm-self-test.c |   53 +++++++++++++++++++++++++
 3 files changed, 140 insertions(+), 0 deletions(-)
---
diff --git a/libcolor-glib/gcm-profile.c b/libcolor-glib/gcm-profile.c
index e6f6e66..69894e7 100644
--- a/libcolor-glib/gcm-profile.c
+++ b/libcolor-glib/gcm-profile.c
@@ -1062,6 +1062,91 @@ out:
 }
 
 /**
+ * gcm_profile_guess_and_add_vcgt:
+ * @profile: A valid #GcmProfile
+ * @error: A #GError, or %NULL
+ *
+ * Runs a grey image through the profile, to guess semi-correct VCGT curves
+ *
+ * Return value: %TRUE for success
+ *
+ * Since: 0.0.1
+ **/
+gboolean
+gcm_profile_guess_and_add_vcgt (GcmProfile *profile, GError **error)
+{
+	cmsHPROFILE srgb_profile = NULL;
+	cmsHTRANSFORM transform = NULL;
+	cmsToneCurve *transfer_curve[3];
+	cmsUInt16Number rawdata[3][256];
+	const guint size = 256;
+	gboolean ret = FALSE;
+	gdouble *values_in = NULL;
+	gdouble *values_out = NULL;
+	gfloat divadd;
+	gfloat divamount;
+	guint i;
+	GcmProfilePrivate *priv = profile->priv;
+
+	/* not loaded */
+	if (priv->lcms_profile == NULL) {
+		g_set_error_literal (error, 1, 0, "not already loaded or generated");
+		goto out;
+	}
+
+	/* create arrays */
+	values_in = g_new0 (gdouble, size * 3);
+	values_out = g_new0 (gdouble, size * 3);
+
+	/* populate with data */
+	divamount = 1.0f / (gfloat) (size - 1);
+	for (i=0; i<size; i++) {
+		divadd = divamount * (gfloat) i;
+
+		/* grey component */
+		values_in[(i * 3)+0] = divadd;
+		values_in[(i * 3)+1] = divadd;
+		values_in[(i * 3)+2] = divadd;
+	}
+
+	/* create a transform from sRGB to profile */
+	srgb_profile = cmsCreate_sRGBProfile ();
+	transform = cmsCreateTransform (priv->lcms_profile, TYPE_RGB_DBL,
+					srgb_profile, TYPE_RGB_DBL,
+					INTENT_ABSOLUTE_COLORIMETRIC, 0);
+	if (transform == NULL) {
+		g_set_error_literal (error, 1, 0, "failed to generate transform");
+		goto out;
+	}
+
+	/* do transform */
+	cmsDoTransform (transform, values_in, values_out, size);
+
+	/* unroll the data */
+	for (i=0; i<size; i++) {
+		rawdata[0][i] = values_out[(i * 3)+0] * 0xffff;
+		rawdata[1][i] = values_out[(i * 3)+1] * 0xffff;
+		rawdata[2][i] = values_out[(i * 3)+2] * 0xffff;
+	}
+
+	/* build tone curves */
+	for (i=0; i<3; i++)
+		transfer_curve[i] = cmsBuildTabulatedToneCurve16 (NULL, 256, rawdata[i]);
+
+	/* write to VCGT */
+	ret = cmsWriteTag (priv->lcms_profile, cmsSigVcgtType, transfer_curve);
+	cmsFreeToneCurveTriple (transfer_curve);
+out:
+	g_free (values_in);
+	g_free (values_out);
+	if (transform != NULL)
+		cmsDeleteTransform (transform);
+	if (srgb_profile != NULL)
+		cmsCloseProfile (srgb_profile);
+	return ret;
+}
+
+/**
  * gcm_profile_generate_vcgt:
  * @profile: A valid #GcmProfile
  * @size: the size of the table to generate
diff --git a/libcolor-glib/gcm-profile.h b/libcolor-glib/gcm-profile.h
index 7812db2..c6cc720 100644
--- a/libcolor-glib/gcm-profile.h
+++ b/libcolor-glib/gcm-profile.h
@@ -90,6 +90,8 @@ gboolean	 gcm_profile_create_from_chroma		(GcmProfile	*profile,
 							 const GcmColorYxy *blue,
 							 const GcmColorYxy *white,
 							 GError		**error);
+gboolean	 gcm_profile_guess_and_add_vcgt		(GcmProfile	*profile,
+							 GError		**error);
 const gchar	*gcm_profile_get_description		(GcmProfile	*profile);
 void		 gcm_profile_set_description		(GcmProfile	*profile,
 							 const gchar 	*description);
diff --git a/libcolor-glib/gcm-self-test.c b/libcolor-glib/gcm-self-test.c
index ff3e8a9..d84c7d2 100644
--- a/libcolor-glib/gcm-self-test.c
+++ b/libcolor-glib/gcm-self-test.c
@@ -341,6 +341,10 @@ gcm_test_profile_func (void)
 	GError *error = NULL;
 	GcmColorXYZ *xyz;
 	GcmColorYxy yxy;
+	GcmColorYxy red;
+	GcmColorYxy green;
+	GcmColorYxy blue;
+	GcmColorYxy white;
 
 	/* bluish test */
 	profile = gcm_profile_new ();
@@ -398,6 +402,55 @@ gcm_test_profile_func (void)
 	g_assert (gcm_profile_get_has_vcgt (profile));
 
 	g_object_unref (profile);
+
+	/* create test */
+	profile = gcm_profile_new ();
+
+	/* from my T61 */
+	gcm_color_set_Yxy (&red, 1.0f, 0.569336f, 0.332031f);
+	gcm_color_set_Yxy (&green, 1.0f, 0.311523f, 0.543945f);
+	gcm_color_set_Yxy (&blue, 1.0f, 0.149414f, 0.131836f);
+	gcm_color_set_Yxy (&white, 1.0f, 0.313477f, 0.329102f);
+
+	/* create from chroma */
+	ret = gcm_profile_create_from_chroma (profile, 2.2f, &red, &green, &blue, &white, &error);
+	g_assert_no_error (error);
+	g_assert (ret);
+
+	/* add vcgt */
+	ret = gcm_profile_guess_and_add_vcgt (profile, &error);
+	g_assert_no_error (error);
+	g_assert (ret);
+
+	/* save */
+	gcm_profile_save (profile, "dave.icc", &error);
+	g_assert_no_error (error);
+	g_assert (ret);
+	g_object_unref (profile);
+
+	/* verify values */
+	profile = gcm_profile_new ();
+	file = g_file_new_for_path ("dave.icc");
+	ret = gcm_profile_parse (profile, file, &error);
+	g_assert_no_error (error);
+	g_assert (ret);
+
+	g_assert_cmpstr (gcm_profile_get_copyright (profile), ==, "No copyright, use freely");
+	g_assert_cmpstr (gcm_profile_get_manufacturer (profile), ==, NULL);
+	g_assert_cmpstr (gcm_profile_get_model (profile), ==, NULL);
+	g_assert_cmpstr (gcm_profile_get_description (profile), ==, "RGB built-in");
+	g_assert_cmpint (gcm_profile_get_kind (profile), ==, GCM_PROFILE_KIND_DISPLAY_DEVICE);
+	g_assert_cmpint (gcm_profile_get_colorspace (profile), ==, GCM_COLORSPACE_RGB);
+	g_assert_cmpint (gcm_profile_get_temperature (profile), ==, 5000);
+	g_assert (gcm_profile_get_has_vcgt (profile));
+
+	/* delete temp file */
+	ret = g_file_delete (file, NULL, &error);
+	g_assert_no_error (error);
+	g_assert (ret);
+
+	g_object_unref (file);
+	g_object_unref (profile);
 }
 
 



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