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