app, pdb: fix gimp_drawable_get_thumbnail() on high-bit depth drawable.

This bug had several causes:

* gimp_drawable_get_thumbnail_data() is pretty crappy as it just returns
  dimensions and bpp. You get no real format information.
* When using it to create a GdkPixbuf, which seems like the most common
  usage, only sRGB (with or without alpha) in 8-bit is supported by
  GdkPixbuf.

So I'm just making sure that private _gimp_drawable_thumbnail() PDB proc
is only returning 8-bit sRGB(A) data. For thumbnailing, this is probably
fine anyway.

Fixes when calling gimp_drawable_get_thumbnail() on an item from a
high-bit depth image:

> LibGimp-CRITICAL **: 20:12:21.028: file ../../../../../../../dev/src/gimp/libgimp/gimppixbuf.c: line 112 (_gimp_pixbuf_from_data): should not be reached
This commit is contained in:
Jehan 2025-10-29 20:13:17 +01:00
parent dcec82a6a1
commit f78a062950
2 changed files with 73 additions and 13 deletions

View file

@ -988,11 +988,41 @@ drawable_thumbnail_invoker (GimpProcedure *procedure,
if (buf)
{
actual_width = gimp_temp_buf_get_width (buf);
actual_height = gimp_temp_buf_get_height (buf);
bpp = babl_format_get_bytes_per_pixel (gimp_temp_buf_get_format (buf));
thumbnail_data = g_bytes_new (gimp_temp_buf_get_data (buf),
gimp_temp_buf_get_data_size (buf));
const Babl *format = gimp_temp_buf_get_format (buf);
const Babl *rgb_format = babl_format ("R'G'B' u8");
const Babl *rgba_format = babl_format ("R'G'B'A u8");
const Babl *fish = NULL;
if (babl_format_has_alpha (format) && format != rgba_format)
{
fish = babl_fish (format, rgba_format);
format = rgba_format;
}
else if (! babl_format_has_alpha (format) && format != rgb_format)
{
fish = babl_fish (format, rgb_format);
format = rgb_format;
}
actual_width = gimp_temp_buf_get_width (buf);
actual_height = gimp_temp_buf_get_height (buf);
bpp = babl_format_get_bytes_per_pixel (format);
if (fish)
{
guchar *data;
gint data_size = bpp * actual_width * actual_height;
data = g_malloc (data_size);
babl_process (fish, gimp_temp_buf_get_data (buf), data, actual_width * actual_height);
thumbnail_data = g_bytes_new (data, data_size);
g_free (data);
}
else
{
thumbnail_data = g_bytes_new (gimp_temp_buf_get_data (buf),
gimp_temp_buf_get_data_size (buf));
}
gimp_temp_buf_unref (buf);
}

View file

@ -959,9 +959,9 @@ HELP
desc => 'The previews height' },
{ name => 'bpp', type => 'int32',
desc => 'The previews bpp' },
{ name => 'thumbnail_data', type => 'bytes',
desc => 'The thumbnail data', }
);
{ name => 'thumbnail_data', type => 'bytes',
desc => 'The thumbnail data', }
);
%invoke = (
code => <<'CODE'
@ -991,11 +991,41 @@ HELP
if (buf)
{
actual_width = gimp_temp_buf_get_width (buf);
actual_height = gimp_temp_buf_get_height (buf);
bpp = babl_format_get_bytes_per_pixel (gimp_temp_buf_get_format (buf));
thumbnail_data = g_bytes_new (gimp_temp_buf_get_data (buf),
gimp_temp_buf_get_data_size (buf));
const Babl *format = gimp_temp_buf_get_format (buf);
const Babl *rgb_format = babl_format ("R'G'B' u8");
const Babl *rgba_format = babl_format ("R'G'B'A u8");
const Babl *fish = NULL;
if (babl_format_has_alpha (format) && format != rgba_format)
{
fish = babl_fish (format, rgba_format);
format = rgba_format;
}
else if (! babl_format_has_alpha (format) && format != rgb_format)
{
fish = babl_fish (format, rgb_format);
format = rgb_format;
}
actual_width = gimp_temp_buf_get_width (buf);
actual_height = gimp_temp_buf_get_height (buf);
bpp = babl_format_get_bytes_per_pixel (format);
if (fish)
{
guchar *data;
gint data_size = bpp * actual_width * actual_height;
data = g_malloc (data_size);
babl_process (fish, gimp_temp_buf_get_data (buf), data, actual_width * actual_height);
thumbnail_data = g_bytes_new (data, data_size);
g_free (data);
}
else
{
thumbnail_data = g_bytes_new (gimp_temp_buf_get_data (buf),
gimp_temp_buf_get_data_size (buf));
}
gimp_temp_buf_unref (buf);
}