// Approximate a blackbody illuminant based on CHAD information
static
cmsFloat64Number CHAD2Temp(const cmsMAT3* Chad)
{
    // Convert D50 across inverse CHAD to get the absolute white point
    cmsVEC3 d, s;
    cmsCIEXYZ Dest;
    cmsCIExyY DestChromaticity;
    cmsFloat64Number TempK;
    cmsMAT3 m1, m2;

    m1 = *Chad;
    if (!_cmsMAT3inverse(&m1, &m2)) return FALSE;

    s.n[VX] = cmsD50_XYZ() -> X;
    s.n[VY] = cmsD50_XYZ() -> Y;
    s.n[VZ] = cmsD50_XYZ() -> Z;

    _cmsMAT3eval(&d, &m2, &s);

    Dest.X = d.n[VX];
    Dest.Y = d.n[VY];
    Dest.Z = d.n[VZ];

    cmsXYZ2xyY(&DestChromaticity, &Dest);

    if (!cmsTempFromWhitePoint(&TempK, &DestChromaticity))
        return -1.0;

    return TempK;
}
Beispiel #2
0
static void
gcm_picker_refresh_results (GcmPickerPrivate *priv)
{
	cmsCIExyY xyY;
	cmsHPROFILE profile_lab;
	cmsHPROFILE profile_rgb;
	cmsHPROFILE profile_xyz;
	cmsHTRANSFORM transform_error;
	cmsHTRANSFORM transform_lab;
	cmsHTRANSFORM transform_rgb;
	gboolean ret;
	CdColorLab color_lab;
	CdColorRGB8 color_rgb;
	CdColorXYZ color_error;
	CdColorXYZ color_xyz;
	gdouble temperature = 0.0f;
	GtkImage *image;
	GtkLabel *label;
	g_autoptr(GdkPixbuf) pixbuf = NULL;
	g_autofree gchar *text_ambient = NULL;
	g_autofree gchar *text_error = NULL;
	g_autofree gchar *text_lab = NULL;
	g_autofree gchar *text_rgb = NULL;
	g_autofree gchar *text_temperature = NULL;
	g_autofree gchar *text_whitepoint = NULL;
	g_autofree gchar *text_xyz = NULL;

	/* nothing set yet */
	if (priv->profile_filename == NULL)
		return;

	/* copy as we're modifying the value */
	cd_color_xyz_copy (&priv->last_sample, &color_xyz);

	/* create new pixbuf of the right size */
	image = GTK_IMAGE (gtk_builder_get_object (priv->builder, "image_preview"));
	pixbuf = gdk_pixbuf_new (GDK_COLORSPACE_RGB, FALSE, 8,
				 gtk_widget_get_allocated_width (GTK_WIDGET (image)),
				 gtk_widget_get_allocated_height (GTK_WIDGET (image)));

	/* lcms scales these for some reason */
	color_xyz.X /= 100.0f;
	color_xyz.Y /= 100.0f;
	color_xyz.Z /= 100.0f;

	/* get profiles */
	profile_xyz = cmsCreateXYZProfile ();
	profile_rgb = cmsOpenProfileFromFile (priv->profile_filename, "r");
	profile_lab = cmsCreateLab4Profile (cmsD50_xyY ());

	/* create transforms */
	transform_rgb = cmsCreateTransform (profile_xyz, TYPE_XYZ_DBL,
					    profile_rgb, TYPE_RGB_8,
					    INTENT_PERCEPTUAL, 0);
	if (transform_rgb == NULL)
		return;
	transform_lab = cmsCreateTransform (profile_xyz, TYPE_XYZ_DBL,
					    profile_lab, TYPE_Lab_DBL,
					    INTENT_PERCEPTUAL, 0);
	if (transform_lab == NULL)
		return;
	transform_error = cmsCreateTransform (profile_rgb, TYPE_RGB_8,
					      profile_xyz, TYPE_XYZ_DBL,
					      INTENT_PERCEPTUAL, 0);
	if (transform_error == NULL)
		return;

	cmsDoTransform (transform_rgb, &color_xyz, &color_rgb, 1);
	cmsDoTransform (transform_lab, &color_xyz, &color_lab, 1);
	cmsDoTransform (transform_error, &color_rgb, &color_error, 1);

	/* destroy lcms state */
	cmsDeleteTransform (transform_rgb);
	cmsDeleteTransform (transform_lab);
	cmsDeleteTransform (transform_error);
	cmsCloseProfile (profile_xyz);
	cmsCloseProfile (profile_rgb);
	cmsCloseProfile (profile_lab);

	/* set XYZ */
	label = GTK_LABEL (gtk_builder_get_object (priv->builder, "label_xyz"));
	text_xyz = g_strdup_printf ("%.3f, %.3f, %.3f",
				    priv->last_sample.X,
				    priv->last_sample.Y,
				    priv->last_sample.Z);
	gtk_label_set_label (label, text_xyz);

	/* set LAB */
	label = GTK_LABEL (gtk_builder_get_object (priv->builder, "label_lab"));
	text_lab = g_strdup_printf ("%.3f, %.3f, %.3f",
				    color_lab.L,
				    color_lab.a,
				    color_lab.b);
	gtk_label_set_label (label, text_lab);

	/* set whitepoint */
	cmsXYZ2xyY (&xyY, (cmsCIEXYZ *)&priv->last_sample);
	label = GTK_LABEL (gtk_builder_get_object (priv->builder, "label_whitepoint"));
	text_whitepoint = g_strdup_printf ("%.3f,%.3f [%.3f]",
					   xyY.x, xyY.y, xyY.Y);
	gtk_label_set_label (label, text_whitepoint);

	/* set temperature */
	ret = cmsTempFromWhitePoint (&temperature, &xyY);
	if (ret) {
		/* round to nearest 10K */
		temperature = (((guint) temperature) / 10) * 10;
	}
	label = GTK_LABEL (gtk_builder_get_object (priv->builder, "label_temperature"));
	text_temperature = g_strdup_printf ("%.0fK", temperature);
	gtk_label_set_label (label, text_temperature);

	/* set RGB */
	label = GTK_LABEL (gtk_builder_get_object (priv->builder, "label_rgb"));
	text_rgb = g_strdup_printf ("%i, %i, %i (#%02X%02X%02X)",
				    color_rgb.R, color_rgb.G, color_rgb.B,
				    color_rgb.R, color_rgb.G, color_rgb.B);
	gtk_label_set_label (label, text_rgb);
	gcm_picker_set_pixbuf_color (pixbuf, color_rgb.R, color_rgb.G, color_rgb.B);

	/* set error */
	label = GTK_LABEL (gtk_builder_get_object (priv->builder, "label_error"));
	if (color_xyz.X > 0.01f &&
	    color_xyz.Y > 0.01f &&
	    color_xyz.Z > 0.01f) {
		text_error = g_strdup_printf ("%.1f%%, %.1f%%, %.1f%%",
					      ABS ((color_error.X - color_xyz.X) / color_xyz.X * 100),
					      ABS ((color_error.Y - color_xyz.Y) / color_xyz.Y * 100),
					      ABS ((color_error.Z - color_xyz.Z) / color_xyz.Z * 100));
		gtk_label_set_label (label, text_error);
	} else {
		/* TRANSLATORS: this is when the error is invalid */
		gtk_label_set_label (label, _("Unknown"));
	}

	/* set ambient */
	label = GTK_LABEL (gtk_builder_get_object (priv->builder, "label_ambient"));
	if (priv->last_ambient < 0) {
		/* TRANSLATORS: this is when the ambient light level is unknown */
		gtk_label_set_label (label, _("Unknown"));
	} else {
		text_ambient = g_strdup_printf ("%.1f Lux", priv->last_ambient);
		gtk_label_set_label (label, text_ambient);
	}

	/* set image */
	gtk_image_set_from_pixbuf (image, pixbuf);
}