summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRichard Hughes <richard@hughsie.com>2013-04-24 16:26:25 +0100
committerRichard Hughes <richard@hughsie.com>2013-04-24 16:26:25 +0100
commitc9607e452074d67a8b2ffede317b469609411c34 (patch)
tree45e6bef256c554e5bef385a26b38bb0dd3816667
parentd3c84958d237fd335832e40e0e04bc6c5d3f524f (diff)
downloadcolord-c9607e452074d67a8b2ffede317b469609411c34.tar.gz
Move the warning check code from the daemon to libcolord for code reuse
This allows us to write a helper tool to identify lots of broken profiles.
-rw-r--r--lib/colord/cd-icc.c372
-rw-r--r--lib/colord/cd-icc.h1
-rw-r--r--lib/colord/cd-self-test.c6
-rw-r--r--src/cd-profile.c359
4 files changed, 380 insertions, 358 deletions
diff --git a/lib/colord/cd-icc.c b/lib/colord/cd-icc.c
index d5edaa0..026c0f3 100644
--- a/lib/colord/cd-icc.c
+++ b/lib/colord/cd-icc.c
@@ -31,6 +31,7 @@
#include <locale.h>
#include <string.h>
#include <stdlib.h>
+#include <math.h>
#include "cd-icc.h"
@@ -2533,6 +2534,377 @@ out:
}
/**
+ * cd_icc_check_vcgt:
+ **/
+static CdProfileWarning
+cd_icc_check_vcgt (cmsHPROFILE profile)
+{
+ CdProfileWarning warning = CD_PROFILE_WARNING_NONE;
+ cmsFloat32Number in;
+ cmsFloat32Number now[3];
+ cmsFloat32Number previous[3] = { -1, -1, -1};
+ const cmsToneCurve **vcgt;
+ const guint size = 32;
+ guint i;
+
+ /* does profile have monotonic VCGT */
+ vcgt = cmsReadTag (profile, cmsSigVcgtTag);
+ if (vcgt == NULL)
+ goto out;
+ for (i = 0; i < size; i++) {
+ in = (gdouble) i / (gdouble) (size - 1);
+ now[0] = cmsEvalToneCurveFloat(vcgt[0], in);
+ now[1] = cmsEvalToneCurveFloat(vcgt[1], in);
+ now[2] = cmsEvalToneCurveFloat(vcgt[2], in);
+
+ /* check VCGT is increasing */
+ if (i > 0) {
+ if (now[0] < previous[0] ||
+ now[1] < previous[1] ||
+ now[2] < previous[2]) {
+ warning = CD_PROFILE_WARNING_VCGT_NON_MONOTONIC;
+ goto out;
+ }
+ }
+ previous[0] = now[0];
+ previous[1] = now[1];
+ previous[2] = now[2];
+ }
+out:
+ return warning;
+}
+
+/**
+ * cd_profile_check_scum_dot:
+ **/
+static CdProfileWarning
+cd_profile_check_scum_dot (cmsHPROFILE profile)
+{
+ CdProfileWarning warning = CD_PROFILE_WARNING_NONE;
+ cmsCIELab white;
+ cmsHPROFILE profile_lab;
+ cmsHTRANSFORM transform;
+ guint8 rgb[3] = { 0, 0, 0 };
+
+ /* do Lab to RGB transform of 100,0,0 */
+ profile_lab = cmsCreateLab2Profile (cmsD50_xyY ());
+ transform = cmsCreateTransform (profile_lab, TYPE_Lab_DBL,
+ profile, TYPE_RGB_8,
+ INTENT_RELATIVE_COLORIMETRIC,
+ cmsFLAGS_NOOPTIMIZE);
+ if (transform == NULL) {
+ g_warning ("failed to setup Lab -> RGB transform");
+ goto out;
+ }
+ white.L = 100.0;
+ white.a = 0.0;
+ white.b = 0.0;
+ cmsDoTransform (transform, &white, rgb, 1);
+ if (rgb[0] != 255 || rgb[1] != 255 || rgb[2] != 255) {
+ warning = CD_PROFILE_WARNING_SCUM_DOT;
+ goto out;
+ }
+out:
+ if (profile_lab != NULL)
+ cmsCloseProfile (profile_lab);
+ if (transform != NULL)
+ cmsDeleteTransform (transform);
+ return warning;
+}
+
+/**
+ * cd_icc_check_primaries:
+ **/
+static CdProfileWarning
+cd_icc_check_primaries (cmsHPROFILE profile)
+{
+ CdProfileWarning warning = CD_PROFILE_WARNING_NONE;
+ cmsCIEXYZ *tmp;
+
+ /* The values used to check are based on the following ultra-wide
+ * gamut profile XYZ values:
+ *
+ * CIERGB:
+ * Red: 0.486893 0.174667 -0.001251
+ * Green: 0.306320 0.824768 0.016998
+ * Blue: 0.170990 0.000565 0.809158
+
+ * ProPhoto RGB:
+ * Red: 0.797546 0.288025 0.000000
+ * Green: 0.135315 0.711899 -0.000015
+ * Blue: 0.031342 0.000076 0.824921
+ */
+
+ /* check red */
+ tmp = cmsReadTag (profile, cmsSigRedColorantTag);
+ if (tmp == NULL)
+ goto out;
+ if (tmp->X > 0.85f || tmp->Y < 0.15f || tmp->Z < -0.01) {
+ warning = CD_PROFILE_WARNING_PRIMARIES_INVALID;
+ goto out;
+ }
+
+ /* check green */
+ tmp = cmsReadTag (profile, cmsSigGreenColorantTag);
+ if (tmp == NULL)
+ goto out;
+ if (tmp->X < 0.10f || tmp->Y > 0.85f || tmp->Z < -0.01f) {
+ warning = CD_PROFILE_WARNING_PRIMARIES_INVALID;
+ goto out;
+ }
+
+ /* check blue */
+ tmp = cmsReadTag (profile, cmsSigBlueColorantTag);
+ if (tmp == NULL)
+ goto out;
+ if (tmp->X < 0.10f || tmp->Y < 0.01f || tmp->Z > 0.87f) {
+ warning = CD_PROFILE_WARNING_PRIMARIES_INVALID;
+ goto out;
+ }
+out:
+ return warning;
+}
+
+/**
+ * cd_icc_check_gray_axis:
+ **/
+static CdProfileWarning
+cd_icc_check_gray_axis (cmsHPROFILE profile)
+{
+ CdProfileWarning warning = CD_PROFILE_WARNING_NONE;
+ cmsCIELab gray[16];
+ cmsHPROFILE profile_lab = NULL;
+ cmsHTRANSFORM transform = NULL;
+ const gdouble gray_error = 5.0f;
+ gdouble last_l = -1;
+ guint8 rgb[3*16];
+ guint8 tmp;
+ guint i;
+
+ /* only do this for display profiles */
+ if (cmsGetDeviceClass (profile) != cmsSigDisplayClass)
+ goto out;
+
+ /* do Lab to RGB transform of 100,0,0 */
+ profile_lab = cmsCreateLab2Profile (cmsD50_xyY ());
+ transform = cmsCreateTransform (profile, TYPE_RGB_8,
+ profile_lab, TYPE_Lab_DBL,
+ INTENT_RELATIVE_COLORIMETRIC,
+ cmsFLAGS_NOOPTIMIZE);
+ if (transform == NULL) {
+ g_warning ("failed to setup RGB -> Lab transform");
+ goto out;
+ }
+
+ /* run a 16 item gray ramp through the transform */
+ for (i = 0; i < 16; i++) {
+ tmp = (255.0f / (16.0f - 1)) * i;
+ rgb[(i * 3) + 0] = tmp;
+ rgb[(i * 3) + 1] = tmp;
+ rgb[(i * 3) + 2] = tmp;
+ }
+ cmsDoTransform (transform, rgb, gray, 16);
+
+ /* check a/b is small */
+ for (i = 0; i < 16; i++) {
+ if (gray[i].a > gray_error ||
+ gray[i].b > gray_error) {
+ warning = CD_PROFILE_WARNING_GRAY_AXIS_INVALID;
+ goto out;
+ }
+ }
+
+ /* check it's monotonic */
+ for (i = 0; i < 16; i++) {
+ if (last_l > 0 && gray[i].L < last_l) {
+ warning = CD_PROFILE_WARNING_GRAY_AXIS_NON_MONOTONIC;
+ goto out;
+ }
+ last_l = gray[i].L;
+ }
+out:
+ if (profile_lab != NULL)
+ cmsCloseProfile (profile_lab);
+ if (transform != NULL)
+ cmsDeleteTransform (transform);
+ return warning;
+}
+
+/**
+ * cd_icc_check_d50_whitepoint:
+ **/
+static CdProfileWarning
+cd_icc_check_d50_whitepoint (cmsHPROFILE profile)
+{
+ CdProfileWarning warning = CD_PROFILE_WARNING_NONE;
+ cmsCIExyY tmp;
+ cmsCIEXYZ additive;
+ cmsCIEXYZ primaries[4];
+ cmsHPROFILE profile_lab;
+ cmsHTRANSFORM transform;
+ const cmsCIEXYZ *d50;
+ const gdouble rgb_error = 0.05;
+ const gdouble additive_error = 0.1f;
+ const gdouble white_error = 0.05;
+ guint8 rgb[3*4];
+ guint i;
+
+ /* do Lab to RGB transform to get primaries */
+ profile_lab = cmsCreateXYZProfile ();
+ transform = cmsCreateTransform (profile, TYPE_RGB_8,
+ profile_lab, TYPE_XYZ_DBL,
+ INTENT_RELATIVE_COLORIMETRIC,
+ cmsFLAGS_NOOPTIMIZE);
+ if (transform == NULL) {
+ g_warning ("failed to setup RGB -> XYZ transform");
+ goto out;
+ }
+
+ /* Run RGBW through the transform */
+ rgb[0 + 0] = 255;
+ rgb[0 + 1] = 0;
+ rgb[0 + 2] = 0;
+ rgb[3 + 0] = 0;
+ rgb[3 + 1] = 255;
+ rgb[3 + 2] = 0;
+ rgb[6 + 0] = 0;
+ rgb[6 + 1] = 0;
+ rgb[6 + 2] = 255;
+ rgb[9 + 0] = 255;
+ rgb[9 + 1] = 255;
+ rgb[9 + 2] = 255;
+ cmsDoTransform (transform, rgb, primaries, 4);
+
+ /* check red is in gamut */
+ cmsXYZ2xyY (&tmp, &primaries[0]);
+ if (tmp.x - 0.735 > rgb_error || 0.265 - tmp.y > rgb_error) {
+ warning = CD_PROFILE_WARNING_PRIMARIES_UNLIKELY;
+ goto out;
+ }
+
+ /* check green is in gamut */
+ cmsXYZ2xyY (&tmp, &primaries[1]);
+ if (0.160 - tmp.x > rgb_error || tmp.y - 0.840 > rgb_error) {
+ warning = CD_PROFILE_WARNING_PRIMARIES_UNLIKELY;
+ goto out;
+ }
+
+ /* check blue is in gamut */
+ cmsXYZ2xyY (&tmp, &primaries[2]);
+ if (0.037 - tmp.x > rgb_error || tmp.y - 0.358 > rgb_error) {
+ warning = CD_PROFILE_WARNING_PRIMARIES_UNLIKELY;
+ goto out;
+ }
+
+ /* only do the rest for display profiles */
+ if (cmsGetDeviceClass (profile) != cmsSigDisplayClass)
+ goto out;
+
+ /* check white is D50 */
+ d50 = cmsD50_XYZ();
+ if (fabs (primaries[3].X - d50->X) > white_error ||
+ fabs (primaries[3].Y - d50->Y) > white_error ||
+ fabs (primaries[3].Z - d50->Z) > white_error) {
+ warning = CD_PROFILE_WARNING_WHITEPOINT_INVALID;
+ goto out;
+ }
+
+ /* check primaries add up to D50 */
+ additive.X = 0;
+ additive.Y = 0;
+ additive.Z = 0;
+ for (i = 0; i < 3; i++) {
+ additive.X += primaries[i].X;
+ additive.Y += primaries[i].Y;
+ additive.Z += primaries[i].Z;
+ }
+ if (fabs (additive.X - d50->X) > additive_error ||
+ fabs (additive.Y - d50->Y) > additive_error ||
+ fabs (additive.Z - d50->Z) > additive_error) {
+ warning = CD_PROFILE_WARNING_PRIMARIES_NON_ADDITIVE;
+ goto out;
+ }
+out:
+ if (profile_lab != NULL)
+ cmsCloseProfile (profile_lab);
+ if (transform != NULL)
+ cmsDeleteTransform (transform);
+ return warning;
+}
+
+/**
+ * cd_icc_get_warnings:
+ * @icc: a #CdIcc instance.
+ *
+ * Returns any warnings with profiles
+ *
+ * Return value: Array of %CdProfileWarning enum values
+ *
+ * Since: 0.1.34
+ **/
+GArray *
+cd_icc_get_warnings (CdIcc *icc)
+{
+ GArray *flags;
+ gboolean ret;
+ gchar ascii_name[1024];
+ CdProfileWarning warning;
+
+ g_return_val_if_fail (CD_IS_ICC (icc), NULL);
+ g_return_val_if_fail (icc->priv->lcms_profile != NULL, NULL);
+
+ flags = g_array_new (FALSE, FALSE, sizeof (CdProfileWarning));
+
+ /* check that the profile has a description and a copyright */
+ ret = cmsGetProfileInfoASCII (icc->priv->lcms_profile,
+ cmsInfoDescription, "en", "US",
+ ascii_name, 1024);
+ if (!ret || ascii_name[0] == '\0') {
+ warning = CD_PROFILE_WARNING_DESCRIPTION_MISSING;
+ g_array_append_val (flags, warning);
+ }
+ ret = cmsGetProfileInfoASCII (icc->priv->lcms_profile,
+ cmsInfoCopyright, "en", "US",
+ ascii_name, 1024);
+ if (!ret || ascii_name[0] == '\0') {
+ warning = CD_PROFILE_WARNING_COPYRIGHT_MISSING;
+ g_array_append_val (flags, warning);
+ }
+
+ /* not a RGB space */
+ if (cmsGetColorSpace (icc->priv->lcms_profile) != cmsSigRgbData)
+ goto out;
+
+ /* does profile have monotonic VCGT */
+ warning = cd_icc_check_vcgt (icc->priv->lcms_profile);
+ if (warning != CD_PROFILE_WARNING_NONE)
+ g_array_append_val (flags, warning);
+
+ /* if Lab 100,0,0 does not map to RGB 255,255,255 for relative
+ * colorimetric then white it will not work on printers */
+ warning = cd_profile_check_scum_dot (icc->priv->lcms_profile);
+ if (warning != CD_PROFILE_WARNING_NONE)
+ g_array_append_val (flags, warning);
+
+ /* gray should give low a/b and should be monotonic */
+ warning = cd_icc_check_gray_axis (icc->priv->lcms_profile);
+ if (warning != CD_PROFILE_WARNING_NONE)
+ g_array_append_val (flags, warning);
+
+ /* tristimulus values cannot be negative */
+ warning = cd_icc_check_primaries (icc->priv->lcms_profile);
+ if (warning != CD_PROFILE_WARNING_NONE)
+ g_array_append_val (flags, warning);
+
+ /* check whitepoint works out to D50 */
+ warning = cd_icc_check_d50_whitepoint (icc->priv->lcms_profile);
+ if (warning != CD_PROFILE_WARNING_NONE)
+ g_array_append_val (flags, warning);
+out:
+ return flags;
+}
+
+/**
* cd_icc_get_property:
**/
static void
diff --git a/lib/colord/cd-icc.h b/lib/colord/cd-icc.h
index 1a9e616..4fee6ac 100644
--- a/lib/colord/cd-icc.h
+++ b/lib/colord/cd-icc.h
@@ -217,6 +217,7 @@ const CdColorXYZ *cd_icc_get_green (CdIcc *icc);
const CdColorXYZ *cd_icc_get_blue (CdIcc *icc);
const CdColorXYZ *cd_icc_get_white (CdIcc *icc);
guint cd_icc_get_temperature (CdIcc *icc);
+GArray *cd_icc_get_warnings (CdIcc *icc);
gboolean cd_icc_create_from_edid (CdIcc *icc,
gdouble gamma_value,
const CdColorYxy *red,
diff --git a/lib/colord/cd-self-test.c b/lib/colord/cd-self-test.c
index 4363310..5c9f007 100644
--- a/lib/colord/cd-self-test.c
+++ b/lib/colord/cd-self-test.c
@@ -3363,6 +3363,7 @@ colord_icc_func (void)
CdIcc *icc;
const CdColorXYZ *xyz_tmp;
const gchar *str;
+ GArray *warnings;
gboolean ret;
gchar *created_str;
gchar *filename;
@@ -3436,6 +3437,11 @@ colord_icc_func (void)
g_hash_table_unref (metadata);
g_assert_cmpstr (cd_icc_get_metadata_item (icc, "EDID_md5"), ==, "f09e42aa86585d1bb6687d3c322ed0c1");
+ /* check warnings */
+ warnings = cd_icc_get_warnings (icc);
+ g_assert_cmpint (warnings->len, ==, 0);
+ g_array_unref (warnings);
+
/* marshall to a string */
tmp = cd_icc_to_string (icc);
g_assert_cmpstr (tmp, !=, NULL);
diff --git a/src/cd-profile.c b/src/cd-profile.c
index cf218b5..3b298f8 100644
--- a/src/cd-profile.c
+++ b/src/cd-profile.c
@@ -866,363 +866,6 @@ out:
}
/**
- * cd_profile_check_vcgt:
- **/
-static CdProfileWarning
-cd_profile_check_vcgt (cmsHPROFILE profile)
-{
- CdProfileWarning warning = CD_PROFILE_WARNING_NONE;
- cmsFloat32Number in;
- cmsFloat32Number now[3];
- cmsFloat32Number previous[3] = { -1, -1, -1};
- const cmsToneCurve **vcgt;
- const guint size = 32;
- guint i;
-
- /* does profile have monotonic VCGT */
- vcgt = cmsReadTag (profile, cmsSigVcgtTag);
- if (vcgt == NULL)
- goto out;
- for (i = 0; i < size; i++) {
- in = (gdouble) i / (gdouble) (size - 1);
- now[0] = cmsEvalToneCurveFloat(vcgt[0], in);
- now[1] = cmsEvalToneCurveFloat(vcgt[1], in);
- now[2] = cmsEvalToneCurveFloat(vcgt[2], in);
-
- /* check VCGT is increasing */
- if (i > 0) {
- if (now[0] < previous[0] ||
- now[1] < previous[1] ||
- now[2] < previous[2]) {
- warning = CD_PROFILE_WARNING_VCGT_NON_MONOTONIC;
- goto out;
- }
- }
- previous[0] = now[0];
- previous[1] = now[1];
- previous[2] = now[2];
- }
-out:
- return warning;
-}
-
-/**
- * cd_profile_check_scum_dot:
- **/
-static CdProfileWarning
-cd_profile_check_scum_dot (cmsHPROFILE profile)
-{
- CdProfileWarning warning = CD_PROFILE_WARNING_NONE;
- cmsCIELab white;
- cmsHPROFILE profile_lab;
- cmsHTRANSFORM transform;
- guint8 rgb[3] = { 0, 0, 0 };
-
- /* do Lab to RGB transform of 100,0,0 */
- profile_lab = cmsCreateLab2Profile (cmsD50_xyY ());
- transform = cmsCreateTransform (profile_lab, TYPE_Lab_DBL,
- profile, TYPE_RGB_8,
- INTENT_RELATIVE_COLORIMETRIC,
- cmsFLAGS_NOOPTIMIZE);
- if (transform == NULL) {
- g_warning ("failed to setup Lab -> RGB transform");
- goto out;
- }
- white.L = 100.0;
- white.a = 0.0;
- white.b = 0.0;
- cmsDoTransform (transform, &white, rgb, 1);
- if (rgb[0] != 255 || rgb[1] != 255 || rgb[2] != 255) {
- warning = CD_PROFILE_WARNING_SCUM_DOT;
- goto out;
- }
-out:
- if (profile_lab != NULL)
- cmsCloseProfile (profile_lab);
- if (transform != NULL)
- cmsDeleteTransform (transform);
- return warning;
-}
-
-/**
- * cd_profile_check_primaries:
- **/
-static CdProfileWarning
-cd_profile_check_primaries (cmsHPROFILE profile)
-{
- CdProfileWarning warning = CD_PROFILE_WARNING_NONE;
- cmsCIEXYZ *tmp;
-
- /* The values used to check are based on the following ultra-wide
- * gamut profile XYZ values:
- *
- * CIERGB:
- * Red: 0.486893 0.174667 -0.001251
- * Green: 0.306320 0.824768 0.016998
- * Blue: 0.170990 0.000565 0.809158
-
- * ProPhoto RGB:
- * Red: 0.797546 0.288025 0.000000
- * Green: 0.135315 0.711899 -0.000015
- * Blue: 0.031342 0.000076 0.824921
- */
-
- /* check red */
- tmp = cmsReadTag (profile, cmsSigRedColorantTag);
- if (tmp == NULL)
- goto out;
- if (tmp->X > 0.85f || tmp->Y < 0.15f || tmp->Z < -0.01) {
- warning = CD_PROFILE_WARNING_PRIMARIES_INVALID;
- goto out;
- }
-
- /* check green */
- tmp = cmsReadTag (profile, cmsSigGreenColorantTag);
- if (tmp == NULL)
- goto out;
- if (tmp->X < 0.10f || tmp->Y > 0.85f || tmp->Z < -0.01f) {
- warning = CD_PROFILE_WARNING_PRIMARIES_INVALID;
- goto out;
- }
-
- /* check blue */
- tmp = cmsReadTag (profile, cmsSigBlueColorantTag);
- if (tmp == NULL)
- goto out;
- if (tmp->X < 0.10f || tmp->Y < 0.01f || tmp->Z > 0.87f) {
- warning = CD_PROFILE_WARNING_PRIMARIES_INVALID;
- goto out;
- }
-out:
- return warning;
-}
-
-/**
- * cd_profile_check_gray_axis:
- **/
-static CdProfileWarning
-cd_profile_check_gray_axis (cmsHPROFILE profile)
-{
- CdProfileWarning warning = CD_PROFILE_WARNING_NONE;
- cmsCIELab gray[16];
- cmsHPROFILE profile_lab = NULL;
- cmsHTRANSFORM transform = NULL;
- const gdouble gray_error = 5.0f;
- gdouble last_l = -1;
- guint8 rgb[3*16];
- guint8 tmp;
- guint i;
-
- /* only do this for display profiles */
- if (cmsGetDeviceClass (profile) != cmsSigDisplayClass)
- goto out;
-
- /* do Lab to RGB transform of 100,0,0 */
- profile_lab = cmsCreateLab2Profile (cmsD50_xyY ());
- transform = cmsCreateTransform (profile, TYPE_RGB_8,
- profile_lab, TYPE_Lab_DBL,
- INTENT_RELATIVE_COLORIMETRIC,
- cmsFLAGS_NOOPTIMIZE);
- if (transform == NULL) {
- g_warning ("failed to setup RGB -> Lab transform");
- goto out;
- }
-
- /* run a 16 item gray ramp through the transform */
- for (i = 0; i < 16; i++) {
- tmp = (255.0f / (16.0f - 1)) * i;
- rgb[(i * 3) + 0] = tmp;
- rgb[(i * 3) + 1] = tmp;
- rgb[(i * 3) + 2] = tmp;
- }
- cmsDoTransform (transform, rgb, gray, 16);
-
- /* check a/b is small */
- for (i = 0; i < 16; i++) {
- if (gray[i].a > gray_error ||
- gray[i].b > gray_error) {
- warning = CD_PROFILE_WARNING_GRAY_AXIS_INVALID;
- goto out;
- }
- }
-
- /* check it's monotonic */
- for (i = 0; i < 16; i++) {
- if (last_l > 0 && gray[i].L < last_l) {
- warning = CD_PROFILE_WARNING_GRAY_AXIS_NON_MONOTONIC;
- goto out;
- }
- last_l = gray[i].L;
- }
-out:
- if (profile_lab != NULL)
- cmsCloseProfile (profile_lab);
- if (transform != NULL)
- cmsDeleteTransform (transform);
- return warning;
-}
-
-/**
- * cd_profile_check_d50_whitepoint:
- **/
-static CdProfileWarning
-cd_profile_check_d50_whitepoint (cmsHPROFILE profile)
-{
- CdProfileWarning warning = CD_PROFILE_WARNING_NONE;
- cmsCIExyY tmp;
- cmsCIEXYZ additive;
- cmsCIEXYZ primaries[4];
- cmsHPROFILE profile_lab;
- cmsHTRANSFORM transform;
- const cmsCIEXYZ *d50;
- const gdouble rgb_error = 0.05;
- const gdouble additive_error = 0.1f;
- const gdouble white_error = 0.05;
- guint8 rgb[3*4];
- guint i;
-
- /* do Lab to RGB transform to get primaries */
- profile_lab = cmsCreateXYZProfile ();
- transform = cmsCreateTransform (profile, TYPE_RGB_8,
- profile_lab, TYPE_XYZ_DBL,
- INTENT_RELATIVE_COLORIMETRIC,
- cmsFLAGS_NOOPTIMIZE);
- if (transform == NULL) {
- g_warning ("failed to setup RGB -> XYZ transform");
- goto out;
- }
-
- /* Run RGBW through the transform */
- rgb[0 + 0] = 255;
- rgb[0 + 1] = 0;
- rgb[0 + 2] = 0;
- rgb[3 + 0] = 0;
- rgb[3 + 1] = 255;
- rgb[3 + 2] = 0;
- rgb[6 + 0] = 0;
- rgb[6 + 1] = 0;
- rgb[6 + 2] = 255;
- rgb[9 + 0] = 255;
- rgb[9 + 1] = 255;
- rgb[9 + 2] = 255;
- cmsDoTransform (transform, rgb, primaries, 4);
-
- /* check red is in gamut */
- cmsXYZ2xyY (&tmp, &primaries[0]);
- if (tmp.x - 0.735 > rgb_error || 0.265 - tmp.y > rgb_error) {
- warning = CD_PROFILE_WARNING_PRIMARIES_UNLIKELY;
- goto out;
- }
-
- /* check green is in gamut */
- cmsXYZ2xyY (&tmp, &primaries[1]);
- if (0.160 - tmp.x > rgb_error || tmp.y - 0.840 > rgb_error) {
- warning = CD_PROFILE_WARNING_PRIMARIES_UNLIKELY;
- goto out;
- }
-
- /* check blue is in gamut */
- cmsXYZ2xyY (&tmp, &primaries[2]);
- if (0.037 - tmp.x > rgb_error || tmp.y - 0.358 > rgb_error) {
- warning = CD_PROFILE_WARNING_PRIMARIES_UNLIKELY;
- goto out;
- }
-
- /* only do the rest for display profiles */
- if (cmsGetDeviceClass (profile) != cmsSigDisplayClass)
- goto out;
-
- /* check white is D50 */
- d50 = cmsD50_XYZ();
- if (fabs (primaries[3].X - d50->X) > white_error ||
- fabs (primaries[3].Y - d50->Y) > white_error ||
- fabs (primaries[3].Z - d50->Z) > white_error) {
- warning = CD_PROFILE_WARNING_WHITEPOINT_INVALID;
- goto out;
- }
-
- /* check primaries add up to D50 */
- additive.X = 0;
- additive.Y = 0;
- additive.Z = 0;
- for (i = 0; i < 3; i++) {
- additive.X += primaries[i].X;
- additive.Y += primaries[i].Y;
- additive.Z += primaries[i].Z;
- }
- if (fabs (additive.X - d50->X) > additive_error ||
- fabs (additive.Y - d50->Y) > additive_error ||
- fabs (additive.Z - d50->Z) > additive_error) {
- warning = CD_PROFILE_WARNING_PRIMARIES_NON_ADDITIVE;
- goto out;
- }
-out:
- if (profile_lab != NULL)
- cmsCloseProfile (profile_lab);
- if (transform != NULL)
- cmsDeleteTransform (transform);
- return warning;
-}
-
-/**
- * cd_profile_get_warnings:
- **/
-static GArray *
-cd_profile_get_warnings (cmsHPROFILE profile)
-{
- GArray *flags;
- gboolean ret;
- gchar ascii_name[1024];
- CdProfileWarning warning;
-
- flags = g_array_new (FALSE, FALSE, sizeof (CdProfileWarning));
-
- /* check that the profile has a description and a copyright */
- ret = cmsGetProfileInfoASCII (profile, cmsInfoDescription, "en", "US", ascii_name, 1024);
- if (!ret || ascii_name[0] == '\0') {
- warning = CD_PROFILE_WARNING_DESCRIPTION_MISSING;
- g_array_append_val (flags, warning);
- }
- ret = cmsGetProfileInfoASCII (profile, cmsInfoCopyright, "en", "US", ascii_name, 1024);
- if (!ret || ascii_name[0] == '\0') {
- warning = CD_PROFILE_WARNING_COPYRIGHT_MISSING;
- g_array_append_val (flags, warning);
- }
-
- /* not a RGB space */
- if (cmsGetColorSpace (profile) != cmsSigRgbData)
- goto out;
-
- /* does profile have monotonic VCGT */
- warning = cd_profile_check_vcgt (profile);
- if (warning != CD_PROFILE_WARNING_NONE)
- g_array_append_val (flags, warning);
-
- /* if Lab 100,0,0 does not map to RGB 255,255,255 for relative
- * colorimetric then white it will not work on printers */
- warning = cd_profile_check_scum_dot (profile);
- if (warning != CD_PROFILE_WARNING_NONE)
- g_array_append_val (flags, warning);
-
- /* gray should give low a/b and should be monotonic */
- warning = cd_profile_check_gray_axis (profile);
- if (warning != CD_PROFILE_WARNING_NONE)
- g_array_append_val (flags, warning);
-
- /* tristimulus values cannot be negative */
- warning = cd_profile_check_primaries (profile);
- if (warning != CD_PROFILE_WARNING_NONE)
- g_array_append_val (flags, warning);
-
- /* check whitepoint works out to D50 */
- warning = cd_profile_check_d50_whitepoint (profile);
- if (warning != CD_PROFILE_WARNING_NONE)
- g_array_append_val (flags, warning);
-out:
- return flags;
-}
-
-/**
* cd_profile_set_from_profile:
**/
static gboolean
@@ -1301,7 +944,7 @@ cd_profile_set_from_profile (CdProfile *profile,
priv->checksum = g_strdup (cd_icc_get_checksum (icc));
/* get any warnings for the profile */
- flags = cd_profile_get_warnings (lcms_profile);
+ flags = cd_icc_get_warnings (icc);
priv->warnings = g_new0 (gchar *, flags->len + 1);
if (flags->len > 0) {
for (i = 0; i < flags->len; i++) {