Commit 401c35f7 authored by Maurits Rijk's avatar Maurits Rijk
Browse files

More use of gimpmisc generic region iterator routines.

parent cfd1c729
2002-11-27 Maurits Rijk <lpeek.mrijk@consunet.nl>
* plug-ins/common/AlienMap.c
* plug-ins/common/AlienMap2.c
* plug-ins/common/autostretch_hsv.c
* plug-ins/common/semiflatten.c
* plug-ins/common/threshold_alpha.c: use gimpmisc region iterator
funcs.
2002-11-27 Sven Neumann <sven@gimp.org>
 
* app/config/gimprc.[ch]: added (yet unused) autosave feature.
......
......@@ -872,11 +872,6 @@ static void run (char *name,
GimpParam **return_vals);
static void alienmap (GimpDrawable *drawable);
static void alienmap_render_row (const guchar *src_row,
guchar *dest_row,
gint row,
gint row_width,
gint bytes, double, double, double);
static void transform (guchar *, guchar *, guchar *,
double, double, double);
......@@ -893,6 +888,8 @@ static void alienmap_logo_dialog (void);
/***** Variables *****/
static GimpRunMode run_mode;
GimpPlugInInfo PLUG_IN_INFO =
{
NULL, /* init_proc */
......@@ -1038,7 +1035,6 @@ run (char *name,
GimpParam **return_vals)
{
static GimpParam values[1];
GimpRunMode run_mode;
double xhsiz, yhsiz;
gint sel_width, sel_height;
int pwidth, pheight;
......@@ -1167,92 +1163,30 @@ run (char *name,
gimp_drawable_detach (drawable);
}
static void
alienmap_render_row (const guchar *src_row,
guchar *dest_row,
gint row,
gint row_width,
gint bytes,
double redstretch,
double greenstretch,
double bluestretch)
static void
alienmap_func (guchar *src, guchar *dest, gint bpp, gpointer data)
{
gint col, bytenum;
for (col = 0; col < row_width ; col++)
{
guchar v1, v2, v3;
guchar v1, v2, v3;
v1 = src_row[0];
v2 = src_row[1];
v3 = src_row[2];
v1 = src[0];
v2 = src[1];
v3 = src[2];
transform(&v1, &v2, &v3, redstretch, greenstretch, bluestretch);
transform(&v1, &v2, &v3, wvals.redstretch, wvals.greenstretch,
wvals.bluestretch);
dest_row[0] = v1;
dest_row[1] = v2;
dest_row[2] = v3;
dest[0] = v1;
dest[1] = v2;
dest[2] = v3;
for (bytenum = 3; bytenum < bytes; bytenum++)
{
dest_row[bytenum] = src_row[bytenum];
}
src_row += bytes;
dest_row += bytes;
}
if (bpp == 4)
dest[3] = src[3];
}
static void
alienmap (GimpDrawable *drawable)
{
GimpPixelRgn srcPR, destPR;
gint width, height;
gint bytes;
guchar *src_row;
guchar *dest_row;
gint row;
gint x1, y1, x2, y2;
double redstretch,greenstretch,bluestretch;
gimp_drawable_mask_bounds (drawable->drawable_id, &x1, &y1, &x2, &y2);
width = x2 - x1;
height = y2 - y1;
bytes = drawable->bpp;
/* allocate row buffers */
src_row = g_new (guchar, width * bytes);
dest_row = g_new (guchar, width * bytes);
/* initialize the pixel regions */
gimp_pixel_rgn_init (&srcPR, drawable, x1, y1, width, height, FALSE, FALSE);
gimp_pixel_rgn_init (&destPR, drawable, x1, y1, width, height, TRUE, TRUE);
redstretch = wvals.redstretch;
greenstretch = wvals.greenstretch;
bluestretch = wvals.bluestretch;
for (row = y1; row < y2; row++)
{
gimp_pixel_rgn_get_row (&srcPR, src_row, x1, row, width);
alienmap_render_row (src_row, dest_row, row, width, bytes,
redstretch, greenstretch, bluestretch);
/* store the dest */
gimp_pixel_rgn_set_row (&destPR, dest_row, x1, row, width);
if ((row % 10) == 0)
gimp_progress_update ((double) row / (double) height);
}
/* update the processed region */
gimp_drawable_flush (drawable);
gimp_drawable_merge_shadow (drawable->drawable_id, TRUE);
gimp_drawable_update (drawable->drawable_id, x1, y1, width, height);
g_free (src_row);
g_free (dest_row);
gimp_rgn_iterate2 (drawable, run_mode, alienmap_func, NULL);
}
static void
......
......@@ -875,11 +875,6 @@ static void run (char *name,
GimpParam **return_vals);
static void alienmap2 (GimpDrawable *drawable);
static void alienmap2_render_row (const guchar *src_row,
guchar *dest_row,
gint row,
gint row_width,
gint bytes);
static void transform (guchar*, guchar*, guchar*);
......@@ -898,6 +893,8 @@ static void alienmap2_logo_dialog (void);
/***** Variables *****/
static GimpRunMode run_mode;
GimpPlugInInfo PLUG_IN_INFO =
{
NULL, /* init_proc */
......@@ -1025,7 +1022,6 @@ run (char *name,
GimpParam **return_vals)
{
static GimpParam values[1];
GimpRunMode run_mode;
double xhsiz, yhsiz;
int pwidth, pheight;
GimpPDBStatusType status = GIMP_PDB_SUCCESS;
......@@ -1158,86 +1154,29 @@ run (char *name,
gimp_drawable_detach (drawable);
}
static void
alienmap2_render_row (const guchar *src_row,
guchar *dest_row,
gint row,
gint row_width,
gint bytes)
static void
alienmap2_func (guchar *src, guchar *dest, gint bpp, gpointer data)
{
gint col, bytenum;
for (col = 0; col < row_width ; col++)
{
guchar v1, v2, v3;
guchar v1, v2, v3;
v1 = src_row[0];
v2 = src_row[1];
v3 = src_row[2];
v1 = src[0];
v2 = src[1];
v3 = src[2];
transform(&v1, &v2, &v3);
transform(&v1, &v2, &v3);
dest_row[0] = v1;
dest_row[1] = v2;
dest_row[2] = v3;
dest[0] = v1;
dest[1] = v2;
dest[2] = v3;
for (bytenum = 3; bytenum < bytes; bytenum++)
{
dest_row[bytenum] = src_row[bytenum];
}
src_row += bytes;
dest_row += bytes;
}
if (bpp == 4)
dest[3] = src[3];
}
static void
alienmap2 (GimpDrawable *drawable)
{
GimpPixelRgn srcPR, destPR;
gint width, height;
gint bytes;
guchar *src_row;
guchar *dest_row;
gint row;
gint x1, y1, x2, y2;
gimp_drawable_mask_bounds (drawable->drawable_id, &x1, &y1, &x2, &y2);
/* Get the size of the input image. (This will/must be the same
* as the size of the output image.
*/
width = x2 - x1;
height = y2 - y1;
bytes = drawable->bpp;
/* allocate row buffers */
src_row = g_new (guchar, width * bytes);
dest_row = g_new (guchar, width * bytes);
/* initialize the pixel regions */
gimp_pixel_rgn_init (&srcPR, drawable, x1, y1, width, height, FALSE, FALSE);
gimp_pixel_rgn_init (&destPR, drawable, x1, y1, width, height, TRUE, TRUE);
for (row = y1; row < y2; row++)
{
gimp_pixel_rgn_get_row (&srcPR, src_row, x1, row, width);
alienmap2_render_row (src_row, dest_row, row, width, bytes);
/* store the dest */
gimp_pixel_rgn_set_row (&destPR, dest_row, x1, row, width);
if ((row % 10) == 0)
gimp_progress_update ((double) row / (double) height);
}
/* update the processed region */
gimp_drawable_flush (drawable);
gimp_drawable_merge_shadow (drawable->drawable_id, TRUE);
gimp_drawable_update (drawable->drawable_id, x1, y1, width, height);
g_free (src_row);
g_free (dest_row);
gimp_rgn_iterate2 (drawable, run_mode, alienmap2_func, NULL);
}
static void
......
......@@ -51,6 +51,7 @@ static void run (gchar *name,
static void autostretch_hsv (GimpDrawable *drawable);
static void indexed_autostretch_hsv (gint32 image_ID);
static GimpRunMode run_mode;
GimpPlugInInfo PLUG_IN_INFO =
{
......@@ -104,7 +105,6 @@ run (gchar *name,
{
static GimpParam values[1];
GimpDrawable *drawable;
GimpRunMode run_mode;
GimpPDBStatusType status = GIMP_PDB_SUCCESS;
gint32 image_ID;
......@@ -150,15 +150,49 @@ run (gchar *name,
gimp_drawable_detach (drawable);
}
typedef struct {
double shi;
double slo;
double vhi;
double vlo;
} AutostretchData;
static void
find_max (guchar *src, gint bpp, AutostretchData *data)
{
double h, s, v;
gimp_rgb_to_hsv4(src, &h, &s, &v);
if (s > data->shi) data->shi = s;
if (s < data->slo) data->slo = s;
if (v > data->vhi) data->vhi = v;
if (v < data->vlo) data->vlo = v;
}
static void
autostretch_hsv_func (guchar *src, guchar *dest, gint bpp,
AutostretchData *data)
{
double h, s, v;
gimp_rgb_to_hsv4(src, &h, &s, &v);
if (data->shi != data->slo)
s = (s - data->slo) / (data->shi - data->slo);
if (data->vhi != data->vlo)
v = (v - data->vlo) / (data->vhi - data->vlo);
gimp_hsv_to_rgb4(dest, h, s, v);
if (bpp == 4)
dest[3] = src[3];
}
static void
indexed_autostretch_hsv (gint32 image_ID) /* a.d.m. */
{
guchar *cmap;
AutostretchData data = {0.0, 1.0, 0.0, 1.0};
gint ncols,i;
double shi = 0.0, vhi = 0.0, slo = 1.0, vlo = 1.0;
cmap = gimp_image_get_cmap (image_ID, &ncols);
if (cmap==NULL)
......@@ -167,137 +201,27 @@ indexed_autostretch_hsv (gint32 image_ID) /* a.d.m. */
gimp_quit();
}
for (i=0;i<ncols;i++)
for (i = 0; i < ncols; i++)
{
double h, s, v;
gimp_rgb_to_hsv4(&cmap[i*3], &h, &s, &v);
if (s > shi) shi = s;
if (s < slo) slo = s;
if (v > vhi) vhi = v;
if (v < vlo) vlo = v;
find_max (&cmap[i * 3], 3, &data);
}
for (i=0;i<ncols;i++)
for (i = 0; i < ncols; i++)
{
double h, s, v;
gimp_rgb_to_hsv4(&cmap[i*3], &h, &s, &v);
if (shi!=slo)
s = (s-slo) / (shi-slo);
if (vhi!=vlo)
v = (v-vlo) / (vhi-vlo);
gimp_hsv_to_rgb4(&cmap[i*3], h, s, v);
autostretch_hsv_func (&cmap[i * 3], &cmap[i * 3], 3, &data);
}
gimp_image_set_cmap (image_ID, cmap, ncols);
}
static void
autostretch_hsv (GimpDrawable *drawable)
{
GimpPixelRgn src_rgn, dest_rgn;
guchar *src, *s;
guchar *dest, *d;
double shi = 0.0, slo = 1.0, vhi = 0.0, vlo = 1.0;
gint progress, max_progress;
gint has_alpha, alpha;
gint x1, y1, x2, y2;
gint x, y;
gpointer pr;
/* Get selection area */
gimp_drawable_mask_bounds (drawable->drawable_id, &x1, &y1, &x2, &y2);
has_alpha = gimp_drawable_has_alpha (drawable->drawable_id);
alpha = (has_alpha) ? drawable->bpp - 1 : drawable->bpp;
/* Initialize progress */
progress = 0;
max_progress = (x2 - x1) * (y2 - y1) * 2;
gimp_pixel_rgn_init (&src_rgn, drawable,
x1, y1, (x2 - x1), (y2 - y1), FALSE, FALSE);
for (pr = gimp_pixel_rgns_register (1, &src_rgn);
pr != NULL;
pr = gimp_pixel_rgns_process (pr))
{
src = src_rgn.data;
for (y = 0; y < src_rgn.h; y++)
{
s = src;
for (x = 0; x < src_rgn.w; x++)
{
if (!has_alpha || (has_alpha && s[alpha]))
{
double h, z, v;
gimp_rgb_to_hsv4(s, &h, &z, &v);
if (z > shi) shi = z;
if (z < slo) slo = z;
if (v > vhi) vhi = v;
if (v < vlo) vlo = v;
}
s += src_rgn.bpp;
}
src += src_rgn.rowstride;
}
/* Update progress */
progress += src_rgn.w * src_rgn.h;
gimp_progress_update ((double) progress / (double) max_progress);
}
/* Now substitute pixel vales */
gimp_pixel_rgn_init (&src_rgn, drawable,
x1, y1, (x2 - x1), (y2 - y1), FALSE, FALSE);
gimp_pixel_rgn_init (&dest_rgn, drawable,
x1, y1, (x2 - x1), (y2 - y1), TRUE, TRUE);
AutostretchData data = {0.0, 1.0, 0.0, 1.0};
for (pr = gimp_pixel_rgns_register (2, &src_rgn, &dest_rgn);
pr != NULL;
pr = gimp_pixel_rgns_process (pr))
{
src = src_rgn.data;
dest = dest_rgn.data;
for (y = 0; y < src_rgn.h; y++)
{
s = src;
d = dest;
for (x = 0; x < src_rgn.w; x++)
{
double h, z, v;
gimp_rgb_to_hsv4(s, &h, &z, &v);
if (shi!=slo)
z = (z-slo) / (shi-slo);
if (vhi!=vlo)
v = (v-vlo) / (vhi-vlo);
gimp_hsv_to_rgb4(d, h, z, v);
if (has_alpha)
d[alpha] = s[alpha];
s += src_rgn.bpp;
d += dest_rgn.bpp;
}
src += src_rgn.rowstride;
dest += dest_rgn.rowstride;
}
gimp_rgn_iterate1 (drawable, run_mode, (GimpRgnFunc1) find_max, &data);
gimp_rgn_iterate2 (drawable, run_mode, (GimpRgnFunc2) autostretch_hsv_func,
&data);
}
/* Update progress */
progress += src_rgn.w * src_rgn.h;
gimp_progress_update ((double) progress / (double) max_progress);
}
/* update the region */
gimp_drawable_flush (drawable);
gimp_drawable_merge_shadow (drawable->drawable_id, TRUE);
gimp_drawable_update (drawable->drawable_id, x1, y1, (x2 - x1), (y2 - y1));
}
......@@ -20,11 +20,6 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
/*
* TODO:
* Use tile iteration instead of dumb row-walking
*/
#include "config.h"
#include <stdio.h>
......@@ -45,14 +40,10 @@ static void run (gchar *name,
GimpParam **return_vals);
static void semiflatten (GimpDrawable *drawable);
static void semiflatten_render_row (const guchar *src,
guchar *dest,
gint row_width,
gint bytes);
static guchar bgred, bggreen, bgblue;
static GimpRunMode run_mode;
GimpPlugInInfo PLUG_IN_INFO =
{
......@@ -107,6 +98,8 @@ run (gchar *name,
*nreturn_vals = 1;
*return_vals = values;
run_mode = param[0].data.d_int32;
values[0].type = GIMP_PDB_STATUS;
values[0].data.d_status = status;
......@@ -138,79 +131,23 @@ run (gchar *name,
gimp_drawable_detach (drawable);
}
static void
semiflatten_render_row (const guchar *src,
guchar *dest,
gint row_width,
gint bytes)
static void
semiflatten_func (guchar *src, guchar *dest, gint bpp, gpointer data)
{
gint col;
for (col = 0; col < row_width ; col++)
{
dest[0] = (src[0] * src[3]) / 255 + (bgred * (255 - src[3])) / 255;
dest[1] = (src[1] * src[3]) / 255 + (bggreen * (255 - src[3])) / 255;
dest[2] = (src[2] * src[3]) / 255 + (bgblue * (255 - src[3])) / 255;
dest[3] = (src[3] == 0) ? 0 : 255;
src += bytes;
dest += bytes;
}
dest[0] = (src[0] * src[3]) / 255 + (bgred * (255 - src[3])) / 255;
dest[1] = (src[1] * src[3]) / 255 + (bggreen * (255 - src[3])) / 255;
dest[2] = (src[2] * src[3]) / 255 + (bgblue * (255 - src[3])) / 255;
dest[3] = (src[3] == 0) ? 0 : 255;
}
static void
semiflatten (GimpDrawable *drawable)
{
GimpPixelRgn srcPR, destPR;
GimpRGB background;
gint width, height;
gint bytes;
guchar *src_row;
guchar *dest_row;
gint row;
gint x1, y1, x2, y2;
/* Fetch the GIMP current background colour, to semi-flatten against */
gimp_palette_get_background (&background);
gimp_rgb_get_uchar (&background, &bgred, &bggreen, &bgblue);
gimp_drawable_mask_bounds (drawable->drawable_id, &x1, &y1, &x2, &y2);
/* Get the size of the input image. (This will/must be the same
* as the size of the output image.
*/
width = drawable->width;
height = drawable->height;
bytes = drawable->bpp;
/* allocate row buffers */
src_row = g_new (guchar, (x2 - x1) * bytes);
dest_row = g_new (guchar, (x2 - x1) * bytes);
/* initialize the pixel regions */
gimp_pixel_rgn_init (&srcPR, drawable, 0, 0, width, height, FALSE, FALSE);
gimp_pixel_rgn_init (&destPR, drawable, 0, 0, width, height, TRUE, TRUE);
for (row = y1; row < y2; row++)
{
gimp_pixel_rgn_get_row (&srcPR, src_row, x1, row, x2 - x1);
semiflatten_render_row (src_row,
dest_row,
(x2 - x1),
bytes);
gimp_pixel_rgn_set_row (&destPR, dest_row, x1, row, x2 - x1);
if ((row % 10) == 0)
gimp_progress_update ((double) row / (double) (y2 - y1));
}
/* update the processed region */
gimp_drawable_flush (drawable);
gimp_drawable_merge_shadow (drawable->drawable_id, TRUE);
gimp_drawable_update (drawable->drawable_id, x1, y1, (