~ubuntu-branches/ubuntu/jaunty/gimp/jaunty-security

« back to all changes in this revision

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

  • Committer: Bazaar Package Importer
  • Author(s): Daniel Holbach
  • Date: 2007-05-02 16:33:03 UTC
  • mfrom: (1.1.4 upstream)
  • Revision ID: james.westby@ubuntu.com-20070502163303-bvzhjzbpw8qglc4y
Tags: 2.3.16-1ubuntu1
* Resynchronized with Debian, remaining Ubuntu changes:
  - debian/rules: i18n magic.
* debian/control.in:
  - Maintainer: Ubuntu Core Developers <ubuntu-devel@lists.ubuntu.com>
* debian/patches/02_help-message.patch,
  debian/patches/03_gimp.desktop.in.in.patch,
  debian/patches/10_dont_show_wizard.patch: updated.
* debian/patches/04_composite-signedness.patch,
  debian/patches/05_add-letter-spacing.patch: dropped, used upstream.

Show diffs side-by-side

added added

removed removed

Lines of Context:
31
31
 
32
32
#include "config.h"
33
33
 
34
 
#include <stdio.h>
35
 
#include <stdlib.h>
36
34
#include <string.h>
37
35
 
38
 
#include <gtk/gtk.h>
39
 
 
40
36
#include <libgimp/gimp.h>
41
37
#include <libgimp/gimpui.h>
42
38
 
43
39
#include "libgimp/stdplugins-intl.h"
44
40
 
45
41
 
46
 
#define  SCALE_WIDTH  175
47
 
#define  ENTRY_WIDTH    7
48
 
#define  MAX_CHANNELS   4
49
 
#define  PSV            2  /* point spread value */
50
 
#define  EPSILON        0.001
51
 
 
52
 
#define  NATURAL     0
53
 
#define  FOREGROUND  1
54
 
#define  BACKGROUND  2
 
42
#define PLUG_IN_PROC   "plug-in-sparkle"
 
43
#define PLUG_IN_BINARY "sparkle"
 
44
 
 
45
#define SCALE_WIDTH    175
 
46
#define ENTRY_WIDTH      7
 
47
#define MAX_CHANNELS     4
 
48
#define PSV              2  /* point spread value */
 
49
 
 
50
#define NATURAL          0
 
51
#define FOREGROUND       1
 
52
#define BACKGROUND       2
 
53
 
55
54
 
56
55
typedef struct
57
56
{
61
60
  gdouble   spike_pts;
62
61
  gdouble   spike_angle;
63
62
  gdouble   density;
64
 
  gdouble   opacity;
 
63
  gdouble   transparency;
65
64
  gdouble   random_hue;
66
65
  gdouble   random_saturation;
67
66
  gboolean  preserve_luminosity;
68
67
  gboolean  inverse;
69
68
  gboolean  border;
70
69
  gint      colortype;
 
70
  gboolean  update_preview;
71
71
} SparkleVals;
72
72
 
73
73
 
81
81
                         gint             *nreturn_vals,
82
82
                         GimpParam       **return_vals);
83
83
 
84
 
static gboolean  sparkle_dialog        (void);
 
84
static gboolean  sparkle_dialog        (GimpDrawable *drawable);
85
85
 
86
86
static gint      compute_luminosity    (const guchar *pixel,
87
87
                                        gboolean      gray,
89
89
static gint      compute_lum_threshold (GimpDrawable *drawable,
90
90
                                        gdouble       percentile);
91
91
static void      sparkle               (GimpDrawable *drawable,
92
 
                                        gint          threshold);
 
92
                                        GimpPreview  *preview);
93
93
static void      fspike                (GimpPixelRgn *src_rgn,
94
94
                                        GimpPixelRgn *dest_rgn,
95
95
                                        gint          x1,
103
103
                                        gdouble       inten,
104
104
                                        gdouble       length,
105
105
                                        gdouble       angle,
106
 
                                        GRand        *gr);
 
106
                                        GRand        *gr,
 
107
                                        guchar       *dest_buf);
107
108
static GimpTile * rpnt                 (GimpDrawable *drawable,
108
109
                                        GimpTile     *tile,
109
110
                                        gint          x1,
118
119
                                        gint         *col,
119
120
                                        gint          bytes,
120
121
                                        gdouble       inten,
121
 
                                        guchar        color[MAX_CHANNELS]);
122
 
 
123
 
 
124
 
GimpPlugInInfo PLUG_IN_INFO =
 
122
                                        guchar        color[MAX_CHANNELS],
 
123
                                        guchar       *dest_buf);
 
