blob: cff452b1ad192999b1525f1368eaeda4bb41f4ad [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*/
cristy4c08aed2011-07-01 19:47:50 +000043#include "MagickCore/studio.h"
44#include "MagickCore/annotate.h"
45#include "MagickCore/blob.h"
46#include "MagickCore/blob-private.h"
47#include "MagickCore/cache.h"
48#include "MagickCore/coder.h"
49#include "MagickCore/client.h"
50#include "MagickCore/coder.h"
51#include "MagickCore/configure.h"
52#include "MagickCore/constitute.h"
53#include "MagickCore/delegate.h"
54#include "MagickCore/draw.h"
55#include "MagickCore/exception.h"
56#include "MagickCore/exception-private.h"
57#include "MagickCore/locale_.h"
58#include "MagickCore/log.h"
59#include "MagickCore/magic.h"
60#include "MagickCore/magick.h"
61#include "MagickCore/memory_.h"
62#include "MagickCore/mime.h"
63#include "MagickCore/module.h"
cristy0157aea2010-04-24 21:12:18 +000064#if defined(MAGICKCORE_WINDOWS_SUPPORT)
cristy4c08aed2011-07-01 19:47:50 +000065# include "MagickCore/nt-feature.h"
cristy3ed852e2009-09-05 21:47:34 +000066#endif
cristy4c08aed2011-07-01 19:47:50 +000067#include "MagickCore/random_.h"
68#include "MagickCore/registry.h"
69#include "MagickCore/resource_.h"
70#include "MagickCore/policy.h"
71#include "MagickCore/semaphore.h"
72#include "MagickCore/semaphore-private.h"
73#include "MagickCore/signature-private.h"
74#include "MagickCore/splay-tree.h"
75#include "MagickCore/string_.h"
76#include "MagickCore/string-private.h"
77#include "MagickCore/thread_.h"
78#include "MagickCore/thread-private.h"
79#include "MagickCore/token.h"
80#include "MagickCore/utility.h"
81#include "MagickCore/xwindow-private.h"
cristy3ed852e2009-09-05 21:47:34 +000082
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)
cristyb51dff52011-05-19 16:55:47 +0000957 (void) FormatLocaleFile(file," Format Mode Description\n");
cristy3ed852e2009-09-05 21:47:34 +0000958#else
cristyb51dff52011-05-19 16:55:47 +0000959 (void) FormatLocaleFile(file," Format Module Mode Description\n");
cristy3ed852e2009-09-05 21:47:34 +0000960#endif
cristy1e604812011-05-19 18:07:50 +0000961 (void) FormatLocaleFile(file,
962 "--------------------------------------------------------"
cristy3ed852e2009-09-05 21:47:34 +0000963 "-----------------------\n");
cristybb503372010-05-27 20:51:26 +0000964 for (i=0; i < (ssize_t) number_formats; i++)
cristy3ed852e2009-09-05 21:47:34 +0000965 {
966 if (magick_info[i]->stealth != MagickFalse)
967 continue;
cristy1e604812011-05-19 18:07:50 +0000968 (void) FormatLocaleFile(file,"%9s%c ",
969 magick_info[i]->name != (char *) NULL ? magick_info[i]->name : "",
cristy3ed852e2009-09-05 21:47:34 +0000970 magick_info[i]->blob_support != MagickFalse ? '*' : ' ');
971#if defined(MAGICKCORE_MODULES_SUPPORT)
972 {
973 char
974 module[MaxTextExtent];
975
976 *module='\0';
977 if (magick_info[i]->module != (char *) NULL)
978 (void) CopyMagickString(module,magick_info[i]->module,MaxTextExtent);
979 (void) ConcatenateMagickString(module," ",MaxTextExtent);
980 module[9]='\0';
cristyb51dff52011-05-19 16:55:47 +0000981 (void) FormatLocaleFile(file,"%9s ",module);
cristy3ed852e2009-09-05 21:47:34 +0000982 }
983#endif
cristyb51dff52011-05-19 16:55:47 +0000984 (void) FormatLocaleFile(file,"%c%c%c ",magick_info[i]->decoder ? 'r' : '-',
cristy3ed852e2009-09-05 21:47:34 +0000985 magick_info[i]->encoder ? 'w' : '-',magick_info[i]->encoder != NULL &&
986 magick_info[i]->adjoin != MagickFalse ? '+' : '-');
987 if (magick_info[i]->description != (char *) NULL)
cristyb51dff52011-05-19 16:55:47 +0000988 (void) FormatLocaleFile(file," %s",magick_info[i]->description);
cristy3ed852e2009-09-05 21:47:34 +0000989 if (magick_info[i]->version != (char *) NULL)
cristyb51dff52011-05-19 16:55:47 +0000990 (void) FormatLocaleFile(file," (%s)",magick_info[i]->version);
991 (void) FormatLocaleFile(file,"\n");
cristy3ed852e2009-09-05 21:47:34 +0000992 if (magick_info[i]->note != (char *) NULL)
993 {
994 char
995 **text;
996
997 text=StringToList(magick_info[i]->note);
998 if (text != (char **) NULL)
999 {
1000 for (j=0; text[j] != (char *) NULL; j++)
1001 {
cristyb51dff52011-05-19 16:55:47 +00001002 (void) FormatLocaleFile(file," %s\n",text[j]);
cristy3ed852e2009-09-05 21:47:34 +00001003 text[j]=DestroyString(text[j]);
1004 }
1005 text=(char **) RelinquishMagickMemory(text);
1006 }
1007 }
1008 }
cristyb51dff52011-05-19 16:55:47 +00001009 (void) FormatLocaleFile(file,"\n* native blob support\n");
1010 (void) FormatLocaleFile(file,"r read support\n");
1011 (void) FormatLocaleFile(file,"w write support\n");
1012 (void) FormatLocaleFile(file,"+ support for multiple images\n");
cristy3ed852e2009-09-05 21:47:34 +00001013 (void) fflush(file);
1014 magick_info=(const MagickInfo **) RelinquishMagickMemory((void *)
1015 magick_info);
1016 return(MagickTrue);
1017}
1018
1019/*
1020%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1021% %
1022% %
1023% %
1024% I s M a g i c k I n s t a n t i a t e d %
1025% %
1026% %
1027% %
1028%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1029%
1030% IsMagickInstantiated() returns MagickTrue if the ImageMagick environment
1031% is currently instantiated: MagickCoreGenesis() has been called but
1032% MagickDestroy() has not.
1033%
1034% The format of the IsMagickInstantiated method is:
1035%
1036% MagickBooleanType IsMagickInstantiated(void)
1037%
1038*/
1039MagickExport MagickBooleanType IsMagickInstantiated(void)
1040{
1041 return(instantiate_magick);
1042}
1043
1044/*
1045%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1046% %
1047% %
1048% %
cristyf34a1452009-10-24 22:29:27 +00001049+ M a g i c k C o m p o n e n t G e n e s i s %
1050% %
1051% %
1052% %
1053%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1054%
1055% MagickComponentGenesis() instantiates the magick component.
1056%
1057% The format of the MagickComponentGenesis method is:
1058%
1059% MagickBooleanType MagickComponentGenesis(void)
1060%
1061*/
1062MagickExport MagickBooleanType MagickComponentGenesis(void)
1063{
cristy165b6092009-10-26 13:52:10 +00001064 AcquireSemaphoreInfo(&magick_semaphore);
cristyf34a1452009-10-24 22:29:27 +00001065 return(MagickTrue);
1066}
1067
1068/*
1069%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1070% %
1071% %
1072% %
1073+ M a g i c k C o m p o n e n t T e r m i n u s %
1074% %
1075% %
1076% %
1077%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1078%
1079% MagickComponentTerminus() destroys the magick component.
1080%
1081% The format of the MagickComponentTerminus method is:
1082%
1083% void MagickComponentTerminus(void)
1084%
1085*/
1086MagickExport void MagickComponentTerminus(void)
1087{
cristy18b17442009-10-25 18:36:48 +00001088 if (magick_semaphore == (SemaphoreInfo *) NULL)
1089 AcquireSemaphoreInfo(&magick_semaphore);
cristyf84a1932010-01-03 18:00:18 +00001090 LockSemaphoreInfo(magick_semaphore);
cristyf34a1452009-10-24 22:29:27 +00001091 if (magick_list != (SplayTreeInfo *) NULL)
1092 magick_list=DestroySplayTree(magick_list);
1093 instantiate_magick=MagickFalse;
cristyf84a1932010-01-03 18:00:18 +00001094 UnlockSemaphoreInfo(magick_semaphore);
cristyf34a1452009-10-24 22:29:27 +00001095 DestroySemaphoreInfo(&magick_semaphore);
1096}
1097
1098/*
1099%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1100% %
1101% %
1102% %
cristy3ed852e2009-09-05 21:47:34 +00001103% M a g i c k C o r e G e n e s i s %
1104% %
1105% %
1106% %
1107%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1108%
1109% MagickCoreGenesis() initializes the MagickCore environment.
1110%
1111% The format of the MagickCoreGenesis function is:
1112%
1113% MagickCoreGenesis(const char *path,
1114% const MagickBooleanType establish_signal_handlers)
1115%
1116% A description of each parameter follows:
1117%
1118% o path: the execution path of the current ImageMagick client.
1119%
1120% o establish_signal_handlers: set to MagickTrue to use MagickCore's own
1121% signal handlers for common signals.
1122%
1123*/
1124
1125static SignalHandler *SetMagickSignalHandler(int signal_number,
1126 SignalHandler *handler)
1127{
1128#if defined(MAGICKCORE_HAVE_SIGACTION) && defined(MAGICKCORE_HAVE_SIGEMPTYSET)
1129 int
1130 status;
1131
1132 sigset_t
1133 mask;
1134
1135 struct sigaction
1136 action,
1137 previous_action;
1138
1139 sigemptyset(&mask);
1140 sigaddset(&mask,signal_number);
1141 sigprocmask(SIG_BLOCK,&mask,NULL);
1142 action.sa_mask=mask;
1143 action.sa_handler=handler;
1144 action.sa_flags=0;
1145#if defined(SA_INTERRUPT)
1146 action.sa_flags|=SA_INTERRUPT;
1147#endif
1148 status=sigaction(signal_number,&action,&previous_action);
1149 if (status < 0)
1150 return(SIG_ERR);
1151 sigprocmask(SIG_UNBLOCK,&mask,NULL);
1152 return(previous_action.sa_handler);
1153#else
1154 return(signal(signal_number,handler));
1155#endif
1156}
1157
1158static void MagickSignalHandler(int signal_number)
1159{
1160#if !defined(MAGICKCORE_HAVE_SIGACTION)
1161 (void) signal(signal_number,SIG_IGN);
1162#endif
cristyf34a1452009-10-24 22:29:27 +00001163 AsynchronousResourceComponentTerminus();
cristy3ed852e2009-09-05 21:47:34 +00001164 instantiate_magick=MagickFalse;
1165 (void) SetMagickSignalHandler(signal_number,signal_handlers[signal_number]);
1166#if defined(MAGICKCORE_HAVE_RAISE)
1167 if (signal_handlers[signal_number] != MagickSignalHandler)
1168 raise(signal_number);
1169#endif
cristy5f03dab2011-02-20 21:55:17 +00001170#if defined(SIGQUIT)
1171 if (signal_number == SIGQUIT)
1172 abort();
1173#endif
1174#if defined(SIGABRT)
1175 if (signal_number == SIGABRT)
1176 abort();
1177#endif
1178#if defined(SIGFPE)
1179 if (signal_number == SIGFPE)
1180 abort();
1181#endif
1182#if defined(SIGXCPU)
1183 if (signal_number == SIGXCPU)
1184 abort();
1185#endif
1186#if defined(SIGXFSZ)
1187 if (signal_number == SIGXFSZ)
1188 abort();
1189#endif
cristy32a348b2011-04-22 16:03:42 +00001190#if defined(SIGSEGV)
1191 if (signal_number == SIGSEGV)
cristy7ae29582011-04-21 16:10:06 +00001192 abort();
1193#endif
cristy3ed852e2009-09-05 21:47:34 +00001194#if !defined(MAGICKCORE_HAVE__EXIT)
1195 exit(signal_number);
1196#else
1197#if defined(SIGHUP)
1198 if (signal_number == SIGHUP)
1199 exit(signal_number);
1200#endif
cristy0157aea2010-04-24 21:12:18 +00001201#if defined(SIGINT) && !defined(MAGICKCORE_WINDOWS_SUPPORT)
cristy3ed852e2009-09-05 21:47:34 +00001202 if (signal_number == SIGINT)
1203 exit(signal_number);
1204#endif
1205#if defined(SIGTERM)
1206 if (signal_number == SIGTERM)
1207 exit(signal_number);
1208#endif
cristy70bda3d2011-02-20 21:58:06 +00001209 _exit(signal_number); /* do not invoke registered atexit() methods */
cristy3ed852e2009-09-05 21:47:34 +00001210#endif
1211}
1212
1213static SignalHandler *RegisterMagickSignalHandler(int signal_number)
1214{
1215 SignalHandler
1216 *handler;
1217
1218 handler=SetMagickSignalHandler(signal_number,MagickSignalHandler);
1219 if (handler == SIG_ERR)
1220 return(handler);
1221 if (handler != SIG_DFL)
1222 handler=SetMagickSignalHandler(signal_number,handler);
1223 else
1224 (void) LogMagickEvent(ConfigureEvent,GetMagickModule(),
1225 "Register handler for signal: %d",signal_number);
1226 return(handler);
1227}
1228
1229MagickExport void MagickCoreGenesis(const char *path,
1230 const MagickBooleanType establish_signal_handlers)
1231{
1232 char
1233 *events,
1234 execution_path[MaxTextExtent],
1235 filename[MaxTextExtent];
1236
cristy3ed852e2009-09-05 21:47:34 +00001237 /*
1238 Initialize the Magick environment.
1239 */
cristyd1ebf4a2010-05-13 01:54:31 +00001240 LockMagickMutex();
1241 if (instantiate_magickcore != MagickFalse)
1242 {
1243 UnlockMagickMutex();
1244 return;
1245 }
cristyf34a1452009-10-24 22:29:27 +00001246 (void) SemaphoreComponentGenesis();
1247 (void) LogComponentGenesis();
1248 (void) LocaleComponentGenesis();
1249 (void) RandomComponentGenesis();
cristy3ed852e2009-09-05 21:47:34 +00001250 events=GetEnvironmentValue("MAGICK_DEBUG");
1251 if (events != (char *) NULL)
1252 {
1253 (void) SetLogEventMask(events);
1254 events=DestroyString(events);
1255 }
cristy0157aea2010-04-24 21:12:18 +00001256#if defined(MAGICKCORE_WINDOWS_SUPPORT)
cristy3ed852e2009-09-05 21:47:34 +00001257#if defined(_DEBUG) && !defined(__BORLANDC__) && !defined(__MINGW32__)
1258 if (IsEventLogging() != MagickFalse)
1259 {
1260 int
1261 debug;
1262
1263 debug=_CrtSetDbgFlag(_CRTDBG_REPORT_FLAG);
1264 debug|=_CRTDBG_CHECK_ALWAYS_DF |_CRTDBG_DELAY_FREE_MEM_DF |
1265 _CRTDBG_LEAK_CHECK_DF;
1266 if (0)
1267 {
1268 debug=_CrtSetDbgFlag(debug);
1269 _ASSERTE(_CrtCheckMemory());
1270 }
1271 }
1272#endif
1273#endif
1274 /*
1275 Set client name and execution path.
1276 */
1277 (void) GetExecutionPath(execution_path,MaxTextExtent);
1278 if ((path != (const char *) NULL) && (*path != '\0'))
1279 (void) CopyMagickString(execution_path,path,MaxTextExtent);
1280 GetPathComponent(execution_path,TailPath,filename);
1281 (void) SetClientName(filename);
1282 GetPathComponent(execution_path,HeadPath,execution_path);
1283 (void) SetClientPath(execution_path);
1284 if (establish_signal_handlers != MagickFalse)
1285 {
1286 /*
1287 Set signal handlers.
1288 */
1289#if defined(SIGABRT)
1290 if (signal_handlers[SIGABRT] == (SignalHandler *) NULL)
1291 signal_handlers[SIGABRT]=RegisterMagickSignalHandler(SIGABRT);
1292#endif
cristy32a348b2011-04-22 16:03:42 +00001293#if defined(SIGSEGV)
1294 if (signal_handlers[SIGSEGV] == (SignalHandler *) NULL)
1295 signal_handlers[SIGSEGV]=RegisterMagickSignalHandler(SIGSEGV);
cristy7ae29582011-04-21 16:10:06 +00001296#endif
cristy3ed852e2009-09-05 21:47:34 +00001297#if defined(SIGFPE)
1298 if (signal_handlers[SIGFPE] == (SignalHandler *) NULL)
1299 signal_handlers[SIGFPE]=RegisterMagickSignalHandler(SIGFPE);
1300#endif
1301#if defined(SIGHUP)
1302 if (signal_handlers[SIGHUP] == (SignalHandler *) NULL)
1303 signal_handlers[SIGHUP]=RegisterMagickSignalHandler(SIGHUP);
1304#endif
cristy0157aea2010-04-24 21:12:18 +00001305#if defined(SIGINT) && !defined(MAGICKCORE_WINDOWS_SUPPORT)
cristy3ed852e2009-09-05 21:47:34 +00001306 if (signal_handlers[SIGINT] == (SignalHandler *) NULL)
1307 signal_handlers[SIGINT]=RegisterMagickSignalHandler(SIGINT);
1308#endif
1309#if defined(SIGQUIT)
1310 if (signal_handlers[SIGQUIT] == (SignalHandler *) NULL)
1311 signal_handlers[SIGQUIT]=RegisterMagickSignalHandler(SIGQUIT);
1312#endif
1313#if defined(SIGTERM)
1314 if (signal_handlers[SIGTERM] == (SignalHandler *) NULL)
1315 signal_handlers[SIGTERM]=RegisterMagickSignalHandler(SIGTERM);
1316#endif
1317#if defined(SIGXCPU)
1318 if (signal_handlers[SIGXCPU] == (SignalHandler *) NULL)
1319 signal_handlers[SIGXCPU]=RegisterMagickSignalHandler(SIGXCPU);
1320#endif
1321#if defined(SIGXFSZ)
1322 if (signal_handlers[SIGXFSZ] == (SignalHandler *) NULL)
1323 signal_handlers[SIGXFSZ]=RegisterMagickSignalHandler(SIGXFSZ);
1324#endif
1325 }
1326 /*
cristyaf8b5cd2009-10-24 00:29:23 +00001327 Instantiate magick resources.
cristy3ed852e2009-09-05 21:47:34 +00001328 */
cristy18b17442009-10-25 18:36:48 +00001329 (void) ConfigureComponentGenesis();
cristyf34a1452009-10-24 22:29:27 +00001330 (void) PolicyComponentGenesis();
1331 (void) CacheComponentGenesis();
1332 (void) RegistryComponentGenesis();
1333 (void) ResourceComponentGenesis();
1334 (void) CoderComponentGenesis();
1335 (void) MagickComponentGenesis();
cristyaf8b5cd2009-10-24 00:29:23 +00001336#if defined(MAGICKCORE_MODULES_SUPPORT)
cristyf34a1452009-10-24 22:29:27 +00001337 (void) ModuleComponentGenesis();
cristyaf8b5cd2009-10-24 00:29:23 +00001338#endif
cristyf34a1452009-10-24 22:29:27 +00001339 (void) DelegateComponentGenesis();
1340 (void) MagicComponentGenesis();
1341 (void) ColorComponentGenesis();
1342 (void) TypeComponentGenesis();
cristyf34a1452009-10-24 22:29:27 +00001343 (void) MimeComponentGenesis();
1344 (void) ConstituteComponentGenesis();
cristyd7ecaca2011-01-24 14:14:53 +00001345 (void) AnnotateComponentGenesis();
cristy0157aea2010-04-24 21:12:18 +00001346#if defined(MAGICKCORE_X11_DELEGATE)
cristyf34a1452009-10-24 22:29:27 +00001347 (void) XComponentGenesis();
cristy0157aea2010-04-24 21:12:18 +00001348#endif
cristyd1ebf4a2010-05-13 01:54:31 +00001349 instantiate_magickcore=MagickTrue;
1350 UnlockMagickMutex();
cristy3ed852e2009-09-05 21:47:34 +00001351}
1352
1353/*
1354%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1355% %
1356% %
1357% %
1358% M a g i c k C o r e T e r m i n u s %
1359% %
1360% %
1361% %
1362%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1363%
1364% MagickCoreTerminus() destroys the MagickCore environment.
1365%
cristyf34a1452009-10-24 22:29:27 +00001366% The format of the MagickCoreTerminus function is:
cristy3ed852e2009-09-05 21:47:34 +00001367%
1368% MagickCoreTerminus(void)
1369%
1370*/
1371MagickExport void MagickCoreTerminus(void)
1372{
cristyd1ebf4a2010-05-13 01:54:31 +00001373 LockMagickMutex();
1374 if (instantiate_magickcore == MagickFalse)
1375 {
1376 UnlockMagickMutex();
1377 return;
1378 }
cristy3ed852e2009-09-05 21:47:34 +00001379#if defined(MAGICKCORE_X11_DELEGATE)
cristyf34a1452009-10-24 22:29:27 +00001380 XComponentTerminus();
cristy3ed852e2009-09-05 21:47:34 +00001381#endif
cristyd7ecaca2011-01-24 14:14:53 +00001382 AnnotateComponentTerminus();
cristyf34a1452009-10-24 22:29:27 +00001383 ConstituteComponentTerminus();
1384 MimeComponentTerminus();
cristyf34a1452009-10-24 22:29:27 +00001385 TypeComponentTerminus();
1386 ColorComponentTerminus();
cristy0157aea2010-04-24 21:12:18 +00001387#if defined(MAGICKCORE_WINDOWS_SUPPORT)
cristy3ed852e2009-09-05 21:47:34 +00001388 NTGhostscriptUnLoadDLL();
1389#endif
cristyf34a1452009-10-24 22:29:27 +00001390 MagicComponentTerminus();
1391 DelegateComponentTerminus();
1392 MagickComponentTerminus();
cristyaf8b5cd2009-10-24 00:29:23 +00001393#if !defined(MAGICKCORE_BUILD_MODULES)
1394 UnregisterStaticModules();
1395#endif
1396#if defined(MAGICKCORE_MODULES_SUPPORT)
cristyf34a1452009-10-24 22:29:27 +00001397 ModuleComponentTerminus();
cristyaf8b5cd2009-10-24 00:29:23 +00001398#endif
cristyf34a1452009-10-24 22:29:27 +00001399 CoderComponentTerminus();
1400 ResourceComponentTerminus();
1401 RegistryComponentTerminus();
1402 CacheComponentTerminus();
1403 PolicyComponentTerminus();
cristy18b17442009-10-25 18:36:48 +00001404 ConfigureComponentTerminus();
cristyf34a1452009-10-24 22:29:27 +00001405 RandomComponentTerminus();
1406 LocaleComponentTerminus();
1407 LogComponentTerminus();
1408 SemaphoreComponentTerminus();
cristyd1ebf4a2010-05-13 01:54:31 +00001409 instantiate_magickcore=MagickFalse;
1410 UnlockMagickMutex();
cristy3ed852e2009-09-05 21:47:34 +00001411}
1412
1413/*
1414%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1415% %
1416% %
1417% %
1418+ R e g i s t e r M a g i c k I n f o %
1419% %
1420% %
1421% %
1422%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1423%
1424% RegisterMagickInfo() adds attributes for a particular image format to the
1425% list of supported formats. The attributes include the image format name,
1426% a method to read and/or write the format, whether the format supports the
1427% saving of more than one frame to the same file or blob, whether the format
1428% supports native in-memory I/O, and a brief description of the format.
1429%
1430% The format of the RegisterMagickInfo method is:
1431%
1432% MagickInfo *RegisterMagickInfo(MagickInfo *magick_info)
1433%
1434% A description of each parameter follows:
1435%
1436% o magick_info: the magick info.
1437%
1438*/
1439MagickExport MagickInfo *RegisterMagickInfo(MagickInfo *magick_info)
1440{
1441 MagickBooleanType
1442 status;
1443
1444 /*
1445 Delete any existing name.
1446 */
1447 assert(magick_info != (MagickInfo *) NULL);
1448 assert(magick_info->signature == MagickSignature);
1449 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",magick_info->name);
1450 if (magick_list == (SplayTreeInfo *) NULL)
1451 return((MagickInfo *) NULL);
1452 status=AddValueToSplayTree(magick_list,magick_info->name,magick_info);
1453 if (status == MagickFalse)
1454 ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed");
1455 return(magick_info);
1456}
1457
1458/*
1459%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1460% %
1461% %
1462% %
1463+ S e t M a g i c k I n f o %
1464% %
1465% %
1466% %
1467%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1468%
1469% SetMagickInfo() allocates a MagickInfo structure and initializes the members
1470% to default values.
1471%
1472% The format of the SetMagickInfo method is:
1473%
1474% MagickInfo *SetMagickInfo(const char *name)
1475%
1476% A description of each parameter follows:
1477%
1478% o magick_info: Method SetMagickInfo returns the allocated and initialized
1479% MagickInfo structure.
1480%
1481% o name: a character string that represents the image format associated
1482% with the MagickInfo structure.
1483%
1484*/
1485MagickExport MagickInfo *SetMagickInfo(const char *name)
1486{
1487 MagickInfo
1488 *magick_info;
1489
1490 assert(name != (const char *) NULL);
1491 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",name);
cristy73bd4a52010-10-05 11:24:23 +00001492 magick_info=(MagickInfo *) AcquireMagickMemory(sizeof(*magick_info));
cristy3ed852e2009-09-05 21:47:34 +00001493 if (magick_info == (MagickInfo *) NULL)
1494 ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed");
1495 (void) ResetMagickMemory(magick_info,0,sizeof(*magick_info));
1496 magick_info->name=ConstantString(name);
1497 magick_info->adjoin=MagickTrue;
1498 magick_info->blob_support=MagickTrue;
1499 magick_info->thread_support=(MagickStatusType) (DecoderThreadSupport |
1500 EncoderThreadSupport);
1501 magick_info->signature=MagickSignature;
1502 return(magick_info);
1503}
1504
1505/*
1506%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1507% %
1508% %
1509% %
cristye7f51092010-01-17 00:39:37 +00001510% S e t M a g i c k P r e c i s i o n %
1511% %
1512% %
1513% %
1514%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1515%
1516% SetMagickPrecision() sets the maximum number of significant digits to be
cristybf2766a2010-01-17 03:33:23 +00001517% printed and returns it.
cristye7f51092010-01-17 00:39:37 +00001518%
1519% The format of the SetMagickPrecision method is:
1520%
cristybf2766a2010-01-17 03:33:23 +00001521% int SetMagickPrecision(const int precision)
cristye7f51092010-01-17 00:39:37 +00001522%
1523% A description of each parameter follows:
1524%
1525% o precision: set the maximum number of significant digits to be printed.
1526%
1527*/
cristybf2766a2010-01-17 03:33:23 +00001528MagickExport int SetMagickPrecision(const int precision)
cristye7f51092010-01-17 00:39:37 +00001529{
cristybf2766a2010-01-17 03:33:23 +00001530 static int
1531 magick_precision = 0;
1532
cristye7f51092010-01-17 00:39:37 +00001533 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
cristybf2766a2010-01-17 03:33:23 +00001534 if (precision != 0)
1535 magick_precision=precision;
1536 return(magick_precision);
cristye7f51092010-01-17 00:39:37 +00001537}
1538
1539/*
1540%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1541% %
1542% %
1543% %
cristy3ed852e2009-09-05 21:47:34 +00001544+ U n r e g i s t e r M a g i c k I n f o %
1545% %
1546% %
1547% %
1548%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1549%
1550% UnregisterMagickInfo() removes a name from the magick info list. It returns
1551% MagickFalse if the name does not exist in the list otherwise MagickTrue.
1552%
1553% The format of the UnregisterMagickInfo method is:
1554%
1555% MagickBooleanType UnregisterMagickInfo(const char *name)
1556%
1557% A description of each parameter follows:
1558%
1559% o name: a character string that represents the image format we are
1560% looking for.
1561%
1562*/
1563MagickExport MagickBooleanType UnregisterMagickInfo(const char *name)
1564{
1565 register const MagickInfo
1566 *p;
1567
1568 MagickBooleanType
1569 status;
1570
1571 assert(name != (const char *) NULL);
1572 if (magick_list == (SplayTreeInfo *) NULL)
1573 return(MagickFalse);
1574 if (GetNumberOfNodesInSplayTree(magick_list) == 0)
1575 return(MagickFalse);
cristyf84a1932010-01-03 18:00:18 +00001576 LockSemaphoreInfo(magick_semaphore);
cristy3ed852e2009-09-05 21:47:34 +00001577 ResetSplayTreeIterator(magick_list);
1578 p=(const MagickInfo *) GetNextValueInSplayTree(magick_list);
1579 while (p != (const MagickInfo *) NULL)
1580 {
1581 if (LocaleCompare(p->name,name) == 0)
1582 break;
1583 p=(const MagickInfo *) GetNextValueInSplayTree(magick_list);
1584 }
1585 status=DeleteNodeByValueFromSplayTree(magick_list,p);
cristyf84a1932010-01-03 18:00:18 +00001586 UnlockSemaphoreInfo(magick_semaphore);
cristy3ed852e2009-09-05 21:47:34 +00001587 return(status);
1588}