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