]> 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 L i s t                                         %
128 %                                                                             %
129 %                                                                             %
130 %                                                                             %
131 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
132 %
133 %  DestroyMagickList() deallocates memory associated with the MagickInfo list.
134 %
135 %  The format of the DestroyMagickList method is:
136 %
137 %      void DestroyMagickList(void)
138 %
139 */
140 MagickExport void DestroyMagickList(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 s M a g i c k C o n f l i c t                                           %
865 %                                                                             %
866 %                                                                             %
867 %                                                                             %
868 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
869 %
870 %  IsMagickConflict() returns MagickTrue if the image format is not a valid
871 %  image format or conflicts with a logical drive (.e.g. X:).
872 %
873 %  The format of the IsMagickConflict method is:
874 %
875 %      MagickBooleanType IsMagickConflict(const char *magick)
876 %
877 %  A description of each parameter follows:
878 %
879 %    o magick: Specifies the image format.
880 %
881 */
882 MagickExport MagickBooleanType IsMagickConflict(const char *magick)
883 {
884   const DelegateInfo
885     *delegate_info;
886
887   const MagickInfo
888     *magick_info;
889
890   ExceptionInfo
891     *exception;
892
893   assert(magick != (char *) NULL);
894   exception=AcquireExceptionInfo();
895   magick_info=GetMagickInfo(magick,exception);
896   delegate_info=GetDelegateInfo(magick,(char *) NULL,exception);
897   if (delegate_info == (const DelegateInfo *) NULL)
898     delegate_info=GetDelegateInfo((char *) NULL,magick,exception);
899   exception=DestroyExceptionInfo(exception);
900   if ((magick_info == (const MagickInfo *) NULL) &&
901       (delegate_info == (const DelegateInfo *) NULL))
902     return(MagickTrue);
903 #if defined(macintosh)
904   return(MACIsMagickConflict(magick));
905 #elif defined(vms)
906   return(VMSIsMagickConflict(magick));
907 #elif defined(__WINDOWS__)
908   return(NTIsMagickConflict(magick));
909 #else
910   return(MagickFalse);
911 #endif
912 }
913 \f
914 /*
915 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
916 %                                                                             %
917 %                                                                             %
918 %                                                                             %
919 +  L i s t M a g i c k I n f o                                                %
920 %                                                                             %
921 %                                                                             %
922 %                                                                             %
923 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
924 %
925 %  ListMagickInfo() lists the image formats to a file.
926 %
927 %  The format of the ListMagickInfo method is:
928 %
929 %      MagickBooleanType ListMagickInfo(FILE *file,ExceptionInfo *exception)
930 %
931 %  A description of each parameter follows.
932 %
933 %    o file: A file handle.
934 %
935 %    o exception: return any errors or warnings in this structure.
936 %
937 */
938 MagickExport MagickBooleanType ListMagickInfo(FILE *file,
939   ExceptionInfo *exception)
940 {
941   const MagickInfo
942     **magick_info;
943
944   long
945     j;
946
947   register long
948     i;
949
950   unsigned long
951     number_formats;
952
953   if (file == (FILE *) NULL)
954     file=stdout;
955   magick_info=GetMagickInfoList("*",&number_formats,exception);
956   if (magick_info == (const MagickInfo **) NULL)
957     return(MagickFalse);
958   ClearMagickException(exception);
959 #if !defined(MAGICKCORE_MODULES_SUPPORT)
960   (void) fprintf(file,"   Format  Mode  Description\n");
961 #else
962   (void) fprintf(file,"   Format  Module    Mode  Description\n");
963 #endif
964   (void) fprintf(file,"--------------------------------------------------------"
965     "-----------------------\n");
966   for (i=0; i < (long) number_formats; i++)
967   {
968     if (magick_info[i]->stealth != MagickFalse)
969       continue;
970     (void) fprintf(file,"%9s%c ",magick_info[i]->name != (char *) NULL ?
971       magick_info[i]->name : "",
972       magick_info[i]->blob_support != MagickFalse ? '*' : ' ');
973 #if defined(MAGICKCORE_MODULES_SUPPORT)
974     {
975       char
976         module[MaxTextExtent];
977
978       *module='\0';
979       if (magick_info[i]->module != (char *) NULL)
980         (void) CopyMagickString(module,magick_info[i]->module,MaxTextExtent);
981       (void) ConcatenateMagickString(module,"          ",MaxTextExtent);
982       module[9]='\0';
983       (void) fprintf(file,"%9s ",module);
984     }
985 #endif
986     (void) fprintf(file,"%c%c%c ",magick_info[i]->decoder ? 'r' : '-',
987       magick_info[i]->encoder ? 'w' : '-',magick_info[i]->encoder != NULL &&
988       magick_info[i]->adjoin != MagickFalse ? '+' : '-');
989     if (magick_info[i]->description != (char *) NULL)
990       (void) fprintf(file,"  %s",magick_info[i]->description);
991     if (magick_info[i]->version != (char *) NULL)
992       (void) fprintf(file," (%s)",magick_info[i]->version);
993     (void) fprintf(file,"\n");
994     if (magick_info[i]->note != (char *) NULL)
995       {
996         char
997           **text;
998
999         text=StringToList(magick_info[i]->note);
1000         if (text != (char **) NULL)
1001           {
1002             for (j=0; text[j] != (char *) NULL; j++)
1003             {
1004               (void) fprintf(file,"           %s\n",text[j]);
1005               text[j]=DestroyString(text[j]);
1006             }
1007             text=(char **) RelinquishMagickMemory(text);
1008           }
1009       }
1010   }
1011   (void) fprintf(file,"\n* native blob support\n");
1012   (void) fprintf(file,"r read support\n");
1013   (void) fprintf(file,"w write support\n");
1014   (void) fprintf(file,"+ support for multiple images\n");
1015   (void) fflush(file);
1016   magick_info=(const MagickInfo **) RelinquishMagickMemory((void *)
1017     magick_info);
1018   return(MagickTrue);
1019 }
1020 \f
1021 /*
1022 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1023 %                                                                             %
1024 %                                                                             %
1025 %                                                                             %
1026 %  I s M a g i c k I n s t a n t i a t e d                                    %
1027 %                                                                             %
1028 %                                                                             %
1029 %                                                                             %
1030 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1031 %
1032 %  IsMagickInstantiated() returns MagickTrue if the ImageMagick environment
1033 %  is currently instantiated:  MagickCoreGenesis() has been called but
1034 %  MagickDestroy() has not.
1035 %
1036 %  The format of the IsMagickInstantiated method is:
1037 %
1038 %      MagickBooleanType IsMagickInstantiated(void)
1039 %
1040 */
1041 MagickExport MagickBooleanType IsMagickInstantiated(void)
1042 {
1043   return(instantiate_magick);
1044 }
1045 \f
1046 /*
1047 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1048 %                                                                             %
1049 %                                                                             %
1050 %                                                                             %
1051 %   M a g i c k C o r e G e n e s i s                                         %
1052 %                                                                             %
1053 %                                                                             %
1054 %                                                                             %
1055 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1056 %
1057 %  MagickCoreGenesis() initializes the MagickCore environment.
1058 %
1059 %  The format of the MagickCoreGenesis function is:
1060 %
1061 %      MagickCoreGenesis(const char *path,
1062 %        const MagickBooleanType establish_signal_handlers)
1063 %
1064 %  A description of each parameter follows:
1065 %
1066 %    o path: the execution path of the current ImageMagick client.
1067 %
1068 %    o establish_signal_handlers: set to MagickTrue to use MagickCore's own
1069 %      signal handlers for common signals.
1070 %
1071 */
1072
1073 static SignalHandler *SetMagickSignalHandler(int signal_number,
1074   SignalHandler *handler)
1075 {
1076 #if defined(MAGICKCORE_HAVE_SIGACTION) && defined(MAGICKCORE_HAVE_SIGEMPTYSET)
1077   int
1078     status;
1079
1080   sigset_t
1081     mask;
1082
1083   struct sigaction
1084     action,
1085     previous_action;
1086
1087   sigemptyset(&mask);
1088   sigaddset(&mask,signal_number);
1089   sigprocmask(SIG_BLOCK,&mask,NULL);
1090   action.sa_mask=mask;
1091   action.sa_handler=handler;
1092   action.sa_flags=0;
1093 #if defined(SA_INTERRUPT)
1094   action.sa_flags|=SA_INTERRUPT;
1095 #endif
1096   status=sigaction(signal_number,&action,&previous_action);
1097   if (status < 0)
1098     return(SIG_ERR);
1099   sigprocmask(SIG_UNBLOCK,&mask,NULL);
1100   return(previous_action.sa_handler);
1101 #else
1102   return(signal(signal_number,handler));
1103 #endif
1104 }
1105
1106 static void MagickSignalHandler(int signal_number)
1107 {
1108 #if !defined(MAGICKCORE_HAVE_SIGACTION)
1109   (void) signal(signal_number,SIG_IGN);
1110 #endif
1111   AsynchronousDestroyMagickResources();
1112   instantiate_magick=MagickFalse;
1113   (void) SetMagickSignalHandler(signal_number,signal_handlers[signal_number]);
1114 #if defined(MAGICKCORE_HAVE_RAISE)
1115   if (signal_handlers[signal_number] != MagickSignalHandler)
1116     raise(signal_number);
1117 #endif
1118 #if !defined(MAGICKCORE_HAVE__EXIT)
1119   exit(signal_number);
1120 #else
1121 #if defined(SIGHUP)
1122   if (signal_number == SIGHUP)
1123     exit(signal_number);
1124 #endif
1125 #if defined(SIGINT) && !defined(__WINDOWS__)
1126   if (signal_number == SIGINT)
1127     exit(signal_number);
1128 #endif
1129 #if defined(SIGTERM)
1130   if (signal_number == SIGTERM)
1131     exit(signal_number);
1132 #endif
1133   _exit(signal_number);
1134 #endif
1135 }
1136
1137 static SignalHandler *RegisterMagickSignalHandler(int signal_number)
1138 {
1139   SignalHandler
1140     *handler;
1141
1142   handler=SetMagickSignalHandler(signal_number,MagickSignalHandler);
1143   if (handler == SIG_ERR)
1144     return(handler);
1145   if (handler != SIG_DFL)
1146     handler=SetMagickSignalHandler(signal_number,handler);
1147   else
1148     (void) LogMagickEvent(ConfigureEvent,GetMagickModule(),
1149       "Register handler for signal: %d",signal_number);
1150   return(handler);
1151 }
1152
1153 MagickExport void MagickCoreGenesis(const char *path,
1154   const MagickBooleanType establish_signal_handlers)
1155 {
1156   char
1157     *events,
1158     execution_path[MaxTextExtent],
1159     filename[MaxTextExtent];
1160
1161   ExceptionInfo
1162     *exception;
1163
1164   time_t
1165     seconds;
1166
1167   /*
1168     Initialize the Magick environment.
1169   */
1170   (void) setlocale(LC_ALL,"");
1171   (void) setlocale(LC_NUMERIC,"C");
1172   InitializeSemaphore();
1173   seconds=time((time_t *) NULL);
1174   events=GetEnvironmentValue("MAGICK_DEBUG");
1175   if (events != (char *) NULL)
1176     {
1177       (void) SetLogEventMask(events);
1178       events=DestroyString(events);
1179     }
1180 #if defined(__WINDOWS__)
1181 #if defined(_DEBUG) && !defined(__BORLANDC__) && !defined(__MINGW32__)
1182   if (IsEventLogging() != MagickFalse)
1183     {
1184       int
1185         debug;
1186
1187       debug=_CrtSetDbgFlag(_CRTDBG_REPORT_FLAG);
1188       debug|=_CRTDBG_CHECK_ALWAYS_DF |_CRTDBG_DELAY_FREE_MEM_DF |
1189         _CRTDBG_LEAK_CHECK_DF;
1190       if (0)
1191         {
1192           debug=_CrtSetDbgFlag(debug);
1193           _ASSERTE(_CrtCheckMemory());
1194         }
1195     }
1196 #endif
1197 #endif
1198   /*
1199     Set client name and execution path.
1200   */
1201   (void) GetExecutionPath(execution_path,MaxTextExtent);
1202   if ((path != (const char *) NULL) && (*path != '\0'))
1203     (void) CopyMagickString(execution_path,path,MaxTextExtent);
1204   GetPathComponent(execution_path,TailPath,filename);
1205   (void) SetClientName(filename);
1206   GetPathComponent(execution_path,HeadPath,execution_path);
1207   (void) SetClientPath(execution_path);
1208   if (establish_signal_handlers != MagickFalse)
1209     {
1210       /*
1211         Set signal handlers.
1212       */
1213 #if defined(SIGABRT)
1214       if (signal_handlers[SIGABRT] == (SignalHandler *) NULL)
1215         signal_handlers[SIGABRT]=RegisterMagickSignalHandler(SIGABRT);
1216 #endif
1217 #if defined(SIGFPE)
1218       if (signal_handlers[SIGFPE] == (SignalHandler *) NULL)
1219         signal_handlers[SIGFPE]=RegisterMagickSignalHandler(SIGFPE);
1220 #endif
1221 #if defined(SIGHUP)
1222       if (signal_handlers[SIGHUP] == (SignalHandler *) NULL)
1223         signal_handlers[SIGHUP]=RegisterMagickSignalHandler(SIGHUP);
1224 #endif
1225 #if defined(SIGINT) && !defined(__WINDOWS__)
1226       if (signal_handlers[SIGINT] == (SignalHandler *) NULL)
1227         signal_handlers[SIGINT]=RegisterMagickSignalHandler(SIGINT);
1228 #endif
1229 #if defined(SIGQUIT)
1230       if (signal_handlers[SIGQUIT] == (SignalHandler *) NULL)
1231         signal_handlers[SIGQUIT]=RegisterMagickSignalHandler(SIGQUIT);
1232 #endif
1233 #if defined(SIGTERM)
1234       if (signal_handlers[SIGTERM] == (SignalHandler *) NULL)
1235         signal_handlers[SIGTERM]=RegisterMagickSignalHandler(SIGTERM);
1236 #endif
1237 #if defined(SIGXCPU)
1238       if (signal_handlers[SIGXCPU] == (SignalHandler *) NULL)
1239         signal_handlers[SIGXCPU]=RegisterMagickSignalHandler(SIGXCPU);
1240 #endif
1241 #if defined(SIGXFSZ)
1242       if (signal_handlers[SIGXFSZ] == (SignalHandler *) NULL)
1243         signal_handlers[SIGXFSZ]=RegisterMagickSignalHandler(SIGXFSZ);
1244 #endif
1245     }
1246   /*
1247     Initialize magick resources.
1248   */
1249   InitializeMagickResources();
1250   exception=AcquireExceptionInfo();
1251 #if defined(MAGICKCORE_MODULES_SUPPORT)
1252   InitializeModuleList(exception);
1253 #endif
1254   exception=DestroyExceptionInfo(exception);
1255 }
1256 \f
1257 /*
1258 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1259 %                                                                             %
1260 %                                                                             %
1261 %                                                                             %
1262 %   M a g i c k C o r e T e r m i n u s                                       %
1263 %                                                                             %
1264 %                                                                             %
1265 %                                                                             %
1266 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1267 %
1268 %  MagickCoreTerminus() destroys the MagickCore environment.
1269 %
1270 %  The format of the DestroyMagick function is:
1271 %
1272 %      MagickCoreTerminus(void)
1273 %
1274 */
1275 MagickExport void MagickCoreTerminus(void)
1276 {
1277 #if defined(MAGICKCORE_X11_DELEGATE)
1278   DestroyXResources();
1279 #endif
1280   DestroyConstitute();
1281   DestroyMimeList();
1282   DestroyConfigureList();
1283   DestroyTypeList();
1284   DestroyColorList();
1285 #if defined(__WINDOWS__)
1286   NTGhostscriptUnLoadDLL();
1287 #endif
1288   DestroyMagicList();
1289   DestroyDelegateList();
1290   DestroyMagickList();
1291   DestroyCoderList();
1292   DestroyMagickResources();
1293   DestroyImageRegistry();
1294   DestroyPixelCacheResources();
1295   DestroyPolicyList();
1296   DestroyRandomReservoir();
1297   DestroyLocaleList();
1298   DestroyLogList();
1299   instantiate_magick=MagickFalse;
1300 }
1301 \f
1302 /*
1303 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1304 %                                                                             %
1305 %                                                                             %
1306 %                                                                             %
1307 +   R e g i s t e r M a g i c k I n f o                                       %
1308 %                                                                             %
1309 %                                                                             %
1310 %                                                                             %
1311 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1312 %
1313 %  RegisterMagickInfo() adds attributes for a particular image format to the
1314 %  list of supported formats.  The attributes include the image format name,
1315 %  a method to read and/or write the format, whether the format supports the
1316 %  saving of more than one frame to the same file or blob, whether the format
1317 %  supports native in-memory I/O, and a brief description of the format.
1318 %
1319 %  The format of the RegisterMagickInfo method is:
1320 %
1321 %      MagickInfo *RegisterMagickInfo(MagickInfo *magick_info)
1322 %
1323 %  A description of each parameter follows:
1324 %
1325 %    o magick_info: the magick info.
1326 %
1327 */
1328 MagickExport MagickInfo *RegisterMagickInfo(MagickInfo *magick_info)
1329 {
1330   MagickBooleanType
1331     status;
1332
1333   /*
1334     Delete any existing name.
1335   */
1336   assert(magick_info != (MagickInfo *) NULL);
1337   assert(magick_info->signature == MagickSignature);
1338   (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",magick_info->name);
1339   if (magick_list == (SplayTreeInfo *) NULL)
1340     return((MagickInfo *) NULL);
1341   status=AddValueToSplayTree(magick_list,magick_info->name,magick_info);
1342   if (status == MagickFalse)
1343     ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed");
1344   return(magick_info);
1345 }
1346 \f
1347 /*
1348 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1349 %                                                                             %
1350 %                                                                             %
1351 %                                                                             %
1352 +   S e t M a g i c k I n f o                                                 %
1353 %                                                                             %
1354 %                                                                             %
1355 %                                                                             %
1356 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1357 %
1358 %  SetMagickInfo() allocates a MagickInfo structure and initializes the members
1359 %  to default values.
1360 %
1361 %  The format of the SetMagickInfo method is:
1362 %
1363 %      MagickInfo *SetMagickInfo(const char *name)
1364 %
1365 %  A description of each parameter follows:
1366 %
1367 %    o magick_info: Method SetMagickInfo returns the allocated and initialized
1368 %      MagickInfo structure.
1369 %
1370 %    o name: a character string that represents the image format associated
1371 %      with the MagickInfo structure.
1372 %
1373 */
1374 MagickExport MagickInfo *SetMagickInfo(const char *name)
1375 {
1376   MagickInfo
1377     *magick_info;
1378
1379   assert(name != (const char *) NULL);
1380   (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",name);
1381   magick_info=(MagickInfo *) AcquireMagickMemory(sizeof(*magick_info));
1382   if (magick_info == (MagickInfo *) NULL)
1383     ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed");
1384   (void) ResetMagickMemory(magick_info,0,sizeof(*magick_info));
1385   magick_info->name=ConstantString(name);
1386   magick_info->adjoin=MagickTrue;
1387   magick_info->blob_support=MagickTrue;
1388   magick_info->thread_support=(MagickStatusType) (DecoderThreadSupport |
1389     EncoderThreadSupport);
1390   magick_info->signature=MagickSignature;
1391   return(magick_info);
1392 }
1393 \f
1394 /*
1395 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1396 %                                                                             %
1397 %                                                                             %
1398 %                                                                             %
1399 +   U n r e g i s t e r M a g i c k I n f o                                   %
1400 %                                                                             %
1401 %                                                                             %
1402 %                                                                             %
1403 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1404 %
1405 %  UnregisterMagickInfo() removes a name from the magick info list.  It returns
1406 %  MagickFalse if the name does not exist in the list otherwise MagickTrue.
1407 %
1408 %  The format of the UnregisterMagickInfo method is:
1409 %
1410 %      MagickBooleanType UnregisterMagickInfo(const char *name)
1411 %
1412 %  A description of each parameter follows:
1413 %
1414 %    o name: a character string that represents the image format we are
1415 %      looking for.
1416 %
1417 */
1418 MagickExport MagickBooleanType UnregisterMagickInfo(const char *name)
1419 {
1420   register const MagickInfo
1421     *p;
1422
1423   MagickBooleanType
1424     status;
1425
1426   assert(name != (const char *) NULL);
1427   if (magick_list == (SplayTreeInfo *) NULL)
1428     return(MagickFalse);
1429   if (GetNumberOfNodesInSplayTree(magick_list) == 0)
1430     return(MagickFalse);
1431   AcquireSemaphoreInfo(&magick_semaphore);
1432   ResetSplayTreeIterator(magick_list);
1433   p=(const MagickInfo *) GetNextValueInSplayTree(magick_list);
1434   while (p != (const MagickInfo *) NULL)
1435   {
1436     if (LocaleCompare(p->name,name) == 0)
1437       break;
1438     p=(const MagickInfo *) GetNextValueInSplayTree(magick_list);
1439   }
1440   status=DeleteNodeByValueFromSplayTree(magick_list,p);
1441   RelinquishSemaphoreInfo(magick_semaphore);
1442   return(status);
1443 }