[gimp] Fix #4560 - file-xpm saving unused transparency



commit 22bedfc3769ec14b5b901680337b0f2a680d69b5
Author: space pudim <rogi skylittlesystem org>
Date:   Sat Feb 1 17:00:07 2020 +0000

    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.
    
    (cherry picked from commit 0a9bb2839eddfc272d78ce63626665f2810b80f4)

 plug-ins/common/file-xpm.c | 33 ++++++++++++++++++++++++++++-----
 1 file changed, 28 insertions(+), 5 deletions(-)
---
diff --git a/plug-ins/common/file-xpm.c b/plug-ins/common/file-xpm.c
index 3fa7bfbb42..41dd853b29 100644
--- a/plug-ins/common/file-xpm.c
+++ b/plug-ins/common/file-xpm.c
@@ -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)
@@ -622,6 +624,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 (GFile         *file,
             GimpImage     *image,
@@ -637,6 +647,7 @@ save_image (GFile         *file,
   gint       *indexno;
   gboolean    indexed;
   gboolean    alpha;
+  gboolean    alpha_used = FALSE;
   XpmColor   *colormap;
   gchar      *filename;
   XpmImage   *xpm_image;
@@ -741,6 +752,7 @@ save_image (GFile         *file,
               if (a < threshold)
                 {
                   *(idata++) = 0;
+                  alpha_used = TRUE;
                 }
               else
                 {
@@ -770,6 +782,17 @@ save_image (GFile         *file,
 
   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, &ncolors);
@@ -777,17 +800,17 @@ save_image (GFile         *file,
 
       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;
@@ -809,7 +832,7 @@ save_image (GFile         *file,
       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);


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]