gimp/plug-ins/common/sharpen.c

807 lines
21 KiB
C
Raw Normal View History

/*
* "$Id$"
*
* Sharpen filters for The GIMP -- an image manipulation program
*
* Copyright 1997-1998 Michael Sweet (mike@easysw.com)
*
* 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 2 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, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*
*/
#include "config.h"
#include <string.h>
#include <libgimp/gimp.h>
#include <libgimp/gimpui.h>
#include "libgimp/stdplugins-intl.h"
/*
* Constants...
*/
#define PLUG_IN_PROC "plug-in-sharpen"
#define PLUG_IN_BINARY "sharpen"
#define PLUG_IN_VERSION "1.4.2 - 3 June 1998"
#define SCALE_WIDTH 100
/*
* Local functions...
*/
static void query (void);
static void run (const gchar *name,
gint nparams,
const GimpParam *param,
gint *nreturn_vals,
GimpParam **returm_vals);
static void compute_luts (void);
static void sharpen (GimpDrawable *drawable);
static gboolean sharpen_dialog (GimpDrawable *drawable);
static void preview_update (GimpPreview *preview);
typedef gint32 intneg;
typedef gint32 intpos;
static void gray_filter (int width, guchar *src, guchar *dst, intneg *neg0,
intneg *neg1, intneg *neg2);
static void graya_filter (int width, guchar *src, guchar *dst, intneg *neg0,
intneg *neg1, intneg *neg2);
static void rgb_filter (int width, guchar *src, guchar *dst, intneg *neg0,
intneg *neg1, intneg *neg2);
static void rgba_filter (int width, guchar *src, guchar *dst, intneg *neg0,
intneg *neg1, intneg *neg2);
/*
* Globals...
*/
GimpPlugInInfo PLUG_IN_INFO =
{
NULL, /* init_proc */
NULL, /* quit_proc */
query, /* query_proc */
run /* run_proc */
};
typedef struct
{
gint sharpen_percent;
gboolean update_preview;
} SharpenParams;
static SharpenParams sharpen_params =
{
10,
TRUE
};
static intneg neg_lut[256]; /* Negative coefficient LUT */
static intpos pos_lut[256]; /* Positive coefficient LUT */
MAIN ()
static void
query (void)
{
static GimpParamDef args[] =
{
{ GIMP_PDB_INT32, "run-mode", "Interactive, non-interactive" },
{ GIMP_PDB_IMAGE, "image", "Input image" },
{ GIMP_PDB_DRAWABLE, "drawable", "Input drawable" },
{ GIMP_PDB_INT32, "percent", "Percent sharpening (default = 10)" }
};
gimp_install_procedure (PLUG_IN_PROC,
"Sharpen filter, typically used to 'sharpen' a "
"photographic image.",
"This plug-in selectively performs a convolution "
"filter on an image.",
"Michael Sweet <mike@easysw.com>",
"Copyright 1997-1998 by Michael Sweet",
PLUG_IN_VERSION,
N_("_Sharpen..."),
"RGB*, GRAY*",
GIMP_PLUGIN,
G_N_ELEMENTS (args), 0,
args, NULL);
gimp_plugin_menu_register (PLUG_IN_PROC, "<Image>/Filters/Enhance");
}
static void
run (const gchar *name,
gint nparams,
const GimpParam *param,
gint *nreturn_vals,
GimpParam **return_vals)
{
GimpRunMode run_mode; /* Current run mode */
GimpPDBStatusType status; /* Return status */
GimpParam *values; /* Return values */
GimpDrawable *drawable; /* Current image */
/*
* Initialize parameter data...
*/
status = GIMP_PDB_SUCCESS;
run_mode = param[0].data.d_int32;
INIT_I18N ();
values = g_new (GimpParam, 1);
*nreturn_vals = 1;
*return_vals = values;
values[0].type = GIMP_PDB_STATUS;
values[0].data.d_status = status;
/*
* Get drawable information...
*/
drawable = gimp_drawable_get (param[2].data.d_drawable);
gimp_tile_cache_ntiles (2 * drawable->ntile_cols);
/*
* See how we will run
*/
switch (run_mode)
{
case GIMP_RUN_INTERACTIVE:
/*
* Possibly retrieve data...
*/
gimp_get_data (PLUG_IN_PROC, &sharpen_params);
/*
* Get information from the dialog...
*/
if (!sharpen_dialog (drawable))
return;
break;
case GIMP_RUN_NONINTERACTIVE:
/*
* Make sure all the arguments are present...
*/
if (nparams != 4)
status = GIMP_PDB_CALLING_ERROR;
else
sharpen_params.sharpen_percent = param[3].data.d_int32;
break;
case GIMP_RUN_WITH_LAST_VALS:
/*
* Possibly retrieve data...
*/
gimp_get_data (PLUG_IN_PROC, &sharpen_params);
break;
default:
status = GIMP_PDB_CALLING_ERROR;
break;
}
/*
* Sharpen the image...
*/
if (status == GIMP_PDB_SUCCESS)
{
if ((gimp_drawable_is_rgb (drawable->drawable_id) ||
gimp_drawable_is_gray (drawable->drawable_id)))
{
/*
* Run!
*/
sharpen (drawable);
/*
* If run mode is interactive, flush displays...
*/
if (run_mode != GIMP_RUN_NONINTERACTIVE)
gimp_displays_flush ();
/*
* Store data...
*/
if (run_mode == GIMP_RUN_INTERACTIVE)
gimp_set_data (PLUG_IN_PROC,
&sharpen_params, sizeof (SharpenParams));
}
else
status = GIMP_PDB_EXECUTION_ERROR;
}
/*
* Reset the current run status...
*/
values[0].data.d_status = status;
/*
* Detach from the drawable...
*/
gimp_drawable_detach (drawable);
}
static void
compute_luts (void)
{
gint i; /* Looping var */
gint fact; /* 1 - sharpness */
fact = 100 - sharpen_params.sharpen_percent;
if (fact < 1)
fact = 1;
for (i = 0; i < 256; i ++)
{
pos_lut[i] = 800 * i / fact;
neg_lut[i] = (4 + pos_lut[i] - (i << 3)) >> 3;
}
}
/*
* 'sharpen()' - Sharpen an image using a convolution filter.
*/
static void
sharpen (GimpDrawable *drawable)
{
GimpPixelRgn src_rgn; /* Source image region */
GimpPixelRgn dst_rgn; /* Destination image region */
guchar *src_rows[4]; /* Source pixel rows */
guchar *src_ptr; /* Current source pixel */
guchar *dst_row; /* Destination pixel row */
intneg *neg_rows[4]; /* Negative coefficient rows */
intneg *neg_ptr; /* Current negative coefficient */
gint i; /* Looping vars */
gint y; /* Current location in image */
gint row; /* Current row in src_rows */
gint count; /* Current number of filled src_rows */
gint width; /* Byte width of the image */
gint x1; /* Selection bounds */
gint y1;
gint x2;
gint y2;
gint sel_width; /* Selection width */
gint sel_height; /* Selection height */
gint img_bpp; /* Bytes-per-pixel in image */
void (*filter)(int, guchar *, guchar *, intneg *, intneg *, intneg *);
filter = NULL;
gimp_drawable_mask_bounds (drawable->drawable_id,
&x1, &y1, &x2, &y2);
sel_width = x2 - x1;
sel_height = y2 - y1;
img_bpp = gimp_drawable_bpp (drawable->drawable_id);
/*
* Let the user know what we're doing...
*/
gimp_progress_init( _("Sharpening..."));
/*
* Setup for filter...
*/
gimp_pixel_rgn_init (&src_rgn, drawable,
x1, y1, sel_width, sel_height, FALSE, FALSE);
gimp_pixel_rgn_init (&dst_rgn, drawable,
x1, y1, sel_width, sel_height, TRUE, TRUE);
compute_luts ();
width = sel_width * img_bpp;
for (row = 0; row < 4; row ++)
{
src_rows[row] = g_new (guchar, width);
neg_rows[row] = g_new (intneg, width);
}
dst_row = g_new (guchar, width);
/*
* Pre-load the first row for the filter...
*/
gimp_pixel_rgn_get_row (&src_rgn, src_rows[0], x1, y1, sel_width);
for (i = width, src_ptr = src_rows[0], neg_ptr = neg_rows[0];
i > 0;
i --, src_ptr ++, neg_ptr ++)
*neg_ptr = neg_lut[*src_ptr];
row = 1;
count = 1;
/*
* Select the filter...
*/
switch (img_bpp)
{
case 1 :
filter = gray_filter;
break;
case 2 :
filter = graya_filter;
break;
case 3 :
filter = rgb_filter;
break;
case 4 :
filter = rgba_filter;
break;
};
/*
* Sharpen...
*/
for (y = y1; y < y2; y ++)
{
/*
* Load the next pixel row...
*/
if ((y + 1) < y2)
{
/*
* Check to see if our src_rows[] array is overflowing yet...
*/
if (count >= 3)
count --;
/*
* Grab the next row...
*/
gimp_pixel_rgn_get_row (&src_rgn, src_rows[row],
x1, y + 1, sel_width);
for (i = width, src_ptr = src_rows[row], neg_ptr = neg_rows[row];
i > 0;
i --, src_ptr ++, neg_ptr ++)
*neg_ptr = neg_lut[*src_ptr];
count ++;
row = (row + 1) & 3;
}
else
{
/*
* No more pixels at the bottom... Drop the oldest samples...
*/
count --;
}
/*
* Now sharpen pixels and save the results...
*/
if (count == 3)
{
(* filter) (sel_width, src_rows[(row + 2) & 3], dst_row,
neg_rows[(row + 1) & 3] + img_bpp,
neg_rows[(row + 2) & 3] + img_bpp,
neg_rows[(row + 3) & 3] + img_bpp);
/*
* Set the row...
*/
gimp_pixel_rgn_set_row (&dst_rgn, dst_row, x1, y, sel_width);
}
else if (count == 2)
{
if (y == y1) /* first row */
gimp_pixel_rgn_set_row (&dst_rgn, src_rows[0],
x1, y, sel_width);
else /* last row */
gimp_pixel_rgn_set_row (&dst_rgn, src_rows[(sel_height - 1) & 3],
x1, y, sel_width);
}
if ((y & 15) == 0)
gimp_progress_update ((gdouble) (y - y1) / (gdouble) sel_height);
}
/*
* OK, we're done. Free all memory used...
*/
for (row = 0; row < 4; row ++)
{
g_free (src_rows[row]);
g_free (neg_rows[row]);
}
g_free (dst_row);
/*
* Update the screen...
*/
gimp_drawable_flush (drawable);
gimp_drawable_merge_shadow (drawable->drawable_id, TRUE);
gimp_drawable_update (drawable->drawable_id,
x1, y1, sel_width, sel_height);
}
/*
* 'sharpen_dialog()' - Popup a dialog window for the filter box size...
*/
static gboolean
sharpen_dialog (GimpDrawable *drawable)
{
GtkWidget *dialog;
GtkWidget *main_vbox;
GtkWidget *preview;
GtkWidget *table;
GtkObject *adj;
removed our own action_area API and use GtkDialog's one. Create all 2003-11-06 Michael Natterer <mitch@gimp.org> * libgimpwidgets/gimpdialog.[ch]: removed our own action_area API and use GtkDialog's one. Create all dialogs without separator. Changed almost everything else too. Fixes bug #125143. * libgimpwidgets/gimpquerybox.c * libgimpwidgets/gimpunitmenu.c: changed accordingly. * libgimp/gimpexport.[ch]: ditto. Renamed enum GimpExportReturnType to GimpExportReturn. * libgimp/gimpcompat.h: added a #define for the old name. * themes/Default/gtkrc: increased action_area border to 6 pixels. * app/display/gimpdisplayshell-filter-dialog.c * app/display/gimpdisplayshell-scale.c * app/display/gimpprogress.c * app/gui/brush-select.c * app/gui/channels-commands.c * app/gui/color-notebook.c * app/gui/convert-dialog.c * app/gui/file-new-dialog.c * app/gui/font-select.c * app/gui/gradient-editor-commands.c * app/gui/gradient-select.c * app/gui/grid-dialog.c * app/gui/image-commands.c * app/gui/info-window.c * app/gui/layers-commands.c * app/gui/module-browser.c * app/gui/offset-dialog.c * app/gui/palette-import-dialog.c * app/gui/palette-select.c * app/gui/pattern-select.c * app/gui/preferences-dialog.c * app/gui/qmask-commands.c * app/gui/resize-dialog.c * app/gui/resolution-calibrate-dialog.c * app/gui/stroke-dialog.c * app/gui/templates-commands.c * app/gui/user-install-dialog.c * app/gui/vectors-commands.c * app/tools/gimpcolorpickertool.c * app/tools/gimpcroptool.c * app/tools/gimpimagemaptool.c * app/tools/gimpmeasuretool.c * app/tools/gimptransformtool.c * app/widgets/gimptexteditor.c * app/widgets/gimptooldialog.[ch] * app/widgets/gimpviewabledialog.[ch] * app/widgets/gimpwidgets-utils.c: changed accordingly and increased the dialogs' outer borders to 6 pixels all over the place. * plug-ins/*/*.c: changed accordingly. The plug-ins may be arbitrarily broken, I tested none of them.
2003-11-06 23:27:05 +08:00
gboolean run;
gimp_ui_init (PLUG_IN_BINARY, TRUE);
dialog = gimp_dialog_new (_("Sharpen"), PLUG_IN_BINARY,
removed our own action_area API and use GtkDialog's one. Create all 2003-11-06 Michael Natterer <mitch@gimp.org> * libgimpwidgets/gimpdialog.[ch]: removed our own action_area API and use GtkDialog's one. Create all dialogs without separator. Changed almost everything else too. Fixes bug #125143. * libgimpwidgets/gimpquerybox.c * libgimpwidgets/gimpunitmenu.c: changed accordingly. * libgimp/gimpexport.[ch]: ditto. Renamed enum GimpExportReturnType to GimpExportReturn. * libgimp/gimpcompat.h: added a #define for the old name. * themes/Default/gtkrc: increased action_area border to 6 pixels. * app/display/gimpdisplayshell-filter-dialog.c * app/display/gimpdisplayshell-scale.c * app/display/gimpprogress.c * app/gui/brush-select.c * app/gui/channels-commands.c * app/gui/color-notebook.c * app/gui/convert-dialog.c * app/gui/file-new-dialog.c * app/gui/font-select.c * app/gui/gradient-editor-commands.c * app/gui/gradient-select.c * app/gui/grid-dialog.c * app/gui/image-commands.c * app/gui/info-window.c * app/gui/layers-commands.c * app/gui/module-browser.c * app/gui/offset-dialog.c * app/gui/palette-import-dialog.c * app/gui/palette-select.c * app/gui/pattern-select.c * app/gui/preferences-dialog.c * app/gui/qmask-commands.c * app/gui/resize-dialog.c * app/gui/resolution-calibrate-dialog.c * app/gui/stroke-dialog.c * app/gui/templates-commands.c * app/gui/user-install-dialog.c * app/gui/vectors-commands.c * app/tools/gimpcolorpickertool.c * app/tools/gimpcroptool.c * app/tools/gimpimagemaptool.c * app/tools/gimpmeasuretool.c * app/tools/gimptransformtool.c * app/widgets/gimptexteditor.c * app/widgets/gimptooldialog.[ch] * app/widgets/gimpviewabledialog.[ch] * app/widgets/gimpwidgets-utils.c: changed accordingly and increased the dialogs' outer borders to 6 pixels all over the place. * plug-ins/*/*.c: changed accordingly. The plug-ins may be arbitrarily broken, I tested none of them.
2003-11-06 23:27:05 +08:00
NULL, 0,
gimp_standard_help_func, PLUG_IN_PROC,
removed our own action_area API and use GtkDialog's one. Create all 2003-11-06 Michael Natterer <mitch@gimp.org> * libgimpwidgets/gimpdialog.[ch]: removed our own action_area API and use GtkDialog's one. Create all dialogs without separator. Changed almost everything else too. Fixes bug #125143. * libgimpwidgets/gimpquerybox.c * libgimpwidgets/gimpunitmenu.c: changed accordingly. * libgimp/gimpexport.[ch]: ditto. Renamed enum GimpExportReturnType to GimpExportReturn. * libgimp/gimpcompat.h: added a #define for the old name. * themes/Default/gtkrc: increased action_area border to 6 pixels. * app/display/gimpdisplayshell-filter-dialog.c * app/display/gimpdisplayshell-scale.c * app/display/gimpprogress.c * app/gui/brush-select.c * app/gui/channels-commands.c * app/gui/color-notebook.c * app/gui/convert-dialog.c * app/gui/file-new-dialog.c * app/gui/font-select.c * app/gui/gradient-editor-commands.c * app/gui/gradient-select.c * app/gui/grid-dialog.c * app/gui/image-commands.c * app/gui/info-window.c * app/gui/layers-commands.c * app/gui/module-browser.c * app/gui/offset-dialog.c * app/gui/palette-import-dialog.c * app/gui/palette-select.c * app/gui/pattern-select.c * app/gui/preferences-dialog.c * app/gui/qmask-commands.c * app/gui/resize-dialog.c * app/gui/resolution-calibrate-dialog.c * app/gui/stroke-dialog.c * app/gui/templates-commands.c * app/gui/user-install-dialog.c * app/gui/vectors-commands.c * app/tools/gimpcolorpickertool.c * app/tools/gimpcroptool.c * app/tools/gimpimagemaptool.c * app/tools/gimpmeasuretool.c * app/tools/gimptransformtool.c * app/widgets/gimptexteditor.c * app/widgets/gimptooldialog.[ch] * app/widgets/gimpviewabledialog.[ch] * app/widgets/gimpwidgets-utils.c: changed accordingly and increased the dialogs' outer borders to 6 pixels all over the place. * plug-ins/*/*.c: changed accordingly. The plug-ins may be arbitrarily broken, I tested none of them.
2003-11-06 23:27:05 +08:00
GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
GTK_STOCK_OK, GTK_RESPONSE_OK,
removed our own action_area API and use GtkDialog's one. Create all 2003-11-06 Michael Natterer <mitch@gimp.org> * libgimpwidgets/gimpdialog.[ch]: removed our own action_area API and use GtkDialog's one. Create all dialogs without separator. Changed almost everything else too. Fixes bug #125143. * libgimpwidgets/gimpquerybox.c * libgimpwidgets/gimpunitmenu.c: changed accordingly. * libgimp/gimpexport.[ch]: ditto. Renamed enum GimpExportReturnType to GimpExportReturn. * libgimp/gimpcompat.h: added a #define for the old name. * themes/Default/gtkrc: increased action_area border to 6 pixels. * app/display/gimpdisplayshell-filter-dialog.c * app/display/gimpdisplayshell-scale.c * app/display/gimpprogress.c * app/gui/brush-select.c * app/gui/channels-commands.c * app/gui/color-notebook.c * app/gui/convert-dialog.c * app/gui/file-new-dialog.c * app/gui/font-select.c * app/gui/gradient-editor-commands.c * app/gui/gradient-select.c * app/gui/grid-dialog.c * app/gui/image-commands.c * app/gui/info-window.c * app/gui/layers-commands.c * app/gui/module-browser.c * app/gui/offset-dialog.c * app/gui/palette-import-dialog.c * app/gui/palette-select.c * app/gui/pattern-select.c * app/gui/preferences-dialog.c * app/gui/qmask-commands.c * app/gui/resize-dialog.c * app/gui/resolution-calibrate-dialog.c * app/gui/stroke-dialog.c * app/gui/templates-commands.c * app/gui/user-install-dialog.c * app/gui/vectors-commands.c * app/tools/gimpcolorpickertool.c * app/tools/gimpcroptool.c * app/tools/gimpimagemaptool.c * app/tools/gimpmeasuretool.c * app/tools/gimptransformtool.c * app/widgets/gimptexteditor.c * app/widgets/gimptooldialog.[ch] * app/widgets/gimpviewabledialog.[ch] * app/widgets/gimpwidgets-utils.c: changed accordingly and increased the dialogs' outer borders to 6 pixels all over the place. * plug-ins/*/*.c: changed accordingly. The plug-ins may be arbitrarily broken, I tested none of them.
2003-11-06 23:27:05 +08:00
NULL);
gtk_dialog_set_alternative_button_order (GTK_DIALOG (dialog),
GTK_RESPONSE_OK,
GTK_RESPONSE_CANCEL,
-1);
Added parent window API to the GimpProgress interface and to the libgimp 2005-09-09 Michael Natterer <mitch@gimp.org> Added parent window API to the GimpProgress interface and to the libgimp progress stuff. Might look strange, but does the right thing in almost all cases (image window, file dialog, script-fu dialog etc). Fixes bug #62988. * app/core/gimpprogress.[ch]: added GimpProgress::get_window() which should return a toplevel window ID if the progress is in a window that wants to be the transient parent of plug-in dialogs. * app/widgets/gimpwidgets-utils.[ch] (gimp_window_get_native): new function which returns the window handle of a GtkWindow's GdkWindow. * app/widgets/gimpfiledialog.c: implement ::get_window(). * app/display/gimpdisplay.[ch]: ditto. Removed window handle API. * app/gui/gui-vtable.c: changed accordingly. * libgimpbase/gimpbaseenums.[ch] (enum GimpProgressCommand): added GIMP_PROGRESS_COMMAND_GET_WINDOW. * app/plug-in/plug-in-progress.[ch] (plug_in_progress_get_window): new function. Also renamed some functions to match the GimpProgress interface, and not the legacy PDB procedure names. * tools/pdbgen/pdb/progress.pdb * app/core/gimppdbprogress.c: implement get_window() on both sides of the wire, keeping backward compatibility (hopefully). * libgimp/gimpprogress.[ch]: deprecated gimp_progress_install() and added gimp_progress_install_vtable() which takes a vtable with padding to be extensible. Added get_window() vtable entry and dispatch it accordingly. Also added pulse() which was implemented in a hackish way before. Everything is of course backward compatible. * libgimp/gimpprogressbar.c: inmplement the get_window() stuff so a plug-in dialog containing a progress can be the transient parent of another dialog in another plug-in. * libgimp/gimpui.[ch] (gimp_ui_get_progress_window): new function which returns a foreign GdkWindow of this plug-ins progress window. Renamed gimp_window_set_transient_for_default_display() to gimp_window_set_transient() and make it use the progress' window handle instead of the display's (which is the right thing to do in almost all cases). * libgimp/gimp.def * libgimp/gimpui.def: add the new functions. * tools/pdbgen/enums.pl * app/pdb/internal_procs.c * app/pdb/progress_cmds.c * libgimp/gimpprogress_pdb.[ch]: regenerated. * libgimp/gimpexport.c * plug-ins/*/*.c: follow API change.
2005-09-10 02:07:31 +08:00
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 (dialog)->vbox), main_vbox);
gtk_widget_show (main_vbox);
preview = gimp_drawable_preview_new (drawable,
&sharpen_params.update_preview);
gtk_box_pack_start (GTK_BOX (main_vbox), preview, TRUE, TRUE, 0);
gtk_widget_show (preview);
g_signal_connect (preview, "invalidated",
G_CALLBACK (preview_update),
NULL);
table = gtk_table_new (1, 3, FALSE);
gtk_table_set_col_spacings (GTK_TABLE (table), 6);
gtk_box_pack_start (GTK_BOX (main_vbox), table, FALSE, FALSE, 0);
gtk_widget_show (table);
adj = gimp_scale_entry_new (GTK_TABLE (table), 0, 0,
_("_Sharpness:"), SCALE_WIDTH, 0,
sharpen_params.sharpen_percent,
1, 99, 1, 10, 0,
TRUE, 0, 0,
NULL, NULL);
g_signal_connect (adj, "value-changed",
G_CALLBACK (gimp_int_adjustment_update),
&sharpen_params.sharpen_percent);
g_signal_connect_swapped (adj, "value-changed",
G_CALLBACK (gimp_preview_invalidate),
preview);
gtk_widget_show (dialog);
run = (gimp_dialog_run (GIMP_DIALOG (dialog)) == GTK_RESPONSE_OK);
removed our own action_area API and use GtkDialog's one. Create all 2003-11-06 Michael Natterer <mitch@gimp.org> * libgimpwidgets/gimpdialog.[ch]: removed our own action_area API and use GtkDialog's one. Create all dialogs without separator. Changed almost everything else too. Fixes bug #125143. * libgimpwidgets/gimpquerybox.c * libgimpwidgets/gimpunitmenu.c: changed accordingly. * libgimp/gimpexport.[ch]: ditto. Renamed enum GimpExportReturnType to GimpExportReturn. * libgimp/gimpcompat.h: added a #define for the old name. * themes/Default/gtkrc: increased action_area border to 6 pixels. * app/display/gimpdisplayshell-filter-dialog.c * app/display/gimpdisplayshell-scale.c * app/display/gimpprogress.c * app/gui/brush-select.c * app/gui/channels-commands.c * app/gui/color-notebook.c * app/gui/convert-dialog.c * app/gui/file-new-dialog.c * app/gui/font-select.c * app/gui/gradient-editor-commands.c * app/gui/gradient-select.c * app/gui/grid-dialog.c * app/gui/image-commands.c * app/gui/info-window.c * app/gui/layers-commands.c * app/gui/module-browser.c * app/gui/offset-dialog.c * app/gui/palette-import-dialog.c * app/gui/palette-select.c * app/gui/pattern-select.c * app/gui/preferences-dialog.c * app/gui/qmask-commands.c * app/gui/resize-dialog.c * app/gui/resolution-calibrate-dialog.c * app/gui/stroke-dialog.c * app/gui/templates-commands.c * app/gui/user-install-dialog.c * app/gui/vectors-commands.c * app/tools/gimpcolorpickertool.c * app/tools/gimpcroptool.c * app/tools/gimpimagemaptool.c * app/tools/gimpmeasuretool.c * app/tools/gimptransformtool.c * app/widgets/gimptexteditor.c * app/widgets/gimptooldialog.[ch] * app/widgets/gimpviewabledialog.[ch] * app/widgets/gimpwidgets-utils.c: changed accordingly and increased the dialogs' outer borders to 6 pixels all over the place. * plug-ins/*/*.c: changed accordingly. The plug-ins may be arbitrarily broken, I tested none of them.
2003-11-06 23:27:05 +08:00
gtk_widget_destroy (dialog);
removed our own action_area API and use GtkDialog's one. Create all 2003-11-06 Michael Natterer <mitch@gimp.org> * libgimpwidgets/gimpdialog.[ch]: removed our own action_area API and use GtkDialog's one. Create all dialogs without separator. Changed almost everything else too. Fixes bug #125143. * libgimpwidgets/gimpquerybox.c * libgimpwidgets/gimpunitmenu.c: changed accordingly. * libgimp/gimpexport.[ch]: ditto. Renamed enum GimpExportReturnType to GimpExportReturn. * libgimp/gimpcompat.h: added a #define for the old name. * themes/Default/gtkrc: increased action_area border to 6 pixels. * app/display/gimpdisplayshell-filter-dialog.c * app/display/gimpdisplayshell-scale.c * app/display/gimpprogress.c * app/gui/brush-select.c * app/gui/channels-commands.c * app/gui/color-notebook.c * app/gui/convert-dialog.c * app/gui/file-new-dialog.c * app/gui/font-select.c * app/gui/gradient-editor-commands.c * app/gui/gradient-select.c * app/gui/grid-dialog.c * app/gui/image-commands.c * app/gui/info-window.c * app/gui/layers-commands.c * app/gui/module-browser.c * app/gui/offset-dialog.c * app/gui/palette-import-dialog.c * app/gui/palette-select.c * app/gui/pattern-select.c * app/gui/preferences-dialog.c * app/gui/qmask-commands.c * app/gui/resize-dialog.c * app/gui/resolution-calibrate-dialog.c * app/gui/stroke-dialog.c * app/gui/templates-commands.c * app/gui/user-install-dialog.c * app/gui/vectors-commands.c * app/tools/gimpcolorpickertool.c * app/tools/gimpcroptool.c * app/tools/gimpimagemaptool.c * app/tools/gimpmeasuretool.c * app/tools/gimptransformtool.c * app/widgets/gimptexteditor.c * app/widgets/gimptooldialog.[ch] * app/widgets/gimpviewabledialog.[ch] * app/widgets/gimpwidgets-utils.c: changed accordingly and increased the dialogs' outer borders to 6 pixels all over the place. * plug-ins/*/*.c: changed accordingly. The plug-ins may be arbitrarily broken, I tested none of them.
2003-11-06 23:27:05 +08:00
return run;
}
static void
preview_update (GimpPreview *preview)
{
GimpDrawable *drawable;
GimpPixelRgn src_rgn; /* Source image region */
guchar *src_ptr; /* Current source pixel */
guchar *dst_ptr; /* Current destination pixel */
intneg *neg_ptr; /* Current negative pixel */
gint i; /* Looping var */
gint y; /* Current location in image */
gint width; /* Byte width of the image */
gint x1, y1;
gint preview_width, preview_height;
guchar *preview_src, *preview_dst;
intneg *preview_neg;
gint img_bpp; /* Bytes-per-pixel in image */
void (*filter)(int, guchar *, guchar *, intneg *, intneg *, intneg *);
filter = NULL;
compute_luts();
gimp_preview_get_position (preview, &x1, &y1);
gimp_preview_get_size (preview, &preview_width, &preview_height);
drawable =
gimp_drawable_preview_get_drawable (GIMP_DRAWABLE_PREVIEW (preview));
img_bpp = gimp_drawable_bpp (drawable->drawable_id);
preview_src = g_new (guchar, preview_width * preview_height * img_bpp);
preview_neg = g_new (intneg, preview_width * preview_height * img_bpp);
preview_dst = g_new (guchar, preview_width * preview_height * img_bpp);
gimp_pixel_rgn_init (&src_rgn, drawable,
x1, y1, preview_width, preview_height,
FALSE, FALSE);
width = preview_width * img_bpp;
/*
* Load the preview area...
*/
gimp_pixel_rgn_get_rect (&src_rgn, preview_src, x1, y1,
preview_width, preview_height);
for (i = width * preview_height, src_ptr = preview_src, neg_ptr = preview_neg;
i > 0;
i --)
*neg_ptr++ = neg_lut[*src_ptr++];
/*
* Select the filter...
*/
switch (img_bpp)
{
case 1:
filter = gray_filter;
break;
case 2:
filter = graya_filter;
break;
case 3:
filter = rgb_filter;
break;
case 4:
filter = rgba_filter;
break;
}
/*
* Sharpen...
*/
memcpy (preview_dst, preview_src, width);
memcpy (preview_dst + width * (preview_height - 1),
preview_src + width * (preview_height - 1),
width);
for (y = preview_height - 2, src_ptr = preview_src + width,
neg_ptr = preview_neg + width + img_bpp,
dst_ptr = preview_dst + width;
y > 0;
y --, src_ptr += width, neg_ptr += width, dst_ptr += width)
(*filter)(preview_width, src_ptr, dst_ptr, neg_ptr - width,
neg_ptr, neg_ptr + width);
gimp_preview_draw_buffer (preview, preview_dst, preview_width * img_bpp);
g_free (preview_src);
g_free (preview_neg);
g_free (preview_dst);
}
/*
* 'gray_filter()' - Sharpen grayscale pixels.
*/
static void
gray_filter (gint width, /* I - Width of line in pixels */
guchar *src, /* I - Source line */
guchar *dst, /* O - Destination line */
intneg *neg0, /* I - Top negative coefficient line */
intneg *neg1, /* I - Middle negative coefficient line */
intneg *neg2) /* I - Bottom negative coefficient line */
{
intpos pixel; /* New pixel value */
*dst++ = *src++;
width -= 2;
while (width > 0)
{
pixel = (pos_lut[*src++] - neg0[-1] - neg0[0] - neg0[1] -
neg1[-1] - neg1[1] -
neg2[-1] - neg2[0] - neg2[1]);
pixel = (pixel + 4) >> 3;
*dst++ = CLAMP0255 (pixel);
neg0 ++;
neg1 ++;
neg2 ++;
width --;
}
*dst++ = *src++;
}
/*
* 'graya_filter()' - Sharpen grayscale+alpha pixels.
*/
static void
graya_filter (gint width, /* I - Width of line in pixels */
guchar *src, /* I - Source line */
guchar *dst, /* O - Destination line */
intneg *neg0, /* I - Top negative coefficient line */
intneg *neg1, /* I - Middle negative coefficient line */
intneg *neg2) /* I - Bottom negative coefficient line */
{
intpos pixel; /* New pixel value */
*dst++ = *src++;
*dst++ = *src++;
width -= 2;
while (width > 0)
{
pixel = (pos_lut[*src++] - neg0[-2] - neg0[0] - neg0[2] -
neg1[-2] - neg1[2] -
neg2[-2] - neg2[0] - neg2[2]);
pixel = (pixel + 4) >> 3;
*dst++ = CLAMP0255 (pixel);
*dst++ = *src++;
neg0 += 2;
neg1 += 2;
neg2 += 2;
width --;
}
*dst++ = *src++;
*dst++ = *src++;
}
/*
* 'rgb_filter()' - Sharpen RGB pixels.
*/
static void
rgb_filter (gint width, /* I - Width of line in pixels */
guchar *src, /* I - Source line */
guchar *dst, /* O - Destination line */
intneg *neg0, /* I - Top negative coefficient line */
intneg *neg1, /* I - Middle negative coefficient line */
intneg *neg2) /* I - Bottom negative coefficient line */
{
intpos pixel; /* New pixel value */
*dst++ = *src++;
*dst++ = *src++;
*dst++ = *src++;
width -= 2;
while (width > 0)
{
pixel = (pos_lut[*src++] - neg0[-3] - neg0[0] - neg0[3] -
neg1[-3] - neg1[3] -
neg2[-3] - neg2[0] - neg2[3]);
pixel = (pixel + 4) >> 3;
*dst++ = CLAMP0255 (pixel);
pixel = (pos_lut[*src++] - neg0[-2] - neg0[1] - neg0[4] -
neg1[-2] - neg1[4] -
neg2[-2] - neg2[1] - neg2[4]);
pixel = (pixel + 4) >> 3;
*dst++ = CLAMP0255 (pixel);
pixel = (pos_lut[*src++] - neg0[-1] - neg0[2] - neg0[5] -
neg1[-1] - neg1[5] -
neg2[-1] - neg2[2] - neg2[5]);
pixel = (pixel + 4) >> 3;
*dst++ = CLAMP0255 (pixel);
neg0 += 3;
neg1 += 3;
neg2 += 3;
width --;
}
*dst++ = *src++;
*dst++ = *src++;
*dst++ = *src++;
}
/*
* 'rgba_filter()' - Sharpen RGBA pixels.
*/
static void
rgba_filter (gint width, /* I - Width of line in pixels */
guchar *src, /* I - Source line */
guchar *dst, /* O - Destination line */
intneg *neg0, /* I - Top negative coefficient line */
intneg *neg1, /* I - Middle negative coefficient line */
intneg *neg2) /* I - Bottom negative coefficient line */
{
intpos pixel; /* New pixel value */
*dst++ = *src++;
*dst++ = *src++;
*dst++ = *src++;
*dst++ = *src++;
width -= 2;
while (width > 0)
{
pixel = (pos_lut[*src++] - neg0[-4] - neg0[0] - neg0[4] -
neg1[-4] - neg1[4] -
neg2[-4] - neg2[0] - neg2[4]);
pixel = (pixel + 4) >> 3;
*dst++ = CLAMP0255 (pixel);
pixel = (pos_lut[*src++] - neg0[-3] - neg0[1] - neg0[5] -
neg1[-3] - neg1[5] -
neg2[-3] - neg2[1] - neg2[5]);
pixel = (pixel + 4) >> 3;
*dst++ = CLAMP0255 (pixel);
pixel = (pos_lut[*src++] - neg0[-2] - neg0[2] - neg0[6] -
neg1[-2] - neg1[6] -
neg2[-2] - neg2[2] - neg2[6]);
pixel = (pixel + 4) >> 3;
*dst++ = CLAMP0255 (pixel);
*dst++ = *src++;
neg0 += 4;
neg1 += 4;
neg2 += 4;
width --;
}
*dst++ = *src++;
*dst++ = *src++;
*dst++ = *src++;
*dst++ = *src++;
}