124
 
 
125
const GimpPlugInInfo PLUG_IN_INFO =
125
126
{
126
127
  NULL,  /* init_proc  */
127
128
  NULL,  /* quit_proc  */
131
132
 
132
133
static SparkleVals svals =
133
134
{
134
 
  0.001,  /* luminosity threshold */
135
 
  0.5,    /* flare intensity      */
136
 
  20.0,   /* spike length         */
137
 
  4.0,    /* spike points         */
138
 
  15.0,   /* spike angle          */
139
 
  1.0,    /* spike density        */
140
 
  0.0,    /* opacity              */
141
 
  0.0,    /* random hue           */
142
 
  0.0,    /* random saturation    */
143
 
  FALSE,  /* preserve_luminosity  */
144
 
  FALSE,  /* inverse              */
145
 
  FALSE,  /* border               */
146
 
  NATURAL /* colortype            */
 
135
  0.001,   /* luminosity threshold */
 
136
  0.5,     /* flare intensity      */
 
137
  20.0,    /* spike length         */
 
138
  4.0,     /* spike points         */
 
139
  15.0,    /* spike angle          */
 
140
  1.0,     /* spike density        */
 
141
  0.0,     /* transparency         */
 
142
  0.0,     /* random hue           */
 
143
  0.0,     /* random saturation    */
 
144
  FALSE,   /* preserve_luminosity  */
 
145
  FALSE,   /* inverse              */
 
146
  FALSE,   /* border               */
 
147
  NATURAL, /* colortype            */
 
148
  FALSE    /* update_preview       */
147
149
};
148
150
 
149
151
static gint num_sparkles;
154
156
static void
155
157
query (void)
156
158
{
157
 
  static GimpParamDef args[] =
 
159
  static const GimpParamDef args[] =
158
160
  {
159
 
    { GIMP_PDB_INT32,    "run_mode",      "Interactive, non-interactive" },
 
161
    { GIMP_PDB_INT32,    "run-mode",      "Interactive, non-interactive" },
160
162
    { GIMP_PDB_IMAGE,    "image",         "Input image (unused)" },
161
163
    { GIMP_PDB_DRAWABLE, "drawable",      "Input drawable" },
162
 
    { GIMP_PDB_FLOAT,    "lum_threshold", "Luminosity threshold (0.0 - 1.0)" },
163
 
    { GIMP_PDB_FLOAT,    "flare_inten",   "Flare intensity (0.0 - 1.0)" },
164
 
    { GIMP_PDB_INT32,    "spike_len",     "Spike length (in pixels)" },
165
 
    { GIMP_PDB_INT32,    "spike_pts",     "# of spike points" },
166
 
    { GIMP_PDB_INT32,    "spike_angle",   "Spike angle (0-360 degrees, -1: random)" },
 
164
    { GIMP_PDB_FLOAT,    "lum-threshold", "Luminosity threshold (0.0 - 1.0)" },
 
165
    { GIMP_PDB_FLOAT,    "flare-inten",   "Flare intensity (0.0 - 1.0)" },
 
166
    { GIMP_PDB_INT32,    "spike-len",     "Spike length (in pixels)" },
 
167
    { GIMP_PDB_INT32,    "spike-pts",     "# of spike points" },
 
168
    { GIMP_PDB_INT32,    "spike-angle",   "Spike angle (0-360 degrees, -1: random)" },
167
169
    { GIMP_PDB_FLOAT,    "density",       "Spike density (0.0 - 1.0)" },
168
 
    { GIMP_PDB_FLOAT,    "opacity",       "Opacity (0.0 - 1.0)" },
169
 
    { GIMP_PDB_FLOAT,    "random_hue",    "Random hue (0.0 - 1.0)" },
170
 
    { GIMP_PDB_FLOAT,    "random_saturation",   "Random saturation (0.0 - 1.0)" },
171
 
    { GIMP_PDB_INT32,    "preserve_luminosity", "Preserve luminosity (TRUE/FALSE)" },
 
170
    { GIMP_PDB_FLOAT,    "transparency",  "Transparency (0.0 - 1.0)" },
 
171
    { GIMP_PDB_FLOAT,    "random-hue",    "Random hue (0.0 - 1.0)" },
 
172
    { GIMP_PDB_FLOAT,    "random-saturation",   "Random saturation (0.0 - 1.0)" },
 
173
    { GIMP_PDB_INT32,    "preserve-luminosity", "Preserve luminosity (TRUE/FALSE)" },
172
174
    { GIMP_PDB_INT32,    "inverse",       "Inverse (TRUE/FALSE)" },
173
175
    { GIMP_PDB_INT32,    "border",        "Add border (TRUE/FALSE)" },
174
 
    { GIMP_PDB_INT32,    "colortype",     "Color of sparkles: { NATURAL (0), FOREGROUND (1), BACKGROUND (2) }" }
 
176
    { GIMP_PDB_INT32,    "color-type",    "Color of sparkles: { NATURAL (0), FOREGROUND (1), BACKGROUND (2) }" }
175
177
  };
176
178
 
177
 
  gimp_install_procedure ("plug_in_sparkle",
178
 
                          "Simulates pixel bloom and diffraction effects",
 
179
  gimp_install_procedure (PLUG_IN_PROC,
 
180
                          N_("Turn bright spots into starry sparkles"),
179
181
                          "Uses a percentage based luminoisty threhsold to find "
180
182
                          "candidate pixels for adding some sparkles (spikes). ",
181
183
                          "John Beale, & (ported to GIMP v0.54) Michael "
189
191
                          G_N_ELEMENTS (args), 0,
190
192
                          args, NULL);
191
193
 
192
 
  gimp_plugin_menu_register ("plug_in_sparkle",
193
 
                             "<Image>/Filters/Light Effects");
 
194
  gimp_plugin_menu_register (PLUG_IN_PROC,
 
195
                             "<Image>/Filters/Light and Shadow/Light");
194
196
}
195
197
 
196
198
static void
204
206
  GimpDrawable      *drawable;
205
207
  GimpRunMode        run_mode;
206
208
  GimpPDBStatusType  status = GIMP_PDB_SUCCESS;
207
 
  gint               threshold, x1, y1, x2, y2;
 
209
  gint               x, y, w, h;
208
210
 
209
211
  run_mode = param[0].data.d_int32;
210
212
 
216
218
  values[0].type          = GIMP_PDB_STATUS;
217
219
  values[0].data.d_status = status;
218
220
 
 
221
  /*  Get the specified drawable  */
 
222
  drawable = gimp_drawable_get (param[2].data.d_drawable);
 
223
  if (! gimp_drawable_mask_intersect (drawable->drawable_id, &x, &y, &w, &h))
 
224
    {
 
225
      g_message (_("Region selected for filter is empty"));
 
226
      return;
 
227
    }
 
228
 
 
229
  gimp_tile_cache_ntiles (2 * (drawable->width / gimp_tile_width () + 1));
 
230
 
219
231
  switch (run_mode)
220
232
    {
221
233
    case GIMP_RUN_INTERACTIVE:
222
234
      /*  Possibly retrieve data  */
223
 
      gimp_get_data ("plug_in_sparkle", &svals);
 
235
      gimp_get_data (PLUG_IN_PROC, &svals);
224
236
 
225
237
      /*  First acquire information with a dialog  */
226
 
      if (! sparkle_dialog ())
 
238
      if (! sparkle_dialog (drawable))
227
239
    return;
228
240
      break;
229
241
 
241
253
          svals.spike_pts = param[6].data.d_int32;
242
254
          svals.spike_angle = param[7].data.d_int32;
243
255
          svals.density = param[8].data.d_float;
244
 
          svals.opacity = param[9].data.d_float;
 
256
          svals.transparency = param[9].data.d_float;
245
257
          svals.random_hue = param[10].data.d_float;
246
258
          svals.random_saturation = param[11].data.d_float;
247
259
          svals.preserve_luminosity = (param[12].data.d_int32) ? TRUE : FALSE;
261
273
            status = GIMP_PDB_CALLING_ERROR;
262
274
          else if (svals.density < 0.0 || svals.density > 1.0)
263
275
            status = GIMP_PDB_CALLING_ERROR;
264
 
          else if (svals.opacity < 0.0 || svals.opacity > 1.0)
 
276
          else if (svals.transparency < 0.0 || svals.transparency > 1.0)
265
277
            status = GIMP_PDB_CALLING_ERROR;
266
278
          else if (svals.random_hue < 0.0 || svals.random_hue > 1.0)
267
279
            status = GIMP_PDB_CALLING_ERROR;
275
287
 
276
288
    case GIMP_RUN_WITH_LAST_VALS:
277
289
      /*  Possibly retrieve data  */
278
 
      gimp_get_data ("plug_in_sparkle", &svals);
 
290
      gimp_get_data (PLUG_IN_PROC, &svals);
279
291
      break;
280
292
 
281
293
    default:
282
294
      break;
283
295
    }
284
296
 
285
 
  /*  Get the specified drawable  */
286
 
  drawable = gimp_drawable_get (param[2].data.d_drawable);
287
 
 
288
297
  /*  Make sure that the drawable is gray or RGB color  */
289
298
  if (gimp_drawable_is_rgb (drawable->drawable_id) ||
290
299
      gimp_drawable_is_gray (drawable->drawable_id))
291
300
    {
292
 
      gimp_progress_init (_("Sparkling..."));
293
 
      gimp_tile_cache_ntiles (2 * (drawable->width / gimp_tile_width () + 1));
294
 
 
295
 
      if (svals.border)
296
 
        {
297
 
          gimp_drawable_mask_bounds (drawable->drawable_id,
298
 
                                     &x1, &y1, &x2, &y2);
299
 
          num_sparkles = 2 * (x2 - x1 + y2 - y1);
300
 
          threshold = 255;
301
 
        }
302
 
      else
303
 
        {
304
 
          /*  compute the luminosity which exceeds the luminosity threshold  */
305
 
          threshold = compute_lum_threshold (drawable, svals.lum_threshold);
306
 
        }
307
 
 
308
 
      sparkle (drawable, threshold);
 
301
      gimp_progress_init (_("Sparkling"));
 
302
 
 
303
      sparkle (drawable, NULL);
309
304
 
310
305
      if (run_mode != GIMP_RUN_NONINTERACTIVE)
311
306
        gimp_displays_flush ();
312
307
 
313
308
      /*  Store mvals data  */
314
309
      if (run_mode == GIMP_RUN_INTERACTIVE)
315
 
        gimp_set_data ("plug_in_sparkle", &svals, sizeof (SparkleVals));
 
310
        gimp_set_data (PLUG_IN_PROC, &svals, sizeof (SparkleVals));
316
311
    }
317
312
  else
318
313
    {
326
321
}
327
322
 
328
323
static gboolean
329
 
sparkle_dialog (void)
 
324
sparkle_dialog (GimpDrawable *drawable)
330
325
{
331
 
  GtkWidget *dlg;
 
326
  GtkWidget *dialog;
332
327
  GtkWidget *main_vbox;
 
328
  GtkWidget *preview;
333
329
  GtkWidget *vbox;
334
330
  GtkWidget *hbox;
335
331
  GtkWidget *table;
338
334
  GtkObject *scale_data;
339
335
  gboolean   run;
340
336
 
341
 
  gimp_ui_init ("sparkle", FALSE);
342
 
 
343
 
  dlg = gimp_dialog_new (_("Sparkle"), "sparkle",
344
 
                         NULL, 0,
345
 
                         gimp_standard_help_func, "plug-in-sparkle",
346
 
 
347
 
                         GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
348
 
                         GTK_STOCK_OK,     GTK_RESPONSE_OK,
349
 
 
350
 
                         NULL);
 
337
  gimp_ui_init (PLUG_IN_BINARY, FALSE);
 
338
 
 
339
  dialog = gimp_dialog_new (_("Sparkle"), PLUG_IN_BINARY,
 
340
                            NULL, 0,
 
341
                            gimp_standard_help_func, PLUG_IN_PROC,
 
342
 
 
343
                            GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
 
344
                            GTK_STOCK_OK,     GTK_RESPONSE_OK,
 
345
 
 
346
                            NULL);
 
347
 
 
348
  gtk_dialog_set_alternative_button_order (GTK_DIALOG (dialog),
 
349
                                           GTK_RESPONSE_OK,
 
350
                                           GTK_RESPONSE_CANCEL,
 
351
                                           -1);
 
352
 
 
353
  gimp_window_set_transient (GTK_WINDOW (dialog));
351
354
 
352
355
  main_vbox = gtk_vbox_new (FALSE, 12);
353
356
  gtk_container_set_border_width (GTK_CONTAINER (main_vbox), 12);
354
 
  gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dlg)->vbox), main_vbox,
355
 
                      TRUE, TRUE, 0);
 
