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

« back to all changes in this revision

Viewing changes to plug-ins/common/emboss.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:
22
22
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23
23
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
24
24
 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25
 
 *
26
 
 * $Id: emboss.c,v 1.50.2.1 2005/02/21 16:13:07 neo Exp $
27
25
 */
28
26
 
29
27
#include "config.h"
30
28
 
31
 
#include <stdio.h>
32
29
#include <string.h>
33
 
#include <stdlib.h>
34
 
#include <sys/types.h>
35
 
 
36
 
#include <gtk/gtk.h>
37
30
 
38
31
#include <libgimp/gimp.h>
39
32
#include <libgimp/gimpui.h>
41
34
#include "libgimp/stdplugins-intl.h"
42
35
 
43
36
 
 
37
#define PLUG_IN_PROC   "plug-in-emboss"
 
38
#define PLUG_IN_BINARY "emboss"
 
39
 
 
40
 
44
41
enum
45
42
{
46
43
  FUNCTION_BUMPMAP = 0,
76
73
  gdouble bg;
77
74
} Filter;
78
75
 
79
 
static void query (void);
80
 
static void run   (const gchar      *name,
81
 
                   gint              nparam,
82
 
                   const GimpParam  *param,
83
 
                   gint             *nretvals,
84
 
                   GimpParam       **retvals);
85
 
 
86
 
static gint emboss            (GimpDrawable *drawable,
87
 
                               GimpPreview  *preview);
88
 
static gint emboss_dialog     (GimpDrawable *drawable);
89
 
 
90
 
static inline void EmbossInit (gdouble       azimuth,
91
 
                               gdouble       elevation,
92
 
                               gushort       width45);
93
 
static inline void EmbossRow  (guchar       *src,
94
 
                               guchar       *texture,
95
 
                               guchar       *dst,
96
 
                               guint         xSize,
97
 
                               guint         bypp,
98
 
                               gint          alpha);
 
76
static void     query         (void);
 
77
static void     run           (const gchar      *name,
 
78
                               gint              nparam,
 
79
                               const GimpParam  *param,
 
80
                               gint             *nretvals,
 
81
                               GimpParam       **retvals);
 
82
 
 
83
static void     emboss        (GimpDrawable     *drawable,
 
84
                               GimpPreview      *preview);
 
85
static gboolean emboss_dialog (GimpDrawable     *drawable);
 
86
 
 
87
static void     emboss_init   (gdouble           azimuth,
 
88
                               gdouble           elevation,
 
89
                               gushort           width45);
 
90
static void     emboss_row    (const guchar     *src,
 
91
                               const guchar     *texture,
 
92
                               guchar           *dst,
 
93
                               guint             width,
 
94
                               guint             bypp,
 
95
                               gboolean          alpha);
 
96
 
99
97
 
100
98
#define DtoR(d) ((d)*(G_PI/(gdouble)180))
101
99
 
102
 
GimpPlugInInfo PLUG_IN_INFO =
 
