Make sure that non-indexed images never have a colormap. Fixes bug

2004-02-12  Michael Natterer  <mitch@gimp.org>

	Make sure that non-indexed images never have a colormap.
	Fixes bug #121033.

	* app/core/gimpimage-colormap.c (gimp_image_set_colormap): set
	image->cmap to NULL when called with a NULL colormap.

	* app/core/gimpimage-undo-push.c: made colormap undo/redo aware
	of NULL colormaps.

	* app/core/gimpimage-convert.c (gimp_image_convert): remove the
	colormap using gimp_image_set_colormap() instead of freeing it
	manually.

	* app/widgets/gimpcolormapeditor.c: always check if the image
	is INDEXED *and* has a colormap before accessing the colormap.

	(need this new check because the fixed behaviour of colormap undo
	produces undo groups which, when being popped, make the image have
	no colormap while still being INDEXED in the small time frame
	between the emission of "colormap_changed" and "mode_changed").
This commit is contained in:
Michael Natterer 2004-02-12 12:13:21 +00:00 committed by Michael Natterer
parent ecdf62b5ce
commit 8312e82ad8
5 changed files with 79 additions and 49 deletions

View File

@ -1,3 +1,26 @@
2004-02-12 Michael Natterer <mitch@gimp.org>
Make sure that non-indexed images never have a colormap.
Fixes bug #121033.
* app/core/gimpimage-colormap.c (gimp_image_set_colormap): set
image->cmap to NULL when called with a NULL colormap.
* app/core/gimpimage-undo-push.c: made colormap undo/redo aware
of NULL colormaps.
* app/core/gimpimage-convert.c (gimp_image_convert): remove the
colormap using gimp_image_set_colormap() instead of freeing it
manually.
* app/widgets/gimpcolormapeditor.c: always check if the image
is INDEXED *and* has a colormap before accessing the colormap.
(need this new check because the fixed behaviour of colormap undo
produces undo groups which, when being popped, make the image have
no colormap while still being INDEXED in the small time frame
between the emission of "colormap_changed" and "mode_changed").
2004-02-12 Sven Neumann <sven@gimp.org>
* app/tools/gimptexttool.[ch]: derive the text tool from GimpTool

View File

