diff options
author | Richard Hughes <richard@hughsie.com> | 2013-04-24 16:26:25 +0100 |
---|---|---|
committer | Richard Hughes <richard@hughsie.com> | 2013-04-24 16:26:25 +0100 |
commit | c9607e452074d67a8b2ffede317b469609411c34 (patch) | |
tree | 45e6bef256c554e5bef385a26b38bb0dd3816667 | |
parent | d3c84958d237fd335832e40e0e04bc6c5d3f524f (diff) | |
download | colord-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.c | 372 | ||||
-rw-r--r-- | lib/colord/cd-icc.h | 1 | ||||
-rw-r--r-- | lib/colord/cd-self-test.c | 6 | ||||
-rw-r--r-- | src/cd-profile.c | 359 |
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++) { |