357
  gtk_container_add (GTK_CONTAINER (GTK_DIALOG (dialog)->vbox), main_vbox);
356
358
  gtk_widget_show (main_vbox);
357
359
 
 
360
  preview = gimp_drawable_preview_new (drawable, &svals.update_preview);
 
361
  gtk_box_pack_start_defaults (GTK_BOX (main_vbox), preview);
 
362
  gtk_widget_show (preview);
 
363
  g_signal_connect_swapped (preview, "invalidated",
 
364
                            G_CALLBACK (sparkle),
 
365
                            drawable);
 
366
 
358
367
  table = gtk_table_new (9, 3, FALSE);
359
368
  gtk_table_set_col_spacings (GTK_TABLE (table), 6);
360
369
  gtk_table_set_row_spacings (GTK_TABLE (table), 6);
363
372
 
364
373
  scale_data =
365
374
    gimp_scale_entry_new (GTK_TABLE (table), 0, 0,
366
 
              _("Luminosity _Threshold:"), SCALE_WIDTH, ENTRY_WIDTH,
 
375
              _("Luminosity _threshold:"), SCALE_WIDTH, ENTRY_WIDTH,
367
376
              svals.lum_threshold, 0.0, 0.1, 0.001, 0.01, 3,
368
377
              TRUE, 0, 0,
369
 
              _("Adjust the Luminosity Threshold"), NULL);
