Home | History | Annotate | Download | only in MagickCore
      1 /*
      2 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
      3 %                                                                             %
      4 %                                                                             %
      5 %                                                                             %
      6 %                  M   M   AAA    GGGG  IIIII   CCCC  K   K                   %
      7 %                  MM MM  A   A  G        I    C      K  K                    %
      8 %                  M M M  AAAAA  G GGG    I    C      KKK                     %
      9 %                  M   M  A   A  G   G    I    C      K  K                    %
     10 %                  M   M  A   A   GGGG  IIIII   CCCC  K   K                   %
     11 %                                                                             %
     12 %                                                                             %
     13 %               Methods to Read or List ImageMagick Image formats             %
     14 %                                                                             %
     15 %                            Software Design                                  %
     16 %                            Bob Friesenhahn                                  %
     17 %                                 Cristy                                      %
     18 %                             November 1998                                   %
     19 %                                                                             %
     20 %                                                                             %
     21 %  Copyright 1999-2016 ImageMagick Studio LLC, a non-profit organization      %
     22 %  dedicated to making software imaging solutions freely available.           %
     23 %                                                                             %
     24 %  You may not use this file except in compliance with the License.  You may  %
     25 %  obtain a copy of the License at                                            %
     26 %                                                                             %
     27 %    http://www.imagemagick.org/script/license.php                            %
     28 %                                                                             %
     29 %  Unless required by applicable law or agreed to in writing, software        %
     30 %  distributed under the License is distributed on an "AS IS" BASIS,          %
     31 %  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.   %
     32 %  See the License for the specific language governing permissions and        %
     33 %  limitations under the License.                                             %
     34 %                                                                             %
     35 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
     36 %
     37 %
     38 */
     39 
     40 /*
     42   Include declarations.
     43 */
     44 #include "MagickCore/studio.h"
     45 #include "MagickCore/annotate-private.h"
     46 #include "MagickCore/blob.h"
     47 #include "MagickCore/blob-private.h"
     48 #include "MagickCore/cache.h"
     49 #include "MagickCore/cache-private.h"
     50 #include "MagickCore/coder-private.h"
     51 #include "MagickCore/client.h"
     52 #include "MagickCore/color-private.h"
     53 #include "MagickCore/configure-private.h"
     54 #include "MagickCore/constitute-private.h"
     55 #include "MagickCore/delegate-private.h"
     56 #include "MagickCore/draw.h"
     57 #include "MagickCore/exception.h"
     58 #include "MagickCore/exception-private.h"
     59 #include "MagickCore/locale-private.h"
     60 #include "MagickCore/log-private.h"
     61 #include "MagickCore/magic-private.h"
     62 #include "MagickCore/magick.h"
     63 #include "MagickCore/magick-private.h"
     64 #include "MagickCore/memory_.h"
     65 #include "MagickCore/mime-private.h"
     66 #include "MagickCore/module.h"
     67 #include "MagickCore/module-private.h"
     68 #include "MagickCore/nt-base-private.h"
     69 #include "MagickCore/nt-feature.h"
     70 #include "MagickCore/opencl-private.h"
     71 #include "MagickCore/option-private.h"
     72 #include "MagickCore/random-private.h"
     73 #include "MagickCore/registry.h"
     74 #include "MagickCore/registry-private.h"
     75 #include "MagickCore/resource_.h"
     76 #include "MagickCore/resource-private.h"
     77 #include "MagickCore/policy.h"
     78 #include "MagickCore/policy-private.h"
     79 #include "MagickCore/semaphore.h"
     80 #include "MagickCore/semaphore-private.h"
     81 #include "MagickCore/signature-private.h"
     82 #include "MagickCore/splay-tree.h"
     83 #include "MagickCore/string_.h"
     84 #include "MagickCore/string-private.h"
     85 #include "MagickCore/thread_.h"
     86 #include "MagickCore/thread-private.h"
     87 #include "MagickCore/type-private.h"
     88 #include "MagickCore/token.h"
     89 #include "MagickCore/utility.h"
     90 #include "MagickCore/utility-private.h"
     91 #include "MagickCore/xwindow-private.h"
     92 
     93 /*
     95   Define declarations.
     96 */
     97 #if !defined(MAGICKCORE_RETSIGTYPE)
     98 # define MAGICKCORE_RETSIGTYPE  void
     99 #endif
    100 #if !defined(SIG_DFL)
    101 # define SIG_DFL  ((SignalHandler *) 0)
    102 #endif
    103 #if !defined(SIG_ERR)
    104 # define SIG_ERR  ((SignalHandler *) -1)
    105 #endif
    106 #if !defined(SIGMAX)
    107 #define SIGMAX  64
    108 #endif
    109 
    110 /*
    112   Typedef declarations.
    113 */
    114 typedef MAGICKCORE_RETSIGTYPE
    115   SignalHandler(int);
    116 
    117 /*
    119   Global declarations.
    120 */
    121 static SemaphoreInfo
    122   *magick_semaphore = (SemaphoreInfo *) NULL;
    123 
    124 static SignalHandler
    125   *signal_handlers[SIGMAX] = { (SignalHandler *) NULL };
    126 
    127 static SplayTreeInfo
    128   *magick_list = (SplayTreeInfo *) NULL;
    129 
    130 static volatile MagickBooleanType
    131   instantiate_magickcore = MagickFalse,
    132   magickcore_signal_in_progress = MagickFalse;
    133 
    134 /*
    136   Forward declarations.
    137 */
    138 static MagickBooleanType
    139   IsMagickTreeInstantiated(ExceptionInfo *);
    140 
    141 /*
    143 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    144 %                                                                             %
    145 %                                                                             %
    146 %                                                                             %
    147 %    A c q u i r e M a g i c k I n f o                                        %
    148 %                                                                             %
    149 %                                                                             %
    150 %                                                                             %
    151 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    152 %
    153 %  AcquireMagickInfo() allocates a MagickInfo structure and initializes the
    154 %  members to default values.
    155 %
    156 %  The format of the AcquireMagickInfo method is:
    157 %
    158 %      MagickInfo *AcquireMagickInfo(const char *module, const char *name,)
    159 %
    160 %  A description of each parameter follows:
    161 %
    162 %    o module: a character string that represents the module associated
    163 %      with the MagickInfo structure.
    164 %
    165 %    o name: a character string that represents the image format associated
    166 %      with the MagickInfo structure.
    167 %
    168 %    o description: a character string that represents the image format
    169 %      associated with the MagickInfo structure.
    170 %
    171 */
    172 MagickExport MagickInfo *AcquireMagickInfo(const char *module,
    173   const char *name, const char *description)
    174 {
    175   MagickInfo
    176     *magick_info;
    177 
    178   assert(module != (const char *) NULL);
    179   assert(name != (const char *) NULL);
    180   assert(description != (const char *) NULL);
    181   (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",name);
    182   magick_info=(MagickInfo *) AcquireMagickMemory(sizeof(*magick_info));
    183   if (magick_info == (MagickInfo *) NULL)
    184     ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed");
    185   (void) ResetMagickMemory(magick_info,0,sizeof(*magick_info));
    186   magick_info->module=ConstantString(module);
    187   magick_info->name=ConstantString(name);
    188   magick_info->description=ConstantString(description);
    189   magick_info->flags=CoderAdjoinFlag | CoderBlobSupportFlag |
    190     CoderDecoderThreadSupportFlag | CoderEncoderThreadSupportFlag |
    191     CoderUseExtensionFlag;
    192   magick_info->signature=MagickCoreSignature;
    193   return(magick_info);
    194 }
    195 
    196 /*
    198 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    199 %                                                                             %
    200 %                                                                             %
    201 %                                                                             %
    202 +   G e t I m a g e D e c o d e r                                             %
    203 %                                                                             %
    204 %                                                                             %
    205 %                                                                             %
    206 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    207 %
    208 %  GetImageDecoder() returns the image decoder.
    209 %
    210 %  The format of the GetImageDecoder method is:
    211 %
    212 %      DecodeImageHandler *GetImageDecoder(const MagickInfo *magick_info)
    213 %
    214 %  A description of each parameter follows:
    215 %
    216 %    o magick_info:  The magick info.
    217 %
    218 */
    219 MagickExport DecodeImageHandler *GetImageDecoder(const MagickInfo *magick_info)
    220 {
    221   assert(magick_info != (MagickInfo *) NULL);
    222   assert(magick_info->signature == MagickCoreSignature);
    223   return(magick_info->decoder);
    224 }
    225 
    226 /*
    228 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    229 %                                                                             %
    230 %                                                                             %
    231 %                                                                             %
    232 +   G e t I m a g e E n c o d e r                                             %
    233 %                                                                             %
    234 %                                                                             %
    235 %                                                                             %
    236 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    237 %
    238 %  GetImageEncoder() returns the image encoder.
    239 %
    240 %  The format of the GetImageEncoder method is:
    241 %
    242 %      EncodeImageHandler *GetImageEncoder(const MagickInfo *magick_info)
    243 %
    244 %  A description of each parameter follows:
    245 %
    246 %    o magick_info:  The magick info.
    247 %
    248 */
    249 MagickExport EncodeImageHandler *GetImageEncoder(const MagickInfo *magick_info)
    250 {
    251   assert(magick_info != (MagickInfo *) NULL);
    252   assert(magick_info->signature == MagickCoreSignature);
    253   return(magick_info->encoder);
    254 }
    255 
    256 /*
    258 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    259 %                                                                             %
    260 %                                                                             %
    261 %                                                                             %
    262 +   G e t I m a g e M a g i c k                                               %
    263 %                                                                             %
    264 %                                                                             %
    265 %                                                                             %
    266 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    267 %
    268 %  GetImageMagick() searches for an image format that matches the specified
    269 %  magick string.  If one is found, MagickTrue is returned otherwise
    270 %  MagickFalse.
    271 %
    272 %  The format of the GetImageMagick method is:
    273 %
    274 %      MagickBooleanType GetImageMagick(const unsigned char *magick,
    275 %        const size_t length,char *format)
    276 %
    277 %  A description of each parameter follows:
    278 %
    279 %    o magick: the image format we are searching for.
    280 %
    281 %    o length: the length of the binary string.
    282 %
    283 %    o format: the image format as determined by the magick bytes.
    284 %
    285 */
    286 MagickExport MagickBooleanType GetImageMagick(const unsigned char *magick,
    287   const size_t length,char *format)
    288 {
    289   ExceptionInfo
    290     *exception;
    291 
    292   MagickBooleanType
    293     status;
    294 
    295   register const MagickInfo
    296     *p;
    297 
    298   (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
    299   assert(magick != (const unsigned char *) NULL);
    300   exception=AcquireExceptionInfo();
    301   p=GetMagickInfo("*",exception);
    302   exception=DestroyExceptionInfo(exception);
    303   if (p == (const MagickInfo *) NULL)
    304     return(MagickFalse);
    305   status=MagickFalse;
    306   LockSemaphoreInfo(magick_semaphore);
    307   ResetSplayTreeIterator(magick_list);
    308   p=(const MagickInfo *) GetNextValueInSplayTree(magick_list);
    309   while (p != (const MagickInfo *) NULL)
    310   {
    311     if ((p->magick != (IsImageFormatHandler *) NULL) &&
    312         (p->magick(magick,length) != 0))
    313       {
    314         status=MagickTrue;
    315         (void) CopyMagickString(format,p->name,MagickPathExtent);
    316         break;
    317       }
    318     p=(const MagickInfo *) GetNextValueInSplayTree(magick_list);
    319   }
    320   UnlockSemaphoreInfo(magick_semaphore);
    321   return(status);
    322 }
    323 
    324 /*
    326 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    327 %                                                                             %
    328 %                                                                             %
    329 %                                                                             %
    330 +   G e t M a g i c k A d j o i n                                             %
    331 %                                                                             %
    332 %                                                                             %
    333 %                                                                             %
    334 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    335 %
    336 %  GetMagickAdjoin() returns MagickTrue if the magick adjoin is MagickTrue.
    337 %
    338 %  The format of the GetMagickAdjoin method is:
    339 %
    340 %      MagickBooleanType GetMagickAdjoin(const MagickInfo *magick_info)
    341 %
    342 %  A description of each parameter follows:
    343 %
    344 %    o magick_info:  The magick info.
    345 %
    346 */
    347 MagickExport MagickBooleanType GetMagickAdjoin(const MagickInfo *magick_info)
    348 {
    349   assert(magick_info != (MagickInfo *) NULL);
    350   assert(magick_info->signature == MagickCoreSignature);
    351   return(((magick_info->flags & CoderAdjoinFlag) == 0) ? MagickFalse :
    352     MagickTrue);
    353 }
    354 
    355 /*
    357 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    358 %                                                                             %
    359 %                                                                             %
    360 %                                                                             %
    361 +   G e t M a g i c k B l o b S u p p o r t                                   %
    362 %                                                                             %
    363 %                                                                             %
    364 %                                                                             %
    365 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    366 %
    367 %  GetMagickBlobSupport() returns MagickTrue if the magick supports blobs.
    368 %
    369 %  The format of the GetMagickBlobSupport method is:
    370 %
    371 %      MagickBooleanType GetMagickBlobSupport(const MagickInfo *magick_info)
    372 %
    373 %  A description of each parameter follows:
    374 %
    375 %    o magick_info:  The magick info.
    376 %
    377 */
    378 MagickExport MagickBooleanType GetMagickBlobSupport(
    379   const MagickInfo *magick_info)
    380 {
    381   assert(magick_info != (MagickInfo *) NULL);
    382   assert(magick_info->signature == MagickCoreSignature);
    383   return(((magick_info->flags & CoderBlobSupportFlag) == 0) ? MagickFalse :
    384     MagickTrue);
    385 }
    386 
    387 /*
    389 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    390 %                                                                             %
    391 %                                                                             %
    392 %                                                                             %
    393 +   G e t M a g i c k D e c o d e r T h r e a d S u p p o r t                 %
    394 %                                                                             %
    395 %                                                                             %
    396 %                                                                             %
    397 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    398 %
    399 %  GetMagickDecoderThreadSupport() returns MagickTrue if the decoder supports
    400 %  threads.
    401 %
    402 %  The format of the GetMagickDecoderThreadSupport method is:
    403 %
    404 %      MagickStatusType GetMagickDecoderThreadSupport(
    405 %        const MagickInfo *magick_info)
    406 %
    407 %  A description of each parameter follows:
    408 %
    409 %    o magick_info:  The magick info.
    410 %
    411 */
    412 MagickExport MagickBooleanType GetMagickDecoderThreadSupport(
    413   const MagickInfo *magick_info)
    414 {
    415   assert(magick_info != (MagickInfo *) NULL);
    416   assert(magick_info->signature == MagickCoreSignature);
    417   return(((magick_info->flags & CoderDecoderThreadSupportFlag) == 0) ?
    418     MagickFalse : MagickTrue);
    419 }
    420 
    421 /*
    423 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    424 %                                                                             %
    425 %                                                                             %
    426 %                                                                             %
    427 +   G e t M a g i c k D e s c r i p t i o n                                   %
    428 %                                                                             %
    429 %                                                                             %
    430 %                                                                             %
    431 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    432 %
    433 %  GetMagickDescription() returns the magick description.
    434 %
    435 %  The format of the GetMagickDescription method is:
    436 %
    437 %      const char *GetMagickDescription(const MagickInfo *magick_info)
    438 %
    439 %  A description of each parameter follows:
    440 %
    441 %    o magick_info:  The magick info.
    442 %
    443 */
    444 MagickExport const char *GetMagickDescription(const MagickInfo *magick_info)
    445 {
    446   assert(magick_info != (MagickInfo *) NULL);
    447   assert(magick_info->signature == MagickCoreSignature);
    448   return(magick_info->description);
    449 }
    450 
    451 /*
    453 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    454 %                                                                             %
    455 %                                                                             %
    456 %                                                                             %
    457 +   G e t M a g i c k E n c o d e r T h r e a d S u p p o r t                 %
    458 %                                                                             %
    459 %                                                                             %
    460 %                                                                             %
    461 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    462 %
    463 %  GetMagickEncoderThreadSupport() returns MagickTrue if the encoder supports
    464 %  threads.
    465 %
    466 %  The format of the GetMagickEncoderThreadSupport method is:
    467 %
    468 %      MagickStatusType GetMagickEncoderThreadSupport(
    469 %        const MagickInfo *magick_info)
    470 %
    471 %  A description of each parameter follows:
    472 %
    473 %    o magick_info:  The magick info.
    474 %
    475 */
    476 MagickExport MagickBooleanType GetMagickEncoderThreadSupport(
    477   const MagickInfo *magick_info)
    478 {
    479   assert(magick_info != (MagickInfo *) NULL);
    480   assert(magick_info->signature == MagickCoreSignature);
    481   return(((magick_info->flags & CoderDecoderThreadSupportFlag) == 0) ?
    482     MagickFalse : MagickTrue);
    483 }
    484 
    485 /*
    487 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    488 %                                                                             %
    489 %                                                                             %
    490 %                                                                             %
    491 +   G e t M a g i c k E n d i a n S u p p o r t                               %
    492 %                                                                             %
    493 %                                                                             %
    494 %                                                                             %
    495 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    496 %
    497 %  GetMagickEndianSupport() returns the MagickTrue if the coder respects
    498 %  endianness other than MSBEndian.
    499 %
    500 %  The format of the GetMagickEndianSupport method is:
    501 %
    502 %      MagickBooleanType GetMagickEndianSupport(const MagickInfo *magick_info)
    503 %
    504 %  A description of each parameter follows:
    505 %
    506 %    o magick_info:  The magick info.
    507 %
    508 */
    509 MagickExport MagickBooleanType GetMagickEndianSupport(
    510   const MagickInfo *magick_info)
    511 {
    512   assert(magick_info != (MagickInfo *) NULL);
    513   assert(magick_info->signature == MagickCoreSignature);
    514   return(((magick_info->flags & CoderEndianSupportFlag) == 0) ? MagickFalse :
    515     MagickTrue);
    516 }
    517 
    518 /*
    520 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    521 %                                                                             %
    522 %                                                                             %
    523 %                                                                             %
    524 +   G e t M a g i c k I n f o                                                 %
    525 %                                                                             %
    526 %                                                                             %
    527 %                                                                             %
    528 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    529 %
    530 %  GetMagickInfo() returns a pointer MagickInfo structure that matches
    531 %  the specified name.  If name is NULL, the head of the image format list
    532 %  is returned.
    533 %
    534 %  The format of the GetMagickInfo method is:
    535 %
    536 %      const MagickInfo *GetMagickInfo(const char *name,Exception *exception)
    537 %
    538 %  A description of each parameter follows:
    539 %
    540 %    o name: the image format we are looking for.
    541 %
    542 %    o exception: return any errors or warnings in this structure.
    543 %
    544 */
    545 MagickExport const MagickInfo *GetMagickInfo(const char *name,
    546   ExceptionInfo *exception)
    547 {
    548   register const MagickInfo
    549     *p;
    550 
    551   assert(exception != (ExceptionInfo *) NULL);
    552   if (IsMagickTreeInstantiated(exception) == MagickFalse)
    553     return((const MagickInfo *) NULL);
    554 #if defined(MAGICKCORE_MODULES_SUPPORT)
    555   if ((name != (const char *) NULL) && (LocaleCompare(name,"*") == 0))
    556     (void) OpenModules(exception);
    557 #endif
    558   /*
    559     Find name in list.
    560   */
    561   LockSemaphoreInfo(magick_semaphore);
    562   ResetSplayTreeIterator(magick_list);
    563   p=(const MagickInfo *) GetNextValueInSplayTree(magick_list);
    564   if ((name == (const char *) NULL) || (LocaleCompare(name,"*") == 0))
    565     {
    566       ResetSplayTreeIterator(magick_list);
    567       p=(const MagickInfo *) GetNextValueInSplayTree(magick_list);
    568       UnlockSemaphoreInfo(magick_semaphore);
    569       return(p);
    570     }
    571   while (p != (const MagickInfo *) NULL)
    572   {
    573     if (LocaleCompare(p->name,name) == 0)
    574       break;
    575     p=(const MagickInfo *) GetNextValueInSplayTree(magick_list);
    576   }
    577 #if defined(MAGICKCORE_MODULES_SUPPORT)
    578   if (p == (const MagickInfo *) NULL)
    579     {
    580       if (*name != '\0')
    581         (void) OpenModule(name,exception);
    582       ResetSplayTreeIterator(magick_list);
    583       p=(const MagickInfo *) GetNextValueInSplayTree(magick_list);
    584       while (p != (const MagickInfo *) NULL)
    585       {
    586         if (LocaleCompare(p->name,name) == 0)
    587           break;
    588         p=(const MagickInfo *) GetNextValueInSplayTree(magick_list);
    589       }
    590     }
    591 #endif
    592   UnlockSemaphoreInfo(magick_semaphore);
    593   return(p);
    594 }
    595 
    596 /*
    598 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    599 %                                                                             %
    600 %                                                                             %
    601 %                                                                             %
    602 +   G e t M a g i c k I n f o L i s t                                         %
    603 %                                                                             %
    604 %                                                                             %
    605 %                                                                             %
    606 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    607 %
    608 %  GetMagickInfoList() returns any image formats that match the specified
    609 %  pattern.
    610 %
    611 %  The format of the GetMagickInfoList function is:
    612 %
    613 %      const MagickInfo **GetMagickInfoList(const char *pattern,
    614 %        size_t *number_formats,ExceptionInfo *exception)
    615 %
    616 %  A description of each parameter follows:
    617 %
    618 %    o pattern: Specifies a pointer to a text string containing a pattern.
    619 %
    620 %    o number_formats:  This integer returns the number of formats in the list.
    621 %
    622 %    o exception: return any errors or warnings in this structure.
    623 %
    624 */
    625 
    626 #if defined(__cplusplus) || defined(c_plusplus)
    627 extern "C" {
    628 #endif
    629 
    630 static int MagickInfoCompare(const void *x,const void *y)
    631 {
    632   const MagickInfo
    633     **p,
    634     **q;
    635 
    636   p=(const MagickInfo **) x,
    637   q=(const MagickInfo **) y;
    638   return(LocaleCompare((*p)->name,(*q)->name));
    639 }
    640 
    641 #if defined(__cplusplus) || defined(c_plusplus)
    642 }
    643 #endif
    644 
    645 MagickExport const MagickInfo **GetMagickInfoList(const char *pattern,
    646   size_t *number_formats,ExceptionInfo *exception)
    647 {
    648   const MagickInfo
    649     **formats;
    650 
    651   register const MagickInfo
    652     *p;
    653 
    654   register ssize_t
    655     i;
    656 
    657   /*
    658     Allocate magick list.
    659   */
    660   assert(pattern != (char *) NULL);
    661   (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",pattern);
    662   assert(number_formats != (size_t *) NULL);
    663   *number_formats=0;
    664   p=GetMagickInfo("*",exception);
    665   if (p == (const MagickInfo *) NULL)
    666     return((const MagickInfo **) NULL);
    667   formats=(const MagickInfo **) AcquireQuantumMemory((size_t)
    668     GetNumberOfNodesInSplayTree(magick_list)+1UL,sizeof(*formats));
    669   if (formats == (const MagickInfo **) NULL)
    670     return((const MagickInfo **) NULL);
    671   /*
    672     Generate magick list.
    673   */
    674   LockSemaphoreInfo(magick_semaphore);
    675   ResetSplayTreeIterator(magick_list);
    676   p=(const MagickInfo *) GetNextValueInSplayTree(magick_list);
    677   for (i=0; p != (const MagickInfo *) NULL; )
    678   {
    679     if ((GetMagickStealth(p) == MagickFalse) &&
    680         (GlobExpression(p->name,pattern,MagickFalse) != MagickFalse))
    681       formats[i++]=p;
    682     p=(const MagickInfo *) GetNextValueInSplayTree(magick_list);
    683   }
    684   UnlockSemaphoreInfo(magick_semaphore);
    685   qsort((void *) formats,(size_t) i,sizeof(*formats),MagickInfoCompare);
    686   formats[i]=(MagickInfo *) NULL;
    687   *number_formats=(size_t) i;
    688   return(formats);
    689 }
    690 
    691 /*
    693 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    694 %                                                                             %
    695 %                                                                             %
    696 %                                                                             %
    697 +   G e t M a g i c k L i s t                                                 %
    698 %                                                                             %
    699 %                                                                             %
    700 %                                                                             %
    701 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    702 %
    703 %  GetMagickList() returns any image formats that match the specified pattern.
    704 %
    705 %  The format of the GetMagickList function is:
    706 %
    707 %      char **GetMagickList(const char *pattern,size_t *number_formats,
    708 %        ExceptionInfo *exception)
    709 %
    710 %  A description of each parameter follows:
    711 %
    712 %    o pattern: Specifies a pointer to a text string containing a pattern.
    713 %
    714 %    o number_formats:  This integer returns the number of formats in the list.
    715 %
    716 %    o exception: return any errors or warnings in this structure.
    717 %
    718 */
    719 
    720 #if defined(__cplusplus) || defined(c_plusplus)
    721 extern "C" {
    722 #endif
    723 
    724 static int MagickCompare(const void *x,const void *y)
    725 {
    726   register const char
    727     **p,
    728     **q;
    729 
    730   p=(const char **) x;
    731   q=(const char **) y;
    732   return(LocaleCompare(*p,*q));
    733 }
    734 
    735 #if defined(__cplusplus) || defined(c_plusplus)
    736 }
    737 #endif
    738 
    739 MagickExport char **GetMagickList(const char *pattern,
    740   size_t *number_formats,ExceptionInfo *exception)
    741 {
    742   char
    743     **formats;
    744 
    745   register const MagickInfo
    746     *p;
    747 
    748   register ssize_t
    749     i;
    750 
    751   /*
    752     Allocate magick list.
    753   */
    754   assert(pattern != (char *) NULL);
    755   (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",pattern);
    756   assert(number_formats != (size_t *) NULL);
    757   *number_formats=0;
    758   p=GetMagickInfo("*",exception);
    759   if (p == (const MagickInfo *) NULL)
    760     return((char **) NULL);
    761   formats=(char **) AcquireQuantumMemory((size_t)
    762     GetNumberOfNodesInSplayTree(magick_list)+1UL,sizeof(*formats));
    763   if (formats == (char **) NULL)
    764     return((char **) NULL);
    765   LockSemaphoreInfo(magick_semaphore);
    766   ResetSplayTreeIterator(magick_list);
    767   p=(const MagickInfo *) GetNextValueInSplayTree(magick_list);
    768   for (i=0; p != (const MagickInfo *) NULL; )
    769   {
    770     if ((GetMagickStealth(p) == MagickFalse) &&
    771         (GlobExpression(p->name,pattern,MagickFalse) != MagickFalse))
    772       formats[i++]=ConstantString(p->name);
    773     p=(const MagickInfo *) GetNextValueInSplayTree(magick_list);
    774   }
    775   UnlockSemaphoreInfo(magick_semaphore);
    776   qsort((void *) formats,(size_t) i,sizeof(*formats),MagickCompare);
    777   formats[i]=(char *) NULL;
    778   *number_formats=(size_t) i;
    779   return(formats);
    780 }
    781 
    782 /*
    784 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    785 %                                                                             %
    786 %                                                                             %
    787 %                                                                             %
    788 +   G e t M a g i c k M i m e T y p e                                         %
    789 %                                                                             %
    790 %                                                                             %
    791 %                                                                             %
    792 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    793 %
    794 %  GetMagickMimeType() returns the magick mime type.
    795 %
    796 %  The format of the GetMagickMimeType method is:
    797 %
    798 %      const char *GetMagickMimeType(const MagickInfo *magick_info)
    799 %
    800 %  A description of each parameter follows:
    801 %
    802 %    o magick_info:  The magick info.
    803 %
    804 */
    805 MagickExport const char *GetMagickMimeType(const MagickInfo *magick_info)
    806 {
    807   assert(magick_info != (MagickInfo *) NULL);
    808   assert(magick_info->signature == MagickCoreSignature);
    809   return(magick_info->mime_type);
    810 }
    811 
    812 /*
    814 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    815 %                                                                             %
    816 %                                                                             %
    817 %                                                                             %
    818 %   G e t M a g i c k P r e c i s i o n                                       %
    819 %                                                                             %
    820 %                                                                             %
    821 %                                                                             %
    822 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    823 %
    824 %  GetMagickPrecision() returns the maximum number of significant digits to be
    825 %  printed.
    826 %
    827 %  The format of the GetMagickPrecision method is:
    828 %
    829 %      int GetMagickPrecision(void)
    830 %
    831 */
    832 MagickExport int GetMagickPrecision(void)
    833 {
    834   (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
    835   return(SetMagickPrecision(0));
    836 }
    837 
    838 /*
    840 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    841 %                                                                             %
    842 %                                                                             %
    843 %                                                                             %
    844 +   G e t M a g i c k R a w S u p p o r t                                     %
    845 %                                                                             %
    846 %                                                                             %
    847 %                                                                             %
    848 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    849 %
    850 %  GetMagickRawSupport() returns the MagickTrue if the coder is a raw format.
    851 %
    852 %  The format of the GetMagickRawSupport method is:
    853 %
    854 %      MagickBooleanType GetMagickRawSupport(const MagickInfo *magick_info)
    855 %
    856 %  A description of each parameter follows:
    857 %
    858 %    o magick_info:  The magick info.
    859 %
    860 */
    861 MagickExport MagickBooleanType GetMagickRawSupport(
    862   const MagickInfo *magick_info)
    863 {
    864   assert(magick_info != (MagickInfo *) NULL);
    865   assert(magick_info->signature == MagickCoreSignature);
    866   return(((magick_info->flags & CoderRawSupportFlag) == 0) ? MagickFalse :
    867     MagickTrue);
    868 }
    869 
    870 /*
    872 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    873 %                                                                             %
    874 %                                                                             %
    875 %                                                                             %
    876 +   G e t M a g i c k S e e k a b l e S t r e a m                             %
    877 %                                                                             %
    878 %                                                                             %
    879 %                                                                             %
    880 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    881 %
    882 %  GetMagickSeekableStream() returns MagickTrue if the magick supports a
    883 %  seekable stream.
    884 %
    885 %  The format of the GetMagickSeekableStream method is:
    886 %
    887 %      MagickBooleanType GetMagickSeekableStream(const MagickInfo *magick_info)
    888 %
    889 %  A description of each parameter follows:
    890 %
    891 %    o magick_info:  The magick info.
    892 %
    893 */
    894 MagickExport MagickBooleanType GetMagickSeekableStream(
    895   const MagickInfo *magick_info)
    896 {
    897   assert(magick_info != (MagickInfo *) NULL);
    898   assert(magick_info->signature == MagickCoreSignature);
    899   return(((magick_info->flags & CoderSeekableStreamFlag) == 0) ? MagickFalse :
    900     MagickTrue);
    901 }
    902 
    903 /*
    904 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    905 %                                                                             %
    906 %                                                                             %
    907 %                                                                             %
    908 +   G e t M a g i c k S t e a l t h                                           %
    909 %                                                                             %
    910 %                                                                             %
    911 %                                                                             %
    912 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    913 %
    914 %  GetMagickStealth() returns MagickTrue if the magick is a stealth coder.
    915 %
    916 %  The format of the GetMagickStealth method is:
    917 %
    918 %      MagickBooleanType GetMagickStealth(const MagickInfo *magick_info)
    919 %
    920 %  A description of each parameter follows:
    921 %
    922 %    o magick_info:  The magick info.
    923 %
    924 */
    925 MagickExport MagickBooleanType GetMagickStealth(const MagickInfo *magick_info)
    926 {
    927   assert(magick_info != (MagickInfo *) NULL);
    928   assert(magick_info->signature == MagickCoreSignature);
    929   return(((magick_info->flags & CoderStealthFlag) == 0) ? MagickFalse :
    930     MagickTrue);
    931 }
    932 
    933 /*
    934 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    935 %                                                                             %
    936 %                                                                             %
    937 %                                                                             %
    938 +   G e t M a g i c k U s e E x t e n s i o n                                 %
    939 %                                                                             %
    940 %                                                                             %
    941 %                                                                             %
    942 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    943 %
    944 %  GetMagickUseExtension() returns MagickTrue if the magick can use the
    945 %  extension of the format if the format return by IsImageFormatHandler uses
    946 %  the same coder.
    947 %
    948 %  The format of the GetMagickUseExtension method is:
    949 %
    950 %      MagickBooleanType GetMagickUseExtension(const MagickInfo *magick_info)
    951 %
    952 %  A description of each parameter follows:
    953 %
    954 %    o magick_info:  The magick info.
    955 %
    956 */
    957 MagickExport MagickBooleanType GetMagickUseExtension(
    958   const MagickInfo *magick_info)
    959 {
    960   assert(magick_info != (MagickInfo *) NULL);
    961   assert(magick_info->signature == MagickCoreSignature);
    962   return(((magick_info->flags & CoderUseExtensionFlag) == 0) ? MagickFalse :
    963     MagickTrue);
    964 }
    965 
    966 /*
    968 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    969 %                                                                             %
    970 %                                                                             %
    971 %                                                                             %
    972 +   I s M a g i c k T r e e I n s t a n t i a t e d                           %
    973 %                                                                             %
    974 %                                                                             %
    975 %                                                                             %
    976 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    977 %
    978 %  IsMagickTreeInstantiated() determines if the magick tree is instantiated.
    979 %  If not, it instantiates the tree and returns it.
    980 %
    981 %  The format of the IsMagickTreeInstantiated() method is:
    982 %
    983 %      IsMagickTreeInstantiated(Exceptioninfo *exception)
    984 %
    985 %  A description of each parameter follows.
    986 %
    987 %    o exception: return any errors or warnings in this structure.
    988 %
    989 */
    990 
    991 static void *DestroyMagickNode(void *magick_info)
    992 {
    993   register MagickInfo
    994     *p;
    995 
    996   p=(MagickInfo *) magick_info;
    997   if (p->module != (char *) NULL)
    998     p->module=DestroyString(p->module);
    999   if (p->note != (char *) NULL)
   1000     p->note=DestroyString(p->note);
   1001   if (p->mime_type != (char *) NULL)
   1002     p->mime_type=DestroyString(p->mime_type);
   1003   if (p->version != (char *) NULL)
   1004     p->version=DestroyString(p->version);
   1005   if (p->description != (char *) NULL)
   1006     p->description=DestroyString(p->description);
   1007   if (p->name != (char *) NULL)
   1008     p->name=DestroyString(p->name);
   1009   if (p->semaphore != (SemaphoreInfo *) NULL)
   1010     RelinquishSemaphoreInfo(&p->semaphore);
   1011   return(RelinquishMagickMemory(p));
   1012 }
   1013 
   1014 static MagickBooleanType IsMagickTreeInstantiated(ExceptionInfo *exception)
   1015 {
   1016   (void) exception;
   1017   if (magick_list == (SplayTreeInfo *) NULL)
   1018     {
   1019       if (magick_semaphore == (SemaphoreInfo *) NULL)
   1020         ActivateSemaphoreInfo(&magick_semaphore);
   1021       LockSemaphoreInfo(magick_semaphore);
   1022       if (magick_list == (SplayTreeInfo *) NULL)
   1023         {
   1024           magick_list=NewSplayTree(CompareSplayTreeString,(void *(*)(void *))
   1025             NULL,DestroyMagickNode);
   1026           if (magick_list == (SplayTreeInfo *) NULL)
   1027             ThrowFatalException(ResourceLimitFatalError,
   1028               "MemoryAllocationFailed");
   1029 #if defined(MAGICKCORE_MODULES_SUPPORT)
   1030           (void) GetModuleInfo((char *) NULL,exception);
   1031 #endif
   1032 #if !defined(MAGICKCORE_BUILD_MODULES)
   1033           RegisterStaticModules();
   1034 #endif
   1035         }
   1036       UnlockSemaphoreInfo(magick_semaphore);
   1037     }
   1038   return(magick_list != (SplayTreeInfo *) NULL ? MagickTrue : MagickFalse);
   1039 }
   1040 
   1041 /*
   1043 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   1044 %                                                                             %
   1045 %                                                                             %
   1046 %                                                                             %
   1047 +   I s M a g i c k C o n f l i c t                                           %
   1048 %                                                                             %
   1049 %                                                                             %
   1050 %                                                                             %
   1051 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   1052 %
   1053 %  IsMagickConflict() returns MagickTrue if the image format conflicts with a
   1054 %  logical drive (.e.g. X:).
   1055 %
   1056 %  The format of the IsMagickConflict method is:
   1057 %
   1058 %      MagickBooleanType IsMagickConflict(const char *magick)
   1059 %
   1060 %  A description of each parameter follows:
   1061 %
   1062 %    o magick: Specifies the image format.
   1063 %
   1064 */
   1065 MagickPrivate MagickBooleanType IsMagickConflict(const char *magick)
   1066 {
   1067   assert(magick != (char *) NULL);
   1068 #if defined(macintosh)
   1069   return(MACIsMagickConflict(magick));
   1070 #elif defined(vms)
   1071   return(VMSIsMagickConflict(magick));
   1072 #elif defined(MAGICKCORE_WINDOWS_SUPPORT)
   1073   return(NTIsMagickConflict(magick));
   1074 #else
   1075   return(MagickFalse);
   1076 #endif
   1077 }
   1078 
   1079 /*
   1081 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   1082 %                                                                             %
   1083 %                                                                             %
   1084 %                                                                             %
   1085 +  L i s t M a g i c k I n f o                                                %
   1086 %                                                                             %
   1087 %                                                                             %
   1088 %                                                                             %
   1089 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   1090 %
   1091 %  ListMagickInfo() lists the image formats to a file.
   1092 %
   1093 %  The format of the ListMagickInfo method is:
   1094 %
   1095 %      MagickBooleanType ListMagickInfo(FILE *file,ExceptionInfo *exception)
   1096 %
   1097 %  A description of each parameter follows.
   1098 %
   1099 %    o file: A file handle.
   1100 %
   1101 %    o exception: return any errors or warnings in this structure.
   1102 %
   1103 */
   1104 MagickExport MagickBooleanType ListMagickInfo(FILE *file,
   1105   ExceptionInfo *exception)
   1106 {
   1107   const MagickInfo
   1108     **magick_info;
   1109 
   1110   register ssize_t
   1111     i;
   1112 
   1113   size_t
   1114     number_formats;
   1115 
   1116   ssize_t
   1117     j;
   1118 
   1119   if (file == (FILE *) NULL)
   1120     file=stdout;
   1121   magick_info=GetMagickInfoList("*",&number_formats,exception);
   1122   if (magick_info == (const MagickInfo **) NULL)
   1123     return(MagickFalse);
   1124   ClearMagickException(exception);
   1125 #if !defined(MAGICKCORE_MODULES_SUPPORT)
   1126   (void) FormatLocaleFile(file,"   Format  Mode  Description\n");
   1127 #else
   1128   (void) FormatLocaleFile(file,"   Format  Module    Mode  Description\n");
   1129 #endif
   1130   (void) FormatLocaleFile(file,
   1131     "--------------------------------------------------------"
   1132     "-----------------------\n");
   1133   for (i=0; i < (ssize_t) number_formats; i++)
   1134   {
   1135     if (GetMagickStealth(magick_info[i]) != MagickFalse)
   1136       continue;
   1137     (void) FormatLocaleFile(file,"%9s%c ",
   1138       magick_info[i]->name != (char *) NULL ? magick_info[i]->name : "",
   1139       GetMagickBlobSupport(magick_info[i]) != MagickFalse ? '*' : ' ');
   1140 #if defined(MAGICKCORE_MODULES_SUPPORT)
   1141     {
   1142       char
   1143         module[MagickPathExtent];
   1144 
   1145       *module='\0';
   1146       if (magick_info[i]->module != (char *) NULL)
   1147         (void) CopyMagickString(module,magick_info[i]->module,MagickPathExtent);
   1148       (void) ConcatenateMagickString(module,"          ",MagickPathExtent);
   1149       module[9]='\0';
   1150       (void) FormatLocaleFile(file,"%9s ",module);
   1151     }
   1152 #endif
   1153     (void) FormatLocaleFile(file,"%c%c%c ",magick_info[i]->decoder ? 'r' : '-',
   1154       magick_info[i]->encoder ? 'w' : '-',magick_info[i]->encoder != NULL &&
   1155       GetMagickAdjoin(magick_info[i]) != MagickFalse ? '+' : '-');
   1156     if (magick_info[i]->description != (char *) NULL)
   1157       (void) FormatLocaleFile(file,"  %s",magick_info[i]->description);
   1158     if (magick_info[i]->version != (char *) NULL)
   1159       (void) FormatLocaleFile(file," (%s)",magick_info[i]->version);
   1160     (void) FormatLocaleFile(file,"\n");
   1161     if (magick_info[i]->note != (char *) NULL)
   1162       {
   1163         char
   1164           **text;
   1165 
   1166         text=StringToList(magick_info[i]->note);
   1167         if (text != (char **) NULL)
   1168           {
   1169             for (j=0; text[j] != (char *) NULL; j++)
   1170             {
   1171               (void) FormatLocaleFile(file,"           %s\n",text[j]);
   1172               text[j]=DestroyString(text[j]);
   1173             }
   1174             text=(char **) RelinquishMagickMemory(text);
   1175           }
   1176       }
   1177   }
   1178   (void) FormatLocaleFile(file,"\n* native blob support\n");
   1179   (void) FormatLocaleFile(file,"r read support\n");
   1180   (void) FormatLocaleFile(file,"w write support\n");
   1181   (void) FormatLocaleFile(file,"+ support for multiple images\n");
   1182   (void) fflush(file);
   1183   magick_info=(const MagickInfo **) RelinquishMagickMemory((void *)
   1184     magick_info);
   1185   return(MagickTrue);
   1186 }
   1187 
   1188 /*
   1190 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   1191 %                                                                             %
   1192 %                                                                             %
   1193 %                                                                             %
   1194 %  I s M a g i c k C o r e I n s t a n t i a t e d                            %
   1195 %                                                                             %
   1196 %                                                                             %
   1197 %                                                                             %
   1198 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   1199 %
   1200 %  IsMagickCoreInstantiated() returns MagickTrue if the ImageMagick environment
   1201 %  is currently instantiated:  MagickCoreGenesis() has been called but
   1202 %  MagickDestroy() has not.
   1203 %
   1204 %  The format of the IsMagickCoreInstantiated method is:
   1205 %
   1206 %      MagickBooleanType IsMagickCoreInstantiated(void)
   1207 %
   1208 */
   1209 MagickExport MagickBooleanType IsMagickCoreInstantiated(void)
   1210 {
   1211   return(instantiate_magickcore);
   1212 }
   1213 
   1214 /*
   1216 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   1217 %                                                                             %
   1218 %                                                                             %
   1219 %                                                                             %
   1220 +   M a g i c k C o m p o n e n t G e n e s i s                               %
   1221 %                                                                             %
   1222 %                                                                             %
   1223 %                                                                             %
   1224 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   1225 %
   1226 %  MagickComponentGenesis() instantiates the magick component.
   1227 %
   1228 %  The format of the MagickComponentGenesis method is:
   1229 %
   1230 %      MagickBooleanType MagickComponentGenesis(void)
   1231 %
   1232 */
   1233 MagickPrivate MagickBooleanType MagickComponentGenesis(void)
   1234 {
   1235   if (magick_semaphore == (SemaphoreInfo *) NULL)
   1236     magick_semaphore=AcquireSemaphoreInfo();
   1237   return(MagickTrue);
   1238 }
   1239 
   1240 /*
   1242 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   1243 %                                                                             %
   1244 %                                                                             %
   1245 %                                                                             %
   1246 +   M a g i c k C o m p o n e n t T e r m i n u s                             %
   1247 %                                                                             %
   1248 %                                                                             %
   1249 %                                                                             %
   1250 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   1251 %
   1252 %  MagickComponentTerminus() destroys the magick component.
   1253 %
   1254 %  The format of the MagickComponentTerminus method is:
   1255 %
   1256 %      void MagickComponentTerminus(void)
   1257 %
   1258 */
   1259 MagickPrivate void MagickComponentTerminus(void)
   1260 {
   1261   if (magick_semaphore == (SemaphoreInfo *) NULL)
   1262     ActivateSemaphoreInfo(&magick_semaphore);
   1263   LockSemaphoreInfo(magick_semaphore);
   1264   if (magick_list != (SplayTreeInfo *) NULL)
   1265     magick_list=DestroySplayTree(magick_list);
   1266   UnlockSemaphoreInfo(magick_semaphore);
   1267   RelinquishSemaphoreInfo(&magick_semaphore);
   1268 }
   1269 
   1270 /*
   1272 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   1273 %                                                                             %
   1274 %                                                                             %
   1275 %                                                                             %
   1276 %   M a g i c k C o r e G e n e s i s                                         %
   1277 %                                                                             %
   1278 %                                                                             %
   1279 %                                                                             %
   1280 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   1281 %
   1282 %  MagickCoreGenesis() initializes the MagickCore environment.
   1283 %
   1284 %  The format of the MagickCoreGenesis function is:
   1285 %
   1286 %      MagickCoreGenesis(const char *path,
   1287 %        const MagickBooleanType establish_signal_handlers)
   1288 %
   1289 %  A description of each parameter follows:
   1290 %
   1291 %    o path: the execution path of the current ImageMagick client.
   1292 %
   1293 %    o establish_signal_handlers: set to MagickTrue to use MagickCore's own
   1294 %      signal handlers for common signals.
   1295 %
   1296 */
   1297 
   1298 static SignalHandler *SetMagickSignalHandler(int signal_number,
   1299   SignalHandler *handler)
   1300 {
   1301 #if defined(MAGICKCORE_HAVE_SIGACTION) && defined(MAGICKCORE_HAVE_SIGEMPTYSET)
   1302   int
   1303     status;
   1304 
   1305   sigset_t
   1306     mask;
   1307 
   1308   struct sigaction
   1309     action,
   1310     previous_action;
   1311 
   1312   sigemptyset(&mask);
   1313   sigaddset(&mask,signal_number);
   1314   sigprocmask(SIG_BLOCK,&mask,NULL);
   1315   action.sa_mask=mask;
   1316   action.sa_handler=handler;
   1317   action.sa_flags=0;
   1318 #if defined(SA_INTERRUPT)
   1319   action.sa_flags|=SA_INTERRUPT;
   1320 #endif
   1321   status=sigaction(signal_number,&action,&previous_action);
   1322   if (status < 0)
   1323     return(SIG_ERR);
   1324   sigprocmask(SIG_UNBLOCK,&mask,NULL);
   1325   return(previous_action.sa_handler);
   1326 #else
   1327   return(signal(signal_number,handler));
   1328 #endif
   1329 }
   1330 
   1331 static void MagickSignalHandler(int signal_number)
   1332 {
   1333   if (magickcore_signal_in_progress != MagickFalse)
   1334     (void) SetMagickSignalHandler(signal_number,signal_handlers[signal_number]);
   1335   magickcore_signal_in_progress=MagickTrue;
   1336   AsynchronousResourceComponentTerminus();
   1337 #if defined(SIGQUIT)
   1338   if (signal_number == SIGQUIT)
   1339     abort();
   1340 #endif
   1341 #if defined(SIGABRT)
   1342   if (signal_number == SIGABRT)
   1343     abort();
   1344 #endif
   1345 #if defined(SIGFPE)
   1346   if (signal_number == SIGFPE)
   1347     abort();
   1348 #endif
   1349 #if defined(SIGXCPU)
   1350   if (signal_number == SIGXCPU)
   1351     abort();
   1352 #endif
   1353 #if defined(SIGXFSZ)
   1354   if (signal_number == SIGXFSZ)
   1355     abort();
   1356 #endif
   1357 #if defined(SIGSEGV)
   1358   if (signal_number == SIGSEGV)
   1359     abort();
   1360 #endif
   1361 #if !defined(MAGICKCORE_HAVE__EXIT)
   1362   exit(signal_number);
   1363 #else
   1364 #if defined(SIGHUP)
   1365   if (signal_number == SIGHUP)
   1366     _exit(signal_number);
   1367 #endif
   1368 #if defined(SIGINT)
   1369   if (signal_number == SIGINT)
   1370     _exit(signal_number);
   1371 #endif
   1372 #if defined(SIGTERM)
   1373   if (signal_number == SIGTERM)
   1374     _exit(signal_number);
   1375 #endif
   1376 #if defined(MAGICKCORE_HAVE_RAISE)
   1377   if (signal_handlers[signal_number] != MagickSignalHandler)
   1378     raise(signal_number);
   1379 #endif
   1380   _exit(signal_number);  /* do not invoke registered atexit() methods */
   1381 #endif
   1382 }
   1383 
   1384 static SignalHandler *RegisterMagickSignalHandler(int signal_number)
   1385 {
   1386   SignalHandler
   1387     *handler;
   1388 
   1389   handler=SetMagickSignalHandler(signal_number,MagickSignalHandler);
   1390   if (handler == SIG_ERR)
   1391     return(handler);
   1392   if (handler != SIG_DFL)
   1393     handler=SetMagickSignalHandler(signal_number,handler);
   1394   else
   1395     (void) LogMagickEvent(ConfigureEvent,GetMagickModule(),
   1396       "Register handler for signal: %d",signal_number);
   1397   return(handler);
   1398 }
   1399 
   1400 MagickExport void MagickCoreGenesis(const char *path,
   1401   const MagickBooleanType establish_signal_handlers)
   1402 {
   1403   char
   1404     *events,
   1405     execution_path[MagickPathExtent],
   1406     filename[MagickPathExtent];
   1407 
   1408   /*
   1409     Initialize the Magick environment.
   1410   */
   1411   InitializeMagickMutex();
   1412   LockMagickMutex();
   1413   if (instantiate_magickcore != MagickFalse)
   1414     {
   1415       UnlockMagickMutex();
   1416       return;
   1417     }
   1418   (void) SemaphoreComponentGenesis();
   1419   (void) LogComponentGenesis();
   1420   (void) LocaleComponentGenesis();
   1421   (void) RandomComponentGenesis();
   1422   events=GetEnvironmentValue("MAGICK_DEBUG");
   1423   if (events != (char *) NULL)
   1424     {
   1425       (void) SetLogEventMask(events);
   1426       events=DestroyString(events);
   1427     }
   1428 #if defined(MAGICKCORE_WINDOWS_SUPPORT)
   1429   NTWindowsGenesis();
   1430 #endif
   1431   /*
   1432     Set client name and execution path.
   1433   */
   1434 #if defined(MAGICKCORE_WINDOWS_SUPPORT)
   1435   if ((path != (const char *) NULL) && (IsPathAccessible(path) != MagickFalse))
   1436 #else
   1437   if ((path != (const char *) NULL) && (*path == *DirectorySeparator) &&
   1438       (IsPathAccessible(path) != MagickFalse))
   1439 #endif
   1440     (void) CopyMagickString(execution_path,path,MagickPathExtent);
   1441   else
   1442     (void) GetExecutionPath(execution_path,MagickPathExtent);
   1443   GetPathComponent(execution_path,TailPath,filename);
   1444   (void) SetClientName(filename);
   1445   GetPathComponent(execution_path,HeadPath,execution_path);
   1446   (void) SetClientPath(execution_path);
   1447   if (establish_signal_handlers != MagickFalse)
   1448     {
   1449       /*
   1450         Set signal handlers.
   1451       */
   1452 #if defined(SIGABRT)
   1453       if (signal_handlers[SIGABRT] == (SignalHandler *) NULL)
   1454         signal_handlers[SIGABRT]=RegisterMagickSignalHandler(SIGABRT);
   1455 #endif
   1456 #if defined(SIGSEGV)
   1457       if (signal_handlers[SIGSEGV] == (SignalHandler *) NULL)
   1458         signal_handlers[SIGSEGV]=RegisterMagickSignalHandler(SIGSEGV);
   1459 #endif
   1460 #if defined(SIGFPE)
   1461       if (signal_handlers[SIGFPE] == (SignalHandler *) NULL)
   1462         signal_handlers[SIGFPE]=RegisterMagickSignalHandler(SIGFPE);
   1463 #endif
   1464 #if defined(SIGHUP)
   1465       if (signal_handlers[SIGHUP] == (SignalHandler *) NULL)
   1466         signal_handlers[SIGHUP]=RegisterMagickSignalHandler(SIGHUP);
   1467 #endif
   1468 #if defined(SIGINT)
   1469       if (signal_handlers[SIGINT] == (SignalHandler *) NULL)
   1470         signal_handlers[SIGINT]=RegisterMagickSignalHandler(SIGINT);
   1471 #endif
   1472 #if defined(SIGQUIT)
   1473       if (signal_handlers[SIGQUIT] == (SignalHandler *) NULL)
   1474         signal_handlers[SIGQUIT]=RegisterMagickSignalHandler(SIGQUIT);
   1475 #endif
   1476 #if defined(SIGTERM)
   1477       if (signal_handlers[SIGTERM] == (SignalHandler *) NULL)
   1478         signal_handlers[SIGTERM]=RegisterMagickSignalHandler(SIGTERM);
   1479 #endif
   1480 #if defined(SIGXCPU)
   1481       if (signal_handlers[SIGXCPU] == (SignalHandler *) NULL)
   1482         signal_handlers[SIGXCPU]=RegisterMagickSignalHandler(SIGXCPU);
   1483 #endif
   1484 #if defined(SIGXFSZ)
   1485       if (signal_handlers[SIGXFSZ] == (SignalHandler *) NULL)
   1486         signal_handlers[SIGXFSZ]=RegisterMagickSignalHandler(SIGXFSZ);
   1487 #endif
   1488     }
   1489   /*
   1490     Instantiate magick resources.
   1491   */
   1492   (void) ConfigureComponentGenesis();
   1493   (void) PolicyComponentGenesis();
   1494   (void) CacheComponentGenesis();
   1495   (void) ResourceComponentGenesis();
   1496   (void) CoderComponentGenesis();
   1497   (void) MagickComponentGenesis();
   1498 #if defined(MAGICKCORE_MODULES_SUPPORT)
   1499   (void) ModuleComponentGenesis();
   1500 #endif
   1501   (void) DelegateComponentGenesis();
   1502   (void) MagicComponentGenesis();
   1503   (void) ColorComponentGenesis();
   1504   (void) TypeComponentGenesis();
   1505   (void) MimeComponentGenesis();
   1506   (void) AnnotateComponentGenesis();
   1507 #if defined(MAGICKCORE_X11_DELEGATE)
   1508   (void) XComponentGenesis();
   1509 #endif
   1510   (void) RegistryComponentGenesis();
   1511   instantiate_magickcore=MagickTrue;
   1512   UnlockMagickMutex();
   1513 }
   1514 
   1515 /*
   1517 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   1518 %                                                                             %
   1519 %                                                                             %
   1520 %                                                                             %
   1521 %   M a g i c k C o r e T e r m i n u s                                       %
   1522 %                                                                             %
   1523 %                                                                             %
   1524 %                                                                             %
   1525 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   1526 %
   1527 %  MagickCoreTerminus() destroys the MagickCore environment.
   1528 %
   1529 %  The format of the MagickCoreTerminus function is:
   1530 %
   1531 %      MagickCoreTerminus(void)
   1532 %
   1533 */
   1534 MagickExport void MagickCoreTerminus(void)
   1535 {
   1536   InitializeMagickMutex();
   1537   LockMagickMutex();
   1538   if (instantiate_magickcore == MagickFalse)
   1539     {
   1540       UnlockMagickMutex();
   1541       return;
   1542     }
   1543   RegistryComponentTerminus();
   1544 #if defined(MAGICKCORE_X11_DELEGATE)
   1545   XComponentTerminus();
   1546 #endif
   1547   AnnotateComponentTerminus();
   1548   MimeComponentTerminus();
   1549   TypeComponentTerminus();
   1550 #if defined(MAGICKCORE_OPENCL_SUPPORT)
   1551   OpenCLTerminus();
   1552 #endif
   1553   ColorComponentTerminus();
   1554 #if defined(MAGICKCORE_WINDOWS_SUPPORT)
   1555   NTWindowsTerminus();
   1556 #endif
   1557   MagicComponentTerminus();
   1558   DelegateComponentTerminus();
   1559   MagickComponentTerminus();
   1560 #if !defined(MAGICKCORE_BUILD_MODULES)
   1561   UnregisterStaticModules();
   1562 #endif
   1563 #if defined(MAGICKCORE_MODULES_SUPPORT)
   1564   ModuleComponentTerminus();
   1565 #endif
   1566   CoderComponentTerminus();
   1567   ResourceComponentTerminus();
   1568   CacheComponentTerminus();
   1569   PolicyComponentTerminus();
   1570   ConfigureComponentTerminus();
   1571   RandomComponentTerminus();
   1572   LocaleComponentTerminus();
   1573   LogComponentTerminus();
   1574   instantiate_magickcore=MagickFalse;
   1575   UnlockMagickMutex();
   1576   SemaphoreComponentTerminus();
   1577 }
   1578 
   1579 /*
   1581 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   1582 %                                                                             %
   1583 %                                                                             %
   1584 %                                                                             %
   1585 +   R e g i s t e r M a g i c k I n f o                                       %
   1586 %                                                                             %
   1587 %                                                                             %
   1588 %                                                                             %
   1589 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   1590 %
   1591 %  RegisterMagickInfo() adds attributes for a particular image format to the
   1592 %  list of supported formats.  The attributes include the image format name,
   1593 %  a method to read and/or write the format, whether the format supports the
   1594 %  saving of more than one frame to the same file or blob, whether the format
   1595 %  supports native in-memory I/O, and a brief description of the format.
   1596 %
   1597 %  The format of the RegisterMagickInfo method is:
   1598 %
   1599 %      MagickInfo *RegisterMagickInfo(MagickInfo *magick_info)
   1600 %
   1601 %  A description of each parameter follows:
   1602 %
   1603 %    o magick_info: the magick info.
   1604 %
   1605 */
   1606 MagickExport MagickBooleanType RegisterMagickInfo(MagickInfo *magick_info)
   1607 {
   1608   MagickBooleanType
   1609     status;
   1610 
   1611   /*
   1612     Register a new image format.
   1613   */
   1614   assert(magick_info != (MagickInfo *) NULL);
   1615   assert(magick_info->signature == MagickCoreSignature);
   1616   (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",magick_info->name);
   1617   if (magick_list == (SplayTreeInfo *) NULL)
   1618     return(MagickFalse);
   1619   if ((GetMagickDecoderThreadSupport(magick_info) == MagickFalse) ||
   1620       (GetMagickEncoderThreadSupport(magick_info) == MagickFalse))
   1621     magick_info->semaphore=AcquireSemaphoreInfo();
   1622   status=AddValueToSplayTree(magick_list,magick_info->name,magick_info);
   1623   return(status);
   1624 }
   1625 
   1626 /*
   1628 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   1629 %                                                                             %
   1630 %                                                                             %
   1631 %                                                                             %
   1632 %   S e t M a g i c k P r e c i s i o n                                       %
   1633 %                                                                             %
   1634 %                                                                             %
   1635 %                                                                             %
   1636 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   1637 %
   1638 %  SetMagickPrecision() sets the maximum number of significant digits to be
   1639 %  printed.
   1640 %
   1641 %  An input argument of 0 returns the current precision setting.
   1642 %
   1643 %  A negative value forces the precision to reset to a default value according
   1644 %  to the environment variable "MAGICK_PRECISION", the current 'policy'
   1645 %  configuration setting, or the default value of '6', in that order.
   1646 %
   1647 %  The format of the SetMagickPrecision method is:
   1648 %
   1649 %      int SetMagickPrecision(const int precision)
   1650 %
   1651 %  A description of each parameter follows:
   1652 %
   1653 %    o precision: set the maximum number of significant digits to be printed.
   1654 %
   1655 */
   1656 MagickExport int SetMagickPrecision(const int precision)
   1657 {
   1658 #define MagickPrecision  6
   1659 
   1660   static int
   1661     magick_precision = 0;
   1662 
   1663   (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
   1664   if (precision > 0)
   1665     magick_precision=precision;
   1666   if ((precision < 0) || (magick_precision == 0))
   1667     {
   1668       char
   1669         *limit;
   1670 
   1671       /*
   1672         Precision reset, or it has not been set yet
   1673       */
   1674       magick_precision=MagickPrecision;
   1675       limit=GetEnvironmentValue("MAGICK_PRECISION");
   1676       if (limit == (char *) NULL)
   1677         limit=GetPolicyValue("precision");
   1678       if (limit != (char *) NULL)
   1679         {
   1680           magick_precision=StringToInteger(limit);
   1681           limit=DestroyString(limit);
   1682         }
   1683     }
   1684   return(magick_precision);
   1685 }
   1686 
   1687 /*
   1689 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   1690 %                                                                             %
   1691 %                                                                             %
   1692 %                                                                             %
   1693 +   U n r e g i s t e r M a g i c k I n f o                                   %
   1694 %                                                                             %
   1695 %                                                                             %
   1696 %                                                                             %
   1697 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   1698 %
   1699 %  UnregisterMagickInfo() removes a name from the magick info list.  It returns
   1700 %  MagickFalse if the name does not exist in the list otherwise MagickTrue.
   1701 %
   1702 %  The format of the UnregisterMagickInfo method is:
   1703 %
   1704 %      MagickBooleanType UnregisterMagickInfo(const char *name)
   1705 %
   1706 %  A description of each parameter follows:
   1707 %
   1708 %    o name: a character string that represents the image format we are
   1709 %      looking for.
   1710 %
   1711 */
   1712 MagickExport MagickBooleanType UnregisterMagickInfo(const char *name)
   1713 {
   1714   register const MagickInfo
   1715     *p;
   1716 
   1717   MagickBooleanType
   1718     status;
   1719 
   1720   assert(name != (const char *) NULL);
   1721   if (magick_list == (SplayTreeInfo *) NULL)
   1722     return(MagickFalse);
   1723   if (GetNumberOfNodesInSplayTree(magick_list) == 0)
   1724     return(MagickFalse);
   1725   LockSemaphoreInfo(magick_semaphore);
   1726   ResetSplayTreeIterator(magick_list);
   1727   p=(const MagickInfo *) GetNextValueInSplayTree(magick_list);
   1728   while (p != (const MagickInfo *) NULL)
   1729   {
   1730     if (LocaleCompare(p->name,name) == 0)
   1731       break;
   1732     p=(const MagickInfo *) GetNextValueInSplayTree(magick_list);
   1733   }
   1734   status=DeleteNodeByValueFromSplayTree(magick_list,p);
   1735   UnlockSemaphoreInfo(magick_semaphore);
   1736   return(status);
   1737 }
   1738