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