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