gimpimage.c 99.5 KB
Newer Older
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
/* The GIMP -- an image manipulation program
 * Copyright (C) 1995 Spencer Kimball and Peter Mattis
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 */
18
19
#include "config.h"

20
#include <string.h>
21

22
#include "gimpimageP.h"
23
#include "cursorutil.h"
24
25
#include "drawable.h"
#include "floating_sel.h"
26
#include "gdisplay.h"
27
#include "gimage_mask.h"
28
#include "gimpcontext.h"
29
#include "paint_funcs.h"
30
#include "parasitelist.h"
31
32
#include "undo.h"
#include "gimpsignal.h"
Manish Singh's avatar
Manish Singh committed
33
#include "gimpparasite.h"
34
#include "path.h"
35
#include "gimprc.h"
36

scott's avatar
scott committed
37
38
#include "tile_manager.h"
#include "tile.h"
39
40
41
#include "layer_pvt.h"
#include "drawable_pvt.h"		/* ick ick. */

42
43
#include "libgimp/gimpcolorspace.h"
#include "libgimp/gimplimits.h"
44
#include "libgimp/gimpparasite.h"
45
46
47

#include "libgimp/gimpintl.h"

48

49
50
51
52
53
54
55
#ifdef DEBUG
#define TRC(x) printf x
#else
#define TRC(x)
#endif


56
/*  Local function declarations  */
57
static void     gimp_image_destroy               (GtkObject *object);
58
static void     gimp_image_free_projection       (GimpImage *);
59
static void     gimp_image_allocate_shadow       (GimpImage *, gint, gint, gint);
60
61
62
static void     gimp_image_allocate_projection   (GimpImage *);
static void     gimp_image_free_layers           (GimpImage *);
static void     gimp_image_free_channels         (GimpImage *);
63
64
65
66
static void     gimp_image_construct_layers      (GimpImage *, gint, gint, gint, gint);
static void     gimp_image_construct_channels    (GimpImage *, gint, gint, gint, gint);
static void     gimp_image_initialize_projection (GimpImage *, gint, gint, gint, gint);
static void     gimp_image_get_active_channels   (GimpImage *, GimpDrawable *, gint *);
67
68

/*  projection functions  */
69
70
static void     project_intensity            (GimpImage *, Layer *,
					      PixelRegion *, PixelRegion *,
71
					      PixelRegion *);
72
73
static void     project_intensity_alpha      (GimpImage *, Layer *,
					      PixelRegion *, PixelRegion *,
74
					      PixelRegion *);
75
76
77
78
static void     project_indexed              (GimpImage *, Layer *,
					      PixelRegion *, PixelRegion *);
static void     project_channel              (GimpImage *, Channel *,
					      PixelRegion *, PixelRegion *);
79
80
81
82

/*
 *  Global variables
 */
83
gint valid_combinations[][MAX_CHANNELS + 1] =
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
{
  /* RGB GIMAGE */
  { -1, -1, -1, COMBINE_INTEN_INTEN, COMBINE_INTEN_INTEN_A },
  /* RGBA GIMAGE */
  { -1, -1, -1, COMBINE_INTEN_A_INTEN, COMBINE_INTEN_A_INTEN_A },
  /* GRAY GIMAGE */
  { -1, COMBINE_INTEN_INTEN, COMBINE_INTEN_INTEN_A, -1, -1 },
  /* GRAYA GIMAGE */
  { -1, COMBINE_INTEN_A_INTEN, COMBINE_INTEN_A_INTEN_A, -1, -1 },
  /* INDEXED GIMAGE */
  { -1, COMBINE_INDEXED_INDEXED, COMBINE_INDEXED_INDEXED_A, -1, -1 },
  /* INDEXEDA GIMAGE */
  { -1, -1, COMBINE_INDEXED_A_INDEXED_A, -1, -1 },
};

99
guint32 next_guide_id = 1;  /* For generating guide_ID handles for PDB stuff */
100

101
102
103
104
105

/*
 *  Static variables
 */

106
enum {
107
  CLEAN,
108
109
110
111
112
  DIRTY,
  REPAINT,
  RENAME,
  RESIZE,
  RESTRUCTURE,
113
  COLORMAP_CHANGED,
114
  UNDO_EVENT,
115
116
  LAST_SIGNAL
};
117

118
static guint            gimp_image_signals[LAST_SIGNAL];
119
static GimpObjectClass *parent_class;
120

121

122
123
124
125
static void
gimp_image_class_init (GimpImageClass *klass)
{
  GtkObjectClass *object_class;
126
  GtkType         type;
127
128
129
130
131
132
133
134
  
  object_class = GTK_OBJECT_CLASS(klass);
  parent_class = gtk_type_class (gimp_object_get_type ());
  
  type=object_class->type;

  object_class->destroy =  gimp_image_destroy;

135
136
137
  gimp_image_signals[CLEAN] =
	  gimp_signal_new ("clean", GTK_RUN_FIRST, type, 0,
			   gimp_sigtype_void);
138
  gimp_image_signals[DIRTY] =
139
140
	  gimp_signal_new ("dirty", GTK_RUN_FIRST, type, 0,
			   gimp_sigtype_void);
141
  gimp_image_signals[REPAINT] =
142
143
	  gimp_signal_new ("repaint", GTK_RUN_FIRST, type, 0,
			   gimp_sigtype_int_int_int_int);
144
  gimp_image_signals[RENAME] =
145
146
	  gimp_signal_new ("rename", GTK_RUN_FIRST, type, 0,
			   gimp_sigtype_void);
147
  gimp_image_signals[RESIZE] =
148
149
	  gimp_signal_new ("resize", GTK_RUN_FIRST, type, 0,
			   gimp_sigtype_void);
150
  gimp_image_signals[RESTRUCTURE] =
151
152
	  gimp_signal_new ("restructure", GTK_RUN_FIRST, type, 0,
			   gimp_sigtype_void);
153
  gimp_image_signals[COLORMAP_CHANGED] =
154
155
	  gimp_signal_new ("colormap_changed", GTK_RUN_FIRST, type, 0,
			   gimp_sigtype_int);
156
157
158
  gimp_image_signals[UNDO_EVENT] = 
	  gimp_signal_new ("undo_event", GTK_RUN_FIRST, type, 0,
			   gimp_sigtype_int);
159
160
161
162
163
164
165
  
  gtk_object_class_add_signals (object_class, gimp_image_signals, LAST_SIGNAL);
}


