xcf: Save/Load color property for NDE filters

This commit is contained in:
Alx Sa 2024-02-13 19:25:18 +00:00
parent 387503507c
commit d055564d26
3 changed files with 178 additions and 2 deletions

View file

@ -2590,6 +2590,114 @@ xcf_load_effect_props (XcfInfo *info,
}
break;
case FILTER_PROP_COLOR:
{
GeglColor *color = gegl_color_new (NULL);
const Babl *format;
gchar *encoding;
guint8 *data = NULL;
gint data_length;
gint profile_data_length;
g_value_init (&filter_prop_value, GEGL_TYPE_COLOR);
xcf_read_string (info, &encoding, 1);
if (! babl_format_exists (encoding))
{
gimp_message (info->gimp, G_OBJECT (info->progress),
GIMP_MESSAGE_WARNING,
"XCF Warning: format \"%s\" for "
"property '%s' of filter '%s' is "
"invalid. The color was discarded.",
encoding, filter->operation_name,
filter_prop_name);
g_free (encoding);
valid_prop_value = FALSE;
break;
}
format = babl_format (encoding);
g_free (encoding);
xcf_read_int32 (info, (guint32 *) &data_length, 1);
if (data_length != babl_format_get_bytes_per_pixel (format))
{
gimp_message (info->gimp, G_OBJECT (info->progress),
GIMP_MESSAGE_WARNING,
"XCF Warning: format \"%s\" for "
"property '%s' of filter '%s' expected "
"%d bpp, but color was serialized as %d "
"bpp. The color was discarded.",
babl_get_name (format), filter->operation_name,
filter_prop_name,
babl_format_get_bytes_per_pixel (format),
data_length);
valid_prop_value = FALSE;
break;
}
data = g_new (guint8, data_length);
xcf_read_int8 (info, data, data_length);
xcf_read_int32 (info, (guint32 *) &profile_data_length, 1);
if (profile_data_length > 0)
{
const Babl *space = NULL;
GimpColorProfile *profile;
guint8 *profile_data;
GError *error = NULL;
profile_data = g_new (guint8, profile_data_length);
xcf_read_int8 (info, profile_data, profile_data_length);
profile = gimp_color_profile_new_from_icc_profile (profile_data,
profile_data_length,
&error);
if (profile)
{
space = gimp_color_profile_get_space (profile,
GIMP_COLOR_RENDERING_INTENT_RELATIVE_COLORIMETRIC,
&error);
if (! space)
{
gimp_message (info->gimp, G_OBJECT (info->progress),
GIMP_MESSAGE_WARNING,
"XCF Warning: failed to create "
"Babl space for serialized color "
"from profile");
g_free (data);
valid_prop_value = FALSE;
break;
}
g_object_unref (profile);
}
else
{
gimp_message (info->gimp, G_OBJECT (info->progress),
GIMP_MESSAGE_WARNING,
"XCF Warning: Invalid profile for "
"serialized color.");
valid_prop_value = FALSE;
break;
}
format = babl_format_with_space (babl_format_get_encoding (format), space);
g_free (profile_data);
}
gegl_color_set_pixel (color, format, data);
g_value_set_object (&filter_prop_value, color);
g_free (data);
g_object_unref (color);
}
break;
default:
gimp_message (info->gimp, G_OBJECT (info->progress),
GIMP_MESSAGE_WARNING,

View file

@ -109,6 +109,7 @@ typedef enum
FILTER_PROP_ENUM = 5,
FILTER_PROP_CONFIG = 6,
FILTER_PROP_UINT = 7,
FILTER_PROP_COLOR = 8,
} FilterPropType;
typedef struct _XcfInfo XcfInfo;

View file

@ -880,6 +880,10 @@ xcf_save_effect_props (XcfInfo *info,
filter_type = FILTER_PROP_INT;
break;
case G_TYPE_UINT:
filter_type = FILTER_PROP_UINT;
break;
case G_TYPE_BOOLEAN:
filter_type = FILTER_PROP_BOOL;
break;
@ -902,9 +906,9 @@ xcf_save_effect_props (XcfInfo *info,
{
filter_type = FILTER_PROP_ENUM;
}
else if (g_type_is_a (G_VALUE_TYPE (&value), G_TYPE_UINT))
else if (g_type_is_a (G_VALUE_TYPE (&value), GEGL_TYPE_COLOR))
{
filter_type = FILTER_PROP_UINT;
filter_type = FILTER_PROP_COLOR;
}
else
{
@ -1809,6 +1813,69 @@ xcf_save_prop (XcfInfo *info,
}
break;
case FILTER_PROP_COLOR:
{
GeglColor *color = g_value_get_object (&filter_value);
if (color)
{
const gchar *encoding;
const Babl *format = gegl_color_get_format (color);
const Babl *space;
GBytes *bytes;
gconstpointer data;
gsize data_length;
int profile_length = 0;
if (babl_format_is_palette (format))
{
guint8 pixel[40];
GeglColor *palette_color;
/* As a special case, we don't want to serialize
* palette colors, because they are just too much
* dependent on external data and cannot be
* deserialized back safely. So we convert them first.
*/
palette_color = gegl_color_duplicate (color);
format = babl_format_with_space ("R'G'B'A u8", format);
gegl_color_get_pixel (palette_color, format, pixel);
gegl_color_set_pixel (color, format, pixel);
g_object_unref (palette_color);
}
encoding = babl_format_get_encoding (format);
xcf_write_string_check_error (info, (gchar **) &encoding, 1, va_end (args));
bytes = gegl_color_get_bytes (color, format);
data = (guint8 *) g_bytes_get_data (bytes, &data_length);
g_bytes_unref (bytes);
xcf_write_int32_check_error (info, (guint32 *) &data_length, 1, ;);
xcf_write_int8_check_error (info, (const guint8 *) data, data_length, ;);
space = babl_format_get_space (format);
if (space != babl_space ("sRGB"))
{
guint8 *profile_data;
profile_data = (guint8 *) babl_space_get_icc (babl_format_get_space (format),
&profile_length);
xcf_write_int32_check_error (info, (guint32 *) &profile_length, 1, ;);
if (profile_data)
xcf_write_int8_check_error (info, (guint8 *) &profile_data, profile_length, ;);
}
else
{
xcf_write_int32_check_error (info, (guint32 *) &profile_length, 1, ;);
}
}
}
break;
case FILTER_PROP_CONFIG:
{
GimpConfig *config = g_value_get_object (&filter_value);