some code cleanup.

2003-09-17  Sven Neumann  <sven@gimp.org>

	* plug-ins/common/sparkle.c: some code cleanup.
This commit is contained in:
Sven Neumann 2003-09-17 12:53:52 +00:00 committed by Sven Neumann
parent 2ce758b846
commit f2da45b6da
2 changed files with 310 additions and 256 deletions
ChangeLog
plug-ins/common

View File

@ -1,3 +1,7 @@
2003-09-17 Sven Neumann <sven@gimp.org>
* plug-ins/common/sparkle.c: some code cleanup.
2003-09-17 Michael Natterer <mitch@gimp.org> 2003-09-17 Michael Natterer <mitch@gimp.org>
Added nomis' favorite feature ;) Added nomis' favorite feature ;)

View File

@ -1,5 +1,6 @@
/* Sparkle --- image filter plug-in for The Gimp image manipulation program /* Sparkle --- image filter plug-in for The Gimp image manipulation program
* Copyright (C) 1996 by John Beale; ported to Gimp by Michael J. Hammel; * Copyright (C) 1996 by John Beale; ported to Gimp by Michael J. Hammel;
*
* It has been optimized a little, bugfixed and modified by Martin Weber * It has been optimized a little, bugfixed and modified by Martin Weber
* for additional functionality. Also bugfixed by Seth Burgess (9/17/03) * for additional functionality. Also bugfixed by Seth Burgess (9/17/03)
* to take rowstrides into account when selections are present (bug #50911). * to take rowstrides into account when selections are present (bug #50911).
@ -43,7 +44,7 @@
#define SCALE_WIDTH 175 #define SCALE_WIDTH 175
#define ENTRY_WIDTH 5 #define ENTRY_WIDTH 7
#define MAX_CHANNELS 4 #define MAX_CHANNELS 4
#define PSV 2 /* point spread value */ #define PSV 2 /* point spread value */
#define EPSILON 0.001 #define EPSILON 0.001
@ -63,9 +64,9 @@ typedef struct
gdouble opacity; gdouble opacity;
gdouble random_hue; gdouble random_hue;
gdouble random_saturation; gdouble random_saturation;
gint preserve_luminosity; gboolean preserve_luminosity;
gint invers; gboolean inverse;
gint border; gboolean border;
gint colortype; gint colortype;
} SparkleVals; } SparkleVals;
@ -88,16 +89,15 @@ static gint sparkle_dialog (void);
static void sparkle_ok_callback (GtkWidget *widget, static void sparkle_ok_callback (GtkWidget *widget,
gpointer data); gpointer data);
static gint compute_luminosity (guchar *pixel, static gint compute_luminosity (const guchar *pixel,
gint gray, gboolean gray,
gint has_alpha); gboolean has_alpha);
static gint compute_lum_threshold (GimpDrawable *drawable, static gint compute_lum_threshold (GimpDrawable *drawable,
gdouble percentile); gdouble percentile);
static void sparkle (GimpDrawable *drawable, static void sparkle (GimpDrawable *drawable,
gint threshold); gint threshold);
static void fspike (GimpPixelRgn *src_rgn, static void fspike (GimpPixelRgn *src_rgn,
GimpPixelRgn *dest_rgn, GimpPixelRgn *dest_rgn,
gint gray,
gint x1, gint x1,
gint y1, gint y1,
gint x2, gint x2,
@ -126,6 +126,7 @@ static GimpTile * rpnt (GimpDrawable *drawable,
gdouble inten, gdouble inten,
guchar color[MAX_CHANNELS]); guchar color[MAX_CHANNELS]);
GimpPlugInInfo PLUG_IN_INFO = GimpPlugInInfo PLUG_IN_INFO =
{ {
NULL, /* init_proc */ NULL, /* init_proc */
@ -146,7 +147,7 @@ static SparkleVals svals =
0.0, /* random hue */ 0.0, /* random hue */
0.0, /* random saturation */ 0.0, /* random saturation */
FALSE, /* preserve_luminosity */ FALSE, /* preserve_luminosity */
FALSE, /* invers */ FALSE, /* inverse */
FALSE, /* border */ FALSE, /* border */
NATURAL /* colortype */ NATURAL /* colortype */
}; };
@ -179,7 +180,7 @@ query (void)
{ GIMP_PDB_FLOAT, "random_hue", "Random hue (0.0 - 1.0)" }, { GIMP_PDB_FLOAT, "random_hue", "Random hue (0.0 - 1.0)" },
{ GIMP_PDB_FLOAT, "random_saturation", "Random saturation (0.0 - 1.0)" }, { GIMP_PDB_FLOAT, "random_saturation", "Random saturation (0.0 - 1.0)" },
{ GIMP_PDB_INT32, "preserve_luminosity", "Preserve luminosity (TRUE/FALSE)" }, { GIMP_PDB_INT32, "preserve_luminosity", "Preserve luminosity (TRUE/FALSE)" },
{ GIMP_PDB_INT32, "invers", "Invers (TRUE/FALSE)" }, { GIMP_PDB_INT32, "inverse", "Inverse (TRUE/FALSE)" },
{ GIMP_PDB_INT32, "border", "Add border (TRUE/FALSE)" }, { GIMP_PDB_INT32, "border", "Add border (TRUE/FALSE)" },
{ GIMP_PDB_INT32, "colortype", "Color of sparkles: { NATURAL (0), FOREGROUND (1), BACKGROUND (2) }" } { GIMP_PDB_INT32, "colortype", "Color of sparkles: { NATURAL (0), FOREGROUND (1), BACKGROUND (2) }" }
}; };
@ -250,7 +251,7 @@ run (const gchar *name,
svals.random_hue = param[10].data.d_float; svals.random_hue = param[10].data.d_float;
svals.random_saturation = param[11].data.d_float; svals.random_saturation = param[11].data.d_float;
svals.preserve_luminosity = (param[12].data.d_int32) ? TRUE : FALSE; svals.preserve_luminosity = (param[12].data.d_int32) ? TRUE : FALSE;
svals.invers = (param[13].data.d_int32) ? TRUE : FALSE; svals.inverse = (param[13].data.d_int32) ? TRUE : FALSE;
svals.border = (param[14].data.d_int32) ? TRUE : FALSE; svals.border = (param[14].data.d_int32) ? TRUE : FALSE;
svals.colortype = param[15].data.d_int32; svals.colortype = param[15].data.d_int32;
@ -297,15 +298,18 @@ run (const gchar *name,
gimp_progress_init (_("Sparkling...")); gimp_progress_init (_("Sparkling..."));
gimp_tile_cache_ntiles (2 * (drawable->width / gimp_tile_width () + 1)); gimp_tile_cache_ntiles (2 * (drawable->width / gimp_tile_width () + 1));
if (svals.border == FALSE) if (svals.border)
/* compute the luminosity which exceeds the luminosity threshold */
threshold = compute_lum_threshold (drawable, svals.lum_threshold);
else
{ {
gimp_drawable_mask_bounds (drawable->drawable_id, &x1, &y1, &x2, &y2); gimp_drawable_mask_bounds (drawable->drawable_id,
&x1, &y1, &x2, &y2);
num_sparkles = 2 * (x2 - x1 + y2 - y1); num_sparkles = 2 * (x2 - x1 + y2 - y1);
threshold = 255; threshold = 255;
} }
else
{
/* compute the luminosity which exceeds the luminosity threshold */
threshold = compute_lum_threshold (drawable, svals.lum_threshold);
}
sparkle (drawable, threshold); sparkle (drawable, threshold);
@ -479,8 +483,8 @@ sparkle_dialog (void)
svals.preserve_luminosity); svals.preserve_luminosity);
gtk_widget_show (toggle); gtk_widget_show (toggle);
gimp_help_set_help_data (toggle, _("Should the Luminosity be preserved?"), gimp_help_set_help_data (toggle,
NULL); _("Should the Luminosity be preserved?"), NULL);
g_signal_connect (toggle, "toggled", g_signal_connect (toggle, "toggled",
G_CALLBACK (gimp_toggle_button_update), G_CALLBACK (gimp_toggle_button_update),
@ -488,14 +492,15 @@ sparkle_dialog (void)
toggle = gtk_check_button_new_with_mnemonic (_("In_verse")); toggle = gtk_check_button_new_with_mnemonic (_("In_verse"));
gtk_box_pack_start (GTK_BOX (vbox), toggle, FALSE, FALSE, 0); gtk_box_pack_start (GTK_BOX (vbox), toggle, FALSE, FALSE, 0);
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (toggle), svals.invers); gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (toggle), svals.inverse);
gtk_widget_show (toggle); gtk_widget_show (toggle);
gimp_help_set_help_data (toggle, _("Should an Inverse Effect be done?"), NULL); gimp_help_set_help_data (toggle,
_("Should an Inverse Effect be done?"), NULL);
g_signal_connect (toggle, "toggled", g_signal_connect (toggle, "toggled",
G_CALLBACK (gimp_toggle_button_update), G_CALLBACK (gimp_toggle_button_update),
&svals.invers); &svals.inverse);
toggle = gtk_check_button_new_with_mnemonic (_("A_dd Border")); toggle = gtk_check_button_new_with_mnemonic (_("A_dd Border"));
gtk_box_pack_start (GTK_BOX (vbox), toggle, FALSE, FALSE, 0); gtk_box_pack_start (GTK_BOX (vbox), toggle, FALSE, FALSE, 0);
@ -503,8 +508,7 @@ sparkle_dialog (void)
gtk_widget_show (toggle); gtk_widget_show (toggle);
gimp_help_set_help_data (toggle, gimp_help_set_help_data (toggle,
_("Draw a Border of Spikes around the Image"), _("Draw a Border of Spikes around the Image"), NULL);
NULL);
g_signal_connect (toggle, "toggled", g_signal_connect (toggle, "toggled",
G_CALLBACK (gimp_toggle_button_update), G_CALLBACK (gimp_toggle_button_update),
@ -548,24 +552,25 @@ sparkle_dialog (void)
} }
static gint static gint
compute_luminosity (guchar *pixel, compute_luminosity (const guchar *pixel,
gint gray, gboolean gray,
gint has_alpha) gboolean has_alpha)
{ {
gint pixel0, pixel1, pixel2; gint pixel0, pixel1, pixel2;
if (svals.invers == FALSE) if (svals.inverse)
{
pixel0 = pixel[0];
pixel1 = pixel[1];
pixel2 = pixel[2];
}
else
{ {
pixel0 = 255 - pixel[0]; pixel0 = 255 - pixel[0];
pixel1 = 255 - pixel[1]; pixel1 = 255 - pixel[1];
pixel2 = 255 - pixel[2]; pixel2 = 255 - pixel[2];
} }
else
{
pixel0 = pixel[0];
pixel1 = pixel[1];
pixel2 = pixel[2];
}
if (gray) if (gray)
{ {
if (has_alpha) if (has_alpha)
@ -595,19 +600,18 @@ compute_lum_threshold (GimpDrawable *drawable,
{ {
GimpPixelRgn src_rgn; GimpPixelRgn src_rgn;
gpointer pr; gpointer pr;
guchar *data;
gint values[256]; gint values[256];
gint total, sum; gint total, sum;
gint gray; gboolean gray;
gint has_alpha; gboolean has_alpha;
gint i; gint i;
gint x1, y1, x2, y2; gint x1, y1, x2, y2;
/* zero out the luminosity values array */ /* zero out the luminosity values array */
memset (values, 0, sizeof (gint) * 256); memset (values, 0, sizeof (gint) * 256);
gimp_drawable_mask_bounds (drawable->drawable_id, &x1, &y1, &x2, &y2); gimp_drawable_mask_bounds (drawable->drawable_id, &x1, &y1, &x2, &y2);
gray = gimp_drawable_is_gray (drawable->drawable_id); gray = gimp_drawable_is_gray (drawable->drawable_id);
has_alpha = gimp_drawable_has_alpha (drawable->drawable_id); has_alpha = gimp_drawable_has_alpha (drawable->drawable_id);
@ -618,17 +622,22 @@ compute_lum_threshold (GimpDrawable *drawable,
pr != NULL; pr != NULL;
pr = gimp_pixel_rgns_process (pr)) pr = gimp_pixel_rgns_process (pr))
{ {
int sx, sy; const guchar *src, *s;
data = src_rgn.data; gint sx, sy;
src = src_rgn.data;
for (sy = 0; sy < src_rgn.h; sy++) for (sy = 0; sy < src_rgn.h; sy++)
{ {
s = src;
for (sx = 0; sx < src_rgn.w; sx++) for (sx = 0; sx < src_rgn.w; sx++)
{ {
values [compute_luminosity (data, gray, has_alpha)]++; values [compute_luminosity (s, gray, has_alpha)]++;
data += src_rgn.bpp; s += src_rgn.bpp;
} }
data+=src_rgn.rowstride-(src_rgn.w*src_rgn.bpp);
src += src_rgn.rowstride;
} }
} }
@ -652,23 +661,24 @@ sparkle (GimpDrawable *drawable,
gint threshold) gint threshold)
{ {
GimpPixelRgn src_rgn, dest_rgn; GimpPixelRgn src_rgn, dest_rgn;
guchar *src, *dest;
gdouble nfrac, length, inten, spike_angle; gdouble nfrac, length, inten, spike_angle;
gint cur_progress, max_progress; gint cur_progress, max_progress;
gint x1, y1, x2, y2; gint x1, y1, x2, y2;
gint lum, x, y, b; gint lum, x, y, b;
gint gray; gboolean gray, has_alpha;
gint has_alpha, alpha; gint alpha;
gpointer pr; gpointer pr;
guchar *tmp1;
gint tile_width, tile_height; gint tile_width, tile_height;
GRand *gr; GRand *gr;
gr = g_rand_new (); gr = g_rand_new ();
gimp_drawable_mask_bounds (drawable->drawable_id, &x1, &y1, &x2, &y2); gimp_drawable_mask_bounds (drawable->drawable_id, &x1, &y1, &x2, &y2);
gray = gimp_drawable_is_gray (drawable->drawable_id); gray = gimp_drawable_is_gray (drawable->drawable_id);
has_alpha = gimp_drawable_has_alpha (drawable->drawable_id); has_alpha = gimp_drawable_has_alpha (drawable->drawable_id);
alpha = (has_alpha) ? drawable->bpp - 1 : drawable->bpp; alpha = (has_alpha) ? drawable->bpp - 1 : drawable->bpp;
tile_width = gimp_tile_width(); tile_width = gimp_tile_width();
tile_height = gimp_tile_height(); tile_height = gimp_tile_height();
@ -686,34 +696,38 @@ sparkle (GimpDrawable *drawable,
pr != NULL; pr != NULL;
pr = gimp_pixel_rgns_process (pr)) pr = gimp_pixel_rgns_process (pr))
{ {
int sx, sy; const guchar *src, *s;
guchar *dest, *d;
src = src_rgn.data; src = src_rgn.data;
dest = dest_rgn.data; dest = dest_rgn.data;
for (sy=0; sy<src_rgn.h; sy++) for (y = 0; y < src_rgn.h; y++)
{ {
for (sx=0; sx<src_rgn.w; sx++) s = src;
d = dest;
for (x = 0; x < src_rgn.w; x++)
{ {
if(has_alpha && src[alpha] == 0) if (has_alpha && s[alpha] == 0)
{ {
memset(dest, 0, alpha * sizeof(guchar)); memset (dest, 0, alpha);
dest += alpha;
} }
else else
{ {
for (b = 0, tmp1 = src; b < alpha; b++) for (b = 0; b < alpha; b++)
{ d[b] = s[b];
*dest++ = *tmp1++;
} }
}
if (has_alpha)
*dest++ = src[alpha];
src += src_rgn.bpp; if (has_alpha)
d[alpha] = src[alpha];
s += src_rgn.bpp;
d += dest_rgn.bpp;
} }
src += src_rgn.rowstride- (src_rgn.bpp * src_rgn.w);
dest += dest_rgn.rowstride- (dest_rgn.bpp * dest_rgn.w); src += src_rgn.rowstride;
dest += dest_rgn.rowstride;
} }
} }
/* add effects to new image based on intensity of old pixels */ /* add effects to new image based on intensity of old pixels */
@ -727,28 +741,42 @@ sparkle (GimpDrawable *drawable,
pr != NULL; pr != NULL;
pr = gimp_pixel_rgns_process (pr)) pr = gimp_pixel_rgns_process (pr))
{ {
const guchar *src, *s;
src = src_rgn.data; src = src_rgn.data;
for (y = 0; y < src_rgn.h; y++) for (y = 0; y < src_rgn.h; y++)
{ {
s = src;
for (x = 0; x < src_rgn.w; x++) for (x = 0; x < src_rgn.w; x++)
{ {
if (svals.border) if (svals.border)
{ {
if (x + src_rgn.x == 0 || y + src_rgn.y == 0 if (x + src_rgn.x == 0 ||
|| x + src_rgn.x == drawable->width - 1 y + src_rgn.y == 0 ||
|| y + src_rgn.y == drawable->height - 1) x + src_rgn.x == drawable->width - 1 ||
y + src_rgn.y == drawable->height - 1)
{
lum = 255; lum = 255;
else
lum = 0;
} }
else else
lum = compute_luminosity (src, gray, has_alpha); {
lum = 0;
}
}
else
{
lum = compute_luminosity (s, gray, has_alpha);
}
if (lum >= threshold) if (lum >= threshold)
{ {
nfrac = fabs ((gdouble) (lum + 1 - threshold) / nfrac = fabs ((gdouble) (lum + 1 - threshold) /
(gdouble) (256 - threshold)); (gdouble) (256 - threshold));
length = (gdouble) svals.spike_len * (gdouble) pow (nfrac, 0.8); length = ((gdouble) svals.spike_len *
inten = svals.flare_inten * nfrac /* pow (nfrac, 1.0) */; (gdouble) pow (nfrac, 0.8));
inten = svals.flare_inten * nfrac;
/* fspike im x,y intens rlength angle */ /* fspike im x,y intens rlength angle */
if (svals.spike_pts > 0) if (svals.spike_pts > 0)
@ -762,12 +790,13 @@ sparkle (GimpDrawable *drawable,
if (random_1 <= svals.density) if (random_1 <= svals.density)
{ {
fspike (&src_rgn, &dest_rgn, gray, x1, y1, x2, y2, fspike (&src_rgn, &dest_rgn, x1, y1, x2, y2,
x + src_rgn.x, y + src_rgn.y, x + src_rgn.x, y + src_rgn.y,
tile_width, tile_height, tile_width, tile_height,
inten, length, spike_angle, gr); inten, length, spike_angle, gr);
/* minor spikes */ /* minor spikes */
fspike (&src_rgn, &dest_rgn, gray, x1, y1, x2, y2, fspike (&src_rgn, &dest_rgn, x1, y1, x2, y2,
x + src_rgn.x, y + src_rgn.y, x + src_rgn.x, y + src_rgn.y,
tile_width, tile_height, tile_width, tile_height,
inten * 0.7, length * 0.7, inten * 0.7, length * 0.7,
@ -775,22 +804,28 @@ sparkle (GimpDrawable *drawable,
gr); gr);
} }
} }
cur_progress ++; cur_progress ++;
if ((cur_progress % 5) == 0) if ((cur_progress % 5) == 0)
gimp_progress_update ((double) cur_progress / gimp_progress_update ((double) cur_progress /
(double) max_progress); (double) max_progress);
} }
src += src_rgn.bpp;
s += src_rgn.bpp;
} }
src += src_rgn.rowstride - (src_rgn.w * src_rgn.bpp);
src += src_rgn.rowstride;
} }
} }
gimp_progress_update (1.0); gimp_progress_update (1.0);
/* update the blurred region */ /* update the blurred region */
gimp_drawable_flush (drawable); gimp_drawable_flush (drawable);
gimp_drawable_merge_shadow (drawable->drawable_id, TRUE); gimp_drawable_merge_shadow (drawable->drawable_id, TRUE);
gimp_drawable_update (drawable->drawable_id, x1, y1, (x2 - x1), (y2 - y1)); gimp_drawable_update (drawable->drawable_id, x1, y1, (x2 - x1), (y2 - y1));
g_rand_free (gr); g_rand_free (gr);
} }
@ -832,8 +867,10 @@ rpnt (GimpDrawable *drawable,
{ {
*col = newcol; *col = newcol;
*row = newrow; *row = newrow;
if (tile) if (tile)
gimp_tile_unref (tile, TRUE); gimp_tile_unref (tile, TRUE);
tile = gimp_drawable_get_tile (drawable, TRUE, *row, *col); tile = gimp_drawable_get_tile (drawable, TRUE, *row, *col);
gimp_tile_ref (tile); gimp_tile_ref (tile);
} }
@ -845,15 +882,17 @@ rpnt (GimpDrawable *drawable,
for (b = 0; b < bytes; b++) for (b = 0; b < bytes; b++)
{ {
if (svals.invers == FALSE) if (svals.inverse)
new = pixel[b];
else
new = 255 - pixel[b]; new = 255 - pixel[b];
else
new = pixel[b];
if (svals.preserve_luminosity==TRUE) if (svals.preserve_luminosity)
{ {
if (new < color[b]) if (new < color[b])
{
new *= (1.0 - val * (1.0 - svals.opacity)); new *= (1.0 - val * (1.0 - svals.opacity));
}
else else
{ {
new -= val * color[b] * (1.0 - svals.opacity); new -= val * color[b] * (1.0 - svals.opacity);
@ -861,25 +900,26 @@ rpnt (GimpDrawable *drawable,
new = 0.0; new = 0.0;
} }
} }
new *= 1.0 - val * svals.opacity; new *= 1.0 - val * svals.opacity;
new += val * color[b]; new += val * color[b];
if (new > 255) if (new > 255)
new = 255; new = 255;
if (svals.invers != FALSE) if (svals.inverse)
pixel[b] = 255 - new; pixel[b] = 255 - new;
else else
pixel[b] = new; pixel[b] = new;
} }
} }
return tile; return tile;
} }
static void static void
fspike (GimpPixelRgn *src_rgn, fspike (GimpPixelRgn *src_rgn,
GimpPixelRgn *dest_rgn, GimpPixelRgn *dest_rgn,
gint gray,
gint x1, gint x1,
gint y1, gint y1,
gint x2, gint x2,
@ -940,7 +980,7 @@ fspike (GimpPixelRgn *src_rgn,
color[1] = pixel[1]; color[1] = pixel[1];
color[2] = pixel[2]; color[2] = pixel[2];
if (svals.invers) if (svals.inverse)
{ {
color[0] = 255 - color[0]; color[0] = 255 - color[0];
color[1] = 255 - color[1]; color[1] = 255 - color[1];
@ -951,15 +991,24 @@ fspike (GimpPixelRgn *src_rgn,
r = 255 - color[0]; r = 255 - color[0];
g = 255 - color[1]; g = 255 - color[1];
b = 255 - color[2]; b = 255 - color[2];
gimp_rgb_to_hsv_int (&r, &g, &b); gimp_rgb_to_hsv_int (&r, &g, &b);
r+= svals.random_hue * g_rand_double_range (gr, -.5, .5) * 255;
r += svals.random_hue * g_rand_double_range (gr, -0.5, 0.5) * 255;
if (r >= 255) if (r >= 255)
r -= 255; r -= 255;
else if (r < 0) else if (r < 0)
r += 255; r += 255;
b+= (svals.random_saturation * g_rand_double_range (gr, -.5, .5))*255;
if (b > 255) b = 255; b += (svals.random_saturation *
g_rand_double_range (gr, -0.5, 0.5)) * 255;
if (b > 255)
b = 255;
gimp_hsv_to_rgb_int (&r, &g, &b); gimp_hsv_to_rgb_int (&r, &g, &b);
color[0] = 255 - r; color[0] = 255 - r;
color[1] = 255 - g; color[1] = 255 - g;
color[2] = 255 - b; color[2] = 255 - b;
@ -996,6 +1045,7 @@ fspike (GimpPixelRgn *src_rgn,
xrt += dx; xrt += dx;
yrt += dy; yrt += dy;
rpos += 0.2; rpos += 0.2;
} while (ok); } while (ok);
theta += 360.0 / svals.spike_pts; theta += 360.0 / svals.spike_pts;