From 65f8afee68460359e094474f3b96ce063137ddab Mon Sep 17 00:00:00 2001 From: Jehan Date: Wed, 27 Dec 2023 01:07:19 +0900 Subject: [PATCH] =?UTF-8?q?app,=20libgimp,=20libgimpbase,=20pdb:=20GimpCol?= =?UTF-8?q?orArray=20as=20a=20typedef=20to=E2=80=A6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit … NULL-terminated array of GeglColor is now a boxed type usable in PDB. --- app/pdb/palette-cmds.c | 33 +++------ libgimp/gimpgpparams-body.c | 91 ++++++++++++++++++++++++ libgimp/gimppalette_pdb.c | 21 ++---- libgimp/gimppalette_pdb.h | 3 +- libgimpbase/gimpbase.def | 4 ++ libgimpbase/gimpchoice.c | 1 + libgimpbase/gimpparamspecs.c | 81 ++++++++++++++++++++++ libgimpbase/gimpparamspecs.h | 44 ++++++++++++ libgimpbase/gimpprotocol.c | 130 +++++++++++++++++++++++++++++++++++ libgimpbase/gimpprotocol.h | 9 +++ pdb/app.pl | 9 +-- pdb/groups/palette.pdb | 14 ++-- pdb/pdb.pl | 21 +++--- 13 files changed, 399 insertions(+), 62 deletions(-) diff --git a/app/pdb/palette-cmds.c b/app/pdb/palette-cmds.c index be17a693b7..dc30edb7f4 100644 --- a/app/pdb/palette-cmds.c +++ b/app/pdb/palette-cmds.c @@ -147,27 +147,24 @@ palette_get_colors_invoker (GimpProcedure *procedure, gboolean success = TRUE; GimpValueArray *return_vals; GimpPalette *palette; - gint num_colors = 0; - GimpRGB *colors = NULL; + GeglColor **colors = NULL; palette = g_value_get_object (gimp_value_array_index (args, 0)); if (success) { GList *list = gimp_palette_get_colors (palette); + gint num_colors; gint i; num_colors = gimp_palette_get_n_colors (palette); - colors = g_new (GimpRGB, num_colors); + colors = g_new0 (GeglColor *, num_colors + 1); for (i = 0; i < num_colors; i++, list = g_list_next (list)) { GimpPaletteEntry *entry = list->data; - GimpRGB rgb; - /* TODO: we need a geglcolorarray type! */ - gegl_color_get_pixel (entry->color, babl_format ("R'G'B'A double"), &rgb); - colors[i] = rgb; + colors[i] = gegl_color_duplicate (entry->color); } } @@ -175,10 +172,7 @@ palette_get_colors_invoker (GimpProcedure *procedure, error ? *error : NULL); if (success) - { - g_value_set_int (gimp_value_array_index (return_vals, 1), num_colors); - gimp_value_take_rgb_array (gimp_value_array_index (return_vals, 2), colors, num_colors); - } + g_value_take_boxed (gimp_value_array_index (return_vals, 1), colors); return return_vals; } @@ -558,7 +552,7 @@ register_palette_procs (GimpPDB *pdb) "gimp-palette-get-colors"); gimp_procedure_set_static_help (procedure, "Gets colors in the palette.", - "Returns an array of colors in the palette.", + "Returns an array of colors in the palette. Free the returned array with 'gimp-color-array-free'.", NULL); gimp_procedure_set_static_attribution (procedure, "Sven Neumann ", @@ -571,16 +565,11 @@ register_palette_procs (GimpPDB *pdb) FALSE, GIMP_PARAM_READWRITE)); gimp_procedure_add_return_value (procedure, - g_param_spec_int ("num-colors", - "num colors", - "Length of the colors array", - 0, G_MAXINT32, 0, - GIMP_PARAM_READWRITE)); - gimp_procedure_add_return_value (procedure, - gimp_param_spec_rgb_array ("colors", - "colors", - "The colors in the palette", - GIMP_PARAM_READWRITE)); + g_param_spec_boxed ("colors", + "colors", + "The colors in the palette", + GIMP_TYPE_COLOR_ARRAY, + GIMP_PARAM_READWRITE)); gimp_pdb_register_procedure (pdb, procedure); g_object_unref (procedure); diff --git a/libgimp/gimpgpparams-body.c b/libgimp/gimpgpparams-body.c index a45d5bdc0b..71b002b334 100644 --- a/libgimp/gimpgpparams-body.c +++ b/libgimp/gimpgpparams-body.c @@ -689,6 +689,58 @@ gimp_gp_param_to_value (gpointer gimp, param->data.d_array.size / sizeof (GimpRGB)); } + else if (GIMP_VALUE_HOLDS_COLOR_ARRAY (value)) + { + GeglColor **colors; + + colors = g_new0 (GeglColor *, param->data.d_color_array.size + 1); + + for (gint i = 0; i < param->data.d_color_array.size; i++) + { + GeglColor *color; + const Babl *format = NULL; + const Babl *space = NULL; + GimpColorProfile *profile = NULL; + const gchar *encoding; + gint bpp; + + encoding = param->data.d_color_array.colors[i].encoding; + if (param->data.d_color_array.colors[i].profile_size > 0) + profile = gimp_color_profile_new_from_icc_profile (param->data.d_color_array.colors[i].profile_data, + param->data.d_color_array.colors[i].profile_size, + NULL); + + if (profile) + { + GError *error = NULL; + + space = gimp_color_profile_get_space (profile, + GIMP_COLOR_RENDERING_INTENT_RELATIVE_COLORIMETRIC, + &error); + + if (! space) + { + g_printerr ("%s: failed to create Babl space from profile: %s\n", + G_STRFUNC, error->message); + g_clear_error (&error); + } + g_object_unref (profile); + } + format = babl_format_with_space (encoding, space); + color = gegl_color_new ("black"); + + bpp = babl_format_get_bytes_per_pixel (format); + if (bpp != param->data.d_color_array.colors[i].size) + g_printerr ("%s: encoding \"%s\" expects %d bpp but data size is %d bpp.\n", + G_STRFUNC, encoding, bpp, param->data.d_color_array.colors[i].size); + else + gegl_color_set_pixel (color, format, param->data.d_color_array.colors[i].data); + + colors[i] = color; + } + + g_value_take_boxed (value, colors); + } else if (GIMP_VALUE_HOLDS_OBJECT_ARRAY (value)) { GType object_type; @@ -1004,6 +1056,41 @@ gimp_value_to_gp_param (const GValue *value, param->data.d_array.data = NULL; } } + else if (GIMP_VALUE_HOLDS_COLOR_ARRAY (value)) + { + GeglColor **colors = g_value_get_boxed (value); + + param->param_type = GP_PARAM_TYPE_COLOR_ARRAY; + + if (colors != NULL) + { + param->data.d_color_array.size = gimp_color_array_get_length (colors); + param->data.d_color_array.colors = g_new0 (GPParamColor, + param->data.d_color_array.size); + for (gint i = 0; i < param->data.d_color_array.size; i++) + { + const Babl *format; + int icc_length = 0; + + format = gegl_color_get_format (colors[i]); + + param->data.d_color_array.colors[i].size = babl_format_get_bytes_per_pixel (format); + gegl_color_get_pixel (colors[i], format, ¶m->data.d_color_array.colors[i].data); + + param->data.d_color_array.colors[i].encoding = (gchar *) babl_format_get_encoding (format); + + if (babl_format_get_space (format) != babl_space ("sRGB")) + param->data.d_color_array.colors[i].profile_data = (guint8 *) babl_space_get_icc (babl_format_get_space (format), + &icc_length); + param->data.d_gegl_color.profile_size = icc_length; + } + } + else + { + param->data.d_color_array.size = 0; + param->data.d_color_array.colors = NULL; + } + } else if (G_VALUE_HOLDS (value, G_TYPE_BYTES)) { GBytes *bytes = g_value_get_boxed (value); @@ -1188,6 +1275,10 @@ _gimp_gp_params_free (GPParam *params, case GP_PARAM_TYPE_GEGL_COLOR: break; + case GP_PARAM_TYPE_COLOR_ARRAY: + g_free (params[i].data.d_color_array.colors); + break; + case GP_PARAM_TYPE_ARRAY: if (full_copy) g_free (params[i].data.d_array.data); diff --git a/libgimp/gimppalette_pdb.c b/libgimp/gimppalette_pdb.c index 22dad8e21c..e021131181 100644 --- a/libgimp/gimppalette_pdb.c +++ b/libgimp/gimppalette_pdb.c @@ -150,25 +150,23 @@ gimp_palette_get_color_count (GimpPalette *palette) /** * gimp_palette_get_colors: * @palette: The palette. - * @num_colors: (out): Length of the colors array. * * Gets colors in the palette. * - * Returns an array of colors in the palette. + * Returns an array of colors in the palette. Free the returned array + * with gimp_color_array_free(). * - * Returns: (array length=num_colors) (element-type GimpRGB) (transfer full): + * Returns: (array zero-terminated=1) (transfer full): * The colors in the palette. - * The returned value must be freed with g_free(). * * Since: 2.6 **/ -GimpRGB * -gimp_palette_get_colors (GimpPalette *palette, - gint *num_colors) +GeglColor ** +gimp_palette_get_colors (GimpPalette *palette) { GimpValueArray *args; GimpValueArray *return_vals; - GimpRGB *colors = NULL; + GeglColor **colors = NULL; args = gimp_value_array_new_from_types (NULL, GIMP_TYPE_PALETTE, palette, @@ -179,13 +177,8 @@ gimp_palette_get_colors (GimpPalette *palette, args); gimp_value_array_unref (args); - *num_colors = 0; - if (GIMP_VALUES_GET_ENUM (return_vals, 0) == GIMP_PDB_SUCCESS) - { - *num_colors = GIMP_VALUES_GET_INT (return_vals, 1); - colors = GIMP_VALUES_DUP_RGB_ARRAY (return_vals, 2); - } + colors = gimp_color_array_copy (g_value_get_boxed (gimp_value_array_index (return_vals, 1))); gimp_value_array_unref (return_vals); diff --git a/libgimp/gimppalette_pdb.h b/libgimp/gimppalette_pdb.h index b779f3aa99..8ac5777486 100644 --- a/libgimp/gimppalette_pdb.h +++ b/libgimp/gimppalette_pdb.h @@ -35,8 +35,7 @@ G_BEGIN_DECLS GimpPalette* gimp_palette_new (const gchar *name); GimpPalette* gimp_palette_get_by_name (const gchar *name); gint gimp_palette_get_color_count (GimpPalette *palette); -GimpRGB* gimp_palette_get_colors (GimpPalette *palette, - gint *num_colors); +GeglColor** gimp_palette_get_colors (GimpPalette *palette); gint gimp_palette_get_columns (GimpPalette *palette); gboolean gimp_palette_set_columns (GimpPalette *palette, gint columns); diff --git a/libgimpbase/gimpbase.def b/libgimpbase/gimpbase.def index c81106b008..137545f6b9 100644 --- a/libgimpbase/gimpbase.def +++ b/libgimpbase/gimpbase.def @@ -29,6 +29,10 @@ EXPORTS gimp_choice_new_with_values gimp_choice_set_sensitive gimp_clone_type_get_type + gimp_color_array_copy + gimp_color_array_free + gimp_color_array_get_length + gimp_color_array_get_type gimp_color_tag_get_type gimp_component_type_get_type gimp_convert_palette_type_get_type diff --git a/libgimpbase/gimpchoice.c b/libgimpbase/gimpchoice.c index 24a01af0b1..cfe294c909 100644 --- a/libgimpbase/gimpchoice.c +++ b/libgimpbase/gimpchoice.c @@ -20,6 +20,7 @@ #include "config.h" +#include #include #include "gimpbasetypes.h" diff --git a/libgimpbase/gimpparamspecs.c b/libgimpbase/gimpparamspecs.c index 0523d7cefe..134a9740b3 100644 --- a/libgimpbase/gimpparamspecs.c +++ b/libgimpbase/gimpparamspecs.c @@ -756,6 +756,87 @@ gimp_value_take_float_array (GValue *value, length * sizeof (gdouble)); } + +/* + * GIMP_TYPE_COLOR_ARRAY + */ + +GType +gimp_color_array_get_type (void) +{ + static gsize static_g_define_type_id = 0; + + if (g_once_init_enter (&static_g_define_type_id)) + { + GType g_define_type_id = + g_boxed_type_register_static (g_intern_static_string ("GimpColorArray"), + (GBoxedCopyFunc) gimp_color_array_copy, + (GBoxedFreeFunc) gimp_color_array_free); + + g_once_init_leave (&static_g_define_type_id, g_define_type_id); + } + + return static_g_define_type_id; +} + +/** + * gimp_color_array_copy: + * @array: an array of colors. + * + * Creates a new #GimpColorArray containing a deep copy of a %NULL-terminated + * array of [class@Gegl.Color]. + * + * Returns: (transfer full): a new #GimpColorArray. + **/ +GimpColorArray +gimp_color_array_copy (GimpColorArray array) +{ + GeglColor **copy; + gint length = gimp_color_array_get_length (array); + + copy = g_malloc0 (sizeof (GeglColor *) * (length + 1)); + + for (gint i = 0; i < length; i++) + copy[i] = gegl_color_duplicate (array[i]); + + return copy; +} + +/** + * gimp_color_array_free: + * @array: an array of colors. + * + * Frees a %NULL-terminated array of [class@Gegl.Color]. + **/ +void +gimp_color_array_free (GimpColorArray array) +{ + gint i = 0; + + while (array[i] != NULL) + g_object_unref (array[i++]); + + g_free (array); +} + +/** + * gimp_color_array_get_length: + * @array: an array of colors. + * + * Returns: the number of [class@Gegl.Color] in @array. + **/ +gint +gimp_color_array_get_length (GimpColorArray array) +{ + gint length = 0; + + while (array[length] != NULL) + length++; + + return length; +} + + /* * GIMP_TYPE_RGB_ARRAY */ diff --git a/libgimpbase/gimpparamspecs.h b/libgimpbase/gimpparamspecs.h index 0650d8f9b6..4461efa8c7 100644 --- a/libgimpbase/gimpparamspecs.h +++ b/libgimpbase/gimpparamspecs.h @@ -246,6 +246,50 @@ void gimp_value_take_float_array (GValue *value, gsize length); +/** + * GIMP_TYPE_COLOR_ARRAY: + * + * The #GType for a boxed type holding a %NULL-terminated array of GeglColor. + * + * 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(). + * + * ```C + * g_object_class_install_property (object_class, + * PROP_COLORS, + * g_param_spec_boxed ("colors", + * _("Colors"), + * _("List of colors"), + * GIMP_TYPE_COLOR_ARRAY, + * G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + * + * GeglColor *colors[] = { gegl_color_new ("red"), gegl_color_new ("blue"), NULL }; + * + * g_object_set (obj, "colors", colors, NULL); + * + * GeglColors **colors; + * + * g_object_get (obj, "colors", &colors, NULL); + * gimp_color_array_free (colors); + * ``` + * + * Since: 3.0 + */ +typedef GeglColor** GimpColorArray; + +#define GIMP_TYPE_COLOR_ARRAY (gimp_color_array_get_type ()) +#define GIMP_VALUE_HOLDS_COLOR_ARRAY(value) (G_TYPE_CHECK_VALUE_TYPE ((value), GIMP_TYPE_COLOR_ARRAY)) + + +GType gimp_color_array_get_type (void) G_GNUC_CONST; + +GimpColorArray gimp_color_array_copy (GimpColorArray array); +void gimp_color_array_free (GimpColorArray array); +gint gimp_color_array_get_length (GimpColorArray array); + + + /* * GIMP_TYPE_RGB_ARRAY */ diff --git a/libgimpbase/gimpprotocol.c b/libgimpbase/gimpprotocol.c index cc895de8bf..07a6d9dcbb 100644 --- a/libgimpbase/gimpprotocol.c +++ b/libgimpbase/gimpprotocol.c @@ -18,6 +18,7 @@ #include "config.h" +#include #include #include "gimpbasetypes.h" @@ -1778,6 +1779,97 @@ _gp_params_read (GIOChannel *channel, break; + case GP_PARAM_TYPE_COLOR_ARRAY: + if (! _gimp_wire_read_int32 (channel, + &(*params)[i].data.d_color_array.size, 1, + user_data)) + goto cleanup; + + (*params)[i].data.d_color_array.colors = g_new0 (GPParamColor, + (*params)[i].data.d_color_array.size); + + for (gint j = 0; j < (*params)[i].data.d_color_array.size; j++) + { + /* Read the color data. */ + if (! _gimp_wire_read_int32 (channel, + &(*params)[i].data.d_color_array.colors[j].size, 1, + user_data)) + { + for (gint k = 0; k < j; j++) + { + g_free ((*params)[i].data.d_color_array.colors[k].encoding); + g_free ((*params)[i].data.d_color_array.colors[k].profile_data); + } + g_clear_pointer (&(*params)[i].data.d_color_array.colors, g_free); + goto cleanup; + } + + if ((*params)[i].data.d_color_array.colors[j].size > 40 || + ! _gimp_wire_read_int8 (channel, + (*params)[i].data.d_color_array.colors[j].data, + (*params)[i].data.d_color_array.colors[j].size, + user_data)) + { + for (gint k = 0; k < j; j++) + { + g_free ((*params)[i].data.d_color_array.colors[k].encoding); + g_free ((*params)[i].data.d_color_array.colors[k].profile_data); + } + g_clear_pointer (&(*params)[i].data.d_color_array.colors, g_free); + goto cleanup; + } + + /* Read encoding. */ + if (! _gimp_wire_read_string (channel, + &(*params)[i].data.d_color_array.colors[j].encoding, 1, + user_data)) + { + for (gint k = 0; k < j; j++) + { + g_free ((*params)[i].data.d_color_array.colors[k].encoding); + g_free ((*params)[i].data.d_color_array.colors[k].profile_data); + } + g_clear_pointer (&(*params)[i].data.d_color_array.colors, g_free); + goto cleanup; + } + + /* Read space (profile data). */ + if (! _gimp_wire_read_int32 (channel, + &(*params)[i].data.d_color_array.colors[j].profile_size, 1, + user_data)) + { + for (gint k = 0; k < j; j++) + { + g_free ((*params)[i].data.d_color_array.colors[k].encoding); + g_free ((*params)[i].data.d_color_array.colors[k].profile_data); + } + g_clear_pointer (&(*params)[i].data.d_color_array.colors[j].encoding, g_free); + g_clear_pointer (&(*params)[i].data.d_color_array.colors, g_free); + goto cleanup; + } + + if ((*params)[i].data.d_color_array.colors[j].profile_size > 0) + { + (*params)[i].data.d_color_array.colors[j].profile_data = g_new0 (guint8, (*params)[i].data.d_color_array.colors[j].profile_size); + if (! _gimp_wire_read_int8 (channel, + (*params)[i].data.d_color_array.colors[j].profile_data, + (*params)[i].data.d_color_array.colors[j].profile_size, + user_data)) + { + for (gint k = 0; k < j; j++) + { + g_free ((*params)[i].data.d_color_array.colors[k].encoding); + g_free ((*params)[i].data.d_color_array.colors[k].profile_data); + } + g_clear_pointer (&(*params)[i].data.d_color_array.colors[j].encoding, g_free); + g_clear_pointer (&(*params)[i].data.d_color_array.colors[j].profile_data, g_free); + g_clear_pointer (&(*params)[i].data.d_color_array.colors, g_free); + goto cleanup; + } + } + } + break; + case GP_PARAM_TYPE_ARRAY: if (! _gimp_wire_read_int32 (channel, &(*params)[i].data.d_array.size, 1, @@ -1993,6 +2085,35 @@ _gp_params_write (GIOChannel *channel, return; break; + case GP_PARAM_TYPE_COLOR_ARRAY: + if (! _gimp_wire_write_int32 (channel, + (const guint32 *) ¶ms[i].data.d_color_array.size, 1, + user_data)) + return; + + for (gint j = 0; j < params[i].data.d_color_array.size; j++) + { + if (! _gimp_wire_write_int32 (channel, + (const guint32 *) ¶ms[i].data.d_color_array.colors[j].size, 1, + user_data) || + ! _gimp_wire_write_int8 (channel, + (const guint8 *) params[i].data.d_color_array.colors[j].data, + params[i].data.d_color_array.colors[j].size, + user_data) || + ! _gimp_wire_write_string (channel, + ¶ms[i].data.d_color_array.colors[j].encoding, 1, + user_data) || + ! _gimp_wire_write_int32 (channel, + (const guint32 *) ¶ms[i].data.d_color_array.colors[j].profile_size, 1, + user_data) || + ! _gimp_wire_write_int8 (channel, + (const guint8 *) params[i].data.d_color_array.colors[j].profile_data, + params[i].data.d_color_array.colors[j].profile_size, + user_data)) + return; + } + break; + case GP_PARAM_TYPE_ARRAY: if (! _gimp_wire_write_int32 (channel, (const guint32 *) ¶ms[i].data.d_array.size, 1, @@ -2120,6 +2241,15 @@ _gp_params_destroy (GPParam *params, g_free (params[i].data.d_gegl_color.profile_data); break; + case GP_PARAM_TYPE_COLOR_ARRAY: + for (gint j = 0; j < params[i].data.d_color_array.size; j++) + { + g_free (params[i].data.d_color_array.colors[j].encoding); + g_free (params[i].data.d_color_array.colors[j].profile_data); + } + g_free (params[i].data.d_color_array.colors); + break; + case GP_PARAM_TYPE_ARRAY: g_free (params[i].data.d_array.data); break; diff --git a/libgimpbase/gimpprotocol.h b/libgimpbase/gimpprotocol.h index 47a9c71d7f..eaf2a7a56b 100644 --- a/libgimpbase/gimpprotocol.h +++ b/libgimpbase/gimpprotocol.h @@ -71,6 +71,7 @@ typedef enum GP_PARAM_TYPE_FILE, GP_PARAM_TYPE_COLOR, GP_PARAM_TYPE_GEGL_COLOR, + GP_PARAM_TYPE_COLOR_ARRAY, GP_PARAM_TYPE_PARASITE, GP_PARAM_TYPE_ARRAY, GP_PARAM_TYPE_ID_ARRAY, @@ -98,6 +99,7 @@ typedef struct _GPParam GPParam; typedef struct _GPParamArray GPParamArray; typedef struct _GPParamIDArray GPParamIDArray; typedef struct _GPParamColor GPParamColor; +typedef struct _GPParamColorArray GPParamColorArray; typedef struct _GPProcRun GPProcRun; typedef struct _GPProcReturn GPProcReturn; typedef struct _GPProcInstall GPProcInstall; @@ -271,6 +273,12 @@ struct _GPParamColor guint8 *profile_data; }; +struct _GPParamColorArray +{ + guint32 size; + GPParamColor *colors; +}; + struct _GPParam { GPParamType param_type; @@ -284,6 +292,7 @@ struct _GPParam gchar **d_strv; GBytes *d_bytes; GPParamColor d_gegl_color; + GPParamColorArray d_color_array; GimpRGB d_color; GimpParasite d_parasite; GPParamArray d_array; diff --git a/pdb/app.pl b/pdb/app.pl index 3be71c5327..29eac62e70 100644 --- a/pdb/app.pl +++ b/pdb/app.pl @@ -654,10 +654,11 @@ CODE } elsif ($pdbtype eq 'colorarray') { $pspec = < 'colors', type => 'colorarray', - desc => 'The colors in the palette', - array => { name => 'num_colors', - desc => 'Length of the colors array' } } + desc => 'The colors in the palette' } ); %invoke = ( code => <<'CODE' { GList *list = gimp_palette_get_colors (palette); + gint num_colors; gint i; num_colors = gimp_palette_get_n_colors (palette); - colors = g_new (GimpRGB, num_colors); + colors = g_new0 (GeglColor *, num_colors + 1); for (i = 0; i < num_colors; i++, list = g_list_next (list)) { GimpPaletteEntry *entry = list->data; - GimpRGB rgb; - /* TODO: we need a geglcolorarray type! */ - gegl_color_get_pixel (entry->color, babl_format ("R'G'B'A double"), &rgb); - colors[i] = rgb; + colors[i] = gegl_color_duplicate (entry->color); } } CODE diff --git a/pdb/pdb.pl b/pdb/pdb.pl index 44227f7214..dfe7ac9089 100644 --- a/pdb/pdb.pl +++ b/pdb/pdb.pl @@ -107,18 +107,17 @@ package Gimp::CodeGen::pdb; set_value_func => 'gimp_value_set_float_array ($value, $var, $var_len)', take_value_func => 'gimp_value_take_float_array ($value, $var, $var_len)' }, - colorarray => { name => 'COLORARRAY', - gtype => 'GIMP_TYPE_RGB_ARRAY', - type => 'GimpRGB *', - const_type => 'const GimpRGB *', - array => 1, + colorarray => { name => 'COLOR_ARRAY', + gtype => 'GIMP_TYPE_COLOR_ARRAY', + type => 'GeglColor **', + const_type => 'const GeglColor **', init_value => 'NULL', - in_annotate => '(element-type GimpRGB)', - out_annotate => '(element-type GimpRGB) (transfer full)', - get_value_func => '$var = gimp_value_get_rgb_array ($value)', - dup_value_func => '$var = GIMP_VALUES_DUP_RGB_ARRAY ($value)', - set_value_func => 'gimp_value_set_rgb_array ($value, $var, $var_len)', - take_value_func => 'gimp_value_take_rgb_array ($value, $var, $var_len)' }, + in_annotate => '(array zero-terminated=1)', + out_annotate => '(array zero-terminated=1) (transfer full)', + get_value_func => '$var = g_value_get_boxed ($value)', + dup_value_func => '$var = gimp_color_array_copy (g_value_get_boxed (gimp_value_array_index ($value)))', + set_value_func => 'g_value_set_boxed ($value, $var)', + take_value_func => 'g_value_take_boxed ($value, $var)' }, imagearray => { name => 'IMAGEARRAY', gtype => 'GIMP_TYPE_OBJECT_ARRAY',