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

« back to all changes in this revision

Viewing changes to plug-ins/common/iwarp.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:
1
 
/* The GIMP -- an image manipulation program
 
1
/* GIMP - The GNU Image Manipulation Program
2
2
 * Copyright (C) 1995 Spencer Kimball and Peter Mattis
3
3
 *
4
4
 * This program is free software; you can redistribute it and/or modify
35
35
  v0.12
36
36
    fixes a very bad bug.
37
37
     (thanks to Arthur Hagen for reporting it)
 
38
  v0.13
 
39
    2005 - changed to scale preview with the window;
 
40
           João S. O. Bueno Calligaris
38
41
 
39
42
*/
40
43
 
41
44
#include "config.h"
42
45
 
43
 
#include <stdlib.h>
44
46
#include <string.h>
45
 
#include <stdio.h>
46
 
 
47
 
#include <gtk/gtk.h>
48
47
 
49
48
#include <libgimp/gimp.h>
50
49
#include <libgimp/gimpui.h>
52
51
#include "libgimp/stdplugins-intl.h"
53
52
 
54
53
 
 
54
#define PLUG_IN_PROC           "plug-in-iwarp"
 
55
#define PLUG_IN_BINARY         "iwarp"
55
56
#define RESPONSE_RESET         1
56
57
 
57
 
#define MAX_PREVIEW_WIDTH      256
58
 
#define MAX_PREVIEW_HEIGHT     256
59
 
#define MAX_DEFORM_AREA_RADIUS 100
 
58
#define MAX_DEFORM_AREA_RADIUS 250
60
59
 
61
 
#define SCALE_WIDTH    100
62
 
#define MAX_NUM_FRAMES 100
 
60
#define SCALE_WIDTH            100
 
61
#define MAX_NUM_FRAMES         100
63
62
 
64
63
typedef enum
65
64
{
97
96
                         gint             *nreturn_vals,
98
97
                         GimpParam       **return_vals);
99
98
 
100
 
static void      iwarp                   (void);
101
 
static void      iwarp_frame             (void);
102
 
 
103
 
static gboolean  iwarp_dialog            (void);
104
 
static void      iwarp_animate_dialog    (GtkWidget *dlg,
105
 
                                          GtkWidget *notebook);
106
 
 
107
 
static void      iwarp_settings_dialog   (GtkWidget *dlg,
108
 
                                          GtkWidget *notebook);
109
 
 
110
 
static void      iwarp_response          (GtkWidget *widget,
111
 
                                          gint       response_id,
112
 
                                          gpointer   data);
113
 
 
114
 
static void      iwarp_realize_callback  (GtkWidget *widget);
115
 
 
116
 
static gint      iwarp_motion_callback   (GtkWidget *widget,
117
 
                                          GdkEvent  *event);
118
 
 
119
 
static void      iwarp_update_preview    (gint       x0,
120
 
                                          gint       y0,
121
 
                                          gint       x1,
122
 
                                          gint       y1);
123
 
 
124
 
static void      iwarp_get_pixel         (gint       x,
125
 
                                          gint       y,
126
 
                                          guchar    *pixel);
127
 
 
128
 
static void      iwarp_get_deform_vector (gdouble    x,
129
 
                                          gdouble    y,
130
 
                                          gdouble   *xv,
131
 
                                          gdouble   *yv);
132
 
 
133
 
static void      iwarp_get_point         (gdouble    x,
134
 
                                          gdouble    y,
135
 
                                          guchar    *color);
136
 
 
137
 
static gint      iwarp_supersample_test  (GimpVector2 *v0,
138
 
                                          GimpVector2 *v1,
139
 
                                          GimpVector2 *v2,
140
 
                                          GimpVector2 *v3);
141
 
 
142
 
static void      iwarp_getsample         (GimpVector2  v0,
143
 
                                          GimpVector2  v1,
144
 
                                          GimpVector2  v2,
145
 
                                          GimpVector2  v3,
146
 
                                          gdouble      x,
147
 
                                          gdouble      y,
148
 
                                          gint        *sample,
149
 
                                          gint        *cc,
150
 
                                          gint         depth,
151
 
                                          gdouble      scale);
152
 
 
153
 
static void      iwarp_supersample       (gint       sxl,
154
 
                                          gint       syl,
155
 
                                          gint       sxr,
156
 
                                          gint       syr,
157
 
                                          guchar    *dest_data,
158
 
                                          gint       stride,
159
 
                                          gint      *progress,
160
 
                                          gint       max_progress);
161
 
 
162
 
static void      iwarp_cpy_images        (void);
163
 
 
164
 
static void      iwarp_preview_get_pixel (gint       x,
165
 
                                          gint       y,
166
 
                                          guchar   **color);
167
 
 
168
 
static void      iwarp_preview_get_point (gdouble    x,
169
 
                                          gdouble    y,
170
 
                                          guchar    *color);
171
 
 
172
 
static void      iwarp_deform            (gint       x,
173
 
                                          gint       y,
174
 
                                          gdouble    vx,
175
 
                                          gdouble    vy);
176
 
 
177
 
static void      iwarp_move              (gint       x,
178
 
                                          gint       y,
179
 
                                          gint       xx,
180
 
                                          gint       yy);
181
 
 
182
 
 
183
 
GimpPlugInInfo PLUG_IN_INFO =
 
99
static void      iwarp                    (void);
 
100
static void      iwarp_frame              (void);
 
101
 
 
102
static gboolean  iwarp_dialog             (void);
 
103
static void      iwarp_animate_dialog     (GtkWidget *dlg,
 
104
                                           GtkWidget *notebook);
 
105
 
 
106
static void      iwarp_settings_dialog    (GtkWidget *dlg,
 
107
                                           GtkWidget *notebook);
 
108
 
 
109
static void      iwarp_response           (GtkWidget *widget,
 
110
                                           gint       response_id,
 
111
                                           gpointer   data);
 
