[gnome-color-manager] Add whitepoint, rXYZ, and VCGT functionality to GcmCalibrateNative
- From: Richard Hughes <rhughes src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-color-manager] Add whitepoint, rXYZ, and VCGT functionality to GcmCalibrateNative
- Date: Thu, 14 Oct 2010 11:16:37 +0000 (UTC)
commit be2207a739ab4eaef2aa071a52a0e54f267af666
Author: Richard Hughes <richard hughsie com>
Date: Thu Oct 14 13:13:49 2010 +0100
Add whitepoint, rXYZ, and VCGT functionality to GcmCalibrateNative
src/gcm-calibrate-native.c | 482 ++++++++++++++++++++++++++++++++++++++------
src/gcm-self-test.c | 61 ++++++-
2 files changed, 485 insertions(+), 58 deletions(-)
---
diff --git a/src/gcm-calibrate-native.c b/src/gcm-calibrate-native.c
index 62e66eb..6fa9e8c 100644
--- a/src/gcm-calibrate-native.c
+++ b/src/gcm-calibrate-native.c
@@ -32,6 +32,7 @@
#include <gio/gio.h>
#include <gtk/gtk.h>
#include <lcms2.h>
+#include <math.h>
#include "gcm-calibrate-native.h"
#include "gcm-sensor-client.h"
@@ -160,7 +161,7 @@ gcm_calibrate_native_sample_write (GPtrArray *array, const gchar *filename)
* gcm_calibrate_native_create_it8_file:
**/
static void
-gcm_calibrate_native_create_it8_file (GcmCalibrateNative *calibrate_native, GcmSensor *sensor, guint precision)
+gcm_calibrate_native_create_it8_file (GcmCalibrateNative *calibrate_native, GcmSensor *sensor, const gchar *filename, guint steps)
{
GcmCalibrateNativePrivate *priv = calibrate_native->priv;
guint i;
@@ -172,7 +173,7 @@ gcm_calibrate_native_create_it8_file (GcmCalibrateNative *calibrate_native, GcmS
gdouble divisions;
/* step size */
- divisions = 1.0f / (gfloat) precision;
+ divisions = 1.0f / (gfloat) (steps - 1);
result.X = 0.1;
result.Y = 0.2;
@@ -187,7 +188,7 @@ gcm_calibrate_native_create_it8_file (GcmCalibrateNative *calibrate_native, GcmS
gcm_calibrate_native_sample_add (array, "CBL", &source);
/* blue ramp */
- for (i=1; i<precision; i++) {
+ for (i=0; i<steps; i++) {
patch_name = g_strdup_printf ("BR%i", i+1);
source.B = 1.0f - (divisions * i);
gcm_calibrate_native_sample_add (array, patch_name, &source);
@@ -201,7 +202,7 @@ gcm_calibrate_native_create_it8_file (GcmCalibrateNative *calibrate_native, GcmS
gcm_calibrate_native_sample_add (array, "CGR", &source);
/* green ramp */
- for (i=1; i<precision; i++) {
+ for (i=0; i<steps; i++) {
patch_name = g_strdup_printf ("GR%i", i+1);
source.G = 1.0f - (divisions * i);
gcm_calibrate_native_sample_add (array, patch_name, &source);
@@ -215,7 +216,7 @@ gcm_calibrate_native_create_it8_file (GcmCalibrateNative *calibrate_native, GcmS
gcm_calibrate_native_sample_add (array, "CRD", &source);
/* red ramp */
- for (i=1; i<precision; i++) {
+ for (i=0; i<steps; i++) {
patch_name = g_strdup_printf ("RR%i", i+1);
source.R = 1.0f - (divisions * i);
gcm_calibrate_native_sample_add (array, patch_name, &source);
@@ -229,7 +230,7 @@ gcm_calibrate_native_create_it8_file (GcmCalibrateNative *calibrate_native, GcmS
gcm_calibrate_native_sample_add (array, "DMIN", &source);
/* grey ramp */
- for (i=0; i<precision; i++) {
+ for (i=0; i<steps; i++) {
patch_name = g_strdup_printf ("GS%i", i+1);
source.R = divisions * i;
source.G = divisions * i;
@@ -259,71 +260,394 @@ gcm_calibrate_native_create_it8_file (GcmCalibrateNative *calibrate_native, GcmS
}
/* write to disk */
- gcm_calibrate_native_sample_write (array, "./dave.it8");
+ gcm_calibrate_native_sample_write (array, filename);
out:
g_ptr_array_unref (array);
}
-/*
- * _cmsWriteTagTextAscii:
- */
-static cmsBool
-_cmsWriteTagTextAscii (cmsHPROFILE lcms_profile, cmsTagSignature sig, const gchar *text)
+/**
+ * gcm_calibrate_native_get_it8_patch_rgb_xyz:
+ **/
+static void
+gcm_calibrate_native_get_it8_patch_rgb_xyz (cmsHANDLE it8_handle, const gchar *patch, GcmColorRGB *rgb, GcmColorXYZ *xyz)
{
- cmsBool ret;
- cmsMLU *mlu = cmsMLUalloc (0, 1);
- cmsMLUsetASCII (mlu, "EN", "us", text);
- ret = cmsWriteTag (lcms_profile, sig, mlu);
- cmsMLUfree (mlu);
- return ret;
+ if (rgb != NULL) {
+ rgb->R = cmsIT8GetDataDbl (it8_handle, patch, "RGB_R");
+ rgb->G = cmsIT8GetDataDbl (it8_handle, patch, "RGB_G");
+ rgb->B = cmsIT8GetDataDbl (it8_handle, patch, "RGB_B");
+ }
+ if (xyz != NULL) {
+ xyz->X = cmsIT8GetDataDbl (it8_handle, patch, "XYZ_X");
+ xyz->Y = cmsIT8GetDataDbl (it8_handle, patch, "XYZ_Y");
+ xyz->Z = cmsIT8GetDataDbl (it8_handle, patch, "XYZ_Z");
+ }
}
/**
- * gcm_calibrate_native_display:
+ * gcm_calibrate_native_get_it8_patch_xyY:
**/
-static gboolean
-gcm_calibrate_native_display (GcmCalibrate *calibrate, GtkWindow *window, GError **error)
+static void
+gcm_calibrate_native_get_it8_patch_xyY (cmsHANDLE it8_handle, const gchar *patch, cmsCIExyY *result)
{
- GcmCalibrateNative *calibrate_native = GCM_CALIBRATE_NATIVE(calibrate);
- GcmCalibrateNativePrivate *priv = calibrate_native->priv;
- gboolean ret = TRUE;
- GcmSensor *sensor;
- const gchar *title;
- const gchar *message;
- const gchar *filename;
+ GcmColorXYZ sample;
+ gcm_calibrate_native_get_it8_patch_rgb_xyz (it8_handle, patch, NULL, &sample);
+ cmsXYZ2xyY (result, (cmsCIEXYZ*) &sample);
+}
+/**
+ * gcm_calibrate_native_interpolate_array:
+ *
+ * Linearly interpolate an array of data into a differently sized array.
+ **/
+static void
+gcm_calibrate_native_interpolate_array (gdouble *data, guint data_size, gdouble *new, guint new_size)
{
-cmsHPROFILE profile;
-cmsViewingConditions PCS;
+ gdouble amount;
+ gdouble div;
+ guint i;
+ guint reg1, reg2;
+
+ /* gcm_calibrate_native_ */
+ for (i=0; i<new_size; i++) {
+ div = i * ((data_size - 1) / (gdouble) (new_size - 1));
+ reg1 = floor (div);
+ reg2 = ceil (div);
+ if (reg1 == reg2) {
+ /* no interpolation reqd */
+ new[i] = data[reg1];
+ } else {
+ amount = div - (gdouble) reg1;
+ new[i] = data[reg1] * (1.0f - amount) + data[reg2] * amount;
+ }
+ }
+}
+
+#if 0
+/**
+ * _gcm_color_normalize_XYZ:
+ *
+ * Return value: the Y value that was normalised
+ **/
+static gdouble
+_gcm_color_normalize_XYZ (GcmColorXYZ *xyz)
+{
+ gdouble Y;
+
+ g_return_val_if_fail (xyz != NULL, 0.0f);
+
+ /* return the value we used the scale */
+ Y = xyz->Y;
+
+ /* scale by luminance */
+ xyz->X /= Y;
+ xyz->Z /= Y;
+ xyz->Y = 1.0;
+ return Y;
+}
+#endif
+
+/**
+ * _gcm_color_scale_XYZ:
+ **/
+static void
+_gcm_color_scale_XYZ (GcmColorXYZ *xyz, gdouble scale)
+{
+ g_return_if_fail (xyz != NULL);
+
+ /* scale by factor */
+ xyz->X /= scale;
+ xyz->Y /= scale;
+ xyz->Z /= scale;
+}
+
+/**
+ * gcm_calibrate_native_create_profile_from_it8:
+ **/
+static gboolean
+gcm_calibrate_native_create_profile_from_it8 (GcmProfile *profile, const gchar *filename, guint vcgt_size, GError **error)
+{
+ gboolean ret = FALSE;
+ guint64 rampsize;
+ cmsHANDLE it8_handle;
+ cmsCIExyYTRIPLE primaries;
+ cmsCIExyY whitepoint;
+ GcmColorXYZ primary_red;
+ GcmColorXYZ primary_green;
+ GcmColorXYZ primary_blue;
+ guint i, j;
+ const gdouble gamma22 = 2.2f;
+ const gchar *patch_data;
+ gchar *patch_name;
+ gdouble div;
+ gdouble temperature;
+ gdouble whitepointY;
+ GcmColorXYZ patch_xyz;
+ GcmColorRGB patch_rgb;
+ GcmColorRGB actual_rgb;
+ GcmColorXYZ actual_xyz;
+ GcmColorRGB scale;
+ GcmColorRGB leakage;
+ cmsHPROFILE conversion_profile = NULL;
+ cmsHPROFILE xyz_profile = NULL;
+ cmsToneCurve *transfer_curve[3];
+ cmsHTRANSFORM conversion_transform = NULL;
+ gdouble *data_sampled[3] = { NULL, NULL, NULL};
+ gdouble *data_interpolated[3] = { NULL, NULL, NULL};
+ guint16 *data_vcgt[3] = { NULL, NULL, NULL};
+
+ /* load it8 file */
+ it8_handle = cmsIT8LoadFromFile(NULL, filename);
+ if (it8_handle == NULL)
+ goto out;
+
+ /* get the whitepoint */
+ gcm_calibrate_native_get_it8_patch_xyY (it8_handle, "DMAX", &whitepoint);
+ cmsTempFromWhitePoint (&temperature, &whitepoint);
+ egg_debug ("native whitepoint=%f,%f [scale:%f] (%fK)", whitepoint.x, whitepoint.y, whitepoint.Y, temperature);
+
+ /* we need to scale each reading by this value */
+ whitepointY = whitepoint.Y;
+// _gcm_color_normalize_XYZ (&whitepoint);
+
+ /* optionally use a D50 target */
+// cmsWhitePointFromTemp (&whitepoint, 5000);
+
+ /* normalize white point for CIECAM */
+ whitepoint.Y = 1.0f;
+
+ /* set white point */
+ cmsxyY2XYZ ((cmsCIEXYZ *) &actual_xyz, &whitepoint);
+ ret = gcm_profile_set_whitepoint (profile, &actual_xyz, error);
+ if (!ret)
+ goto out;
-/* take it8 file, and open */
-profile = cmsCreateProfilePlaceholder (NULL);
+ /* get the primaries */
+ gcm_calibrate_native_get_it8_patch_xyY (it8_handle, "CRD", &primaries.Red);
+ gcm_calibrate_native_get_it8_patch_xyY (it8_handle, "CGR", &primaries.Green);
+ gcm_calibrate_native_get_it8_patch_xyY (it8_handle, "CBL", &primaries.Blue);
+
+ egg_debug ("red=%f,%f green=%f,%f blue=%f,%f",
+ primaries.Red.x, primaries.Red.y,
+ primaries.Green.x, primaries.Green.y,
+ primaries.Blue.x, primaries.Blue.y);
+
+ /* get the primaries */
+ gcm_calibrate_native_get_it8_patch_rgb_xyz (it8_handle, "CRD", NULL, &primary_red);
+ gcm_calibrate_native_get_it8_patch_rgb_xyz (it8_handle, "CGR", NULL, &primary_green);
+ gcm_calibrate_native_get_it8_patch_rgb_xyz (it8_handle, "CBL", NULL, &primary_blue);
+
+ /* scale the values */
+ _gcm_color_scale_XYZ (&primary_red, whitepointY);
+ _gcm_color_scale_XYZ (&primary_green, whitepointY);
+ _gcm_color_scale_XYZ (&primary_blue, whitepointY);
+
+ /* set the primaries */
+ ret = gcm_profile_set_primaries (profile, &primary_red, &primary_green, &primary_blue, error);
+ if (!ret)
+ goto out;
+
+ /* create our RGB conversion transform */
+ transfer_curve[0] = transfer_curve[1] = transfer_curve[2] = cmsBuildGamma (NULL, gamma22);
+ conversion_profile = cmsCreateRGBProfile (&whitepoint, &primaries, transfer_curve);
+ xyz_profile = cmsCreateXYZProfile ();
+ conversion_transform = cmsCreateTransform (xyz_profile, TYPE_XYZ_DBL,
+ conversion_profile, TYPE_RGB_DBL,
+ INTENT_ABSOLUTE_COLORIMETRIC, 0);
+
+ /* get the size of the gray ramp */
+ for (i=0; i<1024; i++) {
+ patch_name = g_strdup_printf ("GS%i", i+1);
+ patch_data = cmsIT8GetData (it8_handle, patch_name, "RGB_R");
+ g_free (patch_name);
+ if (patch_data == NULL)
+ break;
+ }
+ rampsize = i;
+ if (rampsize == 0) {
+ g_set_error_literal (error, 1, 0, "no gray ramp found");
+ goto out;
+ }
+ egg_debug ("rampsize = %li", rampsize);
+
+ /* create arrays for the sampled and processed data */
+ for (j=0; j<3; j++) {
+ data_sampled[j] = g_new0 (gdouble, rampsize);
+ data_interpolated[j] = g_new0 (gdouble, vcgt_size);
+ data_vcgt[j] = g_new0 (guint16, vcgt_size);
+ }
+
+ /* get the gray data */
+ for (i=0; i<rampsize; i++) {
+ patch_name = g_strdup_printf ("GS%i", i+1);
+ gcm_calibrate_native_get_it8_patch_rgb_xyz (it8_handle, patch_name, &patch_rgb, &patch_xyz);
+
+ /* scale the values */
+ _gcm_color_scale_XYZ (&patch_xyz, whitepointY);
+
+ cmsDoTransform (conversion_transform, &patch_xyz, &actual_rgb, 1);
+ egg_debug ("%s = %f,%f,%f -> %f,%f,%f", patch_name,
+ patch_rgb.R, patch_rgb.G, patch_rgb.B,
+ actual_rgb.R, actual_rgb.G, actual_rgb.B);
-cmsSetEncodedICCversion (profile, 0x2000000);
-cmsSetDeviceClass (profile, cmsSigDisplayClass);
-cmsSetColorSpace (profile, cmsSigRgbData);
-cmsSetPCS (profile, cmsSigLabData);
+ data_sampled[0][i] = actual_rgb.R;
+ data_sampled[1][i] = actual_rgb.G;
+ data_sampled[2][i] = actual_rgb.B;
+ g_free (patch_name);
+ }
+
+ for (i=0; i<rampsize; i++) {
+ egg_debug ("%i, %f,%f,%f", i,
+ data_sampled[0][i],
+ data_sampled[1][i],
+ data_sampled[2][i]);
+ }
+
+ /* reverse the profile, as we want to correct the display, not profile it */
+ div = 1.0f / (gdouble) (rampsize - 1);
+ for (i=0; i<rampsize; i++) {
+ gdouble value = (div*i);
+ for (j=0; j<3; j++)
+ data_sampled[j][i] = value + (value - data_sampled[j][i]);
+ }
+
+ /* remove the backlight leakage */
+ gcm_color_set_RGB (&leakage, G_MAXDOUBLE, G_MAXDOUBLE, G_MAXDOUBLE);
+ for (i=0; i<rampsize; i++) {
+ if (data_sampled[0][i] < leakage.R)
+ leakage.R = data_sampled[0][i];
+ if (data_sampled[1][i] < leakage.G)
+ leakage.G = data_sampled[1][i];
+ if (data_sampled[2][i] < leakage.B)
+ leakage.B = data_sampled[2][i];
+ }
+ for (i=0; i<rampsize; i++) {
+ data_sampled[0][i] -= leakage.R;
+ data_sampled[1][i] -= leakage.G;
+ data_sampled[2][i] -= leakage.B;
+ }
+ egg_debug ("removed backlight leakage = %f,%f,%f", leakage.R, leakage.G, leakage.B);
+
+ /* scale all values to 1.0 */
+ gcm_color_set_RGB (&scale, 0.0, 0.0, 0.0);
+ for (i=0; i<rampsize; i++) {
+ if (data_sampled[0][i] > scale.R)
+ scale.R = data_sampled[0][i];
+ if (data_sampled[1][i] > scale.G)
+ scale.G = data_sampled[1][i];
+ if (data_sampled[1][i] > scale.B)
+ scale.B = data_sampled[2][i];
+ }
+ for (i=0; i<rampsize; i++) {
+ data_sampled[0][i] /= scale.R;
+ data_sampled[1][i] /= scale.G;
+ data_sampled[2][i] /= scale.B;
+ }
+ egg_debug ("scaled to 1.0 using = %f,%f,%f", scale.R, scale.G, scale.B);
-_cmsWriteTagTextAscii (profile, cmsSigProfileDescriptionTag, "cmsSigProfileDescriptionTag");
-_cmsWriteTagTextAscii (profile, cmsSigCopyrightTag, "cmsSigCopyrightTag");
-_cmsWriteTagTextAscii (profile, cmsSigDeviceModelDescTag, "cmsSigDeviceModelDescTag");
-_cmsWriteTagTextAscii (profile, cmsSigDeviceMfgDescTag, "cmsSigDeviceMfgDescTag");
+ for (i=0; i<rampsize; i++) {
+ egg_debug ("%i, %f,%f,%f", i,
+ data_sampled[0][i],
+ data_sampled[1][i],
+ data_sampled[2][i]);
+ }
-PCS.whitePoint.X = cmsD50_XYZ()->X * 100.;
-PCS.whitePoint.Y = cmsD50_XYZ()->Y * 100.;
-PCS.whitePoint.Z = cmsD50_XYZ()->Z * 100.;
-PCS.Yb = 20; /* 20% of surround */
-PCS.La = 20; /* Adapting field luminance */
-PCS.surround = AVG_SURROUND;
-PCS.D_value = 1.0; /* Complete adaptation */
+ for (i=0; i<rampsize; i++) {
+ egg_debug ("%i, %f,%f,%f", i,
+ data_sampled[0][i],
+ data_sampled[1][i],
+ data_sampled[2][i]);
+ }
+ /* linear interpolate the values */
+ for (j=0; j<3; j++)
+ gcm_calibrate_native_interpolate_array (data_sampled[j], rampsize, data_interpolated[j], vcgt_size);
-cmsSaveProfileToFile (profile, "dave.icc");
+ /* convert to uint16 type */
+ for (j=0; j<3; j++) {
+ for (i=0; i<vcgt_size; i++) {
+ data_vcgt[j][i] = data_interpolated[j][i] * 0xffff;
+ }
+ }
+
+ /* set this in the profile */
+ ret = gcm_profile_set_vcgt_from_data (profile, data_vcgt[0], data_vcgt[1], data_vcgt[2], vcgt_size, error);
+ if (!ret)
+ goto out;
+out:
+ cmsFreeToneCurve (*transfer_curve);
+ cmsCloseProfile (xyz_profile);
+ cmsCloseProfile (conversion_profile);
+ if (conversion_transform != NULL)
+ cmsDeleteTransform (conversion_transform);
+ for (j=0; j<3; j++) {
+ g_free (data_vcgt[j]);
+ g_free (data_interpolated[j]);
+ g_free (data_sampled[j]);
+ }
+ if (it8_handle != NULL)
+ cmsIT8Free (it8_handle);
+ return ret;
-egg_error ("moo");
}
+/**
+ * gcm_calibrate_native_display:
+ **/
+static gboolean
+gcm_calibrate_native_display (GcmCalibrate *calibrate, GtkWindow *window, GError **error)
+{
+ GcmCalibrateNative *calibrate_native = GCM_CALIBRATE_NATIVE(calibrate);
+ GcmCalibrateNativePrivate *priv = calibrate_native->priv;
+ gboolean ret = TRUE;
+ GcmCalibratePrecision precision;
+ guint steps = 0;
+ GcmSensor *sensor;
+ gchar *copyright = NULL;
+ gchar *description = NULL;
+ gchar *manufacturer = NULL;
+ gchar *model = NULL;
+ const gchar *title;
+ const gchar *message;
+ const gchar *filename;
+ const gchar *basename;
+ gchar *filename_it8 = NULL;
+ gchar *filename_icc = NULL;
+ GcmProfile *profile;
+
+#if 0
+ cmsHPROFILE profile;
+ cmsViewingConditions PCS;
+ cmsViewingConditions device;
+
+ /* take it8 file, and open */
+ profile = cmsCreateProfilePlaceholder (NULL);
+
+ cmsSetEncodedICCversion (profile, 0x2000000);
+ cmsSetDeviceClass (profile, cmsSigDisplayClass);
+ cmsSetColorSpace (profile, cmsSigRgbData);
+ cmsSetPCS (profile, cmsSigLabData);
+
+ PCS.whitePoint.X = cmsD50_XYZ()->X * 100.;
+ PCS.whitePoint.Y = cmsD50_XYZ()->Y * 100.;
+ PCS.whitePoint.Z = cmsD50_XYZ()->Z * 100.;
+ PCS.La = 32; /* Adapting field luminance */
+ PCS.Yb = 20; /* 20% of surround */
+ PCS.surround = AVG_SURROUND;
+ PCS.D_value = 1.0; /* Complete adaptation */
+
+ device.Yb = 20; /* sRGB VCs */
+ device.La = 4;
+ device.surround = DIM_SURROUND;
+ device.D_value = 1.0; /* Complete adaptation */
+
+ int PCSType = PT_Lab;
+ egg_warning ("%i", PCSType);
+
+ cmsSaveProfileToFile (profile, "dave.icc");
+#endif
+
+ /* TODO: get from GcmCalibrate */
sensor = gcm_sensor_huey_new ();
/* show window */
@@ -357,12 +681,8 @@ egg_error ("moo");
/* TRANSLATORS: button text */
gcm_calibrate_dialog_set_button_ok_id (priv->calibrate_dialog, _("Continue"));
-egg_warning ("moo");
-
-// gtk_window_present (GTK_WINDOW (priv->calibrate_dialog));
-
-
/* wait for response */
+// gtk_window_present (GTK_WINDOW (priv->calibrate_dialog));
g_main_loop_run (priv->loop);
/* is cancelled */
@@ -384,11 +704,59 @@ egg_warning ("moo");
gcm_calibrate_dialog_set_show_button_ok (priv->calibrate_dialog, FALSE);
gcm_calibrate_dialog_set_show_expander (priv->calibrate_dialog, FALSE);
- gcm_calibrate_native_create_it8_file (calibrate_native, sensor, 10);
+ /* get filenames */
+ basename = gcm_calibrate_get_basename (calibrate);
+ filename_it8 = g_strdup_printf ("%s.it8", basename);
+ filename_icc = g_strdup_printf ("%s.icc", basename);
+
+ /* get the number of steps to use */
+ g_object_get (calibrate,
+ "precision", &precision,
+ NULL);
+ if (precision == GCM_CALIBRATE_PRECISION_SHORT)
+ steps = 10;
+ else if (precision == GCM_CALIBRATE_PRECISION_NORMAL)
+ steps = 20;
+ else if (precision == GCM_CALIBRATE_PRECISION_LONG)
+ steps = 30;
+
+ egg_debug ("creating %s", filename_it8);
+ gcm_calibrate_native_create_it8_file (calibrate_native, sensor, filename_it8, 10);
+
+ /* get profile text data */
+ copyright = gcm_calibrate_get_profile_copyright (calibrate);
+ description = gcm_calibrate_get_profile_description (calibrate);
+ model = gcm_calibrate_get_profile_model (calibrate);
+ manufacturer = gcm_calibrate_get_profile_manufacturer (calibrate);
+
+ /* create basic profile */
+ profile = gcm_profile_new ();
+ gcm_profile_set_colorspace (profile, GCM_COLORSPACE_RGB);
+ gcm_profile_set_kind (profile, GCM_PROFILE_KIND_DISPLAY_DEVICE);
+ gcm_profile_set_description (profile, description);
+ gcm_profile_set_copyright (profile, copyright);
+ gcm_profile_set_model (profile, model);
+ gcm_profile_set_manufacturer (profile, manufacturer);
+
+ /* convert sampled values to profile tables */
+ ret = gcm_calibrate_native_create_profile_from_it8 (profile, filename_it8, 256, error);
+ if (!ret)
+ goto out;
- g_object_unref (sensor);
+ /* save */
+ egg_debug ("saving %s", filename_icc);
+ ret = gcm_profile_save (profile, filename_icc, error);
+ if (!ret)
+ goto out;
out:
+ g_object_unref (sensor);
+ g_free (filename_it8);
+ g_free (filename_icc);
+ g_free (copyright);
+ g_free (description);
+ g_free (manufacturer);
+ g_free (model);
return ret;
}
@@ -487,7 +855,7 @@ gcm_calibrate_native_finalize (GObject *object)
/* hide */
gcm_calibrate_dialog_hide (priv->calibrate_dialog);
g_object_unref (priv->calibrate_dialog);
- g_object_unref (priv->sample_window);
+// g_object_unref (priv->sample_window);
g_object_unref (priv->cancellable);
g_main_loop_unref (priv->loop);
diff --git a/src/gcm-self-test.c b/src/gcm-self-test.c
index 12204a0..c2b288f 100644
--- a/src/gcm-self-test.c
+++ b/src/gcm-self-test.c
@@ -163,18 +163,77 @@ gcm_test_calibrate_native_func (void)
gboolean ret;
GError *error = NULL;
GcmCalibrate *calibrate;
+ GcmClient *client;
+ GcmX11Screen *screen;
+ GcmDevice *device;
+ gchar *contents;
+ gchar *filename;
calibrate = gcm_calibrate_native_new ();
g_assert (calibrate != NULL);
g_object_set (calibrate,
- "output-name", "LVDS1",
+ "output-name", "LVDS-1",
+ NULL);
+
+ /* create a virtual device we can "calibrate" */
+ client = gcm_client_new ();
+ g_assert (client != NULL);
+ g_setenv ("GCM_TEST", "1", TRUE);
+ filename = gcm_utils_get_default_config_location ();
+ contents = g_strdup_printf ("[xrandr_hewlett_packard_hp_lp2480zx_3cm82200kv]\n"
+ "serial=3CM82200KV\n"
+ "model=HP LP2480zx\n"
+ "manufacturer=Hewlett Packard\n"
+ "title=Hewlett Packard - HP LP2480zx - 24\"\n"
+ "type=display\n"
+ "colorspace=rgb");
+ ret = g_file_set_contents (filename, contents, -1, &error);
+ g_assert_no_error (error);
+ g_assert (ret);
+
+ ret = gcm_client_coldplug (client, GCM_CLIENT_COLDPLUG_SAVED, &error);
+ g_assert_no_error (error);
+ g_assert (ret);
+
+ device = gcm_client_get_device_by_id (client, "xrandr_hewlett_packard_hp_lp2480zx_3cm82200kv");
+ g_assert (device != NULL);
+
+ /* set device */
+ g_object_set (device,
+ "native-device", "LVDS-1",
NULL);
+ ret = gcm_calibrate_set_from_device (calibrate, device, &error);
+ g_assert_no_error (error);
+ g_assert (ret);
+ /* use a screen */
+ screen = gcm_x11_screen_new ();
+ ret = gcm_x11_screen_assign (screen, NULL, &error);
+ g_assert_no_error (error);
+ g_assert (ret);
+
+ /* clear any VCGT */
+ ret = gcm_device_xrandr_reset (GCM_DEVICE_XRANDR (device), &error);
+ g_assert_no_error (error);
+ g_assert (ret);
+
+ /* do the calibration */
ret = gcm_calibrate_display (calibrate, NULL, &error);
g_assert_no_error (error);
g_assert (ret);
+ /* be good and restore the settings if they changed */
+ ret = g_spawn_command_line_sync (BINDIR "/gcm-apply", NULL, NULL, NULL, &error);
+ g_assert_no_error (error);
+ g_assert (ret);
+
+ g_object_unref (client);
+ g_object_unref (device);
+ g_unlink (filename);
+ g_free (contents);
+ g_free (filename);
+ g_object_unref (screen);
g_object_unref (calibrate);
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]