• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
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 %                                 Cristy                                      %
18 %                             November 1998                                   %
19 %                                                                             %
20 %                                                                             %
21 %  Copyright 1999-2019 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 %    https://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 "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/monitor-private.h"
67 #include "MagickCore/module.h"
68 #include "MagickCore/module-private.h"
69 #include "MagickCore/nt-base-private.h"
70 #include "MagickCore/nt-feature.h"
71 #include "MagickCore/opencl-private.h"
72 #include "MagickCore/option-private.h"
73 #include "MagickCore/random-private.h"
74 #include "MagickCore/registry.h"
75 #include "MagickCore/registry-private.h"
76 #include "MagickCore/resource_.h"
77 #include "MagickCore/resource-private.h"
78 #include "MagickCore/policy.h"
79 #include "MagickCore/policy-private.h"
80 #include "MagickCore/semaphore.h"
81 #include "MagickCore/semaphore-private.h"
82 #include "MagickCore/signature-private.h"
83 #include "MagickCore/splay-tree.h"
84 #include "MagickCore/static.h"
85 #include "MagickCore/string_.h"
86 #include "MagickCore/string-private.h"
87 #include "MagickCore/thread_.h"
88 #include "MagickCore/thread-private.h"
89 #include "MagickCore/type-private.h"
90 #include "MagickCore/token.h"
91 #include "MagickCore/utility.h"
92 #include "MagickCore/utility-private.h"
93 #include "MagickCore/xwindow-private.h"
94 #if defined(MAGICKCORE_XML_DELEGATE)
95 #  if defined(MAGICKCORE_WINDOWS_SUPPORT)
96 #    if !defined(__MINGW32__)
97 #      include <win32config.h>
98 #    endif
99 #  endif
100 #  include <libxml/parser.h>
101 #endif
102 
103 /*
104   Define declarations.
105 */
106 #if !defined(MAGICKCORE_RETSIGTYPE)
107 # define MAGICKCORE_RETSIGTYPE  void
108 #endif
109 #if !defined(SIG_DFL)
110 # define SIG_DFL  ((SignalHandler *) 0)
111 #endif
112 #if !defined(SIG_ERR)
113 # define SIG_ERR  ((SignalHandler *) -1)
114 #endif
115 #if !defined(SIGMAX)
116 #define SIGMAX  64
117 #endif
118 
119 /*
120   Typedef declarations.
121 */
122 typedef MAGICKCORE_RETSIGTYPE
123   SignalHandler(int);
124 
125 /*
126   Global declarations.
127 */
128 static SemaphoreInfo
129   *magick_semaphore = (SemaphoreInfo *) NULL;
130 
131 static SignalHandler
132   *signal_handlers[SIGMAX] = { (SignalHandler *) NULL };
133 
134 static SplayTreeInfo
135   *magick_list = (SplayTreeInfo *) NULL;
136 
137 static volatile MagickBooleanType
138   instantiate_magickcore = MagickFalse,
139   magickcore_signal_in_progress = MagickFalse,
140   magick_list_initialized = MagickFalse;
141 
142 static int
143   magick_precision = 0;
144 
145 /*
146   Forward declarations.
147 */
148 static MagickBooleanType
149   IsMagickTreeInstantiated(ExceptionInfo *);
150 
151 /*
152 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
153 %                                                                             %
154 %                                                                             %
155 %                                                                             %
156 %    A c q u i r e M a g i c k I n f o                                        %
157 %                                                                             %
158 %                                                                             %
159 %                                                                             %
160 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
161 %
162 %  AcquireMagickInfo() allocates a MagickInfo structure and initializes the
163 %  members to default values.
164 %
165 %  The format of the AcquireMagickInfo method is:
166 %
167 %      MagickInfo *AcquireMagickInfo(const char *module, const char *name,)
168 %
169 %  A description of each parameter follows:
170 %
171 %    o module: a character string that represents the module associated
172 %      with the MagickInfo structure.
173 %
174 %    o name: a character string that represents the image format associated
175 %      with the MagickInfo structure.
176 %
177 %    o description: a character string that represents the image format
178 %      associated with the MagickInfo structure.
179 %
180 */
AcquireMagickInfo(const char * module,const char * name,const char * description)181 MagickExport MagickInfo *AcquireMagickInfo(const char *module,const char *name,
182   const char *description)
183 {
184   MagickInfo
185     *magick_info;
186 
187   assert(module != (const char *) NULL);
188   assert(name != (const char *) NULL);
189   assert(description != (const char *) NULL);
190   (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",name);
191   magick_info=(MagickInfo *) AcquireCriticalMemory(sizeof(*magick_info));
192   (void) memset(magick_info,0,sizeof(*magick_info));
193   magick_info->module=ConstantString(module);
194   magick_info->name=ConstantString(name);
195   magick_info->description=ConstantString(description);
196   magick_info->flags=CoderAdjoinFlag | CoderBlobSupportFlag |
197     CoderDecoderThreadSupportFlag | CoderEncoderThreadSupportFlag |
198     CoderUseExtensionFlag;
199   magick_info->signature=MagickCoreSignature;
200   return(magick_info);
201 }
202 
203 /*
204 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
205 %                                                                             %
206 %                                                                             %
207 %                                                                             %
208 +   G e t I m a g e D e c o d e r                                             %
209 %                                                                             %
210 %                                                                             %
211 %                                                                             %
212 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
213 %
214 %  GetImageDecoder() returns the image decoder.
215 %
216 %  The format of the GetImageDecoder method is:
217 %
218 %      DecodeImageHandler *GetImageDecoder(const MagickInfo *magick_info)
219 %
220 %  A description of each parameter follows:
221 %
222 %    o magick_info:  The magick info.
223 %
224 */
GetImageDecoder(const MagickInfo * magick_info)225 MagickExport DecodeImageHandler *GetImageDecoder(const MagickInfo *magick_info)
226 {
227   if (magick_info == (MagickInfo *) NULL)
228     return((DecodeImageHandler *) NULL);
229   assert(magick_info->signature == MagickCoreSignature);
230   return(magick_info->decoder);
231 }
232 
233 /*
234 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
235 %                                                                             %
236 %                                                                             %
237 %                                                                             %
238 +   G e t I m a g e E n c o d e r                                             %
239 %                                                                             %
240 %                                                                             %
241 %                                                                             %
242 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
243 %
244 %  GetImageEncoder() returns the image encoder.
245 %
246 %  The format of the GetImageEncoder method is:
247 %
248 %      EncodeImageHandler *GetImageEncoder(const MagickInfo *magick_info)
249 %
250 %  A description of each parameter follows:
251 %
252 %    o magick_info:  The magick info.
253 %
254 */
GetImageEncoder(const MagickInfo * magick_info)255 MagickExport EncodeImageHandler *GetImageEncoder(const MagickInfo *magick_info)
256 {
257   if (magick_info == (MagickInfo *) NULL)
258     return((EncodeImageHandler *) NULL);
259   assert(magick_info->signature == MagickCoreSignature);
260   return(magick_info->encoder);
261 }
262 
263 /*
264 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
265 %                                                                             %
266 %                                                                             %
267 %                                                                             %
268 +   G e t I m a g e M a g i c k                                               %
269 %                                                                             %
270 %                                                                             %
271 %                                                                             %
272 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
273 %
274 %  GetImageMagick() searches for an image format that matches the specified
275 %  magick string.  If one is found, MagickTrue is returned otherwise
276 %  MagickFalse.
277 %
278 %  The format of the GetImageMagick method is:
279 %
280 %      MagickBooleanType GetImageMagick(const unsigned char *magick,
281 %        const size_t length,char *format)
282 %
283 %  A description of each parameter follows:
284 %
285 %    o magick: the image format we are searching for.
286 %
287 %    o length: the length of the binary string.
288 %
289 %    o format: the image format as determined by the magick bytes.
290 %
291 */
GetImageMagick(const unsigned char * magick,const size_t length,char * format)292 MagickExport MagickBooleanType GetImageMagick(const unsigned char *magick,
293   const size_t length,char *format)
294 {
295   ExceptionInfo
296     *exception;
297 
298   MagickBooleanType
299     status;
300 
301   register const MagickInfo
302     *p;
303 
304   (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
305   assert(magick != (const unsigned char *) NULL);
306   exception=AcquireExceptionInfo();
307   p=GetMagickInfo("*",exception);
308   exception=DestroyExceptionInfo(exception);
309   if (p == (const MagickInfo *) NULL)
310     return(MagickFalse);
311   status=MagickFalse;
312   LockSemaphoreInfo(magick_semaphore);
313   ResetSplayTreeIterator(magick_list);
314   p=(const MagickInfo *) GetNextValueInSplayTree(magick_list);
315   while (p != (const MagickInfo *) NULL)
316   {
317     if ((p->magick != (IsImageFormatHandler *) NULL) &&
318         (p->magick(magick,length) != 0))
319       {
320         status=MagickTrue;
321         (void) CopyMagickString(format,p->name,MagickPathExtent);
322         break;
323       }
324     p=(const MagickInfo *) GetNextValueInSplayTree(magick_list);
325   }
326   UnlockSemaphoreInfo(magick_semaphore);
327   return(status);
328 }
329 
330 /*
331 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
332 %                                                                             %
333 %                                                                             %
334 %                                                                             %
335 +   G e t M a g i c k A d j o i n                                             %
336 %                                                                             %
337 %                                                                             %
338 %                                                                             %
339 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
340 %
341 %  GetMagickAdjoin() returns MagickTrue if the magick adjoin is MagickTrue.
342 %
343 %  The format of the GetMagickAdjoin method is:
344 %
345 %      MagickBooleanType GetMagickAdjoin(const MagickInfo *magick_info)
346 %
347 %  A description of each parameter follows:
348 %
349 %    o magick_info:  The magick info.
350 %
351 */
GetMagickAdjoin(const MagickInfo * magick_info)352 MagickExport MagickBooleanType GetMagickAdjoin(const MagickInfo *magick_info)
353 {
354   assert(magick_info != (MagickInfo *) NULL);
355   assert(magick_info->signature == MagickCoreSignature);
356   return(((magick_info->flags & CoderAdjoinFlag) == 0) ? MagickFalse :
357     MagickTrue);
358 }
359 
360 /*
361 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
362 %                                                                             %
363 %                                                                             %
364 %                                                                             %
365 +   G e t M a g i c k B l o b S u p p o r t                                   %
366 %                                                                             %
367 %                                                                             %
368 %                                                                             %
369 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
370 %
371 %  GetMagickBlobSupport() returns MagickTrue if the magick supports blobs.
372 %
373 %  The format of the GetMagickBlobSupport method is:
374 %
375 %      MagickBooleanType GetMagickBlobSupport(const MagickInfo *magick_info)
376 %
377 %  A description of each parameter follows:
378 %
379 %    o magick_info:  The magick info.
380 %
381 */
GetMagickBlobSupport(const MagickInfo * magick_info)382 MagickExport MagickBooleanType GetMagickBlobSupport(
383   const MagickInfo *magick_info)
384 {
385   assert(magick_info != (MagickInfo *) NULL);
386   assert(magick_info->signature == MagickCoreSignature);
387   return(((magick_info->flags & CoderBlobSupportFlag) == 0) ? MagickFalse :
388     MagickTrue);
389 }
390 
391 /*
392 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
393 %                                                                             %
394 %                                                                             %
395 %                                                                             %
396 +   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               %
397 %                                                                             %
398 %                                                                             %
399 %                                                                             %
400 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
401 %
402 %  GetMagickDecoderSeekableStream() returns MagickTrue if the magick supports a
403 %  seekable stream in the decoder.
404 %
405 %  The format of the GetMagickDecoderSeekableStream method is:
406 %
407 %      MagickBooleanType GetMagickDecoderSeekableStream(
408 %        const MagickInfo *magick_info)
409 %
410 %  A description of each parameter follows:
411 %
412 %    o magick_info:  The magick info.
413 %
414 */
GetMagickDecoderSeekableStream(const MagickInfo * magick_info)415 MagickExport MagickBooleanType GetMagickDecoderSeekableStream(
416   const MagickInfo *magick_info)
417 {
418   assert(magick_info != (MagickInfo *) NULL);
419   assert(magick_info->signature == MagickCoreSignature);
420   if ((magick_info->flags & CoderDecoderSeekableStreamFlag) == 0)
421     return(MagickFalse);
422   return(MagickTrue);
423 }
424 
425 /*
426 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
427 %                                                                             %
428 %                                                                             %
429 %                                                                             %
430 +   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                 %
431 %                                                                             %
432 %                                                                             %
433 %                                                                             %
434 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
435 %
436 %  GetMagickDecoderThreadSupport() returns MagickTrue if the decoder supports
437 %  threads.
438 %
439 %  The format of the GetMagickDecoderThreadSupport method is:
440 %
441 %      MagickStatusType GetMagickDecoderThreadSupport(
442 %        const MagickInfo *magick_info)
443 %
444 %  A description of each parameter follows:
445 %
446 %    o magick_info:  The magick info.
447 %
448 */
GetMagickDecoderThreadSupport(const MagickInfo * magick_info)449 MagickExport MagickBooleanType GetMagickDecoderThreadSupport(
450   const MagickInfo *magick_info)
451 {
452   assert(magick_info != (MagickInfo *) NULL);
453   assert(magick_info->signature == MagickCoreSignature);
454   return(((magick_info->flags & CoderDecoderThreadSupportFlag) == 0) ?
455     MagickFalse : MagickTrue);
456 }
457 
458 /*
459 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
460 %                                                                             %
461 %                                                                             %
462 %                                                                             %
463 +   G e t M a g i c k D e s c r i p t i o n                                   %
464 %                                                                             %
465 %                                                                             %
466 %                                                                             %
467 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
468 %
469 %  GetMagickDescription() returns the magick description.
470 %
471 %  The format of the GetMagickDescription method is:
472 %
473 %      const char *GetMagickDescription(const MagickInfo *magick_info)
474 %
475 %  A description of each parameter follows:
476 %
477 %    o magick_info:  The magick info.
478 %
479 */
GetMagickDescription(const MagickInfo * magick_info)480 MagickExport const char *GetMagickDescription(const MagickInfo *magick_info)
481 {
482   assert(magick_info != (MagickInfo *) NULL);
483   assert(magick_info->signature == MagickCoreSignature);
484   return(magick_info->description);
485 }
486 
487 /*
488 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
489 %                                                                             %
490 %                                                                             %
491 %                                                                             %
492 +   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               %
493 %                                                                             %
494 %                                                                             %
495 %                                                                             %
496 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
497 %
498 %  GetMagickEncoderSeekableStream() returns MagickTrue if the magick supports a
499 %  seekable stream in the encoder.
500 %
501 %  The format of the GetMagickEncoderSeekableStream method is:
502 %
503 %      MagickBooleanType GetMagickEncoderSeekableStream(
504 %        const MagickInfo *magick_info)
505 %
506 %  A description of each parameter follows:
507 %
508 %    o magick_info:  The magick info.
509 %
510 */
GetMagickEncoderSeekableStream(const MagickInfo * magick_info)511 MagickExport MagickBooleanType GetMagickEncoderSeekableStream(
512   const MagickInfo *magick_info)
513 {
514   assert(magick_info != (MagickInfo *) NULL);
515   assert(magick_info->signature == MagickCoreSignature);
516   if ((magick_info->flags & CoderEncoderSeekableStreamFlag) == 0)
517     return(MagickFalse);
518   return(MagickTrue);
519 }
520 
521 /*
522 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
523 %                                                                             %
524 %                                                                             %
525 %                                                                             %
526 +   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                 %
527 %                                                                             %
528 %                                                                             %
529 %                                                                             %
530 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
531 %
532 %  GetMagickEncoderThreadSupport() returns MagickTrue if the encoder supports
533 %  threads.
534 %
535 %  The format of the GetMagickEncoderThreadSupport method is:
536 %
537 %      MagickStatusType GetMagickEncoderThreadSupport(
538 %        const MagickInfo *magick_info)
539 %
540 %  A description of each parameter follows:
541 %
542 %    o magick_info:  The magick info.
543 %
544 */
GetMagickEncoderThreadSupport(const MagickInfo * magick_info)545 MagickExport MagickBooleanType GetMagickEncoderThreadSupport(
546   const MagickInfo *magick_info)
547 {
548   assert(magick_info != (MagickInfo *) NULL);
549   assert(magick_info->signature == MagickCoreSignature);
550   return(((magick_info->flags & CoderDecoderThreadSupportFlag) == 0) ?
551     MagickFalse : MagickTrue);
552 }
553 
554 /*
555 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
556 %                                                                             %
557 %                                                                             %
558 %                                                                             %
559 +   G e t M a g i c k E n d i a n S u p p o r t                               %
560 %                                                                             %
561 %                                                                             %
562 %                                                                             %
563 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
564 %
565 %  GetMagickEndianSupport() returns the MagickTrue if the coder respects
566 %  endianness other than MSBEndian.
567 %
568 %  The format of the GetMagickEndianSupport method is:
569 %
570 %      MagickBooleanType GetMagickEndianSupport(const MagickInfo *magick_info)
571 %
572 %  A description of each parameter follows:
573 %
574 %    o magick_info:  The magick info.
575 %
576 */
GetMagickEndianSupport(const MagickInfo * magick_info)577 MagickExport MagickBooleanType GetMagickEndianSupport(
578   const MagickInfo *magick_info)
579 {
580   assert(magick_info != (MagickInfo *) NULL);
581   assert(magick_info->signature == MagickCoreSignature);
582   return(((magick_info->flags & CoderEndianSupportFlag) == 0) ? MagickFalse :
583     MagickTrue);
584 }
585 
586 /*
587 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
588 %                                                                             %
589 %                                                                             %
590 %                                                                             %
591 +   G e t M a g i c k I n f o                                                 %
592 %                                                                             %
593 %                                                                             %
594 %                                                                             %
595 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
596 %
597 %  GetMagickInfo() returns a pointer MagickInfo structure that matches
598 %  the specified name.  If name is NULL, the head of the image format list
599 %  is returned.
600 %
601 %  The format of the GetMagickInfo method is:
602 %
603 %      const MagickInfo *GetMagickInfo(const char *name,Exception *exception)
604 %
605 %  A description of each parameter follows:
606 %
607 %    o name: the image format we are looking for.
608 %
609 %    o exception: return any errors or warnings in this structure.
610 %
611 */
GetMagickInfo(const char * name,ExceptionInfo * exception)612 MagickExport const MagickInfo *GetMagickInfo(const char *name,
613   ExceptionInfo *exception)
614 {
615   register const MagickInfo
616     *magick_info;
617 
618   /*
619     Find named module attributes.
620   */
621   assert(exception != (ExceptionInfo *) NULL);
622   if (IsMagickTreeInstantiated(exception) == MagickFalse)
623     return((const MagickInfo *) NULL);
624   magick_info=(const MagickInfo *) NULL;
625   if ((name != (const char *) NULL) && (*name != '\0'))
626     {
627       LockSemaphoreInfo(magick_semaphore);
628       if (LocaleCompare(name,"*") == 0)
629 #if defined(MAGICKCORE_BUILD_MODULES)
630         (void) OpenModules(exception);
631 #else
632         RegisterStaticModules();
633 #endif
634       else
635         {
636           magick_info=(const MagickInfo *) GetValueFromSplayTree(magick_list,
637             name);
638           if (magick_info == (const MagickInfo *) NULL)
639 #if defined(MAGICKCORE_BUILD_MODULES)
640             (void) OpenModule(name,exception);
641 #else
642             (void) RegisterStaticModule(name,exception);
643 #endif
644         }
645       UnlockSemaphoreInfo(magick_semaphore);
646     }
647   if ((name == (const char *) NULL) || (LocaleCompare(name,"*") == 0))
648     return((const MagickInfo *) GetRootValueFromSplayTree(magick_list));
649   if (magick_info == (const MagickInfo *) NULL)
650     magick_info=(const MagickInfo *) GetValueFromSplayTree(magick_list,name);
651   return(magick_info);
652 }
653 
654 /*
655 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
656 %                                                                             %
657 %                                                                             %
658 %                                                                             %
659 +   G e t M a g i c k I n f o L i s t                                         %
660 %                                                                             %
661 %                                                                             %
662 %                                                                             %
663 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
664 %
665 %  GetMagickInfoList() returns any image formats that match the specified
666 %  pattern.
667 %
668 %  The format of the GetMagickInfoList function is:
669 %
670 %      const MagickInfo **GetMagickInfoList(const char *pattern,
671 %        size_t *number_formats,ExceptionInfo *exception)
672 %
673 %  A description of each parameter follows:
674 %
675 %    o pattern: Specifies a pointer to a text string containing a pattern.
676 %
677 %    o number_formats:  This integer returns the number of formats in the list.
678 %
679 %    o exception: return any errors or warnings in this structure.
680 %
681 */
682 
683 #if defined(__cplusplus) || defined(c_plusplus)
684 extern "C" {
685 #endif
686 
MagickInfoCompare(const void * x,const void * y)687 static int MagickInfoCompare(const void *x,const void *y)
688 {
689   const MagickInfo
690     **p,
691     **q;
692 
693   p=(const MagickInfo **) x,
694   q=(const MagickInfo **) y;
695   return(LocaleCompare((*p)->name,(*q)->name));
696 }
697 
698 #if defined(__cplusplus) || defined(c_plusplus)
699 }
700 #endif
701 
GetMagickInfoList(const char * pattern,size_t * number_formats,ExceptionInfo * exception)702 MagickExport const MagickInfo **GetMagickInfoList(const char *pattern,
703   size_t *number_formats,ExceptionInfo *exception)
704 {
705   const MagickInfo
706     **formats;
707 
708   register const MagickInfo
709     *p;
710 
711   register ssize_t
712     i;
713 
714   /*
715     Allocate magick list.
716   */
717   assert(pattern != (char *) NULL);
718   (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",pattern);
719   assert(number_formats != (size_t *) NULL);
720   *number_formats=0;
721   p=GetMagickInfo("*",exception);
722   if (p == (const MagickInfo *) NULL)
723     return((const MagickInfo **) NULL);
724   formats=(const MagickInfo **) AcquireQuantumMemory((size_t)
725     GetNumberOfNodesInSplayTree(magick_list)+1UL,sizeof(*formats));
726   if (formats == (const MagickInfo **) NULL)
727     return((const MagickInfo **) NULL);
728   /*
729     Generate magick list.
730   */
731   LockSemaphoreInfo(magick_semaphore);
732   ResetSplayTreeIterator(magick_list);
733   p=(const MagickInfo *) GetNextValueInSplayTree(magick_list);
734   for (i=0; p != (const MagickInfo *) NULL; )
735   {
736     if ((GetMagickStealth(p) == MagickFalse) &&
737         (GlobExpression(p->name,pattern,MagickFalse) != MagickFalse))
738       formats[i++]=p;
739     p=(const MagickInfo *) GetNextValueInSplayTree(magick_list);
740   }
741   UnlockSemaphoreInfo(magick_semaphore);
742   qsort((void *) formats,(size_t) i,sizeof(*formats),MagickInfoCompare);
743   formats[i]=(MagickInfo *) NULL;
744   *number_formats=(size_t) i;
745   return(formats);
746 }
747 
748 /*
749 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
750 %                                                                             %
751 %                                                                             %
752 %                                                                             %
753 +   G e t M a g i c k L i s t                                                 %
754 %                                                                             %
755 %                                                                             %
756 %                                                                             %
757 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
758 %
759 %  GetMagickList() returns any image formats that match the specified pattern.
760 %
761 %  The format of the GetMagickList function is:
762 %
763 %      char **GetMagickList(const char *pattern,size_t *number_formats,
764 %        ExceptionInfo *exception)
765 %
766 %  A description of each parameter follows:
767 %
768 %    o pattern: Specifies a pointer to a text string containing a pattern.
769 %
770 %    o number_formats:  This integer returns the number of formats in the list.
771 %
772 %    o exception: return any errors or warnings in this structure.
773 %
774 */
775 
776 #if defined(__cplusplus) || defined(c_plusplus)
777 extern "C" {
778 #endif
779 
MagickCompare(const void * x,const void * y)780 static int MagickCompare(const void *x,const void *y)
781 {
782   register const char
783     **p,
784     **q;
785 
786   p=(const char **) x;
787   q=(const char **) y;
788   return(LocaleCompare(*p,*q));
789 }
790 
791 #if defined(__cplusplus) || defined(c_plusplus)
792 }
793 #endif
794 
GetMagickList(const char * pattern,size_t * number_formats,ExceptionInfo * exception)795 MagickExport char **GetMagickList(const char *pattern,
796   size_t *number_formats,ExceptionInfo *exception)
797 {
798   char
799     **formats;
800 
801   register const MagickInfo
802     *p;
803 
804   register ssize_t
805     i;
806 
807   /*
808     Allocate magick list.
809   */
810   assert(pattern != (char *) NULL);
811   (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",pattern);
812   assert(number_formats != (size_t *) NULL);
813   *number_formats=0;
814   p=GetMagickInfo("*",exception);
815   if (p == (const MagickInfo *) NULL)
816     return((char **) NULL);
817   formats=(char **) AcquireQuantumMemory((size_t)
818     GetNumberOfNodesInSplayTree(magick_list)+1UL,sizeof(*formats));
819   if (formats == (char **) NULL)
820     return((char **) NULL);
821   LockSemaphoreInfo(magick_semaphore);
822   ResetSplayTreeIterator(magick_list);
823   p=(const MagickInfo *) GetNextValueInSplayTree(magick_list);
824   for (i=0; p != (const MagickInfo *) NULL; )
825   {
826     if ((GetMagickStealth(p) == MagickFalse) &&
827         (GlobExpression(p->name,pattern,MagickFalse) != MagickFalse))
828       formats[i++]=ConstantString(p->name);
829     p=(const MagickInfo *) GetNextValueInSplayTree(magick_list);
830   }
831   UnlockSemaphoreInfo(magick_semaphore);
832   qsort((void *) formats,(size_t) i,sizeof(*formats),MagickCompare);
833   formats[i]=(char *) NULL;
834   *number_formats=(size_t) i;
835   return(formats);
836 }
837 
838 /*
839 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
840 %                                                                             %
841 %                                                                             %
842 %                                                                             %
843 +   G e t M a g i c k M i m e T y p e                                         %
844 %                                                                             %
845 %                                                                             %
846 %                                                                             %
847 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
848 %
849 %  GetMagickMimeType() returns the magick mime type.
850 %
851 %  The format of the GetMagickMimeType method is:
852 %
853 %      const char *GetMagickMimeType(const MagickInfo *magick_info)
854 %
855 %  A description of each parameter follows:
856 %
857 %    o magick_info:  The magick info.
858 %
859 */
GetMagickMimeType(const MagickInfo * magick_info)860 MagickExport const char *GetMagickMimeType(const MagickInfo *magick_info)
861 {
862   assert(magick_info != (MagickInfo *) NULL);
863   assert(magick_info->signature == MagickCoreSignature);
864   return(magick_info->mime_type);
865 }
866 
867 /*
868 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
869 %                                                                             %
870 %                                                                             %
871 %                                                                             %
872 %   G e t M a g i c k P r e c i s i o n                                       %
873 %                                                                             %
874 %                                                                             %
875 %                                                                             %
876 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
877 %
878 %  GetMagickPrecision() returns the maximum number of significant digits to be
879 %  printed.
880 %
881 %  The format of the GetMagickPrecision method is:
882 %
883 %      int GetMagickPrecision(void)
884 %
885 */
GetMagickPrecision(void)886 MagickExport int GetMagickPrecision(void)
887 {
888   (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
889   return(SetMagickPrecision(0));
890 }
891 
892 /*
893 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
894 %                                                                             %
895 %                                                                             %
896 %                                                                             %
897 +   G e t M a g i c k R a w S u p p o r t                                     %
898 %                                                                             %
899 %                                                                             %
900 %                                                                             %
901 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
902 %
903 %  GetMagickRawSupport() returns the MagickTrue if the coder is a raw format.
904 %
905 %  The format of the GetMagickRawSupport method is:
906 %
907 %      MagickBooleanType GetMagickRawSupport(const MagickInfo *magick_info)
908 %
909 %  A description of each parameter follows:
910 %
911 %    o magick_info:  The magick info.
912 %
913 */
GetMagickRawSupport(const MagickInfo * magick_info)914 MagickExport MagickBooleanType GetMagickRawSupport(
915   const MagickInfo *magick_info)
916 {
917   assert(magick_info != (MagickInfo *) NULL);
918   assert(magick_info->signature == MagickCoreSignature);
919   return(((magick_info->flags & CoderRawSupportFlag) == 0) ? MagickFalse :
920     MagickTrue);
921 }
922 
923 
924 /*
925 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
926 %                                                                             %
927 %                                                                             %
928 %                                                                             %
929 +   G e t M a g i c k S t e a l t h                                           %
930 %                                                                             %
931 %                                                                             %
932 %                                                                             %
933 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
934 %
935 %  GetMagickStealth() returns MagickTrue if the magick is a stealth coder.
936 %
937 %  The format of the GetMagickStealth method is:
938 %
939 %      MagickBooleanType GetMagickStealth(const MagickInfo *magick_info)
940 %
941 %  A description of each parameter follows:
942 %
943 %    o magick_info:  The magick info.
944 %
945 */
GetMagickStealth(const MagickInfo * magick_info)946 MagickExport MagickBooleanType GetMagickStealth(const MagickInfo *magick_info)
947 {
948   assert(magick_info != (MagickInfo *) NULL);
949   assert(magick_info->signature == MagickCoreSignature);
950   return(((magick_info->flags & CoderStealthFlag) == 0) ? MagickFalse :
951     MagickTrue);
952 }
953 
954 
955 /*
956 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
957 %                                                                             %
958 %                                                                             %
959 %                                                                             %
960 +   G e t M a g i c k U s e E x t e n s i o n                                 %
961 %                                                                             %
962 %                                                                             %
963 %                                                                             %
964 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
965 %
966 %  GetMagickUseExtension() returns MagickTrue if the magick can use the
967 %  extension of the format if the format return by IsImageFormatHandler uses
968 %  the same coder.
969 %
970 %  The format of the GetMagickUseExtension method is:
971 %
972 %      MagickBooleanType GetMagickUseExtension(const MagickInfo *magick_info)
973 %
974 %  A description of each parameter follows:
975 %
976 %    o magick_info:  The magick info.
977 %
978 */
GetMagickUseExtension(const MagickInfo * magick_info)979 MagickExport MagickBooleanType GetMagickUseExtension(
980   const MagickInfo *magick_info)
981 {
982   assert(magick_info != (MagickInfo *) NULL);
983   assert(magick_info->signature == MagickCoreSignature);
984   return(((magick_info->flags & CoderUseExtensionFlag) == 0) ? MagickFalse :
985     MagickTrue);
986 }
987 
988 /*
989 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
990 %                                                                             %
991 %                                                                             %
992 %                                                                             %
993 +   I s M a g i c k T r e e I n s t a n t i a t e d                           %
994 %                                                                             %
995 %                                                                             %
996 %                                                                             %
997 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
998 %
999 %  IsMagickTreeInstantiated() determines if the magick tree is instantiated.
1000 %  If not, it instantiates the tree and returns it.
1001 %
1002 %  The format of the IsMagickTreeInstantiated() method is:
1003 %
1004 %      IsMagickTreeInstantiated(Exceptioninfo *exception)
1005 %
1006 %  A description of each parameter follows.
1007 %
1008 %    o exception: return any errors or warnings in this structure.
1009 %
1010 */
1011 
DestroyMagickNode(void * magick_info)1012 static void *DestroyMagickNode(void *magick_info)
1013 {
1014   register MagickInfo
1015     *p;
1016 
1017   p=(MagickInfo *) magick_info;
1018   if (p->module != (char *) NULL)
1019     p->module=DestroyString(p->module);
1020   if (p->note != (char *) NULL)
1021     p->note=DestroyString(p->note);
1022   if (p->mime_type != (char *) NULL)
1023     p->mime_type=DestroyString(p->mime_type);
1024   if (p->version != (char *) NULL)
1025     p->version=DestroyString(p->version);
1026   if (p->description != (char *) NULL)
1027     p->description=DestroyString(p->description);
1028   if (p->name != (char *) NULL)
1029     p->name=DestroyString(p->name);
1030   if (p->semaphore != (SemaphoreInfo *) NULL)
1031     RelinquishSemaphoreInfo(&p->semaphore);
1032   return(RelinquishMagickMemory(p));
1033 }
1034 
IsMagickTreeInstantiated(ExceptionInfo * exception)1035 static MagickBooleanType IsMagickTreeInstantiated(ExceptionInfo *exception)
1036 {
1037   if (magick_list_initialized == MagickFalse)
1038     {
1039       if (magick_semaphore == (SemaphoreInfo *) NULL)
1040         ActivateSemaphoreInfo(&magick_semaphore);
1041       LockSemaphoreInfo(magick_semaphore);
1042       if (magick_list_initialized == MagickFalse)
1043         {
1044           magick_list=NewSplayTree(CompareSplayTreeString,(void *(*)(void *))
1045             NULL,DestroyMagickNode);
1046 #if defined(MAGICKCORE_MODULES_SUPPORT)
1047           (void) GetModuleInfo((char *) NULL,exception);
1048 #endif
1049           magick_list_initialized=MagickTrue;
1050         }
1051       UnlockSemaphoreInfo(magick_semaphore);
1052     }
1053   return(magick_list != (SplayTreeInfo *) NULL ? MagickTrue : MagickFalse);
1054 }
1055 
1056 /*
1057 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1058 %                                                                             %
1059 %                                                                             %
1060 %                                                                             %
1061 +   I s M a g i c k C o n f l i c t                                           %
1062 %                                                                             %
1063 %                                                                             %
1064 %                                                                             %
1065 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1066 %
1067 %  IsMagickConflict() returns MagickTrue if the image format conflicts with a
1068 %  logical drive (.e.g. X:).
1069 %
1070 %  The format of the IsMagickConflict method is:
1071 %
1072 %      MagickBooleanType IsMagickConflict(const char *magick)
1073 %
1074 %  A description of each parameter follows:
1075 %
1076 %    o magick: Specifies the image format.
1077 %
1078 */
IsMagickConflict(const char * magick)1079 MagickPrivate MagickBooleanType IsMagickConflict(const char *magick)
1080 {
1081   assert(magick != (char *) NULL);
1082 #if defined(macintosh)
1083   return(MACIsMagickConflict(magick));
1084 #elif defined(vms)
1085   return(VMSIsMagickConflict(magick));
1086 #elif defined(MAGICKCORE_WINDOWS_SUPPORT)
1087   return(NTIsMagickConflict(magick));
1088 #else
1089   return(MagickFalse);
1090 #endif
1091 }
1092 
1093 /*
1094 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1095 %                                                                             %
1096 %                                                                             %
1097 %                                                                             %
1098 +  L i s t M a g i c k I n f o                                                %
1099 %                                                                             %
1100 %                                                                             %
1101 %                                                                             %
1102 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1103 %
1104 %  ListMagickInfo() lists the image formats to a file.
1105 %
1106 %  The format of the ListMagickInfo method is:
1107 %
1108 %      MagickBooleanType ListMagickInfo(FILE *file,ExceptionInfo *exception)
1109 %
1110 %  A description of each parameter follows.
1111 %
1112 %    o file: A file handle.
1113 %
1114 %    o exception: return any errors or warnings in this structure.
1115 %
1116 */
ListMagickInfo(FILE * file,ExceptionInfo * exception)1117 MagickExport MagickBooleanType ListMagickInfo(FILE *file,
1118   ExceptionInfo *exception)
1119 {
1120   const MagickInfo
1121     **magick_info;
1122 
1123   register ssize_t
1124     i;
1125 
1126   size_t
1127     number_formats;
1128 
1129   ssize_t
1130     j;
1131 
1132   if (file == (FILE *) NULL)
1133     file=stdout;
1134   magick_info=GetMagickInfoList("*",&number_formats,exception);
1135   if (magick_info == (const MagickInfo **) NULL)
1136     return(MagickFalse);
1137   ClearMagickException(exception);
1138 #if !defined(MAGICKCORE_MODULES_SUPPORT)
1139   (void) FormatLocaleFile(file,"   Format  Mode  Description\n");
1140 #else
1141   (void) FormatLocaleFile(file,"   Format  Module    Mode  Description\n");
1142 #endif
1143   (void) FormatLocaleFile(file,
1144     "--------------------------------------------------------"
1145     "-----------------------\n");
1146   for (i=0; i < (ssize_t) number_formats; i++)
1147   {
1148     if (GetMagickStealth(magick_info[i]) != MagickFalse)
1149       continue;
1150     (void) FormatLocaleFile(file,"%9s%c ",
1151       magick_info[i]->name != (char *) NULL ? magick_info[i]->name : "",
1152       GetMagickBlobSupport(magick_info[i]) != MagickFalse ? '*' : ' ');
1153 #if defined(MAGICKCORE_MODULES_SUPPORT)
1154     {
1155       char
1156         module[MagickPathExtent];
1157 
1158       *module='\0';
1159       if (magick_info[i]->module != (char *) NULL)
1160         (void) CopyMagickString(module,magick_info[i]->module,MagickPathExtent);
1161       (void) ConcatenateMagickString(module,"          ",MagickPathExtent);
1162       module[9]='\0';
1163       (void) FormatLocaleFile(file,"%9s ",module);
1164     }
1165 #endif
1166     (void) FormatLocaleFile(file,"%c%c%c ",magick_info[i]->decoder ? 'r' : '-',
1167       magick_info[i]->encoder ? 'w' : '-',magick_info[i]->encoder != NULL &&
1168       GetMagickAdjoin(magick_info[i]) != MagickFalse ? '+' : '-');
1169     if (magick_info[i]->description != (char *) NULL)
1170       (void) FormatLocaleFile(file,"  %s",magick_info[i]->description);
1171     if (magick_info[i]->version != (char *) NULL)
1172       (void) FormatLocaleFile(file," (%s)",magick_info[i]->version);
1173     (void) FormatLocaleFile(file,"\n");
1174     if (magick_info[i]->note != (char *) NULL)
1175       {
1176         char
1177           **text;
1178 
1179         text=StringToList(magick_info[i]->note);
1180         if (text != (char **) NULL)
1181           {
1182             for (j=0; text[j] != (char *) NULL; j++)
1183             {
1184               (void) FormatLocaleFile(file,"           %s\n",text[j]);
1185               text[j]=DestroyString(text[j]);
1186             }
1187             text=(char **) RelinquishMagickMemory(text);
1188           }
1189       }
1190   }
1191   (void) FormatLocaleFile(file,"\n* native blob support\n");
1192   (void) FormatLocaleFile(file,"r read support\n");
1193   (void) FormatLocaleFile(file,"w write support\n");
1194   (void) FormatLocaleFile(file,"+ support for multiple images\n");
1195   (void) fflush(file);
1196   magick_info=(const MagickInfo **) RelinquishMagickMemory((void *)
1197     magick_info);
1198   return(MagickTrue);
1199 }
1200 
1201 /*
1202 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1203 %                                                                             %
1204 %                                                                             %
1205 %                                                                             %
1206 %  I s M a g i c k C o r e I n s t a n t i a t e d                            %
1207 %                                                                             %
1208 %                                                                             %
1209 %                                                                             %
1210 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1211 %
1212 %  IsMagickCoreInstantiated() returns MagickTrue if the ImageMagick environment
1213 %  is currently instantiated:  MagickCoreGenesis() has been called but
1214 %  MagickDestroy() has not.
1215 %
1216 %  The format of the IsMagickCoreInstantiated method is:
1217 %
1218 %      MagickBooleanType IsMagickCoreInstantiated(void)
1219 %
1220 */
IsMagickCoreInstantiated(void)1221 MagickExport MagickBooleanType IsMagickCoreInstantiated(void)
1222 {
1223   return(instantiate_magickcore);
1224 }
1225 
1226 /*
1227 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1228 %                                                                             %
1229 %                                                                             %
1230 %                                                                             %
1231 +   M a g i c k C o m p o n e n t G e n e s i s                               %
1232 %                                                                             %
1233 %                                                                             %
1234 %                                                                             %
1235 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1236 %
1237 %  MagickComponentGenesis() instantiates the magick component.
1238 %
1239 %  The format of the MagickComponentGenesis method is:
1240 %
1241 %      MagickBooleanType MagickComponentGenesis(void)
1242 %
1243 */
MagickComponentGenesis(void)1244 MagickPrivate MagickBooleanType MagickComponentGenesis(void)
1245 {
1246   if (magick_semaphore == (SemaphoreInfo *) NULL)
1247     magick_semaphore=AcquireSemaphoreInfo();
1248   return(MagickTrue);
1249 }
1250 
1251 /*
1252 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1253 %                                                                             %
1254 %                                                                             %
1255 %                                                                             %
1256 +   M a g i c k C o m p o n e n t T e r m i n u s                             %
1257 %                                                                             %
1258 %                                                                             %
1259 %                                                                             %
1260 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1261 %
1262 %  MagickComponentTerminus() destroys the magick component.
1263 %
1264 %  The format of the MagickComponentTerminus method is:
1265 %
1266 %      void MagickComponentTerminus(void)
1267 %
1268 */
MagickComponentTerminus(void)1269 MagickPrivate void MagickComponentTerminus(void)
1270 {
1271   if (magick_semaphore == (SemaphoreInfo *) NULL)
1272     ActivateSemaphoreInfo(&magick_semaphore);
1273   LockSemaphoreInfo(magick_semaphore);
1274   if (magick_list != (SplayTreeInfo *) NULL)
1275     {
1276       magick_list=DestroySplayTree(magick_list);
1277       magick_list_initialized=MagickFalse;
1278     }
1279   UnlockSemaphoreInfo(magick_semaphore);
1280   RelinquishSemaphoreInfo(&magick_semaphore);
1281 }
1282 
1283 /*
1284 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1285 %                                                                             %
1286 %                                                                             %
1287 %                                                                             %
1288 %   M a g i c k C o r e G e n e s i s                                         %
1289 %                                                                             %
1290 %                                                                             %
1291 %                                                                             %
1292 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1293 %
1294 %  MagickCoreGenesis() initializes the MagickCore environment.
1295 %
1296 %  The format of the MagickCoreGenesis function is:
1297 %
1298 %      MagickCoreGenesis(const char *path,
1299 %        const MagickBooleanType establish_signal_handlers)
1300 %
1301 %  A description of each parameter follows:
1302 %
1303 %    o path: the execution path of the current ImageMagick client.
1304 %
1305 %    o establish_signal_handlers: set to MagickTrue to use MagickCore's own
1306 %      signal handlers for common signals.
1307 %
1308 */
1309 
SetMagickSignalHandler(int signal_number,SignalHandler * handler)1310 static SignalHandler *SetMagickSignalHandler(int signal_number,
1311   SignalHandler *handler)
1312 {
1313 #if defined(MAGICKCORE_HAVE_SIGACTION) && defined(MAGICKCORE_HAVE_SIGEMPTYSET)
1314   int
1315     status;
1316 
1317   sigset_t
1318     mask;
1319 
1320   struct sigaction
1321     action,
1322     previous_action;
1323 
1324   sigemptyset(&mask);
1325   sigaddset(&mask,signal_number);
1326   sigprocmask(SIG_BLOCK,&mask,NULL);
1327   action.sa_mask=mask;
1328   action.sa_handler=handler;
1329   action.sa_flags=0;
1330 #if defined(SA_INTERRUPT)
1331   action.sa_flags|=SA_INTERRUPT;
1332 #endif
1333 #if defined(SA_ONSTACK)
1334   action.sa_flags|=SA_ONSTACK;
1335 #endif
1336   status=sigaction(signal_number,&action,&previous_action);
1337   if (status < 0)
1338     return(SIG_ERR);
1339   sigprocmask(SIG_UNBLOCK,&mask,NULL);
1340   return(previous_action.sa_handler);
1341 #else
1342   return(signal(signal_number,handler));
1343 #endif
1344 }
1345 
MagickSignalHandler(int signal_number)1346 static void MagickSignalHandler(int signal_number)
1347 {
1348   if (magickcore_signal_in_progress != MagickFalse)
1349     (void) SetMagickSignalHandler(signal_number,signal_handlers[signal_number]);
1350   magickcore_signal_in_progress=MagickTrue;
1351   AsynchronousResourceComponentTerminus();
1352 #if defined(SIGQUIT)
1353   if (signal_number == SIGQUIT)
1354     abort();
1355 #endif
1356 #if defined(SIGABRT)
1357   if (signal_number == SIGABRT)
1358     abort();
1359 #endif
1360 #if defined(SIGBUS)
1361   if (signal_number == SIGBUS)
1362     abort();
1363 #endif
1364 #if defined(SIGFPE)
1365   if (signal_number == SIGFPE)
1366     abort();
1367 #endif
1368 #if defined(SIGXCPU)
1369   if (signal_number == SIGXCPU)
1370     abort();
1371 #endif
1372 #if defined(SIGXFSZ)
1373   if (signal_number == SIGXFSZ)
1374     abort();
1375 #endif
1376 #if defined(SIGSEGV)
1377   if (signal_number == SIGSEGV)
1378     abort();
1379 #endif
1380 #if !defined(MAGICKCORE_HAVE__EXIT)
1381   exit(signal_number);
1382 #else
1383 #if defined(SIGHUP)
1384   if (signal_number == SIGHUP)
1385     _exit(signal_number);
1386 #endif
1387 #if defined(SIGINT)
1388   if (signal_number == SIGINT)
1389     _exit(signal_number);
1390 #endif
1391 #if defined(SIGBUS)
1392   if (signal_number == SIGBUS)
1393     _exit(signal_number);
1394 #endif
1395 #if defined(MAGICKCORE_HAVE_RAISE)
1396   if (signal_handlers[signal_number] != MagickSignalHandler)
1397     raise(signal_number);
1398 #endif
1399   _exit(signal_number);  /* do not invoke registered atexit() methods */
1400 #endif
1401 }
1402 
RegisterMagickSignalHandler(int signal_number)1403 static SignalHandler *RegisterMagickSignalHandler(int signal_number)
1404 {
1405   SignalHandler
1406     *handler;
1407 
1408   handler=SetMagickSignalHandler(signal_number,MagickSignalHandler);
1409   if (handler == SIG_ERR)
1410     return(handler);
1411   if (handler != SIG_DFL)
1412     handler=SetMagickSignalHandler(signal_number,handler);
1413   else
1414     (void) LogMagickEvent(ConfigureEvent,GetMagickModule(),
1415       "Register handler for signal: %d",signal_number);
1416   return(handler);
1417 }
1418 
MagickCoreGenesis(const char * path,const MagickBooleanType establish_signal_handlers)1419 MagickExport void MagickCoreGenesis(const char *path,
1420   const MagickBooleanType establish_signal_handlers)
1421 {
1422   char
1423     *events,
1424     execution_path[MagickPathExtent],
1425     filename[MagickPathExtent];
1426 
1427   /*
1428     Initialize the Magick environment.
1429   */
1430   InitializeMagickMutex();
1431   LockMagickMutex();
1432   if (instantiate_magickcore != MagickFalse)
1433     {
1434       UnlockMagickMutex();
1435       return;
1436     }
1437   (void) SemaphoreComponentGenesis();
1438   (void) LogComponentGenesis();
1439   (void) LocaleComponentGenesis();
1440   (void) RandomComponentGenesis();
1441   events=GetEnvironmentValue("MAGICK_DEBUG");
1442   if (events != (char *) NULL)
1443     {
1444       (void) SetLogEventMask(events);
1445       events=DestroyString(events);
1446     }
1447 #if defined(MAGICKCORE_WINDOWS_SUPPORT)
1448   NTWindowsGenesis();
1449 #endif
1450   /*
1451     Set client name and execution path.
1452   */
1453 #if defined(MAGICKCORE_WINDOWS_SUPPORT)
1454   if ((path != (const char *) NULL) && (IsPathAccessible(path) != MagickFalse))
1455 #else
1456   if ((path != (const char *) NULL) && (*path == *DirectorySeparator) &&
1457       (IsPathAccessible(path) != MagickFalse))
1458 #endif
1459     (void) CopyMagickString(execution_path,path,MagickPathExtent);
1460   else
1461     (void) GetExecutionPath(execution_path,MagickPathExtent);
1462   GetPathComponent(execution_path,TailPath,filename);
1463   (void) SetClientName(filename);
1464   GetPathComponent(execution_path,HeadPath,execution_path);
1465   (void) SetClientPath(execution_path);
1466   if (establish_signal_handlers != MagickFalse)
1467     {
1468       /*
1469         Set signal handlers.
1470       */
1471 #if defined(SIGABRT)
1472       if (signal_handlers[SIGABRT] == (SignalHandler *) NULL)
1473         signal_handlers[SIGABRT]=RegisterMagickSignalHandler(SIGABRT);
1474 #endif
1475 #if defined(SIGBUS)
1476       if (signal_handlers[SIGBUS] == (SignalHandler *) NULL)
1477         signal_handlers[SIGBUS]=RegisterMagickSignalHandler(SIGBUS);
1478 #endif
1479 #if defined(SIGSEGV)
1480       if (signal_handlers[SIGSEGV] == (SignalHandler *) NULL)
1481         signal_handlers[SIGSEGV]=RegisterMagickSignalHandler(SIGSEGV);
1482 #endif
1483 #if defined(SIGFPE)
1484       if (signal_handlers[SIGFPE] == (SignalHandler *) NULL)
1485         signal_handlers[SIGFPE]=RegisterMagickSignalHandler(SIGFPE);
1486 #endif
1487 #if defined(SIGHUP)
1488       if (signal_handlers[SIGHUP] == (SignalHandler *) NULL)
1489         signal_handlers[SIGHUP]=RegisterMagickSignalHandler(SIGHUP);
1490 #endif
1491 #if defined(SIGINT)
1492       if (signal_handlers[SIGINT] == (SignalHandler *) NULL)
1493         signal_handlers[SIGINT]=RegisterMagickSignalHandler(SIGINT);
1494 #endif
1495 #if defined(SIGQUIT)
1496       if (signal_handlers[SIGQUIT] == (SignalHandler *) NULL)
1497         signal_handlers[SIGQUIT]=RegisterMagickSignalHandler(SIGQUIT);
1498 #endif
1499 #if defined(SIGTERM)
1500       if (signal_handlers[SIGTERM] == (SignalHandler *) NULL)
1501         signal_handlers[SIGTERM]=RegisterMagickSignalHandler(SIGTERM);
1502 #endif
1503 #if defined(SIGXCPU)
1504       if (signal_handlers[SIGXCPU] == (SignalHandler *) NULL)
1505         signal_handlers[SIGXCPU]=RegisterMagickSignalHandler(SIGXCPU);
1506 #endif
1507 #if defined(SIGXFSZ)
1508       if (signal_handlers[SIGXFSZ] == (SignalHandler *) NULL)
1509         signal_handlers[SIGXFSZ]=RegisterMagickSignalHandler(SIGXFSZ);
1510 #endif
1511     }
1512   /*
1513     Instantiate magick resources.
1514   */
1515   (void) ConfigureComponentGenesis();
1516   (void) PolicyComponentGenesis();
1517 #if defined(MAGICKCORE_ZERO_CONFIGURATION_SUPPORT)
1518   (void) ZeroConfigurationPolicy;
1519 #endif
1520   (void) CacheComponentGenesis();
1521   (void) ResourceComponentGenesis();
1522   (void) CoderComponentGenesis();
1523   (void) MagickComponentGenesis();
1524 #if defined(MAGICKCORE_MODULES_SUPPORT)
1525   (void) ModuleComponentGenesis();
1526 #endif
1527   (void) DelegateComponentGenesis();
1528   (void) MagicComponentGenesis();
1529   (void) ColorComponentGenesis();
1530   (void) TypeComponentGenesis();
1531   (void) MimeComponentGenesis();
1532   (void) AnnotateComponentGenesis();
1533 #if defined(MAGICKCORE_X11_DELEGATE)
1534   (void) XComponentGenesis();
1535 #endif
1536   (void) RegistryComponentGenesis();
1537   (void) MonitorComponentGenesis();
1538   instantiate_magickcore=MagickTrue;
1539   UnlockMagickMutex();
1540 }
1541 
1542 /*
1543 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1544 %                                                                             %
1545 %                                                                             %
1546 %                                                                             %
1547 %   M a g i c k C o r e T e r m i n u s                                       %
1548 %                                                                             %
1549 %                                                                             %
1550 %                                                                             %
1551 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1552 %
1553 %  MagickCoreTerminus() destroys the MagickCore environment.
1554 %
1555 %  The format of the MagickCoreTerminus function is:
1556 %
1557 %      MagickCoreTerminus(void)
1558 %
1559 */
MagickCoreTerminus(void)1560 MagickExport void MagickCoreTerminus(void)
1561 {
1562   InitializeMagickMutex();
1563   LockMagickMutex();
1564   if (instantiate_magickcore == MagickFalse)
1565     {
1566       UnlockMagickMutex();
1567       return;
1568     }
1569   MonitorComponentTerminus();
1570   RegistryComponentTerminus();
1571 #if defined(MAGICKCORE_X11_DELEGATE)
1572   XComponentTerminus();
1573 #endif
1574 #if defined(MAGICKCORE_XML_DELEGATE)
1575   xmlCleanupParser();
1576 #endif
1577   AnnotateComponentTerminus();
1578   MimeComponentTerminus();
1579   TypeComponentTerminus();
1580 #if defined(MAGICKCORE_OPENCL_SUPPORT)
1581   OpenCLTerminus();
1582 #endif
1583   ColorComponentTerminus();
1584 #if defined(MAGICKCORE_WINDOWS_SUPPORT)
1585   NTWindowsTerminus();
1586 #endif
1587   MagicComponentTerminus();
1588   DelegateComponentTerminus();
1589   MagickComponentTerminus();
1590 #if !defined(MAGICKCORE_BUILD_MODULES)
1591   UnregisterStaticModules();
1592 #endif
1593 #if defined(MAGICKCORE_MODULES_SUPPORT)
1594   ModuleComponentTerminus();
1595 #endif
1596   CoderComponentTerminus();
1597   ResourceComponentTerminus();
1598   CacheComponentTerminus();
1599   PolicyComponentTerminus();
1600   ConfigureComponentTerminus();
1601   RandomComponentTerminus();
1602   LocaleComponentTerminus();
1603   LogComponentTerminus();
1604   instantiate_magickcore=MagickFalse;
1605   UnlockMagickMutex();
1606   SemaphoreComponentTerminus();
1607 }
1608 
1609 /*
1610 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1611 %                                                                             %
1612 %                                                                             %
1613 %                                                                             %
1614 +   R e g i s t e r M a g i c k I n f o                                       %
1615 %                                                                             %
1616 %                                                                             %
1617 %                                                                             %
1618 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1619 %
1620 %  RegisterMagickInfo() adds attributes for a particular image format to the
1621 %  list of supported formats.  The attributes include the image format name,
1622 %  a method to read and/or write the format, whether the format supports the
1623 %  saving of more than one frame to the same file or blob, whether the format
1624 %  supports native in-memory I/O, and a brief description of the format.
1625 %
1626 %  The format of the RegisterMagickInfo method is:
1627 %
1628 %      MagickInfo *RegisterMagickInfo(MagickInfo *magick_info)
1629 %
1630 %  A description of each parameter follows:
1631 %
1632 %    o magick_info: the magick info.
1633 %
1634 */
RegisterMagickInfo(MagickInfo * magick_info)1635 MagickExport MagickBooleanType RegisterMagickInfo(MagickInfo *magick_info)
1636 {
1637   MagickBooleanType
1638     status;
1639 
1640   /*
1641     Register a new image format.
1642   */
1643   assert(magick_info != (MagickInfo *) NULL);
1644   assert(magick_info->signature == MagickCoreSignature);
1645   (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",magick_info->name);
1646   if (magick_list == (SplayTreeInfo *) NULL)
1647     return(MagickFalse);
1648   if ((GetMagickDecoderThreadSupport(magick_info) == MagickFalse) ||
1649       (GetMagickEncoderThreadSupport(magick_info) == MagickFalse))
1650     magick_info->semaphore=AcquireSemaphoreInfo();
1651   status=AddValueToSplayTree(magick_list,magick_info->name,magick_info);
1652   return(status);
1653 }
1654 
1655 /*
1656 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1657 %                                                                             %
1658 %                                                                             %
1659 %                                                                             %
1660 +   R e s e t M a g i c k P r e c i s i o n                                   %
1661 %                                                                             %
1662 %                                                                             %
1663 %                                                                             %
1664 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1665 %
1666 %  ResetMagickPrecision() resets the magick_precision value.
1667 %
1668 %  The format of the ResetMagickPrecision method is:
1669 %
1670 %      void ResetMagickPrecision(void)
1671 %
1672 */
ResetMagickPrecision(void)1673 MagickPrivate void ResetMagickPrecision(void)
1674 {
1675   magick_precision=0;
1676 }
1677 
1678 /*
1679 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1680 %                                                                             %
1681 %                                                                             %
1682 %                                                                             %
1683 %   S e t M a g i c k P r e c i s i o n                                       %
1684 %                                                                             %
1685 %                                                                             %
1686 %                                                                             %
1687 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1688 %
1689 %  SetMagickPrecision() sets the maximum number of significant digits to be
1690 %  printed.
1691 %
1692 %  An input argument of 0 returns the current precision setting.
1693 %
1694 %  A negative value forces the precision to reset to a default value according
1695 %  to the environment variable "MAGICK_PRECISION", the current 'policy'
1696 %  configuration setting, or the default value of '6', in that order.
1697 %
1698 %  The format of the SetMagickPrecision method is:
1699 %
1700 %      int SetMagickPrecision(const int precision)
1701 %
1702 %  A description of each parameter follows:
1703 %
1704 %    o precision: set the maximum number of significant digits to be printed.
1705 %
1706 */
SetMagickPrecision(const int precision)1707 MagickExport int SetMagickPrecision(const int precision)
1708 {
1709 #define MagickPrecision  6
1710 
1711   (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
1712   if (precision > 0)
1713     magick_precision=precision;
1714   if ((precision < 0) || (magick_precision == 0))
1715     {
1716       char
1717         *limit;
1718 
1719       /*
1720         Precision reset, or it has not been set yet
1721       */
1722       magick_precision=MagickPrecision;
1723       limit=GetEnvironmentValue("MAGICK_PRECISION");
1724       if (limit == (char *) NULL)
1725         limit=GetPolicyValue("system:precision");
1726       if (limit != (char *) NULL)
1727         {
1728           magick_precision=StringToInteger(limit);
1729           limit=DestroyString(limit);
1730         }
1731     }
1732   return(magick_precision);
1733 }
1734 
1735 /*
1736 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1737 %                                                                             %
1738 %                                                                             %
1739 %                                                                             %
1740 +   U n r e g i s t e r M a g i c k I n f o                                   %
1741 %                                                                             %
1742 %                                                                             %
1743 %                                                                             %
1744 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1745 %
1746 %  UnregisterMagickInfo() removes a name from the magick info list.  It returns
1747 %  MagickFalse if the name does not exist in the list otherwise MagickTrue.
1748 %
1749 %  The format of the UnregisterMagickInfo method is:
1750 %
1751 %      MagickBooleanType UnregisterMagickInfo(const char *name)
1752 %
1753 %  A description of each parameter follows:
1754 %
1755 %    o name: a character string that represents the image format we are
1756 %      looking for.
1757 %
1758 */
UnregisterMagickInfo(const char * name)1759 MagickExport MagickBooleanType UnregisterMagickInfo(const char *name)
1760 {
1761   register const MagickInfo
1762     *p;
1763 
1764   MagickBooleanType
1765     status;
1766 
1767   assert(name != (const char *) NULL);
1768   if (magick_list == (SplayTreeInfo *) NULL)
1769     return(MagickFalse);
1770   if (GetNumberOfNodesInSplayTree(magick_list) == 0)
1771     return(MagickFalse);
1772   LockSemaphoreInfo(magick_semaphore);
1773   ResetSplayTreeIterator(magick_list);
1774   p=(const MagickInfo *) GetNextValueInSplayTree(magick_list);
1775   while (p != (const MagickInfo *) NULL)
1776   {
1777     if (LocaleCompare(p->name,name) == 0)
1778       break;
1779     p=(const MagickInfo *) GetNextValueInSplayTree(magick_list);
1780   }
1781   status=DeleteNodeByValueFromSplayTree(magick_list,p);
1782   UnlockSemaphoreInfo(magick_semaphore);
1783   return(status);
1784 }
1785