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

« back to all changes in this revision

Viewing changes to plug-ins/ifscompose/ifscompose_utils.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
 * IfsCompose is a interface for creating IFS fractals by
22
22
#include "config.h"
23
23
 
24
24
#include <stdlib.h>
25
 
#include <stdio.h>
26
25
#include <string.h>
27
26
 
28
27
#include <gdk/gdk.h>
41
40
 
42
41
/* local functions */
43
42
static void     aff_element_compute_click_boundary (AffElement     *elem,
44
 
                                                    gint            num_elements,
45
 
                                                    gdouble        *points_x,
46
 
                                                    gdouble        *points_y);
 
43
                                                    gint            num_elements,
 
44
                                                    gdouble        *points_x,
 
45
                                                    gdouble        *points_y);
47
46
static guchar * create_brush                       (IfsComposeVals *ifsvals,
48
 
                                                    gint           *brush_size,
49
 
                                                    gdouble        *brush_offset);
 
47
                                                    gint           *brush_size,
 
48
                                                    gdouble        *brush_offset);
50
49
 
51
50
 
52
51
void
53
52
aff2_translate (Aff2    *naff,
54
 
                gdouble  x,
55
 
                gdouble  y)
 
53
                gdouble  x,
 
54
                gdouble  y)
56
55
{
57
56
  naff->a11 = 1.0;
58
57
  naff->a12 = 0;
64
63
 
65
64
void
66
65
aff2_rotate (Aff2    *naff,
67
 
             gdouble  theta)
 
66
             gdouble  theta)
68
67
{
69
68
  naff->a11 = cos(theta);
70
69
  naff->a12 = sin(theta);
75
74
}
76
75
 
77
76
void
78
 
aff2_scale(Aff2    *naff,
79
 
           gdouble  s,
80
 
           gint     flip)
 
77
aff2_scale (Aff2    *naff,
 
78
            gdouble  s,
 
79
            gboolean flip)
81
80
{
82
81
  if (flip)
83
82
    naff->a11 = -s;
94
93
/* Create a unitary transform with given x-y asymmetry and shear */
95
94
void
96
95
aff2_distort (Aff2    *naff,
97
 
              gdouble  asym,
98
 
              gdouble  shear)
 
96
              gdouble  asym,
 
97
              gdouble  shear)
99
98
{
100
99
  naff->a11 = asym;
101
100
  naff->a22 = 1/asym;
108
107
/* Find a pure stretch in some directon that brings xo,yo to xn,yn */
109
108
void
110
109
aff2_compute_stretch (Aff2    *naff,
111
 
                      gdouble  xo,
112
 
                      gdouble  yo,
113
 
                      gdouble  xn,
114
 
                      gdouble  yn)
 
110
                      gdouble  xo,
 
111
                      gdouble  yo,
 
112
                      gdouble  xn,
 
113
                      gdouble  yn)