112
 
 
113
static void      iwarp_realize_callback   (GtkWidget *widget);
 
114
static gboolean  iwarp_motion_callback    (GtkWidget *widget,
 
115
                                           GdkEvent  *event);
 
116
static void      iwarp_resize_callback    (GtkWidget *widget);
 
117
 
 
118
static void      iwarp_update_preview     (gint       x0,
 
119
                                           gint       y0,
 
120
                                           gint       x1,
 
121
                                           gint       y1);
 
122
 
 
123
static void      iwarp_get_pixel          (gint       x,
 
124
                                           gint       y,
 
125
                                           guchar    *pixel);
 
126
 
 
127
static void      iwarp_get_deform_vector  (gdouble    x,
 
128
                                           gdouble    y,
 
129
                                           gdouble   *xv,
 
130
                                           gdouble   *yv);
 
131
 
 
132
static void      iwarp_get_point          (gdouble    x,
 
133
                                           gdouble    y,
 
134
                                           guchar    *color);
 
135
 
 
136
static gint      iwarp_supersample_test   (GimpVector2 *v0,
 
137
                                           GimpVector2 *v1,
 
138
                                           GimpVector2 *v2,
 
139
                                           GimpVector2 *v3);
 
140
 
 
141
static void      iwarp_getsample          (GimpVector2  v0,
 
142
                                           GimpVector2  v1,
 
143
                                           GimpVector2  v2,
 
144
                                           GimpVector2  v3,
 
145
                                           gdouble      x,
 
146
                                           gdouble      y,
 
147
                                           gint        *sample,
 
148
                                           gint        *cc,
 
149
                                           gint         depth,
 
150
                                           gdouble      scale);
 
151
 
 
152
static void      iwarp_supersample        (gint       sxl,
 
153
                                           gint       syl,
 
154
                                           gint       sxr,
 
155
                                           gint       syr,
 
156
                                           guchar    *dest_data,
 
157
                                           gint       stride,
 
158
                                           gint      *progress,
 
159
                                           gint       max_progress);
 
160
 
 
161
static void      iwarp_cpy_images         (void);
 
162
 
 
163
static void      iwarp_preview_get_pixel  (gint       x,
 
164
                                           gint       y,
 
165
                                           guchar   **color);
 
166
 
 
167
static void      iwarp_preview_get_point  (gdouble    x,
 
168
                                           gdouble    y,
 
169
                                           guchar    *color);
 
170
 
 
171
static void      iwarp_deform             (gint       x,
 
172
                                           gint       y,
 
173
                                           gdouble    vx,
 
174
                                           gdouble    vy);
 
175
 
 
176
static void      iwarp_move               (gint       x,
 
177
                                           gint       y,
 
178
                                           gint       xx,
 
179
                                           gint       yy);
 
180
 
 
181
static void     iwarp_scale_preview       (gint       new_width,
 
182
                                           gint       new_height,
 
183
                                           gint       old_width,
 
184
                                           gint       old_height);
 
185
static void     iwarp_preview_build       (GtkWidget *vbox);
 
186
 
 
187
static void     iwarp_init                (void);
 
188
static void     iwarp_preview_init        (void);
 
189
 
 
190
 
 
191
 
 
192
const GimpPlugInInfo PLUG_IN_INFO =
184
193
{
185
194
  NULL,  /* init_proc  */
186
195
  NULL,  /* quit_proc  */
204
213
  2
205
214
};
206
215
 
207
 
static GimpDrawable   *drawable = NULL;
208
 
static GimpDrawable   *destdrawable = NULL;
209
 
static GtkWidget   *preview = NULL;
210
 
static guchar      *srcimage = NULL;
211
 
static guchar      *dstimage = NULL;
212
 
static gint         preview_width, preview_height;
213
 
static gint         sel_width, sel_height;
214
 
static gint         image_bpp;
215
 
static gint         preserve_trans;
216
 
static GimpVector2 *deform_vectors = NULL;
217
 
static GimpVector2 *deform_area_vectors = NULL;
218
 
static gint         lastx, lasty;
219
 
static gdouble      filter[MAX_DEFORM_AREA_RADIUS];
220
 
static gboolean     do_animate = FALSE;
221
 
static gboolean     do_animate_reverse = FALSE;
222
 
static gboolean     do_animate_ping_pong = FALSE;
223
 
static gdouble      supersample_threshold_2;
224
 
static gint         xl, yl, xh, yh;
225
 
static gint         tile_width, tile_height;
226
 
static GimpTile    *tile = NULL;
227
 
static gdouble      pre2img, img2pre;
228
 
static gint         preview_bpp;
229
 
static gdouble      animate_deform_value = 1.0;
230
 
static gint32       imageID;
231
 
static gint         animate_num_frames = 2;
232
 
static gint         frame_number;
233
 
static gboolean     layer_alpha;
 
216
 
 
217
static GimpDrawable *drawable = NULL;
 
218
static GimpDrawable *destdrawable = NULL;
 
219
static GtkWidget    *preview = NULL;
 
220
static guchar       *srcimage = NULL;
 
221
static guchar       *dstimage = NULL;
 
222
static gint          preview_width, preview_height;
 
223
static gint          sel_width, sel_height;
 
224
static gint          image_bpp;
 
225
static gint          lock_alpha;
 
226
static GimpVector2  *deform_vectors = NULL;
 
227
static GimpVector2  *deform_area_vectors = NULL;
 
228
static gint          lastx, lasty;
 
229
static gdouble       filter[MAX_DEFORM_AREA_RADIUS];
 
230
static gboolean      do_animate = FALSE;
 
231
static gboolean      do_animate_reverse = FALSE;
 
232
static gboolean      do_animate_ping_pong = FALSE;
 
233
static gdouble       supersample_threshold_2;
 
