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