gimp/plug-ins/common/pixelize.c

740 lines
20 KiB
C
Raw Normal View History

1997-11-25 06:05:25 +08:00
/* The GIMP -- an image manipulation program
* Copyright (C) 1995 Spencer Kimball and Peter Mattis
*
* Pixelize plug-in (ported to GIMP v1.0)
* Copyright (C) 1997 Eiichi Takamori <taka@ma1.seikyou.ne.jp>
* original pixelize.c for GIMP 0.54 by Tracy Scott
*
* 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.
1997-11-25 06:05:25 +08:00
*/
/*
* version 1.04
* This version requires GIMP v0.99.10 or above.
*
* This plug-in "pixelizes" the image.
*
* Eiichi Takamori <taka@ma1.seikyou.ne.jp>
* http://ha1.seikyou.ne.jp/home/taka/gimp/
*
* Changes from version 1.03 to version 1.04:
* - Added gtk_rc_parse
* - Added entry with scale
* - Fixed bug that large pixelwidth >=64 sometimes caused core dump
*
* Changes from gimp-0.99.9/plug-ins/pixelize.c to version 1.03:
* - Fixed comments and help strings
* - Fixed `RGB, GRAY' to `RGB*, GRAY*'
* - Fixed procedure db name `pixelize' to `plug_in_pixelize'
*
* Differences from Tracy Scott's original `pixelize' plug-in:
*
* - Algorithm is modified to work around with the tile management.
* The way of pixelizing is switched by the value of pixelwidth. If
* pixelwidth is greater than (or equal to) tile width, then this
* plug-in makes GimpPixelRgn with that width and proceeds. Otherwise,
1997-11-25 06:05:25 +08:00
* it makes the region named `PixelArea', whose size is smaller than
* tile width and is multiply of pixel width, and acts onto it.
*/
/* pixelize filter written for the GIMP
* -Tracy Scott
*
* This filter acts as a low pass filter on the color components of
* the provided region
*/
#include "config.h"
1997-11-25 06:05:25 +08:00
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <gtk/gtk.h>
app/gimpui.[ch] removed & renamed some functions from gimpui.[ch] (see 2000-01-13 Michael Natterer <mitch@gimp.org> * app/gimpui.[ch] * app/preferences_dialog.c: removed & renamed some functions from gimpui.[ch] (see below). * libgimp/Makefile.am * libgimp/gimpwidgets.[ch]; new files. Functions moved from app/gimpui.[ch]. Added a constructor for the label + hscale + entry combination used in many plugins (now hscale + spinbutton). * libgimp/gimpui.h: include gimpwidgets.h * plug-ins/megawidget/megawidget.[ch]: removed all functions except the preview stuff (I'm not yet sure how to implement this in libgimp because the libgimp preview should be general enough to replace all the other plugin previews, too). * plug-ins/borderaverage/Makefile.am * plug-ins/borderaverage/borderaverage.c * plug-ins/common/plugin-defs.pl * plug-ins/common/Makefile.am * plug-ins/common/aa.c * plug-ins/common/align_layers.c * plug-ins/common/animationplay.c * plug-ins/common/apply_lens.c * plug-ins/common/blinds.c * plug-ins/common/bumpmap.c * plug-ins/common/checkerboard.c * plug-ins/common/colorify.c * plug-ins/common/convmatrix.c * plug-ins/common/cubism.c * plug-ins/common/curve_bend.c * plug-ins/common/deinterlace.c * plug-ins/common/despeckle.c * plug-ins/common/destripe.c * plug-ins/common/displace.c * plug-ins/common/edge.c * plug-ins/common/emboss.c * plug-ins/common/hot.c * plug-ins/common/nlfilt.c * plug-ins/common/pixelize.c * plug-ins/common/waves.c * plug-ins/sgi/sgi.c * plug-ins/sinus/sinus.c: ui updates like removing megawidget, using the dialog constructor, I18N fixes, indentation, ...
2000-01-13 23:39:26 +08:00
#include <libgimp/gimp.h>
#include <libgimp/gimpui.h>
#include "libgimp/stdplugins-intl.h"
1997-11-25 06:05:25 +08:00
1997-11-25 06:05:25 +08:00
#ifdef RCSID
static char rcsid[] = "$Id$";
#endif
/* Some useful macros */
app/gimpui.[ch] removed & renamed some functions from gimpui.[ch] (see 2000-01-13 Michael Natterer <mitch@gimp.org> * app/gimpui.[ch] * app/preferences_dialog.c: removed & renamed some functions from gimpui.[ch] (see below). * libgimp/Makefile.am * libgimp/gimpwidgets.[ch]; new files. Functions moved from app/gimpui.[ch]. Added a constructor for the label + hscale + entry combination used in many plugins (now hscale + spinbutton). * libgimp/gimpui.h: include gimpwidgets.h * plug-ins/megawidget/megawidget.[ch]: removed all functions except the preview stuff (I'm not yet sure how to implement this in libgimp because the libgimp preview should be general enough to replace all the other plugin previews, too). * plug-ins/borderaverage/Makefile.am * plug-ins/borderaverage/borderaverage.c * plug-ins/common/plugin-defs.pl * plug-ins/common/Makefile.am * plug-ins/common/aa.c * plug-ins/common/align_layers.c * plug-ins/common/animationplay.c * plug-ins/common/apply_lens.c * plug-ins/common/blinds.c * plug-ins/common/bumpmap.c * plug-ins/common/checkerboard.c * plug-ins/common/colorify.c * plug-ins/common/convmatrix.c * plug-ins/common/cubism.c * plug-ins/common/curve_bend.c * plug-ins/common/deinterlace.c * plug-ins/common/despeckle.c * plug-ins/common/destripe.c * plug-ins/common/displace.c * plug-ins/common/edge.c * plug-ins/common/emboss.c * plug-ins/common/hot.c * plug-ins/common/nlfilt.c * plug-ins/common/pixelize.c * plug-ins/common/waves.c * plug-ins/sgi/sgi.c * plug-ins/sinus/sinus.c: ui updates like removing megawidget, using the dialog constructor, I18N fixes, indentation, ...
2000-01-13 23:39:26 +08:00
#define TILE_CACHE_SIZE 16
#define SCALE_WIDTH 125
changed "Number of Colors" to "Max Number of Colors" to clarify what this 2002-09-06 Michael Natterer <mitch@gimp.org> * app/gui/convert-dialog.c: changed "Number of Colors" to "Max Number of Colors" to clarify what this parameter does. (fixes #92194). * app/gui/menus.c: use GIMP_STOCK_INFO for "View/Info Window". Specify spibutton sizes in chars, not pixels (eek) all over the place. Also removed explicit sizes where the GtkSpinButton default size does not disturbe tabular widget layouts. * libgimpwidgets/gimpwidgets.c: removed the hardcoded width of 75 pixels in gimp_spin_button_new(). Changed gimp_scale_entry_new() and gimp_coordinates_new() to interpret their "spinbutton_width" parameters as chars if < 16, and as pixels otherwise. This gives reasonable results and doesn't cause unchanged plug-ins to suddenly have spinbuttons of dozens of chars width :) * libgimpwidgets/gimpsizeentry.c: added the same heuristic here. * libgimpwidgets/gimpquerybox.c * app/gui/color-notebook.c * app/gui/convert-dialog.c * app/tools/gimpairbrushtool.c * app/tools/gimpblendtool.c * app/tools/gimpbrightnesscontrasttool.c * app/tools/gimpbucketfilltool.c * app/tools/gimpcolorbalancetool.c * app/tools/gimpcolorpickertool.c * app/tools/gimpconvolvetool.c * app/tools/gimpdodgeburntool.c * app/tools/gimphuesaturationtool.c * app/tools/gimpinktool.c * app/tools/gimplevelstool.c * app/tools/gimpmagnifytool.c * app/tools/gimpposterizetool.c * app/tools/gimpsmudgetool.c * app/tools/gimptexttool.c * app/tools/gimpthresholdtool.c * app/tools/paint_options.c * app/tools/selection_options.c * app/widgets/gimpbrusheditor.c * app/widgets/gimpbrushfactoryview.c * app/widgets/gimppaletteeditor.c: changed accordingly. * plug-ins/FractalExplorer/Dialogs.c * plug-ins/FractalExplorer/FractalExplorer.c * plug-ins/Lighting/lighting_ui.c * plug-ins/common/AlienMap.c * plug-ins/common/AlienMap2.c * plug-ins/common/CML_explorer.c * plug-ins/common/bumpmap.c * plug-ins/common/checkerboard.c * plug-ins/common/cubism.c * plug-ins/common/curve_bend.c * plug-ins/common/depthmerge.c * plug-ins/common/despeckle.c * plug-ins/common/diffraction.c * plug-ins/common/emboss.c * plug-ins/common/film.c * plug-ins/common/flarefx.c * plug-ins/common/fractaltrace.c * plug-ins/common/gauss_iir.c * plug-ins/common/gauss_rle.c * plug-ins/common/glasstile.c * plug-ins/common/grid.c * plug-ins/common/illusion.c * plug-ins/common/iwarp.c * plug-ins/common/jigsaw.c * plug-ins/common/lic.c * plug-ins/common/max_rgb.c * plug-ins/common/mblur.c * plug-ins/common/newsprint.c * plug-ins/common/nova.c * plug-ins/common/pixelize.c * plug-ins/common/sample_colorize.c * plug-ins/common/scatter_hsv.c * plug-ins/common/shift.c * plug-ins/common/sinus.c * plug-ins/common/sparkle.c * plug-ins/common/spread.c * plug-ins/common/tile.c * plug-ins/common/tileit.c * plug-ins/common/unsharp.c * plug-ins/common/vpropagate.c * plug-ins/common/waves.c * plug-ins/common/whirlpinch.c * plug-ins/gflare/gflare.c * plug-ins/mosaic/mosaic.c * plug-ins/rcm/rcm_dialog.c: changed accordingly, which involves removals of gtk_widget_set_size_request(spinbutton), removal of lots of explicit spinbutton sizes in gimp_scale_entry_new(), and adding of new ones because GtkSpinButton's auto-size trashed tabular layouts. Lots of cleanup & indentation while browsing the plug-ins' code. Changed spacings, moved toggle buttons into frame titles, use stock items, stuff...
2002-09-07 04:44:47 +08:00
#define ENTRY_WIDTH 6
1997-11-25 06:05:25 +08:00
app/gimpui.[ch] removed & renamed some functions from gimpui.[ch] (see 2000-01-13 Michael Natterer <mitch@gimp.org> * app/gimpui.[ch] * app/preferences_dialog.c: removed & renamed some functions from gimpui.[ch] (see below). * libgimp/Makefile.am * libgimp/gimpwidgets.[ch]; new files. Functions moved from app/gimpui.[ch]. Added a constructor for the label + hscale + entry combination used in many plugins (now hscale + spinbutton). * libgimp/gimpui.h: include gimpwidgets.h * plug-ins/megawidget/megawidget.[ch]: removed all functions except the preview stuff (I'm not yet sure how to implement this in libgimp because the libgimp preview should be general enough to replace all the other plugin previews, too). * plug-ins/borderaverage/Makefile.am * plug-ins/borderaverage/borderaverage.c * plug-ins/common/plugin-defs.pl * plug-ins/common/Makefile.am * plug-ins/common/aa.c * plug-ins/common/align_layers.c * plug-ins/common/animationplay.c * plug-ins/common/apply_lens.c * plug-ins/common/blinds.c * plug-ins/common/bumpmap.c * plug-ins/common/checkerboard.c * plug-ins/common/colorify.c * plug-ins/common/convmatrix.c * plug-ins/common/cubism.c * plug-ins/common/curve_bend.c * plug-ins/common/deinterlace.c * plug-ins/common/despeckle.c * plug-ins/common/destripe.c * plug-ins/common/displace.c * plug-ins/common/edge.c * plug-ins/common/emboss.c * plug-ins/common/hot.c * plug-ins/common/nlfilt.c * plug-ins/common/pixelize.c * plug-ins/common/waves.c * plug-ins/sgi/sgi.c * plug-ins/sinus/sinus.c: ui updates like removing megawidget, using the dialog constructor, I18N fixes, indentation, ...
2000-01-13 23:39:26 +08:00
typedef struct
{
1997-11-25 06:05:25 +08:00
gint pixelwidth;
gint pixelheight;
1997-11-25 06:05:25 +08:00
} PixelizeValues;
app/gimpui.[ch] removed & renamed some functions from gimpui.[ch] (see 2000-01-13 Michael Natterer <mitch@gimp.org> * app/gimpui.[ch] * app/preferences_dialog.c: removed & renamed some functions from gimpui.[ch] (see below). * libgimp/Makefile.am * libgimp/gimpwidgets.[ch]; new files. Functions moved from app/gimpui.[ch]. Added a constructor for the label + hscale + entry combination used in many plugins (now hscale + spinbutton). * libgimp/gimpui.h: include gimpwidgets.h * plug-ins/megawidget/megawidget.[ch]: removed all functions except the preview stuff (I'm not yet sure how to implement this in libgimp because the libgimp preview should be general enough to replace all the other plugin previews, too). * plug-ins/borderaverage/Makefile.am * plug-ins/borderaverage/borderaverage.c * plug-ins/common/plugin-defs.pl * plug-ins/common/Makefile.am * plug-ins/common/aa.c * plug-ins/common/align_layers.c * plug-ins/common/animationplay.c * plug-ins/common/apply_lens.c * plug-ins/common/blinds.c * plug-ins/common/bumpmap.c * plug-ins/common/checkerboard.c * plug-ins/common/colorify.c * plug-ins/common/convmatrix.c * plug-ins/common/cubism.c * plug-ins/common/curve_bend.c * plug-ins/common/deinterlace.c * plug-ins/common/despeckle.c * plug-ins/common/destripe.c * plug-ins/common/displace.c * plug-ins/common/edge.c * plug-ins/common/emboss.c * plug-ins/common/hot.c * plug-ins/common/nlfilt.c * plug-ins/common/pixelize.c * plug-ins/common/waves.c * plug-ins/sgi/sgi.c * plug-ins/sinus/sinus.c: ui updates like removing megawidget, using the dialog constructor, I18N fixes, indentation, ...
2000-01-13 23:39:26 +08:00
typedef struct
{
GtkWidget *sizeentry;
gint run;
1997-11-25 06:05:25 +08:00
} PixelizeInterface;
app/gimpui.[ch] removed & renamed some functions from gimpui.[ch] (see 2000-01-13 Michael Natterer <mitch@gimp.org> * app/gimpui.[ch] * app/preferences_dialog.c: removed & renamed some functions from gimpui.[ch] (see below). * libgimp/Makefile.am * libgimp/gimpwidgets.[ch]; new files. Functions moved from app/gimpui.[ch]. Added a constructor for the label + hscale + entry combination used in many plugins (now hscale + spinbutton). * libgimp/gimpui.h: include gimpwidgets.h * plug-ins/megawidget/megawidget.[ch]: removed all functions except the preview stuff (I'm not yet sure how to implement this in libgimp because the libgimp preview should be general enough to replace all the other plugin previews, too). * plug-ins/borderaverage/Makefile.am * plug-ins/borderaverage/borderaverage.c * plug-ins/common/plugin-defs.pl * plug-ins/common/Makefile.am * plug-ins/common/aa.c * plug-ins/common/align_layers.c * plug-ins/common/animationplay.c * plug-ins/common/apply_lens.c * plug-ins/common/blinds.c * plug-ins/common/bumpmap.c * plug-ins/common/checkerboard.c * plug-ins/common/colorify.c * plug-ins/common/convmatrix.c * plug-ins/common/cubism.c * plug-ins/common/curve_bend.c * plug-ins/common/deinterlace.c * plug-ins/common/despeckle.c * plug-ins/common/destripe.c * plug-ins/common/displace.c * plug-ins/common/edge.c * plug-ins/common/emboss.c * plug-ins/common/hot.c * plug-ins/common/nlfilt.c * plug-ins/common/pixelize.c * plug-ins/common/waves.c * plug-ins/sgi/sgi.c * plug-ins/sinus/sinus.c: ui updates like removing megawidget, using the dialog constructor, I18N fixes, indentation, ...
2000-01-13 23:39:26 +08:00
typedef struct
{
1997-11-25 06:05:25 +08:00
gint x, y, w, h;
gint width;
gint height;
1997-11-25 06:05:25 +08:00
guchar *data;
} PixelArea;
/* Declare local functions.
*/
static void query (void);
static void run (gchar *name,
gint nparams,
GimpParam *param,
gint *nreturn_vals,
GimpParam **return_vals);
static gint pixelize_dialog (GimpDrawable *drawable);
static void pixelize_ok_callback (GtkWidget *widget,
gpointer data);
static void pixelize (GimpDrawable *drawable);
static void pixelize_large (GimpDrawable *drawable,
gint pixelwidth,
gint pixelheight);
static void pixelize_small (GimpDrawable *drawable,
gint pixelwidth,
gint pixelheight,
gint tile_width,
gint tile_height);
static void pixelize_sub (gint pixelwidth,
gint pixelheight,
gint bpp,
gint has_alpha);
1997-11-25 06:05:25 +08:00
/***** Local vars *****/
GimpPlugInInfo PLUG_IN_INFO =
1997-11-25 06:05:25 +08:00
{
NULL, /* init_proc */
NULL, /* quit_proc */
query, /* query_proc */
run /* run_proc */
1997-11-25 06:05:25 +08:00
};
static PixelizeValues pvals =
{
10,
1997-11-25 06:05:25 +08:00
10
};
static PixelizeInterface pint =
{
NULL,
1997-11-25 06:05:25 +08:00
FALSE /* run */
};
static PixelArea area;
/***** Functions *****/
MAIN ()
static void
query (void)
1997-11-25 06:05:25 +08:00
{
static GimpParamDef pixelize_args[]=
app/gimpui.[ch] removed & renamed some functions from gimpui.[ch] (see 2000-01-13 Michael Natterer <mitch@gimp.org> * app/gimpui.[ch] * app/preferences_dialog.c: removed & renamed some functions from gimpui.[ch] (see below). * libgimp/Makefile.am * libgimp/gimpwidgets.[ch]; new files. Functions moved from app/gimpui.[ch]. Added a constructor for the label + hscale + entry combination used in many plugins (now hscale + spinbutton). * libgimp/gimpui.h: include gimpwidgets.h * plug-ins/megawidget/megawidget.[ch]: removed all functions except the preview stuff (I'm not yet sure how to implement this in libgimp because the libgimp preview should be general enough to replace all the other plugin previews, too). * plug-ins/borderaverage/Makefile.am * plug-ins/borderaverage/borderaverage.c * plug-ins/common/plugin-defs.pl * plug-ins/common/Makefile.am * plug-ins/common/aa.c * plug-ins/common/align_layers.c * plug-ins/common/animationplay.c * plug-ins/common/apply_lens.c * plug-ins/common/blinds.c * plug-ins/common/bumpmap.c * plug-ins/common/checkerboard.c * plug-ins/common/colorify.c * plug-ins/common/convmatrix.c * plug-ins/common/cubism.c * plug-ins/common/curve_bend.c * plug-ins/common/deinterlace.c * plug-ins/common/despeckle.c * plug-ins/common/destripe.c * plug-ins/common/displace.c * plug-ins/common/edge.c * plug-ins/common/emboss.c * plug-ins/common/hot.c * plug-ins/common/nlfilt.c * plug-ins/common/pixelize.c * plug-ins/common/waves.c * plug-ins/sgi/sgi.c * plug-ins/sinus/sinus.c: ui updates like removing megawidget, using the dialog constructor, I18N fixes, indentation, ...
2000-01-13 23:39:26 +08:00
{
{ GIMP_PDB_INT32, "run_mode", "Interactive, non-interactive" },
{ GIMP_PDB_IMAGE, "image", "Input image (unused)" },
{ GIMP_PDB_DRAWABLE, "drawable", "Input drawable" },
{ GIMP_PDB_INT32, "pixelwidth", "Pixel width (the decrease in resolution)" }
};
static GimpParamDef pixelize2_args[]=
{
{ GIMP_PDB_INT32, "run_mode", "Interactive, non-interactive" },
{ GIMP_PDB_IMAGE, "image", "Input image (unused)" },
{ GIMP_PDB_DRAWABLE, "drawable", "Input drawable" },
{ GIMP_PDB_INT32, "pixelwidth", "Pixel width (the decrease in horizontal resolution)" },
{ GIMP_PDB_INT32, "pixelheight", "Pixel height (the decrease in vertical resolution)" }
app/gimpui.[ch] removed & renamed some functions from gimpui.[ch] (see 2000-01-13 Michael Natterer <mitch@gimp.org> * app/gimpui.[ch] * app/preferences_dialog.c: removed & renamed some functions from gimpui.[ch] (see below). * libgimp/Makefile.am * libgimp/gimpwidgets.[ch]; new files. Functions moved from app/gimpui.[ch]. Added a constructor for the label + hscale + entry combination used in many plugins (now hscale + spinbutton). * libgimp/gimpui.h: include gimpwidgets.h * plug-ins/megawidget/megawidget.[ch]: removed all functions except the preview stuff (I'm not yet sure how to implement this in libgimp because the libgimp preview should be general enough to replace all the other plugin previews, too). * plug-ins/borderaverage/Makefile.am * plug-ins/borderaverage/borderaverage.c * plug-ins/common/plugin-defs.pl * plug-ins/common/Makefile.am * plug-ins/common/aa.c * plug-ins/common/align_layers.c * plug-ins/common/animationplay.c * plug-ins/common/apply_lens.c * plug-ins/common/blinds.c * plug-ins/common/bumpmap.c * plug-ins/common/checkerboard.c * plug-ins/common/colorify.c * plug-ins/common/convmatrix.c * plug-ins/common/cubism.c * plug-ins/common/curve_bend.c * plug-ins/common/deinterlace.c * plug-ins/common/despeckle.c * plug-ins/common/destripe.c * plug-ins/common/displace.c * plug-ins/common/edge.c * plug-ins/common/emboss.c * plug-ins/common/hot.c * plug-ins/common/nlfilt.c * plug-ins/common/pixelize.c * plug-ins/common/waves.c * plug-ins/sgi/sgi.c * plug-ins/sinus/sinus.c: ui updates like removing megawidget, using the dialog constructor, I18N fixes, indentation, ...
2000-01-13 23:39:26 +08:00
};
1997-11-25 06:05:25 +08:00
gimp_install_procedure ("plug_in_pixelize",
2000-01-31 10:32:30 +08:00
"Pixelize the contents of the specified drawable",
"Pixelize the contents of the specified drawable with speficied pixelizing width.",
1997-11-25 06:05:25 +08:00
"Spencer Kimball & Peter Mattis, Tracy Scott, (ported to 1.0 by) Eiichi Takamori",
"Spencer Kimball & Peter Mattis, Tracy Scott",
"1995",
N_("<Image>/Filters/Blur/Pixelize..."),
1997-11-25 06:05:25 +08:00
"RGB*, GRAY*",
GIMP_PLUGIN,
G_N_ELEMENTS (pixelize_args), 0,
pixelize_args, NULL);
gimp_install_procedure ("plug_in_pixelize2",
"Pixelize the contents of the specified drawable",
"Pixelize the contents of the specified drawable with speficied pixelizing width.",
"Spencer Kimball & Peter Mattis, Tracy Scott, (ported to 1.0 by) Eiichi Takamori",
"Spencer Kimball & Peter Mattis, Tracy Scott",
"2001",
NULL,
"RGB*, GRAY*",
GIMP_PLUGIN,
G_N_ELEMENTS (pixelize2_args), 0,
pixelize2_args, NULL);
1997-11-25 06:05:25 +08:00
}
static void
run (gchar *name,
gint nparams,
GimpParam *param,
gint *nreturn_vals,
GimpParam **return_vals)
1997-11-25 06:05:25 +08:00
{
static GimpParam values[1];
GimpDrawable *drawable;
GimpRunMode run_mode;
GimpPDBStatusType status = GIMP_PDB_SUCCESS;
1997-11-25 06:05:25 +08:00
run_mode = param[0].data.d_int32;
*nreturn_vals = 1;
*return_vals = values;
1997-11-25 06:05:25 +08:00
values[0].type = GIMP_PDB_STATUS;
1997-11-25 06:05:25 +08:00
values[0].data.d_status = status;
/* Get the specified drawable */
drawable = gimp_drawable_get (param[2].data.d_drawable);
switch (run_mode)
{
case GIMP_RUN_INTERACTIVE:
INIT_I18N_UI();
1997-11-25 06:05:25 +08:00
/* Possibly retrieve data */
gimp_get_data ("plug_in_pixelize", &pvals);
/* First acquire information with a dialog */
if (! pixelize_dialog (drawable))
1997-11-25 06:05:25 +08:00
{
gimp_drawable_detach (drawable);
return;
}
break;
case GIMP_RUN_NONINTERACTIVE:
INIT_I18N();
1997-11-25 06:05:25 +08:00
/* Make sure all the arguments are there! */
if ((! strcmp (name, "plug_in_pixelize") && nparams != 4) ||
(! strcmp (name, "plug_in_pixelize2") && nparams != 5))
{
status = GIMP_PDB_CALLING_ERROR;
}
if (status == GIMP_PDB_SUCCESS)
1997-11-25 06:05:25 +08:00
{
pvals.pixelwidth = (gdouble) param[3].data.d_int32;
if (nparams == 4)
pvals.pixelheight = pvals.pixelwidth;
else
pvals.pixelheight = (gdouble) param[4].data.d_int32;
1997-11-25 06:05:25 +08:00
}
if ((status == GIMP_PDB_SUCCESS) &&
(pvals.pixelwidth <= 0 || pvals.pixelheight <= 0))
{
status = GIMP_PDB_CALLING_ERROR;
}
1997-11-25 06:05:25 +08:00
break;
case GIMP_RUN_WITH_LAST_VALS:
INIT_I18N();
1997-11-25 06:05:25 +08:00
/* Possibly retrieve data */
gimp_get_data ("plug_in_pixelize", &pvals);
break;
default:
break;
}
if (status == GIMP_PDB_SUCCESS)
1997-11-25 06:05:25 +08:00
{
/* Make sure that the drawable is gray or RGB color */
if (gimp_drawable_is_rgb (drawable->drawable_id) ||
gimp_drawable_is_gray (drawable->drawable_id))
1997-11-25 06:05:25 +08:00
{
gimp_progress_init (_("Pixelizing..."));
1997-11-25 06:05:25 +08:00
/* set the tile cache size */
gimp_tile_cache_ntiles (TILE_CACHE_SIZE);
/* run the pixelize effect */
pixelize (drawable);
if (run_mode != GIMP_RUN_NONINTERACTIVE)
1997-11-25 06:05:25 +08:00
gimp_displays_flush ();
/* Store data */
if (run_mode == GIMP_RUN_INTERACTIVE)
1997-11-25 06:05:25 +08:00
gimp_set_data ("plug_in_pixelize", &pvals, sizeof (PixelizeValues));
}
else
{
/* g_message ("pixelize: cannot operate on indexed color images"); */
status = GIMP_PDB_EXECUTION_ERROR;
1997-11-25 06:05:25 +08:00
}
}
values[0].data.d_status = status;
gimp_drawable_detach (drawable);
}
static gint
pixelize_dialog (GimpDrawable *drawable)
1997-11-25 06:05:25 +08:00
{
GtkWidget *dlg;
GtkWidget *frame;
GtkWidget *vbox;
guint32 image_id;
GimpUnit unit;
gdouble xres, yres;
1997-11-25 06:05:25 +08:00
gimp_ui_init ("pixelize", FALSE);
1997-11-25 06:05:25 +08:00
dlg = gimp_dialog_new (_("Pixelize"), "pixelize",
gimp_standard_help_func, "filters/pixelize.html",
GTK_WIN_POS_MOUSE,
FALSE, TRUE, FALSE,
2001-08-04 03:52:08 +08:00
GTK_STOCK_CANCEL, gtk_widget_destroy,
NULL, 1, NULL, FALSE, TRUE,
GTK_STOCK_OK, pixelize_ok_callback,
NULL, NULL, NULL, TRUE, FALSE,
NULL);
1997-11-25 06:05:25 +08:00
g_signal_connect (dlg, "destroy",
G_CALLBACK (gtk_main_quit),
NULL);
1997-11-25 06:05:25 +08:00
/* parameter settings */
frame = gtk_frame_new (_("Parameter Settings"));
1997-11-25 06:05:25 +08:00
gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_ETCHED_IN);
added -DGTK_DISABLE_COMPAT_H to CPPFLAGS. 2000-08-28 Michael Natterer <mitch@gimp.org> * configure.in: added -DGTK_DISABLE_COMPAT_H to CPPFLAGS. * app/app_procs.c * app/gdisplay.c * app/layers_dialog.c * app/menus.c * app/tips_dialog.c * libgimp/gimpcolorbutton.c * plug-ins/FractalExplorer/Dialogs.c * plug-ins/FractalExplorer/FractalExplorer.c * plug-ins/bmp/bmpwrite.c * plug-ins/common/AlienMap.c * plug-ins/common/AlienMap2.c * plug-ins/common/CML_explorer.c * plug-ins/common/animationplay.c * plug-ins/common/cubism.c * plug-ins/common/curve_bend.c * plug-ins/common/deinterlace.c * plug-ins/common/gee.c * plug-ins/common/glasstile.c * plug-ins/common/iwarp.c * plug-ins/common/mail.c * plug-ins/common/pat.c * plug-ins/common/pixelize.c * plug-ins/common/plugindetails.c * plug-ins/common/png.c * plug-ins/common/sample_colorize.c * plug-ins/common/sel_gauss.c * plug-ins/common/sinus.c * plug-ins/common/sparkle.c * plug-ins/common/spheredesigner.c * plug-ins/common/tga.c * plug-ins/common/tileit.c * plug-ins/common/vpropagate.c * plug-ins/common/warp.c * plug-ins/common/waves.c * plug-ins/common/wmf.c * plug-ins/flame/flame.c * plug-ins/fp/fp_gtk.c * plug-ins/gap/gap_arr_dialog.c * plug-ins/gap/gap_dbbrowser_utils.c * plug-ins/gap/gap_mov_dialog.c * plug-ins/gap/gap_navigator_dialog.c * plug-ins/gap/gap_resi_dialog.c * plug-ins/gdyntext/gdyntext_ui.c * plug-ins/gfig/gfig.c * plug-ins/gimpressionist/brush.c * plug-ins/gimpressionist/gimpressionist.c * plug-ins/pagecurl/pagecurl.c * plug-ins/print/gimp_main_window.c * plug-ins/rcm/rcm_callback.c * plug-ins/rcm/rcm_dialog.c * plug-ins/script-fu/script-fu-console.c * plug-ins/script-fu/script-fu-scripts.c * plug-ins/script-fu/script-fu-server.c * plug-ins/sel2path/sel2path_adv_dialog.c * plug-ins/xjt/xjt.c: removed COMPAT_CRUFT.
2000-08-28 08:42:32 +08:00
gtk_container_set_border_width (GTK_CONTAINER (frame), 6);
1997-11-25 06:05:25 +08:00
gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dlg)->vbox), frame, TRUE, TRUE, 0);
gtk_widget_show (frame);
1997-11-25 06:05:25 +08:00
vbox = gtk_vbox_new (FALSE, 4);
gtk_container_set_border_width (GTK_CONTAINER (vbox), 4);
gtk_container_add (GTK_CONTAINER (frame), vbox);
gtk_widget_show (vbox);
image_id = gimp_drawable_image (drawable->drawable_id);
unit = gimp_image_get_unit (image_id);
gimp_image_get_resolution (image_id, &xres, &yres);
pint.sizeentry = gimp_coordinates_new (unit, "%a", TRUE, TRUE, ENTRY_WIDTH,
GIMP_SIZE_ENTRY_UPDATE_SIZE,
TRUE, FALSE,
_("Pixel _Width:"),
pvals.pixelwidth, xres,
1, drawable->width,
1, drawable->width,
_("Pixel _Height:"),
pvals.pixelheight, yres,
1, drawable->height,
1, drawable->height);
gtk_box_pack_start (GTK_BOX (vbox), pint.sizeentry, FALSE, FALSE, 0);
gtk_widget_show (pint.sizeentry);
1997-11-25 06:05:25 +08:00
gtk_widget_show (dlg);
gtk_main ();
gdk_flush ();
return pint.run;
}
/* Pixelize interface functions */
static void
pixelize_ok_callback (GtkWidget *widget,
gpointer data)
{
pint.run = TRUE;
pvals.pixelwidth =
gimp_size_entry_get_refval (GIMP_SIZE_ENTRY (pint.sizeentry), 0);
pvals.pixelheight =
gimp_size_entry_get_refval (GIMP_SIZE_ENTRY (pint.sizeentry), 1);
1997-11-25 06:05:25 +08:00
gtk_widget_destroy (GTK_WIDGET (data));
}
/*
Pixelize Effect
*/
static void
pixelize (GimpDrawable *drawable)
1997-11-25 06:05:25 +08:00
{
gint tile_width;
gint tile_height;
1997-11-25 06:05:25 +08:00
gint pixelwidth;
gint pixelheight;
1997-11-25 06:05:25 +08:00
tile_width = gimp_tile_width ();
tile_height = gimp_tile_height ();
pixelwidth = pvals.pixelwidth;
pixelheight = pvals.pixelheight;
1997-11-25 06:05:25 +08:00
if (pixelwidth < 0)
pixelwidth = - pixelwidth;
if (pixelwidth < 1)
pixelwidth = 1;
if (pixelheight < 0)
pixelheight = - pixelheight;
if (pixelheight < 1)
pixelheight = 1;
if (pixelwidth >= tile_width || pixelheight >= tile_height)
pixelize_large (drawable, pixelwidth, pixelheight);
1997-11-25 06:05:25 +08:00
else
pixelize_small (drawable, pixelwidth, pixelheight, tile_width, tile_height);
1997-11-25 06:05:25 +08:00
}
/*
This function operates on the image when pixelwidth >= tile_width.
It simply sets the size of GimpPixelRgn as pixelwidth and proceeds.
1997-11-25 06:05:25 +08:00
*/
static void
pixelize_large (GimpDrawable *drawable,
gint pixelwidth,
gint pixelheight)
1997-11-25 06:05:25 +08:00
{
GimpPixelRgn src_rgn, dest_rgn;
guchar *src_row, *dest_row;
guchar *src, *dest;
gulong *average;
gint row, col, b, bpp, has_alpha;
gint x, y, x_step, y_step;
gulong count;
gint x1, y1, x2, y2;
gint progress, max_progress;
gpointer pr;
1997-11-25 06:05:25 +08:00
gimp_drawable_mask_bounds (drawable->drawable_id, &x1, &y1, &x2, &y2);
1997-11-25 06:05:25 +08:00
bpp = gimp_drawable_bpp (drawable->drawable_id);
has_alpha = gimp_drawable_has_alpha (drawable->drawable_id);
average = g_new (gulong, bpp);
1997-11-25 06:05:25 +08:00
/* Initialize progress */
progress = 0;
max_progress = 2 * (x2 - x1) * (y2 - y1);
for (y = y1; y < y2; y += pixelheight - (y % pixelheight))
1997-11-25 06:05:25 +08:00
{
for (x = x1; x < x2; x += pixelwidth - (x % pixelwidth))
1997-11-25 06:05:25 +08:00
{
x_step = pixelwidth - (x % pixelwidth);
y_step = pixelheight - (y % pixelheight);
x_step = MIN(x_step, x2-x);
y_step = MIN(y_step, y2-y);
gimp_pixel_rgn_init (&src_rgn, drawable,
x, y, x_step, y_step, FALSE, FALSE);
for (b = 0; b < bpp; b++)
1997-11-25 06:05:25 +08:00
average[b] = 0;
count = 0;
for (pr = gimp_pixel_rgns_register (1, &src_rgn);
pr != NULL;
pr = gimp_pixel_rgns_process (pr))
1997-11-25 06:05:25 +08:00
{
src_row = src_rgn.data;
for (row = 0; row < src_rgn.h; row++)
{
src = src_row;
if (has_alpha)
{
for (col = 0; col < src_rgn.w; col++)
{
gulong alpha = src[bpp-1];
average[bpp-1] += alpha;
for (b = 0; b < bpp-1; b++)
average[b] += src[b] * alpha;
src += src_rgn.bpp;
}
}
else
{
for (col = 0; col < src_rgn.w; col++)
{
for (b = 0; b < bpp; b++)
average[b] += src[b];
src += src_rgn.bpp;
}
}
1997-11-25 06:05:25 +08:00
src_row += src_rgn.rowstride;
}
/* Update progress */
count += src_rgn.w * src_rgn.h;
1997-11-25 06:05:25 +08:00
progress += src_rgn.w * src_rgn.h;
gimp_progress_update ((double) progress / (double) max_progress);
}
if (count > 0)
1997-11-25 06:05:25 +08:00
{
if (has_alpha)
{
gulong alpha = average[bpp-1];
if (average[bpp-1] = alpha/count)
for (b = 0; b < bpp-1; b++)
average[b] /= alpha;
}
else
{
for (b = 0; b < bpp; b++)
average[b] /= count;
}
1997-11-25 06:05:25 +08:00
}
gimp_pixel_rgn_init (&dest_rgn, drawable,
x, y, x_step, y_step, TRUE, TRUE);
for (pr = gimp_pixel_rgns_register (1, &dest_rgn);
pr != NULL;
pr = gimp_pixel_rgns_process (pr))
1997-11-25 06:05:25 +08:00
{
dest_row = dest_rgn.data;
for (row = 0; row < dest_rgn.h; row++)
{
dest = dest_row;
for (col = 0; col < dest_rgn.w; col++)
{
for (b = 0; b < bpp; b++)
1997-11-25 06:05:25 +08:00
dest[b] = average[b];
dest += dest_rgn.bpp;
count += 1;
}
dest_row += dest_rgn.rowstride;
}
/* Update progress */
progress += dest_rgn.w * dest_rgn.h;
gimp_progress_update ((double) progress / (double) max_progress);
}
}
}
g_free (average);
1997-11-25 06:05:25 +08:00
/* update the blurred 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));
1997-11-25 06:05:25 +08:00
}
/*
This function operates on PixelArea, whose width and height are
multiply of pixel width, and less than the tile size (to enhance
its speed).
If any coordinates of mask boundary is not multiply of pixel width
(e.g. x1 % pixelwidth != 0), operates on the region whose width
1997-11-25 06:05:25 +08:00
or height is the remainder.
*/
static void
pixelize_small (GimpDrawable *drawable,
gint pixelwidth,
gint pixelheight,
gint tile_width,
gint tile_height)
1997-11-25 06:05:25 +08:00
{
GimpPixelRgn src_rgn, dest_rgn;
gint bpp, has_alpha;
gint x1, y1, x2, y2;
gint progress, max_progress;
1997-11-25 06:05:25 +08:00
gimp_drawable_mask_bounds (drawable->drawable_id, &x1, &y1, &x2, &y2);
1997-11-25 06:05:25 +08:00
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);
/* Initialize progress */
progress = 0;
max_progress = (x2 - x1) * (y2 - y1);
bpp = drawable->bpp;
has_alpha = gimp_drawable_has_alpha (drawable->drawable_id);
1997-11-25 06:05:25 +08:00
area.width = (tile_width / pixelwidth) * pixelwidth;
area.height = (tile_height / pixelheight) * pixelheight;
area.data= g_new (guchar, (glong) bpp * area.width * area.height);
1997-11-25 06:05:25 +08:00
for (area.y = y1; area.y < y2;
area.y += area.height - (area.y % area.height))
1997-11-25 06:05:25 +08:00
{
area.h = area.height - (area.y % area.height);
area.h = MIN (area.h, y2 - area.y);
for (area.x = x1; area.x < x2;
area.x += area.width - (area.x % area.width))
1997-11-25 06:05:25 +08:00
{
area.w = area.width - (area.x % area.width);
area.w = MIN(area.w, x2 - area.x);
1997-11-25 06:05:25 +08:00
gimp_pixel_rgn_get_rect (&src_rgn, area.data,
area.x, area.y, area.w, area.h);
1997-11-25 06:05:25 +08:00
pixelize_sub (pixelwidth, pixelheight, bpp, has_alpha);
1997-11-25 06:05:25 +08:00
gimp_pixel_rgn_set_rect (&dest_rgn, area.data,
area.x, area.y, area.w, area.h);
1997-11-25 06:05:25 +08:00
/* Update progress */
progress += area.w * area.h;
gimp_progress_update ((double) progress / (double) max_progress);
}
}
g_free(area.data);
1997-11-25 06:05:25 +08:00
/* update the pixelized 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));
1997-11-25 06:05:25 +08:00
}
/*
This function acts on one PixelArea. Since there were so many
nested FORs in pixelize_small(), I put a few of them here...
*/
static void
pixelize_sub (gint pixelwidth,
gint pixelheight,
gint bpp,
gint has_alpha)
1997-11-25 06:05:25 +08:00
{
gulong average[4]; /* bpp <= 4 */
1997-11-25 06:05:25 +08:00
gint x, y, w, h;
guchar *buf_row, *buf;
gint row, col;
gint rowstride;
gint count;
gint i;
rowstride = area.w * bpp;
for (y = area.y; y < area.y + area.h; y += pixelheight - (y % pixelheight))
1997-11-25 06:05:25 +08:00
{
h = pixelheight - (y % pixelheight);
h = MIN (h, area.y + area.h - y);
for (x = area.x; x < area.x + area.w; x += pixelwidth - (x % pixelwidth))
1997-11-25 06:05:25 +08:00
{
w = pixelwidth - (x % pixelwidth);
w = MIN (w, area.x + area.w - x);
1997-11-25 06:05:25 +08:00
for (i = 0; i < bpp; i++)
1997-11-25 06:05:25 +08:00
average[i] = 0;
count = 0;
/* Read */
buf_row = area.data + (y-area.y)*rowstride + (x-area.x)*bpp;
for (row = 0; row < h; row++)
1997-11-25 06:05:25 +08:00
{
buf = buf_row;
if (has_alpha)
{
for (col = 0; col < w; col++)
{
gulong alpha = buf[bpp-1];
average[bpp-1] += alpha;
for (i = 0; i < bpp-1; i++)
average[i] += buf[i] * alpha;
buf += bpp;
}
}
else
{
for (col = 0; col < w; col++)
{
for (i = 0; i < bpp; i++)
average[i] += buf[i];
buf += bpp;
}
}
1997-11-25 06:05:25 +08:00
buf_row += rowstride;
}
count += w*h;
1997-11-25 06:05:25 +08:00
/* Average */
if (count > 0)
{
if (has_alpha)
{
gulong alpha = average[bpp-1];
if (average[bpp-1] = alpha/count)
{
for (i = 0; i < bpp-1; i++)
average[i] /= alpha;
}
}
else
{
for (i = 0; i < bpp; i++)
average[i] /= count;
}
1997-11-25 06:05:25 +08:00
}
/* Write */
buf_row = area.data + (y-area.y)*rowstride + (x-area.x)*bpp;
for (row = 0; row < h; row++)
1997-11-25 06:05:25 +08:00
{
buf = buf_row;
for (col = 0; col < w; col++)
1997-11-25 06:05:25 +08:00
{
for (i = 0; i < bpp; i++)
1997-11-25 06:05:25 +08:00
buf[i] = average[i];
count++;
buf += bpp;
}
buf_row += rowstride;
}
}
}
}