Backport lcms 2.x support from master, making it optional.

In order to retain support for lcms 1.x, this merges the lcms2-specific
code as a configurable alternative.

The user can specify which version to use by specifying
"--with-lcms=lcms1" or "--with-lcms=lcms2" when running configure. If no
version is specified explicitly, version 1.x will be preferred if both
versions are available. This ensures that GIMP is built with the same
lcms version as an older version, if the same configure switches are
used and the same libraries are available.

This builds on the following commits from the master branch:

    commit c59ab4d817
    Author:     Massimo Valentini <mvalentini@src.gnome.org>
    AuthorDate: Tue Sep 4 17:53:06 2012 +0200

        lcms: oversight

    commit 8bbfc9e5cf
    Author:     Michael Natterer <mitch@gimp.org>
    AuthorDate: Mon Sep 3 20:03:53 2012 +0200

        Bug 675558 - switch from lcms-1 to lcms-2

        Applied modified patch from Hartmut Kuhse which ports to lcms-2.
This commit is contained in:
Nils Philippsen 2013-09-17 16:43:11 +02:00
parent c9c927603b
commit b2c6bd7614
6 changed files with 360 additions and 20 deletions

View file

@ -61,7 +61,8 @@ m4_define([libcurl_required_version], [7.15.1])
m4_define([dbus_glib_required_version], [0.70])
m4_define([libgudev_required_version], [167])
m4_define([exif_required_version], [0.6.15])
m4_define([lcms_required_version], [1.16])
m4_define([lcms1_required_version], [1.16])
m4_define([lcms2_required_version], [2.2])
m4_define([libpng_required_version], [1.2.37])
@ -1539,19 +1540,51 @@ AC_SUBST(JP2_LIBS)
# Check for lcms
################
AC_ARG_WITH(lcms, [ --without-lcms build without lcms support])
AC_ARG_WITH(lcms, [ --with-lcms build with lcms support (check, lcms1, lcms2)],
[],
[with_lcms=check])
have_lcms="no (lcms support disabled)"
if test "x$with_lcms" != xno; then
have_lcms=yes
PKG_CHECK_MODULES(LCMS, lcms >= lcms_required_version,
AC_DEFINE(HAVE_LCMS, 1, [Define to 1 if lcms is available])
LCMS='lcms$(EXEEXT)',
have_lcms="no (lcms not found or unusable)")
if test "x$with_lcms" == x1 || \
test "x$with_lcms" == xlcms1 || \
test "x$with_lcms" == xcheck; then
PKG_CHECK_MODULES(LCMS1, lcms >= lcms1_required_version,
[have_lcms="yes (lcms1)"
AC_DEFINE(HAVE_LCMS, 1, [Define to 1 if lcms is available])
AC_DEFINE(HAVE_LCMS1, 1, [Define to 1 if lcms1 is available])
LCMS_CFLAGS="$LCMS1_CFLAGS"
LCMS_LIBS="$LCMS1_LIBS"
LCMS='lcms$(EXEEXT)'],
[have_lcms="no (lcms1 not found)"])
fi
if test "x$have_lcms" != "xyes (lcms1)"; then
if test "x$with_lcms" == x2 || \
test "x$with_lcms" == xlcms2 || \
test "x$with_lcms" == xcheck; then
PKG_CHECK_MODULES(LCMS2, lcms2 >= lcms2_required_version,
[have_lcms="yes (lcms2)"
AC_DEFINE(HAVE_LCMS, 1, [Define to 1 if lcms is available])
AC_DEFINE(HAVE_LCMS2, 1, [Define to 1 if lcms2 is available])
LCMS_CFLAGS="$LCMS2_CFLAGS"
LCMS_LIBS="$LCMS2_LIBS"
LCMS='lcms$(EXEEXT)'],
[if test "x$with_lcms" == xcheck; then
have_lcms="no (lcms not found)"
else
have_lcms="no (lcms2 not found)"
fi])
fi
fi
fi
AC_SUBST(LCMS_CFLAGS)
AC_SUBST(LCMS_LIBS)
AC_SUBST(LCMS)
AM_CONDITIONAL(HAVE_LCMS, test "x$have_lcms" = xyes)
AM_CONDITIONAL(HAVE_LCMS,
[test "x$have_lcms" = "xyes (lcms1)" || \
test "x$have_lcms" == "xyes (lcms2)"])
######################

View file