/* static functions */

Sven Neumann's avatar
Sven Neumann committed
166
167
static void 
gimp_image_init (GimpImage *gimage)
168
{
169
170
171
  gimage->has_filename          = FALSE;
  gimage->num_cols              = 0;
  gimage->cmap                  = NULL;
172
  gimage->disp_count            = 0;
173
174
  gimage->instance_count        = 0;
  gimage->shadow                = NULL;
175
  gimage->dirty                 = 1;
176
177
178
179
180
181
182
183
184
185
186
187
  gimage->undo_on               = TRUE;
  gimage->construct_flag        = -1;
  gimage->tattoo_state          = 0;
  gimage->projection            = NULL;
  gimage->guides                = NULL;
  gimage->layers                = NULL;
  gimage->channels              = NULL;
  gimage->layer_stack           = NULL;
  gimage->undo_stack            = NULL;
  gimage->redo_stack            = NULL;
  gimage->undo_bytes            = 0;
  gimage->undo_levels           = 0;
188
  gimage->group_count           = 0;
189
  gimage->pushing_undo_group    = UNDO_NULL;
190
191
192
  gimage->comp_preview_valid[0] = FALSE;
  gimage->comp_preview_valid[1] = FALSE;
  gimage->comp_preview_valid[2] = FALSE;
193
  gimage->comp_preview          = NULL;
194
  gimage->parasites             = parasite_list_new ();
195
196
197
198
199
  gimage->xresolution           = default_xresolution;
  gimage->yresolution           = default_yresolution;
  gimage->unit                  = default_units;
  gimage->save_proc             = NULL;
  gimage->paths                 = NULL;
200
201
}

Sven Neumann's avatar
Sven Neumann committed
202
203
204
205
206
GtkType 
gimp_image_get_type (void) 
{
  static GtkType type;

207
208
209
210
211
212
  GIMP_TYPE_INIT (type,
		  GimpImage,
		  GimpImageClass,
		  gimp_image_init,
		  gimp_image_class_init,
		  GIMP_TYPE_OBJECT);
Sven Neumann's avatar
Sven Neumann committed
213
  return type;
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
}

static void
gimp_image_allocate_projection (GimpImage *gimage)
{
  if (gimage->projection)
    gimp_image_free_projection (gimage);

  /*  Find the number of bytes required for the projection.
   *  This includes the intensity channels and an alpha channel
   *  if one doesn't exist.
   */
  switch (gimp_image_base_type (gimage))
    {
    case RGB:
    case INDEXED:
      gimage->proj_bytes = 4;
      gimage->proj_type = RGBA_GIMAGE;
      break;
    case GRAY:
      gimage->proj_bytes = 2;
      gimage->proj_type = GRAYA_GIMAGE;
      break;
    default:
238
      g_assert_not_reached ();
239
240
241
242
    }

  /*  allocate the new projection  */
  gimage->projection = tile_manager_new (gimage->width, gimage->height, gimage->proj_bytes);
243
  tile_manager_set_user_data (gimage->projection, (void *) gimage);
244
245
246
247
248
249
250
251
252
253
254
255
256
  tile_manager_set_validate_proc (gimage->projection, gimp_image_validate);
}

static void
gimp_image_free_projection (GimpImage *gimage)
{
  if (gimage->projection)
    tile_manager_destroy (gimage->projection);

  gimage->projection = NULL;
}

static void
Sven Neumann's avatar
Sven Neumann committed
257
gimp_image_allocate_shadow (GimpImage *gimage, 
258
259
260
			    gint       width, 
			    gint       height, 
			    gint       bpp)
261
262
263
264
265
266
267
268
269
{
  /*  allocate the new projection  */
  gimage->shadow = tile_manager_new (width, height, bpp);
}


/* function definitions */

GimpImage *
270
271
272
gimp_image_new (gint               width,
		gint               height,
		GimpImageBaseType  base_type)
273
{
274
275
  GimpImage *gimage = GIMP_IMAGE (gtk_type_new (gimp_image_get_type ()));
  gint i;
276

277
278
279
  gimage->filename  = NULL;
  gimage->width     = width;
  gimage->height    = height;
280
281
282
283
284
285
286
287
288
289
  gimage->base_type = base_type;

  switch (base_type)
    {
    case RGB:
    case GRAY:
      break;
    case INDEXED:
      /* always allocate 256 colors for the colormap */
      gimage->num_cols = 0;
290
      gimage->cmap     = (guchar *) g_malloc0 (COLORMAP_SIZE);
291
292
293
294
295
296
      break;
    default:
      break;
    }

  /*  configure the active pointers  */
297
  gimage->active_layer   = NULL;
298
  gimage->active_channel = NULL;  /* no default active channel */
299
  gimage->floating_sel   = NULL;
300
301
302
303

  /*  set all color channels visible and active  */
  for (i = 0; i < MAX_CHANNELS; i++)
    {
304
305
      gimage->visible[i] = TRUE;
      gimage->active[i]  = TRUE;
306
307
308
    }

  /* create the selection mask */
309
310
  gimage->selection_mask = channel_new_mask (gimage,
					     gimage->width, gimage->height);
311

312
  /* set the qmask properties */
313
314
  gimage->qmask_state    = FALSE;
  gimage->qmask_opacity  = 50;
315
316
317
  gimage->qmask_color[0] = 255; 
  gimage->qmask_color[1] = 0; 
  gimage->qmask_color[2] = 0; 
318
319
320
321
322

  return gimage;
}