100
 
 
101
const GimpPlugInInfo PLUG_IN_INFO =
103
102
{
104
103
  NULL,  /* init  */
105
104
  NULL,  /* quit  */
112
111
static void
113
112
query (void)
114
113
{
115
 
  static GimpParamDef args[] =
 
114
  static const GimpParamDef args[] =
116
115
  {
117
 
    { GIMP_PDB_INT32, "run_mode", "Interactive, non-interactive" },
118
 
    { GIMP_PDB_IMAGE, "img", "The Image" },
119
 
    { GIMP_PDB_DRAWABLE, "drw", "The Drawable" },
120
 
    { GIMP_PDB_FLOAT, "azimuth", "The Light Angle (degrees)" },
121
 
    { GIMP_PDB_FLOAT, "elevation", "The Elevation Angle (degrees)" },
122
 
    { GIMP_PDB_INT32, "depth", "The Filter Width" },
123
 
    { GIMP_PDB_INT32, "embossp", "Emboss or Bumpmap" }
 
116
    { GIMP_PDB_INT32,    "run-mode",  "Interactive, non-interactive"  },
 
117
    { GIMP_PDB_IMAGE,    "image",     "The Image"                     },
 
118
    { GIMP_PDB_DRAWABLE, "drawable",  "The Drawable"                  },
 
119
    { GIMP_PDB_FLOAT,    "azimuth",   "The Light Angle (degrees)"     },
 
120
    { GIMP_PDB_FLOAT,    "elevation", "The Elevation Angle (degrees)" },
 
121
    { GIMP_PDB_INT32,    "depth",     "The Filter Width"              },
 
122
    { GIMP_PDB_INT32,    "emboss",    "Emboss or Bumpmap"             }
124
123
  };
125
124
 
126
 
  gimp_install_procedure ("plug_in_emboss",
127
 
                          "Emboss filter",
 
125
  gimp_install_procedure (PLUG_IN_PROC,
 
126
                          N_("Simulate an image created by embossing"),
128
127
                          "Emboss or Bumpmap the given drawable, specifying "
129
128
                          "the angle and elevation for the light source.",
130
129
                          "Eric L. Hernes, John Schlag",
136
135
                          G_N_ELEMENTS (args), 0,
137
136
                          args, NULL);
138
137
 
139
 
  gimp_plugin_menu_register ("plug_in_emboss", "<Image>/Filters/Distorts");
 
138
  gimp_plugin_menu_register (PLUG_IN_PROC, "<Image>/Filters/Distorts");
140
139
}
141
140
 
142
141
static void
164
163
  switch (param[0].data.d_int32)
165
164
    {
166
165
    case GIMP_RUN_INTERACTIVE:
167
 
      gimp_get_data ("plug_in_emboss", &evals);
 
166
      gimp_get_data (PLUG_IN_PROC, &evals);
168
167
 
169
 
      if (emboss_dialog (drawable) == -1)
 
168
      if (! emboss_dialog (drawable))
170
169
        {
171
 
          rvals[0].data.d_status = GIMP_PDB_EXECUTION_ERROR;
 
170
          rvals[0].data.d_status = GIMP_PDB_CANCEL;
172
171
        }
173
172
      else
174
173
        {
175
 
          gimp_set_data ("plug_in_emboss", &evals, sizeof (piArgs));
 
174
          gimp_set_data (PLUG_IN_PROC, &evals, sizeof (piArgs));
176
175
        }
177
176
 
178
177
      break;
189
188
      evals.depth     = param[5].data.d_int32;
190
189
      evals.embossp   = param[6].data.d_int32;
191
190
 
192
 
      if (emboss (drawable, NULL)==-1)
193
 
        {
194
 
          rvals[0].data.d_status = GIMP_PDB_EXECUTION_ERROR;
195
 
          break;
196
 
        }
 
191
      emboss (drawable, NULL);
197
192
      break;
198
193
 
199
194
    case GIMP_RUN_WITH_LAST_VALS:
200
 
      gimp_get_data ("plug_in_emboss", &evals);
 
195
      gimp_get_data (PLUG_IN_PROC, &evals);
201
196
      /* use this image and drawable, even with last args */
202
 
      if (emboss (drawable, NULL)==-1)
203
 
        {
204
 
          rvals[0].data.d_status = GIMP_PDB_EXECUTION_ERROR;
205
 
        }
 
197
      emboss (drawable, NULL);
206
198
    break;
207
199
  }
208
200
}
210
202
#define pixelScale 255.9
211
203
 
212
204
static void
213
 
EmbossInit (gdouble azimuth,
214
 
            gdouble elevation,
215
 
            gushort width45)
 
205
emboss_init (gdouble azimuth,
 
206
             gdouble elevation,
 
207
             gushort width45)
216
208
{
217
209
  /*
218
210
   * compute the light vector from the input parameters.
248
240
 * The unary case ('texture' == NULL) uses the shading result as output.
249
241
 * The binary case multiples the optional 'texture' image by the shade.
250
242
 * Images are in row major order with interleaved color components (rgbrgb...).
251
 
 * E.g., component c of pixel x,y of 'dst' is dst[3*(y*xSize + x) + c].
 
243
 * E.g., component c of pixel x,y of 'dst' is dst[3*(y*width + x) + c].
252
244
 *
253
245
 */
254
246
 
255
 
static inline void
256
 
EmbossRow (guchar *src,
257
 
           guchar *texture,
258
 
           guchar *dst,
259
 
           guint   xSize,
260
 
           guint   bypp,
261
 
           gint    alpha)
 
247
static void
 
248
emboss_row (const guchar *src,
 
249
            const guchar *texture,
 
250
            guchar       *dst,
 
251
            guint         width,
 
252
            guint         bypp,
 
253
            gboolean      alpha)
262
254
{
263
 
  glong Nx, Ny, NdotL;
264
 
  guchar *s1, *s2, *s3;
265
 
  gint x, shade, b;
266
 
  gint bytes;
 
255
  const guchar *s[3];
 
256
  gdouble       M[3][3];
 
257
  gint          x, bytes;
267
258
 
268
259
  /* mung pixels, avoiding edge pixels */
269
 
  s1 = src + bypp;
270
 
  s2 = s1 + (xSize * bypp);
271
 
  s3 = s2 + (xSize * bypp);
 
260
  s[0] = src;
 
261
  s[1] = s[0] + (width * bypp);
 
262
  s[2] = s[1] + (width * bypp);
272
263
  dst += bypp;
273
264
 
274
265
  bytes = (alpha) ? bypp - 1 : bypp;
275
266
 
276
267
  if (texture)
277
 
    texture += bypp;
 
268
    texture += (width + 1) * bypp;
278
269
 
279
 
  for (x = 1; x < xSize - 1; x++, s1 += bypp, s2 += bypp, s3 += bypp)
 
270
  for (x = 1; x < width - 1; x++)
280
271
    {
281
 
      /*
282
 
       * compute the normal from the src map. the type of the
283
 
       * expression before the cast is compiler dependent. in
284
 
       * some cases the sum is unsigned, in others it is
285
 
       * signed. ergo, cast to signed.
286
 
       */
287
 
      Nx = (int) (s1[-(int)bypp] + s2[-(int)bypp] + s3[-(int)bypp]
288
 
                  - s1[bypp] - s2[bypp] - s3[bypp]);
289
 
      Ny = (int) (s3[-(int)bypp] + s3[0] + s3[bypp] - s1[-(int)bypp]
290
 
                  - s1[0] - s1[bypp]);
 
272
      gdouble a;
 
273
      glong   Nx, Ny, NdotL;
 
274
      gint    shade, b;
 
275
      gint    i, j;
 
276
 
 
277
      for (i = 0; i < 3; i++)
 
278
        for (j = 0; j < 3; j++)
 
279
          M[i][j] = 0.0;
 
280
 
 
281
      for (b = 0; b < bytes; b++)
 
282
        {
 
283
          for (i = 0; i < 3; i++)
 
284
            for (j = 0; j < 3; j++)
 
285
              {
 
286
                if (alpha)
 
287
                  a = s[i][j * bypp + bytes] / 255.0;
 
288
                else
 
289
                  a = 1.0;
 
290
 
 
291
                M[i][j] += a * s[i][j * bypp + b];
 
292
              }
 
293
        }
 
294
 
 
295
      Nx = M[0][0] + M[1][0] + M[2][0] - M[0][2] - M[1][2] - M[2][2];
 
296
      Ny = M[2][0] + M[2][1] + M[2][2] - M[0][0] - M[0][1] - M[0][2];
291
297
 
292
298
      /* shade with distant light source */
293
299
      if ( Nx == 0 && Ny == 0 )
301
307
      if (texture)
302
308
        {
303
309
          for (b = 0; b < bytes; b++)
304
 
            {
305
 
              *dst++ = (*texture++ * shade) >> 8;
306
 
            }
 
310
            *dst++ = (*texture++ * shade) >> 8;
 
311
 
307
312
          if (alpha)
308
313
            {
309
 
              *dst++ = s2[bytes]; /* preserve the alpha */
 
314
              *dst++ = s[1][bypp + bytes]; /* preserve the alpha */
310
315
              texture++;
311
316
            }
312
317
        }
313
318
      else
314
319
        {
315
320
          for (b = 0; b < bytes; b++)
316
 
            {
317
 
              *dst++ = shade;
318
 
            }
 
321
            *dst++ = shade;
 
322
 
319
323
          if (alpha)
320
 
            *dst++ = s2[bytes]; /* preserve the alpha */
 
324
            *dst++ = s[1][bypp + bytes]; /* preserve the alpha */
321
325
        }
 
326
 
 
327
      for (i = 0; i < 3; i++)
 
328
        s[i] += bypp;
322
329
    }
 
330
 
323
331
  if (texture)
324
332
    texture += bypp;
325
333
}
326
334
 
327
 
static gint
 
335
static void
328
336
emboss (GimpDrawable *drawable,
329
337
        GimpPreview  *preview)
330
338
{
332
340
  gint          p_update;
333
341
  gint          y;
334
342
  gint          x1, y1, x2, y2;
335
 
  guint         width, height;
336
 
  gint          bypp, rowsize, has_alpha;
 
343
  gint          width, height;
 
344
  gint          bypp, rowsize;
 
345
  gboolean      has_alpha;
337
346
  guchar       *srcbuf, *dstbuf;
338
347
 
339
348
  if (preview)
356
365
      width = x2 - x1;
357
366
      height = y2 - y1;
358
367
    }
 
368
 
359
369
  bypp = drawable->bpp;
360
370
  p_update = MAX (1, height / 20);
361
371
  rowsize = width * bypp;
371
381
  srcbuf = g_new0 (guchar, rowsize * 3);
372
382
  dstbuf = g_new0 (guchar, rowsize);
373
383
 
374
 
  EmbossInit (DtoR(evals.azimuth), DtoR(evals.elevation), evals.depth);
 
384
  emboss_init (DtoR(evals.azimuth), DtoR(evals.elevation), evals.depth);
375
385
  if (!preview)
376
386
    gimp_progress_init (_("Emboss"));
377
387
 
378
388
  /* first row */
379
389
  gimp_pixel_rgn_get_rect (&src, srcbuf, x1, y1, width, 3);
380
390
  memcpy (srcbuf, srcbuf + rowsize, rowsize);
381
 
  EmbossRow (srcbuf, evals.embossp ? (guchar *) 0 : srcbuf,
382
 
             dstbuf, width, bypp, has_alpha);
 
391
  emboss_row (srcbuf, evals.embossp ? NULL : srcbuf,
 
392
              dstbuf, width, bypp, has_alpha);
383
393
  gimp_pixel_rgn_set_row (&dst, dstbuf, 0, 0, width);
384
394
 
 
395
  /* middle rows */
 
396
  for (y = 0; y < height - 2; y++)
 
397
    {
 
398
      if (! preview && (y % p_update == 0))
 
399
        gimp_progress_update ((gdouble) y / (gdouble) height);
 
400
 
 
401
      gimp_pixel_rgn_get_rect (&src, srcbuf, x1, y1 + y, width, 3);
 
402
      emboss_row (srcbuf, evals.embossp ? NULL : srcbuf,
 
403
                  dstbuf, width, bypp, has_alpha);
 
404
      gimp_pixel_rgn_set_row (&dst, dstbuf, x1, y1 + y + 1, width);
 
405
    }
 
406
 
385
407
  /* last row */
386
 
  gimp_pixel_rgn_get_rect (&src, srcbuf, x1, y2-3, width, 3);
 
408
  gimp_pixel_rgn_get_rect (&src, srcbuf, x1, y2 - 3, width, 3);
387
409
  memcpy (srcbuf + rowsize * 2, srcbuf + rowsize, rowsize);
388
 
  EmbossRow (srcbuf, evals.embossp ? (guchar *) 0 : srcbuf,
389
 
             dstbuf, width, bypp, has_alpha);
390
 
  gimp_pixel_rgn_set_row (&dst, dstbuf, x1, y2-1, width);
391
 
 
392
 
  for (y = 0; y < height - 2; y++)
393
 
    {
394
 
      if (! preview && (y % p_update == 0))
395
 
          gimp_progress_update ((gdouble) y / (gdouble) height);
396
 
 
397
 
      gimp_pixel_rgn_get_rect (&src, srcbuf, x1, y1+y, width, 3);
398
 
      EmbossRow (srcbuf, evals.embossp ? (guchar *) 0 : srcbuf,
399
 
                 dstbuf, width, bypp, has_alpha);
400
 
     gimp_pixel_rgn_set_row (&dst, dstbuf, x1, y1+y+1, width);
401
 
  }
 
410
  emboss_row (srcbuf, evals.embossp ? NULL : srcbuf,
 
411
              dstbuf, width, bypp, has_alpha);
 
412
  gimp_pixel_rgn_set_row (&dst, dstbuf, x1, y2 - 1, width);
402
413
 
403
414
  if (preview)
404
415
    {
417
428
 
418
429
  g_free (srcbuf);
419
430
  g_free (dstbuf);
420
 
 
421
 
  return 0;
422
431
}
423
432
 
424
 
static gint
 
433
static gboolean
425
434
emboss_dialog (GimpDrawable *drawable)
426
435
{
427
436
  GtkWidget *dialog;
434
443
  GtkObject *adj;
435
444
  gboolean   run;
436
445
 
437
 
  gimp_ui_init ("emboss", TRUE);
 
446
  gimp_ui_init (PLUG_IN_BINARY, TRUE);
438
447
 
439
 
  dialog = gimp_dialog_new (_("Emboss"), "emboss",
 
448
  dialog = gimp_dialog_new (_("Emboss"), PLUG_IN_BINARY,
440
449
                            NULL, 0,
441
 
                            gimp_standard_help_func, "plug-in-emboss",
 
450
                            gimp_standard_help_func, PLUG_IN_PROC,
442
451
 
443
452
                            GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
444
453
                            GTK_STOCK_OK,     GTK_RESPONSE_OK,
445
454
 
446
455
                            NULL);
447
456
 
 
457
  gtk_dialog_set_alternative_button_order (GTK_DIALOG (dialog),
 
458
                                           GTK_RESPONSE_OK,
 
459
                                           GTK_RESPONSE_CANCEL,
 
460
                                           -1);
 
461
 
 
462
  gimp_window_set_transient (GTK_WINDOW (dialog));
 
463
 
448
464
  main_vbox = gtk_vbox_new (FALSE, 12);
449
465
  gtk_container_set_border_width (GTK_CONTAINER (main_vbox), 12);
450
466
  gtk_container_add (GTK_CONTAINER (GTK_DIALOG (dialog)->vbox), main_vbox);
486
502
                              evals.azimuth, 0.0, 360.0, 1.0, 10.0, 2,
487
503
                              TRUE, 0, 0,
488
504
                              NULL, NULL);
489
 
  g_signal_connect (adj, "value_changed",
 
505
  g_signal_connect (adj, "value-changed",
490
506
                    G_CALLBACK (gimp_double_adjustment_update),
491
507
                    &evals.azimuth);
492
 
  g_signal_connect_swapped (adj, "value_changed",
 
508
  g_signal_connect_swapped (adj, "value-changed",
493
509
                            G_CALLBACK (gimp_preview_invalidate),
494
510
                            preview);
495
511
 
498
514
                              evals.elevation, 0.0, 180.0, 1.0, 10.0, 2,
499
515
                              TRUE, 0, 0,
500
516
                              NULL, NULL);
501
 
  g_signal_connect (adj, "value_changed",
 
517
  g_signal_connect (adj, "value-changed",
502
518
                    G_CALLBACK (gimp_double_adjustment_update),
503
519
                    &evals.elevation);
504
 
  g_signal_connect_swapped (adj, "value_changed",
 
520
  g_signal_connect_swapped (adj, "value-changed",
505
521
                            G_CALLBACK (gimp_preview_invalidate),
506
522
                            preview);
507
523
 
510
526
                              evals.depth, 1.0, 100.0, 1.0, 5.0, 0,
511
527
                              TRUE, 0, 0,
512
528
                              NULL, NULL);
513
 
  g_signal_connect (adj, "value_changed",
 
529
  g_signal_connect (adj, "value-changed",
514
530
                    G_CALLBACK (gimp_int_adjustment_update),
515
531
                    &evals.depth);
516
 
  g_signal_connect_swapped (adj, "value_changed",
 
532
  g_signal_connect_swapped (adj, "value-changed",
517
533
                            G_CALLBACK (gimp_preview_invalidate),
518
534
                            preview);
519
535
 
526
542
  gtk_widget_destroy (dialog);
527
543
 
528
544
  if (run)
529
 
    return emboss (drawable, NULL);
530
 
  else
531
 
    return -1;
 
545
    emboss (drawable, NULL);
 
546
 
 
547
  return run;
532
548
}
533