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