]> granicus.if.org Git - imagemagick/blobdiff - MagickCore/magic.c
(no commit message)
[imagemagick] / MagickCore / magic.c
index 694ba813343af4e899356fd18e60aafeb5f97df4..9eeb5af4fde0d45e0fe82d7af3c85dfbc4b684bd 100644 (file)
@@ -17,7 +17,7 @@
 %                                 July 2000                                   %
 %                                                                             %
 %                                                                             %
-%  Copyright 1999-2014 ImageMagick Studio LLC, a non-profit organization      %
+%  Copyright 1999-2015 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  %
@@ -57,6 +57,7 @@
 #include "MagickCore/utility.h"
 #include "MagickCore/utility-private.h"
 #include "MagickCore/xml-tree.h"
+#include "MagickCore/xml-tree-private.h"
 \f
 /*
   Define declarations.
@@ -120,7 +121,6 @@ static const MagicMapInfo
     { "FIG", 0, MagickString("#FIG") },
     { "FITS", 0, MagickString("IT0") },
     { "FITS", 0, MagickString("SIMPLE") },
-    { "FPX", 0, MagickString("\320\317\021\340") },
     { "GIF", 0, MagickString("GIF8") },
     { "GPLT", 0, MagickString("#!/usr/local/bin/gnuplot") },
     { "HDF", 1, MagickString("HDF") },
@@ -135,8 +135,9 @@ static const MagicMapInfo
     { "IPTC", 0, MagickString("\034\002") },
     { "JNG", 0, MagickString("\213JNG\r\n\032\n") },
     { "JPEG", 0, MagickString("\377\330\377") },
-    { "JPC", 0, MagickString("\377\117") },
-    { "JP2", 4, MagickString("\152\120\040\040\015") },
+    { "J2K", 0, MagickString("\xff\x4f\xff\x51") },
+    { "JPC", 0, MagickString("\x0d\x0a\x87\x0a") },
+    { "JP2", 4, MagickString("\x00\x00\x00\x0c\x6a\x50\x20\x20\x0d\x0a\x87\x0a") },
     { "MAT", 0, MagickString("MATLAB 5.0 MAT-file,") },
     { "MIFF", 0, MagickString("Id=ImageMagick") },
     { "MIFF", 0, MagickString("id=ImageMagick") },
@@ -203,20 +204,117 @@ static const MagicMapInfo
  };
 
 static LinkedListInfo
-  *magic_list = (LinkedListInfo *) NULL;
+  *magic_cache = (LinkedListInfo *) NULL;
 
 static SemaphoreInfo
   *magic_semaphore = (SemaphoreInfo *) NULL;
-
-static volatile MagickBooleanType
-  instantiate_magic = MagickFalse;
 \f
 /*
   Forward declarations.
 */
 static MagickBooleanType