234
static gint          xl, yl, xh, yh;
 
235
static gint          tile_width, tile_height;
 
236
static GimpTile     *tile = NULL;
 
237
static gdouble       pre2img, img2pre;
 
238
static gint          preview_bpp;
 
239
static gdouble       animate_deform_value = 1.0;
 
240
static gint32        imageID;
 
241
static gint          animate_num_frames = 2;
 
242
static gint          frame_number;
 
243
static gboolean      layer_alpha;
 
244
static gint          max_current_preview_width  = 320;
 
245
static gint          max_current_preview_height = 320;
 
246
static gint          resize_idle = 0;
234
247
 
235
248
 
236
249
MAIN ()
238
251
static void
239
252
query (void)
240
253
{
241
 
  static GimpParamDef args[] =
 
254
  static const GimpParamDef args[] =
242
255
  {
243
 
    { GIMP_PDB_INT32,    "run_mode", "Interactive, non-interactive" },
 
256
    { GIMP_PDB_INT32,    "run-mode", "Interactive, non-interactive" },
244
257
    { GIMP_PDB_IMAGE,    "image",    "Input image (unused)"         },
245
258
    { GIMP_PDB_DRAWABLE, "drawable", "Input drawable"               }
246
259
  };
247
260
 
248
 
  gimp_install_procedure ("plug_in_iwarp",
249
 
                          "Interactive warping of the specified drawable",
 
261
  gimp_install_procedure (PLUG_IN_PROC,
 
262
                          N_("Use mouse control to warp image areas"),
250
263
                          "Interactive warping of the specified drawable",
251
264
                          "Norbert Schmitz",
252
265
                          "Norbert Schmitz",
257
270
                          G_N_ELEMENTS (args), 0,
258
271
                          args, NULL);
259
272
 
260
 
  gimp_plugin_menu_register ("plug_in_iwarp", "<Image>/Filters/Distorts");
 
273
  gimp_plugin_menu_register (PLUG_IN_PROC, "<Image>/Filters/Distorts");
261
274
}
262
275
 
263
276
static void
286
299
      switch (run_mode)
287
300
        {
288
301
        case GIMP_RUN_INTERACTIVE:
289
 
          gimp_get_data ("plug_in_iwarp", &iwarp_vals);
 
302
          gimp_get_data (PLUG_IN_PROC, &iwarp_vals);
290
303
          gimp_tile_cache_ntiles (2 * (drawable->width + gimp_tile_width ()-1) /
291
304
                                  gimp_tile_width ());
292
305
          if (iwarp_dialog())
293
306
            iwarp();
294
 
          gimp_set_data ("plug_in_iwarp", &iwarp_vals, sizeof (iwarp_vals_t));
 
307
          gimp_set_data (PLUG_IN_PROC, &iwarp_vals, sizeof (iwarp_vals_t));
295
308
          gimp_displays_flush ();
296
309
          break;
297
310
 
313
326
    }
314
327
 
315
328
  *nreturn_vals = 1;
316
 
  *return_vals = values;
 
329
  *return_vals  = values;
317
330
 
318
 
  values[0].type = GIMP_PDB_STATUS;
 
331
  values[0].type          = GIMP_PDB_STATUS;
319
332
  values[0].data.d_status = status;
320
333
 
321
334
  gimp_drawable_detach (drawable);
648
661
          (*progress)++;
649
662
        }
650
663
 
651
 
      gimp_progress_update ((gdouble) (*progress) / max_progress);
652
664
      vh = srow_old;
653
665
      srow_old = srow;
654
666
      srow = vh;
655
667
    }
656
668
 
 
669
  gimp_progress_update ((gdouble) (*progress) / max_progress);
 
670
 
657
671
  g_free (srow);
658
672
  g_free (srow_old);
659
673
}
685
699
             gimp_drawable_has_alpha (destdrawable->drawable_id));
686
700
 
687
701
  if (!do_animate)
688
 
    gimp_progress_init (_("Warping..."));
 
702
    gimp_progress_init (_("Warping"));
689
703
 
690
704
  for (pr = gimp_pixel_rgns_register (1, &dest_rgn);
691
705
       pr != NULL;
727
741
                }
728
742
 
729
743
              dest_row += dest_rgn.rowstride;
730
 
              gimp_progress_update ((gdouble) (progress) / max_progress);
731
744
            }
 
745
          gimp_progress_update ((gdouble) (progress) / max_progress);
732
746
        }
733
747
      else
