app: keep a GimpPalette around that proxies the image's indexed colormap

and add it to the palette factory as internal object. Work in progress
on the way to getting rid of the ugly code in the colormap editor.
This commit is contained in:
Michael Natterer 2010-10-27 15:40:43 +02:00
parent d1307a84a4
commit a27b6f5f47
4 changed files with 146 additions and 23 deletions

View File

@ -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);
}

View File

@ -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,

View File

@ -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 */

View File

@ -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);