blob: d0a7fac191ef55ed8652d9b8f281e87baacfdea7 [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% %
cristy7e41fe82010-12-04 23:12:08 +000021% Copyright 1999-2011 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"
cristyd7ecaca2011-01-24 14:14:53 +000044#include "magick/annotate.h"
cristy3ed852e2009-09-05 21:47:34 +000045#include "magick/blob.h"
cristyecfd7242011-02-18 20:23:57 +000046#include "magick/blob-private.h"
cristy3ed852e2009-09-05 21:47:34 +000047#include "magick/cache.h"
48#include "magick/coder.h"
49#include "magick/client.h"
50#include "magick/coder.h"
51#include "magick/configure.h"
52#include "magick/constitute.h"
53#include "magick/delegate.h"
54#include "magick/draw.h"
55#include "magick/exception.h"
56#include "magick/exception-private.h"
57#include "magick/locale_.h"
58#include "magick/log.h"
59#include "magick/magic.h"
60#include "magick/magick.h"
61#include "magick/memory_.h"
62#include "magick/mime.h"
63#include "magick/module.h"
cristy0157aea2010-04-24 21:12:18 +000064#if defined(MAGICKCORE_WINDOWS_SUPPORT)
cristy3ed852e2009-09-05 21:47:34 +000065# include "magick/nt-feature.h"
66#endif
67#include "magick/random_.h"
68#include "magick/registry.h"
69#include "magick/resource_.h"
70#include "magick/policy.h"
71#include "magick/semaphore.h"
cristyd1ebf4a2010-05-13 01:54:31 +000072#include "magick/semaphore-private.h"
cristy3ed852e2009-09-05 21:47:34 +000073#include "magick/signature-private.h"
74#include "magick/splay-tree.h"
75#include "magick/string_.h"
cristy7ce14bc2010-01-17 00:01:01 +000076#include "magick/string-private.h"
cristy3ed852e2009-09-05 21:47:34 +000077#include "magick/thread_.h"
78#include "magick/thread-private.h"
79#include "magick/token.h"
80#include "magick/utility.h"
81#include "magick/xwindow-private.h"
82
83/*
84 Define declarations.
85*/
86#if !defined(MAGICKCORE_RETSIGTYPE)
87# define MAGICKCORE_RETSIGTYPE void
88#endif
89#if !defined(SIG_DFL)
90# define SIG_DFL ((SignalHandler *) 0)
91#endif
92#if !defined(SIG_ERR)
93# define SIG_ERR ((SignalHandler *) -1)
94#endif
95#if !defined(SIGMAX)
96#define SIGMAX 64
97#endif
98
99/*
100 Typedef declarations.
101*/
102typedef MAGICKCORE_RETSIGTYPE
103 SignalHandler(int);
104
105/*
106 Global declarations.
107*/
108static SemaphoreInfo
109 *magick_semaphore = (SemaphoreInfo *) NULL;
110
111static SignalHandler
112 *signal_handlers[SIGMAX] = { (SignalHandler *) NULL };
113
114static SplayTreeInfo
115 *magick_list = (SplayTreeInfo *) NULL;
116
117static volatile MagickBooleanType
cristyd1ebf4a2010-05-13 01:54:31 +0000118 instantiate_magick = MagickFalse,
119 instantiate_magickcore = MagickFalse;
cristy3ed852e2009-09-05 21:47:34 +0000120
121/*
122 Forward declarations.
123*/
124static MagickBooleanType
125 InitializeMagickList(ExceptionInfo *);
126
127/*
128%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
129% %
130% %
131% %
cristy3ed852e2009-09-05 21:47:34 +0000132+ G e t I m a g e D e c o d e r %
133% %
134% %
135% %
136%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
137%
138% GetImageDecoder() returns the image decoder.
139%
140% The format of the GetImageDecoder method is:
141%
142% DecodeImageHandler *GetImageDecoder(const MagickInfo *magick_info)
143%
144% A description of each parameter follows:
145%
146% o magick_info: The magick info.
147%
148*/
149MagickExport DecodeImageHandler *GetImageDecoder(const MagickInfo *magick_info)
150{
151 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
152 assert(magick_info != (MagickInfo *) NULL);
153 assert(magick_info->signature == MagickSignature);
154 return(magick_info->decoder);
155}
156
157/*
158%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
159% %
160% %
161% %
162+ G e t I m a g e E n c o d e r %
163% %
164% %
165% %
166%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
167%
168% GetImageEncoder() returns the image encoder.
169%
170% The format of the GetImageEncoder method is:
171%
172% EncodeImageHandler *GetImageEncoder(const MagickInfo *magick_info)
173%
174% A description of each parameter follows:
175%
176% o magick_info: The magick info.
177%
178*/
179MagickExport EncodeImageHandler *GetImageEncoder(const MagickInfo *magick_info)
180{
181 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
182 assert(magick_info != (MagickInfo *) NULL);
183 assert(magick_info->signature == MagickSignature);
184 return(magick_info->encoder);
185}
186
187/*
188%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
189% %
190% %
191% %
192+ G e t I m a g e M a g i c k %
193% %
194% %
195% %
196%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
197%
198% GetImageMagick() searches for an image format that matches the specified
199% magick string. If one is found, MagickTrue is returned otherwise
200% MagickFalse.
201%
202% The format of the GetImageMagick method is:
203%
204% MagickBooleanType GetImageMagick(const unsigned char *magick,
205% const size_t length,char *format)
206%
207% A description of each parameter follows:
208%
209% o magick: the image format we are searching for.
210%
211% o length: the length of the binary string.
212%
213% o format: the image format as determined by the magick bytes.
214%
215*/
216MagickExport MagickBooleanType GetImageMagick(const unsigned char *magick,
217 const size_t length,char *format)
218{
219 ExceptionInfo
220 *exception;
221
222 MagickBooleanType
223 status;
224
225 register const MagickInfo
226 *p;
227
228 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
229 assert(magick != (const unsigned char *) NULL);
230 exception=AcquireExceptionInfo();
231 p=GetMagickInfo("*",exception);
232 exception=DestroyExceptionInfo(exception);
233 if (p == (const MagickInfo *) NULL)
234 return(MagickFalse);
235 status=MagickFalse;
cristyf84a1932010-01-03 18:00:18 +0000236 LockSemaphoreInfo(magick_semaphore);
cristy3ed852e2009-09-05 21:47:34 +0000237 ResetSplayTreeIterator(magick_list);
238 p=(const MagickInfo *) GetNextValueInSplayTree(magick_list);
239 while (p != (const MagickInfo *) NULL)
240 {
241 if ((p->magick != (IsImageFormatHandler *) NULL) &&
242 (p->magick(magick,length) != 0))
243 {
244 status=MagickTrue;
245 (void) CopyMagickString(format,p->name,MaxTextExtent);
246 break;
247 }
248 p=(const MagickInfo *) GetNextValueInSplayTree(magick_list);
249 }
cristyf84a1932010-01-03 18:00:18 +0000250 UnlockSemaphoreInfo(magick_semaphore);
cristy3ed852e2009-09-05 21:47:34 +0000251 return(status);
252}
253
254/*
255%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
256% %
257% %
258% %
259+ G e t M a g i c k A d j o i n %
260% %
261% %
262% %
263%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
264%
265% GetMagickAdjoin() returns MagickTrue if the magick adjoin is MagickTrue.
266%
267% The format of the GetMagickAdjoin method is:
268%
269% MagickBooleanType GetMagickAdjoin(const MagickInfo *magick_info)
270%
271% A description of each parameter follows:
272%
273% o magick_info: The magick info.
274%
275*/
276MagickExport MagickBooleanType GetMagickAdjoin(const MagickInfo *magick_info)
277{
278 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
279 assert(magick_info != (MagickInfo *) NULL);
280 assert(magick_info->signature == MagickSignature);
281 return(magick_info->adjoin);
282}
283
284/*
285%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
286% %
287% %
288% %
289+ G e t M a g i c k B l o b S u p p o r t %
290% %
291% %
292% %
293%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
294%
295% GetMagickBlobSupport() returns MagickTrue if the magick supports blobs.
296%
297% The format of the GetMagickBlobSupport method is:
298%
299% MagickBooleanType GetMagickBlobSupport(const MagickInfo *magick_info)
300%
301% A description of each parameter follows:
302%
303% o magick_info: The magick info.
304%
305*/
306MagickExport MagickBooleanType GetMagickBlobSupport(
307 const MagickInfo *magick_info)
308{
309 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
310 assert(magick_info != (MagickInfo *) NULL);
311 assert(magick_info->signature == MagickSignature);
312 return(magick_info->blob_support);
313}
314
315/*
316%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
317% %
318% %
319% %
320+ G e t M a g i c k D e s c r i p t i o n %
321% %
322% %
323% %
324%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
325%
326% GetMagickDescription() returns the magick description.
327%
328% The format of the GetMagickDescription method is:
329%
330% const char *GetMagickDescription(const MagickInfo *magick_info)
331%
332% A description of each parameter follows:
333%
334% o magick_info: The magick info.
335%
336*/
337MagickExport const char *GetMagickDescription(const MagickInfo *magick_info)
338{
339 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
340 assert(magick_info != (MagickInfo *) NULL);
341 assert(magick_info->signature == MagickSignature);
342 return(magick_info->description);
343}
344
345/*
346%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
347% %
348% %
349% %
350+ G e t M a g i c k E n d i a n S u p p o r t %
351% %
352% %
353% %
354%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
355%
356% GetMagickEndianSupport() returns the MagickTrue if the coder respects
357% endianness other than MSBEndian.
358%
359% The format of the GetMagickEndianSupport method is:
360%
361% MagickBooleanType GetMagickEndianSupport(const MagickInfo *magick_info)
362%
363% A description of each parameter follows:
364%
365% o magick_info: The magick info.
366%
367*/
368MagickExport MagickBooleanType GetMagickEndianSupport(
369 const MagickInfo *magick_info)
370{
371 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
372 assert(magick_info != (MagickInfo *) NULL);
373 assert(magick_info->signature == MagickSignature);
374 return(magick_info->endian_support);
375}
376
377/*
378%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
379% %
380% %
381% %
382+ G e t M a g i c k I n f o %
383% %
384% %
385% %
386%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
387%
388% GetMagickInfo() returns a pointer MagickInfo structure that matches
389% the specified name. If name is NULL, the head of the image format list
390% is returned.
391%
392% The format of the GetMagickInfo method is:
393%
394% const MagickInfo *GetMagickInfo(const char *name,Exception *exception)
395%
396% A description of each parameter follows:
397%
398% o name: the image format we are looking for.
399%
400% o exception: return any errors or warnings in this structure.
401%
402*/
403MagickExport const MagickInfo *GetMagickInfo(const char *name,
404 ExceptionInfo *exception)
405{
406 register const MagickInfo
407 *p;
408
409 assert(exception != (ExceptionInfo *) NULL);
410 if ((magick_list == (SplayTreeInfo *) NULL) ||
411 (instantiate_magick == MagickFalse))
412 if (InitializeMagickList(exception) == MagickFalse)
413 return((const MagickInfo *) NULL);
414 if ((name == (const char *) NULL) || (LocaleCompare(name,"*") == 0))
415 {
416#if defined(MAGICKCORE_MODULES_SUPPORT)
417 if (LocaleCompare(name,"*") == 0)
418 (void) OpenModules(exception);
419#endif
cristyf84a1932010-01-03 18:00:18 +0000420 LockSemaphoreInfo(magick_semaphore);
cristy3ed852e2009-09-05 21:47:34 +0000421 ResetSplayTreeIterator(magick_list);
422 p=(const MagickInfo *) GetNextValueInSplayTree(magick_list);
cristyf84a1932010-01-03 18:00:18 +0000423 UnlockSemaphoreInfo(magick_semaphore);
cristy3ed852e2009-09-05 21:47:34 +0000424 return(p);
425 }
426 /*
427 Find name in list.
428 */
cristyf84a1932010-01-03 18:00:18 +0000429 LockSemaphoreInfo(magick_semaphore);
cristy3ed852e2009-09-05 21:47:34 +0000430 ResetSplayTreeIterator(magick_list);
431 p=(const MagickInfo *) GetNextValueInSplayTree(magick_list);
432 while (p != (const MagickInfo *) NULL)
433 {
434 if (LocaleCompare(p->name,name) == 0)
435 break;
436 p=(const MagickInfo *) GetNextValueInSplayTree(magick_list);
437 }
438#if defined(MAGICKCORE_MODULES_SUPPORT)
439 if (p == (const MagickInfo *) NULL)
440 {
441 if (*name != '\0')
442 (void) OpenModule(name,exception);
443 ResetSplayTreeIterator(magick_list);
444 p=(const MagickInfo *) GetNextValueInSplayTree(magick_list);
445 while (p != (const MagickInfo *) NULL)
446 {
447 if (LocaleCompare(p->name,name) == 0)
448 break;
449 p=(const MagickInfo *) GetNextValueInSplayTree(magick_list);
450 }
451 }
452#endif
cristyf84a1932010-01-03 18:00:18 +0000453 UnlockSemaphoreInfo(magick_semaphore);
cristy3ed852e2009-09-05 21:47:34 +0000454 return(p);
455}
456
457/*
458%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
459% %
460% %
461% %
462+ G e t M a g i c k I n f o L i s t %
463% %
464% %
465% %
466%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
467%
468% GetMagickInfoList() returns any image formats that match the specified
469% pattern.
470%
471% The format of the GetMagickInfoList function is:
472%
473% const MagickInfo **GetMagickInfoList(const char *pattern,
cristybb503372010-05-27 20:51:26 +0000474% size_t *number_formats,ExceptionInfo *exception)
cristy3ed852e2009-09-05 21:47:34 +0000475%
476% A description of each parameter follows:
477%
478% o pattern: Specifies a pointer to a text string containing a pattern.
479%
480% o number_formats: This integer returns the number of formats in the list.
481%
482% o exception: return any errors or warnings in this structure.
483%
484*/
485
486#if defined(__cplusplus) || defined(c_plusplus)
487extern "C" {
488#endif
489
490static int MagickInfoCompare(const void *x,const void *y)
491{
492 const MagickInfo
493 **p,
494 **q;
495
496 p=(const MagickInfo **) x,
497 q=(const MagickInfo **) y;
498 return(LocaleCompare((*p)->name,(*q)->name));
499}
500
501#if defined(__cplusplus) || defined(c_plusplus)
502}
503#endif
504
505MagickExport const MagickInfo **GetMagickInfoList(const char *pattern,
cristybb503372010-05-27 20:51:26 +0000506 size_t *number_formats,ExceptionInfo *exception)
cristy3ed852e2009-09-05 21:47:34 +0000507{
508 const MagickInfo
509 **formats;
510
511 register const MagickInfo
512 *p;
513
cristybb503372010-05-27 20:51:26 +0000514 register ssize_t
cristy3ed852e2009-09-05 21:47:34 +0000515 i;
516
517 /*
518 Allocate magick list.
519 */
520 assert(pattern != (char *) NULL);
521 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",pattern);
cristybb503372010-05-27 20:51:26 +0000522 assert(number_formats != (size_t *) NULL);
cristy3ed852e2009-09-05 21:47:34 +0000523 *number_formats=0;
524 p=GetMagickInfo("*",exception);
525 if (p == (const MagickInfo *) NULL)
526 return((const MagickInfo **) NULL);
527 formats=(const MagickInfo **) AcquireQuantumMemory((size_t)
528 GetNumberOfNodesInSplayTree(magick_list)+1UL,sizeof(*formats));
529 if (formats == (const MagickInfo **) NULL)
530 return((const MagickInfo **) NULL);
531 /*
532 Generate magick list.
533 */
cristyf84a1932010-01-03 18:00:18 +0000534 LockSemaphoreInfo(magick_semaphore);
cristy3ed852e2009-09-05 21:47:34 +0000535 ResetSplayTreeIterator(magick_list);
536 p=(const MagickInfo *) GetNextValueInSplayTree(magick_list);
537 for (i=0; p != (const MagickInfo *) NULL; )
538 {
539 if ((p->stealth == MagickFalse) &&
540 (GlobExpression(p->name,pattern,MagickFalse) != MagickFalse))
541 formats[i++]=p;
542 p=(const MagickInfo *) GetNextValueInSplayTree(magick_list);
543 }
cristyf84a1932010-01-03 18:00:18 +0000544 UnlockSemaphoreInfo(magick_semaphore);
cristy3ed852e2009-09-05 21:47:34 +0000545 qsort((void *) formats,(size_t) i,sizeof(*formats),MagickInfoCompare);
546 formats[i]=(MagickInfo *) NULL;
cristybb503372010-05-27 20:51:26 +0000547 *number_formats=(size_t) i;
cristy3ed852e2009-09-05 21:47:34 +0000548 return(formats);
549}
550
551/*
552%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
553% %
554% %
555% %
556+ G e t M a g i c k L i s t %
557% %
558% %
559% %
560%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
561%
562% GetMagickList() returns any image formats that match the specified pattern.
563%
564% The format of the GetMagickList function is:
565%
cristybb503372010-05-27 20:51:26 +0000566% char **GetMagickList(const char *pattern,size_t *number_formats,
cristy3ed852e2009-09-05 21:47:34 +0000567% ExceptionInfo *exception)
568%
569% A description of each parameter follows:
570%
571% o pattern: Specifies a pointer to a text string containing a pattern.
572%
573% o number_formats: This integer returns the number of formats in the list.
574%
575% o exception: return any errors or warnings in this structure.
576%
577*/
578
579#if defined(__cplusplus) || defined(c_plusplus)
580extern "C" {
581#endif
582
583static int MagickCompare(const void *x,const void *y)
584{
585 register const char
586 **p,
587 **q;
588
589 p=(const char **) x;
590 q=(const char **) y;
591 return(LocaleCompare(*p,*q));
592}
593
594#if defined(__cplusplus) || defined(c_plusplus)
595}
596#endif
597
598MagickExport char **GetMagickList(const char *pattern,
cristybb503372010-05-27 20:51:26 +0000599 size_t *number_formats,ExceptionInfo *exception)
cristy3ed852e2009-09-05 21:47:34 +0000600{
601 char
602 **formats;
603
604 register const MagickInfo
605 *p;
606
cristybb503372010-05-27 20:51:26 +0000607 register ssize_t
cristy3ed852e2009-09-05 21:47:34 +0000608 i;
609
610 /*
611 Allocate magick list.
612 */
613 assert(pattern != (char *) NULL);
614 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",pattern);
cristybb503372010-05-27 20:51:26 +0000615 assert(number_formats != (size_t *) NULL);
cristy3ed852e2009-09-05 21:47:34 +0000616 *number_formats=0;
617 p=GetMagickInfo("*",exception);
618 if (p == (const MagickInfo *) NULL)
619 return((char **) NULL);
620 formats=(char **) AcquireQuantumMemory((size_t)
621 GetNumberOfNodesInSplayTree(magick_list)+1UL,sizeof(*formats));
622 if (formats == (char **) NULL)
623 return((char **) NULL);
cristyf84a1932010-01-03 18:00:18 +0000624 LockSemaphoreInfo(magick_semaphore);
cristy3ed852e2009-09-05 21:47:34 +0000625 ResetSplayTreeIterator(magick_list);
626 p=(const MagickInfo *) GetNextValueInSplayTree(magick_list);
627 for (i=0; p != (const MagickInfo *) NULL; )
628 {
629 if ((p->stealth == MagickFalse) &&
630 (GlobExpression(p->name,pattern,MagickFalse) != MagickFalse))
631 formats[i++]=ConstantString(p->name);
632 p=(const MagickInfo *) GetNextValueInSplayTree(magick_list);
633 }
cristyf84a1932010-01-03 18:00:18 +0000634 UnlockSemaphoreInfo(magick_semaphore);
cristy3ed852e2009-09-05 21:47:34 +0000635 qsort((void *) formats,(size_t) i,sizeof(*formats),MagickCompare);
636 formats[i]=(char *) NULL;
cristybb503372010-05-27 20:51:26 +0000637 *number_formats=(size_t) i;
cristy3ed852e2009-09-05 21:47:34 +0000638 return(formats);
639}
640
641/*
642%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
643% %
644% %
645% %
cristye7f51092010-01-17 00:39:37 +0000646% G e t M a g i c k P r e c i s i o n %
cristy7ce14bc2010-01-17 00:01:01 +0000647% %
648% %
649% %
650%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
651%
652% GetMagickPrecision() returns the maximum number of significant digits to be
653% printed.
654%
655% The format of the GetMagickPrecision method is:
656%
cristye7f51092010-01-17 00:39:37 +0000657% int GetMagickPrecision(void)
cristy7ce14bc2010-01-17 00:01:01 +0000658%
659*/
cristye7f51092010-01-17 00:39:37 +0000660MagickExport int GetMagickPrecision(void)
cristy7ce14bc2010-01-17 00:01:01 +0000661{
cristye7f51092010-01-17 00:39:37 +0000662#define MagickPrecision 6
cristy7ce14bc2010-01-17 00:01:01 +0000663
664 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
cristybf2766a2010-01-17 03:33:23 +0000665 if (SetMagickPrecision(0) == 0)
cristy7ce14bc2010-01-17 00:01:01 +0000666 {
667 char
668 *limit;
669
cristybf2766a2010-01-17 03:33:23 +0000670 (void) SetMagickPrecision(MagickPrecision);
cristye7f51092010-01-17 00:39:37 +0000671 limit=GetEnvironmentValue("MAGICK_PRECISION");
672 if (limit == (char *) NULL)
673 limit=GetPolicyValue("precision");
674 if (limit != (char *) NULL)
675 {
cristybf2766a2010-01-17 03:33:23 +0000676 (void) SetMagickPrecision(StringToInteger(limit));
cristye7f51092010-01-17 00:39:37 +0000677 limit=DestroyString(limit);
678 }
cristy7ce14bc2010-01-17 00:01:01 +0000679 }
cristybf2766a2010-01-17 03:33:23 +0000680 return(SetMagickPrecision(0));
cristy7ce14bc2010-01-17 00:01:01 +0000681}
682
683/*
684%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
685% %
686% %
687% %
688+ 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 +0000689% %
690% %
691% %
692%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
693%
694% GetMagickRawSupport() returns the MagickTrue if the coder is a raw format.
695%
696% The format of the GetMagickRawSupport method is:
697%
698% MagickBooleanType GetMagickRawSupport(const MagickInfo *magick_info)
699%
700% A description of each parameter follows:
701%
702% o magick_info: The magick info.
703%
704*/
705MagickExport MagickBooleanType GetMagickRawSupport(
706 const MagickInfo *magick_info)
707{
708 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
709 assert(magick_info != (MagickInfo *) NULL);
710 assert(magick_info->signature == MagickSignature);
711 return(magick_info->raw);
712}
713
714/*
715%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
716% %
717% %
718% %
719+ G e t M a g i c k S e e k a b l e S t r e a m %
720% %
721% %
722% %
723%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
724%
725% GetMagickSeekableStream() returns MagickTrue if the magick supports a
726% seekable stream.
727%
728% The format of the GetMagickSeekableStream method is:
729%
730% MagickBooleanType GetMagickSeekableStream(const MagickInfo *magick_info)
731%
732% A description of each parameter follows:
733%
734% o magick_info: The magick info.
735%
736*/
737MagickExport MagickBooleanType GetMagickSeekableStream(
738 const MagickInfo *magick_info)
739{
740 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
741 assert(magick_info != (MagickInfo *) NULL);
742 assert(magick_info->signature == MagickSignature);
743 return(magick_info->seekable_stream);
744}
745
746/*
747%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
748% %
749% %
750% %
751+ G e t M a g i c k T h r e a d S u p p o r t %
752% %
753% %
754% %
755%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
756%
757% GetMagickThreadSupport() returns MagickTrue if the magick supports threads.
758%
759% The format of the GetMagickThreadSupport method is:
760%
761% MagickStatusType GetMagickThreadSupport(const MagickInfo *magick_info)
762%
763% A description of each parameter follows:
764%
765% o magick_info: The magick info.
766%
767*/
768MagickExport MagickStatusType GetMagickThreadSupport(
769 const MagickInfo *magick_info)
770{
771 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
772 assert(magick_info != (MagickInfo *) NULL);
773 assert(magick_info->signature == MagickSignature);
774 return(magick_info->thread_support);
775}
776
777/*
778%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
779% %
780% %
781% %
782+ I n i t i a l i z e M a g i c k L i s t %
783% %
784% %
785% %
786%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
787%
788% InitializeMagickList() initializes the magick list.
789%
790% The format of the InitializeMagickList() method is:
791%
792% InitializeMagickList(Exceptioninfo *exception)
793%
794% A description of each parameter follows.
795%
796% o exception: return any errors or warnings in this structure.
797%
798*/
799
800static void *DestroyMagickNode(void *magick_info)
801{
802 register MagickInfo
803 *p;
804
805 p=(MagickInfo *) magick_info;
806 if (p->name != (char *) NULL)
807 p->name=DestroyString(p->name);
808 if (p->description != (char *) NULL)
809 p->description=DestroyString(p->description);
810 if (p->version != (char *) NULL)
811 p->version=DestroyString(p->version);
812 if (p->note != (char *) NULL)
813 p->note=DestroyString(p->note);
814 if (p->module != (char *) NULL)
815 p->module=DestroyString(p->module);
816 return(RelinquishMagickMemory(p));
817}
818
819static MagickBooleanType InitializeMagickList(ExceptionInfo *exception)
820{
cristyf2e11662009-10-14 01:24:43 +0000821 (void) exception;
cristy3ed852e2009-09-05 21:47:34 +0000822 if ((magick_list == (SplayTreeInfo *) NULL) &&
823 (instantiate_magick == MagickFalse))
824 {
cristy4e1dff62009-10-25 20:36:03 +0000825 if (magick_semaphore == (SemaphoreInfo *) NULL)
826 AcquireSemaphoreInfo(&magick_semaphore);
cristyf84a1932010-01-03 18:00:18 +0000827 LockSemaphoreInfo(magick_semaphore);
cristy3ed852e2009-09-05 21:47:34 +0000828 if ((magick_list == (SplayTreeInfo *) NULL) &&
829 (instantiate_magick == MagickFalse))
830 {
831 MagickBooleanType
832 status;
833
834 MagickInfo
835 *magick_info;
836
837 magick_list=NewSplayTree(CompareSplayTreeString,
838 (void *(*)(void *)) NULL,DestroyMagickNode);
839 if (magick_list == (SplayTreeInfo *) NULL)
840 ThrowFatalException(ResourceLimitFatalError,
841 "MemoryAllocationFailed");
842 magick_info=SetMagickInfo("ephemeral");
843 magick_info->stealth=MagickTrue;
844 status=AddValueToSplayTree(magick_list,magick_info->name,magick_info);
845 if (status == MagickFalse)
846 ThrowFatalException(ResourceLimitFatalError,
847 "MemoryAllocationFailed");
848 magick_info=SetMagickInfo("clipmask");
849 magick_info->stealth=MagickTrue;
850 status=AddValueToSplayTree(magick_list,magick_info->name,magick_info);
851 if (status == MagickFalse)
852 {
853 char
854 *message;
855
856 message=GetExceptionMessage(errno);
857 ThrowFatalException(ResourceLimitFatalError,
858 "MemoryAllocationFailed");
859 message=DestroyString(message);
860 }
861#if defined(MAGICKCORE_MODULES_SUPPORT)
862 (void) GetModuleInfo((char *) NULL,exception);
863#endif
864#if !defined(MAGICKCORE_BUILD_MODULES)
865 RegisterStaticModules();
866#endif
867 instantiate_magick=MagickTrue;
868 }
cristyf84a1932010-01-03 18:00:18 +0000869 UnlockSemaphoreInfo(magick_semaphore);
cristy3ed852e2009-09-05 21:47:34 +0000870 }
871 return(magick_list != (SplayTreeInfo *) NULL ? MagickTrue : MagickFalse);
872}
873
874/*
875%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
876% %
877% %
878% %
879+ I s M a g i c k C o n f l i c t %
880% %
881% %
882% %
883%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
884%
cristy05a9a622010-03-15 17:26:04 +0000885% IsMagickConflict() returns MagickTrue if the image format conflicts with a
886% logical drive (.e.g. X:).
cristy3ed852e2009-09-05 21:47:34 +0000887%
888% The format of the IsMagickConflict method is:
889%
890% MagickBooleanType IsMagickConflict(const char *magick)
891%
892% A description of each parameter follows:
893%
894% o magick: Specifies the image format.
895%
896*/
897MagickExport MagickBooleanType IsMagickConflict(const char *magick)
898{
cristy3ed852e2009-09-05 21:47:34 +0000899 assert(magick != (char *) NULL);
cristy3ed852e2009-09-05 21:47:34 +0000900#if defined(macintosh)
901 return(MACIsMagickConflict(magick));
902#elif defined(vms)
903 return(VMSIsMagickConflict(magick));
cristy0157aea2010-04-24 21:12:18 +0000904#elif defined(MAGICKCORE_WINDOWS_SUPPORT)
cristy3ed852e2009-09-05 21:47:34 +0000905 return(NTIsMagickConflict(magick));
906#else
907 return(MagickFalse);
908#endif
909}
910
911/*
912%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
913% %
914% %
915% %
916+ L i s t M a g i c k I n f o %
917% %
918% %
919% %
920%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
921%
922% ListMagickInfo() lists the image formats to a file.
923%
924% The format of the ListMagickInfo method is:
925%
926% MagickBooleanType ListMagickInfo(FILE *file,ExceptionInfo *exception)
927%
928% A description of each parameter follows.
929%
930% o file: A file handle.
931%
932% o exception: return any errors or warnings in this structure.
933%
934*/
935MagickExport MagickBooleanType ListMagickInfo(FILE *file,
936 ExceptionInfo *exception)
937{
938 const MagickInfo
939 **magick_info;
940
cristybb503372010-05-27 20:51:26 +0000941 register ssize_t
cristy3ed852e2009-09-05 21:47:34 +0000942 i;
943
cristybb503372010-05-27 20:51:26 +0000944 size_t
cristy3ed852e2009-09-05 21:47:34 +0000945 number_formats;
946
cristy9d314ff2011-03-09 01:30:28 +0000947 ssize_t
948 j;
949
cristy3ed852e2009-09-05 21:47:34 +0000950 if (file == (FILE *) NULL)
951 file=stdout;
952 magick_info=GetMagickInfoList("*",&number_formats,exception);
953 if (magick_info == (const MagickInfo **) NULL)
954 return(MagickFalse);
955 ClearMagickException(exception);
956#if !defined(MAGICKCORE_MODULES_SUPPORT)
957 (void) fprintf(file," Format Mode Description\n");
958#else
959 (void) fprintf(file," Format Module Mode Description\n");
960#endif
961 (void) fprintf(file,"--------------------------------------------------------"
962 "-----------------------\n");
cristybb503372010-05-27 20:51:26 +0000963 for (i=0; i < (ssize_t) number_formats; i++)
cristy3ed852e2009-09-05 21:47:34 +0000964 {
965 if (magick_info[i]->stealth != MagickFalse)
966 continue;
967 (void) fprintf(file,"%9s%c ",magick_info[i]->name != (char *) NULL ?
968 magick_info[i]->name : "",
969 magick_info[i]->blob_support != MagickFalse ? '*' : ' ');
970#if defined(MAGICKCORE_MODULES_SUPPORT)
971 {
972 char
973 module[MaxTextExtent];
974
975 *module='\0';
976 if (magick_info[i]->module != (char *) NULL)
977 (void) CopyMagickString(module,magick_info[i]->module,MaxTextExtent);
978 (void) ConcatenateMagickString(module," ",MaxTextExtent);
979 module[9]='\0';
980 (void) fprintf(file,"%9s ",module);
981 }
982#endif
983 (void) fprintf(file,"%c%c%c ",magick_info[i]->decoder ? 'r' : '-',
984 magick_info[i]->encoder ? 'w' : '-',magick_info[i]->encoder != NULL &&
985 magick_info[i]->adjoin != MagickFalse ? '+' : '-');
986 if (magick_info[i]->description != (char *) NULL)
987 (void) fprintf(file," %s",magick_info[i]->description);
988 if (magick_info[i]->version != (char *) NULL)
989 (void) fprintf(file," (%s)",magick_info[i]->version);
990 (void) fprintf(file,"\n");
991 if (magick_info[i]->note != (char *) NULL)
992 {
993 char
994 **text;
995
996 text=StringToList(magick_info[i]->note);
997 if (text != (char **) NULL)
998 {
999 for (j=0; text[j] != (char *) NULL; j++)
1000 {
1001 (void) fprintf(file," %s\n",text[j]);
1002 text[j]=DestroyString(text[j]);
1003 }
1004 text=(char **) RelinquishMagickMemory(text);
1005 }
1006 }
1007 }
1008 (void) fprintf(file,"\n* native blob support\n");
1009 (void) fprintf(file,"r read support\n");
1010 (void) fprintf(file,"w write support\n");
1011 (void) fprintf(file,"+ support for multiple images\n");
1012 (void) fflush(file);
1013 magick_info=(const MagickInfo **) RelinquishMagickMemory((void *)
1014 magick_info);
1015 return(MagickTrue);
1016}
1017
1018/*
1019%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1020% %
1021% %
1022% %
1023% I s M a g i c k I n s t a n t i a t e d %
1024% %
1025% %
1026% %
1027%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1028%
1029% IsMagickInstantiated() returns MagickTrue if the ImageMagick environment
1030% is currently instantiated: MagickCoreGenesis() has been called but
1031% MagickDestroy() has not.
1032%
1033% The format of the IsMagickInstantiated method is:
1034%
1035% MagickBooleanType IsMagickInstantiated(void)
1036%
1037*/
1038MagickExport MagickBooleanType IsMagickInstantiated(void)
1039{
1040 return(instantiate_magick);
1041}
1042
1043/*
1044%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1045% %
1046% %
1047% %
cristyf34a1452009-10-24 22:29:27 +00001048+ M a g i c k C o m p o n e n t G e n e s i s %
1049% %
1050% %
1051% %
1052%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1053%
1054% MagickComponentGenesis() instantiates the magick component.
1055%
1056% The format of the MagickComponentGenesis method is:
1057%
1058% MagickBooleanType MagickComponentGenesis(void)
1059%
1060*/
1061MagickExport MagickBooleanType MagickComponentGenesis(void)
1062{
cristy165b6092009-10-26 13:52:10 +00001063 AcquireSemaphoreInfo(&magick_semaphore);
cristyf34a1452009-10-24 22:29:27 +00001064 return(MagickTrue);
1065}
1066
1067/*
1068%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1069% %
1070% %
1071% %
1072+ M a g i c k C o m p o n e n t T e r m i n u s %
1073% %
1074% %
1075% %
1076%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1077%
1078% MagickComponentTerminus() destroys the magick component.
1079%
1080% The format of the MagickComponentTerminus method is:
1081%
1082% void MagickComponentTerminus(void)
1083%
1084*/
1085MagickExport void MagickComponentTerminus(void)
1086{
cristy18b17442009-10-25 18:36:48 +00001087 if (magick_semaphore == (SemaphoreInfo *) NULL)
1088 AcquireSemaphoreInfo(&magick_semaphore);
cristyf84a1932010-01-03 18:00:18 +00001089 LockSemaphoreInfo(magick_semaphore);
cristyf34a1452009-10-24 22:29:27 +00001090 if (magick_list != (SplayTreeInfo *) NULL)
1091 magick_list=DestroySplayTree(magick_list);
1092 instantiate_magick=MagickFalse;
cristyf84a1932010-01-03 18:00:18 +00001093 UnlockSemaphoreInfo(magick_semaphore);
cristyf34a1452009-10-24 22:29:27 +00001094 DestroySemaphoreInfo(&magick_semaphore);
1095}
1096
1097/*
1098%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1099% %
1100% %
1101% %
cristy3ed852e2009-09-05 21:47:34 +00001102% M a g i c k C o r e G e n e s i s %
1103% %
1104% %
1105% %
1106%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1107%
1108% MagickCoreGenesis() initializes the MagickCore environment.
1109%
1110% The format of the MagickCoreGenesis function is:
1111%
1112% MagickCoreGenesis(const char *path,
1113% const MagickBooleanType establish_signal_handlers)
1114%
1115% A description of each parameter follows:
1116%
1117% o path: the execution path of the current ImageMagick client.
1118%
1119% o establish_signal_handlers: set to MagickTrue to use MagickCore's own
1120% signal handlers for common signals.
1121%
1122*/
1123
1124static SignalHandler *SetMagickSignalHandler(int signal_number,
1125 SignalHandler *handler)
1126{
1127#if defined(MAGICKCORE_HAVE_SIGACTION) && defined(MAGICKCORE_HAVE_SIGEMPTYSET)
1128 int
1129 status;
1130
1131 sigset_t
1132 mask;
1133
1134 struct sigaction
1135 action,
1136 previous_action;
1137
1138 sigemptyset(&mask);
1139 sigaddset(&mask,signal_number);
1140 sigprocmask(SIG_BLOCK,&mask,NULL);
1141 action.sa_mask=mask;
1142 action.sa_handler=handler;
1143 action.sa_flags=0;
1144#if defined(SA_INTERRUPT)
1145 action.sa_flags|=SA_INTERRUPT;
1146#endif
1147 status=sigaction(signal_number,&action,&previous_action);
1148 if (status < 0)
1149 return(SIG_ERR);
1150 sigprocmask(SIG_UNBLOCK,&mask,NULL);
1151 return(previous_action.sa_handler);
1152#else
1153 return(signal(signal_number,handler));
1154#endif
1155}
1156
1157static void MagickSignalHandler(int signal_number)
1158{
1159#if !defined(MAGICKCORE_HAVE_SIGACTION)
1160 (void) signal(signal_number,SIG_IGN);
1161#endif
cristyf34a1452009-10-24 22:29:27 +00001162 AsynchronousResourceComponentTerminus();
cristy3ed852e2009-09-05 21:47:34 +00001163 instantiate_magick=MagickFalse;
1164 (void) SetMagickSignalHandler(signal_number,signal_handlers[signal_number]);
1165#if defined(MAGICKCORE_HAVE_RAISE)
1166 if (signal_handlers[signal_number] != MagickSignalHandler)
1167 raise(signal_number);
1168#endif
cristy5f03dab2011-02-20 21:55:17 +00001169#if defined(SIGQUIT)
1170 if (signal_number == SIGQUIT)
1171 abort();
1172#endif
1173#if defined(SIGABRT)
1174 if (signal_number == SIGABRT)
1175 abort();
1176#endif
1177#if defined(SIGFPE)
1178 if (signal_number == SIGFPE)
1179 abort();
1180#endif
1181#if defined(SIGXCPU)
1182 if (signal_number == SIGXCPU)
1183 abort();
1184#endif
1185#if defined(SIGXFSZ)
1186 if (signal_number == SIGXFSZ)
1187 abort();
1188#endif
cristy7ae29582011-04-21 16:10:06 +00001189#if defined(SIGBUS)
1190 if (signal_number == SIGBUS)
1191 abort();
1192#endif
cristy3ed852e2009-09-05 21:47:34 +00001193#if !defined(MAGICKCORE_HAVE__EXIT)
1194 exit(signal_number);
1195#else
1196#if defined(SIGHUP)
1197 if (signal_number == SIGHUP)
1198 exit(signal_number);
1199#endif
cristy0157aea2010-04-24 21:12:18 +00001200#if defined(SIGINT) && !defined(MAGICKCORE_WINDOWS_SUPPORT)
cristy3ed852e2009-09-05 21:47:34 +00001201 if (signal_number == SIGINT)
1202 exit(signal_number);
1203#endif
1204#if defined(SIGTERM)
1205 if (signal_number == SIGTERM)
1206 exit(signal_number);
1207#endif
cristy70bda3d2011-02-20 21:58:06 +00001208 _exit(signal_number); /* do not invoke registered atexit() methods */
cristy3ed852e2009-09-05 21:47:34 +00001209#endif
1210}
1211
1212static SignalHandler *RegisterMagickSignalHandler(int signal_number)
1213{
1214 SignalHandler
1215 *handler;
1216
1217 handler=SetMagickSignalHandler(signal_number,MagickSignalHandler);
1218 if (handler == SIG_ERR)
1219 return(handler);
1220 if (handler != SIG_DFL)
1221 handler=SetMagickSignalHandler(signal_number,handler);
1222 else
1223 (void) LogMagickEvent(ConfigureEvent,GetMagickModule(),
1224 "Register handler for signal: %d",signal_number);
1225 return(handler);
1226}
1227
1228MagickExport void MagickCoreGenesis(const char *path,
1229 const MagickBooleanType establish_signal_handlers)
1230{
1231 char
1232 *events,
1233 execution_path[MaxTextExtent],
1234 filename[MaxTextExtent];
1235
cristy3ed852e2009-09-05 21:47:34 +00001236 /*
1237 Initialize the Magick environment.
1238 */
cristyd1ebf4a2010-05-13 01:54:31 +00001239 LockMagickMutex();
1240 if (instantiate_magickcore != MagickFalse)
1241 {
1242 UnlockMagickMutex();
1243 return;
1244 }
cristyf34a1452009-10-24 22:29:27 +00001245 (void) SemaphoreComponentGenesis();
1246 (void) LogComponentGenesis();
1247 (void) LocaleComponentGenesis();
1248 (void) RandomComponentGenesis();
cristy3ed852e2009-09-05 21:47:34 +00001249 events=GetEnvironmentValue("MAGICK_DEBUG");
1250 if (events != (char *) NULL)
1251 {
1252 (void) SetLogEventMask(events);
1253 events=DestroyString(events);
1254 }
cristy0157aea2010-04-24 21:12:18 +00001255#if defined(MAGICKCORE_WINDOWS_SUPPORT)
cristy3ed852e2009-09-05 21:47:34 +00001256#if defined(_DEBUG) && !defined(__BORLANDC__) && !defined(__MINGW32__)
1257 if (IsEventLogging() != MagickFalse)
1258 {
1259 int
1260 debug;
1261
1262 debug=_CrtSetDbgFlag(_CRTDBG_REPORT_FLAG);
1263 debug|=_CRTDBG_CHECK_ALWAYS_DF |_CRTDBG_DELAY_FREE_MEM_DF |
1264 _CRTDBG_LEAK_CHECK_DF;
1265 if (0)
1266 {
1267 debug=_CrtSetDbgFlag(debug);
1268 _ASSERTE(_CrtCheckMemory());
1269 }
1270 }
1271#endif
1272#endif
1273 /*
1274 Set client name and execution path.
1275 */
1276 (void) GetExecutionPath(execution_path,MaxTextExtent);
1277 if ((path != (const char *) NULL) && (*path != '\0'))
1278 (void) CopyMagickString(execution_path,path,MaxTextExtent);
1279 GetPathComponent(execution_path,TailPath,filename);
1280 (void) SetClientName(filename);
1281 GetPathComponent(execution_path,HeadPath,execution_path);
1282 (void) SetClientPath(execution_path);
1283 if (establish_signal_handlers != MagickFalse)
1284 {
1285 /*
1286 Set signal handlers.
1287 */
1288#if defined(SIGABRT)
1289 if (signal_handlers[SIGABRT] == (SignalHandler *) NULL)
1290 signal_handlers[SIGABRT]=RegisterMagickSignalHandler(SIGABRT);
1291#endif
cristy7ae29582011-04-21 16:10:06 +00001292#if defined(SIGBUS)
1293 if (signal_handlers[SIGBUS] == (SignalHandler *) NULL)
1294 signal_handlers[SIGBUS]=RegisterMagickSignalHandler(SIGBUS);
1295#endif
cristy3ed852e2009-09-05 21:47:34 +00001296#if defined(SIGFPE)
1297 if (signal_handlers[SIGFPE] == (SignalHandler *) NULL)
1298 signal_handlers[SIGFPE]=RegisterMagickSignalHandler(SIGFPE);
1299#endif
1300#if defined(SIGHUP)
1301 if (signal_handlers[SIGHUP] == (SignalHandler *) NULL)
1302 signal_handlers[SIGHUP]=RegisterMagickSignalHandler(SIGHUP);
1303#endif
cristy0157aea2010-04-24 21:12:18 +00001304#if defined(SIGINT) && !defined(MAGICKCORE_WINDOWS_SUPPORT)
cristy3ed852e2009-09-05 21:47:34 +00001305 if (signal_handlers[SIGINT] == (SignalHandler *) NULL)
1306 signal_handlers[SIGINT]=RegisterMagickSignalHandler(SIGINT);
1307#endif
1308#if defined(SIGQUIT)
1309 if (signal_handlers[SIGQUIT] == (SignalHandler *) NULL)
1310 signal_handlers[SIGQUIT]=RegisterMagickSignalHandler(SIGQUIT);
1311#endif
1312#if defined(SIGTERM)
1313 if (signal_handlers[SIGTERM] == (SignalHandler *) NULL)
1314 signal_handlers[SIGTERM]=RegisterMagickSignalHandler(SIGTERM);
1315#endif
1316#if defined(SIGXCPU)
1317 if (signal_handlers[SIGXCPU] == (SignalHandler *) NULL)
1318 signal_handlers[SIGXCPU]=RegisterMagickSignalHandler(SIGXCPU);
1319#endif
1320#if defined(SIGXFSZ)
1321 if (signal_handlers[SIGXFSZ] == (SignalHandler *) NULL)
1322 signal_handlers[SIGXFSZ]=RegisterMagickSignalHandler(SIGXFSZ);
1323#endif
1324 }
1325 /*
cristyaf8b5cd2009-10-24 00:29:23 +00001326 Instantiate magick resources.
cristy3ed852e2009-09-05 21:47:34 +00001327 */
cristy18b17442009-10-25 18:36:48 +00001328 (void) ConfigureComponentGenesis();
cristyf34a1452009-10-24 22:29:27 +00001329 (void) PolicyComponentGenesis();
1330 (void) CacheComponentGenesis();
1331 (void) RegistryComponentGenesis();
1332 (void) ResourceComponentGenesis();
1333 (void) CoderComponentGenesis();
1334 (void) MagickComponentGenesis();
cristyaf8b5cd2009-10-24 00:29:23 +00001335#if defined(MAGICKCORE_MODULES_SUPPORT)
cristyf34a1452009-10-24 22:29:27 +00001336 (void) ModuleComponentGenesis();
cristyaf8b5cd2009-10-24 00:29:23 +00001337#endif
cristyf34a1452009-10-24 22:29:27 +00001338 (void) DelegateComponentGenesis();
1339 (void) MagicComponentGenesis();
1340 (void) ColorComponentGenesis();
1341 (void) TypeComponentGenesis();
cristyf34a1452009-10-24 22:29:27 +00001342 (void) MimeComponentGenesis();
1343 (void) ConstituteComponentGenesis();
cristyd7ecaca2011-01-24 14:14:53 +00001344 (void) AnnotateComponentGenesis();
cristy0157aea2010-04-24 21:12:18 +00001345#if defined(MAGICKCORE_X11_DELEGATE)
cristyf34a1452009-10-24 22:29:27 +00001346 (void) XComponentGenesis();
cristy0157aea2010-04-24 21:12:18 +00001347#endif
cristyd1ebf4a2010-05-13 01:54:31 +00001348 instantiate_magickcore=MagickTrue;
1349 UnlockMagickMutex();
cristy3ed852e2009-09-05 21:47:34 +00001350}
1351
1352/*
1353%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1354% %
1355% %
1356% %
1357% M a g i c k C o r e T e r m i n u s %
1358% %
1359% %
1360% %
1361%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1362%
1363% MagickCoreTerminus() destroys the MagickCore environment.
1364%
cristyf34a1452009-10-24 22:29:27 +00001365% The format of the MagickCoreTerminus function is:
cristy3ed852e2009-09-05 21:47:34 +00001366%
1367% MagickCoreTerminus(void)
1368%
1369*/
1370MagickExport void MagickCoreTerminus(void)
1371{
cristyd1ebf4a2010-05-13 01:54:31 +00001372 LockMagickMutex();
1373 if (instantiate_magickcore == MagickFalse)
1374 {
1375 UnlockMagickMutex();
1376 return;
1377 }
cristy3ed852e2009-09-05 21:47:34 +00001378#if defined(MAGICKCORE_X11_DELEGATE)
cristyf34a1452009-10-24 22:29:27 +00001379 XComponentTerminus();
cristy3ed852e2009-09-05 21:47:34 +00001380#endif
cristyd7ecaca2011-01-24 14:14:53 +00001381 AnnotateComponentTerminus();
cristyf34a1452009-10-24 22:29:27 +00001382 ConstituteComponentTerminus();
1383 MimeComponentTerminus();
cristyf34a1452009-10-24 22:29:27 +00001384 TypeComponentTerminus();
1385 ColorComponentTerminus();
cristy0157aea2010-04-24 21:12:18 +00001386#if defined(MAGICKCORE_WINDOWS_SUPPORT)
cristy3ed852e2009-09-05 21:47:34 +00001387 NTGhostscriptUnLoadDLL();
1388#endif
cristyf34a1452009-10-24 22:29:27 +00001389 MagicComponentTerminus();
1390 DelegateComponentTerminus();
1391 MagickComponentTerminus();
cristyaf8b5cd2009-10-24 00:29:23 +00001392#if !defined(MAGICKCORE_BUILD_MODULES)
1393 UnregisterStaticModules();
1394#endif
1395#if defined(MAGICKCORE_MODULES_SUPPORT)
cristyf34a1452009-10-24 22:29:27 +00001396 ModuleComponentTerminus();
cristyaf8b5cd2009-10-24 00:29:23 +00001397#endif
cristyf34a1452009-10-24 22:29:27 +00001398 CoderComponentTerminus();
1399 ResourceComponentTerminus();
1400 RegistryComponentTerminus();
1401 CacheComponentTerminus();
1402 PolicyComponentTerminus();
cristy18b17442009-10-25 18:36:48 +00001403 ConfigureComponentTerminus();
cristyf34a1452009-10-24 22:29:27 +00001404 RandomComponentTerminus();
1405 LocaleComponentTerminus();
1406 LogComponentTerminus();
1407 SemaphoreComponentTerminus();
cristyd1ebf4a2010-05-13 01:54:31 +00001408 instantiate_magickcore=MagickFalse;
1409 UnlockMagickMutex();
cristy3ed852e2009-09-05 21:47:34 +00001410}
1411
1412/*
1413%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1414% %
1415% %
1416% %
1417+ R e g i s t e r M a g i c k I n f o %
1418% %
1419% %
1420% %
1421%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1422%
1423% RegisterMagickInfo() adds attributes for a particular image format to the
1424% list of supported formats. The attributes include the image format name,
1425% a method to read and/or write the format, whether the format supports the
1426% saving of more than one frame to the same file or blob, whether the format
1427% supports native in-memory I/O, and a brief description of the format.
1428%
1429% The format of the RegisterMagickInfo method is:
1430%
1431% MagickInfo *RegisterMagickInfo(MagickInfo *magick_info)
1432%
1433% A description of each parameter follows:
1434%
1435% o magick_info: the magick info.
1436%
1437*/
1438MagickExport MagickInfo *RegisterMagickInfo(MagickInfo *magick_info)
1439{
1440 MagickBooleanType
1441 status;
1442
1443 /*
1444 Delete any existing name.
1445 */
1446 assert(magick_info != (MagickInfo *) NULL);
1447 assert(magick_info->signature == MagickSignature);
1448 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",magick_info->name);
1449 if (magick_list == (SplayTreeInfo *) NULL)
1450 return((MagickInfo *) NULL);
1451 status=AddValueToSplayTree(magick_list,magick_info->name,magick_info);
1452 if (status == MagickFalse)
1453 ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed");
1454 return(magick_info);
1455}
1456
1457/*
1458%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1459% %
1460% %
1461% %
1462+ S e t M a g i c k I n f o %
1463% %
1464% %
1465% %
1466%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1467%
1468% SetMagickInfo() allocates a MagickInfo structure and initializes the members
1469% to default values.
1470%
1471% The format of the SetMagickInfo method is:
1472%
1473% MagickInfo *SetMagickInfo(const char *name)
1474%
1475% A description of each parameter follows:
1476%
1477% o magick_info: Method SetMagickInfo returns the allocated and initialized
1478% MagickInfo structure.
1479%
1480% o name: a character string that represents the image format associated
1481% with the MagickInfo structure.
1482%
1483*/
1484MagickExport MagickInfo *SetMagickInfo(const char *name)
1485{
1486 MagickInfo
1487 *magick_info;
1488
1489 assert(name != (const char *) NULL);
1490 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",name);
cristy73bd4a52010-10-05 11:24:23 +00001491 magick_info=(MagickInfo *) AcquireMagickMemory(sizeof(*magick_info));
cristy3ed852e2009-09-05 21:47:34 +00001492 if (magick_info == (MagickInfo *) NULL)
1493 ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed");
1494 (void) ResetMagickMemory(magick_info,0,sizeof(*magick_info));
1495 magick_info->name=ConstantString(name);
1496 magick_info->adjoin=MagickTrue;
1497 magick_info->blob_support=MagickTrue;
1498 magick_info->thread_support=(MagickStatusType) (DecoderThreadSupport |
1499 EncoderThreadSupport);
1500 magick_info->signature=MagickSignature;
1501 return(magick_info);
1502}
1503
1504/*
1505%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1506% %
1507% %
1508% %
cristye7f51092010-01-17 00:39:37 +00001509% S e t M a g i c k P r e c i s i o n %
1510% %
1511% %
1512% %
1513%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1514%
1515% SetMagickPrecision() sets the maximum number of significant digits to be
cristybf2766a2010-01-17 03:33:23 +00001516% printed and returns it.
cristye7f51092010-01-17 00:39:37 +00001517%
1518% The format of the SetMagickPrecision method is:
1519%
cristybf2766a2010-01-17 03:33:23 +00001520% int SetMagickPrecision(const int precision)
cristye7f51092010-01-17 00:39:37 +00001521%
1522% A description of each parameter follows:
1523%
1524% o precision: set the maximum number of significant digits to be printed.
1525%
1526*/
cristybf2766a2010-01-17 03:33:23 +00001527MagickExport int SetMagickPrecision(const int precision)
cristye7f51092010-01-17 00:39:37 +00001528{
cristybf2766a2010-01-17 03:33:23 +00001529 static int
1530 magick_precision = 0;
1531
cristye7f51092010-01-17 00:39:37 +00001532 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
cristybf2766a2010-01-17 03:33:23 +00001533 if (precision != 0)
1534 magick_precision=precision;
1535 return(magick_precision);
cristye7f51092010-01-17 00:39:37 +00001536}
1537
1538/*
1539%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1540% %
1541% %
1542% %
cristy3ed852e2009-09-05 21:47:34 +00001543+ U n r e g i s t e r M a g i c k I n f o %
1544% %
1545% %
1546% %
1547%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1548%
1549% UnregisterMagickInfo() removes a name from the magick info list. It returns
1550% MagickFalse if the name does not exist in the list otherwise MagickTrue.
1551%
1552% The format of the UnregisterMagickInfo method is:
1553%
1554% MagickBooleanType UnregisterMagickInfo(const char *name)
1555%
1556% A description of each parameter follows:
1557%
1558% o name: a character string that represents the image format we are
1559% looking for.
1560%
1561*/
1562MagickExport MagickBooleanType UnregisterMagickInfo(const char *name)
1563{
1564 register const MagickInfo
1565 *p;
1566
1567 MagickBooleanType
1568 status;
1569
1570 assert(name != (const char *) NULL);
1571 if (magick_list == (SplayTreeInfo *) NULL)
1572 return(MagickFalse);
1573 if (GetNumberOfNodesInSplayTree(magick_list) == 0)
1574 return(MagickFalse);
cristyf84a1932010-01-03 18:00:18 +00001575 LockSemaphoreInfo(magick_semaphore);
cristy3ed852e2009-09-05 21:47:34 +00001576 ResetSplayTreeIterator(magick_list);
1577 p=(const MagickInfo *) GetNextValueInSplayTree(magick_list);
1578 while (p != (const MagickInfo *) NULL)
1579 {
1580 if (LocaleCompare(p->name,name) == 0)
1581 break;
1582 p=(const MagickInfo *) GetNextValueInSplayTree(magick_list);
1583 }
1584 status=DeleteNodeByValueFromSplayTree(magick_list,p);
cristyf84a1932010-01-03 18:00:18 +00001585 UnlockSemaphoreInfo(magick_semaphore);
cristy3ed852e2009-09-05 21:47:34 +00001586 return(status);
1587}