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