blob: a8e7332ac2f3e7389284439714157c0975432918 [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% %
cristydf1cc5f2009-10-19 16:02:33 +0000127+ D e s t r o y M a g i c k C o m p o n e n t %
cristy3ed852e2009-09-05 21:47:34 +0000128% %
129% %
130% %
131%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
132%
cristydf1cc5f2009-10-19 16:02:33 +0000133% DestroyMagickComponent() destroys the magick component.
cristy3ed852e2009-09-05 21:47:34 +0000134%
cristydf1cc5f2009-10-19 16:02:33 +0000135% The format of the DestroyMagickComponent method is:
cristy3ed852e2009-09-05 21:47:34 +0000136%
cristydf1cc5f2009-10-19 16:02:33 +0000137% void DestroyMagickComponent(void)
cristy3ed852e2009-09-05 21:47:34 +0000138%
139*/
cristydf1cc5f2009-10-19 16:02:33 +0000140MagickExport void DestroyMagickComponent(void)
cristy3ed852e2009-09-05 21:47:34 +0000141{
142 AcquireSemaphoreInfo(&magick_semaphore);
143 if (magick_list != (SplayTreeInfo *) NULL)
144 magick_list=DestroySplayTree(magick_list);
145 instantiate_magick=MagickFalse;
146 RelinquishSemaphoreInfo(magick_semaphore);
147 DestroySemaphoreInfo(&magick_semaphore);
148#if !defined(MAGICKCORE_BUILD_MODULES)
149 UnregisterStaticModules();
150#endif
151#if defined(MAGICKCORE_MODULES_SUPPORT)
152 DestroyModuleList();
153#endif
154}
155
156/*
157%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
158% %
159% %
160% %
161+ G e t I m a g e D e c o d e r %
162% %
163% %
164% %
165%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
166%
167% GetImageDecoder() returns the image decoder.
168%
169% The format of the GetImageDecoder method is:
170%
171% DecodeImageHandler *GetImageDecoder(const MagickInfo *magick_info)
172%
173% A description of each parameter follows:
174%
175% o magick_info: The magick info.
176%
177*/
178MagickExport DecodeImageHandler *GetImageDecoder(const MagickInfo *magick_info)
179{
180 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
181 assert(magick_info != (MagickInfo *) NULL);
182 assert(magick_info->signature == MagickSignature);
183 return(magick_info->decoder);
184}
185
186/*
187%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
188% %
189% %
190% %
191+ G e t I m a g e E n c o d e r %
192% %
193% %
194% %
195%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
196%
197% GetImageEncoder() returns the image encoder.
198%
199% The format of the GetImageEncoder method is:
200%
201% EncodeImageHandler *GetImageEncoder(const MagickInfo *magick_info)
202%
203% A description of each parameter follows:
204%
205% o magick_info: The magick info.
206%
207*/
208MagickExport EncodeImageHandler *GetImageEncoder(const MagickInfo *magick_info)
209{
210 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
211 assert(magick_info != (MagickInfo *) NULL);
212 assert(magick_info->signature == MagickSignature);
213 return(magick_info->encoder);
214}
215
216/*
217%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
218% %
219% %
220% %
221+ G e t I m a g e M a g i c k %
222% %
223% %
224% %
225%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
226%
227% GetImageMagick() searches for an image format that matches the specified
228% magick string. If one is found, MagickTrue is returned otherwise
229% MagickFalse.
230%
231% The format of the GetImageMagick method is:
232%
233% MagickBooleanType GetImageMagick(const unsigned char *magick,
234% const size_t length,char *format)
235%
236% A description of each parameter follows:
237%
238% o magick: the image format we are searching for.
239%
240% o length: the length of the binary string.
241%
242% o format: the image format as determined by the magick bytes.
243%
244*/
245MagickExport MagickBooleanType GetImageMagick(const unsigned char *magick,
246 const size_t length,char *format)
247{
248 ExceptionInfo
249 *exception;
250
251 MagickBooleanType
252 status;
253
254 register const MagickInfo
255 *p;
256
257 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
258 assert(magick != (const unsigned char *) NULL);
259 exception=AcquireExceptionInfo();
260 p=GetMagickInfo("*",exception);
261 exception=DestroyExceptionInfo(exception);
262 if (p == (const MagickInfo *) NULL)
263 return(MagickFalse);
264 status=MagickFalse;
265 AcquireSemaphoreInfo(&magick_semaphore);
266 ResetSplayTreeIterator(magick_list);
267 p=(const MagickInfo *) GetNextValueInSplayTree(magick_list);
268 while (p != (const MagickInfo *) NULL)
269 {
270 if ((p->magick != (IsImageFormatHandler *) NULL) &&
271 (p->magick(magick,length) != 0))
272 {
273 status=MagickTrue;
274 (void) CopyMagickString(format,p->name,MaxTextExtent);
275 break;
276 }
277 p=(const MagickInfo *) GetNextValueInSplayTree(magick_list);
278 }
279 RelinquishSemaphoreInfo(magick_semaphore);
280 return(status);
281}
282
283/*
284%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
285% %
286% %
287% %
288+ G e t M a g i c k A d j o i n %
289% %
290% %
291% %
292%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
293%
294% GetMagickAdjoin() returns MagickTrue if the magick adjoin is MagickTrue.
295%
296% The format of the GetMagickAdjoin method is:
297%
298% MagickBooleanType GetMagickAdjoin(const MagickInfo *magick_info)
299%
300% A description of each parameter follows:
301%
302% o magick_info: The magick info.
303%
304*/
305MagickExport MagickBooleanType GetMagickAdjoin(const MagickInfo *magick_info)
306{
307 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
308 assert(magick_info != (MagickInfo *) NULL);
309 assert(magick_info->signature == MagickSignature);
310 return(magick_info->adjoin);
311}
312
313/*
314%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
315% %
316% %
317% %
318+ G e t M a g i c k B l o b S u p p o r t %
319% %
320% %
321% %
322%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
323%
324% GetMagickBlobSupport() returns MagickTrue if the magick supports blobs.
325%
326% The format of the GetMagickBlobSupport method is:
327%
328% MagickBooleanType GetMagickBlobSupport(const MagickInfo *magick_info)
329%
330% A description of each parameter follows:
331%
332% o magick_info: The magick info.
333%
334*/
335MagickExport MagickBooleanType GetMagickBlobSupport(
336 const MagickInfo *magick_info)
337{
338 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
339 assert(magick_info != (MagickInfo *) NULL);
340 assert(magick_info->signature == MagickSignature);
341 return(magick_info->blob_support);
342}
343
344/*
345%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
346% %
347% %
348% %
349+ G e t M a g i c k D e s c r i p t i o n %
350% %
351% %
352% %
353%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
354%
355% GetMagickDescription() returns the magick description.
356%
357% The format of the GetMagickDescription method is:
358%
359% const char *GetMagickDescription(const MagickInfo *magick_info)
360%
361% A description of each parameter follows:
362%
363% o magick_info: The magick info.
364%
365*/
366MagickExport const char *GetMagickDescription(const MagickInfo *magick_info)
367{
368 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
369 assert(magick_info != (MagickInfo *) NULL);
370 assert(magick_info->signature == MagickSignature);
371 return(magick_info->description);
372}
373
374/*
375%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
376% %
377% %
378% %
379+ G e t M a g i c k E n d i a n S u p p o r t %
380% %
381% %
382% %
383%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
384%
385% GetMagickEndianSupport() returns the MagickTrue if the coder respects
386% endianness other than MSBEndian.
387%
388% The format of the GetMagickEndianSupport method is:
389%
390% MagickBooleanType GetMagickEndianSupport(const MagickInfo *magick_info)
391%
392% A description of each parameter follows:
393%
394% o magick_info: The magick info.
395%
396*/
397MagickExport MagickBooleanType GetMagickEndianSupport(
398 const MagickInfo *magick_info)
399{
400 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
401 assert(magick_info != (MagickInfo *) NULL);
402 assert(magick_info->signature == MagickSignature);
403 return(magick_info->endian_support);
404}
405
406/*
407%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
408% %
409% %
410% %
411+ G e t M a g i c k I n f o %
412% %
413% %
414% %
415%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
416%
417% GetMagickInfo() returns a pointer MagickInfo structure that matches
418% the specified name. If name is NULL, the head of the image format list
419% is returned.
420%
421% The format of the GetMagickInfo method is:
422%
423% const MagickInfo *GetMagickInfo(const char *name,Exception *exception)
424%
425% A description of each parameter follows:
426%
427% o name: the image format we are looking for.
428%
429% o exception: return any errors or warnings in this structure.
430%
431*/
432MagickExport const MagickInfo *GetMagickInfo(const char *name,
433 ExceptionInfo *exception)
434{
435 register const MagickInfo
436 *p;
437
438 assert(exception != (ExceptionInfo *) NULL);
439 if ((magick_list == (SplayTreeInfo *) NULL) ||
440 (instantiate_magick == MagickFalse))
441 if (InitializeMagickList(exception) == MagickFalse)
442 return((const MagickInfo *) NULL);
443 if ((name == (const char *) NULL) || (LocaleCompare(name,"*") == 0))
444 {
445#if defined(MAGICKCORE_MODULES_SUPPORT)
446 if (LocaleCompare(name,"*") == 0)
447 (void) OpenModules(exception);
448#endif
449 AcquireSemaphoreInfo(&magick_semaphore);
450 ResetSplayTreeIterator(magick_list);
451 p=(const MagickInfo *) GetNextValueInSplayTree(magick_list);
452 RelinquishSemaphoreInfo(magick_semaphore);
453 return(p);
454 }
455 /*
456 Find name in list.
457 */
458 AcquireSemaphoreInfo(&magick_semaphore);
459 ResetSplayTreeIterator(magick_list);
460 p=(const MagickInfo *) GetNextValueInSplayTree(magick_list);
461 while (p != (const MagickInfo *) NULL)
462 {
463 if (LocaleCompare(p->name,name) == 0)
464 break;
465 p=(const MagickInfo *) GetNextValueInSplayTree(magick_list);
466 }
467#if defined(MAGICKCORE_MODULES_SUPPORT)
468 if (p == (const MagickInfo *) NULL)
469 {
470 if (*name != '\0')
471 (void) OpenModule(name,exception);
472 ResetSplayTreeIterator(magick_list);
473 p=(const MagickInfo *) GetNextValueInSplayTree(magick_list);
474 while (p != (const MagickInfo *) NULL)
475 {
476 if (LocaleCompare(p->name,name) == 0)
477 break;
478 p=(const MagickInfo *) GetNextValueInSplayTree(magick_list);
479 }
480 }
481#endif
482 RelinquishSemaphoreInfo(magick_semaphore);
483 return(p);
484}
485
486/*
487%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
488% %
489% %
490% %
491+ G e t M a g i c k I n f o L i s t %
492% %
493% %
494% %
495%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
496%
497% GetMagickInfoList() returns any image formats that match the specified
498% pattern.
499%
500% The format of the GetMagickInfoList function is:
501%
502% const MagickInfo **GetMagickInfoList(const char *pattern,
503% unsigned long *number_formats,ExceptionInfo *exception)
504%
505% A description of each parameter follows:
506%
507% o pattern: Specifies a pointer to a text string containing a pattern.
508%
509% o number_formats: This integer returns the number of formats in the list.
510%
511% o exception: return any errors or warnings in this structure.
512%
513*/
514
515#if defined(__cplusplus) || defined(c_plusplus)
516extern "C" {
517#endif
518
519static int MagickInfoCompare(const void *x,const void *y)
520{
521 const MagickInfo
522 **p,
523 **q;
524
525 p=(const MagickInfo **) x,
526 q=(const MagickInfo **) y;
527 return(LocaleCompare((*p)->name,(*q)->name));
528}
529
530#if defined(__cplusplus) || defined(c_plusplus)
531}
532#endif
533
534MagickExport const MagickInfo **GetMagickInfoList(const char *pattern,
535 unsigned long *number_formats,ExceptionInfo *exception)
536{
537 const MagickInfo
538 **formats;
539
540 register const MagickInfo
541 *p;
542
543 register long
544 i;
545
546 /*
547 Allocate magick list.
548 */
549 assert(pattern != (char *) NULL);
550 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",pattern);
551 assert(number_formats != (unsigned long *) NULL);
552 *number_formats=0;
553 p=GetMagickInfo("*",exception);
554 if (p == (const MagickInfo *) NULL)
555 return((const MagickInfo **) NULL);
556 formats=(const MagickInfo **) AcquireQuantumMemory((size_t)
557 GetNumberOfNodesInSplayTree(magick_list)+1UL,sizeof(*formats));
558 if (formats == (const MagickInfo **) NULL)
559 return((const MagickInfo **) NULL);
560 /*
561 Generate magick list.
562 */
563 AcquireSemaphoreInfo(&magick_semaphore);
564 ResetSplayTreeIterator(magick_list);
565 p=(const MagickInfo *) GetNextValueInSplayTree(magick_list);
566 for (i=0; p != (const MagickInfo *) NULL; )
567 {
568 if ((p->stealth == MagickFalse) &&
569 (GlobExpression(p->name,pattern,MagickFalse) != MagickFalse))
570 formats[i++]=p;
571 p=(const MagickInfo *) GetNextValueInSplayTree(magick_list);
572 }
573 RelinquishSemaphoreInfo(magick_semaphore);
574 qsort((void *) formats,(size_t) i,sizeof(*formats),MagickInfoCompare);
575 formats[i]=(MagickInfo *) NULL;
576 *number_formats=(unsigned long) i;
577 return(formats);
578}
579
580/*
581%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
582% %
583% %
584% %
585+ G e t M a g i c k L i s t %
586% %
587% %
588% %
589%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
590%
591% GetMagickList() returns any image formats that match the specified pattern.
592%
593% The format of the GetMagickList function is:
594%
595% char **GetMagickList(const char *pattern,unsigned long *number_formats,
596% ExceptionInfo *exception)
597%
598% A description of each parameter follows:
599%
600% o pattern: Specifies a pointer to a text string containing a pattern.
601%
602% o number_formats: This integer returns the number of formats in the list.
603%
604% o exception: return any errors or warnings in this structure.
605%
606*/
607
608#if defined(__cplusplus) || defined(c_plusplus)
609extern "C" {
610#endif
611
612static int MagickCompare(const void *x,const void *y)
613{
614 register const char
615 **p,
616 **q;
617
618 p=(const char **) x;
619 q=(const char **) y;
620 return(LocaleCompare(*p,*q));
621}
622
623#if defined(__cplusplus) || defined(c_plusplus)
624}
625#endif
626
627MagickExport char **GetMagickList(const char *pattern,
628 unsigned long *number_formats,ExceptionInfo *exception)
629{
630 char
631 **formats;
632
633 register const MagickInfo
634 *p;
635
636 register long
637 i;
638
639 /*
640 Allocate magick list.
641 */
642 assert(pattern != (char *) NULL);
643 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",pattern);
644 assert(number_formats != (unsigned long *) NULL);
645 *number_formats=0;
646 p=GetMagickInfo("*",exception);
647 if (p == (const MagickInfo *) NULL)
648 return((char **) NULL);
649 formats=(char **) AcquireQuantumMemory((size_t)
650 GetNumberOfNodesInSplayTree(magick_list)+1UL,sizeof(*formats));
651 if (formats == (char **) NULL)
652 return((char **) NULL);
653 AcquireSemaphoreInfo(&magick_semaphore);
654 ResetSplayTreeIterator(magick_list);
655 p=(const MagickInfo *) GetNextValueInSplayTree(magick_list);
656 for (i=0; p != (const MagickInfo *) NULL; )
657 {
658 if ((p->stealth == MagickFalse) &&
659 (GlobExpression(p->name,pattern,MagickFalse) != MagickFalse))
660 formats[i++]=ConstantString(p->name);
661 p=(const MagickInfo *) GetNextValueInSplayTree(magick_list);
662 }
663 RelinquishSemaphoreInfo(magick_semaphore);
664 qsort((void *) formats,(size_t) i,sizeof(*formats),MagickCompare);
665 formats[i]=(char *) NULL;
666 *number_formats=(unsigned long) i;
667 return(formats);
668}
669
670/*
671%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
672% %
673% %
674% %
675+ G e t M a g i c k E n d i a n S u p p o r t %
676% %
677% %
678% %
679%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
680%
681% GetMagickRawSupport() returns the MagickTrue if the coder is a raw format.
682%
683% The format of the GetMagickRawSupport method is:
684%
685% MagickBooleanType GetMagickRawSupport(const MagickInfo *magick_info)
686%
687% A description of each parameter follows:
688%
689% o magick_info: The magick info.
690%
691*/
692MagickExport MagickBooleanType GetMagickRawSupport(
693 const MagickInfo *magick_info)
694{
695 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
696 assert(magick_info != (MagickInfo *) NULL);
697 assert(magick_info->signature == MagickSignature);
698 return(magick_info->raw);
699}
700
701/*
702%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
703% %
704% %
705% %
706+ G e t M a g i c k S e e k a b l e S t r e a m %
707% %
708% %
709% %
710%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
711%
712% GetMagickSeekableStream() returns MagickTrue if the magick supports a
713% seekable stream.
714%
715% The format of the GetMagickSeekableStream method is:
716%
717% MagickBooleanType GetMagickSeekableStream(const MagickInfo *magick_info)
718%
719% A description of each parameter follows:
720%
721% o magick_info: The magick info.
722%
723*/
724MagickExport MagickBooleanType GetMagickSeekableStream(
725 const MagickInfo *magick_info)
726{
727 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
728 assert(magick_info != (MagickInfo *) NULL);
729 assert(magick_info->signature == MagickSignature);
730 return(magick_info->seekable_stream);
731}
732
733/*
734%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
735% %
736% %
737% %
738+ G e t M a g i c k T h r e a d S u p p o r t %
739% %
740% %
741% %
742%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
743%
744% GetMagickThreadSupport() returns MagickTrue if the magick supports threads.
745%
746% The format of the GetMagickThreadSupport method is:
747%
748% MagickStatusType GetMagickThreadSupport(const MagickInfo *magick_info)
749%
750% A description of each parameter follows:
751%
752% o magick_info: The magick info.
753%
754*/
755MagickExport MagickStatusType GetMagickThreadSupport(
756 const MagickInfo *magick_info)
757{
758 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
759 assert(magick_info != (MagickInfo *) NULL);
760 assert(magick_info->signature == MagickSignature);
761 return(magick_info->thread_support);
762}
763
764/*
765%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
766% %
767% %
768% %
769+ I n i t i a l i z e M a g i c k L i s t %
770% %
771% %
772% %
773%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
774%
775% InitializeMagickList() initializes the magick list.
776%
777% The format of the InitializeMagickList() method is:
778%
779% InitializeMagickList(Exceptioninfo *exception)
780%
781% A description of each parameter follows.
782%
783% o exception: return any errors or warnings in this structure.
784%
785*/
786
787static void *DestroyMagickNode(void *magick_info)
788{
789 register MagickInfo
790 *p;
791
792 p=(MagickInfo *) magick_info;
793 if (p->name != (char *) NULL)
794 p->name=DestroyString(p->name);
795 if (p->description != (char *) NULL)
796 p->description=DestroyString(p->description);
797 if (p->version != (char *) NULL)
798 p->version=DestroyString(p->version);
799 if (p->note != (char *) NULL)
800 p->note=DestroyString(p->note);
801 if (p->module != (char *) NULL)
802 p->module=DestroyString(p->module);
803 return(RelinquishMagickMemory(p));
804}
805
806static MagickBooleanType InitializeMagickList(ExceptionInfo *exception)
807{
cristyf2e11662009-10-14 01:24:43 +0000808 (void) exception;
cristy3ed852e2009-09-05 21:47:34 +0000809 if ((magick_list == (SplayTreeInfo *) NULL) &&
810 (instantiate_magick == MagickFalse))
811 {
812 AcquireSemaphoreInfo(&magick_semaphore);
813 if ((magick_list == (SplayTreeInfo *) NULL) &&
814 (instantiate_magick == MagickFalse))
815 {
816 MagickBooleanType
817 status;
818
819 MagickInfo
820 *magick_info;
821
822 magick_list=NewSplayTree(CompareSplayTreeString,
823 (void *(*)(void *)) NULL,DestroyMagickNode);
824 if (magick_list == (SplayTreeInfo *) NULL)
825 ThrowFatalException(ResourceLimitFatalError,
826 "MemoryAllocationFailed");
827 magick_info=SetMagickInfo("ephemeral");
828 magick_info->stealth=MagickTrue;
829 status=AddValueToSplayTree(magick_list,magick_info->name,magick_info);
830 if (status == MagickFalse)
831 ThrowFatalException(ResourceLimitFatalError,
832 "MemoryAllocationFailed");
833 magick_info=SetMagickInfo("clipmask");
834 magick_info->stealth=MagickTrue;
835 status=AddValueToSplayTree(magick_list,magick_info->name,magick_info);
836 if (status == MagickFalse)
837 {
838 char
839 *message;
840
841 message=GetExceptionMessage(errno);
842 ThrowFatalException(ResourceLimitFatalError,
843 "MemoryAllocationFailed");
844 message=DestroyString(message);
845 }
846#if defined(MAGICKCORE_MODULES_SUPPORT)
847 (void) GetModuleInfo((char *) NULL,exception);
848#endif
849#if !defined(MAGICKCORE_BUILD_MODULES)
850 RegisterStaticModules();
851#endif
852 instantiate_magick=MagickTrue;
853 }
854 RelinquishSemaphoreInfo(magick_semaphore);
855 }
856 return(magick_list != (SplayTreeInfo *) NULL ? MagickTrue : MagickFalse);
857}
858
859/*
860%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
861% %
862% %
863% %
cristydf1cc5f2009-10-19 16:02:33 +0000864+ I n s t a n t i a t e M a g i c k C o m p o n e n t %
cristy41c3c772009-10-19 02:17:37 +0000865% %
866% %
867% %
868%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
869%
cristydf1cc5f2009-10-19 16:02:33 +0000870% InstantiateMagickComponent() instantiates the magick component.
cristy41c3c772009-10-19 02:17:37 +0000871%
cristydf1cc5f2009-10-19 16:02:33 +0000872% The format of the InstantiateMagickComponent method is:
cristy41c3c772009-10-19 02:17:37 +0000873%
cristydf1cc5f2009-10-19 16:02:33 +0000874% MagickBooleanType InstantiateMagickComponent(void)
cristy41c3c772009-10-19 02:17:37 +0000875%
876*/
cristydf1cc5f2009-10-19 16:02:33 +0000877MagickExport MagickBooleanType InstantiateMagickComponent(void)
cristy41c3c772009-10-19 02:17:37 +0000878{
879 AcquireSemaphoreInfo(&magick_semaphore);
880 RelinquishSemaphoreInfo(magick_semaphore);
881 return(MagickTrue);
882}
883
884/*
885%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
886% %
887% %
888% %
cristy3ed852e2009-09-05 21:47:34 +0000889+ I s M a g i c k C o n f l i c t %
890% %
891% %
892% %
893%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
894%
895% IsMagickConflict() returns MagickTrue if the image format is not a valid
896% image format or conflicts with a logical drive (.e.g. X:).
897%
898% The format of the IsMagickConflict method is:
899%
900% MagickBooleanType IsMagickConflict(const char *magick)
901%
902% A description of each parameter follows:
903%
904% o magick: Specifies the image format.
905%
906*/
907MagickExport MagickBooleanType IsMagickConflict(const char *magick)
908{
909 const DelegateInfo
910 *delegate_info;
911
912 const MagickInfo
913 *magick_info;
914
915 ExceptionInfo
916 *exception;
917
918 assert(magick != (char *) NULL);
919 exception=AcquireExceptionInfo();
920 magick_info=GetMagickInfo(magick,exception);
921 delegate_info=GetDelegateInfo(magick,(char *) NULL,exception);
922 if (delegate_info == (const DelegateInfo *) NULL)
923 delegate_info=GetDelegateInfo((char *) NULL,magick,exception);
924 exception=DestroyExceptionInfo(exception);
925 if ((magick_info == (const MagickInfo *) NULL) &&
926 (delegate_info == (const DelegateInfo *) NULL))
927 return(MagickTrue);
928#if defined(macintosh)
929 return(MACIsMagickConflict(magick));
930#elif defined(vms)
931 return(VMSIsMagickConflict(magick));
932#elif defined(__WINDOWS__)
933 return(NTIsMagickConflict(magick));
934#else
935 return(MagickFalse);
936#endif
937}
938
939/*
940%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
941% %
942% %
943% %
944+ L i s t M a g i c k I n f o %
945% %
946% %
947% %
948%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
949%
950% ListMagickInfo() lists the image formats to a file.
951%
952% The format of the ListMagickInfo method is:
953%
954% MagickBooleanType ListMagickInfo(FILE *file,ExceptionInfo *exception)
955%
956% A description of each parameter follows.
957%
958% o file: A file handle.
959%
960% o exception: return any errors or warnings in this structure.
961%
962*/
963MagickExport MagickBooleanType ListMagickInfo(FILE *file,
964 ExceptionInfo *exception)
965{
966 const MagickInfo
967 **magick_info;
968
969 long
970 j;
971
972 register long
973 i;
974
975 unsigned long
976 number_formats;
977
978 if (file == (FILE *) NULL)
979 file=stdout;
980 magick_info=GetMagickInfoList("*",&number_formats,exception);
981 if (magick_info == (const MagickInfo **) NULL)
982 return(MagickFalse);
983 ClearMagickException(exception);
984#if !defined(MAGICKCORE_MODULES_SUPPORT)
985 (void) fprintf(file," Format Mode Description\n");
986#else
987 (void) fprintf(file," Format Module Mode Description\n");
988#endif
989 (void) fprintf(file,"--------------------------------------------------------"
990 "-----------------------\n");
991 for (i=0; i < (long) number_formats; i++)
992 {
993 if (magick_info[i]->stealth != MagickFalse)
994 continue;
995 (void) fprintf(file,"%9s%c ",magick_info[i]->name != (char *) NULL ?
996 magick_info[i]->name : "",
997 magick_info[i]->blob_support != MagickFalse ? '*' : ' ');
998#if defined(MAGICKCORE_MODULES_SUPPORT)
999 {
1000 char
1001 module[MaxTextExtent];
1002
1003 *module='\0';
1004 if (magick_info[i]->module != (char *) NULL)
1005 (void) CopyMagickString(module,magick_info[i]->module,MaxTextExtent);
1006 (void) ConcatenateMagickString(module," ",MaxTextExtent);
1007 module[9]='\0';
1008 (void) fprintf(file,"%9s ",module);
1009 }
1010#endif
1011 (void) fprintf(file,"%c%c%c ",magick_info[i]->decoder ? 'r' : '-',
1012 magick_info[i]->encoder ? 'w' : '-',magick_info[i]->encoder != NULL &&
1013 magick_info[i]->adjoin != MagickFalse ? '+' : '-');
1014 if (magick_info[i]->description != (char *) NULL)
1015 (void) fprintf(file," %s",magick_info[i]->description);
1016 if (magick_info[i]->version != (char *) NULL)
1017 (void) fprintf(file," (%s)",magick_info[i]->version);
1018 (void) fprintf(file,"\n");
1019 if (magick_info[i]->note != (char *) NULL)
1020 {
1021 char
1022 **text;
1023
1024 text=StringToList(magick_info[i]->note);
1025 if (text != (char **) NULL)
1026 {
1027 for (j=0; text[j] != (char *) NULL; j++)
1028 {
1029 (void) fprintf(file," %s\n",text[j]);
1030 text[j]=DestroyString(text[j]);
1031 }
1032 text=(char **) RelinquishMagickMemory(text);
1033 }
1034 }
1035 }
1036 (void) fprintf(file,"\n* native blob support\n");
1037 (void) fprintf(file,"r read support\n");
1038 (void) fprintf(file,"w write support\n");
1039 (void) fprintf(file,"+ support for multiple images\n");
1040 (void) fflush(file);
1041 magick_info=(const MagickInfo **) RelinquishMagickMemory((void *)
1042 magick_info);
1043 return(MagickTrue);
1044}
1045
1046/*
1047%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1048% %
1049% %
1050% %
1051% I s M a g i c k I n s t a n t i a t e d %
1052% %
1053% %
1054% %
1055%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1056%
1057% IsMagickInstantiated() returns MagickTrue if the ImageMagick environment
1058% is currently instantiated: MagickCoreGenesis() has been called but
1059% MagickDestroy() has not.
1060%
1061% The format of the IsMagickInstantiated method is:
1062%
1063% MagickBooleanType IsMagickInstantiated(void)
1064%
1065*/
1066MagickExport MagickBooleanType IsMagickInstantiated(void)
1067{
1068 return(instantiate_magick);
1069}
1070
1071/*
1072%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1073% %
1074% %
1075% %
1076% M a g i c k C o r e G e n e s i s %
1077% %
1078% %
1079% %
1080%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1081%
1082% MagickCoreGenesis() initializes the MagickCore environment.
1083%
1084% The format of the MagickCoreGenesis function is:
1085%
1086% MagickCoreGenesis(const char *path,
1087% const MagickBooleanType establish_signal_handlers)
1088%
1089% A description of each parameter follows:
1090%
1091% o path: the execution path of the current ImageMagick client.
1092%
1093% o establish_signal_handlers: set to MagickTrue to use MagickCore's own
1094% signal handlers for common signals.
1095%
1096*/
1097
1098static SignalHandler *SetMagickSignalHandler(int signal_number,
1099 SignalHandler *handler)
1100{
1101#if defined(MAGICKCORE_HAVE_SIGACTION) && defined(MAGICKCORE_HAVE_SIGEMPTYSET)
1102 int
1103 status;
1104
1105 sigset_t
1106 mask;
1107
1108 struct sigaction
1109 action,
1110 previous_action;
1111
1112 sigemptyset(&mask);
1113 sigaddset(&mask,signal_number);
1114 sigprocmask(SIG_BLOCK,&mask,NULL);
1115 action.sa_mask=mask;
1116 action.sa_handler=handler;
1117 action.sa_flags=0;
1118#if defined(SA_INTERRUPT)
1119 action.sa_flags|=SA_INTERRUPT;
1120#endif
1121 status=sigaction(signal_number,&action,&previous_action);
1122 if (status < 0)
1123 return(SIG_ERR);
1124 sigprocmask(SIG_UNBLOCK,&mask,NULL);
1125 return(previous_action.sa_handler);
1126#else
1127 return(signal(signal_number,handler));
1128#endif
1129}
1130
1131static void MagickSignalHandler(int signal_number)
1132{
1133#if !defined(MAGICKCORE_HAVE_SIGACTION)
1134 (void) signal(signal_number,SIG_IGN);
1135#endif
cristydf1cc5f2009-10-19 16:02:33 +00001136 AsynchronousDestroyResourceComponent();
cristy3ed852e2009-09-05 21:47:34 +00001137 instantiate_magick=MagickFalse;
1138 (void) SetMagickSignalHandler(signal_number,signal_handlers[signal_number]);
1139#if defined(MAGICKCORE_HAVE_RAISE)
1140 if (signal_handlers[signal_number] != MagickSignalHandler)
1141 raise(signal_number);
1142#endif
1143#if !defined(MAGICKCORE_HAVE__EXIT)
1144 exit(signal_number);
1145#else
1146#if defined(SIGHUP)
1147 if (signal_number == SIGHUP)
1148 exit(signal_number);
1149#endif
1150#if defined(SIGINT) && !defined(__WINDOWS__)
1151 if (signal_number == SIGINT)
1152 exit(signal_number);
1153#endif
1154#if defined(SIGTERM)
1155 if (signal_number == SIGTERM)
1156 exit(signal_number);
1157#endif
1158 _exit(signal_number);
1159#endif
1160}
1161
1162static SignalHandler *RegisterMagickSignalHandler(int signal_number)
1163{
1164 SignalHandler
1165 *handler;
1166
1167 handler=SetMagickSignalHandler(signal_number,MagickSignalHandler);
1168 if (handler == SIG_ERR)
1169 return(handler);
1170 if (handler != SIG_DFL)
1171 handler=SetMagickSignalHandler(signal_number,handler);
1172 else
1173 (void) LogMagickEvent(ConfigureEvent,GetMagickModule(),
1174 "Register handler for signal: %d",signal_number);
1175 return(handler);
1176}
1177
1178MagickExport void MagickCoreGenesis(const char *path,
1179 const MagickBooleanType establish_signal_handlers)
1180{
1181 char
1182 *events,
1183 execution_path[MaxTextExtent],
1184 filename[MaxTextExtent];
1185
1186 ExceptionInfo
1187 *exception;
1188
1189 time_t
1190 seconds;
1191
1192 /*
1193 Initialize the Magick environment.
1194 */
1195 (void) setlocale(LC_ALL,"");
1196 (void) setlocale(LC_NUMERIC,"C");
cristydf1cc5f2009-10-19 16:02:33 +00001197 (void) InstantiateSemaphoreComponent();
1198 (void) InstantiateLogComponent();
1199 (void) InstantiateLocaleComponent();
1200 (void) InstantiateRandomComponent();
cristy3ed852e2009-09-05 21:47:34 +00001201 seconds=time((time_t *) NULL);
1202 events=GetEnvironmentValue("MAGICK_DEBUG");
1203 if (events != (char *) NULL)
1204 {
1205 (void) SetLogEventMask(events);
1206 events=DestroyString(events);
1207 }
1208#if defined(__WINDOWS__)
1209#if defined(_DEBUG) && !defined(__BORLANDC__) && !defined(__MINGW32__)
1210 if (IsEventLogging() != MagickFalse)
1211 {
1212 int
1213 debug;
1214
1215 debug=_CrtSetDbgFlag(_CRTDBG_REPORT_FLAG);
1216 debug|=_CRTDBG_CHECK_ALWAYS_DF |_CRTDBG_DELAY_FREE_MEM_DF |
1217 _CRTDBG_LEAK_CHECK_DF;
1218 if (0)
1219 {
1220 debug=_CrtSetDbgFlag(debug);
1221 _ASSERTE(_CrtCheckMemory());
1222 }
1223 }
1224#endif
1225#endif
1226 /*
1227 Set client name and execution path.
1228 */
1229 (void) GetExecutionPath(execution_path,MaxTextExtent);
1230 if ((path != (const char *) NULL) && (*path != '\0'))
1231 (void) CopyMagickString(execution_path,path,MaxTextExtent);
1232 GetPathComponent(execution_path,TailPath,filename);
1233 (void) SetClientName(filename);
1234 GetPathComponent(execution_path,HeadPath,execution_path);
1235 (void) SetClientPath(execution_path);
1236 if (establish_signal_handlers != MagickFalse)
1237 {
1238 /*
1239 Set signal handlers.
1240 */
1241#if defined(SIGABRT)
1242 if (signal_handlers[SIGABRT] == (SignalHandler *) NULL)
1243 signal_handlers[SIGABRT]=RegisterMagickSignalHandler(SIGABRT);
1244#endif
1245#if defined(SIGFPE)
1246 if (signal_handlers[SIGFPE] == (SignalHandler *) NULL)
1247 signal_handlers[SIGFPE]=RegisterMagickSignalHandler(SIGFPE);
1248#endif
1249#if defined(SIGHUP)
1250 if (signal_handlers[SIGHUP] == (SignalHandler *) NULL)
1251 signal_handlers[SIGHUP]=RegisterMagickSignalHandler(SIGHUP);
1252#endif
1253#if defined(SIGINT) && !defined(__WINDOWS__)
1254 if (signal_handlers[SIGINT] == (SignalHandler *) NULL)
1255 signal_handlers[SIGINT]=RegisterMagickSignalHandler(SIGINT);
1256#endif
1257#if defined(SIGQUIT)
1258 if (signal_handlers[SIGQUIT] == (SignalHandler *) NULL)
1259 signal_handlers[SIGQUIT]=RegisterMagickSignalHandler(SIGQUIT);
1260#endif
1261#if defined(SIGTERM)
1262 if (signal_handlers[SIGTERM] == (SignalHandler *) NULL)
1263 signal_handlers[SIGTERM]=RegisterMagickSignalHandler(SIGTERM);
1264#endif
1265#if defined(SIGXCPU)
1266 if (signal_handlers[SIGXCPU] == (SignalHandler *) NULL)
1267 signal_handlers[SIGXCPU]=RegisterMagickSignalHandler(SIGXCPU);
1268#endif
1269#if defined(SIGXFSZ)
1270 if (signal_handlers[SIGXFSZ] == (SignalHandler *) NULL)
1271 signal_handlers[SIGXFSZ]=RegisterMagickSignalHandler(SIGXFSZ);
1272#endif
1273 }
1274 /*
1275 Initialize magick resources.
1276 */
cristydf1cc5f2009-10-19 16:02:33 +00001277 (void) InstantiatePolicyComponent();
1278 (void) InstantiateCacheComponent();
1279 (void) InstantiateRegistryComponent();
1280 (void) InstantiateResourcesComponent();
1281 (void) InstantiateCoderComponent();
1282 (void) InstantiateMagickComponent();
1283 (void) InstantiateModuleComponent();
1284 (void) InstantiateDelegateComponent();
1285 (void) InstantiateMagicComponent();
1286 (void) InstantiateColorComponent();
1287 (void) InstantiateTypeComponent();
1288 (void) InstantiateConfigureComponent();
1289 (void) InstantiateMimeComponent();
1290 (void) InstantiateConstituteComponent();
cristy3ed852e2009-09-05 21:47:34 +00001291 exception=AcquireExceptionInfo();
cristy498543d2009-10-11 03:14:50 +00001292#if defined(MAGICKCORE_MODULES_SUPPORT)
1293 InitializeModuleList(exception);
1294#endif
cristy3ed852e2009-09-05 21:47:34 +00001295 exception=DestroyExceptionInfo(exception);
cristydf1cc5f2009-10-19 16:02:33 +00001296 (void) InstantiateLogComponent();
cristy3ed852e2009-09-05 21:47:34 +00001297}
1298
1299/*
1300%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1301% %
1302% %
1303% %
1304% M a g i c k C o r e T e r m i n u s %
1305% %
1306% %
1307% %
1308%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1309%
1310% MagickCoreTerminus() destroys the MagickCore environment.
1311%
1312% The format of the DestroyMagick function is:
1313%
1314% MagickCoreTerminus(void)
1315%
1316*/
1317MagickExport void MagickCoreTerminus(void)
1318{
1319#if defined(MAGICKCORE_X11_DELEGATE)
1320 DestroyXResources();
1321#endif
cristydf1cc5f2009-10-19 16:02:33 +00001322 DestroyConstituteComponent();
1323 DestroyMimeComponent();
1324 DestroyConfigureComponent();
1325 DestroyTypeComponent();
1326 DestroyColorComponent();
cristy3ed852e2009-09-05 21:47:34 +00001327#if defined(__WINDOWS__)
1328 NTGhostscriptUnLoadDLL();
1329#endif
cristydf1cc5f2009-10-19 16:02:33 +00001330 DestroyMagicComponent();
1331 DestroyDelegateComponent();
1332 DestroyMagickComponent();
1333 DestroyCoderComponent();
1334 DestroyResourceComponent();
1335 DestroyRegistryComponent();
cristy41c3c772009-10-19 02:17:37 +00001336 DestroyCacheFaclity();
cristydf1cc5f2009-10-19 16:02:33 +00001337 DestroyPolicyComponent();
1338 DestroyRandomComponent();
1339 DestroyLocaleComponent();
1340 DestroyLogComponent();
1341 DestroySemaphoreComponent();
cristy3ed852e2009-09-05 21:47:34 +00001342 instantiate_magick=MagickFalse;
1343}
1344
1345/*
1346%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1347% %
1348% %
1349% %
1350+ R e g i s t e r M a g i c k I n f o %
1351% %
1352% %
1353% %
1354%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1355%
1356% RegisterMagickInfo() adds attributes for a particular image format to the
1357% list of supported formats. The attributes include the image format name,
1358% a method to read and/or write the format, whether the format supports the
1359% saving of more than one frame to the same file or blob, whether the format
1360% supports native in-memory I/O, and a brief description of the format.
1361%
1362% The format of the RegisterMagickInfo method is:
1363%
1364% MagickInfo *RegisterMagickInfo(MagickInfo *magick_info)
1365%
1366% A description of each parameter follows:
1367%
1368% o magick_info: the magick info.
1369%
1370*/
1371MagickExport MagickInfo *RegisterMagickInfo(MagickInfo *magick_info)
1372{
1373 MagickBooleanType
1374 status;
1375
1376 /*
1377 Delete any existing name.
1378 */
1379 assert(magick_info != (MagickInfo *) NULL);
1380 assert(magick_info->signature == MagickSignature);
1381 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",magick_info->name);
1382 if (magick_list == (SplayTreeInfo *) NULL)
1383 return((MagickInfo *) NULL);
1384 status=AddValueToSplayTree(magick_list,magick_info->name,magick_info);
1385 if (status == MagickFalse)
1386 ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed");
1387 return(magick_info);
1388}
1389
1390/*
1391%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1392% %
1393% %
1394% %
1395+ S e t M a g i c k I n f o %
1396% %
1397% %
1398% %
1399%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1400%
1401% SetMagickInfo() allocates a MagickInfo structure and initializes the members
1402% to default values.
1403%
1404% The format of the SetMagickInfo method is:
1405%
1406% MagickInfo *SetMagickInfo(const char *name)
1407%
1408% A description of each parameter follows:
1409%
1410% o magick_info: Method SetMagickInfo returns the allocated and initialized
1411% MagickInfo structure.
1412%
1413% o name: a character string that represents the image format associated
1414% with the MagickInfo structure.
1415%
1416*/
1417MagickExport MagickInfo *SetMagickInfo(const char *name)
1418{
1419 MagickInfo
1420 *magick_info;
1421
1422 assert(name != (const char *) NULL);
1423 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",name);
1424 magick_info=(MagickInfo *) AcquireMagickMemory(sizeof(*magick_info));
1425 if (magick_info == (MagickInfo *) NULL)
1426 ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed");
1427 (void) ResetMagickMemory(magick_info,0,sizeof(*magick_info));
1428 magick_info->name=ConstantString(name);
1429 magick_info->adjoin=MagickTrue;
1430 magick_info->blob_support=MagickTrue;
1431 magick_info->thread_support=(MagickStatusType) (DecoderThreadSupport |
1432 EncoderThreadSupport);
1433 magick_info->signature=MagickSignature;
1434 return(magick_info);
1435}
1436
1437/*
1438%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1439% %
1440% %
1441% %
1442+ U n r e g i s t e r M a g i c k I n f o %
1443% %
1444% %
1445% %
1446%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1447%
1448% UnregisterMagickInfo() removes a name from the magick info list. It returns
1449% MagickFalse if the name does not exist in the list otherwise MagickTrue.
1450%
1451% The format of the UnregisterMagickInfo method is:
1452%
1453% MagickBooleanType UnregisterMagickInfo(const char *name)
1454%
1455% A description of each parameter follows:
1456%
1457% o name: a character string that represents the image format we are
1458% looking for.
1459%
1460*/
1461MagickExport MagickBooleanType UnregisterMagickInfo(const char *name)
1462{
1463 register const MagickInfo
1464 *p;
1465
1466 MagickBooleanType
1467 status;
1468
1469 assert(name != (const char *) NULL);
1470 if (magick_list == (SplayTreeInfo *) NULL)
1471 return(MagickFalse);
1472 if (GetNumberOfNodesInSplayTree(magick_list) == 0)
1473 return(MagickFalse);
1474 AcquireSemaphoreInfo(&magick_semaphore);
1475 ResetSplayTreeIterator(magick_list);
1476 p=(const MagickInfo *) GetNextValueInSplayTree(magick_list);
1477 while (p != (const MagickInfo *) NULL)
1478 {
1479 if (LocaleCompare(p->name,name) == 0)
1480 break;
1481 p=(const MagickInfo *) GetNextValueInSplayTree(magick_list);
1482 }
1483 status=DeleteNodeByValueFromSplayTree(magick_list,p);
1484 RelinquishSemaphoreInfo(magick_semaphore);
1485 return(status);
1486}