370
 
  g_signal_connect (scale_data, "value_changed",
 
378
              _("Adjust the luminosity threshold"), NULL);
 
379
  g_signal_connect (scale_data, "value-changed",
371
380
                    G_CALLBACK (gimp_double_adjustment_update),
372
381
                    &svals.lum_threshold);
 
382
  g_signal_connect_swapped (scale_data, "value-changed",
 
383
                            G_CALLBACK (gimp_preview_invalidate),
 
384
                            preview);
373
385
 
374
386
  scale_data =
375
387
    gimp_scale_entry_new (GTK_TABLE (table), 0, 1,
376
388
              _("F_lare intensity:"), SCALE_WIDTH, ENTRY_WIDTH,
377
389
              svals.flare_inten, 0.0, 1.0, 0.01, 0.1, 2,
378
390
              TRUE, 0, 0,
379
 
              _("Adjust the Flare Intensity"), NULL);
380
 
  g_signal_connect (scale_data, "value_changed",
 
391
              _("Adjust the flare intensity"), NULL);
 
392
  g_signal_connect (scale_data, "value-changed",
381
393
                    G_CALLBACK (gimp_double_adjustment_update),
382
394
                    &svals.flare_inten);
 
395
  g_signal_connect_swapped (scale_data, "value-changed",
 
396
                            G_CALLBACK (gimp_preview_invalidate),
 
397
                            preview);
383
398
 
384
399
  scale_data =
385
400
    gimp_scale_entry_new (GTK_TABLE (table), 0, 2,
386
401
              _("_Spike length:"), SCALE_WIDTH, ENTRY_WIDTH,
387
402
              svals.spike_len, 1, 100, 1, 10, 0,
388
403
              TRUE, 0, 0,
389
 
              _("Adjust the Spike Length"), NULL);
390
 
  g_signal_connect (scale_data, "value_changed",
 
404
              _("Adjust the spike length"), NULL);
 
405
  g_signal_connect (scale_data, "value-changed",
391
406
                    G_CALLBACK (gimp_double_adjustment_update),
392
407
                    &svals.spike_len);
 
408
  g_signal_connect_swapped (scale_data, "value-changed",
 
409
                            G_CALLBACK (gimp_preview_invalidate),
 
410
                            preview);
393
411
 
394
412
  scale_data =
395
413
    gimp_scale_entry_new (GTK_TABLE (table), 0, 3,
396
414
              _("Sp_ike points:"), SCALE_WIDTH, ENTRY_WIDTH,
397
415
              svals.spike_pts, 0, 16, 1, 4, 0,
398
416
              TRUE, 0, 0,
399
 
              _("Adjust the Number of Spikes"), NULL);
400
 
  g_signal_connect (scale_data, "value_changed",
 
417
              _("Adjust the number of spikes"), NULL);
 
418
  g_signal_connect (scale_data, "value-changed",
401
419
                    G_CALLBACK (gimp_double_adjustment_update),
402
420
                    &svals.spike_pts);
 
421
  g_signal_connect_swapped (scale_data, "value-changed",
 
422
                            G_CALLBACK (gimp_preview_invalidate),
 
423
                            preview);
403
424
 
404
425
  scale_data =