734
748
        {
753
767
  gint     i;
754
768
  gint32   layerID;
755
769
  gint32  *animlayers;
756
 
  gchar   *st;
757
770
  gdouble  delta;
758
771
 
759
772
  if (image_bpp == 1 || image_bpp == 3)
780
793
      frame_number = 0;
781
794
      for (i = 0; i < animate_num_frames; i++)
782
795
        {
783
 
          st = g_strdup_printf (_("Frame %d"), i);
 
796
          gchar *st = g_strdup_printf (_("Frame %d"), i);
 
797
 
784
798
          animlayers[i] = gimp_layer_copy (layerID);
785
799
          gimp_layer_add_alpha (animlayers[i]);
786
800
          gimp_drawable_set_name (animlayers[i], st);
790
804
 
791
805
          destdrawable = gimp_drawable_get (animlayers[i]);
792
806
 
793
 
          st = g_strdup_printf (_("Warping Frame No. %d..."), frame_number);
794
 
          gimp_progress_init (st);
795
 
          g_free (st);
 
807
          gimp_progress_init_printf (_("Warping Frame %d"),
 
808
                                     frame_number);
796
809
 
797
810
          if (animate_deform_value > 0.0)
798
811
            iwarp_frame ();
800
813
          animate_deform_value = animate_deform_value + delta;
801
814
          frame_number++;
802
815
        }
 
816
 
803
817
      if (do_animate_ping_pong)
804
818
        {
805
 
          st = g_strdup_printf (_("Warping Frame No. %d..."), frame_number);
806
819
          gimp_progress_init (_("Ping pong"));
807
 
          g_free (st);
808
820
 
809
821
          for (i = 0; i < animate_num_frames; i++)
810
822
            {
 
823
              gchar *st;
 
824
 
811
825
              gimp_progress_update ((gdouble) i / (animate_num_frames - 1));
812
826
              layerID = gimp_layer_copy (animlayers[animate_num_frames-i-1]);
813
827
 
843
857
}
844
858
 
845
859
static void
846
 
iwarp_init (void)
 
860
iwarp_scale_preview (gint new_width,
 
861
                     gint new_height,
 
862
                     gint old_width,
 
863
                     gint old_height)
 
864
{
 
865
  gint     x, y, z;
 
866
  gdouble  ox, oy, dx, dy;
 
867
  gint     src1, src2, ix, iy;
 
868
  gdouble  in0, in1, in2;
 
869
  guchar  *new_data;
 
870
 
 
871
  new_data = g_new (guchar, new_width * new_height * preview_bpp);
 
872
 
 
873
  for (y = 0; y < new_height; y++)
 
874
    for (x = 0; x < new_width; x++)
 
875
      {
 
876
        ox = ((gdouble) x / new_width) * old_width;
 
877
        oy = ((gdouble) y / new_height) * old_height;
 
878
 
 
879
        ix = (gint) ox;
 
880
        iy = (gint) oy;
 
881
 
 
882
        dx = ox - ix;
 
883
        dy = oy - iy;
 
884
 
 
885
        if (ix == old_width - 1)
 
886
          dx = 0.0;
 
887
 
 
888
        for (z = 0; z < preview_bpp; z++)
 
889
          {
 
890
            src1 = (iy * old_width + ix) * preview_bpp + z;
 
891
 
 
892
            if (iy != old_height - 1)
 
893
              src2 = src1 + old_width * preview_bpp;
 
894
            else
 
895
              src2 = src1;
 
896
 
 
897
            in0 = dstimage [src1] + (dstimage [src1 + preview_bpp] -
 
898
                                     dstimage [src1]) * dx;
 
899
            in1 = dstimage [src2] + (dstimage [src2 + preview_bpp] -
 
900
                                     dstimage [src2]) * dx;
 
901
            in2 = in0 + (in1 - in0) * dy;
 
902
 
 
903
            new_data[(y * new_width +  x) * preview_bpp + z] = (guchar) in2;
 
904
          }
 
905
      }
 
906
 
 
907
  g_free (dstimage);
 
908
  dstimage = new_data;
 
909
}
 
910
 
 
911
static void
 
912
iwarp_preview_init (void)
847
913
{
848
914
  gint       y, x, xi, i;
849
915
  GimpPixelRgn  srcrgn;
851
917
  guchar    *linebuffer = NULL;
852
918
  gdouble    dx, dy;
853
919
 
854
 
  gimp_drawable_mask_bounds (drawable->drawable_id, &xl, &yl, &xh, &yh);
855
 
  sel_width = xh - xl;
856
 
  sel_height = yh - yl;
857
 
 
858
 
  image_bpp = gimp_drawable_bpp (drawable->drawable_id);
859
 
 
860
 
  if (gimp_drawable_is_layer (drawable->drawable_id))
861
 
    preserve_trans = gimp_layer_get_preserve_trans (drawable->drawable_id);
862
 
  else
863
 
    preserve_trans = FALSE;
864
 
 
865
 
  preview_bpp = image_bpp;
866
 
 
867
 
  dx = (gdouble) sel_width / MAX_PREVIEW_WIDTH;
868
 
  dy = (gdouble) sel_height / MAX_PREVIEW_HEIGHT;
 
920
 
 
921
  dx = (gdouble) sel_width / max_current_preview_width;
 
922
  dy = (gdouble) sel_height / max_current_preview_height;
869
923
 
870
924
  if (dx > dy)
871
925
    pre2img = dx;
880
934
  preview_width  = (gint) (sel_width  / pre2img);
881
935
  preview_height = (gint) (sel_height / pre2img);
882
936
 
883
 
  tile_width  = gimp_tile_width ();
884
 
  tile_height = gimp_tile_height ();
885
 
 
886
 
  srcimage = g_new (guchar, preview_width * preview_height * image_bpp);
887
 
  dstimage = g_new (guchar, preview_width * preview_height * preview_bpp);
888
 
  deform_vectors = g_new0 (GimpVector2, preview_width * preview_height);
889
 
  deform_area_vectors = g_new (GimpVector2,
890
 
                               (MAX_DEFORM_AREA_RADIUS * 2 + 1) *
891
 
                               (MAX_DEFORM_AREA_RADIUS * 2 + 1));
 
937
 
 
938
  if (srcimage)
 
939
    {
 
940
      srcimage = g_renew (guchar,
 
941
                          srcimage, preview_width * preview_height * image_bpp);
 
942
    }
 
943
  else
 
944
    {
 
945
      srcimage = g_new (guchar, preview_width * preview_height * image_bpp);
 
946
      dstimage = g_new (guchar, preview_width * preview_height * preview_bpp);
 
947
    }
 
948
 
892
949
  linebuffer = g_new (guchar, sel_width * image_bpp);
893
950
 
894
951
  gimp_pixel_rgn_init (&srcrgn, drawable,
902
959
        {
903
960
          pts = srcimage + (y * preview_width + x) * image_bpp;
904
961
          xi = (gint) (pre2img * x);
 
962
 
905
963
          for (i = 0; i < image_bpp; i++)
906
 
            {
907
 
              *pts++ = linebuffer[xi*image_bpp+i];
908
 
            }
 
964
            *pts++ = linebuffer[xi * image_bpp + i];
909
965
        }
910
966
    }
911
967
 
 
968
  g_free (linebuffer);
 
969
}
 
970
 
 
971
static void
 
972
iwarp_init (void)
 
973
{
 
974
  gint  i;
 
975
 
 
976
  gimp_drawable_mask_bounds (drawable->drawable_id, &xl, &yl, &xh, &yh);
 
977
  sel_width = xh - xl;
 
978
  sel_height = yh - yl;
 
979
 
 
980
  image_bpp = gimp_drawable_bpp (drawable->drawable_id);
 
981
 
 
982
  if (gimp_drawable_is_layer (drawable->drawable_id))
 
983
    lock_alpha = gimp_layer_get_lock_alpha (drawable->drawable_id);
 
984
  else
 
985
    lock_alpha = FALSE;
 
986
 
 
987
  preview_bpp = image_bpp;
 
988
 
 
989
  tile_width  = gimp_tile_width ();
 
990
  tile_height = gimp_tile_height ();
 
991
 
 
992
  iwarp_preview_init ();
912
993
  iwarp_cpy_images ();
913
994
 
 
995
  deform_vectors = g_new0 (GimpVector2, preview_width * preview_height);
 
996
  deform_area_vectors = g_new (GimpVector2,
 
997
                               (MAX_DEFORM_AREA_RADIUS * 2 + 1) *
 
998
                               (MAX_DEFORM_AREA_RADIUS * 2 + 1));
 
999
 
914
1000
  for (i = 0; i < MAX_DEFORM_AREA_RADIUS; i++)
915
1001
    {
916
1002
      filter[i] =
917
1003
        pow ((cos (sqrt((gdouble) i / MAX_DEFORM_AREA_RADIUS) * G_PI) + 1) *
918
1004
             0.5, 0.7); /*0.7*/
919
1005
    }
920
 
 
921
 
  g_free (linebuffer);
922
1006
}
923
1007
 
924
1008
static void
925
1009
iwarp_animate_dialog (GtkWidget *dlg,
926
1010
                      GtkWidget *notebook)
927
1011
{
 
1012
  GtkWidget *frame;
928
1013
  GtkWidget *vbox;
929
 
  GtkWidget *frame;
930
1014
  GtkWidget *table;
931
1015
  GtkWidget *button;
932
1016
  GtkObject *scale_data;
957
1041
  gtk_widget_set_sensitive (table, do_animate);
958
1042
 
959
1043
  scale_data = gimp_scale_entry_new (GTK_TABLE (table), 0, 0,
960
 
                                     _("Number of _Frames:"), SCALE_WIDTH, 0,
 
1044
                                     _("Number of _frames:"), SCALE_WIDTH, 0,
961
1045
                                     animate_num_frames,
962
1046
                                     2, MAX_NUM_FRAMES, 1, 10, 0,
963
1047
                                     TRUE, 0, 0,
964
1048
                                     NULL, NULL);
965
 
  g_signal_connect (scale_data, "value_changed",
 
1049
  g_signal_connect (scale_data, "value-changed",
966
1050
                    G_CALLBACK (gimp_int_adjustment_update),
967
1051
                    &animate_num_frames);
968
1052
 
975
1059
                    G_CALLBACK (gimp_toggle_button_update),
976
1060
                    &do_animate_reverse);
977
1061
 
978
 
  button = gtk_check_button_new_with_mnemonic (_("_Ping Pong"));
 
1062
  button = gtk_check_button_new_with_mnemonic (_("_Ping pong"));
979
1063
  gtk_table_attach (GTK_TABLE (table), button, 0, 3, 2, 3,
980
1064
                    GTK_FILL | GTK_EXPAND, GTK_FILL | GTK_EXPAND, 0, 0);
981
1065
  gtk_widget_show (button);
1061
1145
                                     5.0, MAX_DEFORM_AREA_RADIUS, 1.0, 10.0, 0,
1062
1146
                                     TRUE, 0, 0,
1063
1147
                                     NULL, NULL);
1064
 
  g_signal_connect (scale_data, "value_changed",
 
1148
  g_signal_connect (scale_data, "value-changed",
1065
1149
                    G_CALLBACK (gimp_int_adjustment_update),
1066
1150
                    &iwarp_vals.deform_area_radius);
1067
1151
 
1071
1155
                                     0.0, 1.0, 0.01, 0.1, 2,
1072
1156
                                     TRUE, 0, 0,
1073
1157
                                     NULL, NULL);
1074
 
  g_signal_connect (scale_data, "value_changed",
 
1158
  g_signal_connect (scale_data, "value-changed",
1075
1159
                    G_CALLBACK (gimp_double_adjustment_update),
1076
1160
                    &iwarp_vals.deform_amount);
1077
1161
 
1114
1198
                                     1.0, 5.0, 1.1, 1.0, 0,
1115
1199
                                     TRUE, 0, 0,
1116
1200
                                     NULL, NULL);
1117
 
  g_signal_connect (scale_data, "value_changed",
 
1201
  g_signal_connect (scale_data, "value-changed",
1118
1202
                    G_CALLBACK (gimp_int_adjustment_update),
1119
1203
                    &iwarp_vals.max_supersample_depth);
1120
1204
 
1124
1208
                                     1.0, 10.0, 0.01, 0.1, 2,
1125
1209
                                     TRUE, 0, 0,
1126
1210
                                     NULL, NULL);
1127
 
  g_signal_connect (scale_data, "value_changed",
 
1211
  g_signal_connect (scale_data, "value-changed",
1128
1212
                    G_CALLBACK (gimp_double_adjustment_update),
1129
1213
                    &iwarp_vals.supersample_threshold);
1130
1214
 
1135
1219
                            gtk_label_new_with_mnemonic (_("_Settings")));
1136
1220
}
1137
1221
 
 
1222
static void
 
1223
iwarp_preview_build (GtkWidget *vbox)
 
1224
{
 
1225
  GtkWidget *frame;
 
1226
 
 
1227
  frame = gtk_aspect_frame_new (NULL, 0.0, 0.0, 1.0, TRUE);
 
1228
  gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_IN);
 
1229
  gtk_box_pack_start (GTK_BOX (vbox), frame, TRUE, TRUE, 0);
 
1230
  gtk_widget_show (frame);
 
1231
 
 
1232
  preview = gimp_preview_area_new ();
 
1233
  gtk_widget_set_size_request (preview, preview_width, preview_height);
 
1234
  gtk_container_add (GTK_CONTAINER (frame), preview);
 
1235
  gtk_widget_show (preview);
 
1236
 
 
1237
  gtk_widget_add_events (preview,
 
1238
                         GDK_BUTTON_PRESS_MASK |
 
1239
                         GDK_BUTTON_RELEASE_MASK |
 
1240
                         GDK_BUTTON1_MOTION_MASK |
 
1241
                         GDK_POINTER_MOTION_HINT_MASK);
 
1242
 
 
1243
  g_signal_connect (preview, "realize",
 
1244
                    G_CALLBACK (iwarp_realize_callback),
 
1245
                    NULL);
 
1246
  g_signal_connect (preview, "event",
 
1247
                    G_CALLBACK (iwarp_motion_callback),
 
1248
                    NULL);
 
1249
  g_signal_connect (preview, "size-allocate",
 
1250
                    G_CALLBACK (iwarp_resize_callback),
 
1251
                    NULL);
 
1252
}
 