115
114
{
116
115
  gdouble denom = xo*xn + yo*yn;
117
116
 
118
 
  if (denom == 0.0)     /* singular */
 
117
  if (denom == 0.0)     /* singular */
119
118
    {
120
119
      naff->a11 = 1.0;
121
120
      naff->a12 = 0.0;
135
134
 
136
135
void
137
136
aff2_compose (Aff2 *naff,
138
 
              Aff2 *aff1,
139
 
              Aff2 *aff2)
 
137
              Aff2 *aff1,
 
138
              Aff2 *aff2)
140
139
{
141
140
  naff->a11 = aff1->a11 * aff2->a11 + aff1->a12 * aff2->a21;
142
141
  naff->a12 = aff1->a11 * aff2->a12 + aff1->a12 * aff2->a22;
149
148
/* Returns the identity matrix if the original matrix was singular */
150
149
void
151
150
aff2_invert (Aff2 *naff,
152
 
             Aff2 *aff)
 
151
             Aff2 *aff)
153
152
{
154
153
  gdouble det = aff->a11 * aff->a22 - aff->a12 * aff->a21;
155
154
 
170
169
 
171
170
void
172
171
aff2_apply (Aff2    *aff,
173
 
            gdouble  x,
174
 
            gdouble  y,
175
 
            gdouble *xf,
176
 
            gdouble *yf)
 
172
            gdouble  x,
 
173
            gdouble  y,
 
174
            gdouble *xf,
 
175
            gdouble *yf)
177
176
{
178
177
  gdouble xt = aff->a11 * x + aff->a12 * y + aff->b1;
179
178
  gdouble yt = aff->a21 * x + aff->a22 * y + aff->b2;
187
186
 
188
187
void
189
188
aff2_fixed_point (Aff2    *aff,
190
 
                  gdouble *xf,
191
 
                  gdouble *yf)
 
189
                  gdouble *xf,
 
190
                  gdouble *yf)
192
191
{
193
192
  Aff2 t1,t2;
194
193
 
205
204
 
206
205
void
207
206
aff3_apply (Aff3    *t,
208
 
            gdouble  x,
209
 
            gdouble  y,
210
 
            gdouble  z,
211
 
            gdouble *xf,
212
 
            gdouble *yf,
213
 
            gdouble *zf)
 
207
            gdouble  x,
 
208
            gdouble  y,
 
209
            gdouble  z,
 
210
            gdouble *xf,
 
211
            gdouble *yf,
 
212
            gdouble *zf)
214
213
{
215
214
  gdouble xt = (t->vals[0][0] * x +
216
215
                t->vals[0][1] * y +
229
228
 
230
229
static int
231
230
ipolygon_sort_func (const void *a,
232
 
                    const void *b)
 
231
                    const void *b)
233
232
{
234
233
  if (((SortPoint *)a)->angle < ((SortPoint *)b)->angle)
235
234
    return -1;
273
272
  lowest_pt = poly->points[0];
274
273
  lowest = 0;
275
274
 
276
 
  for (i=1;i<num_new;i++)
 
275
  for (i = 1; i < num_new; i++)
277
276
    if (poly->points[i].y < lowest_pt.y)
278
277
      {
279
 
        lowest_pt = poly->points[i];
280
 
        lowest = i;
 
278
        lowest_pt = poly->points[i];
 
279
        lowest = i;
281
280
      }
282
281
 
283
282
  /* sort by angle from lowest point */
284
283
 
285
 
  for (i=0,j=0;i<num_new;i++,j++)
 
284
  for (i = 0, j = 0; i < num_new; i++, j++)
286
285
    {
287
286
      if (i==lowest)
288
 
        j--;
 
287
        j--;
289
288
      else
290
 
        {
291
 
          gdouble dy = poly->points[i].y - lowest_pt.y;
292
 
          gdouble dx = poly->points[i].x - lowest_pt.x;
 
289
        {
 
290
          gdouble dy = poly->points[i].y - lowest_pt.y;
 
291
          gdouble dx = poly->points[i].x - lowest_pt.x;
293
292
 
294
 
          if (dy==0 && dx==0)
295
 
            {
296
 
              j--;
297
 
              num_new--;
298
 
              continue;
299
 
            }
300
 
          sort_points[j].point = poly->points[i];
301
 
          sort_points[j].angle = atan2 (dy, dx);
302
 
        }
 
293
          if (dy == 0 && dx == 0)
 
294
            {
 
295
              j--;
 
296
              num_new--;
 
297
              continue;
 
298
            }
 
299
          sort_points[j].point = poly->points[i];
 
300
          sort_points[j].angle = atan2 (dy, dx);
 
301
        }
303
302
    }
304
303
 
305
 
  qsort (sort_points, num_new-1, sizeof (SortPoint), ipolygon_sort_func);
 
304
  qsort (sort_points, num_new - 1, sizeof (SortPoint), ipolygon_sort_func);
306
305
 
307
306
  /* now ensure that all turns as we trace the perimiter are
308
307
     counter-clockwise */
312
311
  x1 = new_points[1].x - new_points[0].x;
313
312
  y1 = new_points[1].y - new_points[0].y;
314
313
 
315
 
  for (i=1,j=2;j<num_new;i++,j++)
 
314
  for (i = 1, j = 2; j < num_new; i++, j++)
316
315
    {
317
 
      x2 = sort_points[i].point.x - new_points[j-1].x;
318
 
      y2 = sort_points[i].point.y - new_points[j-1].y;
319
 
 
320
 
      if (x2==0 && y2==0)
321
 
        {
322
 
          num_new--;
323
 
          j--;
324
 
          continue;
325
 
        }
326
 
 
327
 
      while (x1*y2 - x2*y1 < 0) /* clockwise rotation */
328
 
        {
329
 
          num_new--;
330
 
          j--;
331
 
          x1 = new_points[j-1].x - new_points[j-2].x;
332
 
          y1 = new_points[j-1].y - new_points[j-2].y;
333
 
          x2 = sort_points[i].point.x - new_points[j-1].x;
334
 
          y2 = sort_points[i].point.y - new_points[j-1].y;
335
 
        }
 
316
      x2 = sort_points[i].point.x - new_points[j - 1].x;
 
317
      y2 = sort_points[i].point.y - new_points[j - 1].y;
 
318
 
 
319
      if (x2 == 0 && y2 == 0)
 
320
        {
 
321
          num_new--;
 
322
          j--;
 
323
          continue;
 
324
        }
 
325
 
 
326
      while (x1 * y2 - x2 * y1 < 0) /* clockwise rotation */
 
327
        {
 
328
          num_new--;
 
329
          j--;
 
330
          x1 = new_points[j - 1].x - new_points[j - 2].x;
 
331
          y1 = new_points[j - 1].y - new_points[j - 2].y;
 
332
          x2 = sort_points[i].point.x - new_points[j - 1].x;
 
333
          y2 = sort_points[i].point.y - new_points[j - 1].y;
 
334
        }
336
335
      new_points[j] = sort_points[i].point;
337
336
      x1 = x2;
338
337
      y1 = y2;
355
354
 
356
355
gint
357
356
ipolygon_contains (IPolygon *poly,
358
 
                   gint      xt,
359
 
                   gint      yt)
 
357
                   gint      xt,
 
358
                   gint      yt)
360
359
{
361
360
  gint xnew, ynew;
362
361
  gint xold, yold;
369
368
  if (poly->npoints < 3)
370
369
    return 0;
371
370
 
372
 
  xold=poly->points[poly->npoints-1].x;
373
 
  yold=poly->points[poly->npoints-1].y;
374
 
  for (i=0;i<poly->npoints;i++)
 
371
  xold=poly->points[poly->npoints - 1].x;
 
372
  yold=poly->points[poly->npoints - 1].y;
 
373
  for (i = 0; i < poly->npoints; i++)
375
374
    {
376
375
      xnew = poly->points[i].x;
377
376
      ynew = poly->points[i].y;
378
377
      if (xnew > xold)
379
 
        {
380
 
          x1 = xold;
381
 
          x2 = xnew;
382
 
          y1 = yold;
383
 
          y2 = ynew;
384
 
        }
 
378
        {
 
379
          x1 = xold;
 
380
          x2 = xnew;
 
381
          y1 = yold;
 
382
          y2 = ynew;
 
383
        }
385
384
      else
386
 
        {
387
 
          x1 = xnew;
388
 
          x2 = xold;
389
 
          y1 = ynew;
390
 
          y2 = yold;
391
 
        }
 
385
        {
 
386
          x1 = xnew;
 
387
          x2 = xold;
 
388
          y1 = ynew;
 
389
          y2 = yold;
 
390
        }
392
391
      if ((xnew < xt) == (xt <= xold) &&
393
 
          (yt - y1)*(x2 - x1) < (y2 - y1)*(xt - x1))
394
 
        inside = !inside;
 
392
          (yt - y1)*(x2 - x1) < (y2 - y1)*(xt - x1))
 
393
        inside = !inside;
395
394
      xold = xnew;
396
395
      yold = ynew;
397
396
    }
401
400
void
402
401
aff_element_compute_color_trans (AffElement *elem)
403
402
{
404
 
  int i,j;
 
403
  int i, j;
405
404
 
406
405
  if (elem->v.simple_color)
407
406
    {
408
407
      gdouble mag2;
409
408
 
410
 
      mag2 =  SQR(elem->v.target_color.r);
411
 
      mag2 += SQR(elem->v.target_color.g);
412
 
      mag2 += SQR(elem->v.target_color.b);
 
409
      mag2  = SQR (elem->v.target_color.r);
 
410
      mag2 += SQR (elem->v.target_color.g);
 
411
      mag2 += SQR (elem->v.target_color.b);
413
412
 
414
413
      /* For mag2 == 0, the transformation blows up in general
415
 
         but is well defined for hue_scale == value_scale, so
416
 
         we assume that special case. */
 
414
         but is well defined for hue_scale == value_scale, so
 
415
         we assume that special case. */
417
416
      if (mag2 == 0)
418
 
        for (i=0; i<3; i++)
419
 
          {
420
 
            for (j=0; j<4; j++)
421
 
              elem->color_trans.vals[i][j] = 0.0;
 
417
        for (i = 0; i < 3; i++)
 
418
          {
 
419
            for (j = 0; j < 4; j++)
 
420
              elem->color_trans.vals[i][j] = 0.0;
422
421
 
423
 
            elem->color_trans.vals[i][i] = elem->v.hue_scale;
424
 
          }
 
422
            elem->color_trans.vals[i][i] = elem->v.hue_scale;
 
423
          }
425
424
      else
426
 
        {
427
 
          /*  red  */
428
 
          for (j=0; j<3; j++)
429
 
            {
430
 
              elem->color_trans.vals[0][j] = elem->v.target_color.r
431
 
                / mag2 * (elem->v.value_scale - elem->v.hue_scale);
432
 
            }
433
 
 
434
 
          /*  green  */
435
 
          for (j=0; j<3; j++)
436
 
            {
437
 
              elem->color_trans.vals[1][j] = elem->v.target_color.g
438
 
                / mag2 * (elem->v.value_scale - elem->v.hue_scale);
439
 
            }
440
 
 
441
 
          /*  blue  */
442
 
          for (j=0; j<3; j++)
443
 
            {
444
 
              elem->color_trans.vals[2][j] = elem->v.target_color.g
445
 
                / mag2 * (elem->v.value_scale - elem->v.hue_scale);
446
 
            }
447
 
 
448
 
          elem->color_trans.vals[0][0] += elem->v.hue_scale;
449
 
          elem->color_trans.vals[1][1] += elem->v.hue_scale;
450
 
          elem->color_trans.vals[2][2] += elem->v.hue_scale;
451
 
 
452
 
 
453
 
          elem->color_trans.vals[0][3] =
454
 
            (1-elem->v.value_scale)*elem->v.target_color.r;
455
 
          elem->color_trans.vals[1][3] =
456
 
            (1-elem->v.value_scale)*elem->v.target_color.g;
457
 
          elem->color_trans.vals[2][3] =
458
 
            (1-elem->v.value_scale)*elem->v.target_color.b;
459
 
 
460
 
          }
 
425
        {
 
426
          /*  red  */
 
427
          for (j = 0; j < 3; j++)
 
428
            {
 
429
              elem->color_trans.vals[0][j] = elem->v.target_color.r
 
430
                / mag2 * (elem->v.value_scale - elem->v.hue_scale);
 
431
            }
 
432
 
 
433
          /*  green  */
 
434
          for (j = 0; j < 3; j++)
 
435
            {
 
436
              elem->color_trans.vals[1][j] = elem->v.target_color.g
 
437
                / mag2 * (elem->v.value_scale - elem->v.hue_scale);
 
438
            }
 
439
 
 
440
          /*  blue  */
 
441
          for (j = 0; j < 3; j++)
 
442
            {
 
443
              elem->color_trans.vals[2][j] = elem->v.target_color.g
 
444
                / mag2 * (elem->v.value_scale - elem->v.hue_scale);
 
445
            }
 
446
 
 
447
          elem->color_trans.vals[0][0] += elem->v.hue_scale;
 
448
          elem->color_trans.vals[1][1] += elem->v.hue_scale;
 
449
          elem->color_trans.vals[2][2] += elem->v.hue_scale;
 
450
 
 
451
          elem->color_trans.vals[0][3] =
 
452
            (1 - elem->v.value_scale) * elem->v.target_color.r;
 
453
          elem->color_trans.vals[1][3] =
 
454
            (1 - elem->v.value_scale) * elem->v.target_color.g;
 
455
          elem->color_trans.vals[2][3] =
 
456
            (1 - elem->v.value_scale) * elem->v.target_color.b;
 
457
 
 
458
          }
461
459
 
462
460
 
463
461
      aff3_apply (&elem->color_trans, 1.0, 0.0, 0.0,
464
 
                  &elem->v.red_color.r,
465
 
                  &elem->v.red_color.g,
466
 
                  &elem->v.red_color.b);
 
462
                  &elem->v.red_color.r,
 
463
                  &elem->v.red_color.g,
 
464
                  &elem->v.red_color.b);
467
465
      aff3_apply (&elem->color_trans, 0.0, 1.0, 0.0,
468
 
                  &elem->v.green_color.r,
469
 
                  &elem->v.green_color.g,
470
 
                  &elem->v.green_color.b);
 
466
                  &elem->v.green_color.r,
 
467
                  &elem->v.green_color.g,
 
468
                  &elem->v.green_color.b);
471
469
      aff3_apply (&elem->color_trans, 0.0, 0.0, 1.0,
472
 
                  &elem->v.blue_color.r,
473
 
                  &elem->v.blue_color.g,
474
 
                  &elem->v.blue_color.b);
 
470
                  &elem->v.blue_color.r,
 
471
                  &elem->v.blue_color.g,
 
472
                  &elem->v.blue_color.b);
475
473
      aff3_apply (&elem->color_trans, 0.0, 0.0, 0.0,
476
 
                  &elem->v.black_color.r,
477
 
                  &elem->v.black_color.g,
478
 
                  &elem->v.black_color.b);
 
474
                  &elem->v.black_color.r,
 
475
                  &elem->v.black_color.g,
 
476
                  &elem->v.black_color.b);
479
477
    }
