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