Index: plug-ins/common/Makefile.in =================================================================== --- plug-ins/common/Makefile.in +++ plug-ins/common/Makefile.in @@ -43,6 +43,7 @@ channel-mixer$(EXEEXT) checkerboard$(EXEEXT) \ cml-explorer$(EXEEXT) color-cube-analyze$(EXEEXT) \ color-enhance$(EXEEXT) color-exchange$(EXEEXT) \ + color-range-map$(EXEEXT) \ color-to-alpha$(EXEEXT) colorify$(EXEEXT) \ colormap-remap$(EXEEXT) compose$(EXEEXT) \ contrast-normalize$(EXEEXT) contrast-retinex$(EXEEXT) \ @@ -235,6 +236,12 @@ $(libgimpmodule) $(libgimp) $(libgimpmath) $(libgimpconfig) \ $(libgimpcolor) $(libgimpbase) $(am__DEPENDENCIES_1) \ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) +am_color_range_map_OBJECTS = color-range-map.$(OBJEXT) +color_range_map_OBJECTS = $(am_color_range_map_OBJECTS) +color_range_map_DEPENDENCIES = $(libgimpui) $(libgimpwidgets) \ + $(libgimpmodule) $(libgimp) $(libgimpmath) $(libgimpconfig) \ + $(libgimpcolor) $(libgimpbase) $(am__DEPENDENCIES_1) \ + $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) am_color_to_alpha_OBJECTS = color-to-alpha.$(OBJEXT) color_to_alpha_OBJECTS = $(am_color_to_alpha_OBJECTS) color_to_alpha_DEPENDENCIES = $(libgimpui) $(libgimpwidgets) \ @@ -1020,6 +1027,7 @@ $(checkerboard_SOURCES) $(cml_explorer_SOURCES) \ $(color_cube_analyze_SOURCES) $(color_enhance_SOURCES) \ $(color_exchange_SOURCES) $(color_to_alpha_SOURCES) \ + $(color_range_map_SOURCES) \ $(colorify_SOURCES) $(colormap_remap_SOURCES) \ $(compose_SOURCES) $(contrast_normalize_SOURCES) \ $(contrast_retinex_SOURCES) $(contrast_stretch_SOURCES) \ @@ -1081,6 +1089,7 @@ $(checkerboard_SOURCES) $(cml_explorer_SOURCES) \ $(color_cube_analyze_SOURCES) $(color_enhance_SOURCES) \ $(color_exchange_SOURCES) $(color_to_alpha_SOURCES) \ + $(color_range_map_SOURCES) \ $(colorify_SOURCES) $(colormap_remap_SOURCES) \ $(compose_SOURCES) $(contrast_normalize_SOURCES) \ $(contrast_retinex_SOURCES) $(contrast_stretch_SOURCES) \ @@ -1762,6 +1771,22 @@ $(RT_LIBS) \ $(INTLLIBS) +color_range_map_SOURCES = \ + color-range-map.c + +color_range_map_LDADD = \ + $(libgimpui) \ + $(libgimpwidgets) \ + $(libgimpmodule) \ + $(libgimp) \ + $(libgimpmath) \ + $(libgimpconfig) \ + $(libgimpcolor) \ + $(libgimpbase) \ + $(GTK_LIBS) \ + $(RT_LIBS) \ + $(INTLLIBS) + color_to_alpha_SOURCES = \ color-to-alpha.c @@ -3850,6 +3875,9 @@ color-exchange$(EXEEXT): $(color_exchange_OBJECTS) $(color_exchange_DEPENDENCIES) @rm -f color-exchange$(EXEEXT) $(LINK) $(color_exchange_OBJECTS) $(color_exchange_LDADD) $(LIBS) +color-range-map$(EXEEXT): $(color_range_map_OBJECTS) $(color_range_map_DEPENDENCIES) + @rm -f color-range-map$(EXEEXT) + $(LINK) $(color_range_map_OBJECTS) $(color_range_map_LDADD) $(LIBS) color-to-alpha$(EXEEXT): $(color_to_alpha_OBJECTS) $(color_to_alpha_DEPENDENCIES) @rm -f color-to-alpha$(EXEEXT) $(LINK) $(color_to_alpha_OBJECTS) $(color_to_alpha_LDADD) $(LIBS) @@ -4249,6 +4277,7 @@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/color-cube-analyze.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/color-enhance.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/color-exchange.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/color-range-map.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/color-to-alpha.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/colorify.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/colormap-remap.Po@am__quote@ Index: plug-ins/common/Makefile.am =================================================================== --- plug-ins/common/Makefile.am +++ plug-ins/common/Makefile.am @@ -63,6 +63,7 @@ libexec_PROGRAMS = \ color-cube-analyze \ color-enhance \ color-exchange \ + color-range-map \ color-to-alpha \ colorify \ colormap-remap \ @@ -552,6 +553,23 @@ color_exchange_LDADD = \ $(INTLLIBS) \ $(color_exchange_RC) +color_range_map_SOURCES = \ + color-range-map.c + +color_range_map_LDADD = \ + $(libgimpui) \ + $(libgimpwidgets) \ + $(libgimpmodule) \ + $(libgimp) \ + $(libgimpmath) \ + $(libgimpconfig) \ + $(libgimpcolor) \ + $(libgimpbase) \ + $(GTK_LIBS) \ + $(RT_LIBS) \ + $(INTLLIBS) \ + $(color_exchange_RC) + color_to_alpha_SOURCES = \ color-to-alpha.c Index: plug-ins/common/color-range-map.c =================================================================== --- plug-ins/common/color-range-map.c +++ plug-ins/common/color-range-map.c @@ -0,0 +1,498 @@ +/* + * This is a plug-in for GIMP. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (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 . + * + * + */ + +/* + * Exchange one color range with another - very useful for many images, + * plugin was removed due to bitrot, then revived and updated. + * + * Copyright (C) 1995 Spencer Kimball and Peter Mattis + * Copyright (C) 1998 Peter Kirchgessner + * email: peter@kirchgessner.net, WWW: http://www.kirchgessner.net) + * Copyright (C) 2011 Owen Swerkstrom (owenswerk@gmail.com) + * + * Event history: + * 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 + * V 1.03,neo, 22-May-00: Fixed divide by zero in preview code. + * V 2.00, OS, 02-FEB-11: Refactor to use new plug-in architecture + */ + +#include "config.h" + +#include +#include + +#include "libgimp/stdplugins-intl.h" + + +#define PLUG_IN_PROC "plug-in-colorrangemap" +#define PLUG_IN_BINARY "colorrangemap" + +#define SCALE_WIDTH 128 +#define PRV_WIDTH 50 +#define PRV_HEIGHT 20 + + +/* datastructure to store parameters in */ +typedef struct +{ + GimpRGB colors[4]; + gint32 map_mode; + gboolean preview; +} myParams; + +/* lets prototype */ +static void query (void); +static void run (const gchar *name, + gint nparams, + const GimpParam *param, + gint *nreturn_vals, + GimpParam **return_vals); +static void update_img_preview (GimpDrawable *drawable, + GimpPreview *preview); +static gboolean mapcolor_dialog (GimpDrawable *drawable); +static void get_mapping (GimpRGB *src_col1, + GimpRGB *src_col2, + GimpRGB *dst_col1, + GimpRGB *dst_col2, + gint32 map_mode, + guchar *redmap, + guchar *greenmap, + guchar *bluemap); +static void add_color_button (gint csel_index, + gint left, + gint top, + GtkWidget *table, + GtkWidget *preview); +static void color_mapping (GimpDrawable *drawable); + + + +/* some global variables */ +static myParams xargs = +{ + { + { 0.0, 0.0, 0.0, 1.0 }, /* from col1 */ + { 1.0, 1.0, 1.0, 1.0 }, /* col2 */ + { 0.0, 0.0, 0.0, 1.0 }, /* to col1 */ + { 1.0, 1.0, 1.0, 1.0 } /* col2 */ + }, + 0, + 0 +}; +static guchar redmap[256], greenmap[256], bluemap[256]; +static gchar *csel_title[4] = +{ + N_("First Source Color"), + N_("Second Source Color"), + N_("First Destination Color"), + N_("Second Destination Color") +}; + +/* lets declare what we want to do */ +const GimpPlugInInfo PLUG_IN_INFO = +{ + NULL, /* init_proc */ + NULL, /* quit_proc */ + query, /* query_proc */ + run, /* run_proc */ +}; + +/* run program */ +MAIN () + +/* tell GIMP who we are */ +static void +query (void) +{ + static const GimpParamDef args[] = + { + { GIMP_PDB_INT32, "run-mode", "The run mode { RUN-INTERACTIVE (0), RUN-NONINTERACTIVE (1) }" }, + { GIMP_PDB_IMAGE, "image", "Input image" }, + { GIMP_PDB_DRAWABLE, "drawable", "Input drawable" }, + { GIMP_PDB_COLOR, "srccolor-1", "First source color" }, + { GIMP_PDB_COLOR, "srccolor-2", "Second source color" }, + { GIMP_PDB_COLOR, "dstcolor-1", "First destination color" }, + { GIMP_PDB_COLOR, "dstcolor-2", "Second destination color" }, + { GIMP_PDB_INT32, "map-mode", "Mapping mode (0: linear, others reserved)" } + }; + + gimp_install_procedure (PLUG_IN_PROC, + N_("Map color range specified by two colors " + "to another range"), + "Map color range specified by two colors" + "to color range specified by two other color. " + "Intermediate colors are interpolated.", + "Peter Kirchgessner", + "Peter Kirchgessner", + "Feb 8, 2011", + N_("_Color Range _Mapping..."), + "RGB*", + GIMP_PLUGIN, + G_N_ELEMENTS (args), 0, + args, NULL); + + gimp_plugin_menu_register (PLUG_IN_PROC, "/Colors/Map"); +} + +/* main function */ +static void +run (const gchar *name, + gint nparams, + const GimpParam *param, + gint *nreturn_vals, + GimpParam **return_vals) +{ + static GimpParam values[1]; + GimpRunMode run_mode; + GimpDrawable *drawable = NULL; + GimpPDBStatusType status = GIMP_PDB_SUCCESS; + gint j; + + INIT_I18N (); + + run_mode = param[0].data.d_int32; + + *nreturn_vals = 1; + *return_vals = values; + + values[0].type = GIMP_PDB_STATUS; + values[0].data.d_status = status; + + while (status == GIMP_PDB_SUCCESS) + { + if (nparams < 3) + { + status = GIMP_PDB_CALLING_ERROR; + break; + } + + /* Make sure the drawable is RGB color */ + drawable = gimp_drawable_get (param[2].data.d_drawable); + if (!gimp_drawable_is_rgb (drawable->drawable_id)) + { + g_message (_("Cannot operate on gray or indexed color images.")); + status = GIMP_PDB_EXECUTION_ERROR; + break; + } + + if (run_mode == GIMP_RUN_NONINTERACTIVE) + { + if (nparams != 8) /* Make sure all the arguments are there */ + { + status = GIMP_PDB_CALLING_ERROR; + break; + } + + for (j = 0; j < 4; j++) + { + xargs.colors[j] = param[3+j].data.d_color; + } + xargs.map_mode = param[7].data.d_int32; + } + else if (run_mode == GIMP_RUN_INTERACTIVE) + { + gimp_get_data (name, &xargs); + + gimp_context_get_foreground (xargs.colors); + gimp_context_get_background (xargs.colors + 1); + + if (!mapcolor_dialog (drawable)) + break; + } + else if (run_mode == GIMP_RUN_WITH_LAST_VALS) + { + gimp_get_data (name, &xargs); + } + else + { + status = GIMP_PDB_CALLING_ERROR; + break; + } + + gimp_progress_init (_("Mapping colors")); + + color_mapping (drawable); + + if (run_mode == GIMP_RUN_INTERACTIVE) + gimp_set_data (name, &xargs, sizeof (xargs)); + + break; + + status = GIMP_PDB_EXECUTION_ERROR; + } + + if ((status == GIMP_PDB_SUCCESS) && (run_mode != GIMP_RUN_NONINTERACTIVE)) + gimp_displays_flush (); + + if (drawable != NULL) + gimp_drawable_detach (drawable); + + values[0].data.d_status = status; +} + +static void +update_img_preview (GimpDrawable *drawable, + GimpPreview *preview) +{ + guchar redmap[256], greenmap[256], bluemap[256]; + gint width, height, bpp; + gboolean has_alpha; + guchar *src, *dest, *s, *d; + gint j; + + get_mapping (xargs.colors, + xargs.colors + 1, + xargs.colors + 2, + xargs.colors + 3, + xargs.map_mode, + redmap, greenmap, bluemap); + + src = gimp_zoom_preview_get_source (GIMP_ZOOM_PREVIEW (preview), + &width, &height, &bpp); + has_alpha = gimp_drawable_has_alpha (drawable->drawable_id); + + j = width * height; + dest = g_new (guchar, j * bpp); + + s = src; d = dest; + while (j-- > 0) + { + *(d++) = redmap[*(s++)]; + *(d++) = greenmap[*(s++)]; + *(d++) = bluemap[*(s++)]; + if (has_alpha) + *(d++) = *(s++); + } + + gimp_preview_draw_buffer (preview, dest, width * bpp); + + g_free (src); + g_free (dest); +} + +static gboolean +mapcolor_dialog (GimpDrawable *drawable) +{ + GtkWidget *dialog; + GtkWidget *main_vbox; + GtkWidget *preview; + GtkWidget *frame; + GtkWidget *table; + gint j; + gboolean run; + + gimp_ui_init (PLUG_IN_BINARY, TRUE); + + dialog = gimp_dialog_new (_("Map Color Range"), PLUG_IN_BINARY, + NULL, 0, + gimp_standard_help_func, PLUG_IN_PROC, + + GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, + GTK_STOCK_OK, GTK_RESPONSE_OK, + + NULL); + + gtk_dialog_set_alternative_button_order (GTK_DIALOG (dialog), + GTK_RESPONSE_OK, + GTK_RESPONSE_CANCEL, + -1); + + gimp_window_set_transient (GTK_WINDOW (dialog)); + + main_vbox = gtk_vbox_new (FALSE, 12); + gtk_container_set_border_width (GTK_CONTAINER (main_vbox), 12); + gtk_container_add (GTK_CONTAINER (gtk_dialog_get_content_area (GTK_DIALOG (dialog))), + main_vbox); + gtk_widget_show (main_vbox); + + preview = gimp_zoom_preview_new (drawable); + gtk_box_pack_start_defaults (GTK_BOX (main_vbox), preview); + gtk_widget_show (preview); + g_signal_connect_swapped (preview, "invalidated", + G_CALLBACK (update_img_preview), + drawable); + + for (j = 0; j < 2; j++) + { + frame = gimp_frame_new ((j == 0) ? + _("Source Color Range") : + _("Destination Color Range")); + gtk_box_pack_start (GTK_BOX (main_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_col_spacings (GTK_TABLE (table), 6); + gtk_container_add (GTK_CONTAINER (frame), table); + gtk_widget_show (table); + + add_color_button (j * 2, 0, 0, table, preview); + add_color_button (j * 2 + 1, 2, 0, table, preview); + } + + gtk_widget_show (dialog); + + run = (gimp_dialog_run (GIMP_DIALOG (dialog)) == GTK_RESPONSE_OK); + + if (run) + xargs.map_mode = 0; /* Currently always linear mapping */ + + gtk_widget_destroy (dialog); + + return run; +} + +static void +add_color_button (gint csel_index, + gint left, + gint top, + GtkWidget *table, + GtkWidget *preview) +{ + GtkWidget *button; + + button = gimp_color_button_new (gettext (csel_title[csel_index]), + PRV_WIDTH, PRV_HEIGHT, + &xargs.colors[csel_index], + GIMP_COLOR_AREA_FLAT); + gimp_table_attach_aligned (GTK_TABLE (table), left + 1, top, + (left == 0) ? _("From:") : _("To:"), + 0.0, 0.5, + button, 1, TRUE); + + g_signal_connect (button, "color-changed", + G_CALLBACK (gimp_color_button_get_color), + &xargs.colors[csel_index]); + g_signal_connect_swapped (button, "color-changed", + G_CALLBACK (gimp_preview_invalidate), + preview); +} + +static void +get_mapping (GimpRGB *src_col1, + GimpRGB *src_col2, + GimpRGB *dst_col1, + GimpRGB *dst_col2, + gint32 map_mode, + guchar *redmap, + guchar *greenmap, + guchar *bluemap) +{ + guchar src1[3]; + guchar src2[3]; + guchar dst1[3]; + guchar dst2[3]; + gint rgb, i, a, as, b, bs; + guchar *colormap[3]; + + /* Currently we always do a linear mapping */ + + colormap[0] = redmap; + colormap[1] = greenmap; + colormap[2] = bluemap; + + gimp_rgb_get_uchar (src_col1, src1, src1 + 1, src1 + 2); + gimp_rgb_get_uchar (src_col2, src2, src2 + 1, src2 + 2); + gimp_rgb_get_uchar (dst_col1, dst1, dst1 + 1, dst1 + 2); + gimp_rgb_get_uchar (dst_col2, dst2, dst2 + 1, dst2 + 2); + + switch (map_mode) + { + case 0: + default: + for (rgb = 0; rgb < 3; rgb++) + { + a = src1[rgb]; as = dst1[rgb]; + b = src2[rgb]; bs = dst2[rgb]; + + if (b == a) + { + /* For this channel, both source color values are the same. */ + + /* Map everything below to the start of the destination range. */ + for (i = 0; i < a; i++) + { + colormap[rgb][i] = as; + } + + /* Map source color to the middle of the destination range. */ + colormap[rgb][a] = (as + bs) / 2; + + /* Map everything above to the end of the destination range. */ + for (i = a + 1; i < 256; i++) + { + colormap[rgb][i] = bs; + } + } + else + { + /* Map color ranges. */ + for (i = 0; i < 256; i++) + { + gint j = ((i - a) * (bs - as)) / (b - a) + as; + + colormap[rgb][i] = CLAMP0255(j); + } + } + } + break; + } +} + +static void +mapcolor_func (const guchar *src, + guchar *dest, + gint bpp, + gpointer data) +{ + dest[0] = redmap[src[0]]; + dest[1] = greenmap[src[1]]; + dest[2] = bluemap[src[2]]; + if (bpp > 3) + dest[3] = src[3]; +} + + +/* show our dialog */ +static void +color_mapping (GimpDrawable *drawable) + +{ + if (!gimp_drawable_is_rgb (drawable->drawable_id)) + { + g_message (_("Cannot operate on gray or indexed color images.")); + return; + } + + gimp_tile_cache_ntiles (2 * (drawable->width / gimp_tile_width () + 1)); + + get_mapping (xargs.colors, + xargs.colors + 1, + xargs.colors + 2, + xargs.colors + 3, + xargs.map_mode, + redmap, greenmap, bluemap); + + gimp_rgn_iterate2 (drawable, 0 /* unused */, mapcolor_func, NULL); +} Index: plug-ins/common/plugin-defs.pl =================================================================== --- plug-ins/common/plugin-defs.pl +++ plug-ins/common/plugin-defs.pl @@ -19,6 +19,7 @@ 'color-cube-analyze' => { ui => 1 }, 'color-enhance' => { ui => 1 }, 'color-exchange' => { ui => 1 }, + 'color-range-map' => { ui => 1 }, 'color-to-alpha' => { ui => 1 }, 'colorify' => { ui => 1 }, 'colormap-remap' => { ui => 1 }, Index: plug-ins/makefile.msc =================================================================== --- plug-ins/makefile.msc +++ plug-ins/makefile.msc @@ -34,7 +34,7 @@ FROMPLUGINSDIR=YES # Used to bypass other parts below # The COMMON* ones are in the common subdirectory COMMON0 = alien-map align-layers animation-optimize animation-play antialias apply-canvas COMMON1 = blinds blur-gauss-selective blur-gauss blur-motion blur border-average bump-map -COMMON2 = cartoon channel-mixer checkerboard cml-explorer color-cube-analyze color-enhance color-exchange color-to-alpha colorify colormap-remap compose contrast-normalize contrast-retinex contrast-stretch-hsv contrast-stretch convolution-matrix crop-auto crop-zealous cubism curve-bend +COMMON2 = cartoon channel-mixer checkerboard cml-explorer color-cube-analyze color-enhance color-exchange color-range-map color-to-alpha colorify colormap-remap compose contrast-normalize contrast-retinex contrast-stretch-hsv contrast-stretch convolution-matrix crop-auto crop-zealous cubism curve-bend COMMON3 = decompose deinterlace depth-merge despeckle destripe diffraction displace edge-dog edge-laplace edge-neon edge-sobel edge emboss engrave ## file-aa file-mng file-pdf file-wmf file-xpm COMMON4 = file-cel file-compressor file-csource file-desktop-link file-dicom file-gbr file-gif-load file-gif-save file-gih file-glob file-header file-html-table file-pat file-pcx file-pix file-png file-pnm file-ps file-psp file-raw file-sunras file-svg file-tga file-tiff-load file-tiff-save file-xbm file-xwd film filter-pack fractal-trace -- 1.7.0.4