480
478
  else
481
479
    {
482
480
      elem->color_trans.vals[0][0] =
483
 
        elem->v.red_color.r - elem->v.black_color.r;
 
481
        elem->v.red_color.r - elem->v.black_color.r;
484
482
      elem->color_trans.vals[1][0] =
485
 
        elem->v.red_color.g - elem->v.black_color.g;
 
483
        elem->v.red_color.g - elem->v.black_color.g;
486
484
      elem->color_trans.vals[2][0] =
487
 
        elem->v.red_color.b - elem->v.black_color.b;
 
485
        elem->v.red_color.b - elem->v.black_color.b;
488
486
 
489
487
      elem->color_trans.vals[0][1] =
490
 
        elem->v.green_color.r - elem->v.black_color.r;
 
488
        elem->v.green_color.r - elem->v.black_color.r;
491
489
      elem->color_trans.vals[1][1] =
492
 
        elem->v.green_color.g - elem->v.black_color.g;
 
490
        elem->v.green_color.g - elem->v.black_color.g;
493
491
      elem->color_trans.vals[2][1] =
494
 
        elem->v.green_color.b - elem->v.black_color.b;
 
492
        elem->v.green_color.b - elem->v.black_color.b;
495
493
 
496
494
      elem->color_trans.vals[0][2] =
497
 
        elem->v.blue_color.r - elem->v.black_color.r;
 
495
        elem->v.blue_color.r - elem->v.black_color.r;
498
496
      elem->color_trans.vals[1][2] =
499
 
        elem->v.blue_color.g - elem->v.black_color.g;
 
497
        elem->v.blue_color.g - elem->v.black_color.g;
500
498
      elem->color_trans.vals[2][2] =
501
 
        elem->v.blue_color.b - elem->v.black_color.b;
 
499
        elem->v.blue_color.b - elem->v.black_color.b;
502
500
 
503
501
      elem->color_trans.vals[0][3] = elem->v.black_color.r;
504
502
      elem->color_trans.vals[1][3] = elem->v.black_color.g;
508
506
 
509
507
void
510
508
aff_element_compute_trans (AffElement *elem,
511
 
                           gdouble     width,
512
 
                           gdouble     height,
513
 
                           gdouble     center_x,
514
 
                           gdouble     center_y)
 
509
                           gdouble     width,
 
510
                           gdouble     height,
 
511
                           gdouble     center_x,
 
512
                           gdouble     center_y)
