blob: 06a4a3eec9dc814d14ae20d82a3a0391d6d9daea [file] [log] [blame]
cristy3ed852e2009-09-05 21:47:34 +00001/*
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% %
cristy16af1cb2009-12-11 21:38:29 +000021% Copyright 1999-2010 ImageMagick Studio LLC, a non-profit organization %
cristy3ed852e2009-09-05 21:47:34 +000022% 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
40/*
41 Include declarations.
42*/
43#include "magick/studio.h"
44#include "magick/blob.h"
45#include "magick/cache.h"
46#include "magick/coder.h"
47#include "magick/client.h"
48#include "magick/coder.h"
49#include "magick/configure.h"
50#include "magick/constitute.h"
51#include "magick/delegate.h"
52#include "magick/draw.h"
53#include "magick/exception.h"
54#include "magick/exception-private.h"
55#include "magick/locale_.h"
56#include "magick/log.h"
57#include "magick/magic.h"
58#include "magick/magick.h"
59#include "magick/memory_.h"
60#include "magick/mime.h"
61#include "magick/module.h"
62#if defined(__WINDOWS__)
63# include "magick/nt-feature.h"
64#endif
65#include "magick/random_.h"
66#include "magick/registry.h"
67#include "magick/resource_.h"
68#include "magick/policy.h"
69#include "magick/semaphore.h"
70#include "magick/signature-private.h"
71#include "magick/splay-tree.h"
72#include "magick/string_.h"
cristy7ce14bc2010-01-17 00:01:01 +000073#include "magick/string-private.h"
cristy3ed852e2009-09-05 21:47:34 +000074#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
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
96/*
97 Typedef declarations.
98*/
99typedef MAGICKCORE_RETSIGTYPE
100 SignalHandler(int);
101
102/*
103 Global declarations.
104*/
105static SemaphoreInfo
106 *magick_semaphore = (SemaphoreInfo *) NULL;
107
108static SignalHandler
109 *signal_handlers[SIGMAX] = { (SignalHandler *) NULL };
110
111static SplayTreeInfo
112 *magick_list = (SplayTreeInfo *) NULL;
113
114static volatile MagickBooleanType
115 instantiate_magick = MagickFalse; /* double-checked locking pattern */
116
117/*
118 Forward declarations.
119*/
120static MagickBooleanType
121 InitializeMagickList(ExceptionInfo *);
122
123/*
124%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
125% %
126% %
127% %
cristy3ed852e2009-09-05 21:47:34 +0000128+ 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*/
145MagickExport 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
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*/
175MagickExport 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
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*/
212MagickExport 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;
cristyf84a1932010-01-03 18:00:18 +0000232 LockSemaphoreInfo(magick_semaphore);
cristy3ed852e2009-09-05 21:47:34 +0000233 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 }
cristyf84a1932010-01-03 18:00:18 +0000246 UnlockSemaphoreInfo(magick_semaphore);
cristy3ed852e2009-09-05 21:47:34 +0000247 return(status);
248}
249
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*/
272MagickExport 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
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*/
302MagickExport 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
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*/
333MagickExport 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
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*/
364MagickExport 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
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*/
399MagickExport 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
cristyf84a1932010-01-03 18:00:18 +0000416 LockSemaphoreInfo(magick_semaphore);
cristy3ed852e2009-09-05 21:47:34 +0000417 ResetSplayTreeIterator(magick_list);
418 p=(const MagickInfo *) GetNextValueInSplayTree(magick_list);
cristyf84a1932010-01-03 18:00:18 +0000419 UnlockSemaphoreInfo(magick_semaphore);
cristy3ed852e2009-09-05 21:47:34 +0000420 return(p);
421 }
422 /*
423 Find name in list.
424 */
cristyf84a1932010-01-03 18:00:18 +0000425 LockSemaphoreInfo(magick_semaphore);
cristy3ed852e2009-09-05 21:47:34 +0000426 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
cristyf84a1932010-01-03 18:00:18 +0000449 UnlockSemaphoreInfo(magick_semaphore);
cristy3ed852e2009-09-05 21:47:34 +0000450 return(p);
451}
452
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)
483extern "C" {
484#endif
485
486static 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
501MagickExport 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 */
cristyf84a1932010-01-03 18:00:18 +0000530 LockSemaphoreInfo(magick_semaphore);
cristy3ed852e2009-09-05 21:47:34 +0000531 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 }
cristyf84a1932010-01-03 18:00:18 +0000540 UnlockSemaphoreInfo(magick_semaphore);
cristy3ed852e2009-09-05 21:47:34 +0000541 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
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)
576extern "C" {
577#endif
578
579static 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
594MagickExport 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);
cristyf84a1932010-01-03 18:00:18 +0000620 LockSemaphoreInfo(magick_semaphore);
cristy3ed852e2009-09-05 21:47:34 +0000621 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 }
cristyf84a1932010-01-03 18:00:18 +0000630 UnlockSemaphoreInfo(magick_semaphore);
cristy3ed852e2009-09-05 21:47:34 +0000631 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
637/*
638%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
639% %
640% %
641% %
cristye7f51092010-01-17 00:39:37 +0000642% G e t M a g i c k P r e c i s i o n %
cristy7ce14bc2010-01-17 00:01:01 +0000643% %
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%
cristye7f51092010-01-17 00:39:37 +0000653% int GetMagickPrecision(void)
cristy7ce14bc2010-01-17 00:01:01 +0000654%
655*/
cristye7f51092010-01-17 00:39:37 +0000656MagickExport int GetMagickPrecision(void)
cristy7ce14bc2010-01-17 00:01:01 +0000657{
cristye7f51092010-01-17 00:39:37 +0000658#define MagickPrecision 6
cristy7ce14bc2010-01-17 00:01:01 +0000659
660 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
cristybf2766a2010-01-17 03:33:23 +0000661 if (SetMagickPrecision(0) == 0)
cristy7ce14bc2010-01-17 00:01:01 +0000662 {
663 char
664 *limit;
665
cristybf2766a2010-01-17 03:33:23 +0000666 (void) SetMagickPrecision(MagickPrecision);
cristye7f51092010-01-17 00:39:37 +0000667 limit=GetEnvironmentValue("MAGICK_PRECISION");
668 if (limit == (char *) NULL)
669 limit=GetPolicyValue("precision");
670 if (limit != (char *) NULL)
671 {
cristybf2766a2010-01-17 03:33:23 +0000672 (void) SetMagickPrecision(StringToInteger(limit));
cristye7f51092010-01-17 00:39:37 +0000673 limit=DestroyString(limit);
674 }
cristy7ce14bc2010-01-17 00:01:01 +0000675 }
cristybf2766a2010-01-17 03:33:23 +0000676 return(SetMagickPrecision(0));
cristy7ce14bc2010-01-17 00:01:01 +0000677}
678
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 %
cristy3ed852e2009-09-05 21:47:34 +0000685% %
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*/
701MagickExport 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
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*/
733MagickExport 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
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*/
764MagickExport 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
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
796static 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
815static MagickBooleanType InitializeMagickList(ExceptionInfo *exception)
816{
cristyf2e11662009-10-14 01:24:43 +0000817 (void) exception;
cristy3ed852e2009-09-05 21:47:34 +0000818 if ((magick_list == (SplayTreeInfo *) NULL) &&
819 (instantiate_magick == MagickFalse))
820 {
cristy4e1dff62009-10-25 20:36:03 +0000821 if (magick_semaphore == (SemaphoreInfo *) NULL)
822 AcquireSemaphoreInfo(&magick_semaphore);
cristyf84a1932010-01-03 18:00:18 +0000823 LockSemaphoreInfo(magick_semaphore);
cristy3ed852e2009-09-05 21:47:34 +0000824 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 }
cristyf84a1932010-01-03 18:00:18 +0000865 UnlockSemaphoreInfo(magick_semaphore);
cristy3ed852e2009-09-05 21:47:34 +0000866 }
867 return(magick_list != (SplayTreeInfo *) NULL ? MagickTrue : MagickFalse);
868}
869
870/*
871%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
872% %
873% %
874% %
875+ I s M a g i c k C o n f l i c t %
876% %
877% %
878% %
879%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
880%
881% IsMagickConflict() returns MagickTrue if the image format is not a valid
882% image format or conflicts with a logical drive (.e.g. X:).
883%
884% The format of the IsMagickConflict method is:
885%
886% MagickBooleanType IsMagickConflict(const char *magick)
887%
888% A description of each parameter follows:
889%
890% o magick: Specifies the image format.
891%
892*/
893MagickExport MagickBooleanType IsMagickConflict(const char *magick)
894{
895 const DelegateInfo
896 *delegate_info;
897
898 const MagickInfo
899 *magick_info;
900
901 ExceptionInfo
902 *exception;
903
904 assert(magick != (char *) NULL);
905 exception=AcquireExceptionInfo();
906 magick_info=GetMagickInfo(magick,exception);
907 delegate_info=GetDelegateInfo(magick,(char *) NULL,exception);
908 if (delegate_info == (const DelegateInfo *) NULL)
909 delegate_info=GetDelegateInfo((char *) NULL,magick,exception);
910 exception=DestroyExceptionInfo(exception);
911 if ((magick_info == (const MagickInfo *) NULL) &&
912 (delegate_info == (const DelegateInfo *) NULL))
913 return(MagickTrue);
914#if defined(macintosh)
915 return(MACIsMagickConflict(magick));
916#elif defined(vms)
917 return(VMSIsMagickConflict(magick));
918#elif defined(__WINDOWS__)
919 return(NTIsMagickConflict(magick));
920#else
921 return(MagickFalse);
922#endif
923}
924
925/*
926%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
927% %
928% %
929% %
930+ L i s t M a g i c k I n f o %
931% %
932% %
933% %
934%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
935%
936% ListMagickInfo() lists the image formats to a file.
937%
938% The format of the ListMagickInfo method is:
939%
940% MagickBooleanType ListMagickInfo(FILE *file,ExceptionInfo *exception)
941%
942% A description of each parameter follows.
943%
944% o file: A file handle.
945%
946% o exception: return any errors or warnings in this structure.
947%
948*/
949MagickExport MagickBooleanType ListMagickInfo(FILE *file,
950 ExceptionInfo *exception)
951{
952 const MagickInfo
953 **magick_info;
954
955 long
956 j;
957
958 register long
959 i;
960
961 unsigned long
962 number_formats;
963
964 if (file == (FILE *) NULL)
965 file=stdout;
966 magick_info=GetMagickInfoList("*",&number_formats,exception);
967 if (magick_info == (const MagickInfo **) NULL)
968 return(MagickFalse);
969 ClearMagickException(exception);
970#if !defined(MAGICKCORE_MODULES_SUPPORT)
971 (void) fprintf(file," Format Mode Description\n");
972#else
973 (void) fprintf(file," Format Module Mode Description\n");
974#endif
975 (void) fprintf(file,"--------------------------------------------------------"
976 "-----------------------\n");
977 for (i=0; i < (long) number_formats; i++)
978 {
979 if (magick_info[i]->stealth != MagickFalse)
980 continue;
981 (void) fprintf(file,"%9s%c ",magick_info[i]->name != (char *) NULL ?
982 magick_info[i]->name : "",
983 magick_info[i]->blob_support != MagickFalse ? '*' : ' ');
984#if defined(MAGICKCORE_MODULES_SUPPORT)
985 {
986 char
987 module[MaxTextExtent];
988
989 *module='\0';
990 if (magick_info[i]->module != (char *) NULL)
991 (void) CopyMagickString(module,magick_info[i]->module,MaxTextExtent);
992 (void) ConcatenateMagickString(module," ",MaxTextExtent);
993 module[9]='\0';
994 (void) fprintf(file,"%9s ",module);
995 }
996#endif
997 (void) fprintf(file,"%c%c%c ",magick_info[i]->decoder ? 'r' : '-',
998 magick_info[i]->encoder ? 'w' : '-',magick_info[i]->encoder != NULL &&
999 magick_info[i]->adjoin != MagickFalse ? '+' : '-');
1000 if (magick_info[i]->description != (char *) NULL)
1001 (void) fprintf(file," %s",magick_info[i]->description);
1002 if (magick_info[i]->version != (char *) NULL)
1003 (void) fprintf(file," (%s)",magick_info[i]->version);
1004 (void) fprintf(file,"\n");
1005 if (magick_info[i]->note != (char *) NULL)
1006 {
1007 char
1008 **text;
1009
1010 text=StringToList(magick_info[i]->note);
1011 if (text != (char **) NULL)
1012 {
1013 for (j=0; text[j] != (char *) NULL; j++)
1014 {
1015 (void) fprintf(file," %s\n",text[j]);
1016 text[j]=DestroyString(text[j]);
1017 }
1018 text=(char **) RelinquishMagickMemory(text);
1019 }
1020 }
1021 }
1022 (void) fprintf(file,"\n* native blob support\n");
1023 (void) fprintf(file,"r read support\n");
1024 (void) fprintf(file,"w write support\n");
1025 (void) fprintf(file,"+ support for multiple images\n");
1026 (void) fflush(file);
1027 magick_info=(const MagickInfo **) RelinquishMagickMemory((void *)
1028 magick_info);
1029 return(MagickTrue);
1030}
1031
1032/*
1033%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1034% %
1035% %
1036% %
1037% I s M a g i c k I n s t a n t i a t e d %
1038% %
1039% %
1040% %
1041%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1042%
1043% IsMagickInstantiated() returns MagickTrue if the ImageMagick environment
1044% is currently instantiated: MagickCoreGenesis() has been called but
1045% MagickDestroy() has not.
1046%
1047% The format of the IsMagickInstantiated method is:
1048%
1049% MagickBooleanType IsMagickInstantiated(void)
1050%
1051*/
1052MagickExport MagickBooleanType IsMagickInstantiated(void)
1053{
1054 return(instantiate_magick);
1055}
1056
1057/*
1058%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1059% %
1060% %
1061% %
cristyf34a1452009-10-24 22:29:27 +00001062+ M a g i c k C o m p o n e n t G e n e s i s %
1063% %
1064% %
1065% %
1066%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1067%
1068% MagickComponentGenesis() instantiates the magick component.
1069%
1070% The format of the MagickComponentGenesis method is:
1071%
1072% MagickBooleanType MagickComponentGenesis(void)
1073%
1074*/
1075MagickExport MagickBooleanType MagickComponentGenesis(void)
1076{
cristy165b6092009-10-26 13:52:10 +00001077 AcquireSemaphoreInfo(&magick_semaphore);
cristyf34a1452009-10-24 22:29:27 +00001078 return(MagickTrue);
1079}
1080
1081/*
1082%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1083% %
1084% %
1085% %
1086+ M a g i c k C o m p o n e n t T e r m i n u s %
1087% %
1088% %
1089% %
1090%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1091%
1092% MagickComponentTerminus() destroys the magick component.
1093%
1094% The format of the MagickComponentTerminus method is:
1095%
1096% void MagickComponentTerminus(void)
1097%
1098*/
1099MagickExport void MagickComponentTerminus(void)
1100{
cristy18b17442009-10-25 18:36:48 +00001101 if (magick_semaphore == (SemaphoreInfo *) NULL)
1102 AcquireSemaphoreInfo(&magick_semaphore);
cristyf84a1932010-01-03 18:00:18 +00001103 LockSemaphoreInfo(magick_semaphore);
cristyf34a1452009-10-24 22:29:27 +00001104 if (magick_list != (SplayTreeInfo *) NULL)
1105 magick_list=DestroySplayTree(magick_list);
1106 instantiate_magick=MagickFalse;
cristyf84a1932010-01-03 18:00:18 +00001107 UnlockSemaphoreInfo(magick_semaphore);
cristyf34a1452009-10-24 22:29:27 +00001108 DestroySemaphoreInfo(&magick_semaphore);
1109}
1110
1111/*
1112%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1113% %
1114% %
1115% %
cristy3ed852e2009-09-05 21:47:34 +00001116% M a g i c k C o r e G e n e s i s %
1117% %
1118% %
1119% %
1120%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1121%
1122% MagickCoreGenesis() initializes the MagickCore environment.
1123%
1124% The format of the MagickCoreGenesis function is:
1125%
1126% MagickCoreGenesis(const char *path,
1127% const MagickBooleanType establish_signal_handlers)
1128%
1129% A description of each parameter follows:
1130%
1131% o path: the execution path of the current ImageMagick client.
1132%
1133% o establish_signal_handlers: set to MagickTrue to use MagickCore's own
1134% signal handlers for common signals.
1135%
1136*/
1137
1138static SignalHandler *SetMagickSignalHandler(int signal_number,
1139 SignalHandler *handler)
1140{
1141#if defined(MAGICKCORE_HAVE_SIGACTION) && defined(MAGICKCORE_HAVE_SIGEMPTYSET)
1142 int
1143 status;
1144
1145 sigset_t
1146 mask;
1147
1148 struct sigaction
1149 action,
1150 previous_action;
1151
1152 sigemptyset(&mask);
1153 sigaddset(&mask,signal_number);
1154 sigprocmask(SIG_BLOCK,&mask,NULL);
1155 action.sa_mask=mask;
1156 action.sa_handler=handler;
1157 action.sa_flags=0;
1158#if defined(SA_INTERRUPT)
1159 action.sa_flags|=SA_INTERRUPT;
1160#endif
1161 status=sigaction(signal_number,&action,&previous_action);
1162 if (status < 0)
1163 return(SIG_ERR);
1164 sigprocmask(SIG_UNBLOCK,&mask,NULL);
1165 return(previous_action.sa_handler);
1166#else
1167 return(signal(signal_number,handler));
1168#endif
1169}
1170
1171static void MagickSignalHandler(int signal_number)
1172{
1173#if !defined(MAGICKCORE_HAVE_SIGACTION)
1174 (void) signal(signal_number,SIG_IGN);
1175#endif
cristyf34a1452009-10-24 22:29:27 +00001176 AsynchronousResourceComponentTerminus();
cristy3ed852e2009-09-05 21:47:34 +00001177 instantiate_magick=MagickFalse;
1178 (void) SetMagickSignalHandler(signal_number,signal_handlers[signal_number]);
1179#if defined(MAGICKCORE_HAVE_RAISE)
1180 if (signal_handlers[signal_number] != MagickSignalHandler)
1181 raise(signal_number);
1182#endif
1183#if !defined(MAGICKCORE_HAVE__EXIT)
1184 exit(signal_number);
1185#else
1186#if defined(SIGHUP)
1187 if (signal_number == SIGHUP)
1188 exit(signal_number);
1189#endif
1190#if defined(SIGINT) && !defined(__WINDOWS__)
1191 if (signal_number == SIGINT)
1192 exit(signal_number);
1193#endif
1194#if defined(SIGTERM)
1195 if (signal_number == SIGTERM)
1196 exit(signal_number);
1197#endif
1198 _exit(signal_number);
1199#endif
1200}
1201
1202static SignalHandler *RegisterMagickSignalHandler(int signal_number)
1203{
1204 SignalHandler
1205 *handler;
1206
1207 handler=SetMagickSignalHandler(signal_number,MagickSignalHandler);
1208 if (handler == SIG_ERR)
1209 return(handler);
1210 if (handler != SIG_DFL)
1211 handler=SetMagickSignalHandler(signal_number,handler);
1212 else
1213 (void) LogMagickEvent(ConfigureEvent,GetMagickModule(),
1214 "Register handler for signal: %d",signal_number);
1215 return(handler);
1216}
1217
1218MagickExport void MagickCoreGenesis(const char *path,
1219 const MagickBooleanType establish_signal_handlers)
1220{
1221 char
1222 *events,
1223 execution_path[MaxTextExtent],
1224 filename[MaxTextExtent];
1225
cristy3ed852e2009-09-05 21:47:34 +00001226 /*
1227 Initialize the Magick environment.
1228 */
1229 (void) setlocale(LC_ALL,"");
1230 (void) setlocale(LC_NUMERIC,"C");
cristyf34a1452009-10-24 22:29:27 +00001231 (void) SemaphoreComponentGenesis();
1232 (void) LogComponentGenesis();
1233 (void) LocaleComponentGenesis();
1234 (void) RandomComponentGenesis();
cristy3ed852e2009-09-05 21:47:34 +00001235 events=GetEnvironmentValue("MAGICK_DEBUG");
1236 if (events != (char *) NULL)
1237 {
1238 (void) SetLogEventMask(events);
1239 events=DestroyString(events);
1240 }
1241#if defined(__WINDOWS__)
1242#if defined(_DEBUG) && !defined(__BORLANDC__) && !defined(__MINGW32__)
1243 if (IsEventLogging() != MagickFalse)
1244 {
1245 int
1246 debug;
1247
1248 debug=_CrtSetDbgFlag(_CRTDBG_REPORT_FLAG);
1249 debug|=_CRTDBG_CHECK_ALWAYS_DF |_CRTDBG_DELAY_FREE_MEM_DF |
1250 _CRTDBG_LEAK_CHECK_DF;
1251 if (0)
1252 {
1253 debug=_CrtSetDbgFlag(debug);
1254 _ASSERTE(_CrtCheckMemory());
1255 }
1256 }
1257#endif
1258#endif
1259 /*
1260 Set client name and execution path.
1261 */
1262 (void) GetExecutionPath(execution_path,MaxTextExtent);
1263 if ((path != (const char *) NULL) && (*path != '\0'))
1264 (void) CopyMagickString(execution_path,path,MaxTextExtent);
1265 GetPathComponent(execution_path,TailPath,filename);
1266 (void) SetClientName(filename);
1267 GetPathComponent(execution_path,HeadPath,execution_path);
1268 (void) SetClientPath(execution_path);
1269 if (establish_signal_handlers != MagickFalse)
1270 {
1271 /*
1272 Set signal handlers.
1273 */
1274#if defined(SIGABRT)
1275 if (signal_handlers[SIGABRT] == (SignalHandler *) NULL)
1276 signal_handlers[SIGABRT]=RegisterMagickSignalHandler(SIGABRT);
1277#endif
1278#if defined(SIGFPE)
1279 if (signal_handlers[SIGFPE] == (SignalHandler *) NULL)
1280 signal_handlers[SIGFPE]=RegisterMagickSignalHandler(SIGFPE);
1281#endif
1282#if defined(SIGHUP)
1283 if (signal_handlers[SIGHUP] == (SignalHandler *) NULL)
1284 signal_handlers[SIGHUP]=RegisterMagickSignalHandler(SIGHUP);
1285#endif
1286#if defined(SIGINT) && !defined(__WINDOWS__)
1287 if (signal_handlers[SIGINT] == (SignalHandler *) NULL)
1288 signal_handlers[SIGINT]=RegisterMagickSignalHandler(SIGINT);
1289#endif
1290#if defined(SIGQUIT)
1291 if (signal_handlers[SIGQUIT] == (SignalHandler *) NULL)
1292 signal_handlers[SIGQUIT]=RegisterMagickSignalHandler(SIGQUIT);
1293#endif
1294#if defined(SIGTERM)
1295 if (signal_handlers[SIGTERM] == (SignalHandler *) NULL)
1296 signal_handlers[SIGTERM]=RegisterMagickSignalHandler(SIGTERM);
1297#endif
1298#if defined(SIGXCPU)
1299 if (signal_handlers[SIGXCPU] == (SignalHandler *) NULL)
1300 signal_handlers[SIGXCPU]=RegisterMagickSignalHandler(SIGXCPU);
1301#endif
1302#if defined(SIGXFSZ)
1303 if (signal_handlers[SIGXFSZ] == (SignalHandler *) NULL)
1304 signal_handlers[SIGXFSZ]=RegisterMagickSignalHandler(SIGXFSZ);
1305#endif
1306 }
1307 /*
cristyaf8b5cd2009-10-24 00:29:23 +00001308 Instantiate magick resources.
cristy3ed852e2009-09-05 21:47:34 +00001309 */
cristy18b17442009-10-25 18:36:48 +00001310 (void) ConfigureComponentGenesis();
cristyf34a1452009-10-24 22:29:27 +00001311 (void) PolicyComponentGenesis();
1312 (void) CacheComponentGenesis();
1313 (void) RegistryComponentGenesis();
1314 (void) ResourceComponentGenesis();
1315 (void) CoderComponentGenesis();
1316 (void) MagickComponentGenesis();
cristyaf8b5cd2009-10-24 00:29:23 +00001317#if defined(MAGICKCORE_MODULES_SUPPORT)
cristyf34a1452009-10-24 22:29:27 +00001318 (void) ModuleComponentGenesis();
cristyaf8b5cd2009-10-24 00:29:23 +00001319#endif
cristyf34a1452009-10-24 22:29:27 +00001320 (void) DelegateComponentGenesis();
1321 (void) MagicComponentGenesis();
1322 (void) ColorComponentGenesis();
1323 (void) TypeComponentGenesis();
cristyf34a1452009-10-24 22:29:27 +00001324 (void) MimeComponentGenesis();
1325 (void) ConstituteComponentGenesis();
1326 (void) XComponentGenesis();
cristy3ed852e2009-09-05 21:47:34 +00001327}
1328
1329/*
1330%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1331% %
1332% %
1333% %
1334% M a g i c k C o r e T e r m i n u s %
1335% %
1336% %
1337% %
1338%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1339%
1340% MagickCoreTerminus() destroys the MagickCore environment.
1341%
cristyf34a1452009-10-24 22:29:27 +00001342% The format of the MagickCoreTerminus function is:
cristy3ed852e2009-09-05 21:47:34 +00001343%
1344% MagickCoreTerminus(void)
1345%
1346*/
1347MagickExport void MagickCoreTerminus(void)
1348{
1349#if defined(MAGICKCORE_X11_DELEGATE)
cristyf34a1452009-10-24 22:29:27 +00001350 XComponentTerminus();
cristy3ed852e2009-09-05 21:47:34 +00001351#endif
cristyf34a1452009-10-24 22:29:27 +00001352 ConstituteComponentTerminus();
1353 MimeComponentTerminus();
cristyf34a1452009-10-24 22:29:27 +00001354 TypeComponentTerminus();
1355 ColorComponentTerminus();
cristy3ed852e2009-09-05 21:47:34 +00001356#if defined(__WINDOWS__)
1357 NTGhostscriptUnLoadDLL();
1358#endif
cristyf34a1452009-10-24 22:29:27 +00001359 MagicComponentTerminus();
1360 DelegateComponentTerminus();
1361 MagickComponentTerminus();
cristyaf8b5cd2009-10-24 00:29:23 +00001362#if !defined(MAGICKCORE_BUILD_MODULES)
1363 UnregisterStaticModules();
1364#endif
1365#if defined(MAGICKCORE_MODULES_SUPPORT)
cristyf34a1452009-10-24 22:29:27 +00001366 ModuleComponentTerminus();
cristyaf8b5cd2009-10-24 00:29:23 +00001367#endif
cristyf34a1452009-10-24 22:29:27 +00001368 CoderComponentTerminus();
1369 ResourceComponentTerminus();
1370 RegistryComponentTerminus();
1371 CacheComponentTerminus();
1372 PolicyComponentTerminus();
cristy18b17442009-10-25 18:36:48 +00001373 ConfigureComponentTerminus();
cristyf34a1452009-10-24 22:29:27 +00001374 RandomComponentTerminus();
1375 LocaleComponentTerminus();
1376 LogComponentTerminus();
1377 SemaphoreComponentTerminus();
cristy3ed852e2009-09-05 21:47:34 +00001378 instantiate_magick=MagickFalse;
1379}
1380
1381/*
1382%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1383% %
1384% %
1385% %
1386+ R e g i s t e r M a g i c k I n f o %
1387% %
1388% %
1389% %
1390%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1391%
1392% RegisterMagickInfo() adds attributes for a particular image format to the
1393% list of supported formats. The attributes include the image format name,
1394% a method to read and/or write the format, whether the format supports the
1395% saving of more than one frame to the same file or blob, whether the format
1396% supports native in-memory I/O, and a brief description of the format.
1397%
1398% The format of the RegisterMagickInfo method is:
1399%
1400% MagickInfo *RegisterMagickInfo(MagickInfo *magick_info)
1401%
1402% A description of each parameter follows:
1403%
1404% o magick_info: the magick info.
1405%
1406*/
1407MagickExport MagickInfo *RegisterMagickInfo(MagickInfo *magick_info)
1408{
1409 MagickBooleanType
1410 status;
1411
1412 /*
1413 Delete any existing name.
1414 */
1415 assert(magick_info != (MagickInfo *) NULL);
1416 assert(magick_info->signature == MagickSignature);
1417 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",magick_info->name);
1418 if (magick_list == (SplayTreeInfo *) NULL)
1419 return((MagickInfo *) NULL);
1420 status=AddValueToSplayTree(magick_list,magick_info->name,magick_info);
1421 if (status == MagickFalse)
1422 ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed");
1423 return(magick_info);
1424}
1425
1426/*
1427%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1428% %
1429% %
1430% %
1431+ S e t M a g i c k I n f o %
1432% %
1433% %
1434% %
1435%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1436%
1437% SetMagickInfo() allocates a MagickInfo structure and initializes the members
1438% to default values.
1439%
1440% The format of the SetMagickInfo method is:
1441%
1442% MagickInfo *SetMagickInfo(const char *name)
1443%
1444% A description of each parameter follows:
1445%
1446% o magick_info: Method SetMagickInfo returns the allocated and initialized
1447% MagickInfo structure.
1448%
1449% o name: a character string that represents the image format associated
1450% with the MagickInfo structure.
1451%
1452*/
1453MagickExport MagickInfo *SetMagickInfo(const char *name)
1454{
1455 MagickInfo
1456 *magick_info;
1457
1458 assert(name != (const char *) NULL);
1459 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",name);
cristy90823212009-12-12 20:48:33 +00001460 magick_info=(MagickInfo *) AcquireAlignedMemory(1,sizeof(*magick_info));
cristy3ed852e2009-09-05 21:47:34 +00001461 if (magick_info == (MagickInfo *) NULL)
1462 ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed");
1463 (void) ResetMagickMemory(magick_info,0,sizeof(*magick_info));
1464 magick_info->name=ConstantString(name);
1465 magick_info->adjoin=MagickTrue;
1466 magick_info->blob_support=MagickTrue;
1467 magick_info->thread_support=(MagickStatusType) (DecoderThreadSupport |
1468 EncoderThreadSupport);
1469 magick_info->signature=MagickSignature;
1470 return(magick_info);
1471}
1472
1473/*
1474%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1475% %
1476% %
1477% %
cristye7f51092010-01-17 00:39:37 +00001478% S e t M a g i c k P r e c i s i o n %
1479% %
1480% %
1481% %
1482%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1483%
1484% SetMagickPrecision() sets the maximum number of significant digits to be
cristybf2766a2010-01-17 03:33:23 +00001485% printed and returns it.
cristye7f51092010-01-17 00:39:37 +00001486%
1487% The format of the SetMagickPrecision method is:
1488%
cristybf2766a2010-01-17 03:33:23 +00001489% int SetMagickPrecision(const int precision)
cristye7f51092010-01-17 00:39:37 +00001490%
1491% A description of each parameter follows:
1492%
1493% o precision: set the maximum number of significant digits to be printed.
1494%
1495*/
cristybf2766a2010-01-17 03:33:23 +00001496MagickExport int SetMagickPrecision(const int precision)
cristye7f51092010-01-17 00:39:37 +00001497{
cristybf2766a2010-01-17 03:33:23 +00001498 static int
1499 magick_precision = 0;
1500
cristye7f51092010-01-17 00:39:37 +00001501 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
cristybf2766a2010-01-17 03:33:23 +00001502 if (precision != 0)
1503 magick_precision=precision;
1504 return(magick_precision);
cristye7f51092010-01-17 00:39:37 +00001505}
1506
1507/*
1508%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1509% %
1510% %
1511% %
cristy3ed852e2009-09-05 21:47:34 +00001512+ U n r e g i s t e r M a g i c k I n f o %
1513% %
1514% %
1515% %
1516%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1517%
1518% UnregisterMagickInfo() removes a name from the magick info list. It returns
1519% MagickFalse if the name does not exist in the list otherwise MagickTrue.
1520%
1521% The format of the UnregisterMagickInfo method is:
1522%
1523% MagickBooleanType UnregisterMagickInfo(const char *name)
1524%
1525% A description of each parameter follows:
1526%
1527% o name: a character string that represents the image format we are
1528% looking for.
1529%
1530*/
1531MagickExport MagickBooleanType UnregisterMagickInfo(const char *name)
1532{
1533 register const MagickInfo
1534 *p;
1535
1536 MagickBooleanType
1537 status;
1538
1539 assert(name != (const char *) NULL);
1540 if (magick_list == (SplayTreeInfo *) NULL)
1541 return(MagickFalse);
1542 if (GetNumberOfNodesInSplayTree(magick_list) == 0)
1543 return(MagickFalse);
cristyf84a1932010-01-03 18:00:18 +00001544 LockSemaphoreInfo(magick_semaphore);
cristy3ed852e2009-09-05 21:47:34 +00001545 ResetSplayTreeIterator(magick_list);
1546 p=(const MagickInfo *) GetNextValueInSplayTree(magick_list);
1547 while (p != (const MagickInfo *) NULL)
1548 {
1549 if (LocaleCompare(p->name,name) == 0)
1550 break;
1551 p=(const MagickInfo *) GetNextValueInSplayTree(magick_list);
1552 }
1553 status=DeleteNodeByValueFromSplayTree(magick_list,p);
cristyf84a1932010-01-03 18:00:18 +00001554 UnlockSemaphoreInfo(magick_semaphore);
cristy3ed852e2009-09-05 21:47:34 +00001555 return(status);
1556}