[gnome-color-manager] Add gcm_profile_guess_and_add_vcgt() to emulate a VCGT from an ICC profile
- From: Richard Hughes <rhughes src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-color-manager] Add gcm_profile_guess_and_add_vcgt() to emulate a VCGT from an ICC profile
- Date: Wed, 13 Oct 2010 14:30:43 +0000 (UTC)
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]