515
513
{
516
514
  Aff2 t1, t2, t3;
517
515
 
531
529
 
532
530
void
533
531
aff_element_decompose_trans (AffElement *elem,
534
 
                             Aff2       *aff,
535
 
                             gdouble     width,
536
 
                             gdouble     height,
537
 
                             gdouble     center_x,
538
 
                             gdouble     center_y)
 
532
                             Aff2       *aff,
 
533
                             gdouble     width,
 
534
                             gdouble     height,
 
535
                             gdouble     center_x,
 
536
                             gdouble     center_y)
539
537
{
540
 
  Aff2 t1,t2;
541
 
  gdouble det,scale,sign;
 
538
  Aff2    t1, t2;
 
539
  gdouble det, scale, sign;
542
540
 
543
541
  /* pull of the translational parts */
544
 
  aff2_translate (&t1,center_x*width,center_y*width);
545
 
  aff2_compose (&t2,aff,&t1);
 
542
  aff2_translate (&t1,center_x * width, center_y * width);
 
543
  aff2_compose (&t2, aff, &t1);
546
544
 
547
545
  elem->v.x = t2.b1 / width;
548
546
  elem->v.y = t2.b2 / width;
560
558
  else
561
559
    {
562
560
      if (det >= 0)
563
 
        {
564
 
          scale = elem->v.scale = sqrt (det);
565
 
          sign = 1;
566
 
          elem->v.flip = 0;
567
 
        }
 
561
        {
 
562
          scale = elem->v.scale = sqrt (det);
 
563
          sign = 1;
 
564
          elem->v.flip = 0;
 
565
        }
568
566
      else
569
 
        {
570
 
          scale = elem->v.scale = sqrt (-det);
571
 
          sign = -1;
572
 
          elem->v.flip = 1;
573
 
        }
 
567
        {
 
568
          scale = elem->v.scale = sqrt (-det);
 
569
          sign = -1;
 
570
          elem->v.flip = 1;
 
571
        }
574
572
 
575
573
      elem->v.theta = atan2 (-t2.a21, t2.a11);
576
574
 
577
575
      if (cos (elem->v.theta) == 0.0)
578
 
        {
579
 
          elem->v.asym = - t2.a21 / scale / sin(elem->v.theta);
580
 
          elem->v.shear = - sign * t2.a22 / scale / sin(elem->v.theta);
581
 
        }
 
576
        {
 
577
          elem->v.asym = - t2.a21 / scale / sin (elem->v.theta);
 
578
          elem->v.shear = - sign * t2.a22 / scale / sin (elem->v.theta);
 
579
        }
582
580
      else
583
 
        {
584
 
          elem->v.asym = sign * t2.a11 / scale / cos(elem->v.theta);
585
 
          elem->v.shear = sign *
586
 
            (t2.a12/scale - sin(elem->v.theta)/elem->v.asym)
587
 
            / cos(elem->v.theta);
588
 
        }
 
581
        {
 
582
          elem->v.asym = sign * t2.a11 / scale / cos (elem->v.theta);
 
583
          elem->v.shear = sign *
 
584
            (t2.a12/scale - sin (elem->v.theta)/elem->v.asym)
 
585
            / cos (elem->v.theta);
 
586
        }
589
587
    }
590
588
}
591
589
 
592
590
static void
593
591
aff_element_compute_click_boundary (AffElement *elem,
594
 
                                    int         num_elements,
595
 
                                    gdouble    *points_x,
596
 
                                    gdouble    *points_y)
 
592
                                    int         num_elements,
 
593
                                    gdouble    *points_x,
 
594
                                    gdouble    *points_y)
597
595
{
598
 
  gint i;
 
596
  gint    i;
599
597
  gdouble xtot = 0;
600
598
  gdouble ytot = 0;
601
599
  gdouble xc, yc;
602
600
  gdouble theta;
603
 
  gdouble sth,cth;              /* sin(theta), cos(theta) */
604
 
  gdouble axis1,axis2;
 
601
  gdouble sth, cth;              /* sin(theta), cos(theta) */
 
602
  gdouble axis1, axis2;
605
603
  gdouble axis1max, axis2max, axis1min, axis2min;
606
604
 
607
605
  /* compute the center of mass of the points */
608
 
  for (i=0; i<num_elements; i++)
 
606
  for (i = 0; i < num_elements; i++)
609
607
    {
610
608
      xtot += points_x[i];
611
609
      ytot += points_y[i];
612
610
    }
613
 
  xc = xtot/num_elements;
614
 
  yc = ytot/num_elements;
 
611
  xc = xtot / num_elements;
 
612
  yc = ytot / num_elements;
615
613
 
616
614
  /* compute the sum of the (x+iy)^2, and take half the the resulting
617
615
     angle (xtot+iytot = A*exp(2i*theta)), to get an average direction */
623
621
      xtot += SQR (points_x[i] - xc) - SQR (points_y[i] - yc);
624
622
      ytot += 2 * (points_x[i] - xc) * (points_y[i] - yc);
625
623
    }