void
323
gimp_image_set_filename (GimpImage *gimage, 
324
			 gchar     *filename)
325
{
326
327
  gchar *new_filename, *old_filename;
  gboolean free_old;
328

329
330
331
332
333
334
  /* 
   * WARNING: this function will free the current filename even if you are 
   * setting it to itself so any pointer you hold to the filename will be
   * invalid after this call.  So please use with care.
   */

335
  new_filename = g_strdup (filename);
336
337
  old_filename = gimage->filename;
  free_old = gimage->has_filename;
338
339
340
341
342
343
344
345
346
347
348
349

  if (filename && filename[0])
    {
      gimage->filename = new_filename;
      gimage->has_filename = TRUE;
    }
  else
    {
      gimage->filename = NULL;
      gimage->has_filename = FALSE;
    }

350
351
352
  if (free_old)
    g_free (old_filename);

353
354
355
  gtk_signal_emit (GTK_OBJECT (gimage), gimp_image_signals[RENAME]);
}

356
void
357
gimp_image_set_resolution (GimpImage *gimage,
358
359
			   gdouble    xresolution,
			   gdouble    yresolution)
360
{
361
362
363
364
365
  /* nothing to do if setting res to the same as before */
  if ((ABS (gimage->xresolution - xresolution) < 1e-5) &&
      (ABS (gimage->yresolution - yresolution) < 1e-5))
      return;

366
367
368
  /* don't allow to set the resolution out of bounds */
  if (xresolution < GIMP_MIN_RESOLUTION || xresolution > GIMP_MAX_RESOLUTION ||
      yresolution < GIMP_MIN_RESOLUTION || yresolution > GIMP_MAX_RESOLUTION)
369
370
    return;

371
  undo_push_resolution (gimage);
372

373
374
  gimage->xresolution = xresolution;
  gimage->yresolution = yresolution;
375
376
377

  /* really just want to recalc size and repaint */
  gdisplays_shrink_wrap (gimage);
378
379
}

380
381
void
gimp_image_get_resolution (GimpImage *gimage,
382
383
			   gdouble   *xresolution,
			   gdouble   *yresolution)
384
{
385
386
  g_return_if_fail (xresolution && yresolution);

387
388
  *xresolution = gimage->xresolution;
  *yresolution = gimage->yresolution;
389
390
}

391
392
void
gimp_image_set_unit (GimpImage *gimage,
393
		     GimpUnit   unit)
394
{
395
396
  undo_push_resolution (gimage);

397
398
399
  gimage->unit = unit;
}

400
GimpUnit
401
402
403
404
405
gimp_image_get_unit (GimpImage *gimage)
{
  return gimage->unit;
}

406
void
Sven Neumann's avatar
Sven Neumann committed
407
408
gimp_image_set_save_proc (GimpImage     *gimage, 
			  PlugInProcDef *proc)
409
410
411
412
413
414
415
416
417
{
  gimage->save_proc = proc;
}

PlugInProcDef *
gimp_image_get_save_proc (GimpImage *gimage)
{
  return gimage->save_proc;
}
418

419
void
420
gimp_image_resize (GimpImage *gimage, 
421
422
423
424
		   gint       new_width, 
		   gint       new_height,
		   gint       offset_x, 
		   gint       offset_y)
425
426
{
  Channel *channel;
427
428
429
430
  Layer   *layer;
  Layer   *floating_layer;
  GSList  *list;
  GList   *guide_list;
431

432
433
  gimp_add_busy_cursors();

434
  g_assert (new_width > 0 && new_height > 0);
435
436
437
438

  /*  Get the floating layer if one exists  */
  floating_layer = gimp_image_floating_sel (gimage);

Sven Neumann's avatar
Sven Neumann committed
439
  undo_push_group_start (gimage, IMAGE_RESIZE_UNDO);
440
441
442
443
444
445
446
447
448

  /*  Relax the floating selection  */
  if (floating_layer)
    floating_sel_relax (floating_layer, TRUE);

  /*  Push the image size to the stack  */
  undo_push_gimage_mod (gimage);

  /*  Set the new width and height  */
449
  gimage->width  = new_width;
450
451
452
453
454
455
456
457
458
  gimage->height = new_height;

  /*  Resize all channels  */
  list = gimage->channels;
  while (list)
    {
      channel = (Channel *) list->data;
      channel_resize (channel, new_width, new_height, offset_x, offset_y);
      list = g_slist_next (list);
459
460
461
462
463
464
465
466
467
468

    }

  /*  Reposition or remove any guides  */
  guide_list = gimage->guides;
  while (guide_list)
    {
      Guide *guide;

      guide = (Guide*) guide_list->data;
Sven Neumann's avatar
Sven Neumann committed
469
      guide_list = g_list_next (guide_list);
470
471
472

      switch (guide->orientation)
	{
473
	case ORIENTATION_HORIZONTAL:
Sven Neumann's avatar
Sven Neumann committed
474
	  undo_push_guide (gimage, guide);
475
476
477
478
	  guide->position += offset_y;
	  if (guide->position < 0 || guide->position > new_height)
	    gimp_image_delete_guide (gimage, guide);
	  break;
479
	case ORIENTATION_VERTICAL:
Sven Neumann's avatar
Sven Neumann committed
480
	  undo_push_guide (gimage, guide);
481
482
483
484
485
486
487
	  guide->position += offset_x;
	  if (guide->position < 0 || guide->position > new_width)
	    gimp_image_delete_guide (gimage, guide);
	  break;
	default:
	  g_error("Unknown guide orientation I.\n");
	}
488
489
490
    }

  /*  Don't forget the selection mask!  */
491
492
  channel_resize (gimage->selection_mask,
		  new_width, new_height, offset_x, offset_y);
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
  gimage_mask_invalidate (gimage);

  /*  Reposition all layers  */
  list = gimage->layers;
  while (list)
    {
      layer = (Layer *) list->data;
      layer_translate (layer, offset_x, offset_y);
      list = g_slist_next (list);
    }

  /*  Make sure the projection matches the gimage size  */
  gimp_image_projection_realloc (gimage);

  /*  Rigor the floating selection  */
  if (floating_layer)
    floating_sel_rigor (floating_layer, TRUE);

  gtk_signal_emit (GTK_OBJECT (gimage), gimp_image_signals[RESIZE]);
512

513
  gimp_remove_busy_cursors (NULL);
514
515
}

