2 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
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 %
13 % Methods to Read or List ImageMagick Image formats %
21 % Copyright 1999-2009 ImageMagick Studio LLC, a non-profit organization %
22 % dedicated to making software imaging solutions freely available. %
24 % You may not use this file except in compliance with the License. You may %
25 % obtain a copy of the License at %
27 % http://www.imagemagick.org/script/license.php %
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. %
35 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
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"
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"
82 #if !defined(MAGICKCORE_RETSIGTYPE)
83 # define MAGICKCORE_RETSIGTYPE void
86 # define SIG_DFL ((SignalHandler *) 0)
89 # define SIG_ERR ((SignalHandler *) -1)
98 typedef MAGICKCORE_RETSIGTYPE
105 *magick_semaphore = (SemaphoreInfo *) NULL;
108 *signal_handlers[SIGMAX] = { (SignalHandler *) NULL };
111 *magick_list = (SplayTreeInfo *) NULL;
113 static volatile MagickBooleanType
114 instantiate_magick = MagickFalse; /* double-checked locking pattern */
117 Forward declarations.
119 static MagickBooleanType
120 InitializeMagickList(ExceptionInfo *);
123 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
127 + D e s t r o y M a g i c k L i s t %
131 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
133 % DestroyMagickList() deallocates memory associated with the MagickInfo list.
135 % The format of the DestroyMagickList method is:
137 % void DestroyMagickList(void)
140 MagickExport void DestroyMagickList(void)
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();
151 #if defined(MAGICKCORE_MODULES_SUPPORT)
157 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
161 + G e t I m a g e D e c o d e r %
165 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
167 % GetImageDecoder() returns the image decoder.
169 % The format of the GetImageDecoder method is:
171 % DecodeImageHandler *GetImageDecoder(const MagickInfo *magick_info)
173 % A description of each parameter follows:
175 % o magick_info: The magick info.
178 MagickExport DecodeImageHandler *GetImageDecoder(const MagickInfo *magick_info)
180 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
181 assert(magick_info != (MagickInfo *) NULL);
182 assert(magick_info->signature == MagickSignature);
183 return(magick_info->decoder);
187 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
191 + G e t I m a g e E n c o d e r %
195 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
197 % GetImageEncoder() returns the image encoder.
199 % The format of the GetImageEncoder method is:
201 % EncodeImageHandler *GetImageEncoder(const MagickInfo *magick_info)
203 % A description of each parameter follows:
205 % o magick_info: The magick info.
208 MagickExport EncodeImageHandler *GetImageEncoder(const MagickInfo *magick_info)
210 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
211 assert(magick_info != (MagickInfo *) NULL);
212 assert(magick_info->signature == MagickSignature);
213 return(magick_info->encoder);
217 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
221 + G e t I m a g e M a g i c k %
225 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
227 % GetImageMagick() searches for an image format that matches the specified
228 % magick string. If one is found, MagickTrue is returned otherwise
231 % The format of the GetImageMagick method is:
233 % MagickBooleanType GetImageMagick(const unsigned char *magick,
234 % const size_t length,char *format)
236 % A description of each parameter follows:
238 % o magick: the image format we are searching for.
240 % o length: the length of the binary string.
242 % o format: the image format as determined by the magick bytes.
245 MagickExport MagickBooleanType GetImageMagick(const unsigned char *magick,
246 const size_t length,char *format)
254 register const MagickInfo
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)
265 AcquireSemaphoreInfo(&magick_semaphore);
266 ResetSplayTreeIterator(magick_list);
267 p=(const MagickInfo *) GetNextValueInSplayTree(magick_list);
268 while (p != (const MagickInfo *) NULL)
270 if ((p->magick != (IsImageFormatHandler *) NULL) &&
271 (p->magick(magick,length) != 0))
274 (void) CopyMagickString(format,p->name,MaxTextExtent);
277 p=(const MagickInfo *) GetNextValueInSplayTree(magick_list);
279 RelinquishSemaphoreInfo(magick_semaphore);
284 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
288 + G e t M a g i c k A d j o i n %
292 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
294 % GetMagickAdjoin() returns MagickTrue if the magick adjoin is MagickTrue.
296 % The format of the GetMagickAdjoin method is:
298 % MagickBooleanType GetMagickAdjoin(const MagickInfo *magick_info)
300 % A description of each parameter follows:
302 % o magick_info: The magick info.
305 MagickExport MagickBooleanType GetMagickAdjoin(const MagickInfo *magick_info)
307 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
308 assert(magick_info != (MagickInfo *) NULL);
309 assert(magick_info->signature == MagickSignature);
310 return(magick_info->adjoin);
314 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
318 + G e t M a g i c k B l o b S u p p o r t %
322 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
324 % GetMagickBlobSupport() returns MagickTrue if the magick supports blobs.
326 % The format of the GetMagickBlobSupport method is:
328 % MagickBooleanType GetMagickBlobSupport(const MagickInfo *magick_info)
330 % A description of each parameter follows:
332 % o magick_info: The magick info.
335 MagickExport MagickBooleanType GetMagickBlobSupport(
336 const MagickInfo *magick_info)
338 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
339 assert(magick_info != (MagickInfo *) NULL);
340 assert(magick_info->signature == MagickSignature);
341 return(magick_info->blob_support);
345 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
349 + G e t M a g i c k D e s c r i p t i o n %
353 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
355 % GetMagickDescription() returns the magick description.
357 % The format of the GetMagickDescription method is:
359 % const char *GetMagickDescription(const MagickInfo *magick_info)
361 % A description of each parameter follows:
363 % o magick_info: The magick info.
366 MagickExport const char *GetMagickDescription(const MagickInfo *magick_info)
368 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
369 assert(magick_info != (MagickInfo *) NULL);
370 assert(magick_info->signature == MagickSignature);
371 return(magick_info->description);
375 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
379 + G e t M a g i c k E n d i a n S u p p o r t %
383 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
385 % GetMagickEndianSupport() returns the MagickTrue if the coder respects
386 % endianness other than MSBEndian.
388 % The format of the GetMagickEndianSupport method is:
390 % MagickBooleanType GetMagickEndianSupport(const MagickInfo *magick_info)
392 % A description of each parameter follows:
394 % o magick_info: The magick info.
397 MagickExport MagickBooleanType GetMagickEndianSupport(
398 const MagickInfo *magick_info)
400 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
401 assert(magick_info != (MagickInfo *) NULL);
402 assert(magick_info->signature == MagickSignature);
403 return(magick_info->endian_support);
407 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
411 + G e t M a g i c k I n f o %
415 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
417 % GetMagickInfo() returns a pointer MagickInfo structure that matches
418 % the specified name. If name is NULL, the head of the image format list
421 % The format of the GetMagickInfo method is:
423 % const MagickInfo *GetMagickInfo(const char *name,Exception *exception)
425 % A description of each parameter follows:
427 % o name: the image format we are looking for.
429 % o exception: return any errors or warnings in this structure.
432 MagickExport const MagickInfo *GetMagickInfo(const char *name,
433 ExceptionInfo *exception)
435 register const MagickInfo
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))
445 #if defined(MAGICKCORE_MODULES_SUPPORT)
446 if (LocaleCompare(name,"*") == 0)
447 (void) OpenModules(exception);
449 AcquireSemaphoreInfo(&magick_semaphore);
450 ResetSplayTreeIterator(magick_list);
451 p=(const MagickInfo *) GetNextValueInSplayTree(magick_list);
452 RelinquishSemaphoreInfo(magick_semaphore);
458 AcquireSemaphoreInfo(&magick_semaphore);
459 ResetSplayTreeIterator(magick_list);
460 p=(const MagickInfo *) GetNextValueInSplayTree(magick_list);
461 while (p != (const MagickInfo *) NULL)
463 if (LocaleCompare(p->name,name) == 0)
465 p=(const MagickInfo *) GetNextValueInSplayTree(magick_list);
467 #if defined(MAGICKCORE_MODULES_SUPPORT)
468 if (p == (const MagickInfo *) NULL)
471 (void) OpenModule(name,exception);
472 ResetSplayTreeIterator(magick_list);
473 p=(const MagickInfo *) GetNextValueInSplayTree(magick_list);
474 while (p != (const MagickInfo *) NULL)
476 if (LocaleCompare(p->name,name) == 0)
478 p=(const MagickInfo *) GetNextValueInSplayTree(magick_list);
482 RelinquishSemaphoreInfo(magick_semaphore);
487 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
491 + G e t M a g i c k I n f o L i s t %
495 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
497 % GetMagickInfoList() returns any image formats that match the specified
500 % The format of the GetMagickInfoList function is:
502 % const MagickInfo **GetMagickInfoList(const char *pattern,
503 % unsigned long *number_formats,ExceptionInfo *exception)
505 % A description of each parameter follows:
507 % o pattern: Specifies a pointer to a text string containing a pattern.
509 % o number_formats: This integer returns the number of formats in the list.
511 % o exception: return any errors or warnings in this structure.
515 #if defined(__cplusplus) || defined(c_plusplus)
519 static int MagickInfoCompare(const void *x,const void *y)
525 p=(const MagickInfo **) x,
526 q=(const MagickInfo **) y;
527 return(LocaleCompare((*p)->name,(*q)->name));
530 #if defined(__cplusplus) || defined(c_plusplus)
534 MagickExport const MagickInfo **GetMagickInfoList(const char *pattern,
535 unsigned long *number_formats,ExceptionInfo *exception)
540 register const MagickInfo
547 Allocate magick list.
549 assert(pattern != (char *) NULL);
550 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",pattern);
551 assert(number_formats != (unsigned long *) NULL);
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);
561 Generate magick list.
563 AcquireSemaphoreInfo(&magick_semaphore);
564 ResetSplayTreeIterator(magick_list);
565 p=(const MagickInfo *) GetNextValueInSplayTree(magick_list);
566 for (i=0; p != (const MagickInfo *) NULL; )
568 if ((p->stealth == MagickFalse) &&
569 (GlobExpression(p->name,pattern,MagickFalse) != MagickFalse))
571 p=(const MagickInfo *) GetNextValueInSplayTree(magick_list);
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;
581 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
585 + G e t M a g i c k L i s t %
589 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
591 % GetMagickList() returns any image formats that match the specified pattern.
593 % The format of the GetMagickList function is:
595 % char **GetMagickList(const char *pattern,unsigned long *number_formats,
596 % ExceptionInfo *exception)
598 % A description of each parameter follows:
600 % o pattern: Specifies a pointer to a text string containing a pattern.
602 % o number_formats: This integer returns the number of formats in the list.
604 % o exception: return any errors or warnings in this structure.
608 #if defined(__cplusplus) || defined(c_plusplus)
612 static int MagickCompare(const void *x,const void *y)
620 return(LocaleCompare(*p,*q));
623 #if defined(__cplusplus) || defined(c_plusplus)
627 MagickExport char **GetMagickList(const char *pattern,
628 unsigned long *number_formats,ExceptionInfo *exception)
633 register const MagickInfo
640 Allocate magick list.
642 assert(pattern != (char *) NULL);
643 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",pattern);
644 assert(number_formats != (unsigned long *) NULL);
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; )
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);
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;
671 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
675 + G e t M a g i c k E n d i a n S u p p o r t %
679 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
681 % GetMagickRawSupport() returns the MagickTrue if the coder is a raw format.
683 % The format of the GetMagickRawSupport method is:
685 % MagickBooleanType GetMagickRawSupport(const MagickInfo *magick_info)
687 % A description of each parameter follows:
689 % o magick_info: The magick info.
692 MagickExport MagickBooleanType GetMagickRawSupport(
693 const MagickInfo *magick_info)
695 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
696 assert(magick_info != (MagickInfo *) NULL);
697 assert(magick_info->signature == MagickSignature);
698 return(magick_info->raw);
702 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
706 + G e t M a g i c k S e e k a b l e S t r e a m %
710 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
712 % GetMagickSeekableStream() returns MagickTrue if the magick supports a
715 % The format of the GetMagickSeekableStream method is:
717 % MagickBooleanType GetMagickSeekableStream(const MagickInfo *magick_info)
719 % A description of each parameter follows:
721 % o magick_info: The magick info.
724 MagickExport MagickBooleanType GetMagickSeekableStream(
725 const MagickInfo *magick_info)
727 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
728 assert(magick_info != (MagickInfo *) NULL);
729 assert(magick_info->signature == MagickSignature);
730 return(magick_info->seekable_stream);
734 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
738 + G e t M a g i c k T h r e a d S u p p o r t %
742 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
744 % GetMagickThreadSupport() returns MagickTrue if the magick supports threads.
746 % The format of the GetMagickThreadSupport method is:
748 % MagickStatusType GetMagickThreadSupport(const MagickInfo *magick_info)
750 % A description of each parameter follows:
752 % o magick_info: The magick info.
755 MagickExport MagickStatusType GetMagickThreadSupport(
756 const MagickInfo *magick_info)
758 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
759 assert(magick_info != (MagickInfo *) NULL);
760 assert(magick_info->signature == MagickSignature);
761 return(magick_info->thread_support);
765 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
769 + I n i t i a l i z e M a g i c k L i s t %
773 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
775 % InitializeMagickList() initializes the magick list.
777 % The format of the InitializeMagickList() method is:
779 % InitializeMagickList(Exceptioninfo *exception)
781 % A description of each parameter follows.
783 % o exception: return any errors or warnings in this structure.
787 static void *DestroyMagickNode(void *magick_info)
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));
806 static MagickBooleanType InitializeMagickList(ExceptionInfo *exception)
809 if ((magick_list == (SplayTreeInfo *) NULL) &&
810 (instantiate_magick == MagickFalse))
812 AcquireSemaphoreInfo(&magick_semaphore);
813 if ((magick_list == (SplayTreeInfo *) NULL) &&
814 (instantiate_magick == MagickFalse))
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)
841 message=GetExceptionMessage(errno);
842 ThrowFatalException(ResourceLimitFatalError,
843 "MemoryAllocationFailed");
844 message=DestroyString(message);
846 #if defined(MAGICKCORE_MODULES_SUPPORT)
847 (void) GetModuleInfo((char *) NULL,exception);
849 #if !defined(MAGICKCORE_BUILD_MODULES)
850 RegisterStaticModules();
852 instantiate_magick=MagickTrue;
854 RelinquishSemaphoreInfo(magick_semaphore);
856 return(magick_list != (SplayTreeInfo *) NULL ? MagickTrue : MagickFalse);
860 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
864 + I s M a g i c k C o n f l i c t %
868 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
870 % IsMagickConflict() returns MagickTrue if the image format is not a valid
871 % image format or conflicts with a logical drive (.e.g. X:).
873 % The format of the IsMagickConflict method is:
875 % MagickBooleanType IsMagickConflict(const char *magick)
877 % A description of each parameter follows:
879 % o magick: Specifies the image format.
882 MagickExport MagickBooleanType IsMagickConflict(const char *magick)
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))
903 #if defined(macintosh)
904 return(MACIsMagickConflict(magick));
906 return(VMSIsMagickConflict(magick));
907 #elif defined(__WINDOWS__)
908 return(NTIsMagickConflict(magick));
915 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
919 + L i s t M a g i c k I n f o %
923 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
925 % ListMagickInfo() lists the image formats to a file.
927 % The format of the ListMagickInfo method is:
929 % MagickBooleanType ListMagickInfo(FILE *file,ExceptionInfo *exception)
931 % A description of each parameter follows.
933 % o file: A file handle.
935 % o exception: return any errors or warnings in this structure.
938 MagickExport MagickBooleanType ListMagickInfo(FILE *file,
939 ExceptionInfo *exception)
953 if (file == (FILE *) NULL)
955 magick_info=GetMagickInfoList("*",&number_formats,exception);
956 if (magick_info == (const MagickInfo **) NULL)
958 ClearMagickException(exception);
959 #if !defined(MAGICKCORE_MODULES_SUPPORT)
960 (void) fprintf(file," Format Mode Description\n");
962 (void) fprintf(file," Format Module Mode Description\n");
964 (void) fprintf(file,"--------------------------------------------------------"
965 "-----------------------\n");
966 for (i=0; i < (long) number_formats; i++)
968 if (magick_info[i]->stealth != MagickFalse)
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)
976 module[MaxTextExtent];
979 if (magick_info[i]->module != (char *) NULL)
980 (void) CopyMagickString(module,magick_info[i]->module,MaxTextExtent);
981 (void) ConcatenateMagickString(module," ",MaxTextExtent);
983 (void) fprintf(file,"%9s ",module);
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)
999 text=StringToList(magick_info[i]->note);
1000 if (text != (char **) NULL)
1002 for (j=0; text[j] != (char *) NULL; j++)
1004 (void) fprintf(file," %s\n",text[j]);
1005 text[j]=DestroyString(text[j]);
1007 text=(char **) RelinquishMagickMemory(text);
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 *)
1022 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1026 % I s M a g i c k I n s t a n t i a t e d %
1030 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1032 % IsMagickInstantiated() returns MagickTrue if the ImageMagick environment
1033 % is currently instantiated: MagickCoreGenesis() has been called but
1034 % MagickDestroy() has not.
1036 % The format of the IsMagickInstantiated method is:
1038 % MagickBooleanType IsMagickInstantiated(void)
1041 MagickExport MagickBooleanType IsMagickInstantiated(void)
1043 return(instantiate_magick);
1047 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1051 % M a g i c k C o r e G e n e s i s %
1055 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1057 % MagickCoreGenesis() initializes the MagickCore environment.
1059 % The format of the MagickCoreGenesis function is:
1061 % MagickCoreGenesis(const char *path,
1062 % const MagickBooleanType establish_signal_handlers)
1064 % A description of each parameter follows:
1066 % o path: the execution path of the current ImageMagick client.
1068 % o establish_signal_handlers: set to MagickTrue to use MagickCore's own
1069 % signal handlers for common signals.
1073 static SignalHandler *SetMagickSignalHandler(int signal_number,
1074 SignalHandler *handler)
1076 #if defined(MAGICKCORE_HAVE_SIGACTION) && defined(MAGICKCORE_HAVE_SIGEMPTYSET)
1088 sigaddset(&mask,signal_number);
1089 sigprocmask(SIG_BLOCK,&mask,NULL);
1090 action.sa_mask=mask;
1091 action.sa_handler=handler;
1093 #if defined(SA_INTERRUPT)
1094 action.sa_flags|=SA_INTERRUPT;
1096 status=sigaction(signal_number,&action,&previous_action);
1099 sigprocmask(SIG_UNBLOCK,&mask,NULL);
1100 return(previous_action.sa_handler);
1102 return(signal(signal_number,handler));
1106 static void MagickSignalHandler(int signal_number)
1108 #if !defined(MAGICKCORE_HAVE_SIGACTION)
1109 (void) signal(signal_number,SIG_IGN);
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);
1118 #if !defined(MAGICKCORE_HAVE__EXIT)
1119 exit(signal_number);
1122 if (signal_number == SIGHUP)
1123 exit(signal_number);
1125 #if defined(SIGINT) && !defined(__WINDOWS__)
1126 if (signal_number == SIGINT)
1127 exit(signal_number);
1129 #if defined(SIGTERM)
1130 if (signal_number == SIGTERM)
1131 exit(signal_number);
1133 _exit(signal_number);
1137 static SignalHandler *RegisterMagickSignalHandler(int signal_number)
1142 handler=SetMagickSignalHandler(signal_number,MagickSignalHandler);
1143 if (handler == SIG_ERR)
1145 if (handler != SIG_DFL)
1146 handler=SetMagickSignalHandler(signal_number,handler);
1148 (void) LogMagickEvent(ConfigureEvent,GetMagickModule(),
1149 "Register handler for signal: %d",signal_number);
1153 MagickExport void MagickCoreGenesis(const char *path,
1154 const MagickBooleanType establish_signal_handlers)
1158 execution_path[MaxTextExtent],
1159 filename[MaxTextExtent];
1168 Initialize the Magick environment.
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)
1177 (void) SetLogEventMask(events);
1178 events=DestroyString(events);
1180 #if defined(__WINDOWS__)
1181 #if defined(_DEBUG) && !defined(__BORLANDC__) && !defined(__MINGW32__)
1182 if (IsEventLogging() != MagickFalse)
1187 debug=_CrtSetDbgFlag(_CRTDBG_REPORT_FLAG);
1188 debug|=_CRTDBG_CHECK_ALWAYS_DF |_CRTDBG_DELAY_FREE_MEM_DF |
1189 _CRTDBG_LEAK_CHECK_DF;
1192 debug=_CrtSetDbgFlag(debug);
1193 _ASSERTE(_CrtCheckMemory());
1199 Set client name and execution path.
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)
1211 Set signal handlers.
1213 #if defined(SIGABRT)
1214 if (signal_handlers[SIGABRT] == (SignalHandler *) NULL)
1215 signal_handlers[SIGABRT]=RegisterMagickSignalHandler(SIGABRT);
1218 if (signal_handlers[SIGFPE] == (SignalHandler *) NULL)
1219 signal_handlers[SIGFPE]=RegisterMagickSignalHandler(SIGFPE);
1222 if (signal_handlers[SIGHUP] == (SignalHandler *) NULL)
1223 signal_handlers[SIGHUP]=RegisterMagickSignalHandler(SIGHUP);
1225 #if defined(SIGINT) && !defined(__WINDOWS__)
1226 if (signal_handlers[SIGINT] == (SignalHandler *) NULL)
1227 signal_handlers[SIGINT]=RegisterMagickSignalHandler(SIGINT);
1229 #if defined(SIGQUIT)
1230 if (signal_handlers[SIGQUIT] == (SignalHandler *) NULL)
1231 signal_handlers[SIGQUIT]=RegisterMagickSignalHandler(SIGQUIT);
1233 #if defined(SIGTERM)
1234 if (signal_handlers[SIGTERM] == (SignalHandler *) NULL)
1235 signal_handlers[SIGTERM]=RegisterMagickSignalHandler(SIGTERM);
1237 #if defined(SIGXCPU)
1238 if (signal_handlers[SIGXCPU] == (SignalHandler *) NULL)
1239 signal_handlers[SIGXCPU]=RegisterMagickSignalHandler(SIGXCPU);
1241 #if defined(SIGXFSZ)
1242 if (signal_handlers[SIGXFSZ] == (SignalHandler *) NULL)
1243 signal_handlers[SIGXFSZ]=RegisterMagickSignalHandler(SIGXFSZ);
1247 Initialize magick resources.
1249 InitializeMagickResources();
1250 exception=AcquireExceptionInfo();
1251 #if defined(MAGICKCORE_MODULES_SUPPORT)
1252 InitializeModuleList(exception);
1254 exception=DestroyExceptionInfo(exception);
1258 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1262 % M a g i c k C o r e T e r m i n u s %
1266 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1268 % MagickCoreTerminus() destroys the MagickCore environment.
1270 % The format of the DestroyMagick function is:
1272 % MagickCoreTerminus(void)
1275 MagickExport void MagickCoreTerminus(void)
1277 #if defined(MAGICKCORE_X11_DELEGATE)
1278 DestroyXResources();
1280 DestroyConstitute();
1282 DestroyConfigureList();
1285 #if defined(__WINDOWS__)
1286 NTGhostscriptUnLoadDLL();
1289 DestroyDelegateList();
1290 DestroyMagickList();
1292 DestroyMagickResources();
1293 DestroyImageRegistry();
1294 DestroyPixelCacheResources();
1295 DestroyPolicyList();
1296 DestroyRandomReservoir();
1297 DestroyLocaleList();
1299 instantiate_magick=MagickFalse;
1303 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1307 + R e g i s t e r M a g i c k I n f o %
1311 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
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.
1319 % The format of the RegisterMagickInfo method is:
1321 % MagickInfo *RegisterMagickInfo(MagickInfo *magick_info)
1323 % A description of each parameter follows:
1325 % o magick_info: the magick info.
1328 MagickExport MagickInfo *RegisterMagickInfo(MagickInfo *magick_info)
1334 Delete any existing name.
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);
1348 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1352 + S e t M a g i c k I n f o %
1356 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1358 % SetMagickInfo() allocates a MagickInfo structure and initializes the members
1359 % to default values.
1361 % The format of the SetMagickInfo method is:
1363 % MagickInfo *SetMagickInfo(const char *name)
1365 % A description of each parameter follows:
1367 % o magick_info: Method SetMagickInfo returns the allocated and initialized
1368 % MagickInfo structure.
1370 % o name: a character string that represents the image format associated
1371 % with the MagickInfo structure.
1374 MagickExport MagickInfo *SetMagickInfo(const char *name)
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);
1395 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1399 + U n r e g i s t e r M a g i c k I n f o %
1403 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
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.
1408 % The format of the UnregisterMagickInfo method is:
1410 % MagickBooleanType UnregisterMagickInfo(const char *name)
1412 % A description of each parameter follows:
1414 % o name: a character string that represents the image format we are
1418 MagickExport MagickBooleanType UnregisterMagickInfo(const char *name)
1420 register const MagickInfo
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)
1436 if (LocaleCompare(p->name,name) == 0)
1438 p=(const MagickInfo *) GetNextValueInSplayTree(magick_list);
1440 status=DeleteNodeByValueFromSplayTree(magick_list,p);
1441 RelinquishSemaphoreInfo(magick_semaphore);