Issue #10885: gimp-palette-get-colors warning and critical when…

… 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.
This commit is contained in:
Jehan 2024-02-28 22:13:57 +01:00
parent d6a134e6c1
commit 3f79f3589d
4 changed files with 81 additions and 34 deletions

View File

@ -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

View File

@ -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,

View File

@ -22,11 +22,13 @@
#include <string.h>
#include <gegl.h>
#include <glib-object.h>
#include <gobject/gvaluecollector.h>
#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,

View File

@ -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);
/*