516
517
518
519
520
521
522
523
524
525
526
527
gint
gimp_image_get_width (const GimpImage *gimage)
{
  return gimage->width;
}

gint
gimp_image_get_height (const GimpImage *gimage)
{
  return gimage->height;
}

528
void
529
gimp_image_scale (GimpImage *gimage, 
530
531
		  gint       new_width, 
		  gint       new_height)
532
533
{
  Channel *channel;
Sven Neumann's avatar
Sven Neumann committed
534
535
536
  Layer   *layer;
  Layer   *floating_layer;
  GSList  *list;
537
  GSList  *remove = NULL;
Sven Neumann's avatar
Sven Neumann committed
538
539
  GList   *glist;
  Guide   *guide;
540
541
542
543
  gint     old_width;
  gint     old_height;
  gdouble  img_scale_w = 1.0;
  gdouble  img_scale_h = 1.0;
544

545
  if ((new_width == 0) || (new_height == 0))
546
    {
547
      g_message (("gimp_image_scale: Scaling to zero width or height has been rejected."));
548
549
      return;
    }
550

551
  gimp_add_busy_cursors ();
552

553
554
555
  /*  Get the floating layer if one exists  */
  floating_layer = gimp_image_floating_sel (gimage);

Sven Neumann's avatar
Sven Neumann committed
556
  undo_push_group_start (gimage, IMAGE_SCALE_UNDO);
557
558
559
560
561
562
563
564
565

  /*  Relax the floating selection  */
  if (floating_layer)
    floating_sel_relax (floating_layer, TRUE);

  /*  Push the image size to the stack  */
  undo_push_gimage_mod (gimage);

  /*  Set the new width and height  */
566
567
568

  old_width      = gimage->width;
  old_height     = gimage->height;
569
  gimage->width  = new_width;
570
  gimage->height = new_height;
571
572
  img_scale_w    = (gdouble)new_width / (gdouble)old_width;
  img_scale_h    = (gdouble)new_height / (gdouble)old_height;
573
 
574
  /*  Scale all channels  */
575
  for (list = gimage->channels; list; list = g_slist_next (list))
576
577
578
579
580
581
    {
      channel = (Channel *) list->data;
      channel_scale (channel, new_width, new_height);
    }

  /*  Don't forget the selection mask!  */
582
583
584
585
586
  /*  if (channel_is_empty(gimage->selection_mask))
        channel_resize(gimage->selection_mask, new_width, new_height, 0, 0)
      else
  */
        
587
588
589
590
591
  channel_scale (gimage->selection_mask, new_width, new_height);
  gimage_mask_invalidate (gimage);

  /*  Scale all layers  */
  list = gimage->layers;
592
  for (list = gimage->layers; list; list = g_slist_next (list))
593
    {
594
595
      layer = (Layer *) list->data;
      if (layer_scale_by_factors (layer, img_scale_w, img_scale_h) == FALSE)
596
597
598
599
600
601
	{
	  /* Since 0 < img_scale_w, img_scale_h, failure due to one or more     */
	  /* vanishing scaled layer dimensions. Implicit delete implemented     */
	  /* here. Upstream warning implemented in resize_check_layer_scaling() */
          /* [resize.c line 1295], which offers the user the chance to bail out.*/

602
          remove = g_slist_append (remove, layer);
603
604
605
606
607
        }
    }
  /* We defer removing layers lost to scaling until now            */
  /* so as not to mix the operations of iterating over and removal */
  /* from gimage->layers.                                          */  
608

609
  for (list = remove; list; list = g_slist_next (list))
610
    {
611
      layer = list->data;
612
      gimage_remove_layer (gimage, layer);
613
    }
614
  g_slist_free (remove);
615

616
  /*  Scale any Guides  */
617
  for (glist = gimage->guides; glist; glist = g_list_next (glist))
618
619
620
621
622
    {
      guide = (Guide*) glist->data;

      switch (guide->orientation)
	{
623
	case ORIENTATION_HORIZONTAL:
Sven Neumann's avatar
Sven Neumann committed
624
	  undo_push_guide (gimage, guide);
625
626
	  guide->position = (guide->position * new_height) / old_height;
	  break;
627
	case ORIENTATION_VERTICAL:
Sven Neumann's avatar
Sven Neumann committed
628
	  undo_push_guide (gimage, guide);
629
630
631
632
633
634
	  guide->position = (guide->position * new_width) / old_width;
	  break;
	default:
	  g_error("Unknown guide orientation II.\n");
	}
    }
635

636
637
638
639
640
641
642
643
  /*  Make sure the projection matches the gimage size  */
  gimp_image_projection_realloc (gimage);

  /*  Rigor the floating selection  */
  if (floating_layer)
    floating_sel_rigor (floating_layer, TRUE);

  gtk_signal_emit (GTK_OBJECT (gimage), gimp_image_signals[RESIZE]);
644

645
  gimp_remove_busy_cursors (NULL);
646
647
648
}

