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.
This commit is contained in:
Michael Natterer 2003-03-18 13:49:02 +00:00 committed by Michael Natterer
parent cf8e7202f5
commit 94590602b0
20 changed files with 515 additions and 342 deletions

View File

@ -1,3 +1,37 @@
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.

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -0,0 +1,137 @@
/* 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);
}

View File

@ -0,0 +1,45 @@
/* 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__ */

View File

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

View File

@ -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);
}
@ -1517,7 +1590,6 @@ undo_free_layer_mask (GimpUndo *undo,
lmu = (LayerMaskUndo *) undo->data;
g_object_unref (lmu->mask);
g_free (lmu);
}
@ -1862,11 +1934,7 @@ static void
undo_free_layer_properties (GimpUndo *undo,
GimpUndoMode undo_mode)
{
LayerPropertiesUndo *lpu;
lpu = (LayerPropertiesUndo *) undo->data;
g_free (lpu);
g_free (undo->data);
}
@ -2021,11 +2089,7 @@ static void
undo_free_channel (GimpUndo *undo,
GimpUndoMode undo_mode)
{
ChannelUndo *cu;
cu = (ChannelUndo *) undo->data;
g_free (cu);
g_free (undo->data);
}
@ -2136,7 +2200,6 @@ undo_free_channel_mod (GimpUndo *undo,
cmu = (ChannelModUndo *) undo->data;
tile_manager_destroy (cmu->tiles);
g_free (cmu);
}
@ -2431,11 +2494,7 @@ static void
undo_free_vectors (GimpUndo *undo,
GimpUndoMode undo_mode)
{
VectorsUndo *vu;
vu = (VectorsUndo *) undo->data;
g_free (vu);
g_free (undo->data);
}
@ -2528,7 +2587,6 @@ undo_free_vectors_mod (GimpUndo *undo,
vmu = (VectorsModUndo *) undo->data;
g_object_unref (vmu->undo_vectors);
g_free (vmu);
}
@ -2748,18 +2806,9 @@ undo_free_fs_to_layer (GimpUndo *undo,
/* Floating Selection Rigor Undo */
/***********************************/
typedef struct _FSRigorUndo FSRigorUndo;
struct _FSRigorUndo
{
GimpLayer *floating_layer;
};
static gboolean undo_pop_fs_rigor (GimpUndo *undo,
GimpUndoMode undo_mode,
GimpUndoAccumulator *accum);
static void undo_free_fs_rigor (GimpUndo *undo,
GimpUndoMode undo_mode);
static gboolean undo_pop_fs_rigor (GimpUndo *undo,
GimpUndoMode undo_mode,
GimpUndoAccumulator *accum);
gboolean
gimp_image_undo_push_fs_rigor (GimpImage *gimage,
@ -2771,20 +2820,13 @@ gimp_image_undo_push_fs_rigor (GimpImage *gimage,
g_return_val_if_fail (GIMP_IS_IMAGE (gimage), FALSE);
g_return_val_if_fail (GIMP_IS_LAYER (floating_layer), FALSE);
if ((new = gimp_image_undo_push (gimage,
sizeof (FSRigorUndo),
sizeof (FSRigorUndo),
GIMP_UNDO_FS_RIGOR, undo_desc,
FALSE,
undo_pop_fs_rigor,
undo_free_fs_rigor)))
if ((new = gimp_image_undo_push_item (gimage, GIMP_ITEM (floating_layer),
0, 0,
GIMP_UNDO_FS_RIGOR, undo_desc,
FALSE,
undo_pop_fs_rigor,
NULL)))
{
FSRigorUndo *fsu;
fsu = new->data;
fsu->floating_layer = g_object_ref (floating_layer);
return TRUE;
}
@ -2796,57 +2838,35 @@ undo_pop_fs_rigor (GimpUndo *undo,
GimpUndoMode undo_mode,
GimpUndoAccumulator *accum)
{
FSRigorUndo *fsu;
GimpLayer *floating_layer;
fsu = (FSRigorUndo *) undo->data;
floating_layer = GIMP_LAYER (GIMP_ITEM_UNDO (undo)->item);
if (! gimp_layer_is_floating_sel (fsu->floating_layer))
if (! gimp_layer_is_floating_sel (floating_layer))
return FALSE;
switch (undo_mode)
{
case GIMP_UNDO_MODE_UNDO:
floating_sel_relax (fsu->floating_layer, FALSE);
floating_sel_relax (floating_layer, FALSE);
break;
case GIMP_UNDO_MODE_REDO:
floating_sel_rigor (fsu->floating_layer, FALSE);
floating_sel_rigor (floating_layer, FALSE);
break;
}
return TRUE;
}
static void
undo_free_fs_rigor (GimpUndo *undo,
GimpUndoMode undo_mode)
{
FSRigorUndo *fsu;
fsu = (FSRigorUndo *) undo->data;
g_object_unref (fsu->floating_layer);
g_free (fsu);
}
/***********************************/
/* Floating Selection Relax Undo */
/***********************************/
typedef struct _FSRelaxUndo FSRelaxUndo;
struct _FSRelaxUndo
{
GimpLayer *floating_layer;
};
static gboolean undo_pop_fs_relax (GimpUndo *undo,
GimpUndoMode undo_mode,
GimpUndoAccumulator *accum);
static void undo_free_fs_relax (GimpUndo *undo,
GimpUndoMode undo_mode);
static gboolean undo_pop_fs_relax (GimpUndo *undo,
GimpUndoMode undo_mode,
GimpUndoAccumulator *accum);
gboolean
gimp_image_undo_push_fs_relax (GimpImage *gimage,
@ -2858,20 +2878,13 @@ gimp_image_undo_push_fs_relax (GimpImage *gimage,
g_return_val_if_fail (GIMP_IS_IMAGE (gimage), FALSE);
g_return_val_if_fail (GIMP_IS_LAYER (floating_layer), FALSE);
if ((new = gimp_image_undo_push (gimage,
sizeof (gint32),
sizeof (gint32),
GIMP_UNDO_FS_RELAX, undo_desc,
FALSE,
undo_pop_fs_relax,
undo_free_fs_relax)))
if ((new = gimp_image_undo_push_item (gimage, GIMP_ITEM (floating_layer),
0, 0,
GIMP_UNDO_FS_RELAX, undo_desc,
FALSE,
undo_pop_fs_relax,
NULL)))
{
FSRelaxUndo *fsu;
fsu = new->data;
fsu->floating_layer = g_object_ref (floating_layer);
return TRUE;
}
@ -2883,40 +2896,27 @@ undo_pop_fs_relax (GimpUndo *undo,
GimpUndoMode undo_mode,
GimpUndoAccumulator *accum)
{
FSRelaxUndo *fsu;
GimpLayer *floating_layer;
fsu = (FSRelaxUndo *) undo->data;
floating_layer = GIMP_LAYER (GIMP_ITEM_UNDO (undo)->item);
if (! gimp_layer_is_floating_sel (fsu->floating_layer))
if (! gimp_layer_is_floating_sel (floating_layer))
return FALSE;
switch (undo_mode)
{
case GIMP_UNDO_MODE_UNDO:
floating_sel_rigor (fsu->floating_layer, FALSE);
floating_sel_rigor (floating_layer, FALSE);
break;
case GIMP_UNDO_MODE_REDO:
floating_sel_relax (fsu->floating_layer, FALSE);
floating_sel_relax (floating_layer, FALSE);
break;
}
return TRUE;
}
static void
undo_free_fs_relax (GimpUndo *undo,
GimpUndoMode undo_mode)
{
FSRelaxUndo *fsu;
fsu = (FSRelaxUndo *) undo->data;
g_object_unref (fsu->floating_layer);
g_free (fsu);
}
/*******************/
/* Parasite Undo */

View File

@ -49,6 +49,8 @@ gboolean gimp_image_undo_push_image_qmask (GimpImage *gimage,
gboolean gimp_image_undo_push_image_guide (GimpImage *gimage,
const gchar *undo_desc,
GimpGuide *guide);
gboolean gimp_image_undo_push_image_colormap (GimpImage *gimage,
const gchar *undo_desc);
/* mask undo */

View File

@ -41,6 +41,7 @@
#include "gimpcontext.h"
#include "gimpimage.h"
#include "gimpimage-colorhash.h"
#include "gimpimage-colormap.h"
#include "gimpimage-mask.h"
#include "gimpimage-projection.h"
#include "gimpimage-undo.h"
@ -631,7 +632,7 @@ gimp_image_get_memsize (GimpObject *object)
gimage = GIMP_IMAGE (object);
if (gimage->cmap)
memsize += COLORMAP_SIZE;
memsize += GIMP_IMAGE_COLORMAP_SIZE;
if (gimage->shadow)
memsize += tile_manager_get_memsize (gimage->shadow);
@ -1081,7 +1082,7 @@ gimp_image_new (Gimp *gimp,
case GIMP_INDEXED:
/* always allocate 256 colors for the colormap */
gimage->num_cols = 0;
gimage->cmap = (guchar *) g_malloc0 (COLORMAP_SIZE);
gimage->cmap = g_new0 (guchar, GIMP_IMAGE_COLORMAP_SIZE);
break;
default:
break;
@ -1380,25 +1381,6 @@ gimp_image_floating_selection_changed (GimpImage *gimage)
g_signal_emit (gimage, gimp_image_signals[FLOATING_SELECTION_CHANGED], 0);
}
guchar *
gimp_image_get_colormap (const GimpImage *gimage)
{
g_return_val_if_fail (GIMP_IS_IMAGE (gimage), NULL);
return gimage->cmap;
}
void
gimp_image_colormap_changed (GimpImage *gimage,
gint col)
{
g_return_if_fail (GIMP_IS_IMAGE (gimage));
g_return_if_fail (col < gimage->num_cols);
g_signal_emit (gimage, gimp_image_signals[COLORMAP_CHANGED], 0,
col);
}
GimpChannel *
gimp_image_get_mask (const GimpImage *gimage)
{
@ -1560,6 +1542,17 @@ gimp_image_update_guide (GimpImage *gimage,
g_signal_emit (gimage, gimp_image_signals[UPDATE_GUIDE], 0, guide);
}
void
gimp_image_colormap_changed (GimpImage *gimage,
gint col)
{
g_return_if_fail (GIMP_IS_IMAGE (gimage));
g_return_if_fail (col >= -1 && col < gimage->num_cols);
g_signal_emit (gimage, gimp_image_signals[COLORMAP_CHANGED], 0,
col);
}
void
gimp_image_selection_control (GimpImage *gimage,
GimpSelectionControl control)

View File

@ -23,8 +23,6 @@
#include "gimpviewable.h"
#define COLORMAP_SIZE 768
#define GIMP_IMAGE_TYPE_IS_RGB(t) ((t) == GIMP_RGB_IMAGE || \
(t) == GIMP_RGBA_IMAGE)
#define GIMP_IMAGE_TYPE_IS_GRAY(t) ((t) == GIMP_GRAY_IMAGE || \
@ -255,10 +253,6 @@ gboolean gimp_image_is_empty (const GimpImage *gimage);
GimpLayer * gimp_image_floating_sel (const GimpImage *gimage);
void gimp_image_floating_selection_changed (GimpImage *gimage);
guchar * gimp_image_get_colormap (const GimpImage *gimage);
void gimp_image_colormap_changed (GimpImage *gimage,
gint col);
GimpChannel * gimp_image_get_mask (const GimpImage *gimage);
void gimp_image_mask_changed (GimpImage *gimage);
@ -286,6 +280,8 @@ void gimp_image_update (GimpImage *gimage,
gint height);
void gimp_image_update_guide (GimpImage *gimage,
GimpGuide *guide);
void gimp_image_colormap_changed (GimpImage *gimage,
gint col);
void gimp_image_selection_control (GimpImage *gimage,
GimpSelectionControl control);
void gimp_image_qmask_changed (GimpImage *gimage);

View File

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

View File

@ -18,16 +18,14 @@
#include "config.h"
#include <string.h>
#include <gtk/gtk.h>
#include "libgimpbase/gimpbase.h"
#include "gui-types.h"
#include "splash.h"
#include "libgimpbase/gimpbase.h"
#include "libgimp/gimpintl.h"
@ -47,6 +45,7 @@ static void splash_map (void);
void
splash_create (gboolean show_image)
{
GtkWidget *frame;
GtkWidget *vbox;
GdkPixbuf *pixbuf = NULL;
@ -68,8 +67,13 @@ splash_create (gboolean show_image)
G_CALLBACK (splash_map),
NULL);
frame = gtk_frame_new (NULL);
gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_OUT);
gtk_container_add (GTK_CONTAINER (win_initstatus), frame);
gtk_widget_show (frame);
vbox = gtk_vbox_new (FALSE, 4);
gtk_container_add (GTK_CONTAINER (win_initstatus), vbox);
gtk_container_add (GTK_CONTAINER (frame), vbox);
gtk_widget_show (vbox);
if (show_image)

View File

@ -36,6 +36,7 @@
#include "core/gimpchannel.h"
#include "core/gimpcontainer.h"
#include "core/gimpdrawable.h"
#include "core/gimpimage-colormap.h"
#include "core/gimpimage-crop.h"
#include "core/gimpimage-duplicate.h"
#include "core/gimpimage-merge.h"
@ -2032,17 +2033,7 @@ image_set_cmap_invoker (Gimp *gimp,
cmap = (guint8 *) args[2].value.pdb_pointer;
if (success)
{
if (gimage->cmap == NULL)
gimage->cmap = g_new (guchar, COLORMAP_SIZE);
if (num_bytes)
memcpy (gimage->cmap, cmap, num_bytes);
gimage->num_cols = num_bytes / 3;
gimp_image_colormap_changed (gimage, -1);
}
gimp_image_set_colormap (gimage, cmap, num_bytes / 3, TRUE);
return procedural_db_return_args (&image_set_cmap_proc, success);
}

View File

@ -45,6 +45,7 @@
#include "core/gimpcontainer.h"
#include "core/gimpcontext.h"
#include "core/gimpimage.h"
#include "core/gimpimage-colormap.h"
#include "core/gimpmarshal.h"
#include "display/gimpdisplayshell-render.h"
@ -291,7 +292,9 @@ gimp_colormap_editor_set_image (GimpImageEditor *image_editor,
{
gimp_colormap_editor_draw (editor);
editor->index_adjustment->upper = gimage->num_cols - 1;
editor->index_adjustment->upper =
gimp_image_get_colormap_size (gimage) - 1;
gtk_adjustment_changed (editor->index_adjustment);
}
}
@ -417,7 +420,6 @@ gimp_colormap_editor_real_selected (GimpColormapEditor *editor)
GimpContext *user_context;
GimpImage *gimage;
GimpRGB color;
gint index;
gimage = GIMP_IMAGE_EDITOR (editor)->gimage;
@ -426,13 +428,7 @@ gimp_colormap_editor_real_selected (GimpColormapEditor *editor)
user_context = gimp_get_user_context (gimage->gimp);
index = editor->col_index;
gimp_rgba_set_uchar (&color,
gimage->cmap[index * 3 + 0],
gimage->cmap[index * 3 + 1],
gimage->cmap[index * 3 + 2],
OPAQUE_OPACITY);
gimp_image_get_colormap_entry (gimage, editor->col_index, &color);
if (active_color == FOREGROUND)
gimp_context_set_foreground (user_context, &color);
@ -458,7 +454,7 @@ gimp_colormap_editor_draw (GimpColormapEditor *editor)
palette = editor->palette;
width = palette->allocation.width;
height = palette->allocation.height;
ncol = gimage->num_cols;
ncol = gimp_image_get_colormap_size (gimage);
if (! ncol)
{
@ -731,7 +727,6 @@ gimp_colormap_preview_button_press (GtkWidget *widget,
GimpColormapEditor *editor)
{
GimpImage *gimage;
guchar r, g, b;
guint col;
gimage = GIMP_IMAGE_EDITOR (editor)->gimage;
@ -746,13 +741,9 @@ gimp_colormap_preview_button_press (GtkWidget *widget,
col = (editor->xn * ((gint) bevent->y / editor->cellsize) +
((gint) bevent->x / editor->cellsize));
if (col >= gimage->num_cols)
if (col >= gimp_image_get_colormap_size (gimage))
return TRUE;
r = gimage->cmap[col * 3 + 0];
g = gimage->cmap[col * 3 + 1];
b = gimage->cmap[col * 3 + 2];
switch (bevent->button)
{
case 1:
@ -789,15 +780,7 @@ gimp_colormap_preview_drag_color (GtkWidget *widget,
if (gimage && (gimp_image_base_type (gimage) == GIMP_INDEXED))
{
guint col;
col = editor->dnd_col_index;
gimp_rgba_set_uchar (color,
gimage->cmap[col * 3 + 0],
gimage->cmap[col * 3 + 1],
gimage->cmap[col * 3 + 2],
OPAQUE_OPACITY);
gimp_image_get_colormap_entry (gimage, editor->dnd_col_index, color);
}
}
@ -812,18 +795,11 @@ 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))
if (gimage &&
gimp_image_base_type (gimage) == GIMP_INDEXED &&
gimp_image_get_colormap_size (gimage) < 256)
{
if (gimage->num_cols < 256)
{
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);
}
gimp_image_add_colormap_entry (gimage, color);
}
}
@ -856,16 +832,18 @@ gimp_colormap_hex_entry_activate (GtkEntry *entry,
if (sscanf (s, "#%lx", &i))
{
guchar *c = &gimage->cmap[3 * editor->col_index];
GimpRGB color;
guchar r, g, b;
c[0] = (i & 0xFF0000) >> 16;
c[1] = (i & 0x00FF00) >> 8;
c[2] = (i & 0x0000FF);
r = (i & 0xFF0000) >> 16;
g = (i & 0x00FF00) >> 8;
b = (i & 0x0000FF);
gimp_image_colormap_changed (gimage, editor->col_index);
gimp_rgb_set_uchar (&color, r, g, b);
gimp_image_set_colormap_entry (gimage, editor->col_index, &color,
TRUE);
}
gimp_colormap_editor_update_entries (editor);
}
}
@ -900,9 +878,12 @@ gimp_colormap_image_colormap_changed (GimpImage *gimage,
gimp_colormap_editor_draw_cell (editor, ncol);
}
if ((editor->index_adjustment->upper + 1) < gimage->num_cols)
if (editor->index_adjustment->upper !=
(gimp_image_get_colormap_size (gimage) - 1))
{
editor->index_adjustment->upper = gimage->num_cols - 1;
editor->index_adjustment->upper =
gimp_image_get_colormap_size (gimage) - 1;
gtk_adjustment_changed (editor->index_adjustment);
}
}

View File

@ -31,6 +31,7 @@
#include "core/gimpcontext.h"
#include "core/gimpedit.h"
#include "core/gimpimage.h"
#include "core/gimpimage-colormap.h"
#include "core/gimplayer.h"
#include "core/gimplayermask.h"
#include "core/gimplist.h"
@ -862,10 +863,10 @@ toolbox_drop_drawable (GtkWidget *widget,
gimp_image_undo_disable (new_gimage);
if (type == GIMP_INDEXED) /* copy the colormap */
{
new_gimage->num_cols = gimage->num_cols;
memcpy (new_gimage->cmap, gimage->cmap, COLORMAP_SIZE);
}
gimp_image_set_colormap (new_gimage,
gimp_image_get_colormap (gimage),
gimp_image_get_colormap_size (gimage),
FALSE);
gimp_image_set_resolution (new_gimage,
gimage->xresolution, gimage->yresolution);

View File

@ -20,11 +20,6 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
/*
* BUGS:
* Is not undoable when operating on indexed images - GIMP's fault.
*/
#include "config.h"
#include <stdio.h>
@ -37,19 +32,19 @@
/* Declare local functions.
*/
static void query (void);
static void run (gchar *name,
gint nparams,
GimpParam *param,
gint *nreturn_vals,
GimpParam **return_vals);
static void query (void);
static void run (gchar *name,
gint nparams,
GimpParam *param,
gint *nreturn_vals,
GimpParam **return_vals);
static void vinvert (GimpDrawable *drawable);
static void indexed_vinvert (gint32 image_ID);
static void vinvert_render_row (guchar *src,
guchar *dest,
gint row_width,
const gint bpp);
static void vinvert (GimpDrawable *drawable);
static void indexed_vinvert (gint32 image_ID);
static void vinvert_render_row (guchar *src,
guchar *dest,
gint row_width,
gint bpp);
static GimpRunMode run_mode;
@ -159,7 +154,7 @@ indexed_vinvert (gint32 image_ID)
cmap = gimp_image_get_cmap (image_ID, &ncols);
if (cmap==NULL)
if (cmap == NULL)
{
g_print ("vinvert: cmap was NULL! Quitting...\n");
gimp_quit ();
@ -192,12 +187,12 @@ vinvert_func (guchar *src, guchar *dest, gint bpp, gpointer data)
}
static void
vinvert_render_row (guchar *src,
guchar *dest,
gint col, /* row width in pixels */
const gint bpp)
vinvert_render_row (guchar *src,
guchar *dest,
gint row_width, /* in pixels */
gint bpp)
{
while (col--)
while (row_width--)
{
vinvert_func (src, dest, bpp, NULL);
src += bpp;
@ -210,4 +205,3 @@ vinvert (GimpDrawable *drawable)
{
gimp_rgn_iterate2 (drawable, run_mode, vinvert_func, NULL);
}

View File

@ -831,6 +831,7 @@ HELP
);
%invoke = (
headers => [ qw("core/gimpimage-colormap.h") ],
code => <<'CODE'
{
num_bytes = gimage->num_cols * 3;
@ -861,20 +862,9 @@ HELP
%%desc%%' } }
);
%invoke = ( code => <<'CODE'
{
if (gimage->cmap == NULL)
gimage->cmap = g_new (guchar, COLORMAP_SIZE);
if (num_bytes)
memcpy (gimage->cmap, cmap, num_bytes);
gimage->num_cols = num_bytes / 3;
gimp_image_colormap_changed (gimage, -1);
}
CODE
);
%invoke = (
headers => [ qw("core/gimpimage-colormap.h") ],
code => 'gimp_image_set_colormap (gimage, cmap, num_bytes / 3, TRUE);' );
}
sub image_undo_is_enabled {