From 5e8f4f5e00f8a909990098830ff767607a5876fd Mon Sep 17 00:00:00 2001 From: Jehan Date: Wed, 29 Nov 2023 13:54:00 +0100 Subject: [PATCH] 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). --- app/core/gimpimage-color-profile.c | 52 ++++++++------------------ app/core/gimppalette.c | 60 ++++++++++++++++++++++++++++++ app/core/gimppalette.h | 15 ++++++-- 3 files changed, 87 insertions(+), 40 deletions(-) diff --git a/app/core/gimpimage-color-profile.c b/app/core/gimpimage-color-profile.c index a9471f9327..aba497c2ae 100644 --- a/app/core/gimpimage-color-profile.c +++ b/app/core/gimpimage-color-profile.c @@ -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 diff --git a/app/core/gimppalette.c b/app/core/gimppalette.c index f2c7ec26fc..6620aa9650 100644 --- a/app/core/gimppalette.c +++ b/app/core/gimppalette.c @@ -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); diff --git a/app/core/gimppalette.h b/app/core/gimppalette.h index ee4ad85f21..e159ad89d8 100644 --- a/app/core/gimppalette.h +++ b/app/core/gimppalette.h @@ -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);