TileManager *
649
gimp_image_shadow (GimpImage *gimage, 
650
651
652
		   gint       width, 
		   gint       height, 
		   gint       bpp)
653
654
{
  if (gimage->shadow &&
655
656
657
      ((width != tile_manager_level_width (gimage->shadow)) ||
       (height != tile_manager_level_height (gimage->shadow)) ||
       (bpp != tile_manager_level_bpp (gimage->shadow))))
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
    gimp_image_free_shadow (gimage);
  else if (gimage->shadow)
    return gimage->shadow;

  gimp_image_allocate_shadow (gimage, width, height, bpp);

  return gimage->shadow;
}

void
gimp_image_free_shadow (GimpImage *gimage)
{
  /*  Free the shadow buffer from the specified gimage if it exists  */
  if (gimage->shadow)
    tile_manager_destroy (gimage->shadow);

  gimage->shadow = NULL;
}

static void
gimp_image_destroy (GtkObject *object)
{
680
  GimpImage* gimage = GIMP_IMAGE (object);
Sven Neumann's avatar
Sven Neumann committed
681
682
683
684
685
686
687
688
689
690
691
692
693

  gimp_image_free_projection (gimage);
  gimp_image_free_shadow (gimage);
  
  if (gimage->cmap)
    g_free (gimage->cmap);
  
  if (gimage->has_filename)
    g_free (gimage->filename);
  
  gimp_image_free_layers (gimage);
  gimp_image_free_channels (gimage);
  channel_delete (gimage->selection_mask);
694

BST 1999 Andy Thomas's avatar
BST 1999 Andy Thomas committed
695
696
697
  if (gimage->comp_preview)
    temp_buf_free (gimage->comp_preview);

Sven Neumann's avatar
Sven Neumann committed
698
  if (gimage->parasites)
699
    gtk_object_unref (GTK_OBJECT (gimage->parasites));
700
701
702
}

void
703
704
705
706
707
708
gimp_image_apply_image (GimpImage	 *gimage,
			GimpDrawable	 *drawable,
			PixelRegion	 *src2PR,
			gint              undo,
			gint              opacity,
			LayerModeEffects  mode,
709
			/*  alternative to using drawable tiles as src1: */
710
711
712
			TileManager	 *src1_tiles,
			gint              x,
			gint              y)
713
{
714
715
716
717
718
719
  Channel     *mask;
  gint         x1, y1, x2, y2;
  gint         offset_x, offset_y;
  PixelRegion  src1PR, destPR, maskPR;
  gint         operation;
  gint         active [MAX_CHANNELS];
720
721

  /*  get the selection mask if one exists  */
722
  mask = (gimage_mask_is_empty (gimage)) ? NULL : gimp_image_get_mask (gimage);
723
724
725
726
727
728
729
730
731
732

  /*  configure the active channel array  */
  gimp_image_get_active_channels (gimage, drawable, active);

  /*  determine what sort of operation is being attempted and
   *  if it's actually legal...
   */
  operation = valid_combinations [drawable_type (drawable)][src2PR->bytes];
  if (operation == -1)
    {
Sven Neumann's avatar
Sven Neumann committed
733
      g_message ("gimp_image_apply_image sent illegal parameters");
734
735
736
737
738
739
740
      return;
    }

  /*  get the layer offsets  */
  drawable_offsets (drawable, &offset_x, &offset_y);

  /*  make sure the image application coordinates are within gimage bounds  */
741
  x1 = CLAMP (x, 0, drawable_width  (drawable));
742
  y1 = CLAMP (y, 0, drawable_height (drawable));
743
  x2 = CLAMP (x + src2PR->w, 0, drawable_width  (drawable));
744
745
746
747
748
749
750
751
  y2 = CLAMP (y + src2PR->h, 0, drawable_height (drawable));

  if (mask)
    {
      /*  make sure coordinates are in mask bounds ...
       *  we need to add the layer offset to transform coords
       *  into the mask coordinate system
       */
752
753
754
755
      x1 = CLAMP (x1, -offset_x, drawable_width (GIMP_DRAWABLE(mask))-offset_x);
      y1 = CLAMP (y1, -offset_y, drawable_height(GIMP_DRAWABLE(mask))-offset_y);
      x2 = CLAMP (x2, -offset_x, drawable_width (GIMP_DRAWABLE(mask))-offset_x);
      y2 = CLAMP (y2, -offset_y, drawable_height(GIMP_DRAWABLE(mask))-offset_y);
756
757
758
759
    }

  /*  If the calling procedure specified an undo step...  */
  if (undo)
760
    undo_push_image (gimp_drawable_gimage (drawable), drawable, x1, y1, x2, y2);
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782

  /* configure the pixel regions
   *  If an alternative to using the drawable's data as src1 was provided...
   */
  if (src1_tiles)
    pixel_region_init (&src1PR, src1_tiles, x1, y1, (x2 - x1), (y2 - y1), FALSE);
  else
    pixel_region_init (&src1PR, drawable_data (drawable), x1, y1, (x2 - x1), (y2 - y1), FALSE);
  pixel_region_init (&destPR, drawable_data (drawable), x1, y1, (x2 - x1), (y2 - y1), TRUE);
  pixel_region_resize (src2PR, src2PR->x + (x1 - x), src2PR->y + (y1 - y), (x2 - x1), (y2 - y1));

  if (mask)
    {
      int mx, my;

      /*  configure the mask pixel region
       *  don't use x1 and y1 because they are in layer
       *  coordinate system.  Need mask coordinate system
       */
      mx = x1 + offset_x;
      my = y1 + offset_y;

783
784
785
786
787
      pixel_region_init (&maskPR, 
			 drawable_data (GIMP_DRAWABLE(mask)), 
			 mx, my, 
			 (x2 - x1), (y2 - y1), 
			 FALSE);
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
      combine_regions (&src1PR, src2PR, &destPR, &maskPR, NULL,
		       opacity, mode, active, operation);
    }
  else
    combine_regions (&src1PR, src2PR, &destPR, NULL, NULL,
		     opacity, mode, active, operation);
}

