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