From 6327d1b3ef4d2cf141b6d3a6f6e3cf5faa88c031 Mon Sep 17 00:00:00 2001 From: Jehan Date: Sun, 3 Nov 2024 13:12:33 +0100 Subject: [PATCH] app, libgimp, pdb, plug-ins: gimp_gradient_get_uniform_samples() returns an array of GeglColor. --- app/core/gimpgradient.c | 4 +- app/pdb/gradient-cmds.c | 37 ++++-------- libgimp/gimpgradient_pdb.c | 40 +++++-------- libgimp/gimpgradient_pdb.h | 6 +- libgimp/gimpgradientchooser.c | 28 +++++---- pdb/groups/gradient.pdb | 37 ++++-------- plug-ins/common/gradient-map.c | 33 ++++++---- plug-ins/common/sample-colorize.c | 32 +++++----- plug-ins/flame/flame.c | 17 +++--- .../fractal-explorer-dialogs.c | 60 ++++++++----------- plug-ins/gradient-flare/gradient-flare.c | 13 ++-- plug-ins/pagecurl/pagecurl.c | 17 ++++-- 12 files changed, 147 insertions(+), 177 deletions(-) diff --git a/app/core/gimpgradient.c b/app/core/gimpgradient.c index 148fc8a09a..c47e0eab06 100644 --- a/app/core/gimpgradient.c +++ b/app/core/gimpgradient.c @@ -456,8 +456,8 @@ gimp_gradient_get_extension (GimpData *data) * @blend_color_space: color space to use for blending RGB segments * @color: returns a newly allocated color * - * If you are iterating over an gradient, you should pass the the - * return value from the last call for @seg. + * If you are iterating over an gradient, you should pass the return + * value from the last call for @seg. * * Returns: the gradient segment the color is from **/ diff --git a/app/pdb/gradient-cmds.c b/app/pdb/gradient-cmds.c index 36e657f55c..ba0b2ea8bd 100644 --- a/app/pdb/gradient-cmds.c +++ b/app/pdb/gradient-cmds.c @@ -160,8 +160,7 @@ gradient_get_uniform_samples_invoker (GimpProcedure *procedure, GimpGradient *gradient; gint num_samples; gboolean reverse; - gsize num_color_samples = 0; - gdouble *color_samples = NULL; + GeglColor **color_samples = NULL; gradient = g_value_get_object (gimp_value_array_index (args, 0)); num_samples = g_value_get_int (gimp_value_array_index (args, 1)); @@ -174,30 +173,19 @@ gradient_get_uniform_samples_invoker (GimpProcedure *procedure, GimpGradientSegment *seg = NULL; gdouble pos = 0.0; gdouble delta = 1.0 / (num_samples - 1); - gdouble *sample; + GeglColor **sample; - num_color_samples = num_samples * 4; - - sample = color_samples = g_new0 (gdouble, num_color_samples); + sample = color_samples = g_new0 (GeglColor *, num_samples + 1); while (num_samples--) { - GeglColor *color = NULL; - seg = gimp_gradient_get_color_at (gradient, context, seg, pos, reverse, GIMP_GRADIENT_BLEND_RGB_PERCEPTUAL, - &color); - if (color) - gegl_color_get_pixel (color, babl_format ("R'G'B'A double"), sample); - /* TODO: should we really return a list of floats? What about a list - * of GeglColor? - */ + sample); - sample += 4; - pos += delta; - - g_clear_object (&color); + sample++, + pos += delta; } } else @@ -208,7 +196,7 @@ gradient_get_uniform_samples_invoker (GimpProcedure *procedure, error ? *error : NULL); if (success) - gimp_value_take_double_array (gimp_value_array_index (return_vals, 1), color_samples, num_color_samples); + g_value_take_boxed (gimp_value_array_index (return_vals, 1), color_samples); return return_vals; } @@ -1353,7 +1341,7 @@ register_gradient_procs (GimpPDB *pdb) "gimp-gradient-get-uniform-samples"); gimp_procedure_set_static_help (procedure, "Sample the gradient in uniform parts.", - "Samples colors uniformly across the gradient. It returns a list of floating-point values which correspond to the RGBA values for each sample. The minimum number of samples to take is 2, in which case the returned colors will correspond to the { 0.0, 1.0 } positions in the gradient. For example, if the number of samples is 3, the procedure will return the colors at positions { 0.0, 0.5, 1.0 }.", + "Samples colors uniformly across the gradient. It returns a list of colors for each sample. The minimum number of samples to take is 2, in which case the returned colors will correspond to the `{ 0.0, 1.0 }` positions in the gradient. For example, if the number of samples is 3, the procedure will return the colors at positions `{ 0.0, 0.5, 1.0 }`.", NULL); gimp_procedure_set_static_attribution (procedure, "Federico Mena Quintero", @@ -1380,10 +1368,11 @@ register_gradient_procs (GimpPDB *pdb) FALSE, GIMP_PARAM_READWRITE)); gimp_procedure_add_return_value (procedure, - gimp_param_spec_double_array ("color-samples", - "color samples", - "Color samples: { R1, G1, B1, A1, ..., Rn, Gn, Bn, An }", - GIMP_PARAM_READWRITE)); + g_param_spec_boxed ("color-samples", + "color samples", + "Color samples", + GIMP_TYPE_COLOR_ARRAY, + GIMP_PARAM_READWRITE)); gimp_pdb_register_procedure (pdb, procedure); g_object_unref (procedure); diff --git a/libgimp/gimpgradient_pdb.c b/libgimp/gimpgradient_pdb.c index 39e4087aea..50274bbe31 100644 --- a/libgimp/gimpgradient_pdb.c +++ b/libgimp/gimpgradient_pdb.c @@ -150,32 +150,29 @@ gimp_gradient_get_number_of_segments (GimpGradient *gradient) * @gradient: The gradient. * @num_samples: The number of samples to take. * @reverse: Use the reverse gradient. - * @num_color_samples: (out): Length of the color_samples array (4 * num_samples). - * @color_samples: (out) (array length=num_color_samples) (element-type gdouble) (transfer full): Color samples: { R1, G1, B1, A1, ..., Rn, Gn, Bn, An }. * * Sample the gradient in uniform parts. * * Samples colors uniformly across the gradient. It returns a list of - * floating-point values which correspond to the RGBA values for each - * sample. The minimum number of samples to take is 2, in which case - * the returned colors will correspond to the { 0.0, 1.0 } positions in - * the gradient. For example, if the number of samples is 3, the - * procedure will return the colors at positions { 0.0, 0.5, 1.0 }. + * colors for each sample. The minimum number of samples to take is 2, + * in which case the returned colors will correspond to the `{ 0.0, 1.0 + * }` positions in the gradient. For example, if the number of samples + * is 3, the procedure will return the colors at positions `{ 0.0, 0.5, + * 1.0 }`. * - * Returns: TRUE on success. + * Returns: (array zero-terminated=1) (transfer full): Color samples. + * The returned value must be freed with gimp_color_array_free(). * * Since: 2.2 **/ -gboolean -gimp_gradient_get_uniform_samples (GimpGradient *gradient, - gint num_samples, - gboolean reverse, - gsize *num_color_samples, - gdouble **color_samples) +GeglColor ** +gimp_gradient_get_uniform_samples (GimpGradient *gradient, + gint num_samples, + gboolean reverse) { GimpValueArray *args; GimpValueArray *return_vals; - gboolean success = TRUE; + GeglColor **color_samples = NULL; args = gimp_value_array_new_from_types (NULL, GIMP_TYPE_GRADIENT, gradient, @@ -188,19 +185,12 @@ gimp_gradient_get_uniform_samples (GimpGradient *gradient, args); gimp_value_array_unref (args); - *num_color_samples = 0; - *color_samples = NULL; - - success = GIMP_VALUES_GET_ENUM (return_vals, 0) == GIMP_PDB_SUCCESS; - - if (success) - { - *color_samples = GIMP_VALUES_DUP_DOUBLE_ARRAY (return_vals, 1, num_color_samples); - } + if (GIMP_VALUES_GET_ENUM (return_vals, 0) == GIMP_PDB_SUCCESS) + color_samples = gimp_color_array_copy (g_value_get_boxed (gimp_value_array_index (return_vals, 1))); gimp_value_array_unref (return_vals); - return success; + return color_samples; } /** diff --git a/libgimp/gimpgradient_pdb.h b/libgimp/gimpgradient_pdb.h index 0b9cea2ff4..848fc75221 100644 --- a/libgimp/gimpgradient_pdb.h +++ b/libgimp/gimpgradient_pdb.h @@ -35,11 +35,9 @@ G_BEGIN_DECLS GimpGradient* gimp_gradient_new (const gchar *name); GimpGradient* gimp_gradient_get_by_name (const gchar *name); gint gimp_gradient_get_number_of_segments (GimpGradient *gradient); -gboolean gimp_gradient_get_uniform_samples (GimpGradient *gradient, +GeglColor** gimp_gradient_get_uniform_samples (GimpGradient *gradient, gint num_samples, - gboolean reverse, - gsize *num_color_samples, - gdouble **color_samples); + gboolean reverse); gboolean gimp_gradient_get_custom_samples (GimpGradient *gradient, gsize num_samples, const gdouble *positions, diff --git a/libgimp/gimpgradientchooser.c b/libgimp/gimpgradientchooser.c index 32dc64f40c..1de423b007 100644 --- a/libgimp/gimpgradientchooser.c +++ b/libgimp/gimpgradientchooser.c @@ -216,21 +216,27 @@ get_gradient_data (GimpGradient *gradient, gsize *sample_count, gdouble **sample_array) { - gboolean result; - gdouble *samples; - gsize n_samples; + gboolean result = FALSE; + GeglColor **samples; - result = gimp_gradient_get_uniform_samples (gradient, - allocation_width, - FALSE, /* not reversed. */ - &n_samples, - &samples); + samples = gimp_gradient_get_uniform_samples (gradient, allocation_width, + FALSE /* not reversed. */); - if (result) + if (samples) { + gdouble *dsamples; + /* Return array of samples to dereferenced handles. */ - *sample_array = samples; - *sample_count = n_samples; + *sample_count = gimp_color_array_get_length (samples);; + *sample_array = dsamples = g_new0 (gdouble, *sample_count * 4); + for (gint i = 0; samples[i] != NULL; i++) + { + gegl_color_get_pixel (samples[i], babl_format ("R'G'B'A double"), dsamples); + dsamples += 4; + } + gimp_color_array_free (samples); + + result = TRUE; } /* When result is true, caller must free the array. */ diff --git a/pdb/groups/gradient.pdb b/pdb/groups/gradient.pdb index 64983d250f..16d721ab7b 100644 --- a/pdb/groups/gradient.pdb +++ b/pdb/groups/gradient.pdb @@ -137,11 +137,11 @@ sub gradient_get_uniform_samples { $blurb = 'Sample the gradient in uniform parts.'; $help = <<'HELP'; -Samples colors uniformly across the gradient. It returns a list of floating-point values -which correspond to the RGBA values for each sample. The minimum number of -samples to take is 2, in which case the returned colors will correspond to the -{ 0.0, 1.0 } positions in the gradient. For example, if the number of samples -is 3, the procedure will return the colors at positions { 0.0, 0.5, 1.0 }. +Samples colors uniformly across the gradient. It returns a list of +colors for each sample. The minimum number of samples to take is 2, in +which case the returned colors will correspond to the `{ 0.0, 1.0 }` +positions in the gradient. For example, if the number of samples is 3, +the procedure will return the colors at positions `{ 0.0, 0.5, 1.0 }`. HELP &federico_pdb_misc('1997', '2.2'); @@ -155,10 +155,8 @@ HELP ); @outargs = ( - { name => 'color_samples', type => 'doublearray', void_ret => 1, - desc => 'Color samples: { R1, G1, B1, A1, ..., Rn, Gn, Bn, An }', - array => { desc => 'Length of the color_samples array (4 * - num_samples)' } } + { name => 'color_samples', type => 'colorarray', + desc => 'Color samples' } ); %invoke = ( @@ -169,30 +167,19 @@ HELP GimpGradientSegment *seg = NULL; gdouble pos = 0.0; gdouble delta = 1.0 / (num_samples - 1); - gdouble *sample; + GeglColor **sample; - num_color_samples = num_samples * 4; - - sample = color_samples = g_new0 (gdouble, num_color_samples); + sample = color_samples = g_new0 (GeglColor *, num_samples + 1); while (num_samples--) { - GeglColor *color = NULL; - seg = gimp_gradient_get_color_at (gradient, context, seg, pos, reverse, GIMP_GRADIENT_BLEND_RGB_PERCEPTUAL, - &color); - if (color) - gegl_color_get_pixel (color, babl_format ("R'G'B'A double"), sample); - /* TODO: should we really return a list of floats? What about a list - * of GeglColor? - */ + sample); - sample += 4; - pos += delta; - - g_clear_object (&color); + sample++, + pos += delta; } } else diff --git a/plug-ins/common/gradient-map.c b/plug-ins/common/gradient-map.c index 1d2cc238c3..5a36de2cff 100644 --- a/plug-ins/common/gradient-map.c +++ b/plug-ins/common/gradient-map.c @@ -414,25 +414,34 @@ map (GeglBuffer *buffer, static gdouble * get_samples_gradient (GimpDrawable *drawable) { - GimpGradient *gradient; - - gsize n_d_samples; - gdouble *d_samples = NULL; + GimpGradient *gradient; + GeglColor **colors; + const Babl *format_dst; + gdouble *d_samples; + gint bpp; gradient = gimp_context_get_gradient (); /* FIXME: "reverse" hardcoded to FALSE. */ - gimp_gradient_get_uniform_samples (gradient, NSAMPLES, FALSE, - &n_d_samples, &d_samples); + colors = gimp_gradient_get_uniform_samples (gradient, NSAMPLES, FALSE); - if (! gimp_drawable_is_rgb (drawable)) + if (gimp_drawable_is_rgb (drawable)) { - const Babl *format_src = babl_format ("R'G'B'A double"); - const Babl *format_dst = babl_format ("Y'A double"); - const Babl *fish = babl_fish (format_src, format_dst); - - babl_process (fish, d_samples, d_samples, NSAMPLES); + format_dst = babl_format ("R'G'B'A double"); + bpp = 4; } + else + { + format_dst = babl_format ("Y'A double"); + bpp = 2; + } + + d_samples = g_new0 (gdouble, NSAMPLES * bpp); + + for (gint i = 0; colors[i] != NULL; i++) + gegl_color_get_pixel (colors[i], format_dst, &d_samples[i * bpp]); + + gimp_color_array_free (colors); return d_samples; } diff --git a/plug-ins/common/sample-colorize.c b/plug-ins/common/sample-colorize.c index 8f514b7318..8844cf1b28 100644 --- a/plug-ins/common/sample-colorize.c +++ b/plug-ins/common/sample-colorize.c @@ -2405,36 +2405,34 @@ fill_missing_colors (void) static void get_gradient (gint mode) { - GimpGradient *gradient; - - gsize n_f_samples; - gdouble *f_samples; - gdouble *f_samp; /* float samples */ - gint lum; + GimpGradient *gradient; + GeglColor **colors; + const Babl *format_dst = babl_format ("RGB u8"); + guchar *g_sample_color_tab_p; + gint lum; free_colors (); gradient = gimp_context_get_gradient (); - gimp_gradient_get_uniform_samples (gradient, 256 /* n_samples */, - mode == SMP_INV_GRADIENT, - &n_f_samples, &f_samples); + colors = gimp_gradient_get_uniform_samples (gradient, 256 /* n_samples */, + mode == SMP_INV_GRADIENT); + g_return_if_fail (gimp_color_array_get_length (colors) == 256); + + g_sample_color_tab_p = g_sample_color_tab; for (lum = 0; lum < 256; lum++) { - f_samp = &f_samples[lum * 4]; + gegl_color_get_pixel (colors[lum], format_dst, g_sample_color_tab_p); - g_sample_color_tab[3 * lum + 0] = f_samp[0] * 255; - g_sample_color_tab[3 * lum + 1] = f_samp[1] * 255; - g_sample_color_tab[3 * lum + 2] = f_samp[2] * 255; - - g_lum_tab[lum].col_ptr = - new_samp_color (&g_sample_color_tab[3 * lum]); + g_lum_tab[lum].col_ptr = new_samp_color (g_sample_color_tab_p); g_lum_tab[lum].from_sample = TRUE; g_lum_tab[lum].all_samples = 1; + + g_sample_color_tab_p += 3; } - g_free (f_samples); + gimp_color_array_free (colors); } static void diff --git a/plug-ins/flame/flame.c b/plug-ins/flame/flame.c index 0810455a02..1100b43ab7 100644 --- a/plug-ins/flame/flame.c +++ b/plug-ins/flame/flame.c @@ -382,20 +382,17 @@ drawable_to_cmap (control_point *cp) } else if (GRADIENT_DRAWABLE == config.cmap_drawable_id) { - GimpGradient *gradient = gimp_context_get_gradient (); - - gsize num; - gdouble *g; + GimpGradient *gradient = gimp_context_get_gradient (); + GeglColor **colors; + const Babl *format_dst = babl_format ("R'G'B' double"); /* FIXME: "reverse" hardcoded to FALSE. */ - gimp_gradient_get_uniform_samples (gradient, 256, FALSE, - &num, &g); - + colors = gimp_gradient_get_uniform_samples (gradient, 256, FALSE); for (i = 0; i < 256; i++) - for (j = 0; j < 3; j++) - cp->cmap[i][j] = g[i*4 + j]; - g_free (g); + gegl_color_get_pixel (colors[i], format_dst, &(cp->cmap[i][0])); + + gimp_color_array_free (colors); } else { diff --git a/plug-ins/fractal-explorer/fractal-explorer-dialogs.c b/plug-ins/fractal-explorer/fractal-explorer-dialogs.c index 0b25eed42c..01ab7bb7fb 100644 --- a/plug-ins/fractal-explorer/fractal-explorer-dialogs.c +++ b/plug-ins/fractal-explorer/fractal-explorer-dialogs.c @@ -36,8 +36,7 @@ #define ZOOM_UNDO_SIZE 100 -static gsize n_gradient_samples = 0; -static gdouble *gradient_samples = NULL; +static GeglColor **gradient_samples = NULL; static GimpGradient *gradient = NULL; static gboolean ready_now = FALSE; static gchar *tpath = NULL; @@ -1186,22 +1185,23 @@ set_cmap_preview (GimpProcedureConfig *config) void make_color_map (GimpProcedureConfig *config) { - gint i; - gint r; - gint gr; - gint bl; - gdouble redstretch; - gdouble greenstretch; - gdouble bluestretch; - gdouble pi = atan (1) * 4; - gint n_colors; - gint color_mode; - gint red_mode; - gint green_mode; - gint blue_mode; - gboolean red_invert; - gboolean green_invert; - gboolean blue_invert; + const Babl *colormap_format = babl_format ("R'G'B' u8"); + gint i; + gint r; + gint gr; + gint bl; + gdouble redstretch; + gdouble greenstretch; + gdouble bluestretch; + gdouble pi = atan (1) * 4; + gint n_colors; + gint color_mode; + gint red_mode; + gint green_mode; + gint blue_mode; + gboolean red_invert; + gboolean green_invert; + gboolean blue_invert; g_object_get (config, "n-colors", &n_colors, @@ -1224,11 +1224,8 @@ make_color_map (GimpProcedureConfig *config) { GimpGradient *gradient = gimp_context_get_gradient (); - gimp_gradient_get_uniform_samples (gradient, - n_colors, - FALSE, - &n_gradient_samples, - &gradient_samples); + gradient_samples = gimp_gradient_get_uniform_samples (gradient, + n_colors, FALSE); } redstretch *= 127.5; @@ -1238,9 +1235,7 @@ make_color_map (GimpProcedureConfig *config) for (i = 0; i < n_colors; i++) if (color_mode == 1) { - colormap[i].r = (guchar)(gradient_samples[i * 4] * 255.9); - colormap[i].g = (guchar)(gradient_samples[i * 4 + 1] * 255.9); - colormap[i].b = (guchar)(gradient_samples[i * 4 + 2] * 255.9); + gegl_color_get_pixel (gradient_samples[i], colormap_format, (void *) &(colormap[i])); } else { @@ -1587,8 +1582,8 @@ create_save_file_chooser (GtkWidget *widget, /* Set cache of gradient and samples from it. * - * The cache is in three global variables: - * gradient, gradient_samples, n_gradient_samples. + * The cache is in 2 global variables: + * gradient, gradient_samples. * This keeps the three variables coherent. * * !!! There is one other writer of gradient_samples, see below. @@ -1614,13 +1609,10 @@ set_grad_data_cache (GimpGradient *in_gradient, /* Refresh the global cache of samples. */ if (gradient_samples != NULL) - g_free (gradient_samples); + gimp_color_array_free (gradient_samples); - gimp_gradient_get_uniform_samples (gradient, - n_colors, - FALSE, - &n_gradient_samples, - &gradient_samples); + gradient_samples = gimp_gradient_get_uniform_samples (gradient, + n_colors, FALSE); } gchar* diff --git a/plug-ins/gradient-flare/gradient-flare.c b/plug-ins/gradient-flare/gradient-flare.c index ed842e9adb..9a45baa687 100644 --- a/plug-ins/gradient-flare/gradient-flare.c +++ b/plug-ins/gradient-flare/gradient-flare.c @@ -5034,22 +5034,21 @@ gradient_get_values_real_external (const gchar *gradient_name, gint nvalues, gboolean reverse) { - GimpGradient *gradient; - gsize n_tmp_values; + GimpGradient *gradient; + GeglColor **colors; + const Babl *format = babl_format ("R'G'B'A u8"); gdouble *tmp_values; gint i; gint j; gradient = gimp_gradient_get_by_name (gradient_name); - gimp_gradient_get_uniform_samples (gradient, nvalues, reverse, - &n_tmp_values, &tmp_values); + colors = gimp_gradient_get_uniform_samples (gradient, nvalues, reverse); for (i = 0; i < nvalues; i++) - for (j = 0; j < 4; j++) - values[4 * i + j] = (guchar) (tmp_values[4 * i + j] * 255); + gegl_color_get_pixel (colors[i], format, (void *) &values[4 * i]); - g_free (tmp_values); + gimp_color_array_free (colors); } void diff --git a/plug-ins/pagecurl/pagecurl.c b/plug-ins/pagecurl/pagecurl.c index b8c756639f..51d489b885 100644 --- a/plug-ins/pagecurl/pagecurl.c +++ b/plug-ins/pagecurl/pagecurl.c @@ -887,15 +887,20 @@ static gdouble * get_gradient_samples (GimpDrawable *drawable, gboolean reverse) { - GimpGradient *gradient; - - gsize n_d_samples; - gdouble *d_samples = NULL; + GimpGradient *gradient; + GeglColor **colors; + const Babl *format = babl_format ("R'G'B'A double"); + gdouble *d_samples; gradient = gimp_context_get_gradient (); - gimp_gradient_get_uniform_samples (gradient, NGRADSAMPLES, reverse, - &n_d_samples, &d_samples); + colors = gimp_gradient_get_uniform_samples (gradient, NGRADSAMPLES, reverse); + + d_samples = g_new0 (gdouble, NGRADSAMPLES * 4); + for (gint i = 0; i < NGRADSAMPLES; i++) + gegl_color_get_pixel (colors[i], format, &d_samples[i * 4]); + + gimp_color_array_free (colors); return d_samples; }