626
 
  theta = 0.5*atan2(ytot,xtot);
627
 
  sth = sin(theta);
628
 
  cth = cos(theta);
 
624
  theta = 0.5 * atan2 (ytot, xtot);
 
625
  sth = sin (theta);
 
626
  cth = cos (theta);
629
627
 
630
628
  /* compute the minimum rectangle at angle theta that bounds the points,
631
629
     1/2 side lenghs left in axis1, axis2, center in xc, yc */
632
630
 
633
631
  axis1max = axis1min = 0.0;
634
632
  axis2max = axis2min = 0.0;
635
 
  for (i=0; i<num_elements; i++)
 
633
  for (i = 0; i < num_elements; i++)
636
634
    {
637
 
      gdouble proj1 = (points_x[i]-xc)*cth + (points_y[i]-yc)*sth;
638
 
      gdouble proj2 = -(points_x[i]-xc)*sth + (points_y[i]-yc)*cth;
 
635
      gdouble proj1 =  (points_x[i] - xc) * cth + (points_y[i] - yc) * sth;
 
636
      gdouble proj2 = -(points_x[i] - xc) * sth + (points_y[i] - yc) * cth;
639
637
      if (proj1 < axis1min)
640
 
        axis1min = proj1;
 
638
        axis1min = proj1;
641
639
      if (proj1 > axis1max)
642
 
        axis1max = proj1;
 
640
        axis1max = proj1;
643
641
      if (proj2 < axis2min)
644
 
        axis2min = proj2;
 
642
        axis2min = proj2;
645
643
      if (proj2 > axis2max)
646
 
        axis2max = proj2;
 
644
        axis2max = proj2;
647
645
    }
648
 
  axis1 = 0.5*(axis1max - axis1min);
649
 
  axis2 = 0.5*(axis2max - axis2min);
650
 
  xc += 0.5*((axis1max + axis1min)*cth - (axis2max+axis2min)*sth);
651
 
  yc += 0.5*((axis1max + axis1min)*sth + (axis2max+axis2min)*cth);
 
646
  axis1 = 0.5 * (axis1max - axis1min);
 
647
  axis2 = 0.5 * (axis2max - axis2min);
 
648
  xc += 0.5 * ((axis1max + axis1min) * cth - (axis2max + axis2min) * sth);
 
649
  yc += 0.5 * ((axis1max + axis1min) * sth + (axis2max + axis2min) * cth);
652
650
 
653
651
  /* if the the rectangle is less than 10 pixels in any dimension,
654
652
     make it click_boundary, otherwise set click_boundary = draw_boundary */
655
653
 
656
654
  if (axis1 < 8.0 || axis2 < 8.0)
657
655
    {
658
 
      GdkPoint *points = g_new (GdkPoint,4);
 
656
      GdkPoint *points = g_new (GdkPoint, 4);
659
657
 
660
 
      elem->click_boundary = g_new (IPolygon,1);
 
658
      elem->click_boundary = g_new (IPolygon, 1);
661
659
      elem->click_boundary->points = points;
662
660
      elem->click_boundary->npoints = 4;
663
661
 
664
662
      if (axis1 < 8.0) axis1 = 8.0;
665
663
      if (axis2 < 8.0) axis2 = 8.0;
666
664
 
667
 
      points[0].x = xc + axis1*cth - axis2*sth;
668
 
      points[0].y = yc + axis1*sth + axis2*cth;
669
 
      points[1].x = xc - axis1*cth - axis2*sth;
670
 
      points[1].y = yc - axis1*sth + axis2*cth;
671
 
      points[2].x = xc - axis1*cth + axis2*sth;
672
 
      points[2].y = yc - axis1*sth - axis2*cth;
673
 
      points[3].x = xc + axis1*cth + axis2*sth;
674
 
      points[3].y = yc + axis1*sth - axis2*cth;
 
665
      points[0].x = xc + axis1 * cth - axis2 * sth;
 
666
      points[0].y = yc + axis1 * sth + axis2 * cth;
 
667
      points[1].x = xc - axis1 * cth - axis2 * sth;
 
668
      points[1].y = yc - axis1 * sth + axis2 * cth;
 
669
      points[2].x = xc - axis1 * cth + axis2 * sth;
 
670
      points[2].y = yc - axis1 * sth - axis2 * cth;
 
671
      points[3].x = xc + axis1 * cth + axis2 * sth;
 
672
      points[3].y = yc + axis1 * sth - axis2 * cth;
675
673
    }
676
674
  else
677
675
    elem->click_boundary = elem->draw_boundary;
679
677
 
680
678
void
681
679
aff_element_compute_boundary (AffElement  *elem,
682
 
                              gint         width,
683
 
                              gint         height,
684
 
                              AffElement **elements,
685
 
                              gint         num_elements)
 
680
                              gint         width,
 
681
                              gint         height,
 
682
                              AffElement **elements,
 
683
                              gint         num_elements)
