~ubuntu-branches/ubuntu/karmic/gimp/karmic-security

« back to all changes in this revision

Viewing changes to plug-ins/common/lens.c

  • Committer: Bazaar Package Importer
  • Author(s): Sebastien Bacher
  • Date: 2008-10-06 13:30:41 UTC
  • mfrom: (1.1.15 upstream)
  • Revision ID: james.westby@ubuntu.com-20081006133041-axco233xt49jobn7
Tags: 2.6.0-1ubuntu1
* Sync on debian and new version (lp: #276839)
* debian/patches/02_help-message.patch,
  debian/patches/03_gimp.desktop.in.in.patch:
  - updated some strings for ubuntu
* debian/rules:
  - updated translation templates

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/* GIMP - The GNU Image Manipulation Program
2
 
 * Copyright (C) 1995 Spencer Kimball and Peter Mattis
3
 
 *
4
 
 * Lens plug-in - adjust for lens distortion
5
 
 * Copyright (C) 2001-2005 David Hodson hodsond@acm.org
6
 
 * Many thanks for Lars Clausen for the original inspiration,
7
 
 *   useful discussion, optimisation and improvements.
8
 
 * Framework borrowed from many similar plugins...
9
 
 *
10
 
 * This program is free software; you can redistribute it and/or modify
11
 
 * it under the terms of the GNU General Public License as published by
12
 
 * the Free Software Foundation; either version 2 of the License, or
13
 
 * (at your option) any later version.
14
 
 *
15
 
 * This program is distributed in the hope that it will be useful,
16
 
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17
 
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18
 
 * GNU General Public License for more details.
19
 
 *
20
 
 * You should have received a copy of the GNU General Public License
21
 
 * along with this program; if not, write to the Free Software
22
 
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
23
 
 */
24
 
 
25
 
#include "config.h"
26
 
 
27
 
#include <string.h>
28
 
 
29
 
#include <libgimp/gimp.h>
30
 
#include <libgimp/gimpui.h>
31
 
 
32
 
#include "libgimp/stdplugins-intl.h"
33
 
 
34
 
 
35
 
#define PLUG_IN_PROC     "plug-in-lens-distortion"
36
 
#define PLUG_IN_BINARY   "lens"
37
 
 
38
 
#define RESPONSE_RESET   1
39
 
 
40
 
#define LENS_MAX_PIXEL_DEPTH        4
41
 
 
42
 
 
43
 
typedef struct
44
 
{
45
 
  gdouble  centre_x;
46
 
  gdouble  centre_y;
47
 
  gdouble  square_a;
48
 
  gdouble  quad_a;
49
 
  gdouble  scale_a;
50
 
  gdouble  brighten;
51
 
} LensValues;
52
 
 
53
 
typedef struct
54
 
{
55
 
  gdouble  normallise_radius_sq;
56
 
  gdouble  centre_x;
57
 
  gdouble  centre_y;
58
 
  gdouble  mult_sq;
59
 
  gdouble  mult_qd;
60
 
  gdouble  rescale;
61
 
  gdouble  brighten;
62
 
} LensCalcValues;
63
 
 
64
 
 
65
 
/* Declare local functions. */
66
 
 
67
 
static void     query (void);
68
 
static void     run   (const gchar      *name,
69
 
                       gint              nparams,
70
 
                       const GimpParam  *param,
71
 
                       gint             *nreturn_vals,
72
 
                       GimpParam       **return_vals);
73
 
 
74
 
static void     lens_distort    (GimpDrawable *drawable);
75
 
static gboolean lens_dialog     (GimpDrawable *drawable);
76
 
 
77
 
 
78
 
static LensValues         vals = { 0.0, 0.0, 0.0, 0.0 };
79
 
static LensCalcValues     calc_vals;
80
 
 
81
 
static gint               drawable_width, drawable_height;
82
 
static guchar             background_color[4];
83
 
 
84
 
 
85
 
const GimpPlugInInfo PLUG_IN_INFO =
86
 
  {
87
 
    NULL,  /* init_proc  */
88
 
    NULL,  /* quit_proc  */
89
 
    query, /* query_proc */
90
 
    run,   /* run_proc   */
91
 
  };
92
 
 
93
 
 
94
 
MAIN ()
95
 
 
96
 
static void
97
 
query (void)
98
 
{
99
 
  static GimpParamDef args[] =
100
 
    {
101
 
      { GIMP_PDB_INT32,      "run-mode",    "Interactive, non-interactive" },
102
 
      { GIMP_PDB_IMAGE,      "image",       "Input image (unused)" },
103
 
      { GIMP_PDB_DRAWABLE,   "drawable",    "Input drawable" },
104
 
      { GIMP_PDB_FLOAT,      "offset-x",    "Effect centre offset in X" },
105
 
      { GIMP_PDB_FLOAT,      "offset-y",    "Effect centre offset in Y" },
106
 
      { GIMP_PDB_FLOAT,      "main-adjust",
107
 
        "Amount of second-order distortion" },
108
 
      { GIMP_PDB_FLOAT,      "edge-adjust",
109
 
        "Amount of fourth-order distortion" },
110
 
      { GIMP_PDB_FLOAT,      "rescale",     "Rescale overall image size" },
111
 
      { GIMP_PDB_FLOAT,      "brighten",    "Adjust brightness in corners" }
112
 
    };
113
 
 
114
 
  gimp_install_procedure (PLUG_IN_PROC,
115
 
                          N_("Corrects lens distortion"),
116
 
                          "Corrects barrel or pincushion lens distortion.",
117
 
                          "David Hodson, Aurimas Juška",
118
 
                          "David Hodson",
119
 
                          "Version 1.0.10",
120
 
                          N_("Lens Distortion..."),
121
 
                          "RGB*, GRAY*",
122
 
                          GIMP_PLUGIN,
123
 
                          G_N_ELEMENTS (args), 0,
124
 
                          args, NULL);
125
 
 
126
 
  gimp_plugin_menu_register (PLUG_IN_PROC, "<Image>/Filters/Distorts");
127
 
}
128
 
 
129
 
static void
130
 
run (const gchar      *name,
131
 
     gint              nparams,
132
 
     const GimpParam  *param,
133
 
     gint             *nreturn_vals,
134
 
     GimpParam       **return_vals)
135
 
{
136
 
  static GimpParam   values[1];
137
 
  GimpDrawable      *drawable;
138
 
  gint32             image_ID;
139
 
  GimpRGB            background;
140
 
  GimpPDBStatusType  status   = GIMP_PDB_SUCCESS;
141
 
  GimpRunMode        run_mode;
142
 
 
143
 
  run_mode = param[0].data.d_int32;
144
 
  image_ID = param[1].data.d_int32;
145
 
 
146
 
  values[0].type = GIMP_PDB_STATUS;
147
 
  values[0].data.d_status = status;
148
 
 
149
 
  INIT_I18N ();
150
 
 
151
 
  drawable = gimp_drawable_get (param[2].data.d_drawable);
152
 
 
153
 
  drawable_width = drawable->width;
154
 
  drawable_height = drawable->height;
155
 
 
156
 
  /* Get background color */
157
 
  gimp_context_get_background (&background);
158
 
  gimp_rgb_set_alpha (&background, 0.0);
159
 
  gimp_drawable_get_color_uchar (drawable->drawable_id, &background,
160
 
                                 background_color);
161
 
 
162
 
  /* Set the tile cache size */
163
 
  gimp_tile_cache_ntiles (2 * MAX (drawable->ntile_rows, drawable->ntile_cols));
164
 
 
165
 
  *nreturn_vals = 1;
166
 
  *return_vals = values;
167
 
 
168
 
  switch (run_mode) {
169
 
  case GIMP_RUN_INTERACTIVE:
170
 
    gimp_get_data (PLUG_IN_PROC, &vals);
171
 
    if (! lens_dialog (drawable))
172
 
      return;
173
 
    break;
174
 
 
175
 
  case GIMP_RUN_NONINTERACTIVE:
176
 
    if (nparams != 9)
177
 
      status = GIMP_PDB_CALLING_ERROR;
178
 
 
179
 
    if (status == GIMP_PDB_SUCCESS)
180
 
      {
181
 
        vals.centre_x = param[3].data.d_float;
182
 
        vals.centre_y = param[4].data.d_float;
183
 
        vals.square_a = param[5].data.d_float;
184
 
        vals.quad_a = param[6].data.d_float;
185
 
        vals.scale_a = param[7].data.d_float;
186
 
        vals.brighten = param[8].data.d_float;
187
 
      }
188
 
 
189
 
    break;
190
 
 
191
 
  case GIMP_RUN_WITH_LAST_VALS:
192
 
    gimp_get_data (PLUG_IN_PROC, &vals);
193
 
    break;
194
 
 
195
 
  default:
196
 
    break;
197
 
  }
198
 
 
199
 
  if ( status == GIMP_PDB_SUCCESS )
200
 
    {
201
 
      lens_distort (drawable);
202
 
 
203
 
      if (run_mode != GIMP_RUN_NONINTERACTIVE)
204
 
        gimp_displays_flush ();
205
 
 
206
 
      if (run_mode == GIMP_RUN_INTERACTIVE)
207
 
        gimp_set_data (PLUG_IN_PROC, &vals, sizeof (LensValues));
208
 
 
209
 
      gimp_drawable_detach (drawable);
210
 
    }
211
 
 
212
 
  values[0].data.d_status = status;
213
 
}
214
 
 
215
 
static void
216
 
lens_get_source_coords (gdouble  i,
217
 
                        gdouble  j,
218
 
                        gdouble *x,
219
 
                        gdouble *y,
220
 
                        gdouble *mag)
221
 
{
222
 
  gdouble radius_sq;
223
 
 
224
 
  gdouble off_x;
225
 
  gdouble off_y;
226
 
 
227
 
  gdouble radius_mult;
228
 
 
229
 
  off_x = i - calc_vals.centre_x;
230
 
  off_y = j - calc_vals.centre_y;
231
 
  radius_sq = (off_x * off_x) + (off_y * off_y);
232
 
 
233
 
  radius_sq *= calc_vals.normallise_radius_sq;
234
 
 
235
 
  radius_mult = radius_sq * calc_vals.mult_sq + radius_sq * radius_sq *
236
 
    calc_vals.mult_qd;
237
 
  *mag = radius_mult;
238
 
  radius_mult = calc_vals.rescale * (1.0 + radius_mult);
239
 
 
240
 
  *x = calc_vals.centre_x + radius_mult * off_x;
241
 
  *y = calc_vals.centre_y + radius_mult * off_y;
242
 
}
243
 
 
244
 
static void
245
 
lens_setup_calc (gint width, gint height)
246
 
{
247
 
  calc_vals.normallise_radius_sq =
248
 
    4.0 / (width * width + height * height);
249
 
 
250
 
  calc_vals.centre_x = width * (100.0 + vals.centre_x) / 200.0;
251
 
  calc_vals.centre_y = height * (100.0 + vals.centre_y) / 200.0;
252
 
  calc_vals.mult_sq = vals.square_a / 200.0;
253
 
  calc_vals.mult_qd = vals.quad_a / 200.0;
254
 
  calc_vals.rescale = pow(2.0, - vals.scale_a / 100.0);
255
 
  calc_vals.brighten = - vals.brighten / 10.0;
256
 
}
257
 
 
258
 
/*
259
 
 * Catmull-Rom cubic interpolation
260
 
 *
261
 
 * equally spaced points p0, p1, p2, p3
262
 
 * interpolate 0 <= u < 1 between p1 and p2
263
 
 *
264
 
 * (1 u u^2 u^3) (  0.0  1.0  0.0  0.0 ) (p0)
265
 
 *               ( -0.5  0.0  0.5  0.0 ) (p1)
266
 
 *               (  1.0 -2.5  2.0 -0.5 ) (p2)
267
 
 *               ( -0.5  1.5 -1.5  0.5 ) (p3)
268
 
 *
269
 
 */
270
 
 
271
 
static void
272
 
lens_cubic_interpolate (const guchar *src,
273
 
                        gint          row_stride,
274
 
                        gint          src_depth,
275
 
                        guchar       *dst,
276
 
                        gint          dst_depth,
277
 
                        gdouble       dx,
278
 
                        gdouble       dy,
279
 
                        gdouble       brighten)
280
 
{
281
 
  gfloat um1, u, up1, up2;
282
 
  gfloat vm1, v, vp1, vp2;
283
 
  gint   c;
284
 
  gfloat verts[4 * LENS_MAX_PIXEL_DEPTH];
285
 
 
286
 
  um1 = ((-0.5 * dx + 1.0) * dx - 0.5) * dx;
287
 
  u = (1.5 * dx - 2.5) * dx * dx + 1.0;
288
 
  up1 = ((-1.5 * dx + 2.0) * dx + 0.5) * dx;
289
 
  up2 = (0.5 * dx - 0.5) * dx * dx;
290
 
 
291
 
  vm1 = ((-0.5 * dy + 1.0) * dy - 0.5) * dy;
292
 
  v = (1.5 * dy - 2.5) * dy * dy + 1.0;
293
 
  vp1 = ((-1.5 * dy + 2.0) * dy + 0.5) * dy;
294
 
  vp2 = (0.5 * dy - 0.5) * dy * dy;
295
 
 
296
 
  /* Note: if dst_depth < src_depth, we calculate unneeded pixels here */
297
 
  /* later - select or create index array */
298
 
  for (c = 0; c < 4 * src_depth; ++c)
299
 
    {
300
 
      verts[c] = vm1 * src[c] + v * src[c+row_stride] +
301
 
        vp1 * src[c+row_stride*2] + vp2 * src[c+row_stride*3];
302
 
    }
303
 
 
304
 
  for (c = 0; c < dst_depth; ++c)
305
 
    {
306
 
      gfloat result;
307
 
 
308
 
      result = um1 * verts[c] + u * verts[c+src_depth] +
309
 
        up1 * verts[c+src_depth*2] + up2 * verts[c+src_depth*3];
310
 
 
311
 
      result *= brighten;
312
 
 
313
 
      dst[c] = CLAMP (result, 0, 255);
314
 
    }
315
 
}
316
 
 
317
 
static void
318
 
lens_distort_func (gint              ix,
319
 
                   gint              iy,
320
 
                   guchar           *dest,
321
 
                   gint              bpp,
322
 
                   GimpPixelFetcher *pft)
323
 
{
324
 
  gdouble  src_x, src_y, mag;
325
 
  gdouble  brighten;
326
 
  guchar   pixel_buffer[16 * LENS_MAX_PIXEL_DEPTH];
327
 
  guchar  *pixel;
328
 
  gdouble  dx, dy;
329
 
  gint     x_int, y_int;
330
 
  gint     x, y;
331
 
 
332
 
  lens_get_source_coords (ix, iy, &src_x, &src_y, &mag);
333
 
 
334
 
  brighten = 1.0 + mag * calc_vals.brighten;
335
 
  x_int = floor (src_x);
336
 
  dx = src_x - x_int;
337
 
 
338
 
  y_int = floor (src_y);
339
 
  dy = src_y - y_int;
340
 
 
341
 
  pixel = pixel_buffer;
342
 
  for (y = y_int - 1; y <= y_int + 2; y++)
343
 
    {
344
 
      for (x = x_int -1; x <= x_int + 2; x++)
345
 
        {
346
 
          if (x >= 0  && y >= 0 &&
347
 
              x < drawable_width &&  y < drawable_height)
348
 
            {
349
 
              gimp_pixel_fetcher_get_pixel (pft, x, y, pixel);
350
 
            }
351
 
          else
352
 
            {
353
 
              gint i;
354
 
 
355
 
              for (i = 0; i < bpp; i++)
356
 
                pixel[i] = background_color[i];
357
 
            }
358
 
 
359
 
          pixel += bpp;
360
 
        }
361
 
    }
362
 
 
363
 
  lens_cubic_interpolate (pixel_buffer, bpp * 4, bpp,
364
 
                          dest, bpp, dx, dy, brighten);
365
 
}
366
 
 
367
 
static void
368
 
lens_distort (GimpDrawable *drawable)
369
 
{
370
 
  GimpRgnIterator  *iter;
371
 
  GimpPixelFetcher *pft;
372
 
  GimpRGB           background;
373
 
 
374
 
  lens_setup_calc (drawable->width, drawable->height);
375
 
 
376
 
  pft = gimp_pixel_fetcher_new (drawable, FALSE);
377
 
 
378
 
  gimp_context_get_background (&background);
379
 
  gimp_rgb_set_alpha (&background, 0.0);
380
 
  gimp_pixel_fetcher_set_bg_color (pft, &background);
381
 
  gimp_pixel_fetcher_set_edge_mode (pft, GIMP_PIXEL_FETCHER_EDGE_BACKGROUND);
382
 
 
383
 
  gimp_progress_init (_("Lens distortion"));
384
 
 
385
 
  iter = gimp_rgn_iterator_new (drawable, 0);
386
 
  gimp_rgn_iterator_dest (iter, (GimpRgnFuncDest) lens_distort_func, pft);
387
 
  gimp_rgn_iterator_free (iter);
388
 
 
389
 
  gimp_pixel_fetcher_destroy (pft);
390
 
}
391
 
 
392
 
static void
393
 
lens_distort_preview (GimpDrawable *drawable,
394
 
                      GimpPreview  *preview)
395
 
{
396
 
  guchar               *dest;
397
 
  guchar               *pixel;
398
 
  gint                  width, height, bpp;
399
 
  gint                  x, y;
400
 
  GimpPixelFetcher     *pft;
401
 
  GimpRGB               background;
402
 
 
403
 
  pft = gimp_pixel_fetcher_new (drawable, FALSE);
404
 
 
405
 
  gimp_context_get_background (&background);
406
 
  gimp_rgb_set_alpha (&background, 0.0);
407
 
  gimp_pixel_fetcher_set_bg_color (pft, &background);
408
 
  gimp_pixel_fetcher_set_edge_mode (pft, GIMP_PIXEL_FETCHER_EDGE_BACKGROUND);
409
 
 
410
 
  lens_setup_calc (drawable->width, drawable->height);
411
 
 
412
 
  dest = gimp_zoom_preview_get_source (GIMP_ZOOM_PREVIEW (preview),
413
 
                                       &width, &height, &bpp);
414
 
  pixel = dest;
415
 
 
416
 
  for (y = 0; y < height; y++)
417
 
    {
418
 
      for (x = 0; x < width; x++)
419
 
        {
420
 
          gint sx, sy;
421
 
 
422
 
          gimp_preview_untransform (preview, x, y, &sx, &sy);
423
 
 
424
 
          lens_distort_func (sx, sy, pixel, bpp, pft);
425
 
 
426
 
          pixel += bpp;
427
 
        }
428
 
    }
429
 
 
430
 
  gimp_pixel_fetcher_destroy (pft);
431
 
 
432
 
  gimp_preview_draw_buffer (preview, dest, width * bpp);
433
 
  g_free (dest);
434
 
}
435
 
 
436
 
/* UI callback functions */
437
 
 
438
 
static GSList *adjustments = NULL;
439
 
 
440
 
static void
441
 
lens_dialog_reset (void)
442
 
{
443
 
  GSList *list;
444
 
 
445
 
  for (list = adjustments; list; list = list->next)
446
 
    gtk_adjustment_set_value (GTK_ADJUSTMENT (list->data), 0.0);
447
 
}
448
 
 
449
 
static void
450
 
lens_response (GtkWidget *widget,
451
 
               gint       response_id,
452
 
               gboolean  *run)
453
 
{
454
 
  switch (response_id)
455
 
    {
456
 
    case RESPONSE_RESET:
457
 
      lens_dialog_reset ();
458
 
      break;
459
 
 
460
 
    case GTK_RESPONSE_OK:
461
 
      *run = TRUE;
462
 
      /* fallthrough */
463
 
 
464
 
    default:
465
 
      gtk_widget_destroy (GTK_WIDGET (widget));
466
 
      break;
467
 
    }
468
 
}
469
 
 
470
 
static gboolean
471
 
lens_dialog (GimpDrawable *drawable)
472
 
{
473
 
  GtkWidget *dialog;
474
 
  GtkWidget *main_vbox;
475
 
  GtkWidget *table;
476
 
  GtkWidget *preview;
477
 
  GtkObject *adj;
478
 
  gint       row = 0;
479
 
  gboolean   run = FALSE;
480
 
 
481
 
  gimp_ui_init (PLUG_IN_BINARY, FALSE);
482
 
 
483
 
  dialog = gimp_dialog_new (_("Lens Distortion"), PLUG_IN_BINARY,
484
 
                            NULL, 0,
485
 
                            gimp_standard_help_func, PLUG_IN_PROC,
486
 
 
487
 
                            GIMP_STOCK_RESET, RESPONSE_RESET,
488
 
                            GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
489
 
                            GTK_STOCK_OK,     GTK_RESPONSE_OK,
490
 
 
491
 
                            NULL);
492
 
 
493
 
  gtk_dialog_set_alternative_button_order (GTK_DIALOG (dialog),
494
 
                                           RESPONSE_RESET,
495
 
                                           GTK_RESPONSE_OK,
496
 
                                           GTK_RESPONSE_CANCEL,
497
 
                                           -1);
498
 
 
499
 
  gimp_window_set_transient (GTK_WINDOW (dialog));
500
 
 
501
 
  main_vbox = gtk_vbox_new (FALSE, 12);
502
 
  gtk_container_set_border_width (GTK_CONTAINER (main_vbox), 12);
503
 
  gtk_container_add (GTK_CONTAINER (GTK_DIALOG (dialog)->vbox), main_vbox);
504
 
  gtk_widget_show (main_vbox);
505
 
 
506
 
  preview = gimp_zoom_preview_new (drawable);
507
 
  gtk_box_pack_start_defaults (GTK_BOX (main_vbox), preview);
508
 
  gtk_widget_show (preview);
509
 
  g_signal_connect_swapped (preview, "invalidated",
510
 
                            G_CALLBACK (lens_distort_preview),
511
 
                            drawable);
512
 
 
513
 
  table = gtk_table_new (6, 3, FALSE);
514
 
  gtk_table_set_col_spacings (GTK_TABLE (table), 6);
515
 
  gtk_table_set_row_spacings (GTK_TABLE (table), 6);
516
 
  gtk_box_pack_start (GTK_BOX (main_vbox), table, FALSE, FALSE, 0);
517
 
  gtk_widget_show (table);
518
 
 
519
 
  adj = gimp_scale_entry_new (GTK_TABLE (table), 0, row++,
520
 
                              _("_Main:"), 120, 6,
521
 
                              vals.square_a, -100.0, 100.0, 0.1, 1.0, 3,
522
 
                              TRUE, 0, 0,
523
 
                              NULL, NULL);
524
 
  adjustments = g_slist_append (adjustments, adj);
525
 
 
526
 
  g_signal_connect (adj, "value-changed",
527
 
                    G_CALLBACK (gimp_double_adjustment_update),
528
 
                    &vals.square_a);
529
 
  g_signal_connect_swapped (adj, "value-changed",
530
 
                            G_CALLBACK (gimp_preview_invalidate),
531
 
                            preview);
532
 
 
533
 
  adj = gimp_scale_entry_new (GTK_TABLE (table), 0, row++,
534
 
                              _("_Edge:"), 120, 6,
535
 
                              vals.quad_a, -100.0, 100.0, 0.1, 1.0, 3,
536
 
                              TRUE, 0, 0,
537
 
                              NULL, NULL);
538
 
  adjustments = g_slist_append (adjustments, adj);
539
 
 
540
 
  g_signal_connect (adj, "value-changed",
541
 
                    G_CALLBACK (gimp_double_adjustment_update),
542
 
                    &vals.quad_a);
543
 
  g_signal_connect_swapped (adj, "value-changed",
544
 
                            G_CALLBACK (gimp_preview_invalidate),
545
 
                            preview);
546
 
 
547
 
  adj = gimp_scale_entry_new (GTK_TABLE (table), 0, row++,
548
 
                              _("_Zoom:"), 120, 6,
549
 
                              vals.scale_a, -100.0, 100.0, 0.1, 1.0, 3,
550
 
                              TRUE, 0, 0,
551
 
                              NULL, NULL);
552
 
  adjustments = g_slist_append (adjustments, adj);
553
 
 
554
 
  g_signal_connect (adj, "value-changed",
555
 
                    G_CALLBACK (gimp_double_adjustment_update),
556
 
                    &vals.scale_a);
557
 
  g_signal_connect_swapped (adj, "value-changed",
558
 
                            G_CALLBACK (gimp_preview_invalidate),
559
 
                            preview);
560
 
 
561
 
  adj = gimp_scale_entry_new (GTK_TABLE (table), 0, row++,
562
 
                              _("_Brighten:"), 120, 6,
563
 
                              vals.brighten, -100.0, 100.0, 0.1, 1.0, 3,
564
 
                              TRUE, 0, 0,
565
 
                              NULL, NULL);
566
 
  adjustments = g_slist_append (adjustments, adj);
567
 
 
568
 
  g_signal_connect (adj, "value-changed",
569
 
                    G_CALLBACK (gimp_double_adjustment_update),
570
 
                    &vals.brighten);
571
 
  g_signal_connect_swapped (adj, "value-changed",
572
 
                            G_CALLBACK (gimp_preview_invalidate),
573
 
                            preview);
574
 
 
575
 
  adj = gimp_scale_entry_new (GTK_TABLE (table), 0, row++,
576
 
                              _("_X shift:"), 120, 6,
577
 
                              vals.centre_x, -100.0, 100.0, 0.1, 1.0, 3,
578
 
                              TRUE, 0, 0,
579
 
                              NULL, NULL);
580
 
  adjustments = g_slist_append (adjustments, adj);
581
 
 
582
 
  g_signal_connect (adj, "value-changed",
583
 
                    G_CALLBACK (gimp_double_adjustment_update),
584
 
                    &vals.centre_x);
585
 
  g_signal_connect_swapped (adj, "value-changed",
586
 
                            G_CALLBACK (gimp_preview_invalidate),
587
 
                            preview);
588
 
 
589
 
  adj = gimp_scale_entry_new (GTK_TABLE (table), 0, row++,
590
 
                              _("_Y shift:"), 120, 6,
591
 
                              vals.centre_y, -100.0, 100.0, 0.1, 1.0, 3,
592
 
                              TRUE, 0, 0,
593
 
                              NULL, NULL);
594
 
  adjustments = g_slist_append (adjustments, adj);
595
 
 
596
 
  g_signal_connect (adj, "value-changed",
597
 
                    G_CALLBACK (gimp_double_adjustment_update),
598
 
                    &vals.centre_y);
599
 
  g_signal_connect_swapped (adj, "value-changed",
600
 
                            G_CALLBACK (gimp_preview_invalidate),
601
 
                            preview);
602
 
 
603
 
  g_signal_connect (dialog, "response",
604
 
                    G_CALLBACK (lens_response),
605
 
                    &run);
606
 
  g_signal_connect (dialog, "destroy",
607
 
                    G_CALLBACK (gtk_main_quit),
608
 
                    NULL);
609
 
 
610
 
  gtk_widget_show (dialog);
611
 
 
612
 
  gtk_main ();
613
 
 
614
 
  g_slist_free (adjustments);
615
 
  adjustments = NULL;
616
 
 
617
 
  return run;
618
 
}