]> granicus.if.org Git - imagemagick/blobdiff - MagickCore/property.c
(no commit message)
[imagemagick] / MagickCore / property.c
index 267f46ab236b7f1b28ba11f56e30e070b5bf11f4..fd947edc8704985a83c8e6832960657308a8af49 100644 (file)
@@ -17,7 +17,7 @@
 %                                 March 2000                                  %
 %                                                                             %
 %                                                                             %
-%  Copyright 1999-2011 ImageMagick Studio LLC, a non-profit organization      %
+%  Copyright 1999-2012 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  %
@@ -143,9 +143,7 @@ MagickExport MagickBooleanType CloneImageProperties(Image *image,
   image->page=clone_image->page;
   image->tile_offset=clone_image->tile_offset;
   image->extract_info=clone_image->extract_info;
-  image->bias=clone_image->bias;
   image->filter=clone_image->filter;
-  image->blur=clone_image->blur;
   image->fuzz=clone_image->fuzz;
   image->interlace=clone_image->interlace;
   image->interpolate=clone_image->interpolate;
@@ -463,6 +461,13 @@ static inline ssize_t MagickMax(const ssize_t x,const ssize_t y)
   return(y);
 }
 
+static inline ssize_t MagickMin(const ssize_t x,const ssize_t y)
+{
+  if (x < y)
+    return(x);
+  return(y);
+}
+
 static inline int ReadPropertyByte(const unsigned char **p,size_t *length)
 {
   int
@@ -598,7 +603,7 @@ static MagickBooleanType Get8BIMProperty(const Image *image,const char *key,
       continue;
     if (ReadPropertyByte(&info,&length) != (unsigned char) 'M')
       continue;
-    id=(ssize_t) ReadPropertyMSBShort(&info,&length);
+    id=(ssize_t) ((int) ReadPropertyMSBShort(&info,&length));
     if (id < (ssize_t) start)
       continue;
     if (id > (ssize_t) stop)
@@ -629,7 +634,7 @@ static MagickBooleanType Get8BIMProperty(const Image *image,const char *key,
             No name match, scroll forward and try next.
           */
           info+=count;
-          length-=count;
+          length-=MagickMin(count,(ssize_t) length);
           continue;
         }
     if ((*name == '#') && (sub_number != 1))
@@ -639,7 +644,7 @@ static MagickBooleanType Get8BIMProperty(const Image *image,const char *key,
         */
         sub_number--;
         info+=count;
-        length-=count;
+        length-=MagickMin(count,(ssize_t) length);
         continue;
       }
     /*
@@ -654,7 +659,7 @@ static MagickBooleanType Get8BIMProperty(const Image *image,const char *key,
         (void) CopyMagickMemory(attribute,(char *) info,(size_t) count);
         attribute[count]='\0';
         info+=count;
-        length-=count;
+        length-=MagickMin(count,(ssize_t) length);
         if ((id <= 1999) || (id >= 2999))
           (void) SetImageProperty((Image *) image,key,(const char *)
             attribute,exception);
@@ -779,7 +784,7 @@ static MagickBooleanType GetEXIFProperty(const Image *image,
    for (component=0; component < components; component++) \
    { \
      length+=FormatLocaleString(buffer+length,MaxTextExtent-length, \
-       format", ",arg1,arg2); \
+       format", ",(arg1),(arg2)); \
      if (length >= (MaxTextExtent-1)) \
        length=MaxTextExtent-1; \
      p1+=size; \
@@ -795,7 +800,9 @@ static MagickBooleanType GetEXIFProperty(const Image *image,
       *directory;
 
     size_t
-      entry,
+      entry;
+
+    ssize_t
       offset;
   } DirectoryInfo;
 
@@ -1107,14 +1114,17 @@ static MagickBooleanType GetEXIFProperty(const Image *image,
     entry,
     length,
     number_entries,
-    tag_offset,
     tag;
 
+  SplayTreeInfo
+    *exif_resources;
+
   ssize_t
     all,
     id,
     level,
     offset,
+    tag_offset,
     tag_value;
 
   static int
@@ -1230,7 +1240,7 @@ static MagickBooleanType GetEXIFProperty(const Image *image,
   }
   if (length < 16)
     return(MagickFalse);
-  id=(ssize_t) ReadPropertyShort(LSBEndian,exif);
+  id=(ssize_t) ((int) ReadPropertyShort(LSBEndian,exif));
   endian=LSBEndian;
   if (id == 0x4949)
     endian=LSBEndian;
@@ -1245,7 +1255,7 @@ static MagickBooleanType GetEXIFProperty(const Image *image,
     This the offset to the first IFD.
   */
   offset=(ssize_t) ((int) ReadPropertyLong(endian,exif+4));
-  if ((size_t) offset >= length)
+  if ((offset < 0) || (size_t) offset >= length)
     return(MagickFalse);
   /*
     Set the pointer to the first IFD and follow it were it leads.
@@ -1255,6 +1265,8 @@ static MagickBooleanType GetEXIFProperty(const Image *image,
   level=0;
   entry=0;
   tag_offset=0;
+  exif_resources=NewSplayTree((int (*)(const void *,const void *)) NULL,
+    (void *(*)(void *)) NULL,(void *(*)(void *)) NULL);
   do
   {
     /*
@@ -1270,7 +1282,7 @@ static MagickBooleanType GetEXIFProperty(const Image *image,
     /*
       Determine how many entries there are in the current IFD.
     */
-    number_entries=ReadPropertyShort(endian,directory);
+    number_entries=(size_t) ((int) ReadPropertyShort(endian,directory));
     for ( ; entry < number_entries; entry++)
     {
       register unsigned char
@@ -1284,13 +1296,18 @@ static MagickBooleanType GetEXIFProperty(const Image *image,
       ssize_t
         components;
 
-      q=(unsigned char *) (directory+2+(12*entry));
-      tag_value=(ssize_t) (ReadPropertyShort(endian,q)+tag_offset);
-      format=(size_t) ReadPropertyShort(endian,q+2);
+      q=(unsigned char *) (directory+(12*entry)+2);
+      if (GetValueFromSplayTree(exif_resources,q) == q)
+        break;
+      (void) AddValueToSplayTree(exif_resources,q,q);
+      tag_value=(ssize_t) ((int) ReadPropertyShort(endian,q)+tag_offset);
+      format=(size_t) ((int) ReadPropertyShort(endian,q+2));
       if (format >= (sizeof(tag_bytes)/sizeof(*tag_bytes)))
         break;
       components=(ssize_t) ((int) ReadPropertyLong(endian,q+4));
       number_bytes=(size_t) components*tag_bytes[format];
+      if (number_bytes < components)
+        break;  /* prevent overflow */
       if (number_bytes <= 4)
         p=q+8;
       else
@@ -1304,6 +1321,8 @@ static MagickBooleanType GetEXIFProperty(const Image *image,
           offset=(ssize_t) ((int) ReadPropertyLong(endian,q+8));
           if ((size_t) (offset+number_bytes) > length)
             continue;
+          if (~length < number_bytes)
+            continue;  /* prevent overflow */
           p=(unsigned char *) (exif+offset);
         }
       if ((all != 0) || (tag == (size_t) tag_value))
@@ -1312,6 +1331,8 @@ static MagickBooleanType GetEXIFProperty(const Image *image,
             buffer[MaxTextExtent],
             *value;
 
+          value=(char *) NULL;
+          *buffer='\0';
           switch (format)
           {
             case EXIF_FMT_BYTE:
@@ -1338,7 +1359,7 @@ static MagickBooleanType GetEXIFProperty(const Image *image,
             case EXIF_FMT_ULONG:
             {
               EXIFMultipleValues(4,"%.20g",(double)
-                ReadPropertyLong(endian,p1));
+                ((int) ReadPropertyLong(endian,p1)));
               break;
             }
             case EXIF_FMT_SLONG:
@@ -1350,8 +1371,8 @@ static MagickBooleanType GetEXIFProperty(const Image *image,
             case EXIF_FMT_URATIONAL:
             {
               EXIFMultipleFractions(8,"%.20g/%.20g",(double)
-                ReadPropertyLong(endian,p1),(double)
-                ReadPropertyLong(endian,p1+4));
+                ((int) ReadPropertyLong(endian,p1)),(double)
+                ((int) ReadPropertyLong(endian,p1+4)));
               break;
             }
             case EXIF_FMT_SRATIONAL:
@@ -1452,19 +1473,19 @@ static MagickBooleanType GetEXIFProperty(const Image *image,
             }
         }
         if ((tag_value == TAG_EXIF_OFFSET) ||
-            (tag_value == TAG_INTEROP_OFFSET) ||
-            (tag_value == TAG_GPS_OFFSET))
+            (tag_value == TAG_INTEROP_OFFSET) || (tag_value == TAG_GPS_OFFSET))
           {
-            size_t
+            ssize_t
               offset;
 
-            offset=(size_t) ReadPropertyLong(endian,p);
-            if ((offset < length) && (level < (MaxDirectoryStack-2)))
+            offset=(ssize_t) ((int) ReadPropertyLong(endian,p));
+            if (((size_t) offset < length) && (level < (MaxDirectoryStack-2)))
               {
-                size_t
+                ssize_t
                   tag_offset1;
 
-                tag_offset1=(tag_value == TAG_GPS_OFFSET) ? 0x10000UL : 0UL;
+                tag_offset1=(ssize_t) ((tag_value == TAG_GPS_OFFSET) ? 0x10000 :
+                  0);
                 directory_stack[level].directory=directory;
                 entry++;
                 directory_stack[level].entry=entry;
@@ -1476,9 +1497,9 @@ static MagickBooleanType GetEXIFProperty(const Image *image,
                 level++;
                 if ((directory+2+(12*number_entries)) > (exif+length))
                   break;
-                offset=(size_t) ReadPropertyLong(endian,directory+2+(12*
-                  number_entries));
-                if ((offset != 0) && (offset < length) &&
+                offset=(ssize_t) ((int) ReadPropertyLong(endian,directory+2+(12*
+                  number_entries)));
+                if ((offset != 0) && ((size_t) offset < length) &&
                     (level < (MaxDirectoryStack-2)))
                   {
                     directory_stack[level].directory=exif+offset;
@@ -1491,6 +1512,7 @@ static MagickBooleanType GetEXIFProperty(const Image *image,
           }
     }
   } while (level > 0);
+  exif_resources=DestroySplayTree(exif_resources);
   return(status);
 }
 
@@ -1571,8 +1593,7 @@ static MagickBooleanType GetXMPProperty(const Image *image,const char *property)
 }
 
 static char *TracePSClippath(const unsigned char *blob,size_t length,
-  const size_t magick_unused(columns),
-  const size_t magick_unused(rows))
+  const size_t magick_unused(columns),const size_t magick_unused(rows))
 {
   char
     *path,
@@ -1631,7 +1652,7 @@ static char *TracePSClippath(const unsigned char *blob,size_t length,
   in_subpath=MagickFalse;
   while (length > 0)
   {
-    selector=(ssize_t) ReadPropertyMSBShort(&blob,&length);
+    selector=(ssize_t) ((int) ReadPropertyMSBShort(&blob,&length));
     switch (selector)
     {
       case 0:
@@ -1640,15 +1661,15 @@ static char *TracePSClippath(const unsigned char *blob,size_t length,
         if (knot_count != 0)
           {
             blob+=24;
-            length-=24;
+            length-=MagickMin(24,(ssize_t) length);
             break;
           }
         /*
           Expected subpath length record.
         */
-        knot_count=(ssize_t) ReadPropertyMSBShort(&blob,&length);
+        knot_count=(ssize_t) ((int) ReadPropertyMSBShort(&blob,&length));
         blob+=22;
-        length-=22;
+        length-=MagickMin(22,(ssize_t) length);
         break;
       }
       case 1:
@@ -1662,7 +1683,7 @@ static char *TracePSClippath(const unsigned char *blob,size_t length,
               Unexpected subpath knot
             */
             blob+=24;
-            length-=24;
+            length-=MagickMin(24,(ssize_t) length);
             break;
           }
         /*
@@ -1674,8 +1695,8 @@ static char *TracePSClippath(const unsigned char *blob,size_t length,
             xx,
             yy;
 
-          yy=ReadPropertyMSBLong(&blob,&length);
-          xx=ReadPropertyMSBLong(&blob,&length);
+          yy=(size_t) ((int) ReadPropertyMSBLong(&blob,&length));
+          xx=(size_t) ((int) ReadPropertyMSBLong(&blob,&length));
           x=(ssize_t) xx;
           if (xx > 2147483647)
             x=(ssize_t) xx-4294967295U-1;
@@ -1763,7 +1784,7 @@ static char *TracePSClippath(const unsigned char *blob,size_t length,
       default:
       {
         blob+=24;
-        length-=24;
+        length-=MagickMin(24,(ssize_t) length);
         break;
       }
     }
@@ -1828,7 +1849,7 @@ static char *TraceSVGClippath(const unsigned char *blob,size_t length,
   in_subpath=MagickFalse;
   while (length != 0)
   {
-    selector=(ssize_t) ReadPropertyMSBShort(&blob,&length);
+    selector=(ssize_t) ((int) ReadPropertyMSBShort(&blob,&length));
     switch (selector)
     {
       case 0:
@@ -1837,15 +1858,15 @@ static char *TraceSVGClippath(const unsigned char *blob,size_t length,
         if (knot_count != 0)
           {
             blob+=24;
-            length-=24;
+            length-=MagickMin(24,(ssize_t) length);
             break;
           }
         /*
           Expected subpath length record.
         */
-        knot_count=(ssize_t) ReadPropertyMSBShort(&blob,&length);
+        knot_count=(ssize_t) ((int) ReadPropertyMSBShort(&blob,&length));
         blob+=22;
-        length-=22;
+        length-=MagickMin(22,(ssize_t) length);
         break;
       }
       case 1:
@@ -1859,7 +1880,7 @@ static char *TraceSVGClippath(const unsigned char *blob,size_t length,
               Unexpected subpath knot.
             */
             blob+=24;
-            length-=24;
+            length-=MagickMin(24,(ssize_t) length);
             break;
           }
         /*
@@ -1871,8 +1892,8 @@ static char *TraceSVGClippath(const unsigned char *blob,size_t length,
             xx,
             yy;
 
-          yy=ReadPropertyMSBLong(&blob,&length);
-          xx=ReadPropertyMSBLong(&blob,&length);
+          yy=(size_t) ((int) ReadPropertyMSBLong(&blob,&length));
+          xx=(size_t) ((int) ReadPropertyMSBLong(&blob,&length));
           x=(ssize_t) xx;
           if (xx > 2147483647)
             x=(ssize_t) xx-4294967295U-1;
@@ -1934,7 +1955,7 @@ static char *TraceSVGClippath(const unsigned char *blob,size_t length,
       default:
       {
         blob+=24;
-        length-=24;
+        length-=MagickMin(24,(ssize_t) length);
         break;
       }
     }
@@ -2349,6 +2370,13 @@ MagickExport const char *GetMagickProperty(const ImageInfo *image_info,
             "true",MaxTextExtent);
           break;
         }
+      if (LocaleNCompare("orientation",property,11) == 0)
+        {
+          (void) FormatLocaleString(value,MaxTextExtent,"%s", 
+            CommandOptionToMnemonic(MagickOrientationOptions,(ssize_t) 
+            image->orientation));
+          break;
+        }
       if (LocaleNCompare("output",property,6) == 0)
         {
           (void) CopyMagickString(value,image_info->filename,MaxTextExtent);
@@ -2366,6 +2394,22 @@ MagickExport const char *GetMagickProperty(const ImageInfo *image_info,
         }
       break;
     }
+    case 'r':
+    {
+      if (LocaleNCompare("resolution.x",property,11) == 0)
+        {
+          (void) FormatLocaleString(value,MaxTextExtent,"%g",
+            image->resolution.x);
+          break;
+        }
+      if (LocaleNCompare("resolution.y",property,11) == 0)
+        {
+          (void) FormatLocaleString(value,MaxTextExtent,"%g",
+            image->resolution.y);
+          break;
+        }
+      break;
+    }
     case 's':
     {
       if (LocaleNCompare("size",property,4) == 0)
@@ -2385,6 +2429,7 @@ MagickExport const char *GetMagickProperty(const ImageInfo *image_info,
         }
       if (LocaleNCompare("scene",property,5) == 0)
         {
+          /* FUTURE: I am not certain this property return makes sense! */
           (void) FormatLocaleString(value,MaxTextExtent,"%.20g",(double)
             image->scene);
           if (image_info->number_scenes != 0)
@@ -2447,26 +2492,6 @@ MagickExport const char *GetMagickProperty(const ImageInfo *image_info,
         }
       break;
     }
-    case 'x':
-    {
-      if (LocaleNCompare("xresolution",property,11) == 0)
-        {
-          (void) FormatLocaleString(value,MaxTextExtent,"%g",
-            image->resolution.x);
-          break;
-        }
-      break;
-    }
-    case 'y':
-    {
-      if (LocaleNCompare("yresolution",property,11) == 0)
-        {
-          (void) FormatLocaleString(value,MaxTextExtent,"%g",
-            image->resolution.y);
-          break;
-        }
-      break;
-    }
     case 'z':
     {
       if (LocaleNCompare("zero",property,4) == 0)
@@ -2535,7 +2560,8 @@ MagickExport char *GetNextImageProperty(const Image *image)
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 %
 %  InterpretImageProperties() replaces any embedded formatting characters with
-%  the appropriate image property and returns the interpreted text.
+%  the appropriate image property and returns the interpreted text.  Free with
+%  DestoryString() or RelinquishMagickMemory().
 %
 %  The format of the InterpretImageProperties method is:
 %
@@ -2871,10 +2897,10 @@ MagickExport char *InterpretImageProperties(const ImageInfo *image_info,
         q+=CopyMagickString(q,image_info->filename,extent);
         break;
       }
-      case 'p': /* Image index in curent image list  */
+      case 'p': /* Image index in current image list  */
       {
         q+=FormatLocaleString(q,extent,"%.20g",(double)
-            GetImageIndexInList(image));
+          GetImageIndexInList(image));
         break;
       }
       case 'q': /* Quantum depth of image in memory */
@@ -3197,11 +3223,6 @@ MagickExport MagickBooleanType SetImageProperty(Image *image,
             &image->background_color,exception);
           break;
         }
-      if (LocaleCompare(property,"bias") == 0)
-        {
-          image->bias=StringToDoubleInterval(value,(double) QuantumRange+1.0);
-          break;
-        }
       status=AddValueToSplayTree((SplayTreeInfo *) image->properties,
         ConstantString(property),ConstantString(value));
       break;