686
684
{
687
 
  int i;
688
 
  IPolygon tmp_poly;
689
 
  gdouble *points_x;
690
 
  gdouble *points_y;
 
685
  gint      i;
 
686
  IPolygon  tmp_poly;
 
687
  gdouble  *points_x;
 
688
  gdouble  *points_y;
691
689
 
692
690
  if (elem->click_boundary && elem->click_boundary != elem->draw_boundary)
693
691
    g_free (elem->click_boundary);
699
697
  points_x = g_new (gdouble, num_elements);
700
698
  points_y = g_new (gdouble, num_elements);
701
699
 
702
 
  for (i=0;i<num_elements;i++)
 
700
  for (i = 0; i < num_elements; i++)
703
701
    {
704
 
      aff2_apply (&elem->trans,elements[i]->v.x*width,elements[i]->v.y*width,
 
702
      aff2_apply (&elem->trans,
 
703
                  elements[i]->v.x * width, elements[i]->v.y * width,
705
704
                  &points_x[i],&points_y[i]);
706
705
      tmp_poly.points[i].x = (gint)points_x[i];
707
706
      tmp_poly.points[i].y = (gint)points_y[i];
708
707
    }
709
708
 
710
709
  elem->draw_boundary = ipolygon_convex_hull (&tmp_poly);
711
 
  aff_element_compute_click_boundary (elem,num_elements,points_x,points_y);
 
710
  aff_element_compute_click_boundary (elem, num_elements, points_x, points_y);
712
711
 
713
712
  g_free (tmp_poly.points);
714
713
}
715
714
 
716
715
void
717
716
aff_element_draw (AffElement  *elem,
718
 
                  gboolean     selected,
719
 
                  gint         width,
720
 
                  gint         height,
721
 
                  GdkDrawable *win,
722
 
                  GdkGC       *normal_gc,
723
 
                  GdkGC       *selected_gc,
724
 
                  PangoLayout *layout)
 
717
                  gboolean     selected,
 
718
                  gint         width,
 
719
                  gint         height,
 
720
                  GdkDrawable *win,
 
721
                  GdkGC       *normal_gc,
 
722
                  GdkGC       *selected_gc,
 
723
                  PangoLayout *layout)
725
724
{
726
725
  PangoRectangle  rect;
727
726
  GdkGC          *gc;
749
748
 
750
749
AffElement *
751
750
aff_element_new (gdouble  x,
752
 
                 gdouble  y,
753
 
                 GimpRGB *color,
754
 
                 gint     count)
 
751
                 gdouble  y,
 
752
                 GimpRGB *color,
 
753
                 gint     count)
755
754
{
756
 
  AffElement *elem = g_new(AffElement, 1);
 
755
  AffElement *elem = g_new (AffElement, 1);
757
756
  gchar buffer[16];
758
757
 
759
758
  elem->v.x = x;
782
781
 
783
782
  elem->v.prob = 1.0;
784
783
 
785
 
  sprintf (buffer,"%d",count);
786
 
  elem->name = g_strdup(buffer);
 
784
  sprintf (buffer,"%d", count);
 
785
  elem->name = g_strdup (buffer);
787
786
 
788
787
  return elem;
789
788
}
804
803
 
805
804
static guchar *
806
805
create_brush (IfsComposeVals *ifsvals,
807
 
              gint           *brush_size,
808
 
              gdouble        *brush_offset)
 
806
              gint           *brush_size,
 
807
              gdouble        *brush_offset)