-  InitializeMagicList(ExceptionInfo *),
-  LoadMagicLists(const char *,ExceptionInfo *);
+  IsMagicCacheInstantiated(ExceptionInfo *),
+  LoadMagicCache(LinkedListInfo *,const char *,const char *,const size_t,
+    ExceptionInfo *);
+\f
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%                                                                             %
+%                                                                             %
+%                                                                             %
+%  A c q u i r e M a g i c L i s t s                                          %
+%                                                                             %
+%                                                                             %
+%                                                                             %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+%  AcquireMagicCache() caches one or more magic configurations which provides a
+%  mapping between magic attributes and a magic name.
+%
+%  The format of the AcquireMagicCache method is:
+%
+%      LinkedListInfo *AcquireMagicCache(const char *filename,
+%        ExceptionInfo *exception)
+%
+%  A description of each parameter follows:
+%
+%    o filename: the font file name.
+%
+%    o exception: return any errors or warnings in this structure.
+%
+*/
+static LinkedListInfo *AcquireMagicCache(const char *filename,
+  ExceptionInfo *exception)
+{
+  char
+    path[MaxTextExtent];
+
+  const StringInfo
+    *option;
+
+  LinkedListInfo
+    *magic_cache,
+    *options;
+
+  MagickStatusType
+    status;
+
+  register ssize_t
+    i;
+
+  /*
+    Load external magic map.
+  */
+  magic_cache=NewLinkedList(0);
+  if (magic_cache == (LinkedListInfo *) NULL)
+    ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed");
+  status=MagickTrue;
+  *path='\0';
+  options=GetConfigureOptions(filename,exception);
+  option=(const StringInfo *) GetNextValueInLinkedList(options);
+  while (option != (const StringInfo *) NULL)
+  {
+    (void) CopyMagickString(path,GetStringInfoPath(option),MaxTextExtent);
+    status&=LoadMagicCache(magic_cache,(const char *)
+      GetStringInfoDatum(option),GetStringInfoPath(option),0,exception);
+    option=(const StringInfo *) GetNextValueInLinkedList(options);
+  }
+  options=DestroyConfigureOptions(options);
+  /*
+    Load built-in magic map.
+  */
+  for (i=0; i < (ssize_t) (sizeof(MagicMap)/sizeof(*MagicMap)); i++)
+  {
+    MagicInfo
+      *magic_info;
+
+    register const MagicMapInfo
+      *p;
+
+    p=MagicMap+i;
+    magic_info=(MagicInfo *) AcquireMagickMemory(sizeof(*magic_info));
+    if (magic_info == (MagicInfo *) NULL)
+      {
+        (void) ThrowMagickException(exception,GetMagickModule(),
+          ResourceLimitError,"MemoryAllocationFailed","`%s'",p->name);
+        continue;
+      }
+    (void) ResetMagickMemory(magic_info,0,sizeof(*magic_info));
+    magic_info->path=(char *) "[built-in]";
+    magic_info->name=(char *) p->name;
+    magic_info->offset=p->offset;
+    magic_info->target=(char *) p->magic;
+    magic_info->magic=(unsigned char *) p->magic;
+    magic_info->length=p->length;
+    magic_info->exempt=MagickTrue;
+    magic_info->signature=MagickSignature;
+    status&=AppendValueToLinkedList(magic_cache,magic_info);
+    if (status == MagickFalse)
+      (void) ThrowMagickException(exception,GetMagickModule(),
+        ResourceLimitError,"MemoryAllocationFailed","`%s'",magic_info->name);
+  }
+  return(magic_cache);
+}
 \f
 /*
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@@ -254,34 +352,30 @@ MagickExport const MagicInfo *GetMagicInfo(const unsigned char *magic,
     *p;
 
   assert(exception != (ExceptionInfo *) NULL);
-  if ((magic_list == (LinkedListInfo *) NULL) ||
-      (instantiate_magic == MagickFalse))
-    if (InitializeMagicList(exception) == MagickFalse)
-      return((const MagicInfo *) NULL);
-  if ((magic_list == (LinkedListInfo *) NULL) ||
-      (IsLinkedListEmpty(magic_list) != MagickFalse))
-    return((const MagicInfo *) NULL);
-  if (magic == (const unsigned char *) NULL)
-    return((const MagicInfo *) GetValueFromLinkedList(magic_list,0));
-  if (length == 0)
+  if (IsMagicCacheInstantiated(exception) == MagickFalse)
     return((const MagicInfo *) NULL);
   /*
     Search for magic tag.
   */
   LockSemaphoreInfo(magic_semaphore);
-  ResetLinkedListIterator(magic_list);
-  p=(const MagicInfo *) GetNextValueInLinkedList(magic_list);
+  ResetLinkedListIterator(magic_cache);
+  p=(const MagicInfo *) GetNextValueInLinkedList(magic_cache);
+  if (magic == (const unsigned char *) NULL)
+    {
+      UnlockSemaphoreInfo(magic_semaphore);
+      return(p);
+    }
   while (p != (const MagicInfo *) NULL)
   {
     assert(p->offset >= 0);
     if (((size_t) (p->offset+p->length) <= length) &&
         (memcmp(magic+p->offset,p->magic,p->length) == 0))
       break;
-    p=(const MagicInfo *) GetNextValueInLinkedList(magic_list);
+    p=(const MagicInfo *) GetNextValueInLinkedList(magic_cache);
   }
   if (p != (const MagicInfo *) NULL)
-    (void) InsertValueInLinkedList(magic_list,0,
-      RemoveElementByValueFromLinkedList(magic_list,p));
+    (void) InsertValueInLinkedList(magic_cache,0,
+      RemoveElementByValueFromLinkedList(magic_cache,p));
   UnlockSemaphoreInfo(magic_semaphore);
   return(p);
 }
@@ -359,21 +453,21 @@ MagickExport const MagicInfo **GetMagicInfoList(const char *pattern,
   if (p == (const MagicInfo *) NULL)
     return((const MagicInfo **) NULL);
   aliases=(const MagicInfo **) AcquireQuantumMemory((size_t)
-    GetNumberOfElementsInLinkedList(magic_list)+1UL,sizeof(*aliases));
+    GetNumberOfElementsInLinkedList(magic_cache)+1UL,sizeof(*aliases));
   if (aliases == (const MagicInfo **) NULL)
     return((const MagicInfo **) NULL);
   /*
     Generate magic list.
   */
   LockSemaphoreInfo(magic_semaphore);
