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