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