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