applied modified version of gimp-timecop-200005-12.plasma which adds a

2000-05-23  Sven Neumann  <sven@gimp.org>

* plug-ins/common/plasma.c: applied modified version of
  gimp-timecop-200005-12.plasma which adds a preview to the
  plasma plug-in.

* plug-ins/common/wind.c: applied modified version of
  gimp-timecop-200005-14.wind which adds a preview to the
  wind plug-in.


--Sven
This commit is contained in:
Sven Neumann 2000-05-23 16:04:02 +00:00 committed by Sven Neumann
parent ffa15c468d
commit f7a9520579
3 changed files with 588 additions and 177 deletions

View File

@ -1,3 +1,13 @@
2000-05-23 Sven Neumann <sven@gimp.org>
* plug-ins/common/plasma.c: applied modified version of
gimp-timecop-200005-12.plasma which adds a preview to the
plasma plug-in.
* plug-ins/common/wind.c: applied modified version of
gimp-timecop-200005-14.wind which adds a preview to the
wind plug-in.
2000-05-23 Sven Neumann <sven@gimp.org>
* plug-ins/common/flarefx.c

View File

@ -46,6 +46,13 @@
*
* Feel free to correct my WRONG English, or to modify Plug-in Path,
* and so on. ;-)
*
* Version 1.02
*
* May 2000
* tim copperfield [timecop@japan.co.jp]
* Added dynamic preview mode.
*
*/
#include "config.h"
@ -67,6 +74,7 @@
#define ENTRY_WIDTH 75
#define SCALE_WIDTH 128
#define TILE_CACHE_SIZE 32
#define PREVIEW_SIZE 128
typedef struct
{
@ -92,34 +100,41 @@ static void run (gchar *name,
gint *nreturn_vals,
GParam **return_vals);
static gint plasma_dialog (void);
static void plasma_ok_callback (GtkWidget *widget,
gpointer data);
static GtkWidget *preview_widget (void);
static gint plasma_dialog (GDrawable *drawable);
static void plasma_ok_callback (GtkWidget *widget,
gpointer data);
static void plasma (GDrawable *drawable);
static void plasma (GDrawable *drawable,
gboolean preview_mode);
static void random_rgb (guchar *d);
static void add_random (guchar *d,
gint amnt);
static void init_plasma (GDrawable *drawable);
static void init_plasma (GDrawable *drawable,
gboolean preview_mode);
static void provide_tile (GDrawable *drawable,
gint col,
gint row);
static void end_plasma (GDrawable *drawable);
static void end_plasma (GDrawable *drawable,
gboolean preview_mode);
static void get_pixel (GDrawable *drawable,
gint x,
gint y,
guchar *pixel);
guchar *pixel,
gboolean preview_mode);
static void put_pixel (GDrawable *drawable,
gint x,
gint y,
guchar *pixel);
guchar *pixel,
gboolean preview_mode);
static gint do_plasma (GDrawable *drawable,
gint x1,
gint y1,
gint x2,
gint y2,
gint depth,
gint scale_depth);
gint scale_depth,
gboolean preview_mode);
/***** Local vars *****/
@ -143,6 +158,9 @@ static PlasmaInterface pint =
FALSE /* run */
};
static guchar *work_buffer;
static GtkWidget *preview;
/***** Functions *****/
MAIN ()
@ -165,7 +183,7 @@ query (void)
"More help",
"Stephen Norris & (ported to 1.0 by) Eiichi Takamori",
"Stephen Norris",
"1995",
"May 2000",
N_("<Image>/Filters/Render/Clouds/Plasma..."),
"RGB*, GRAY*",
PROC_PLUG_IN,
@ -204,7 +222,7 @@ run (gchar *name,
gimp_get_data ("plug_in_plasma", &pvals);
/* First acquire information with a dialog */
if (! plasma_dialog ())
if (! plasma_dialog (drawable))
{
gimp_drawable_detach (drawable);
return;
@ -246,7 +264,7 @@ run (gchar *name,
gimp_progress_init (_("Plasma..."));
gimp_tile_cache_ntiles (TILE_CACHE_SIZE);
plasma (drawable);
plasma (drawable, FALSE);
if (run_mode != RUN_NONINTERACTIVE)
gimp_displays_flush ();
@ -264,17 +282,18 @@ run (gchar *name,
}
values[0].data.d_status = status;
gimp_drawable_detach (drawable);
}
static gint
plasma_dialog (void)
plasma_dialog (GDrawable *drawable)
{
GtkWidget *dlg;
GtkWidget *main_vbox;
GtkWidget *abox;
GtkWidget *frame;
GtkWidget *table;
GtkWidget *seed_hbox;
GtkWidget *seed;
GtkObject *adj;
gimp_ui_init ("plasma", FALSE);
@ -297,11 +316,34 @@ plasma_dialog (void)
gimp_help_init ();
main_vbox = gtk_vbox_new (FALSE, 2);
gtk_container_set_border_width (GTK_CONTAINER (main_vbox), 6);
gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dlg)->vbox), main_vbox, TRUE, TRUE, 0);
gtk_widget_show (main_vbox);
/* make a nice preview frame */
frame = gtk_frame_new (_("Preview"));
gtk_container_set_border_width (GTK_CONTAINER (frame), 4);
gtk_box_pack_start (GTK_BOX (main_vbox), frame, FALSE, FALSE, 0);
gtk_widget_show (frame);
abox = gtk_alignment_new (0.5, 0.5, 0.0, 0.0);
gtk_container_set_border_width (GTK_CONTAINER (abox), 4);
gtk_container_add (GTK_CONTAINER (frame), abox);
gtk_widget_show (abox);
frame = gtk_frame_new (NULL);
gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_IN);
gtk_container_add (GTK_CONTAINER (abox), frame);
gtk_widget_show (frame);
preview = preview_widget (); /* we are here */
gtk_container_add (GTK_CONTAINER (frame), preview);
plasma (drawable, TRUE); /* preview image */
gtk_widget_show (preview);
/* parameter settings */
frame = gtk_frame_new (_("Parameter Settings"));
gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_ETCHED_IN);
gtk_container_set_border_width (GTK_CONTAINER (frame), 6);
gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dlg)->vbox), frame, TRUE, TRUE, 0);
gtk_box_pack_start (GTK_BOX (main_vbox), frame, TRUE, TRUE, 0);
table = gtk_table_new (2, 3, FALSE);
gtk_table_set_col_spacings (GTK_TABLE (table), 4);
@ -309,12 +351,20 @@ plasma_dialog (void)
gtk_container_set_border_width (GTK_CONTAINER (table), 4);
gtk_container_add (GTK_CONTAINER (frame), table);
seed_hbox = gimp_random_seed_new (&pvals.seed,
&pvals.timeseed,
TRUE, FALSE);
seed = gimp_random_seed_new (&pvals.seed,
&pvals.timeseed,
TRUE, FALSE);
gimp_table_attach_aligned (GTK_TABLE (table), 0, 0,
_("Random Seed:"), 1.0, 0.5,
seed_hbox, 1, TRUE);
seed, 1, TRUE);
gtk_signal_connect_object (GTK_OBJECT (GIMP_RANDOM_SEED_SPINBUTTON_ADJ (seed)),
"value_changed",
GTK_SIGNAL_FUNC (plasma),
(gpointer)drawable);
gtk_signal_connect_object (GTK_OBJECT (GIMP_RANDOM_SEED_TOGGLEBUTTON (seed)),
"toggled",
GTK_SIGNAL_FUNC (plasma),
(gpointer)drawable);
adj = gimp_scale_entry_new (GTK_TABLE (table), 0, 1,
_("Turbulence:"), SCALE_WIDTH, 0,
@ -325,6 +375,9 @@ plasma_dialog (void)
gtk_signal_connect (GTK_OBJECT (adj), "value_changed",
GTK_SIGNAL_FUNC (gimp_double_adjustment_update),
&pvals.turbulence);
gtk_signal_connect_object (GTK_OBJECT (adj), "value_changed",
GTK_SIGNAL_FUNC (plasma),
(gpointer)drawable);
gtk_widget_show (frame);
gtk_widget_show (table);
@ -368,11 +421,12 @@ static glong max_progress, progress;
*/
static void
plasma (GDrawable *drawable)
plasma (GDrawable *drawable,
gboolean preview_mode)
{
gint depth;
init_plasma (drawable);
init_plasma (drawable, preview_mode);
/*
* This first time only puts in the seed pixels - one in each
@ -380,21 +434,22 @@ plasma (GDrawable *drawable)
* center of the image.
*/
do_plasma (drawable, ix1, iy1, ix2 - 1, iy2 - 1, -1, 0);
do_plasma (drawable, ix1, iy1, ix2 - 1, iy2 - 1, -1, 0, preview_mode);
/*
* Now we recurse through the images, going further each time.
*/
depth = 1;
while (!do_plasma (drawable, ix1, iy1, ix2 - 1, iy2 - 1, depth, 0))
while (!do_plasma (drawable, ix1, iy1, ix2 - 1, iy2 - 1, depth, 0, preview_mode))
{
depth ++;
}
end_plasma (drawable);
end_plasma (drawable, preview_mode);
}
static void
init_plasma (GDrawable *drawable)
init_plasma (GDrawable *drawable,
gboolean preview_mode)
{
if (pvals.timeseed)
pvals.seed = time(NULL);
@ -402,23 +457,36 @@ init_plasma (GDrawable *drawable)
srand (pvals.seed);
turbulence = pvals.turbulence;
gimp_drawable_mask_bounds (drawable->id, &ix1, &iy1, &ix2, &iy2);
if (preview_mode)
{
ix1 = iy1 = 0;
ix2 = GTK_PREVIEW (preview)->buffer_width;
iy2 = GTK_PREVIEW (preview)->buffer_height;
bpp = GTK_PREVIEW (preview)->bpp;
alpha = bpp;
has_alpha = 0;
work_buffer = g_malloc (ix2 * iy2 * bpp);
memcpy (work_buffer, GTK_PREVIEW (preview)->buffer, ix2 * iy2 * bpp);
}
else
{
gimp_drawable_mask_bounds (drawable->id, &ix1, &iy1, &ix2, &iy2);
bpp = drawable->bpp;
has_alpha = gimp_drawable_has_alpha (drawable->id);
if (has_alpha)
alpha = bpp-1;
else
alpha = bpp;
}
max_progress = (ix2 - ix1) * (iy2 - iy1);
progress = 0;
tile_width = gimp_tile_width ();
tile_width = gimp_tile_width ();
tile_height = gimp_tile_height ();
tile = NULL;
tile_row = 0; tile_col = 0;
bpp = drawable->bpp;
has_alpha = gimp_drawable_has_alpha (drawable->id);
if (has_alpha)
alpha = bpp-1;
else
alpha = bpp;
}
static void
@ -430,6 +498,7 @@ provide_tile (GDrawable *drawable,
{
if (tile)
gimp_tile_unref (tile, tile_dirty);
tile_col = col;
tile_row = row;
tile = gimp_drawable_get_tile (drawable, TRUE, tile_row, tile_col);
@ -439,22 +508,33 @@ provide_tile (GDrawable *drawable,
}
static void
end_plasma (GDrawable *drawable)
end_plasma (GDrawable *drawable,
gboolean preview_mode)
{
if (tile)
gimp_tile_unref (tile, tile_dirty);
tile = NULL;
if (preview_mode)
{
memcpy (GTK_PREVIEW (preview)->buffer, work_buffer, ix2 * iy2 * bpp);
g_free (work_buffer);
gtk_widget_queue_draw (preview);
}
else
{
if (tile)
gimp_tile_unref (tile, tile_dirty);
tile = NULL;
gimp_drawable_flush (drawable);
gimp_drawable_merge_shadow (drawable->id, TRUE);
gimp_drawable_update (drawable->id, ix1, iy1, (ix2 - ix1), (iy2 - iy1));
gimp_drawable_flush (drawable);
gimp_drawable_merge_shadow (drawable->id, TRUE);
gimp_drawable_update (drawable->id, ix1, iy1, (ix2 - ix1), (iy2 - iy1));
}
}
static void
get_pixel (GDrawable *drawable,
gint x,
gint y,
guchar *pixel)
guchar *pixel,
gboolean preview_mode)
{
gint row, col;
gint offx, offy, i;
@ -465,23 +545,31 @@ get_pixel (GDrawable *drawable,
if (y < iy1) y = iy1;
if (y > iy2 - 1) y = iy2 - 1;
col = x / tile_width;
row = y / tile_height;
offx = x % tile_width;
offy = y % tile_height;
if (preview_mode)
{
memcpy (pixel, work_buffer + (y * ix2 * bpp) + (x * bpp), bpp);
}
else
{
col = x / tile_width;
row = y / tile_height;
offx = x % tile_width;
offy = y % tile_height;
provide_tile (drawable, col, row);
ptr = tile->data + (offy * tile->ewidth + offx) * bpp;
provide_tile (drawable, col, row);
ptr = tile->data + (offy * tile->ewidth + offx) * bpp;
for(i = 0; i < alpha; i++)
pixel[i] = ptr[i];
for (i = 0; i < alpha; i++)
pixel[i] = ptr[i];
}
}
static void
put_pixel (GDrawable *drawable,
gint x,
gint y,
guchar *pixel)
guchar *pixel,
gboolean preview_mode)
{
gint row, col;
gint offx, offy, i;
@ -492,22 +580,27 @@ put_pixel (GDrawable *drawable,
if (y < iy1) y = iy1;
if (y > iy2 - 1) y = iy2 - 1;
col = x / tile_width;
row = y / tile_height;
offx = x % tile_width;
offy = y % tile_height;
if (preview_mode)
memcpy (work_buffer + (y * ix2 * bpp) + (x * bpp), pixel, bpp);
else
{
col = x / tile_width;
row = y / tile_height;
offx = x % tile_width;
offy = y % tile_height;
provide_tile (drawable, col, row);
provide_tile (drawable, col, row);
ptr = tile->data + (offy * tile->ewidth + offx) * bpp;
ptr = tile->data + (offy * tile->ewidth + offx) * bpp;
for(i = 0; i < alpha; i++)
ptr[i] = pixel[i];
if (has_alpha)
ptr[alpha] = 255;
for (i = 0; i < alpha; i++)
ptr[i] = pixel[i];
tile_dirty = TRUE;
if (has_alpha)
ptr[alpha] = 255;
progress++;
tile_dirty = TRUE;
progress++;
}
}
static void
@ -557,7 +650,8 @@ do_plasma (GDrawable *drawable,
gint x2,
gint y2,
gint depth,
gint scale_depth)
gint scale_depth,
gboolean preview_mode)
{
guchar tl[3], ml[3], bl[3], mt[3], mm[3], mb[3], tr[3], mr[3], br[3];
guchar tmp[3];
@ -571,23 +665,23 @@ do_plasma (GDrawable *drawable,
if (depth == -1)
{
random_rgb (tl);
put_pixel (drawable, x1, y1, tl);
put_pixel (drawable, x1, y1, tl, preview_mode);
random_rgb (tr);
put_pixel (drawable, x2, y1, tr);
put_pixel (drawable, x2, y1, tr, preview_mode);
random_rgb (bl);
put_pixel (drawable, x1, y2, bl);
put_pixel (drawable, x1, y2, bl, preview_mode);
random_rgb (br);
put_pixel (drawable, x2, y2, br);
put_pixel (drawable, x2, y2, br, preview_mode);
random_rgb (mm);
put_pixel (drawable, (x1 + x2) / 2, (y1 + y2) / 2, mm);
put_pixel (drawable, (x1 + x2) / 2, (y1 + y2) / 2, mm, preview_mode);
random_rgb (ml);
put_pixel (drawable, x1, (y1 + y2) / 2, ml);
put_pixel (drawable, x1, (y1 + y2) / 2, ml, preview_mode);
random_rgb (mr);
put_pixel (drawable, x2, (y1 + y2) / 2, mr);
put_pixel (drawable, x2, (y1 + y2) / 2, mr, preview_mode);
random_rgb (mt);
put_pixel (drawable, (x1 + x2) / 2, y1, mt);
put_pixel (drawable, (x1 + x2) / 2, y1, mt, preview_mode);
random_rgb (ml);
put_pixel (drawable, (x1 + x2) / 2, y2, ml);
put_pixel (drawable, (x1 + x2) / 2, y2, ml, preview_mode);
return 0;
}
@ -601,10 +695,10 @@ do_plasma (GDrawable *drawable,
gdouble rnd;
gint xave, yave;
get_pixel (drawable, x1, y1, tl);
get_pixel (drawable, x1, y2, bl);
get_pixel (drawable, x2, y1, tr);
get_pixel (drawable, x2, y2, br);
get_pixel (drawable, x1, y1, tl, preview_mode);
get_pixel (drawable, x1, y2, bl, preview_mode);
get_pixel (drawable, x2, y1, tr, preview_mode);
get_pixel (drawable, x2, y2, br, preview_mode);
rnd = (256.0 / (2.0 * (gdouble)scale_depth)) * turbulence;
ran = rnd;
@ -622,14 +716,14 @@ do_plasma (GDrawable *drawable,
/* Left. */
AVE (ml, tl, bl);
add_random (ml, ran);
put_pixel (drawable, x1, yave, ml);
put_pixel (drawable, x1, yave, ml, preview_mode);
if (x1 != x2)
{
/* Right. */
AVE (mr, tr, br);
add_random (mr, ran);
put_pixel (drawable, x2, yave, mr);
put_pixel (drawable, x2, yave, mr, preview_mode);
}
}
@ -640,7 +734,7 @@ do_plasma (GDrawable *drawable,
/* Bottom. */
AVE (mb, bl, br);
add_random (mb, ran);
put_pixel (drawable, xave, y2, mb);
put_pixel (drawable, xave, y2, mb, preview_mode);
}
if (y1 != y2)
@ -648,7 +742,7 @@ do_plasma (GDrawable *drawable,
/* Top. */
AVE (mt, tl, tr);
add_random (mt, ran);
put_pixel (drawable, xave, y1, mt);
put_pixel (drawable, xave, y1, mt, preview_mode);
}
}
@ -660,12 +754,12 @@ do_plasma (GDrawable *drawable,
AVE (mm, mm, tmp);
add_random (mm, ran);
put_pixel (drawable, xave, yave, mm);
put_pixel (drawable, xave, yave, mm, preview_mode);
}
count ++;
if (!(count % 2000))
if (!(count % 2000) && !preview_mode)
{
gimp_progress_update ((double) progress / (double) max_progress);
}
@ -681,11 +775,33 @@ do_plasma (GDrawable *drawable,
ym = (y1 + y2) >> 1;
/* Top left. */
do_plasma (drawable, x1, y1, xm, ym, depth - 1, scale_depth + 1);
do_plasma (drawable, x1, y1, xm, ym, depth - 1, scale_depth + 1, preview_mode);
/* Bottom left. */
do_plasma (drawable, x1, ym, xm ,y2, depth - 1, scale_depth + 1);
do_plasma (drawable, x1, ym, xm ,y2, depth - 1, scale_depth + 1, preview_mode);
/* Top right. */
do_plasma (drawable, xm, y1, x2 , ym, depth - 1, scale_depth + 1);
do_plasma (drawable, xm, y1, x2 , ym, depth - 1, scale_depth + 1, preview_mode);
/* Bottom right. */
return do_plasma (drawable, xm, ym, x2, y2, depth - 1, scale_depth + 1);
return do_plasma (drawable, xm, ym, x2, y2, depth - 1, scale_depth + 1, preview_mode);
}
/* preview library */
static GtkWidget *
preview_widget (void)
{
GtkWidget *preview;
guchar *buf;
gint y;
preview = gtk_preview_new (GTK_PREVIEW_COLOR);
gtk_preview_size (GTK_PREVIEW (preview), PREVIEW_SIZE, PREVIEW_SIZE);
buf = g_malloc0 (PREVIEW_SIZE * 3);
for (y = 0; y < PREVIEW_SIZE; y++)
gtk_preview_draw_row (GTK_PREVIEW (preview), buf, 0, y, PREVIEW_SIZE);
g_free (buf);
return preview;
}

View File

@ -1,5 +1,5 @@
/*
* wind - a plug-in for the GIMP
* wind 1.1.0 - a plug-in for the GIMP
*
* Copyright (C) Nigel Wetten
*
@ -18,8 +18,13 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*
* Contact info: nigel@cs.nwu.edu
*
* Version: 1.0.0
*
* Version: 1.1.0
* May 2000 tim copperfield [timecop@japan.co.jp]
*
* Added dynamic preview.
*
*/
#include "config.h"
@ -44,6 +49,7 @@
#define MAX_THRESHOLD 50
#define MIN_STRENGTH 1
#define MAX_STRENGTH 50
#define PREVIEW_SIZE 128
typedef enum
{
@ -72,26 +78,57 @@ static void run (gchar *name,
gint *nreturn_vals,
GParam **return_vals);
static void dialog_box (void);
static gint render_effect (GDrawable *drawable);
static void render_wind (GDrawable *drawable, gint threshold, gint strength,
direction_t direction, edge_t edge);
static void render_blast (GDrawable *drawable, gint threshold, gint strength,
direction_t direction, edge_t edge);
static gint render_blast_row (guchar *buffer, gint bytes, gint lpi,
gint threshold,
gint strength, edge_t edge);
static void render_wind_row (guchar *sb, gint bytes, gint lpi, gint threshold,
gint strength, edge_t edge);
static void dialog_box (GDrawable *drawable);
static void ok_callback (GtkWidget *widget,
gpointer data);
static void radio_callback (GtkWidget *widget,
gpointer data);
static void ok_callback (GtkWidget *widget, gpointer data);
static gint render_effect (GDrawable *drawable,
gboolean preview_mode);
static void render_wind (GDrawable *drawable,
gint threshold,
gint strength,
direction_t direction,
edge_t edge,
gboolean preview_mode);
static void render_blast (GDrawable *drawable,
gint threshold,
gint strength,
direction_t direction,
edge_t edge,
gboolean preview_mode);
static gint render_blast_row (guchar *buffer,
gint bytes,
gint lpi,
gint threshold,
gint strength,
edge_t edge);
static void render_wind_row (guchar *sb,
gint bytes,
gint lpi,
gint threshold,
gint strength,
edge_t edge);
static void get_derivative (guchar *pixel_R1, guchar *pixel_R2,
edge_t edge, gint *derivative_R,
gint *derivative_G, gint *derivative_B);
static gint threshold_exceeded (guchar *pixel_R1, guchar *pixel_R2,
edge_t edge, gint threshold);
static void reverse_buffer (guchar *buffer, gint length, gint bytes);
static void get_derivative (guchar *pixel_R1,
guchar *pixel_R2,
edge_t edge,
gint *derivative_R,
gint *derivative_G,
gint *derivative_B);
static gint threshold_exceeded (guchar *pixel_R1,
guchar *pixel_R2,
edge_t edge,
gint threshold);
static void reverse_buffer (guchar *buffer,
gint length,
gint bytes);
static void fill_preview (GtkWidget *preview_widget,
GDrawable *drawable);
static GtkWidget *preview_widget (GDrawable *drawable);
GPlugInInfo PLUG_IN_INFO =
@ -117,7 +154,9 @@ struct config_tag
direction_t direction; /* of wind, LEFT or RIGHT */
gint strength; /* how many pixels to bleed */
algorithm_t alg; /* which algorithm */
edge_t edge; /* controls abs, negation of derivative */
edge_t edge; /* controls abs, ne+ static guchar *preview_bits;
+ static GtkWidget *preview;
gation of derivative */
};
typedef struct config_tag config_t;
@ -130,6 +169,9 @@ config_t config =
LEADING /* abs(derivative); */
};
static guchar *preview_bits;
static GtkWidget *preview;
MAIN ()
@ -154,7 +196,7 @@ query (void)
"Renders a wind effect.",
"Nigel Wetten",
"Nigel Wetten",
"1998",
"May 2000",
N_("<Image>/Filters/Distorts/Wind..."),
"RGB*",
PROC_PLUG_IN,
@ -193,7 +235,7 @@ run (gchar *name,
config.alg = param[6].data.d_int32;
config.edge = param[7].data.d_int32;
if (render_effect(drawable) == -1)
if (render_effect(drawable, 0) == -1)
status = STATUS_EXECUTION_ERROR;
}
break;
@ -201,17 +243,18 @@ run (gchar *name,
case RUN_INTERACTIVE:
INIT_I18N_UI();
gimp_get_data("plug_in_wind", &config);
dialog_box();
dialog_box(drawable);
if (dialog_result == -1)
{
status = STATUS_EXECUTION_ERROR;
break;
}
if (render_effect(drawable) == -1)
if (render_effect(drawable, 0) == -1)
{
status = STATUS_CALLING_ERROR;
break;
}
g_free(preview_bits);
gimp_set_data("plug_in_wind", &config, sizeof(config_t));
gimp_displays_flush();
break;
@ -219,14 +262,14 @@ run (gchar *name,
case RUN_WITH_LAST_VALS:
INIT_I18N();
gimp_get_data("plug_in_wind", &config);
if (render_effect(drawable) == -1)
if (render_effect (drawable, FALSE) == -1)
{
status = STATUS_EXECUTION_ERROR;
gimp_message("An execution error occured.");
}
else
{
gimp_displays_flush();
gimp_displays_flush ();
}
}
@ -241,19 +284,18 @@ run (gchar *name,
}
static gint
render_effect (GDrawable *drawable)
render_effect (GDrawable *drawable,
gboolean preview_mode)
{
if (config.alg == RENDER_WIND)
{
gimp_progress_init( _("Rendering Wind..."));
render_wind(drawable, config.threshold, config. strength,
config.direction, config.edge);
render_wind (drawable, config.threshold, config.strength,
config.direction, config.edge, preview_mode);
}
else if (config.alg == RENDER_BLAST)
{
gimp_progress_init( _("Rendering Blast..."));
render_blast(drawable, config.threshold, config.strength,
config.direction, config.edge);
render_blast (drawable, config.threshold, config.strength,
config.direction, config.edge, preview_mode);
}
return 0;
}
@ -263,7 +305,8 @@ render_blast (GDrawable *drawable,
gint threshold,
gint strength,
direction_t direction,
edge_t edge)
edge_t edge,
gboolean preview_mode)
{
gint x1, x2, y1, y2;
gint width;
@ -276,21 +319,37 @@ render_blast (GDrawable *drawable,
gint marker = 0;
gint lpi;
gimp_drawable_mask_bounds (drawable->id, &x1, &y1, &x2, &y2);
if (preview_mode)
{
width = GTK_PREVIEW (preview)->buffer_width;
height = GTK_PREVIEW (preview)->buffer_height;
bytes = GTK_PREVIEW (preview)->bpp;
x1 = y1 = 0;
x2 = width;
y2 = height;
}
else
{
gimp_progress_init( _("Rendering Blast..."));
gimp_drawable_mask_bounds (drawable->id, &x1, &y1, &x2, &y2);
width = x2 - x1;
height = y2 - y1;
gimp_pixel_rgn_init (&src_region, drawable, x1, y1, width, height, FALSE, FALSE);
gimp_pixel_rgn_init (&dest_region, drawable, x1, y1, width, height, TRUE, TRUE);
}
width = x2 - x1;
height = y2 - y1;
row_stride = width * bytes;
lpi = row_stride - bytes;
gimp_pixel_rgn_init (&src_region, drawable, x1, y1, width, height, FALSE, FALSE);
gimp_pixel_rgn_init (&dest_region, drawable, x1, y1, width, height, TRUE, TRUE);
buffer = (guchar *) g_malloc(row_stride);
for (row = y1; row < y2; row++)
{
gimp_pixel_rgn_get_row (&src_region, buffer, x1, row, width);
if (preview_mode)
memcpy (buffer, preview_bits + (row * bytes * width), width * bytes);
else
gimp_pixel_rgn_get_row (&src_region, buffer, x1, row, width);
if (direction == RIGHT)
{
@ -304,8 +363,15 @@ render_blast (GDrawable *drawable,
reverse_buffer (buffer, row_stride, bytes);
}
gimp_pixel_rgn_set_row (&dest_region, buffer, x1, row, width);
gimp_progress_update ((double) (row - y1)/ (double) (height));
if (preview_mode)
{
memcpy (GTK_PREVIEW (preview)->buffer + (width * bytes * row), buffer, width * bytes);
}
else
{
gimp_pixel_rgn_set_row (&dest_region, buffer, x1, row, width);
gimp_progress_update ((double) (row - y1)/ (double) (height));
}
if (marker)
{
@ -317,8 +383,17 @@ render_blast (GDrawable *drawable,
row++;
if (row < y2)
{
gimp_pixel_rgn_get_row (&src_region, buffer, x1, row, width);
gimp_pixel_rgn_set_row (&dest_region, buffer, x1, row, width);
if (preview_mode)
{
memcpy (buffer, preview_bits + (row * bytes * width), width * bytes);
memcpy (GTK_PREVIEW (preview)->buffer + (width * bytes * row),
buffer, width * bytes);
}
else
{
gimp_pixel_rgn_get_row (&src_region, buffer, x1, row, width);
gimp_pixel_rgn_set_row (&dest_region, buffer, x1, row, width);
}
}
}
marker = 0;
@ -328,9 +403,16 @@ render_blast (GDrawable *drawable,
g_free(buffer);
/* update the region */
gimp_drawable_flush (drawable);
gimp_drawable_merge_shadow (drawable->id, TRUE);
gimp_drawable_update (drawable->id, x1, y1, x2 - x1, y2 - y1);
if (preview_mode)
{
gtk_widget_queue_draw (preview);
}
else
{
gimp_drawable_flush (drawable);
gimp_drawable_merge_shadow (drawable->id, TRUE);
gimp_drawable_update (drawable->id, x1, y1, x2 - x1, y2 - y1);
}
return;
}
@ -340,12 +422,13 @@ render_wind (GDrawable *drawable,
gint threshold,
gint strength,
direction_t direction,
edge_t edge)
edge_t edge,
gboolean preview_mode)
{
GPixelRgn src_region, dest_region;
gint width;
gint height;
gint bytes = drawable->bpp;
gint bytes;
gint row_stride;
gint comp_stride;
gint row;
@ -353,45 +436,72 @@ render_wind (GDrawable *drawable,
gint lpi;
gint x1, y1, x2, y2;
gimp_drawable_mask_bounds (drawable->id, &x1, &y1, &x2, &y2);
if (preview_mode)
{
width = GTK_PREVIEW (preview)->buffer_width;
height = GTK_PREVIEW (preview)->buffer_height;
bytes = GTK_PREVIEW (preview)->bpp;
width = x2 - x1;
height = y2 - y1;
x1 = y1 = 0;
x2 = width;
y2 = height;
}
else
{
gimp_progress_init( _("Rendering Wind..."));
gimp_drawable_mask_bounds (drawable->id, &x1, &y1, &x2, &y2);
bytes = drawable->bpp;
width = x2 - x1;
height = y2 - y1;
gimp_pixel_rgn_init (&src_region, drawable, x1, y1, width, height, FALSE, FALSE);
gimp_pixel_rgn_init (&dest_region, drawable, x1, y1, width, height, TRUE, TRUE);
}
row_stride = width * bytes;
comp_stride = bytes * COMPARE_WIDTH;
lpi = row_stride - comp_stride;
gimp_pixel_rgn_init (&src_region, drawable, x1, y1, width, height, FALSE, FALSE);
gimp_pixel_rgn_init (&dest_region, drawable, x1, y1, width, height, TRUE, TRUE);
sb = g_malloc (row_stride);
for (row = y1; row < y2; row++)
{
gimp_pixel_rgn_get_row (&src_region, sb, x1, row, width);
if (preview_mode)
memcpy (sb, preview_bits + (row * bytes * width), width * bytes);
else
gimp_pixel_rgn_get_row (&src_region, sb, x1, row, width);
if (direction == RIGHT)
{
reverse_buffer (sb, row_stride, bytes);
}
reverse_buffer (sb, row_stride, bytes);
render_wind_row (sb, bytes, lpi, threshold, strength, edge);
if (direction == RIGHT)
{
reverse_buffer(sb, row_stride, bytes);
}
reverse_buffer(sb, row_stride, bytes);
gimp_pixel_rgn_set_row (&dest_region, sb, x1, row, width);
gimp_progress_update ((double) (row - y1)/ (double) (height));
if (preview_mode)
{
memcpy (GTK_PREVIEW (preview)->buffer + (width * bytes * row), sb, width * bytes);
}
else
{
gimp_pixel_rgn_set_row (&dest_region, sb, x1, row, width);
gimp_progress_update ((double) (row - y1)/ (double) (height));
}
}
g_free(sb);
/* update the region */
gimp_drawable_flush (drawable);
gimp_drawable_merge_shadow (drawable->id, TRUE);
gimp_drawable_update (drawable->id, x1, y1, x2 - x1, y2 - y1);
if (preview_mode)
{
gtk_widget_queue_draw (preview);
}
else
{
gimp_drawable_flush (drawable);
gimp_drawable_merge_shadow (drawable->id, TRUE);
gimp_drawable_update (drawable->id, x1, y1, x2 - x1, y2 - y1);
}
return;
}
@ -692,13 +802,33 @@ ok_callback (GtkWidget *widget,
}
static void
dialog_box (void)
radio_callback (GtkWidget *widget,
gpointer data)
{
GDrawable *drawable;
gimp_radio_button_update (widget, data);
drawable = gtk_object_get_data (GTK_OBJECT (widget), "drawable");
render_effect (drawable, TRUE);
}
static void
dialog_box (GDrawable *drawable)
{
GtkWidget *main_vbox;
GtkWidget *vbox;
GtkWidget *abox;
GtkWidget *table;
GtkObject *adj;
GtkWidget *frame;
GtkWidget *dlg;
GtkWidget *style1;
GtkWidget *style2;
GtkWidget *dir1;
GtkWidget *dir2;
GtkWidget *edge1;
GtkWidget *edge2;
GtkWidget *edge3;
gimp_ui_init ("wind", FALSE);
@ -720,15 +850,37 @@ dialog_box (void)
/* init tooltips */
gimp_help_init ();
vbox = gtk_vbox_new (FALSE, 2);
gtk_container_set_border_width (GTK_CONTAINER (vbox), 0);
gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dlg)->vbox), vbox, TRUE, TRUE, 0);
gtk_widget_show (vbox);
frame = gtk_frame_new (_("Preview"));
gtk_container_set_border_width (GTK_CONTAINER (frame), 6);
gtk_box_pack_start (GTK_BOX (vbox), frame, FALSE, FALSE, 0);
gtk_widget_show (frame);
abox = gtk_alignment_new (0.5, 0.5, 0.0, 0.0);
gtk_container_set_border_width (GTK_CONTAINER (abox), 4);
gtk_container_add (GTK_CONTAINER (frame), abox);
gtk_widget_show (abox);
frame = gtk_frame_new (NULL);
gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_IN);
gtk_container_add (GTK_CONTAINER (abox), frame);
gtk_widget_show (frame);
preview = preview_widget (drawable); /* we are here */
gtk_container_add (GTK_CONTAINER (frame), preview);
render_effect (drawable, TRUE); /* render preview image */
gtk_widget_show (preview);
frame = gtk_frame_new (_("Parameter Settings"));
gtk_container_set_border_width (GTK_CONTAINER (frame), 6);
gtk_container_add (GTK_CONTAINER (GTK_DIALOG (dlg)->vbox), frame);
gtk_box_pack_start (GTK_BOX (vbox), frame, TRUE, TRUE, 0);
gtk_widget_show (frame);
main_vbox = gtk_vbox_new (FALSE, 4);
gtk_container_set_border_width (GTK_CONTAINER (main_vbox), 6);
gtk_container_add (GTK_CONTAINER (frame), main_vbox);
gtk_container_set_border_width (GTK_CONTAINER (main_vbox), 4);
gtk_widget_show (main_vbox);
/*****************************************************
@ -736,7 +888,8 @@ dialog_box (void)
***************************************************/
table = gtk_table_new (1, 3, FALSE);
gtk_table_set_col_spacings (GTK_TABLE(table), 4);
gtk_table_set_col_spacings (GTK_TABLE (table), 4);
gtk_table_set_row_spacings (GTK_TABLE (table), 2);
gtk_box_pack_start (GTK_BOX (main_vbox), table, FALSE, FALSE, 0);
/*********************************************************
@ -744,13 +897,14 @@ dialog_box (void)
******************************************************/
frame = gimp_radio_group_new2 (TRUE, _("Style"),
gimp_radio_button_update,
radio_callback,
&config.alg, (gpointer) config.alg,
_("Wind"), (gpointer) RENDER_WIND, NULL,
_("Blast"), (gpointer) RENDER_BLAST, NULL,
_("Wind"), (gpointer) RENDER_WIND, &style1,
_("Blast"), (gpointer) RENDER_BLAST, &style2,
NULL);
gtk_object_set_data (GTK_OBJECT (style1), "drawable", drawable);
gtk_object_set_data (GTK_OBJECT (style2), "drawable", drawable);
gtk_table_attach (GTK_TABLE (table), frame, 0, 1, 0, 1,
GTK_FILL | GTK_EXPAND, GTK_FILL | GTK_EXPAND, 0, 0);
@ -761,13 +915,13 @@ dialog_box (void)
**************************************************/
frame = gimp_radio_group_new2 (TRUE, _("Direction"),
gimp_radio_button_update,
radio_callback,
&config.direction, (gpointer) config.direction,
_("Left"), (gpointer) LEFT, NULL,
_("Right"), (gpointer) RIGHT, NULL,
_("Left"), (gpointer) LEFT, &dir1,
_("Right"), (gpointer) RIGHT, &dir2,
NULL);
gtk_object_set_data (GTK_OBJECT (dir1), "drawable", drawable);
gtk_object_set_data (GTK_OBJECT (dir2), "drawable", drawable);
gtk_table_attach (GTK_TABLE (table), frame, 1, 2, 0, 1,
GTK_FILL | GTK_EXPAND, GTK_FILL | GTK_EXPAND, 0, 0);
@ -778,14 +932,17 @@ dialog_box (void)
***************************************************/
frame = gimp_radio_group_new2 (TRUE, _("Edge Affected"),
gimp_radio_button_update,
radio_callback,
&config.edge, (gpointer) config.edge,
_("Leading"), (gpointer) LEADING, NULL,
_("Trailing"), (gpointer) TRAILING, NULL,
_("Both"), (gpointer) BOTH, NULL,
_("Leading"), (gpointer) LEADING, &edge1,
_("Trailing"), (gpointer) TRAILING, &edge2,
_("Both"), (gpointer) BOTH, &edge3,
NULL);
gtk_object_set_data (GTK_OBJECT (edge1), "drawable", drawable);
gtk_object_set_data (GTK_OBJECT (edge2), "drawable", drawable);
gtk_object_set_data (GTK_OBJECT (edge3), "drawable", drawable);
gtk_table_attach (GTK_TABLE (table), frame, 2, 3, 0, 1,
GTK_FILL | GTK_EXPAND, GTK_FILL | GTK_EXPAND, 0, 0);
@ -814,6 +971,9 @@ dialog_box (void)
gtk_signal_connect (GTK_OBJECT (adj), "value_changed",
GTK_SIGNAL_FUNC (gimp_int_adjustment_update),
&config.threshold);
gtk_signal_connect_object (GTK_OBJECT (adj), "value_changed",
GTK_SIGNAL_FUNC (render_effect),
(gpointer)drawable);
/*****************************************************
slider and entry for strength of wind
@ -825,9 +985,13 @@ dialog_box (void)
MIN_STRENGTH, MAX_STRENGTH, 1.0, 10.0, 0,
TRUE, 0, 0,
_("Higher values increase the magnitude of the effect"), NULL);
gtk_signal_connect (GTK_OBJECT (adj), "value_changed",
GTK_SIGNAL_FUNC (gimp_int_adjustment_update),
&config.strength);
gtk_signal_connect_object (GTK_OBJECT (adj), "value_changed",
GTK_SIGNAL_FUNC (render_effect),
(gpointer)drawable);
gtk_widget_show (table);
@ -836,3 +1000,124 @@ dialog_box (void)
gtk_main ();
gdk_flush ();
}
static GtkWidget *
preview_widget (GDrawable *drawable)
{
gint size;
GtkWidget *preview;
preview = gtk_preview_new (GTK_PREVIEW_COLOR);
fill_preview (preview, drawable);
size = (GTK_PREVIEW (preview)->buffer_width) *
(GTK_PREVIEW (preview)->buffer_height) *
(GTK_PREVIEW (preview)->bpp);
preview_bits = g_malloc (size);
memcpy (preview_bits, GTK_PREVIEW (preview)->buffer, size);
return preview;
}
static void
fill_preview (GtkWidget *widget,
GDrawable *drawable)
{
GPixelRgn srcPR;
gint width;
gint height;
gint x1, x2, y1, y2;
gint bpp;
gint x, y;
guchar *src;
gdouble r, g, b, a;
gdouble c0, c1;
guchar *p0, *p1;
guchar *even, *odd;
gimp_drawable_mask_bounds (drawable->id, &x1, &y1, &x2, &y2);
if (x2 - x1 > PREVIEW_SIZE)
x2 = x1 + PREVIEW_SIZE;
if (y2 - y1 > PREVIEW_SIZE)
y2 = y1 + PREVIEW_SIZE;
width = x2 - x1;
height = y2 - y1;
bpp = gimp_drawable_bpp (drawable->id);
if (width < 1 || height < 1)
return;
gtk_preview_size (GTK_PREVIEW (widget), width, height);
gimp_pixel_rgn_init (&srcPR, drawable, x1, y1, x2, y2, FALSE, FALSE);
even = g_malloc (width * 3);
odd = g_malloc (width * 3);
src = g_malloc (width * bpp);
for (y = 0; y < height; y++)
{
gimp_pixel_rgn_get_row (&srcPR, src, x1, y + y1, width);
p0 = even;
p1 = odd;
for (x = 0; x < width; x++)
{
if (bpp == 4)
{
r = ((gdouble)src[x*4+0]) / 255.0;
g = ((gdouble)src[x*4+1]) / 255.0;
b = ((gdouble)src[x*4+2]) / 255.0;
a = ((gdouble)src[x*4+3]) / 255.0;
}
else if (bpp == 3)
{
r = ((gdouble)src[x*3+0]) / 255.0;
g = ((gdouble)src[x*3+1]) / 255.0;
b = ((gdouble)src[x*3+2]) / 255.0;
a = 1.0;
}
else
{
r = ((gdouble)src[x*bpp+0]) / 255.0;
g = b = r;
if (bpp == 2)
a = ((gdouble)src[x*bpp+1]) / 255.0;
else
a = 1.0;
}
if ((x / GIMP_CHECK_SIZE) & 1)
{
c0 = GIMP_CHECK_LIGHT;
c1 = GIMP_CHECK_DARK;
}
else
{
c0 = GIMP_CHECK_DARK;
c1 = GIMP_CHECK_LIGHT;
}
*p0++ = (c0 + (r - c0) * a) * 255.0;
*p0++ = (c0 + (g - c0) * a) * 255.0;
*p0++ = (c0 + (b - c0) * a) * 255.0;
*p1++ = (c1 + (r - c1) * a) * 255.0;
*p1++ = (c1 + (g - c1) * a) * 255.0;
*p1++ = (c1 + (b - c1) * a) * 255.0;
} /* for */
if ((y / GIMP_CHECK_SIZE) & 1)
gtk_preview_draw_row (GTK_PREVIEW (widget), (guchar *)odd, 0, y, width);
else
gtk_preview_draw_row (GTK_PREVIEW (widget), (guchar *)even, 0, y, width);
}
g_free (even);
g_free (odd);
g_free (src);
}