]> granicus.if.org Git - imagemagick/commitdiff
https://github.com/ImageMagick/ImageMagick/issues/1684
authorCristy <urban-warrior@imagemagick.org>
Mon, 2 Sep 2019 13:24:10 +0000 (09:24 -0400)
committerCristy <urban-warrior@imagemagick.org>
Mon, 2 Sep 2019 13:24:10 +0000 (09:24 -0400)
coders/xpm.c

index 2e06ee715b1def520304c0815d5f99cb2fdded41..722d65d27d9a8549c59930591cbc02eb8549c205 100644 (file)
 #include "MagickCore/threshold.h"
 #include "MagickCore/utility.h"
 \f
+/*
+  Global declarations.
+*/
+static SplayTreeInfo
+  *xpm_symbolic = (SplayTreeInfo *) NULL;
+\f
 /*
   Forward declarations.
 */
@@ -158,7 +164,11 @@ static ssize_t CopyXPMColor(char *destination,const char *source,size_t length)
 
   p=source;
   while (length-- && (*p != '\0'))
+  {
+    if (*p == '"')
+      break;
     *destination++=(*p++);
+  }
   if (length != 0)
     *destination='\0';
   return((ssize_t) (p-source));
@@ -385,6 +395,9 @@ static Image *ReadXPMImage(const ImageInfo *image_info,ExceptionInfo *exception)
   next=NextXPMLine(xpm_buffer);
   for (j=0; (j < (ssize_t) image->colors) && (next != (char *) NULL); j++)
   {
+    char
+      symbolic[MagickPathExtent];
+
     p=next;
     next=NextXPMLine(p);
     if (next == (char *) NULL)
@@ -400,6 +413,7 @@ static Image *ReadXPMImage(const ImageInfo *image_info,ExceptionInfo *exception)
     q=(char *) NULL;
     if (strlen(p) > width)
       q=ParseXPMColor(p+width,MagickTrue);
+    *symbolic='\0';
     if (q != (char *) NULL)
       {
         while ((isspace((int) ((unsigned char) *q)) == 0) && (*q != '\0'))
@@ -409,10 +423,15 @@ static Image *ReadXPMImage(const ImageInfo *image_info,ExceptionInfo *exception)
         (void) CopyXPMColor(target,q,MagickMin((size_t) (next-q),
           MagickPathExtent-1));
         q=ParseXPMColor(target,MagickFalse);
+        (void) CopyXPMColor(symbolic,q,MagickMin((size_t) (next-q),
+          MagickPathExtent-1));
         if (q != (char *) NULL)
           *q='\0';
       }
     StripString(target);
+    if (*symbolic != '\0')
+      (void) AddValueToSplayTree(xpm_symbolic,ConstantString(target),
+        ConstantString(symbolic));
     grey=strstr(target,"grey");
     if (grey != (char *) NULL)
       grey[2]='a';
@@ -519,6 +538,9 @@ ModuleExport size_t RegisterXPMImage(void)
   MagickInfo
     *entry;
 
+  if (xpm_symbolic == (SplayTreeInfo *) NULL)
+    xpm_symbolic=NewSplayTree(CompareSplayTreeString,RelinquishMagickMemory,
+      RelinquishMagickMemory);
   entry=AcquireMagickInfo("XPM","PICON","Personal Icon");
   entry->decoder=(DecodeImageHandler *) ReadXPMImage;
   entry->encoder=(EncodeImageHandler *) WritePICONImage;
@@ -563,6 +585,8 @@ ModuleExport void UnregisterXPMImage(void)
   (void) UnregisterMagickInfo("PICON");
   (void) UnregisterMagickInfo("PM");
   (void) UnregisterMagickInfo("XPM");
+  if (xpm_symbolic != (SplayTreeInfo *) NULL)
+    xpm_symbolic=DestroySplayTree(xpm_symbolic);
 }
 \f
 /*
@@ -764,9 +788,9 @@ static MagickBooleanType WritePICONImage(const ImageInfo *image_info,
         picon->colormap,(size_t) colors,sizeof(*picon->colormap));
       if (picon->colormap == (PixelInfo *) NULL)
         ThrowWriterException(ResourceLimitError,"MemoryAllocationError");
-      picon->colormap[colors-1].red=0;
-      picon->colormap[colors-1].green=0;
-      picon->colormap[colors-1].blue=0;
+      picon->colormap[colors-1].red=0.0;
+      picon->colormap[colors-1].green=0.0;
+      picon->colormap[colors-1].blue=0.0;
       picon->colormap[colors-1].alpha=TransparentAlpha;
       for (y=0; y < (ssize_t) picon->rows; y++)
       {
@@ -1041,6 +1065,9 @@ static MagickBooleanType WriteXPMImage(const ImageInfo *image_info,Image *image,
   GetPixelInfo(image,&pixel);
   for (i=0; i < (ssize_t) image->colors; i++)
   {
+    const char
+      *symbolic;
+
     /*
       Define XPM color.
     */
@@ -1062,8 +1089,13 @@ static MagickBooleanType WriteXPMImage(const ImageInfo *image_info,Image *image,
       symbol[j]=Cixel[k];
     }
     symbol[j]='\0';
-    (void) FormatLocaleString(buffer,MagickPathExtent,
-      "\"%.1024s c %.1024s\",\n",symbol,name);
+    symbolic=GetValueFromSplayTree(xpm_symbolic,name);
+    if (symbolic == (const char *) NULL)
+      (void) FormatLocaleString(buffer,MagickPathExtent,
+        "\"%.1024s c %.1024s\",\n",symbol,name);
+    else
+      (void) FormatLocaleString(buffer,MagickPathExtent,
+        "\"%.1024s c %.1024s %.1024s\",\n",symbol,name,symbolic);
     (void) WriteBlobString(image,buffer);
   }
   /*