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