1998-05-01 07:42:31 +08:00
/****************************************************************************
* This is a plugin for the GIMP v 0.99 .8 or later . Documentation is
* available at http : //www.rru.com/~meo/gimp/ .
*
1998-07-03 02:06:30 +08:00
* Copyright ( C ) 1997 - 98 Miles O ' Neal < meo @ rru . com > http : //www.rru.com/~meo/
1998-05-01 07:42:31 +08:00
* Blur code Copyright ( C ) 1995 Spencer Kimball and Peter Mattis
* GUI based on GTK code from :
* alienmap ( Copyright ( C ) 1996 , 1997 Daniel Cotting )
* plasma ( Copyright ( C ) 1996 Stephen Norris ) ,
* oilify ( Copyright ( C ) 1996 Torsten Martinsen ) ,
* ripple ( Copyright ( C ) 1997 Brian Degenhardt ) and
* whirl ( Copyright ( C ) 1997 Federico Mena Quintero ) .
1997-11-25 06:05:25 +08:00
*
* 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
1998-04-13 13:44:11 +08:00
* Foundation , Inc . , 59 Temple Place - Suite 330 , Boston , MA 02111 - 1307 , USA .
1998-05-01 07:42:31 +08:00
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/****************************************************************************
* Blur :
*
1998-07-03 02:06:30 +08:00
* blur version 2.0 ( 1 May 1998 , MEO )
1998-05-01 07:42:31 +08:00
* history
1998-07-03 02:06:30 +08:00
* 2.0 - 1 May 1998 MEO
* based on randomize 1.7
1998-05-01 07:42:31 +08:00
*
* Please send any patches or suggestions to the author : meo @ rru . com .
*
* Blur applies a 3 x3 blurring convolution kernel to the specified drawable .
*
* For each pixel in the selection or image ,
* whether to change the pixel is decided by picking a
* random number , weighted by the user ' s " randomization " percentage .
* If the random number is in range , the pixel is modified . For
* blurring , an average is determined from the current and adjacent
* pixels . * ( Except for the random factor , the blur code came
* straight from the original S & P blur plug - in . ) *
*
* This works only with RGB and grayscale images .
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2000-01-11 23:48:00 +08:00
# ifdef HAVE_CONFIG_H
# include "config.h"
# endif
1998-06-09 19:41:13 +08:00
# include <stdio.h>
1997-11-25 06:05:25 +08:00
# include <stdlib.h>
1999-05-29 09:28:24 +08:00
# include <string.h>
1998-05-01 07:42:31 +08:00
# include <time.h>
2000-01-11 23:48:00 +08:00
# include <gtk/gtk.h>
# include <libgimp/gimp.h>
# include <libgimp/gimpui.h>
1999-05-30 00:35:47 +08:00
# include "libgimp/stdplugins-intl.h"
1998-05-01 07:42:31 +08:00
/*********************************
*
* PLUGIN - SPECIFIC CONSTANTS
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
1997-11-25 06:05:25 +08:00
1998-05-01 07:42:31 +08:00
/*
* progress meter update frequency
1997-11-25 06:05:25 +08:00
*/
1998-05-01 07:42:31 +08:00
# define PROG_UPDATE_TIME ((row % 10) == 0)
1997-11-25 06:05:25 +08:00
1998-05-01 07:42:31 +08:00
# define PLUG_IN_NAME "plug_in_blur"
1997-11-25 06:05:25 +08:00
configure.in app/core/gimpbrushpipe.c app/gui/about-dialog.c
2002-11-20 Dave Neary <bolsh@gimp.org>
* configure.in
* app/core/gimpbrushpipe.c
* app/gui/about-dialog.c
* app/paint-funcs/paint-funcs-generic.h
* app/paint-funcs/paint-funcs.c
* libgimpmath/gimpmath.h
* libgimpwidgets/gimpwidgets.c
* plug-ins/common/CML_explorer.c
* plug-ins/common/blur.c
* plug-ins/common/cubism.c
* plug-ins/common/gee.c
* plug-ins/common/gee_zoom.c
* plug-ins/common/gqbist.c
* plug-ins/common/jigsaw.c
* plug-ins/common/lic.c
* plug-ins/common/noisify.c
* plug-ins/common/nova.c
* plug-ins/common/papertile.c
* plug-ins/common/plasma.c
* plug-ins/common/randomize.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/smooth_palette.c
* plug-ins/common/snoise.c
* plug-ins/common/sparkle.c
* plug-ins/common/spheredesigner.c
* plug-ins/common/spread.c
* plug-ins/common/warp.c
* plug-ins/common/wind.c
* plug-ins/flame/cmap.c
* plug-ins/flame/flame.c
* plug-ins/flame/libifs.c
* plug-ins/gflare/gflare.c
* plug-ins/gimpressionist/gimpressionist.c
* plug-ins/gimpressionist/gimpressionist.h
* plug-ins/gimpressionist/plasma.c
* plug-ins/gimpressionist/repaint.c
* plug-ins/ifscompose/ifscompose_utils.c
* plug-ins/maze/algorithms.c
* plug-ins/maze/maze.c
* plug-ins/maze/maze.h
* plug-ins/mosaic/mosaic.c: Change all occurrences of RAND_MAX,
G_MAXRAND, rand(), srand(), lrand48(), srand48(), random(),
srandom(), RAND_FUNC and SRAND_FUNC to the appropriate g_rand*
equivalent. Programs which require seed setting for reproducible
results, and anything in the core, gets a dedicated GRand * for
the lifetime required. Programs which only ever used random
numbers for tossing a coin, rolling a dice, etc use g_random
functions. For the rest, judgement was used. Where it was easy, a
GRand * object was used and g_rand_* functions were
preferred. This fixes bug #67386 in HEAD.
2002-11-20 17:27:48 +08:00
# define SEED_DEFAULT 10
1998-05-01 07:42:31 +08:00
# define SEED_USER 11
1997-11-25 06:05:25 +08:00
1998-05-01 07:42:31 +08:00
# define SCALE_WIDTH 100
/*********************************
*
* PLUGIN - SPECIFIC STRUCTURES AND DATA
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2000-01-12 01:41:07 +08:00
typedef struct
{
gdouble blur_pct ; /* likelihood of randomization (as %age) */
gdouble blur_rcount ; /* repeat count */
2003-07-03 21:26:06 +08:00
guint blur_seed ; /* seed value for g_random_set_seed() function */
1998-05-01 07:42:31 +08:00
} BlurVals ;
2000-01-12 01:41:07 +08:00
static BlurVals pivals =
{
100.0 ,
1.0 ,
0 ,
1998-05-01 07:42:31 +08:00
} ;
2000-01-12 01:41:07 +08:00
typedef struct
{
2003-07-02 02:54:28 +08:00
gboolean run ;
1998-05-01 07:42:31 +08:00
} BlurInterface ;
2000-01-12 01:41:07 +08:00
static BlurInterface blur_int =
{
FALSE /* have we run? */
1997-11-25 06:05:25 +08:00
} ;
1998-05-01 07:42:31 +08:00
/*********************************
*
* LOCAL FUNCTIONS
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2000-01-11 23:48:00 +08:00
static void query ( void ) ;
2003-07-02 02:54:28 +08:00
static void run ( const gchar * name ,
gint nparams ,
const GimpParam * param ,
gint * nreturn_vals ,
GimpParam * * return_vals ) ;
2000-01-11 23:48:00 +08:00
2000-08-22 09:26:57 +08:00
GimpPlugInInfo PLUG_IN_INFO =
2000-01-11 23:48:00 +08:00
{
2000-02-05 06:18:50 +08:00
NULL , /* init_proc */
NULL , /* quit_proc */
query , /* query_proc */
run , /* run_proc */
1998-05-01 07:42:31 +08:00
} ;
2000-08-22 09:26:57 +08:00
static void blur ( GimpDrawable * drawable ) ;
1998-05-01 07:42:31 +08:00
2000-08-22 09:26:57 +08:00
static inline void blur_prepare_row ( GimpPixelRgn * pixel_rgn ,
2003-05-17 08:44:56 +08:00
guchar * data ,
gint x ,
gint y ,
gint w ) ;
1998-05-01 07:42:31 +08:00
2000-01-26 01:46:56 +08:00
static gint blur_dialog ( void ) ;
static void blur_ok_callback ( GtkWidget * widget ,
gpointer data ) ;
1998-05-01 07:42:31 +08:00
/************************************ Guts ***********************************/
2000-01-11 23:48:00 +08:00
MAIN ( )
1998-05-01 07:42:31 +08:00
/*********************************
*
* query ( ) - query_proc
*
* called by the GIMP to learn about this plug - in
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
1997-11-25 06:05:25 +08:00
static void
2000-01-11 23:48:00 +08:00
query ( void )
1997-11-25 06:05:25 +08:00
{
2000-08-22 09:26:57 +08:00
static GimpParamDef args_ni [ ] =
2000-01-11 23:48:00 +08:00
{
2000-08-22 09:26:57 +08:00
{ GIMP_PDB_INT32 , " run_mode " , " non-interactive " } ,
{ GIMP_PDB_IMAGE , " image " , " Input image (unused) " } ,
{ GIMP_PDB_DRAWABLE , " drawable " , " Input drawable " }
2000-01-11 23:48:00 +08:00
} ;
2000-08-22 09:26:57 +08:00
static GimpParamDef args [ ] =
2000-01-11 23:48:00 +08:00
{
2000-08-22 09:26:57 +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_FLOAT , " blur_pct " , " Randomization percentage (1 - 100) " } ,
{ GIMP_PDB_FLOAT , " blur_rcount " , " Repeat count(1 - 100) " } ,
{ GIMP_PDB_INT32 , " blur_seed " , " Seed value (used only if seed type is 11) " }
2000-01-11 23:48:00 +08:00
} ;
2000-01-31 10:32:30 +08:00
const gchar * blurb = " Apply a 3x3 blurring convolution kernel to the specified drawable. " ;
const gchar * help = " This plug-in randomly blurs the specified drawable, using a 3x3 blur. You control the percentage of the pixels that are blurred and the number of times blurring is applied. Indexed images are not supported. " ;
2000-01-26 01:46:56 +08:00
const gchar * author = " Miles O'Neal <meo@rru.com> http://www.rru.com/~meo/ " ;
const gchar * copyrights = " Miles O'Neal, Spencer Kimball, Peter Mattis, Torsten Martinsen, Brian Degenhardt, Federico Mena Quintero, Stephen Norris, Daniel Cotting " ;
const gchar * copyright_date = " 1995-1998 " ;
2000-01-11 23:48:00 +08:00
gimp_install_procedure ( " plug_in_blur_randomize " ,
2000-01-26 01:46:56 +08:00
( gchar * ) blurb ,
( gchar * ) help ,
( gchar * ) author ,
( gchar * ) copyrights ,
( gchar * ) copyright_date ,
2003-07-17 23:47:18 +08:00
N_ ( " <Image>/Filters/Blur/_Blur... " ) ,
2000-01-11 23:48:00 +08:00
" RGB*, GRAY* " ,
2000-08-22 09:26:57 +08:00
GIMP_PLUGIN ,
2001-12-06 10:28:58 +08:00
G_N_ELEMENTS ( args ) , 0 ,
2000-02-05 06:18:50 +08:00
args , NULL ) ;
2000-01-11 23:48:00 +08:00
gimp_install_procedure ( PLUG_IN_NAME ,
2000-01-26 01:46:56 +08:00
( gchar * ) blurb ,
( gchar * ) help ,
( gchar * ) author ,
( gchar * ) copyrights ,
( gchar * ) copyright_date ,
2000-01-11 23:48:00 +08:00
NULL ,
" RGB*, GRAY* " ,
2000-08-22 09:26:57 +08:00
GIMP_PLUGIN ,
2001-12-06 10:28:58 +08:00
G_N_ELEMENTS ( args_ni ) , 0 ,
2000-02-05 06:18:50 +08:00
args_ni , NULL ) ;
1997-11-25 06:05:25 +08:00
}
1998-05-01 07:42:31 +08:00
/*********************************
*
* run ( ) - main routine
*
* This handles the main interaction with the GIMP itself ,
* and invokes the routine that actually does the work .
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
1997-11-25 06:05:25 +08:00
static void
2003-07-02 02:54:28 +08:00
run ( const gchar * name ,
gint nparams ,
const GimpParam * param ,
gint * nreturn_vals ,
GimpParam * * return_vals )
1997-11-25 06:05:25 +08:00
{
2003-05-17 08:44:56 +08:00
GimpDrawable * drawable ;
GimpRunMode run_mode ;
GimpPDBStatusType status = GIMP_PDB_SUCCESS ; /* assume the best! */
static GimpParam values [ 1 ] ;
2000-01-11 23:48:00 +08:00
2003-03-26 00:38:19 +08:00
INIT_I18N ( ) ;
2000-01-11 23:48:00 +08:00
/*
* Get the specified drawable , do standard initialization .
*/
run_mode = param [ 0 ] . data . d_int32 ;
2003-05-17 08:44:56 +08:00
drawable = gimp_drawable_get ( param [ 2 ] . data . d_drawable ) ;
2000-01-11 23:48:00 +08:00
2000-08-22 09:26:57 +08:00
values [ 0 ] . type = GIMP_PDB_STATUS ;
2000-01-11 23:48:00 +08:00
values [ 0 ] . data . d_status = status ;
* nreturn_vals = 1 ;
* return_vals = values ;
2002-11-25 03:26:58 +08:00
2000-01-11 23:48:00 +08:00
/*
* Make sure the drawable type is appropriate .
*/
2001-06-15 04:07:38 +08:00
if ( gimp_drawable_is_rgb ( drawable - > drawable_id ) | |
gimp_drawable_is_gray ( drawable - > drawable_id ) )
2000-01-11 23:48:00 +08:00
{
switch ( run_mode )
{
/*
* If we ' re running interactively , pop up the dialog box .
*/
2000-08-22 09:26:57 +08:00
case GIMP_RUN_INTERACTIVE :
2000-05-01 05:03:44 +08:00
gimp_get_data ( PLUG_IN_NAME , & pivals ) ;
if ( ! blur_dialog ( ) ) /* return on Cancel */
2000-01-11 23:48:00 +08:00
return ;
break ;
/*
* If we ' re not interactive ( probably scripting ) , we
* get the parameters from the param [ ] array , since
* we don ' t use the dialog box . Make sure all
* parameters have legitimate values .
*/
2000-08-22 09:26:57 +08:00
case GIMP_RUN_NONINTERACTIVE :
2000-01-26 01:46:56 +08:00
if ( ( strcmp ( name , " plug_in_blur_randomize " ) = = 0 ) & &
2000-01-11 23:48:00 +08:00
( nparams = = 7 ) )
{
2000-01-26 01:46:56 +08:00
pivals . blur_pct = ( gdouble ) param [ 3 ] . data . d_float ;
pivals . blur_pct = ( gdouble ) MIN ( 100.0 , pivals . blur_pct ) ;
pivals . blur_pct = ( gdouble ) MAX ( 1.0 , pivals . blur_pct ) ;
pivals . blur_rcount = ( gdouble ) param [ 4 ] . data . d_float ;
pivals . blur_rcount = ( gdouble ) MIN ( 100.0 , pivals . blur_rcount ) ;
pivals . blur_rcount = ( gdouble ) MAX ( 1.0 , pivals . blur_rcount ) ;
2000-01-16 23:38:38 +08:00
pivals . blur_seed = ( gint ) param [ 6 ] . data . d_int32 ;
2000-01-11 23:48:00 +08:00
}
2000-01-26 01:46:56 +08:00
else if ( ( strcmp ( name , PLUG_IN_NAME ) = = 0 ) & &
2000-01-11 23:48:00 +08:00
( nparams = = 3 ) )
{
2000-01-16 23:38:38 +08:00
pivals . blur_pct = ( gdouble ) 100.0 ;
2000-01-11 23:48:00 +08:00
pivals . blur_rcount = ( gdouble ) 1.0 ;
2002-11-25 03:26:58 +08:00
pivals . blur_seed = g_random_int ( ) ;
2000-01-11 23:48:00 +08:00
}
else
{
2000-08-22 09:26:57 +08:00
status = GIMP_PDB_CALLING_ERROR ;
2000-01-11 23:48:00 +08:00
}
break ;
/*
* If we ' re running with the last set of values , get those values .
*/
2000-08-22 09:26:57 +08:00
case GIMP_RUN_WITH_LAST_VALS :
2000-01-26 01:46:56 +08:00
gimp_get_data ( PLUG_IN_NAME , & pivals ) ;
2000-01-11 23:48:00 +08:00
break ;
/*
* Hopefully we never get here !
*/
default :
break ;
1998-05-01 07:42:31 +08:00
}
2000-02-05 06:18:50 +08:00
2000-08-22 09:26:57 +08:00
if ( status = = GIMP_PDB_SUCCESS )
2000-01-11 23:48:00 +08:00
{
/*
* JUST DO IT !
*/
2002-06-19 17:48:41 +08:00
gimp_progress_init ( _ ( " Blurring... " ) ) ;
2003-05-17 08:44:56 +08:00
gimp_tile_cache_ntiles ( 2 * ( drawable - > width / gimp_tile_width ( )
+ 1 ) ) ;
2000-01-11 23:48:00 +08:00
/*
* Initialize the rand ( ) function seed
*/
2002-11-25 03:26:58 +08:00
g_random_set_seed ( pivals . blur_seed ) ;
2000-01-26 01:46:56 +08:00
blur ( drawable ) ;
2000-01-11 23:48:00 +08:00
/*
* If we ran interactively ( even repeating ) update the display .
*/
2000-08-22 09:26:57 +08:00
if ( run_mode ! = GIMP_RUN_NONINTERACTIVE )
2000-01-11 23:48:00 +08:00
{
2000-01-26 01:46:56 +08:00
gimp_displays_flush ( ) ;
1998-05-01 07:42:31 +08:00
}
2000-01-11 23:48:00 +08:00
/*
* If we use the dialog popup , set the data for future use .
*/
2000-08-22 09:26:57 +08:00
if ( run_mode = = GIMP_RUN_INTERACTIVE )
2000-01-11 23:48:00 +08:00
{
2000-01-26 01:46:56 +08:00
gimp_set_data ( PLUG_IN_NAME , & pivals , sizeof ( BlurVals ) ) ;
1998-05-01 07:42:31 +08:00
}
}
1997-11-25 06:05:25 +08:00
}
2000-01-11 23:48:00 +08:00
else
{
/*
* If we got the wrong drawable type , we need to complain .
*/
2000-08-22 09:26:57 +08:00
status = GIMP_PDB_EXECUTION_ERROR ;
2000-01-11 23:48:00 +08:00
}
/*
* DONE !
* Set the status where the GIMP can see it , and let go
* of the drawable .
*/
values [ 0 ] . data . d_status = status ;
2000-01-26 01:46:56 +08:00
gimp_drawable_detach ( drawable ) ;
2002-11-25 03:26:58 +08:00
1998-05-01 07:42:31 +08:00
}
1997-11-25 06:05:25 +08:00
1998-05-01 07:42:31 +08:00
/*********************************
*
* blur_prepare_row ( )
*
* Get a row of pixels . If the requested row
* is off the edge , clone the edge row .
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
1997-11-25 06:05:25 +08:00
1998-05-01 07:42:31 +08:00
static inline void
2000-08-22 09:26:57 +08:00
blur_prepare_row ( GimpPixelRgn * pixel_rgn ,
1999-11-24 04:29:20 +08:00
guchar * data ,
2002-06-19 17:48:41 +08:00
gint x ,
gint y ,
gint w )
1998-05-01 07:42:31 +08:00
{
2000-01-11 23:48:00 +08:00
int b ;
1997-11-25 06:05:25 +08:00
2002-06-19 17:48:41 +08:00
y = CLAMP ( y , 1 , pixel_rgn - > h - 1 ) ;
gimp_pixel_rgn_get_row ( pixel_rgn , data , x , y , w ) ;
2000-01-11 23:48:00 +08:00
/*
* Fill in edge pixels
*/
for ( b = 0 ; b < pixel_rgn - > bpp ; b + + )
{
data [ - ( gint ) pixel_rgn - > bpp + b ] = data [ b ] ;
data [ w * pixel_rgn - > bpp + b ] = data [ ( w - 1 ) * pixel_rgn - > bpp + b ] ;
1998-05-01 07:42:31 +08:00
}
1997-11-25 06:05:25 +08:00
}
1998-05-01 07:42:31 +08:00
/*********************************
*
* blur ( )
*
* Actually mess with the image .
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
1997-11-25 06:05:25 +08:00
static void
2000-08-22 09:26:57 +08:00
blur ( GimpDrawable * drawable )
1997-11-25 06:05:25 +08:00
{
2003-05-17 08:44:56 +08:00
GimpPixelRgn srcPR , destPR , destPR2 , * sp , * dp , * tp ;
gint width , height ;
gint bytes ;
guchar * dest , * d ;
guchar * prev_row , * pr ;
guchar * cur_row , * cr ;
guchar * next_row , * nr ;
guchar * tmp ;
gint row , col ;
gint x1 , y1 , x2 , y2 ;
gint cnt , ind ;
gint repeat_count ;
gboolean has_alpha ;
2000-01-11 23:48:00 +08:00
/*
* Get the input area . This is the bounding box of the selection in
* the image ( or the entire image if there is no selection ) . Only
* operating on the input area is simply an optimization . It doesn ' t
* need to be done for correct operation . ( It simply makes it go
* faster , since fewer pixels need to be operated on ) .
*/
2003-05-17 08:44:56 +08:00
gimp_drawable_mask_bounds ( drawable - > drawable_id , & x1 , & y1 , & x2 , & y2 ) ;
2000-01-11 23:48:00 +08:00
/*
* Get the size of the input image . ( This will / must be the same
* as the size of the output image . Also get alpha info .
*/
width = drawable - > width ;
height = drawable - > height ;
bytes = drawable - > bpp ;
2003-05-17 08:44:56 +08:00
has_alpha = gimp_drawable_has_alpha ( drawable - > drawable_id ) ;
2000-01-11 23:48:00 +08:00
/*
* allocate row buffers
*/
2000-01-12 01:41:07 +08:00
prev_row = g_new ( guchar , ( x2 - x1 + 2 ) * bytes ) ;
2000-02-05 06:18:50 +08:00
cur_row = g_new ( guchar , ( x2 - x1 + 2 ) * bytes ) ;
2000-01-12 01:41:07 +08:00
next_row = g_new ( guchar , ( x2 - x1 + 2 ) * bytes ) ;
2000-02-05 06:18:50 +08:00
dest = g_new ( guchar , ( x2 - x1 ) * bytes ) ;
2000-01-11 23:48:00 +08:00
/*
* initialize the pixel regions
*/
2000-02-05 06:18:50 +08:00
gimp_pixel_rgn_init ( & srcPR , drawable , 0 , 0 , width , height , FALSE , FALSE ) ;
gimp_pixel_rgn_init ( & destPR , drawable , 0 , 0 , width , height , TRUE , TRUE ) ;
gimp_pixel_rgn_init ( & destPR2 , drawable , 0 , 0 , width , height , TRUE , TRUE ) ;
2000-01-11 23:48:00 +08:00
sp = & srcPR ;
dp = & destPR ;
tp = NULL ;
pr = prev_row + bytes ;
cr = cur_row + bytes ;
nr = next_row + bytes ;
2003-05-17 08:44:56 +08:00
repeat_count = ( gint ) pivals . blur_rcount ;
for ( cnt = 1 ; cnt < = repeat_count ; cnt + + )
2000-01-11 23:48:00 +08:00
{
/*
* prepare the first row and previous row
*/
2003-05-17 08:44:56 +08:00
blur_prepare_row ( sp , pr , x1 , y1 - 1 , ( x2 - x1 ) ) ;
blur_prepare_row ( dp , cr , x1 , y1 , ( x2 - x1 ) ) ;
2000-01-11 23:48:00 +08:00
/*
* loop through the rows , applying the selected convolution
*/
for ( row = y1 ; row < y2 ; row + + )
{
/* prepare the next row */
2003-05-17 08:44:56 +08:00
blur_prepare_row ( sp , nr , x1 , row + 1 , ( x2 - x1 ) ) ;
2000-01-11 23:48:00 +08:00
d = dest ;
ind = 0 ;
for ( col = 0 ; col < ( x2 - x1 ) * bytes ; col + + )
{
2002-11-25 03:26:58 +08:00
if ( g_random_int_range ( 0 , 100 ) < = ( gint ) pivals . blur_pct )
2000-01-11 23:48:00 +08:00
{
ind + + ;
2002-06-19 17:48:41 +08:00
if ( ind = = bytes | | ! has_alpha )
2000-01-11 23:48:00 +08:00
{
/*
* If no alpha channel ,
* or if there is one and this is it . . .
*/
* d + + = ( ( gint ) pr [ col - bytes ] + ( gint ) pr [ col ] +
( gint ) pr [ col + bytes ] +
( gint ) cr [ col - bytes ] + ( gint ) cr [ col ] +
( gint ) cr [ col + bytes ] +
( gint ) nr [ col - bytes ] + ( gint ) nr [ col ] +
( gint ) nr [ col + bytes ] ) / 9 ;
ind = 0 ;
}
else
{
/*
* otherwise we have an alpha channel ,
* but this is a color channel
*/
* d + + = ( ( gint )
( ( ( gdouble ) ( pr [ col - bytes ] * pr [ col - ind ] )
+ ( gdouble ) ( pr [ col ] * pr [ col + bytes - ind ] )
+ ( gdouble ) ( pr [ col + bytes ] * pr [ col + 2 * bytes - ind ] )
+ ( gdouble ) ( cr [ col - bytes ] * cr [ col - ind ] )
+ ( gdouble ) ( cr [ col ] * cr [ col + bytes - ind ] )
+ ( gdouble ) ( cr [ col + bytes ] * cr [ col + 2 * bytes - ind ] )
+ ( gdouble ) ( nr [ col - bytes ] * nr [ col - ind ] )
+ ( gdouble ) ( nr [ col ] * nr [ col + bytes - ind ] )
+ ( gdouble ) ( nr [ col + bytes ] * nr [ col + 2 * bytes - ind ] ) )
1998-05-01 07:42:31 +08:00
/ ( ( gdouble ) pr [ col - ind ]
2000-01-11 23:48:00 +08:00
+ ( gdouble ) pr [ col + bytes - ind ]
+ ( gdouble ) pr [ col + 2 * bytes - ind ]
+ ( gdouble ) cr [ col - ind ]
+ ( gdouble ) cr [ col + bytes - ind ]
+ ( gdouble ) cr [ col + 2 * bytes - ind ]
+ ( gdouble ) nr [ col - ind ]
+ ( gdouble ) nr [ col + bytes - ind ]
+ ( gdouble ) nr [ col + 2 * bytes - ind ] ) ) ) ;
1998-05-01 07:42:31 +08:00
}
2000-01-11 23:48:00 +08:00
/*
* Otherwise , this pixel was not selected for randomization ,
* so use the current value .
*/
}
else
{
* d + + = ( gint ) cr [ col ] ;
1998-05-01 07:42:31 +08:00
}
}
2000-01-11 23:48:00 +08:00
/*
* Save the modified row , shuffle the row pointers , and every
* so often , update the progress meter .
*/
2003-05-17 08:44:56 +08:00
gimp_pixel_rgn_set_row ( dp , dest , x1 , row , ( x2 - x1 ) ) ;
2000-01-11 23:48:00 +08:00
tmp = pr ;
pr = cr ;
cr = nr ;
nr = tmp ;
if ( PROG_UPDATE_TIME )
2003-05-17 08:44:56 +08:00
gimp_progress_update ( ( double ) row / ( double ) ( y2 - y1 ) ) ;
1998-05-01 07:42:31 +08:00
}
2000-01-11 23:48:00 +08:00
/*
* if we have more cycles to perform , swap the src and dest Pixel Regions
*/
2003-05-17 08:44:56 +08:00
if ( cnt < repeat_count )
2000-01-11 23:48:00 +08:00
{
if ( tp ! = NULL )
{
tp = dp ;
dp = sp ;
sp = tp ;
}
else
{
tp = & srcPR ;
sp = & destPR ;
dp = & destPR2 ;
1998-05-01 07:42:31 +08:00
}
}
1997-11-25 06:05:25 +08:00
}
2000-01-26 01:46:56 +08:00
gimp_progress_update ( ( double ) 100 ) ;
2000-01-11 23:48:00 +08:00
/*
* update the blurred region
*/
2003-05-17 08:44:56 +08:00
gimp_drawable_flush ( drawable ) ;
gimp_drawable_merge_shadow ( drawable - > drawable_id , TRUE ) ;
gimp_drawable_update ( drawable - > drawable_id , x1 , y1 , ( x2 - x1 ) , ( y2 - y1 ) ) ;
2000-01-11 23:48:00 +08:00
/*
* clean up after ourselves .
*/
2000-01-12 01:41:07 +08:00
g_free ( prev_row ) ;
g_free ( cur_row ) ;
g_free ( next_row ) ;
g_free ( dest ) ;
1997-11-25 06:05:25 +08:00
}
1998-05-01 07:42:31 +08:00
/*********************************
* GUI ROUTINES
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static gint
2000-01-11 23:48:00 +08:00
blur_dialog ( void )
1997-11-25 06:05:25 +08:00
{
2000-01-11 23:48:00 +08:00
GtkWidget * dlg ;
GtkWidget * table ;
2002-06-01 23:32:03 +08:00
GtkWidget * label ;
2000-01-26 01:46:56 +08:00
GtkWidget * seed_hbox ;
2000-01-16 23:38:38 +08:00
GtkObject * adj ;
2000-01-11 23:48:00 +08:00
2000-05-01 05:03:44 +08:00
gimp_ui_init ( " blur " , FALSE ) ;
2000-01-11 23:48:00 +08:00
2003-08-17 02:22:08 +08:00
dlg = gimp_dialog_new ( _ ( " Blur " ) , " blur " ,
2000-05-23 01:10:28 +08:00
gimp_standard_help_func , " filters/blur.html " ,
2000-01-11 23:48:00 +08:00
GTK_WIN_POS_MOUSE ,
FALSE , TRUE , FALSE ,
2001-08-04 03:52:08 +08:00
GTK_STOCK_CANCEL , gtk_widget_destroy ,
2000-01-11 23:48:00 +08:00
NULL , 1 , NULL , FALSE , TRUE ,
2001-11-29 21:23:44 +08:00
GTK_STOCK_OK , blur_ok_callback ,
NULL , NULL , NULL , TRUE , FALSE ,
2000-01-11 23:48:00 +08:00
NULL ) ;
2003-01-07 14:16:02 +08:00
g_signal_connect ( dlg , " destroy " ,
2001-12-29 21:26:29 +08:00
G_CALLBACK ( gtk_main_quit ) ,
NULL ) ;
2000-01-26 01:46:56 +08:00
2000-01-11 23:48:00 +08:00
/*
* Parameter settings
*
* First set up the basic containers , label them , etc .
*/
2003-09-14 02:07:44 +08:00
table = gimp_parameter_settings_new ( GTK_DIALOG ( dlg ) - > vbox , 3 , 3 ) ;
2000-01-11 23:48:00 +08:00
2000-01-26 01:46:56 +08:00
/* Random Seed */
2002-11-25 03:26:58 +08:00
seed_hbox = gimp_random_seed_new ( & pivals . blur_seed ) ;
2002-06-01 23:32:03 +08:00
label = gimp_table_attach_aligned ( GTK_TABLE ( table ) , 0 , 0 ,
_ ( " _Random Seed: " ) , 1.0 , 0.5 ,
seed_hbox , 1 , TRUE ) ;
gtk_label_set_mnemonic_widget ( GTK_LABEL ( label ) ,
GIMP_RANDOM_SEED_SPINBUTTON ( seed_hbox ) ) ;
2000-01-16 23:38:38 +08:00
2000-01-11 23:48:00 +08:00
/*
* Randomization percentage label & scale ( 1 to 100 )
*/
2000-01-26 01:46:56 +08:00
adj = gimp_scale_entry_new ( GTK_TABLE ( table ) , 0 , 1 ,
2002-06-01 23:32:03 +08:00
_ ( " R_andomization %: " ) , SCALE_WIDTH , 0 ,
2000-01-16 23:38:38 +08:00
pivals . blur_pct , 1.0 , 100.0 , 1.0 , 10.0 , 0 ,
2000-02-04 23:12:17 +08:00
TRUE , 0 , 0 ,
2000-01-16 23:38:38 +08:00
_ ( " Percentage of pixels to be filtered " ) , NULL ) ;
2003-01-07 14:16:02 +08:00
g_signal_connect ( adj , " value_changed " ,
2001-12-29 21:26:29 +08:00
G_CALLBACK ( gimp_double_adjustment_update ) ,
& pivals . blur_pct ) ;
2000-01-16 23:38:38 +08:00
2000-01-11 23:48:00 +08:00
/*
* Repeat count label & scale ( 1 to 100 )
*/
2000-01-26 01:46:56 +08:00
adj = gimp_scale_entry_new ( GTK_TABLE ( table ) , 0 , 2 ,
2002-06-01 23:32:03 +08:00
_ ( " R_epeat: " ) , SCALE_WIDTH , 0 ,
2000-01-16 23:38:38 +08:00
pivals . blur_rcount , 1.0 , 100.0 , 1.0 , 10.0 , 0 ,
2000-02-04 23:12:17 +08:00
TRUE , 0 , 0 ,
2000-01-16 23:38:38 +08:00
_ ( " Number of times to apply filter " ) , NULL ) ;
2003-01-07 14:16:02 +08:00
g_signal_connect ( adj , " value_changed " ,
2001-12-29 21:26:29 +08:00
G_CALLBACK ( gimp_double_adjustment_update ) ,
& pivals . blur_rcount ) ;
2000-01-16 23:38:38 +08:00
2000-01-11 23:48:00 +08:00
gtk_widget_show ( dlg ) ;
gtk_main ( ) ;
gdk_flush ( ) ;
return blur_int . run ;
1998-05-01 07:42:31 +08:00
}
static void
1999-11-24 04:29:20 +08:00
blur_ok_callback ( GtkWidget * widget ,
gpointer data )
{
2000-01-11 23:48:00 +08:00
blur_int . run = TRUE ;
gtk_widget_destroy ( GTK_WIDGET ( data ) ) ;
1997-11-25 06:05:25 +08:00
}