gimp/plug-ins/common/sparkle.c

1271 lines
41 KiB
C
Raw Normal View History

/* Sparkle --- image filter plug-in for GIMP
1999-09-03 23:14:44 +00:00
* Copyright (C) 1996 by John Beale; ported to Gimp by Michael J. Hammel;
*
1999-09-03 23:14:44 +00:00
* It has been optimized a little, bugfixed and modified by Martin Weber
* for additional functionality. Also bugfixed by Seth Burgess (9/17/03)
* to take rowstrides into account when selections are present (bug #50911).
* Attempted reformatting.
1997-11-24 22:05:25 +00:00
*
* This program is free software: you can redistribute it and/or modify
1997-11-24 22:05:25 +00:00
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
1997-11-24 22:05:25 +00:00
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
1997-11-24 22:05:25 +00:00
*
* You can contact Michael at mjhammel@csn.net
* You can contact Martin at martweb@gmx.net
* You can contact Seth at sjburges@gimp.org
1997-11-24 22:05:25 +00:00
*/
/*
* Sparkle 1.27 - simulate pixel bloom and diffraction effects
1997-11-24 22:05:25 +00:00
*/
#include "config.h"
2000-02-07 15:49:54 +00:00
#include <string.h>
#include <libgimp/gimp.h>
#include <libgimp/gimpui.h>
#include "libgimp/stdplugins-intl.h"
1997-11-24 22:05:25 +00:00
#define PLUG_IN_PROC "plug-in-sparkle"
#define PLUG_IN_BINARY "sparkle"
#define PLUG_IN_ROLE "gimp-sparkle"
#define MAX_CHANNELS 4
#define PSV 2 /* point spread value */
#define NATURAL 0
#define FOREGROUND 1
#define BACKGROUND 2
1997-11-24 22:05:25 +00:00
1999-09-03 23:14:44 +00:00
1997-11-24 22:05:25 +00:00
typedef struct
{
gdouble lum_threshold;
gdouble flare_inten;
gdouble spike_len;
gdouble spike_pts;
gdouble spike_angle;
gdouble density;
gdouble transparency;
gdouble random_hue;
gdouble random_saturation;
gboolean preserve_luminosity;
gboolean inverse;
gboolean border;
gint colortype;
1997-11-24 22:05:25 +00:00
} SparkleVals;
2019-09-03 22:15:37 +02:00
typedef struct _Sparkle Sparkle;
typedef struct _SparkleClass SparkleClass;
struct _Sparkle
{
GimpPlugIn parent_instance;
};
1999-09-03 23:14:44 +00:00
2019-09-03 22:15:37 +02:00
struct _SparkleClass
1997-11-24 22:05:25 +00:00
{
2019-09-03 22:15:37 +02:00
GimpPlugInClass parent_class;
1997-11-24 22:05:25 +00:00
};
2019-09-03 22:15:37 +02:00
#define SPARKLE_TYPE (sparkle_get_type ())
#define SPARKLE (obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), SPARKLE_TYPE, Sparkle))
GType sparkle_get_type (void) G_GNUC_CONST;
static GList * sparkle_query_procedures (GimpPlugIn *plug_in);
static GimpProcedure * sparkle_create_procedure (GimpPlugIn *plug_in,
const gchar *name);
static GimpValueArray * sparkle_run (GimpProcedure *procedure,
GimpRunMode run_mode,
GimpImage *image,
gint n_drawables,
GimpDrawable **drawables,
2019-09-03 22:15:37 +02:00
const GimpValueArray *args,
gpointer run_data);
static gboolean sparkle_dialog (GimpDrawable *drawable);
static void sparkle_scale_entry_update_double (GimpLabelSpin *entry,
gdouble *value);
2019-09-03 22:15:37 +02:00
static gint compute_luminosity (const guchar *pixel,
gboolean gray,
gboolean has_alpha);
static gint compute_lum_threshold (GimpDrawable *drawable,
gdouble percentile);
static void sparkle (GimpDrawable *drawable,
GimpPreview *preview);
static void sparkle_preview (GimpDrawable *drawable,
GimpPreview *preview);
static void fspike (GeglBuffer *src_buffer,
GeglBuffer *dest_buffer,
const Babl *format,
gint bytes,
gint x1,
gint y1,
gint x2,
gint y2,
gint xr,
gint yr,
gdouble inten,
gdouble length,
gdouble angle,
GRand *gr,
guchar *dest_buf);
static void rpnt (GeglBuffer *dest_buffer,
const Babl *format,
gint x1,
gint y1,
gint x2,
gint y2,
gdouble xr,
gdouble yr,
gint bytes,
gdouble inten,
guchar color[MAX_CHANNELS],
guchar *dest_buf);
G_DEFINE_TYPE (Sparkle, sparkle, GIMP_TYPE_PLUG_IN)
GIMP_MAIN (SPARKLE_TYPE)
1997-11-24 22:05:25 +00:00
static SparkleVals svals =
{
0.001, /* luminosity threshold */
0.5, /* flare intensity */
20.0, /* spike length */
4.0, /* spike points */
15.0, /* spike angle */
1.0, /* spike density */
0.0, /* transparency */
0.0, /* random hue */
0.0, /* random saturation */
FALSE, /* preserve_luminosity */
FALSE, /* inverse */
FALSE, /* border */
NATURAL /* colortype */
1997-11-24 22:05:25 +00:00
};
static gint num_sparkles;
static void
2019-09-03 22:15:37 +02:00
sparkle_class_init (SparkleClass *klass)
1997-11-24 22:05:25 +00:00
{
2019-09-03 22:15:37 +02:00
GimpPlugInClass *plug_in_class = GIMP_PLUG_IN_CLASS (klass);
plug_in_class->query_procedures = sparkle_query_procedures;
plug_in_class->create_procedure = sparkle_create_procedure;
1997-11-24 22:05:25 +00:00
}
static void
2019-09-03 22:15:37 +02:00
sparkle_init (Sparkle *sparkle)
1997-11-24 22:05:25 +00:00
{
2019-09-03 22:15:37 +02:00
}
1997-11-24 22:05:25 +00:00
2019-09-03 22:15:37 +02:00
static GList *
sparkle_query_procedures (GimpPlugIn *plug_in)
{
return g_list_append (NULL, g_strdup (PLUG_IN_PROC));
}
static GimpProcedure *
sparkle_create_procedure (GimpPlugIn *plug_in,
const gchar *name)
{
GimpProcedure *procedure = NULL;
2019-09-03 22:15:37 +02:00
if (! strcmp (name, PLUG_IN_PROC))
{
procedure = gimp_image_procedure_new (plug_in, name,
GIMP_PDB_PROC_TYPE_PLUGIN,
sparkle_run, NULL, NULL);
gimp_procedure_set_image_types (procedure, "RGB*, GRAY*");
gimp_procedure_set_sensitivity_mask (procedure,
GIMP_PROCEDURE_SENSITIVE_DRAWABLE);
2019-09-03 22:15:37 +02:00
gimp_procedure_set_menu_label (procedure, N_("_Sparkle..."));
gimp_procedure_add_menu_path (procedure,
"<Image>/Filters/Light and Shadow/Light");
gimp_procedure_set_documentation (procedure,
N_("Turn bright spots into "
"starry sparkles"),
"Uses a percentage based luminoisty "
"threhsold to find candidate pixels "
"for adding some sparkles (spikes).",
name);
gimp_procedure_set_attribution (procedure,
"John Beale, & (ported to GIMP v0.54) "
"Michael J. Hammel & ted to GIMP v1.0) "
"& Seth Burgess & Spencer Kimball",
"John Beale",
"Version 1.27, September 2003");
GIMP_PROC_ARG_DOUBLE (procedure, "lum-threshold",
"Lum threshold",
"Luminosity threshold",
0.0, 1.0, 0.001,
G_PARAM_READWRITE);
GIMP_PROC_ARG_DOUBLE (procedure, "flare-inten",
"Flare inten",
"Flare intensity",
0.0, 1.0, 0.5,
G_PARAM_READWRITE);
GIMP_PROC_ARG_INT (procedure, "spike-len",
"Spike len",
"Spike length (in pixels)",
1, 1000, 20,
G_PARAM_READWRITE);
GIMP_PROC_ARG_INT (procedure, "spike-points",
"Spike points",
"# of spike points",
1, 1000, 4,
G_PARAM_READWRITE);
GIMP_PROC_ARG_INT (procedure, "spike-angle",
"Spike angle",
"Spike angle (-1: random)",
-1, 360, 15,
G_PARAM_READWRITE);
GIMP_PROC_ARG_DOUBLE (procedure, "density",
"Density",
"Spike density",
0.0, 1.0, 1.0,
G_PARAM_READWRITE);
GIMP_PROC_ARG_DOUBLE (procedure, "transparency",
"Transparency",
"Transparency",
0.0, 1.0, 0.0,
G_PARAM_READWRITE);
GIMP_PROC_ARG_DOUBLE (procedure, "random-hue",
"Random hue",
"Random hue",
0.0, 1.0, 0.0,
G_PARAM_READWRITE);
GIMP_PROC_ARG_DOUBLE (procedure, "random-saturation",
"Random saturation",
"Random saturation",
0.0, 1.0, 0.0,
G_PARAM_READWRITE);
GIMP_PROC_ARG_BOOLEAN (procedure, "preserve-luminosity",
"Preserve luminosity",
"Preserve luminosity",
FALSE,
G_PARAM_READWRITE);
GIMP_PROC_ARG_BOOLEAN (procedure, "inverse",
"Inverse",
"Inverse",
FALSE,
G_PARAM_READWRITE);
GIMP_PROC_ARG_BOOLEAN (procedure, "border",
"Border",
"Add border",
FALSE,
G_PARAM_READWRITE);
GIMP_PROC_ARG_INT (procedure, "color-type",
"Color type",
"Color of sparkles: { NATURAL (0), "
"FOREGROUND (1), BACKGROUND (2) }",
0, 2, NATURAL,
G_PARAM_READWRITE);
}
return procedure;
}
1997-11-24 22:05:25 +00:00
2019-09-03 22:15:37 +02:00
static GimpValueArray *
sparkle_run (GimpProcedure *procedure,
GimpRunMode run_mode,
GimpImage *image,
gint n_drawables,
GimpDrawable **drawables,
2019-09-03 22:15:37 +02:00
const GimpValueArray *args,
gpointer run_data)
{
GimpDrawable *drawable;
gint x, y, w, h;
1997-11-24 22:05:25 +00:00
2019-09-03 22:15:37 +02:00
INIT_I18N ();
gegl_init (NULL, NULL);
if (n_drawables != 1)
{
GError *error = NULL;
g_set_error (&error, GIMP_PLUG_IN_ERROR, 0,
_("Procedure '%s' only works with one drawable."),
PLUG_IN_PROC);
return gimp_procedure_new_return_values (procedure,
GIMP_PDB_CALLING_ERROR,
error);
}
else
{
drawable = drawables[0];
}
if (! gimp_drawable_mask_intersect (drawable, &x, &y, &w, &h))
{
g_message (_("Region selected for filter is empty"));
2019-09-03 22:15:37 +02:00
return gimp_procedure_new_return_values (procedure,
GIMP_PDB_SUCCESS,
NULL);
}
1997-11-24 22:05:25 +00:00
switch (run_mode)
{
case GIMP_RUN_INTERACTIVE:
gimp_get_data (PLUG_IN_PROC, &svals);
1997-11-24 22:05:25 +00:00
if (! sparkle_dialog (drawable))
2019-09-03 22:15:37 +02:00
{
return gimp_procedure_new_return_values (procedure,
GIMP_PDB_CANCEL,
NULL);
}
1997-11-24 22:05:25 +00:00
break;
case GIMP_RUN_NONINTERACTIVE:
2019-09-03 22:15:37 +02:00
svals.lum_threshold = GIMP_VALUES_GET_DOUBLE (args, 0);
svals.flare_inten = GIMP_VALUES_GET_DOUBLE (args, 1);
svals.spike_len = GIMP_VALUES_GET_INT (args, 2);
svals.spike_pts = GIMP_VALUES_GET_INT (args, 3);
svals.spike_angle = GIMP_VALUES_GET_INT (args, 4);
svals.density = GIMP_VALUES_GET_DOUBLE (args, 5);
svals.transparency = GIMP_VALUES_GET_DOUBLE (args, 6);
svals.random_hue = GIMP_VALUES_GET_DOUBLE (args, 7);
svals.random_saturation = GIMP_VALUES_GET_DOUBLE (args, 8);
svals.preserve_luminosity = GIMP_VALUES_GET_BOOLEAN (args, 9);
svals.inverse = GIMP_VALUES_GET_BOOLEAN (args, 10);
svals.border = GIMP_VALUES_GET_BOOLEAN (args, 11);
svals.colortype = GIMP_VALUES_GET_INT (args, 12);
1997-11-24 22:05:25 +00:00
break;
case GIMP_RUN_WITH_LAST_VALS:
gimp_get_data (PLUG_IN_PROC, &svals);
1997-11-24 22:05:25 +00:00
break;
}
if (gimp_drawable_is_rgb (drawable) ||
gimp_drawable_is_gray (drawable))
1997-11-24 22:05:25 +00:00
{
gimp_progress_init (_("Sparkling"));
sparkle (drawable, NULL);
1997-11-24 22:05:25 +00:00
if (run_mode != GIMP_RUN_NONINTERACTIVE)
gimp_displays_flush ();
1997-11-24 22:05:25 +00:00
if (run_mode == GIMP_RUN_INTERACTIVE)
gimp_set_data (PLUG_IN_PROC, &svals, sizeof (SparkleVals));
1997-11-24 22:05:25 +00:00
}
else
{
2019-09-03 22:15:37 +02:00
return gimp_procedure_new_return_values (procedure,
GIMP_PDB_EXECUTION_ERROR,
NULL);
1997-11-24 22:05:25 +00:00
}
2019-09-03 22:15:37 +02:00
return gimp_procedure_new_return_values (procedure, GIMP_PDB_SUCCESS, NULL);
1997-11-24 22:05:25 +00:00
}
static gboolean
sparkle_dialog (GimpDrawable *drawable)
1997-11-24 22:05:25 +00:00
{
GtkWidget *dialog;
GtkWidget *main_vbox;
GtkWidget *preview;
GtkWidget *vbox;
GtkWidget *hbox;
GtkWidget *grid;
GtkWidget *toggle;
GtkWidget *r1, *r2, *r3;
GtkWidget *scale;
gboolean run;
1997-11-24 22:05:25 +00:00
gimp_ui_init (PLUG_IN_BINARY);
1997-11-24 22:05:25 +00:00
dialog = gimp_dialog_new (_("Sparkle"), PLUG_IN_ROLE,
NULL, 0,
gimp_standard_help_func, PLUG_IN_PROC,
_("_Cancel"), GTK_RESPONSE_CANCEL,
_("_OK"), GTK_RESPONSE_OK,
NULL);
1997-11-24 22:05:25 +00:00
gimp_dialog_set_alternative_button_order (GTK_DIALOG (dialog),
GTK_RESPONSE_OK,
GTK_RESPONSE_CANCEL,
-1);
Added parent window API to the GimpProgress interface and to the libgimp 2005-09-09 Michael Natterer <mitch@gimp.org> Added parent window API to the GimpProgress interface and to the libgimp progress stuff. Might look strange, but does the right thing in almost all cases (image window, file dialog, script-fu dialog etc). Fixes bug #62988. * app/core/gimpprogress.[ch]: added GimpProgress::get_window() which should return a toplevel window ID if the progress is in a window that wants to be the transient parent of plug-in dialogs. * app/widgets/gimpwidgets-utils.[ch] (gimp_window_get_native): new function which returns the window handle of a GtkWindow's GdkWindow. * app/widgets/gimpfiledialog.c: implement ::get_window(). * app/display/gimpdisplay.[ch]: ditto. Removed window handle API. * app/gui/gui-vtable.c: changed accordingly. * libgimpbase/gimpbaseenums.[ch] (enum GimpProgressCommand): added GIMP_PROGRESS_COMMAND_GET_WINDOW. * app/plug-in/plug-in-progress.[ch] (plug_in_progress_get_window): new function. Also renamed some functions to match the GimpProgress interface, and not the legacy PDB procedure names. * tools/pdbgen/pdb/progress.pdb * app/core/gimppdbprogress.c: implement get_window() on both sides of the wire, keeping backward compatibility (hopefully). * libgimp/gimpprogress.[ch]: deprecated gimp_progress_install() and added gimp_progress_install_vtable() which takes a vtable with padding to be extensible. Added get_window() vtable entry and dispatch it accordingly. Also added pulse() which was implemented in a hackish way before. Everything is of course backward compatible. * libgimp/gimpprogressbar.c: inmplement the get_window() stuff so a plug-in dialog containing a progress can be the transient parent of another dialog in another plug-in. * libgimp/gimpui.[ch] (gimp_ui_get_progress_window): new function which returns a foreign GdkWindow of this plug-ins progress window. Renamed gimp_window_set_transient_for_default_display() to gimp_window_set_transient() and make it use the progress' window handle instead of the display's (which is the right thing to do in almost all cases). * libgimp/gimp.def * libgimp/gimpui.def: add the new functions. * tools/pdbgen/enums.pl * app/pdb/internal_procs.c * app/pdb/progress_cmds.c * libgimp/gimpprogress_pdb.[ch]: regenerated. * libgimp/gimpexport.c * plug-ins/*/*.c: follow API change.
2005-09-09 18:07:31 +00:00
gimp_window_set_transient (GTK_WINDOW (dialog));
2011-09-30 12:17:53 +02:00
main_vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 12);
gtk_container_set_border_width (GTK_CONTAINER (main_vbox), 12);
gtk_box_pack_start (GTK_BOX (gtk_dialog_get_content_area (GTK_DIALOG (dialog))),
main_vbox, TRUE, TRUE, 0);
gtk_widget_show (main_vbox);
preview = gimp_drawable_preview_new_from_drawable (drawable);
gtk_box_pack_start (GTK_BOX (main_vbox), preview, TRUE, TRUE, 0);
gtk_widget_show (preview);
g_signal_connect_swapped (preview, "invalidated",
G_CALLBACK (sparkle_preview),
drawable);
2018-05-11 12:22:08 +02:00
grid = gtk_grid_new ();
gtk_grid_set_row_spacing (GTK_GRID (grid), 6);
gtk_grid_set_column_spacing (GTK_GRID (grid), 6);
gtk_box_pack_start (GTK_BOX (main_vbox), grid, FALSE, FALSE, 0);
gtk_widget_show (grid);
1999-09-03 23:14:44 +00:00
scale = gimp_scale_entry_new (_("Luminosity _threshold:"), svals.lum_threshold, 0.0, 0.1, 3);
gimp_help_set_help_data (scale, _("Adjust the luminosity threshold"), NULL);
g_signal_connect (scale, "value-changed",
G_CALLBACK (sparkle_scale_entry_update_double),
&svals.lum_threshold);
g_signal_connect_swapped (scale, "value-changed",
G_CALLBACK (gimp_preview_invalidate),
preview);
gtk_grid_attach (GTK_GRID (grid), scale, 0, 0, 3, 1);
gtk_widget_show (scale);
scale = gimp_scale_entry_new (_("F_lare intensity:"), svals.flare_inten, 0.0, 1.0, 2);
gimp_help_set_help_data (scale, _("Adjust the flare intensity"), NULL);
g_signal_connect (scale, "value-changed",
G_CALLBACK (sparkle_scale_entry_update_double),
&svals.flare_inten);
g_signal_connect_swapped (scale, "value-changed",
G_CALLBACK (gimp_preview_invalidate),
preview);
gtk_grid_attach (GTK_GRID (grid), scale, 0, 1, 3, 1);
gtk_widget_show (scale);
scale = gimp_scale_entry_new (_("_Spike length:"), svals.spike_len, 1, 100, 0);
gimp_help_set_help_data (scale, _("Adjust the spike length"), NULL);
g_signal_connect (scale, "value-changed",
G_CALLBACK (sparkle_scale_entry_update_double),
&svals.spike_len);
g_signal_connect_swapped (scale, "value-changed",
G_CALLBACK (gimp_preview_invalidate),
preview);
gtk_grid_attach (GTK_GRID (grid), scale, 0, 2, 3, 1);
gtk_widget_show (scale);
scale = gimp_scale_entry_new (_("Sp_ike points:"), svals.spike_pts, 0, 16, 0);
gimp_help_set_help_data (scale, _("Adjust the number of spikes"), NULL);
g_signal_connect (scale, "value-changed",
G_CALLBACK (sparkle_scale_entry_update_double),
&svals.spike_pts);
g_signal_connect_swapped (scale, "value-changed",
G_CALLBACK (gimp_preview_invalidate),
preview);
gtk_grid_attach (GTK_GRID (grid), scale, 0, 3, 3, 1);
gtk_widget_show (scale);
scale = gimp_scale_entry_new (_("Spi_ke angle (-1: random):"), svals.spike_angle, -1, 360, 0);
gimp_help_set_help_data (scale, _("Adjust the spike angle "
"(-1 causes a random angle to be chosen)"), NULL);
gimp_label_spin_set_increments (GIMP_LABEL_SPIN (scale), 1.0, 15.0);
g_signal_connect (scale, "value-changed",
G_CALLBACK (sparkle_scale_entry_update_double),
&svals.spike_angle);
g_signal_connect_swapped (scale, "value-changed",
G_CALLBACK (gimp_preview_invalidate),
preview);
gtk_grid_attach (GTK_GRID (grid), scale, 0, 4, 3, 1);
gtk_widget_show (scale);
scale = gimp_scale_entry_new (_("Spik_e density:"), svals.density, 0.0, 1.0, 2);
gimp_help_set_help_data (scale, _("Adjust the spike density"), NULL);
g_signal_connect (scale, "value-changed",
G_CALLBACK (sparkle_scale_entry_update_double),
&svals.density);
g_signal_connect_swapped (scale, "value-changed",
G_CALLBACK (gimp_preview_invalidate),
preview);
gtk_grid_attach (GTK_GRID (grid), scale, 0, 5, 3, 1);
gtk_widget_show (scale);
scale = gimp_scale_entry_new (_("Tr_ansparency:"), svals.transparency, 0.0, 1.0, 2);
gimp_help_set_help_data (scale, _("Adjust the opacity of the spikes"), NULL);
g_signal_connect (scale, "value-changed",
G_CALLBACK (sparkle_scale_entry_update_double),
&svals.transparency);
g_signal_connect_swapped (scale, "value-changed",
G_CALLBACK (gimp_preview_invalidate),
preview);
gtk_grid_attach (GTK_GRID (grid), scale, 0, 6, 3, 1);
gtk_widget_show (scale);
scale = gimp_scale_entry_new (_("_Random hue:"), svals.random_hue, 0.0, 1.0, 2);
gimp_help_set_help_data (scale, _("Adjust how much the hue should be changed randomly"), NULL);
g_signal_connect (scale, "value-changed",
G_CALLBACK (sparkle_scale_entry_update_double),
&svals.random_hue);
g_signal_connect_swapped (scale, "value-changed",
G_CALLBACK (gimp_preview_invalidate),
preview);
gtk_grid_attach (GTK_GRID (grid), scale, 0, 7, 3, 1);
gtk_widget_show (scale);
scale = gimp_scale_entry_new (_("Rando_m saturation:"), svals.random_saturation, 0.0, 1.0, 2);
gimp_help_set_help_data (scale, _("Adjust how much the saturation should be changed randomly"), NULL);
g_signal_connect (scale, "value-changed",
G_CALLBACK (sparkle_scale_entry_update_double),
&svals.random_saturation);
g_signal_connect_swapped (scale, "value-changed",
G_CALLBACK (gimp_preview_invalidate),
preview);
gtk_grid_attach (GTK_GRID (grid), scale, 0, 8, 3, 1);
gtk_widget_show (scale);
2011-09-30 12:17:53 +02:00
hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 12);
gtk_box_pack_start (GTK_BOX (main_vbox), hbox, FALSE, FALSE, 0);
gtk_widget_show (hbox);
2011-09-30 12:17:53 +02:00
vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 2);
gtk_box_pack_start (GTK_BOX (hbox), vbox, TRUE, TRUE, 0);
gtk_widget_show (vbox);
1999-09-03 23:14:44 +00:00
toggle = gtk_check_button_new_with_mnemonic (_("_Preserve luminosity"));
gtk_box_pack_start (GTK_BOX (vbox), toggle, FALSE, FALSE, 0);
added -DGTK_DISABLE_COMPAT_H to CPPFLAGS. 2000-08-28 Michael Natterer <mitch@gimp.org> * configure.in: added -DGTK_DISABLE_COMPAT_H to CPPFLAGS. * app/app_procs.c * app/gdisplay.c * app/layers_dialog.c * app/menus.c * app/tips_dialog.c * libgimp/gimpcolorbutton.c * plug-ins/FractalExplorer/Dialogs.c * plug-ins/FractalExplorer/FractalExplorer.c * plug-ins/bmp/bmpwrite.c * plug-ins/common/AlienMap.c * plug-ins/common/AlienMap2.c * plug-ins/common/CML_explorer.c * plug-ins/common/animationplay.c * plug-ins/common/cubism.c * plug-ins/common/curve_bend.c * plug-ins/common/deinterlace.c * plug-ins/common/gee.c * plug-ins/common/glasstile.c * plug-ins/common/iwarp.c * plug-ins/common/mail.c * plug-ins/common/pat.c * plug-ins/common/pixelize.c * plug-ins/common/plugindetails.c * plug-ins/common/png.c * plug-ins/common/sample_colorize.c * plug-ins/common/sel_gauss.c * plug-ins/common/sinus.c * plug-ins/common/sparkle.c * plug-ins/common/spheredesigner.c * plug-ins/common/tga.c * plug-ins/common/tileit.c * plug-ins/common/vpropagate.c * plug-ins/common/warp.c * plug-ins/common/waves.c * plug-ins/common/wmf.c * plug-ins/flame/flame.c * plug-ins/fp/fp_gtk.c * plug-ins/gap/gap_arr_dialog.c * plug-ins/gap/gap_dbbrowser_utils.c * plug-ins/gap/gap_mov_dialog.c * plug-ins/gap/gap_navigator_dialog.c * plug-ins/gap/gap_resi_dialog.c * plug-ins/gdyntext/gdyntext_ui.c * plug-ins/gfig/gfig.c * plug-ins/gimpressionist/brush.c * plug-ins/gimpressionist/gimpressionist.c * plug-ins/pagecurl/pagecurl.c * plug-ins/print/gimp_main_window.c * plug-ins/rcm/rcm_callback.c * plug-ins/rcm/rcm_dialog.c * plug-ins/script-fu/script-fu-console.c * plug-ins/script-fu/script-fu-scripts.c * plug-ins/script-fu/script-fu-server.c * plug-ins/sel2path/sel2path_adv_dialog.c * plug-ins/xjt/xjt.c: removed COMPAT_CRUFT.
2000-08-28 00:42:32 +00:00
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (toggle),
svals.preserve_luminosity);
1999-09-03 23:14:44 +00:00
gtk_widget_show (toggle);
gimp_help_set_help_data (toggle,
_("Should the luminosity be preserved?"), NULL);
1999-09-03 23:14:44 +00:00
g_signal_connect (toggle, "toggled",
G_CALLBACK (gimp_toggle_button_update),
&svals.preserve_luminosity);
g_signal_connect_swapped (toggle, "toggled",
G_CALLBACK (gimp_preview_invalidate),
preview);
2002-05-27 17:25:30 +00:00
toggle = gtk_check_button_new_with_mnemonic (_("In_verse"));
gtk_box_pack_start (GTK_BOX (vbox), toggle, FALSE, FALSE, 0);
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (toggle), svals.inverse);
1999-09-03 23:14:44 +00:00
gtk_widget_show (toggle);
gimp_help_set_help_data (toggle,
_("Should the effect be inversed?"), NULL);
g_signal_connect (toggle, "toggled",
G_CALLBACK (gimp_toggle_button_update),
&svals.inverse);
g_signal_connect_swapped (toggle, "toggled",
G_CALLBACK (gimp_preview_invalidate),
preview);
toggle = gtk_check_button_new_with_mnemonic (_("A_dd border"));
gtk_box_pack_start (GTK_BOX (vbox), toggle, FALSE, FALSE, 0);
added -DGTK_DISABLE_COMPAT_H to CPPFLAGS. 2000-08-28 Michael Natterer <mitch@gimp.org> * configure.in: added -DGTK_DISABLE_COMPAT_H to CPPFLAGS. * app/app_procs.c * app/gdisplay.c * app/layers_dialog.c * app/menus.c * app/tips_dialog.c * libgimp/gimpcolorbutton.c * plug-ins/FractalExplorer/Dialogs.c * plug-ins/FractalExplorer/FractalExplorer.c * plug-ins/bmp/bmpwrite.c * plug-ins/common/AlienMap.c * plug-ins/common/AlienMap2.c * plug-ins/common/CML_explorer.c * plug-ins/common/animationplay.c * plug-ins/common/cubism.c * plug-ins/common/curve_bend.c * plug-ins/common/deinterlace.c * plug-ins/common/gee.c * plug-ins/common/glasstile.c * plug-ins/common/iwarp.c * plug-ins/common/mail.c * plug-ins/common/pat.c * plug-ins/common/pixelize.c * plug-ins/common/plugindetails.c * plug-ins/common/png.c * plug-ins/common/sample_colorize.c * plug-ins/common/sel_gauss.c * plug-ins/common/sinus.c * plug-ins/common/sparkle.c * plug-ins/common/spheredesigner.c * plug-ins/common/tga.c * plug-ins/common/tileit.c * plug-ins/common/vpropagate.c * plug-ins/common/warp.c * plug-ins/common/waves.c * plug-ins/common/wmf.c * plug-ins/flame/flame.c * plug-ins/fp/fp_gtk.c * plug-ins/gap/gap_arr_dialog.c * plug-ins/gap/gap_dbbrowser_utils.c * plug-ins/gap/gap_mov_dialog.c * plug-ins/gap/gap_navigator_dialog.c * plug-ins/gap/gap_resi_dialog.c * plug-ins/gdyntext/gdyntext_ui.c * plug-ins/gfig/gfig.c * plug-ins/gimpressionist/brush.c * plug-ins/gimpressionist/gimpressionist.c * plug-ins/pagecurl/pagecurl.c * plug-ins/print/gimp_main_window.c * plug-ins/rcm/rcm_callback.c * plug-ins/rcm/rcm_dialog.c * plug-ins/script-fu/script-fu-console.c * plug-ins/script-fu/script-fu-scripts.c * plug-ins/script-fu/script-fu-server.c * plug-ins/sel2path/sel2path_adv_dialog.c * plug-ins/xjt/xjt.c: removed COMPAT_CRUFT.
2000-08-28 00:42:32 +00:00
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (toggle), svals.border);
1999-09-03 23:14:44 +00:00
gtk_widget_show (toggle);
gimp_help_set_help_data (toggle,
_("Draw a border of spikes around the image"), NULL);
1999-09-03 23:14:44 +00:00
g_signal_connect (toggle, "toggled",
G_CALLBACK (gimp_toggle_button_update),
&svals.border);
g_signal_connect_swapped (toggle, "toggled",
G_CALLBACK (gimp_preview_invalidate),
preview);
/* colortype */
implementedgimp_int_option_menu_new and gimp_int_radio_group_new, which 2003-11-14 Manish Singh <yosh@gimp.org> * libgimpwidgets/gimpwidgets.[ch]: implementedgimp_int_option_menu_new and gimp_int_radio_group_new, which are the same as gimp_option_menu_new2 and gimp_radio_group_new2, but they take integers as values to map instead of gpointers, which avoids casts in pretty much all uses of it in the tree. * app/gui/image-commands.c * app/gui/offset-dialog.c * app/widgets/gimppropwidgets.c * app/widgets/gimpwidgets-constructors.c * libgimpwidgets/gimpmemsizeentry.c * modules/cdisplay_colorblind.c * plug-ins/FractalExplorer/Dialogs.c * plug-ins/Lighting/lighting_ui.c * plug-ins/MapObject/mapobject_ui.c * plug-ins/common/AlienMap.c * plug-ins/common/AlienMap2.c * plug-ins/common/CML_explorer.c * plug-ins/common/align_layers.c * plug-ins/common/blinds.c * plug-ins/common/borderaverage.c * plug-ins/common/bumpmap.c * plug-ins/common/curve_bend.c * plug-ins/common/deinterlace.c * plug-ins/common/edge.c * plug-ins/common/emboss.c * plug-ins/common/fractaltrace.c * plug-ins/common/gif.c * plug-ins/common/hot.c * plug-ins/common/iwarp.c * plug-ins/common/jigsaw.c * plug-ins/common/jpeg.c * plug-ins/common/lic.c * plug-ins/common/mail.c * plug-ins/common/max_rgb.c * plug-ins/common/mblur.c * plug-ins/common/mng.c * plug-ins/common/mosaic.c * plug-ins/common/nlfilt.c * plug-ins/common/papertile.c * plug-ins/common/pnm.c * plug-ins/common/ps.c * plug-ins/common/psp.c * plug-ins/common/ripple.c * plug-ins/common/shift.c * plug-ins/common/sinus.c * plug-ins/common/sparkle.c * plug-ins/common/struc.c * plug-ins/common/sunras.c * plug-ins/common/tiff.c * plug-ins/common/waves.c * plug-ins/common/wind.c * plug-ins/fits/fits.c * plug-ins/flame/flame.c * plug-ins/gfig/gfig.c * plug-ins/gimpressionist/color.c * plug-ins/gimpressionist/orientmap.c * plug-ins/gimpressionist/placement.c * plug-ins/maze/maze_face.c * plug-ins/sgi/sgi.c: Use gimp_int_option_menu_new and gimp_int_radio_group_new. * plug-ins/common/CML_explorer.c: make function_graph_new take a gpointer *data instead of a gpointer data, and properly pass an int through it. * plug-ins/common/mng.c: mark menu strings for translation. * plug-ins/rcm/rcm.c: remove initialization for Success member in RcmParams, since it's gone now.
2003-11-14 18:05:39 +00:00
vbox = gimp_int_radio_group_new (FALSE, NULL,
G_CALLBACK (gimp_radio_button_update),
&svals.colortype, NULL, svals.colortype,
1999-09-03 23:14:44 +00:00
_("_Natural color"), NATURAL, &r1,
_("_Foreground color"), FOREGROUND, &r2,
_("_Background color"), BACKGROUND, &r3,
implementedgimp_int_option_menu_new and gimp_int_radio_group_new, which 2003-11-14 Manish Singh <yosh@gimp.org> * libgimpwidgets/gimpwidgets.[ch]: implementedgimp_int_option_menu_new and gimp_int_radio_group_new, which are the same as gimp_option_menu_new2 and gimp_radio_group_new2, but they take integers as values to map instead of gpointers, which avoids casts in pretty much all uses of it in the tree. * app/gui/image-commands.c * app/gui/offset-dialog.c * app/widgets/gimppropwidgets.c * app/widgets/gimpwidgets-constructors.c * libgimpwidgets/gimpmemsizeentry.c * modules/cdisplay_colorblind.c * plug-ins/FractalExplorer/Dialogs.c * plug-ins/Lighting/lighting_ui.c * plug-ins/MapObject/mapobject_ui.c * plug-ins/common/AlienMap.c * plug-ins/common/AlienMap2.c * plug-ins/common/CML_explorer.c * plug-ins/common/align_layers.c * plug-ins/common/blinds.c * plug-ins/common/borderaverage.c * plug-ins/common/bumpmap.c * plug-ins/common/curve_bend.c * plug-ins/common/deinterlace.c * plug-ins/common/edge.c * plug-ins/common/emboss.c * plug-ins/common/fractaltrace.c * plug-ins/common/gif.c * plug-ins/common/hot.c * plug-ins/common/iwarp.c * plug-ins/common/jigsaw.c * plug-ins/common/jpeg.c * plug-ins/common/lic.c * plug-ins/common/mail.c * plug-ins/common/max_rgb.c * plug-ins/common/mblur.c * plug-ins/common/mng.c * plug-ins/common/mosaic.c * plug-ins/common/nlfilt.c * plug-ins/common/papertile.c * plug-ins/common/pnm.c * plug-ins/common/ps.c * plug-ins/common/psp.c * plug-ins/common/ripple.c * plug-ins/common/shift.c * plug-ins/common/sinus.c * plug-ins/common/sparkle.c * plug-ins/common/struc.c * plug-ins/common/sunras.c * plug-ins/common/tiff.c * plug-ins/common/waves.c * plug-ins/common/wind.c * plug-ins/fits/fits.c * plug-ins/flame/flame.c * plug-ins/gfig/gfig.c * plug-ins/gimpressionist/color.c * plug-ins/gimpressionist/orientmap.c * plug-ins/gimpressionist/placement.c * plug-ins/maze/maze_face.c * plug-ins/sgi/sgi.c: Use gimp_int_option_menu_new and gimp_int_radio_group_new. * plug-ins/common/CML_explorer.c: make function_graph_new take a gpointer *data instead of a gpointer data, and properly pass an int through it. * plug-ins/common/mng.c: mark menu strings for translation. * plug-ins/rcm/rcm.c: remove initialization for Success member in RcmParams, since it's gone now.
2003-11-14 18:05:39 +00:00
NULL);
1999-09-03 23:14:44 +00:00
gtk_box_pack_start (GTK_BOX (hbox), vbox, TRUE, TRUE, 0);
gtk_widget_show (vbox);
gimp_help_set_help_data (r1, _("Use the color of the image"), NULL);
gimp_help_set_help_data (r2, _("Use the foreground color"), NULL);
gimp_help_set_help_data (r3, _("Use the background color"), NULL);
g_signal_connect_swapped (r1, "toggled",
G_CALLBACK (gimp_preview_invalidate),
preview);
g_signal_connect_swapped (r2, "toggled",
G_CALLBACK (gimp_preview_invalidate),
preview);
g_signal_connect_swapped (r3, "toggled",
G_CALLBACK (gimp_preview_invalidate),
preview);
1999-09-03 23:14:44 +00:00
gtk_widget_show (dialog);
1997-11-24 22:05:25 +00:00
run = (gimp_dialog_run (GIMP_DIALOG (dialog)) == GTK_RESPONSE_OK);
removed our own action_area API and use GtkDialog's one. Create all 2003-11-06 Michael Natterer <mitch@gimp.org> * libgimpwidgets/gimpdialog.[ch]: removed our own action_area API and use GtkDialog's one. Create all dialogs without separator. Changed almost everything else too. Fixes bug #125143. * libgimpwidgets/gimpquerybox.c * libgimpwidgets/gimpunitmenu.c: changed accordingly. * libgimp/gimpexport.[ch]: ditto. Renamed enum GimpExportReturnType to GimpExportReturn. * libgimp/gimpcompat.h: added a #define for the old name. * themes/Default/gtkrc: increased action_area border to 6 pixels. * app/display/gimpdisplayshell-filter-dialog.c * app/display/gimpdisplayshell-scale.c * app/display/gimpprogress.c * app/gui/brush-select.c * app/gui/channels-commands.c * app/gui/color-notebook.c * app/gui/convert-dialog.c * app/gui/file-new-dialog.c * app/gui/font-select.c * app/gui/gradient-editor-commands.c * app/gui/gradient-select.c * app/gui/grid-dialog.c * app/gui/image-commands.c * app/gui/info-window.c * app/gui/layers-commands.c * app/gui/module-browser.c * app/gui/offset-dialog.c * app/gui/palette-import-dialog.c * app/gui/palette-select.c * app/gui/pattern-select.c * app/gui/preferences-dialog.c * app/gui/qmask-commands.c * app/gui/resize-dialog.c * app/gui/resolution-calibrate-dialog.c * app/gui/stroke-dialog.c * app/gui/templates-commands.c * app/gui/user-install-dialog.c * app/gui/vectors-commands.c * app/tools/gimpcolorpickertool.c * app/tools/gimpcroptool.c * app/tools/gimpimagemaptool.c * app/tools/gimpmeasuretool.c * app/tools/gimptransformtool.c * app/widgets/gimptexteditor.c * app/widgets/gimptooldialog.[ch] * app/widgets/gimpviewabledialog.[ch] * app/widgets/gimpwidgets-utils.c: changed accordingly and increased the dialogs' outer borders to 6 pixels all over the place. * plug-ins/*/*.c: changed accordingly. The plug-ins may be arbitrarily broken, I tested none of them.
2003-11-06 15:27:05 +00:00
gtk_widget_destroy (dialog);
1997-11-24 22:05:25 +00:00
removed our own action_area API and use GtkDialog's one. Create all 2003-11-06 Michael Natterer <mitch@gimp.org> * libgimpwidgets/gimpdialog.[ch]: removed our own action_area API and use GtkDialog's one. Create all dialogs without separator. Changed almost everything else too. Fixes bug #125143. * libgimpwidgets/gimpquerybox.c * libgimpwidgets/gimpunitmenu.c: changed accordingly. * libgimp/gimpexport.[ch]: ditto. Renamed enum GimpExportReturnType to GimpExportReturn. * libgimp/gimpcompat.h: added a #define for the old name. * themes/Default/gtkrc: increased action_area border to 6 pixels. * app/display/gimpdisplayshell-filter-dialog.c * app/display/gimpdisplayshell-scale.c * app/display/gimpprogress.c * app/gui/brush-select.c * app/gui/channels-commands.c * app/gui/color-notebook.c * app/gui/convert-dialog.c * app/gui/file-new-dialog.c * app/gui/font-select.c * app/gui/gradient-editor-commands.c * app/gui/gradient-select.c * app/gui/grid-dialog.c * app/gui/image-commands.c * app/gui/info-window.c * app/gui/layers-commands.c * app/gui/module-browser.c * app/gui/offset-dialog.c * app/gui/palette-import-dialog.c * app/gui/palette-select.c * app/gui/pattern-select.c * app/gui/preferences-dialog.c * app/gui/qmask-commands.c * app/gui/resize-dialog.c * app/gui/resolution-calibrate-dialog.c * app/gui/stroke-dialog.c * app/gui/templates-commands.c * app/gui/user-install-dialog.c * app/gui/vectors-commands.c * app/tools/gimpcolorpickertool.c * app/tools/gimpcroptool.c * app/tools/gimpimagemaptool.c * app/tools/gimpmeasuretool.c * app/tools/gimptransformtool.c * app/widgets/gimptexteditor.c * app/widgets/gimptooldialog.[ch] * app/widgets/gimpviewabledialog.[ch] * app/widgets/gimpwidgets-utils.c: changed accordingly and increased the dialogs' outer borders to 6 pixels all over the place. * plug-ins/*/*.c: changed accordingly. The plug-ins may be arbitrarily broken, I tested none of them.
2003-11-06 15:27:05 +00:00
return run;
1997-11-24 22:05:25 +00:00
}
static void
sparkle_scale_entry_update_double (GimpLabelSpin *entry,
gdouble *value)
{
*value = gimp_label_spin_get_value (entry);
}
1997-11-24 22:05:25 +00:00
static gint
compute_luminosity (const guchar *pixel,
gboolean gray,
gboolean has_alpha)
1997-11-24 22:05:25 +00:00
{
1999-09-03 23:14:44 +00:00
gint pixel0, pixel1, pixel2;
if (svals.inverse)
1999-09-03 23:14:44 +00:00
{
pixel0 = 255 - pixel[0];
pixel1 = 255 - pixel[1];
pixel2 = 255 - pixel[2];
}
else
{
pixel0 = pixel[0];
pixel1 = pixel[1];
pixel2 = pixel[2];
}
1997-11-24 22:05:25 +00:00
if (gray)
{
if (has_alpha)
return (pixel0 * pixel1) / 255;
1997-11-24 22:05:25 +00:00
else
return (pixel0);
1997-11-24 22:05:25 +00:00
}
else
{
gint min, max;
1999-09-03 23:14:44 +00:00
min = MIN (pixel0, pixel1);
min = MIN (min, pixel2);
max = MAX (pixel0, pixel1);
max = MAX (max, pixel2);
1997-11-24 22:05:25 +00:00
if (has_alpha)
return ((min + max) * pixel[3]) / 510;
1997-11-24 22:05:25 +00:00
else
return (min + max) / 2;
1997-11-24 22:05:25 +00:00
}
}
static gint
compute_lum_threshold (GimpDrawable *drawable,
gdouble percentile)
1997-11-24 22:05:25 +00:00
{
GeglBuffer *src_buffer;
GeglBufferIterator *iter;
const Babl *format;
gint bpp;
gint values[256];
gint total, sum;
gboolean gray;
gboolean has_alpha;
gint i;
gint x1, y1;
gint width, height;
1997-11-24 22:05:25 +00:00
/* zero out the luminosity values array */
memset (values, 0, sizeof (gint) * 256);
1997-11-24 22:05:25 +00:00
if (! gimp_drawable_mask_intersect (drawable,
&x1, &y1, &width, &height))
return 0;
gray = gimp_drawable_is_gray (drawable);
has_alpha = gimp_drawable_has_alpha (drawable);
1997-11-24 22:05:25 +00:00
if (gray)
{
if (has_alpha)
format = babl_format ("Y'A u8");
else
format = babl_format ("Y' u8");
}
else
{
if (has_alpha)
format = babl_format ("R'G'B'A u8");
else
format = babl_format ("R'G'B' u8");
}
bpp = babl_format_get_bytes_per_pixel (format);
1997-11-24 22:05:25 +00:00
src_buffer = gimp_drawable_get_buffer (drawable);
iter = gegl_buffer_iterator_new (src_buffer,
GEGL_RECTANGLE (x1, y1, width, height), 0,
format,
GEGL_ACCESS_READ, GEGL_ABYSS_NONE, 1);
while (gegl_buffer_iterator_next (iter))
{
const guchar *src = iter->items[0].data;
gint length = iter->length;
while (length--)
{
values [compute_luminosity (src, gray, has_alpha)]++;
src += bpp;
}
}
g_object_unref (src_buffer);
1997-11-24 22:05:25 +00:00
total = width * height;
1997-11-24 22:05:25 +00:00
sum = 0;
for (i = 255; i >= 0; i--)
{
sum += values[i];
if ((gdouble) sum > percentile * (gdouble) total)
{
num_sparkles = sum;
return i;
}
1997-11-24 22:05:25 +00:00
}
1997-11-24 22:05:25 +00:00
return 0;
}
static void
sparkle (GimpDrawable *drawable,
GimpPreview *preview)
1997-11-24 22:05:25 +00:00
{
GeglBuffer *src_buffer;
GeglBuffer *dest_buffer;
GeglBufferIterator *iter;
const Babl *format;
gint d_width, d_height;
gdouble nfrac, length, inten, spike_angle;
gint cur_progress, max_progress;
gint x1, y1, x2, y2;
gint width, height;
gint threshold;
gint lum, x, y, b;
gboolean gray, has_alpha;
gint alpha;
gint bytes;
GRand *gr;
guchar *dest_buf = NULL;
gray = gimp_drawable_is_gray (drawable);
has_alpha = gimp_drawable_has_alpha (drawable);
if (gray)
{
if (has_alpha)
format = babl_format ("Y'A u8");
else
format = babl_format ("Y' u8");
}
else
{
if (has_alpha)
format = babl_format ("R'G'B'A u8");
else
format = babl_format ("R'G'B' u8");
}
bytes = babl_format_get_bytes_per_pixel (format);
alpha = (has_alpha) ? bytes - 1 : bytes;
if (preview)
{
gimp_preview_get_position (preview, &x1, &y1);
gimp_preview_get_size (preview, &width, &height);
x2 = x1 + width;
y2 = y1 + height;
dest_buf = g_new0 (guchar, width * height * bytes);
}
else
{
if (! gimp_drawable_mask_intersect (drawable,
&x1, &y1, &width, &height))
2018-02-16 19:12:19 +01:00
return;
x2 = x1 + width;
y2 = y1 + height;
}
if (width < 1 || height < 1)
return;
d_width = gimp_drawable_get_width (drawable);
d_height = gimp_drawable_get_height (drawable);
gr = g_rand_new ();
if (svals.border)
{
num_sparkles = 2 * (width + height);
threshold = 255;
}
else
{
/* compute the luminosity which exceeds the luminosity threshold */
threshold = compute_lum_threshold (drawable, svals.lum_threshold);
}
1997-11-24 22:05:25 +00:00
/* initialize the progress dialog */
cur_progress = 0;
max_progress = num_sparkles;
/* copy what is already there */
src_buffer = gimp_drawable_get_buffer (drawable);
dest_buffer = gimp_drawable_get_shadow_buffer (drawable);
iter = gegl_buffer_iterator_new (src_buffer,
GEGL_RECTANGLE (x1, y1, width, height), 0,
format,
GEGL_ACCESS_READ, GEGL_ABYSS_NONE, 2);
gegl_buffer_iterator_add (iter, dest_buffer,
GEGL_RECTANGLE (x1, y1, width, height), 0,
format,
GEGL_ACCESS_WRITE, GEGL_ABYSS_NONE);
while (gegl_buffer_iterator_next (iter))
1997-11-24 22:05:25 +00:00
{
GeglRectangle roi = iter->items[0].roi;
const guchar *src, *s;
guchar *dest, *d;
src = iter->items[0].data;
if (preview)
dest = dest_buf + (((roi.y - y1) * width) + (roi.x - x1)) * bytes;
else
dest = iter->items[1].data;
1997-11-24 22:05:25 +00:00
for (y = 0; y < roi.height; y++)
1999-09-03 23:14:44 +00:00
{
s = src;
d = dest;
for (x = 0; x < roi.width; x++)
1999-09-03 23:14:44 +00:00
{
if (has_alpha && s[alpha] == 0)
{
memset (d, 0, alpha);
}
else
1999-09-03 23:14:44 +00:00
{
for (b = 0; b < alpha; b++)
d[b] = s[b];
1999-09-03 23:14:44 +00:00
}
if (has_alpha)
d[alpha] = s[alpha];
1999-09-03 23:14:44 +00:00
s += bytes;
d += bytes;
}
src += roi.width * bytes;
if (preview)
dest += width * bytes;
else
dest += roi.width * bytes;
1999-09-03 23:14:44 +00:00
}
1997-11-24 22:05:25 +00:00
}
1997-11-24 22:05:25 +00:00
/* add effects to new image based on intensity of old pixels */
iter = gegl_buffer_iterator_new (src_buffer,
GEGL_RECTANGLE (x1, y1, width, height), 0,
format,
GEGL_ACCESS_READ, GEGL_ABYSS_NONE, 2);
gegl_buffer_iterator_add (iter, dest_buffer,
GEGL_RECTANGLE (x1, y1, width, height), 0,
format,
GEGL_ACCESS_WRITE, GEGL_ABYSS_NONE);
while (gegl_buffer_iterator_next (iter))
1997-11-24 22:05:25 +00:00
{
GeglRectangle roi = iter->items[0].roi;
const guchar *src, *s;
src = iter->items[0].data;
for (y = 0; y < roi.height; y++)
{
s = src;
for (x = 0; x < roi.width; x++)
{
if (svals.border)
{
if (x + roi.x == 0 ||
y + roi.y == 0 ||
x + roi.x == d_width - 1 ||
y + roi.y == d_height - 1)
{
lum = 255;
}
else
{
lum = 0;
}
}
else
{
lum = compute_luminosity (s, gray, has_alpha);
}
if (lum >= threshold)
{
nfrac = fabs ((gdouble) (lum + 1 - threshold) /
(gdouble) (256 - threshold));
length = ((gdouble) svals.spike_len *
(gdouble) pow (nfrac, 0.8));
inten = svals.flare_inten * nfrac;
/* fspike im x,y intens rlength angle */
if (svals.spike_pts > 0)
{
/* major spikes */
if (svals.spike_angle == -1)
spike_angle = g_rand_double_range (gr, 0, 360.0);
else
spike_angle = svals.spike_angle;
if (g_rand_double (gr) <= svals.density)
{
fspike (src_buffer, dest_buffer, format, bytes,
x1, y1, x2, y2,
x + roi.x, y + roi.y,
inten, length, spike_angle, gr, dest_buf);
/* minor spikes */
fspike (src_buffer, dest_buffer, format, bytes,
x1, y1, x2, y2,
x + roi.x, y + roi.y,
inten * 0.7, length * 0.7,
((gdouble)spike_angle+180.0/svals.spike_pts),
gr, dest_buf);
}
}
if (!preview)
{
cur_progress ++;
if ((cur_progress % 5) == 0)
gimp_progress_update ((double) cur_progress /
(double) max_progress);
}
}
s += bytes;
}
src += roi.width * bytes;
}
}
g_object_unref (src_buffer);
g_object_unref (dest_buffer);
if (preview)
{
gimp_preview_draw_buffer (preview, dest_buf, width * bytes);
g_free (dest_buf);
}
else
{
gimp_progress_update (1.0);
1997-11-24 22:05:25 +00:00
gimp_drawable_merge_shadow (drawable, TRUE);
gimp_drawable_update (drawable, x1, y1, width, height);
}
configure.in app/core/gimpbrushpipe.c app/gui/about-dialog.c 2002-11-20 Dave Neary <bolsh@gimp.org> * configure.in * app/core/gimpbrushpipe.c * app/gui/about-dialog.c * app/paint-funcs/paint-funcs-generic.h * app/paint-funcs/paint-funcs.c * libgimpmath/gimpmath.h * libgimpwidgets/gimpwidgets.c * plug-ins/common/CML_explorer.c * plug-ins/common/blur.c * plug-ins/common/cubism.c * plug-ins/common/gee.c * plug-ins/common/gee_zoom.c * plug-ins/common/gqbist.c * plug-ins/common/jigsaw.c * plug-ins/common/lic.c * plug-ins/common/noisify.c * plug-ins/common/nova.c * plug-ins/common/papertile.c * plug-ins/common/plasma.c * plug-ins/common/randomize.c * plug-ins/common/sample_colorize.c * plug-ins/common/scatter_hsv.c * plug-ins/common/shift.c * plug-ins/common/sinus.c * plug-ins/common/smooth_palette.c * plug-ins/common/snoise.c * plug-ins/common/sparkle.c * plug-ins/common/spheredesigner.c * plug-ins/common/spread.c * plug-ins/common/warp.c * plug-ins/common/wind.c * plug-ins/flame/cmap.c * plug-ins/flame/flame.c * plug-ins/flame/libifs.c * plug-ins/gflare/gflare.c * plug-ins/gimpressionist/gimpressionist.c * plug-ins/gimpressionist/gimpressionist.h * plug-ins/gimpressionist/plasma.c * plug-ins/gimpressionist/repaint.c * plug-ins/ifscompose/ifscompose_utils.c * plug-ins/maze/algorithms.c * plug-ins/maze/maze.c * plug-ins/maze/maze.h * plug-ins/mosaic/mosaic.c: Change all occurrences of RAND_MAX, G_MAXRAND, rand(), srand(), lrand48(), srand48(), random(), srandom(), RAND_FUNC and SRAND_FUNC to the appropriate g_rand* equivalent. Programs which require seed setting for reproducible results, and anything in the core, gets a dedicated GRand * for the lifetime required. Programs which only ever used random numbers for tossing a coin, rolling a dice, etc use g_random functions. For the rest, judgement was used. Where it was easy, a GRand * object was used and g_rand_* functions were preferred. This fixes bug #67386 in HEAD.
2002-11-20 09:27:48 +00:00
g_rand_free (gr);
1997-11-24 22:05:25 +00:00
}
static void
sparkle_preview (GimpDrawable *drawable,
GimpPreview *preview)
{
sparkle (drawable, preview);
}
static inline void
rpnt (GeglBuffer *dest_buffer,
const Babl *format,
gint x1,
gint y1,
gint x2,
gint y2,
gdouble xr,
gdouble yr,
gint bytes,
gdouble inten,
guchar color[MAX_CHANNELS],
guchar *dest_buf)
1997-11-24 22:05:25 +00:00
{
gint x, y, b;
gdouble dx, dy, rs, val;
guchar *pixel;
guchar pixel_buf[4];
gdouble new;
1997-11-24 22:05:25 +00:00
x = (int) (xr); /* integer coord. to upper left of real point */
1997-11-24 22:05:25 +00:00
y = (int) (yr);
if (x >= x1 && y >= y1 && x < x2 && y < y2)
{
if (dest_buf)
{
pixel = dest_buf + ((y - y1) * (x2 - x1) + (x - x1)) * bytes;
}
else
{
gegl_buffer_sample (dest_buffer, x, y, NULL,
pixel_buf, format,
GEGL_SAMPLER_NEAREST, GEGL_ABYSS_NONE);
pixel = pixel_buf;
}
1997-11-24 22:05:25 +00:00
dx = xr - x; dy = yr - y;
rs = dx * dx + dy * dy;
1999-09-03 23:14:44 +00:00
val = inten * exp (-rs / PSV);
1997-11-24 22:05:25 +00:00
1999-09-03 23:14:44 +00:00
for (b = 0; b < bytes; b++)
{
if (svals.inverse)
new = 255 - pixel[b];
else
new = pixel[b];
if (svals.preserve_luminosity)
{
if (new < color[b])
{
new *= (1.0 - val * (1.0 - svals.transparency));
}
else
{
new -= val * color[b] * (1.0 - svals.transparency);
if (new < 0.0)
new = 0.0;
}
}
new *= 1.0 - val * svals.transparency;
new += val * color[b];
1997-11-24 22:05:25 +00:00
if (new > 255)
new = 255;
if (svals.inverse)
pixel[b] = 255 - new;
else
pixel[b] = new;
}
if (! dest_buf)
gegl_buffer_set (dest_buffer, GEGL_RECTANGLE (x, y, 1, 1), 0,
format, pixel_buf,
GEGL_AUTO_ROWSTRIDE);
}
1997-11-24 22:05:25 +00:00
}
static void
fspike (GeglBuffer *src_buffer,
GeglBuffer *dest_buffer,
const Babl *format,
gint bytes,
gint x1,
gint y1,
gint x2,
gint y2,
gint xr,
gint yr,
gdouble inten,
gdouble length,
gdouble angle,
GRand *gr,
guchar *dest_buf)
1997-11-24 22:05:25 +00:00
{
const gdouble efac = 2.0;
gdouble xrt, yrt, dx, dy;
gdouble rpos;
gdouble in;
gdouble theta;
gdouble sfac;
gint i;
gboolean ok;
GimpRGB gimp_color;
guchar pixel[MAX_CHANNELS];
guchar chosen_color[MAX_CHANNELS];
guchar color[MAX_CHANNELS];
1997-11-24 22:05:25 +00:00
2000-01-02 22:30:20 +00:00
theta = angle;
1997-11-24 22:05:25 +00:00
switch (svals.colortype)
2000-01-02 22:30:20 +00:00
{
case NATURAL:
break;
1997-11-24 22:05:25 +00:00
case FOREGROUND:
tools/pdbgen/Makefile.am tools/pdbgen/groups.pl removed the "Palette" pdb 2004-09-22 Michael Natterer <mitch@gimp.org> * tools/pdbgen/Makefile.am * tools/pdbgen/groups.pl * tools/pdbgen/pdb/palette.pdb: removed the "Palette" pdb group... * tools/pdbgen/pdb/context.pdb: and added its functions to the "Context" namespace instead. * app/pdb/Makefile.am * app/pdb/palette_cmds.c: removed. * app/pdb/procedural_db.c: added them to the pdb_compat hash table. * libgimp/Makefile.am * libgimp/gimppalette_pdb.[ch]: removed. * libgimp/gimppalette.[ch]: new files holding compat functions which call gimp_context_*() functions. * libgimp/gimp.h * libgimp/gimpui.c: changed accordingly. * app/pdb/context_cmds.c * app/pdb/internal_procs.c * libgimp/gimp_pdb.h * libgimp/gimpcontext_pdb.[ch]: regenerated. * plug-ins/MapObject/mapobject_image.c * plug-ins/MapObject/mapobject_preview.c * plug-ins/common/apply_lens.c * plug-ins/common/blinds.c * plug-ins/common/borderaverage.c * plug-ins/common/checkerboard.c * plug-ins/common/colortoalpha.c * plug-ins/common/cubism.c * plug-ins/common/exchange.c * plug-ins/common/film.c * plug-ins/common/gif.c * plug-ins/common/grid.c * plug-ins/common/mapcolor.c * plug-ins/common/mblur.c * plug-ins/common/mng.c * plug-ins/common/mosaic.c * plug-ins/common/papertile.c * plug-ins/common/png.c * plug-ins/common/polar.c * plug-ins/common/semiflatten.c * plug-ins/common/sinus.c * plug-ins/common/sparkle.c * plug-ins/common/vpropagate.c * plug-ins/common/warp.c * plug-ins/common/whirlpinch.c * plug-ins/gfig/gfig-style.c * plug-ins/gfli/gfli.c * plug-ins/ifscompose/ifscompose.c * plug-ins/maze/handy.c * plug-ins/pagecurl/pagecurl.c * plug-ins/pygimp/gimpmodule.c * plug-ins/script-fu/scripts/*.scm: changed accordingly.
2004-09-22 18:43:09 +00:00
gimp_context_get_foreground (&gimp_color);
gimp_rgb_get_uchar (&gimp_color, &chosen_color[0], &chosen_color[1],
&chosen_color[2]);
break;
case BACKGROUND:
tools/pdbgen/Makefile.am tools/pdbgen/groups.pl removed the "Palette" pdb 2004-09-22 Michael Natterer <mitch@gimp.org> * tools/pdbgen/Makefile.am * tools/pdbgen/groups.pl * tools/pdbgen/pdb/palette.pdb: removed the "Palette" pdb group... * tools/pdbgen/pdb/context.pdb: and added its functions to the "Context" namespace instead. * app/pdb/Makefile.am * app/pdb/palette_cmds.c: removed. * app/pdb/procedural_db.c: added them to the pdb_compat hash table. * libgimp/Makefile.am * libgimp/gimppalette_pdb.[ch]: removed. * libgimp/gimppalette.[ch]: new files holding compat functions which call gimp_context_*() functions. * libgimp/gimp.h * libgimp/gimpui.c: changed accordingly. * app/pdb/context_cmds.c * app/pdb/internal_procs.c * libgimp/gimp_pdb.h * libgimp/gimpcontext_pdb.[ch]: regenerated. * plug-ins/MapObject/mapobject_image.c * plug-ins/MapObject/mapobject_preview.c * plug-ins/common/apply_lens.c * plug-ins/common/blinds.c * plug-ins/common/borderaverage.c * plug-ins/common/checkerboard.c * plug-ins/common/colortoalpha.c * plug-ins/common/cubism.c * plug-ins/common/exchange.c * plug-ins/common/film.c * plug-ins/common/gif.c * plug-ins/common/grid.c * plug-ins/common/mapcolor.c * plug-ins/common/mblur.c * plug-ins/common/mng.c * plug-ins/common/mosaic.c * plug-ins/common/papertile.c * plug-ins/common/png.c * plug-ins/common/polar.c * plug-ins/common/semiflatten.c * plug-ins/common/sinus.c * plug-ins/common/sparkle.c * plug-ins/common/vpropagate.c * plug-ins/common/warp.c * plug-ins/common/whirlpinch.c * plug-ins/gfig/gfig-style.c * plug-ins/gfli/gfli.c * plug-ins/ifscompose/ifscompose.c * plug-ins/maze/handy.c * plug-ins/pagecurl/pagecurl.c * plug-ins/pygimp/gimpmodule.c * plug-ins/script-fu/scripts/*.scm: changed accordingly.
2004-09-22 18:43:09 +00:00
gimp_context_get_background (&gimp_color);
gimp_rgb_get_uchar (&gimp_color, &chosen_color[0], &chosen_color[1],
&chosen_color[2]);
break;
}
/* draw the major spikes */
for (i = 0; i < svals.spike_pts; i++)
{
gegl_buffer_sample (dest_buffer, xr, yr, NULL, pixel, format,
GEGL_SAMPLER_NEAREST, GEGL_ABYSS_NONE);
if (svals.colortype == NATURAL)
{
color[0] = pixel[0];
color[1] = pixel[1];
color[2] = pixel[2];
}
else
{
color[0] = chosen_color[0];
color[1] = chosen_color[1];
color[2] = chosen_color[2];
}
color[3] = pixel[3];
if (svals.inverse)
{
color[0] = 255 - color[0];
color[1] = 255 - color[1];
color[2] = 255 - color[2];
2000-01-02 22:30:20 +00:00
}
2000-01-02 22:30:20 +00:00
if (svals.random_hue > 0.0 || svals.random_saturation > 0.0)
{
GimpRGB rgb;
GimpHSV hsv;
rgb.r = (gdouble) (255 - color[0]) / 255.0;
rgb.g = (gdouble) (255 - color[1]) / 255.0;
rgb.b = (gdouble) (255 - color[2]) / 255.0;
gimp_rgb_to_hsv (&rgb, &hsv);
hsv.h += svals.random_hue * g_rand_double_range (gr, -0.5, 0.5);
if (hsv.h >= 1.0)
hsv.h -= 1.0;
else if (hsv.h < 0.0)
hsv.h += 1.0;
hsv.v += (svals.random_saturation *
g_rand_double_range (gr, -1.0, 1.0));
hsv.v = CLAMP (hsv.v, 0.0, 1.0);
gimp_hsv_to_rgb (&hsv, &rgb);
color[0] = 255 - ROUND (rgb.r * 255.0);
color[1] = 255 - ROUND (rgb.g * 255.0);
color[2] = 255 - ROUND (rgb.b * 255.0);
}
1997-11-24 22:05:25 +00:00
2000-01-02 22:30:20 +00:00
dx = 0.2 * cos (theta * G_PI / 180.0);
dy = 0.2 * sin (theta * G_PI / 180.0);
xrt = (gdouble) xr; /* (gdouble) is needed because some */
yrt = (gdouble) yr; /* compilers optimize too much otherwise */
2000-01-02 22:30:20 +00:00
rpos = 0.2;
1997-11-24 22:05:25 +00:00
2000-01-02 22:30:20 +00:00
do
{
sfac = inten * exp (-pow (rpos / length, efac));
ok = FALSE;
2000-01-02 22:30:20 +00:00
in = 0.2 * sfac;
if (in > 0.01)
2000-01-02 22:30:20 +00:00
ok = TRUE;
rpnt (dest_buffer, format, x1, y1, x2, y2,
xrt, yrt,
bytes, in, color, dest_buf);
rpnt (dest_buffer, format, x1, y1, x2, y2,
xrt + 1.0, yrt,
bytes, in, color, dest_buf);
rpnt (dest_buffer, format, x1, y1, x2, y2,
xrt + 1.0, yrt + 1.0,
bytes, in, color, dest_buf);
rpnt (dest_buffer, format, x1, y1, x2, y2,
xrt, yrt + 1.0,
bytes, in, color, dest_buf);
xrt += dx;
yrt += dy;
rpos += 0.2;
} while (ok);
2000-01-02 22:30:20 +00:00
theta += 360.0 / svals.spike_pts;
1997-11-24 22:05:25 +00:00
}
2000-01-02 22:30:20 +00:00
}