home *** CD-ROM | disk | FTP | other *** search
/ ftp.sunet.sepub/pictures / 2014.11.ftp.sunet.se-pictures.tar / ftp.sunet.se / pub / pictures / ACiD-artpacks / programs / unix / editors / gimp-plugins-unstable-0_99_23_tar.gz / gimp-plugins-unstable-0_99_23_tar / gimp-plugins-unstable-0.99.23 / twist / twist.c < prev   
C/C++ Source or Header  |  1998-02-19  |  92KB  |  2,627 lines

  1. /* Twist - A geometric image distortion plugin for 'The GIMP'
  2.  * (see legal notice below).
  3.  * Copyright (C) 1997 Peter Uray.
  4.  *
  5.  * This program is free software; you can redistribute it and/or modify
  6.  * it under the terms of the GNU General Public License as published by
  7.  * the Free Software Foundation; either version 2 of the License, or
  8.  * (at your option) any later version.
  9.  *
  10.  * This program is distributed WITHOUT ANY WARRANTY; without even
  11.  * the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
  12.  * PURPOSE.  See the GNU General Public License for more details.
  13.  *
  14.  * You should have received a copy of the GNU General Public License
  15.  * along with this program; if not, write to the Free Software
  16.  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  17.  */
  18.  
  19.  
  20.  
  21.  
  22. /* The GIMP -- an image manipulation program
  23.  * Copyright (C) 1995 Spencer Kimball and Peter Mattis
  24.  *
  25.  * This program is free software; you can redistribute it and/or modify
  26.  * it under the terms of the GNU General Public License as published by
  27.  * the Free Software Foundation; either version 2 of the License, or
  28.  * (at your option) any later version.
  29.  *
  30.  * This program is distributed in the hope that it will be useful,
  31.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  32.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  33.  * GNU General Public License for more details.
  34.  *
  35.  * You should have received a copy of the GNU General Public License
  36.  * along with this program; if not, write to the Free Software
  37.  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  38.  */
  39.  
  40.  
  41.  
  42.  
  43. #include <math.h>
  44. #include <stdio.h>
  45. #include <stdlib.h>
  46. #include <gtk/gtk.h>
  47. #include <libgimp/gimp.h>
  48.  
  49.  
  50. #define ENTRY_WIDTH 70
  51. #define epsilon 0.001
  52. #define preview_width 128
  53. #define preview_height 128
  54.                       
  55. /* The number of parameters needed for non-interative mode */
  56. #define N_PARAMETERS 15
  57.  
  58. /* The number of available functions */
  59. #define N_FUNCTIONS 8
  60.  
  61. /* I learned that in general PI is not defined in math.h */
  62. /* (Thanks to all who pointed this out.) Now this #define */
  63. /* solves the problem rather brutally but once and for all. */
  64. #define TWIST_PI 3.1415927
  65.  
  66. /* Identifiers for the distortion function types */
  67. #define FUNCTION_R_r             0
  68. #define FUNCTION_R_phi           1
  69. #define FUNCTION_Phi_r           2
  70. #define FUNCTION_Phi_phi         3
  71. #define FUNCTION_R_r_Phi_phi     4
  72. #define FUNCTION_R_r_R_phi       5
  73. #define FUNCTION_Cosines         6
  74. #define FUNCTION_Gauss           7
  75.  
  76.  
  77. /***************************************************************************
  78.  *
  79.  *
  80.  *  Global data definition.
  81.  *
  82.  *
  83.  ***************************************************************************/
  84.  
  85.  
  86.  
  87.  
  88. /* do_action is used for preventing the plugin to act when the
  89.    [Cancel] button was pressed.
  90. */
  91. static gint do_action = 0;
  92.  
  93.  
  94. static gint do_update_preview = 1;
  95.  
  96.  
  97. /* Some frequently used strings. */
  98. static char PluginName[] = "Twist";
  99. static char PluginResource[] = "plug_in_Twist";
  100. static char PluginAuthor[] = "Peter Uray";
  101. static char PluginYear[] = "1997";
  102. static char PluginDescription[] = "Twist - Geometric image distortion";
  103. static char PluginGroup[] = "<Image>/Filters/Distorts/Twist";
  104.  
  105.  
  106. /* Definition of global structure types */
  107.  
  108. /* A GtkObject and a label - used below */
  109. typedef struct 
  110. {
  111.  GtkWidget *object;
  112.  GtkLabel *label;
  113. }ObjectAndLabel;
  114.  
  115.  
  116. /* These parameters are modified in the 'Parameter settings' section. */
  117. typedef struct
  118. {
  119.  gfloat a1;
  120.  gfloat a2;
  121.  gfloat a3;
  122.  gfloat a4;
  123.  gfloat a5;
  124.  gfloat a6;
  125.  gfloat a7;
  126.  gfloat a8;
  127.  
  128.  gchar lettering01[30];
  129.  gchar lettering02[30];
  130.  gchar lettering03[30];
  131.  gchar lettering04[30];
  132.  gchar lettering05[30];
  133.  gchar lettering06[30];
  134.  gchar lettering07[30];
  135.  gchar lettering08[30];
  136.  
  137.  gint use_cutoff;
  138.  gfloat r;
  139.  gfloat dr;
  140.  
  141.  gint current_function;
  142.  
  143. }Parameters;
  144.  
  145.  
  146. /* The labels of the parameter selection box */
  147. /* These depend on the selected function     */
  148. typedef struct 
  149. {
  150.  char name_a1[30];
  151.  char name_a2[30];
  152.  char name_a3[30];
  153.  char name_a4[30];
  154.  char name_a5[30];
  155.  char name_a6[30];
  156.  char name_a7[30];
  157.  char name_a8[30];
  158. }ParameterNames;
  159.  
  160.  
  161. /* Data fields used for creating a dialog and the action area. */
  162. typedef struct
  163. {
  164.  GtkWidget *dlg;
  165.  GtkWidget *ok_button;
  166.  GtkWidget *cancel_button;
  167.  GtkWidget *dialog_frame;
  168.  gchar **argv;
  169.  gint argc;
  170. }DialogTemplateData;
  171.  
  172.  
  173. /* Data used for maintaining the preview image */
  174. typedef struct
  175. {
  176.  gint width;
  177.  gint height;
  178.  gint bpp;
  179.  gfloat scale;
  180.  guchar *bits;
  181.  GtkWidget *display;
  182. }PreviewData;
  183.  
  184.  
  185.  
  186. /* These pointers are needed for modifying the sliders in update_dialog */
  187. typedef struct 
  188. {
  189.  GtkWidget *slider01;
  190.  GtkWidget *slider02;
  191.  GtkWidget *slider03;
  192.  GtkWidget *slider04;
  193.  GtkWidget *slider05;
  194.  GtkWidget *slider06;
  195.  GtkWidget *slider07;
  196.  GtkWidget *slider08;
  197.  GtkWidget *slider09;
  198.  GtkWidget *slider10;
  199.  
  200.  GtkLabel *label01;
  201.  GtkLabel *label02;
  202.  GtkLabel *label03;
  203.  GtkLabel *label04;
  204.  GtkLabel *label05;
  205.  GtkLabel *label06;
  206.  GtkLabel *label07;
  207.  GtkLabel *label08;
  208.  
  209.  GtkWidget *toggle01;
  210. }WidgetData; 
  211.  
  212.  
  213. /* Parameter initialization */
  214. static Parameters parameter_values = { 0.0,            /* a1               */
  215.                                        0.0,            /* a2               */
  216.                                        0.0,            /* a3               */
  217.                                        0.0,            /* a4               */
  218.                                        0.0,            /* a5               */
  219.                                        0.0,            /* a6               */
  220.                                        0.0,            /* a7               */
  221.                                        0.0,            /* a8               */
  222.                                        "unused",       /* lettering01      */
  223.                                        "unused",       /* lettering02      */
  224.                                        "unused",       /* lettering03      */
  225.                                        "unused",       /* lettering04      */
  226.                                        "unused",       /* lettering05      */
  227.                                        "unused",       /* lettering06      */
  228.                                        "unused",       /* lettering07      */
  229.                                        "unused",       /* lettering08      */
  230.                                        FALSE,          /* use_cutoff       */
  231.                                        0.5,            /* r                */                              
  232.                                        0.2,            /* dr               */     
  233.                                        FUNCTION_R_r    /* current_function */                             
  234.                                       };
  235. static DialogTemplateData dtd;
  236. static PreviewData preview_data;
  237. static WidgetData widget_data;
  238. static ParameterNames parameter_names[N_FUNCTIONS];
  239. static Parameters EffectsParameters[N_FUNCTIONS][9];
  240.  
  241.  
  242.  
  243. /***************************************************************************
  244.  *
  245.  *
  246.  *  Forward declarations
  247.  *
  248.  *
  249.  ***************************************************************************/
  250.  
  251.  
  252.  
  253. /* Declare local functions. */
  254. static void      query(void);
  255. static void      run(gchar *name,
  256.                      gint nparams,
  257.                      GParam *param,
  258.                      gint *nreturn_vals,
  259.                      GParam **return_vals);
  260.  
  261.  
  262.  
  263.  
  264. /* Callback functions */
  265. static void     close_callback(GtkWidget *widget, gpointer data);
  266. static void     ok_callback(GtkWidget *widget, gpointer data);
  267. static void     cancel_callback(GtkWidget *widget, gpointer data);
  268.  
  269. static void     a1_callback(GtkAdjustment *adjustment, gpointer data);
  270. static void     a2_callback(GtkAdjustment *adjustment, gpointer data);
  271. static void     a3_callback(GtkAdjustment *adjustment, gpointer data);
  272. static void     a4_callback(GtkAdjustment *adjustment, gpointer data);
  273. static void     a5_callback(GtkAdjustment *adjustment, gpointer data);
  274. static void     a6_callback(GtkAdjustment *adjustment, gpointer data);
  275. static void     a7_callback(GtkAdjustment *adjustment, gpointer data);
  276. static void     a8_callback(GtkAdjustment *adjustment, gpointer data);
  277.  
  278.  
  279. static void    use_cutoff_callback(GtkWidget *widget, gpointer data);
  280. static void    r_callback(GtkAdjustment *adjustment, gpointer data);
  281. static void    dr_callback(GtkAdjustment *adjustment, gpointer data);
  282.  
  283.  
  284. static void    effect01_callback(GtkWidget *widget, gpointer data);
  285. static void    effect02_callback(GtkWidget *widget, gpointer data);
  286. static void    effect03_callback(GtkWidget *widget, gpointer data);
  287.  
  288. static void    effect04_callback(GtkWidget *widget, gpointer data);
  289. static void    effect05_callback(GtkWidget *widget, gpointer data);
  290. static void    effect06_callback(GtkWidget *widget, gpointer data);
  291.  
  292. static void    effect07_callback(GtkWidget *widget, gpointer data);
  293. static void    effect08_callback(GtkWidget *widget, gpointer data);
  294. static void    effect09_callback(GtkWidget *widget, gpointer data);
  295.  
  296.  
  297.  
  298. static void    function01_callback(GtkWidget *widget, gpointer data);
  299. static void    function02_callback(GtkWidget *widget, gpointer data);
  300. static void    function03_callback(GtkWidget *widget, gpointer data);
  301. static void    function04_callback(GtkWidget *widget, gpointer data);
  302. static void    function05_callback(GtkWidget *widget, gpointer data);
  303. static void    function06_callback(GtkWidget *widget, gpointer data);
  304. static void    function07_callback(GtkWidget *widget, gpointer data);
  305. static void    function08_callback(GtkWidget *widget, gpointer data);
  306.  
  307.  
  308.  
  309.  
  310.  
  311. /* Dialog creation/updating functions */
  312.  
  313. /* This function executes the user dialog */
  314. static gint    user_dialog(void);
  315.  
  316. /* This function syncs the dialog display with the contents of the
  317.    parameter_values
  318. */
  319. static void    update_dialog(void);
  320.  
  321. static void    create_base_dialog(void);
  322. static ObjectAndLabel create_slider_with_label(gchar *text,                                                            
  323.                                                GtkWidget *container,
  324.                                                GtkSignalFunc callback_func,
  325.                                                gfloat initial_value,
  326.                                                gfloat min_value,
  327.                                                gfloat max_value);
  328.                                                
  329. static void    create_functions_menu(GtkWidget *container);                                               
  330. static void    create_effects_menu(GtkWidget *container);                                 
  331.                                                                             
  332. static void    create_cutoff_panel(GtkWidget *container);
  333.  
  334.  
  335.  
  336.  
  337. /* Functions for handling the preview */
  338. static void    create_preview(GDrawable *drawable);
  339. static void    update_preview(GtkWidget *preview);
  340.  
  341.  
  342. /* This function actually modifies the image */
  343. void        image_action(GDrawable *drawable, Parameters params);
  344.  
  345. /* Functions for calculating the image distortion */
  346. static void    polar_coordinates(gfloat x, gfloat y, gfloat *rho, gfloat *phi);
  347.  
  348.  
  349. /* The distortion functions. */
  350. static void    distortion_function01(gfloat x1, gfloat x2, gfloat *delta_x1, gfloat *delta_x2);
  351. static void    distortion_function02(gfloat x1, gfloat x2, gfloat *delta_x1, gfloat *delta_x2);
  352. static void    distortion_function03(gfloat x1, gfloat x2, gfloat *delta_x1, gfloat *delta_x2);
  353. static void    distortion_function04(gfloat x1, gfloat x2, gfloat *delta_x1, gfloat *delta_x2);
  354. static void    distortion_function05(gfloat x1, gfloat x2, gfloat *delta_x1, gfloat *delta_x2);
  355. static void    distortion_function06(gfloat x1, gfloat x2, gfloat *delta_x1, gfloat *delta_x2);
  356. static void    distortion_function07(gfloat x1, gfloat x2, gfloat *delta_x1, gfloat *delta_x2);
  357. static void    distortion_function08(gfloat x1, gfloat x2, gfloat *delta_x1, gfloat *delta_x2);
  358.  
  359.  
  360. static void    calculate_distortion_function(gint i, gint j, gint width, gint height, gfloat *u, gfloat *v);
  361. static gfloat    cutoff_function(gfloat u, gfloat v);
  362. static void    calculate_pixel_color(gfloat u, gfloat f, guchar *source, gint width, gint height, gint bpp, guchar *r, guchar *g, guchar *b);
  363.  
  364. /* Functions for image data exchange between GIMP and the plugin */
  365. static void    get_source_image(GPixelRgn source_rgn, guchar *buffer, gint x, gint y, gint width, gint height, gint bytes); 
  366.  
  367.  
  368.  
  369.  
  370.  
  371. /***************************************************************************
  372.  *
  373.  *
  374.  *  Implementation
  375.  *
  376.  *
  377.  ***************************************************************************/
  378.  
  379.  
  380. /* An auxiliary function to make life easier while initializing the effects */
  381. static void SET_EFFECTS_PARAMS(gint i, gint j,
  382.                                gfloat a1, gfloat a2, 
  383.                                gfloat a3, gfloat a4, 
  384.                                gfloat a5, gfloat a6,
  385.                                gfloat a7, gfloat a8,
  386.                                gint uc,
  387.                                gfloat r, gfloat dr) 
  388. {
  389.  EffectsParameters[i][j].a1 = a1;                 
  390.  EffectsParameters[i][j].a2 = a2;                 
  391.  EffectsParameters[i][j].a3 = a3;                 
  392.  EffectsParameters[i][j].a4 = a4;                 
  393.  EffectsParameters[i][j].a5 = a5;                 
  394.  EffectsParameters[i][j].a6 = a6;                 
  395.  EffectsParameters[i][j].a7 = a7;                 
  396.  EffectsParameters[i][j].a8 = a8;                 
  397.  EffectsParameters[i][j].use_cutoff = uc;         
  398.  EffectsParameters[i][j].r = r;                   
  399.  EffectsParameters[i][j].dr = dr;              
  400. }                    
  401.  
  402.  
  403.  
  404. GPlugInInfo PLUG_IN_INFO =
  405. {
  406.   NULL,    /* init_proc */
  407.   NULL,    /* quit_proc */
  408.   query,   /* query_proc */
  409.   run,     /* run_proc */
  410. };
  411.  
  412.  
  413.  
  414. /******************************************************************************/
  415. /*                           Standard functions                               */
  416. /******************************************************************************/
  417.  
  418.  
  419. /* The main function */
  420. MAIN ();
  421.  
  422.  
  423.  
  424.  
  425.  
  426. static void query ()
  427. {
  428.  static GParamDef args[] =
  429.  {
  430.   { PARAM_INT32, "run_mode", "Interactive, non-interactive" },
  431.   { PARAM_IMAGE, "image", "Input image" },
  432.   { PARAM_DRAWABLE, "drawable", "Input drawable" },
  433.   { PARAM_FLOAT, "a1", "float parameter #1" },
  434.   { PARAM_FLOAT, "a2", "float parameter #2" },
  435.   { PARAM_FLOAT, "a3", "float parameter #3" },
  436.   { PARAM_FLOAT, "a4", "float parameter #4" },
  437.   { PARAM_FLOAT, "a5", "float parameter #5" },
  438.   { PARAM_FLOAT, "a6", "float parameter #6" },
  439.   { PARAM_FLOAT, "a7", "float parameter #7" },
  440.   { PARAM_FLOAT, "a8", "float parameter #8" },
  441.   { PARAM_STRING , "lettering01", "lettering #1" },
  442.   { PARAM_STRING , "lettering02", "lettering #2" },
  443.   { PARAM_STRING , "lettering03", "lettering #3" },
  444.   { PARAM_STRING , "lettering04", "lettering #4" },
  445.   { PARAM_STRING , "lettering05", "lettering #5" },
  446.   { PARAM_STRING , "lettering06", "lettering #6" },
  447.   { PARAM_STRING , "lettering07", "lettering #7" },
  448.   { PARAM_STRING , "lettering08", "lettering #8" },
  449.   { PARAM_INT32, "use_cutoff", "Use cutoff or not" },
  450.   { PARAM_FLOAT, "r", "The cutoff radius" },
  451.   { PARAM_FLOAT, "dr", "The falloff radius" },
  452.   { PARAM_INT32, "current_function", "The current function" },
  453.  };
  454.  static GParamDef *return_vals = NULL;
  455.  static gint nargs = sizeof (args) / sizeof (args[0]);
  456.  static gint nreturn_vals = 0;
  457.  
  458.  gimp_install_procedure (PluginResource,
  459.              PluginDescription,
  460.              PluginDescription,
  461.              PluginAuthor,
  462.              PluginAuthor,
  463.              PluginYear,
  464.              PluginGroup,
  465.              "RGB*, GRAY*",
  466.              PROC_PLUG_IN,
  467.              nargs, nreturn_vals,
  468.              args, return_vals);
  469. }
  470.  
  471. static void run(gchar *name, gint nparams, GParam *param, gint *nreturn_vals, GParam **return_vals)
  472. {
  473.  static GParam values[1];
  474.  GDrawable *drawable;
  475.  GRunModeType run_mode;
  476.  GStatusType status = STATUS_SUCCESS;
  477.  
  478.  run_mode = param[0].data.d_int32;
  479.  
  480.  *nreturn_vals = 1;
  481.  *return_vals = values;
  482.  
  483.  values[0].type = PARAM_STATUS;
  484.  values[0].data.d_status = status;
  485.  
  486.  /*  Get the drawable  */
  487.  drawable = gimp_drawable_get(param[2].data.d_drawable);
  488.  
  489.  /* Parameter names for R(r) distortion */
  490.  strcpy(parameter_names[0].name_a1, "Linear coefficient:");
  491.  strcpy(parameter_names[0].name_a2, "Quadratic coefficient:");
  492.  strcpy(parameter_names[0].name_a3, "Cubic coefficient:");
  493.  strcpy(parameter_names[0].name_a4, "Quartic coefficient:");
  494.  strcpy(parameter_names[0].name_a5, "unused");
  495.  strcpy(parameter_names[0].name_a6, "unused");
  496.  strcpy(parameter_names[0].name_a7, "unused");
  497.  strcpy(parameter_names[0].name_a8, "unused");
  498.  
  499.  
  500.  /* Parameter names for R(phi) distortion */
  501.  strcpy(parameter_names[1].name_a1, "Amplitude 1:");
  502.  strcpy(parameter_names[1].name_a2, "Frequency 1:");
  503.  strcpy(parameter_names[1].name_a3, "Amplitude 2:");
  504.  strcpy(parameter_names[1].name_a4, "Frequency 2");
  505.  strcpy(parameter_names[1].name_a5, "unused");
  506.  strcpy(parameter_names[1].name_a6, "unused");
  507.  strcpy(parameter_names[1].name_a7, "unused");
  508.  strcpy(parameter_names[1].name_a8, "unused");
  509.  
  510.  /* Parameter names for Phi(r) distortion */
  511.  strcpy(parameter_names[2].name_a1, "Linear coefficient:");
  512.  strcpy(parameter_names[2].name_a2, "Quadratic coefficient:");
  513.  strcpy(parameter_names[2].name_a3, "Cubic coefficient:");
  514.  strcpy(parameter_names[2].name_a4, "Quartic coefficient:");
  515.  strcpy(parameter_names[2].name_a5, "unused");
  516.  strcpy(parameter_names[2].name_a6, "unused");
  517.  strcpy(parameter_names[2].name_a7, "unused");
  518.  strcpy(parameter_names[2].name_a8, "unused");
  519.  
  520.  
  521.  /* Parameter names for Phi(phi) distortion */
  522.  strcpy(parameter_names[3].name_a1, "Amplitude 1:");
  523.  strcpy(parameter_names[3].name_a2, "Frequency 1:");
  524.  strcpy(parameter_names[3].name_a3, "Amplitude 2:");
  525.  strcpy(parameter_names[3].name_a4, "Frequency 2");
  526.  strcpy(parameter_names[3].name_a5, "unused");
  527.  strcpy(parameter_names[3].name_a6, "unused");
  528.  strcpy(parameter_names[3].name_a7, "unused");
  529.  strcpy(parameter_names[3].name_a8, "unused");
  530.  
  531.  
  532.  /* Parameter names for R(r)Phi(phi) distortion */
  533.  strcpy(parameter_names[4].name_a1, "Linear coefficient:");
  534.  strcpy(parameter_names[4].name_a2, "Quadratic coefficient:");
  535.  strcpy(parameter_names[4].name_a3, "Cubic coefficient:");
  536.  strcpy(parameter_names[4].name_a4, "Quartic coefficient:");
  537.  strcpy(parameter_names[4].name_a5, "Amplitude 1:");
  538.  strcpy(parameter_names[4].name_a6, "Frequency 1:");
  539.  strcpy(parameter_names[4].name_a7, "Amplitude 2:");
  540.  strcpy(parameter_names[4].name_a8, "Frequency 2");
  541.  
  542.  /* Parameter names for R(r)R(phi) distortion */
  543.  strcpy(parameter_names[5].name_a1, "Linear coefficient:");
  544.  strcpy(parameter_names[5].name_a2, "Quadratic coefficient:");
  545.  strcpy(parameter_names[5].name_a3, "Cubic coefficient:");
  546.  strcpy(parameter_names[5].name_a4, "Quartic coefficient:");
  547.  strcpy(parameter_names[5].name_a5, "Amplitude 1:");
  548.  strcpy(parameter_names[5].name_a6, "Frequency 1:");
  549.  strcpy(parameter_names[5].name_a7, "Amplitude 2:");
  550.  strcpy(parameter_names[5].name_a8, "Frequency 2");
  551.  
  552.  
  553.  /* Parameter names for Cosines distortion */
  554.  strcpy(parameter_names[6].name_a1, "x-Amplitude:");
  555.  strcpy(parameter_names[6].name_a2, "y-Amplitude:");
  556.  strcpy(parameter_names[6].name_a3, "x-Frequency #1:");
  557.  strcpy(parameter_names[6].name_a4, "x-Frequency #2:");
  558.  strcpy(parameter_names[6].name_a5, "y-Frequency #1:");
  559.  strcpy(parameter_names[6].name_a6, "y-Frequency #2:");
  560.  strcpy(parameter_names[6].name_a7, "unused:");
  561.  strcpy(parameter_names[6].name_a8, "unused");
  562.  
  563.  
  564.   /* Parameter names for Gauss distortion */
  565.  strcpy(parameter_names[7].name_a1, "x-Strength:");
  566.  strcpy(parameter_names[7].name_a2, "y-Strength:");
  567.  strcpy(parameter_names[7].name_a3, "x-Offset:");
  568.  strcpy(parameter_names[7].name_a4, "y-Offset:");
  569.  strcpy(parameter_names[7].name_a5, "x-Deviation:");
  570.  strcpy(parameter_names[7].name_a6, "y-Deviation:");
  571.  strcpy(parameter_names[7].name_a7, "unused:");
  572.  strcpy(parameter_names[7].name_a8, "unused");
  573.  
  574.  
  575.  
  576.  /* this paragraph initializes the letterings */
  577.  strcpy(parameter_values.lettering01, parameter_names[0].name_a1);
  578.  strcpy(parameter_values.lettering02, parameter_names[0].name_a2);
  579.  strcpy(parameter_values.lettering03, parameter_names[0].name_a3);
  580.  strcpy(parameter_values.lettering04, parameter_names[0].name_a4);
  581.  strcpy(parameter_values.lettering05, parameter_names[0].name_a5);
  582.  strcpy(parameter_values.lettering06, parameter_names[0].name_a6);
  583.  strcpy(parameter_values.lettering07, parameter_names[0].name_a7);
  584.  strcpy(parameter_values.lettering08, parameter_names[0].name_a8);
  585.  
  586.  
  587.  /* This section defines the 'effects' parameters */
  588.  SET_EFFECTS_PARAMS(FUNCTION_R_r, 0, 0.0, 0.0, 0.0, -3.5, 0.0, 0.0, 0.0, 0.0, FALSE, 0.5, 0.2);
  589.  SET_EFFECTS_PARAMS(FUNCTION_R_r, 1, -0.2, 0.0, 0.0, 4.0, 0.0, 0.0, 0.0, 0.0, FALSE, 0.5, 0.2);
  590.  SET_EFFECTS_PARAMS(FUNCTION_R_r, 2, 0.45, -0.4, -0.5, 0.0, 0.0, 0.0, 0.0, 0.0, FALSE, 0.5, 0.2);
  591.  SET_EFFECTS_PARAMS(FUNCTION_R_r, 3, -0.25, -0.5, 0.0, -4.5, 0.0, 0.0, 0.0, 0.0, TRUE, 0.3, 0.01);
  592.  SET_EFFECTS_PARAMS(FUNCTION_R_r, 4, 1.6, -2.5, -3.7, -1.0, 0.0, 0.0, 0.0, 0.0, FALSE, 0.5, 0.2);
  593.  SET_EFFECTS_PARAMS(FUNCTION_R_r, 5, 1.8, -0.8, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, TRUE, 0.0, 1.0);
  594.  SET_EFFECTS_PARAMS(FUNCTION_R_r, 6, -6.0, 4.0, -10.0, 0.0, 0.0, 0.0, 0.0, 0.0, TRUE, 0.0, 0.7);
  595.  SET_EFFECTS_PARAMS(FUNCTION_R_r, 7, 0.15, 0.2, 5.0, -1.3, 0.0, 0.0, 0.0, 0.0, TRUE, 0.2, 1.0);
  596.  SET_EFFECTS_PARAMS(FUNCTION_R_r, 8, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, FALSE, 0.5, 0.2);
  597.  
  598.  
  599.  
  600.  SET_EFFECTS_PARAMS(FUNCTION_R_phi, 0, -0.65, 0.35, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, FALSE, 0.5, 0.2);
  601.  SET_EFFECTS_PARAMS(FUNCTION_R_phi, 1, 0.1, 4.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, FALSE, 0.5, 0.2);
  602.  SET_EFFECTS_PARAMS(FUNCTION_R_phi, 2, 0.2, 6.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, FALSE, 0.5, 0.2);
  603.  SET_EFFECTS_PARAMS(FUNCTION_R_phi, 3, 0.2, 3.0, 0.5, 2.0, 0.0, 0.0, 0.0, 0.0, FALSE, 0.5, 0.2);
  604.  SET_EFFECTS_PARAMS(FUNCTION_R_phi, 4, 0.2, 3.0, 0.5, 2.0, 0.0, 0.0, 0.0, 0.0, TRUE, 0.0, 0.2);
  605.  SET_EFFECTS_PARAMS(FUNCTION_R_phi, 5, -1.0, -7.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, FALSE, 0.5, 0.2);
  606.  SET_EFFECTS_PARAMS(FUNCTION_R_phi, 6, 0.7, -0.85, -0.25, -0.4, 0.0, 0.0, 0.0, 0.0, TRUE, 0.0, 1.0);
  607.  SET_EFFECTS_PARAMS(FUNCTION_R_phi, 7, 0.0, 0.0, 10.0, -10.0, 0.0, 0.0, 0.0, 0.0, TRUE, 0.0, 0.7);
  608.  SET_EFFECTS_PARAMS(FUNCTION_R_phi, 8, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, FALSE, 0.5, 0.2);
  609.  
  610.  
  611.  
  612.  SET_EFFECTS_PARAMS(FUNCTION_Phi_r, 0, 1.3, 0.9, -10.0, -10.0, 0.0, 0.0, 0.0, 0.0, FALSE, 0.5, 0.2);
  613.  SET_EFFECTS_PARAMS(FUNCTION_Phi_r, 1, 1.5, 0.5, -4.2, -6.7, 0.0, 0.0, 0.0, 0.0, FALSE, 0.5, 0.2);
  614.  SET_EFFECTS_PARAMS(FUNCTION_Phi_r, 2, -2.1, 1.0, 2.45, 5.8, 0.0, 0.0, 0.0, 0.0, FALSE, 0.5, 0.2);
  615.  SET_EFFECTS_PARAMS(FUNCTION_Phi_r, 3, -1.9, 1.0, 1.0, 6.0, 0.0, 0.0, 0.0, 0.0, TRUE, 0.2, 1.0);
  616.  SET_EFFECTS_PARAMS(FUNCTION_Phi_r, 4, -4.0, 10.0, 10.0, 10.0, 0.0, 0.0, 0.0, 0.0, FALSE, 0.5, 0.2);
  617.  SET_EFFECTS_PARAMS(FUNCTION_Phi_r, 5, 0.6, 3.0, 10.0, 10.0, 0.0, 0.0, 0.0, 0.0, TRUE, 0.25, 0.01);
  618.  SET_EFFECTS_PARAMS(FUNCTION_Phi_r, 6, 0.0, 0.0, -1.85, -2.45, 0.0, 0.0, 0.0, 0.0, TRUE, 0.4, 0.01);
  619.  SET_EFFECTS_PARAMS(FUNCTION_Phi_r, 7, -0.8, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, TRUE, 0.4, 0.2);
  620.  SET_EFFECTS_PARAMS(FUNCTION_Phi_r, 8, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, FALSE, 0.5, 0.2);
  621.  
  622.  
  623.  
  624.  SET_EFFECTS_PARAMS(FUNCTION_Phi_phi, 0, 0.8, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, FALSE, 0.5, 0.2);
  625.  SET_EFFECTS_PARAMS(FUNCTION_Phi_phi, 1, -0.3, 10.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, FALSE, 0.5, 0.2);
  626.  SET_EFFECTS_PARAMS(FUNCTION_Phi_phi, 2, -0.3, 10.0, 0.9, 8.0, 0.0, 0.0, 0.0, 0.0, FALSE, 0.5, 0.2);
  627.  SET_EFFECTS_PARAMS(FUNCTION_Phi_phi, 3, -7.0, 10.0, 2.0, 1.0, 0.0, 0.0, 0.0, 0.0, TRUE, 0.0, 1.0);
  628.  SET_EFFECTS_PARAMS(FUNCTION_Phi_phi, 4, 1.0, 8.0, -1.0, 4.0, 0.0, 0.0, 0.0, 0.0, FALSE, 0.5, 0.2);
  629.  SET_EFFECTS_PARAMS(FUNCTION_Phi_phi, 5, -6.0, 4.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, TRUE, 0.25, 0.4);
  630.  SET_EFFECTS_PARAMS(FUNCTION_Phi_phi, 6, -5.0, 5.0, 10.0, 1.0, 0.0, 0.0, 0.0, 0.0, TRUE, 0.25, 0.4);
  631.  SET_EFFECTS_PARAMS(FUNCTION_Phi_phi, 7, -0.5, 3.0, -1.0, 1.0, 0.0, 0.0, 0.0, 0.0, FALSE, 0.5, 0.2);
  632.  SET_EFFECTS_PARAMS(FUNCTION_Phi_phi, 8, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, FALSE, 0.5, 0.2);
  633.  
  634.  
  635.  
  636.  SET_EFFECTS_PARAMS(FUNCTION_R_r_Phi_phi, 0, 1.0, 0.0, 0.0, 0.0, 0.8, 1.0, 0.0, 0.0, FALSE, 0.5, 0.2);
  637.  SET_EFFECTS_PARAMS(FUNCTION_R_r_Phi_phi, 1, 0.6, 0.0, 0.0, 0.0, -0.3, 10.0, 0.0, 0.0, FALSE, 0.5, 0.2);
  638.  SET_EFFECTS_PARAMS(FUNCTION_R_r_Phi_phi, 2, 0.3, -0.25, -2.5, 2.4, -0.3, 10.0, 0.9, 8.0, FALSE, 0.5, 0.2);
  639.  SET_EFFECTS_PARAMS(FUNCTION_R_r_Phi_phi, 3, -0.05, 0.0, 0.0, 0.0, -7.0, 10.0, 2.0, 1.0, TRUE, 0.0, 1.0);
  640.  SET_EFFECTS_PARAMS(FUNCTION_R_r_Phi_phi, 4, 1.85, -3.9, 0.0, 0.0, 1.0, 8.0, -1.0, 4.0, FALSE, 0.5, 0.2);
  641.  SET_EFFECTS_PARAMS(FUNCTION_R_r_Phi_phi, 5, 0.1, 0.0, 0.0, 0.0, -6.0, 4.0, 0.0, 0.0, TRUE, 0.25, 0.4);
  642.  SET_EFFECTS_PARAMS(FUNCTION_R_r_Phi_phi, 6, 0.3, -0.35, 0.4, -2.8, -5.0, 5.0, 10.0, 1.0, TRUE, 0.25, 0.4);
  643.  SET_EFFECTS_PARAMS(FUNCTION_R_r_Phi_phi, 7, -2.6, -0.6, -3.1, 10.0, -0.5, 3.0, -1.0, 1.0, FALSE, 0.5, 0.2);
  644.  SET_EFFECTS_PARAMS(FUNCTION_R_r_Phi_phi, 8, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, FALSE, 0.5, 0.2);
  645.  
  646.  
  647.  
  648.  SET_EFFECTS_PARAMS(FUNCTION_R_r_R_phi, 0, 0.0, 2.1, -0.5, 10.0 ,-0.65, 0.35, 0.0, 0.0, FALSE, 0.5, 0.2);
  649.  SET_EFFECTS_PARAMS(FUNCTION_R_r_R_phi, 1, 2.5, 0.0, 10.0, 6.0, 0.1, 4.0, 0.0, 0.0, FALSE, 0.5, 0.2);
  650.  SET_EFFECTS_PARAMS(FUNCTION_R_r_R_phi, 2, 0.75, -6.5, -2.6, 5.6, 0.2, 6.0, 0.0, 0.0, FALSE, 0.5, 0.2);
  651.  SET_EFFECTS_PARAMS(FUNCTION_R_r_R_phi, 3, 0.4, 1.0, 0.7, 0.7, 0.2, 3.0, 0.5, 2.0, FALSE, 0.5, 0.2);
  652.  SET_EFFECTS_PARAMS(FUNCTION_R_r_R_phi, 4, -1.0, -1.4, 1.3, 1.3, 0.2, 3.0, 0.5, 2.0, TRUE, 0.0, 0.2);
  653.  SET_EFFECTS_PARAMS(FUNCTION_R_r_R_phi, 5, 0.1, 0.4, -1.1, 0.1, -1.0, -7.0, 0.0, 0.0, FALSE, 0.5, 0.2);
  654.  SET_EFFECTS_PARAMS(FUNCTION_R_r_R_phi, 6, -10.0, -10.0, -10.0, -10.0, 0.7, -1.0, -0.25, 3.0, TRUE, 0.0, 1.0);
  655.  SET_EFFECTS_PARAMS(FUNCTION_R_r_R_phi, 7, 0.1, 0.35, -1.7, -2.3, 0.0, 0.0, 10.0, -10.0, TRUE, 0.0, 0.7);
  656.  SET_EFFECTS_PARAMS(FUNCTION_R_r_R_phi, 8, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, FALSE, 0.5, 0.2);
  657.  
  658.  
  659.  
  660.  
  661.  SET_EFFECTS_PARAMS(FUNCTION_Cosines, 0, 0.8, 0.0, 3.0, 0.0, 0.0, 0.0, 0.0, 0.0, FALSE, 0.5, 0.2);
  662.  SET_EFFECTS_PARAMS(FUNCTION_Cosines, 1, 2.75, -2.75, 3.0, 0.0, -3.0, 0.0, 0.0, 0.0, FALSE, 0.5, 0.2);
  663.  SET_EFFECTS_PARAMS(FUNCTION_Cosines, 2, 0.8, -0.8, 1.0, -1.6, -1.0, -1.4, 0.0, 0.0, FALSE, 0.5, 0.2);
  664.  SET_EFFECTS_PARAMS(FUNCTION_Cosines, 3, -0.1, -2.0, 1.0, -0.7, -10.0, -1.4, 0.0, 0.0, FALSE, 0.5, 0.2);
  665.  SET_EFFECTS_PARAMS(FUNCTION_Cosines, 4, -0.2, -2.0, 1.0, -10.0, 0.25, 6.7, 0.0, 0.0, TRUE, 0.5, 0.2);
  666.  SET_EFFECTS_PARAMS(FUNCTION_Cosines, 5, -6.2, 6.6, -3.8, -1.4, 2.0, 1.2, 0.0, 0.0, TRUE, 0.15, 1.0);
  667.  SET_EFFECTS_PARAMS(FUNCTION_Cosines, 6, -6.2, 6.6, -3.8, -1.4, 2.0, 1.2, 0.0, 0.0, FALSE, 0.5, 0.2);
  668.  SET_EFFECTS_PARAMS(FUNCTION_Cosines, 7, 10.0, 10.0, -1.7, -1.7, 2.1, 2.1, 0.0, 0.0, TRUE, 0.3, 0.6);
  669.  SET_EFFECTS_PARAMS(FUNCTION_Cosines, 8, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, FALSE, 0.5, 0.2);
  670.  
  671.  
  672.  
  673.  SET_EFFECTS_PARAMS(FUNCTION_Gauss, 0, 4.0, 0.0, 0.0, 0.0, -9.0, 0.0, 0.0, 0.0, FALSE, 0.5, 0.2);
  674.  SET_EFFECTS_PARAMS(FUNCTION_Gauss, 1, 4.0, 4.0, 0.0, 0.0, -9.0, -9.0, 0.0, 0.0, FALSE, 0.5, 0.2);
  675.  SET_EFFECTS_PARAMS(FUNCTION_Gauss, 2, 4.0, 4.0, 0.0, 0.0, -9.0, -9.0, 0.0, 0.0, TRUE, 0.0, 1.0);
  676.  SET_EFFECTS_PARAMS(FUNCTION_Gauss, 3, 0.0, -2.4, 0.0, -3.0, 0.0, 0.0, 0.0, 0.0, FALSE, 0.5, 0.2);
  677.  SET_EFFECTS_PARAMS(FUNCTION_Gauss, 4, 2.3, -3.4, 0.0, -3.0, -9.0, 0.2, 0.0, 0.0, TRUE, 0.0, 1.0);
  678.  SET_EFFECTS_PARAMS(FUNCTION_Gauss, 5, 10.0, -10.0, 4.0, -3.0, -6.0, 5.6, 0.0, 0.0, TRUE, 0.05, 0.5);
  679.  SET_EFFECTS_PARAMS(FUNCTION_Gauss, 6, 5.25, 0.0, -10.0, 0.0, 0.0, 0.0, 0.0, 0.0, TRUE, 0.25, 1.0);
  680.  SET_EFFECTS_PARAMS(FUNCTION_Gauss, 7, -10.0, 0.0, 10.0, 0.0, 0.0, 0.0, 0.0, 0.0, TRUE, 0.05, 1.0);
  681.  
  682.  SET_EFFECTS_PARAMS(FUNCTION_Gauss, 8, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0, 0.5, 0.2);
  683.  
  684.  
  685.  
  686.  
  687.  switch (run_mode)
  688.  {
  689.   case RUN_INTERACTIVE: /*  Possibly retrieve data  */
  690.                         gimp_get_data(PluginResource, ¶meter_values);
  691.                                  
  692.                         /*  Create the preview  */
  693.                         create_preview(drawable);
  694.  
  695.                         /*  First acquire information with a dialog  */
  696.                         if(! user_dialog ()) return;                       
  697.                         break;
  698.  
  699.   case RUN_NONINTERACTIVE: /*  Make sure all the arguments are there!  */
  700.                            
  701.                            if(nparams != N_PARAMETERS) status = STATUS_CALLING_ERROR;
  702.                            if(status == STATUS_SUCCESS)
  703.                        {
  704.                         parameter_values.a1 =                param[3].data.d_float;
  705.                         parameter_values.a2 =                param[4].data.d_float;
  706.                         parameter_values.a3 =                param[5].data.d_float;
  707.                         parameter_values.a4 =                param[6].data.d_float;
  708.                         parameter_values.a5 =                param[7].data.d_float;
  709.                         parameter_values.a6 =                param[8].data.d_float;
  710.                         parameter_values.a7 =                param[9].data.d_float;
  711.                         parameter_values.a8 =                param[10].data.d_float;
  712.                         parameter_values.use_cutoff =        param[11].data.d_int32;
  713.                         parameter_values.r =                 param[12].data.d_float;
  714.                         parameter_values.dr =                param[13].data.d_float;
  715.                         parameter_values.current_function =  param[14].data.d_int32;
  716.                        }
  717.       
  718.                            break;
  719.  
  720.   case RUN_WITH_LAST_VALS: /*  Possibly retrieve data  */
  721.                            gimp_get_data(PluginResource, ¶meter_values);
  722.                            break;
  723.  
  724.   default: break;
  725.  }
  726.  
  727.  /*  Make sure that the drawable is gray or RGB color  */
  728.  if(gimp_drawable_color(drawable->id) || gimp_drawable_gray(drawable->id))
  729.  {
  730.   if(do_action == 0) gimp_progress_init(PluginName);
  731.  
  732.   /* set the tile cache size  */
  733.   gimp_tile_cache_ntiles(2 * (MAX(drawable->width, drawable->height) / gimp_tile_width () + 1));
  734.   
  735.   
  736.   if(do_action == 0) image_action(drawable, parameter_values);
  737.  
  738.   if(run_mode != RUN_NONINTERACTIVE) gimp_displays_flush();
  739.  
  740.   /*  Store parameter data  */
  741.   if(run_mode == RUN_INTERACTIVE) gimp_set_data(PluginResource, ¶meter_values, sizeof(Parameters));
  742.  }
  743.  else
  744.  {
  745.   status = STATUS_EXECUTION_ERROR;
  746.  }
  747.  
  748.  values[0].data.d_status = status;
  749.  gimp_drawable_detach(drawable);
  750. }
  751.  
  752.  
  753.  
  754.  
  755.  
  756. /******************************************************************************/
  757. /*                       Dialog creation functions                            */
  758. /******************************************************************************/
  759.  
  760. /* create_base_dialog() creates the dialog window and the action area. */
  761. static void create_base_dialog(void)
  762. {
  763.  dtd.argc = 1;
  764.  dtd.argv = g_new(gchar *, 1);
  765.  dtd.argv[0] = g_strdup(PluginName);
  766.  
  767.  gtk_init(&dtd.argc, &dtd.argv);
  768.  gtk_rc_parse(gimp_gtkrc ());
  769.  
  770.  dtd.dlg = gtk_dialog_new();
  771.  gtk_window_set_title(GTK_WINDOW(dtd.dlg), PluginName);
  772.  gtk_window_position(GTK_WINDOW(dtd.dlg), GTK_WIN_POS_MOUSE);
  773.  gtk_signal_connect(GTK_OBJECT(dtd.dlg), "destroy",
  774.              (GtkSignalFunc)close_callback,
  775.              NULL);
  776.  
  777.  /*  Action area  */
  778.  dtd.ok_button = gtk_button_new_with_label("OK");
  779.  GTK_WIDGET_SET_FLAGS(dtd.ok_button, GTK_CAN_DEFAULT);
  780.  gtk_signal_connect(GTK_OBJECT (dtd.ok_button), "clicked",
  781.                    (GtkSignalFunc) ok_callback, GTK_OBJECT(dtd.dlg));
  782.  gtk_box_pack_start(GTK_BOX (GTK_DIALOG (dtd.dlg)->action_area), dtd.ok_button, TRUE, TRUE, 0);
  783.  gtk_widget_grab_default(dtd.ok_button);
  784.  gtk_widget_show(dtd.ok_button);
  785.  
  786.  dtd.cancel_button = gtk_button_new_with_label("Cancel");
  787.  GTK_WIDGET_SET_FLAGS(dtd.cancel_button, GTK_CAN_DEFAULT);
  788.  gtk_signal_connect_object(GTK_OBJECT(dtd.cancel_button), "clicked",
  789.               (GtkSignalFunc)cancel_callback,
  790.                GTK_OBJECT(dtd.dlg));
  791.  gtk_box_pack_start(GTK_BOX (GTK_DIALOG (dtd.dlg)->action_area), dtd.cancel_button, TRUE, TRUE, 0);
  792.  gtk_widget_show(dtd.cancel_button);
  793. }
  794.  
  795.  
  796.  
  797. /* Not really surprisingly this functon creates a slider and a label. */
  798. /* The widget returned is the GtkObject *data, NOT the slider widget!!! */
  799. static ObjectAndLabel create_slider_with_label(gchar *text, GtkWidget *container, GtkSignalFunc callback_func, gfloat initial_value, gfloat min_value, gfloat max_value)
  800. {
  801.  GtkObject *data;
  802.  GtkWidget *label;
  803.  GtkWidget *slider_field;
  804.  GtkWidget *slider_widget;
  805.  
  806.  ObjectAndLabel ret;
  807.  
  808.  
  809.  slider_field = gtk_hbox_new(FALSE, 1);
  810.  gtk_container_border_width(GTK_CONTAINER(slider_field), 2);
  811.  gtk_box_pack_start(GTK_BOX(container), slider_field, TRUE, TRUE, 0);
  812.  
  813.  label = gtk_label_new(text);
  814.  gtk_widget_set_usize(label, 140, 0);
  815.  gtk_box_pack_start(GTK_BOX(slider_field), label, TRUE, TRUE, 0);
  816.  gtk_misc_set_alignment(GTK_MISC(label), 0.0, 1.0);
  817.  gtk_widget_show(label);
  818.  
  819.  data = gtk_adjustment_new(initial_value, min_value, max_value, 0.01, 0.01, 0);
  820.  slider_widget = gtk_hscale_new(GTK_ADJUSTMENT(data));
  821.  gtk_box_pack_start(GTK_BOX(slider_field), slider_widget, TRUE, TRUE, 0);
  822.  
  823.  gtk_widget_set_usize(slider_widget, 300, 0);
  824.  gtk_scale_set_value_pos(GTK_SCALE(slider_widget), GTK_POS_TOP);
  825.  gtk_scale_set_digits(GTK_SCALE(slider_widget), 2);
  826.  gtk_range_set_update_policy(GTK_RANGE(slider_widget), GTK_UPDATE_DELAYED);
  827.  
  828.  gtk_signal_connect(GTK_OBJECT(data), "value_changed",
  829.            (GtkSignalFunc)callback_func,
  830.             &initial_value);
  831.  
  832.  gtk_widget_show(slider_widget);
  833.  gtk_widget_show(slider_field);
  834.  
  835.  ret.object = (GtkWidget *)data;
  836.  ret.label = (GtkLabel *)label;
  837.  return(ret);
  838. }
  839.  
  840.  
  841.  
  842. /*                        WARNING                    */
  843. /* I need this function, taken directly from the gtk code, here.
  844.    My linker refuses to link this function from the gtk library.
  845.    
  846.    Further information:
  847.    
  848.    GIMP version:   0.99.10
  849.    gcc  version:   2.7.2.
  850.    ld   version:   cygnus-2.6 (with BFD 2.6.0.14)
  851.    
  852.    All other gtk functions worked so far.
  853.    
  854.                                 Peter
  855. */
  856. static void
  857. gtk_option_menu_remove_contents(GtkOptionMenu *option_menu)
  858. {
  859.   g_return_if_fail (option_menu != NULL);
  860.   g_return_if_fail (GTK_IS_OPTION_MENU (option_menu));
  861.  
  862.   if (GTK_BUTTON (option_menu)->child)
  863.     {
  864.       gtk_container_block_resize (GTK_CONTAINER (option_menu));
  865.       if (GTK_WIDGET (option_menu->menu_item)->state != GTK_BUTTON (option_menu)->child->state)
  866.     gtk_widget_set_state (GTK_BUTTON (option_menu)->child,
  867.                   GTK_WIDGET (option_menu->menu_item)->state);
  868.       GTK_WIDGET_UNSET_FLAGS (GTK_BUTTON (option_menu)->child, GTK_MAPPED | GTK_REALIZED);
  869.       gtk_widget_reparent (GTK_BUTTON (option_menu)->child, option_menu->menu_item);
  870.       gtk_container_unblock_resize (GTK_CONTAINER (option_menu));
  871.       option_menu->menu_item = NULL;
  872.     }
  873. }
  874.  
  875.  
  876.  
  877.  
  878. static void create_functions_menu(GtkWidget *container)
  879. {
  880.  GtkWidget *menu_field;
  881.  GtkWidget *label;
  882.  GtkWidget *menu;
  883.  GtkWidget *menuitem;
  884.  GtkWidget *chooser;
  885.  GtkWidget *child;
  886.  GtkWidget *current_item;
  887.  gint dummy;
  888.  
  889.  /* current_item must be initialized in order to prevent warnings */
  890.  current_item = NULL;
  891.  
  892.  menu_field = gtk_hbox_new(FALSE, 1);
  893.  gtk_container_border_width(GTK_CONTAINER(menu_field), 2);
  894.  gtk_box_pack_start(GTK_BOX(container), menu_field, TRUE, TRUE, 0);
  895.  
  896.  label = gtk_label_new("Functions:");
  897.  gtk_widget_set_usize(label, 70, 0);
  898.  gtk_box_pack_start(GTK_BOX(menu_field), label, TRUE, TRUE, 0);
  899.  gtk_widget_show(label);
  900.  
  901.  
  902.  chooser = gtk_option_menu_new();
  903.  gtk_box_pack_start(GTK_BOX(menu_field), chooser, TRUE, TRUE, 0);
  904.  gtk_widget_set_usize(chooser, 180, 0);
  905.  
  906.  
  907.  menu = gtk_menu_new();
  908.  
  909.  
  910.  menuitem = gtk_menu_item_new_with_label("R(r) - 4th order poly");
  911.  gtk_menu_append(GTK_MENU(menu), menuitem);
  912.  gtk_signal_connect(GTK_OBJECT(menuitem), "activate", (GtkSignalFunc)function01_callback, &dummy);
  913.  gtk_widget_show(menuitem);
  914.  if(parameter_values.current_function == FUNCTION_R_r) current_item = menuitem;
  915.  
  916.  menuitem = gtk_menu_item_new_with_label("R(phi) - cosine");
  917.  gtk_menu_append(GTK_MENU(menu), menuitem);
  918.  gtk_signal_connect(GTK_OBJECT(menuitem), "activate", (GtkSignalFunc)function02_callback, &dummy);
  919.  gtk_widget_show(menuitem);
  920.  if(parameter_values.current_function == FUNCTION_R_phi) current_item = menuitem;
  921.  
  922.  menuitem = gtk_menu_item_new_with_label("Phi(r) - 4th order poly");
  923.  gtk_menu_append(GTK_MENU(menu), menuitem);
  924.  gtk_signal_connect(GTK_OBJECT(menuitem), "activate", (GtkSignalFunc)function03_callback, &dummy);
  925.  gtk_widget_show(menuitem);
  926.  if(parameter_values.current_function == FUNCTION_Phi_r) current_item = menuitem;
  927.  
  928.  menuitem = gtk_menu_item_new_with_label("Phi(phi) - cosine");
  929.  gtk_menu_append(GTK_MENU(menu), menuitem);
  930.  gtk_signal_connect(GTK_OBJECT(menuitem), "activate", (GtkSignalFunc)function04_callback, &dummy);
  931.  gtk_widget_show(menuitem);
  932.  if(parameter_values.current_function == FUNCTION_Phi_phi) current_item = menuitem;
  933.  
  934.  menuitem = gtk_menu_item_new_with_label("R(r)Phi(phi)");
  935.  gtk_menu_append(GTK_MENU(menu), menuitem);
  936.  gtk_signal_connect(GTK_OBJECT(menuitem), "activate", (GtkSignalFunc)function05_callback, &dummy);
  937.  gtk_widget_show(menuitem);
  938.  if(parameter_values.current_function == FUNCTION_R_r_Phi_phi) current_item = menuitem;
  939.  
  940.  menuitem = gtk_menu_item_new_with_label("R(r)R(phi)");
  941.  gtk_menu_append(GTK_MENU(menu), menuitem);
  942.  gtk_signal_connect(GTK_OBJECT(menuitem), "activate", (GtkSignalFunc)function06_callback, &dummy);
  943.  gtk_widget_show(menuitem);
  944.  if(parameter_values.current_function == FUNCTION_R_r_R_phi) current_item = menuitem;
  945.  
  946.  menuitem = gtk_menu_item_new_with_label("Cosines");
  947.  gtk_menu_append(GTK_MENU(menu), menuitem);
  948.  gtk_signal_connect(GTK_OBJECT(menuitem), "activate", (GtkSignalFunc)function07_callback, &dummy);
  949.  gtk_widget_show(menuitem);
  950.  if(parameter_values.current_function == FUNCTION_Cosines) current_item = menuitem;
  951.  
  952.  menuitem = gtk_menu_item_new_with_label("Gauss");
  953.  gtk_menu_append(GTK_MENU(menu), menuitem);
  954.  gtk_signal_connect(GTK_OBJECT(menuitem), "activate", (GtkSignalFunc)function08_callback, &dummy);
  955.  gtk_widget_show(menuitem);
  956.  if(parameter_values.current_function == FUNCTION_Gauss) current_item = menuitem;
  957.  
  958.  
  959.  
  960.  gtk_option_menu_set_menu(GTK_OPTION_MENU(chooser), menu);
  961.  
  962.  /* BEGIN - This code was taken from gtk 0.99.10*/
  963.  
  964.  /* Update the chooser in order to display the CORRECT function */
  965.  gtk_option_menu_remove_contents(GTK_OPTION_MENU(chooser));
  966.  
  967.  GTK_OPTION_MENU(chooser)->menu_item = current_item;
  968.  child = GTK_BIN(GTK_OPTION_MENU(chooser)->menu_item)->child;
  969.  if(child)
  970.  {
  971.   gtk_container_block_resize(GTK_CONTAINER(chooser));
  972.   if(GTK_WIDGET(chooser)->state != child->state)
  973.         gtk_widget_set_state (child, GTK_WIDGET(chooser)->state);
  974.   gtk_widget_reparent(child, GTK_WIDGET(chooser));
  975.   gtk_container_unblock_resize(GTK_CONTAINER(chooser));
  976.  }
  977.  
  978.  gtk_widget_size_allocate(GTK_WIDGET(chooser), &(GTK_WIDGET(chooser)->allocation));
  979.  
  980.  if(GTK_WIDGET_DRAWABLE(chooser)) gtk_widget_draw(GTK_WIDGET(chooser), NULL);
  981.  
  982.  /* END - This code was taken from gtk 0.99.10. Thanks to the developers.*/
  983.  
  984.  
  985.  gtk_widget_show(chooser);
  986.  
  987.  
  988.  gtk_widget_show(menu_field);
  989. }
  990.                                   
  991.                                   
  992.                                   
  993.                                   
  994.                                                
  995. static void create_effects_menu(GtkWidget *container)
  996. {
  997.  GtkWidget *menu_field;
  998.  GtkWidget *label;
  999.  GtkWidget *menu;
  1000.  GtkWidget *menuitem;
  1001.  GtkWidget *chooser;
  1002.  
  1003.  gint dummy;
  1004.  
  1005.  menu_field = gtk_hbox_new(FALSE, 1);
  1006.  gtk_container_border_width(GTK_CONTAINER(menu_field), 2);
  1007.  gtk_box_pack_start(GTK_BOX(container), menu_field, TRUE, TRUE, 0);
  1008.  
  1009.  label = gtk_label_new("Effects:");
  1010.  gtk_widget_set_usize(label, 70, 0);
  1011.  gtk_box_pack_start(GTK_BOX(menu_field), label, TRUE, TRUE, 0);
  1012.  gtk_widget_show(label);
  1013.  
  1014.  
  1015.  menu = gtk_menu_new();
  1016.  
  1017.  
  1018.  menuitem = gtk_menu_item_new_with_label("Effect #1");
  1019.  gtk_menu_append(GTK_MENU(menu), menuitem);
  1020.  gtk_signal_connect(GTK_OBJECT(menuitem), "activate", (GtkSignalFunc)effect01_callback, &dummy); 
  1021.  gtk_widget_show(menuitem);
  1022.  
  1023.  menuitem = gtk_menu_item_new_with_label("Effect #2");
  1024.  gtk_menu_append(GTK_MENU(menu), menuitem);
  1025.  gtk_signal_connect(GTK_OBJECT(menuitem), "activate", (GtkSignalFunc)effect02_callback, &dummy); 
  1026.  gtk_widget_show(menuitem);
  1027.  
  1028.  menuitem = gtk_menu_item_new_with_label("Effect #3");
  1029.  gtk_menu_append(GTK_MENU(menu), menuitem);
  1030.  gtk_signal_connect(GTK_OBJECT(menuitem), "activate", (GtkSignalFunc)effect03_callback, &dummy);  
  1031.  gtk_widget_show(menuitem);
  1032.  
  1033.  menuitem = gtk_menu_item_new_with_label("Effect #4");
  1034.  gtk_menu_append(GTK_MENU(menu), menuitem);
  1035.  gtk_signal_connect(GTK_OBJECT(menuitem), "activate", (GtkSignalFunc)effect04_callback, &dummy); 
  1036.  gtk_widget_show(menuitem);
  1037.  
  1038.  menuitem = gtk_menu_item_new_with_label("Effect #5");
  1039.  gtk_menu_append(GTK_MENU(menu), menuitem);
  1040.  gtk_signal_connect(GTK_OBJECT(menuitem), "activate", (GtkSignalFunc)effect05_callback, &dummy);  
  1041.  gtk_widget_show(menuitem);
  1042.  
  1043.  menuitem = gtk_menu_item_new_with_label("Effect #6");
  1044.  gtk_menu_append(GTK_MENU(menu), menuitem);
  1045.  gtk_signal_connect(GTK_OBJECT(menuitem), "activate", (GtkSignalFunc)effect06_callback, &dummy); 
  1046.  gtk_widget_show(menuitem);
  1047.  
  1048.  menuitem = gtk_menu_item_new_with_label("Effect #7");
  1049.  gtk_menu_append(GTK_MENU(menu), menuitem);
  1050.  gtk_signal_connect(GTK_OBJECT(menuitem), "activate", (GtkSignalFunc)effect07_callback, &dummy); 
  1051.  gtk_widget_show(menuitem);
  1052.  
  1053.  menuitem = gtk_menu_item_new_with_label("Effect #8");
  1054.  gtk_menu_append(GTK_MENU(menu), menuitem);
  1055.  gtk_signal_connect(GTK_OBJECT(menuitem), "activate", (GtkSignalFunc)effect08_callback, &dummy);
  1056.  gtk_widget_show(menuitem);
  1057.  
  1058.  menuitem = gtk_menu_item_new_with_label("Reset");
  1059.  gtk_menu_append(GTK_MENU(menu), menuitem);
  1060.  gtk_signal_connect(GTK_OBJECT(menuitem), "activate", (GtkSignalFunc)effect09_callback, &dummy);
  1061.  gtk_widget_show(menuitem);
  1062.  
  1063.  
  1064.  
  1065.  
  1066.  
  1067.  chooser = gtk_option_menu_new();
  1068.  gtk_box_pack_start(GTK_BOX(menu_field), chooser, TRUE, TRUE, 0);
  1069.  
  1070.  gtk_widget_set_usize(chooser, 180, 0);
  1071.  
  1072.  
  1073.  gtk_option_menu_set_menu(GTK_OPTION_MENU(chooser), menu);
  1074.  gtk_widget_show(chooser);
  1075.  
  1076.  
  1077.  gtk_widget_show(menu_field);
  1078. }
  1079.                  
  1080.  
  1081.  
  1082.  
  1083.  
  1084. /* This function creates the panel for the cutoff function parameters. */
  1085. static void create_cutoff_panel(GtkWidget *container)
  1086. {
  1087.  GtkObject *data;
  1088.  GtkWidget *label;
  1089.  GtkWidget *slider;
  1090.  GtkWidget *toggle;
  1091.  
  1092.  gfloat dummy;
  1093.  gint int_dummy;
  1094.  
  1095.  
  1096.  toggle = gtk_check_button_new_with_label("Use cutoff");
  1097.  widget_data.toggle01 = toggle;
  1098.  gtk_box_pack_start(GTK_BOX(container), toggle, FALSE, FALSE, 0);
  1099.  gtk_signal_connect(GTK_OBJECT(toggle), "toggled",
  1100.            (GtkSignalFunc)use_cutoff_callback,
  1101.             &int_dummy);
  1102.  gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(toggle), parameter_values.use_cutoff);
  1103.  
  1104.  gtk_misc_set_alignment(GTK_MISC(toggle), 0.0, 0.5);
  1105.  gtk_widget_show (toggle);
  1106.  
  1107.  
  1108.  label = gtk_label_new("r");
  1109.  gtk_box_pack_start(GTK_BOX(container), label, TRUE, TRUE, 0);
  1110.  gtk_misc_set_alignment(GTK_MISC(label), 0.8, 0.5);
  1111.  gtk_widget_show(label);
  1112.  
  1113.  
  1114.  data = gtk_adjustment_new(parameter_values.r, 0.0, 1.0, 0.01, 0.01, 0);
  1115.  widget_data.slider09 = (GtkWidget *)data;
  1116.  slider = gtk_hscale_new(GTK_ADJUSTMENT(data));
  1117.  gtk_box_pack_start(GTK_BOX(container), slider, TRUE, TRUE, 0);
  1118.  
  1119.  gtk_widget_set_usize(slider, 100, 0);
  1120.  gtk_scale_set_value_pos(GTK_SCALE(slider), GTK_POS_TOP);
  1121.  gtk_scale_set_digits(GTK_SCALE(slider), 2);
  1122.  gtk_range_set_update_policy(GTK_RANGE(slider), GTK_UPDATE_DELAYED);
  1123.  
  1124.  gtk_signal_connect(GTK_OBJECT(data), "value_changed",
  1125.            (GtkSignalFunc)r_callback,
  1126.             &dummy);
  1127.             
  1128.  gtk_widget_show(slider);
  1129.  
  1130.              
  1131.             
  1132.             
  1133.  label = gtk_label_new("dr");
  1134.  gtk_box_pack_start(GTK_BOX(container), label, TRUE, TRUE, 0);
  1135.  gtk_misc_set_alignment(GTK_MISC(label), 0.8, 0.5);
  1136.  gtk_widget_show(label);
  1137.  
  1138.  data = gtk_adjustment_new(parameter_values.dr, 0.01, 1.0, 0.01, 0.01, 0);
  1139.  widget_data.slider10 = (GtkWidget *)data;
  1140.  slider = gtk_hscale_new(GTK_ADJUSTMENT(data));
  1141.  gtk_box_pack_start(GTK_BOX(container), slider, TRUE, TRUE, 0);
  1142.  
  1143.  gtk_widget_set_usize(slider, 100, 0);
  1144.  gtk_scale_set_value_pos(GTK_SCALE(slider), GTK_POS_TOP);
  1145.  gtk_scale_set_digits(GTK_SCALE(slider), 2);
  1146.  gtk_range_set_update_policy(GTK_RANGE(slider), GTK_UPDATE_DELAYED);
  1147.  
  1148.  gtk_signal_connect(GTK_OBJECT(data), "value_changed",
  1149.            (GtkSignalFunc)dr_callback,
  1150.             &dummy);            
  1151.             
  1152.  gtk_widget_show(slider);            
  1153.                                       
  1154. }
  1155.  
  1156.  
  1157.  
  1158. /* This function creates a preview. It should be called only once. */
  1159. /* This function writes all data to a global PreviewData preview_data */
  1160. static void create_preview(GDrawable *drawable)
  1161. {
  1162.  gint i, j;
  1163.  gint x0, y0;
  1164.  gint x1, y1, x2, y2;
  1165.  gint image_width, image_height;
  1166.  guchar *image_bytes;
  1167.  gint image_bpp;
  1168.  gint offset;
  1169.  gint count;
  1170.  gfloat delta_pixel;
  1171.  
  1172.  GPixelRgn image_rgn;
  1173.  
  1174.  
  1175.  gimp_drawable_mask_bounds(drawable->id, &x1, &y1, &x2, &y2);
  1176.  
  1177.  image_width = (x2 - x1);
  1178.  image_height = (y2 - y1);
  1179.  image_bpp = drawable->bpp;
  1180.  image_bytes = (guchar *)malloc(image_bpp*image_width);
  1181.  
  1182.  
  1183.  if(image_width > image_height)
  1184.  {
  1185.   preview_data.scale = (gfloat)image_width/(gfloat)preview_width;
  1186.   preview_data.width = preview_width;
  1187.   preview_data.height = (gfloat)(image_height)/(preview_data.scale);
  1188.   x0 = 0;
  1189.   y0 = (preview_height - preview_data.height)/2;
  1190.  }
  1191.  else
  1192.  {
  1193.   preview_data.scale = (gfloat)image_height/(gfloat)preview_height;
  1194.   preview_data.height = preview_height;
  1195.   preview_data.width = (gfloat)(image_width)/(preview_data.scale);
  1196.   x0 = (preview_width - preview_data.width)/2;
  1197.   y0 = 0;
  1198.  }
  1199.  
  1200.  preview_data.bpp = 3;
  1201.  
  1202.  preview_data.bits = (guchar *)malloc(preview_data.bpp*preview_width*preview_height);
  1203.  
  1204.  /* Clear the preview area */
  1205.  count = 0;
  1206.  for(i = 0; i < preview_data.bpp*preview_width*preview_height; i++) preview_data.bits[count++] = 0;
  1207.  
  1208.  
  1209.  /* Copy a thumbnail of the original image to the preview image. */
  1210.  gimp_pixel_rgn_init(&image_rgn, drawable, 0, 0, drawable->width, drawable->height, FALSE, FALSE);
  1211.  
  1212.  for(j = 0; j < preview_data.height; j++)
  1213.  {
  1214.   offset = preview_data.bpp*((y0 + j)*preview_width + x0);
  1215.   count = 0;
  1216.   delta_pixel = 0.0;
  1217.   gimp_pixel_rgn_get_row(&image_rgn, image_bytes, x1, y1 + (int)(preview_data.scale*(gfloat)j), image_width);
  1218.   
  1219.   for(i = 0; i < preview_data.width; i++)
  1220.   {
  1221.    switch(image_bpp)
  1222.    {
  1223.     case 4:  preview_data.bits[offset++] = image_bytes[count++];
  1224.              preview_data.bits[offset++] = image_bytes[count++];
  1225.              preview_data.bits[offset++] = image_bytes[count++];
  1226.    
  1227.              delta_pixel += preview_data.scale;
  1228.              count = 4*(int)delta_pixel;
  1229.              break;
  1230.              
  1231.     case 3:  preview_data.bits[offset++] = image_bytes[count++];
  1232.              preview_data.bits[offset++] = image_bytes[count++];
  1233.              preview_data.bits[offset++] = image_bytes[count++];
  1234.    
  1235.              delta_pixel += preview_data.scale;
  1236.              count = 3*(int)delta_pixel;
  1237.              break;
  1238.              
  1239.     case 2:  preview_data.bits[offset++] = image_bytes[count];
  1240.              preview_data.bits[offset++] = image_bytes[count];
  1241.              preview_data.bits[offset++] = image_bytes[count];
  1242.    
  1243.              delta_pixel += preview_data.scale;
  1244.              count = 2*(int)delta_pixel;
  1245.              break;
  1246.              
  1247.      case 1: preview_data.bits[offset++] = image_bytes[count];
  1248.              preview_data.bits[offset++] = image_bytes[count];
  1249.              preview_data.bits[offset++] = image_bytes[count];
  1250.    
  1251.              delta_pixel += preview_data.scale;
  1252.              count = (int)delta_pixel;
  1253.              break;
  1254.              
  1255.    }
  1256.   }
  1257.  } 
  1258. }
  1259.  
  1260.  
  1261.  
  1262. /* This function re-calculates the preview image and displays it */
  1263. static void update_preview(GtkWidget *preview)
  1264. {
  1265.  guchar *dest;
  1266.  gint i, j;
  1267.  gfloat u, v;
  1268.  gint count;
  1269.  
  1270.  if(do_update_preview != 1) return;
  1271.  
  1272.  dest = (guchar *)malloc(3*preview_width);
  1273.  
  1274.  
  1275.  /* Distort and display the preview */
  1276.  for(j = 0; j < preview_height; j++)
  1277.  {
  1278.   count = 0;
  1279.   for(i = 0; i < preview_width; i++)
  1280.   {
  1281.    calculate_distortion_function(i, j, preview_width, preview_height, &u, &v);
  1282.    
  1283.    if((u >= 0) && (u < preview_width) && (v >= 0) && (v < preview_height))
  1284.    {         
  1285.     dest[count] = preview_data.bits[3*((int)v*preview_width + (int)u)]; count++;
  1286.     dest[count] = preview_data.bits[3*((int)v*preview_width + (int)u)+1]; count++;
  1287.     dest[count] = preview_data.bits[3*((int)v*preview_width + (int)u)+2]; count++;           
  1288.    }
  1289.    else
  1290.    {
  1291.     dest[count] = 0; count++;
  1292.     dest[count] = 0; count++;
  1293.     dest[count] = 0; count++;             
  1294.    }
  1295.   }
  1296.   gtk_preview_draw_row(GTK_PREVIEW(preview), dest, 0, j, preview_width);      
  1297.  }
  1298.             
  1299.            
  1300.  gtk_widget_draw(preview, NULL);
  1301.  
  1302.  free(dest);                 
  1303. }
  1304.  
  1305.  
  1306.  
  1307.  
  1308. /* This function creates the complete user dialog */
  1309. static gint user_dialog()
  1310. {
  1311.  GtkWidget *frame;
  1312.  
  1313.  GtkWidget *main_box;
  1314.  GtkWidget *north_box;
  1315.  GtkWidget *south_box;
  1316.  GtkWidget *west_box;
  1317.  
  1318.  GtkWidget *preview_box;
  1319.  GtkWidget *parameter_box;
  1320.  GtkWidget *cutoff_box;
  1321.  
  1322.  GtkWidget *preview_frame;
  1323.  GtkWidget *preview_display;
  1324.  
  1325.  GtkWidget *functions_frame;
  1326.  GtkWidget *functions_box;
  1327.  
  1328.  ObjectAndLabel oal;
  1329.  
  1330.  /* Create a basic dialog window */
  1331.  create_base_dialog();
  1332.  
  1333.  
  1334.  /*  The main box -- contains the north and south box  */
  1335.  main_box = gtk_vbox_new(FALSE, 1);
  1336.  gtk_container_border_width(GTK_CONTAINER(main_box), 15);
  1337.  gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dtd.dlg)->vbox), main_box, TRUE, TRUE, 0);
  1338.  
  1339.  
  1340.  /* Add the north box */
  1341.  north_box = gtk_hbox_new(FALSE, 1);
  1342.  gtk_box_pack_start(GTK_BOX(main_box), north_box, TRUE, TRUE, 0);
  1343.  
  1344.  
  1345.  west_box = gtk_vbox_new(FALSE, 0);
  1346.  gtk_container_border_width(GTK_CONTAINER(west_box), 0);
  1347.  gtk_container_add(GTK_CONTAINER(north_box), west_box);
  1348.  
  1349.  /* Add the preview display */ 
  1350.  preview_frame = gtk_frame_new("Preview image");
  1351.  gtk_frame_set_shadow_type(GTK_FRAME(preview_frame), GTK_SHADOW_ETCHED_IN);
  1352.  gtk_box_pack_start(GTK_BOX(west_box), preview_frame, TRUE, TRUE, 0);
  1353.  
  1354.  preview_box = gtk_vbox_new(FALSE, 0);
  1355.  gtk_container_border_width(GTK_CONTAINER(preview_box), 10);
  1356.  gtk_container_add(GTK_CONTAINER(preview_frame), preview_box);
  1357.  
  1358.  frame = gtk_frame_new(NULL);
  1359.  gtk_frame_set_shadow_type(GTK_FRAME(frame), GTK_SHADOW_IN);
  1360.  gtk_box_pack_start(GTK_BOX(preview_box), frame, TRUE, TRUE, 0);
  1361.  
  1362.  preview_display = gtk_preview_new(GTK_PREVIEW_COLOR);
  1363.  gtk_preview_size(GTK_PREVIEW(preview_display), preview_width, preview_height);
  1364.  gtk_container_add(GTK_CONTAINER(frame), preview_display);
  1365.  
  1366.  preview_data.display = preview_display;
  1367.  update_preview(preview_data.display);
  1368.  
  1369.  
  1370.  
  1371.  
  1372.  /* Add the functions/effects frame */ 
  1373.  functions_frame = gtk_frame_new("Functions / Effects");
  1374.  gtk_frame_set_shadow_type(GTK_FRAME(functions_frame), GTK_SHADOW_ETCHED_IN);
  1375.  gtk_box_pack_start(GTK_BOX(west_box), functions_frame, FALSE, FALSE, 0);
  1376.  
  1377.  functions_box = gtk_vbox_new(FALSE, 0);
  1378.  gtk_container_border_width(GTK_CONTAINER(functions_box), 10);
  1379.  gtk_container_add(GTK_CONTAINER(functions_frame), functions_box);
  1380.  
  1381.  
  1382.  
  1383.  
  1384.  
  1385.  
  1386.  /* Add a test object to the functions/effects box (to be replaced.*/
  1387.  create_functions_menu(functions_box);
  1388.  create_effects_menu(functions_box);
  1389.  
  1390.  
  1391.  
  1392.  
  1393.  
  1394.  
  1395.  gtk_widget_show(functions_box);
  1396.  gtk_widget_show(functions_frame);
  1397.  
  1398.  
  1399.  
  1400.  
  1401.  gtk_widget_show(preview_display);
  1402.  gtk_widget_show(frame);
  1403.  gtk_widget_show(preview_frame);
  1404.  
  1405.  gtk_widget_show(preview_box);
  1406.  gtk_widget_show(west_box);
  1407.  
  1408.  
  1409.  
  1410.  
  1411.  /*  Create the parameter control box  */
  1412.  frame = gtk_frame_new("Parameter settings");
  1413.  gtk_frame_set_shadow_type(GTK_FRAME(frame), GTK_SHADOW_ETCHED_IN);
  1414.  gtk_box_pack_start(GTK_BOX(north_box), frame, TRUE, TRUE, 0);
  1415.  
  1416.  parameter_box = gtk_vbox_new(FALSE, 5);
  1417.  gtk_container_add(GTK_CONTAINER(frame), parameter_box);
  1418.  
  1419.  
  1420.  oal = create_slider_with_label(parameter_values.lettering01, parameter_box, (GtkSignalFunc)a1_callback, parameter_values.a1, -10.0, 10.0);
  1421.  widget_data.slider01 = oal.object;
  1422.  widget_data.label01 = oal.label;
  1423.  
  1424.  oal = create_slider_with_label(parameter_values.lettering02, parameter_box, (GtkSignalFunc)a2_callback, parameter_values.a2, -10.0, 10.0);
  1425.  widget_data.slider02 = oal.object;
  1426.  widget_data.label02 = oal.label;
  1427.  
  1428.  oal = create_slider_with_label(parameter_values.lettering03, parameter_box, (GtkSignalFunc)a3_callback, parameter_values.a3, -10.0, 10.0);
  1429.  widget_data.slider03 = oal.object;
  1430.  widget_data.label03 = oal.label;
  1431.  
  1432.  oal = create_slider_with_label(parameter_values.lettering04, parameter_box, (GtkSignalFunc)a4_callback, parameter_values.a4, -10.0, 10.0);
  1433.  widget_data.slider04 = oal.object;
  1434.  widget_data.label04 = oal.label;
  1435.  
  1436.  oal = create_slider_with_label(parameter_values.lettering05, parameter_box, (GtkSignalFunc)a5_callback, parameter_values.a5, -10.0, 10.0);
  1437.  widget_data.slider05 = oal.object;
  1438.  widget_data.label05 = oal.label;
  1439.  
  1440.  oal = create_slider_with_label(parameter_values.lettering06, parameter_box, (GtkSignalFunc)a6_callback, parameter_values.a6, -10.0, 10.0);
  1441.  widget_data.slider06 = oal.object;
  1442.  widget_data.label06 = oal.label;
  1443.  
  1444.  oal = create_slider_with_label(parameter_values.lettering07, parameter_box, (GtkSignalFunc)a7_callback, parameter_values.a7, -10.0, 10.0);
  1445.  widget_data.slider07 = oal.object;
  1446.  widget_data.label07 = oal.label;
  1447.  
  1448.  oal = create_slider_with_label(parameter_values.lettering08, parameter_box, (GtkSignalFunc)a8_callback, parameter_values.a8, -10.0, 10.0);
  1449.  widget_data.slider08 = oal.object;
  1450.  widget_data.label08 = oal.label;
  1451.  
  1452.  
  1453.  gtk_widget_show(parameter_box);
  1454.  gtk_widget_show(frame);
  1455.  gtk_widget_show(north_box);
  1456.  
  1457.  
  1458.  
  1459.  
  1460.  /* Create the south box (contains the cutoff panel)*/
  1461.  south_box = gtk_hbox_new(FALSE, 5);
  1462.  gtk_box_pack_start(GTK_BOX(main_box), south_box, TRUE, TRUE, 0);
  1463.  
  1464.  frame = gtk_frame_new("Cutoff function");
  1465.  gtk_frame_set_shadow_type(GTK_FRAME(frame), GTK_SHADOW_ETCHED_IN);
  1466.  gtk_box_pack_start(GTK_BOX(south_box), frame, TRUE, TRUE, 0);
  1467.  
  1468.  cutoff_box = gtk_hbox_new(FALSE, 5);
  1469.  gtk_container_border_width(GTK_CONTAINER(cutoff_box), 10);
  1470.  gtk_container_add(GTK_CONTAINER(frame), cutoff_box);
  1471.  
  1472.  
  1473.  create_cutoff_panel(cutoff_box);
  1474.  
  1475.  gtk_widget_show(cutoff_box);
  1476.  gtk_widget_show(frame);
  1477.  gtk_widget_show(south_box);
  1478.  
  1479.  
  1480.  gtk_widget_show(main_box);
  1481.  
  1482.  gtk_widget_show(dtd.dlg);
  1483.  
  1484.  gtk_main ();
  1485.  gdk_flush ();
  1486.   
  1487.  return 1;
  1488. }
  1489.  
  1490.  
  1491.  
  1492. /* Modify the dialog controls such that they resemble the actual 
  1493.    parameter values. The parameters are modified by selecting an effect.
  1494. */
  1495. static void update_dialog(void)
  1496. {
  1497.  GtkAdjustment *adjustment;
  1498.  
  1499.  adjustment = (GtkAdjustment *)widget_data.slider01;
  1500.  adjustment->value = parameter_values.a1;
  1501.  gtk_signal_emit_by_name(GTK_OBJECT(adjustment), "value_changed");
  1502.  gtk_label_set(widget_data.label01, parameter_values.lettering01);
  1503.  
  1504.  adjustment = (GtkAdjustment *)widget_data.slider02;
  1505.  adjustment->value = parameter_values.a2;
  1506.  gtk_signal_emit_by_name(GTK_OBJECT(adjustment), "value_changed");
  1507.  gtk_label_set(widget_data.label02, parameter_values.lettering02);
  1508.  
  1509.  adjustment = (GtkAdjustment *)widget_data.slider03;
  1510.  adjustment->value = parameter_values.a3;
  1511.  gtk_signal_emit_by_name(GTK_OBJECT(adjustment), "value_changed");
  1512.  gtk_label_set(widget_data.label03, parameter_values.lettering03);
  1513.  
  1514.  adjustment = (GtkAdjustment *)widget_data.slider04;
  1515.  adjustment->value = parameter_values.a4;
  1516.  gtk_signal_emit_by_name(GTK_OBJECT(adjustment), "value_changed");
  1517.  gtk_label_set(widget_data.label04, parameter_values.lettering04);
  1518.  
  1519.  adjustment = (GtkAdjustment *)widget_data.slider05;
  1520.  adjustment->value = parameter_values.a5;
  1521.  gtk_signal_emit_by_name(GTK_OBJECT(adjustment), "value_changed");
  1522.  gtk_label_set(widget_data.label05, parameter_values.lettering05);
  1523.  
  1524.  adjustment = (GtkAdjustment *)widget_data.slider06;
  1525.  adjustment->value = parameter_values.a6;
  1526.  gtk_signal_emit_by_name(GTK_OBJECT(adjustment), "value_changed");
  1527.  gtk_label_set(widget_data.label06, parameter_values.lettering06);
  1528.  
  1529.  adjustment = (GtkAdjustment *)widget_data.slider07;
  1530.  adjustment->value = parameter_values.a7;
  1531.  gtk_signal_emit_by_name(GTK_OBJECT(adjustment), "value_changed");
  1532.  gtk_label_set(widget_data.label07, parameter_values.lettering07);
  1533.  
  1534.  adjustment = (GtkAdjustment *)widget_data.slider08;
  1535.  adjustment->value = parameter_values.a8;
  1536.  gtk_signal_emit_by_name(GTK_OBJECT(adjustment), "value_changed");
  1537.  gtk_label_set(widget_data.label08, parameter_values.lettering08);
  1538.  
  1539.  
  1540.  
  1541.  adjustment = (GtkAdjustment *)widget_data.slider09;
  1542.  adjustment->value = parameter_values.r;
  1543.  gtk_signal_emit_by_name(GTK_OBJECT(adjustment), "value_changed");
  1544.  
  1545.  adjustment = (GtkAdjustment *)widget_data.slider10;
  1546.  adjustment->value = parameter_values.dr;
  1547.  gtk_signal_emit_by_name(GTK_OBJECT(adjustment), "value_changed");
  1548.  
  1549.  gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(widget_data.toggle01), parameter_values.use_cutoff);
  1550. }
  1551.  
  1552.  
  1553. /******************************************************************************/
  1554. /*                          Callback functions                                */
  1555. /******************************************************************************/
  1556.  
  1557. static void close_callback(GtkWidget *widget, gpointer data)
  1558. {
  1559.  gtk_main_quit();
  1560. }
  1561.  
  1562. static void ok_callback(GtkWidget *widget, gpointer data)
  1563. {
  1564.  gtk_widget_destroy(GTK_WIDGET(data));
  1565. }
  1566.  
  1567. void cancel_callback(GtkWidget *widget, gpointer data)
  1568. {
  1569.  do_action = -1;
  1570.  gtk_main_quit();
  1571. }
  1572.  
  1573.  
  1574.  
  1575. static void a1_callback(GtkAdjustment *adjustment, gpointer data)
  1576. {
  1577.  parameter_values.a1 = adjustment->value;
  1578.  update_preview(preview_data.display);
  1579. }
  1580.  
  1581. static void a2_callback(GtkAdjustment *adjustment, gpointer data)
  1582. {
  1583.  parameter_values.a2 = adjustment->value;
  1584.  update_preview(preview_data.display);
  1585. }
  1586.  
  1587. static void a3_callback(GtkAdjustment *adjustment, gpointer data)
  1588. {
  1589.  parameter_values.a3 = adjustment->value;
  1590.  update_preview(preview_data.display);
  1591. }
  1592.  
  1593. static void a4_callback(GtkAdjustment *adjustment, gpointer data)
  1594. {
  1595.  parameter_values.a4 = adjustment->value;
  1596.  update_preview(preview_data.display);
  1597. }
  1598.  
  1599. static void a5_callback(GtkAdjustment *adjustment, gpointer data)
  1600. {
  1601.  parameter_values.a5 = adjustment->value;
  1602.  update_preview(preview_data.display);
  1603. }
  1604.  
  1605. static void a6_callback(GtkAdjustment *adjustment, gpointer data)
  1606. {
  1607.  parameter_values.a6 = adjustment->value;
  1608.  update_preview(preview_data.display);
  1609. }
  1610.  
  1611. static void a7_callback(GtkAdjustment *adjustment, gpointer data)
  1612. {
  1613.  parameter_values.a7 = adjustment->value;
  1614.  update_preview(preview_data.display);
  1615. }
  1616.  
  1617. static void a8_callback(GtkAdjustment *adjustment, gpointer data)
  1618. {
  1619.  parameter_values.a8 = adjustment->value;
  1620.  update_preview(preview_data.display);
  1621. }
  1622.  
  1623.  
  1624.  
  1625.  
  1626. static void use_cutoff_callback(GtkWidget *widget, gpointer data)
  1627. {
  1628.  parameter_values.use_cutoff = 0;
  1629.  if(GTK_TOGGLE_BUTTON(widget)->active) parameter_values.use_cutoff = 1;
  1630.  update_preview(preview_data.display);
  1631. }
  1632.  
  1633. static void r_callback(GtkAdjustment *adjustment, gpointer data)
  1634. {
  1635.  parameter_values.r = adjustment->value;
  1636.  update_preview(preview_data.display);
  1637. }
  1638.  
  1639. static void dr_callback(GtkAdjustment *adjustment, gpointer data)
  1640. {
  1641.  parameter_values.dr = adjustment->value;
  1642.  update_preview(preview_data.display);
  1643. }
  1644.  
  1645.  
  1646.  
  1647.  
  1648.  
  1649.  
  1650.  
  1651. static void effect01_callback(GtkWidget *widget, gpointer data)
  1652.  gint f = parameter_values.current_function;
  1653.  
  1654.  parameter_values.a1 = EffectsParameters[f][0].a1;                 
  1655.  parameter_values.a2 = EffectsParameters[f][0].a2;                 
  1656.  parameter_values.a3 = EffectsParameters[f][0].a3;                 
  1657.  parameter_values.a4 = EffectsParameters[f][0].a4;                 
  1658.  parameter_values.a5 = EffectsParameters[f][0].a5;                 
  1659.  parameter_values.a6 = EffectsParameters[f][0].a6;                 
  1660.  parameter_values.a7 = EffectsParameters[f][0].a7;                 
  1661.  parameter_values.a8 = EffectsParameters[f][0].a8;                 
  1662.  parameter_values.use_cutoff = EffectsParameters[f][0].use_cutoff;         
  1663.  parameter_values.r = EffectsParameters[f][0].r;                   
  1664.  parameter_values.dr = EffectsParameters[f][0].dr;  
  1665.  
  1666.  do_update_preview = 0;
  1667.  update_dialog();
  1668.  do_update_preview = 1;
  1669.  update_preview(preview_data.display);
  1670. }
  1671.  
  1672. static void effect02_callback(GtkWidget *widget, gpointer data)
  1673. {
  1674.  gint f = parameter_values.current_function;
  1675.  
  1676.  parameter_values.a1 = EffectsParameters[f][1].a1;                 
  1677.  parameter_values.a2 = EffectsParameters[f][1].a2;                 
  1678.  parameter_values.a3 = EffectsParameters[f][1].a3;                 
  1679.  parameter_values.a4 = EffectsParameters[f][1].a4;                 
  1680.  parameter_values.a5 = EffectsParameters[f][1].a5;                 
  1681.  parameter_values.a6 = EffectsParameters[f][1].a6;                 
  1682.  parameter_values.a7 = EffectsParameters[f][1].a7;                 
  1683.  parameter_values.a8 = EffectsParameters[f][1].a8;                 
  1684.  parameter_values.use_cutoff = EffectsParameters[f][1].use_cutoff;         
  1685.  parameter_values.r = EffectsParameters[f][1].r;                   
  1686.  parameter_values.dr = EffectsParameters[f][1].dr;  
  1687.  
  1688.  do_update_preview = 0;
  1689.  update_dialog();
  1690.  do_update_preview = 1;
  1691.  update_preview(preview_data.display);
  1692. }
  1693.  
  1694. static void effect03_callback(GtkWidget *widget, gpointer data)
  1695. {
  1696.  gint f = parameter_values.current_function;
  1697.  
  1698.  parameter_values.a1 = EffectsParameters[f][2].a1;                 
  1699.  parameter_values.a2 = EffectsParameters[f][2].a2;                 
  1700.  parameter_values.a3 = EffectsParameters[f][2].a3;                 
  1701.  parameter_values.a4 = EffectsParameters[f][2].a4;                 
  1702.  parameter_values.a5 = EffectsParameters[f][2].a5;                 
  1703.  parameter_values.a6 = EffectsParameters[f][2].a6;                 
  1704.  parameter_values.a7 = EffectsParameters[f][2].a7;                 
  1705.  parameter_values.a8 = EffectsParameters[f][2].a8;                 
  1706.  parameter_values.use_cutoff = EffectsParameters[f][2].use_cutoff;         
  1707.  parameter_values.r = EffectsParameters[f][2].r;                   
  1708.  parameter_values.dr = EffectsParameters[f][2].dr;  
  1709.  
  1710.  do_update_preview = 0;
  1711.  update_dialog();
  1712.  do_update_preview = 1;
  1713.  update_preview(preview_data.display);
  1714. }
  1715.  
  1716. static void effect04_callback(GtkWidget *widget, gpointer data)
  1717. {
  1718.  gint f = parameter_values.current_function;
  1719.  
  1720.  parameter_values.a1 = EffectsParameters[f][3].a1;                 
  1721.  parameter_values.a2 = EffectsParameters[f][3].a2;                 
  1722.  parameter_values.a3 = EffectsParameters[f][3].a3;                 
  1723.  parameter_values.a4 = EffectsParameters[f][3].a4;                 
  1724.  parameter_values.a5 = EffectsParameters[f][3].a5;                 
  1725.  parameter_values.a6 = EffectsParameters[f][3].a6;                 
  1726.  parameter_values.a7 = EffectsParameters[f][3].a7;                 
  1727.  parameter_values.a8 = EffectsParameters[f][3].a8;                 
  1728.  parameter_values.use_cutoff = EffectsParameters[f][3].use_cutoff;         
  1729.  parameter_values.r = EffectsParameters[f][3].r;                   
  1730.  parameter_values.dr = EffectsParameters[f][3].dr;  
  1731.  
  1732.  do_update_preview = 0;
  1733.  update_dialog();
  1734.  do_update_preview = 1;
  1735.  update_preview(preview_data.display);
  1736. }
  1737.  
  1738. static void effect05_callback(GtkWidget *widget, gpointer data)
  1739. {
  1740.  gint f = parameter_values.current_function;
  1741.  
  1742.  parameter_values.a1 = EffectsParameters[f][4].a1;                 
  1743.  parameter_values.a2 = EffectsParameters[f][4].a2;                 
  1744.  parameter_values.a3 = EffectsParameters[f][4].a3;                 
  1745.  parameter_values.a4 = EffectsParameters[f][4].a4;                 
  1746.  parameter_values.a5 = EffectsParameters[f][4].a5;                 
  1747.  parameter_values.a6 = EffectsParameters[f][4].a6;                 
  1748.  parameter_values.a7 = EffectsParameters[f][4].a7;                 
  1749.  parameter_values.a8 = EffectsParameters[f][4].a8;                 
  1750.  parameter_values.use_cutoff = EffectsParameters[f][4].use_cutoff;         
  1751.  parameter_values.r = EffectsParameters[f][4].r;                   
  1752.  parameter_values.dr = EffectsParameters[f][4].dr;  
  1753.  
  1754.  do_update_preview = 0;
  1755.  update_dialog();
  1756.  do_update_preview = 1;
  1757.  update_preview(preview_data.display);
  1758. }
  1759.  
  1760. static void effect06_callback(GtkWidget *widget, gpointer data)
  1761. {
  1762.  gint f = parameter_values.current_function;
  1763.  
  1764.  parameter_values.a1 = EffectsParameters[f][5].a1;                 
  1765.  parameter_values.a2 = EffectsParameters[f][5].a2;                 
  1766.  parameter_values.a3 = EffectsParameters[f][5].a3;                 
  1767.  parameter_values.a4 = EffectsParameters[f][5].a4;                 
  1768.  parameter_values.a5 = EffectsParameters[f][5].a5;                 
  1769.  parameter_values.a6 = EffectsParameters[f][5].a6;                 
  1770.  parameter_values.a7 = EffectsParameters[f][5].a7;                 
  1771.  parameter_values.a8 = EffectsParameters[f][5].a8;                 
  1772.  parameter_values.use_cutoff = EffectsParameters[f][5].use_cutoff;         
  1773.  parameter_values.r = EffectsParameters[f][5].r;                   
  1774.  parameter_values.dr = EffectsParameters[f][5].dr;  
  1775.  
  1776.  do_update_preview = 0;
  1777.  update_dialog();
  1778.  do_update_preview = 1;
  1779.  update_preview(preview_data.display);
  1780. }
  1781.  
  1782. static void effect07_callback(GtkWidget *widget, gpointer data)
  1783. {
  1784.  gint f = parameter_values.current_function;
  1785.  
  1786.  parameter_values.a1 = EffectsParameters[f][6].a1;                 
  1787.  parameter_values.a2 = EffectsParameters[f][6].a2;                 
  1788.  parameter_values.a3 = EffectsParameters[f][6].a3;                 
  1789.  parameter_values.a4 = EffectsParameters[f][6].a4;                 
  1790.  parameter_values.a5 = EffectsParameters[f][6].a5;                 
  1791.  parameter_values.a6 = EffectsParameters[f][6].a6;                 
  1792.  parameter_values.a7 = EffectsParameters[f][6].a7;                 
  1793.  parameter_values.a8 = EffectsParameters[f][6].a8;                 
  1794.  parameter_values.use_cutoff = EffectsParameters[f][6].use_cutoff;         
  1795.  parameter_values.r = EffectsParameters[f][6].r;                   
  1796.  parameter_values.dr = EffectsParameters[f][6].dr;  
  1797.  
  1798.  do_update_preview = 0;
  1799.  update_dialog();
  1800.  do_update_preview = 1;
  1801.  update_preview(preview_data.display);
  1802. }
  1803.  
  1804. static void effect08_callback(GtkWidget *widget, gpointer data)
  1805. {
  1806.  gint f = parameter_values.current_function;
  1807.  
  1808.  parameter_values.a1 = EffectsParameters[f][7].a1;                 
  1809.  parameter_values.a2 = EffectsParameters[f][7].a2;                 
  1810.  parameter_values.a3 = EffectsParameters[f][7].a3;                 
  1811.  parameter_values.a4 = EffectsParameters[f][7].a4;                 
  1812.  parameter_values.a5 = EffectsParameters[f][7].a5;                 
  1813.  parameter_values.a6 = EffectsParameters[f][7].a6;                 
  1814.  parameter_values.a7 = EffectsParameters[f][7].a7;                 
  1815.  parameter_values.a8 = EffectsParameters[f][7].a8;                 
  1816.  parameter_values.use_cutoff = EffectsParameters[f][7].use_cutoff;         
  1817.  parameter_values.r = EffectsParameters[f][7].r;                   
  1818.  parameter_values.dr = EffectsParameters[f][7].dr;  
  1819.  
  1820.  do_update_preview = 0;
  1821.  update_dialog();
  1822.  do_update_preview = 1;
  1823.  update_preview(preview_data.display);
  1824. }
  1825.  
  1826. static void effect09_callback(GtkWidget *widget, gpointer data)
  1827. {
  1828.  gint f = parameter_values.current_function;
  1829.  
  1830.  parameter_values.a1 = EffectsParameters[f][8].a1;                 
  1831.  parameter_values.a2 = EffectsParameters[f][8].a2;                 
  1832.  parameter_values.a3 = EffectsParameters[f][8].a3;                 
  1833.  parameter_values.a4 = EffectsParameters[f][8].a4;                 
  1834.  parameter_values.a5 = EffectsParameters[f][8].a5;                 
  1835.  parameter_values.a6 = EffectsParameters[f][8].a6;                 
  1836.  parameter_values.a7 = EffectsParameters[f][8].a7;                 
  1837.  parameter_values.a8 = EffectsParameters[f][8].a8;                 
  1838.  parameter_values.use_cutoff = EffectsParameters[f][8].use_cutoff;         
  1839.  parameter_values.r = EffectsParameters[f][8].r;                   
  1840.  parameter_values.dr = EffectsParameters[f][8].dr;  
  1841.  
  1842.  do_update_preview = 0;
  1843.  update_dialog();
  1844.  do_update_preview = 1;
  1845.  update_preview(preview_data.display);
  1846. }
  1847.  
  1848.  
  1849.  
  1850.  
  1851. static void function01_callback(GtkWidget *widget, gpointer data)
  1852. {
  1853.  strcpy(parameter_values.lettering01, parameter_names[0].name_a1);
  1854.  strcpy(parameter_values.lettering02, parameter_names[0].name_a2);
  1855.  strcpy(parameter_values.lettering03, parameter_names[0].name_a3);
  1856.  strcpy(parameter_values.lettering04, parameter_names[0].name_a4);
  1857.  strcpy(parameter_values.lettering05, parameter_names[0].name_a5);
  1858.  strcpy(parameter_values.lettering06, parameter_names[0].name_a6);
  1859.  strcpy(parameter_values.lettering07, parameter_names[0].name_a7);
  1860.  strcpy(parameter_values.lettering08, parameter_names[0].name_a8);
  1861.  
  1862.  parameter_values.a1 = 0; parameter_values.a5 = 0;
  1863.  parameter_values.a2 = 0; parameter_values.a6 = 0;
  1864.  parameter_values.a3 = 0; parameter_values.a7 = 0;
  1865.  parameter_values.a4 = 0; parameter_values.a8 = 0;
  1866.  
  1867.  parameter_values.use_cutoff = 0;         
  1868.  parameter_values.r = 0.5;                   
  1869.  parameter_values.dr = 0.2;  
  1870.  
  1871.  parameter_values.current_function = FUNCTION_R_r;
  1872.  
  1873.  do_update_preview = 0;
  1874.  update_dialog();
  1875.  do_update_preview = 1;
  1876.  update_preview(preview_data.display);
  1877. }
  1878.  
  1879.  
  1880. static void function02_callback(GtkWidget *widget, gpointer data)
  1881. {
  1882.  strcpy(parameter_values.lettering01, parameter_names[1].name_a1);
  1883.  strcpy(parameter_values.lettering02, parameter_names[1].name_a2);
  1884.  strcpy(parameter_values.lettering03, parameter_names[1].name_a3);
  1885.  strcpy(parameter_values.lettering04, parameter_names[1].name_a4);
  1886.  strcpy(parameter_values.lettering05, parameter_names[1].name_a5);
  1887.  strcpy(parameter_values.lettering06, parameter_names[1].name_a6);
  1888.  strcpy(parameter_values.lettering07, parameter_names[1].name_a7);
  1889.  strcpy(parameter_values.lettering08, parameter_names[1].name_a8);
  1890.  
  1891.  parameter_values.a1 = 0; parameter_values.a5 = 0;
  1892.  parameter_values.a2 = 0; parameter_values.a6 = 0;
  1893.  parameter_values.a3 = 0; parameter_values.a7 = 0;
  1894.  parameter_values.a4 = 0; parameter_values.a8 = 0;
  1895.  
  1896.  parameter_values.use_cutoff = 0;         
  1897.  parameter_values.r = 0.5;                   
  1898.  parameter_values.dr = 0.2;  
  1899.  
  1900.  parameter_values.current_function = FUNCTION_R_phi;
  1901.  
  1902.  do_update_preview = 0;
  1903.  update_dialog();
  1904.  do_update_preview = 1;
  1905.  update_preview(preview_data.display);
  1906. }
  1907.  
  1908. static void function03_callback(GtkWidget *widget, gpointer data)
  1909. {
  1910.  strcpy(parameter_values.lettering01, parameter_names[2].name_a1);
  1911.  strcpy(parameter_values.lettering02, parameter_names[2].name_a2);
  1912.  strcpy(parameter_values.lettering03, parameter_names[2].name_a3);
  1913.  strcpy(parameter_values.lettering04, parameter_names[2].name_a4);
  1914.  strcpy(parameter_values.lettering05, parameter_names[2].name_a5);
  1915.  strcpy(parameter_values.lettering06, parameter_names[2].name_a6);
  1916.  strcpy(parameter_values.lettering07, parameter_names[2].name_a7);
  1917.  strcpy(parameter_values.lettering08, parameter_names[2].name_a8);
  1918.  
  1919.  parameter_values.a1 = 0; parameter_values.a5 = 0;
  1920.  parameter_values.a2 = 0; parameter_values.a6 = 0;
  1921.  parameter_values.a3 = 0; parameter_values.a7 = 0;
  1922.  parameter_values.a4 = 0; parameter_values.a8 = 0;
  1923.  
  1924.  parameter_values.use_cutoff = 0;         
  1925.  parameter_values.r = 0.5;                   
  1926.  parameter_values.dr = 0.2;  
  1927.  
  1928.  parameter_values.current_function = FUNCTION_Phi_r;
  1929.  
  1930.  do_update_preview = 0;
  1931.  update_dialog();
  1932.  do_update_preview = 1;
  1933.  update_preview(preview_data.display);
  1934. }
  1935.  
  1936. static void function04_callback(GtkWidget *widget, gpointer data)
  1937. {
  1938.  strcpy(parameter_values.lettering01, parameter_names[3].name_a1);
  1939.  strcpy(parameter_values.lettering02, parameter_names[3].name_a2);
  1940.  strcpy(parameter_values.lettering03, parameter_names[3].name_a3);
  1941.  strcpy(parameter_values.lettering04, parameter_names[3].name_a4);
  1942.  strcpy(parameter_values.lettering05, parameter_names[3].name_a5);
  1943.  strcpy(parameter_values.lettering06, parameter_names[3].name_a6);
  1944.  strcpy(parameter_values.lettering07, parameter_names[3].name_a7);
  1945.  strcpy(parameter_values.lettering08, parameter_names[3].name_a8);
  1946.  
  1947.  parameter_values.a1 = 0; parameter_values.a5 = 0;
  1948.  parameter_values.a2 = 0; parameter_values.a6 = 0;
  1949.  parameter_values.a3 = 0; parameter_values.a7 = 0;
  1950.  parameter_values.a4 = 0; parameter_values.a8 = 0;
  1951.  
  1952.  parameter_values.use_cutoff = 0;         
  1953.  parameter_values.r = 0.5;                   
  1954.  parameter_values.dr = 0.2;  
  1955.  
  1956.  parameter_values.current_function = FUNCTION_Phi_phi;
  1957.  
  1958.  do_update_preview = 0;
  1959.  update_dialog();
  1960.  do_update_preview = 1;
  1961.  update_preview(preview_data.display);
  1962. }
  1963.  
  1964. static void function05_callback(GtkWidget *widget, gpointer data)
  1965. {
  1966.  strcpy(parameter_values.lettering01, parameter_names[4].name_a1);
  1967.  strcpy(parameter_values.lettering02, parameter_names[4].name_a2);
  1968.  strcpy(parameter_values.lettering03, parameter_names[4].name_a3);
  1969.  strcpy(parameter_values.lettering04, parameter_names[4].name_a4);
  1970.  strcpy(parameter_values.lettering05, parameter_names[4].name_a5);
  1971.  strcpy(parameter_values.lettering06, parameter_names[4].name_a6);
  1972.  strcpy(parameter_values.lettering07, parameter_names[4].name_a7);
  1973.  strcpy(parameter_values.lettering08, parameter_names[4].name_a8);
  1974.  
  1975.  parameter_values.a1 = 0; parameter_values.a5 = 0;
  1976.  parameter_values.a2 = 0; parameter_values.a6 = 0;
  1977.  parameter_values.a3 = 0; parameter_values.a7 = 0;
  1978.  parameter_values.a4 = 0; parameter_values.a8 = 0;
  1979.  
  1980.  parameter_values.use_cutoff = 0;         
  1981.  parameter_values.r = 0.5;                   
  1982.  parameter_values.dr = 0.2;  
  1983.  
  1984.  parameter_values.current_function = FUNCTION_R_r_Phi_phi;
  1985.  
  1986.  do_update_preview = 0;
  1987.  update_dialog();
  1988.  do_update_preview = 1;
  1989.  update_preview(preview_data.display);
  1990. }
  1991.  
  1992. static void function06_callback(GtkWidget *widget, gpointer data)
  1993. {
  1994.  strcpy(parameter_values.lettering01, parameter_names[5].name_a1);
  1995.  strcpy(parameter_values.lettering02, parameter_names[5].name_a2);
  1996.  strcpy(parameter_values.lettering03, parameter_names[5].name_a3);
  1997.  strcpy(parameter_values.lettering04, parameter_names[5].name_a4);
  1998.  strcpy(parameter_values.lettering05, parameter_names[5].name_a5);
  1999.  strcpy(parameter_values.lettering06, parameter_names[5].name_a6);
  2000.  strcpy(parameter_values.lettering07, parameter_names[5].name_a7);
  2001.  strcpy(parameter_values.lettering08, parameter_names[5].name_a8);
  2002.  
  2003.  parameter_values.a1 = 0; parameter_values.a5 = 0;
  2004.  parameter_values.a2 = 0; parameter_values.a6 = 0;
  2005.  parameter_values.a3 = 0; parameter_values.a7 = 0;
  2006.  parameter_values.a4 = 0; parameter_values.a8 = 0;
  2007.  
  2008.  parameter_values.use_cutoff = 0;         
  2009.  parameter_values.r = 0.5;                   
  2010.  parameter_values.dr = 0.2;  
  2011.  
  2012.  parameter_values.current_function = FUNCTION_R_r_R_phi;
  2013.  
  2014.  do_update_preview = 0;
  2015.  update_dialog();
  2016.  do_update_preview = 1;
  2017.  update_preview(preview_data.display);
  2018. }
  2019.  
  2020. static void function07_callback(GtkWidget *widget, gpointer data)
  2021. {
  2022.  strcpy(parameter_values.lettering01, parameter_names[6].name_a1);
  2023.  strcpy(parameter_values.lettering02, parameter_names[6].name_a2);
  2024.  strcpy(parameter_values.lettering03, parameter_names[6].name_a3);
  2025.  strcpy(parameter_values.lettering04, parameter_names[6].name_a4);
  2026.  strcpy(parameter_values.lettering05, parameter_names[6].name_a5);
  2027.  strcpy(parameter_values.lettering06, parameter_names[6].name_a6);
  2028.  strcpy(parameter_values.lettering07, parameter_names[6].name_a7);
  2029.  strcpy(parameter_values.lettering08, parameter_names[6].name_a8);
  2030.  
  2031.  parameter_values.a1 = 0; parameter_values.a5 = 0;
  2032.  parameter_values.a2 = 0; parameter_values.a6 = 0;
  2033.  parameter_values.a3 = 0; parameter_values.a7 = 0;
  2034.  parameter_values.a4 = 0; parameter_values.a8 = 0;
  2035.  
  2036.  parameter_values.use_cutoff = 0;         
  2037.  parameter_values.r = 0.5;                   
  2038.  parameter_values.dr = 0.2;  
  2039.  
  2040.  parameter_values.current_function = FUNCTION_Cosines;
  2041.  
  2042.  do_update_preview = 0;
  2043.  update_dialog();
  2044.  do_update_preview = 1;
  2045.  update_preview(preview_data.display);
  2046. }
  2047.  
  2048.  
  2049.  
  2050. static void function08_callback(GtkWidget *widget, gpointer data)
  2051. {
  2052.  strcpy(parameter_values.lettering01, parameter_names[7].name_a1);
  2053.  strcpy(parameter_values.lettering02, parameter_names[7].name_a2);
  2054.  strcpy(parameter_values.lettering03, parameter_names[7].name_a3);
  2055.  strcpy(parameter_values.lettering04, parameter_names[7].name_a4);
  2056.  strcpy(parameter_values.lettering05, parameter_names[7].name_a5);
  2057.  strcpy(parameter_values.lettering06, parameter_names[7].name_a6);
  2058.  strcpy(parameter_values.lettering07, parameter_names[7].name_a7);
  2059.  strcpy(parameter_values.lettering08, parameter_names[7].name_a8);
  2060.  
  2061.  parameter_values.a1 = 0; parameter_values.a5 = 0;
  2062.  parameter_values.a2 = 0; parameter_values.a6 = 0;
  2063.  parameter_values.a3 = 0; parameter_values.a7 = 0;
  2064.  parameter_values.a4 = 0; parameter_values.a8 = 0;
  2065.  
  2066.  parameter_values.use_cutoff = 0;         
  2067.  parameter_values.r = 0.5;                   
  2068.  parameter_values.dr = 0.2;  
  2069.  
  2070.  parameter_values.current_function = FUNCTION_Gauss;
  2071.  
  2072.  do_update_preview = 0;
  2073.  update_dialog();
  2074.  do_update_preview = 1;
  2075.  update_preview(preview_data.display);
  2076. }
  2077.  
  2078.  
  2079.  
  2080.  
  2081.  
  2082.  
  2083. /******************************************************************************/
  2084. /*                    Image manipulation functions                            */
  2085. /******************************************************************************/
  2086.  
  2087.  
  2088. void image_action(GDrawable *drawable, Parameters params)
  2089. {
  2090.  gint width, height;
  2091.  gint bytes;
  2092.  gint x1, y1, x2, y2;
  2093.  GPixelRgn src_rgn, dest_rgn;
  2094.  guchar *dest;
  2095.  guchar *src;
  2096.  
  2097.  guchar r, g, b;
  2098.  
  2099.  
  2100.  gfloat u, v;
  2101.  gint image_size;
  2102.  
  2103.  gint i, j;
  2104.  gint count; 
  2105.   
  2106.  gimp_drawable_mask_bounds(drawable->id, &x1, &y1, &x2, &y2);
  2107.  
  2108.  width = (x2 - x1);
  2109.  height = (y2 - y1);
  2110.  bytes = drawable->bpp;
  2111.  
  2112.  image_size = width*height*bytes;
  2113.  
  2114.  /* Allocate the necessary storage memory */
  2115.  src = (guchar *)malloc(image_size);
  2116.  dest = (guchar *)malloc(width * bytes);
  2117.  
  2118.  gimp_pixel_rgn_init(&src_rgn, drawable, 0, 0, drawable->width, drawable->height, FALSE, FALSE);
  2119.  gimp_pixel_rgn_init(&dest_rgn, drawable, 0, 0, drawable->width, drawable->height, TRUE, TRUE);
  2120.  
  2121.  /* Get the source image */
  2122.  get_source_image(src_rgn, src, x1, y1, width, height, bytes);
  2123.  
  2124.  switch(bytes)
  2125.  {
  2126.   case 4:   for(j = 0; j < height; j++)
  2127.             {
  2128.              count = 0;
  2129.              for(i = 0; i < width; i++)
  2130.              {
  2131.               calculate_distortion_function(i, j, width, height, &u, &v);
  2132.    
  2133.               if((u >= 0) && (u < width) && (v >= 0) && (v < height))
  2134.               {
  2135.                calculate_pixel_color(u, v, src, width, height, bytes, &r, &g, &b);               
  2136.                dest[count] = r; count++;
  2137.                dest[count] = g; count++;
  2138.                dest[count] = b; count++;
  2139.                dest[count] = 255; count++;
  2140.               }
  2141.               else
  2142.               {
  2143.                dest[count] = 0; count++;
  2144.                dest[count] = 0; count++;
  2145.                dest[count] = 0; count++;
  2146.                dest[count] = 0; count++;
  2147.               }
  2148.              }
  2149.              gimp_pixel_rgn_set_row (&dest_rgn, dest, x1, j + y1, width);
  2150.              gimp_progress_update((double)j / (double)height);
  2151.             }
  2152.             break;
  2153.             
  2154.   case 3:   for(j = 0; j < height; j++)
  2155.             {
  2156.              count = 0;
  2157.              for(i = 0; i < width; i++)
  2158.              {
  2159.               calculate_distortion_function(i, j, width, height, &u, &v);
  2160.    
  2161.               if((u >= 0) && (u < width) && (v >= 0) && (v < height))
  2162.               {
  2163.                calculate_pixel_color(u, v, src, width, height, bytes, &r, &g, &b);               
  2164.                dest[count] = r; count++;
  2165.                dest[count] = g; count++;
  2166.                dest[count] = b; count++;           
  2167.               }
  2168.               else
  2169.               {
  2170.                dest[count] = 0; count++;
  2171.                dest[count] = 0; count++;
  2172.                dest[count] = 0; count++;             
  2173.               }
  2174.              }
  2175.              gimp_pixel_rgn_set_row (&dest_rgn, dest, x1, j + y1, width);
  2176.              gimp_progress_update((double)j / (double)height);
  2177.             }
  2178.             break;
  2179.             
  2180.   case 2:   for(j = 0; j < height; j++)
  2181.             {
  2182.              count = 0;
  2183.              for(i = 0; i < width; i++)
  2184.              {
  2185.               calculate_distortion_function(i, j, width, height, &u, &v);
  2186.    
  2187.               if((u >= 0) && (u < width) && (v >= 0) && (v < height))
  2188.               {
  2189.                calculate_pixel_color(u, v, src, width, height, bytes, &r, &g, &b);               
  2190.                dest[count] = r;   count++;          
  2191.                dest[count] = 255; count++;
  2192.               }
  2193.               else
  2194.               {
  2195.                dest[count] = 0; count++;              
  2196.                dest[count] = 0; count++;
  2197.               }
  2198.              }
  2199.              gimp_pixel_rgn_set_row (&dest_rgn, dest, x1, j + y1, width);
  2200.              gimp_progress_update((double)j / (double)height);
  2201.             }
  2202.             break;
  2203.             
  2204.   case 1:   for(j = 0; j < height; j++)
  2205.             {
  2206.              count = 0;
  2207.              for(i = 0; i < width; i++)
  2208.              {
  2209.               calculate_distortion_function(i, j, width, height, &u, &v);
  2210.    
  2211.               if((u >= 0) && (u < width) && (v >= 0) && (v < height))
  2212.               {
  2213.                calculate_pixel_color(u, v, src, width, height, bytes, &r, &g, &b);               
  2214.                dest[count] = r; count++;            
  2215.               }
  2216.               else
  2217.               {
  2218.                dest[count] = 0; count++;          
  2219.               }
  2220.              }
  2221.              gimp_pixel_rgn_set_row (&dest_rgn, dest, x1, j + y1, width);
  2222.              gimp_progress_update((double)j / (double)height);
  2223.             }
  2224.             break;
  2225.  }
  2226.  
  2227.  /*  merge the shadow, update the drawable  */
  2228.  gimp_drawable_flush(drawable);
  2229.  gimp_drawable_merge_shadow(drawable->id, TRUE);
  2230.  gimp_drawable_update(drawable->id, x1, y1, width, height);
  2231.  
  2232.  
  2233.  free(src);
  2234.  free(dest);
  2235. }
  2236.  
  2237.  
  2238.  
  2239. static void polar_coordinates(gfloat x, gfloat y, gfloat *rho, gfloat *phi)
  2240. {
  2241.  gfloat r, p;
  2242.  
  2243.  /* Calculate the radius */
  2244.  r = sqrt(x*x + y*y);
  2245.  p = 0.0;
  2246.  
  2247.  /* exceptions first .. */
  2248.  if((x == 0.0) && (y == 0.0)) p = 0.0; 
  2249.  else if((x < epsilon) && (x > -epsilon) && (y > 0.0)) p = TWIST_PI/2.0;
  2250.  else if((x < epsilon) && (x > -epsilon) && (y < 0.0)) p = 3.0*TWIST_PI/2.0;
  2251.  else if((x > 0.0) && (y < epsilon) && (y > -epsilon)) p = 0.0;
  2252.  else if((x < 0.0) && (y < epsilon) && (y > -epsilon)) p = TWIST_PI;
  2253.  
  2254.  /* simple cases in the four quadrants */
  2255.  else if((x > 0.0) && (y > 0.0)) p = atan(y/x);
  2256.  else if((x < 0.0) && (y > 0.0)) p = TWIST_PI - atan(-y/x);
  2257.  else if((x < 0.0) && (y < 0.0)) p = TWIST_PI + atan(y/x);
  2258.  else if((x > 0.0) && (y < 0.0)) p = 2.0*TWIST_PI - atan(-y/x);
  2259.  
  2260.  /* Return the values */
  2261.  *rho = r;
  2262.  *phi = p;
  2263. }
  2264.  
  2265.  
  2266.  
  2267. /* The distortion functions */
  2268.  
  2269. static void distortion_function01(gfloat x1, gfloat x2, gfloat *delta_x1, gfloat *delta_x2)
  2270. {
  2271.  gfloat r2;
  2272.  
  2273.  r2 = x1*x1;
  2274.  
  2275.  *delta_x1 = parameter_values.a1*x1 + parameter_values.a2*r2 +
  2276.              parameter_values.a3*r2*x1 + parameter_values.a4*r2*r2;
  2277. }
  2278.  
  2279. static void distortion_function02(gfloat x1, gfloat x2, gfloat *delta_x1, gfloat *delta_x2)
  2280. {
  2281.  *delta_x1 = parameter_values.a1*cos(x2*parameter_values.a2) + 
  2282.              parameter_values.a3*cos(x2*parameter_values.a4);
  2283. }
  2284.  
  2285. static void distortion_function03(gfloat x1, gfloat x2, gfloat *delta_x1, gfloat *delta_x2)
  2286. {
  2287.  gfloat r2;
  2288.  
  2289.  r2 = x1*x1;
  2290.  
  2291.  *delta_x2 = parameter_values.a1*x1 + parameter_values.a2*r2 +
  2292.              parameter_values.a3*r2*x1 + parameter_values.a4*r2*r2;
  2293. }
  2294.  
  2295. static void distortion_function04(gfloat x1, gfloat x2, gfloat *delta_x1, gfloat *delta_x2)
  2296. {
  2297.  *delta_x2 = parameter_values.a1*cos(x2*parameter_values.a2) + 
  2298.              parameter_values.a3*cos(x2*parameter_values.a4);
  2299. }
  2300.  
  2301.  
  2302. static void distortion_function05(gfloat x1, gfloat x2, gfloat *delta_x1, gfloat *delta_x2)
  2303. {
  2304.  gfloat P, Q;
  2305.  gfloat r2;
  2306.  
  2307.  r2 = x1*x1;
  2308.  
  2309.  P = parameter_values.a1*x1 + parameter_values.a2*r2 +
  2310.      parameter_values.a3*r2*x1 + parameter_values.a4*r2*r2;
  2311.      
  2312.  Q = parameter_values.a5*cos(x2*parameter_values.a6) + 
  2313.              parameter_values.a7*cos(x2*parameter_values.a8);
  2314.  
  2315.  *delta_x2 = P*Q;
  2316. }
  2317.  
  2318.  
  2319. static void distortion_function06(gfloat x1, gfloat x2, gfloat *delta_x1, gfloat *delta_x2)
  2320. {
  2321.  gfloat P, Q;
  2322.  gfloat r2;
  2323.  
  2324.  r2 = x1*x1;
  2325.  
  2326.  P = parameter_values.a1*x1 + parameter_values.a2*r2 +
  2327.      parameter_values.a3*r2*x1 + parameter_values.a4*r2*r2;
  2328.      
  2329.  Q = parameter_values.a5*cos(x2*parameter_values.a6) + 
  2330.              parameter_values.a7*cos(x2*parameter_values.a8);
  2331.  
  2332.  *delta_x2 = P*Q;
  2333. }
  2334.  
  2335.  
  2336.  
  2337. static void distortion_function07(gfloat x1, gfloat x2, gfloat *delta_x1, gfloat *delta_x2)
  2338. {
  2339.  *delta_x1 = 0.1*parameter_values.a1*sin(5.0*parameter_values.a3*x1)*cos(5.0*parameter_values.a4*x1);
  2340.  *delta_x2 = 0.1*parameter_values.a2*sin(5.0*parameter_values.a5*x2)*cos(5.0*parameter_values.a6*x2);
  2341. }
  2342.  
  2343.  
  2344.  
  2345. static void distortion_function08(gfloat x1, gfloat x2, gfloat *delta_x1, gfloat *delta_x2)
  2346. {
  2347.  gfloat x0, y0;
  2348.  gfloat lambda1, lambda2;
  2349.  
  2350.  x0 = parameter_values.a3/10.0;
  2351.  y0 = parameter_values.a4/10.0;
  2352.  
  2353.  lambda1 = 30.0/(10.1 + parameter_values.a5);
  2354.  lambda2 = 30.0/(10.1 + parameter_values.a6);
  2355.  
  2356.  
  2357.  *delta_x1 = 0.5*parameter_values.a1*(x1 - x0)*exp(-lambda1*(x1 - x0)*(x1 - x0));
  2358.  *delta_x2 = 0.5*parameter_values.a2*(x2 - y0)*exp(-lambda2*(x2 - y0)*(x2 - y0));
  2359. }
  2360.  
  2361.  
  2362. static void calculate_distortion_function(gint i, gint j, gint width, gint height, gfloat *u, gfloat *v)
  2363. {
  2364.  gint x, y;
  2365.  gfloat scale_factor;
  2366.  gint mx, my;
  2367.  gfloat scaled_x, scaled_y;
  2368.  gfloat delta_rho, delta_phi;
  2369.  gfloat delta_x, delta_y;
  2370.  gfloat rho, phi;
  2371.  gfloat damp;
  2372.  
  2373.  mx = width/2;
  2374.  my = height/2;
  2375.  
  2376.  /* The scale factor is chosed such that the scaled image fits into a unit square. */
  2377.  scale_factor = (gfloat)MAX(width, height);
  2378.  
  2379.  x = i - mx;
  2380.  y = my - j;
  2381.     
  2382.  scaled_x = ((float)x)/scale_factor;
  2383.  scaled_y = ((float)y)/scale_factor;
  2384.  
  2385.  switch(parameter_values.current_function)
  2386.  {
  2387.   case FUNCTION_R_r: 
  2388.        /* Calculate the (u, v) coordinates of the distorted image
  2389.           from the original image */
  2390.        polar_coordinates(scaled_x, scaled_y, &rho, &phi);
  2391.  
  2392.        distortion_function01(rho, phi, &delta_rho, &delta_phi);
  2393.  
  2394.        /* calculate the damping factor */
  2395.        damp = 1.0;
  2396.        if(parameter_values.use_cutoff != 0) damp = cutoff_function(scaled_x, scaled_y);
  2397.   
  2398.        *u = (float)x + (float)mx + damp*scale_factor*delta_rho*cos(phi);
  2399.        *v = (float)my - (float)y - damp*scale_factor*delta_rho*sin(phi);
  2400.        break;
  2401.        
  2402.        
  2403.   case FUNCTION_R_phi:
  2404.        /* Calculate the (u, v) coordinates of the distorted image
  2405.           from the original image */
  2406.        polar_coordinates(scaled_x, scaled_y, &rho, &phi);
  2407.  
  2408.        distortion_function02(rho, phi, &delta_rho, &delta_phi);
  2409.  
  2410.        /* calculate the damping factor */
  2411.        damp = 1.0;
  2412.        if(parameter_values.use_cutoff != 0) damp = cutoff_function(scaled_x, scaled_y);
  2413.   
  2414.        *u = (float)x + (float)mx + damp*scale_factor*delta_rho*cos(phi);
  2415.        *v = (float)my - (float)y - damp*scale_factor*delta_rho*sin(phi);
  2416.        break;
  2417.        
  2418.        
  2419.   case FUNCTION_Phi_r:
  2420.        /* Calculate the (u, v) coordinates of the distorted image
  2421.           from the original image */
  2422.        polar_coordinates(scaled_x, scaled_y, &rho, &phi);
  2423.  
  2424.        distortion_function03(rho, phi, &delta_rho, &delta_phi);
  2425.  
  2426.        /* calculate the damping factor */
  2427.        damp = 1.0;
  2428.        if(parameter_values.use_cutoff != 0) damp = cutoff_function(scaled_x, scaled_y);
  2429.   
  2430.        *u = (float)x + (float)mx + damp*scale_factor*delta_phi*sin(phi);
  2431.        *v = (float)my - (float)y + damp*scale_factor*delta_phi*cos(phi);
  2432.        break;
  2433.        
  2434.        
  2435.   case FUNCTION_Phi_phi:
  2436.        /* Calculate the (u, v) coordinates of the distorted image
  2437.           from the original image */
  2438.        polar_coordinates(scaled_x, scaled_y, &rho, &phi);
  2439.  
  2440.        distortion_function04(rho, phi, &delta_rho, &delta_phi);
  2441.  
  2442.        /* calculate the damping factor */
  2443.        damp = 1.0;
  2444.        if(parameter_values.use_cutoff != 0) damp = cutoff_function(scaled_x, scaled_y);
  2445.   
  2446.        *u = (float)x + (float)mx + damp*scale_factor*delta_phi*sin(phi);
  2447.        *v = (float)my - (float)y + damp*scale_factor*delta_phi*cos(phi);
  2448.        break;
  2449.        
  2450.        
  2451.   case FUNCTION_R_r_Phi_phi:
  2452.        /* Calculate the (u, v) coordinates of the distorted image
  2453.           from the original image */
  2454.        polar_coordinates(scaled_x, scaled_y, &rho, &phi);
  2455.  
  2456.        distortion_function05(rho, phi, &delta_rho, &delta_phi);
  2457.  
  2458.        /* calculate the damping factor */
  2459.        damp = 1.0;
  2460.        if(parameter_values.use_cutoff != 0) damp = cutoff_function(scaled_x, scaled_y);
  2461.   
  2462.        *u = (float)x + (float)mx + damp*scale_factor*delta_phi*sin(phi);
  2463.        *v = (float)my - (float)y + damp*scale_factor*delta_phi*cos(phi);
  2464.        break;
  2465.        
  2466.   case FUNCTION_R_r_R_phi:
  2467.        /* Calculate the (u, v) coordinates of the distorted image
  2468.           from the original image */
  2469.        polar_coordinates(scaled_x, scaled_y, &rho, &phi);
  2470.  
  2471.        distortion_function06(rho, phi, &delta_rho, &delta_phi);
  2472.  
  2473.        /* calculate the damping factor */
  2474.        damp = 1.0;
  2475.        if(parameter_values.use_cutoff != 0) damp = cutoff_function(scaled_x, scaled_y);
  2476.   
  2477.        *u = (float)x + (float)mx + damp*scale_factor*delta_phi*cos(phi);
  2478.        *v = (float)my - (float)y - damp*scale_factor*delta_phi*sin(phi);
  2479.        break;
  2480.        
  2481.       
  2482.   case FUNCTION_Cosines:
  2483.        /* Calculate the (u, v) coordinates of the distorted image
  2484.           from the original image */
  2485.        distortion_function07(scaled_x, scaled_y, &delta_x, &delta_y);
  2486.  
  2487.        /* calculate the damping factor */
  2488.        damp = 1.0;
  2489.        if(parameter_values.use_cutoff != 0) damp = cutoff_function(scaled_x, scaled_y);
  2490.   
  2491.        *u = (float)x + (float)mx + damp*scale_factor*delta_x;
  2492.        *v = (float)my - (float)y - damp*scale_factor*delta_y;
  2493.        break;
  2494.        
  2495.        
  2496.   case FUNCTION_Gauss:
  2497.     
  2498.        distortion_function08(scaled_x, scaled_y, &delta_x, &delta_y);
  2499.  
  2500.        /* calculate the damping factor */
  2501.        damp = 1.0;
  2502.        if(parameter_values.use_cutoff != 0) damp = cutoff_function(scaled_x, scaled_y);
  2503.   
  2504.        *u = (float)x + (float)mx + damp*scale_factor*delta_x;
  2505.        *v = (float)my - (float)y - damp*scale_factor*delta_y;
  2506.        break;
  2507.  }
  2508. }
  2509.  
  2510.  
  2511.  
  2512.  
  2513.  
  2514.  
  2515.  
  2516. static gfloat cutoff_function(gfloat u, gfloat v)
  2517. {
  2518.  gfloat radius;
  2519.  gfloat x;
  2520.  
  2521.  radius = sqrt(u*u + v*v);
  2522.  
  2523.  if(radius <= parameter_values.r) return(1.0);
  2524.  
  2525.  x = (radius - parameter_values.r)/(0.2*parameter_values.dr);
  2526.  return(exp(-x*x));
  2527. }
  2528.  
  2529.  
  2530.  
  2531. static void calculate_pixel_color(gfloat u, gfloat v, guchar *source, gint width, gint height, gint bpp, guchar *r, guchar *g, guchar *b)
  2532. {
  2533.  gint address;
  2534.  gfloat ru, rv;
  2535.  gfloat w0, w1, w2, w3;
  2536.  
  2537.  guchar red[4];
  2538.  guchar green[4];
  2539.  guchar blue[4];
  2540.  
  2541.  if(((gint)u < width - 1) && ((gint)v < height - 1))
  2542.  {
  2543.   ru = u - (int)u;
  2544.   rv = v - (int)v;
  2545.   
  2546.   /* Calculate the area weights.  */
  2547.   w0 = (1.0 - ru)*rv;
  2548.   w1 = rv*ru;
  2549.   w2 = (1.0 - ru)*(1.0 - rv);
  2550.   w3 = (1.0 - rv)*ru;
  2551.   
  2552.   /* Get the four pixel colors depending on bpp. */
  2553.   switch(bpp)
  2554.   {
  2555.    case 4:    
  2556.    case 3:  address = bpp*((int)v*width + (int)u);
  2557.             red[0] = source[address];
  2558.             green[0] = source[address +1];
  2559.             blue[0] = source[address + 2];
  2560.             
  2561.             address = bpp*((int)v*width + (int)(u + 1.0));
  2562.             red[1] = source[address];
  2563.             green[1] = source[address + 1];
  2564.             blue[1] = source[address + 2];
  2565.             
  2566.             address = bpp*((int)(v - 1.0)*width + (int)u);
  2567.             red[2] = source[address];
  2568.             green[2] = source[address + 1];
  2569.             blue[2] = source[address + 2];
  2570.             
  2571.             address = bpp*((int)(v - 1.0)*width + (int)(u + 1.0));
  2572.             red[3] = source[address];
  2573.             green[3] = source[address + 1];
  2574.             blue[3] = source[address + 2];
  2575.             
  2576.             *r = w0*red[0]   + w1*red[1]   + w2*red[2]   + w3*red[3];
  2577.             *g = w0*green[0] + w1*green[1] + w2*green[2] + w3*green[3];
  2578.             *b = w0*blue[0]  + w1*blue[1]  + w2*blue[2]  + w3*blue[3];
  2579.             break;
  2580.             
  2581.             
  2582.    /* For grayscale images, the grayvalue is stored in the
  2583.       red component.  
  2584.    */       
  2585.    case 2:  
  2586.    case 1:  address = bpp*((int)v*width + (int)u);
  2587.             red[0] = source[address];
  2588.                       
  2589.             address = bpp*((int)v*width + (int)(u + 1.0));
  2590.             red[1] = source[address];
  2591.             
  2592.             address = bpp*((int)(v - 1.0)*width + (int)u);
  2593.             red[2] = source[address];
  2594.             
  2595.             address = bpp*((int)(v - 1.0)*width + (int)(u + 1.0));
  2596.             red[3] = source[address];
  2597.             
  2598.             *r = w0*red[0]   + w1*red[1]   + w2*red[2]   + w3*red[3];
  2599.             break;
  2600.    
  2601.   }
  2602.  } 
  2603. }
  2604.  
  2605.  
  2606.  
  2607. static void get_source_image(GPixelRgn source_rgn, guchar *buffer, gint x, gint y, gint width, gint height, gint bytes)
  2608. {
  2609.  gint offset;
  2610.  gint i, j;
  2611.  
  2612.  guchar *src_buffer;
  2613.  
  2614.  src_buffer = (guchar *)malloc(width * bytes);
  2615.  
  2616.  offset = 0;
  2617.  for(j = 0; j < height; j++)
  2618.  {
  2619.   gimp_pixel_rgn_get_row(&source_rgn, src_buffer, x, j + y, width);
  2620.   for(i = 0; i < bytes*width; i++) buffer[i + offset] = src_buffer[i];
  2621.   offset += bytes*width;
  2622.  }
  2623.  
  2624.  free(src_buffer);
  2625. }
  2626.