809
808
{
810
 
  gint i,j;
811
 
  gint ii,jj;
812
 
  guchar *brush;
 
809
  gint     i, j;
 
810
  gint     ii, jj;
 
811
  guchar  *brush;
813
812
#ifdef DEBUG_BRUSH
814
 
  gdouble totpix = 0.0;
 
813
  gdouble  totpix = 0.0;
815
814
#endif
816
815
 
817
816
  gdouble radius = ifsvals->radius * ifsvals->subdivide;
821
820
 
822
821
  brush = g_new (guchar, SQR (*brush_size));
823
822
 
824
 
  for (i=0 ; i < *brush_size; i++)
 
823
  for (i = 0; i < *brush_size; i++)
825
824
    {
826
825
      for (j = 0; j < *brush_size; j++)
827
 
        {
828
 
          gdouble pixel = 0.0;
829
 
          gdouble d     = sqrt (SQR (i - *brush_offset) +
 
826
        {
 
827
          gdouble pixel = 0.0;
 
828
          gdouble d     = sqrt (SQR (i - *brush_offset) +
830
829
                                SQR (j - *brush_offset));
831
830
 
832
 
          if (d - 0.5 * G_SQRT2 > radius)
833
 
            pixel = 0.0;
834
 
          else if (d + 0.5 * G_SQRT2 < radius)
835
 
            pixel = 1.0;
836
 
          else
837
 
            for (ii = 0; ii < 10; ii++)
838
 
              for (jj = 0; jj < 10; jj++)
839
 
                {
840
 
                  d = sqrt (SQR (i - *brush_offset + ii * 0.1 - 0.45) +
 
831
          if (d - 0.5 * G_SQRT2 > radius)
 
832
            pixel = 0.0;
 
833
          else if (d + 0.5 * G_SQRT2 < radius)
 
834
            pixel = 1.0;
 
835
          else
 
836
            for (ii = 0; ii < 10; ii++)
 
837
              for (jj = 0; jj < 10; jj++)
 
838
                {
 
839
                  d = sqrt (SQR (i - *brush_offset + ii * 0.1 - 0.45) +
841
840
                            SQR (j - *brush_offset + jj * 0.1 - 0.45));
842
 
                  pixel += (d < radius) / 100.0;
843
 
                }
 
841
                  pixel += (d < radius) / 100.0;
 
842
                }
844
843
 
845
 
          brush[i**brush_size + j] = 255.999 * pixel;
 
844
          brush[i * *brush_size + j] = 255.999 * pixel;
846
845
 
847
846
#ifdef DEBUG_BRUSH
848
 
          putchar(brush_chars[(gint)(pixel * 3.999)]);
849
 
          totpix += pixel;
 
847
          putchar(brush_chars[(gint)(pixel * 3.999)]);
 
848
          totpix += pixel;
850
849
#endif /* DEBUG_BRUSH */
851
 
        }
 
850
        }
852
851
#ifdef DEBUG_BRUSH
853
852
      putchar('\n');
854
853
#endif /* DEBUG_BRUSH */
855
854
    }
856
855
#ifdef DEBUG_BRUSH
857
 
  printf("Brush total / area = %f\n",totpix/SQR(ifsvals->subdivide));
 
856
  printf ("Brush total / area = %f\n", totpix / SQR (ifsvals->subdivide));
858
857
#endif /* DEBUG_BRUSH */
859
858
  return brush;
860
859
}
861
860
 
862
861
void
863
862
ifs_render (AffElement     **elements,
864
 
            gint             num_elements,
865
 
            gint             width,
866
 
            gint             height,
867
 
            gint             nsteps,
868
 
            IfsComposeVals  *vals,
869
 
            gint             band_y,
870
 
            gint             band_height,
871
 
            guchar          *data,
872
 
            guchar          *mask,
873
 
            guchar          *nhits,
874
 
            gint             preview)
 
863
            gint             num_elements,
 
864
            gint             width,
 
865
            gint             height,
 
866
            gint             nsteps,
 
867
            IfsComposeVals  *vals,
 
868
            gint             band_y,
 
869
            gint             band_height,
 
870
            guchar          *data,
 
871
            guchar          *mask,
 
872
            guchar          *nhits,
 
873
            gboolean         preview)
875
874
{
876
875
  gint     i, k;
877
876
  gdouble  x, y;
884
883
  gdouble *fprob;
885
884
  gint     subdivide;
886
885
  guchar  *brush = NULL;
887
 
  gint     brush_size;
888
 
  gdouble  brush_offset;
 
886
  gint     brush_size = 1;
 
887
  gdouble  brush_offset = 0.0;
 
888
  gint     next_progress = 0 ;
889
889
 
890
890
  if (preview)
891
891
    subdivide = 1;
896
896
  fprob = g_new (gdouble, num_elements);
897
897
  prob = g_new (guint32, num_elements);
898
898
  pt = 0.0;
899
 
  for (i=0;i<num_elements;i++)
 
899
 
 
900
  for (i = 0; i < num_elements; i++)
900
901
    {
901
 
      aff_element_compute_trans(elements[i],width*subdivide,height*subdivide,
902
 
                                vals->center_x, vals->center_y);
 
902
      aff_element_compute_trans(elements[i],
 
903
                                width * subdivide,
 
904
                                height * subdivide,
 
905
                                vals->center_x,
 
906
                                vals->center_y);
903
907
      fprob[i] = fabs(
904
 
        elements[i]->trans.a11 * elements[i]->trans.a22
905
 
        - elements[i]->trans.a12 * elements[i]->trans.a21);
 
908
          elements[i]->trans.a11 * elements[i]->trans.a22
 
909
        - elements[i]->trans.a12 * elements[i]->trans.a21);
 
910
 
906
911
      /* As a heuristic, if the determinant is really small, it's
907
 
         probably a line element, so increase the probability so
908
 
         it gets rendered */
 
912
         probably a line element, so increase the probability so
 
913
         it gets rendered */
 
914
 
909
915
      /* FIXME: figure out what 0.01 really should be */
910
916
      if (fprob[i] < 0.01)
911
917
        fprob[i] = 0.01;
 
918
 
912
919
      fprob[i] *= elements[i]->v.prob;
913
920
 
914
921
      pt += fprob[i];
917
924
  psum = 0;
918
925
  for (i = 0; i < num_elements; i++)
919
926
    {
920
 
      psum += (guint32) -1 * (fprob[i]/pt);
 
927
      psum += (guint32) -1 * (fprob[i] / pt);
921
928
      prob[i] = psum;
922
929
    }
923
 
  prob[i-1] = (guint32) -1;      /* make sure we don't get bitten
924
 
                                   by roundoff*/
 
930
 
 
931
  prob[i - 1] = (guint32) -1;  /* make sure we don't get bitten by roundoff */
 
932
 
925
933
  /* create the brush */
926
934
  if (!preview)
927
 
    brush = create_brush (vals,&brush_size,&brush_offset);
 
935
    brush = create_brush (vals, &brush_size, &brush_offset);
928
936
 
929
937
  x = y = 0;
930
938
  r = g = b = 0;
931
939
 
932
940
  /* now run the iteration */
933
 
  for (i=0;i<nsteps;i++)
 
941
  for (i = 0; i < nsteps; i++)
934
942
    {
935
 
      if (!preview && !(i % 5000))
936
 
        gimp_progress_update ((gdouble) i / (gdouble) nsteps);
 
943
      if (!preview && (i > next_progress))
 
944
        {
 
945
          next_progress = i + nsteps / 32 + 100;
 
946
          gimp_progress_update ((gdouble) i / (gdouble) nsteps);
 
947
        }
 
948
 
937
949
      p0 = g_random_int ();
938
 
      k=0;
 
950
      k = 0;
 
951
 
939
952
      while (p0 > prob[k])
940
 
        k++;
941
 
 
942
 
      aff2_apply(&elements[k]->trans,x,y,&x,&y);
943
 
      aff3_apply(&elements[k]->color_trans,r,g,b,&r,&g,&b);
944
 
      if (i<50) continue;
945
 
 
946
 
      ri = (gint) (254.999 * r + 0.5);
947
 
      gi = (gint) (254.999 * g + 0.5);
948
 
      bi = (gint) (254.999 * b + 0.5);
 
953
        k++;
 
954
 
 
955
      aff2_apply (&elements[k]->trans, x, y, &x, &y);
 
956
      aff3_apply (&elements[k]->color_trans, r, g, b, &r, &g, &b);
 
957
 
 
958
      if (i < 50)
 
959
        continue;
 
960
 
 
961
      ri = (gint) (255.0 * r + 0.5);
 
962
      gi = (gint) (255.0 * g + 0.5);
 
963
      bi = (gint) (255.0 * b + 0.5);
 
964
 
 
965
      if ((ri < 0) || (ri > 255) ||
 
966
          (gi < 0) || (gi > 255) ||
 
967
          (bi < 0) || (bi > 255))
 
968
        continue;
949
969
 
950
970
      if (preview)
951
 
        {
952
 
          if ((x<width) && (y<(band_y+band_height)) &&
953
 
              (x >= 0) && (y >= band_y) &&
954
 
              (ri >= 0) && (ri < 256) &&
955
 
              (gi >= 0) && (gi < 256) &&
956
 
              (bi >= 0) && (bi < 256))
957
 
            {
958
 
              ptr = data + 3 * (((gint)(y-band_y))*width + (gint)x);
959
 
              *ptr++ = ri;
960
 
              *ptr++ = gi;
961
 
              *ptr = bi;
962
 
            }
963
 
        }
 
971
        {
 
972
          if ((x < width) && (y < (band_y + band_height)) &&
 
973
              (x >= 0) && (y >= band_y))
 
974
            {
 
975
              ptr = data + 3 * (((gint) (y - band_y)) * width + (gint) x);
 
976
 
 
977
              *ptr++ = ri;
 
978
              *ptr++ = gi;
 
979
              *ptr   = bi;
 
980
            }
 
981
        }
964
982
      else
965
 
        if ((ri >= 0) && (ri < 256) &&
966
 
            (gi >= 0) && (gi < 256) &&
967
 
            (bi >= 0) && (bi < 256))
968
 
          {
969
 
            guint m_old;
970
 
            guint m_new;
971
 
            guint m_pix;
972
 
            guint n_hits;
973
 
            guint old_scale;
974
 
            guint pix_scale;
975
 
 
976
 
            gint index;
977
 
            gint ii,jj;
978
 
            gint jj0 = floor(y-brush_offset-band_y*subdivide);
979
 
            gint ii0 = floor(x-brush_offset);
980
 
            gint jjmax,iimax;
981
 
            gint jjmin = 0;
982
 
            gint iimin = 0;
983
 
 
984
 
            if (ii0 < 0)
985
 
              iimin = - ii0;
986
 
            else
987
 
              iimin = 0;
988
 
 
989
 
            if (jj0 < 0)
990
 
              jjmin = - jj0;
991
 
            else
992
 
              jjmin = 0;
993
 
 
994
 
            if (jj0 + brush_size >= subdivide * band_height)
995
 
              jjmax = subdivide * band_height - jj0;
996
 
            else
997
 
              jjmax = brush_size;
998
 
 
999
 
            if (ii0 + brush_size >= subdivide * width)
1000
 
              iimax = subdivide * width - ii0;
1001
 
            else
1002
 
              iimax = brush_size;
1003
 
 
1004
 
            for (jj = jjmin; jj < jjmax; jj++)
1005
 
              for (ii = iimin; ii < iimax; ii++)
1006
 
                {
1007
 
                  index = (jj0 + jj) * width * subdivide + ii0 + ii;
1008
 
                  n_hits = nhits[index];
1009
 
                  if (n_hits == 255)
1010
 
                    continue;
1011
 
 
1012
 
                  m_pix = brush[jj*brush_size+ii];
1013
 
                  if (!m_pix)
1014
 
                    continue;
1015
 
                  nhits[index] = ++n_hits;
1016
 
                  m_old = mask[index];
1017
 
                  m_new = m_old + m_pix - m_old*m_pix/255;
1018
 
                  mask[index] = m_new;
1019
 
 
1020
 
                  /* relative probability that old colored pixel is on top */
1021
 
                  old_scale = m_old*(255*n_hits-m_pix);
1022
 
                  /* relative probability that new colored pixel is on top */
1023
 
                  pix_scale = m_pix*((255-m_old)*n_hits+m_old);
1024
 
 
1025
 
                  ptr = data + 3*index;
1026
 
                  *ptr = ( old_scale * (*ptr) + pix_scale * ri ) /
1027
 
                    ( old_scale + pix_scale );
1028
 
                  ptr++;
1029
 
                  *ptr = ( old_scale * (*ptr) + pix_scale * gi ) /
1030
 
                    ( old_scale + pix_scale );
1031
 
                  ptr++;
1032
 
                  *ptr = ( old_scale * (*ptr) + pix_scale * bi ) /
1033
 
                    ( old_scale + pix_scale );
1034
 
                }
1035
 
          }
 
983
        {
 
984
          if ((x < width * subdivide) && (y < height * subdivide) &&
 
985
              (x >= 0) && (y >= 0))
 
986
            {
 
987
              gint ii;
 
988
              gint jj;
 
989
              gint jj0   = floor (y - brush_offset - band_y * subdivide);
 
990
              gint ii0   = floor (x - brush_offset);
 
991
              gint jjmin = 0;
 
992
              gint iimin = 0;
 
993
              gint jjmax;
 
994
              gint iimax;
 
995
 
 
996
              if (ii0 < 0)
 
997
                iimin = - ii0;
 
998
              else
 
999
                iimin = 0;
 
1000
 
 
1001
              if (jj0 < 0)
 
1002
                jjmin = - jj0;
 
1003
              else
 
1004
                jjmin = 0;
 
1005
 
 
1006
              if (jj0 + brush_size >= subdivide * band_height)
 
1007
                jjmax = subdivide * band_height - jj0;
 
1008
              else
 
1009
                jjmax = brush_size;
 
1010
 
 
1011
              if (ii0 + brush_size >= subdivide * width)
 
1012
                iimax = subdivide * width - ii0;
 
1013
              else
 
1014
                iimax = brush_size;
 
1015
 
 
1016
              for (jj = jjmin; jj < jjmax; jj++)
 
1017
                for (ii = iimin; ii < iimax; ii++)
 
1018
                  {
 
1019
                    guint m_old;
 
1020
                    guint m_new;
 
1021
                    guint m_pix;
 
1022
                    guint n_hits;
 
1023
                    guint old_scale;
 
1024
                    guint pix_scale;
 
1025
                    gint  index = (jj0 + jj) * width * subdivide + ii0 + ii;
 
1026
 
 
1027
                    n_hits = nhits[index];
 
1028
                    if (n_hits == 255)
 
1029
                      continue;
 
1030
 
 
1031
                    m_pix = brush[jj * brush_size + ii];
 
1032
                    if (!m_pix)
 
1033
                      continue;
 
1034
 
 
1035
                    nhits[index] = ++n_hits;
 
1036
                    m_old = mask[index];
 
1037
                    m_new = m_old + m_pix - m_old * m_pix / 255;
 
1038
                    mask[index] = m_new;
 
1039
 
 
1040
                    /* relative probability that old colored pixel is on top */
 
1041
                    old_scale = m_old * (255 * n_hits - m_pix);
 
1042
 
 
1043
                    /* relative probability that new colored pixel is on top */
 
1044
                    pix_scale = m_pix * ((255 - m_old) * n_hits + m_old);
 
1045
 
 
1046
                    ptr = data + 3 * index;
 
1047
 
 
1048
                    *ptr = ((old_scale * (*ptr) + pix_scale * ri) /
 
1049
                            (old_scale + pix_scale));
 
1050
                    ptr++;
 
1051
 
 
1052
                    *ptr = ((old_scale * (*ptr) + pix_scale * gi) /
 
1053
                            (old_scale + pix_scale));
 
1054
                    ptr++;
 
1055
 
 
1056
                    *ptr = ((old_scale * (*ptr) + pix_scale * bi) /
 
1057
                            (old_scale + pix_scale));
 
1058
                  }
 
1059
            }
 
1060
        }
1036
1061
    } /* main iteration */
1037
1062
 
 
1063
  if (!preview )
 
1064
    gimp_progress_update (1.0);
 
1065
 
1038
1066
  g_free (brush);
1039
1067
  g_free (prob);
1040
1068
  g_free (fprob);