1253
 
 
1254
 
1138
1255
static gboolean
1139
1256
iwarp_dialog (void)
1140
1257
{
1141
1258
  GtkWidget *dlg;
1142
1259
  GtkWidget *main_hbox;
1143
 
  GtkWidget *frame;
1144
 
  GtkWidget *abox;
 
1260
  GtkWidget *vbox;
 
1261
  GtkWidget *hint;
1145
1262
  GtkWidget *notebook;
1146
1263
 
1147
 
  gimp_ui_init ("iwarp", TRUE);
 
1264
  gimp_ui_init (PLUG_IN_BINARY, TRUE);
1148
1265
 
1149
1266
  iwarp_init ();
1150
1267
 
1151
 
  dlg = gimp_dialog_new (_("IWarp"), "iwarp",
 
1268
  dlg = gimp_dialog_new (_("IWarp"), PLUG_IN_BINARY,
1152
1269
                         NULL, 0,
1153
 
                         gimp_standard_help_func, "plug-in-iwarp",
 
1270
                         gimp_standard_help_func, PLUG_IN_PROC,
1154
1271
 
1155
1272
                         GIMP_STOCK_RESET, RESPONSE_RESET,
1156
1273
                         GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
1158
1275
 
1159
1276
                         NULL);
1160
1277
 
 
1278
  gtk_dialog_set_alternative_button_order (GTK_DIALOG (dlg),
 
1279
                                           RESPONSE_RESET,
 
1280
                                           GTK_RESPONSE_OK,
 
1281
                                           GTK_RESPONSE_CANCEL,
 
1282
                                           -1);
 
1283
 
 
1284
  gimp_window_set_transient (GTK_WINDOW (dlg));
 
1285
 
1161
1286
  g_signal_connect (dlg, "response",
1162
1287
                    G_CALLBACK (iwarp_response),
1163
1288
                    NULL);
1168
1293
  main_hbox = gtk_hbox_new (FALSE, 12);
1169
1294
  gtk_container_set_border_width (GTK_CONTAINER (main_hbox), 12);
1170
1295
  gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dlg)->vbox), main_hbox,
