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-2018 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 % https://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 "MagickCore/studio.h"
44 #include "MagickCore/annotate-private.h"
45 #include "MagickCore/blob.h"
46 #include "MagickCore/blob-private.h"
47 #include "MagickCore/cache.h"
48 #include "MagickCore/cache-private.h"
49 #include "MagickCore/coder-private.h"
50 #include "MagickCore/client.h"
51 #include "MagickCore/color-private.h"
52 #include "MagickCore/configure-private.h"
53 #include "MagickCore/constitute-private.h"
54 #include "MagickCore/delegate-private.h"
55 #include "MagickCore/draw.h"
56 #include "MagickCore/exception.h"
57 #include "MagickCore/exception-private.h"
58 #include "MagickCore/locale-private.h"
59 #include "MagickCore/log-private.h"
60 #include "MagickCore/magic-private.h"
61 #include "MagickCore/magick.h"
62 #include "MagickCore/magick-private.h"
63 #include "MagickCore/memory_.h"
64 #include "MagickCore/memory-private.h"
65 #include "MagickCore/mime-private.h"
66 #include "MagickCore/module.h"
67 #include "MagickCore/module-private.h"
68 #include "MagickCore/nt-base-private.h"
69 #include "MagickCore/nt-feature.h"
70 #include "MagickCore/opencl-private.h"
71 #include "MagickCore/option-private.h"
72 #include "MagickCore/random-private.h"
73 #include "MagickCore/registry.h"
74 #include "MagickCore/registry-private.h"
75 #include "MagickCore/resource_.h"
76 #include "MagickCore/resource-private.h"
77 #include "MagickCore/policy.h"
78 #include "MagickCore/policy-private.h"
79 #include "MagickCore/semaphore.h"
80 #include "MagickCore/semaphore-private.h"
81 #include "MagickCore/signature-private.h"
82 #include "MagickCore/splay-tree.h"
83 #include "MagickCore/string_.h"
84 #include "MagickCore/string-private.h"
85 #include "MagickCore/thread_.h"
86 #include "MagickCore/thread-private.h"
87 #include "MagickCore/type-private.h"
88 #include "MagickCore/token.h"
89 #include "MagickCore/utility.h"
90 #include "MagickCore/utility-private.h"
91 #include "MagickCore/xwindow-private.h"
96 #if !defined(MAGICKCORE_RETSIGTYPE)
97 # define MAGICKCORE_RETSIGTYPE void
100 # define SIG_DFL ((SignalHandler *) 0)
102 #if !defined(SIG_ERR)
103 # define SIG_ERR ((SignalHandler *) -1)
110 Typedef declarations.
112 typedef MAGICKCORE_RETSIGTYPE
119 *magick_semaphore = (SemaphoreInfo *) NULL;
122 *signal_handlers[SIGMAX] = { (SignalHandler *) NULL };
125 *magick_list = (SplayTreeInfo *) NULL;
127 static volatile MagickBooleanType
128 instantiate_magickcore = MagickFalse,
129 magickcore_signal_in_progress = MagickFalse,
130 magick_list_initialized = MagickFalse;
133 Forward declarations.
135 static MagickBooleanType
136 IsMagickTreeInstantiated(ExceptionInfo *);
139 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
143 % A c q u i r e M a g i c k I n f o %
147 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
149 % AcquireMagickInfo() allocates a MagickInfo structure and initializes the
150 % members to default values.
152 % The format of the AcquireMagickInfo method is:
154 % MagickInfo *AcquireMagickInfo(const char *module, const char *name,)
156 % A description of each parameter follows:
158 % o module: a character string that represents the module associated
159 % with the MagickInfo structure.
161 % o name: a character string that represents the image format associated
162 % with the MagickInfo structure.
164 % o description: a character string that represents the image format
165 % associated with the MagickInfo structure.
168 MagickExport MagickInfo *AcquireMagickInfo(const char *module,
169 const char *name, const char *description)
174 assert(module != (const char *) NULL);
175 assert(name != (const char *) NULL);
176 assert(description != (const char *) NULL);
177 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",name);
178 magick_info=(MagickInfo *) AcquireCriticalMemory(sizeof(*magick_info));
179 (void) ResetMagickMemory(magick_info,0,sizeof(*magick_info));
180 magick_info->module=ConstantString(module);
181 magick_info->name=ConstantString(name);
182 magick_info->description=ConstantString(description);
183 magick_info->flags=CoderAdjoinFlag | CoderBlobSupportFlag |
184 CoderDecoderThreadSupportFlag | CoderEncoderThreadSupportFlag |
185 CoderUseExtensionFlag;
186 magick_info->signature=MagickCoreSignature;
191 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
195 + G e t I m a g e D e c o d e r %
199 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
201 % GetImageDecoder() returns the image decoder.
203 % The format of the GetImageDecoder method is:
205 % DecodeImageHandler *GetImageDecoder(const MagickInfo *magick_info)
207 % A description of each parameter follows:
209 % o magick_info: The magick info.
212 MagickExport DecodeImageHandler *GetImageDecoder(const MagickInfo *magick_info)
214 assert(magick_info != (MagickInfo *) NULL);
215 assert(magick_info->signature == MagickCoreSignature);
216 return(magick_info->decoder);
220 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
224 + G e t I m a g e E n c o d e r %
228 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
230 % GetImageEncoder() returns the image encoder.
232 % The format of the GetImageEncoder method is:
234 % EncodeImageHandler *GetImageEncoder(const MagickInfo *magick_info)
236 % A description of each parameter follows:
238 % o magick_info: The magick info.
241 MagickExport EncodeImageHandler *GetImageEncoder(const MagickInfo *magick_info)
243 assert(magick_info != (MagickInfo *) NULL);
244 assert(magick_info->signature == MagickCoreSignature);
245 return(magick_info->encoder);
249 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
253 + G e t I m a g e M a g i c k %
257 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
259 % GetImageMagick() searches for an image format that matches the specified
260 % magick string. If one is found, MagickTrue is returned otherwise
263 % The format of the GetImageMagick method is:
265 % MagickBooleanType GetImageMagick(const unsigned char *magick,
266 % const size_t length,char *format)
268 % A description of each parameter follows:
270 % o magick: the image format we are searching for.
272 % o length: the length of the binary string.
274 % o format: the image format as determined by the magick bytes.
277 MagickExport MagickBooleanType GetImageMagick(const unsigned char *magick,
278 const size_t length,char *format)
286 register const MagickInfo
289 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
290 assert(magick != (const unsigned char *) NULL);
291 exception=AcquireExceptionInfo();
292 p=GetMagickInfo("*",exception);
293 exception=DestroyExceptionInfo(exception);
294 if (p == (const MagickInfo *) NULL)
297 LockSemaphoreInfo(magick_semaphore);
298 ResetSplayTreeIterator(magick_list);
299 p=(const MagickInfo *) GetNextValueInSplayTree(magick_list);
300 while (p != (const MagickInfo *) NULL)
302 if ((p->magick != (IsImageFormatHandler *) NULL) &&
303 (p->magick(magick,length) != 0))
306 (void) CopyMagickString(format,p->name,MagickPathExtent);
309 p=(const MagickInfo *) GetNextValueInSplayTree(magick_list);
311 UnlockSemaphoreInfo(magick_semaphore);
316 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
320 + G e t M a g i c k A d j o i n %
324 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
326 % GetMagickAdjoin() returns MagickTrue if the magick adjoin is MagickTrue.
328 % The format of the GetMagickAdjoin method is:
330 % MagickBooleanType GetMagickAdjoin(const MagickInfo *magick_info)
332 % A description of each parameter follows:
334 % o magick_info: The magick info.
337 MagickExport MagickBooleanType GetMagickAdjoin(const MagickInfo *magick_info)
339 assert(magick_info != (MagickInfo *) NULL);
340 assert(magick_info->signature == MagickCoreSignature);
341 return(((magick_info->flags & CoderAdjoinFlag) == 0) ? MagickFalse :
346 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
350 + G e t M a g i c k B l o b S u p p o r t %
354 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
356 % GetMagickBlobSupport() returns MagickTrue if the magick supports blobs.
358 % The format of the GetMagickBlobSupport method is:
360 % MagickBooleanType GetMagickBlobSupport(const MagickInfo *magick_info)
362 % A description of each parameter follows:
364 % o magick_info: The magick info.
367 MagickExport MagickBooleanType GetMagickBlobSupport(
368 const MagickInfo *magick_info)
370 assert(magick_info != (MagickInfo *) NULL);
371 assert(magick_info->signature == MagickCoreSignature);
372 return(((magick_info->flags & CoderBlobSupportFlag) == 0) ? MagickFalse :
377 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
381 + G e t M a g i c k D e c o d e r S e e k a b l e S t r e a m %
385 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
387 % GetMagickDecoderSeekableStream() returns MagickTrue if the magick supports a
388 % seekable stream in the decoder.
390 % The format of the GetMagickDecoderSeekableStream method is:
392 % MagickBooleanType GetMagickDecoderSeekableStream(
393 % const MagickInfo *magick_info)
395 % A description of each parameter follows:
397 % o magick_info: The magick info.
400 MagickExport MagickBooleanType GetMagickDecoderSeekableStream(
401 const MagickInfo *magick_info)
403 assert(magick_info != (MagickInfo *) NULL);
404 assert(magick_info->signature == MagickCoreSignature);
405 if ((magick_info->flags & CoderDecoderSeekableStreamFlag) == 0)
411 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
415 + G e t M a g i c k D e c o d e r T h r e a d S u p p o r t %
419 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
421 % GetMagickDecoderThreadSupport() returns MagickTrue if the decoder supports
424 % The format of the GetMagickDecoderThreadSupport method is:
426 % MagickStatusType GetMagickDecoderThreadSupport(
427 % const MagickInfo *magick_info)
429 % A description of each parameter follows:
431 % o magick_info: The magick info.
434 MagickExport MagickBooleanType GetMagickDecoderThreadSupport(
435 const MagickInfo *magick_info)
437 assert(magick_info != (MagickInfo *) NULL);
438 assert(magick_info->signature == MagickCoreSignature);
439 return(((magick_info->flags & CoderDecoderThreadSupportFlag) == 0) ?
440 MagickFalse : MagickTrue);
444 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
448 + G e t M a g i c k D e s c r i p t i o n %
452 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
454 % GetMagickDescription() returns the magick description.
456 % The format of the GetMagickDescription method is:
458 % const char *GetMagickDescription(const MagickInfo *magick_info)
460 % A description of each parameter follows:
462 % o magick_info: The magick info.
465 MagickExport const char *GetMagickDescription(const MagickInfo *magick_info)
467 assert(magick_info != (MagickInfo *) NULL);
468 assert(magick_info->signature == MagickCoreSignature);
469 return(magick_info->description);
473 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
477 + G e t M a g i c k E n c o d e r S e e k a b l e S t r e a m %
481 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
483 % GetMagickEncoderSeekableStream() returns MagickTrue if the magick supports a
484 % seekable stream in the encoder.
486 % The format of the GetMagickEncoderSeekableStream method is:
488 % MagickBooleanType GetMagickEncoderSeekableStream(
489 % const MagickInfo *magick_info)
491 % A description of each parameter follows:
493 % o magick_info: The magick info.
496 MagickExport MagickBooleanType GetMagickEncoderSeekableStream(
497 const MagickInfo *magick_info)
499 assert(magick_info != (MagickInfo *) NULL);
500 assert(magick_info->signature == MagickCoreSignature);
501 if ((magick_info->flags & CoderEncoderSeekableStreamFlag) == 0)
507 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
511 + G e t M a g i c k E n c o d e r T h r e a d S u p p o r t %
515 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
517 % GetMagickEncoderThreadSupport() returns MagickTrue if the encoder supports
520 % The format of the GetMagickEncoderThreadSupport method is:
522 % MagickStatusType GetMagickEncoderThreadSupport(
523 % const MagickInfo *magick_info)
525 % A description of each parameter follows:
527 % o magick_info: The magick info.
530 MagickExport MagickBooleanType GetMagickEncoderThreadSupport(
531 const MagickInfo *magick_info)
533 assert(magick_info != (MagickInfo *) NULL);
534 assert(magick_info->signature == MagickCoreSignature);
535 return(((magick_info->flags & CoderDecoderThreadSupportFlag) == 0) ?
536 MagickFalse : MagickTrue);
540 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
544 + G e t M a g i c k E n d i a n S u p p o r t %
548 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
550 % GetMagickEndianSupport() returns the MagickTrue if the coder respects
551 % endianness other than MSBEndian.
553 % The format of the GetMagickEndianSupport method is:
555 % MagickBooleanType GetMagickEndianSupport(const MagickInfo *magick_info)
557 % A description of each parameter follows:
559 % o magick_info: The magick info.
562 MagickExport MagickBooleanType GetMagickEndianSupport(
563 const MagickInfo *magick_info)
565 assert(magick_info != (MagickInfo *) NULL);
566 assert(magick_info->signature == MagickCoreSignature);
567 return(((magick_info->flags & CoderEndianSupportFlag) == 0) ? MagickFalse :
572 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
576 + G e t M a g i c k I n f o %
580 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
582 % GetMagickInfo() returns a pointer MagickInfo structure that matches
583 % the specified name. If name is NULL, the head of the image format list
586 % The format of the GetMagickInfo method is:
588 % const MagickInfo *GetMagickInfo(const char *name,Exception *exception)
590 % A description of each parameter follows:
592 % o name: the image format we are looking for.
594 % o exception: return any errors or warnings in this structure.
597 MagickExport const MagickInfo *GetMagickInfo(const char *name,
598 ExceptionInfo *exception)
600 register const MagickInfo
604 Find named module attributes.
606 assert(exception != (ExceptionInfo *) NULL);
607 if (IsMagickTreeInstantiated(exception) == MagickFalse)
608 return((const MagickInfo *) NULL);
609 magick_info=(const MagickInfo *) NULL;
610 #if defined(MAGICKCORE_MODULES_SUPPORT)
611 if ((name != (const char *) NULL) && (*name != '\0'))
613 LockSemaphoreInfo(magick_semaphore);
614 if (LocaleCompare(name,"*") == 0)
615 (void) OpenModules(exception);
618 magick_info=(const MagickInfo *) GetValueFromSplayTree(magick_list,
620 if (magick_info == (const MagickInfo *) NULL)
621 (void) OpenModule(name,exception);
623 UnlockSemaphoreInfo(magick_semaphore);
626 if ((name == (const char *) NULL) || (LocaleCompare(name,"*") == 0))
627 magick_info=(const MagickInfo *) GetRootValueFromSplayTree(magick_list);
628 if (magick_info == (const MagickInfo *) NULL)
629 magick_info=(const MagickInfo *) GetValueFromSplayTree(magick_list,name);
634 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
638 + G e t M a g i c k I n f o L i s t %
642 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
644 % GetMagickInfoList() returns any image formats that match the specified
647 % The format of the GetMagickInfoList function is:
649 % const MagickInfo **GetMagickInfoList(const char *pattern,
650 % size_t *number_formats,ExceptionInfo *exception)
652 % A description of each parameter follows:
654 % o pattern: Specifies a pointer to a text string containing a pattern.
656 % o number_formats: This integer returns the number of formats in the list.
658 % o exception: return any errors or warnings in this structure.
662 #if defined(__cplusplus) || defined(c_plusplus)
666 static int MagickInfoCompare(const void *x,const void *y)
672 p=(const MagickInfo **) x,
673 q=(const MagickInfo **) y;
674 return(LocaleCompare((*p)->name,(*q)->name));
677 #if defined(__cplusplus) || defined(c_plusplus)
681 MagickExport const MagickInfo **GetMagickInfoList(const char *pattern,
682 size_t *number_formats,ExceptionInfo *exception)
687 register const MagickInfo
694 Allocate magick list.
696 assert(pattern != (char *) NULL);
697 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",pattern);
698 assert(number_formats != (size_t *) NULL);
700 p=GetMagickInfo("*",exception);
701 if (p == (const MagickInfo *) NULL)
702 return((const MagickInfo **) NULL);
703 formats=(const MagickInfo **) AcquireQuantumMemory((size_t)
704 GetNumberOfNodesInSplayTree(magick_list)+1UL,sizeof(*formats));
705 if (formats == (const MagickInfo **) NULL)
706 return((const MagickInfo **) NULL);
708 Generate magick list.
710 LockSemaphoreInfo(magick_semaphore);
711 ResetSplayTreeIterator(magick_list);
712 p=(const MagickInfo *) GetNextValueInSplayTree(magick_list);
713 for (i=0; p != (const MagickInfo *) NULL; )
715 if ((GetMagickStealth(p) == MagickFalse) &&
716 (GlobExpression(p->name,pattern,MagickFalse) != MagickFalse))
718 p=(const MagickInfo *) GetNextValueInSplayTree(magick_list);
720 UnlockSemaphoreInfo(magick_semaphore);
721 qsort((void *) formats,(size_t) i,sizeof(*formats),MagickInfoCompare);
722 formats[i]=(MagickInfo *) NULL;
723 *number_formats=(size_t) i;
728 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
732 + G e t M a g i c k L i s t %
736 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
738 % GetMagickList() returns any image formats that match the specified pattern.
740 % The format of the GetMagickList function is:
742 % char **GetMagickList(const char *pattern,size_t *number_formats,
743 % ExceptionInfo *exception)
745 % A description of each parameter follows:
747 % o pattern: Specifies a pointer to a text string containing a pattern.
749 % o number_formats: This integer returns the number of formats in the list.
751 % o exception: return any errors or warnings in this structure.
755 #if defined(__cplusplus) || defined(c_plusplus)
759 static int MagickCompare(const void *x,const void *y)
767 return(LocaleCompare(*p,*q));
770 #if defined(__cplusplus) || defined(c_plusplus)
774 MagickExport char **GetMagickList(const char *pattern,
775 size_t *number_formats,ExceptionInfo *exception)
780 register const MagickInfo
787 Allocate magick list.
789 assert(pattern != (char *) NULL);
790 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",pattern);
791 assert(number_formats != (size_t *) NULL);
793 p=GetMagickInfo("*",exception);
794 if (p == (const MagickInfo *) NULL)
795 return((char **) NULL);
796 formats=(char **) AcquireQuantumMemory((size_t)
797 GetNumberOfNodesInSplayTree(magick_list)+1UL,sizeof(*formats));
798 if (formats == (char **) NULL)
799 return((char **) NULL);
800 LockSemaphoreInfo(magick_semaphore);
801 ResetSplayTreeIterator(magick_list);
802 p=(const MagickInfo *) GetNextValueInSplayTree(magick_list);
803 for (i=0; p != (const MagickInfo *) NULL; )
805 if ((GetMagickStealth(p) == MagickFalse) &&
806 (GlobExpression(p->name,pattern,MagickFalse) != MagickFalse))
807 formats[i++]=ConstantString(p->name);
808 p=(const MagickInfo *) GetNextValueInSplayTree(magick_list);
810 UnlockSemaphoreInfo(magick_semaphore);
811 qsort((void *) formats,(size_t) i,sizeof(*formats),MagickCompare);
812 formats[i]=(char *) NULL;
813 *number_formats=(size_t) i;
818 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
822 + G e t M a g i c k M i m e T y p e %
826 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
828 % GetMagickMimeType() returns the magick mime type.
830 % The format of the GetMagickMimeType method is:
832 % const char *GetMagickMimeType(const MagickInfo *magick_info)
834 % A description of each parameter follows:
836 % o magick_info: The magick info.
839 MagickExport const char *GetMagickMimeType(const MagickInfo *magick_info)
841 assert(magick_info != (MagickInfo *) NULL);
842 assert(magick_info->signature == MagickCoreSignature);
843 return(magick_info->mime_type);
847 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
851 % G e t M a g i c k P r e c i s i o n %
855 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
857 % GetMagickPrecision() returns the maximum number of significant digits to be
860 % The format of the GetMagickPrecision method is:
862 % int GetMagickPrecision(void)
865 MagickExport int GetMagickPrecision(void)
867 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
868 return(SetMagickPrecision(0));
872 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
876 + G e t M a g i c k R a w S u p p o r t %
880 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
882 % GetMagickRawSupport() returns the MagickTrue if the coder is a raw format.
884 % The format of the GetMagickRawSupport method is:
886 % MagickBooleanType GetMagickRawSupport(const MagickInfo *magick_info)
888 % A description of each parameter follows:
890 % o magick_info: The magick info.
893 MagickExport MagickBooleanType GetMagickRawSupport(
894 const MagickInfo *magick_info)
896 assert(magick_info != (MagickInfo *) NULL);
897 assert(magick_info->signature == MagickCoreSignature);
898 return(((magick_info->flags & CoderRawSupportFlag) == 0) ? MagickFalse :
904 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
908 + G e t M a g i c k S t e a l t h %
912 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
914 % GetMagickStealth() returns MagickTrue if the magick is a stealth coder.
916 % The format of the GetMagickStealth method is:
918 % MagickBooleanType GetMagickStealth(const MagickInfo *magick_info)
920 % A description of each parameter follows:
922 % o magick_info: The magick info.
925 MagickExport MagickBooleanType GetMagickStealth(const MagickInfo *magick_info)
927 assert(magick_info != (MagickInfo *) NULL);
928 assert(magick_info->signature == MagickCoreSignature);
929 return(((magick_info->flags & CoderStealthFlag) == 0) ? MagickFalse :
935 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
939 + G e t M a g i c k U s e E x t e n s i o n %
943 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
945 % GetMagickUseExtension() returns MagickTrue if the magick can use the
946 % extension of the format if the format return by IsImageFormatHandler uses
949 % The format of the GetMagickUseExtension method is:
951 % MagickBooleanType GetMagickUseExtension(const MagickInfo *magick_info)
953 % A description of each parameter follows:
955 % o magick_info: The magick info.
958 MagickExport MagickBooleanType GetMagickUseExtension(
959 const MagickInfo *magick_info)
961 assert(magick_info != (MagickInfo *) NULL);
962 assert(magick_info->signature == MagickCoreSignature);
963 return(((magick_info->flags & CoderUseExtensionFlag) == 0) ? MagickFalse :
968 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
972 + I s M a g i c k T r e e I n s t a n t i a t e d %
976 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
978 % IsMagickTreeInstantiated() determines if the magick tree is instantiated.
979 % If not, it instantiates the tree and returns it.
981 % The format of the IsMagickTreeInstantiated() method is:
983 % IsMagickTreeInstantiated(Exceptioninfo *exception)
985 % A description of each parameter follows.
987 % o exception: return any errors or warnings in this structure.
991 static void *DestroyMagickNode(void *magick_info)
996 p=(MagickInfo *) magick_info;
997 if (p->module != (char *) NULL)
998 p->module=DestroyString(p->module);
999 if (p->note != (char *) NULL)
1000 p->note=DestroyString(p->note);
1001 if (p->mime_type != (char *) NULL)
1002 p->mime_type=DestroyString(p->mime_type);
1003 if (p->version != (char *) NULL)
1004 p->version=DestroyString(p->version);
1005 if (p->description != (char *) NULL)
1006 p->description=DestroyString(p->description);
1007 if (p->name != (char *) NULL)
1008 p->name=DestroyString(p->name);
1009 if (p->semaphore != (SemaphoreInfo *) NULL)
1010 RelinquishSemaphoreInfo(&p->semaphore);
1011 return(RelinquishMagickMemory(p));
1014 static MagickBooleanType IsMagickTreeInstantiated(ExceptionInfo *exception)
1016 if (magick_list_initialized == MagickFalse)
1018 if (magick_semaphore == (SemaphoreInfo *) NULL)
1019 ActivateSemaphoreInfo(&magick_semaphore);
1020 LockSemaphoreInfo(magick_semaphore);
1021 if (magick_list_initialized == MagickFalse)
1023 magick_list=NewSplayTree(CompareSplayTreeString,(void *(*)(void *))
1024 NULL,DestroyMagickNode);
1025 #if defined(MAGICKCORE_MODULES_SUPPORT)
1026 (void) GetModuleInfo((char *) NULL,exception);
1028 #if !defined(MAGICKCORE_BUILD_MODULES)
1029 RegisterStaticModules();
1031 magick_list_initialized=MagickTrue;
1033 UnlockSemaphoreInfo(magick_semaphore);
1035 return(magick_list != (SplayTreeInfo *) NULL ? MagickTrue : MagickFalse);
1039 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1043 + I s M a g i c k C o n f l i c t %
1047 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1049 % IsMagickConflict() returns MagickTrue if the image format conflicts with a
1050 % logical drive (.e.g. X:).
1052 % The format of the IsMagickConflict method is:
1054 % MagickBooleanType IsMagickConflict(const char *magick)
1056 % A description of each parameter follows:
1058 % o magick: Specifies the image format.
1061 MagickPrivate MagickBooleanType IsMagickConflict(const char *magick)
1063 assert(magick != (char *) NULL);
1064 #if defined(macintosh)
1065 return(MACIsMagickConflict(magick));
1067 return(VMSIsMagickConflict(magick));
1068 #elif defined(MAGICKCORE_WINDOWS_SUPPORT)
1069 return(NTIsMagickConflict(magick));
1071 return(MagickFalse);
1076 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1080 + L i s t M a g i c k I n f o %
1084 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1086 % ListMagickInfo() lists the image formats to a file.
1088 % The format of the ListMagickInfo method is:
1090 % MagickBooleanType ListMagickInfo(FILE *file,ExceptionInfo *exception)
1092 % A description of each parameter follows.
1094 % o file: A file handle.
1096 % o exception: return any errors or warnings in this structure.
1099 MagickExport MagickBooleanType ListMagickInfo(FILE *file,
1100 ExceptionInfo *exception)
1114 if (file == (FILE *) NULL)
1116 magick_info=GetMagickInfoList("*",&number_formats,exception);
1117 if (magick_info == (const MagickInfo **) NULL)
1118 return(MagickFalse);
1119 ClearMagickException(exception);
1120 #if !defined(MAGICKCORE_MODULES_SUPPORT)
1121 (void) FormatLocaleFile(file," Format Mode Description\n");
1123 (void) FormatLocaleFile(file," Format Module Mode Description\n");
1125 (void) FormatLocaleFile(file,
1126 "--------------------------------------------------------"
1127 "-----------------------\n");
1128 for (i=0; i < (ssize_t) number_formats; i++)
1130 if (GetMagickStealth(magick_info[i]) != MagickFalse)
1132 (void) FormatLocaleFile(file,"%9s%c ",
1133 magick_info[i]->name != (char *) NULL ? magick_info[i]->name : "",
1134 GetMagickBlobSupport(magick_info[i]) != MagickFalse ? '*' : ' ');
1135 #if defined(MAGICKCORE_MODULES_SUPPORT)
1138 module[MagickPathExtent];
1141 if (magick_info[i]->module != (char *) NULL)
1142 (void) CopyMagickString(module,magick_info[i]->module,MagickPathExtent);
1143 (void) ConcatenateMagickString(module," ",MagickPathExtent);
1145 (void) FormatLocaleFile(file,"%9s ",module);
1148 (void) FormatLocaleFile(file,"%c%c%c ",magick_info[i]->decoder ? 'r' : '-',
1149 magick_info[i]->encoder ? 'w' : '-',magick_info[i]->encoder != NULL &&
1150 GetMagickAdjoin(magick_info[i]) != MagickFalse ? '+' : '-');
1151 if (magick_info[i]->description != (char *) NULL)
1152 (void) FormatLocaleFile(file," %s",magick_info[i]->description);
1153 if (magick_info[i]->version != (char *) NULL)
1154 (void) FormatLocaleFile(file," (%s)",magick_info[i]->version);
1155 (void) FormatLocaleFile(file,"\n");
1156 if (magick_info[i]->note != (char *) NULL)
1161 text=StringToList(magick_info[i]->note);
1162 if (text != (char **) NULL)
1164 for (j=0; text[j] != (char *) NULL; j++)
1166 (void) FormatLocaleFile(file," %s\n",text[j]);
1167 text[j]=DestroyString(text[j]);
1169 text=(char **) RelinquishMagickMemory(text);
1173 (void) FormatLocaleFile(file,"\n* native blob support\n");
1174 (void) FormatLocaleFile(file,"r read support\n");
1175 (void) FormatLocaleFile(file,"w write support\n");
1176 (void) FormatLocaleFile(file,"+ support for multiple images\n");
1177 (void) fflush(file);
1178 magick_info=(const MagickInfo **) RelinquishMagickMemory((void *)
1184 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1188 % I s M a g i c k C o r e I n s t a n t i a t e d %
1192 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1194 % IsMagickCoreInstantiated() returns MagickTrue if the ImageMagick environment
1195 % is currently instantiated: MagickCoreGenesis() has been called but
1196 % MagickDestroy() has not.
1198 % The format of the IsMagickCoreInstantiated method is:
1200 % MagickBooleanType IsMagickCoreInstantiated(void)
1203 MagickExport MagickBooleanType IsMagickCoreInstantiated(void)
1205 return(instantiate_magickcore);
1209 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1213 + M a g i c k C o m p o n e n t G e n e s i s %
1217 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1219 % MagickComponentGenesis() instantiates the magick component.
1221 % The format of the MagickComponentGenesis method is:
1223 % MagickBooleanType MagickComponentGenesis(void)
1226 MagickPrivate MagickBooleanType MagickComponentGenesis(void)
1228 if (magick_semaphore == (SemaphoreInfo *) NULL)
1229 magick_semaphore=AcquireSemaphoreInfo();
1234 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1238 + M a g i c k C o m p o n e n t T e r m i n u s %
1242 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1244 % MagickComponentTerminus() destroys the magick component.
1246 % The format of the MagickComponentTerminus method is:
1248 % void MagickComponentTerminus(void)
1251 MagickPrivate void MagickComponentTerminus(void)
1253 if (magick_semaphore == (SemaphoreInfo *) NULL)
1254 ActivateSemaphoreInfo(&magick_semaphore);
1255 LockSemaphoreInfo(magick_semaphore);
1256 if (magick_list != (SplayTreeInfo *) NULL)
1258 magick_list=DestroySplayTree(magick_list);
1259 magick_list_initialized=MagickFalse;
1261 UnlockSemaphoreInfo(magick_semaphore);
1262 RelinquishSemaphoreInfo(&magick_semaphore);
1266 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1270 % M a g i c k C o r e G e n e s i s %
1274 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1276 % MagickCoreGenesis() initializes the MagickCore environment.
1278 % The format of the MagickCoreGenesis function is:
1280 % MagickCoreGenesis(const char *path,
1281 % const MagickBooleanType establish_signal_handlers)
1283 % A description of each parameter follows:
1285 % o path: the execution path of the current ImageMagick client.
1287 % o establish_signal_handlers: set to MagickTrue to use MagickCore's own
1288 % signal handlers for common signals.
1292 static SignalHandler *SetMagickSignalHandler(int signal_number,
1293 SignalHandler *handler)
1295 #if defined(MAGICKCORE_HAVE_SIGACTION) && defined(MAGICKCORE_HAVE_SIGEMPTYSET)
1307 sigaddset(&mask,signal_number);
1308 sigprocmask(SIG_BLOCK,&mask,NULL);
1309 action.sa_mask=mask;
1310 action.sa_handler=handler;
1312 #if defined(SA_INTERRUPT)
1313 action.sa_flags|=SA_INTERRUPT;
1315 status=sigaction(signal_number,&action,&previous_action);
1318 sigprocmask(SIG_UNBLOCK,&mask,NULL);
1319 return(previous_action.sa_handler);
1321 return(signal(signal_number,handler));
1325 static void MagickSignalHandler(int signal_number)
1327 if (magickcore_signal_in_progress != MagickFalse)
1328 (void) SetMagickSignalHandler(signal_number,signal_handlers[signal_number]);
1329 magickcore_signal_in_progress=MagickTrue;
1330 AsynchronousResourceComponentTerminus();
1331 #if defined(SIGQUIT)
1332 if (signal_number == SIGQUIT)
1335 #if defined(SIGABRT)
1336 if (signal_number == SIGABRT)
1340 if (signal_number == SIGBUS)
1344 if (signal_number == SIGFPE)
1347 #if defined(SIGXCPU)
1348 if (signal_number == SIGXCPU)
1351 #if defined(SIGXFSZ)
1352 if (signal_number == SIGXFSZ)
1355 #if defined(SIGSEGV)
1356 if (signal_number == SIGSEGV)
1359 #if !defined(MAGICKCORE_HAVE__EXIT)
1360 exit(signal_number);
1363 if (signal_number == SIGHUP)
1364 _exit(signal_number);
1367 if (signal_number == SIGINT)
1368 _exit(signal_number);
1371 if (signal_number == SIGBUS)
1372 _exit(signal_number);
1374 #if defined(MAGICKCORE_HAVE_RAISE)
1375 if (signal_handlers[signal_number] != MagickSignalHandler)
1376 raise(signal_number);
1378 _exit(signal_number); /* do not invoke registered atexit() methods */
1382 static SignalHandler *RegisterMagickSignalHandler(int signal_number)
1387 handler=SetMagickSignalHandler(signal_number,MagickSignalHandler);
1388 if (handler == SIG_ERR)
1390 if (handler != SIG_DFL)
1391 handler=SetMagickSignalHandler(signal_number,handler);
1393 (void) LogMagickEvent(ConfigureEvent,GetMagickModule(),
1394 "Register handler for signal: %d",signal_number);
1398 MagickExport void MagickCoreGenesis(const char *path,
1399 const MagickBooleanType establish_signal_handlers)
1403 execution_path[MagickPathExtent],
1404 filename[MagickPathExtent];
1407 Initialize the Magick environment.
1409 InitializeMagickMutex();
1411 if (instantiate_magickcore != MagickFalse)
1413 UnlockMagickMutex();
1416 (void) SemaphoreComponentGenesis();
1417 (void) LogComponentGenesis();
1418 (void) LocaleComponentGenesis();
1419 (void) RandomComponentGenesis();
1420 events=GetEnvironmentValue("MAGICK_DEBUG");
1421 if (events != (char *) NULL)
1423 (void) SetLogEventMask(events);
1424 events=DestroyString(events);
1426 #if defined(MAGICKCORE_WINDOWS_SUPPORT)
1430 Set client name and execution path.
1432 #if defined(MAGICKCORE_WINDOWS_SUPPORT)
1433 if ((path != (const char *) NULL) && (IsPathAccessible(path) != MagickFalse))
1435 if ((path != (const char *) NULL) && (*path == *DirectorySeparator) &&
1436 (IsPathAccessible(path) != MagickFalse))
1438 (void) CopyMagickString(execution_path,path,MagickPathExtent);
1440 (void) GetExecutionPath(execution_path,MagickPathExtent);
1441 GetPathComponent(execution_path,TailPath,filename);
1442 (void) SetClientName(filename);
1443 GetPathComponent(execution_path,HeadPath,execution_path);
1444 (void) SetClientPath(execution_path);
1445 if (establish_signal_handlers != MagickFalse)
1448 Set signal handlers.
1450 #if defined(SIGABRT)
1451 if (signal_handlers[SIGABRT] == (SignalHandler *) NULL)
1452 signal_handlers[SIGABRT]=RegisterMagickSignalHandler(SIGABRT);
1455 if (signal_handlers[SIGBUS] == (SignalHandler *) NULL)
1456 signal_handlers[SIGBUS]=RegisterMagickSignalHandler(SIGBUS);
1458 #if defined(SIGSEGV)
1459 if (signal_handlers[SIGSEGV] == (SignalHandler *) NULL)
1460 signal_handlers[SIGSEGV]=RegisterMagickSignalHandler(SIGSEGV);
1463 if (signal_handlers[SIGFPE] == (SignalHandler *) NULL)
1464 signal_handlers[SIGFPE]=RegisterMagickSignalHandler(SIGFPE);
1467 if (signal_handlers[SIGHUP] == (SignalHandler *) NULL)
1468 signal_handlers[SIGHUP]=RegisterMagickSignalHandler(SIGHUP);
1471 if (signal_handlers[SIGINT] == (SignalHandler *) NULL)
1472 signal_handlers[SIGINT]=RegisterMagickSignalHandler(SIGINT);
1474 #if defined(SIGQUIT)
1475 if (signal_handlers[SIGQUIT] == (SignalHandler *) NULL)
1476 signal_handlers[SIGQUIT]=RegisterMagickSignalHandler(SIGQUIT);
1478 #if defined(SIGTERM)
1479 if (signal_handlers[SIGTERM] == (SignalHandler *) NULL)
1480 signal_handlers[SIGTERM]=RegisterMagickSignalHandler(SIGTERM);
1482 #if defined(SIGXCPU)
1483 if (signal_handlers[SIGXCPU] == (SignalHandler *) NULL)
1484 signal_handlers[SIGXCPU]=RegisterMagickSignalHandler(SIGXCPU);
1486 #if defined(SIGXFSZ)
1487 if (signal_handlers[SIGXFSZ] == (SignalHandler *) NULL)
1488 signal_handlers[SIGXFSZ]=RegisterMagickSignalHandler(SIGXFSZ);
1492 Instantiate magick resources.
1494 (void) ConfigureComponentGenesis();
1495 (void) PolicyComponentGenesis();
1496 #if defined(MAGICKCORE_ZERO_CONFIGURATION_SUPPORT)
1497 (void) ZeroConfigurationPolicy;
1499 (void) CacheComponentGenesis();
1500 (void) ResourceComponentGenesis();
1501 (void) CoderComponentGenesis();
1502 (void) MagickComponentGenesis();
1503 #if defined(MAGICKCORE_MODULES_SUPPORT)
1504 (void) ModuleComponentGenesis();
1506 (void) DelegateComponentGenesis();
1507 (void) MagicComponentGenesis();
1508 (void) ColorComponentGenesis();
1509 (void) TypeComponentGenesis();
1510 (void) MimeComponentGenesis();
1511 (void) AnnotateComponentGenesis();
1512 #if defined(MAGICKCORE_X11_DELEGATE)
1513 (void) XComponentGenesis();
1515 (void) RegistryComponentGenesis();
1516 instantiate_magickcore=MagickTrue;
1517 UnlockMagickMutex();
1521 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1525 % M a g i c k C o r e T e r m i n u s %
1529 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1531 % MagickCoreTerminus() destroys the MagickCore environment.
1533 % The format of the MagickCoreTerminus function is:
1535 % MagickCoreTerminus(void)
1538 MagickExport void MagickCoreTerminus(void)
1540 InitializeMagickMutex();
1542 if (instantiate_magickcore == MagickFalse)
1544 UnlockMagickMutex();
1547 RegistryComponentTerminus();
1548 #if defined(MAGICKCORE_X11_DELEGATE)
1549 XComponentTerminus();
1551 AnnotateComponentTerminus();
1552 MimeComponentTerminus();
1553 TypeComponentTerminus();
1554 #if defined(MAGICKCORE_OPENCL_SUPPORT)
1557 ColorComponentTerminus();
1558 #if defined(MAGICKCORE_WINDOWS_SUPPORT)
1559 NTWindowsTerminus();
1561 MagicComponentTerminus();
1562 DelegateComponentTerminus();
1563 MagickComponentTerminus();
1564 #if !defined(MAGICKCORE_BUILD_MODULES)
1565 UnregisterStaticModules();
1567 #if defined(MAGICKCORE_MODULES_SUPPORT)
1568 ModuleComponentTerminus();
1570 CoderComponentTerminus();
1571 ResourceComponentTerminus();
1572 CacheComponentTerminus();
1573 PolicyComponentTerminus();
1574 ConfigureComponentTerminus();
1575 RandomComponentTerminus();
1576 LocaleComponentTerminus();
1577 LogComponentTerminus();
1578 instantiate_magickcore=MagickFalse;
1579 UnlockMagickMutex();
1580 SemaphoreComponentTerminus();
1584 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1588 + R e g i s t e r M a g i c k I n f o %
1592 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1594 % RegisterMagickInfo() adds attributes for a particular image format to the
1595 % list of supported formats. The attributes include the image format name,
1596 % a method to read and/or write the format, whether the format supports the
1597 % saving of more than one frame to the same file or blob, whether the format
1598 % supports native in-memory I/O, and a brief description of the format.
1600 % The format of the RegisterMagickInfo method is:
1602 % MagickInfo *RegisterMagickInfo(MagickInfo *magick_info)
1604 % A description of each parameter follows:
1606 % o magick_info: the magick info.
1609 MagickExport MagickBooleanType RegisterMagickInfo(MagickInfo *magick_info)
1615 Register a new image format.
1617 assert(magick_info != (MagickInfo *) NULL);
1618 assert(magick_info->signature == MagickCoreSignature);
1619 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",magick_info->name);
1620 if (magick_list == (SplayTreeInfo *) NULL)
1621 return(MagickFalse);
1622 if ((GetMagickDecoderThreadSupport(magick_info) == MagickFalse) ||
1623 (GetMagickEncoderThreadSupport(magick_info) == MagickFalse))
1624 magick_info->semaphore=AcquireSemaphoreInfo();
1625 status=AddValueToSplayTree(magick_list,magick_info->name,magick_info);
1630 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1634 % S e t M a g i c k P r e c i s i o n %
1638 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1640 % SetMagickPrecision() sets the maximum number of significant digits to be
1643 % An input argument of 0 returns the current precision setting.
1645 % A negative value forces the precision to reset to a default value according
1646 % to the environment variable "MAGICK_PRECISION", the current 'policy'
1647 % configuration setting, or the default value of '6', in that order.
1649 % The format of the SetMagickPrecision method is:
1651 % int SetMagickPrecision(const int precision)
1653 % A description of each parameter follows:
1655 % o precision: set the maximum number of significant digits to be printed.
1658 MagickExport int SetMagickPrecision(const int precision)
1660 #define MagickPrecision 6
1663 magick_precision = 0;
1665 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
1667 magick_precision=precision;
1668 if ((precision < 0) || (magick_precision == 0))
1674 Precision reset, or it has not been set yet
1676 magick_precision=MagickPrecision;
1677 limit=GetEnvironmentValue("MAGICK_PRECISION");
1678 if (limit == (char *) NULL)
1679 limit=GetPolicyValue("system:precision");
1680 if (limit != (char *) NULL)
1682 magick_precision=StringToInteger(limit);
1683 limit=DestroyString(limit);
1686 return(magick_precision);
1690 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1694 + U n r e g i s t e r M a g i c k I n f o %
1698 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1700 % UnregisterMagickInfo() removes a name from the magick info list. It returns
1701 % MagickFalse if the name does not exist in the list otherwise MagickTrue.
1703 % The format of the UnregisterMagickInfo method is:
1705 % MagickBooleanType UnregisterMagickInfo(const char *name)
1707 % A description of each parameter follows:
1709 % o name: a character string that represents the image format we are
1713 MagickExport MagickBooleanType UnregisterMagickInfo(const char *name)
1715 register const MagickInfo
1721 assert(name != (const char *) NULL);
1722 if (magick_list == (SplayTreeInfo *) NULL)
1723 return(MagickFalse);
1724 if (GetNumberOfNodesInSplayTree(magick_list) == 0)
1725 return(MagickFalse);
1726 LockSemaphoreInfo(magick_semaphore);
1727 ResetSplayTreeIterator(magick_list);
1728 p=(const MagickInfo *) GetNextValueInSplayTree(magick_list);
1729 while (p != (const MagickInfo *) NULL)
1731 if (LocaleCompare(p->name,name) == 0)
1733 p=(const MagickInfo *) GetNextValueInSplayTree(magick_list);
1735 status=DeleteNodeByValueFromSplayTree(magick_list,p);
1736 UnlockSemaphoreInfo(magick_semaphore);