@ -19,7 +19,12 @@
#include <glib.h> /* lcms.h uses the "inline" keyword */
#ifdef HAVE_LCMS1
#include <lcms.h>
typedef DWORD cmsUInt32Number;
#else
#include <lcms2.h>
#endif
#include <gtk/gtk.h>
@ -152,7 +157,9 @@ colorsel_cmyk_class_init (ColorselCmykClass *klass)
selector_class->set_color = colorsel_cmyk_set_color;
selector_class->set_config = colorsel_cmyk_set_config;
#ifdef HAVE_LCMS1
cmsErrorAction (LCMS_ERROR_IGNORE);
#endif
}
static void
@ -391,10 +398,16 @@ colorsel_cmyk_config_changed (ColorselCmyk *module)
{
GimpColorSelector *selector = GIMP_COLOR_SELECTOR (module);
GimpColorConfig *config = module->config;
DWORD flags = 0;
cmsUInt32Number flags = 0;
#ifdef HAVE_LCMS2
cmsUInt32Number descSize = 0;
#endif
cmsHPROFILE rgb_profile;
cmsHPROFILE cmyk_profile;
const gchar *name;
#ifdef HAVE_LCMS2
gchar *descData;
#endif
const gchar *name = NULL;
gchar *text;
if (module->rgb2cmyk)
@ -419,13 +432,55 @@ colorsel_cmyk_config_changed (ColorselCmyk *module)
! (cmyk_profile = cmsOpenProfileFromFile (config->cmyk_profile, "r")))
goto out;
#ifdef HAVE_LCMS1
name = cmsTakeProductDesc (cmyk_profile);
#else
descSize = cmsGetProfileInfoASCII (cmyk_profile, cmsInfoDescription,
"en", "US", NULL, 0);
if (descSize > 0)
{
descData = g_new (gchar, descSize + 1);
descSize = cmsGetProfileInfoASCII (cmyk_profile, cmsInfoDescription,
"en", "US", descData, descSize);
if (descSize > 0)
{
name = descData;
}
else
{
g_free (descData);
descData = NULL;
}
}
#endif
if (name && ! g_utf8_validate (name, -1, NULL))
name = _("(invalid UTF-8 string)");
if (! name)
{
#ifdef HAVE_LCMS1
name = cmsTakeProductName (cmyk_profile);
#else
descSize = cmsGetProfileInfoASCII (cmyk_profile, cmsInfoModel,
"en", "US", NULL, 0);
if (descSize > 0)
{
descData = g_new (gchar, descSize + 1);
descSize = cmsGetProfileInfoASCII (cmyk_profile, cmsInfoModel,
"en", "US", descData, descSize);
if (descSize > 0)
{
name = descData;
}
else
{
g_free (descData);
descData = NULL;
}
}
#endif
if (name && ! g_utf8_validate (name, -1, NULL))
name = _("(invalid UTF-8 string)");
}
@ -435,6 +490,11 @@ colorsel_cmyk_config_changed (ColorselCmyk *module)
gimp_help_set_help_data (module->name_label, text, NULL);
g_free (text);
#ifdef HAVE_LCMS2
if (descData)
g_free (descData);
#endif
rgb_profile = color_config_get_rgb_profile (config);
if (config->display_intent ==

View file

@ -27,7 +27,12 @@
#define LCMS_WIN_TYPES_ALREADY_DEFINED
#endif
#ifdef HAVE_LCMS1
#include <lcms.h>
typedef DWORD cmsUInt32Number;
#else
#include <lcms2.h>
#endif
#include <gtk/gtk.h>
@ -136,7 +141,9 @@ cdisplay_lcms_class_init (CdisplayLcmsClass *klass)
display_class->convert_surface = cdisplay_lcms_convert_surface;
display_class->changed = cdisplay_lcms_changed;
#ifdef HAVE_LCMS1
cmsErrorAction (LCMS_ERROR_IGNORE);
#endif
}
static void
@ -164,28 +171,101 @@ cdisplay_lcms_finalize (GObject *object)
G_OBJECT_CLASS (cdisplay_lcms_parent_class)->finalize (object);
}
#ifdef HAVE_LCMS1
static void
cdisplay_lcms_profile_get_info (cmsHPROFILE profile,
const gchar **name,
const gchar **info)
#else
static void
cdisplay_lcms_profile_get_info (cmsHPROFILE profile,
gchar **name,
gchar **info)
#endif
{
if (profile)
{
#ifdef HAVE_LCMS1
*name = cmsTakeProductDesc (profile);
#else
cmsUInt32Number descSize;
gchar *descData;
descSize = cmsGetProfileInfoASCII (profile, cmsInfoDescription,
"en", "US", NULL, 0);
if (descSize > 0)
{
descData = g_new (gchar, descSize + 1);
descSize = cmsGetProfileInfoASCII (profile, cmsInfoDescription,
"en", "US", descData, descSize);
if (descSize > 0)
*name = descData;
else
g_free (descData);
}
#endif
if (! *name)
#ifdef HAVE_LCMS1
*name = cmsTakeProductName (profile);
#else
{
descSize = cmsGetProfileInfoASCII (profile, cmsInfoModel,
"en", "US", NULL, 0);
if (descSize > 0)
{
descData = g_new (gchar, descSize + 1);
descSize = cmsGetProfileInfoASCII(profile, cmsInfoModel,
"en", "US", descData, descSize);
if (descSize > 0)
*name = descData;
else
g_free (descData);
}
#endif
}
#ifdef HAVE_LCMS1
if (*name && ! g_utf8_validate (*name, -1, NULL))
*name = _("(invalid UTF-8 string)");
*info = cmsTakeProductInfo (profile);
if (*name && ! g_utf8_validate (*info, -1, NULL))
*info = NULL;
#else
if (*name && ! g_utf8_validate (*name, -1, NULL))
{
g_free (*name);
*name = g_strdup (_("(invalid UTF-8 string)"));
}
descSize = cmsGetProfileInfoASCII (profile, cmsInfoManufacturer,
"en", "US", NULL, 0);
if (descSize > 0)
{
descData = g_new (gchar, descSize + 1);
descSize = cmsGetProfileInfoASCII (profile, cmsInfoManufacturer,
"en", "US", descData, descSize);
if (descSize > 0)
*info = descData;
else
g_free (descData);
}
if (*info && ! g_utf8_validate (*info, -1, NULL))
{
g_free (*info);
*info = NULL;
}
#endif
}
else
{
#ifdef HAVE_LCMS1
*name = _("None");
#else
*name = g_strdup (_("None"));
#endif
*info = NULL;
}
}
@ -315,7 +395,10 @@ cdisplay_lcms_changed (GimpColorDisplay *display)
cmsHPROFILE src_profile = NULL;
cmsHPROFILE dest_profile = NULL;
cmsHPROFILE proof_profile = NULL;
DWORD flags = 0;
cmsUInt32Number flags = 0;
#ifdef HAVE_LCMS2
cmsUInt16Number alarmCodes[cmsMAXCHANNELS] = { 0 };
#endif
if (lcms->transform)
{
@ -365,7 +448,15 @@ cdisplay_lcms_changed (GimpColorDisplay *display)
gimp_rgb_get_uchar (&config->out_of_gamut_color, &r, &g, &b);
#ifdef HAVE_LCMS1
cmsSetAlarmCodes (r, g, b);
#else
alarmCodes[0] = (cmsUInt16Number) r;
alarmCodes[1] = (cmsUInt16Number) g;
alarmCodes[2] = (cmsUInt16Number) b;
cmsSetAlarmCodes (alarmCodes);
#endif
}
lcms->transform = cmsCreateProofingTransform (src_profile, TYPE_ARGB_8,
@ -400,7 +491,11 @@ cdisplay_lcms_changed (GimpColorDisplay *display)
static gboolean
cdisplay_lcms_profile_is_rgb (cmsHPROFILE profile)
{
#ifdef HAVE_LCMS1
return (cmsGetColorSpace (profile) == icSigRgbData);
#else
return (cmsGetColorSpace (profile) == cmsSigRgbData);
#endif
}
static cmsHPROFILE
@ -621,8 +716,13 @@ cdisplay_lcms_update_profile_label (CdisplayLcms *lcms,
{
GtkWidget *label;
cmsHPROFILE profile = NULL;
#ifdef HAVE_LCMS1
const gchar *text;
const gchar *tooltip;
#else
gchar *text = NULL;
gchar *tooltip = NULL;
#endif
label = g_object_get_data (G_OBJECT (lcms), name);
@ -651,6 +751,11 @@ cdisplay_lcms_update_profile_label (CdisplayLcms *lcms,
gtk_label_set_text (GTK_LABEL (label), text);
gimp_help_set_help_data (label, tooltip, NULL);
#ifdef HAVE_LCMS2
g_free (text);
g_free (tooltip);
#endif
if (profile)
cmsCloseProfile (profile);
}

View file

@ -19,7 +19,12 @@
#include <glib.h> /* lcms.h uses the "inline" keyword */
#ifdef HAVE_LCMS1
#include <lcms.h>
typedef DWORD cmsUInt32Number;
#else
#include <lcms2.h>
#endif
#include <gtk/gtk.h>
@ -146,7 +151,9 @@ cdisplay_proof_class_init (CdisplayProofClass *klass)
display_class->configure = cdisplay_proof_configure;
display_class->changed = cdisplay_proof_changed;
#ifdef HAVE_LCMS1
cmsErrorAction (LCMS_ERROR_IGNORE);
#endif
}
static void
@ -298,9 +305,45 @@ cdisplay_proof_combo_box_set_active (GimpColorProfileComboBox *combo,
if (profile)
{
#ifdef HAVE_LCMS1
label = gimp_any_to_utf8 (cmsTakeProductDesc (profile), -1, NULL);
#else
cmsUInt32Number descSize;
gchar *descData;
descSize = cmsGetProfileInfoASCII(profile, cmsInfoDescription,
"en", "US", NULL, 0);
if (descSize > 0)
{
descData = g_new (gchar, descSize + 1);
descSize = cmsGetProfileInfoASCII (profile, cmsInfoDescription,
"en", "US", descData, descSize);
if (descSize > 0)
label = gimp_any_to_utf8 (descData, -1, NULL);
g_free (descData);
}
#endif
if (! label)
#ifdef HAVE_LCMS1
label = gimp_any_to_utf8 (cmsTakeProductName (profile), -1, NULL);
#else
{
descSize = cmsGetProfileInfoASCII (profile, cmsInfoModel,
"en", "US", NULL, 0);
if (descSize > 0)
{
descData = g_new (gchar, descSize + 1);
descSize = cmsGetProfileInfoASCII (profile, cmsInfoModel,
"en", "US", descData, descSize);
if (descSize > 0)
label = gimp_any_to_utf8 (descData, -1, NULL);
g_free (descData);
}
#endif
}
cmsCloseProfile (profile);
}
@ -465,7 +508,7 @@ cdisplay_proof_changed (GimpColorDisplay *display)
if (proofProfile)
{
DWORD flags = cmsFLAGS_SOFTPROOFING;
cmsUInt32Number flags = cmsFLAGS_SOFTPROOFING;
if (proof->bpc)
flags |= cmsFLAGS_BLACKPOINTCOMPENSATION;

View file

@ -24,7 +24,12 @@
#include <glib.h> /* lcms.h uses the "inline" keyword */
#ifdef HAVE_LCMS1
#include <lcms.h>
typedef DWORD cmsUInt32Number;
#else
#include <lcms2.h>
#endif
#include <libgimp/gimp.h>
#include <libgimp/gimpui.h>
@ -428,7 +433,9 @@ run (const gchar *name,
}
}
#ifdef HAVE_LCMS1
cmsErrorAction (LCMS_ERROR_SHOW);
#endif
switch (proc)
{
@ -459,7 +466,9 @@ run (const gchar *name,
gchar *desc = NULL;
gchar *info = NULL;
#ifdef HAVE_LCMS1
cmsErrorAction (LCMS_ERROR_IGNORE);
#endif
if (proc == PROC_INFO)
status = lcms_icc_info (config, image, &name, &desc, &info);
@ -496,25 +505,92 @@ run (const gchar *name,
static gchar *
lcms_icc_profile_get_name (cmsHPROFILE profile)
{
#ifdef HAVE_LCMS1
return gimp_any_to_utf8 (cmsTakeProductName (profile), -1, NULL);
#else
cmsUInt32Number descSize;
gchar *descData;
gchar *name = NULL;
descSize = cmsGetProfileInfoASCII (profile, cmsInfoModel,
"en", "US", NULL, 0);
if (descSize > 0)
{
descData = g_new (gchar, descSize + 1);
descSize = cmsGetProfileInfoASCII (profile, cmsInfoModel,
"en", "US", descData, descSize);
if (descSize > 0)
name = gimp_any_to_utf8 (descData, -1, NULL);
g_free (descData);
}
return name;
#endif
}
static gchar *
lcms_icc_profile_get_desc (cmsHPROFILE profile)
{
#ifdef HAVE_LCMS1
return gimp_any_to_utf8 (cmsTakeProductDesc (profile), -1, NULL);
#else
cmsUInt32Number descSize;
gchar *descData;
gchar *desc = NULL;
descSize = cmsGetProfileInfoASCII (profile, cmsInfoDescription,
"en", "US", NULL, 0);
if (descSize > 0)
{
descData = g_new (gchar, descSize + 1);
descSize = cmsGetProfileInfoASCII (profile, cmsInfoDescription,
"en", "US", descData, descSize);
if (descSize > 0)
desc = gimp_any_to_utf8 (descData, -1, NULL);
g_free (descData);
}
return desc;
#endif
}
static gchar *
lcms_icc_profile_get_info (cmsHPROFILE profile)
{
#ifdef HAVE_LCMS1
return gimp_any_to_utf8 (cmsTakeProductInfo (profile), -1, NULL);
#else
cmsUInt32Number descSize;
gchar *descData;
gchar *info = NULL;
descSize = cmsGetProfileInfoASCII (profile, cmsInfoModel,
"en", "US", NULL, 0);
if (descSize > 0)
{
descData = g_new (gchar, descSize + 1);
descSize = cmsGetProfileInfoASCII (profile, cmsInfoModel,
"en", "US", descData, descSize);
if (descSize > 0)
info = gimp_any_to_utf8 (descData, -1, NULL);
g_free (descData);
}
return info;
#endif
}
static gboolean
lcms_icc_profile_is_rgb (cmsHPROFILE profile)
{
#ifdef HAVE_LCMS1
return (cmsGetColorSpace (profile) == icSigRgbData);
#else
return (cmsGetColorSpace (profile) == cmsSigRgbData);
#endif
}
static GimpPDBStatusType
@ -737,9 +813,15 @@ lcms_calculate_checksum (const gchar *data,
{
GChecksum *md5 = g_checksum_new (G_CHECKSUM_MD5);
#ifdef HAVE_LCMS1
g_checksum_update (md5,
(const guchar *) data + sizeof (icHeader),
len - sizeof (icHeader));
#else
g_checksum_update (md5,
(const guchar *) data + sizeof (cmsICCHeader),
len - sizeof (cmsICCHeader));
#endif
len = 16;
g_checksum_get_digest (md5, digest, &len);
@ -934,18 +1016,18 @@ lcms_image_transform_rgb (gint32 image,
GimpColorRenderingIntent intent,
gboolean bpc)
{
cmsHTRANSFORM transform = NULL;
DWORD last_format = 0;
gint *layers;
gint num_layers;
gint i;
cmsHTRANSFORM transform = NULL;
cmsUInt32Number last_format = 0;
gint *layers;
gint num_layers;
gint i;
layers = gimp_image_get_layers (image, &num_layers);
for (i = 0; i < num_layers; i++)
{
GimpDrawable *drawable = gimp_drawable_get (layers[i]);
DWORD format;
GimpDrawable *drawable = gimp_drawable_get (layers[i]);
cmsUInt32Number format;
switch (drawable->bpp)
{

View file

@ -31,7 +31,12 @@
#endif /* HAVE_LIBEXIF */
#ifdef HAVE_LCMS
#ifdef HAVE_LCMS1
#include <lcms.h>
typedef DWORD cmsUInt32Number;
#else
#include <lcms2.h>
#endif
#endif
#include <libgimp/gimp.h>
@ -966,7 +971,7 @@ jpeg_load_cmyk_transform (guint8 *profile_data,
GimpColorConfig *config = gimp_get_color_configuration ();
cmsHPROFILE cmyk_profile = NULL;
cmsHPROFILE rgb_profile = NULL;
DWORD flags = 0;
cmsUInt32Number flags = 0;
cmsHTRANSFORM transform;
/* try to load the embedded CMYK profile */
@ -976,7 +981,11 @@ jpeg_load_cmyk_transform (guint8 *profile_data,
if (cmyk_profile)
{
#ifdef HAVE_LCMS1
if (! cmsGetColorSpace (cmyk_profile) == icSigCmykData)
#else
if (! cmsGetColorSpace (cmyk_profile) == cmsSigCmykData)
#endif
{
cmsCloseProfile (cmyk_profile);
cmyk_profile = NULL;
@ -989,7 +998,11 @@ jpeg_load_cmyk_transform (guint8 *profile_data,
{
cmyk_profile = cmsOpenProfileFromFile (config->cmyk_profile, "r");
#ifdef HAVE_LCMS1
if (cmyk_profile && ! cmsGetColorSpace (cmyk_profile) == icSigCmykData)
#else
if (cmyk_profile && ! cmsGetColorSpace (cmyk_profile) == cmsSigCmykData)
#endif
{
cmsCloseProfile (cmyk_profile);
cmyk_profile = NULL;
@ -1008,7 +1021,11 @@ jpeg_load_cmyk_transform (guint8 *profile_data,
{
rgb_profile = cmsOpenProfileFromFile (config->rgb_profile, "r");
#ifdef HAVE_LCMS1
if (rgb_profile && ! cmsGetColorSpace (rgb_profile) == icSigRgbData)
#else
if (rgb_profile && ! cmsGetColorSpace (rgb_profile) == cmsSigRgbData)
#endif
{
cmsCloseProfile (rgb_profile);
rgb_profile = NULL;