Improved performance of parsing the xmp profile.
authordirk <dirk@git.imagemagick.org>
Fri, 23 May 2014 11:11:17 +0000 (11:11 +0000)
committerdirk <dirk@git.imagemagick.org>
Fri, 23 May 2014 11:11:17 +0000 (11:11 +0000)
MagickCore/property.c
MagickCore/xml-tree.c

index 284ae1a391c4e174bc12a98de1e73c3c879a88b3..bc929ac565c314a36e6ad951e2d44eed330bf6ec 100644 (file)
@@ -1610,11 +1610,29 @@ static MagickBooleanType GetICCProperty(const Image *image,const char *property,
   return(MagickTrue);
 }
 
+static MagickBooleanType SkipXMPValue(const char *value)
+{
+  if (value == (const char*) NULL)
+    return(MagickTrue);
+
+  while(*value != '\0')
+  {
+    if (!isspace((int) ((const char) *value)))
+      return(MagickFalse);
+    value++;
+  }
+
+  return(MagickTrue);
+}
+
 static MagickBooleanType GetXMPProperty(const Image *image,const char *property)
 {
   char
     *xmp_profile;
 
+  const char
+    *content;
+
   const StringInfo
     *profile;
 
@@ -1665,16 +1683,19 @@ static MagickBooleanType GetXMPProperty(const Image *image,const char *property)
         while (node != (XMLTreeInfo *) NULL)
         {
           child=GetXMLTreeChild(node,(const char *) NULL);
-          if (child == (XMLTreeInfo *) NULL)
+          content=GetXMLTreeContent(node);
+          if (child == (XMLTreeInfo *) NULL && SkipXMPValue(content) ==
+              MagickFalse)
             (void) AddValueToSplayTree((SplayTreeInfo *) image->properties,
               ConstantString(GetXMLTreeTag(node)),
-              ConstantString(GetXMLTreeContent(node)));
+              ConstantString(content));
           while (child != (XMLTreeInfo *) NULL)
           {
-            if (LocaleCompare(GetXMLTreeTag(child),"rdf:Seq") != 0)
+            content=GetXMLTreeContent(child);
+            if (SkipXMPValue(content) == MagickFalse)
               (void) AddValueToSplayTree((SplayTreeInfo *) image->properties,
                 ConstantString(GetXMLTreeTag(child)),
-                ConstantString(GetXMLTreeContent(child)));
+                ConstantString(content));
             child=GetXMLTreeSibling(child);
           }
           node=GetXMLTreeSibling(node);
index e3c8a82acfa1f231bce6c85cc2ed4ad436a3c00d..657cc03abb07be355d426c6bf2b892e87728791c 100644 (file)
@@ -1577,7 +1577,7 @@ static void ParseCharacterContent(XMLTreeRoot *root,char *xml,
 }
 
 static XMLTreeInfo *ParseCloseTag(XMLTreeRoot *root,char *tag,
-  char *magick_unused(xml),ExceptionInfo *exception)
+  ExceptionInfo *exception)
 {
   if ((root->node == (XMLTreeInfo *) NULL) ||
       (root->node->tag == (char *) NULL) || (strcmp(tag,root->node->tag) != 0))
@@ -1928,6 +1928,28 @@ static void ParseOpenTag(XMLTreeRoot *root,char *tag,char **attributes)
   root->node=xml_info;
 }
 
+static const char *ignore_tags[3] =
+{
+  "rdf:Bag",
+  "rdf:Seq",
+  (const char *)NULL
+};
+
+static inline MagickBooleanType CanIgnoreTag(const char *tag)
+{
+  register ssize_t
+    i;
+
+  i=0;
+  while (ignore_tags[i] != (const char *) NULL)
+  {
+    if (LocaleCompare(tag,ignore_tags[i]) == 0)
+      return(MagickTrue);
+    i++;
+  }
+  return(MagickFalse);
+}
+
 MagickExport XMLTreeInfo *NewXMLTree(const char *xml,ExceptionInfo *exception)
 {
   char
@@ -1950,6 +1972,7 @@ MagickExport XMLTreeInfo *NewXMLTree(const char *xml,ExceptionInfo *exception)
     i;
 
   size_t
+    ignore_depth,
     length;
 
   ssize_t
@@ -1990,6 +2013,8 @@ MagickExport XMLTreeInfo *NewXMLTree(const char *xml,ExceptionInfo *exception)
       return((XMLTreeInfo *) NULL);
     }
   attribute=(char **) NULL;