1171
 
                      FALSE, FALSE, 0);
 
1296
                      TRUE, TRUE, 0);
1172
1297
  gtk_widget_show (main_hbox);
1173
1298
 
1174
 
  abox = gtk_alignment_new (0.0, 0.0, 0.0, 0.0);
1175
 
  gtk_box_pack_start (GTK_BOX (main_hbox), abox, FALSE, FALSE, 0);
1176
 
  gtk_widget_show (abox);
1177
 
 
1178
 
  frame = gtk_frame_new (NULL);
1179
 
  gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_IN);
1180
 
  gtk_container_add (GTK_CONTAINER (abox), frame);
1181
 
  gtk_widget_show (frame);
1182
 
 
1183
 
  preview = gimp_preview_area_new ();
1184
 
  gtk_widget_set_size_request (preview, preview_width, preview_height);
1185
 
  gtk_container_add (GTK_CONTAINER (frame), preview);
1186
 
  gtk_widget_show (preview);
1187
 
 
1188
 
  gtk_widget_set_events (preview,
1189
 
                         GDK_BUTTON_PRESS_MASK |
1190
 
                         GDK_BUTTON_RELEASE_MASK |
1191
 
                         GDK_BUTTON1_MOTION_MASK |
1192
 
                         GDK_POINTER_MOTION_HINT_MASK);
1193
 
 
1194
 
  g_signal_connect (preview, "realize",
1195
 
                    G_CALLBACK (iwarp_realize_callback),
1196
 
                    NULL);
1197
 
  g_signal_connect (preview, "event",
1198
 
                    G_CALLBACK (iwarp_motion_callback),
1199
 
                    NULL);
 
1299
  vbox = gtk_vbox_new (FALSE, 12);
 
1300
  gtk_box_pack_start (GTK_BOX (main_hbox), vbox, TRUE, TRUE, 0);
 
1301
  gtk_widget_show (vbox);
 
1302
 
 
1303
  iwarp_preview_build (vbox);
 
1304
  hint = gimp_hint_box_new (_("Click and drag in the preview to define "
 
1305
                              "the distortions to apply to the image."));
 
1306
  gtk_box_pack_end (GTK_BOX (vbox), hint, FALSE, FALSE, 0);
 
1307
  gtk_widget_show (hint);