405
426
    gimp_scale_entry_new (GTK_TABLE (table), 0, 4,
406
427
              _("Spi_ke angle (-1: random):"), SCALE_WIDTH, ENTRY_WIDTH,
407
428
              svals.spike_angle, -1, 360, 1, 15, 0,
408
429
              TRUE, 0, 0,
409
 
              _("Adjust the Spike Angle "
410
 
                "(-1 means a Random Angle is chosen)"), NULL);
411
 
  g_signal_connect (scale_data, "value_changed",
 
430
              _("Adjust the spike angle "
 
431
                "(-1 causes a random angle to be chosen)"), NULL);
 
432
  g_signal_connect (scale_data, "value-changed",
412
433
                    G_CALLBACK (gimp_double_adjustment_update),
413
434
                    &svals.spike_angle);
 
435
  g_signal_connect_swapped (scale_data, "value-changed",
 
436
                            G_CALLBACK (gimp_preview_invalidate),
 
437
                            preview);
414
438
 
415
439
  scale_data =
416
440
    gimp_scale_entry_new (GTK_TABLE (table), 0, 5,
417
441
              _("Spik_e density:"), SCALE_WIDTH, ENTRY_WIDTH,
418
442
              svals.density, 0.0, 1.0, 0.01, 0.1, 2,
419
443
              TRUE, 0, 0,
420
 
              _("Adjust the Spike Density"), NULL);
421
 
  g_signal_connect (scale_data, "value_changed",
 
444
              _("Adjust the spike density"), NULL);
 
445
  g_signal_connect (scale_data, "value-changed",
422
446
                    G_CALLBACK (gimp_double_adjustment_update),
423
447
                    &svals.density);
 
448
  g_signal_connect_swapped (scale_data, "value-changed",
 
449
                            G_CALLBACK (gimp_preview_invalidate),
 
450
                            preview);
424
451
 
425
452
  scale_data =
426
453
    gimp_scale_entry_new (GTK_TABLE (table), 0, 6,
427
 
              _("Op_acity:"), SCALE_WIDTH, ENTRY_WIDTH,
428
 
              svals.opacity, 0.0, 1.0, 0.01, 0.1, 2,
 
454
              _("Tr_ansparency:"), SCALE_WIDTH, ENTRY_WIDTH,
 
455
              svals.transparency, 0.0, 1.0, 0.01, 0.1, 2,
429
456
              TRUE, 0, 0,
430
 
              _("Adjust the Opacity of the Spikes"), NULL);
431
 
  g_signal_connect (scale_data, "value_changed",
 
457
              _("Adjust the opacity of the spikes"), NULL);
 
458
  g_signal_connect (scale_data, "value-changed",
432
459
                    G_CALLBACK (gimp_double_adjustment_update),
433
 
                    &svals.opacity);
 
460
                    &svals.transparency);
 
461
  g_signal_connect_swapped (scale_data, "value-changed",
 
462
                            G_CALLBACK (gimp_preview_invalidate),
 
463
                            preview);
434
464
 
435
465
  scale_data =
436
466
    gimp_scale_entry_new (GTK_TABLE (table), 0, 7,
437
467
              _("_Random hue:"), SCALE_WIDTH, ENTRY_WIDTH,
438
468
              svals.random_hue, 0.0, 1.0, 0.01, 0.1, 2,
439
469
              TRUE, 0, 0,
440
 
              _("Adjust the Value how much the Hue should "
441
 
                "be changed randomly"), NULL);
442
 
  g_signal_connect (scale_data, "value_changed",
 
470
              _("Adjust how much the hue should be changed randomly"), NULL);
 
471
  g_signal_connect (scale_data, "value-changed",
443
472
                    G_CALLBACK (gimp_double_adjustment_update),
444
473
                    &svals.random_hue);
 
474
  g_signal_connect_swapped (scale_data, "value-changed",
 
475
                            G_CALLBACK (gimp_preview_invalidate),
 
476
                            preview);
445
477
 
446
478
  scale_data =
447
479
    gimp_scale_entry_new (GTK_TABLE (table), 0, 8,
448
480
              _("Rando_m saturation:"), SCALE_WIDTH, ENTRY_WIDTH,
449
481
              svals.random_saturation, 0.0, 1.0, 0.01, 0.1, 2,
450
482
              TRUE, 0, 0,
451
 
              _("Adjust the Value how much the Saturation should "
452
 
                "be changed randomly"), NULL);
453
 
  g_signal_connect (scale_data, "value_changed",
 
483
              _("Adjust how much the saturation should be changed randomly"),
 
484
              NULL);
 
485
  g_signal_connect (scale_data, "value-changed",
454
486
                    G_CALLBACK (gimp_double_adjustment_update),
455
487
                    &svals.random_saturation);
 
488
  g_signal_connect_swapped (scale_data, "value-changed",
 
489
                            G_CALLBACK (gimp_preview_invalidate),
 
490
                            preview);
456
491
 
457
492
  hbox = gtk_hbox_new (FALSE, 12);
458
493
  gtk_box_pack_start (GTK_BOX (main_vbox), hbox, FALSE, FALSE, 0);
469
504
  gtk_widget_show (toggle);
470
505
 
471
506
  gimp_help_set_help_data (toggle,
472
 
                           _("Should the Luminosity be preserved?"), NULL);
 
507
                           _("Should the luminosity be preserved?"), NULL);
473
508
 
474
509
  g_signal_connect (toggle, "toggled",
475
510
                    G_CALLBACK (gimp_toggle_button_update),
476
511
                    &svals.preserve_luminosity);
 
