1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/PTdecode/CImg-1.3.0/examples/greycstoration4gimp.cpp Mon Aug 03 14:09:20 2009 +0100 1.3 @@ -0,0 +1,649 @@ 1.4 +/* 1.5 + # 1.6 + # File : greycstoration4gimp.cpp 1.7 + # ( C++ source file ) 1.8 + # 1.9 + # Description : GREYCstoration - A tool to denoise, inpaint and resize images. 1.10 + # ( GIMP>=2.3.4 plug-in version ) 1.11 + # This file is a part of the CImg Library project. 1.12 + # ( http://cimg.sourceforge.net ) 1.13 + # 1.14 + # The GREYCstoration algorithm is an implementation of diffusion tensor-directed 1.15 + # diffusion PDE's for image regularization and interpolation, published in 1.16 + # 1.17 + # "Fast Anisotropic Smoothing of Multi-Valued Images 1.18 + # using Curvature-Preserving PDE's" 1.19 + # (D. Tschumperle) 1.20 + # International Journal of Computer Vision, May 2006. 1.21 + # (see also http://www.greyc.ensicaen.fr/~dtschump/greycstoration) 1.22 + # 1.23 + # "Vector-Valued Image Regularization with PDE's : A Common Framework 1.24 + # for Different Applications" 1.25 + # (D. Tschumperle, R. Deriche). 1.26 + # IEEE Transactions on Pattern Analysis and Machine Intelligence, 1.27 + # Vol 27, No 4, pp 506-517, April 2005. 1.28 + # 1.29 + # Copyright : Grzegorz Szwoch (Original GIMP plugin code) 1.30 + # David Tschumperle (GREYCstoration API) 1.31 + # Nikita Melnichenko (Bugs corrections) 1.32 + # Phillip Wood (Contribution) 1.33 + # 1.34 + # Plug-in version: 1.1 1.35 + # Version history: 1.36 + # 2008.12.05 1.37 + # - Support for denoising in YCrCb color space (patch by Phillip Wood) 1.38 + # 2.9 (2008.06.09) 1.39 + # - New version number, following the release number of CImg. 1.40 + # - Non-interactive mode allowed (patch by Nikita Melnichenko). 1.41 + # - Pdb description parameters re-ordered (patch by Nikita Melnichenko). 1.42 + # - Bug correction when dealing with 16 bits image processed in the 1.43 + # YUV color space. 1.44 + # 1.1 (2007.03.31) 1.45 + # - Added support for GimpZoomPreview (optional) 1.46 + # - Make plug-in work for 1 bpp images 1.47 + # - Added button to reset parameters to the initial state 1.48 + # 1.0 (2007.03.09) 1.49 + # - Initial release 1.50 + # 1.51 + # License : CeCILL v2.0 1.52 + # ( http://www.cecill.info/licences/Licence_CeCILL_V2-en.html ) 1.53 + # 1.54 + # This software is governed by the CeCILL license under French law and 1.55 + # abiding by the rules of distribution of free software. You can use, 1.56 + # modify and/ or redistribute the software under the terms of the CeCILL 1.57 + # license as circulated by CEA, CNRS and INRIA at the following URL 1.58 + # "http://www.cecill.info". 1.59 + # 1.60 + # As a counterpart to the access to the source code and rights to copy, 1.61 + # modify and redistribute granted by the license, users are provided only 1.62 + # with a limited warranty and the software's author, the holder of the 1.63 + # economic rights, and the successive licensors have only limited 1.64 + # liability. 1.65 + # 1.66 + # In this respect, the user's attention is drawn to the risks associated 1.67 + # with loading, using, modifying and/or developing or reproducing the 1.68 + # software by the user in light of its specific status of free software, 1.69 + # that may mean that it is complicated to manipulate, and that also 1.70 + # therefore means that it is reserved for developers and experienced 1.71 + # professionals having in-depth computer knowledge. Users are therefore 1.72 + # encouraged to load and test the software's suitability as regards their 1.73 + # requirements in conditions enabling the security of their systems and/or 1.74 + # data to be ensured and, more generally, to use and operate it in the 1.75 + # same conditions as regards security. 1.76 + # 1.77 + # The fact that you are presently reading this means that you have had 1.78 + # knowledge of the CeCILL license and that you accept its terms. 1.79 + # 1.80 +*/ 1.81 + 1.82 +/* HOW TO COMPILE THIS PLUG-IN ? 1.83 + *------------------------------ 1.84 + * g++ -o greycstoration4gimp greycstoration4gimp.cpp `gimptool-2.0 --cflags` `gimptool-2.0 --libs` -lpthread -O3 1.85 + * Then, copy the file 'greycstoration4gimp' into your GIMP plug-in directory. 1.86 + */ 1.87 + 1.88 +//---------------------------------- 1.89 +// Define static plug-in parameters 1.90 +//---------------------------------- 1.91 + 1.92 +// Comment the line below if you don't want to use preview with zoom (zoom feature needs GIMP >= 2.3.4) 1.93 +#define ZOOMPREVIEW 1.94 +// Uncomment this line to get a rough estimate of how long the plug-in takes to run 1.95 +// #define TIMER 1.96 + 1.97 +// Size of image tiles (in {0, 256, 512, 1024, 2048}) 1.98 +#define TILESIZE 256 1.99 + 1.100 +// Size of tile borders (in [0-16]). 1.101 +#define TILEBORDER 4 1.102 + 1.103 +// Number of simultaneous computation threads (in [1-16]). 1.104 +// Note : GREYCstoration multi-threading is HIGHLY experimental and may not work on your 1.105 +// computer. Please use it only if you checked that all is working correctly ! 1.106 +#define NTHREADS 1 1.107 + 1.108 +//----------------------------------------------------------------------- 1.109 +// Include necessary headers for GIMP, GTK and CImg + GREYCstoration API 1.110 +//----------------------------------------------------------------------- 1.111 +#if cimg_OS!=2 1.112 +#include <pthread.h> 1.113 +#endif 1.114 +#define cimg_plugin "plugins/greycstoration.h" 1.115 +#define cimg_display_type 0 1.116 +#include <gtk/gtk.h> 1.117 +#include <libgimp/gimp.h> 1.118 +#include <libgimp/gimpui.h> 1.119 +#include "plugins/../CImg.h" 1.120 +using namespace cimg_library; 1.121 + 1.122 +//---------------------------------------------------------- 1.123 +// Define algorithm parameters structure and default values 1.124 +//---------------------------------------------------------- 1.125 +struct Parameters { 1.126 + bool patch_based; // Select patch-based or non-patch method 1.127 + 1.128 + // Parameters for patch-based method 1.129 + gint patch_size; // Size of the patches 1.130 + gdouble sigma_p; // Sigma_p 1.131 + gdouble sigma_s; // Sigma_s 1.132 + gint lookup_size; // Lookup size 1.133 + 1.134 + // Parameters for non-patch method 1.135 + gdouble amplitude; // Regularization amplitude 1.136 + gdouble sharpness; // Contour preservation for regularization (sharpness) 1.137 + gdouble anisotropy; // Regularization anisotropy 1.138 + gdouble alpha; // Noise scale 1.139 + gdouble sigma; // Geometry regularity 1.140 + gdouble dl; // Spatial integration step for regularization 1.141 + gdouble da; // Angular integration step for regulatization 1.142 + gdouble gauss_prec; // Precision of the gaussian function for regularization 1.143 + gint interp; // Interpolation type 1.144 + bool fast_approx; // Use fast approximation for regularization 1.145 + gint channels; // Which channels to process 1.146 + gint iterations; // Number of regularization iterations 1.147 + gboolean update_preview; 1.148 +}; 1.149 + 1.150 +const Parameters defaults_parameters = { 1.151 + false, // patch_based 1.152 + 4, // patch_size 1.153 + 10.0f, // sigma_p 1.154 + 15.0f, // sigma_s 1.155 + 7, // Lookup size 1.156 + 60.0, // amplitude 1.157 + 0.7, // sharpness 1.158 + 0.3, // anisotropy 1.159 + 0.6, // alpha 1.160 + 1.1, // sigma 1.161 + 0.8, // dl 1.162 + 30.0, // da 1.163 + 2.0, // gauss_prec 1.164 + 0, // interp 1.165 + true, // fast_approx 1.166 + 0, // process RGB channels 1.167 + 1, // iterations 1.168 + true // default is to update the preview 1.169 +}; 1.170 + 1.171 +const gint nb_parameters = 20; // Number of parameters + 2 1.172 + 1.173 +//--------------------------- 1.174 +// GIMP plug-in declarations 1.175 +//--------------------------- 1.176 +typedef struct { 1.177 + gboolean run; 1.178 +} Interface; 1.179 + 1.180 +// Plug-in functions 1.181 +static void query(void); 1.182 +static void run(const gchar*name, gint nparams, const GimpParam *param, gint *nreturn_vals, GimpParam **return_vals); 1.183 +static void process(GimpPixelRgn *srcPTR, GimpPixelRgn *dstPTR, gint bytes, gint x1, gint x2, gint y1, gint y2, gboolean show_progress); 1.184 +static void callback_response(GtkWidget *widget, gint response_id, gpointer data); 1.185 +static void run_greycstoration(CImg<unsigned char>& img, const gboolean show_progress); 1.186 +static gboolean dialog(GimpDrawable *drawable); 1.187 +static void update_preview(GimpPreview *preview); 1.188 + 1.189 +// Plug-in global variables 1.190 +static gboolean runflag = FALSE; 1.191 +static Parameters params = defaults_parameters; 1.192 +GtkWidget *preview; 1.193 +GtkObject* adj_amplitude; 1.194 +GtkObject* adj_sharpness; 1.195 +GtkObject* adj_anisotropy; 1.196 +GtkObject* adj_alpha; 1.197 +GtkObject* adj_sigma; 1.198 +GtkObject* adj_dl; 1.199 +GtkObject* adj_da; 1.200 +GtkObject* adj_iterations; 1.201 +GtkObject* adj_patch_size; 1.202 +GtkObject* adj_sigma_s; 1.203 +GtkObject* adj_sigma_p; 1.204 +GtkObject* adj_lookup_size; 1.205 +GtkWidget* combo_interp; 1.206 +GtkWidget* combo_channels; 1.207 +GtkWidget* button_fast_approx; 1.208 +GtkWidget* button_patch_based; 1.209 +CImg<unsigned char> img; 1.210 + 1.211 +// Specific GIMP stuffs. 1.212 +GimpPlugInInfo PLUG_IN_INFO = { 0,0,query,run }; // { init_proc, quit_proc, query_proc, run_proc } 1.213 +MAIN () 1.214 + static void query(void) { 1.215 + static GimpParamDef args[] = { 1.216 + {GIMP_PDB_INT32, "run_mode", "Interactive, non-interactive"}, 1.217 + {GIMP_PDB_IMAGE, "image", "(unused)"}, 1.218 + {GIMP_PDB_DRAWABLE, "drawable", "Drawable to draw on"}, 1.219 + {GIMP_PDB_FLOAT, "amplitude", "Regularization strength for one iteration"}, 1.220 + {GIMP_PDB_FLOAT, "sharpness", "Contour preservation for regularization"}, 1.221 + {GIMP_PDB_FLOAT, "anisotropy", "Regularization anisotropy"}, 1.222 + {GIMP_PDB_FLOAT, "alpha", "Noise scale"}, 1.223 + {GIMP_PDB_FLOAT, "sigma", "Geometry regularity"} , 1.224 + {GIMP_PDB_FLOAT, "dl", "Spatial integration step for regularization"} , 1.225 + {GIMP_PDB_FLOAT, "da", "Angular integration step for regulatization"}, 1.226 + {GIMP_PDB_FLOAT, "gauss_prec", "Precision of the gaussian function for regularization"}, 1.227 + {GIMP_PDB_INT8, "interp", "Interpolation type"}, 1.228 + {GIMP_PDB_INT32, "patch_based", "Use patch-based intead of non-patch method"}, 1.229 + {GIMP_PDB_INT32, "patch_size", "Size of the patches (for patch-based method)"}, 1.230 + {GIMP_PDB_FLOAT, "sigma_p", "Sigma_p (for patch-based method)"}, 1.231 + {GIMP_PDB_FLOAT, "sigma_s", "Sigma_s (for patch-based method)"}, 1.232 + {GIMP_PDB_INT32, "lookup_size", "Lookup size (for patch-based method)"}, 1.233 + {GIMP_PDB_INT32, "fast_approx", "Use fast approximation for regularization"}, 1.234 + {GIMP_PDB_INT32, "channels", "Channels to process"}, 1.235 + {GIMP_PDB_INT32, "iterations", "Iterations accuracy"} 1.236 + }; 1.237 + gimp_install_procedure ("plug_in_greycstoration", 1.238 + "GREYCstoration Denoising Plugin", 1.239 + "GREYCstoration is an image regularization algorithm which is able to process" 1.240 + " a color image by locally removing small variations of pixel intensities" 1.241 + " while preserving significant global image features, such as edges and corners." 1.242 + " This plugin uses image regularization for image denoising.", 1.243 + "Grzegorz Szwoch & David Tschumperle", 1.244 + "Grzegorz Szwoch & David Tschumperle", 1.245 + "2008-06-02", 1.246 + "_GREYCstoration...", 1.247 + "RGB*, GRAY*", 1.248 + GIMP_PLUGIN,G_N_ELEMENTS(args),0,args, NULL); 1.249 + gimp_plugin_menu_register ("plug_in_greycstoration", "<Image>/Filters/Enhance"); 1.250 +} 1.251 + 1.252 +//------------------------------ 1.253 +// GIMP plug-in 'run' function 1.254 +//------------------------------ 1.255 +static void run(const gchar *name, gint nparams, const GimpParam *param, gint *nreturn_vals, GimpParam **return_vals) { 1.256 + name = 0; 1.257 + static GimpParam values[1]; 1.258 + GimpPDBStatusType status = GIMP_PDB_SUCCESS; 1.259 + GimpDrawable *drawable; 1.260 + GimpRunMode run_mode; 1.261 +#ifdef TIMER 1.262 + GTimer *timer = g_timer_new (); 1.263 +#endif 1.264 + run_mode = (GimpRunMode)param[0].data.d_int32; 1.265 + *return_vals = values; 1.266 + *nreturn_vals = 1; 1.267 + values[0].type = GIMP_PDB_STATUS; 1.268 + values[0].data.d_status = status; 1.269 + //INIT_I18N (); 1.270 + 1.271 + // Get drawable information 1.272 + drawable = gimp_drawable_get(param[2].data.d_drawable); 1.273 + 1.274 + // Make tile cache 1.275 + gimp_tile_cache_ntiles (2 * (drawable->width / gimp_tile_width () + 1)); 1.276 + 1.277 + switch (run_mode) { 1.278 + case GIMP_RUN_INTERACTIVE: 1.279 + gimp_get_data ("plug_in_greycstoration", ¶ms); // Reset default values show preview unmodified 1.280 + if (!dialog(drawable)) return; 1.281 + break; 1.282 + case GIMP_RUN_NONINTERACTIVE: 1.283 + if (nparams != nb_parameters) { status = GIMP_PDB_CALLING_ERROR; } 1.284 + else { 1.285 + params.amplitude = param[3].data.d_float; 1.286 + params.sharpness = param[4].data.d_float; 1.287 + params.anisotropy = param[5].data.d_float; 1.288 + params.alpha = param[6].data.d_float; 1.289 + params.sigma = param[7].data.d_float; 1.290 + params.dl = param[8].data.d_float; 1.291 + params.da = param[9].data.d_float; 1.292 + params.gauss_prec = param[10].data.d_float; 1.293 + params.interp = param[11].data.d_int32; 1.294 + params.patch_based = param[12].data.d_int32; 1.295 + params.patch_size = param[13].data.d_int32; 1.296 + params.sigma_p = param[14].data.d_float; 1.297 + params.sigma_s = param[15].data.d_float; 1.298 + params.lookup_size = param[16].data.d_int32; 1.299 + params.fast_approx = param[17].data.d_int32; 1.300 + params.channels = param[18].data.d_int32; 1.301 + params.iterations = param[19].data.d_int32; 1.302 + if((params.amplitude<0.0) || (params.sharpness<0.0)) status = GIMP_PDB_CALLING_ERROR; 1.303 + } 1.304 + break; 1.305 + case GIMP_RUN_WITH_LAST_VALS: 1.306 + gimp_get_data ("plug_in_greycstoration", ¶ms); 1.307 + break; 1.308 + default: 1.309 + break; 1.310 + } 1.311 + 1.312 + if(status==GIMP_PDB_SUCCESS) { 1.313 + drawable = gimp_drawable_get(param[2].data.d_drawable); 1.314 + 1.315 + // Process image 1.316 + GimpPixelRgn srcPR, destPR; 1.317 + gint x1, y1, x2, y2; 1.318 + 1.319 + // Initialize pixel regions 1.320 + gimp_pixel_rgn_init(&srcPR,drawable,0,0,drawable->width,drawable->height,false,false); 1.321 + gimp_pixel_rgn_init(&destPR,drawable,0,0,drawable->width,drawable->height,true,true); 1.322 + 1.323 + // Get the input 1.324 + gimp_drawable_mask_bounds(drawable->drawable_id,&x1,&y1,&x2,&y2); 1.325 + 1.326 + // Process region 1.327 + process(&srcPR,&destPR,drawable->bpp,x1,x2,y1,y2,true); 1.328 + 1.329 + // Update image and clean 1.330 + gimp_drawable_flush(drawable); 1.331 + gimp_drawable_merge_shadow(drawable->drawable_id,true); 1.332 + gimp_drawable_update(drawable->drawable_id,x1,y1,x2-x1,y2-y1); 1.333 + gimp_displays_flush(); 1.334 + 1.335 + // Set data for next use of filter 1.336 + gimp_set_data("plug_in_greycstoration",¶ms,sizeof(Parameters)); 1.337 + gimp_drawable_detach(drawable); 1.338 + values[0].data.d_status = status; 1.339 + } 1.340 + 1.341 +#ifdef TIMER 1.342 + g_printerr("%f seconds\n",g_timer_elapsed(timer,0)); 1.343 + g_timer_destroy(timer); 1.344 +#endif 1.345 +} 1.346 + 1.347 +//----------------------------------- 1.348 +// GIMP plug-in 'process' function 1.349 +//----------------------------------- 1.350 +static void process(GimpPixelRgn *srcPR, GimpPixelRgn *destPR, gint bytes, gint x1, gint x2, gint y1, gint y2, gboolean show_progress) { 1.351 + gint width = x2 - x1; 1.352 + gint height = y2 - y1; 1.353 + guchar* row, *row_ptr; 1.354 + if (show_progress) gimp_progress_init("GREYCstoration Filter..."); 1.355 + 1.356 + // Make CImg instance and fill it with image information 1.357 + const gint channels = (bytes<3)?1:3; 1.358 + img.assign(width,height,1,channels,0); 1.359 + row = g_new(guchar,width*bytes); 1.360 + cimg_forY(img,y) { 1.361 + gimp_pixel_rgn_get_row(srcPR,row,x1,y1+y,width); 1.362 + row_ptr = row; 1.363 + cimg_forX(img,x) { cimg_forV(img,k) img(x,y,k) = row_ptr[k]; row_ptr+=bytes; } 1.364 + } 1.365 + 1.366 + // run GREYCstoration processing 1.367 + run_greycstoration(img,show_progress); 1.368 + 1.369 + // Write processed image 1.370 + cimg_forY(img,y) { 1.371 + gimp_pixel_rgn_get_row(srcPR,row,x1,y1+y,width); 1.372 + row_ptr = row; 1.373 + cimg_forX(img,x) { cimg_forV(img,k) row_ptr[k] = img(x,y,k); row_ptr+=bytes; } 1.374 + gimp_pixel_rgn_set_row(destPR,row,x1,y1+y,width); 1.375 + } 1.376 + g_free(row); 1.377 +} 1.378 + 1.379 +//----------------------------------------- 1.380 +// Run GREYCstoration process on the image 1.381 +//----------------------------------------- 1.382 +static void run_greycstoration(CImg<unsigned char>& img, const gboolean show_progress) { 1.383 + guint crange_beg=0, crange_end = img.dimv()-1U; 1.384 + if (params.channels && img.dimv() > 1) { // Set up colour model and channel options 1.385 + img.RGBtoYCbCr(); 1.386 + if (params.channels == 1) { 1.387 + crange_beg=1; 1.388 + } else { 1.389 + crange_end=0; 1.390 + } 1.391 + } 1.392 + CImg<unsigned char> img_range = img.get_shared_channels(crange_beg, crange_end); 1.393 + 1.394 + for (gint iter=0; iter<params.iterations; ++iter) { 1.395 + if (params.patch_based) img_range.greycstoration_patch_run(params.patch_size, 1.396 + params.sigma_p, 1.397 + params.sigma_s, 1.398 + params.lookup_size, 1.399 + params.fast_approx, 1.400 + show_progress?TILESIZE:0, 1.401 + TILEBORDER, 1.402 + show_progress?NTHREADS:1); 1.403 + else img_range.greycstoration_run(params.amplitude, 1.404 + params.sharpness, 1.405 + params.anisotropy, 1.406 + params.alpha, 1.407 + params.sigma, 1.408 + 1.0f, 1.409 + params.dl, 1.410 + params.da, 1.411 + params.gauss_prec, 1.412 + params.interp, 1.413 + params.fast_approx, 1.414 + show_progress?TILESIZE:0, 1.415 + TILEBORDER, 1.416 + show_progress?NTHREADS:1); 1.417 + gint tick = 0; 1.418 + do { 1.419 + cimg::wait(100); 1.420 + ++tick; 1.421 + if (tick==10 && show_progress) { // Update progress bar 1.422 + const float pr_iteration = img_range.greycstoration_progress(); 1.423 + const unsigned int pr_global = (unsigned int)((iter*100 + pr_iteration) / params.iterations); 1.424 + gimp_progress_update(pr_global/100.0); 1.425 + tick = 0; 1.426 + } 1.427 + } while (img_range.greycstoration_is_running()); 1.428 + } 1.429 + if (params.channels && img.dimv() > 1) { // Convert back to RGB if required 1.430 + img.YCbCrtoRGB(); 1.431 + } 1.432 +} 1.433 + 1.434 +//---------------------- 1.435 +// Update image preview 1.436 +//---------------------- 1.437 +static void update_preview(GimpPreview *preview) { 1.438 +#ifdef ZOOMPREVIEW 1.439 + // Zoomable style preview 1.440 + //------------------------- 1.441 + gint width, height, bytes; 1.442 + guchar *src, *row_ptr; 1.443 + if (img.greycstoration_is_running()) img.greycstoration_stop(); 1.444 + src = gimp_zoom_preview_get_source(GIMP_ZOOM_PREVIEW(preview),&width,&height,&bytes); 1.445 + const gint channels = (bytes<3)?1:3; 1.446 + img.assign(width,height,1,channels,0); 1.447 + row_ptr = src; 1.448 + cimg_forY(img,y) { cimg_forX(img,x) { cimg_forV(img,k) img(x,y,k) = row_ptr[k]; row_ptr += bytes; }} 1.449 + run_greycstoration(img,false); 1.450 + row_ptr = src; 1.451 + cimg_forY(img,y) { cimg_forX(img,x) { cimg_forV(img,k) row_ptr[k] = img(x,y,k); row_ptr += bytes; }} 1.452 + gimp_preview_draw_buffer(preview,src,width*bytes); 1.453 + g_free(src); 1.454 + 1.455 +#else 1.456 + // Old style preview (without zoom) 1.457 + //---------------------------------- 1.458 + GimpDrawable *drawable; 1.459 + gint x, y, width, height; 1.460 + GimpPixelRgn srcPR, destPR; 1.461 + drawable = gimp_drawable_preview_get_drawable(GIMP_DRAWABLE_PREVIEW(preview)); 1.462 + gimp_pixel_rgn_init(&srcPR,drawable,0,0,drawable->width,drawable->height,false,false); 1.463 + gimp_pixel_rgn_init(&destPR,drawable,0,0,drawable->width,drawable->height,true,true); 1.464 + gimp_preview_get_position(preview,&x,&y); 1.465 + gimp_preview_get_size(preview,&width,&height); 1.466 + if(img.greycstoration_is_running()) img.greycstoration_stop(); 1.467 + process(&srcPR,&destPR,drawable->bpp,x,x+width,y,y+height,false); 1.468 + gimp_pixel_rgn_init(&destPR,drawable,x,y,width,height,false,true); 1.469 + gimp_drawable_preview_draw_region(GIMP_DRAWABLE_PREVIEW(preview),&destPR); 1.470 +#endif 1.471 +} 1.472 + 1.473 +//---------------------- 1.474 +// Define dialog window 1.475 +//---------------------- 1.476 +static gboolean dialog (GimpDrawable *drawable) { 1.477 + GtkWidget *dialog; 1.478 + GtkWidget *main_hbox; 1.479 + GtkWidget *table; 1.480 + 1.481 +#define SCALE_WIDTH 150 1.482 +#define ENTRY_WIDTH 4 1.483 +#define RESPONSE_RESET 1 1.484 + 1.485 + gimp_ui_init("greycstoration",true); 1.486 + runflag = false; 1.487 + dialog = gimp_dialog_new("GREYCstoration", "greycstoration",0,(GtkDialogFlags)0,gimp_standard_help_func,"plug-in-greycstoration", 1.488 + GIMP_STOCK_RESET,RESPONSE_RESET,GTK_STOCK_CANCEL,GTK_RESPONSE_CANCEL,GTK_STOCK_OK,GTK_RESPONSE_OK,NULL); 1.489 + gtk_dialog_set_alternative_button_order(GTK_DIALOG(dialog),RESPONSE_RESET,GTK_RESPONSE_OK,GTK_RESPONSE_CANCEL,-1); 1.490 + 1.491 +#ifdef ZOOMPREVIEW 1.492 + gimp_window_set_transient(GTK_WINDOW (dialog)); 1.493 +#endif 1.494 + 1.495 + g_signal_connect(dialog,"response",G_CALLBACK(callback_response),preview); 1.496 + g_signal_connect(dialog, "destroy",G_CALLBACK(gtk_main_quit),0); 1.497 + 1.498 + main_hbox = gtk_hbox_new(false,12); 1.499 + gtk_container_set_border_width(GTK_CONTAINER(main_hbox),12); 1.500 + gtk_container_add(GTK_CONTAINER(GTK_DIALOG(dialog)->vbox),main_hbox); 1.501 + gtk_widget_show(main_hbox); 1.502 + 1.503 +#ifdef ZOOMPREVIEW 1.504 + preview = gimp_zoom_preview_new(drawable); 1.505 +#else 1.506 + preview = gimp_drawable_preview_new(drawable,¶ms.update_preview); 1.507 +#endif 1.508 + gtk_box_pack_start(GTK_BOX(main_hbox),preview,true,true,0); 1.509 + gtk_widget_show(preview); 1.510 + g_signal_connect(preview,"invalidated",G_CALLBACK(update_preview),0); 1.511 + 1.512 + table = gtk_table_new(3,3,false); 1.513 + gtk_table_set_col_spacings(GTK_TABLE(table),6); 1.514 + gtk_table_set_row_spacings(GTK_TABLE(table),6); 1.515 + gtk_box_pack_start(GTK_BOX(main_hbox),table,false,false,0); 1.516 + gtk_widget_show(table); 1.517 + 1.518 + // 'Amplitude' slider 1.519 + adj_amplitude = gimp_scale_entry_new(GTK_TABLE(table),0,0,"_Strength :",SCALE_WIDTH,ENTRY_WIDTH, 1.520 + params.amplitude,0.0,200.0,1,10,1,true,0,0,0,0); 1.521 + g_signal_connect(adj_amplitude,"value_changed",G_CALLBACK(gimp_double_adjustment_update),¶ms.amplitude); 1.522 + g_signal_connect_swapped(adj_amplitude,"value_changed",G_CALLBACK(gimp_preview_invalidate),preview); 1.523 + 1.524 + // 'Sharpness' slider 1.525 + adj_sharpness = gimp_scale_entry_new(GTK_TABLE(table),0,1,"Contour preser_vation :",SCALE_WIDTH,ENTRY_WIDTH, 1.526 + params.sharpness,0.0,5.0,0.05,0.5,2,true,0,0,0,0); 1.527 + g_signal_connect(adj_sharpness,"value_changed",G_CALLBACK(gimp_double_adjustment_update),¶ms.sharpness); 1.528 + g_signal_connect_swapped(adj_sharpness,"value_changed",G_CALLBACK(gimp_preview_invalidate),preview); 1.529 + 1.530 + // 'Anisotropy' slider 1.531 + adj_anisotropy = gimp_scale_entry_new(GTK_TABLE(table),0,2,"_Anisotropy :",SCALE_WIDTH,ENTRY_WIDTH, 1.532 + params.anisotropy,0.0,1.0,0.05,0.5,2,true,0,0,0,0); 1.533 + g_signal_connect(adj_anisotropy,"value_changed",G_CALLBACK(gimp_double_adjustment_update),¶ms.anisotropy); 1.534 + g_signal_connect_swapped(adj_anisotropy,"value_changed",G_CALLBACK(gimp_preview_invalidate),preview); 1.535 + 1.536 + // 'Alpha' slider 1.537 + adj_alpha = gimp_scale_entry_new(GTK_TABLE(table),0,3,"_Noise scale :",SCALE_WIDTH,ENTRY_WIDTH, 1.538 + params.alpha,0.0,16.0,0.1,0.5, 1,true,0,0,0,0); 1.539 + g_signal_connect(adj_alpha,"value_changed",G_CALLBACK(gimp_double_adjustment_update),¶ms.alpha); 1.540 + g_signal_connect_swapped(adj_alpha,"value_changed",G_CALLBACK(gimp_preview_invalidate),preview); 1.541 + 1.542 + // 'Sigma' slider 1.543 + adj_sigma = gimp_scale_entry_new(GTK_TABLE(table),0,4,"Geometry _regularity :",SCALE_WIDTH,ENTRY_WIDTH, 1.544 + params.sigma,0,8.0,0.1,0.5,2,true,0,0,0,0); 1.545 + g_signal_connect(adj_sigma,"value_changed",G_CALLBACK(gimp_double_adjustment_update),¶ms.sigma); 1.546 + g_signal_connect_swapped(adj_sigma,"value_changed",G_CALLBACK(gimp_preview_invalidate),preview); 1.547 + 1.548 + // 'Spatial step' slider 1.549 + adj_dl = gimp_scale_entry_new(GTK_TABLE (table),0,5,"Spatial step :",SCALE_WIDTH,ENTRY_WIDTH, 1.550 + params.dl,0.1,1.0,0.01,0.1,2,true,0,0,0,0); 1.551 + g_signal_connect(adj_dl,"value_changed",G_CALLBACK(gimp_double_adjustment_update),¶ms.dl); 1.552 + g_signal_connect_swapped(adj_dl,"value_changed",G_CALLBACK(gimp_preview_invalidate),preview); 1.553 + 1.554 + // 'Angular step' slider 1.555 + adj_da = gimp_scale_entry_new(GTK_TABLE(table),0,6,"Angu_lar step :",SCALE_WIDTH,ENTRY_WIDTH, 1.556 + params.da,1.0,90.0,1.0,10.0,1,true,0,0,0,0); 1.557 + g_signal_connect(adj_da,"value_changed",G_CALLBACK(gimp_double_adjustment_update),¶ms.da); 1.558 + g_signal_connect_swapped(adj_da,"value_changed",G_CALLBACK(gimp_preview_invalidate),preview); 1.559 + 1.560 + // 'Interpolation' choice 1.561 + combo_interp = gimp_int_combo_box_new("Nearest neighbor",0,"Linear",1,"Runge-Kutta",2,NULL); 1.562 + gimp_int_combo_box_set_active(GIMP_INT_COMBO_BOX(combo_interp),params.interp); 1.563 + gimp_table_attach_aligned(GTK_TABLE(table),0,8,"Interpolation _type :",0.0,0.5,combo_interp,2,false); 1.564 + g_signal_connect(combo_interp,"changed",G_CALLBACK(gimp_int_combo_box_get_active),¶ms.interp); 1.565 + g_signal_connect_swapped(combo_interp,"changed",G_CALLBACK(gimp_preview_invalidate),preview); 1.566 + 1.567 + // 'Patch-based' button 1.568 + button_patch_based = gtk_check_button_new_with_mnemonic("_Patch-based"); 1.569 + gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(button_patch_based),params.patch_based); 1.570 + gimp_table_attach_aligned(GTK_TABLE(table),0,9,"Patch-based :",0.0,0.5,button_patch_based,2,false); 1.571 + g_signal_connect(button_patch_based,"toggled",G_CALLBACK(gimp_toggle_button_update),¶ms.patch_based); 1.572 + g_signal_connect_swapped(button_patch_based,"toggled",G_CALLBACK(gimp_preview_invalidate),preview); 1.573 + 1.574 + // 'Patch size' slider 1.575 + adj_patch_size = gimp_scale_entry_new(GTK_TABLE(table),0,10,"Patch size :",SCALE_WIDTH,ENTRY_WIDTH, 1.576 + params.patch_size,1.0,9.0,1.0,1.0,0,true,0,0,0,0); 1.577 + g_signal_connect(adj_patch_size,"value_changed",G_CALLBACK(gimp_int_adjustment_update),¶ms.patch_size); 1.578 + g_signal_connect_swapped(adj_patch_size,"value_changed",G_CALLBACK(gimp_preview_invalidate),preview); 1.579 + 1.580 + // 'Sigma_p' slider 1.581 + adj_sigma_p = gimp_scale_entry_new(GTK_TABLE(table),0,11,"_Sigma-p :",SCALE_WIDTH,ENTRY_WIDTH, 1.582 + params.sigma_p,0.0,30.0,0.1,0.5,1,true,0,0,0,0); 1.583 + g_signal_connect(adj_sigma_p,"value_changed",G_CALLBACK(gimp_double_adjustment_update),¶ms.sigma_p); 1.584 + g_signal_connect_swapped(adj_sigma_p,"value_changed",G_CALLBACK(gimp_preview_invalidate),preview); 1.585 + 1.586 + // 'Sigma_s' slider 1.587 + adj_sigma_s = gimp_scale_entry_new(GTK_TABLE(table),0,12,"_Sigma-s :",SCALE_WIDTH,ENTRY_WIDTH, 1.588 + params.sigma_s,0.0,30.0,0.1,0.5,1,true,0,0,0,0); 1.589 + g_signal_connect(adj_sigma_s,"value_changed",G_CALLBACK(gimp_double_adjustment_update),¶ms.sigma_s); 1.590 + g_signal_connect_swapped(adj_sigma_s,"value_changed",G_CALLBACK(gimp_preview_invalidate),preview); 1.591 + 1.592 + // 'Lookup size' slider 1.593 + adj_lookup_size = gimp_scale_entry_new(GTK_TABLE(table),0,13,"Lookup size :",SCALE_WIDTH,ENTRY_WIDTH, 1.594 + params.lookup_size,1.0,40.0,1.0,1.0,0,true,0,0,0,0); 1.595 + g_signal_connect(adj_lookup_size,"value_changed",G_CALLBACK(gimp_int_adjustment_update),¶ms.lookup_size); 1.596 + g_signal_connect_swapped(adj_lookup_size,"value_changed",G_CALLBACK(gimp_preview_invalidate),preview); 1.597 + 1.598 + // 'Fast approximation' button 1.599 + button_fast_approx = gtk_check_button_new_with_mnemonic("_Enable"); 1.600 + gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(button_fast_approx),params.fast_approx); 1.601 + gimp_table_attach_aligned(GTK_TABLE(table),0,14,"Approximation :",0.0,0.5,button_fast_approx,2,false); 1.602 + g_signal_connect(button_fast_approx,"toggled",G_CALLBACK(gimp_toggle_button_update),¶ms.fast_approx); 1.603 + g_signal_connect_swapped(button_fast_approx,"toggled",G_CALLBACK(gimp_preview_invalidate),preview); 1.604 + 1.605 + // 'Channels' choice 1.606 + combo_channels = gimp_int_combo_box_new("All",0,"Chroma",1,"Luminance",2,NULL); 1.607 + gimp_int_combo_box_set_active(GIMP_INT_COMBO_BOX(combo_channels),params.channels); 1.608 + gimp_table_attach_aligned(GTK_TABLE(table),0,15,"Channels",0.0,0.5,combo_channels,2,false); 1.609 + g_signal_connect(combo_channels,"changed",G_CALLBACK(gimp_int_combo_box_get_active),¶ms.channels); 1.610 + g_signal_connect_swapped(combo_channels,"changed",G_CALLBACK(gimp_preview_invalidate),preview); 1.611 + if (drawable->bpp < 3) gtk_widget_set_sensitive(combo_channels, FALSE); 1.612 + 1.613 + // 'Number of iterations' slider 1.614 + adj_iterations = gimp_scale_entry_new(GTK_TABLE(table),0,16,"Number of _iterations :",SCALE_WIDTH,ENTRY_WIDTH, 1.615 + params.iterations,1.0,30.0,1.0,1.0,0,true,0,0,0,0); 1.616 + g_signal_connect(adj_iterations,"value_changed",G_CALLBACK(gimp_int_adjustment_update),¶ms.iterations); 1.617 + g_signal_connect_swapped(adj_iterations,"value_changed",G_CALLBACK(gimp_preview_invalidate),preview); 1.618 + 1.619 + // Show dialog window 1.620 + gtk_widget_show (dialog); 1.621 + gtk_main (); 1.622 + 1.623 + return runflag; 1.624 +} 1.625 + 1.626 +static void callback_response(GtkWidget *widget, gint response_id, gpointer data) { 1.627 + data = 0; 1.628 + switch (response_id) { 1.629 + case RESPONSE_RESET: // Reset parameters to default values & update window 1.630 + params = defaults_parameters; 1.631 + gtk_adjustment_set_value(GTK_ADJUSTMENT(adj_amplitude), params.amplitude); 1.632 + gtk_adjustment_set_value(GTK_ADJUSTMENT(adj_sharpness), params.sharpness); 1.633 + gtk_adjustment_set_value(GTK_ADJUSTMENT(adj_anisotropy), params.anisotropy); 1.634 + gtk_adjustment_set_value(GTK_ADJUSTMENT(adj_alpha), params.alpha); 1.635 + gtk_adjustment_set_value(GTK_ADJUSTMENT(adj_sigma), params.sigma); 1.636 + gtk_adjustment_set_value(GTK_ADJUSTMENT(adj_dl), params.dl); 1.637 + gtk_adjustment_set_value(GTK_ADJUSTMENT(adj_da), params.da); 1.638 + gtk_adjustment_set_value(GTK_ADJUSTMENT(adj_iterations), params.iterations); 1.639 + gimp_int_combo_box_set_active(GIMP_INT_COMBO_BOX(combo_channels), params.channels); 1.640 + gimp_int_combo_box_set_active(GIMP_INT_COMBO_BOX(combo_interp), params.interp); 1.641 + gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button_fast_approx), params.fast_approx); 1.642 + gimp_preview_invalidate((GimpPreview*)preview); 1.643 + break; 1.644 + case GTK_RESPONSE_OK: 1.645 + runflag = TRUE; 1.646 + gtk_widget_destroy (widget); 1.647 + break; 1.648 + default: 1.649 + gtk_widget_destroy (widget); 1.650 + break; 1.651 + } 1.652 +}