/* Similar to gimp_image_apply_image but works in "replace" mode (i.e.
   transparent pixels in src2 make the result transparent rather
   than opaque.

   Takes an additional mask pixel region as well.
*/
void
803
804
805
gimp_image_replace_image (GimpImage    *gimage, 
			  GimpDrawable *drawable, 
			  PixelRegion  *src2PR,
806
807
			  gint          undo, 
			  gint          opacity,
808
			  PixelRegion  *maskPR,
809
810
			  gint          x, 
			  gint          y)
811
{
812
813
814
815
816
817
818
819
  Channel     *mask;
  gint         x1, y1, x2, y2;
  gint         offset_x, offset_y;
  PixelRegion  src1PR, destPR;
  PixelRegion  mask2PR, tempPR;
  guchar      *temp_data;
  gint         operation;
  gint         active [MAX_CHANNELS];
820
821

  /*  get the selection mask if one exists  */
822
  mask = (gimage_mask_is_empty (gimage)) ? NULL : gimp_image_get_mask (gimage);
823
824
825
826
827
828
829
830
831
832

  /*  configure the active channel array  */
  gimp_image_get_active_channels (gimage, drawable, active);

  /*  determine what sort of operation is being attempted and
   *  if it's actually legal...
   */
  operation = valid_combinations [drawable_type (drawable)][src2PR->bytes];
  if (operation == -1)
    {
Sven Neumann's avatar
Sven Neumann committed
833
      g_message ("gimp_image_apply_image sent illegal parameters");
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
      return;
    }

  /*  get the layer offsets  */
  drawable_offsets (drawable, &offset_x, &offset_y);

  /*  make sure the image application coordinates are within gimage bounds  */
  x1 = CLAMP (x, 0, drawable_width (drawable));
  y1 = CLAMP (y, 0, drawable_height (drawable));
  x2 = CLAMP (x + src2PR->w, 0, drawable_width (drawable));
  y2 = CLAMP (y + src2PR->h, 0, drawable_height (drawable));

  if (mask)
    {
      /*  make sure coordinates are in mask bounds ...
       *  we need to add the layer offset to transform coords
       *  into the mask coordinate system
       */
852
853
854
855
      x1 = CLAMP (x1, -offset_x, drawable_width (GIMP_DRAWABLE(mask))-offset_x);
      y1 = CLAMP (y1, -offset_y, drawable_height(GIMP_DRAWABLE(mask))-offset_y);
      x2 = CLAMP (x2, -offset_x, drawable_width (GIMP_DRAWABLE(mask))-offset_x);
      y2 = CLAMP (y2, -offset_y, drawable_height(GIMP_DRAWABLE(mask))-offset_y);
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
    }

  /*  If the calling procedure specified an undo step...  */
  if (undo)
    drawable_apply_image (drawable, x1, y1, x2, y2, NULL, FALSE);

  /* configure the pixel regions
   *  If an alternative to using the drawable's data as src1 was provided...
   */
  pixel_region_init (&src1PR, drawable_data (drawable), x1, y1, (x2 - x1), (y2 - y1), FALSE);
  pixel_region_init (&destPR, drawable_data (drawable), x1, y1, (x2 - x1), (y2 - y1), TRUE);
  pixel_region_resize (src2PR, src2PR->x + (x1 - x), src2PR->y + (y1 - y), (x2 - x1), (y2 - y1));

  if (mask)
    {
      int mx, my;

      /*  configure the mask pixel region
       *  don't use x1 and y1 because they are in layer
       *  coordinate system.  Need mask coordinate system
       */
      mx = x1 + offset_x;
      my = y1 + offset_y;

880
881
882
883
884
      pixel_region_init (&mask2PR, 
			 drawable_data (GIMP_DRAWABLE(mask)), 
			 mx, my, 
			 (x2 - x1), (y2 - y1), 
			 FALSE);
885
886
887
888
889
890

      tempPR.bytes = 1;
      tempPR.x = 0;
      tempPR.y = 0;
      tempPR.w = x2 - x1;
      tempPR.h = y2 - y1;
891
      tempPR.rowstride = tempPR.w * tempPR.bytes;
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
      temp_data = g_malloc (tempPR.h * tempPR.rowstride);
      tempPR.data = temp_data;

      copy_region (&mask2PR, &tempPR);

      /* apparently, region operations can mutate some PR data. */
      tempPR.x = 0;
      tempPR.y = 0;
      tempPR.w = x2 - x1;
      tempPR.h = y2 - y1;
      tempPR.data = temp_data;

      apply_mask_to_region (&tempPR, maskPR, OPAQUE_OPACITY);

      tempPR.x = 0;
      tempPR.y = 0;
      tempPR.w = x2 - x1;
      tempPR.h = y2 - y1;
      tempPR.data = temp_data;

      combine_regions_replace (&src1PR, src2PR, &destPR, &tempPR, NULL,
		       opacity, active, operation);

      g_free (temp_data);
    }
  else
    combine_regions_replace (&src1PR, src2PR, &destPR, maskPR, NULL,
		     opacity, active, operation);
}

