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