1200
1308
 
1201
1309
  notebook = gtk_notebook_new ();
1202
1310
  gtk_notebook_set_tab_pos (GTK_NOTEBOOK (notebook), GTK_POS_TOP);
1203
 
  gtk_box_pack_start (GTK_BOX (main_hbox), notebook, TRUE, TRUE, 0);
 
1311
  gtk_box_pack_start (GTK_BOX (main_hbox), notebook, FALSE, FALSE, 0);
1204
1312
  gtk_widget_show (notebook);
1205
1313
 
1206
1314
  iwarp_settings_dialog (dlg, notebook);
1211
1319
  iwarp_update_preview (0, 0, preview_width, preview_height);
1212
1320
 
1213
1321
  gtk_main ();
1214
 
  gdk_flush ();
1215
1322
 
1216
1323
  return wint.run;
1217
1324
}
1222
1329
                      gint x1,
1223
1330
                      gint y1)
1224
1331
{
1225
 
  x0 = MAX (x0, 0);
1226
 
  y0 = MAX (y0, 0);
1227
 
  x1 = MIN (x1, preview_width);
1228
 
  y1 = MIN (y1, preview_height);
 
1332
  x0 = CLAMP (x0, 0, preview_width);
 
1333
  y0 = CLAMP (y0, 0, preview_height);
 
1334
  x1 = CLAMP (x1, x0, preview_width);
 
1335
  y1 = CLAMP (y1, y0, preview_height);
1229
1336
 
1230
 
  gimp_preview_area_draw (GIMP_PREVIEW_AREA (preview),
1231
 
                          x0, y0,
1232
 
                          x1 - x0, y1 - y0,
1233
 
                          gimp_drawable_type(drawable->drawable_id),
1234
 
                          dstimage + (y0 * preview_width + x0) * preview_bpp,
1235
 
                          preview_width * preview_bpp);
 
1337
  if (x1 > x0 && y1 > y0)
 
1338
    gimp_preview_area_draw (GIMP_PREVIEW_AREA (preview),
 
1339
                            x0, y0,
 
1340
                            x1 - x0, y1 - y0,
 
1341
                            gimp_drawable_type(drawable->drawable_id),
 
1342
                            dstimage + (y0 * preview_width + x0) * preview_bpp,
 
1343
                            preview_width * preview_bpp);
1236
1344
}
1237
1345
 
1238
1346
static void
1328
1436
            switch (iwarp_vals.deform_mode)
1329
1437
              {
1330
1438
              case GROW:
1331
 
                deform_value = filter[length2] *  0.1* iwarp_vals.deform_amount;
 
1439
                deform_value = filter[length2] *  0.1 * iwarp_vals.deform_amount;
1332
1440
                nvx = -deform_value * xi;
1333
1441
                nvy = -deform_value * yi;
1334
1442
                break;
1335
1443
 
1336
1444
              case SHRINK:
1337
 
                deform_value = filter[length2] * 0.1* iwarp_vals.deform_amount;
 
1445
                deform_value = filter[length2] * 0.1 * iwarp_vals.deform_amount;
1338
1446
                nvx = deform_value * xi;
1339
1447
                nvy = deform_value * yi;
1340
1448
                break;
1393
1501
                nvy = nvy * em;
1394
1502
 
1395
1503
                iwarp_get_deform_vector (nvx + x+ xi, nvy + y + yi, &xv, &yv);
1396
 
                xv = nvx +xv;
 
1504
                xv += nvx;
1397
1505
                if (xv +x+xi <0.0)
1398
1506
                  xv = -x - xi;
1399
1507
                else if (xv + x +xi > (preview_width-1))
1400
1508
                  xv = preview_width - x -xi-1;
1401
 
                yv = nvy +yv;
 
1509
                yv += nvy;
1402
1510
                if (yv + y + yi < 0.0)
1403
1511
                  yv = -y - yi;
1404
1512
                else if (yv + y + yi > (preview_height-1))
1413
1521
            /* Yeah, it is ugly but since color is a pointer into image-data
1414
1522
             * I must not change color[image_bpp - 1]  ...
1415
1523
             */
1416
 
            if (preserve_trans && (image_bpp == 4 || image_bpp == 2))
 
1524
            if (lock_alpha && (image_bpp == 4 || image_bpp == 2))
1417
1525
              {
1418
1526
                iwarp_preview_get_point (x + xi, y + yi, color);
1419
1527
                alpha = color[image_bpp - 1];
1421
1529
 
1422
1530
            iwarp_preview_get_point (xn, yn, color);
1423
1531
 
1424
 
            if (!preserve_trans && (image_bpp == 4 || image_bpp == 2))
 
1532
            if (!lock_alpha && (image_bpp == 4 || image_bpp == 2))
1425
1533
              {
1426
1534
                alpha = color[image_bpp - 1];
1427
1535
              }
1428
1536
 
1429
1537
            switch (preview_bpp)
1430
 
            {
 
1538
              {
1431
1539
              case 4:
1432
1540
                dstimage[ptr*4 + 0] = color[0];
1433
1541
                dstimage[ptr*4 + 1] = color[1];
1448
1556
 
1449
1557
              case 1:
1450
1558
                dstimage[ptr] = color[0];
1451
 
            }
 
1559
              }
1452
1560
          }
1453
1561
      }
1454
1562
 
1456
1564
    for (xi = x0; xi <= x1; xi++)