/* Get rid of these! A "foreground" is an UI concept.. */

void
925
926
927
gimp_image_get_foreground (GimpImage    *gimage, 
			   GimpDrawable *drawable, 
			   guchar       *fg)
928
{
929
  guchar pfg[3];
930
931

  /*  Get the palette color  */
932
  gimp_context_get_foreground (NULL, &pfg[0], &pfg[1], &pfg[2]);
933
934
935
936
937

  gimp_image_transform_color (gimage, drawable, pfg, fg, RGB);
}

void
938
939
940
gimp_image_get_background (GimpImage    *gimage, 
			   GimpDrawable *drawable, 
			   guchar       *bg)
941
{
942
  guchar pbg[3];
943
944

  /*  Get the palette color  */
945
  gimp_context_get_background (NULL, &pbg[0], &pbg[1], &pbg[2]);
946
947
948
949

  gimp_image_transform_color (gimage, drawable, pbg, bg, RGB);
}

950
guchar *
951
gimp_image_get_color_at (GimpImage *gimage, 
952
953
			 gint       x, 
			 gint       y)
954
{
955
  Tile   *tile;
956
957
  guchar *src;
  guchar *dest;
958

959
960
  g_return_val_if_fail (GIMP_IS_IMAGE (gimage), NULL);

961
  if (x < 0 || y < 0 || x >= gimage->width || y >= gimage->height)
962
963
964
965
    {
      return NULL;
    }
  dest = g_new (unsigned char, 5);
966
967
968
969
  tile = tile_manager_get_tile (gimp_image_composite (gimage), x, y,
				TRUE, FALSE);
  src = tile_data_pointer (tile, x % TILE_WIDTH, y % TILE_HEIGHT);
  gimp_image_get_color (gimage, gimp_image_composite_type (gimage), dest, src);
970
971

  if (TYPE_HAS_ALPHA (gimp_image_composite_type (gimage)))
972
973
974
    dest[3] = src[gimp_image_composite_bytes (gimage) - 1];
  else
    dest[3] = 255;
975

976
977
  dest[4] = 0;
  tile_release (tile, FALSE);
978

979
980
981
  return dest;
}

982
void
983
gimp_image_get_color (GimpImage     *gimage, 
984
		      GimpImageType  d_type,
985
986
		      guchar        *rgb, 
		      guchar        *src)
987
{
988
989
  g_return_if_fail (GIMP_IS_IMAGE (gimage));

990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
  switch (d_type)
    {
    case RGB_GIMAGE: case RGBA_GIMAGE:
      map_to_color (0, NULL, src, rgb);
      break;
    case GRAY_GIMAGE: case GRAYA_GIMAGE:
      map_to_color (1, NULL, src, rgb);
      break;
    case INDEXED_GIMAGE: case INDEXEDA_GIMAGE:
      map_to_color (2, gimage->cmap, src, rgb);
      break;
    }
}

void
1005
1006
1007
1008
1009
gimp_image_transform_color (GimpImage         *gimage, 
			    GimpDrawable      *drawable,
			    guchar            *src, 
			    guchar            *dest, 
			    GimpImageBaseType  type)
1010
{
1011
  GimpImageType d_type;
1012

1013
1014
  g_return_if_fail (GIMP_IS_IMAGE (gimage));

1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
  d_type = (drawable != NULL) ? drawable_type (drawable) :
    gimp_image_base_type_with_alpha (gimage);

  switch (type)
    {
    case RGB:
      switch (d_type)
	{
	case RGB_GIMAGE: case RGBA_GIMAGE:
	  /*  Straight copy  */
	  *dest++ = *src++;
	  *dest++ = *src++;
	  *dest++ = *src++;
	  break;
	case GRAY_GIMAGE: case GRAYA_GIMAGE:
	  /*  NTSC conversion  */
	  *dest = INTENSITY (src[RED_PIX],
			     src[GREEN_PIX],
			     src[BLUE_PIX]);
	  break;
	case INDEXED_GIMAGE: case INDEXEDA_GIMAGE:
	  /*  Least squares method  */
	  *dest = map_rgb_to_indexed (gimage->cmap,
				      gimage->num_cols,
1039
				      gimage,
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
				      src[RED_PIX],
				      src[GREEN_PIX],
				      src[BLUE_PIX]);
	  break;
	}
      break;
    case GRAY:
      switch (d_type)
	{
	case RGB_GIMAGE: case RGBA_GIMAGE:
	  /*  Gray to RG&B */
	  *dest++ = *src;
	  *dest++ = *src;
	  *dest++ = *src;
	  break;
	case GRAY_GIMAGE: case GRAYA_GIMAGE:
	  /*  Straight copy  */
	  *dest = *src;
	  break;
	case INDEXED_GIMAGE: case INDEXEDA_GIMAGE:
	  /*  Least squares method  */
	  *dest = map_rgb_to_indexed (gimage->cmap,
				      gimage->num_cols,
1063
				      gimage,
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
				      src[GRAY_PIX],
				      src[GRAY_PIX],
				      src[GRAY_PIX]);
	  break;
	}
      break;
    default:
      break;
    }
}

