]> granicus.if.org Git - imagemagick/blobdiff - MagickCore/property.c
(no commit message)
[imagemagick] / MagickCore / property.c
index 8e770ef29da0d0e183b3ce2276b17c6219507339..9868e822caf2b5b2c1b0e4197b4dace34c2b62bd 100644 (file)
 %                         MagickCore Property Methods                         %
 %                                                                             %
 %                              Software Design                                %
-%                                John Cristy                                  %
+%                                   Cristy                                    %
 %                                 March 2000                                  %
 %                                                                             %
 %                                                                             %
-%  Copyright 1999-2013 ImageMagick Studio LLC, a non-profit organization      %
+%  Copyright 1999-2014 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  %
 #include "lcms.h"
 #endif
 #endif
-
-
+\f
+/*
+  Define declarations.
+*/
+#if defined(MAGICKCORE_LCMS_DELEGATE)
+#if defined(LCMS_VERSION) && (LCMS_VERSION < 2000)
+#define cmsUInt32Number  DWORD
+#endif
+#endif
+\f
 /*
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 %                                                                             %
@@ -190,8 +198,7 @@ MagickExport MagickBooleanType CloneImageProperties(Image *image,
     }
   return(MagickTrue);
 }
-
-
+\f
 /*
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 %                                                                             %
@@ -243,8 +250,7 @@ MagickExport MagickBooleanType DefineImageProperty(Image *image,
   *p='\0';
   return(SetImageProperty(image,key,value,exception));
 }
-
-
+\f
 /*
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 %                                                                             %
@@ -281,8 +287,7 @@ MagickExport MagickBooleanType DeleteImageProperty(Image *image,
     return(MagickFalse);
   return(DeleteNodeFromSplayTree((SplayTreeInfo *) image->properties,property));
 }
-
-
+\f
 /*
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 %                                                                             %
@@ -317,8 +322,7 @@ MagickExport void DestroyImageProperties(Image *image)
     image->properties=(void *) DestroySplayTree((SplayTreeInfo *)
       image->properties);
 }
-
-
+\f
 /*
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 %                                                                             %
@@ -375,8 +379,7 @@ MagickExport MagickBooleanType FormatImageProperty(Image *image,
   exception=DestroyExceptionInfo(exception);
   return(status);
 }
-
-
+\f
 /*
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 %                                                                             %
@@ -557,7 +560,7 @@ static inline unsigned short ReadPropertyMSBShort(const unsigned char **p,
     value;
 
   if (*length < 2)
-    return((unsigned short) ~0UL);
+    return((unsigned short) ~0);
   for (i=0; i < 2; i++)
   {
     c=(int) (*(*p)++);
@@ -1550,6 +1553,63 @@ static MagickBooleanType GetEXIFProperty(const Image *image,
   return(status);
 }
 
+static MagickBooleanType GetICCProperty(const Image *image,const char *property,
+  ExceptionInfo *exception)
+{
+  const StringInfo
+    *profile;
+
+  magick_unreferenced(property);
+
+  profile=GetImageProfile(image,"icc");
+  if (profile == (StringInfo *) NULL)
+    profile=GetImageProfile(image,"icm");
+  if (profile == (StringInfo *) NULL)
+    return(MagickFalse);
+  if (GetStringInfoLength(profile) < 128)
+    return(MagickFalse);  /* minimum ICC profile length */
+#if defined(MAGICKCORE_LCMS_DELEGATE)
+  {
+    cmsHPROFILE
+      icc_profile;
+
+    icc_profile=cmsOpenProfileFromMem(GetStringInfoDatum(profile),
+      (cmsUInt32Number) GetStringInfoLength(profile));
+    if (icc_profile != (cmsHPROFILE *) NULL)
+      {
+#if defined(LCMS_VERSION) && (LCMS_VERSION < 2000)
+        const char
+          *name;
+
+        name=cmsTakeProductName(icc_profile);
+        if (name != (const char *) NULL)
+          (void) SetImageProperty((Image *) image,"icc:name",name,exception);
+#else
+        char
+          info[MaxTextExtent];
+
+        (void) cmsGetProfileInfoASCII(icc_profile,cmsInfoDescription,
+          "en","US",info,MaxTextExtent);
+        (void) SetImageProperty((Image *) image,"icc:description",info,
+          exception);
+        (void) cmsGetProfileInfoASCII(icc_profile,cmsInfoManufacturer,
+          "en","US",info,MaxTextExtent);
+        (void) SetImageProperty((Image *) image,"icc:manufacturer",info,
+          exception);
+        (void) cmsGetProfileInfoASCII(icc_profile,cmsInfoModel,"en",
+          "US",info,MaxTextExtent);
+        (void) SetImageProperty((Image *) image,"icc:model",info,exception);
+        (void) cmsGetProfileInfoASCII(icc_profile,cmsInfoCopyright,
+          "en","US",info,MaxTextExtent);
+        (void) SetImageProperty((Image *) image,"icc:copyright",info,exception);
+#endif
+        (void) cmsCloseProfile(icc_profile);
+      }
+  }
+#endif
+  return(MagickTrue);
+}
+
 static MagickBooleanType GetXMPProperty(const Image *image,const char *property)
 {
   char
@@ -1937,9 +1997,9 @@ static char *TraceSVGClippath(const unsigned char *blob,size_t length,
           point[i].x=(double) x*columns/4096/4096;
           point[i].y=(double) y*rows/4096/4096;
         }
-        if( IfMagickFalse(in_subpath) )
+        if (in_subpath == MagickFalse)
           {
-            (void) FormatLocaleString(message,MaxTextExtent,"M %g,%g\n",
+            (void) FormatLocaleString(message,MaxTextExtent,"M %g %g\n",
               point[1].x,point[1].y);
             for (i=0; i < 3; i++)
             {
@@ -1956,20 +2016,20 @@ static char *TraceSVGClippath(const unsigned char *blob,size_t length,
             if ((last[1].x == last[2].x) && (last[1].y == last[2].y) &&
                 (point[0].x == point[1].x) && (point[0].y == point[1].y))
               (void) FormatLocaleString(message,MaxTextExtent,
-                "  %g %g l\n",point[1].x,point[1].y);
+                "L %g %g\n",point[1].x,point[1].y);
             else
               if ((last[1].x == last[2].x) && (last[1].y == last[2].y))
                 (void) FormatLocaleString(message,MaxTextExtent,
-                  "  %g %g %g %g v\n",point[0].x,point[0].y,
+                  "V %g %g %g %g\n",point[0].x,point[0].y,
                   point[1].x,point[1].y);
               else
                 if ((point[0].x == point[1].x) && (point[0].y == point[1].y))
                   (void) FormatLocaleString(message,MaxTextExtent,
-                    "  %g %g %g %g y\n",last[2].x,last[2].y,
+                    "Y %g %g %g %g\n",last[2].x,last[2].y,
                     point[1].x,point[1].y);
                 else
                   (void) FormatLocaleString(message,MaxTextExtent,
-                    "  %g %g %g %g %g %g c\n",last[2].x,
+                    "C %g %g %g %g %g %g\n",last[2].x,
                     last[2].y,point[0].x,point[0].y,point[1].x,point[1].y);
             for (i=0; i < 3; i++)
               last[i]=point[i];
@@ -1989,20 +2049,20 @@ static char *TraceSVGClippath(const unsigned char *blob,size_t length,
             if ((last[1].x == last[2].x) && (last[1].y == last[2].y) &&
                 (first[0].x == first[1].x) && (first[0].y == first[1].y))
               (void) FormatLocaleString(message,MaxTextExtent,
-                "  %g %g l z\n",first[1].x,first[1].y);
+                "L %g %g Z\n",first[1].x,first[1].y);
             else
               if ((last[1].x == last[2].x) && (last[1].y == last[2].y))
                 (void) FormatLocaleString(message,MaxTextExtent,
-                  "  %g %g %g %g v z\n",first[0].x,first[0].y,
+                  "V %g %g %g %g Z\n",first[0].x,first[0].y,
                   first[1].x,first[1].y);
               else
                 if ((first[0].x == first[1].x) && (first[0].y == first[1].y))
                   (void) FormatLocaleString(message,MaxTextExtent,
-                    "  %g %g %g %g y z\n",last[2].x,last[2].y,
+                    "Y %g %g %g %g Z\n",last[2].x,last[2].y,
                     first[1].x,first[1].y);
                 else
                   (void) FormatLocaleString(message,MaxTextExtent,
-                    "  %g %g %g %g %g %g c z\n",last[2].x,
+                    "C %g %g %g %g %g %g Z\n",last[2].x,
                     last[2].y,first[0].x,first[0].y,first[1].x,first[1].y);
             (void) ConcatenateString(&path,message);
             in_subpath=MagickFalse;
@@ -2041,11 +2101,9 @@ MagickExport const char *GetImageProperty(const Image *image,
 
   assert(image != (Image *) NULL);
   assert(image->signature == MagickSignature);
-  if( IfMagickTrue(image->debug) )
+  if (IfMagickTrue(image->debug))
     (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
-
   p=(const char *) NULL;
-  /* if property is in splay tree - return it and we are done */
   if (image->properties != (void *) NULL)
     {
       if (property == (const char *) NULL)
@@ -2069,13 +2127,8 @@ MagickExport const char *GetImageProperty(const Image *image,
     {
       if (LocaleNCompare("8bim:",property,5) == 0)
         {
-          if( IfMagickTrue(Get8BIMProperty(image,property,exception)) &&
-              (image->properties != (void *) NULL))
-            {
-              p=(const char *) GetValueFromSplayTree((SplayTreeInfo *)
-                image->properties,property);
-              return(p);
-            }
+          (void) Get8BIMProperty(image,property,exception);
+          break;
         }
       break;
     }
@@ -2084,28 +2137,24 @@ MagickExport const char *GetImageProperty(const Image *image,
     {
       if (LocaleNCompare("exif:",property,5) == 0)
         {
-          if( IfMagickTrue(GetEXIFProperty(image,property,exception)) &&
-              (image->properties != (void *) NULL))
-            {
-              p=(const char *) GetValueFromSplayTree((SplayTreeInfo *)
-                image->properties,property);
-              return(p);
-            }
+          (void) GetEXIFProperty(image,property,exception);
+          break;
         }
       break;
     }
     case 'I':
     case 'i':
     {
+      if ((LocaleNCompare("icc:",property,4) == 0) ||
+          (LocaleNCompare("icm:",property,4) == 0))
+        {
+          (void) GetICCProperty(image,property,exception);
+          break;
+        }
       if (LocaleNCompare("iptc:",property,5) == 0)
         {
-          if( IfMagickTrue(GetIPTCProperty(image,property,exception)) &&
-              (image->properties != (void *) NULL))
-            {
-              p=(const char *) GetValueFromSplayTree((SplayTreeInfo *)
-                image->properties,property);
-              return(p);
-            }
+          (void) GetIPTCProperty(image,property,exception);
+          break;
         }
       break;
     }
@@ -2114,23 +2163,23 @@ MagickExport const char *GetImageProperty(const Image *image,
     {
       if (LocaleNCompare("xmp:",property,4) == 0)
         {
-          if( IfMagickTrue(GetXMPProperty(image,property)) &&
-              (image->properties != (void *) NULL))
-            {
-              p=(const char *) GetValueFromSplayTree((SplayTreeInfo *)
-                image->properties,property);
-              return(p);
-            }
+          (void) GetXMPProperty(image,property);
+          break;
         }
       break;
     }
     default:
       break;
   }
-  return(p);
+  if (image->properties != (void *) NULL)
+    {
+      p=(const char *) GetValueFromSplayTree((SplayTreeInfo *)
+        image->properties,property);
+      return(p);
+    }
+  return((const char *) NULL);
 }
-
-
+\f
 /*
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 %                                                                             %
@@ -2180,7 +2229,7 @@ MagickExport const char *GetImageProperty(const Image *image,
     return((const char *)NULL); \
   }
 #define WarnNoImageInfoReturn(format,arg) \
-  if (image == (Image *) NULL ) { \
+  if (image_info == (ImageInfo *) NULL ) { \
     (void) ThrowMagickException(exception,GetMagickModule(),OptionWarning, \
         "NoImageInfoForProperty",format,arg); \
     return((const char *)NULL); \
@@ -2523,8 +2572,11 @@ static const char *GetMagickPropertyLetter(ImageInfo *image_info,
         page.y);
       break;
     }
-    case '#': /* Image signature */
+    case '#':
     {
+      /*
+        Image signature.
+      */
       WarnNoImageReturn("\"%%%c\"",letter);
       (void) SignatureImage(image,exception);
       string=GetImageProperty(image,"signature",exception);
@@ -2534,19 +2586,21 @@ static const char *GetMagickPropertyLetter(ImageInfo *image_info,
   if (string != (char *) NULL)
     return(string);
   if (*value != '\0')
-  {
-    /* create a cloned copy of result, that will get cleaned up, eventually */
-    if (image != (Image *)NULL)
-      {
-        (void) SetImageArtifact(image,"get-property",value);
-        return(GetImageArtifact(image,"get-property"));
-      }
-    else
-      {
-        (void) SetImageOption(image_info,"get-property",value);
-        return(GetImageOption(image_info,"get-property"));
-      }
-  }
+    {
+      /*
+        Create a cloned copy of result.
+      */
+      if (image != (Image *)NULL)
+        {
+          (void) SetImageArtifact(image,"get-property",value);
+          return(GetImageArtifact(image,"get-property"));
+        }
+      else
+        {
+          (void) SetImageOption(image_info,"get-property",value);
+          return(GetImageOption(image_info,"get-property"));
+        }
+    }
   return((char *)NULL);
 }
 
@@ -2781,6 +2835,10 @@ MagickExport const char *GetMagickProperty(ImageInfo *image_info,
       if (LocaleCompare("profile:icc",property) == 0 ||
           LocaleCompare("profile:icm",property) == 0)
         {
+#if !defined(LCMS_VERSION) || (LCMS_VERSION < 2000)
+#define cmsUInt32Number  DWORD
+#endif
+
           const StringInfo
             *profile;
 
@@ -3008,8 +3066,7 @@ MagickExport const char *GetMagickProperty(ImageInfo *image_info,
   return((char *)NULL);
 }
 #undef WarnNoImageReturn
-
-
+\f
 /*
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 %                                                                             %
@@ -3043,8 +3100,7 @@ MagickExport char *GetNextImageProperty(const Image *image)
     return((char *) NULL);
   return((char *) GetNextKeyInSplayTree((SplayTreeInfo *) image->properties));
 }
-
-
+\f
 /*
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 %                                                                             %
@@ -3102,6 +3158,7 @@ MagickExport char *GetNextImageProperty(const Image *image)
 
 /* common inline code to expand the interpreted text string */
 #define ExtendInterpretText(string_length)  do { \
+DisableMSCWarning(4127) \
     size_t length=(string_length); \
     if ((size_t) (q-interpret_text+length+1) >= extent) \
      { extent+=length; \
@@ -3110,10 +3167,12 @@ MagickExport char *GetNextImageProperty(const Image *image)
        if (interpret_text == (char *) NULL) \
          return((char *)NULL); \
        q=interpret_text+strlen(interpret_text); \
-   } } while (0)  /* no trailing ; */
+   } } while (0)  /* no trailing ; */ \
+RestoreMSCWarning
 
 /* same but append the given string */
 #define AppendString2Text(string)  do { \
+DisableMSCWarning(4127) \
     size_t length=strlen((string)); \
     if ((size_t) (q-interpret_text+length+1) >= extent) \
      { extent+=length; \
@@ -3125,10 +3184,12 @@ MagickExport char *GetNextImageProperty(const Image *image)
       } \
      (void) CopyMagickString(q,(string),extent); \
      q+=length; \
-   } while (0)  /* no trailing ; */
+   } while (0)  /* no trailing ; */ \
+RestoreMSCWarning
 
 /* same but append a 'key' and 'string' pair */
 #define AppendKeyValue2Text(key,string)  do { \
+DisableMSCWarning(4127) \
     size_t length=strlen(key)+strlen(string)+2; \
     if ((size_t) (q-interpret_text+length+1) >= extent) \
      { extent+=length; \
@@ -3139,7 +3200,8 @@ MagickExport char *GetNextImageProperty(const Image *image)
       q=interpret_text+strlen(interpret_text); \
      } \
      q+=FormatLocaleString(q,extent,"%s=%s\n",(key),(string)); \
-   } while (0)  /* no trailing ; */
+   } while (0)  /* no trailing ; */ \
+RestoreMSCWarning
 
 MagickExport char *InterpretImageProperties(ImageInfo *image_info,
   Image *image,const char *embed_text,ExceptionInfo *exception)
@@ -3595,8 +3657,7 @@ PropertyLookupFailure:
   *q='\0';
   return(interpret_text);
 }
-
-
+\f
 /*
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 %                                                                             %
@@ -3642,8 +3703,7 @@ MagickExport char *RemoveImageProperty(Image *image,
     property);
   return(value);
 }
-
-
+\f
 /*
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 %                                                                             %
@@ -3679,8 +3739,7 @@ MagickExport void ResetImagePropertyIterator(const Image *image)
     return;
   ResetSplayTreeIterator((SplayTreeInfo *) image->properties);
 }
-
-
+\f
 /*
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 %                                                                             %
@@ -3727,28 +3786,23 @@ MagickExport MagickBooleanType SetImageProperty(Image *image,
   assert(image->signature == MagickSignature);
   if( IfMagickTrue(image->debug) )
     (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
-
-  /* Create splay-tree */
   if (image->properties == (void *) NULL)
     image->properties=NewSplayTree(CompareSplayTreeString,
-      RelinquishMagickMemory,RelinquishMagickMemory);
-
-  /* Delete property if NULL --  empty string values are valid! */
+      RelinquishMagickMemory,RelinquishMagickMemory);  /* create splay-tree */
   if (value == (const char *) NULL)
-    return(DeleteImageProperty(image,property));
+    return(DeleteImageProperty(image,property));  /* delete if NULL */
   status=MagickTrue;
-
-  /* Do not 'set' single letter properties - read only shorthand */
   if (strlen(property) <= 1)
     {
-      (void) ThrowMagickException(exception,GetMagickModule(),
-          OptionError,"SetReadOnlyProperty","`%s'",property);
+      /*
+        Do not 'set' single letter properties - read only shorthand.
+       */
+      (void) ThrowMagickException(exception,GetMagickModule(),OptionError,
+        "SetReadOnlyProperty","`%s'",property);
       return(MagickFalse);
     }
 
   /* FUTURE: binary chars or quotes in key should produce a error */
-
-
   /* Set attributes with known names or special prefixes
      return result is found, or break to set a free form properity
   */
@@ -3784,8 +3838,8 @@ MagickExport MagickBooleanType SetImageProperty(Image *image,
     {
       if (LocaleCompare("channels",property) == 0)
         {
-          (void) ThrowMagickException(exception,GetMagickModule(),
-               OptionError,"SetReadOnlyProperty","`%s'",property);
+          (void) ThrowMagickException(exception,GetMagickModule(),OptionError,
+            "SetReadOnlyProperty","`%s'",property);
           return(MagickFalse);
         }
       if (LocaleCompare("colorspace",property) == 0)
@@ -3797,7 +3851,7 @@ MagickExport MagickBooleanType SetImageProperty(Image *image,
             value);
           if (colorspace < 0)
             return(MagickFalse); /* FUTURE: value exception?? */
-          return(SetImageColorspace(image,colorspace,exception));
+          return(SetImageColorspace(image,(ColorspaceType) colorspace,exception));
         }
       if (LocaleCompare("compose",property) == 0)
         {