From 3f79f3589d1ec6662081d18a1d403f3da8673384 Mon Sep 17 00:00:00 2001 From: Jehan Date: Wed, 28 Feb 2024 22:13:57 +0100 Subject: [PATCH] =?UTF-8?q?Issue=20#10885:=20gimp-palette-get-colors=20war?= =?UTF-8?q?ning=20and=20critical=20when=E2=80=A6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit … accessed from Python. Creating a new function gimp_value_array_get_color_array(). This should normally not be needed (it isn't in C), but because of GObject Introspection limitation and the fact that pygobject will automatically try to convert GValue to the embedded value, we get this weird situation where the result is unusable in Python for certain types. One of these types is GimpColorArray. I suggest an annotation request to GObject Introspection: https://gitlab.gnome.org/GNOME/gobject-introspection/-/issues/492 I think that with such annotation, followed as a second step by pygobject support, correctly handling NULL terminated C arrays generically should be feasible by bindings. --- libgimpbase/gimpbase.def | 1 + libgimpbase/gimpparamspecs.h | 13 +++++--- libgimpbase/gimpvaluearray.c | 42 +++++++++++++++++++++++++ libgimpbase/gimpvaluearray.h | 59 ++++++++++++++++++------------------ 4 files changed, 81 insertions(+), 34 deletions(-) diff --git a/libgimpbase/gimpbase.def b/libgimpbase/gimpbase.def index 137545f6b9..74fdd53447 100644 --- a/libgimpbase/gimpbase.def +++ b/libgimpbase/gimpbase.def @@ -220,6 +220,7 @@ EXPORTS gimp_utf8_strtrim gimp_value_array_append gimp_value_array_copy + gimp_value_array_get_color_array gimp_value_array_get_type gimp_value_array_index gimp_value_array_insert diff --git a/libgimpbase/gimpparamspecs.h b/libgimpbase/gimpparamspecs.h index 4461efa8c7..040aeafead 100644 --- a/libgimpbase/gimpparamspecs.h +++ b/libgimpbase/gimpparamspecs.h @@ -246,14 +246,19 @@ void gimp_value_take_float_array (GValue *value, gsize length); +/* + * GIMP_TYPE_COLOR_ARRAY + */ + /** - * GIMP_TYPE_COLOR_ARRAY: + * GimpColorArray: (array zero-terminated=1) (element-type GeglColor) * - * The #GType for a boxed type holding a %NULL-terminated array of GeglColor. + * A boxed type which is nothing more than an alias to a %NULL-terminated array + * of [class@Gegl.Color]. * * The code fragments in the following example show the use of a property of - * type %GIMP_TYPE_COLORV with g_object_class_install_property(), g_object_set() - * and g_object_get(). + * type %GIMP_TYPE_COLOR_ARRAY with g_object_class_install_property(), + * g_object_set() and g_object_get(). * * ```C * g_object_class_install_property (object_class, diff --git a/libgimpbase/gimpvaluearray.c b/libgimpbase/gimpvaluearray.c index 4ce140539c..6715f76b95 100644 --- a/libgimpbase/gimpvaluearray.c +++ b/libgimpbase/gimpvaluearray.c @@ -22,11 +22,13 @@ #include +#include #include #include #include "gimpbasetypes.h" +#include "gimpparamspecs.h" #include "gimpvaluearray.h" @@ -75,6 +77,12 @@ G_DEFINE_BOXED_TYPE (GimpValueArray, gimp_value_array, * * Return a pointer to the value at @index contained in @value_array. * + * *Note*: in binding languages, some custom types fail to be correctly passed + * through. For these types, you should use specific functions. + * For instance, in the Python binding, a [type@ColorArray] `GValue` + * won't be usable with this function. You should use instead + * [method@ValueArray.get_color_array]. + * * Returns: (transfer none): pointer to a value at @index in @value_array * * Since: 2.10 @@ -89,6 +97,40 @@ gimp_value_array_index (const GimpValueArray *value_array, return value_array->values + index; } +/** + * gimp_value_array_get_color_array: + * @value_array: #GimpValueArray to get a value from + * @index: index of the value of interest + * + * Return a pointer to the value at @index contained in @value_array. This value + * is supposed to be a [type@ColorArray]. + * + * Returns: (transfer none) (array zero-terminated=1): the [type@ColorArray] stored at @index in @value_array. + * + * Since: 3.0 + */ +/* XXX See: https://gitlab.gnome.org/GNOME/gimp/-/issues/10885#note_2030308 + * This explains why we created a specific function for GimpColorArray, instead + * of using the generic gimp_value_array_index(). + */ +GeglColor ** +gimp_value_array_get_color_array (const GimpValueArray *value_array, + gint index) +{ + GValue *value; + GimpColorArray colors; + + g_return_val_if_fail (value_array != NULL, NULL); + g_return_val_if_fail (index < value_array->n_values, NULL); + + value = value_array->values + index; + g_return_val_if_fail (GIMP_VALUE_HOLDS_COLOR_ARRAY (value), NULL); + + colors = g_value_get_boxed (value); + + return colors; +} + static inline void value_array_grow (GimpValueArray *value_array, gint n_values, diff --git a/libgimpbase/gimpvaluearray.h b/libgimpbase/gimpvaluearray.h index 2ca4cf7704..0afd3eb326 100644 --- a/libgimpbase/gimpvaluearray.h +++ b/libgimpbase/gimpvaluearray.h @@ -38,43 +38,42 @@ G_BEGIN_DECLS #define GIMP_TYPE_VALUE_ARRAY (gimp_value_array_get_type ()) -GType gimp_value_array_get_type (void) G_GNUC_CONST; +GType gimp_value_array_get_type (void) G_GNUC_CONST; -GimpValueArray * gimp_value_array_new (gint n_prealloced); -GimpValueArray * gimp_value_array_new_from_types - (gchar **error_msg, - GType first_type, - ...); -GimpValueArray * gimp_value_array_new_from_types_valist - (gchar **error_msg, - GType first_type, - va_list va_args); -GimpValueArray * gimp_value_array_new_from_values - (const GValue *values, - gint n_values); +GimpValueArray * gimp_value_array_new (gint n_prealloced); +GimpValueArray * gimp_value_array_new_from_types (gchar **error_msg, + GType first_type, + ...); +GimpValueArray * gimp_value_array_new_from_types_valist (gchar **error_msg, + GType first_type, + va_list va_args); +GimpValueArray * gimp_value_array_new_from_values (const GValue *values, + gint n_values); -GimpValueArray * gimp_value_array_copy (const GimpValueArray *value_array); +GimpValueArray * gimp_value_array_copy (const GimpValueArray *value_array); -GimpValueArray * gimp_value_array_ref (GimpValueArray *value_array); -void gimp_value_array_unref (GimpValueArray *value_array); +GimpValueArray * gimp_value_array_ref (GimpValueArray *value_array); +void gimp_value_array_unref (GimpValueArray *value_array); -gint gimp_value_array_length (const GimpValueArray *value_array); +gint gimp_value_array_length (const GimpValueArray *value_array); -GValue * gimp_value_array_index (const GimpValueArray *value_array, - gint index); +GValue * gimp_value_array_index (const GimpValueArray *value_array, + gint index); +GeglColor ** gimp_value_array_get_color_array (const GimpValueArray *value_array, + gint index); -GimpValueArray * gimp_value_array_prepend (GimpValueArray *value_array, - const GValue *value); -GimpValueArray * gimp_value_array_append (GimpValueArray *value_array, - const GValue *value); -GimpValueArray * gimp_value_array_insert (GimpValueArray *value_array, - gint index, - const GValue *value); +GimpValueArray * gimp_value_array_prepend (GimpValueArray *value_array, + const GValue *value); +GimpValueArray * gimp_value_array_append (GimpValueArray *value_array, + const GValue *value); +GimpValueArray * gimp_value_array_insert (GimpValueArray *value_array, + gint index, + const GValue *value); -GimpValueArray * gimp_value_array_remove (GimpValueArray *value_array, - gint index); -void gimp_value_array_truncate (GimpValueArray *value_array, - gint n_values); +GimpValueArray * gimp_value_array_remove (GimpValueArray *value_array, + gint index); +void gimp_value_array_truncate (GimpValueArray *value_array, + gint n_values); /*