]> granicus.if.org Git - imagemagick/blobdiff - magick/property.c
(no commit message)
[imagemagick] / magick / property.c
index 7cf2c2559eb9f5158c84ee4acb67d783cb1d84ed..49dc1cdd7360b19a41ade621ca3fc605f8a56a00 100644 (file)
@@ -17,7 +17,7 @@
 %                                 March 2000                                  %
 %                                                                             %
 %                                                                             %
-%  Copyright 1999-2010 ImageMagick Studio LLC, a non-profit organization      %
+%  Copyright 1999-2011 ImageMagick Studio LLC, a non-profit organization      %
 %  dedicated to making software imaging solutions freely available.           %
 %                                                                             %
 %  You may not use this file except in compliance with the License.  You may  %
@@ -75,6 +75,7 @@
 #include "magick/string-private.h"
 #include "magick/token.h"
 #include "magick/utility.h"
+#include "magick/version.h"
 #include "magick/xml-tree.h"
 \f
 /*
@@ -303,7 +304,7 @@ MagickExport void DestroyImageProperties(Image *image)
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 %
 %  FormatImageProperty() permits formatted property/value pairs to be saved as
-%  an image proporty.
+%  an image property.
 %
 %  The format of the FormatImageProperty method is:
 %
@@ -381,10 +382,10 @@ MagickExport MagickBooleanType FormatImageProperty(Image *image,
 */
 
 static char
