// 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; }
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); }