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