-  *TracePSClippath(const unsigned char *,size_t,const unsigned long,
-    const unsigned long),
-  *TraceSVGClippath(const unsigned char *,size_t,const unsigned long,
-    const unsigned long);
+  *TracePSClippath(const unsigned char *,size_t,const size_t,
+    const size_t),
+  *TraceSVGClippath(const unsigned char *,size_t,const size_t,
+    const size_t);
 
 static MagickBooleanType GetIPTCProperty(const Image *image,const char *key)
 {
@@ -400,7 +401,7 @@ static MagickBooleanType GetIPTCProperty(const Image *image,const char *key)
     dataset,
     record;
 
-  register long
+  register ssize_t
     i;
 
   size_t
@@ -415,10 +416,10 @@ static MagickBooleanType GetIPTCProperty(const Image *image,const char *key)
   if (count != 2)
     return(MagickFalse);
   attribute=(char *) NULL;
-  for (i=0; i < (long) GetStringInfoLength(profile); i+=(long) length)
+  for (i=0; i < (ssize_t) GetStringInfoLength(profile); i+=(ssize_t) length)
   {
     length=1;
-    if ((long) GetStringInfoDatum(profile)[i] != 0x1c)
+    if ((ssize_t) GetStringInfoDatum(profile)[i] != 0x1c)
       continue;
     length=(size_t) (GetStringInfoDatum(profile)[i+3] << 8);
     length|=GetStringInfoDatum(profile)[i+4];
@@ -451,7 +452,7 @@ static MagickBooleanType GetIPTCProperty(const Image *image,const char *key)
   return(MagickTrue);
 }
 
-static inline long MagickMax(const long x,const long y)
+static inline ssize_t MagickMax(const ssize_t x,const ssize_t y)
 {
   if (x > y)
     return(x);
@@ -470,19 +471,19 @@ static inline int ReadPropertyByte(const unsigned char **p,size_t *length)
   return(c);
 }
 
-static inline unsigned long ReadPropertyMSBLong(const unsigned char **p,
+static inline size_t ReadPropertyMSBLong(const unsigned char **p,
   size_t *length)
 {
   int
     c;
 
-  register long
+  register ssize_t
     i;
 
   unsigned char
     buffer[4];
 
-  unsigned long
+  size_t
     value;
 
   if (*length < 4)
@@ -493,7 +494,7 @@ static inline unsigned long ReadPropertyMSBLong(const unsigned char **p,
     (*length)--;
     buffer[i]=(unsigned char) c;
   }
-  value=(unsigned long) (buffer[0] << 24);
+  value=(size_t) (buffer[0] << 24);
   value|=buffer[1] << 16;
   value|=buffer[2] << 8;
   value|=buffer[3];
@@ -506,7 +507,7 @@ static inline unsigned short ReadPropertyMSBShort(const unsigned char **p,
   int
     c;
 
-  register long
+  register ssize_t
     i;
 
   unsigned char
@@ -543,25 +544,25 @@ static MagickBooleanType Get8BIMProperty(const Image *image,const char *key)
     *info;
 
   long
-    id,
     start,
-    stop,
-    sub_number;
+    stop;
 
   MagickBooleanType
     status;
 
-  register long
+  register ssize_t
     i;
 
   ssize_t
-    count;
+    count,
+    id,
+    sub_number;
 
   size_t
     length;
 
   /*
-    There's no newlines in path names, so it's safe as terminator.
+    There are no newlines in path names, so it's safe as terminator.
   */
   profile=GetImageProfile(image,"8bim");
   if (profile == (StringInfo *) NULL)
@@ -576,7 +577,7 @@ static MagickBooleanType Get8BIMProperty(const Image *image,const char *key)
     *name='\0';
   sub_number=1;
   if (*name == '#')
-    sub_number=StringToLong(&name[1]);
+    sub_number=(ssize_t) StringToLong(&name[1]);
   sub_number=MagickMax(sub_number,1L);
   resource=(char *) NULL;
   status=MagickFalse;
@@ -592,10 +593,10 @@ static MagickBooleanType Get8BIMProperty(const Image *image,const char *key)
       continue;
     if (ReadPropertyByte(&info,&length) != (unsigned char) 'M')
       continue;
-    id=(long) ReadPropertyMSBShort(&info,&length);
-    if (id < start)
+    id=(ssize_t) ReadPropertyMSBShort(&info,&length);
+    if (id < (ssize_t) start)
       continue;
-    if (id > stop)
+    if (id > (ssize_t) stop)
       continue;
     if (resource != (char *) NULL)
       resource=DestroyString(resource);
@@ -608,14 +609,14 @@ static MagickBooleanType Get8BIMProperty(const Image *image,const char *key)
             sizeof(*resource));
         if (resource != (char *) NULL)
           {
-            for (i=0; i < (long) count; i++)
+            for (i=0; i < (ssize_t) count; i++)
               resource[i]=(char) ReadPropertyByte(&info,&length);
             resource[count]='\0';
           }
       }
     if ((count & 0x01) == 0)
       (void) ReadPropertyByte(&info,&length);
-    count=(ssize_t) ReadPropertyMSBLong(&info,&length);
+    count=(ssize_t) ((int) ReadPropertyMSBLong(&info,&length));
     if ((*name != '\0') && (*name != '#'))
       if ((resource == (char *) NULL) || (LocaleCompare(name,resource) != 0))
         {
@@ -691,21 +692,21 @@ static inline unsigned short ReadPropertyShort(const EndianType endian,
   return((unsigned short) (value & 0xffff));
 }
 
-static inline unsigned long ReadPropertyLong(const EndianType endian,
+static inline size_t ReadPropertyLong(const EndianType endian,
   const unsigned char *buffer)
 {
-  unsigned long
+  size_t
     value;
 
   if (endian == MSBEndian)
     {
-      value=(unsigned long) ((buffer[0] << 24) | (buffer[1] << 16) |
+      value=(size_t) ((buffer[0] << 24) | (buffer[1] << 16) |
         (buffer[2] << 8) | buffer[3]);
-      return((unsigned long) (value & 0xffffffff));
+      return((size_t) (value & 0xffffffff));
     }
-  value=(unsigned long) ((buffer[3] << 24) | (buffer[2] << 16) |
+  value=(size_t) ((buffer[3] << 24) | (buffer[2] << 16) |
     (buffer[1] << 8 ) | (buffer[0]));
-  return((unsigned long) (value & 0xffffffff));
+  return((size_t) (value & 0xffffffff));
 }
 
 static MagickBooleanType GetEXIFProperty(const Image *image,
@@ -732,7 +733,7 @@ static MagickBooleanType GetEXIFProperty(const Image *image,
 
 #define EXIFMultipleValues(size, format, arg) \
 { \
-   long \
+   ssize_t \
      component; \
  \
    size_t \
@@ -758,7 +759,7 @@ static MagickBooleanType GetEXIFProperty(const Image *image,
 
 #define EXIFMultipleFractions(size, format, arg1, arg2) \
 { \
-   long \
+   ssize_t \
      component; \
  \
    size_t \
@@ -787,14 +788,14 @@ static MagickBooleanType GetEXIFProperty(const Image *image,
     const unsigned char
       *directory;
 
-    unsigned long
+    size_t
       entry,
       offset;
   } DirectoryInfo;
 
   typedef struct _TagInfo
   {
-    unsigned long
+    size_t
       tag;
 
     const char
@@ -1090,30 +1091,29 @@ static MagickBooleanType GetEXIFProperty(const Image *image,
   EndianType
     endian;
 
-  long
-    all,
-    id,
-    level,
-    tag_value;
+  MagickBooleanType
+    status;
 
-  register long
+  register ssize_t
     i;
 
   size_t
-    length;
+    entry,
+    length,
+    number_entries,
+    tag_offset,
+    tag;
 
   ssize_t
-    offset;
+    all,
+    id,
+    level,
+    offset,
+    tag_value;
 
   static int
     tag_bytes[] = {0, 1, 1, 2, 4, 8, 1, 1, 2, 4, 8, 4, 8};
 
-  unsigned long
-    entry,
-    number_entries,
-    tag_offset,
-    tag;
-
   /*
     If EXIF data exists, then try to parse the request for a tag.
   */
@@ -1166,7 +1166,7 @@ static MagickBooleanType GetEXIFProperty(const Image *image,
       n/=4;
       do
       {
-        for (i=(long) n-1L; i >= 0; i--)
+        for (i=(ssize_t) n-1L; i >= 0; i--)
         {
           c=(*property++);
           tag<<=4;
@@ -1195,7 +1195,7 @@ static MagickBooleanType GetEXIFProperty(const Image *image,
           break;
         if (LocaleCompare(EXIFTag[i].description,property) == 0)
           {
-            tag=(unsigned long) EXIFTag[i].tag;
+            tag=(size_t) EXIFTag[i].tag;
             break;
           }
       }
@@ -1224,7 +1224,7 @@ static MagickBooleanType GetEXIFProperty(const Image *image,
   }
   if (length < 16)
     return(MagickFalse);
-  id=(long) ReadPropertyShort(LSBEndian,exif);
+  id=(ssize_t) ReadPropertyShort(LSBEndian,exif);
   endian=LSBEndian;
   if (id == 0x4949)
     endian=LSBEndian;
@@ -1238,12 +1238,13 @@ static MagickBooleanType GetEXIFProperty(const Image *image,
   /*
     This the offset to the first IFD.
   */
-  offset=(ssize_t) ReadPropertyLong(endian,exif+4);
+  offset=(ssize_t) ((int) ReadPropertyLong(endian,exif+4));
   if ((size_t) offset >= length)
     return(MagickFalse);
   /*
     Set the pointer to the first IFD and follow it were it leads.
   */
+  status=MagickFalse;
   directory=exif+offset;
   level=0;
   entry=0;
@@ -1266,25 +1267,23 @@ static MagickBooleanType GetEXIFProperty(const Image *image,
     number_entries=ReadPropertyShort(endian,directory);
     for ( ; entry < number_entries; entry++)
     {
-      long
-        components;
-
       register unsigned char
         *p,
         *q;
 
       size_t
+        format,
         number_bytes;
 
-      unsigned long
-        format;
+      ssize_t
+        components;
 
       q=(unsigned char *) (directory+2+(12*entry));
-      tag_value=(long) ReadPropertyShort(endian,q)+tag_offset;
-      format=(unsigned long) ReadPropertyShort(endian,q+2);
+      tag_value=(ssize_t) (ReadPropertyShort(endian,q)+tag_offset);
+      format=(size_t) ReadPropertyShort(endian,q+2);
       if (format >= (sizeof(tag_bytes)/sizeof(*tag_bytes)))
         break;
-      components=(long) ReadPropertyLong(endian,q+4);
+      components=(ssize_t) ((int) ReadPropertyLong(endian,q+4));
       number_bytes=(size_t) components*tag_bytes[format];
       if (number_bytes <= 4)
         p=q+8;
@@ -1296,12 +1295,12 @@ static MagickBooleanType GetEXIFProperty(const Image *image,
           /*
             The directory entry contains an offset.
           */
-          offset=(ssize_t) ReadPropertyLong(endian,q+8);
+          offset=(ssize_t) ((int) ReadPropertyLong(endian,q+8));
           if ((size_t) (offset+number_bytes) > length)
             continue;
           p=(unsigned char *) (exif+offset);
         }
-      if ((all != 0) || (tag == (unsigned long) tag_value))
+      if ((all != 0) || (tag == (size_t) tag_value))
         {
           char
             buffer[MaxTextExtent],
@@ -1312,13 +1311,13 @@ static MagickBooleanType GetEXIFProperty(const Image *image,
             case EXIF_FMT_BYTE:
             case EXIF_FMT_UNDEFINED:
             {
-              EXIFMultipleValues(1,"%lu",(unsigned long)
+              EXIFMultipleValues(1,"%.20g",(double)
                 (*(unsigned char *) p1));
               break;
             }
             case EXIF_FMT_SBYTE:
             {
-              EXIFMultipleValues(1,"%ld",(long) (*(signed char *) p1));
+              EXIFMultipleValues(1,"%.20g",(double) (*(signed char *) p1));
               break;
             }
             case EXIF_FMT_SSHORT:
@@ -1333,23 +1332,27 @@ static MagickBooleanType GetEXIFProperty(const Image *image,
             }
             case EXIF_FMT_ULONG:
             {
-              EXIFMultipleValues(4,"%lu",ReadPropertyLong(endian,p1));
+              EXIFMultipleValues(4,"%.20g",(double)
+                ReadPropertyLong(endian,p1));
               break;
             }
             case EXIF_FMT_SLONG:
             {
-              EXIFMultipleValues(4,"%ld",ReadPropertyLong(endian,p1));
+              EXIFMultipleValues(4,"%.20g",(double)
+                ReadPropertyLong(endian,p1));
               break;
             }
             case EXIF_FMT_URATIONAL:
             {
-              EXIFMultipleFractions(8,"%ld/%ld",ReadPropertyLong(endian,p1),
+              EXIFMultipleFractions(8,"%.20g/%.20g",(double)
+                ReadPropertyLong(endian,p1),(double)
                 ReadPropertyLong(endian,p1+4));
               break;
             }
             case EXIF_FMT_SRATIONAL:
             {
-              EXIFMultipleFractions(8,"%ld/%ld",ReadPropertyLong(endian,p1),
+              EXIFMultipleFractions(8,"%.20g/%.20g",(double)
+                ReadPropertyLong(endian,p1),(double)
                 ReadPropertyLong(endian,p1+4));
               break;
             }
@@ -1372,10 +1375,10 @@ static MagickBooleanType GetEXIFProperty(const Image *image,
                   sizeof(*value));
               if (value != (char *) NULL)
                 {
-                  register long
+                  register ssize_t
                     i;
 
-                  for (i=0; i < (long) number_bytes; i++)
+                  for (i=0; i < (ssize_t) number_bytes; i++)
                   {
                     value[i]='.';
                     if ((isprint((int) p[i]) != 0) || (p[i] == '\0'))
@@ -1402,7 +1405,7 @@ static MagickBooleanType GetEXIFProperty(const Image *image,
                   const char
                     *description;
 
-                  register long
+                  register ssize_t
                     i;
 
                   description="unknown";
@@ -1410,7 +1413,7 @@ static MagickBooleanType GetEXIFProperty(const Image *image,
                   {
                     if (EXIFTag[i].tag == 0)
                       break;
-                    if ((long) EXIFTag[i].tag == tag_value)
+                    if ((ssize_t) EXIFTag[i].tag == tag_value)
                       {
                         description=EXIFTag[i].description;
                         break;
@@ -1424,11 +1427,11 @@ static MagickBooleanType GetEXIFProperty(const Image *image,
                 {
                   if (tag_value < 0x10000)
                     (void) FormatMagickString(key,MaxTextExtent,"#%04lx",
-                      tag_value);
+                      (unsigned long) tag_value);
                   else
                     if (tag_value < 0x20000)
                       (void) FormatMagickString(key,MaxTextExtent,"@%04lx",
-                        tag_value & 0xffff);
+                        (unsigned long) (tag_value & 0xffff));
                     else
                       (void) FormatMagickString(key,MaxTextExtent,"unknown");
                   break;
@@ -1441,6 +1444,7 @@ static MagickBooleanType GetEXIFProperty(const Image *image,
               if (p == (const char *) NULL)
                 (void) SetImageProperty((Image *) image,key,value);
               value=DestroyString(value);
+              status=MagickTrue;
             }
         }
         if ((tag_value == TAG_EXIF_OFFSET) ||
@@ -1453,7 +1457,7 @@ static MagickBooleanType GetEXIFProperty(const Image *image,
             offset=(size_t) ReadPropertyLong(endian,p);
             if ((offset < length) && (level < (MaxDirectoryStack-2)))
               {
-                unsigned long
+                size_t
                   tag_offset1;
 
                 tag_offset1=(tag_value == TAG_GPS_OFFSET) ? 0x10000UL : 0UL;
@@ -1483,7 +1487,7 @@ static MagickBooleanType GetEXIFProperty(const Image *image,
           }
     }
   } while (level > 0);
-  return(MagickTrue);
+  return(status);
 }
 
 static MagickBooleanType GetXMPProperty(const Image *image,
@@ -1564,18 +1568,13 @@ static MagickBooleanType GetXMPProperty(const Image *image,
 }
 
 static char *TracePSClippath(const unsigned char *blob,size_t length,
-  const unsigned long magick_unused(columns),
-  const unsigned long magick_unused(rows))
+  const size_t magick_unused(columns),
+  const size_t magick_unused(rows))
 {
   char
     *path,
     *message;
 
-  long
-    knot_count,
-    selector,
-    y;
-
   MagickBooleanType
     in_subpath;
 
@@ -1584,10 +1583,15 @@ static char *TracePSClippath(const unsigned char *blob,size_t length,
     last[3],
     point[3];
 
-  register long
+  register ssize_t
     i,
     x;
 
+  ssize_t
+    knot_count,
+    selector,
+    y;
+
   path=AcquireString((char *) NULL);
   if (path == (char *) NULL)
     return((char *) NULL);
@@ -1624,7 +1628,7 @@ static char *TracePSClippath(const unsigned char *blob,size_t length,
   in_subpath=MagickFalse;
   while (length > 0)
   {
-    selector=(long) ReadPropertyMSBShort(&blob,&length);
+    selector=(ssize_t) ReadPropertyMSBShort(&blob,&length);
     switch (selector)
     {
       case 0:
@@ -1639,7 +1643,7 @@ static char *TracePSClippath(const unsigned char *blob,size_t length,
         /*
           Expected subpath length record.
         */
-        knot_count=(long) ReadPropertyMSBShort(&blob,&length);
+        knot_count=(ssize_t) ReadPropertyMSBShort(&blob,&length);
         blob+=22;
         length-=22;
         break;
@@ -1663,18 +1667,18 @@ static char *TracePSClippath(const unsigned char *blob,size_t length,
         */
         for (i=0; i < 3; i++)
         {
-          unsigned long 
+          size_t
             xx,
             yy;
 
           yy=ReadPropertyMSBLong(&blob,&length);
           xx=ReadPropertyMSBLong(&blob,&length);
-          x=(long) xx;
+          x=(ssize_t) xx;
           if (xx > 2147483647)
-            x=xx-4294967295-1;
-          y=(long) yy;
+            x=(ssize_t) xx-4294967295-1;
+          y=(ssize_t) yy;
           if (yy > 2147483647)
-            y=yy-4294967295-1;
+            y=(ssize_t) yy-4294967295-1;
           point[i].x=(double) x/4096/4096;
           point[i].y=1.0-(double) y/4096/4096;
         }
@@ -1773,18 +1777,12 @@ static char *TracePSClippath(const unsigned char *blob,size_t length,
 }
 
 static char *TraceSVGClippath(const unsigned char *blob,size_t length,
-  const unsigned long columns,const unsigned long rows)
+  const size_t columns,const size_t rows)
 {
   char
     *path,
     *message;
 
-  long
-    knot_count,
-    selector,
-    x,
-    y;
-
   MagickBooleanType
     in_subpath;
 
@@ -1793,9 +1791,15 @@ static char *TraceSVGClippath(const unsigned char *blob,size_t length,
     last[3],
     point[3];
 
-  register long
+  register ssize_t
     i;
 
+  ssize_t
+    knot_count,
+    selector,
+    x,
+    y;
+
   path=AcquireString((char *) NULL);
   if (path == (char *) NULL)
     return((char *) NULL);
@@ -1804,7 +1808,7 @@ static char *TraceSVGClippath(const unsigned char *blob,size_t length,
     "<?xml version=\"1.0\" encoding=\"iso-8859-1\"?>\n");
   (void) ConcatenateString(&path,message);
   (void) FormatMagickString(message,MaxTextExtent,
-    "<svg width=\"%lu\" height=\"%lu\">\n",columns,rows);
+    "<svg width=\"%.20g\" height=\"%.20g\">\n",(double) columns,(double) rows);
   (void) ConcatenateString(&path,message);
   (void) FormatMagickString(message,MaxTextExtent,"<g>\n");
   (void) ConcatenateString(&path,message);
@@ -1821,7 +1825,7 @@ static char *TraceSVGClippath(const unsigned char *blob,size_t length,
   in_subpath=MagickFalse;
   while (length != 0)
   {
-    selector=(long) ReadPropertyMSBShort(&blob,&length);
+    selector=(ssize_t) ReadPropertyMSBShort(&blob,&length);
     switch (selector)
     {
       case 0:
@@ -1836,7 +1840,7 @@ static char *TraceSVGClippath(const unsigned char *blob,size_t length,
         /*
           Expected subpath length record.
         */
-        knot_count=(long) ReadPropertyMSBShort(&blob,&length);
+        knot_count=(ssize_t) ReadPropertyMSBShort(&blob,&length);
         blob+=22;
         length-=22;
         break;
@@ -1860,18 +1864,18 @@ static char *TraceSVGClippath(const unsigned char *blob,size_t length,
         */
         for (i=0; i < 3; i++)
         {
-          unsigned long 
+          size_t
             xx,
             yy;
 
           yy=ReadPropertyMSBLong(&blob,&length);
           xx=ReadPropertyMSBLong(&blob,&length);
-          x=(long) xx;
+          x=(ssize_t) xx;
           if (xx > 2147483647)
-            x=xx-4294967295-1;
-          y=(long) yy;
+            x=(ssize_t) xx-4294967295-1;
+          y=(ssize_t) yy;
           if (yy > 2147483647)
-            y=yy-4294967295-1;
+            y=(ssize_t) yy-4294967295-1;
           point[i].x=(double) x*columns/4096/4096;
           point[i].y=(double) y*rows/4096/4096;
         }
@@ -1968,22 +1972,25 @@ MagickExport const char *GetImageProperty(const Image *image,
   if (image->debug != MagickFalse)
     (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
   p=(const char *) NULL;
-  if (property == (const char *) NULL)
-    {
-      ResetSplayTreeIterator((SplayTreeInfo *) image->properties);
-      p=(const char *) GetNextValueInSplayTree((SplayTreeInfo *)
-        image->properties);
-      return(p);
-    }
-  if ((image->properties != (void *) NULL) &&
-      (LocaleNCompare("fx:",property,3) != 0))
+  if (image->properties != (void *) NULL)
     {
-      p=(const char *) GetValueFromSplayTree((SplayTreeInfo *)
-        image->properties,property);
-      if (p != (const char *) NULL)
-        return(p);
+      if (property == (const char *) NULL)
+        {
+          ResetSplayTreeIterator((SplayTreeInfo *) image->properties);
+          p=(const char *) GetNextValueInSplayTree((SplayTreeInfo *)
+            image->properties);
+          return(p);
+        }
+      if (LocaleNCompare("fx:",property,3) != 0)
+        {
+          p=(const char *) GetValueFromSplayTree((SplayTreeInfo *)
+            image->properties,property);
+          if (p != (const char *) NULL)
+            return(p);
+        }
     }
-  if (strchr(property,':') == (char *) NULL)
+  if ((property == (const char *) NULL) ||
+      (strchr(property,':') == (char *) NULL))
     return(p);
   exception=(&((Image *) image)->exception);
   switch (*property)
@@ -1992,7 +1999,8 @@ MagickExport const char *GetImageProperty(const Image *image,
     {
       if (LocaleNCompare("8bim:",property,5) == 0)
         {
-          if (Get8BIMProperty(image,property) != MagickFalse)
+          if ((Get8BIMProperty(image,property) != MagickFalse) &&
+              (image->properties != (void *) NULL))
             {
               p=(const char *) GetValueFromSplayTree((SplayTreeInfo *)
                 image->properties,property);
@@ -2006,7 +2014,8 @@ MagickExport const char *GetImageProperty(const Image *image,
     {
       if (LocaleNCompare("exif:",property,5) == 0)
         {
-          if (GetEXIFProperty(image,property) != MagickFalse)
+          if ((GetEXIFProperty(image,property) != MagickFalse) &&
+              (image->properties != (void *) NULL))
             {
               p=(const char *) GetValueFromSplayTree((SplayTreeInfo *)
                 image->properties,property);
@@ -2021,20 +2030,24 @@ MagickExport const char *GetImageProperty(const Image *image,
       if (LocaleNCompare("fx:",property,3) == 0)
         {
           fx_info=AcquireFxInfo(image,property+3);
-          status=FxEvaluateExpression(fx_info,&alpha,exception);
+          status=FxEvaluateChannelExpression(fx_info,DefaultChannels,0,0,&alpha,
+            exception);
           fx_info=DestroyFxInfo(fx_info);
           if (status != MagickFalse)
             {
               char
                 value[MaxTextExtent];
 
-              (void) FormatMagickString(value,MaxTextExtent,"%g",(double)
-                alpha);
+              (void) FormatMagickString(value,MaxTextExtent,"%.*g",
+                GetMagickPrecision(),(double) alpha);
               (void) SetImageProperty((Image *) image,property,value);
             }
-          p=(const char *) GetValueFromSplayTree((SplayTreeInfo *)
-            image->properties,property);
-          return(p);
+          if (image->properties != (void *) NULL)
+            {
+              p=(const char *) GetValueFromSplayTree((SplayTreeInfo *)
+                image->properties,property);
+              return(p);
+            }
         }
       break;
     }
@@ -2043,7 +2056,8 @@ MagickExport const char *GetImageProperty(const Image *image,
     {
       if (LocaleNCompare("iptc:",property,5) == 0)
         {
-          if (GetIPTCProperty(image,property) != MagickFalse)
+          if ((GetIPTCProperty(image,property) != MagickFalse) &&
+              (image->properties != (void *) NULL))
             {
               p=(const char *) GetValueFromSplayTree((SplayTreeInfo *)
                 image->properties,property);
@@ -2099,7 +2113,8 @@ MagickExport const char *GetImageProperty(const Image *image,
     {
       if (LocaleNCompare("xmp:",property,4) == 0)
         {
-          if (GetXMPProperty(image,property) != MagickFalse)
+          if ((GetXMPProperty(image,property) != MagickFalse) &&
+              (image->properties != (void *) NULL))
             {
               p=(const char *) GetValueFromSplayTree((SplayTreeInfo *)
                 image->properties,property);
@@ -2108,6 +2123,8 @@ MagickExport const char *GetImageProperty(const Image *image,
         }
       break;
     }
+    default:
+      break;
   }
   return(p);
 }
@@ -2147,7 +2164,7 @@ MagickExport const char *GetMagickProperty(const ImageInfo *image_info,
     filename[MaxTextExtent];
 
   *value='\0';
-  switch (*(property))
+  switch (*property)
   {
     case 'b':
     {
@@ -2167,7 +2184,7 @@ MagickExport const char *GetMagickProperty(const ImageInfo *image_info,
             Image channels.
           */
           (void) FormatMagickString(value,MaxTextExtent,"%s",
-            MagickOptionToMnemonic(MagickColorspaceOptions,(long)
+            CommandOptionToMnemonic(MagickColorspaceOptions,(ssize_t)
             image->colorspace));
           LocaleLower(value);
           if (image->matte != MagickFalse)
@@ -2186,7 +2203,13 @@ MagickExport const char *GetMagickProperty(const ImageInfo *image_info,
           if (IsGrayImage(image,&image->exception) != MagickFalse)
             colorspace=GRAYColorspace;
           (void) FormatMagickString(value,MaxTextExtent,"%s",
-            MagickOptionToMnemonic(MagickColorspaceOptions,(long) colorspace));
+            CommandOptionToMnemonic(MagickColorspaceOptions,(ssize_t)
+            colorspace));
+          break;
+        }
+      if (LocaleNCompare("copyright",property,9) == 0)
+        {
+          (void) CopyMagickString(value,GetMagickCopyright(),MaxTextExtent);
           break;
         }
       break;
@@ -2195,7 +2218,8 @@ MagickExport const char *GetMagickProperty(const ImageInfo *image_info,
     {
       if (LocaleNCompare("depth",property,5) == 0)
         {
-          (void) FormatMagickString(value,MaxTextExtent,"%lu",image->depth);
+          (void) FormatMagickString(value,MaxTextExtent,"%.20g",(double)
+            image->depth);
           break;
         }
       if (LocaleNCompare("directory",property,9) == 0)
@@ -2221,7 +2245,7 @@ MagickExport const char *GetMagickProperty(const ImageInfo *image_info,
       if (LocaleNCompare("group",property,5) == 0)
         {
           (void) FormatMagickString(value,MaxTextExtent,"0x%lx",
-            image_info->group);
+            (unsigned long) image_info->group);
           break;
         }
       break;
@@ -2230,8 +2254,8 @@ MagickExport const char *GetMagickProperty(const ImageInfo *image_info,
     {
       if (LocaleNCompare("height",property,6) == 0)
         {
-          (void) FormatMagickString(value,MaxTextExtent,"%lu",
-            image->magick_rows != 0 ? image->magick_rows : 256UL);
+          (void) FormatMagickString(value,MaxTextExtent,"%.20g",
+            image->magick_rows != 0 ? (double) image->magick_rows : 256.0);
           break;
         }
       break;
@@ -2276,7 +2300,8 @@ MagickExport const char *GetMagickProperty(const ImageInfo *image_info,
 
           (void) GetImageChannelRange(image,image_info->channel,&minimum,
             &maximum,&image->exception);
-          (void) FormatMagickString(value,MaxTextExtent,"%g",maximum);
+          (void) FormatMagickString(value,MaxTextExtent,"%.*g",
+            GetMagickPrecision(),maximum);
           break;
         }
       if (LocaleNCompare("mean",property,4) == 0)
@@ -2299,7 +2324,8 @@ MagickExport const char *GetMagickProperty(const ImageInfo *image_info,
 
           (void) GetImageChannelRange(image,image_info->channel,&minimum,
             &maximum,&image->exception);
-          (void) FormatMagickString(value,MaxTextExtent,"%g",minimum);
+          (void) FormatMagickString(value,MaxTextExtent,"%.*g",
+            GetMagickPrecision(),minimum);
           break;
         }
       break;
@@ -2315,6 +2341,16 @@ MagickExport const char *GetMagickProperty(const ImageInfo *image_info,
     }
     case 'o':
     {
+      if (LocaleNCompare("opaque",property,6) == 0)
+        {
+          MagickBooleanType
+            opaque;
+
+          opaque=IsOpaqueImage(image,&image->exception);
+          (void) CopyMagickString(value,opaque == MagickFalse ? "false" :
+            "true",MaxTextExtent);
+          break;
+        }
       if (LocaleNCompare("output",property,6) == 0)
         {
           (void) CopyMagickString(value,image_info->filename,MaxTextExtent);
@@ -2326,16 +2362,8 @@ MagickExport const char *GetMagickProperty(const ImageInfo *image_info,
     {
       if (LocaleNCompare("page",property,4) == 0)
         {
-          register const Image
-            *p;
-
-          unsigned long
-            page;
-
-          p=image;
-          for (page=1; GetPreviousImageInList(p) != (Image *) NULL; page++)
-            p=GetPreviousImageInList(p);
-          (void) FormatMagickString(value,MaxTextExtent,"%lu",page);
+          (void) FormatMagickString(value,MaxTextExtent,"%.20g",(double)
+              GetImageIndexInList(image)+1);
           break;
         }
       break;
@@ -2348,20 +2376,21 @@ MagickExport const char *GetMagickProperty(const ImageInfo *image_info,
             format[MaxTextExtent];
 
           (void) FormatMagickSize(GetBlobSize(image),MagickFalse,format);
-          (void) FormatMagickString(value,MaxTextExtent,"%s",format);
+          (void) FormatMagickString(value,MaxTextExtent,"%sB",format);
           break;
         }
       if (LocaleNCompare("scenes",property,6) == 0)
         {
-          (void) FormatMagickString(value,MaxTextExtent,"%lu",
-            (unsigned long) GetImageListLength(image));
+          (void) FormatMagickString(value,MaxTextExtent,"%.20g",(double)
+            GetImageListLength(image));
           break;
         }
       if (LocaleNCompare("scene",property,5) == 0)
         {
-          (void) FormatMagickString(value,MaxTextExtent,"%lu",image->scene);
+          (void) FormatMagickString(value,MaxTextExtent,"%.20g",(double)
+            image->scene);
           if (image_info->number_scenes != 0)
-            (void) FormatMagickString(value,MaxTextExtent,"%lu",
+            (void) FormatMagickString(value,MaxTextExtent,"%.20g",(double)
               image_info->scene);
           break;
         }
@@ -2402,12 +2431,22 @@ MagickExport const char *GetMagickProperty(const ImageInfo *image_info,
         }
       break;
     }
+    case 'v':
+    {
+      if (LocaleNCompare("version",property,7) == 0)
+        {
+          (void) CopyMagickString(value,GetMagickVersion((size_t *) NULL),
+            MaxTextExtent);
+          break;
+        }
+      break;
+    }
     case 'w':
     {
       if (LocaleNCompare("width",property,5) == 0)
         {
-          (void) FormatMagickString(value,MaxTextExtent,"%lu",
-            image->magick_columns != 0 ? image->magick_columns : 256UL);
+          (void) FormatMagickString(value,MaxTextExtent,"%.20g",(double)
+            (image->magick_columns != 0 ? image->magick_columns : 256));
           break;
         }
       break;
@@ -2528,16 +2567,13 @@ MagickExport char *InterpretImageProperties(const ImageInfo *image_info,
   const char
     *value;
 
-  ImageInfo
-    *text_info;
-
   register char
     *q;
 
   register const char
     *p;
 
-  register long
+  register ssize_t
     i;
 
   size_t
@@ -2557,7 +2593,6 @@ MagickExport char *InterpretImageProperties(const ImageInfo *image_info,
   /*
     Translate any embedded format characters.
   */
-  text_info=CloneImageInfo(image_info);
   interpret_text=AcquireString(text);
   extent=MaxTextExtent;
   p=text;
@@ -2610,11 +2645,12 @@ MagickExport char *InterpretImageProperties(const ImageInfo *image_info,
         /*
           File size.
         */
-        (void) FormatMagickString(format,MaxTextExtent,"%lu",(unsigned long)
+        (void) FormatMagickString(format,MaxTextExtent,"%.20g",(double)
           image->extent);
         if (image->extent != (MagickSizeType) ((size_t) image->extent))
           (void) FormatMagickSize(image->extent,MagickFalse,format);
         q+=ConcatenateMagickString(q,format,extent);
+        q+=ConcatenateMagickString(q,"B",extent);
         break;
       }
       case 'c':
@@ -2629,8 +2665,8 @@ MagickExport char *InterpretImageProperties(const ImageInfo *image_info,
         if ((size_t) (q-interpret_text+length+1) >= extent)
           {
             extent+=length;
-            interpret_text=(char *) ResizeQuantumMemory(interpret_text,
-              extent+MaxTextExtent,sizeof(*interpret_text));
+            interpret_text=(char *) ResizeQuantumMemory(interpret_text,extent+
+              MaxTextExtent,sizeof(*interpret_text));
             if (interpret_text == (char *) NULL)
               break;
             q=interpret_text+strlen(interpret_text);
@@ -2695,8 +2731,9 @@ MagickExport char *InterpretImageProperties(const ImageInfo *image_info,
         /*
           Image geometry.
         */
-        q+=FormatMagickString(q,extent,"%lux%lu%+ld%+ld",image->page.width,
-          image->page.height,image->page.x,image->page.y);
+        q+=FormatMagickString(q,extent,"%.20gx%.20g%+.20g%+.20g",(double)
+          image->page.width,(double) image->page.height,(double) image->page.x,
+          (double) image->page.y);
         break;
       }
       case 'h':
@@ -2704,8 +2741,8 @@ MagickExport char *InterpretImageProperties(const ImageInfo *image_info,
         /*
           Image height.
         */
-        q+=FormatMagickString(q,extent,"%lu",image->rows != 0 ? image->rows :
-          image->magick_rows);
+        q+=FormatMagickString(q,extent,"%.20g",(double) (image->rows != 0 ?
+          image->rows : image->magick_rows));
         break;
       }
       case 'i':
@@ -2721,7 +2758,7 @@ MagickExport char *InterpretImageProperties(const ImageInfo *image_info,
         /*
           Number of unique colors.
         */
-        q+=FormatMagickString(q,extent,"%lu",GetNumberColors(image,
+        q+=FormatMagickString(q,extent,"%.20g",(double) GetNumberColors(image,
           (FILE *) NULL,&image->exception));
         break;
       }
@@ -2737,8 +2774,8 @@ MagickExport char *InterpretImageProperties(const ImageInfo *image_info,
         if ((size_t) (q-interpret_text+length+1) >= extent)
           {
             extent+=length;
-            interpret_text=(char *) ResizeQuantumMemory(interpret_text,
-              extent+MaxTextExtent,sizeof(*interpret_text));
+            interpret_text=(char *) ResizeQuantumMemory(interpret_text,extent+
+              MaxTextExtent,sizeof(*interpret_text));
             if (interpret_text == (char *) NULL)
               break;
             q=interpret_text+strlen(interpret_text);
@@ -2767,8 +2804,8 @@ MagickExport char *InterpretImageProperties(const ImageInfo *image_info,
         /*
           Number of images in the list.
         */
-        q+=FormatMagickString(q,extent,"%lu",(unsigned long)
-          GetImageListLength(image));
+        q+=FormatMagickString(q,extent,"%.20g",(double)
+             GetImageListLength(image));
         break;
       }
       case 'o':
@@ -2776,24 +2813,16 @@ MagickExport char *InterpretImageProperties(const ImageInfo *image_info,
         /*
           Image output filename.
         */
-        q+=CopyMagickString(q,text_info->filename,extent);
+        q+=CopyMagickString(q,image_info->filename,extent);
         break;
       }
       case 'p':
       {
-        register const Image
-          *p;
-
-        unsigned long
-          page;
-
         /*
-          Image page number.
+          Image index in list.
         */
-        p=image;
-        for (page=1; GetPreviousImageInList(p) != (Image *) NULL; page++)
-          p=GetPreviousImageInList(p);
-        q+=FormatMagickString(q,extent,"%lu",page);
+        q+=FormatMagickString(q,extent,"%.20g",(double)
+            GetImageIndexInList(image));
         break;
       }
       case 'q':
@@ -2801,7 +2830,8 @@ MagickExport char *InterpretImageProperties(const ImageInfo *image_info,
         /*
           Image depth.
         */
-        q+=FormatMagickString(q,extent,"%lu",image->depth);
+        q+=FormatMagickString(q,extent,"%.20g",(double)
+          MAGICKCORE_QUANTUM_DEPTH);
         break;
       }
       case 'r':
@@ -2815,9 +2845,9 @@ MagickExport char *InterpretImageProperties(const ImageInfo *image_info,
         colorspace=image->colorspace;
         if (IsGrayImage(image,&image->exception) != MagickFalse)
           colorspace=GRAYColorspace;
-        q+=FormatMagickString(q,extent,"%s%s%s",MagickOptionToMnemonic(
-          MagickClassOptions,(long) image->storage_class),
-          MagickOptionToMnemonic(MagickColorspaceOptions,(long) colorspace),
+        q+=FormatMagickString(q,extent,"%s%s%s",CommandOptionToMnemonic(
+          MagickClassOptions,(ssize_t) image->storage_class),
+          CommandOptionToMnemonic(MagickColorspaceOptions,(ssize_t) colorspace),
           image->matte != MagickFalse ? "Matte" : "");
         break;
       }
@@ -2826,10 +2856,10 @@ MagickExport char *InterpretImageProperties(const ImageInfo *image_info,
         /*
           Image scene number.
         */
-        if (text_info->number_scenes == 0)
-          q+=FormatMagickString(q,extent,"%lu",image->scene);
+        if (image_info->number_scenes == 0)
+          q+=FormatMagickString(q,extent,"%.20g",(double) image->scene);
         else
-          q+=FormatMagickString(q,extent,"%lu",text_info->scene);
+          q+=FormatMagickString(q,extent,"%.20g",(double) image_info->scene);
         break;
       }
       case 'u':
@@ -2837,7 +2867,7 @@ MagickExport char *InterpretImageProperties(const ImageInfo *image_info,
         /*
           Unique filename.
         */
-        (void) CopyMagickString(filename,text_info->unique,extent);
+        (void) CopyMagickString(filename,image_info->unique,extent);
         q+=CopyMagickString(q,filename,extent);
         break;
       }
@@ -2846,8 +2876,8 @@ MagickExport char *InterpretImageProperties(const ImageInfo *image_info,
         /*
           Image width.
         */
-        q+=FormatMagickString(q,extent,"%lu",image->columns != 0 ?
-          image->columns : image->magick_columns);
+        q+=FormatMagickString(q,extent,"%.20g",(double) (image->columns != 0 ?
+          image->columns : image->magick_columns));
         break;
       }
       case 'x':
@@ -2856,7 +2886,8 @@ MagickExport char *InterpretImageProperties(const ImageInfo *image_info,
           Image horizontal resolution.
         */
         q+=FormatMagickString(q,extent,"%g %s",image->x_resolution,
-          MagickOptionToMnemonic(MagickResolutionOptions,(long) image->units));
+          CommandOptionToMnemonic(MagickResolutionOptions,(ssize_t)
+            image->units));
         break;
       }
       case 'y':
@@ -2865,7 +2896,8 @@ MagickExport char *InterpretImageProperties(const ImageInfo *image_info,
           Image vertical resolution.
         */
         q+=FormatMagickString(q,extent,"%g %s",image->y_resolution,
-          MagickOptionToMnemonic(MagickResolutionOptions,(long) image->units));
+          CommandOptionToMnemonic(MagickResolutionOptions,(ssize_t)
+          image->units));
         break;
       }
       case 'z':
@@ -2873,7 +2905,7 @@ MagickExport char *InterpretImageProperties(const ImageInfo *image_info,
         /*
           Image depth.
         */
-        q+=FormatMagickString(q,extent,"%lu",image->depth);
+        q+=FormatMagickString(q,extent,"%.20g",(double) image->depth);
         break;
       }
       case 'A':
@@ -2881,8 +2913,8 @@ MagickExport char *InterpretImageProperties(const ImageInfo *image_info,
         /*
           Image alpha channel.
         */
-        q+=FormatMagickString(q,extent,"%s",MagickOptionToMnemonic(
-          MagickBooleanOptions,(long) image->matte));
+        q+=FormatMagickString(q,extent,"%s",CommandOptionToMnemonic(
+          MagickBooleanOptions,(ssize_t) image->matte));
         break;
       }
       case 'C':
@@ -2890,8 +2922,8 @@ MagickExport char *InterpretImageProperties(const ImageInfo *image_info,
         /*
           Image compression method.
         */
-        q+=FormatMagickString(q,extent,"%s",MagickOptionToMnemonic(
-          MagickCompressOptions,(long) image->compression));
+        q+=FormatMagickString(q,extent,"%s",CommandOptionToMnemonic(
+          MagickCompressOptions,(ssize_t) image->compression));
         break;
       }
       case 'D':
@@ -2899,35 +2931,36 @@ MagickExport char *InterpretImageProperties(const ImageInfo *image_info,
         /*
           Image dispose method.
         */
-        q+=FormatMagickString(q,extent,"%s",MagickOptionToMnemonic(
-          MagickDisposeOptions,(long) image->dispose));
+        q+=FormatMagickString(q,extent,"%s",CommandOptionToMnemonic(
+          MagickDisposeOptions,(ssize_t) image->dispose));
         break;
       }
       case 'G':
       {
-        q+=FormatMagickString(q,extent,"%lux%lu",image->magick_columns,
-          image->magick_rows);
+        q+=FormatMagickString(q,extent,"%.20gx%.20g",(double)
+          image->magick_columns,(double) image->magick_rows);
         break;
       }
       case 'H':
       {
-        q+=FormatMagickString(q,extent,"%ld",image->page.height);
+        q+=FormatMagickString(q,extent,"%.20g",(double) image->page.height);
         break;
       }
       case 'O':
       {
-        q+=FormatMagickString(q,extent,"%+ld%+ld",image->page.x,image->page.y);
+        q+=FormatMagickString(q,extent,"%+ld%+ld",(long) image->page.x,(long)
+          image->page.y);
         break;
       }
       case 'P':
       {
-        q+=FormatMagickString(q,extent,"%lux%lu",image->page.width,
-          image->page.height);
+        q+=FormatMagickString(q,extent,"%.20gx%.20g",(double) image->page.width,
+          (double) image->page.height);
         break;
       }
       case 'Q':
       {
-        q+=FormatMagickString(q,extent,"%lu",image->quality);
+        q+=FormatMagickString(q,extent,"%.20g",(double) image->quality);
         break;
       }
       case 'S':
@@ -2935,31 +2968,31 @@ MagickExport char *InterpretImageProperties(const ImageInfo *image_info,
         /*
           Image scenes.
         */
-        if (text_info->number_scenes == 0)
+        if (image_info->number_scenes == 0)
           q+=CopyMagickString(q,"2147483647",extent);
         else
-          q+=FormatMagickString(q,extent,"%lu",text_info->scene+
-            text_info->number_scenes);
+          q+=FormatMagickString(q,extent,"%.20g",(double) (image_info->scene+
+            image_info->number_scenes));
         break;
       }
       case 'T':
       {
-        q+=FormatMagickString(q,extent,"%lu",image->delay);
+        q+=FormatMagickString(q,extent,"%.20g",(double) image->delay);
         break;
       }
       case 'W':
       {
-        q+=FormatMagickString(q,extent,"%ld",image->page.width);
+        q+=FormatMagickString(q,extent,"%.20g",(double) image->page.width);
         break;
       }
       case 'X':
       {
-        q+=FormatMagickString(q,extent,"%+ld",image->page.x);
+        q+=FormatMagickString(q,extent,"%+.20g",(double) image->page.x);
         break;
       }
       case 'Y':
       {
-        q+=FormatMagickString(q,extent,"%+ld",image->page.y);
+        q+=FormatMagickString(q,extent,"%+.20g",(double) image->page.y);
         break;
       }
       case 'Z':
@@ -2967,7 +3000,7 @@ MagickExport char *InterpretImageProperties(const ImageInfo *image_info,
         /*
           Unique filename.
         */
-        (void) CopyMagickString(filename,text_info->zero,extent);
+        (void) CopyMagickString(filename,image_info->zero,extent);
         q+=CopyMagickString(q,filename,extent);
         break;
       }
@@ -2980,7 +3013,7 @@ MagickExport char *InterpretImageProperties(const ImageInfo *image_info,
           *key,
           *value;
 
-        long
+        ssize_t
           depth;
 
         /*
@@ -3050,7 +3083,7 @@ MagickExport char *InterpretImageProperties(const ImageInfo *image_info,
                 key=GetNextImageProperty(image);
               }
             }
-        value=GetMagickProperty(text_info,image,pattern);
+        value=GetMagickProperty(image_info,image,pattern);
         if (value != (const char *) NULL)
           {
             length=strlen(value);
@@ -3065,6 +3098,7 @@ MagickExport char *InterpretImageProperties(const ImageInfo *image_info,
               }
             (void) CopyMagickString(q,value,extent);
             q+=length;
+            break;
           }
         if (image_info == (ImageInfo *) NULL)
           break;
@@ -3083,6 +3117,7 @@ MagickExport char *InterpretImageProperties(const ImageInfo *image_info,
               }
             (void) CopyMagickString(q,value,extent);
             q+=length;
+            break;
           }
         break;
       }
@@ -3095,8 +3130,9 @@ MagickExport char *InterpretImageProperties(const ImageInfo *image_info,
           Image bounding box.
         */
         page=GetImageBoundingBox(image,&image->exception);
-        q+=FormatMagickString(q,MaxTextExtent,"%lux%lu%+ld%+ld",page.width,
-          page.height,page.x,page.y);
+        q+=FormatMagickString(q,MaxTextExtent,"%.20gx%.20g%+.20g%+.20g",
+          (double) page.width,(double) page.height,(double) page.x,(double)
+          page.y);
         break;
       }
       case '#':
@@ -3125,7 +3161,6 @@ MagickExport char *InterpretImageProperties(const ImageInfo *image_info,
     }
   }
   *q='\0';
-  text_info=DestroyImageInfo(text_info);
   if (text != (const char *) embed_text)
     text=DestroyString(text);
   (void) SubstituteString(&interpret_text,"&lt;","<");
@@ -3242,6 +3277,9 @@ MagickExport void ResetImagePropertyIterator(const Image *image)
 MagickExport MagickBooleanType SetImageProperty(Image *image,
   const char *property,const char *value)
 {
+  ExceptionInfo
+    *exception;
+
   MagickBooleanType
     status;
 
@@ -3259,11 +3297,17 @@ MagickExport MagickBooleanType SetImageProperty(Image *image,
   if ((value == (const char *) NULL) || (*value == '\0'))
     return(DeleteImageProperty(image,property));
   status=MagickTrue;
+  exception=(&image->exception);
   switch (*property)
   {
     case 'B':
     case 'b':
     {
+      if (LocaleCompare(property,"background") == 0)
+        {
+          (void) QueryColorDatabase(value,&image->background_color,exception);
+          break;
+        }
       if (LocaleCompare(property,"bias") == 0)
         {
           image->bias=SiPrefixToDouble(value,QuantumRange);
@@ -3278,10 +3322,10 @@ MagickExport MagickBooleanType SetImageProperty(Image *image,
     {
       if (LocaleCompare(property,"colorspace") == 0)
         {
-          long
+          ssize_t
             colorspace;
 
-          colorspace=ParseMagickOption(MagickColorspaceOptions,MagickFalse,
+          colorspace=ParseCommandOption(MagickColorspaceOptions,MagickFalse,
             value);
           if (colorspace < 0)
             break;
@@ -3290,10 +3334,10 @@ MagickExport MagickBooleanType SetImageProperty(Image *image,
         }
       if (LocaleCompare(property,"compose") == 0)
         {
-          long
+          ssize_t
             compose;
 
-          compose=ParseMagickOption(MagickComposeOptions,MagickFalse,value);
+          compose=ParseCommandOption(MagickComposeOptions,MagickFalse,value);
           if (compose < 0)
             break;
           image->compose=(CompositeOperator) compose;
@@ -3301,10 +3345,10 @@ MagickExport MagickBooleanType SetImageProperty(Image *image,
         }
       if (LocaleCompare(property,"compress") == 0)
         {
-          long
+          ssize_t
             compression;
 
-          compression=ParseMagickOption(MagickCompressOptions,MagickFalse,
+          compression=ParseCommandOption(MagickCompressOptions,MagickFalse,
             value);
           if (compression < 0)
             break;
@@ -3326,21 +3370,33 @@ MagickExport MagickBooleanType SetImageProperty(Image *image,
           flags=ParseGeometry(value,&geometry_info);
           if ((flags & GreaterValue) != 0)
             {
-              if (image->delay > (unsigned long) (geometry_info.rho+0.5))
-                image->delay=(unsigned long) (geometry_info.rho+0.5);
+              if (image->delay > (size_t) floor(geometry_info.rho+0.5))
+                image->delay=(size_t) floor(geometry_info.rho+0.5);
             }
           else
             if ((flags & LessValue) != 0)
               {
-                if (image->delay < (unsigned long) (geometry_info.rho+0.5))
-                  image->ticks_per_second=(long) (geometry_info.sigma+0.5);
+                if (image->delay < (size_t) floor(geometry_info.rho+0.5))
+                  image->ticks_per_second=(ssize_t)
+                    floor(geometry_info.sigma+0.5);
               }
             else
-              image->delay=(unsigned long) (geometry_info.rho+0.5);
+              image->delay=(size_t) floor(geometry_info.rho+0.5);
           if ((flags & SigmaValue) != 0)
-            image->ticks_per_second=(long) (geometry_info.sigma+0.5);
+            image->ticks_per_second=(ssize_t) floor(geometry_info.sigma+0.5);
           break;
         }
+      if (LocaleCompare(property,"density") == 0)
+        {
+          GeometryInfo
+            geometry_info;
+
+          flags=ParseGeometry(value,&geometry_info);
+          image->x_resolution=geometry_info.rho;
+          image->y_resolution=geometry_info.sigma;
+          if ((flags & SigmaValue) == 0)
+            image->y_resolution=image->x_resolution;
+        }
       if (LocaleCompare(property,"depth") == 0)
         {
           image->depth=StringToUnsignedLong(value);
@@ -3348,10 +3404,10 @@ MagickExport MagickBooleanType SetImageProperty(Image *image,
         }
       if (LocaleCompare(property,"dispose") == 0)
         {
-          long
+          ssize_t
             dispose;
 
-          dispose=ParseMagickOption(MagickDisposeOptions,MagickFalse,value);
+          dispose=ParseCommandOption(MagickDisposeOptions,MagickFalse,value);
           if (dispose < 0)
             break;
           image->dispose=(DisposeType) dispose;
@@ -3366,10 +3422,10 @@ MagickExport MagickBooleanType SetImageProperty(Image *image,
     {
       if (LocaleCompare(property,"gravity") == 0)
         {
-          long
+          ssize_t
             gravity;
 
-          gravity=ParseMagickOption(MagickGravityOptions,MagickFalse,value);
+          gravity=ParseCommandOption(MagickGravityOptions,MagickFalse,value);
           if (gravity < 0)
             break;
           image->gravity=(GravityType) gravity;
@@ -3384,10 +3440,10 @@ MagickExport MagickBooleanType SetImageProperty(Image *image,
     {
       if (LocaleCompare(property,"intent") == 0)
         {
-          long
+          ssize_t
             rendering_intent;
 
-          rendering_intent=ParseMagickOption(MagickIntentOptions,MagickFalse,
+          rendering_intent=ParseCommandOption(MagickIntentOptions,MagickFalse,
             value);
           if (rendering_intent < 0)
             break;
@@ -3396,10 +3452,10 @@ MagickExport MagickBooleanType SetImageProperty(Image *image,
         }
       if (LocaleCompare(property,"interpolate") == 0)
         {
-          long
+          ssize_t
             interpolate;
 
-          interpolate=ParseMagickOption(MagickInterpolateOptions,MagickFalse,
+          interpolate=ParseCommandOption(MagickInterpolateOptions,MagickFalse,
             value);
           if (interpolate < 0)
             break;
@@ -3435,6 +3491,23 @@ MagickExport MagickBooleanType SetImageProperty(Image *image,
           geometry=DestroyString(geometry);
           break;
         }
+      if (LocaleCompare(property,"profile") == 0)
+        {
+          ImageInfo
+            *image_info;
+
+          StringInfo
+            *profile;
+
+          image_info=AcquireImageInfo();
+          (void) CopyMagickString(image_info->filename,value,MaxTextExtent);
+          (void) SetImageInfo(image_info,1,exception);
+          profile=FileToStringInfo(image_info->filename,~0UL,exception);
+          if (profile != (StringInfo *) NULL)
+            status=SetImageProfile(image,image_info->magick,profile);
+          image_info=DestroyImageInfo(image_info);
+          break;
+        }
       status=AddValueToSplayTree((SplayTreeInfo *) image->properties,
         ConstantString(property),ConstantString(value));
       break;
@@ -3444,10 +3517,10 @@ MagickExport MagickBooleanType SetImageProperty(Image *image,
     {
       if (LocaleCompare(property,"rendering-intent") == 0)
         {
-          long
+          ssize_t
             rendering_intent;
 
-          rendering_intent=ParseMagickOption(MagickIntentOptions,MagickFalse,
+          rendering_intent=ParseCommandOption(MagickIntentOptions,MagickFalse,
             value);
           if (rendering_intent < 0)
             break;
@@ -3475,6 +3548,24 @@ MagickExport MagickBooleanType SetImageProperty(Image *image,
         ConstantString(property),ConstantString(value));
       break;
     }
+    case 'U':
+    case 'u':
+    {
+      if (LocaleCompare(property,"units") == 0)
+        {
+          ssize_t
+            units;
+
+          units=ParseCommandOption(MagickResolutionOptions,MagickFalse,value);
+          if (units < 0)
+            break;
+          image->units=(ResolutionType) units;
+          break;
+        }
+      status=AddValueToSplayTree((SplayTreeInfo *) image->properties,
+        ConstantString(property),ConstantString(value));
+      break;
+    }
     default:
     {
       status=AddValueToSplayTree((SplayTreeInfo *) image->properties,