app: add a concept of format restriction in GimpPalette.

By default a palette can contain any mix of color models and space. These new
internal API add a concept of format/space restriction. For now this will only
be used for indexed images whose palette should only contain colors for the
specific palette format and space (at least as currently implemented in GIMP).
This commit is contained in:
Jehan 2023-11-29 13:54:00 +01:00
parent dc1f5ea227
commit 5e8f4f5e00
3 changed files with 87 additions and 40 deletions

View file

@ -48,6 +48,7 @@
#include "gimpimage-undo.h"
#include "gimpimage-undo-push.h"
#include "gimpobjectqueue.h"
#include "gimppalette.h"
#include "gimpprogress.h"
#include "gimp-intl.h"
@ -1021,48 +1022,25 @@ gimp_image_convert_profile_colormap (GimpImage *image,
gboolean bpc,
GimpProgress *progress)
{
GimpColorTransform *transform;
const Babl *src_format;
const Babl *dest_format;
GimpImagePrivate *private = GIMP_IMAGE_GET_PRIVATE (image);
GimpColorTransformFlags flags = 0;
guchar *cmap;
gint n_colors;
n_colors = gimp_image_get_colormap_size (image);
cmap = gimp_image_get_colormap (image);
GimpPalette *palette;
const Babl *space;
const Babl *format;
if (bpc)
/* TODO: current implementation ignores the black point compensation
* choice because babl doesn't have BCP support yet.
* Previous code was using gimp_color_transform_new() which used
* LittleCMS directly instead.
* This should be fixed.
*/
flags |= GIMP_COLOR_TRANSFORM_FLAGS_BLACK_POINT_COMPENSATION;
src_format = gimp_color_profile_get_format (src_profile,
babl_format ("R'G'B' u8"),
GIMP_COLOR_RENDERING_INTENT_RELATIVE_COLORIMETRIC,
NULL);
dest_format = gimp_color_profile_get_format (dest_profile,
babl_format ("R'G'B' u8"),
GIMP_COLOR_RENDERING_INTENT_RELATIVE_COLORIMETRIC,
NULL);
transform = gimp_color_transform_new (src_profile, src_format,
dest_profile, dest_format,
intent, flags);
if (transform)
{
gimp_color_transform_process_pixels (transform,
babl_format ("R'G'B' u8"), cmap,
babl_format ("R'G'B' u8"), cmap,
n_colors);
g_object_unref (transform);
gimp_image_set_colormap (image, cmap, n_colors, TRUE);
}
else
{
g_warning ("gimp_color_transform_new() failed!");
}
g_free (cmap);
palette = gimp_image_get_colormap_palette (image);
space = gimp_image_get_layer_space (image);
format = gimp_babl_format (GIMP_RGB, private->precision, FALSE, space);
gimp_palette_restrict_format (palette, format);
}
static void

View file

@ -404,6 +404,44 @@ gimp_palette_get_checksum (GimpTagged *tagged)
/* public functions */
void
gimp_palette_restrict_format (GimpPalette *palette,
const Babl *format)
{
gint n_colors;
g_return_if_fail (GIMP_IS_PALETTE (palette));
if (palette->format == format)
return;
palette->format = format;
if (palette->format == NULL)
/* No more restriction. */
return;
/* Convert all colors to the new format. */
n_colors = gimp_palette_get_n_colors (palette);
for (gint i = 0; i < n_colors; i++)
{
GimpPaletteEntry *entry;
guint8 pixel[40];
entry = gimp_palette_get_entry (palette, i);
gegl_color_get_pixel (entry->color, format, pixel);
gegl_color_set_pixel (entry->color, format, pixel);
}
}
const Babl *
gimp_palette_get_restriction (GimpPalette *palette)
{
g_return_val_if_fail (GIMP_IS_PALETTE (palette), NULL);
return palette->format;
}
GList *
gimp_palette_get_colors (GimpPalette *palette)
{
@ -461,6 +499,14 @@ gimp_palette_add_entry (GimpPalette *palette,
entry->color = gegl_color_duplicate (color);
entry->name = g_strdup (name ? name : _("Untitled"));
if (palette->format != NULL)
{
guint8 pixel[40];
gegl_color_get_pixel (entry->color, palette->format, pixel);
gegl_color_set_pixel (entry->color, palette->format, pixel);
}
if (position < 0 || position >= palette->n_colors)
{
palette->colors = g_list_append (palette->colors, entry);
@ -523,6 +569,13 @@ gimp_palette_set_entry (GimpPalette *palette,
return FALSE;
entry->color = gegl_color_duplicate (color);
if (palette->format != NULL)
{
guint8 pixel[40];
gegl_color_get_pixel (entry->color, palette->format, pixel);
gegl_color_set_pixel (entry->color, palette->format, pixel);
}
if (entry->name)
g_free (entry->name);
@ -558,6 +611,13 @@ gimp_palette_set_entry_color (GimpPalette *palette,
C_("undo-type", "Change Colormap entry"));
entry->color = gegl_color_duplicate (color);
if (palette->format != NULL)
{
guint8 pixel[40];
gegl_color_get_pixel (entry->color, palette->format, pixel);
gegl_color_set_pixel (entry->color, palette->format, pixel);
}
if (! gimp_data_is_frozen (GIMP_DATA (palette)))
g_signal_emit (palette, signals[ENTRY_CHANGED], 0, position);

View file

@ -43,10 +43,15 @@ struct _GimpPalette
{
GimpData parent_instance;
GList *colors;
gint n_colors;
/* Palette colors can be restricted to a given format. If NULL, then the
* palette can be a mix of color models and color spaces.
*/
const Babl *format;
gint n_columns;
GList *colors;
gint n_colors;
gint n_columns;
};
struct _GimpPaletteClass
@ -64,6 +69,10 @@ GimpData * gimp_palette_new (GimpContext *context,
const gchar *name);
GimpData * gimp_palette_get_standard (GimpContext *context);
void gimp_palette_restrict_format (GimpPalette *palette,
const Babl *format);
const Babl * gimp_palette_get_restriction (GimpPalette *palette);
GList * gimp_palette_get_colors (GimpPalette *palette);
gint gimp_palette_get_n_colors (GimpPalette *palette);