GitLab repository storage has been migrated to hashed layout. Please contact Infrastructure team if you notice any issues with repositories or hooks.

Commit 94590602 authored by Michael Natterer's avatar Michael Natterer 😴 Committed by Michael Natterer

Added an API for image colormap manupulation and made colormap changes

2003-03-18  Michael Natterer  <mitch@gimp.org>

	Added an API for image colormap manupulation and made colormap
	changes undoable (fixes bug #25963).

	* app/core/Makefile.am
	* app/core/gimpimage-colormap.[ch]: new files implementing
	colormap getters/setters. The setters push undos using the
	new function below.

	* app/core/core-enums.[ch]: added GIMP_UNDO_IMAGE_COLORMAP.

	* app/core/gimpimage-undo-push.[ch]: added
	gimp_image_undo_push_image_colormap(). Use GimpItemUndo even more
	often. Cleanup.

	* app/core/gimpimage.[ch]: removed gimp_image_get_colormap() here.

	* app/core/gimpimage-convert.c
	* app/gui/colormap-editor-commands.c
	* app/widgets/gimpcolormapeditor.c
	* app/widgets/gimptoolbox.c
	* tools/pdbgen/pdb/image.pdb: use the new API.

	* app/pdb/image_cmds.c: regenerated.

	* plug-ins/common/vinvert.c: removed the comment about the bug,
	cosmetic cleanup.

	Unrelated:

	* app/gui/splash.c: added a frame around the splash. Please eek
	if it doesn't please you.
parent cf8e7202
2003-03-18 Michael Natterer <mitch@gimp.org>
Added an API for image colormap manupulation and made colormap
changes undoable (fixes bug #25963).
* app/core/Makefile.am
* app/core/gimpimage-colormap.[ch]: new files implementing
colormap getters/setters. The setters push undos using the
new function below.
* app/core/core-enums.[ch]: added GIMP_UNDO_IMAGE_COLORMAP.
* app/core/gimpimage-undo-push.[ch]: added
gimp_image_undo_push_image_colormap(). Use GimpItemUndo even more
often. Cleanup.
* app/core/gimpimage.[ch]: removed gimp_image_get_colormap() here.
* app/core/gimpimage-convert.c
* app/gui/colormap-editor-commands.c
* app/widgets/gimpcolormapeditor.c
* app/widgets/gimptoolbox.c
* tools/pdbgen/pdb/image.pdb: use the new API.
* app/pdb/image_cmds.c: regenerated.
* plug-ins/common/vinvert.c: removed the comment about the bug,
cosmetic cleanup.
Unrelated:
* app/gui/splash.c: added a frame around the splash. Please eek
if it doesn't please you.
2003-03-17 Sven Neumann <sven@gimp.org>
* data/images/gimp_splash.png: new splash thanks to Jimmac.
......@@ -28,6 +28,7 @@
#include "gui-types.h"
#include "core/gimpimage.h"
#include "core/gimpimage-colormap.h"
#include "widgets/gimpcolormapeditor.h"
......@@ -39,10 +40,10 @@
/* local function prototypes */
static void colormap_editor_color_notebook_callback (ColorNotebook *color_notebook,
const GimpRGB *color,
ColorNotebookState state,
gpointer data);
static void colormap_editor_color_notebook_callback (ColorNotebook *cnb,
const GimpRGB *color,
ColorNotebookState state,
gpointer data);
/* public functions */
......@@ -58,15 +59,17 @@ colormap_editor_add_color_cmd_callback (GtkWidget *widget,
editor = GIMP_COLORMAP_EDITOR (data);
gimage = GIMP_IMAGE_EDITOR (editor)->gimage;
if (! gimage)
return;
if (gimage && gimage->num_cols < 256)
{
GimpRGB color;
memcpy (&gimage->cmap[gimage->num_cols * 3],
&gimage->cmap[editor->col_index * 3],
3);
gimage->num_cols++;
gimp_rgb_set_uchar (&color,
gimage->cmap[editor->col_index * 3],
gimage->cmap[editor->col_index * 3 + 1],
gimage->cmap[editor->col_index * 3 + 2]);
gimp_image_colormap_changed (gimage, -1);
gimp_image_add_colormap_entry (gimage, &color);
}
}
void
......@@ -130,16 +133,13 @@ colormap_editor_color_notebook_callback (ColorNotebook *color_notebook,
{
case COLOR_NOTEBOOK_UPDATE:
break;
case COLOR_NOTEBOOK_OK:
gimp_rgb_get_uchar (color,
&gimage->cmap[editor->col_index * 3 + 0],
&gimage->cmap[editor->col_index * 3 + 1],
&gimage->cmap[editor->col_index * 3 + 2]);
gimp_image_colormap_changed (gimage, editor->col_index);
case COLOR_NOTEBOOK_OK:
gimp_image_set_colormap_entry (gimage, editor->col_index, color, TRUE);
gimp_image_flush (gimage);
/* Fall through */
case COLOR_NOTEBOOK_CANCEL:
color_notebook_hide (editor->color_notebook);
break;
}
}
......@@ -28,6 +28,7 @@
#include "gui-types.h"
#include "core/gimpimage.h"
#include "core/gimpimage-colormap.h"
#include "widgets/gimpcolormapeditor.h"
......@@ -39,10 +40,10 @@
/* local function prototypes */
static void colormap_editor_color_notebook_callback (ColorNotebook *color_notebook,
const GimpRGB *color,
ColorNotebookState state,
gpointer data);
static void colormap_editor_color_notebook_callback (ColorNotebook *cnb,
const GimpRGB *color,
ColorNotebookState state,
gpointer data);
/* public functions */
......@@ -58,15 +59,17 @@ colormap_editor_add_color_cmd_callback (GtkWidget *widget,
editor = GIMP_COLORMAP_EDITOR (data);
gimage = GIMP_IMAGE_EDITOR (editor)->gimage;
if (! gimage)
return;
if (gimage && gimage->num_cols < 256)
{
GimpRGB color;
memcpy (&gimage->cmap[gimage->num_cols * 3],
&gimage->cmap[editor->col_index * 3],
3);
gimage->num_cols++;
gimp_rgb_set_uchar (&color,
gimage->cmap[editor->col_index * 3],
gimage->cmap[editor->col_index * 3 + 1],
gimage->cmap[editor->col_index * 3 + 2]);
gimp_image_colormap_changed (gimage, -1);
gimp_image_add_colormap_entry (gimage, &color);
}
}
void
......@@ -130,16 +133,13 @@ colormap_editor_color_notebook_callback (ColorNotebook *color_notebook,
{
case COLOR_NOTEBOOK_UPDATE:
break;
case COLOR_NOTEBOOK_OK:
gimp_rgb_get_uchar (color,
&gimage->cmap[editor->col_index * 3 + 0],
&gimage->cmap[editor->col_index * 3 + 1],
&gimage->cmap[editor->col_index * 3 + 2]);
gimp_image_colormap_changed (gimage, editor->col_index);
case COLOR_NOTEBOOK_OK:
gimp_image_set_colormap_entry (gimage, editor->col_index, color, TRUE);
gimp_image_flush (gimage);
/* Fall through */
case COLOR_NOTEBOOK_CANCEL:
color_notebook_hide (editor->color_notebook);
break;
}
}
......@@ -83,6 +83,8 @@ libappcore_a_sources = \
gimpimage.h \
gimpimage-colorhash.c \
gimpimage-colorhash.h \
gimpimage-colormap.c \
gimpimage-colormap.h \
gimpimage-contiguous-region.c \
gimpimage-contiguous-region.h \
gimpimage-convert.c \
......
......@@ -461,6 +461,7 @@ static const GEnumValue gimp_undo_type_enum_values[] =
{ GIMP_UNDO_IMAGE_RESOLUTION, N_("Resolution Change"), "image-resolution" },
{ GIMP_UNDO_IMAGE_QMASK, N_("QuickMask"), "image-qmask" },
{ GIMP_UNDO_IMAGE_GUIDE, N_("Guide"), "image-guide" },
{ GIMP_UNDO_IMAGE_COLORMAP, N_("Change Indexed Palette"), "image-colormap" },
{ GIMP_UNDO_MASK, N_("Selection Mask"), "mask" },
{ GIMP_UNDO_ITEM_RENAME, N_("Rename Item"), "item-rename" },
{ GIMP_UNDO_DRAWABLE_VISIBILITY, N_("Drawable Visibility"), "drawable-visibility" },
......
......@@ -360,6 +360,7 @@ typedef enum /*< pdb-skip >*/
GIMP_UNDO_IMAGE_RESOLUTION, /*< desc="Resolution Change" >*/
GIMP_UNDO_IMAGE_QMASK, /*< desc="QuickMask" >*/
GIMP_UNDO_IMAGE_GUIDE, /*< desc="Guide" >*/
GIMP_UNDO_IMAGE_COLORMAP, /*< desc="Change Indexed Palette" >*/
GIMP_UNDO_MASK, /*< desc="Selection Mask" >*/
GIMP_UNDO_ITEM_RENAME, /*< desc="Rename Item" >*/
GIMP_UNDO_DRAWABLE_VISIBILITY, /*< desc="Drawable Visibility" >*/
......
/* 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.
*/
#include "config.h"
#include <string.h>
#include <glib-object.h>
#include "libgimpcolor/gimpcolor.h"
#include "core-types.h"
#include "gimpimage.h"
#include "gimpimage-colormap.h"
#include "gimpimage-mask.h"
#include "gimpimage-undo-push.h"
#include "libgimp/gimpintl.h"
guchar *
gimp_image_get_colormap (const GimpImage *gimage)
{
g_return_val_if_fail (GIMP_IS_IMAGE (gimage), NULL);
return gimage->cmap;
}
gint
gimp_image_get_colormap_size (const GimpImage *gimage)
{
g_return_val_if_fail (GIMP_IS_IMAGE (gimage), 0);
return gimage->num_cols;
}
void
gimp_image_set_colormap (GimpImage *gimage,
guchar *cmap,
gint n_colors,
gboolean push_undo)
{
g_return_if_fail (GIMP_IS_IMAGE (gimage));
g_return_if_fail (n_colors == 0 || cmap != 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);
gimage->num_cols = n_colors;
gimp_image_colormap_changed (gimage, -1);
}
void
gimp_image_get_colormap_entry (GimpImage *gimage,
gint color_index,
GimpRGB *color)
{
g_return_if_fail (GIMP_IS_IMAGE (gimage));
g_return_if_fail (gimage->cmap != NULL);
g_return_if_fail (color_index >= 0 && color_index < gimage->num_cols);
g_return_if_fail (color != NULL);
gimp_rgba_set_uchar (color,
gimage->cmap[color_index * 3],
gimage->cmap[color_index * 3 + 1],
gimage->cmap[color_index * 3 + 2],
OPAQUE_OPACITY);
}
void
gimp_image_set_colormap_entry (GimpImage *gimage,
gint color_index,
const GimpRGB *color,
gboolean push_undo)
{
g_return_if_fail (GIMP_IS_IMAGE (gimage));
g_return_if_fail (gimage->cmap != NULL);
g_return_if_fail (color_index >= 0 && color_index < gimage->num_cols);
g_return_if_fail (color != NULL);
if (push_undo)
gimp_image_undo_push_image_colormap (gimage,
_("Change Indexed Palette Entry"));
gimp_rgb_get_uchar (color,
&gimage->cmap[color_index * 3],
&gimage->cmap[color_index * 3 + 1],
&gimage->cmap[color_index * 3 + 2]);
gimp_image_colormap_changed (gimage, color_index);
}
void
gimp_image_add_colormap_entry (GimpImage *gimage,
const GimpRGB *color)
{
g_return_if_fail (GIMP_IS_IMAGE (gimage));
g_return_if_fail (gimage->cmap != NULL);
g_return_if_fail (gimage->num_cols < 256);
g_return_if_fail (color != NULL);
gimp_image_undo_push_image_colormap (gimage,
_("Add Color to Indexed Palette"));
gimp_rgb_get_uchar (color,
&gimage->cmap[gimage->num_cols * 3],
&gimage->cmap[gimage->num_cols * 3 + 1],
&gimage->cmap[gimage->num_cols * 3 + 2]);
gimage->num_cols++;
gimp_image_colormap_changed (gimage, -1);
}
/* The GIMP -- an image manipulation program
* Copyright (C) 1995 Spencer Kimball and Peter Mattisbvf
*
* 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.
*/
#ifndef __GIMP_IMAGE_COLORMAP_H__
#define __GIMP_IMAGE_COLORMAP_H__
#define GIMP_IMAGE_COLORMAP_SIZE 768
guchar * gimp_image_get_colormap (const GimpImage *gimage);
gint gimp_image_get_colormap_size (const GimpImage *gimage);
void gimp_image_set_colormap (GimpImage *gimage,
guchar *cmap,
gint n_colors,
gboolean push_undo);
void gimp_image_get_colormap_entry (GimpImage *gimage,
gint color_index,
GimpRGB *color);
void gimp_image_set_colormap_entry (GimpImage *gimage,
gint color_index,
const GimpRGB *color,
gboolean push_undo);
void gimp_image_add_colormap_entry (GimpImage *gimage,
const GimpRGB *color);
#endif /* __GIMP_IMAGE_COLORMAP_H__ */
......@@ -138,6 +138,7 @@
#include "gimp.h"
#include "gimpdrawable.h"
#include "gimpimage.h"
#include "gimpimage-colormap.h"
#include "gimpimage-projection.h"
#include "gimpimage-undo.h"
#include "gimpimage-undo-push.h"
......@@ -956,17 +957,17 @@ gimp_image_convert (GimpImage *gimage,
{
if (gimage->cmap)
g_free (gimage->cmap);
gimage->cmap = (unsigned char *) g_malloc (COLORMAP_SIZE);
gimage->cmap = g_new0 (guchar, GIMP_IMAGE_COLORMAP_SIZE);
if (remove_dups &&
((palette_type == GIMP_WEB_PALETTE) ||
(palette_type == GIMP_CUSTOM_PALETTE)))
{
int i,j;
unsigned char old_palette [256 * 3];
unsigned char new_palette [256 * 3];
unsigned char remap_table [256];
int num_entries;
gint i, j;
guchar old_palette [256 * 3];
guchar new_palette [256 * 3];
guchar remap_table [256];
gint num_entries;
for (i = 0, j = 0; i < quantobj->actual_number_of_colors; i++)
{
......@@ -993,7 +994,7 @@ gimp_image_convert (GimpImage *gimage,
remap_indexed_layer (layer, remap_table, num_entries);
}
#else
memcpy(new_palette, old_palette, 256*3);
memcpy (new_palette, old_palette, 256*3);
#endif
for (i = 0, j = 0; i < num_entries; i++)
......
......@@ -39,6 +39,7 @@
#include "gimp.h"
#include "gimpchannel.h"
#include "gimpcontext.h"
#include "gimpimage-colormap.h"
#include "gimpimage-guides.h"
#include "gimpimage-mask.h"
#include "gimpimage-projection.h"
......@@ -69,10 +70,9 @@ typedef struct _ImageUndo ImageUndo;
struct _ImageUndo
{
TileManager *tiles;
GimpDrawable *drawable;
gint x1, y1, x2, y2;
gboolean sparse;
TileManager *tiles;
gint x1, y1, x2, y2;
gboolean sparse;
};
static gboolean undo_pop_image (GimpUndo *undo,
......@@ -104,12 +104,12 @@ gimp_image_undo_push_image (GimpImage *gimage,
size = sizeof (ImageUndo) + ((x2 - x1) * (y2 - y1) *
gimp_drawable_bytes (drawable));
if ((new = gimp_image_undo_push (gimage,
size, sizeof (ImageUndo),
GIMP_UNDO_IMAGE, undo_desc,
TRUE,
undo_pop_image,
undo_free_image)))
if ((new = gimp_image_undo_push_item (gimage, GIMP_ITEM (drawable),
size, sizeof (ImageUndo),
GIMP_UNDO_IMAGE, undo_desc,
TRUE,
undo_pop_image,
undo_free_image)))
{
ImageUndo *image_undo;
TileManager *tiles;
......@@ -130,13 +130,12 @@ gimp_image_undo_push_image (GimpImage *gimage,
copy_region (&srcPR, &destPR);
/* set the image undo structure */
image_undo->tiles = tiles;
image_undo->drawable = drawable;
image_undo->x1 = x1;
image_undo->y1 = y1;
image_undo->x2 = x2;
image_undo->y2 = y2;
image_undo->sparse = FALSE;
image_undo->tiles = tiles;
image_undo->x1 = x1;
image_undo->y1 = y1;
image_undo->x2 = x2;
image_undo->y2 = y2;
image_undo->sparse = FALSE;
return TRUE;
}
......@@ -173,24 +172,23 @@ gimp_image_undo_push_image_mod (GimpImage *gimage,
size = sizeof (ImageUndo) + tile_manager_get_memsize (tiles);
if ((new = gimp_image_undo_push (gimage,
size, sizeof (ImageUndo),
GIMP_UNDO_IMAGE_MOD, undo_desc,
TRUE,
undo_pop_image,
undo_free_image)))
if ((new = gimp_image_undo_push_item (gimage, GIMP_ITEM (drawable),
size, sizeof (ImageUndo),
GIMP_UNDO_IMAGE_MOD, undo_desc,
TRUE,
undo_pop_image,
undo_free_image)))
{
ImageUndo *image_undo;
image_undo = new->data;
image_undo->tiles = tiles;
image_undo->drawable = drawable;
image_undo->x1 = x1;
image_undo->y1 = y1;
image_undo->x2 = x2;
image_undo->y2 = y2;
image_undo->sparse = sparse;
image_undo->tiles = tiles;
image_undo->x1 = x1;
image_undo->y1 = y1;
image_undo->x2 = x2;
image_undo->y2 = y2;
image_undo->sparse = sparse;
return TRUE;
}
......@@ -205,14 +203,17 @@ undo_pop_image (GimpUndo *undo,
GimpUndoMode undo_mode,
GimpUndoAccumulator *accum)
{
ImageUndo *image_undo;
TileManager *tiles;
PixelRegion PR1, PR2;
gint x, y;
gint w, h;
ImageUndo *image_undo;
GimpDrawable *drawable;
TileManager *tiles;
PixelRegion PR1, PR2;
gint x, y;
gint w, h;
image_undo = (ImageUndo *) undo->data;
drawable = GIMP_DRAWABLE (GIMP_ITEM_UNDO (undo)->item);
tiles = image_undo->tiles;
/* some useful values */
......@@ -226,7 +227,7 @@ undo_pop_image (GimpUndo *undo,
pixel_region_init (&PR1, tiles,
0, 0, w, h, TRUE);
pixel_region_init (&PR2, gimp_drawable_data (image_undo->drawable),
pixel_region_init (&PR2, gimp_drawable_data (drawable),
x, y, w, h, TRUE);
/* swap the regions */
......@@ -252,10 +253,12 @@ undo_pop_image (GimpUndo *undo,
src_tile = tile_manager_get_tile (tiles,
j, i, TRUE, FALSE /*TRUE*/);
dest_tile = tile_manager_get_tile (gimp_drawable_data (image_undo->drawable), j, i, TRUE, FALSE /* TRUE */);
dest_tile = tile_manager_get_tile (gimp_drawable_data (drawable), j, i, TRUE, FALSE /* TRUE */);
tile_manager_map_tile (tiles, j, i, dest_tile);
tile_manager_map_tile (gimp_drawable_data (image_undo->drawable), j, i, src_tile);
tile_manager_map_tile (tiles,
j, i, dest_tile);
tile_manager_map_tile (gimp_drawable_data (drawable),
j, i, src_tile);
#if 0
swap_pixels (tile_data_pointer (src_tile, 0, 0),
tile_data_pointer (dest_tile, 0, 0),
......@@ -269,7 +272,7 @@ undo_pop_image (GimpUndo *undo,
}
}
gimp_drawable_update (image_undo->drawable, x, y, w, h);
gimp_drawable_update (drawable, x, y, w, h);
return TRUE;
}
......@@ -713,6 +716,84 @@ undo_free_image_guide (GimpUndo *undo,
}
/*******************/
/* Colormap Undo */
/*******************/
typedef struct _ColormapUndo ColormapUndo;
struct _ColormapUndo
{
guchar cmap[GIMP_IMAGE_COLORMAP_SIZE];
gint num_colors;
};
static gboolean undo_pop_image_colormap (GimpUndo *undo,
GimpUndoMode undo_mode,
GimpUndoAccumulator *accum);
static void undo_free_image_colormap (GimpUndo *undo,
GimpUndoMode undo_mode);
gboolean
gimp_image_undo_push_image_colormap (GimpImage *gimage,
const gchar *undo_desc)
{
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),
sizeof (ColormapUndo),
GIMP_UNDO_IMAGE_COLORMAP, undo_desc,
TRUE,
undo_pop_image_colormap,
undo_free_image_colormap)))
{
ColormapUndo *cu;
cu = new->data;
cu->num_colors = gimp_image_get_colormap_size (gimage);
memcpy (cu->cmap, gimp_image_get_colormap (gimage), cu->num_colors * 3);
return TRUE;
}
return FALSE;
}
static gboolean
undo_pop_image_colormap (GimpUndo *undo,
GimpUndoMode undo_mode,
GimpUndoAccumulator *accum)
{
ColormapUndo *cu;
guchar cmap[GIMP_IMAGE_COLORMAP_SIZE];
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);
gimp_image_set_colormap (undo->gimage, cu->cmap, cu->num_colors, FALSE);
memcpy (cu->cmap, cmap, sizeof (cmap));
cu->num_colors = num_colors;
return TRUE;
}
static void
undo_free_image_colormap (GimpUndo *undo,
GimpUndoMode undo_mode)
{
g_free (undo->data);
}
/***************/
/* Mask Undo */
/***************/
......@@ -1059,11 +1140,7 @@ static void
undo_free_drawable_visibility (GimpUndo *undo,
GimpUndoMode undo_mode)
{
DrawableVisibilityUndo *dvu;
dvu = (DrawableVisibilityUndo *) undo->data;
g_free (dvu);
g_free (undo->data);
}
......@@ -1247,11 +1324,7 @@ static void
undo_free_layer (GimpUndo *undo,
GimpUndoMode undo_mode)
{
LayerUndo *lu;
lu = (LayerUndo *) undo->data;
g_free (lu);
g_free (undo->data);
}