512
  g_signal_connect_swapped (toggle, "toggled",
 
513
                            G_CALLBACK (gimp_preview_invalidate),
 
514
                            preview);
477
515
 
478
516
  toggle = gtk_check_button_new_with_mnemonic (_("In_verse"));
479
517
  gtk_box_pack_start (GTK_BOX (vbox), toggle, FALSE, FALSE, 0);
481
519
  gtk_widget_show (toggle);
482
520
 
483
521
  gimp_help_set_help_data (toggle,
484
 
                           _("Should an Inverse Effect be done?"), NULL);
 
522
                           _("Should the effect be inversed?"), NULL);
485
523
 
486
524
  g_signal_connect (toggle, "toggled",
487
525
                    G_CALLBACK (gimp_toggle_button_update),
488
526
                    &svals.inverse);
 
527
  g_signal_connect_swapped (toggle, "toggled",
 
528
                            G_CALLBACK (gimp_preview_invalidate),
 
529
                            preview);
489
530
 
490
531
  toggle = gtk_check_button_new_with_mnemonic (_("A_dd border"));
491
532
  gtk_box_pack_start (GTK_BOX (vbox), toggle, FALSE, FALSE, 0);
493
534
  gtk_widget_show (toggle);
494
535
 
495
536
  gimp_help_set_help_data (toggle,
496
 
                           _("Draw a Border of Spikes around the Image"), NULL);
 
537
                           _("Draw a border of spikes around the image"), NULL);
497
538
 
498
539
  g_signal_connect (toggle, "toggled",
499
540
                    G_CALLBACK (gimp_toggle_button_update),
500
541
                    &svals.border);
 
542
  g_signal_connect_swapped (toggle, "toggled",
 
543
                            G_CALLBACK (gimp_preview_invalidate),
 
544
                            preview);
501
545
 
502
546
  /*  colortype  */
503
547
  vbox = gimp_int_radio_group_new (FALSE, NULL,
516
560
  gimp_help_set_help_data (r1, _("Use the color of the image"), NULL);
517
561
  gimp_help_set_help_data (r2, _("Use the foreground color"), NULL);
518
562
  gimp_help_set_help_data (r3, _("Use the background color"), NULL);
519
 
 
520
 
  gtk_widget_show (dlg);
521
 
 
522
 
  run = (gimp_dialog_run (GIMP_DIALOG (dlg)) == GTK_RESPONSE_OK);
523
 
 
524
 
  gtk_widget_destroy (dlg);
 
563
  g_signal_connect_swapped (r1, "toggled",
 
564
                            G_CALLBACK (gimp_preview_invalidate),
 
565
                            preview);
 
566
  g_signal_connect_swapped (r2, "toggled",
 
567
                            G_CALLBACK (gimp_preview_invalidate),
 
568
                            preview);
 
569
  g_signal_connect_swapped (r3, "toggled",
 
570
                            G_CALLBACK (gimp_preview_invalidate),
 
571
                            preview);
 
572
 
 
573
  gtk_widget_show (dialog);
 
574
 
 
575
  run = (gimp_dialog_run (GIMP_DIALOG (dialog)) == GTK_RESPONSE_OK);
 
576
 
 
577
  gtk_widget_destroy (dialog);
525
578
 
526
579
  return run;
527
580
}
633
686
 
634
687
static void
635
688
sparkle (GimpDrawable *drawable,
636
 
         gint          threshold)
 
689
         GimpPreview  *preview)
637
690
{
638
691
  GimpPixelRgn src_rgn, dest_rgn;
639
692
  gdouble      nfrac, length, inten, spike_angle;
640
693
  gint         cur_progress, max_progress;
641
694
  gint         x1, y1, x2, y2;
 
695
  gint         width, height;
 
696
  gint         threshold;
642
697
  gint         lum, x, y, b;
643
698
  gboolean     gray, has_alpha;
644
699
  gint         alpha;
 
700
  gint         bytes;
645
701
  gpointer     pr;
646
702
  gint         tile_width, tile_height;
647
703
  GRand       *gr;
 
704
  guchar      *dest_buf = NULL;
648
705
 
649
706
  gr = g_rand_new ();
650
707
 
651
 
  gimp_drawable_mask_bounds (drawable->drawable_id, &x1, &y1, &x2, &y2);
 
708
  bytes = drawable->bpp;
 
709
 
 
710
  if (preview)
 
711
    {
 
712
      gimp_preview_get_position (preview, &x1, &y1);
 
713
      gimp_preview_get_size (preview, &width, &height);
 
714
 
 
715
      x2 = x1 + width;
 
716
      y2 = y1 + height;
 
717
      dest_buf = g_new0 (guchar, width * height * bytes);
 
718
    }
 
719
  else
 
720
    {
 
721
      gimp_drawable_mask_bounds (drawable->drawable_id,
 
722
                                 &x1, &y1, &x2, &y2);
 
723
      width  = x2 - x1;
 
724
      height = y2 - y1;
 
725
    }
 
726
 
 
727
  if (svals.border)
 
728
    {
 
729
      num_sparkles = 2 * (width + height);
 
730
      threshold = 255;
 
731
    }
 
732
  else
 
733
    {
 
734
      /*  compute the luminosity which exceeds the luminosity threshold  */
 
735
      threshold = compute_lum_threshold (drawable, svals.lum_threshold);
 
736
    }
652
737
 
653
738
  gray = gimp_drawable_is_gray (drawable->drawable_id);
654
739
  has_alpha = gimp_drawable_has_alpha (drawable->drawable_id);
663
748
 
664
749
  /* copy what is already there */
665
750
  gimp_pixel_rgn_init (&src_rgn, drawable,
666
 
                       x1, y1, (x2 - x1), (y2 - y1), FALSE, FALSE);
 
751
                       x1, y1, width, height, FALSE, FALSE);
