summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRichard Hughes <richard@hughsie.com>2014-02-13 18:09:26 +0000
committerRichard Hughes <richard@hughsie.com>2014-02-13 20:25:49 +0000
commitb880d80bb30fc0b28c466e7b10ee68eb011f5454 (patch)
tree141a6436cd1d4868ff1f5d985189930f0700d9a3
parenta6e73ca13dcd25fdb4c7bbef6f321b3dae3d2a5b (diff)
downloadcolord-b880d80bb30fc0b28c466e7b10ee68eb011f5454.tar.gz
Use the new cmsContext functionality in LCMS 2.6
-rw-r--r--client/cd-create-profile.c80
-rw-r--r--configure.ac4
-rw-r--r--lib/colord/Makefile.am2
-rw-r--r--lib/colord/cd-context-lcms.c239
-rw-r--r--lib/colord/cd-context-lcms.h45
-rw-r--r--lib/colord/cd-icc-utils.c4
-rw-r--r--lib/colord/cd-icc.c248
-rw-r--r--lib/colord/cd-icc.h1
-rw-r--r--lib/colord/cd-it8.c43
-rw-r--r--lib/colord/cd-transform.c36
10 files changed, 459 insertions, 243 deletions
diff --git a/client/cd-create-profile.c b/client/cd-create-profile.c
index 3a4235b..60587ce 100644
--- a/client/cd-create-profile.c
+++ b/client/cd-create-profile.c
@@ -25,33 +25,18 @@
#include <gio/gio.h>
#include <locale.h>
#include <lcms2.h>
-#include <lcms2_plugin.h>
#include <stdlib.h>
#include <math.h>
#include <colord-private.h>
+#define LCMS_CURVE_PLUGIN_TYPE_REC709 1024
+
typedef struct {
GOptionContext *context;
cmsHPROFILE lcms_profile;
CdIcc *icc;
} CdUtilPrivate;
-static gint lcms_error_code = 0;
-
-/**
- * cd_fix_profile_error_cb:
- **/
-static void
-cd_fix_profile_error_cb (cmsContext ContextID,
- cmsUInt32Number errorcode,
- const char *text)
-{
- g_warning ("LCMS error %i: %s", errorcode, text);
-
- /* copy this sytemwide */
- lcms_error_code = errorcode;
-}
-
static gboolean
set_vcgt_from_data (cmsHPROFILE profile,
const guint16 *red,
@@ -267,7 +252,8 @@ cd_util_create_colprof (CdUtilPrivate *priv,
goto out;
/* open /tmp/$basename.icc as hProfile */
- priv->lcms_profile = cmsOpenProfileFromMemTHR (priv->icc, data, len);
+ priv->lcms_profile = cmsOpenProfileFromMemTHR (cd_icc_get_context (priv->icc),
+ data, len);
if (priv->lcms_profile == NULL) {
ret = FALSE;
g_set_error (error, 1, 0,
@@ -317,8 +303,8 @@ cd_util_create_named_color (CdUtilPrivate *priv,
const GNode *tmp;
gboolean ret = TRUE;
- priv->lcms_profile = cmsCreateNULLProfileTHR (priv->icc);
- if (priv->lcms_profile == NULL || lcms_error_code != 0) {
+ priv->lcms_profile = cmsCreateNULLProfileTHR (cd_icc_get_context (priv->icc));
+ if (priv->lcms_profile == NULL) {
ret = FALSE;
g_set_error_literal (error, 1, 0,
"failed to create NULL profile");
@@ -408,8 +394,8 @@ cd_util_create_x11_gamma (CdUtilPrivate *priv,
points[2] = rgb.B;
/* create a bog-standard sRGB profile */
- priv->lcms_profile = cmsCreate_sRGBProfileTHR (priv->icc);
- if (priv->lcms_profile == NULL || lcms_error_code != 0) {
+ priv->lcms_profile = cmsCreate_sRGBProfileTHR (cd_icc_get_context (priv->icc));
+ if (priv->lcms_profile == NULL) {
ret = FALSE;
g_set_error_literal (error, 1, 0,
"failed to create profile");
@@ -470,45 +456,6 @@ cd_util_build_lstar_gamma (void)
return cmsBuildParametricToneCurve (NULL, 4, params);
}
-#define LCMS_CURVE_PLUGIN_TYPE_REC709 1024
-
-/**
- * cd_util_lcms_rec709_trc_cb:
- **/
-static double
-cd_util_lcms_rec709_trc_cb (int type, const double params[], double x)
-{
- gdouble val = 0.f;
-
- switch (type) {
- case -LCMS_CURVE_PLUGIN_TYPE_REC709:
- if (x < params[4])
- val = x * params[3];
- else
- val = params[1] * pow (x, (1.f / params[0])) + params[2];
- break;
- case LCMS_CURVE_PLUGIN_TYPE_REC709:
- if (x <= (params[3] * params[4]))
- val = x / params[3];
- else
- val = pow (((x + params[2]) / params[1]), params[0]);
- break;
- }
- return val;
-}
-
-/* add Rec. 709 TRC curve type */
-cmsPluginParametricCurves cd_util_lcms_rec709_trc = {
- { cmsPluginMagicNumber, /* 'acpp' */
- 2000, /* minimum version */
- cmsPluginParametricCurveSig, /* type */
- NULL }, /* no more plugins */
- 1, /* number functions */
- {LCMS_CURVE_PLUGIN_TYPE_REC709}, /* function types */
- {5}, /* parameter count */
- cd_util_lcms_rec709_trc_cb /* evaluator */
-};
-
/**
* cd_util_build_rec709_gamma:
**/
@@ -652,7 +599,7 @@ cd_util_create_standard_space (CdUtilPrivate *priv,
primaries.Blue.Y = yxy.Y;
/* create profile */
- priv->lcms_profile = cmsCreateRGBProfileTHR (priv->icc,
+ priv->lcms_profile = cmsCreateRGBProfileTHR (cd_icc_get_context (priv->icc),
&white,
&primaries,
transfer);
@@ -681,8 +628,8 @@ cd_util_create_temperature (CdUtilPrivate *priv,
guint temp;
/* create a bog-standard sRGB profile */
- priv->lcms_profile = cmsCreate_sRGBProfileTHR (priv->icc);
- if (priv->lcms_profile == NULL || lcms_error_code != 0) {
+ priv->lcms_profile = cmsCreate_sRGBProfileTHR (cd_icc_get_context (priv->icc));
+ if (priv->lcms_profile == NULL) {
ret = FALSE;
g_set_error_literal (error, 1, 0,
"failed to create profile");
@@ -929,11 +876,6 @@ main (int argc, char **argv)
bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8");
textdomain (GETTEXT_PACKAGE);
- /* setup LCMS */
- cmsSetLogErrorHandler (cd_fix_profile_error_cb);
- ret = cmsPlugin (&cd_util_lcms_rec709_trc);
- g_assert (ret);
-
priv = g_new0 (CdUtilPrivate, 1);
priv->icc = cd_icc_new ();
priv->context = g_option_context_new (NULL);
diff --git a/configure.ac b/configure.ac
index 73eb467..296e98c 100644
--- a/configure.ac
+++ b/configure.ac
@@ -158,6 +158,10 @@ AC_CHECK_LIB(lcms2, cmsMLUtranslationsCount, have_lcms_mlu_translations_count=ye
if test x$have_lcms_mlu_translations_count != x; then
AC_DEFINE(HAVE_LCMS_MLU_TRANSLATIONS_COUNT,1,[cmsMLUtranslationsCount is available])
fi
+AC_CHECK_LIB(lcms2, cmsCreateContext, have_lcms_create_context=yes)
+if test x$have_lcms_create_context != x; then
+ AC_DEFINE(HAVE_LCMS_CREATE_CONTEXT,1,[cmsCreateContext is available])
+fi
PKG_CHECK_MODULES(SQLITE, sqlite3)
diff --git a/lib/colord/Makefile.am b/lib/colord/Makefile.am
index 7ac18b5..33817e7 100644
--- a/lib/colord/Makefile.am
+++ b/lib/colord/Makefile.am
@@ -56,6 +56,8 @@ libcolordbase_include_HEADERS = \
cd-version.h
libcolordprivate_la_SOURCES = \
+ cd-context-lcms.c \
+ cd-context-lcms.h \
cd-buffer.c \
cd-color.c \
cd-dom.c \
diff --git a/lib/colord/cd-context-lcms.c b/lib/colord/cd-context-lcms.c
new file mode 100644
index 0000000..85d5574
--- /dev/null
+++ b/lib/colord/cd-context-lcms.c
@@ -0,0 +1,239 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
+ *
+ * Copyright (C) 2014 Richard Hughes <richard@hughsie.com>
+ *
+ * Licensed under the GNU Lesser General Public License Version 2.1
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+
+/**
+ * SECTION:cd-context-lcms
+ * @short_description: Functionality to save per-thread context data for LCMS2
+ */
+
+#include "config.h"
+
+#include <lcms2.h>
+#include <lcms2_plugin.h>
+
+#include "cd-context-lcms.h"
+#include "cd-icc.h" /* for the error codes */
+
+/*< private >*/
+#define LCMS_CURVE_PLUGIN_TYPE_REC709 1024
+
+/**
+ * cd_context_lcms_get_error:
+ **/
+static GError **
+cd_context_lcms_get_error (gpointer ctx)
+{
+ GError **error_ctx;
+#ifdef HAVE_LCMS_CREATE_CONTEXT
+ error_ctx = cmsGetContextUserData (ctx);
+#else
+ error_ctx = (GError **) ctx;
+#endif
+ return error_ctx;
+}
+
+/**
+ * cd_context_lcms2_error_cb:
+ **/
+static void
+cd_context_lcms2_error_cb (cmsContext context_id,
+ cmsUInt32Number code,
+ const gchar *message)
+{
+ gint error_code;
+ GError **error_ctx;
+
+ /* nothing set, must be pre-2.6 */
+ if (context_id == NULL) {
+ g_warning ("Error handler called with no context: %s", message);
+ return;
+ }
+
+ /* there's already one error pending */
+ error_ctx = cd_context_lcms_get_error (context_id);
+ if (*error_ctx != NULL) {
+ g_prefix_error (error_ctx, "%s & ", message);
+ return;
+ }
+
+ /* convert the first cmsERROR in into a CdIccError */
+ switch (code) {
+ case cmsERROR_CORRUPTION_DETECTED:
+ error_code = CD_ICC_ERROR_CORRUPTION_DETECTED;
+ break;
+ case cmsERROR_FILE:
+ case cmsERROR_READ:
+ case cmsERROR_SEEK:
+ error_code = CD_ICC_ERROR_FAILED_TO_OPEN;
+ break;
+ case cmsERROR_WRITE:
+ error_code = CD_ICC_ERROR_FAILED_TO_SAVE;
+ break;
+ case cmsERROR_COLORSPACE_CHECK:
+ error_code = CD_ICC_ERROR_INVALID_COLORSPACE;
+ break;
+ case cmsERROR_BAD_SIGNATURE:
+ error_code = CD_ICC_ERROR_FAILED_TO_PARSE;
+ break;
+ case cmsERROR_ALREADY_DEFINED:
+ case cmsERROR_INTERNAL:
+ case cmsERROR_NOT_SUITABLE:
+ case cmsERROR_NULL:
+ case cmsERROR_RANGE:
+ case cmsERROR_UNDEFINED:
+ case cmsERROR_UNKNOWN_EXTENSION:
+ error_code = CD_ICC_ERROR_INTERNAL;
+ break;
+ default:
+ g_warning ("LCMS2 error code not recognised; please report");
+ error_code = CD_ICC_ERROR_INTERNAL;
+ }
+ error_ctx = cd_context_lcms_get_error (context_id);
+ g_set_error_literal (error_ctx, CD_ICC_ERROR, error_code, message);
+}
+
+/**
+ * cd_context_lcms_plugins_cb:
+ **/
+static double
+cd_context_lcms_plugins_cb (int type, const double params[], double x)
+{
+ gdouble val = 0.f;
+
+ switch (type) {
+ case -LCMS_CURVE_PLUGIN_TYPE_REC709:
+ if (x < params[4])
+ val = x * params[3];
+ else
+ val = params[1] * pow (x, (1.f / params[0])) + params[2];
+ break;
+ case LCMS_CURVE_PLUGIN_TYPE_REC709:
+ if (x <= (params[3] * params[4]))
+ val = x / params[3];
+ else
+ val = pow (((x + params[2]) / params[1]), params[0]);
+ break;
+ }
+ return val;
+}
+
+cmsPluginParametricCurves cd_icc_lcms_plugins = {
+ { cmsPluginMagicNumber, /* 'acpp' */
+ 2000, /* minimum version */
+ cmsPluginParametricCurveSig, /* type */
+ NULL }, /* no more plugins */
+ 1, /* number functions */
+ {LCMS_CURVE_PLUGIN_TYPE_REC709}, /* function types */
+ {5}, /* parameter count */
+ cd_context_lcms_plugins_cb /* evaluator */
+};
+
+/**
+ * cd_context_lcms_new:
+ *
+ * Return value: (transfer full): A new LCMS context
+ **/
+gpointer
+cd_context_lcms_new (void)
+{
+ cmsContext ctx;
+ GError **error_ctx;
+ error_ctx = g_new0 (GError *, 1);
+#ifdef HAVE_LCMS_CREATE_CONTEXT
+ ctx = cmsCreateContext (NULL, error_ctx);
+ cmsSetLogErrorHandlerTHR (ctx, cd_context_lcms2_error_cb);
+ cmsPluginTHR (ctx, &cd_icc_lcms_plugins);
+#else
+ ctx = (cmsContext) error_ctx;
+ cmsSetLogErrorHandler (cd_context_lcms2_error_cb);
+ /* we've disabled this as it's unreliable without a context */
+ if(0) cmsPlugin (&cd_icc_lcms_plugins);
+#endif
+ return ctx;
+}
+
+/**
+ * _cd_context_lcms_pre26_start:
+ **/
+void
+_cd_context_lcms_pre26_start (void)
+{
+#ifndef HAVE_LCMS_CREATE_CONTEXT
+ cmsSetLogErrorHandler (cd_context_lcms2_error_cb);
+#endif
+}
+
+/**
+ * _cd_context_lcms_pre26_stop:
+ **/
+void
+_cd_context_lcms_pre26_stop (void)
+{
+#ifndef HAVE_LCMS_CREATE_CONTEXT
+ cmsSetLogErrorHandler (NULL);
+#endif
+}
+
+/**
+ * cd_context_lcms_free:
+ **/
+void
+cd_context_lcms_free (gpointer ctx)
+{
+ GError **error_ctx;
+
+#ifdef HAVE_LCMS_CREATE_CONTEXT
+ error_ctx = cmsGetContextUserData (ctx);
+#else
+ error_ctx = (GError **) ctx;
+#endif
+ g_clear_error (error_ctx);
+
+#ifdef HAVE_LCMS_CREATE_CONTEXT
+ cmsUnregisterPluginsTHR (ctx);
+ cmsDeleteContext (ctx);
+#endif
+}
+
+/**
+ * cd_context_lcms_error_clear:
+ **/
+void
+cd_context_lcms_error_clear (gpointer ctx)
+{
+ g_clear_error (cd_context_lcms_get_error (ctx));
+}
+
+/**
+ * cd_context_lcms_error_check:
+ **/
+gboolean
+cd_context_lcms_error_check (gpointer ctx, GError **error)
+{
+ GError **error_ctx;
+ error_ctx = cd_context_lcms_get_error (ctx);
+ if (*error_ctx == NULL)
+ return TRUE;
+ g_propagate_error (error, *error_ctx);
+ *error_ctx = NULL;
+ return FALSE;
+}
diff --git a/lib/colord/cd-context-lcms.h b/lib/colord/cd-context-lcms.h
new file mode 100644
index 0000000..0d03634
--- /dev/null
+++ b/lib/colord/cd-context-lcms.h
@@ -0,0 +1,45 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
+ *
+ * Copyright (C) 2014 Richard Hughes <richard@hughsie.com>
+ *
+ * Licensed under the GNU Lesser General Public License Version 2.1
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+
+#if !defined (CD_COMPILATION)
+#error "You cannot include this file externaly"
+#endif
+
+#ifndef __CD_CONTEXT_PRIVATE_H
+#define __CD_CONTEXT_PRIVATE_H
+
+#include <glib.h>
+
+gpointer cd_context_lcms_new (void);
+void cd_context_lcms_free (gpointer ctx);
+void cd_context_lcms_error_clear (gpointer ctx);
+gboolean cd_context_lcms_error_check (gpointer ctx,
+ GError **error);
+
+/* not part of the API */
+void _cd_context_lcms_pre26_start (void);
+void _cd_context_lcms_pre26_stop (void);
+
+G_END_DECLS
+
+#endif /* __CD_CONTEXT_PRIVATE_H */
+
diff --git a/lib/colord/cd-icc-utils.c b/lib/colord/cd-icc-utils.c
index b2d58df..8472a27 100644
--- a/lib/colord/cd-icc-utils.c
+++ b/lib/colord/cd-icc-utils.c
@@ -75,8 +75,8 @@ cd_icc_utils_get_coverage_calc (CdIcc *icc,
guint i;
/* create a proofing transform with gamut check */
- profile_null = cmsCreateNULLProfileTHR (icc);
- transform = cmsCreateProofingTransformTHR (icc,
+ profile_null = cmsCreateNULLProfileTHR (cd_icc_get_context (icc));
+ transform = cmsCreateProofingTransformTHR (cd_icc_get_context (icc),
cd_icc_get_handle (icc),
TYPE_RGB_FLT,
profile_null,
diff --git a/lib/colord/cd-icc.c b/lib/colord/cd-icc.c
index f9ade3c..fcb697a 100644
--- a/lib/colord/cd-icc.c
+++ b/lib/colord/cd-icc.c
@@ -33,6 +33,7 @@
#include <stdlib.h>
#include <math.h>
+#include "cd-context-lcms.h"
#include "cd-icc.h"
static void cd_icc_class_init (CdIccClass *klass);
@@ -63,6 +64,7 @@ struct _CdIccPrivate
{
CdColorspace colorspace;
CdProfileKind kind;
+ cmsContext context_lcms;
cmsHPROFILE lcms_profile;
gboolean can_delete;
gchar *checksum;
@@ -78,7 +80,6 @@ struct _CdIccPrivate
CdColorXYZ red;
CdColorXYZ green;
CdColorXYZ blue;
- GError *error_lcms;
};
G_DEFINE_TYPE (CdIcc, cd_icc, G_TYPE_OBJECT)
@@ -160,60 +161,6 @@ cd_icc_uint32_to_str (guint32 id, gchar *str)
}
/**
- * cd_icc_lcms2_error_cb:
- **/
-static void
-cd_icc_lcms2_error_cb (cmsContext context_id,
- cmsUInt32Number code,
- const gchar *message)
-{
- CdIcc *icc = CD_ICC (context_id);
- CdIccPrivate *priv = icc->priv;
- gint error_code;
-
- /* there's already one error pending */
- if (priv->error_lcms != NULL) {
- g_prefix_error (&priv->error_lcms,
- "%s & ", message);
- return;
- }
-
- /* convert the first cmsERROR in into a CdIccError */
- switch (code) {
- case cmsERROR_CORRUPTION_DETECTED:
- error_code = CD_ICC_ERROR_CORRUPTION_DETECTED;
- break;
- case cmsERROR_FILE:
- case cmsERROR_READ:
- case cmsERROR_SEEK:
- error_code = CD_ICC_ERROR_FAILED_TO_OPEN;
- break;
- case cmsERROR_WRITE:
- error_code = CD_ICC_ERROR_FAILED_TO_SAVE;
- break;
- case cmsERROR_COLORSPACE_CHECK:
- error_code = CD_ICC_ERROR_INVALID_COLORSPACE;
- break;
- case cmsERROR_BAD_SIGNATURE:
- error_code = CD_ICC_ERROR_FAILED_TO_PARSE;
- break;
- case cmsERROR_ALREADY_DEFINED:
- case cmsERROR_INTERNAL:
- case cmsERROR_NOT_SUITABLE:
- case cmsERROR_NULL:
- case cmsERROR_RANGE:
- case cmsERROR_UNDEFINED:
- case cmsERROR_UNKNOWN_EXTENSION:
- error_code = CD_ICC_ERROR_INTERNAL;
- break;
- default:
- g_warning ("LCMS2 erorr code not recognised; please report");
- error_code = CD_ICC_ERROR_INTERNAL;
- }
- g_set_error_literal (&priv->error_lcms, CD_ICC_ERROR, error_code, message);
-}
-
-/**
* cd_icc_read_tag:
**/
static gpointer
@@ -221,10 +168,11 @@ cd_icc_read_tag (CdIcc *icc, cmsTagSignature sig, GError **error)
{
CdIccPrivate *priv = icc->priv;
gchar sig_string[5];
+ gboolean ret;
gpointer tmp;
/* ensure context error is not present to aid debugging */
- g_clear_error (&priv->error_lcms);
+ cd_context_lcms_error_clear (priv->context_lcms);
/* read raw value */
tmp = cmsReadTag (priv->lcms_profile, sig);
@@ -232,11 +180,9 @@ cd_icc_read_tag (CdIcc *icc, cmsTagSignature sig, GError **error)
goto out;
/* any context error? */
- if (priv->error_lcms != NULL) {
- g_propagate_error (error, priv->error_lcms);
- priv->error_lcms = NULL;
+ ret = cd_context_lcms_error_check (priv->context_lcms, error);
+ if (!ret)
goto out;
- }
/* missing value */
cd_icc_uint32_to_str (GINT32_FROM_BE (sig), sig_string);
@@ -259,7 +205,7 @@ cd_icc_write_tag (CdIcc *icc, cmsTagSignature sig, gpointer data, GError **error
gchar sig_string[5];
/* ensure context error is not present to aid debugging */
- g_clear_error (&priv->error_lcms);
+ cd_context_lcms_error_clear (priv->context_lcms);
/* read raw value */
ret = cmsWriteTag (priv->lcms_profile, sig, data);
@@ -274,11 +220,9 @@ cd_icc_write_tag (CdIcc *icc, cmsTagSignature sig, gpointer data, GError **error
}
/* any context error? */
- if (priv->error_lcms != NULL) {
- g_propagate_error (error, priv->error_lcms);
- priv->error_lcms = NULL;
+ ret = cd_context_lcms_error_check (priv->context_lcms, error);
+ if (!ret)
goto out;
- }
/* missing value */
cd_icc_uint32_to_str (GINT32_FROM_BE (sig), sig_string);
@@ -323,7 +267,7 @@ cd_icc_to_string (CdIcc *icc)
g_return_val_if_fail (CD_IS_ICC (icc), NULL);
/* setup error handler */
- cmsSetLogErrorHandler (cd_icc_lcms2_error_cb);
+ _cd_context_lcms_pre26_start ();
/* print header */
str = g_string_new ("icc:\nHeader:\n");
@@ -768,7 +712,7 @@ cd_icc_to_string (CdIcc *icc)
if (str->len > 0)
g_string_truncate (str, str->len - 1);
- cmsSetLogErrorHandler (NULL);
+ _cd_context_lcms_pre26_stop ();
return g_string_free (str, FALSE);
}
@@ -857,8 +801,8 @@ cd_icc_calc_whitepoint (CdIcc *icc, GError **error)
/* do Lab to RGB transform to get primaries */
profiles[0] = priv->lcms_profile;
- profiles[1] = cmsCreateXYZProfileTHR (icc);
- transform = cmsCreateExtendedTransform (icc,
+ profiles[1] = cmsCreateXYZProfileTHR (priv->context_lcms);
+ transform = cmsCreateExtendedTransform (priv->context_lcms,
2,
profiles,
bpc,
@@ -976,8 +920,8 @@ cd_icc_load_primaries (CdIcc *icc, GError **error)
}
/* get the illuminants by running it through the profile */
- xyz_profile = cmsCreateXYZProfileTHR (icc);
- transform = cmsCreateTransformTHR (icc,
+ xyz_profile = cmsCreateXYZProfileTHR (priv->context_lcms);
+ transform = cmsCreateTransformTHR (priv->context_lcms,
priv->lcms_profile, TYPE_RGB_DBL,
xyz_profile, TYPE_XYZ_DBL,
INTENT_PERCEPTUAL, 0);
@@ -1116,8 +1060,7 @@ cd_icc_load (CdIcc *icc, CdIccLoadFlags flags, GError **error)
gboolean ret = TRUE;
guint i;
- /* setup error handler */
- cmsSetLogErrorHandler (cd_icc_lcms2_error_cb);
+ _cd_context_lcms_pre26_start ();
/* get version */
priv->version = cmsGetProfileVersion (priv->lcms_profile);
@@ -1181,7 +1124,7 @@ cd_icc_load (CdIcc *icc, CdIccLoadFlags flags, GError **error)
goto out;
}
out:
- cmsSetLogErrorHandler (NULL);
+ _cd_context_lcms_pre26_stop ();
return ret;
}
@@ -1222,7 +1165,8 @@ cd_icc_load_data (CdIcc *icc,
}
/* load icc into lcms */
- priv->lcms_profile = cmsOpenProfileFromMemTHR (icc, data, data_len);
+ priv->lcms_profile = cmsOpenProfileFromMemTHR (priv->context_lcms,
+ data, data_len);
if (priv->lcms_profile == NULL) {
ret = FALSE;
g_set_error_literal (error,
@@ -1388,7 +1332,7 @@ cd_util_write_tag_ascii (CdIcc *icc,
}
/* set value */
- mlu = cmsMLUalloc (icc, 1);
+ mlu = cmsMLUalloc (icc->priv->context_lcms, 1);
ret = cmsMLUsetASCII (mlu, "en", "US", value);
if (!ret) {
g_set_error_literal (error,
@@ -1482,7 +1426,7 @@ cd_util_write_tag_localized (CdIcc *icc,
g_ptr_array_sort (array, cd_util_sort_mlu_array_cb);
/* create MLU object to hold all the translations */
- mlu = cmsMLUalloc (icc, array->len);
+ mlu = cmsMLUalloc (icc->priv->context_lcms, array->len);
for (i = 0; i < array->len; i++) {
obj = g_ptr_array_index (array, i);
if (obj->language_code == NULL &&
@@ -1562,7 +1506,11 @@ cd_icc_check_error_cb (cmsContext context_id,
cmsUInt32Number code,
const char *message)
{
+#ifdef HAVE_LCMS_CREATE_CONTEXT
+ gboolean *ret = (gboolean *) cmsGetContextUserData (context_id);
+#else
gboolean *ret = (gboolean *) context_id;
+#endif
*ret = FALSE;
}
@@ -1584,12 +1532,19 @@ cd_icc_check_lcms2_MemoryWrite (void)
cmsUInt32Number size;
gboolean ret = TRUE;
gchar *data;
+ cmsContext ctx;
- /* setup temporary log handler */
+ /* create context */
+#ifdef HAVE_LCMS_CREATE_CONTEXT
+ ctx = cmsCreateContext (NULL, &ret);
+ cmsSetLogErrorHandlerTHR (ctx, cd_icc_check_error_cb);
+#else
cmsSetLogErrorHandler (cd_icc_check_error_cb);
+ ctx = (void *) &ret;
+#endif
/* create test data */
- p = cmsCreate_sRGBProfileTHR (&ret);
+ p = cmsCreate_sRGBProfileTHR (ctx);
dict = cmsDictAlloc (NULL);
cmsDictAddEntry (dict, L"1", L"2", NULL, NULL);
cmsWriteTag (p, cmsSigMetaTag, dict);
@@ -1600,12 +1555,16 @@ cd_icc_check_lcms2_MemoryWrite (void)
cmsDictFree (dict);
/* open file */
- p = cmsOpenProfileFromMemTHR (&ret, data, size);
+ p = cmsOpenProfileFromMemTHR (ctx, data, size);
dict = cmsReadTag (p, cmsSigMetaTag);
g_assert (dict != (gpointer) 0x01); /* appease GCC */
cmsCloseProfile (p);
g_free (data);
- cmsSetLogErrorHandler (NULL);
+#ifdef HAVE_LCMS_CREATE_CONTEXT
+ cmsDeleteContext (ctx);
+#else
+ _cd_context_lcms_pre26_stop ();
+#endif
return ret;
}
@@ -1747,8 +1706,7 @@ cd_icc_save_data (CdIcc *icc,
g_return_val_if_fail (CD_IS_ICC (icc), FALSE);
- /* setup error handler */
- cmsSetLogErrorHandler (cd_icc_lcms2_error_cb);
+ _cd_context_lcms_pre26_start ();
/* convert profile kind */
for (i = 0; map_profile_kind[i].colord != CD_PROFILE_KIND_LAST; i++) {
@@ -1774,7 +1732,7 @@ cd_icc_save_data (CdIcc *icc,
/* save metadata */
if (g_hash_table_size (priv->metadata) != 0) {
- dict = cmsDictAlloc (icc);
+ dict = cmsDictAlloc (priv->context_lcms);
md_keys = g_hash_table_get_keys (priv->metadata);
if (md_keys != NULL) {
for (l = md_keys; l != NULL; l = l->next) {
@@ -1896,7 +1854,7 @@ cd_icc_save_data (CdIcc *icc,
data = cd_icc_serialize_profile_fallback (icc, error);
}
out:
- cmsSetLogErrorHandler (NULL);
+ _cd_context_lcms_pre26_stop ();
g_list_free (md_keys);
if (dict != NULL)
cmsDictFree (dict);
@@ -2176,7 +2134,7 @@ cd_icc_load_fd (CdIcc *icc,
}
/* parse the ICC file */
- priv->lcms_profile = cmsOpenProfileFromStreamTHR (icc, stream, "r");
+ priv->lcms_profile = cmsOpenProfileFromStreamTHR (priv->context_lcms, stream, "r");
if (priv->lcms_profile == NULL) {
ret = FALSE;
g_set_error_literal (error,
@@ -2211,6 +2169,24 @@ cd_icc_get_handle (CdIcc *icc)
}
/**
+ * cd_icc_get_context:
+ * @icc: a #CdIcc instance.
+ *
+ * Return the cmsContext instance used locally. This may be required if you
+ * are using native LCMS calls and then cd_icc_load_handle().
+ *
+ * Return value: (transfer none): Do not call cmsDeleteContext() on this value!
+ *
+ * Since: 1.1.7
+ **/
+gpointer
+cd_icc_get_context (CdIcc *icc)
+{
+ g_return_val_if_fail (CD_IS_ICC (icc), NULL);
+ return icc->priv->context_lcms;
+}
+
+/**
* cd_icc_load_handle:
* @icc: a #CdIcc instance.
* @handle: a cmsHPROFILE instance
@@ -2226,8 +2202,8 @@ cd_icc_get_handle (CdIcc *icc)
* by this module.
*
* To handle the internal error callback, you should use the thread-safe
- * creation function, e.g. cmsCreateNULLProfileTHR(). The context_id should be
- * set as the value as the @icc parameter.
+ * creation function, e.g. cmsCreateNULLProfileTHR(). The @context_id should be
+ * set as the value of cd_icc_get_context() for this object.
*
* Additionally, this function cannot be called more than once, and also can't
* be called if cd_icc_load_file() has previously been used on the @icc object.
@@ -2250,13 +2226,13 @@ cd_icc_load_handle (CdIcc *icc,
/* check the THR version has been correctly set up */
context = cmsGetProfileContextID (handle);
- if (!CD_IS_ICC (context)) {
+ if (context == NULL) {
ret = FALSE;
g_set_error_literal (error,
CD_ICC_ERROR,
CD_ICC_ERROR_FAILED_TO_CREATE,
"lcms2 threadsafe version (THR) not used, "
- "or CdIcc not set");
+ "or context not set");
goto out;
}
@@ -2698,8 +2674,7 @@ cd_icc_get_mluc_data (CdIcc *icc,
g_return_val_if_fail (CD_IS_ICC (icc), NULL);
- /* setup error handler */
- cmsSetLogErrorHandler (cd_icc_lcms2_error_cb);
+ _cd_context_lcms_pre26_start ();
/* does cache entry exist already? */
locale_key = cd_icc_get_locale_key (locale);
@@ -2786,7 +2761,7 @@ cd_icc_get_mluc_data (CdIcc *icc,
tmp);
value = tmp;
out:
- cmsSetLogErrorHandler (NULL);
+ _cd_context_lcms_pre26_stop ();
g_free (locale_key);
g_free (text_buffer);
g_free (wtext);
@@ -3207,8 +3182,7 @@ cd_icc_create_default (CdIcc *icc, GError **error)
CdIccPrivate *priv = icc->priv;
gboolean ret = TRUE;
- /* setup error handler */
- cmsSetLogErrorHandler (cd_icc_lcms2_error_cb);
+ _cd_context_lcms_pre26_start ();
/* not loaded */
if (priv->lcms_profile != NULL) {
@@ -3221,7 +3195,7 @@ cd_icc_create_default (CdIcc *icc, GError **error)
}
/* create our generated ICC */
- priv->lcms_profile = cmsCreate_sRGBProfileTHR (icc);
+ priv->lcms_profile = cmsCreate_sRGBProfileTHR (priv->context_lcms);
if (priv->lcms_profile == NULL) {
ret = FALSE;
g_set_error (error,
@@ -3239,7 +3213,7 @@ cd_icc_create_default (CdIcc *icc, GError **error)
CD_PROFILE_METADATA_STANDARD_SPACE,
cd_standard_space_to_string (CD_STANDARD_SPACE_SRGB));
out:
- cmsSetLogErrorHandler (NULL);
+ _cd_context_lcms_pre26_stop ();
return ret;
}
@@ -3338,8 +3312,7 @@ cd_icc_create_from_edid (CdIcc *icc,
cmsToneCurve *transfer_curve[3] = { NULL, NULL, NULL };
gboolean ret = FALSE;
- /* setup error handler */
- cmsSetLogErrorHandler (cd_icc_lcms2_error_cb);
+ _cd_context_lcms_pre26_start ();
/* not loaded */
if (priv->lcms_profile != NULL) {
@@ -3368,7 +3341,7 @@ cd_icc_create_from_edid (CdIcc *icc,
transfer_curve[2] = transfer_curve[0];
/* create our generated ICC */
- priv->lcms_profile = cmsCreateRGBProfileTHR (icc,
+ priv->lcms_profile = cmsCreateRGBProfileTHR (priv->context_lcms,
&white_point,
&chroma,
transfer_curve);
@@ -3398,7 +3371,7 @@ cd_icc_create_from_edid (CdIcc *icc,
/* success */
ret = TRUE;
out:
- cmsSetLogErrorHandler (NULL);
+ _cd_context_lcms_pre26_stop ();
if (transfer_curve[0] != NULL)
cmsFreeToneCurve (transfer_curve[0]);
return ret;
@@ -3428,8 +3401,7 @@ cd_icc_get_vcgt (CdIcc *icc, guint size, GError **error)
g_return_val_if_fail (CD_IS_ICC (icc), NULL);
g_return_val_if_fail (icc->priv->lcms_profile != NULL, NULL);
- /* setup error handler */
- cmsSetLogErrorHandler (cd_icc_lcms2_error_cb);
+ _cd_context_lcms_pre26_start ();
/* get tone curves from icc */
vcgt = cmsReadTag (icc->priv->lcms_profile, cmsSigVcgtType);
@@ -3453,7 +3425,7 @@ cd_icc_get_vcgt (CdIcc *icc, guint size, GError **error)
g_ptr_array_add (array, tmp);
}
out:
- cmsSetLogErrorHandler (NULL);
+ _cd_context_lcms_pre26_stop ();
return array;
}
@@ -3472,6 +3444,7 @@ out:
GPtrArray *
cd_icc_get_response (CdIcc *icc, guint size, GError **error)
{
+ CdIccPrivate *priv = icc->priv;
CdColorRGB *data;
CdColorspace colorspace;
cmsHPROFILE srgb_profile = NULL;
@@ -3485,8 +3458,7 @@ cd_icc_get_response (CdIcc *icc, guint size, GError **error)
GPtrArray *array = NULL;
guint i;
- /* setup error handler */
- cmsSetLogErrorHandler (cd_icc_lcms2_error_cb);
+ _cd_context_lcms_pre26_start ();
/* run through the icc */
colorspace = cd_icc_get_colorspace (icc);
@@ -3522,8 +3494,8 @@ cd_icc_get_response (CdIcc *icc, guint size, GError **error)
/* create a transform from icc to sRGB */
values_out = g_new0 (gdouble, size * 3 * component_width);
- srgb_profile = cmsCreate_sRGBProfileTHR (icc);
- transform = cmsCreateTransformTHR (icc,
+ srgb_profile = cmsCreate_sRGBProfileTHR (priv->context_lcms);
+ transform = cmsCreateTransformTHR (priv->context_lcms,
icc->priv->lcms_profile, TYPE_RGB_DBL,
srgb_profile, TYPE_RGB_DBL,
INTENT_PERCEPTUAL, 0);
@@ -3555,7 +3527,7 @@ cd_icc_get_response (CdIcc *icc, guint size, GError **error)
g_ptr_array_add (array, data);
}
out:
- cmsSetLogErrorHandler (NULL);
+ _cd_context_lcms_pre26_stop ();
g_free (values_in);
g_free (values_out);
if (transform != NULL)
@@ -3591,8 +3563,7 @@ cd_icc_set_vcgt (CdIcc *icc, GPtrArray *vcgt, GError **error)
g_return_val_if_fail (CD_IS_ICC (icc), FALSE);
g_return_val_if_fail (icc->priv->lcms_profile != NULL, FALSE);
- /* setup error handler */
- cmsSetLogErrorHandler (cd_icc_lcms2_error_cb);
+ _cd_context_lcms_pre26_start ();
/* unwrap data */
red = g_new0 (guint16, vcgt->len);
@@ -3624,7 +3595,7 @@ cd_icc_set_vcgt (CdIcc *icc, GPtrArray *vcgt, GError **error)
goto out;
}
out:
- cmsSetLogErrorHandler (NULL);
+ _cd_context_lcms_pre26_stop ();
for (i = 0; i < 3; i++)
cmsFreeToneCurve (curve[i]);
g_free (red);
@@ -3659,6 +3630,7 @@ out:
static CdProfileWarning
cd_icc_check_vcgt (CdIcc *icc)
{
+ CdIccPrivate *priv = icc->priv;
CdProfileWarning warning = CD_PROFILE_WARNING_NONE;
cmsFloat32Number in;
cmsFloat32Number now[3];
@@ -3668,7 +3640,7 @@ cd_icc_check_vcgt (CdIcc *icc)
guint i;
/* does profile have monotonic VCGT */
- vcgt = cmsReadTag (icc->priv->lcms_profile, cmsSigVcgtTag);
+ vcgt = cmsReadTag (priv->lcms_profile, cmsSigVcgtTag);
if (vcgt == NULL)
goto out;
for (i = 0; i < size; i++) {
@@ -3700,6 +3672,7 @@ out:
static CdProfileWarning
cd_profile_check_scum_dot (CdIcc *icc)
{
+ CdIccPrivate *priv = icc->priv;
CdProfileWarning warning = CD_PROFILE_WARNING_NONE;
cmsCIELab white;
cmsHPROFILE profile_lab;
@@ -3707,10 +3680,10 @@ cd_profile_check_scum_dot (CdIcc *icc)
guint8 rgb[3] = { 0, 0, 0 };
/* do Lab to RGB transform of 100,0,0 */
- profile_lab = cmsCreateLab2ProfileTHR (icc, cmsD50_xyY ());
- transform = cmsCreateTransformTHR (icc,
+ profile_lab = cmsCreateLab2ProfileTHR (priv->context_lcms, cmsD50_xyY ());
+ transform = cmsCreateTransformTHR (priv->context_lcms,
profile_lab, TYPE_Lab_DBL,
- icc->priv->lcms_profile, TYPE_RGB_8,
+ priv->lcms_profile, TYPE_RGB_8,
INTENT_RELATIVE_COLORIMETRIC,
cmsFLAGS_NOOPTIMIZE);
if (transform == NULL) {
@@ -3739,6 +3712,7 @@ out:
static CdProfileWarning
cd_icc_check_primaries (CdIcc *icc)
{
+ CdIccPrivate *priv = icc->priv;
CdProfileWarning warning = CD_PROFILE_WARNING_NONE;
cmsCIEXYZ *tmp;
@@ -3757,7 +3731,7 @@ cd_icc_check_primaries (CdIcc *icc)
*/
/* check red */
- tmp = cmsReadTag (icc->priv->lcms_profile, cmsSigRedColorantTag);
+ tmp = cmsReadTag (priv->lcms_profile, cmsSigRedColorantTag);
if (tmp == NULL)
goto out;
if (tmp->X > 0.85f || tmp->Y < 0.15f || tmp->Z < -0.01) {
@@ -3766,7 +3740,7 @@ cd_icc_check_primaries (CdIcc *icc)
}
/* check green */
- tmp = cmsReadTag (icc->priv->lcms_profile, cmsSigGreenColorantTag);
+ tmp = cmsReadTag (priv->lcms_profile, cmsSigGreenColorantTag);
if (tmp == NULL)
goto out;
if (tmp->X < 0.10f || tmp->Y > 0.85f || tmp->Z < -0.01f) {
@@ -3775,7 +3749,7 @@ cd_icc_check_primaries (CdIcc *icc)
}
/* check blue */
- tmp = cmsReadTag (icc->priv->lcms_profile, cmsSigBlueColorantTag);
+ tmp = cmsReadTag (priv->lcms_profile, cmsSigBlueColorantTag);
if (tmp == NULL)
goto out;
if (tmp->X < 0.10f || tmp->Y < 0.01f || tmp->Z > 0.87f) {
@@ -3792,6 +3766,7 @@ out:
static CdProfileWarning
cd_icc_check_gray_axis (CdIcc *icc)
{
+ CdIccPrivate *priv = icc->priv;
CdProfileWarning warning = CD_PROFILE_WARNING_NONE;
cmsCIELab gray[16];
cmsHPROFILE profile_lab = NULL;
@@ -3803,13 +3778,13 @@ cd_icc_check_gray_axis (CdIcc *icc)
guint i;
/* only do this for display profiles */
- if (cmsGetDeviceClass (icc->priv->lcms_profile) != cmsSigDisplayClass)
+ if (cmsGetDeviceClass (priv->lcms_profile) != cmsSigDisplayClass)
goto out;
/* do Lab to RGB transform of 100,0,0 */
- profile_lab = cmsCreateLab2ProfileTHR (icc, cmsD50_xyY ());
- transform = cmsCreateTransformTHR (icc,
- icc->priv->lcms_profile, TYPE_RGB_8,
+ profile_lab = cmsCreateLab2ProfileTHR (priv->context_lcms, cmsD50_xyY ());
+ transform = cmsCreateTransformTHR (priv->context_lcms,
+ priv->lcms_profile, TYPE_RGB_8,
profile_lab, TYPE_Lab_DBL,
INTENT_RELATIVE_COLORIMETRIC,
cmsFLAGS_NOOPTIMIZE);
@@ -3858,6 +3833,7 @@ out:
static CdProfileWarning
cd_icc_check_d50_whitepoint (CdIcc *icc)
{
+ CdIccPrivate *priv = icc->priv;
CdProfileWarning warning = CD_PROFILE_WARNING_NONE;
cmsCIExyY tmp;
cmsCIEXYZ additive;
@@ -3872,9 +3848,9 @@ cd_icc_check_d50_whitepoint (CdIcc *icc)
guint i;
/* do Lab to RGB transform to get primaries */
- profile_lab = cmsCreateXYZProfileTHR (icc);
- transform = cmsCreateTransformTHR (icc,
- icc->priv->lcms_profile, TYPE_RGB_8,
+ profile_lab = cmsCreateXYZProfileTHR (priv->context_lcms);
+ transform = cmsCreateTransformTHR (priv->context_lcms,
+ priv->lcms_profile, TYPE_RGB_8,
profile_lab, TYPE_XYZ_DBL,
INTENT_RELATIVE_COLORIMETRIC,
cmsFLAGS_NOOPTIMIZE);
@@ -3920,7 +3896,7 @@ cd_icc_check_d50_whitepoint (CdIcc *icc)
}
/* only do the rest for display profiles */
- if (cmsGetDeviceClass (icc->priv->lcms_profile) != cmsSigDisplayClass)
+ if (cmsGetDeviceClass (priv->lcms_profile) != cmsSigDisplayClass)
goto out;
/* check white is D50 */
@@ -3968,28 +3944,28 @@ out:
GArray *
cd_icc_get_warnings (CdIcc *icc)
{
+ CdIccPrivate *priv = icc->priv;
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);
+ g_return_val_if_fail (priv->lcms_profile != NULL, NULL);
- /* setup error handler */
- cmsSetLogErrorHandler (cd_icc_lcms2_error_cb);
+ _cd_context_lcms_pre26_start ();
flags = g_array_new (FALSE, FALSE, sizeof (CdProfileWarning));
/* check that the profile has a description and a copyright */
- ret = cmsGetProfileInfoASCII (icc->priv->lcms_profile,
+ ret = cmsGetProfileInfoASCII (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,
+ ret = cmsGetProfileInfoASCII (priv->lcms_profile,
cmsInfoCopyright, "en", "US",
ascii_name, 1024);
if (!ret || ascii_name[0] == '\0') {
@@ -3998,7 +3974,7 @@ cd_icc_get_warnings (CdIcc *icc)
}
/* not a RGB space */
- if (cmsGetColorSpace (icc->priv->lcms_profile) != cmsSigRgbData)
+ if (cmsGetColorSpace (priv->lcms_profile) != cmsSigRgbData)
goto out;
/* does profile have an unlikely whitepoint */
@@ -4032,7 +4008,7 @@ cd_icc_get_warnings (CdIcc *icc)
if (warning != CD_PROFILE_WARNING_NONE)
g_array_append_val (flags, warning);
out:
- cmsSetLogErrorHandler (NULL);
+ _cd_context_lcms_pre26_stop ();
return flags;
}
@@ -4232,6 +4208,7 @@ cd_icc_init (CdIcc *icc)
guint i;
icc->priv = CD_ICC_GET_PRIVATE (icc);
+ icc->priv->context_lcms = cd_context_lcms_new ();
icc->priv->kind = CD_PROFILE_KIND_UNKNOWN;
icc->priv->colorspace = CD_COLORSPACE_UNKNOWN;
icc->priv->named_colors = g_ptr_array_new_with_free_func ((GDestroyNotify) cd_color_swatch_free);
@@ -4270,8 +4247,7 @@ cd_icc_finalize (GObject *object)
g_hash_table_destroy (priv->mluc_data[i]);
if (priv->lcms_profile != NULL)
cmsCloseProfile (priv->lcms_profile);
- if (priv->error_lcms != NULL)
- g_error_free (priv->error_lcms);
+ cd_context_lcms_free (priv->context_lcms);
G_OBJECT_CLASS (cd_icc_parent_class)->finalize (object);
}
diff --git a/lib/colord/cd-icc.h b/lib/colord/cd-icc.h
index d74d3a2..599a933 100644
--- a/lib/colord/cd-icc.h
+++ b/lib/colord/cd-icc.h
@@ -182,6 +182,7 @@ gboolean cd_icc_save_default (CdIcc *icc,
gchar *cd_icc_to_string (CdIcc *icc)
G_GNUC_WARN_UNUSED_RESULT;
gpointer cd_icc_get_handle (CdIcc *icc);
+gpointer cd_icc_get_context (CdIcc *icc);
guint32 cd_icc_get_size (CdIcc *icc);
const gchar *cd_icc_get_filename (CdIcc *icc);
void cd_icc_set_filename (CdIcc *icc,
diff --git a/lib/colord/cd-it8.c b/lib/colord/cd-it8.c
index 66dcd81..b1b74df 100644
--- a/lib/colord/cd-it8.c
+++ b/lib/colord/cd-it8.c
@@ -35,6 +35,7 @@
#include "cd-it8.h"
#include "cd-color.h"
+#include "cd-context-lcms.h"
static void cd_it8_class_init (CdIt8Class *klass);
static void cd_it8_init (CdIt8 *it8);
@@ -50,6 +51,7 @@ static void cd_it8_finalize (GObject *object);
struct _CdIt8Private
{
CdIt8Kind kind;
+ cmsContext context_lcms;
CdMat3x3 matrix;
gboolean normalized;
gboolean spectral;
@@ -217,17 +219,6 @@ cd_it8_get_kind (CdIt8 *it8)
}
/**
- * cd_it8_lcms2_error_cb:
- **/
-static void
-cd_it8_lcms2_error_cb (cmsContext context_id,
- cmsUInt32Number code,
- const gchar *text)
-{
- g_warning ("lcms2(it8): Failed with error: %s [%i]", text, code);
-}
-
-/**
* cd_it8_parse_luminance:
**/
static gboolean
@@ -571,6 +562,7 @@ cd_it8_load_from_data (CdIt8 *it8,
gsize size,
GError **error)
{
+ GError *error_local = NULL;
cmsHANDLE it8_lcms = NULL;
const gchar *tmp;
gboolean ret = TRUE;
@@ -581,8 +573,7 @@ cd_it8_load_from_data (CdIt8 *it8,
g_return_val_if_fail (data != NULL, FALSE);
g_return_val_if_fail (size > 0, FALSE);
- /* setup error handler */
- cmsSetLogErrorHandler (cd_it8_lcms2_error_cb);
+ _cd_context_lcms_pre26_start ();
/* clear old data */
g_ptr_array_set_size (it8->priv->array_rgb, 0);
@@ -591,11 +582,22 @@ cd_it8_load_from_data (CdIt8 *it8,
cd_mat33_clear (&it8->priv->matrix);
/* load the it8 data */
- it8_lcms = cmsIT8LoadFromMem (NULL, (void *) data, size);
+ it8_lcms = cmsIT8LoadFromMem (it8->priv->context_lcms, (void *) data, size);
if (it8_lcms == NULL) {
+ ret = cd_context_lcms_error_check (it8->priv->context_lcms, &error_local);
+ if (!ret) {
+ g_set_error_literal (error,
+ CD_IT8_ERROR,
+ CD_IT8_ERROR_FAILED,
+ error_local->message);
+ g_error_free (error_local);
+ goto out;
+ }
ret = FALSE;
- g_set_error_literal (error, 1, 0,
- "Cannot open CCMX file");
+ g_set_error_literal (error,
+ CD_IT8_ERROR,
+ CD_IT8_ERROR_FAILED,
+ "Failed to load but no error set");
goto out;
}
@@ -643,6 +645,7 @@ cd_it8_load_from_data (CdIt8 *it8,
cd_it8_set_originator (it8, cmsIT8GetProperty (it8_lcms, "ORIGINATOR"));
cd_it8_set_reference (it8, cmsIT8GetProperty (it8_lcms, "REFERENCE"));
out:
+ _cd_context_lcms_pre26_stop ();
if (it8_lcms != NULL)
cmsIT8Free (it8_lcms);
return ret;
@@ -933,11 +936,10 @@ cd_it8_save_to_data (CdIt8 *it8,
g_return_val_if_fail (CD_IS_IT8 (it8), FALSE);
- /* setup error handler */
- cmsSetLogErrorHandler (cd_it8_lcms2_error_cb);
+ _cd_context_lcms_pre26_start ();
/* set common data */
- it8_lcms = cmsIT8Alloc (NULL);
+ it8_lcms = cmsIT8Alloc (it8->priv->context_lcms);
if (it8->priv->title != NULL) {
cmsIT8SetPropertyStr (it8_lcms, "DISPLAY",
it8->priv->title);
@@ -996,6 +998,7 @@ cd_it8_save_to_data (CdIt8 *it8,
if (size != NULL)
*size = size_tmp - 1;
out:
+ _cd_context_lcms_pre26_stop ();
if (it8_lcms != NULL)
cmsIT8Free (it8_lcms);
if (datetime != NULL)
@@ -1451,6 +1454,7 @@ static void
cd_it8_init (CdIt8 *it8)
{
it8->priv = CD_IT8_GET_PRIVATE (it8);
+ it8->priv->context_lcms = cd_context_lcms_new ();
cd_mat33_clear (&it8->priv->matrix);
it8->priv->array_rgb = g_ptr_array_new_with_free_func ((GDestroyNotify) cd_color_rgb_free);
@@ -1472,6 +1476,7 @@ cd_it8_finalize (GObject *object)
g_return_if_fail (CD_IS_IT8 (object));
+ cd_context_lcms_free (it8->priv->context_lcms);
g_ptr_array_unref (it8->priv->array_rgb);
g_ptr_array_unref (it8->priv->array_xyz);
g_ptr_array_unref (it8->priv->options);
diff --git a/lib/colord/cd-transform.c b/lib/colord/cd-transform.c
index 01b9b7a..07fa8fc 100644
--- a/lib/colord/cd-transform.c
+++ b/lib/colord/cd-transform.c
@@ -35,6 +35,7 @@
#include <glib.h>
#include <lcms2.h>
+#include "cd-context-lcms.h"
#include "cd-transform.h"
static void cd_transform_class_init (CdTransformClass *klass);
@@ -56,6 +57,7 @@ struct _CdTransformPrivate
CdPixelFormat input_pixel_format;
CdPixelFormat output_pixel_format;
CdRenderingIntent rendering_intent;
+ cmsContext context_lcms;
cmsHPROFILE srgb;
cmsHTRANSFORM lcms_transform;
gboolean bpc;
@@ -416,6 +418,7 @@ static gboolean
cd_transform_setup (CdTransform *transform, GError **error)
{
CdTransformPrivate *priv = transform->priv;
+ GError *error_local = NULL;
cmsHPROFILE profile_in;
cmsHPROFILE profile_out;
cmsUInt32Number lcms_flags = 0;
@@ -473,7 +476,7 @@ cd_transform_setup (CdTransform *transform, GError **error)
profiles[0] = profile_in;
profiles[1] = cd_icc_get_handle (priv->abstract_icc);
profiles[2] = profile_out;
- priv->lcms_transform = cmsCreateMultiprofileTransformTHR (transform,
+ priv->lcms_transform = cmsCreateMultiprofileTransformTHR (priv->context_lcms,
profiles,
3,
priv->input_pixel_format,
@@ -483,7 +486,7 @@ cd_transform_setup (CdTransform *transform, GError **error)
} else {
/* create basic transform */
- priv->lcms_transform = cmsCreateTransformTHR (transform,
+ priv->lcms_transform = cmsCreateTransformTHR (priv->context_lcms,
profile_in,
priv->input_pixel_format,
profile_out,
@@ -494,6 +497,15 @@ cd_transform_setup (CdTransform *transform, GError **error)
/* failed? */
if (priv->lcms_transform == NULL) {
+ ret = cd_context_lcms_error_check (priv->context_lcms, &error_local);
+ if (!ret) {
+ g_set_error_literal (error,
+ CD_TRANSFORM_ERROR,
+ CD_TRANSFORM_ERROR_FAILED_TO_SETUP_TRANSFORM,
+ error_local->message);
+ g_error_free (error_local);
+ goto out;
+ }
ret = FALSE;
g_set_error_literal (error,
CD_TRANSFORM_ERROR,
@@ -570,17 +582,6 @@ out:
}
/**
- * cd_transform_lcms2_error_cb:
- **/
-static void
-cd_transform_lcms2_error_cb (cmsContext context_id,
- cmsUInt32Number code,
- const gchar *text)
-{
- g_warning ("lcms2(transform): Failed with error: %s [%i]", text, code);
-}
-
-/**
* cd_transform_process:
* @transform: a #CdTransform instance.
* @data_in: the data buffer to convert
@@ -625,8 +626,7 @@ cd_transform_process (CdTransform *transform,
g_return_val_if_fail (height != 0, FALSE);
g_return_val_if_fail (rowstride != 0, FALSE);
- /* setup error handler */
- cmsSetLogErrorHandler (cd_transform_lcms2_error_cb);
+ _cd_context_lcms_pre26_start ();
/* check stuff that should have been set */
if (priv->rendering_intent == CD_RENDERING_INTENT_UNKNOWN) {
@@ -707,7 +707,7 @@ cd_transform_process (CdTransform *transform,
p_out += rowstride * rows_to_process;
}
out:
- cmsSetLogErrorHandler (NULL);
+ _cd_context_lcms_pre26_stop ();
if (pool != NULL)
g_thread_pool_free (pool, FALSE, TRUE);
return ret;
@@ -864,10 +864,11 @@ static void
cd_transform_init (CdTransform *transform)
{
transform->priv = CD_TRANSFORM_GET_PRIVATE (transform);
+ transform->priv->context_lcms = cd_context_lcms_new ();
transform->priv->rendering_intent = CD_RENDERING_INTENT_UNKNOWN;
transform->priv->input_pixel_format = CD_PIXEL_FORMAT_UNKNOWN;
transform->priv->output_pixel_format = CD_PIXEL_FORMAT_UNKNOWN;
- transform->priv->srgb = cmsCreate_sRGBProfileTHR (transform);
+ transform->priv->srgb = cmsCreate_sRGBProfileTHR (transform->priv->context_lcms);
transform->priv->max_threads = 1;
}
@@ -889,6 +890,7 @@ cd_transform_finalize (GObject *object)
g_object_unref (priv->abstract_icc);
if (priv->lcms_transform != NULL)
cmsDeleteTransform (priv->lcms_transform);
+ cd_context_lcms_free (priv->context_lcms);
G_OBJECT_CLASS (cd_transform_parent_class)->finalize (object);
}