From: Øyvind Kolås Date: Wed, 3 Feb 2021 00:08:27 +0000 (+0100) Subject: icc: make babl_space_from_icc threadsafe X-Git-Tag: archive/raspbian/1%0.1.106-3+rpi1^2~15^2~6^2~10 X-Git-Url: https://dgit.raspbian.org/?a=commitdiff_plain;h=c8d2ca843e10271c1532863f27dd8c7725085394;p=babl.git icc: make babl_space_from_icc threadsafe When multiple threads concurrently try to use ICC profiles / spaces races during construction could cause broken internal representation of profiles. --- diff --git a/babl/babl-icc.c b/babl/babl-icc.c index 52a35d2..0bbb47e 100644 --- a/babl/babl-icc.c +++ b/babl/babl-icc.c @@ -957,6 +957,8 @@ babl_space_from_icc (const char *icc_data, sign_t profile_class, color_space, pcs; + babl_mutex_lock (babl_space_mutex); + if (!error) error = &int_err; *error = NULL; @@ -973,13 +975,22 @@ babl_space_from_icc (const char *icc_data, { ret = _babl_space_for_lcms (icc_data, icc_length); if (!ret) + { + babl_mutex_unlock (babl_space_mutex); return NULL; + } if (ret->space.icc_type == BablICCTypeCMYK) + { + babl_mutex_unlock (babl_space_mutex); return ret; + } ret->space.icc_length = icc_length; ret->space.icc_profile = malloc (icc_length); if (!ret->space.icc_profile) + { + babl_mutex_unlock (babl_space_mutex); return NULL; + } memcpy (ret->space.icc_profile, icc_data, icc_length); #ifdef HAVE_LCMS @@ -1010,6 +1021,7 @@ babl_space_from_icc (const char *icc_data, cmsCloseProfile (ret->space.cmyk.lcms_profile); // XXX keep it open in case of CMYK to CMYK transforms needed? #endif ret->space.icc_type = BablICCTypeCMYK; + babl_mutex_unlock (babl_space_mutex); return ret; } @@ -1113,6 +1125,7 @@ babl_space_from_icc (const char *icc_data, { babl_free (state); + babl_mutex_unlock (babl_space_mutex); return NULL; } @@ -1130,6 +1143,7 @@ babl_space_from_icc (const char *icc_data, ret->space.icc_profile = malloc (icc_length); memcpy (ret->space.icc_profile, icc_data, icc_length); babl_free (state); + babl_mutex_unlock (babl_space_mutex); return ret; @@ -1175,6 +1189,7 @@ babl_space_from_icc (const char *icc_data, *error = "Inconsistent ICC profile detected, profile contains both cLUTs and a matrix with swapped primaries, this likely means it is an intentionally inconsistent Argyll profile is in use; this profile is only capable of high accuracy rendering and does not permit acceleration for interactive previews."; fprintf (stderr, "babl ICC warning: %s\n", *error); babl_free (state); + babl_mutex_unlock (babl_space_mutex); return NULL; } } @@ -1184,6 +1199,7 @@ babl_space_from_icc (const char *icc_data, if (ret) { babl_free (state); + babl_mutex_unlock (babl_space_mutex); return ret; } @@ -1199,6 +1215,7 @@ babl_space_from_icc (const char *icc_data, ret->space.icc_length = icc_length; ret->space.icc_profile = malloc (icc_length); memcpy (ret->space.icc_profile, icc_data, icc_length); + babl_mutex_unlock (babl_space_mutex); return ret; } } @@ -1216,11 +1233,13 @@ babl_space_from_icc (const char *icc_data, if (phosporant != 0) { *error = "unhandled phosporants, please report bug against babl with profile"; + babl_mutex_unlock (babl_space_mutex); return NULL; } if (channels != 3) { *error = "unexpected non 3 count of channels"; + babl_mutex_unlock (babl_space_mutex); return NULL; } @@ -1250,6 +1269,7 @@ babl_space_from_icc (const char *icc_data, ret->space.icc_profile = malloc (icc_length); memcpy (ret->space.icc_profile, icc_data, icc_length); + babl_mutex_unlock (babl_space_mutex); return ret; } } @@ -1257,6 +1277,7 @@ babl_space_from_icc (const char *icc_data, } babl_free (state); + babl_mutex_unlock (babl_space_mutex); return NULL; } diff --git a/babl/babl-internal.c b/babl/babl-internal.c index f7939a1..94043d3 100644 --- a/babl/babl-internal.c +++ b/babl/babl-internal.c @@ -84,6 +84,7 @@ BablMutex *babl_format_mutex; BablMutex *babl_debug_mutex; #endif BablMutex *babl_reference_mutex; +BablMutex *babl_space_mutex; void babl_internal_init (void) @@ -93,6 +94,7 @@ babl_internal_init (void) babl_fish_mutex = babl_mutex_new (); babl_format_mutex = babl_mutex_new (); babl_reference_mutex = babl_mutex_new (); + babl_space_mutex = babl_mutex_new (); #if BABL_DEBUG_MEM babl_debug_mutex = babl_mutex_new (); #endif diff --git a/babl/babl-internal.h b/babl/babl-internal.h index 56e95e4..8b8ebd6 100644 --- a/babl/babl-internal.h +++ b/babl/babl-internal.h @@ -249,6 +249,7 @@ extern int babl_in_fish_path; extern BablMutex *babl_format_mutex; extern BablMutex *babl_fish_mutex; extern BablMutex *babl_reference_mutex; +extern BablMutex *babl_space_mutex; #define BABL_DEBUG_MEM 0 #if BABL_DEBUG_MEM