MagickCore  7.1.0
Convert, Edit, Or Compose Bitmap Images
magick.c
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 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/mime-private.h"
65 #include "MagickCore/monitor-private.h"
66 #include "MagickCore/module.h"
67 #include "MagickCore/module-private.h"
68 #include "MagickCore/mutex.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/mutex.h"
81 #include "MagickCore/semaphore.h"
82 #include "MagickCore/semaphore-private.h"
83 #include "MagickCore/signature-private.h"
84 #include "MagickCore/splay-tree.h"
85 #include "MagickCore/static.h"
86 #include "MagickCore/string_.h"
87 #include "MagickCore/string-private.h"
88 #include "MagickCore/thread_.h"
89 #include "MagickCore/thread-private.h"
90 #include "MagickCore/type-private.h"
91 #include "MagickCore/token.h"
92 #include "MagickCore/utility.h"
93 #include "MagickCore/utility-private.h"
94 #include "MagickCore/xwindow-private.h"
95 #if defined(MAGICKCORE_XML_DELEGATE)
96 # if defined(MAGICKCORE_WINDOWS_SUPPORT)
97 # if !defined(__MINGW32__)
98 # include <win32config.h>
99 # endif
100 # endif
101 # include <libxml/parser.h>
102 #endif
103 ␌
104 /*
105  Define declarations.
106 */
107 #if !defined(SIG_DFL)
108 # define SIG_DFL ((SignalHandler *) 0)
109 #endif
110 #if !defined(SIG_ERR)
111 # define SIG_ERR ((SignalHandler *) -1)
112 #endif
113 #if !defined(SIGMAX)
114 #define SIGMAX 64
115 #endif
116 ␌
117 /*
118  Typedef declarations.
119 */
120 typedef void SignalHandler(int);
121 ␌
122 /*
123  Global declarations.
124 */
125 static SemaphoreInfo
126  *magick_semaphore = (SemaphoreInfo *) NULL;
127 
128 static SignalHandler
129  *signal_handlers[SIGMAX] = { (SignalHandler *) NULL };
130 
131 static SplayTreeInfo
132  *magick_list = (SplayTreeInfo *) NULL;
133 
134 static volatile MagickBooleanType
135  magickcore_instantiated = MagickFalse,
136  magickcore_signal_in_progress = MagickFalse,
137  magick_list_initialized = MagickFalse;
138 
139 static int
140  magick_precision = 0;
141 ␌
142 /*
143  Forward declarations.
144 */
145 static MagickBooleanType
146  IsMagickTreeInstantiated(ExceptionInfo *);
147 ␌
148 /*
149 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
150 % %
151 % %
152 % %
153 % A c q u i r e M a g i c k I n f o %
154 % %
155 % %
156 % %
157 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
158 %
159 % AcquireMagickInfo() allocates a MagickInfo structure and initializes the
160 % members to default values.
161 %
162 % The format of the AcquireMagickInfo method is:
163 %
164 % MagickInfo *AcquireMagickInfo(const char *magick_module,
165 % const char *name,const char *description)
166 %
167 % A description of each parameter follows:
168 %
169 % o magick_module: a character string that represents the module associated
170 % with the MagickInfo structure.
171 %
172 % o name: a character string that represents the image format associated
173 % with the MagickInfo structure.
174 %
175 % o description: a character string that represents the image format
176 % associated with the MagickInfo structure.
177 %
178 */
179 MagickExport MagickInfo *AcquireMagickInfo(const char *magick_module,
180  const char *name,const char *description)
181 {
182  MagickInfo
183  *magick_info;
184 
185  assert(magick_module != (const char *) NULL);
186  assert(name != (const char *) NULL);
187  assert(description != (const char *) NULL);
188  if (IsEventLogging() != MagickFalse)
189  (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",name);
190  magick_info=(MagickInfo *) AcquireCriticalMemory(sizeof(*magick_info));
191  (void) memset(magick_info,0,sizeof(*magick_info));
192  magick_info->magick_module=ConstantString(magick_module);
193  magick_info->name=ConstantString(name);
194  magick_info->description=ConstantString(description);
195  magick_info->flags=CoderAdjoinFlag | CoderBlobSupportFlag |
196  CoderDecoderThreadSupportFlag | CoderEncoderThreadSupportFlag |
197  CoderUseExtensionFlag;
198  magick_info->signature=MagickCoreSignature;
199  return(magick_info);
200 }
201 ␌
202 /*
203 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
204 % %
205 % %
206 % %
207 + G e t I m a g e D e c o d e r %
208 % %
209 % %
210 % %
211 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
212 %
213 % GetImageDecoder() returns the image decoder.
214 %
215 % The format of the GetImageDecoder method is:
216 %
217 % DecodeImageHandler *GetImageDecoder(const MagickInfo *magick_info)
218 %
219 % A description of each parameter follows:
220 %
221 % o magick_info: The magick info.
222 %
223 */
224 MagickExport DecodeImageHandler *GetImageDecoder(const MagickInfo *magick_info)
225 {
226  if (magick_info == (MagickInfo *) NULL)
227  return((DecodeImageHandler *) NULL);
228  assert(magick_info->signature == MagickCoreSignature);
229  return(magick_info->decoder);
230 }
231 ␌
232 /*
233 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
234 % %
235 % %
236 % %
237 + G e t I m a g e E n c o d e r %
238 % %
239 % %
240 % %
241 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
242 %
243 % GetImageEncoder() returns the image encoder.
244 %
245 % The format of the GetImageEncoder method is:
246 %
247 % EncodeImageHandler *GetImageEncoder(const MagickInfo *magick_info)
248 %
249 % A description of each parameter follows:
250 %
251 % o magick_info: The magick info.
252 %
253 */
254 MagickExport EncodeImageHandler *GetImageEncoder(const MagickInfo *magick_info)
255 {
256  if (magick_info == (MagickInfo *) NULL)
257  return((EncodeImageHandler *) NULL);
258  assert(magick_info->signature == MagickCoreSignature);
259  return(magick_info->encoder);
260 }
261 ␌
262 /*
263 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
264 % %
265 % %
266 % %
267 + G e t I m a g e M a g i c k %
268 % %
269 % %
270 % %
271 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
272 %
273 % GetImageMagick() searches for an image format that matches the specified
274 % magick string. If one is found, MagickTrue is returned otherwise
275 % MagickFalse.
276 %
277 % The format of the GetImageMagick method is:
278 %
279 % MagickBooleanType GetImageMagick(const unsigned char *magick,
280 % const size_t length,char *format)
281 %
282 % A description of each parameter follows:
283 %
284 % o magick: the image format we are searching for.
285 %
286 % o length: the length of the binary string.
287 %
288 % o format: the image format as determined by the magick bytes.
289 %
290 */
291 MagickExport MagickBooleanType GetImageMagick(const unsigned char *magick,
292  const size_t length,char *format)
293 {
295  *exception;
296 
297  MagickBooleanType
298  status;
299 
300  const MagickInfo
301  *p;
302 
303  assert(magick != (const unsigned char *) NULL);
304  if (IsEventLogging() != MagickFalse)
305  (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
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 */
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 */
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 */
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 */
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 */
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 */
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 */
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 */
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 */
612 MagickExport const MagickInfo *GetMagickInfo(const char *name,
613  ExceptionInfo *exception)
614 {
615  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 
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 
702 MagickExport const MagickInfo **GetMagickInfoList(const char *pattern,
703  size_t *number_formats,ExceptionInfo *exception)
704 {
705  const MagickInfo
706  **formats;
707 
708  const MagickInfo
709  *p;
710 
711  ssize_t
712  i;
713 
714  /*
715  Allocate magick list.
716  */
717  assert(pattern != (char *) NULL);
718  assert(number_formats != (size_t *) NULL);
719  if (IsEventLogging() != MagickFalse)
720  (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",pattern);
721  *number_formats=0;
722  p=GetMagickInfo("*",exception);
723  if (p == (const MagickInfo *) NULL)
724  return((const MagickInfo **) NULL);
725  formats=(const MagickInfo **) AcquireQuantumMemory((size_t)
726  GetNumberOfNodesInSplayTree(magick_list)+1UL,sizeof(*formats));
727  if (formats == (const MagickInfo **) NULL)
728  return((const MagickInfo **) NULL);
729  /*
730  Generate magick list.
731  */
732  LockSemaphoreInfo(magick_semaphore);
733  ResetSplayTreeIterator(magick_list);
734  p=(const MagickInfo *) GetNextValueInSplayTree(magick_list);
735  for (i=0; p != (const MagickInfo *) NULL; )
736  {
737  if ((GetMagickStealth(p) == MagickFalse) &&
738  (GlobExpression(p->name,pattern,MagickFalse) != MagickFalse))
739  formats[i++]=p;
740  p=(const MagickInfo *) GetNextValueInSplayTree(magick_list);
741  }
742  UnlockSemaphoreInfo(magick_semaphore);
743  qsort((void *) formats,(size_t) i,sizeof(*formats),MagickInfoCompare);
744  formats[i]=(MagickInfo *) NULL;
745  *number_formats=(size_t) i;
746  return(formats);
747 }
748 ␌
749 /*
750 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
751 % %
752 % %
753 % %
754 + G e t M a g i c k L i s t %
755 % %
756 % %
757 % %
758 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
759 %
760 % GetMagickList() returns any image formats that match the specified pattern.
761 %
762 % The format of the GetMagickList function is:
763 %
764 % char **GetMagickList(const char *pattern,size_t *number_formats,
765 % ExceptionInfo *exception)
766 %
767 % A description of each parameter follows:
768 %
769 % o pattern: Specifies a pointer to a text string containing a pattern.
770 %
771 % o number_formats: This integer returns the number of formats in the list.
772 %
773 % o exception: return any errors or warnings in this structure.
774 %
775 */
776 
777 #if defined(__cplusplus) || defined(c_plusplus)
778 extern "C" {
779 #endif
780 
781 static int MagickCompare(const void *x,const void *y)
782 {
783  const char
784  **p,
785  **q;
786 
787  p=(const char **) x;
788  q=(const char **) y;
789  return(LocaleCompare(*p,*q));
790 }
791 
792 #if defined(__cplusplus) || defined(c_plusplus)
793 }
794 #endif
795 
796 MagickExport char **GetMagickList(const char *pattern,
797  size_t *number_formats,ExceptionInfo *exception)
798 {
799  char
800  **formats;
801 
802  const MagickInfo
803  *p;
804 
805  ssize_t
806  i;
807 
808  /*
809  Allocate magick list.
810  */
811  assert(pattern != (char *) NULL);
812  assert(number_formats != (size_t *) NULL);
813  if (IsEventLogging() != MagickFalse)
814  (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",pattern);
815  *number_formats=0;
816  p=GetMagickInfo("*",exception);
817  if (p == (const MagickInfo *) NULL)
818  return((char **) NULL);
819  formats=(char **) AcquireQuantumMemory((size_t)
820  GetNumberOfNodesInSplayTree(magick_list)+1UL,sizeof(*formats));
821  if (formats == (char **) NULL)
822  return((char **) NULL);
823  LockSemaphoreInfo(magick_semaphore);
824  ResetSplayTreeIterator(magick_list);
825  p=(const MagickInfo *) GetNextValueInSplayTree(magick_list);
826  for (i=0; p != (const MagickInfo *) NULL; )
827  {
828  if ((GetMagickStealth(p) == MagickFalse) &&
829  (GlobExpression(p->name,pattern,MagickFalse) != MagickFalse))
830  formats[i++]=ConstantString(p->name);
831  p=(const MagickInfo *) GetNextValueInSplayTree(magick_list);
832  }
833  UnlockSemaphoreInfo(magick_semaphore);
834  qsort((void *) formats,(size_t) i,sizeof(*formats),MagickCompare);
835  formats[i]=(char *) NULL;
836  *number_formats=(size_t) i;
837  return(formats);
838 }
839 ␌
840 /*
841 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
842 % %
843 % %
844 % %
845 + G e t M a g i c k M i m e T y p e %
846 % %
847 % %
848 % %
849 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
850 %
851 % GetMagickMimeType() returns the magick mime type.
852 %
853 % The format of the GetMagickMimeType method is:
854 %
855 % const char *GetMagickMimeType(const MagickInfo *magick_info)
856 %
857 % A description of each parameter follows:
858 %
859 % o magick_info: The magick info.
860 %
861 */
862 MagickExport const char *GetMagickMimeType(const MagickInfo *magick_info)
863 {
864  assert(magick_info != (MagickInfo *) NULL);
865  assert(magick_info->signature == MagickCoreSignature);
866  return(magick_info->mime_type);
867 }
868 ␌
869 /*
870 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
871 % %
872 % %
873 % %
874 + G e t M a g i c k M o d u l e N a m e %
875 % %
876 % %
877 % %
878 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
879 %
880 % GetMagickModuleName() returns the magick module name.
881 %
882 % The format of the GetMagickModuleName method is:
883 %
884 % const char *GetMagickModuleName(const MagickInfo *magick_info)
885 %
886 % A description of each parameter follows:
887 %
888 % o magick_info: The magick info.
889 %
890 */
891 MagickExport const char *GetMagickModuleName(const MagickInfo *magick_info)
892 {
893  assert(magick_info != (MagickInfo *) NULL);
894  assert(magick_info->signature == MagickCoreSignature);
895  return(magick_info->magick_module);
896 }
897 ␌
898 /*
899 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
900 % %
901 % %
902 % %
903 + G e t M a g i c k N a m e %
904 % %
905 % %
906 % %
907 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
908 %
909 % GetMagickName() returns the magick name.
910 %
911 % The format of the GetMagickName method is:
912 %
913 % const char *GetMagickName(const MagickInfo *magick_info)
914 %
915 % A description of each parameter follows:
916 %
917 % o magick_info: The magick info.
918 %
919 */
920 MagickExport const char *GetMagickName(const MagickInfo *magick_info)
921 {
922  assert(magick_info != (MagickInfo *) NULL);
923  assert(magick_info->signature == MagickCoreSignature);
924  return(magick_info->name);
925 }
926 ␌
927 /*
928 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
929 % %
930 % %
931 % %
932 % G e t M a g i c k P r e c i s i o n %
933 % %
934 % %
935 % %
936 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
937 %
938 % GetMagickPrecision() returns the maximum number of significant digits to be
939 % printed.
940 %
941 % The format of the GetMagickPrecision method is:
942 %
943 % int GetMagickPrecision(void)
944 %
945 */
946 MagickExport int GetMagickPrecision(void)
947 {
948  if (IsEventLogging() != MagickFalse)
949  (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
950  return(SetMagickPrecision(0));
951 }
952 ␌
953 /*
954 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
955 % %
956 % %
957 % %
958 + G e t M a g i c k R a w S u p p o r t %
959 % %
960 % %
961 % %
962 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
963 %
964 % GetMagickRawSupport() returns the MagickTrue if the coder is a raw format.
965 %
966 % The format of the GetMagickRawSupport method is:
967 %
968 % MagickBooleanType GetMagickRawSupport(const MagickInfo *magick_info)
969 %
970 % A description of each parameter follows:
971 %
972 % o magick_info: The magick info.
973 %
974 */
975 MagickExport MagickBooleanType GetMagickRawSupport(
976  const MagickInfo *magick_info)
977 {
978  assert(magick_info != (MagickInfo *) NULL);
979  assert(magick_info->signature == MagickCoreSignature);
980  return(((magick_info->flags & CoderRawSupportFlag) == 0) ? MagickFalse :
981  MagickTrue);
982 }
983 
984 
985 /*
986 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
987 % %
988 % %
989 % %
990 + G e t M a g i c k S t e a l t h %
991 % %
992 % %
993 % %
994 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
995 %
996 % GetMagickStealth() returns MagickTrue if the magick is a stealth coder.
997 %
998 % The format of the GetMagickStealth method is:
999 %
1000 % MagickBooleanType GetMagickStealth(const MagickInfo *magick_info)
1001 %
1002 % A description of each parameter follows:
1003 %
1004 % o magick_info: The magick info.
1005 %
1006 */
1007 MagickExport MagickBooleanType GetMagickStealth(const MagickInfo *magick_info)
1008 {
1009  assert(magick_info != (MagickInfo *) NULL);
1010  assert(magick_info->signature == MagickCoreSignature);
1011  return(((magick_info->flags & CoderStealthFlag) == 0) ? MagickFalse :
1012  MagickTrue);
1013 }
1014 
1015 
1016 /*
1017 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1018 % %
1019 % %
1020 % %
1021 + G e t M a g i c k U s e E x t e n s i o n %
1022 % %
1023 % %
1024 % %
1025 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1026 %
1027 % GetMagickUseExtension() returns MagickTrue if the magick can use the
1028 % extension of the format if the format return by IsImageFormatHandler uses
1029 % the same coder.
1030 %
1031 % The format of the GetMagickUseExtension method is:
1032 %
1033 % MagickBooleanType GetMagickUseExtension(const MagickInfo *magick_info)
1034 %
1035 % A description of each parameter follows:
1036 %
1037 % o magick_info: The magick info.
1038 %
1039 */
1040 MagickExport MagickBooleanType GetMagickUseExtension(
1041  const MagickInfo *magick_info)
1042 {
1043  assert(magick_info != (MagickInfo *) NULL);
1044  assert(magick_info->signature == MagickCoreSignature);
1045  return(((magick_info->flags & CoderUseExtensionFlag) == 0) ? MagickFalse :
1046  MagickTrue);
1047 }
1048 ␌
1049 /*
1050 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1051 % %
1052 % %
1053 % %
1054 + I s M a g i c k T r e e I n s t a n t i a t e d %
1055 % %
1056 % %
1057 % %
1058 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1059 %
1060 % IsMagickTreeInstantiated() determines if the magick tree is instantiated.
1061 % If not, it instantiates the tree and returns it.
1062 %
1063 % The format of the IsMagickTreeInstantiated() method is:
1064 %
1065 % IsMagickTreeInstantiated(Exceptioninfo *exception)
1066 %
1067 % A description of each parameter follows.
1068 %
1069 % o exception: return any errors or warnings in this structure.
1070 %
1071 */
1072 
1073 static void *DestroyMagickNode(void *magick_info)
1074 {
1075  MagickInfo
1076  *p;
1077 
1078  p=(MagickInfo *) magick_info;
1079  if (p->magick_module != (char *) NULL)
1080  p->magick_module=DestroyString(p->magick_module);
1081  if (p->note != (char *) NULL)
1082  p->note=DestroyString(p->note);
1083  if (p->mime_type != (char *) NULL)
1084  p->mime_type=DestroyString(p->mime_type);
1085  if (p->version != (char *) NULL)
1086  p->version=DestroyString(p->version);
1087  if (p->description != (char *) NULL)
1088  p->description=DestroyString(p->description);
1089  if (p->name != (char *) NULL)
1090  p->name=DestroyString(p->name);
1091  if (p->semaphore != (SemaphoreInfo *) NULL)
1092  RelinquishSemaphoreInfo(&p->semaphore);
1093  return(RelinquishMagickMemory(p));
1094 }
1095 
1096 static MagickBooleanType IsMagickTreeInstantiated(ExceptionInfo *exception)
1097 {
1098  (void) exception;
1099  if (magick_list_initialized == MagickFalse)
1100  {
1101  if (magick_semaphore == (SemaphoreInfo *) NULL)
1102  ActivateSemaphoreInfo(&magick_semaphore);
1103  LockSemaphoreInfo(magick_semaphore);
1104  if (magick_list_initialized == MagickFalse)
1105  {
1106  magick_list=NewSplayTree(CompareSplayTreeString,(void *(*)(void *))
1107  NULL,DestroyMagickNode);
1108 #if defined(MAGICKCORE_MODULES_SUPPORT)
1109  (void) GetModuleInfo((char *) NULL,exception);
1110 #endif
1111  magick_list_initialized=MagickTrue;
1112  }
1113  UnlockSemaphoreInfo(magick_semaphore);
1114  }
1115  return(magick_list != (SplayTreeInfo *) NULL ? MagickTrue : MagickFalse);
1116 }
1117 ␌
1118 /*
1119 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1120 % %
1121 % %
1122 % %
1123 + I s M a g i c k C o n f l i c t %
1124 % %
1125 % %
1126 % %
1127 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1128 %
1129 % IsMagickConflict() returns MagickTrue if the image format conflicts with a
1130 % logical drive (.e.g. X:).
1131 %
1132 % The format of the IsMagickConflict method is:
1133 %
1134 % MagickBooleanType IsMagickConflict(const char *magick)
1135 %
1136 % A description of each parameter follows:
1137 %
1138 % o magick: Specifies the image format.
1139 %
1140 */
1141 MagickPrivate MagickBooleanType IsMagickConflict(const char *magick)
1142 {
1143  assert(magick != (char *) NULL);
1144 #if defined(vms)
1145  return(VMSIsMagickConflict(magick));
1146 #elif defined(MAGICKCORE_WINDOWS_SUPPORT)
1147  return(NTIsMagickConflict(magick));
1148 #else
1149  return(MagickFalse);
1150 #endif
1151 }
1152 ␌
1153 /*
1154 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1155 % %
1156 % %
1157 % %
1158 + L i s t M a g i c k I n f o %
1159 % %
1160 % %
1161 % %
1162 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1163 %
1164 % ListMagickInfo() lists the image formats to a file.
1165 %
1166 % The format of the ListMagickInfo method is:
1167 %
1168 % MagickBooleanType ListMagickInfo(FILE *file,ExceptionInfo *exception)
1169 %
1170 % A description of each parameter follows.
1171 %
1172 % o file: A file handle.
1173 %
1174 % o exception: return any errors or warnings in this structure.
1175 %
1176 */
1177 MagickExport MagickBooleanType ListMagickInfo(FILE *file,
1178  ExceptionInfo *exception)
1179 {
1180  const MagickInfo
1181  **magick_info;
1182 
1183  ssize_t
1184  i;
1185 
1186  size_t
1187  number_formats;
1188 
1189  ssize_t
1190  j;
1191 
1192  if (file == (FILE *) NULL)
1193  file=stdout;
1194  magick_info=GetMagickInfoList("*",&number_formats,exception);
1195  if (magick_info == (const MagickInfo **) NULL)
1196  return(MagickFalse);
1197  ClearMagickException(exception);
1198 #if !defined(MAGICKCORE_MODULES_SUPPORT)
1199  (void) FormatLocaleFile(file," Format Mode Description\n");
1200 #else
1201  (void) FormatLocaleFile(file," Format Module Mode Description\n");
1202 #endif
1203  (void) FormatLocaleFile(file,
1204  "--------------------------------------------------------"
1205  "-----------------------\n");
1206  for (i=0; i < (ssize_t) number_formats; i++)
1207  {
1208  if (GetMagickStealth(magick_info[i]) != MagickFalse)
1209  continue;
1210  (void) FormatLocaleFile(file,"%9s%c ",
1211  magick_info[i]->name != (char *) NULL ? magick_info[i]->name : "",
1212  GetMagickBlobSupport(magick_info[i]) != MagickFalse ? '*' : ' ');
1213 #if defined(MAGICKCORE_MODULES_SUPPORT)
1214  {
1215  char
1216  magick_module[MagickPathExtent];
1217 
1218  *magick_module='\0';
1219  if (magick_info[i]->magick_module != (char *) NULL)
1220  (void) CopyMagickString(magick_module,magick_info[i]->magick_module,
1221  MagickPathExtent);
1222  (void) ConcatenateMagickString(magick_module," ",
1223  MagickPathExtent);
1224  magick_module[9]='\0';
1225  (void) FormatLocaleFile(file,"%9s ",magick_module);
1226  }
1227 #endif
1228  (void) FormatLocaleFile(file,"%c%c%c ",magick_info[i]->decoder ? 'r' : '-',
1229  magick_info[i]->encoder ? 'w' : '-',magick_info[i]->encoder != NULL &&
1230  GetMagickAdjoin(magick_info[i]) != MagickFalse ? '+' : '-');
1231  if (magick_info[i]->description != (char *) NULL)
1232  (void) FormatLocaleFile(file," %s",magick_info[i]->description);
1233  if (magick_info[i]->version != (char *) NULL)
1234  (void) FormatLocaleFile(file," (%s)",magick_info[i]->version);
1235  (void) FormatLocaleFile(file,"\n");
1236  if (magick_info[i]->note != (char *) NULL)
1237  {
1238  char
1239  **text;
1240 
1241  text=StringToList(magick_info[i]->note);
1242  if (text != (char **) NULL)
1243  {
1244  for (j=0; text[j] != (char *) NULL; j++)
1245  {
1246  (void) FormatLocaleFile(file," %s\n",text[j]);
1247  text[j]=DestroyString(text[j]);
1248  }
1249  text=(char **) RelinquishMagickMemory(text);
1250  }
1251  }
1252  }
1253  (void) FormatLocaleFile(file,"\n* native blob support\n");
1254  (void) FormatLocaleFile(file,"r read support\n");
1255  (void) FormatLocaleFile(file,"w write support\n");
1256  (void) FormatLocaleFile(file,"+ support for multiple images\n");
1257  (void) fflush(file);
1258  magick_info=(const MagickInfo **) RelinquishMagickMemory((void *)
1259  magick_info);
1260  return(MagickTrue);
1261 }
1262 ␌
1263 /*
1264 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1265 % %
1266 % %
1267 % %
1268 % I s M a g i c k C o r e I n s t a n t i a t e d %
1269 % %
1270 % %
1271 % %
1272 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1273 %
1274 % IsMagickCoreInstantiated() returns MagickFalse if the ImageMagick
1275 % environment has not been instantiated; the ImageMagick environment
1276 % has been instantiated when MagickCoreGenesis() has been called but
1277 % MagickDestroy() has not been called.
1278 %
1279 % The format of the IsMagickCoreInstantiated method is:
1280 %
1281 % MagickBooleanType IsMagickCoreInstantiated(void)
1282 %
1283 */
1284 MagickExport MagickBooleanType IsMagickCoreInstantiated(void)
1285 {
1286  return(magickcore_instantiated);
1287 }
1288 ␌
1289 /*
1290 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1291 % %
1292 % %
1293 % %
1294 + M a g i c k C o m p o n e n t G e n e s i s %
1295 % %
1296 % %
1297 % %
1298 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1299 %
1300 % MagickComponentGenesis() instantiates the magick component.
1301 %
1302 % The format of the MagickComponentGenesis method is:
1303 %
1304 % MagickBooleanType MagickComponentGenesis(void)
1305 %
1306 */
1307 MagickPrivate MagickBooleanType MagickComponentGenesis(void)
1308 {
1309  if (magick_semaphore == (SemaphoreInfo *) NULL)
1310  magick_semaphore=AcquireSemaphoreInfo();
1311  return(MagickTrue);
1312 }
1313 ␌
1314 /*
1315 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1316 % %
1317 % %
1318 % %
1319 + M a g i c k C o m p o n e n t T e r m i n u s %
1320 % %
1321 % %
1322 % %
1323 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1324 %
1325 % MagickComponentTerminus() destroys the magick component.
1326 %
1327 % The format of the MagickComponentTerminus method is:
1328 %
1329 % void MagickComponentTerminus(void)
1330 %
1331 */
1332 MagickPrivate void MagickComponentTerminus(void)
1333 {
1334  if (magick_semaphore == (SemaphoreInfo *) NULL)
1335  ActivateSemaphoreInfo(&magick_semaphore);
1336  LockSemaphoreInfo(magick_semaphore);
1337  if (magick_list != (SplayTreeInfo *) NULL)
1338  {
1339  magick_list=DestroySplayTree(magick_list);
1340  magick_list_initialized=MagickFalse;
1341  }
1342  UnlockSemaphoreInfo(magick_semaphore);
1343  RelinquishSemaphoreInfo(&magick_semaphore);
1344 }
1345 ␌
1346 /*
1347 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1348 % %
1349 % %
1350 % %
1351 % M a g i c k C o r e G e n e s i s %
1352 % %
1353 % %
1354 % %
1355 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1356 %
1357 % MagickCoreGenesis() initializes the MagickCore environment.
1358 %
1359 % The format of the MagickCoreGenesis function is:
1360 %
1361 % MagickCoreGenesis(const char *path,
1362 % const MagickBooleanType establish_signal_handlers)
1363 %
1364 % A description of each parameter follows:
1365 %
1366 % o path: the execution path of the current ImageMagick client.
1367 %
1368 % o establish_signal_handlers: set to MagickTrue to use MagickCore's own
1369 % signal handlers for common signals.
1370 %
1371 */
1372 
1373 static SignalHandler *SetMagickSignalHandler(int signal_number,
1374  SignalHandler *handler)
1375 {
1376 #if defined(MAGICKCORE_HAVE_SIGACTION) && defined(MAGICKCORE_HAVE_SIGEMPTYSET)
1377  int
1378  status;
1379 
1380  sigset_t
1381  mask;
1382 
1383  struct sigaction
1384  action,
1385  previous_action;
1386 
1387  sigemptyset(&mask);
1388  sigaddset(&mask,signal_number);
1389  sigprocmask(SIG_BLOCK,&mask,NULL);
1390  action.sa_mask=mask;
1391  action.sa_handler=handler;
1392  action.sa_flags=0;
1393 #if defined(SA_INTERRUPT)
1394  action.sa_flags|=SA_INTERRUPT;
1395 #endif
1396 #if defined(SA_ONSTACK)
1397  action.sa_flags|=SA_ONSTACK;
1398 #endif
1399  previous_action.sa_handler=SIG_DFL;
1400  status=sigaction(signal_number,&action,&previous_action);
1401  if (status < 0)
1402  return(SIG_ERR);
1403  sigprocmask(SIG_UNBLOCK,&mask,NULL);
1404  return(previous_action.sa_handler);
1405 #else
1406  return(signal(signal_number,handler));
1407 #endif
1408 }
1409 
1410 static void MagickSignalHandler(int signal_number)
1411 {
1412  if (magickcore_signal_in_progress != MagickFalse)
1413  (void) SetMagickSignalHandler(signal_number,signal_handlers[signal_number]);
1414  magickcore_signal_in_progress=MagickTrue;
1415  AsynchronousResourceComponentTerminus();
1416 #if defined(SIGQUIT)
1417  if (signal_number == SIGQUIT)
1418  abort();
1419 #endif
1420 #if defined(SIGABRT)
1421  if (signal_number == SIGABRT)
1422  abort();
1423 #endif
1424 #if defined(SIGBUS)
1425  if (signal_number == SIGBUS)
1426  abort();
1427 #endif
1428 #if defined(SIGFPE)
1429  if (signal_number == SIGFPE)
1430  abort();
1431 #endif
1432 #if defined(SIGSEGV)
1433  if (signal_number == SIGSEGV)
1434  abort();
1435 #endif
1436 #if !defined(MAGICKCORE_HAVE__EXIT)
1437  exit(signal_number);
1438 #else
1439 #if defined(SIGHUP)
1440  if (signal_number == SIGHUP)
1441  _exit(signal_number);
1442 #endif
1443 #if defined(SIGINT)
1444  if (signal_number == SIGINT)
1445  _exit(signal_number);
1446 #endif
1447 #if defined(MAGICKCORE_HAVE_RAISE)
1448  if (signal_handlers[signal_number] != MagickSignalHandler)
1449  raise(signal_number);
1450 #endif
1451  _exit(signal_number); /* do not invoke registered atexit() methods */
1452 #endif
1453 }
1454 
1455 static SignalHandler *RegisterMagickSignalHandler(int signal_number)
1456 {
1457  SignalHandler
1458  *handler;
1459 
1460  handler=SetMagickSignalHandler(signal_number,MagickSignalHandler);
1461  if (handler == SIG_ERR)
1462  return(handler);
1463  if (handler != SIG_DFL)
1464  handler=SetMagickSignalHandler(signal_number,handler);
1465  else
1466  (void) LogMagickEvent(ConfigureEvent,GetMagickModule(),
1467  "Register handler for signal: %d",signal_number);
1468  return(handler);
1469 }
1470 
1471 MagickExport void MagickCoreGenesis(const char *path,
1472  const MagickBooleanType establish_signal_handlers)
1473 {
1474  char
1475  *events,
1476  execution_path[MagickPathExtent],
1477  filename[MagickPathExtent];
1478 
1479  /*
1480  Initialize the Magick environment.
1481  */
1482 #if defined(__has_feature)
1483 #if __has_feature(address_sanitizer)
1484  (void) putenv("MAGICK_THREAD_LIMIT=1");
1485 #endif
1486 #endif
1487  InitializeMagickMutex();
1488  LockMagickMutex();
1489  if (magickcore_instantiated != MagickFalse)
1490  {
1491  UnlockMagickMutex();
1492  return;
1493  }
1494  (void) SemaphoreComponentGenesis();
1495  (void) ExceptionComponentGenesis();
1496  (void) LogComponentGenesis();
1497  (void) LocaleComponentGenesis();
1498  (void) RandomComponentGenesis();
1499  events=GetEnvironmentValue("MAGICK_DEBUG");
1500  if (events != (char *) NULL)
1501  {
1502  (void) SetLogEventMask(events);
1503  events=DestroyString(events);
1504  }
1505 #if defined(MAGICKCORE_WINDOWS_SUPPORT)
1506  NTWindowsGenesis();
1507 #endif
1508  /*
1509  Set client name and execution path.
1510  */
1511 #if defined(MAGICKCORE_WINDOWS_SUPPORT)
1512  if ((path != (const char *) NULL) && (IsPathAccessible(path) != MagickFalse))
1513 #else
1514  if ((path != (const char *) NULL) && (*path == *DirectorySeparator) &&
1515  (IsPathAccessible(path) != MagickFalse))
1516 #endif
1517  (void) CopyMagickString(execution_path,path,MagickPathExtent);
1518  else
1519  (void) GetExecutionPath(execution_path,MagickPathExtent);
1520  GetPathComponent(execution_path,TailPath,filename);
1521  (void) SetClientName(filename);
1522  GetPathComponent(execution_path,HeadPath,execution_path);
1523  (void) SetClientPath(execution_path);
1524  if (establish_signal_handlers != MagickFalse)
1525  {
1526  /*
1527  Set signal handlers.
1528  */
1529 #if defined(SIGABRT)
1530  if (signal_handlers[SIGABRT] == (SignalHandler *) NULL)
1531  signal_handlers[SIGABRT]=RegisterMagickSignalHandler(SIGABRT);
1532 #endif
1533 #if defined(SIGBUS)
1534  if (signal_handlers[SIGBUS] == (SignalHandler *) NULL)
1535  signal_handlers[SIGBUS]=RegisterMagickSignalHandler(SIGBUS);
1536 #endif
1537 #if defined(SIGSEGV)
1538  if (signal_handlers[SIGSEGV] == (SignalHandler *) NULL)
1539  signal_handlers[SIGSEGV]=RegisterMagickSignalHandler(SIGSEGV);
1540 #endif
1541 #if defined(SIGFPE)
1542  if (signal_handlers[SIGFPE] == (SignalHandler *) NULL)
1543  signal_handlers[SIGFPE]=RegisterMagickSignalHandler(SIGFPE);
1544 #endif
1545 #if defined(SIGHUP)
1546  if (signal_handlers[SIGHUP] == (SignalHandler *) NULL)
1547  signal_handlers[SIGHUP]=RegisterMagickSignalHandler(SIGHUP);
1548 #endif
1549 #if defined(SIGINT)
1550  if (signal_handlers[SIGINT] == (SignalHandler *) NULL)
1551  signal_handlers[SIGINT]=RegisterMagickSignalHandler(SIGINT);
1552 #endif
1553 #if defined(SIGQUIT)
1554  if (signal_handlers[SIGQUIT] == (SignalHandler *) NULL)
1555  signal_handlers[SIGQUIT]=RegisterMagickSignalHandler(SIGQUIT);
1556 #endif
1557 #if defined(SIGTERM)
1558  if (signal_handlers[SIGTERM] == (SignalHandler *) NULL)
1559  signal_handlers[SIGTERM]=RegisterMagickSignalHandler(SIGTERM);
1560 #endif
1561 #if defined(SIGXCPU)
1562  if (signal_handlers[SIGXCPU] == (SignalHandler *) NULL)
1563  signal_handlers[SIGXCPU]=RegisterMagickSignalHandler(SIGXCPU);
1564 #endif
1565 #if defined(SIGXFSZ)
1566  if (signal_handlers[SIGXFSZ] == (SignalHandler *) NULL)
1567  signal_handlers[SIGXFSZ]=RegisterMagickSignalHandler(SIGXFSZ);
1568 #endif
1569  }
1570  /*
1571  Instantiate magick resources.
1572  */
1573  (void) ConfigureComponentGenesis();
1574  (void) PolicyComponentGenesis();
1575 #if MAGICKCORE_ZERO_CONFIGURATION_SUPPORT
1576  (void) ZeroConfigurationPolicy;
1577 #endif
1578  (void) CacheComponentGenesis();
1579  (void) ResourceComponentGenesis();
1580  (void) CoderComponentGenesis();
1581  (void) MagickComponentGenesis();
1582 #if defined(MAGICKCORE_MODULES_SUPPORT)
1583  (void) ModuleComponentGenesis();
1584 #endif
1585  (void) DelegateComponentGenesis();
1586  (void) MagicComponentGenesis();
1587  (void) ColorComponentGenesis();
1588  (void) TypeComponentGenesis();
1589  (void) MimeComponentGenesis();
1590  (void) AnnotateComponentGenesis();
1591 #if defined(MAGICKCORE_X11_DELEGATE)
1592  (void) XComponentGenesis();
1593 #endif
1594  (void) RegistryComponentGenesis();
1595  (void) MonitorComponentGenesis();
1596  magickcore_instantiated=MagickTrue;
1597  UnlockMagickMutex();
1598 }
1599 ␌
1600 /*
1601 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1602 % %
1603 % %
1604 % %
1605 % M a g i c k C o r e T e r m i n u s %
1606 % %
1607 % %
1608 % %
1609 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1610 %
1611 % MagickCoreTerminus() destroys the MagickCore environment.
1612 %
1613 % The format of the MagickCoreTerminus function is:
1614 %
1615 % MagickCoreTerminus(void)
1616 %
1617 */
1618 MagickExport void MagickCoreTerminus(void)
1619 {
1620  if (magickcore_instantiated == MagickFalse)
1621  return;
1622  MonitorComponentTerminus();
1623  RegistryComponentTerminus();
1624 #if defined(MAGICKCORE_X11_DELEGATE)
1625  XComponentTerminus();
1626 #endif
1627 #if defined(MAGICKCORE_XML_DELEGATE)
1628  xmlCleanupParser();
1629 #endif
1630  AnnotateComponentTerminus();
1631  MimeComponentTerminus();
1632  TypeComponentTerminus();
1633 #if defined(MAGICKCORE_OPENCL_SUPPORT)
1634  OpenCLTerminus();
1635 #endif
1636  ColorComponentTerminus();
1637 #if defined(MAGICKCORE_WINDOWS_SUPPORT)
1638  NTWindowsTerminus();
1639 #endif
1640  MagicComponentTerminus();
1641  DelegateComponentTerminus();
1642  MagickComponentTerminus();
1643 #if !defined(MAGICKCORE_BUILD_MODULES)
1644  UnregisterStaticModules();
1645 #endif
1646 #if defined(MAGICKCORE_MODULES_SUPPORT)
1647  ModuleComponentTerminus();
1648 #endif
1649  CoderComponentTerminus();
1650  ResourceComponentTerminus();
1651  CacheComponentTerminus();
1652  PolicyComponentTerminus();
1653  ConfigureComponentTerminus();
1654  RandomComponentTerminus();
1655  LocaleComponentTerminus();
1656  LogComponentTerminus();
1657  ExceptionComponentTerminus();
1658  SemaphoreComponentTerminus();
1659  magickcore_instantiated=MagickFalse;
1660 }
1661 ␌
1662 /*
1663 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1664 % %
1665 % %
1666 % %
1667 + R e g i s t e r M a g i c k I n f o %
1668 % %
1669 % %
1670 % %
1671 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1672 %
1673 % RegisterMagickInfo() adds attributes for a particular image format to the
1674 % list of supported formats. The attributes include the image format name,
1675 % a method to read and/or write the format, whether the format supports the
1676 % saving of more than one frame to the same file or blob, whether the format
1677 % supports native in-memory I/O, and a brief description of the format.
1678 %
1679 % The format of the RegisterMagickInfo method is:
1680 %
1681 % MagickInfo *RegisterMagickInfo(MagickInfo *magick_info)
1682 %
1683 % A description of each parameter follows:
1684 %
1685 % o magick_info: the magick info.
1686 %
1687 */
1688 MagickExport MagickBooleanType RegisterMagickInfo(MagickInfo *magick_info)
1689 {
1690  MagickBooleanType
1691  status;
1692 
1693  /*
1694  Register a new image format.
1695  */
1696  assert(magick_info != (MagickInfo *) NULL);
1697  assert(magick_info->signature == MagickCoreSignature);
1698  if (IsEventLogging() != MagickFalse)
1699  (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",magick_info->name);
1700  if (magick_list == (SplayTreeInfo *) NULL)
1701  return(MagickFalse);
1702  if ((GetMagickDecoderThreadSupport(magick_info) == MagickFalse) ||
1703  (GetMagickEncoderThreadSupport(magick_info) == MagickFalse))
1704  magick_info->semaphore=AcquireSemaphoreInfo();
1705  status=AddValueToSplayTree(magick_list,magick_info->name,magick_info);
1706  return(status);
1707 }
1708 ␌
1709 /*
1710 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1711 % %
1712 % %
1713 % %
1714 + R e s e t M a g i c k P r e c i s i o n %
1715 % %
1716 % %
1717 % %
1718 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1719 %
1720 % ResetMagickPrecision() resets the magick_precision value.
1721 %
1722 % The format of the ResetMagickPrecision method is:
1723 %
1724 % void ResetMagickPrecision(void)
1725 %
1726 */
1727 MagickPrivate void ResetMagickPrecision(void)
1728 {
1729  magick_precision=0;
1730 }
1731 ␌
1732 /*
1733 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1734 % %
1735 % %
1736 % %
1737 % S e t M a g i c k P r e c i s i o n %
1738 % %
1739 % %
1740 % %
1741 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1742 %
1743 % SetMagickPrecision() sets the maximum number of significant digits to be
1744 % printed.
1745 %
1746 % An input argument of 0 returns the current precision setting.
1747 %
1748 % A negative value forces the precision to reset to a default value according
1749 % to the environment variable "MAGICK_PRECISION", the current 'policy'
1750 % configuration setting, or the default value of '6', in that order.
1751 %
1752 % The format of the SetMagickPrecision method is:
1753 %
1754 % int SetMagickPrecision(const int precision)
1755 %
1756 % A description of each parameter follows:
1757 %
1758 % o precision: set the maximum number of significant digits to be printed.
1759 %
1760 */
1761 MagickExport int SetMagickPrecision(const int precision)
1762 {
1763 #define MagickPrecision (MAGICKCORE_QUANTUM_DEPTH/8+4)
1764 
1765  if (IsEventLogging() != MagickFalse)
1766  (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
1767  if (precision > 0)
1768  magick_precision=precision;
1769  if ((precision < 0) || (magick_precision == 0))
1770  {
1771  char
1772  *limit;
1773 
1775  *exception = AcquireExceptionInfo();
1776 
1777  magick_precision=MagickPrecision;
1778  limit=(char *) GetImageRegistry(StringRegistryType,"precision",exception);
1779  exception=DestroyExceptionInfo(exception);
1780  if (limit == (char *) NULL)
1781  limit=GetEnvironmentValue("MAGICK_PRECISION");
1782  if (limit == (char *) NULL)
1783  limit=GetPolicyValue("system:precision"); /* deprecated */
1784  if (limit != (char *) NULL)
1785  {
1786  magick_precision=StringToInteger(limit);
1787  limit=DestroyString(limit);
1788  }
1789  }
1790  return(magick_precision);
1791 }
1792 ␌
1793 /*
1794 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1795 % %
1796 % %
1797 % %
1798 + U n r e g i s t e r M a g i c k I n f o %
1799 % %
1800 % %
1801 % %
1802 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1803 %
1804 % UnregisterMagickInfo() removes a name from the magick info list. It returns
1805 % MagickFalse if the name does not exist in the list otherwise MagickTrue.
1806 %
1807 % The format of the UnregisterMagickInfo method is:
1808 %
1809 % MagickBooleanType UnregisterMagickInfo(const char *name)
1810 %
1811 % A description of each parameter follows:
1812 %
1813 % o name: a character string that represents the image format we are
1814 % looking for.
1815 %
1816 */
1817 MagickExport MagickBooleanType UnregisterMagickInfo(const char *name)
1818 {
1819  const MagickInfo
1820  *p;
1821 
1822  MagickBooleanType
1823  status;
1824 
1825  assert(name != (const char *) NULL);
1826  if (magick_list == (SplayTreeInfo *) NULL)
1827  return(MagickFalse);
1828  if (GetNumberOfNodesInSplayTree(magick_list) == 0)
1829  return(MagickFalse);
1830  LockSemaphoreInfo(magick_semaphore);
1831  ResetSplayTreeIterator(magick_list);
1832  p=(const MagickInfo *) GetNextValueInSplayTree(magick_list);
1833  while (p != (const MagickInfo *) NULL)
1834  {
1835  if (LocaleCompare(p->name,name) == 0)
1836  break;
1837  p=(const MagickInfo *) GetNextValueInSplayTree(magick_list);
1838  }
1839  status=DeleteNodeByValueFromSplayTree(magick_list,p);
1840  UnlockSemaphoreInfo(magick_semaphore);
1841  return(status);
1842 }