667
752
  gimp_pixel_rgn_init (&dest_rgn, drawable,
668
 
                       x1, y1, (x2 - x1), (y2 - y1), TRUE, TRUE);
 
753
                       x1, y1, width, height, preview == NULL, TRUE);
669
754
 
670
755
  for (pr = gimp_pixel_rgns_register (2, &src_rgn, &dest_rgn);
671
756
       pr != NULL;
675
760
      guchar       *dest, *d;
676
761
 
677
762
      src = src_rgn.data;
678
 
      dest = dest_rgn.data;
 
763
      if (preview)
 
764
        dest = dest_buf + (((dest_rgn.y - y1) * width) + (dest_rgn.x - x1)) * bytes;
 
765
      else
 
766
        dest = dest_rgn.data;
679
767
 
680
768
      for (y = 0; y < src_rgn.h; y++)
681
769
        {
688
776
                {
689
777
                  memset (d, 0, alpha);
690
778
                }
691
 
              else
 
779
               else
692
780
                {
693
781
                  for (b = 0; b < alpha; b++)
694
782
                    d[b] = s[b];
702
790
            }
703
791
 
704
792
          src += src_rgn.rowstride;
705
 
          dest += dest_rgn.rowstride;
 
793
          if (preview)
 
794
            dest += width * bytes;
 
795
          else
 
796
            dest += dest_rgn.rowstride;
706
797
        }
707
798
    }
708
799
  /* add effects to new image based on intensity of old pixels */
709
800
 
710
801
  gimp_pixel_rgn_init (&src_rgn, drawable,
711
 
                       x1, y1, (x2 - x1), (y2 - y1), FALSE, FALSE);
 
802
                       x1, y1, width, height, FALSE, FALSE);
712
803
  gimp_pixel_rgn_init (&dest_rgn, drawable,
713
 
                       x1, y1, (x2 - x1), (y2 - y1), TRUE, TRUE);
 
804
                       x1, y1, width, height, preview == NULL, TRUE);
714
805
 
715
806
  for (pr = gimp_pixel_rgns_register (2, &src_rgn, &dest_rgn);
716
807
       pr != NULL;
767
858
                          fspike (&src_rgn, &dest_rgn, x1, y1, x2, y2,
768
859
                                  x + src_rgn.x, y + src_rgn.y,
769
860
                                  tile_width, tile_height,
770
 
                                  inten, length, spike_angle, gr);
 
861
                                  inten, length, spike_angle, gr, dest_buf);
771
862
 
772
863
                          /* minor spikes */
773
864
                          fspike (&src_rgn, &dest_rgn, x1, y1, x2, y2,
775
866
                                  tile_width, tile_height,
776
867
                                  inten * 0.7, length * 0.7,
777
868
                                  ((gdouble)spike_angle+180.0/svals.spike_pts),
778
 
                                  gr);
 
869
                                  gr, dest_buf);
779
870
                        }
780
 
                   }
781
 
 
782
 
                 cur_progress ++;
783
 
 
784
 
                 if ((cur_progress % 5) == 0)
785
 
                   gimp_progress_update ((double) cur_progress /
786
 
                                         (double) max_progress);
787
 
               }
788
 
 
 
871
                    }
 
872
                  if (!preview)
 
873
                    {
 
874
                      cur_progress ++;
 
875
 
 
876
                      if ((cur_progress % 5) == 0)
 
877
                        gimp_progress_update ((double) cur_progress /
 
878
                                              (double) max_progress);
 
879
                    }
 
880
                }
789
881
              s += src_rgn.bpp;
790
882
            }
791
883
 
793
885
        }
794
886
    }
795
887
 
796
 
  gimp_progress_update (1.0);
 
888
  if (preview)
 
889
    {
 
890
      gimp_preview_draw_buffer (preview, dest_buf, width * bytes);
 
891
      g_free (dest_buf);
 
892
    }
 
893
  else
 
894
    {
 
895
      gimp_progress_update (1.0);
797
896
 
798
 
  /*  update the blurred region  */
799
 
  gimp_drawable_flush (drawable);
800
 
  gimp_drawable_merge_shadow (drawable->drawable_id, TRUE);
801
 
  gimp_drawable_update (drawable->drawable_id, x1, y1, (x2 - x1), (y2 - y1));
 
897
      /*  update the sparkled region  */
 
898
      gimp_drawable_flush (drawable);
 
899
      gimp_drawable_merge_shadow (drawable->drawable_id, TRUE);
 
900
      gimp_drawable_update (drawable->drawable_id, x1, y1, width, height);
 
901
    }
802
902
 
803
903
  g_rand_free (gr);
804
904
}
818
918
      gint         *col,
819
919
      gint          bytes,
820
920
      gdouble       inten,
821
 
      guchar        color[MAX_CHANNELS])
 
921
      guchar        color[MAX_CHANNELS],
 
922
      guchar       *dest_buf)