+  l=0;
+  ignore_depth=0;
   for (p++; ; p++)
   {
     attributes=(char **) sentinel;
@@ -2011,80 +2036,91 @@ MagickExport XMLTreeInfo *NewXMLTree(const char *xml,ExceptionInfo *exception)
         p+=strcspn(p,XMLWhitespace "/>");
         while (isspace((int) ((unsigned char) *p)) != 0)
           *p++='\0';
-        if ((*p != '\0') && (*p != '/') && (*p != '>'))
+        if (ignore_depth == 0)
           {
-            /*
-              Find tag in default attributes list.
-            */
-            i=0;
-            while ((root->attributes[i] != (char **) NULL) &&
-                   (strcmp(root->attributes[i][0],tag) != 0))
-              i++;
-            attribute=root->attributes[i];
-          }
-        for (l=0; (*p != '\0') && (*p != '/') && (*p != '>'); l+=2)
-        {
-          /*
-            Attribute.
-          */
-          if (l == 0)
-            attributes=(char **) AcquireQuantumMemory(4,sizeof(*attributes));
-          else
-            attributes=(char **) ResizeQuantumMemory(attributes,(size_t) (l+4),
-              sizeof(*attributes));
-          if (attributes == (char **) NULL)
-            {
-              (void) ThrowMagickException(exception,GetMagickModule(),
-                ResourceLimitError,"MemoryAllocationFailed","`%s'","");
-              utf8=DestroyString(utf8);
-              return(&root->root);
-            }
-          attributes[l+2]=(char *) NULL;
-          attributes[l+1]=(char *) NULL;
-          attributes[l]=p;
-          p+=strcspn(p,XMLWhitespace "=/>");
-          if ((*p != '=') && (isspace((int) ((unsigned char) *p)) == 0))
-            attributes[l]=ConstantString("");
-          else
+            if ((*p != '\0') && (*p != '/') && (*p != '>'))
+              {
+                /*
+                  Find tag in default attributes list.
+                */
+                i=0;
+                while ((root->attributes[i] != (char **) NULL) &&
+                       (strcmp(root->attributes[i][0],tag) != 0))
+                  i++;
+                attribute=root->attributes[i];
+              }
+            for (l=0; (*p != '\0') && (*p != '/') && (*p != '>'); l+=2)
             {
-              *p++='\0';
-              p+=strspn(p,XMLWhitespace "=");
-              c=(*p);
-              if ((c == '"') || (c == '\''))
+              /*
+                Attribute.
+              */
+              if (l == 0)
+                attributes=(char **) AcquireQuantumMemory(4,
+                  sizeof(*attributes));
+              else
+                attributes=(char **) ResizeQuantumMemory(attributes,
+                  (size_t) (l+4),sizeof(*attributes));
+              if (attributes == (char **) NULL)
                 {
-                  /*
-                    Attributes value.
-                  */
-                  p++;
-                  attributes[l+1]=p;
-                  while ((*p != '\0') && (*p != c))
-                    p++;
-                  if (*p != '\0')
-                    *p++='\0';
-                  else
+                  (void) ThrowMagickException(exception,GetMagickModule(),
+                    ResourceLimitError,"MemoryAllocationFailed","`%s'","");
+                  utf8=DestroyString(utf8);
+                  return(&root->root);
+                }
+              attributes[l+2]=(char *) NULL;
+              attributes[l+1]=(char *) NULL;
+              attributes[l]=p;
+              p+=strcspn(p,XMLWhitespace "=/>");
+              if ((*p != '=') && (isspace((int) ((unsigned char) *p)) == 0))
+                attributes[l]=ConstantString("");
+              else
+                {
+                  *p++='\0';
+                  p+=strspn(p,XMLWhitespace "=");
+                  c=(*p);
+                  if ((c == '"') || (c == '\''))
                     {
-                      attributes[l]=ConstantString("");
-                      attributes[l+1]=ConstantString("");
-                      (void) DestroyXMLTreeAttributes(attributes);
-                      (void) ThrowMagickException(exception,GetMagickModule(),
-                        OptionWarning,"ParseError","missing %c",c);
-                      utf8=DestroyString(utf8);
-                      return(&root->root);
+                      /*
+                        Attributes value.
+                      */
+                      p++;
+                      attributes[l+1]=p;
+                      while ((*p != '\0') && (*p != c))
+                        p++;
+                      if (*p != '\0')
+                        *p++='\0';
+                      else
+                        {
+                          attributes[l]=ConstantString("");
+                          attributes[l+1]=ConstantString("");
+                          (void) DestroyXMLTreeAttributes(attributes);
+                          (void) ThrowMagickException(exception,
+                            GetMagickModule(),OptionWarning,"ParseError",
+                            "missing %c",c);
+                          utf8=DestroyString(utf8);
+                          return(&root->root);
+                        }
+                      j=1;
+                      while ((attribute != (char **) NULL) &&
+                             (attribute[j] != (char *) NULL) &&
+                             (strcmp(attribute[j],attributes[l]) != 0))
+                        j+=3;
+                      attributes[l+1]=ParseEntities(attributes[l+1],
+                        root->entities,(attribute != (char **) NULL) &&
+                        (attribute[j] != (char *) NULL) ? *attribute[j+2] :
+                        ' ');
                     }
-                  j=1;
-                  while ((attribute != (char **) NULL) &&
-                         (attribute[j] != (char *) NULL) &&
-                         (strcmp(attribute[j],attributes[l]) != 0))
-                    j+=3;
-                  attributes[l+1]=ParseEntities(attributes[l+1],root->entities,
-                    (attribute != (char **) NULL) && (attribute[j] !=
-                    (char *) NULL) ? *attribute[j+2] : ' ');
+                  attributes[l]=ConstantString(attributes[l]);
                 }
-              attributes[l]=ConstantString(attributes[l]);
+              while (isspace((int) ((unsigned char) *p)) != 0)
+                p++;
             }
-          while (isspace((int) ((unsigned char) *p)) != 0)
-            p++;
-        }
+          }
+        else
+          {
+            while((*p != '\0') && (*p != '/') && (*p != '>'))
+              p++;
+          }
         if (*p == '/')
           {
             /*
@@ -2101,8 +2137,11 @@ MagickExport XMLTreeInfo *NewXMLTree(const char *xml,ExceptionInfo *exception)
                 utf8=DestroyString(utf8);
                 return(&root->root);
               }
-            ParseOpenTag(root,tag,attributes);
-            (void) ParseCloseTag(root,tag,p,exception);
+            if (ignore_depth == 0 && CanIgnoreTag(tag) == MagickFalse)
+              {
+                ParseOpenTag(root,tag,attributes);
+                (void) ParseCloseTag(root,tag,exception);
+              }
           }
         else
           {
@@ -2110,7 +2149,10 @@ MagickExport XMLTreeInfo *NewXMLTree(const char *xml,ExceptionInfo *exception)
             if ((*p == '>') || ((*p == '\0') && (terminal == '>')))
               {
                 *p='\0';
-                ParseOpenTag(root,tag,attributes);
+                if (ignore_depth == 0 && CanIgnoreTag(tag) == MagickFalse)
+                  ParseOpenTag(root,tag,attributes);
+                else
+                  ignore_depth++;
                 *p=c;
               }
             else
@@ -2141,11 +2183,14 @@ MagickExport XMLTreeInfo *NewXMLTree(const char *xml,ExceptionInfo *exception)
               return(&root->root);
             }
           *p='\0';
-          if (ParseCloseTag(root,tag,p,exception) != (XMLTreeInfo *) NULL)
+          if (ignore_depth == 0 && ParseCloseTag(root,tag,exception) !=
+              (XMLTreeInfo *) NULL)
             {
               utf8=DestroyString(utf8);
               return(&root->root);
             }
+          if (ignore_depth > 0)
+            ignore_depth--;
           *p=c;
           if (isspace((int) ((unsigned char) *p)) != 0)
             p+=strspn(p,XMLWhitespace);
@@ -2176,7 +2221,8 @@ MagickExport XMLTreeInfo *NewXMLTree(const char *xml,ExceptionInfo *exception)
               if (p != (char *) NULL)
                 {
                   p+=2;
-                  ParseCharacterContent(root,tag+8,(size_t) (p-tag-10),'c');
+                  if (ignore_depth == 0)
+                    ParseCharacterContent(root,tag+8,(size_t) (p-tag-10),'c');
                 }
               else
                 {
@@ -2261,7 +2307,8 @@ MagickExport XMLTreeInfo *NewXMLTree(const char *xml,ExceptionInfo *exception)
           p++;
         if (*p == '\0')
           break;
-        ParseCharacterContent(root,tag,(size_t) (p-tag),'&');
+        if (ignore_depth == 0)
+          ParseCharacterContent(root,tag,(size_t) (p-tag),'&');
       }
     else
       if (*p == '\0')