mirror of
https://gitlab.gnome.org/GNOME/gimp
synced 2024-10-20 19:43:01 +00:00
applied gimp-kirchgessner-000320-0
--Sven
This commit is contained in:
parent
99f85a4626
commit
0309fec9f1
10
ChangeLog
10
ChangeLog
|
@ -1,3 +1,13 @@
|
|||
Fri Mar 24 17:13:41 CET 2000 Sven Neumann <sven@gimp.org>
|
||||
|
||||
plug-ins/common/mapcolor.c: applied gimp-kirchgessner-000320-0.
|
||||
Fixes problem with divide by zero when selecting same colors,
|
||||
adds preview and makes the GUI more intuitive.
|
||||
|
||||
Additionally, I've added another check for the drawable being RGB
|
||||
in the function that does the actual work. Remember that the
|
||||
image_type may change while the dialog is open!
|
||||
|
||||
Fri Mar 24 15:48:40 CET 2000 Sven Neumann <sven@gimp.org>
|
||||
|
||||
applied gimp-quinet-000310-0 by Raphael Quinet <quinet@gamers.org>
|
||||
|
|
|
@ -24,10 +24,13 @@
|
|||
* V 1.00, PK, 26-Oct-98: Creation.
|
||||
* V 1.01, PK, 21-Nov-99: Fix problem with working on layered images
|
||||
* Internationalization
|
||||
* V 1.02, PK, 19-Mar-00: Better explaining text/dialogue
|
||||
* Preview added
|
||||
* Fix problem with divide by zero
|
||||
*/
|
||||
#define VERSIO 1.01
|
||||
static char dversio[] = "v1.01 21-Nov-99";
|
||||
static char ident[] = "@(#) GIMP mapcolor plug-in v1.01 21-Nov-99";
|
||||
#define VERSIO 1.02
|
||||
static char dversio[] = "v1.02 19-Mar-00";
|
||||
static char ident[] = "@(#) GIMP mapcolor plug-in v1.02 19-Mar-00";
|
||||
|
||||
#include "config.h"
|
||||
|
||||
|
@ -57,7 +60,7 @@ typedef struct
|
|||
gint32 map_mode;
|
||||
} PluginValues;
|
||||
|
||||
PluginValues plvals =
|
||||
PluginValues plvals =
|
||||
{
|
||||
{
|
||||
{ 0, 0, 0},
|
||||
|
@ -68,6 +71,26 @@ PluginValues plvals =
|
|||
0
|
||||
};
|
||||
|
||||
|
||||
/* Preview handling stuff */
|
||||
|
||||
#define IMG_PRV_SIZE 128
|
||||
|
||||
typedef struct
|
||||
{
|
||||
guint width, height;
|
||||
guchar *img;
|
||||
} IMG_PREVIEW;
|
||||
|
||||
|
||||
typedef struct
|
||||
{
|
||||
GtkWidget *preview;
|
||||
IMG_PREVIEW *img_preview;
|
||||
IMG_PREVIEW *map_preview;
|
||||
} PLInterface;
|
||||
|
||||
|
||||
gint run_flag = FALSE;
|
||||
|
||||
/* Declare some local functions.
|
||||
|
@ -87,9 +110,22 @@ GPlugInInfo PLUG_IN_INFO =
|
|||
run, /* run_proc */
|
||||
};
|
||||
|
||||
static gint dialog (void);
|
||||
static IMG_PREVIEW *img_preview_alloc (guint width, guint height);
|
||||
static void img_preview_free (IMG_PREVIEW *ip);
|
||||
static void img_preview_copy (IMG_PREVIEW *src, IMG_PREVIEW **dst);
|
||||
static IMG_PREVIEW *img_preview_create_from_drawable (guint maxsize,
|
||||
gint32 drawable_ID);
|
||||
|
||||
static void update_img_preview (void);
|
||||
|
||||
static gint dialog (gint32 drawable_ID);
|
||||
static void mapcolor_ok_callback (GtkWidget *widget,
|
||||
gpointer data);
|
||||
static void get_mapping (guchar *src_col1, guchar *src_col2,
|
||||
guchar *dst_col1, guchar *dst_col2, gint32 map_mode,
|
||||
guchar *redmap, guchar *greenmap, guchar *bluemap);
|
||||
static void color_button_color_changed_callback (GtkWidget *widget,
|
||||
gpointer data);
|
||||
static void add_color_button (gint csel_index,
|
||||
gint left,
|
||||
gint top,
|
||||
|
@ -101,14 +137,174 @@ static void color_mapping (GDrawable *drawable);
|
|||
/* The run mode */
|
||||
static GRunModeType l_run_mode;
|
||||
|
||||
static gchar *csel_title[4] =
|
||||
{
|
||||
N_("First Source Color"),
|
||||
static gchar *csel_title[4] =
|
||||
{
|
||||
N_("First Source Color"),
|
||||
N_("Second Source Color"),
|
||||
N_("First Destination Color"),
|
||||
N_("Second Destination Color")
|
||||
N_("First Destination Color"),
|
||||
N_("Second Destination Color")
|
||||
};
|
||||
|
||||
static PLInterface plinterface;
|
||||
|
||||
|
||||
/* Allocate image preview structure and preview memory */
|
||||
static IMG_PREVIEW *
|
||||
img_preview_alloc (guint width, guint height)
|
||||
|
||||
{IMG_PREVIEW *ip;
|
||||
|
||||
ip = (IMG_PREVIEW *)g_malloc (sizeof (IMG_PREVIEW));
|
||||
ip->img = (guchar *)g_malloc (width*height*3);
|
||||
if (ip->img == NULL)
|
||||
{
|
||||
g_free (ip);
|
||||
return NULL;
|
||||
}
|
||||
ip->width = width;
|
||||
ip->height = height;
|
||||
|
||||
return ip;
|
||||
}
|
||||
|
||||
|
||||
/* Free image preview */
|
||||
static void
|
||||
img_preview_free (IMG_PREVIEW *ip)
|
||||
|
||||
{
|
||||
if (ip)
|
||||
{
|
||||
if (ip->img)
|
||||
{
|
||||
g_free (ip->img);
|
||||
ip->img = NULL;
|
||||
}
|
||||
ip->width = ip->height = 0;
|
||||
g_free (ip);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Copy image preview. Create/modify destinataion preview */
|
||||
static void
|
||||
img_preview_copy (IMG_PREVIEW *src, IMG_PREVIEW **dst)
|
||||
|
||||
{int numbytes;
|
||||
IMG_PREVIEW *dst_p;
|
||||
|
||||
if ((src == NULL) || (src->img == NULL) || (dst == NULL)) return;
|
||||
|
||||
numbytes = src->width * src->height * 3; /* 1 byte spare */
|
||||
if (numbytes <= 0) return;
|
||||
|
||||
if (*dst == NULL) /* Create new preview ? */
|
||||
{
|
||||
*dst = img_preview_alloc (src->width, src->height);
|
||||
if (*dst == NULL) return;
|
||||
memcpy ((*dst)->img, src->img, numbytes);
|
||||
return;
|
||||
}
|
||||
|
||||
/* destination preview already exists */
|
||||
dst_p = *dst;
|
||||
|
||||
/* Did not already allocate enough memory ? */
|
||||
if ((dst_p->img != NULL) && (dst_p->width*dst_p->height*3 < numbytes))
|
||||
{
|
||||
g_free (dst_p->img);
|
||||
dst_p->width = dst_p->height = 0;
|
||||
dst_p->img = NULL;
|
||||
}
|
||||
if (dst_p->img == NULL)
|
||||
{
|
||||
dst_p->img = (guchar *)g_malloc (numbytes);
|
||||
if (dst_p->img == NULL) return;
|
||||
}
|
||||
dst_p->width = src->width;
|
||||
dst_p->height = src->height;
|
||||
memcpy (dst_p->img, src->img, numbytes);
|
||||
}
|
||||
|
||||
|
||||
static IMG_PREVIEW *
|
||||
img_preview_create_from_drawable (guint maxsize, gint32 drawable_ID)
|
||||
|
||||
{GDrawable *drw;
|
||||
GPixelRgn pixel_rgn;
|
||||
guint drw_width, drw_height;
|
||||
guint prv_width, prv_height;
|
||||
gint src_x, src_y, x, y;
|
||||
guchar *prv_data, *img_data, *cu_row;
|
||||
double xfactor, yfactor;
|
||||
gint tile_height, row_start, row_end;
|
||||
gint bpp;
|
||||
IMG_PREVIEW *ip;
|
||||
|
||||
drw_width = gimp_drawable_width (drawable_ID);
|
||||
drw_height = gimp_drawable_height (drawable_ID);
|
||||
tile_height = (gint)gimp_tile_height();
|
||||
bpp = gimp_drawable_bpp(drawable_ID);
|
||||
|
||||
img_data = g_malloc (drw_width * tile_height * bpp);
|
||||
if (img_data == NULL) return NULL;
|
||||
|
||||
/* Calculate preview size */
|
||||
if ((drw_width <= maxsize) && (drw_height <= maxsize))
|
||||
{
|
||||
prv_width = drw_width;
|
||||
prv_height = drw_height;
|
||||
}
|
||||
else
|
||||
{
|
||||
xfactor = ((double)maxsize) / ((double)drw_width);
|
||||
yfactor = ((double)maxsize) / ((double)drw_height);
|
||||
if (xfactor < yfactor)
|
||||
{
|
||||
prv_width = maxsize;
|
||||
prv_height = (guint)(drw_height * xfactor);
|
||||
}
|
||||
else
|
||||
{
|
||||
prv_width = (guint)(drw_width * yfactor);
|
||||
prv_height = maxsize;
|
||||
}
|
||||
}
|
||||
ip = img_preview_alloc (prv_width, prv_height);
|
||||
if (ip == NULL) return NULL;
|
||||
|
||||
drw = gimp_drawable_get (drawable_ID);
|
||||
prv_data = ip->img;
|
||||
gimp_pixel_rgn_init (&pixel_rgn, drw, 0, 0, drw_width, drw_height,
|
||||
FALSE, FALSE);
|
||||
row_start = row_end = -1;
|
||||
|
||||
/* Get the pixels for the preview from the drawable */
|
||||
for (y = 0; y < prv_height; y++)
|
||||
{
|
||||
src_y = ((drw_height-1) * y) / (prv_height-1);
|
||||
if (src_y > row_end) /* Need new row ? */
|
||||
{
|
||||
row_start = (src_y / tile_height) * tile_height;
|
||||
row_end = row_start+tile_height-1;
|
||||
if (row_end > drw_height-1) row_end = drw_height-1;
|
||||
gimp_pixel_rgn_get_rect (&pixel_rgn, img_data, 0, row_start, drw_width,
|
||||
row_end-row_start+1);
|
||||
}
|
||||
cu_row = img_data + (src_y-row_start)*drw_width*bpp;
|
||||
for (x = 0; x < prv_width; x++)
|
||||
{
|
||||
src_x = ((drw_width-1) * x) / (prv_width-1);
|
||||
memcpy (prv_data, cu_row+bpp*src_x, 3);
|
||||
prv_data += 3;
|
||||
}
|
||||
}
|
||||
|
||||
gimp_drawable_detach (drw);
|
||||
g_free (img_data);
|
||||
return ip;
|
||||
}
|
||||
|
||||
|
||||
MAIN ()
|
||||
|
||||
|
@ -140,10 +336,12 @@ query (void)
|
|||
INIT_I18N ();
|
||||
|
||||
gimp_install_procedure ("plug_in_color_adjust",
|
||||
"Adjust current foreground/background color in the "
|
||||
"drawable to black/white",
|
||||
"The current foreground color is mapped to black, "
|
||||
"the current background color is mapped to white.",
|
||||
"Adjust color range given by foreground/background "
|
||||
"color to black/white",
|
||||
"The current foreground color is mapped to black "
|
||||
"(black point), the current background color is "
|
||||
"mapped to white (white point). Intermediate "
|
||||
"colors are interpolated",
|
||||
"Peter Kirchgessner",
|
||||
"Peter Kirchgessner",
|
||||
dversio,
|
||||
|
@ -154,14 +352,15 @@ query (void)
|
|||
adjust_args, NULL);
|
||||
|
||||
gimp_install_procedure ("plug_in_color_map",
|
||||
"Map two source colors to two destination colors. "
|
||||
"Other colors are mapped by interpolation.",
|
||||
"Map two source colors to two destination colors. "
|
||||
"Other colors are mapped by interpolation.",
|
||||
"Map color range specified by two colors"
|
||||
"to color range specified by two other color.",
|
||||
"Map color range specified by two colors"
|
||||
"to color range specified by two other color."
|
||||
"Intermediate colors are interpolated.",
|
||||
"Peter Kirchgessner",
|
||||
"Peter Kirchgessner",
|
||||
dversio,
|
||||
N_("<Image>/Filters/Colors/Map/Color Mapping..."),
|
||||
N_("<Image>/Filters/Colors/Map/Color Range Mapping..."),
|
||||
"RGB*",
|
||||
PROC_PLUG_IN,
|
||||
nmap_args, 0,
|
||||
|
@ -268,7 +467,7 @@ run (gchar *name,
|
|||
c = &(plvals.colors[1][0]); /* Second source color */
|
||||
gimp_palette_get_background (c, c+1, c+2);
|
||||
|
||||
if (!dialog ())
|
||||
if (!dialog (param[2].data.d_drawable))
|
||||
break;
|
||||
}
|
||||
else if (run_mode == RUN_WITH_LAST_VALS)
|
||||
|
@ -302,15 +501,54 @@ run (gchar *name,
|
|||
values[0].data.d_status = status;
|
||||
}
|
||||
|
||||
static void
|
||||
update_img_preview (void)
|
||||
|
||||
{IMG_PREVIEW *dst_ip = plinterface.map_preview;
|
||||
IMG_PREVIEW *src_ip = plinterface.img_preview;
|
||||
guchar *src, *dst;
|
||||
GtkWidget *preview = plinterface.preview;
|
||||
int j;
|
||||
unsigned char redmap[256], greenmap[256], bluemap[256];
|
||||
unsigned char *src_col1 = plvals.colors[0];
|
||||
unsigned char *src_col2 = plvals.colors[1];
|
||||
unsigned char *dst_col1 = plvals.colors[2];
|
||||
unsigned char *dst_col2 = plvals.colors[3];
|
||||
|
||||
if ((dst_ip == NULL) || (src_ip == NULL)) return;
|
||||
|
||||
get_mapping (src_col1, src_col2, dst_col1, dst_col2, plvals.map_mode,
|
||||
redmap, greenmap, bluemap);
|
||||
|
||||
j = dst_ip->width*dst_ip->height;
|
||||
src = src_ip->img;
|
||||
dst = dst_ip->img;
|
||||
while (j-- > 0)
|
||||
{
|
||||
*(dst++) = redmap[*(src++)];
|
||||
*(dst++) = greenmap[*(src++)];
|
||||
*(dst++) = bluemap[*(src++)];
|
||||
}
|
||||
for (j = 0; j < dst_ip->height; j++)
|
||||
gtk_preview_draw_row (GTK_PREVIEW (preview), dst_ip->img + dst_ip->width*3*j,
|
||||
0, j, dst_ip->width);
|
||||
gtk_widget_draw (preview, NULL);
|
||||
gdk_flush ();
|
||||
}
|
||||
|
||||
|
||||
static gint
|
||||
dialog (void)
|
||||
dialog (gint32 drawable_ID)
|
||||
{
|
||||
GtkWidget *dlg;
|
||||
GtkWidget *frame;
|
||||
GtkWidget *frame, *pframe;
|
||||
GtkWidget *abox;
|
||||
GtkWidget *table;
|
||||
GtkWidget *preview;
|
||||
IMG_PREVIEW *ip;
|
||||
guchar *color_cube;
|
||||
gchar **argv;
|
||||
gint argc;
|
||||
gint argc, j;
|
||||
|
||||
argc = 1;
|
||||
argv = g_new (gchar *, 1);
|
||||
|
@ -330,7 +568,9 @@ dialog (void)
|
|||
gtk_widget_set_default_visual (gtk_preview_get_visual ());
|
||||
gtk_widget_set_default_colormap (gtk_preview_get_cmap ());
|
||||
|
||||
dlg = gimp_dialog_new (_("Map Colors"), "mapcolor",
|
||||
memset (&plinterface, 0, sizeof (plinterface));
|
||||
|
||||
dlg = gimp_dialog_new (_("Map Color Range"), "mapcolor",
|
||||
gimp_plugin_help_func, "filters/mapcolor.html",
|
||||
GTK_WIN_POS_MOUSE,
|
||||
FALSE, TRUE, FALSE,
|
||||
|
@ -346,24 +586,59 @@ dialog (void)
|
|||
GTK_SIGNAL_FUNC (gtk_main_quit),
|
||||
NULL);
|
||||
|
||||
frame = gtk_frame_new (_("Colors"));
|
||||
gtk_container_set_border_width (GTK_CONTAINER (frame), 6);
|
||||
gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dlg)->vbox), frame, FALSE, FALSE, 0);
|
||||
gtk_widget_show (frame);
|
||||
/* Preview */
|
||||
ip = img_preview_create_from_drawable (IMG_PRV_SIZE, drawable_ID);
|
||||
if (ip)
|
||||
{
|
||||
plinterface.img_preview = ip;
|
||||
img_preview_copy (plinterface.img_preview, &(plinterface.map_preview));
|
||||
|
||||
/* The table keeps the color selections */
|
||||
table = gtk_table_new (2, 4, FALSE);
|
||||
gtk_table_set_row_spacings (GTK_TABLE (table), 4);
|
||||
gtk_table_set_col_spacings (GTK_TABLE (table), 4);
|
||||
gtk_table_set_col_spacing (GTK_TABLE (table), 1, 6);
|
||||
gtk_container_set_border_width (GTK_CONTAINER (table), 4);
|
||||
gtk_container_add (GTK_CONTAINER (frame), table);
|
||||
gtk_widget_show (table);
|
||||
frame = gtk_frame_new (_("Preview"));
|
||||
gtk_container_set_border_width (GTK_CONTAINER (frame), 6);
|
||||
gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dlg)->vbox),frame,FALSE,FALSE,0);
|
||||
|
||||
add_color_button (0, 0, 0, table);
|
||||
add_color_button (1, 0, 1, table);
|
||||
add_color_button (2, 2, 0, table);
|
||||
add_color_button (3, 2, 1, table);
|
||||
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);
|
||||
|
||||
pframe = gtk_frame_new (NULL);
|
||||
gtk_frame_set_shadow_type (GTK_FRAME (pframe), GTK_SHADOW_IN);
|
||||
gtk_container_set_border_width (GTK_CONTAINER (pframe), 4);
|
||||
gtk_container_add (GTK_CONTAINER (abox), pframe);
|
||||
|
||||
preview = gtk_preview_new (GTK_PREVIEW_COLOR);
|
||||
plinterface.preview = preview;
|
||||
gtk_preview_size (GTK_PREVIEW (preview), ip->width, ip->height);
|
||||
gtk_container_add (GTK_CONTAINER (pframe), preview);
|
||||
|
||||
gtk_widget_show (preview);
|
||||
gtk_widget_show (pframe);
|
||||
gtk_widget_show (abox);
|
||||
gtk_widget_show (frame);
|
||||
}
|
||||
|
||||
for (j = 0; j < 2; j++)
|
||||
{
|
||||
frame = gtk_frame_new ((j==0) ? _("Source color range")
|
||||
: _("Destination color range"));
|
||||
gtk_container_set_border_width (GTK_CONTAINER (frame), 6);
|
||||
gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dlg)->vbox),frame,FALSE,FALSE,0);
|
||||
gtk_widget_show (frame);
|
||||
|
||||
/* The table keeps the color selections */
|
||||
table = gtk_table_new (1, 4, FALSE);
|
||||
gtk_table_set_row_spacings (GTK_TABLE (table), 4);
|
||||
gtk_table_set_col_spacings (GTK_TABLE (table), 4);
|
||||
gtk_table_set_col_spacing (GTK_TABLE (table), 1, 6);
|
||||
gtk_container_set_border_width (GTK_CONTAINER (table), 4);
|
||||
gtk_container_add (GTK_CONTAINER (frame), table);
|
||||
gtk_widget_show (table);
|
||||
|
||||
add_color_button (j*2, 0, 0, table);
|
||||
add_color_button (j*2 + 1, 2, 0, table);
|
||||
}
|
||||
|
||||
update_img_preview ();
|
||||
|
||||
gtk_widget_show (dlg);
|
||||
|
||||
|
@ -373,6 +648,14 @@ dialog (void)
|
|||
return run_flag;
|
||||
}
|
||||
|
||||
static void
|
||||
color_button_color_changed_callback (GtkWidget *widget,
|
||||
gpointer data)
|
||||
{
|
||||
update_img_preview ();
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
add_color_button (gint csel_index,
|
||||
gint left,
|
||||
|
@ -392,11 +675,15 @@ add_color_button (gint csel_index,
|
|||
button = gimp_color_button_new (gettext (csel_title[csel_index]),
|
||||
PRV_WIDTH, PRV_HEIGHT,
|
||||
plvals.colors[csel_index], 3);
|
||||
gtk_signal_connect (GTK_OBJECT (button), "color_changed",
|
||||
GTK_SIGNAL_FUNC (color_button_color_changed_callback),
|
||||
NULL);
|
||||
gtk_table_attach (GTK_TABLE (table), button, left+1, left+2, top, top+1,
|
||||
GTK_FILL, GTK_FILL, 0, 0);
|
||||
gtk_widget_show (button);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
mapcolor_ok_callback (GtkWidget *widget,
|
||||
gpointer data)
|
||||
|
@ -406,6 +693,9 @@ mapcolor_ok_callback (GtkWidget *widget,
|
|||
|
||||
run_flag = TRUE;
|
||||
gtk_widget_destroy (GTK_WIDGET (data));
|
||||
|
||||
img_preview_free (plinterface.img_preview);
|
||||
img_preview_free (plinterface.map_preview);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -436,6 +726,7 @@ get_mapping (guchar *src_col1,
|
|||
{
|
||||
a = src_col1[rgb]; as = dst_col1[rgb];
|
||||
b = src_col2[rgb]; bs = dst_col2[rgb];
|
||||
if (b == a) b = a+1;
|
||||
for (i = 0; i < 256; i++)
|
||||
{
|
||||
j = ((i - a) * (bs - as)) / (b - a) + as;
|
||||
|
@ -467,6 +758,12 @@ color_mapping (GDrawable *drawable)
|
|||
|| (src_col1[1] == src_col2[1])
|
||||
|| (src_col1[2] == src_col2[2])) return;
|
||||
|
||||
if (!gimp_drawable_is_rgb (drawable->id))
|
||||
{
|
||||
g_message (_("Color Mapping / Adjust FG/BG:\nCannot operate on gray/indexed images"));
|
||||
return;
|
||||
}
|
||||
|
||||
gimp_drawable_mask_bounds (drawable->id, &xmin, &ymin, &xmax, &ymax);
|
||||
if ((ymin == ymax) || (xmin == xmax)) return;
|
||||
total = (xmax - xmin) * (ymax - ymin);
|
||||
|
|
Loading…
Reference in a new issue