822
923
{
823
924
  gint     x, y, b;
824
925
  gdouble  dx, dy, rs, val;
832
933
 
833
934
  if (x >= x1 && y >= y1 && x < x2 && y < y2)
834
935
    {
835
 
      newcol    = x / tile_width;
836
 
      newcoloff = x % tile_width;
837
 
      newrow    = y / tile_height;
838
 
      newrowoff = y % tile_height;
839
 
 
840
 
      if ((newcol != *col) || (newrow != *row))
 
936
      if (dest_buf)
 
937
        pixel = dest_buf + ((y - y1) * (x2 - x1) + (x - x1)) * bytes;
 
938
      else
841
939
        {
842
 
          *col = newcol;
843
 
          *row = newrow;
844
 
 
845
 
          if (tile)
846
 
            gimp_tile_unref (tile, TRUE);
847
 
 
848
 
          tile = gimp_drawable_get_tile (drawable, TRUE, *row, *col);
849
 
          gimp_tile_ref (tile);
 
940
          newcol    = x / tile_width;
 
941
          newcoloff = x % tile_width;
 
942
          newrow    = y / tile_height;
 
943
          newrowoff = y % tile_height;
 
944
 
 
945
          if ((newcol != *col) || (newrow != *row))
 
946
            {
 
947
              *col = newcol;
 
948
              *row = newrow;
 
949
 
 
950
              if (tile)
 
951
                gimp_tile_unref (tile, TRUE);
 
952
 
 
953
              tile = gimp_drawable_get_tile (drawable, TRUE, *row, *col);
 
954
              gimp_tile_ref (tile);
 
955
            }
 
956
 
 
957
          pixel = tile->data + tile->bpp * (tile->ewidth * newrowoff + newcoloff);
850
958
        }
851
 
 
852
 
      pixel = tile->data + tile->bpp * (tile->ewidth * newrowoff + newcoloff);
853
959
      dx = xr - x; dy = yr - y;
854
960
      rs = dx * dx + dy * dy;
855
961
      val = inten * exp (-rs / PSV);
865
971
            {
866
972
              if (new < color[b])
867
973
                {
868
 
                  new *= (1.0 - val * (1.0 - svals.opacity));
 
974
                  new *= (1.0 - val * (1.0 - svals.transparency));
869
975
                }
870
976
              else
871
977
                {
872
 
                  new -= val * color[b] * (1.0 - svals.opacity);
 
978
                  new -= val * color[b] * (1.0 - svals.transparency);
873
979
                  if (new < 0.0)
874
980
                    new = 0.0;
875
981
                }
876
982
            }
877
983
 
878
 
          new *= 1.0 - val * svals.opacity;
 
984
          new *= 1.0 - val * svals.transparency;
879
985
          new += val * color[b];
880
986
 
881
987
          if (new > 255)
905
1011
        gdouble       inten,
906
1012
        gdouble       length,
907
1013
        gdouble       angle,
908
 
        GRand        *gr)
 
1014
        GRand        *gr,
 
1015
        guchar       *dest_buf)
909
1016
{
910
 
  const gdouble efac = 2.0;
911
 
  gdouble xrt, yrt, dx, dy;
912
 
  gdouble rpos;
913
 
  gdouble in;
914
 
  gdouble theta;
915
 
  gdouble sfac;
916
 
  gint    r, g, b;
917
 
  GimpTile  *tile = NULL;
918
 
  gint    row, col;
919
 
  gint    i;
920
 
  gint    bytes;
921
 
  gint    ok;
922
 
  GimpRGB gimp_color;
923
 
  guchar  pixel[MAX_CHANNELS];
924
 
  guchar  chosen_color[MAX_CHANNELS];
925
 
  guchar  color[MAX_CHANNELS];
 
1017
  const gdouble  efac = 2.0;
 
1018
  gdouble        xrt, yrt, dx, dy;
 
1019
  gdouble        rpos;
 
1020
  gdouble        in;
 
1021
  gdouble        theta;
 
1022
  gdouble        sfac;
 
1023
  gint           r, g, b;
 
1024
  GimpTile      *tile = NULL;
 
1025
  gint           row, col;
 
1026
  gint           i;
 
1027
  gint           bytes;
 
1028
  gboolean       ok;
 
1029
  GimpRGB        gimp_color;
 
1030
  guchar         pixel[MAX_CHANNELS];
 
1031
  guchar         chosen_color[MAX_CHANNELS];
 
1032
  guchar         color[MAX_CHANNELS];
926
1033
 
927
1034
  theta = angle;
928
1035
  bytes = dest_rgn->bpp;
1019
1126
 
1020
1127
          tile = rpnt (dest_rgn->drawable, tile, x1, y1, x2, y2,
1021
1128
                       xrt, yrt, tile_width, tile_height,
1022
 
                       &row, &col, bytes, in, color);
 
1129
                       &row, &col, bytes, in, color, dest_buf);
1023
1130
          tile = rpnt (dest_rgn->drawable, tile, x1, y1, x2, y2,
1024
1131
                       xrt + 1.0, yrt, tile_width, tile_height,
1025
 
                       &row, &col, bytes, in, color);
 
1132
                       &row, &col, bytes, in, color, dest_buf);
1026
1133
          tile = rpnt (dest_rgn->drawable, tile, x1, y1, x2, y2,
1027
1134
                       xrt + 1.0, yrt + 1.0, tile_width, tile_height,
1028
 
                       &row, &col, bytes, in, color);
 
1135
                       &row, &col, bytes, in, color, dest_buf);
1029
1136
          tile = rpnt (dest_rgn->drawable, tile, x1, y1, x2, y2,
1030
1137
                       xrt, yrt + 1.0, tile_width, tile_height,
1031
 
                       &row, &col, bytes, in, color);
 
1138
                       &row, &col, bytes, in, color, dest_buf);
1032
1139
 
1033
1140
          xrt += dx;
1034
1141
          yrt += dy;