blob: 3b03176f03df281ff2abe500e736ee39ed66cb49 [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% %
127+ D e s t r o y M a g i c k L i s t %
128% %
129% %
130% %
131%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
132%
133% DestroyMagickList() deallocates memory associated with the MagickInfo list.
134%
135% The format of the DestroyMagickList method is:
136%
137% void DestroyMagickList(void)
138%
139*/
140MagickExport void DestroyMagickList(void)
141{
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% %
864+ I s M a g i c k C o n f l i c t %
865% %
866% %
867% %
868%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
869%
870% IsMagickConflict() returns MagickTrue if the image format is not a valid
871% image format or conflicts with a logical drive (.e.g. X:).
872%
873% The format of the IsMagickConflict method is:
874%
875% MagickBooleanType IsMagickConflict(const char *magick)
876%
877% A description of each parameter follows:
878%
879% o magick: Specifies the image format.
880%
881*/
882MagickExport MagickBooleanType IsMagickConflict(const char *magick)
883{
884 const DelegateInfo
885 *delegate_info;
886
887 const MagickInfo
888 *magick_info;
889
890 ExceptionInfo
891 *exception;
892
893 assert(magick != (char *) NULL);
894 exception=AcquireExceptionInfo();
895 magick_info=GetMagickInfo(magick,exception);
896 delegate_info=GetDelegateInfo(magick,(char *) NULL,exception);
897 if (delegate_info == (const DelegateInfo *) NULL)
898 delegate_info=GetDelegateInfo((char *) NULL,magick,exception);
899 exception=DestroyExceptionInfo(exception);
900 if ((magick_info == (const MagickInfo *) NULL) &&
901 (delegate_info == (const DelegateInfo *) NULL))
902 return(MagickTrue);
903#if defined(macintosh)
904 return(MACIsMagickConflict(magick));
905#elif defined(vms)
906 return(VMSIsMagickConflict(magick));
907#elif defined(__WINDOWS__)
908 return(NTIsMagickConflict(magick));
909#else
910 return(MagickFalse);
911#endif
912}
913
914/*
915%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
916% %
917% %
918% %
919+ L i s t M a g i c k I n f o %
920% %
921% %
922% %
923%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
924%
925% ListMagickInfo() lists the image formats to a file.
926%
927% The format of the ListMagickInfo method is:
928%
929% MagickBooleanType ListMagickInfo(FILE *file,ExceptionInfo *exception)
930%
931% A description of each parameter follows.
932%
933% o file: A file handle.
934%
935% o exception: return any errors or warnings in this structure.
936%
937*/
938MagickExport MagickBooleanType ListMagickInfo(FILE *file,
939 ExceptionInfo *exception)
940{
941 const MagickInfo
942 **magick_info;
943
944 long
945 j;
946
947 register long
948 i;
949
950 unsigned long
951 number_formats;
952
953 if (file == (FILE *) NULL)
954 file=stdout;
955 magick_info=GetMagickInfoList("*",&number_formats,exception);
956 if (magick_info == (const MagickInfo **) NULL)
957 return(MagickFalse);
958 ClearMagickException(exception);
959#if !defined(MAGICKCORE_MODULES_SUPPORT)
960 (void) fprintf(file," Format Mode Description\n");
961#else
962 (void) fprintf(file," Format Module Mode Description\n");
963#endif
964 (void) fprintf(file,"--------------------------------------------------------"
965 "-----------------------\n");
966 for (i=0; i < (long) number_formats; i++)
967 {
968 if (magick_info[i]->stealth != MagickFalse)
969 continue;
970 (void) fprintf(file,"%9s%c ",magick_info[i]->name != (char *) NULL ?
971 magick_info[i]->name : "",
972 magick_info[i]->blob_support != MagickFalse ? '*' : ' ');
973#if defined(MAGICKCORE_MODULES_SUPPORT)
974 {
975 char
976 module[MaxTextExtent];
977
978 *module='\0';
979 if (magick_info[i]->module != (char *) NULL)
980 (void) CopyMagickString(module,magick_info[i]->module,MaxTextExtent);
981 (void) ConcatenateMagickString(module," ",MaxTextExtent);
982 module[9]='\0';
983 (void) fprintf(file,"%9s ",module);
984 }
985#endif
986 (void) fprintf(file,"%c%c%c ",magick_info[i]->decoder ? 'r' : '-',
987 magick_info[i]->encoder ? 'w' : '-',magick_info[i]->encoder != NULL &&
988 magick_info[i]->adjoin != MagickFalse ? '+' : '-');
989 if (magick_info[i]->description != (char *) NULL)
990 (void) fprintf(file," %s",magick_info[i]->description);
991 if (magick_info[i]->version != (char *) NULL)
992 (void) fprintf(file," (%s)",magick_info[i]->version);
993 (void) fprintf(file,"\n");
994 if (magick_info[i]->note != (char *) NULL)
995 {
996 char
997 **text;
998
999 text=StringToList(magick_info[i]->note);
1000 if (text != (char **) NULL)
1001 {
1002 for (j=0; text[j] != (char *) NULL; j++)
1003 {
1004 (void) fprintf(file," %s\n",text[j]);
1005 text[j]=DestroyString(text[j]);
1006 }
1007 text=(char **) RelinquishMagickMemory(text);
1008 }
1009 }
1010 }
1011 (void) fprintf(file,"\n* native blob support\n");
1012 (void) fprintf(file,"r read support\n");
1013 (void) fprintf(file,"w write support\n");
1014 (void) fprintf(file,"+ support for multiple images\n");
1015 (void) fflush(file);
1016 magick_info=(const MagickInfo **) RelinquishMagickMemory((void *)
1017 magick_info);
1018 return(MagickTrue);
1019}
1020
1021/*
1022%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1023% %
1024% %
1025% %
1026% I s M a g i c k I n s t a n t i a t e d %
1027% %
1028% %
1029% %
1030%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1031%
1032% IsMagickInstantiated() returns MagickTrue if the ImageMagick environment
1033% is currently instantiated: MagickCoreGenesis() has been called but
1034% MagickDestroy() has not.
1035%
1036% The format of the IsMagickInstantiated method is:
1037%
1038% MagickBooleanType IsMagickInstantiated(void)
1039%
1040*/
1041MagickExport MagickBooleanType IsMagickInstantiated(void)
1042{
1043 return(instantiate_magick);
1044}
1045
1046/*
1047%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1048% %
1049% %
1050% %
1051% M a g i c k C o r e G e n e s i s %
1052% %
1053% %
1054% %
1055%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1056%
1057% MagickCoreGenesis() initializes the MagickCore environment.
1058%
1059% The format of the MagickCoreGenesis function is:
1060%
1061% MagickCoreGenesis(const char *path,
1062% const MagickBooleanType establish_signal_handlers)
1063%
1064% A description of each parameter follows:
1065%
1066% o path: the execution path of the current ImageMagick client.
1067%
1068% o establish_signal_handlers: set to MagickTrue to use MagickCore's own
1069% signal handlers for common signals.
1070%
1071*/
1072
1073static SignalHandler *SetMagickSignalHandler(int signal_number,
1074 SignalHandler *handler)
1075{
1076#if defined(MAGICKCORE_HAVE_SIGACTION) && defined(MAGICKCORE_HAVE_SIGEMPTYSET)
1077 int
1078 status;
1079
1080 sigset_t
1081 mask;
1082
1083 struct sigaction
1084 action,
1085 previous_action;
1086
1087 sigemptyset(&mask);
1088 sigaddset(&mask,signal_number);
1089 sigprocmask(SIG_BLOCK,&mask,NULL);
1090 action.sa_mask=mask;
1091 action.sa_handler=handler;
1092 action.sa_flags=0;
1093#if defined(SA_INTERRUPT)
1094 action.sa_flags|=SA_INTERRUPT;
1095#endif
1096 status=sigaction(signal_number,&action,&previous_action);
1097 if (status < 0)
1098 return(SIG_ERR);
1099 sigprocmask(SIG_UNBLOCK,&mask,NULL);
1100 return(previous_action.sa_handler);
1101#else
1102 return(signal(signal_number,handler));
1103#endif
1104}
1105
1106static void MagickSignalHandler(int signal_number)
1107{
1108#if !defined(MAGICKCORE_HAVE_SIGACTION)
1109 (void) signal(signal_number,SIG_IGN);
1110#endif
1111 AsynchronousDestroyMagickResources();
1112 instantiate_magick=MagickFalse;
1113 (void) SetMagickSignalHandler(signal_number,signal_handlers[signal_number]);
1114#if defined(MAGICKCORE_HAVE_RAISE)
1115 if (signal_handlers[signal_number] != MagickSignalHandler)
1116 raise(signal_number);
1117#endif
1118#if !defined(MAGICKCORE_HAVE__EXIT)
1119 exit(signal_number);
1120#else
1121#if defined(SIGHUP)
1122 if (signal_number == SIGHUP)
1123 exit(signal_number);
1124#endif
1125#if defined(SIGINT) && !defined(__WINDOWS__)
1126 if (signal_number == SIGINT)
1127 exit(signal_number);
1128#endif
1129#if defined(SIGTERM)
1130 if (signal_number == SIGTERM)
1131 exit(signal_number);
1132#endif
1133 _exit(signal_number);
1134#endif
1135}
1136
1137static SignalHandler *RegisterMagickSignalHandler(int signal_number)
1138{
1139 SignalHandler
1140 *handler;
1141
1142 handler=SetMagickSignalHandler(signal_number,MagickSignalHandler);
1143 if (handler == SIG_ERR)
1144 return(handler);
1145 if (handler != SIG_DFL)
1146 handler=SetMagickSignalHandler(signal_number,handler);
1147 else
1148 (void) LogMagickEvent(ConfigureEvent,GetMagickModule(),
1149 "Register handler for signal: %d",signal_number);
1150 return(handler);
1151}
1152
1153MagickExport void MagickCoreGenesis(const char *path,
1154 const MagickBooleanType establish_signal_handlers)
1155{
1156 char
1157 *events,
1158 execution_path[MaxTextExtent],
1159 filename[MaxTextExtent];
1160
1161 ExceptionInfo
1162 *exception;
1163
1164 time_t
1165 seconds;
1166
1167 /*
1168 Initialize the Magick environment.
1169 */
1170 (void) setlocale(LC_ALL,"");
1171 (void) setlocale(LC_NUMERIC,"C");
1172 InitializeSemaphore();
1173 seconds=time((time_t *) NULL);
1174 events=GetEnvironmentValue("MAGICK_DEBUG");
1175 if (events != (char *) NULL)
1176 {
1177 (void) SetLogEventMask(events);
1178 events=DestroyString(events);
1179 }
1180#if defined(__WINDOWS__)
1181#if defined(_DEBUG) && !defined(__BORLANDC__) && !defined(__MINGW32__)
1182 if (IsEventLogging() != MagickFalse)
1183 {
1184 int
1185 debug;
1186
1187 debug=_CrtSetDbgFlag(_CRTDBG_REPORT_FLAG);
1188 debug|=_CRTDBG_CHECK_ALWAYS_DF |_CRTDBG_DELAY_FREE_MEM_DF |
1189 _CRTDBG_LEAK_CHECK_DF;
1190 if (0)
1191 {
1192 debug=_CrtSetDbgFlag(debug);
1193 _ASSERTE(_CrtCheckMemory());
1194 }
1195 }
1196#endif
1197#endif
1198 /*
1199 Set client name and execution path.
1200 */
1201 (void) GetExecutionPath(execution_path,MaxTextExtent);
1202 if ((path != (const char *) NULL) && (*path != '\0'))
1203 (void) CopyMagickString(execution_path,path,MaxTextExtent);
1204 GetPathComponent(execution_path,TailPath,filename);
1205 (void) SetClientName(filename);
1206 GetPathComponent(execution_path,HeadPath,execution_path);
1207 (void) SetClientPath(execution_path);
1208 if (establish_signal_handlers != MagickFalse)
1209 {
1210 /*
1211 Set signal handlers.
1212 */
1213#if defined(SIGABRT)
1214 if (signal_handlers[SIGABRT] == (SignalHandler *) NULL)
1215 signal_handlers[SIGABRT]=RegisterMagickSignalHandler(SIGABRT);
1216#endif
1217#if defined(SIGFPE)
1218 if (signal_handlers[SIGFPE] == (SignalHandler *) NULL)
1219 signal_handlers[SIGFPE]=RegisterMagickSignalHandler(SIGFPE);
1220#endif
1221#if defined(SIGHUP)
1222 if (signal_handlers[SIGHUP] == (SignalHandler *) NULL)
1223 signal_handlers[SIGHUP]=RegisterMagickSignalHandler(SIGHUP);
1224#endif
1225#if defined(SIGINT) && !defined(__WINDOWS__)
1226 if (signal_handlers[SIGINT] == (SignalHandler *) NULL)
1227 signal_handlers[SIGINT]=RegisterMagickSignalHandler(SIGINT);
1228#endif
1229#if defined(SIGQUIT)
1230 if (signal_handlers[SIGQUIT] == (SignalHandler *) NULL)
1231 signal_handlers[SIGQUIT]=RegisterMagickSignalHandler(SIGQUIT);
1232#endif
1233#if defined(SIGTERM)
1234 if (signal_handlers[SIGTERM] == (SignalHandler *) NULL)
1235 signal_handlers[SIGTERM]=RegisterMagickSignalHandler(SIGTERM);
1236#endif
1237#if defined(SIGXCPU)
1238 if (signal_handlers[SIGXCPU] == (SignalHandler *) NULL)
1239 signal_handlers[SIGXCPU]=RegisterMagickSignalHandler(SIGXCPU);
1240#endif
1241#if defined(SIGXFSZ)
1242 if (signal_handlers[SIGXFSZ] == (SignalHandler *) NULL)
1243 signal_handlers[SIGXFSZ]=RegisterMagickSignalHandler(SIGXFSZ);
1244#endif
1245 }
1246 /*
1247 Initialize magick resources.
1248 */
1249 InitializeMagickResources();
1250 exception=AcquireExceptionInfo();
cristy498543d2009-10-11 03:14:50 +00001251#if defined(MAGICKCORE_MODULES_SUPPORT)
1252 InitializeModuleList(exception);
1253#endif
cristy3ed852e2009-09-05 21:47:34 +00001254 exception=DestroyExceptionInfo(exception);
1255}
1256
1257/*
1258%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1259% %
1260% %
1261% %
1262% M a g i c k C o r e T e r m i n u s %
1263% %
1264% %
1265% %
1266%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1267%
1268% MagickCoreTerminus() destroys the MagickCore environment.
1269%
1270% The format of the DestroyMagick function is:
1271%
1272% MagickCoreTerminus(void)
1273%
1274*/
1275MagickExport void MagickCoreTerminus(void)
1276{
1277#if defined(MAGICKCORE_X11_DELEGATE)
1278 DestroyXResources();
1279#endif
1280 DestroyConstitute();
1281 DestroyMimeList();
1282 DestroyConfigureList();
1283 DestroyTypeList();
1284 DestroyColorList();
1285#if defined(__WINDOWS__)
1286 NTGhostscriptUnLoadDLL();
1287#endif
1288 DestroyMagicList();
1289 DestroyDelegateList();
1290 DestroyMagickList();
1291 DestroyCoderList();
1292 DestroyMagickResources();
1293 DestroyImageRegistry();
1294 DestroyPixelCacheResources();
1295 DestroyPolicyList();
1296 DestroyRandomReservoir();
1297 DestroyLocaleList();
1298 DestroyLogList();
1299 instantiate_magick=MagickFalse;
1300}
1301
1302/*
1303%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1304% %
1305% %
1306% %
1307+ R e g i s t e r M a g i c k I n f o %
1308% %
1309% %
1310% %
1311%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1312%
1313% RegisterMagickInfo() adds attributes for a particular image format to the
1314% list of supported formats. The attributes include the image format name,
1315% a method to read and/or write the format, whether the format supports the
1316% saving of more than one frame to the same file or blob, whether the format
1317% supports native in-memory I/O, and a brief description of the format.
1318%
1319% The format of the RegisterMagickInfo method is:
1320%
1321% MagickInfo *RegisterMagickInfo(MagickInfo *magick_info)
1322%
1323% A description of each parameter follows:
1324%
1325% o magick_info: the magick info.
1326%
1327*/
1328MagickExport MagickInfo *RegisterMagickInfo(MagickInfo *magick_info)
1329{
1330 MagickBooleanType
1331 status;
1332
1333 /*
1334 Delete any existing name.
1335 */
1336 assert(magick_info != (MagickInfo *) NULL);
1337 assert(magick_info->signature == MagickSignature);
1338 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",magick_info->name);
1339 if (magick_list == (SplayTreeInfo *) NULL)
1340 return((MagickInfo *) NULL);
1341 status=AddValueToSplayTree(magick_list,magick_info->name,magick_info);
1342 if (status == MagickFalse)
1343 ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed");
1344 return(magick_info);
1345}
1346
1347/*
1348%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1349% %
1350% %
1351% %
1352+ S e t M a g i c k I n f o %
1353% %
1354% %
1355% %
1356%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1357%
1358% SetMagickInfo() allocates a MagickInfo structure and initializes the members
1359% to default values.
1360%
1361% The format of the SetMagickInfo method is:
1362%
1363% MagickInfo *SetMagickInfo(const char *name)
1364%
1365% A description of each parameter follows:
1366%
1367% o magick_info: Method SetMagickInfo returns the allocated and initialized
1368% MagickInfo structure.
1369%
1370% o name: a character string that represents the image format associated
1371% with the MagickInfo structure.
1372%
1373*/
1374MagickExport MagickInfo *SetMagickInfo(const char *name)
1375{
1376 MagickInfo
1377 *magick_info;
1378
1379 assert(name != (const char *) NULL);
1380 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",name);
1381 magick_info=(MagickInfo *) AcquireMagickMemory(sizeof(*magick_info));
1382 if (magick_info == (MagickInfo *) NULL)
1383 ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed");
1384 (void) ResetMagickMemory(magick_info,0,sizeof(*magick_info));
1385 magick_info->name=ConstantString(name);
1386 magick_info->adjoin=MagickTrue;
1387 magick_info->blob_support=MagickTrue;
1388 magick_info->thread_support=(MagickStatusType) (DecoderThreadSupport |
1389 EncoderThreadSupport);
1390 magick_info->signature=MagickSignature;
1391 return(magick_info);
1392}
1393
1394/*
1395%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1396% %
1397% %
1398% %
1399+ U n r e g i s t e r M a g i c k I n f o %
1400% %
1401% %
1402% %
1403%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1404%
1405% UnregisterMagickInfo() removes a name from the magick info list. It returns
1406% MagickFalse if the name does not exist in the list otherwise MagickTrue.
1407%
1408% The format of the UnregisterMagickInfo method is:
1409%
1410% MagickBooleanType UnregisterMagickInfo(const char *name)
1411%
1412% A description of each parameter follows:
1413%
1414% o name: a character string that represents the image format we are
1415% looking for.
1416%
1417*/
1418MagickExport MagickBooleanType UnregisterMagickInfo(const char *name)
1419{
1420 register const MagickInfo
1421 *p;
1422
1423 MagickBooleanType
1424 status;
1425
1426 assert(name != (const char *) NULL);
1427 if (magick_list == (SplayTreeInfo *) NULL)
1428 return(MagickFalse);
1429 if (GetNumberOfNodesInSplayTree(magick_list) == 0)
1430 return(MagickFalse);
1431 AcquireSemaphoreInfo(&magick_semaphore);
1432 ResetSplayTreeIterator(magick_list);
1433 p=(const MagickInfo *) GetNextValueInSplayTree(magick_list);
1434 while (p != (const MagickInfo *) NULL)
1435 {
1436 if (LocaleCompare(p->name,name) == 0)
1437 break;
1438 p=(const MagickInfo *) GetNextValueInSplayTree(magick_list);
1439 }
1440 status=DeleteNodeByValueFromSplayTree(magick_list,p);
1441 RelinquishSemaphoreInfo(magick_semaphore);
1442 return(status);
1443}