diff --git a/app/core/gimpimage-colormap.c b/app/core/gimpimage-colormap.c index 06873e719e..ee66d0d885 100644 --- a/app/core/gimpimage-colormap.c +++ b/app/core/gimpimage-colormap.c @@ -25,14 +25,98 @@ #include "core-types.h" +#include "gimp.h" +#include "gimpcontainer.h" +#include "gimpdatafactory.h" #include "gimpimage.h" #include "gimpimage-colormap.h" #include "gimpimage-private.h" #include "gimpimage-undo-push.h" +#include "gimppalette.h" #include "gimp-intl.h" +/* local function prototype */ + +void gimp_image_colormap_set_palette_entry (GimpImage *image, + gint index); + + +/* public functions */ + +void +gimp_image_colormap_init (GimpImage *image) +{ + GimpImagePrivate *private; + GimpContainer *palettes; + gchar *palette_name; + gchar *palette_id; + + g_return_if_fail (GIMP_IS_IMAGE (image)); + + private = GIMP_IMAGE_GET_PRIVATE (image); + + g_return_if_fail (private->colormap == NULL); + g_return_if_fail (private->palette == NULL); + + palette_name = g_strdup_printf (_("Colormap of Image #%d (%s)"), + gimp_image_get_ID (image), + gimp_image_get_display_name (image)); + palette_id = g_strdup_printf ("gimp-indexed-image-palette-%d", + gimp_image_get_ID (image)); + + private->n_colors = 0; + private->colormap = g_new0 (guchar, GIMP_IMAGE_COLORMAP_SIZE); + private->palette = GIMP_PALETTE (gimp_palette_new (NULL, palette_name)); + + gimp_data_make_internal (GIMP_DATA (private->palette), palette_id); + + palettes = gimp_data_factory_get_container (image->gimp->palette_factory); + + gimp_container_add (palettes, GIMP_OBJECT (private->palette)); + + g_free (palette_name); + g_free (palette_id); +} + +void +gimp_image_colormap_dispose (GimpImage *image) +{ + GimpImagePrivate *private; + GimpContainer *palettes; + + g_return_if_fail (GIMP_IS_IMAGE (image)); + + private = GIMP_IMAGE_GET_PRIVATE (image); + + g_return_if_fail (private->colormap != NULL); + g_return_if_fail (GIMP_IS_PALETTE (private->palette)); + + palettes = gimp_data_factory_get_container (image->gimp->palette_factory); + + gimp_container_remove (palettes, GIMP_OBJECT (private->palette)); +} + +void +gimp_image_colormap_free (GimpImage *image) +{ + GimpImagePrivate *private; + + g_return_if_fail (GIMP_IS_IMAGE (image)); + + private = GIMP_IMAGE_GET_PRIVATE (image); + + g_return_if_fail (private->colormap != NULL); + g_return_if_fail (GIMP_IS_PALETTE (private->palette)); + + g_free (private->colormap); + private->colormap = NULL; + + g_object_unref (private->palette); + private->palette = NULL; +} + const guchar * gimp_image_get_colormap (const GimpImage *image) { @@ -72,21 +156,37 @@ gimp_image_set_colormap (GimpImage *image, if (colormap) { if (! private->colormap) - private->colormap = g_new0 (guchar, GIMP_IMAGE_COLORMAP_SIZE); + { + gimp_image_colormap_init (image); + } memcpy (private->colormap, colormap, n_colors * 3); } - else if (! gimp_image_base_type (image) == GIMP_INDEXED) + else if (private->colormap) { - if (private->colormap) - g_free (private->colormap); - - private->colormap = NULL; + gimp_image_colormap_dispose (image); + gimp_image_colormap_free (image); } private->n_colors = n_colors; gimp_image_colormap_changed (image, -1); + + if (private->palette) + { + GimpPaletteEntry *entry; + gint i; + + gimp_data_freeze (GIMP_DATA (private->palette)); + + while ((entry = gimp_palette_get_entry (private->palette, 0))) + gimp_palette_delete_entry (private->palette, entry); + + for (i = 0; i < private->n_colors; i++) + gimp_image_colormap_set_palette_entry (image, i); + + gimp_data_thaw (GIMP_DATA (private->palette)); + } } void @@ -165,3 +265,28 @@ gimp_image_add_colormap_entry (GimpImage *image, gimp_image_colormap_changed (image, -1); } + + +/* private functions */ + +void +gimp_image_colormap_set_palette_entry (GimpImage *image, + gint index) +{ + GimpImagePrivate *private = GIMP_IMAGE_GET_PRIVATE (image); + GimpRGB color; + gchar name[64]; + + gimp_rgba_set_uchar (&color, + private->colormap[3 * index + 0], + private->colormap[3 * index + 1], + private->colormap[3 * index + 2], + 255); + + g_snprintf (name, sizeof (name), "#%d", index); + + if (gimp_palette_get_n_colors (private->palette) < private->n_colors) + gimp_palette_add_entry (private->palette, index, name, &color); + else + gimp_palette_set_entry (private->palette, index, name, &color); +} diff --git a/app/core/gimpimage-colormap.h b/app/core/gimpimage-colormap.h index 0837769051..03fb04887e 100644 --- a/app/core/gimpimage-colormap.h +++ b/app/core/gimpimage-colormap.h @@ -22,6 +22,10 @@ #define GIMP_IMAGE_COLORMAP_SIZE 768 +void gimp_image_colormap_init (GimpImage *image); +void gimp_image_colormap_dispose (GimpImage *image); +void gimp_image_colormap_free (GimpImage *image); + const guchar * gimp_image_get_colormap (const GimpImage *image); gint gimp_image_get_colormap_size (const GimpImage *image); void gimp_image_set_colormap (GimpImage *image, diff --git a/app/core/gimpimage-private.h b/app/core/gimpimage-private.h index 92e5aed34e..b966ba05a1 100644 --- a/app/core/gimpimage-private.h +++ b/app/core/gimpimage-private.h @@ -49,6 +49,7 @@ struct _GimpImagePrivate guchar *colormap; /* colormap (for indexed) */ gint n_colors; /* # of colors (for indexed) */ + GimpPalette *palette; /* palette of colormap */ gint dirty; /* dirty flag -- # of ops */ guint dirty_time; /* time when image became dirty */ diff --git a/app/core/gimpimage.c b/app/core/gimpimage.c index cdc343d75b..b9cb133a30 100644 --- a/app/core/gimpimage.c +++ b/app/core/gimpimage.c @@ -633,6 +633,7 @@ gimp_image_init (GimpImage *image) private->colormap = NULL; private->n_colors = 0; + private->palette = NULL; private->dirty = 1; private->dirty_time = 0; @@ -768,19 +769,8 @@ gimp_image_constructor (GType type, private->grid = gimp_config_duplicate (GIMP_CONFIG (config->default_grid)); - switch (private->base_type) - { - case GIMP_RGB: - case GIMP_GRAY: - break; - case GIMP_INDEXED: - /* always allocate 256 colors for the colormap */ - private->n_colors = 0; - private->colormap = g_new0 (guchar, GIMP_IMAGE_COLORMAP_SIZE); - break; - default: - break; - } + if (private->base_type == GIMP_INDEXED) + gimp_image_colormap_init (image); /* create the selection mask */ private->selection_mask = gimp_selection_new (image, @@ -877,6 +867,9 @@ gimp_image_dispose (GObject *object) GimpImage *image = GIMP_IMAGE (object); GimpImagePrivate *private = GIMP_IMAGE_GET_PRIVATE (image); + if (private->colormap) + gimp_image_colormap_dispose (image); + gimp_image_undo_free (image); g_signal_handlers_disconnect_by_func (private->layers->container, @@ -931,10 +924,7 @@ gimp_image_finalize (GObject *object) } if (private->colormap) - { - g_free (private->colormap); - private->colormap = NULL; - } + gimp_image_colormap_free (image); if (private->layers) { @@ -1059,6 +1049,9 @@ gimp_image_get_memsize (GimpObject *object, if (gimp_image_get_colormap (image)) memsize += GIMP_IMAGE_COLORMAP_SIZE; + memsize += gimp_object_get_memsize (GIMP_OBJECT (private->palette), + gui_size); + memsize += gimp_object_get_memsize (GIMP_OBJECT (private->projection), gui_size);