Guide*
gimp_image_add_hguide (GimpImage *gimage)
{
  Guide *guide;

1080
1081
  g_return_val_if_fail (GIMP_IS_IMAGE (gimage), NULL);

1082
  guide = g_new (Guide, 1);
1083
1084
1085
  guide->ref_count   = 0;
  guide->position    = -1;
  guide->guide_ID    = next_guide_id++;
1086
  guide->orientation = ORIENTATION_HORIZONTAL;
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097

  gimage->guides = g_list_prepend (gimage->guides, guide);

  return guide;
}

Guide*
gimp_image_add_vguide (GimpImage *gimage)
{
  Guide *guide;

1098
1099
  g_return_val_if_fail (GIMP_IS_IMAGE (gimage), NULL);

1100
  guide = g_new (Guide, 1);
1101
1102
1103
  guide->ref_count   = 0;
  guide->position    = -1;
  guide->guide_ID    = next_guide_id++;
1104
  guide->orientation = ORIENTATION_VERTICAL;
1105
1106
1107
1108
1109
1110
1111
1112

  gimage->guides = g_list_prepend (gimage->guides, guide);

  return guide;
}

void
gimp_image_add_guide (GimpImage *gimage,
1113
		      Guide     *guide)
1114
{
1115
1116
  g_return_if_fail (GIMP_IS_IMAGE (gimage));

1117
1118
1119
1120
1121
  gimage->guides = g_list_prepend (gimage->guides, guide);
}

void
gimp_image_remove_guide (GimpImage *gimage,
1122
			 Guide     *guide)
1123
{
1124
1125
  g_return_if_fail (GIMP_IS_IMAGE (gimage));

1126
1127
1128
1129
1130
  gimage->guides = g_list_remove (gimage->guides, guide);
}

void
gimp_image_delete_guide (GimpImage *gimage,
1131
			 Guide     *guide) 
1132
{
Sven Neumann's avatar
Sven Neumann committed
1133
1134
  guide->position = -1;

1135
1136
  g_return_if_fail (GIMP_IS_IMAGE (gimage));

Sven Neumann's avatar
Sven Neumann committed
1137
1138
1139
1140
1141
  if (guide->ref_count <= 0)
    {
      gimage->guides = g_list_remove (gimage->guides, guide);
      g_free (guide);
    }
1142
1143
}

Sven Neumann's avatar
Sven Neumann committed
1144

1145
GimpParasite *
Marc Lehmann's avatar
Marc Lehmann committed
1146
gimp_image_parasite_find (const GimpImage *gimage, 
1147
			  const gchar     *name)
1148
{
1149
1150
  g_return_val_if_fail (GIMP_IS_IMAGE (gimage), NULL);

1151
  return parasite_list_find (gimage->parasites, name);
1152
1153
}

1154
static void
1155
1156
1157
list_func (gchar          *key, 
	   GimpParasite   *p, 
	   gchar        ***cur)
Marc Lehmann's avatar
Marc Lehmann committed
1158
{
1159
  *(*cur)++ = (gchar *) g_strdup (key);
Marc Lehmann's avatar
Marc Lehmann committed
1160
1161
}

1162
gchar **
1163
gimp_image_parasite_list (GimpImage *gimage, 
1164
			  gint      *count)
Marc Lehmann's avatar
Marc Lehmann committed
1165
{
1166
1167
  gchar **list;
  gchar **cur;
Marc Lehmann's avatar
Marc Lehmann committed
1168

1169
1170
1171
  g_return_val_if_fail (GIMP_IS_IMAGE (gimage), NULL);

  *count = parasite_list_length (gimage->parasites);
1172
  cur = list = g_new (gchar*, *count);
Marc Lehmann's avatar
Marc Lehmann committed
1173

1174
  parasite_list_foreach (gimage->parasites, (GHFunc) list_func, &cur);
Marc Lehmann's avatar
Marc Lehmann committed
1175
1176
1177
1178
  
  return list;
}

1179
void
1180
1181
gimp_image_parasite_attach (GimpImage    *gimage, 
			    GimpParasite *parasite)
1182
{
1183
  g_return_if_fail (GIMP_IS_IMAGE (gimage) && parasite != NULL);
1184

jaycox's avatar
jaycox committed
1185
  /* only set the dirty bit manually if we can be saved and the new
Sven Neumann's avatar
Sven Neumann committed
1186
     parasite differs from the current one and we aren't undoable */
1187
  if (gimp_parasite_is_undoable (parasite))
jaycox's avatar
jaycox committed
1188
    undo_push_image_parasite (gimage, parasite);
1189
1190
1191
1192
1193
1194

  /*  We used to push an cantundo on te stack here. This made the undo stack
      unusable (NULL on the stack) and prevented people from undoing after a 
      save (since most save plug-ins attach an undoable comment parasite).
      Now we simply attach the parasite without pushing an undo. That way it's
      undoable but does not block the undo system.   --Sven
1195
   */
1196
1197
1198

  parasite_list_add (gimage->parasites, parasite);

1199
  if (gimp_parasite_has_flag (parasite, GIMP_PARASITE_ATTACH_PARENT))
1200
1201
    {
      parasite_shift_parent (parasite);
Marc Lehmann's avatar
Marc Lehmann committed
1202
      gimp_parasite_attach (parasite);
1203
    }
1204
1205
1206
}

void
Marc Lehmann's avatar
Marc Lehmann committed
1207
gimp_image_parasite_detach (GimpImage   *gimage, 
1208
			    const gchar *parasite)
1209
{