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