1457
1565
      {
1458
1566
        length2 = (xi*xi+yi*yi) * MAX_DEFORM_AREA_RADIUS / radius2;
1459
 
        if (length2 <MAX_DEFORM_AREA_RADIUS)
 
1567
        if (length2 < MAX_DEFORM_AREA_RADIUS)
1460
1568
          {
1461
1569
            ptr = (yi +y) * preview_width + xi +x;
1462
1570
            fptr =
1480
1588
  gdouble l, dx, dy, xf, yf;
1481
1589
  gint    num, i, x0, y0;
1482
1590
 
1483
 
  dx = x-xx;
1484
 
  dy = y-yy;
 
1591
  dx = x - xx;
 
1592
  dy = y - yy;
1485
1593
  l= sqrt (dx * dx + dy * dy);
1486
1594
  num = (gint) (l * 2 / iwarp_vals.deform_area_radius) + 1;
1487
1595
  dx /= num;
1488
1596
  dy /= num;
1489
1597
  xf = xx + dx; yf = yy + dy;
 
1598
 
1490
1599
  for (i=0; i< num; i++)
1491
1600
    {
1492
1601
      x0 = (gint) xf;
1509
1618
        gint i;
1510
1619
 
1511
1620
        iwarp_cpy_images ();
 
1621
 
1512
1622
        for (i = 0; i < preview_width * preview_height; i++)
1513
1623
          deform_vectors[i].x = deform_vectors[i].y = 0.0;
1514
1624
 
1535
1645
  gdk_cursor_unref (cursor);
1536
1646
}
1537
1647
 
1538
 
static gint
 
1648
static gboolean
1539
1649
iwarp_motion_callback (GtkWidget *widget,
1540
1650
                       GdkEvent  *event)
1541
1651
{
1542
 
  GdkEventButton *mb;
1543
 
  gint x, y;
 
1652
  GdkEventButton *mb = (GdkEventButton *) event;
 
1653
  gint            x, y;
1544
1654
 
1545
 
  mb = (GdkEventButton *) event;
1546
1655
  switch (event->type)
1547
1656
    {
1548
1657
    case GDK_BUTTON_PRESS:
1555
1664
        {
1556
1665
          x = mb->x;
1557
1666
          y = mb->y;
 
1667
 
1558
1668
          if (iwarp_vals.deform_mode == MOVE)
1559
1669
            iwarp_move (x, y, lastx, lasty);
1560
1670
          else
1565
1675
   case GDK_MOTION_NOTIFY:
1566
1676
     if (mb->state & GDK_BUTTON1_MASK)
1567
1677
       {
1568
 
         x = mb->x;
1569
 
         y = mb->y;
 
1678
         gtk_widget_get_pointer (widget, &x, &y);
 
1679
 
1570
1680
         if (iwarp_vals.deform_mode == MOVE)
1571
1681
           iwarp_move (x, y, lastx, lasty);
1572
1682
         else
1573
1683
           iwarp_deform (x, y, 0.0, 0.0);
 
1684
 
1574
1685
         lastx = x;
1575
1686
         lasty = y;
1576
 
         gtk_widget_get_pointer (widget, NULL, NULL);
1577
1687
       }
1578
1688
     break;
1579
1689
 
1583
1693
 
1584
1694
  return FALSE;
1585
1695
}
 
1696
 
 
1697
static gboolean
 
1698
iwarp_resize_idle (GtkWidget *widget)
 
1699
{
 
1700
  GimpVector2 *new_deform_vectors;
 
1701
  gint         old_preview_width, old_preview_height;
 
1702
  gint         new_preview_width, new_preview_height;
 
1703
  gint         x, y;
 
1704
  gdouble      new2old;
 
1705
 
 
1706
  resize_idle = 0;
 
1707
 
 
1708
  old_preview_width = preview_width;
 
1709
  old_preview_height = preview_height;
 
1710
 
 
1711
  max_current_preview_width = widget->allocation.width;
 
1712
  max_current_preview_height = widget->allocation.height;
 
1713
 
 
1714
  /* preview width and height get updated here: */
 
1715
  iwarp_preview_init ();
 
1716
  new_preview_width = preview_width;
 
1717
  new_preview_height = preview_height;
 
1718
 
 
1719
  new_deform_vectors = g_new0 (GimpVector2, preview_width * preview_height);
 
1720
  new2old = (gdouble) old_preview_width / preview_width;
 
1721
 
 
1722
  /* preview_width and height are used as global variables inside
 
1723
   * iwarp_get_deform_factor().  In the following call to the function,
 
1724
   * I need it to run with the old values. Adding a width and height
 
1725
   * to these function parameters would be an option for cleaner code,
 
1726
   * but that would also mean pushing 16 extra parameter bytes several
 
1727
   * times over for each pixel processed.
 
1728
   */
 
1729
 
 
1730
  preview_width = old_preview_width;
 
1731
  preview_height = old_preview_height;
 
1732
 
 
1733
  for (y = 0; y < new_preview_height; y++)
 
1734
    for (x = 0; x < new_preview_width; x++)
 
1735
      iwarp_get_deform_vector (new2old * x,
 
1736
                               new2old * y,
 
1737
                               &new_deform_vectors[x + new_preview_width * y].x,
 
1738
                               &new_deform_vectors[x + new_preview_width * y].y);
 
1739
 
 
1740
  preview_width = new_preview_width;
 
1741
  preview_height = new_preview_height;
 
1742
 
 
1743
  g_free (deform_vectors);
 
1744
  deform_vectors = new_deform_vectors;
 
1745
 
 
1746
  iwarp_scale_preview (new_preview_width, new_preview_height,
 
1747
                       old_preview_width, old_preview_height);
 
1748
 
 
1749
  iwarp_update_preview (0, 0, preview_width, preview_height);
 
1750
 
 
1751
  return FALSE;
 
1752
}
 
1753
 
 
1754
static void
 
1755
iwarp_resize_callback (GtkWidget *widget)
 
1756
{
 
1757
  if (resize_idle)
 
1758
    g_source_remove (resize_idle);
 
1759
 
 
1760
  resize_idle = g_idle_add_full (G_PRIORITY_LOW,
 
1761
                                 (GSourceFunc) iwarp_resize_idle, widget,
 
1762
                                 NULL);
 
1763
}