-  ResetLinkedListIterator(magic_list);
-  p=(const MagicInfo *) GetNextValueInLinkedList(magic_list);
+  ResetLinkedListIterator(magic_cache);
+  p=(const MagicInfo *) GetNextValueInLinkedList(magic_cache);
   for (i=0; p != (const MagicInfo *) NULL; )
   {
     if ((p->stealth == MagickFalse) &&
         (GlobExpression(p->name,pattern,MagickFalse) != MagickFalse))
       aliases[i++]=p;
-    p=(const MagicInfo *) GetNextValueInLinkedList(magic_list);
+    p=(const MagicInfo *) GetNextValueInLinkedList(magic_cache);
   }
   UnlockSemaphoreInfo(magic_semaphore);
   qsort((void *) aliases,(size_t) i,sizeof(*aliases),MagicInfoCompare);
@@ -431,8 +525,8 @@ static int MagicCompare(const void *x,const void *y)
 }
 #endif
 
-MagickExport char **GetMagicList(const char *pattern,
-  size_t *number_aliases,ExceptionInfo *exception)
+MagickExport char **GetMagicList(const char *pattern,size_t *number_aliases,
+  ExceptionInfo *exception)
 {
   char
     **aliases;
@@ -454,18 +548,18 @@ MagickExport char **GetMagicList(const char *pattern,
   if (p == (const MagicInfo *) NULL)
     return((char **) NULL);
   aliases=(char **) AcquireQuantumMemory((size_t)
-    GetNumberOfElementsInLinkedList(magic_list)+1UL,sizeof(*aliases));
+    GetNumberOfElementsInLinkedList(magic_cache)+1UL,sizeof(*aliases));
   if (aliases == (char **) NULL)
     return((char **) NULL);
   LockSemaphoreInfo(magic_semaphore);
-  ResetLinkedListIterator(magic_list);
-  p=(const MagicInfo *) GetNextValueInLinkedList(magic_list);
+  ResetLinkedListIterator(magic_cache);
+  p=(const MagicInfo *) GetNextValueInLinkedList(magic_cache);
   for (i=0; p != (const MagicInfo *) NULL; )
   {
     if ((p->stealth == MagickFalse) &&
         (GlobExpression(p->name,pattern,MagickFalse) != MagickFalse))
       aliases[i++]=ConstantString(p->name);
-    p=(const MagicInfo *) GetNextValueInLinkedList(magic_list);
+    p=(const MagicInfo *) GetNextValueInLinkedList(magic_cache);
   }
   UnlockSemaphoreInfo(magic_semaphore);
   qsort((void *) aliases,(size_t) i,sizeof(*aliases),MagicCompare);
@@ -509,40 +603,36 @@ MagickExport const char *GetMagicName(const MagicInfo *magic_info)
 %                                                                             %
 %                                                                             %
 %                                                                             %
-+   I n i t i a l i z e M a g i c L i s t                                     %
++   I s M a g i c C a c h e I n s t a n t i a t e d                           %
 %                                                                             %
 %                                                                             %
 %                                                                             %
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 %
-%  InitializeMagicList() initializes the magic list.
+%  IsMagicCacheInstantiated() determines if the magic list is instantiated.
+%  If not, it instantiates the list and returns it.
 %
-%  The format of the InitializeMagicList method is:
+%  The format of the IsMagicInstantiated method is:
 %
-%      MagickBooleanType InitializeMagicList(ExceptionInfo *exception)
+%      MagickBooleanType IsMagicCacheInstantiated(ExceptionInfo *exception)
 %
 %  A description of each parameter follows.
 %
 %    o exception: return any errors or warnings in this structure.
 %
 */
-static MagickBooleanType InitializeMagicList(ExceptionInfo *exception)
+static MagickBooleanType IsMagicCacheInstantiated(ExceptionInfo *exception)
 {
-  if ((magic_list == (LinkedListInfo *) NULL) &&
-      (instantiate_magic == MagickFalse))
+  if (magic_cache == (LinkedListInfo *) NULL)
     {
       if (magic_semaphore == (SemaphoreInfo *) NULL)
-        AcquireSemaphoreInfo(&magic_semaphore);
+        ActivateSemaphoreInfo(&magic_semaphore);
       LockSemaphoreInfo(magic_semaphore);
-      if ((magic_list == (LinkedListInfo *) NULL) &&
-          (instantiate_magic == MagickFalse))
-        {
-          (void) LoadMagicLists(MagicFilename,exception);
-          instantiate_magic=MagickTrue;
-        }
+      if (magic_cache == (LinkedListInfo *) NULL)
+        magic_cache=AcquireMagicCache(MagicFilename,exception);
       UnlockSemaphoreInfo(magic_semaphore);
     }
-  return(magic_list != (LinkedListInfo *) NULL ? MagickTrue : MagickFalse);
+  return(magic_cache != (LinkedListInfo *) NULL ? MagickTrue : MagickFalse);
 }
 \f
 /*
@@ -643,13 +733,14 @@ MagickExport MagickBooleanType ListMagicInfo(FILE *file,
 %                                                                             %
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 %
-%  LoadMagicList() loads the magic configuration file which provides a mapping
+%  LoadMagicCache() loads the magic configurations which provides a mapping
 %  between magic attributes and a magic name.
 %
-%  The format of the LoadMagicList method is:
+%  The format of the LoadMagicCache method is:
 %
-%      MagickBooleanType LoadMagicList(const char *xml,const char *filename,
-%        const size_t depth,ExceptionInfo *exception)
+%      MagickBooleanType LoadMagicCache(LinkedListInfo *magic_cache,
+%        const char *xml,const char *filename,const size_t depth,
+%        ExceptionInfo *exception)
 %
 %  A description of each parameter follows:
 %
@@ -662,8 +753,9 @@ MagickExport MagickBooleanType ListMagicInfo(FILE *file,
 %    o exception: return any errors or warnings in this structure.
 %
 */
-static MagickBooleanType LoadMagicList(const char *xml,const char *filename,
-  const size_t depth,ExceptionInfo *exception)
+static MagickBooleanType LoadMagicCache(LinkedListInfo *magic_cache,
+  const char *xml,const char *filename,const size_t depth,
+  ExceptionInfo *exception)
 {
   char
     keyword[MaxTextExtent],
@@ -672,12 +764,12 @@ static MagickBooleanType LoadMagicList(const char *xml,const char *filename,
   const char
     *q;
 
-  MagickBooleanType
-    status;
-
   MagicInfo
     *magic_info;
 
+  MagickStatusType
+    status;
+
   /*
     Load the magic map file.
   */
@@ -685,16 +777,6 @@ static MagickBooleanType LoadMagicList(const char *xml,const char *filename,
     "Loading magic configure file \"%s\" ...",filename);
   if (xml == (char *) NULL)
     return(MagickFalse);
-  if (magic_list == (LinkedListInfo *) NULL)
-    {
-      magic_list=NewLinkedList(0);
-      if (magic_list == (LinkedListInfo *) NULL)
-        {
-          ThrowFileException(exception,ResourceLimitError,
-            "MemoryAllocationFailed",filename);
-          return(MagickFalse);
-        }
-    }
   status=MagickTrue;
   magic_info=(MagicInfo *) NULL;
   token=AcquireString(xml);
@@ -756,10 +838,11 @@ static MagickBooleanType LoadMagicList(const char *xml,const char *filename,
                     (void) CopyMagickString(path,token,MaxTextExtent);
                   else
                     (void) ConcatenateMagickString(path,token,MaxTextExtent);
-                  xml=FileToString(path,~0UL,exception);
+                  xml=FileToXML(path,~0UL);
                   if (xml != (char *) NULL)
                     {
-                      status=LoadMagicList(xml,path,depth+1,exception);
+                      status&=LoadMagicCache(magic_cache,xml,path,depth+1,
+                        exception);
                       xml=(char *) RelinquishMagickMemory(xml);
                     }
                 }
@@ -785,12 +868,13 @@ static MagickBooleanType LoadMagicList(const char *xml,const char *filename,
       continue;
     if (LocaleCompare(keyword,"/>") == 0)
       {
-        status=AppendValueToLinkedList(magic_list,magic_info);
+        status=AppendValueToLinkedList(magic_cache,magic_info);
         if (status == MagickFalse)
           (void) ThrowMagickException(exception,GetMagickModule(),
             ResourceLimitError,"MemoryAllocationFailed","`%s'",
             magic_info->name);
         magic_info=(MagicInfo *) NULL;
+        continue;
       }
     GetMagickToken(q,(const char **) NULL,token);
     if (*token != '=')
@@ -894,111 +978,6 @@ static MagickBooleanType LoadMagicList(const char *xml,const char *filename,
     }
   }
   token=(char *) RelinquishMagickMemory(token);
-  return(status);
-}
-\f
-/*
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-%                                                                             %
-%                                                                             %
-%                                                                             %
-%  L o a d M a g i c L i s t s                                                %
-%                                                                             %
-%                                                                             %
-%                                                                             %
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-%
-%  LoadMagicLists() loads one or more magic configuration file which provides a
-%  mapping between magic attributes and a magic name.
-%
-%  The format of the LoadMagicLists method is:
-%
-%      MagickBooleanType LoadMagicLists(const char *filename,
-%        ExceptionInfo *exception)
-%
-%  A description of each parameter follows:
-%
-%    o filename: the font file name.
-%
-%    o exception: return any errors or warnings in this structure.
-%
-*/
-static MagickBooleanType LoadMagicLists(const char *filename,
-  ExceptionInfo *exception)
-{
-  char
-    path[MaxTextExtent];
-
-  const StringInfo
-    *option;
-
-  LinkedListInfo
-    *options;
-
-  MagickStatusType
-    status;
-
-  register ssize_t
-    i;
-
-  /*
-    Load external magic map.
-  */
-  if (magic_list == (LinkedListInfo *) NULL)
-    {
-      magic_list=NewLinkedList(0);
-      if (magic_list == (LinkedListInfo *) NULL)
-        {
-          ThrowFileException(exception,ResourceLimitError,
-            "MemoryAllocationFailed",filename);
-          return(MagickFalse);
-        }
-    }
-  status=MagickTrue;
-  *path='\0';
-  options=GetConfigureOptions(filename,exception);
-  option=(const StringInfo *) GetNextValueInLinkedList(options);
-  while (option != (const StringInfo *) NULL)
-  {
-    (void) CopyMagickString(path,GetStringInfoPath(option),MaxTextExtent);
-    status&=LoadMagicList((const char *) GetStringInfoDatum(option),
-      GetStringInfoPath(option),0,exception);
-    option=(const StringInfo *) GetNextValueInLinkedList(options);
-  }
-  options=DestroyConfigureOptions(options);
-  /*
-    Load built-in magic map.
-  */
-  for (i=0; i < (ssize_t) (sizeof(MagicMap)/sizeof(*MagicMap)); i++)
-  {
-    MagicInfo
-      *magic_info;
-
-    register const MagicMapInfo
-      *p;
-
-    p=MagicMap+i;
-    magic_info=(MagicInfo *) AcquireMagickMemory(sizeof(*magic_info));
-    if (magic_info == (MagicInfo *) NULL)
-      {
-        (void) ThrowMagickException(exception,GetMagickModule(),
-          ResourceLimitError,"MemoryAllocationFailed","`%s'",magic_info->name);
-        continue;
-      }
-    (void) ResetMagickMemory(magic_info,0,sizeof(*magic_info));
-    magic_info->path=(char *) "[built-in]";
-    magic_info->name=(char *) p->name;
-    magic_info->offset=p->offset;
-    magic_info->target=(char *) p->magic;
-    magic_info->magic=(unsigned char *) p->magic;
-    magic_info->length=p->length;
-    magic_info->exempt=MagickTrue;
-    magic_info->signature=MagickSignature;
-    status&=AppendValueToLinkedList(magic_list,magic_info);
-    if (status == MagickFalse)
-      (void) ThrowMagickException(exception,GetMagickModule(),
-        ResourceLimitError,"MemoryAllocationFailed","`%s'",magic_info->name);
-  }
   return(status != 0 ? MagickTrue : MagickFalse);
 }
 \f
@@ -1022,7 +1001,8 @@ static MagickBooleanType LoadMagicLists(const char *filename,
 */
 MagickPrivate MagickBooleanType MagicComponentGenesis(void)
 {
-  AcquireSemaphoreInfo(&magic_semaphore);
+  if (magic_semaphore == (SemaphoreInfo *) NULL)
+    magic_semaphore=AcquireSemaphoreInfo();
   return(MagickTrue);
 }
 \f
@@ -1069,11 +1049,10 @@ static void *DestroyMagicElement(void *magic_info)
 MagickPrivate void MagicComponentTerminus(void)
 {
   if (magic_semaphore == (SemaphoreInfo *) NULL)
-    AcquireSemaphoreInfo(&magic_semaphore);
+    ActivateSemaphoreInfo(&magic_semaphore);
   LockSemaphoreInfo(magic_semaphore);
-  if (magic_list != (LinkedListInfo *) NULL)
-    magic_list=DestroyLinkedList(magic_list,DestroyMagicElement);
-  instantiate_magic=MagickFalse;
+  if (magic_cache != (LinkedListInfo *) NULL)
+    magic_cache=DestroyLinkedList(magic_cache,DestroyMagicElement);
   UnlockSemaphoreInfo(magic_semaphore);
-  DestroySemaphoreInfo(&magic_semaphore);
+  RelinquishSemaphoreInfo(&magic_semaphore);
 }