@ -56,17 +56,26 @@ gimp_image_set_colormap (GimpImage *gimage,
gboolean push_undo)
{
g_return_if_fail (GIMP_IS_IMAGE (gimage));
g_return_if_fail (n_colors == 0 || cmap != 0);
g_return_if_fail (cmap != NULL || n_colors == 0);
g_return_if_fail (n_colors >= 0 && n_colors <= 256);
if (! gimage->cmap)
gimage->cmap = g_new0 (guchar, GIMP_IMAGE_COLORMAP_SIZE);
if (push_undo)
gimp_image_undo_push_image_colormap (gimage, _("Set Indexed Palette"));
if (n_colors)
memcpy (gimage->cmap, cmap, n_colors * 3);
if (cmap)
{
if (! gimage->cmap)
gimage->cmap = g_new0 (guchar, GIMP_IMAGE_COLORMAP_SIZE);
memcpy (gimage->cmap, cmap, n_colors * 3);
}
else
{
if (gimage->cmap)
g_free (gimage->cmap);
gimage->cmap = NULL;
}
gimage->num_cols = n_colors;

View File

@ -796,10 +796,6 @@ gimp_image_convert (GimpImage *gimage,
old_type = gimage->base_type;
gimage->base_type = new_type;
/* If the image was INDEXED, push its colormap to the undo stack */
if (old_type == GIMP_INDEXED)
gimp_image_undo_push_image_colormap (gimage, NULL);
/* initialize the colour conversion routines */
cpercep_init_conversions ();
@ -956,26 +952,21 @@ gimp_image_convert (GimpImage *gimage,
GIMP_DRAWABLE (layer)->has_alpha = GIMP_IMAGE_TYPE_HAS_ALPHA (new_layer_type);
}
/* colourmap stuff */
if (gimage->cmap)
{
g_free (gimage->cmap);
gimage->cmap = NULL;
}
switch (new_type)
{
case GIMP_RGB:
case GIMP_GRAY:
gimage->num_cols = 0;
if (old_type == GIMP_INDEXED)
gimp_image_set_colormap (gimage, NULL, 0, TRUE);
break;
case GIMP_INDEXED:
gimp_image_undo_push_image_colormap (gimage, NULL);
gimage->cmap = g_new0 (guchar, GIMP_IMAGE_COLORMAP_SIZE);
if (remove_dups &&
((palette_type == GIMP_WEB_PALETTE) ||
(palette_type == GIMP_CUSTOM_PALETTE)))
if (remove_dups && ((palette_type == GIMP_WEB_PALETTE) ||
(palette_type == GIMP_CUSTOM_PALETTE)))
{
gint i, j;
guchar old_palette [256 * 3];

View File

@ -814,8 +814,8 @@ typedef struct _ColormapUndo ColormapUndo;
struct _ColormapUndo
{
guchar cmap[GIMP_IMAGE_COLORMAP_SIZE];
gint num_colors;
gint num_colors;
guchar *cmap;
};
static gboolean undo_pop_image_colormap (GimpUndo *undo,
@ -831,7 +831,6 @@ gimp_image_undo_push_image_colormap (GimpImage *gimage,
GimpUndo *new;
g_return_val_if_fail (GIMP_IS_IMAGE (gimage), FALSE);
g_return_val_if_fail (gimp_image_get_colormap (gimage) != NULL, FALSE);
if ((new = gimp_image_undo_push (gimage,
sizeof (ColormapUndo),
@ -841,12 +840,11 @@ gimp_image_undo_push_image_colormap (GimpImage *gimage,
undo_pop_image_colormap,
undo_free_image_colormap)))
{
ColormapUndo *cu;
cu = new->data;
ColormapUndo *cu = new->data;
cu->num_colors = gimp_image_get_colormap_size (gimage);
memcpy (cu->cmap, gimp_image_get_colormap (gimage), cu->num_colors * 3);
cu->cmap = g_memdup (gimp_image_get_colormap (gimage),
cu->num_colors * 3);
return TRUE;
}
@ -859,19 +857,21 @@ undo_pop_image_colormap (GimpUndo *undo,
GimpUndoMode undo_mode,
GimpUndoAccumulator *accum)
{
ColormapUndo *cu;
guchar cmap[GIMP_IMAGE_COLORMAP_SIZE];
ColormapUndo *cu = undo->data;
guchar *cmap;
gint num_colors;
cu = (ColormapUndo *) undo->data;
num_colors = gimp_image_get_colormap_size (undo->gimage);
memcpy (cmap, gimp_image_get_colormap (undo->gimage), num_colors * 3);
cmap = g_memdup (gimp_image_get_colormap (undo->gimage),
num_colors * 3);
gimp_image_set_colormap (undo->gimage, cu->cmap, cu->num_colors, FALSE);
memcpy (cu->cmap, cmap, sizeof (cmap));
if (cu->cmap)
g_free (cu->cmap);
cu->num_colors = num_colors;
cu->cmap = cmap;
return TRUE;
}
@ -880,7 +880,12 @@ static void
undo_free_image_colormap (GimpUndo *undo,
GimpUndoMode undo_mode)
{
g_free (undo->data);
ColormapUndo *cu = undo->data;
if (cu->cmap)
g_free (cu->cmap);
g_free (cu);
}

View File

@ -79,6 +79,12 @@ enum
};
#define HAVE_COLORMAP(gimage) \
(gimage != NULL && \
gimp_image_base_type (gimage) == GIMP_INDEXED && \
gimp_image_get_colormap (gimage) != NULL)
static void gimp_colormap_editor_class_init (GimpColormapEditorClass *klass);
static void gimp_colormap_editor_init (GimpColormapEditor *colormap_editor);
@ -278,7 +284,7 @@ gimp_colormap_editor_set_image (GimpImageEditor *image_editor,
if (editor->color_notebook)
color_notebook_hide (editor->color_notebook);
if (! gimage || (gimp_image_base_type (gimage) != GIMP_INDEXED))
if (! HAVE_COLORMAP (gimage))
{
editor->index_adjustment->upper = 0;
gtk_adjustment_changed (editor->index_adjustment);
@ -302,7 +308,7 @@ gimp_colormap_editor_set_image (GimpImageEditor *image_editor,
G_CALLBACK (gimp_colormap_image_colormap_changed),
editor);
if (gimp_image_base_type (gimage) == GIMP_INDEXED)
if (HAVE_COLORMAP (gimage))
{
gimp_colormap_editor_draw (editor);
@ -641,7 +647,7 @@ gimp_colormap_editor_update_entries (GimpColormapEditor *editor)
{
GimpImage *gimage = GIMP_IMAGE_EDITOR (editor)->gimage;
if (! gimage || (gimp_image_base_type (gimage) != GIMP_INDEXED))
if (! HAVE_COLORMAP (gimage))
{
gtk_widget_set_sensitive (editor->index_spinbutton, FALSE);
gtk_widget_set_sensitive (editor->color_entry, FALSE);
@ -699,7 +705,7 @@ gimp_colormap_preview_size_allocate (GtkWidget *widget,
{
GimpImage *gimage = GIMP_IMAGE_EDITOR (editor)->gimage;
if (gimage && (gimp_image_base_type (gimage) == GIMP_INDEXED))
if (HAVE_COLORMAP (gimage))
gimp_colormap_editor_draw (editor);
else
gimp_colormap_editor_clear (editor, -1);
@ -716,7 +722,7 @@ gimp_colormap_preview_button_press (GtkWidget *widget,
gimage = GIMP_IMAGE_EDITOR (editor)->gimage;
if (! (gimage && (gimp_image_base_type (gimage) == GIMP_INDEXED)))
if (! HAVE_COLORMAP (gimage))
return TRUE;
if (!(bevent->y < editor->cellsize * editor->yn
@ -770,10 +776,8 @@ gimp_colormap_preview_drag_color (GtkWidget *widget,
editor = GIMP_COLORMAP_EDITOR (data);
gimage = GIMP_IMAGE_EDITOR (editor)->gimage;
if (gimage && (gimp_image_base_type (gimage) == GIMP_INDEXED))
{
gimp_image_get_colormap_entry (gimage, editor->dnd_col_index, color);
}
if (HAVE_COLORMAP (gimage))
gimp_image_get_colormap_entry (gimage, editor->dnd_col_index, color);
}
static void
@ -787,9 +791,7 @@ gimp_colormap_preview_drop_color (GtkWidget *widget,
editor = GIMP_COLORMAP_EDITOR (data);
gimage = GIMP_IMAGE_EDITOR (editor)->gimage;
if (gimage &&
gimp_image_base_type (gimage) == GIMP_INDEXED &&
gimp_image_get_colormap_size (gimage) < 256)
if (HAVE_COLORMAP (gimage) && gimp_image_get_colormap_size (gimage) < 256)
{
gimp_image_add_colormap_entry (gimage, color);
}
@ -801,7 +803,7 @@ gimp_colormap_adjustment_changed (GtkAdjustment *adjustment,
{
GimpImage *gimage = GIMP_IMAGE_EDITOR (editor)->gimage;
if (gimage && gimp_image_base_type (gimage) == GIMP_INDEXED)
if (HAVE_COLORMAP (gimage))
{
gimp_colormap_editor_set_index (editor, adjustment->value + 0.5);
@ -964,7 +966,7 @@ gimp_colormap_image_colormap_changed (GimpImage *gimage,
gint ncol,
GimpColormapEditor *editor)
{
if (gimp_image_base_type (gimage) == GIMP_INDEXED)
if (HAVE_COLORMAP (gimage))
{
if (ncol < 0)
{