1
1
mirror of https://gitlab.gnome.org/GNOME/gimp.git synced 2025-10-06 01:12:40 +02:00

app: work with a GimpPalette rather than a colormap.

We historically have both the colormap and palette concept in core GIMP,
though they are actually kinda the same concept, except that with
"colormap" we work with an array of raw data and it's a lot less
color-aware. It is still much more efficient in some specific cases,
such as when converting the image (we can then convert the whole palette
as a single buffer, because the image palette is space-restricted
anyway), when storing undo data or when storing/loading in XCF.

But for all the rest, let's use gimp_image_get_colormap_palette() and
work with the GimpPalette API.
This commit is contained in:
Jehan
2023-12-09 16:53:44 +09:00
parent 5e8f4f5e00
commit 4a30f431fd
16 changed files with 111 additions and 103 deletions

View File

@@ -28,6 +28,7 @@
#include "core/gimpdrawable.h"
#include "core/gimpimage.h"
#include "core/gimpimage-colormap.h"
#include "core/gimppalette.h"
#include "widgets/gimpactiongroup.h"
#include "widgets/gimpcolormapeditor.h"
@@ -134,7 +135,7 @@ colormap_actions_update (GimpActionGroup *group,
{
GList *drawables = gimp_image_get_selected_drawables (image);
num_colors = gimp_image_get_colormap_size (image);
num_colors = gimp_palette_get_n_colors (gimp_image_get_colormap_palette ((image)));
if (g_list_length (drawables) == 1)
drawable_indexed = gimp_drawable_is_indexed (drawables->data);

View File

@@ -26,6 +26,7 @@
#include "core/gimpcontext.h"
#include "core/gimpimage.h"
#include "core/gimpimage-colormap.h"
#include "core/gimppalette.h"
#include "widgets/gimpcolormapeditor.h"
#include "widgets/gimpcolormapselection.h"
@@ -69,7 +70,7 @@ colormap_add_color_cmd_callback (GimpAction *action,
background = (gboolean) g_variant_get_int32 (value);
if (gimp_image_get_colormap_size (image) < 256)
if (gimp_palette_get_n_colors (gimp_image_get_colormap_palette ((image))) < 256)
{
GeglColor *color;

View File

@@ -1997,18 +1997,6 @@ gimp_drawable_get_component_index (GimpDrawable *drawable,
return -1;
}
guchar *
gimp_drawable_get_colormap (GimpDrawable *drawable)
{
GimpImage *image;
g_return_val_if_fail (GIMP_IS_DRAWABLE (drawable), NULL);
image = gimp_item_get_image (GIMP_ITEM (drawable));
return image ? gimp_image_get_colormap (image) : NULL;
}
void
gimp_drawable_start_paint (GimpDrawable *drawable)
{

View File

@@ -230,8 +230,6 @@ const Babl * gimp_drawable_get_component_format (GimpDrawable *drawable,
gint gimp_drawable_get_component_index (GimpDrawable *drawable,
GimpChannelType channel);
guchar * gimp_drawable_get_colormap (GimpDrawable *drawable);
void gimp_drawable_start_paint (GimpDrawable *drawable);
gboolean gimp_drawable_end_paint (GimpDrawable *drawable);
gboolean gimp_drawable_flush_paint (GimpDrawable *drawable);

View File

@@ -167,8 +167,7 @@ gimp_image_colormap_update_formats (GimpImage *image)
guchar *colormap;
gint n_colors;
colormap = gimp_image_get_colormap (image);
n_colors = gimp_image_get_colormap_size (image);
colormap = _gimp_image_get_colormap (image, &n_colors);
babl_palette_set_palette (private->babl_palette_rgb,
gimp_babl_format (GIMP_RGB,
@@ -251,11 +250,14 @@ gimp_image_set_colormap_palette (GimpImage *image,
}
guchar *
gimp_image_get_colormap (GimpImage *image)
_gimp_image_get_colormap (GimpImage *image,
gint *n_colors)
{
GimpImagePrivate *private;
guchar *colormap = NULL;
gint n_colors, i;
const Babl *space;
const Babl *format;
gint bpp;
g_return_val_if_fail (GIMP_IS_IMAGE (image), NULL);
private = GIMP_IMAGE_GET_PRIVATE (image);
@@ -263,46 +265,39 @@ gimp_image_get_colormap (GimpImage *image)
if (private->palette == NULL)
return NULL;
n_colors = gimp_palette_get_n_colors (private->palette);
space = gimp_image_get_layer_space (image);
format = gimp_babl_format (GIMP_RGB, private->precision, FALSE, space);
bpp = babl_format_get_bytes_per_pixel (format);
if (n_colors > 0)
*n_colors = gimp_palette_get_n_colors (private->palette);
if (*n_colors > 0)
{
colormap = g_new0 (guchar, GIMP_IMAGE_COLORMAP_SIZE);
for (i = 0; i < n_colors; i++)
for (gint i = 0; i < *n_colors; i++)
{
GimpPaletteEntry *entry = gimp_palette_get_entry (private->palette, i);
/* TODO: what should be the format of the colormap? */
gegl_color_get_pixel (entry->color, babl_format ("R'G'B' u8"), &colormap[i * 3]);
gegl_color_get_pixel (entry->color, format, &colormap[i * bpp]);
}
}
return colormap;
}
gint
gimp_image_get_colormap_size (GimpImage *image)
{
GimpImagePrivate *private;
g_return_val_if_fail (GIMP_IS_IMAGE (image), 0);
private = GIMP_IMAGE_GET_PRIVATE (image);
if (private->palette == NULL)
return 0;
return gimp_palette_get_n_colors (private->palette);
}
void
gimp_image_set_colormap (GimpImage *image,
const guchar *colormap,
gint n_colors,
gboolean push_undo)
_gimp_image_set_colormap (GimpImage *image,
const guchar *colormap,
gint n_colors,
gboolean push_undo)
{
GimpImagePrivate *private;
GimpPaletteEntry *entry;
const Babl *space;
const Babl *format;
GeglColor *color;
gint bpp;
gint i;
g_return_if_fail (GIMP_IS_IMAGE (image));
@@ -322,14 +317,17 @@ gimp_image_set_colormap (GimpImage *image,
while ((entry = gimp_palette_get_entry (private->palette, 0)))
gimp_palette_delete_entry (private->palette, entry);
space = gimp_image_get_layer_space (image);
format = gimp_babl_format (GIMP_RGB, private->precision, FALSE, space);
bpp = babl_format_get_bytes_per_pixel (format);
color = gegl_color_new (NULL);
for (i = 0; i < n_colors; i++)
{
GeglColor *color = gegl_color_new (NULL);
gegl_color_set_pixel (color, babl_format ("R'G'B' u8"), &colormap[i * 3]);
gegl_color_set_pixel (color, format, &colormap[i * bpp]);
gimp_image_colormap_set_palette_entry (image, color, i);
g_object_unref (color);
}
g_object_unref (color);
gimp_image_colormap_changed (image, -1);
gimp_data_thaw (GIMP_DATA (private->palette));
@@ -528,19 +526,31 @@ gimp_image_colormap_set_palette_entry (GimpImage *image,
GeglColor *color,
gint index)
{
GimpImagePrivate *private = GIMP_IMAGE_GET_PRIVATE (image);
GeglColor *black = gegl_color_new ("black");
GimpImagePrivate *private = GIMP_IMAGE_GET_PRIVATE (image);
GeglColor *new_color = gegl_color_new ("black");
const Babl *space;
const Babl *format;
guint8 rgb[3];
gchar name[64];
g_return_if_fail (GEGL_IS_COLOR (color));
/* Adding black entries if needed. */
while (gimp_palette_get_n_colors (private->palette) <= index)
gimp_palette_add_entry (private->palette, index, name, black);
gimp_palette_add_entry (private->palette, index, name, new_color);
g_snprintf (name, sizeof (name), "#%d", index);
gimp_palette_set_entry (private->palette, index, name, color);
g_object_unref (black);
space = gimp_image_get_layer_space (image);
format = gimp_babl_format (GIMP_RGB, private->precision, FALSE, space);
/* For image colormap, we force the color to be in the target format (which at
* time of writing is only "R'G'B' u8" for the target space).
*/
gegl_color_get_pixel (color, format, rgb);
gegl_color_set_pixel (new_color, format, rgb);
gimp_palette_set_entry (private->palette, index, name, new_color);
g_object_unref (new_color);
}
static void

View File

@@ -36,9 +36,10 @@ void gimp_image_set_colormap_palette (GimpImage *image,
GimpPalette *palette,
gboolean push_undo);
guchar * gimp_image_get_colormap (GimpImage *image);
gint gimp_image_get_colormap_size (GimpImage *image);
void gimp_image_set_colormap (GimpImage *image,
/* Only internally */
guchar * _gimp_image_get_colormap (GimpImage *image,
gint *n_colors);
void _gimp_image_set_colormap (GimpImage *image,
const guchar *colormap,
gint n_colors,
gboolean push_undo);

View File

@@ -973,8 +973,8 @@ gimp_image_convert_indexed (GimpImage *image,
colormap[j++] = quantobj->cmap[i].blue;
}
gimp_image_set_colormap (image, colormap,
quantobj->actual_number_of_colors, TRUE);
_gimp_image_set_colormap (image, colormap,
quantobj->actual_number_of_colors, TRUE);
}
/* when converting from GRAY, always convert to the new type's
@@ -1071,7 +1071,7 @@ gimp_image_convert_indexed (GimpImage *image,
colormap[j] = new_palette[j]; j++;
}
gimp_image_set_colormap (image, colormap, num_entries, TRUE);
_gimp_image_set_colormap (image, colormap, num_entries, TRUE);
}
/* When converting from GRAY, set the new profile.

View File

@@ -182,8 +182,7 @@ gimp_image_undo_constructed (GObject *object)
break;
case GIMP_UNDO_IMAGE_COLORMAP:
image_undo->num_colors = gimp_image_get_colormap_size (image);
image_undo->colormap = gimp_image_get_colormap (image);
image_undo->colormap = _gimp_image_get_colormap (image, &image_undo->num_colors);
break;
case GIMP_UNDO_IMAGE_HIDDEN_PROFILE:
@@ -452,13 +451,11 @@ gimp_image_undo_pop (GimpUndo *undo,
guchar *colormap;
gint num_colors;
num_colors = gimp_image_get_colormap_size (image);
colormap = gimp_image_get_colormap (image);
colormap = _gimp_image_get_colormap (image, &num_colors);
if (image_undo->colormap)
gimp_image_set_colormap (image,
image_undo->colormap, image_undo->num_colors,
FALSE);
_gimp_image_set_colormap (image, image_undo->colormap,
image_undo->num_colors, FALSE);
else
gimp_image_unset_colormap (image, FALSE);

View File

@@ -1,4 +1,7 @@
EXPORTS
_gimp_image_get_colormap
_gimp_image_get_colormap_size
_gimp_image_set_colormap
_gimp_unit_get_abbreviation
_gimp_unit_get_deletion_flag
_gimp_unit_get_digits
@@ -287,9 +290,7 @@ EXPORTS
gimp_image_get_active_vectors
gimp_image_get_by_ID
gimp_image_get_channels
gimp_image_get_colormap
gimp_image_get_colormap_entry
gimp_image_get_colormap_size
gimp_image_get_component_active
gimp_image_get_component_index
gimp_image_get_component_visible
@@ -352,7 +353,6 @@ EXPORTS
gimp_image_set_active_channel
gimp_image_set_active_layer
gimp_image_set_active_vectors
gimp_image_set_colormap
gimp_image_set_colormap_entry
gimp_image_set_component_active
gimp_image_set_component_visible
@@ -716,7 +716,6 @@ gimp_scan_convert_stroke
gimp_array_free
gimp_array_new
gimp_drawable_get_colormap
gimp_drawable_get_tiles
gimp_drawable_id_get_type
gimp_float_array_get_type

View File

@@ -1528,10 +1528,10 @@ image_get_colormap_invoker (GimpProcedure *procedure,
if (success)
{
guchar *colormap_data;
gint n_colors;
colormap_data = gimp_image_get_colormap (image);
colormap = g_bytes_new_take (colormap_data,
3 * gimp_image_get_colormap_size (image));
colormap_data = _gimp_image_get_colormap (image, &n_colors);
colormap = g_bytes_new_take (colormap_data, 3 * n_colors);
}
return_vals = gimp_procedure_get_return_values (procedure, success,
@@ -1560,10 +1560,10 @@ image_set_colormap_invoker (GimpProcedure *procedure,
if (success)
{
gimp_image_set_colormap (image,
g_bytes_get_data (colormap, NULL),
g_bytes_get_size (colormap) / 3,
TRUE);
_gimp_image_set_colormap (image,
g_bytes_get_data (colormap, NULL),
g_bytes_get_size (colormap) / 3,
TRUE);
}
return gimp_procedure_get_return_values (procedure, success,

View File

@@ -620,7 +620,7 @@ gimp_color_dialog_colormap_add_activate (GimpColorDialog *dialog)
GimpViewableDialog *viewable_dialog = GIMP_VIEWABLE_DIALOG (dialog);
if (dialog->active_image &&
gimp_image_get_colormap_size (dialog->active_image) < 256 &&
gimp_palette_get_n_colors (gimp_image_get_colormap_palette (dialog->active_image)) < 256 &&
viewable_dialog->context)
{
GimpContext *user_context = viewable_dialog->context->gimp->user_context;

View File

@@ -390,10 +390,10 @@ gimp_colormap_selection_get_index (GimpColormapSelection *selection,
if (! gimp_color_is_perceptually_identical (temp, search))
{
gint n_colors = gimp_image_get_colormap_size (image);
gint i;
gint n_colors;
for (i = 0; i < n_colors; i++)
n_colors = gimp_palette_get_n_colors (gimp_image_get_colormap_palette (image));
for (gint i = 0; i < n_colors; i++)
{
temp = gimp_image_get_colormap_entry (image, i);
@@ -425,7 +425,7 @@ gimp_colormap_selection_set_index (GimpColormapSelection *selection,
if (! HAVE_COLORMAP (image))
return FALSE;
size = gimp_image_get_colormap_size (image);
size = gimp_palette_get_n_colors (gimp_image_get_colormap_palette (image));
if (size < 1)
return FALSE;
@@ -463,6 +463,7 @@ gint
gimp_colormap_selection_max_index (GimpColormapSelection *selection)
{
GimpImage *image;
gint n_colors;
g_return_val_if_fail (GIMP_IS_COLORMAP_SELECTION (selection), -1);
@@ -471,7 +472,9 @@ gimp_colormap_selection_max_index (GimpColormapSelection *selection)
if (! HAVE_COLORMAP (image))
return -1;
return MAX (0, gimp_image_get_colormap_size (image) - 1);
n_colors = gimp_palette_get_n_colors (gimp_image_get_colormap_palette (image));
return MAX (0, n_colors - 1);
}
GimpPaletteEntry *
@@ -571,10 +574,13 @@ gimp_colormap_selection_preview_draw (GtkWidget *widget,
static void
gimp_colormap_selection_update_entries (GimpColormapSelection *selection)
{
GimpImage *image = gimp_context_get_image (selection->context);
GimpImage *image = gimp_context_get_image (selection->context);
gint n_colors = 0;
if (! HAVE_COLORMAP (image) ||
! gimp_image_get_colormap_size (image))
if (gimp_image_get_colormap_palette (image))
n_colors = gimp_palette_get_n_colors (gimp_image_get_colormap_palette (image));
if (! HAVE_COLORMAP (image) || ! n_colors)
{
gtk_widget_set_sensitive (selection->index_spinbutton, FALSE);
gtk_widget_set_sensitive (selection->color_entry, FALSE);
@@ -821,13 +827,15 @@ gimp_colormap_selection_set_palette (GimpColormapSelection *selection)
if (palette)
{
gint n_colors;
n_colors = gimp_palette_get_n_colors (palette);
g_signal_connect_swapped (palette, "dirty",
G_CALLBACK (gtk_widget_queue_draw),
selection);
gimp_view_set_viewable (GIMP_VIEW (selection->view),
GIMP_VIEWABLE (palette));
gtk_adjustment_set_upper (selection->index_adjustment,
gimp_image_get_colormap_size (selection->active_image) - 1);
gtk_adjustment_set_upper (selection->index_adjustment, n_colors - 1);
}
}
}

View File

@@ -35,6 +35,7 @@
#include "core/gimpimage.h"
#include "core/gimpimage-colormap.h"
#include "core/gimpimage-undo.h"
#include "core/gimppalette.h"
#include "core/gimpundostack.h"
#include "core/gimp-utils.h"
@@ -479,11 +480,15 @@ gimp_image_prop_view_update (GimpImagePropView *view)
gimp_color_profile_get_label (profile));
break;
case GIMP_INDEXED:
g_snprintf (buf, sizeof (buf),
ngettext ("Indexed color (monochrome)",
"Indexed color (%d colors)",
gimp_image_get_colormap_size (image)),
gimp_image_get_colormap_size (image));
{
gint n_colors;
n_colors = gimp_palette_get_n_colors (gimp_image_get_colormap_palette (image));
g_snprintf (buf, sizeof (buf),
ngettext ("Indexed color (monochrome)",
"Indexed color (%d colors)",
n_colors), n_colors);
}
break;
}

View File

@@ -1178,7 +1178,7 @@ xcf_load_image_props (XcfInfo *info,
* an image state that is impossible.
*/
if (gimp_image_get_base_type (image) == GIMP_INDEXED)
gimp_image_set_colormap (image, cmap, n_colors, FALSE);
_gimp_image_set_colormap (image, cmap, n_colors, FALSE);
GIMP_LOG (XCF, "prop colormap n_colors=%d", n_colors);
}

View File

@@ -487,10 +487,10 @@ xcf_save_image_props (XcfInfo *info,
/* check and see if we should save the colormap property */
if (gimp_image_get_colormap_palette (image))
{
guint8 *colormap = gimp_image_get_colormap (image);
gint n_colors;
guint8 *colormap = _gimp_image_get_colormap (image, &n_colors);
xcf_check_error (xcf_save_prop (info, image, PROP_COLORMAP, error,
gimp_image_get_colormap_size (image),
colormap), ;);
n_colors, colormap), ;);
g_free (colormap);
}

View File

@@ -1521,10 +1521,10 @@ HELP
code => <<'CODE'
{
guchar *colormap_data;
gint n_colors;
colormap_data = gimp_image_get_colormap (image);
colormap = g_bytes_new_take (colormap_data,
3 * gimp_image_get_colormap_size (image));
colormap_data = _gimp_image_get_colormap (image, &n_colors);
colormap = g_bytes_new_take (colormap_data, 3 * n_colors);
}
CODE
);
@@ -1555,10 +1555,10 @@ HELP
headers => [ qw("core/gimpimage-colormap.h") ],
code => <<'CODE'
{
gimp_image_set_colormap (image,
g_bytes_get_data (colormap, NULL),
g_bytes_get_size (colormap) / 3,
TRUE);
_gimp_image_set_colormap (image,
g_bytes_get_data (colormap, NULL),
g_bytes_get_size (colormap) / 3,
TRUE);
}
CODE
);