blob: c94ae65b8f0916cd5e6f287bfc941eb4889b1412 [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"
cristy0157aea2010-04-24 21:12:18 +000062#if defined(MAGICKCORE_WINDOWS_SUPPORT)
cristy3ed852e2009-09-05 21:47:34 +000063# 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%
cristy05a9a622010-03-15 17:26:04 +0000881% IsMagickConflict() returns MagickTrue if the image format conflicts with a
882% logical drive (.e.g. X:).
cristy3ed852e2009-09-05 21:47:34 +0000883%
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{
cristy3ed852e2009-09-05 21:47:34 +0000895 assert(magick != (char *) NULL);
cristy3ed852e2009-09-05 21:47:34 +0000896#if defined(macintosh)
897 return(MACIsMagickConflict(magick));
898#elif defined(vms)
899 return(VMSIsMagickConflict(magick));
cristy0157aea2010-04-24 21:12:18 +0000900#elif defined(MAGICKCORE_WINDOWS_SUPPORT)
cristy3ed852e2009-09-05 21:47:34 +0000901 return(NTIsMagickConflict(magick));
902#else
903 return(MagickFalse);
904#endif
905}
906
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*/
931MagickExport 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
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*/
1034MagickExport MagickBooleanType IsMagickInstantiated(void)
1035{
1036 return(instantiate_magick);
1037}
1038
1039/*
1040%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1041% %
1042% %
1043% %
cristyf34a1452009-10-24 22:29:27 +00001044+ 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*/
1057MagickExport MagickBooleanType MagickComponentGenesis(void)
1058{
cristy165b6092009-10-26 13:52:10 +00001059 AcquireSemaphoreInfo(&magick_semaphore);
cristyf34a1452009-10-24 22:29:27 +00001060 return(MagickTrue);
1061}
1062
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*/
1081MagickExport void MagickComponentTerminus(void)
1082{
cristy18b17442009-10-25 18:36:48 +00001083 if (magick_semaphore == (SemaphoreInfo *) NULL)
1084 AcquireSemaphoreInfo(&magick_semaphore);
cristyf84a1932010-01-03 18:00:18 +00001085 LockSemaphoreInfo(magick_semaphore);
cristyf34a1452009-10-24 22:29:27 +00001086 if (magick_list != (SplayTreeInfo *) NULL)
1087 magick_list=DestroySplayTree(magick_list);
1088 instantiate_magick=MagickFalse;
cristyf84a1932010-01-03 18:00:18 +00001089 UnlockSemaphoreInfo(magick_semaphore);
cristyf34a1452009-10-24 22:29:27 +00001090 DestroySemaphoreInfo(&magick_semaphore);
1091}
1092
1093/*
1094%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1095% %
1096% %
1097% %
cristy3ed852e2009-09-05 21:47:34 +00001098% 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
1120static 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
1153static void MagickSignalHandler(int signal_number)
1154{
1155#if !defined(MAGICKCORE_HAVE_SIGACTION)
1156 (void) signal(signal_number,SIG_IGN);
1157#endif
cristyf34a1452009-10-24 22:29:27 +00001158 AsynchronousResourceComponentTerminus();
cristy3ed852e2009-09-05 21:47:34 +00001159 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
cristy0157aea2010-04-24 21:12:18 +00001172#if defined(SIGINT) && !defined(MAGICKCORE_WINDOWS_SUPPORT)
cristy3ed852e2009-09-05 21:47:34 +00001173 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
1184static 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
1200MagickExport void MagickCoreGenesis(const char *path,
1201 const MagickBooleanType establish_signal_handlers)
1202{
1203 char
1204 *events,
1205 execution_path[MaxTextExtent],
1206 filename[MaxTextExtent];
1207
cristy3ed852e2009-09-05 21:47:34 +00001208 /*
1209 Initialize the Magick environment.
1210 */
cristyf34a1452009-10-24 22:29:27 +00001211 (void) SemaphoreComponentGenesis();
1212 (void) LogComponentGenesis();
1213 (void) LocaleComponentGenesis();
1214 (void) RandomComponentGenesis();
cristy3ed852e2009-09-05 21:47:34 +00001215 events=GetEnvironmentValue("MAGICK_DEBUG");
1216 if (events != (char *) NULL)
1217 {
1218 (void) SetLogEventMask(events);
1219 events=DestroyString(events);
1220 }
cristy0157aea2010-04-24 21:12:18 +00001221#if defined(MAGICKCORE_WINDOWS_SUPPORT)
cristy3ed852e2009-09-05 21:47:34 +00001222#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
cristy0157aea2010-04-24 21:12:18 +00001266#if defined(SIGINT) && !defined(MAGICKCORE_WINDOWS_SUPPORT)
cristy3ed852e2009-09-05 21:47:34 +00001267 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 /*
cristyaf8b5cd2009-10-24 00:29:23 +00001288 Instantiate magick resources.
cristy3ed852e2009-09-05 21:47:34 +00001289 */
cristy18b17442009-10-25 18:36:48 +00001290 (void) ConfigureComponentGenesis();
cristyf34a1452009-10-24 22:29:27 +00001291 (void) PolicyComponentGenesis();
1292 (void) CacheComponentGenesis();
1293 (void) RegistryComponentGenesis();
1294 (void) ResourceComponentGenesis();
1295 (void) CoderComponentGenesis();
1296 (void) MagickComponentGenesis();
cristyaf8b5cd2009-10-24 00:29:23 +00001297#if defined(MAGICKCORE_MODULES_SUPPORT)
cristyf34a1452009-10-24 22:29:27 +00001298 (void) ModuleComponentGenesis();
cristyaf8b5cd2009-10-24 00:29:23 +00001299#endif
cristyf34a1452009-10-24 22:29:27 +00001300 (void) DelegateComponentGenesis();
1301 (void) MagicComponentGenesis();
1302 (void) ColorComponentGenesis();
1303 (void) TypeComponentGenesis();
cristyf34a1452009-10-24 22:29:27 +00001304 (void) MimeComponentGenesis();
1305 (void) ConstituteComponentGenesis();
cristy0157aea2010-04-24 21:12:18 +00001306#if defined(MAGICKCORE_X11_DELEGATE)
cristyf34a1452009-10-24 22:29:27 +00001307 (void) XComponentGenesis();
cristy0157aea2010-04-24 21:12:18 +00001308#endif
cristy3ed852e2009-09-05 21:47:34 +00001309}
1310
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%
cristyf34a1452009-10-24 22:29:27 +00001324% The format of the MagickCoreTerminus function is:
cristy3ed852e2009-09-05 21:47:34 +00001325%
1326% MagickCoreTerminus(void)
1327%
1328*/
1329MagickExport void MagickCoreTerminus(void)
1330{
1331#if defined(MAGICKCORE_X11_DELEGATE)
cristyf34a1452009-10-24 22:29:27 +00001332 XComponentTerminus();
cristy3ed852e2009-09-05 21:47:34 +00001333#endif
cristyf34a1452009-10-24 22:29:27 +00001334 ConstituteComponentTerminus();
1335 MimeComponentTerminus();
cristyf34a1452009-10-24 22:29:27 +00001336 TypeComponentTerminus();
1337 ColorComponentTerminus();
cristy0157aea2010-04-24 21:12:18 +00001338#if defined(MAGICKCORE_WINDOWS_SUPPORT)
cristy3ed852e2009-09-05 21:47:34 +00001339 NTGhostscriptUnLoadDLL();
1340#endif
cristyf34a1452009-10-24 22:29:27 +00001341 MagicComponentTerminus();
1342 DelegateComponentTerminus();
1343 MagickComponentTerminus();
cristyaf8b5cd2009-10-24 00:29:23 +00001344#if !defined(MAGICKCORE_BUILD_MODULES)
1345 UnregisterStaticModules();
1346#endif
1347#if defined(MAGICKCORE_MODULES_SUPPORT)
cristyf34a1452009-10-24 22:29:27 +00001348 ModuleComponentTerminus();
cristyaf8b5cd2009-10-24 00:29:23 +00001349#endif
cristyf34a1452009-10-24 22:29:27 +00001350 CoderComponentTerminus();
1351 ResourceComponentTerminus();
1352 RegistryComponentTerminus();
1353 CacheComponentTerminus();
1354 PolicyComponentTerminus();
cristy18b17442009-10-25 18:36:48 +00001355 ConfigureComponentTerminus();
cristyf34a1452009-10-24 22:29:27 +00001356 RandomComponentTerminus();
1357 LocaleComponentTerminus();
1358 LogComponentTerminus();
1359 SemaphoreComponentTerminus();
cristy3ed852e2009-09-05 21:47:34 +00001360 instantiate_magick=MagickFalse;
1361}
1362
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*/
1389MagickExport 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
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*/
1435MagickExport 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);
cristy90823212009-12-12 20:48:33 +00001442 magick_info=(MagickInfo *) AcquireAlignedMemory(1,sizeof(*magick_info));
cristy3ed852e2009-09-05 21:47:34 +00001443 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
1455/*
1456%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1457% %
1458% %
1459% %
cristye7f51092010-01-17 00:39:37 +00001460% 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
cristybf2766a2010-01-17 03:33:23 +00001467% printed and returns it.
cristye7f51092010-01-17 00:39:37 +00001468%
1469% The format of the SetMagickPrecision method is:
1470%
cristybf2766a2010-01-17 03:33:23 +00001471% int SetMagickPrecision(const int precision)
cristye7f51092010-01-17 00:39:37 +00001472%
1473% A description of each parameter follows:
1474%
1475% o precision: set the maximum number of significant digits to be printed.
1476%
1477*/
cristybf2766a2010-01-17 03:33:23 +00001478MagickExport int SetMagickPrecision(const int precision)
cristye7f51092010-01-17 00:39:37 +00001479{
cristybf2766a2010-01-17 03:33:23 +00001480 static int
1481 magick_precision = 0;
1482
cristye7f51092010-01-17 00:39:37 +00001483 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
cristybf2766a2010-01-17 03:33:23 +00001484 if (precision != 0)
1485 magick_precision=precision;
1486 return(magick_precision);
cristye7f51092010-01-17 00:39:37 +00001487}
1488
1489/*
1490%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1491% %
1492% %
1493% %
cristy3ed852e2009-09-05 21:47:34 +00001494+ 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*/
1513MagickExport 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);
cristyf84a1932010-01-03 18:00:18 +00001526 LockSemaphoreInfo(magick_semaphore);
cristy3ed852e2009-09-05 21:47:34 +00001527 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);
cristyf84a1932010-01-03 18:00:18 +00001536 UnlockSemaphoreInfo(magick_semaphore);
cristy3ed852e2009-09-05 21:47:34 +00001537 return(status);
1538}