Fix #4560 - file-xpm saving unused transparency

The XPM export plugin was saving the color `None` (transparency) to the
exported image palette for all images with an alpha channel, even if the
color was not used on any pixel.

Since it's nice to have `None` as the first color on the palette, mapped
to character ' ', and it could be too wasteful to scan all pixels twice,
the approach taken was to just undo it's premature insertion.
This commit is contained in:
space pudim
2020-02-01 17:00:07 +00:00
committed by Jehan
parent 7e4d4f9d60
commit 0a9bb2839e

View File

@ -15,9 +15,11 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
/* XPM plugin version 1.2.6 */
/* XPM plugin version 1.2.7 */
/*
1.2.7 fixes saving unused transparency (bug #4560)
1.2.6 fixes crash when saving indexed images (bug #109567)
1.2.5 only creates a "None" color entry if the image has alpha (bug #108034)
@ -592,6 +594,14 @@ create_colormap_from_hash (gpointer gkey,
set_XpmImage (user_data, *((int *) value), string);
}
static void
decrement_hash_values (gpointer gkey,
gpointer value,
gpointer user_data)
{
--(*((guint*) value));
}
static gboolean
save_image (const gchar *filename,
gint32 image_ID,
@ -606,6 +616,7 @@ save_image (const gchar *filename,
gint *indexno;
gboolean indexed;
gboolean alpha;
gboolean alpha_used = FALSE;
XpmColor *colormap;
XpmImage *image;
guint *ibuff = NULL;
@ -705,6 +716,7 @@ save_image (const gchar *filename,
if (a < threshold)
{
*(idata++) = 0;
alpha_used = TRUE;
}
else
{
@ -734,6 +746,17 @@ save_image (const gchar *filename,
g_free (buf);
/* remove alpha if not actually used */
if (alpha && !alpha_used)
{
gint i;
--ncolors;
for (i = 0; i < width * height; ++i)
--ibuff[i];
g_hash_table_foreach (hash, decrement_hash_values, NULL);
}
if (indexed)
{
guchar *cmap = gimp_image_get_colormap (image_ID, &ncolors);
@ -741,17 +764,17 @@ save_image (const gchar *filename,
c = cmap;
if (alpha)
if (alpha_used)
ncolors++;
colormap = g_new (XpmColor, ncolors);
cpp =
1 + (gdouble) log (ncolors) / (gdouble) log (sizeof (linenoise) - 1.0);
if (alpha)
if (alpha_used)
set_XpmImage (colormap, 0, "None");
for (i = alpha ? 1 : 0; i < ncolors; i++)
for (i = alpha_used ? 1 : 0; i < ncolors; i++)
{
gchar *string;
guchar r, g, b;
@ -773,7 +796,7 @@ save_image (const gchar *filename,
cpp =
1 + (gdouble) log (ncolors) / (gdouble) log (sizeof (linenoise) - 1.0);
if (alpha)
if (alpha_used)
set_XpmImage (colormap, 0, "None");
g_hash_table_foreach (hash, create_colormap_from_hash, colormap);